source: trunk/lib/Prefs.inc.php @ 149

Last change on this file since 149 was 149, checked in by scdev, 18 years ago

Q - while we're changing interfaces I'm going to change ->clearAuth() to ->clear().

File size: 10.7 KB
Line 
1<?php
2/**
3 * Prefs.inc.php
4 * code by strangecode :: www.strangecode.com :: this document contains copyrighted information
5 *
6 * Prefs provides an API for saving arbitrary values in a user's session.
7 * Session prefs can be stored into a database with the optional save() and load() methods.
8 *
9 * @author  Quinn Comendant <quinn@strangecode.com>
10 * @version 2.1
11 */
12class Prefs {
13
14    // Namespace of this instance of Prefs.
15    var $_ns;
16
17    // Configuration of this object.
18    var $_params = array(
19       
20        // The current user_id for which to load/save preferences.
21        'user_id' => null,
22       
23        // How long before we force a reload of the prefs data? 3600 = once every hour.
24        'load_timeout' => 3600,
25       
26        // Enable database storage.
27        'enable_db' => true,
28       
29        // Name of database table to store prefs.
30        'db_table' => 'pref_tbl',
31
32        // Automatically create table and verify columns. Better set to false after site launch.
33        'create_table' => true,
34    );
35
36    /**
37     * Prefs constructor.
38     */
39    function Prefs($namespace='')
40    {
41        $app =& App::getInstance();
42
43        $this->_ns = '_prefs_' . $namespace;
44       
45        // Initialized the prefs array.
46        if (!isset($_SESSION[$this->_ns])) {
47            $_SESSION[$this->_ns] = array('loaded' => false, 'data' => array());
48        }
49
50        // Get create tables config from global context.
51        if (!is_null($app->getParam('db_create_tables'))) {
52            $this->setParam(array('create_table' => $app->getParam('db_create_tables')));
53        }
54    }
55
56    /**
57     * Setup the database table for this class.
58     *
59     * @access  public
60     * @author  Quinn Comendant <quinn@strangecode.com>
61     * @since   04 Jun 2006 16:41:42
62     */
63    function initDB($recreate_db=false)
64    {
65        $app =& App::getInstance();
66        $db =& DB::getInstance();
67
68        static $_db_tested = false;
69
70        if ($recreate_db || !$_db_tested && $this->getParam('create_table')) {
71            if ($recreate_db) {
72                $db->query("DROP TABLE IF EXISTS " . $this->getParam('db_table'));
73                $app->logMsg(sprintf('Dropping and recreating table %s.', $this->getParam('db_table')), LOG_DEBUG, __FILE__, __LINE__);
74            }
75            $db->query("CREATE TABLE IF NOT EXISTS " . $db->escapeString($this->getParam('db_table')) . " (
76                user_id VARCHAR(32) NOT NULL DEFAULT '',
77                pref_namespace VARCHAR(32) NOT NULL DEFAULT '',
78                pref_key VARCHAR(64) NOT NULL DEFAULT '',
79                pref_value TEXT,
80                PRIMARY KEY (user_id, pref_namespace, pref_key)
81            )");
82
83            if (!$db->columnExists($this->getParam('db_table'), array(
84                'user_id',
85                'pref_namespace',
86                'pref_key',
87                'pref_value',
88            ), false, false)) {
89                $app->logMsg(sprintf('Database table %s has invalid columns. Please update this table manually.', $this->getParam('db_table')), LOG_ALERT, __FILE__, __LINE__);
90                trigger_error(sprintf('Database table %s has invalid columns. Please update this table manually.', $this->getParam('db_table')), E_USER_ERROR);
91            }
92        }
93        $_db_tested = true;
94    }
95
96    /**
97     * Set the params of this object.
98     *
99     * @param  array $params   Array of param keys and values to set.
100     */
101    function setParam($params=null)
102    {
103        if (isset($params) && is_array($params)) {
104            // Merge new parameters with old overriding only those passed.
105            $this->_params = array_merge($this->_params, $params);
106        }
107    }
108
109    /**
110     * Return the value of a parameter, if it exists.
111     *
112     * @access public
113     * @param string $param        Which parameter to return.
114     * @return mixed               Configured parameter value.
115     */
116    function getParam($param)
117    {
118        $app =& App::getInstance();
119   
120        if (isset($this->_params[$param])) {
121            return $this->_params[$param];
122        } else {
123            $app->logMsg(sprintf('Parameter is not set: %s', $param), LOG_DEBUG, __FILE__, __LINE__);
124            return null;
125        }
126    }
127
128    /**
129     * Sets the default value of a preference. The pref will be set only if
130     * is not set already.
131     *
132     * @param  string $key       The name of the preference to modify.
133     * @param  string $val       The new value for this preference.
134     */
135    function setDefaults($defaults)
136    {
137        $app =& App::getInstance();
138        if (isset($defaults) && is_array($defaults)) {
139            // Apply defaults to the session, setting only non-existing values.
140            $app->logMsg(sprintf('Pre-defaulting: %s', getDump($_SESSION[$this->_ns]['data'])), LOG_DEBUG, __FILE__, __LINE__);
141            $_SESSION[$this->_ns]['data'] = array_merge($defaults, $_SESSION[$this->_ns]['data']);
142            $app->logMsg(sprintf('Post-defaulting: %s', getDump($_SESSION[$this->_ns]['data'])), LOG_DEBUG, __FILE__, __LINE__);
143        }
144    }
145
146    /**
147     * Sets the given preferences to the specific value,
148     *
149     * @param  string $key       The name of the preference to modify.
150     * @param  string $val       The new value for this preference.
151     */
152    function set($key, $val)
153    {
154        if ('' != $key && '' != $val) {
155            $_SESSION[$this->_ns]['data'][$key] = $val;
156        }
157    }
158
159    /**
160     * Returns the value of the requested preference.
161     *
162     * @param string $key       The name of the preference to retrieve.
163     *
164     * @return string           The value of the preference.
165     */
166    function get($key)
167    {
168        return (isset($_SESSION[$this->_ns]['data'][$key])) ? $_SESSION[$this->_ns]['data'][$key] : null;
169    }
170
171    /**
172     * To see if a preference has been set.
173     *
174     * @param string $key       The name of the preference to check.
175     *
176     * @return boolean          True if the preference isset and not empty
177     *                          false otherwise.
178     */
179    function exists($key)
180    {
181        return isset($_SESSION[$this->_ns]['data'][$key]);
182    }
183
184    /**
185     * Clear a set preference value.
186     *
187     * @param string $key       The name of the preference to delete.
188     */
189    function delete($key)
190    {
191        unset($_SESSION[$this->_ns]['data'][$key]);
192    }
193
194    /**
195     * Empty the $_SESSION cache. This should be executed with the same consideration as $auth->clear()
196     */
197    function clear()
198    {
199        $_SESSION[$this->_ns] = array();
200    }
201   
202    /*
203    * Retreives all prefs from the database and stores them in the $_SESSION.
204    *
205    * @access   public
206    * @return   bool    True if loading succeeded.
207    * @author   Quinn Comendant <quinn@strangecode.com>
208    * @version  1.0
209    * @since    04 Jun 2006 16:56:53
210    */
211    function load()
212    {
213        $app =& App::getInstance();
214        $db =& DB::getInstance();
215       
216        // Skip this method if not using the db.
217        if (true !== $this->getParam('enable_db')) {
218            return true;
219        }
220
221        // Prefs already loaded for this session.
222        if ($this->_isLoaded()) {
223            return true;
224        }
225
226        // User_id must not be empty.
227        if ('' == $this->getParam('user_id')) {
228            $app->logMsg(sprintf('Cannot save prefs because user_id not set.', null), LOG_ERR, __FILE__, __LINE__);
229            return false;
230        }
231
232        $this->initDB();
233       
234        // Retreive all prefs for this user and namespace.
235        $qid = $db->query("
236            SELECT pref_key, pref_value
237            FROM " . $db->escapeString($this->getParam('db_table')) . "
238            WHERE user_id = '" . $db->escapeString($this->getParam('user_id')) . "'
239            AND pref_namespace = '" . $db->escapeString($this->_ns) . "'
240            LIMIT 10000
241        ");
242        while (list($key, $val) = mysql_fetch_row($qid)) {
243            $_SESSION[$this->_ns]['data'][$key] = $val;
244        }
245       
246        // Data loaded only once per session.
247        $_SESSION[$this->_ns]['loaded'] = true;
248        $_SESSION[$this->_ns]['load_datetime'] = date('Y-m-d H:i:s');
249       
250        return true;
251    }
252   
253    /*
254    * Returns true if the prefs had been loaded from the database into the $_SESSION recently.
255    * This function is simply a check so the database isn't access every page load.
256    *
257    * @access   private
258    * @return   bool    True if prefs are loaded.
259    * @author   Quinn Comendant <quinn@strangecode.com>
260    * @version  1.0
261    * @since    04 Jun 2006 17:12:44
262    */
263    function _isLoaded()
264    {
265        if (isset($_SESSION[$this->_ns]['load_datetime'])
266        && strtotime($_SESSION[$this->_ns]['load_datetime']) > time() - $this->getParam('load_timeout')
267        && isset($_SESSION[$this->_ns]['loaded']) 
268        && true === $_SESSION[$this->_ns]['loaded']) {
269            return true;
270        } else {
271            return false;
272        }
273    }
274   
275    /*
276    * Saves all prefs stored in the $_SESSION into the database.
277    *
278    * @access   public
279    * @return   bool    True if prefs exist and were saved.
280    * @author   Quinn Comendant <quinn@strangecode.com>
281    * @version  1.0
282    * @since    04 Jun 2006 17:19:56
283    */
284    function save()
285    {
286        $app =& App::getInstance();
287        $db =& DB::getInstance();
288       
289        // Skip this method if not using the db.
290        if (true !== $this->getParam('enable_db')) {
291            return true;
292        }
293       
294        // User_id must not be empty.
295        if ('' == $this->getParam('user_id')) {
296            $app->logMsg(sprintf('Cannot save prefs because user_id not set.', null), LOG_ERR, __FILE__, __LINE__);
297            return false;
298        }
299
300        $this->initDB();
301
302        if (isset($_SESSION[$this->_ns]['data']) && is_array($_SESSION[$this->_ns]['data'])) {
303            // Delete old prefs from database.
304            $db->query("
305                DELETE FROM " . $db->escapeString($this->getParam('db_table')) . "
306                WHERE user_id = '" . $db->escapeString($this->getParam('user_id')) . "'
307                AND pref_namespace = '" . $db->escapeString($this->_ns) . "'
308            ");
309           
310            // Insert new prefs.
311            $insert_values = array();
312            foreach ($_SESSION[$this->_ns]['data'] as $key => $val) {
313                if ('' != trim($key) && '' != trim($val)) {
314                    $insert_values[] = sprintf("('%s', '%s', '%s', '%s')", $db->escapeString($this->getParam('user_id')), $db->escapeString($this->_ns), $db->escapeString($key), $db->escapeString($val));
315                }
316            }
317            $db->query("
318                INSERT LOW_PRIORITY INTO " . $db->escapeString($this->getParam('db_table')) . "
319                (user_id, pref_namespace, pref_key, pref_value)
320                VALUES " . join(', ', $insert_values) . "
321            ");
322           
323            $app->logMsg(sprintf('Saved %s preferences to database.', sizeof($insert_values)), LOG_DEBUG, __FILE__, __LINE__);
324            return true;
325        }
326       
327        return false;
328    }
329}
330
331
332?>
Note: See TracBrowser for help on using the repository browser.