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

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

Q - added persistant database storage to Prefs.inc.php. Modified getParam failure log type to LOG_DEBUG in all classes.

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