Changeset 477 for trunk/lib/Prefs.inc.php
- Timestamp:
- May 3, 2014 3:13:19 PM (10 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/lib/Prefs.inc.php
r468 r477 30 30 * @version 2.1 31 31 * 32 * Example of use :32 * Example of use (database storagetype): 33 33 --------------------------------------------------------------------- 34 34 // Load preferences for the user's session. … … 36 36 $prefs = new Prefs('my-namespace'); 37 37 $prefs->setParam(array( 38 ' persistent' => $auth->isLoggedIn(),38 'storagetype' => ($auth->isLoggedIn() ? 'database' : 'session'), 39 39 'user_id' => $auth->get('user_id'), 40 40 )); … … 49 49 $prefs->set('datalog_num_entries', getFormData('datalog_num_entries')); 50 50 $prefs->save(); 51 52 51 --------------------------------------------------------------------- 53 52 */ … … 60 59 private $_params = array( 61 60 61 // Legacy parameter, superceeded by the 'storagetype' setting. 62 62 // Enable database storage. If this is false, all prefs will live only as long as the session. 63 'persistent' => false, 64 65 // The current user_id for which to load/save persistent preferences. 63 'persistent' => null, 64 65 // Store preferences in one of the available storage mechanisms: session, cookie, database 66 'storagetype' => 'session', 67 68 // ---------------------------------------------------------- 69 // Cookie-type settings. 70 71 // Lifespan of the cookie. If set to an integer, interpreted as a timestamp (0 for 'when user closes browser'), otherwise as a strtotime-compatible value ('tomorrow', etc). 72 'cookie_expire' => '+10 years', 73 74 // The path on the server in which the cookie will be available on. 75 'cookie_path' => null, 76 77 // The domain that the cookie is available to. 78 'cookie_domain' => null, 79 80 // ---------------------------------------------------------- 81 // Database-type settings. 82 83 // The current user_id for which to load/save database-backed preferences. 66 84 'user_id' => null, 67 85 … … 82 100 public function __construct($namespace='') 83 101 { 84 102 $app =& App::getInstance(); 85 103 86 104 $this->_ns = $namespace; … … 106 124 public function initDB($recreate_db=false) 107 125 { 108 109 126 $app =& App::getInstance(); 127 $db =& DB::getInstance(); 110 128 111 129 static $_db_tested = false; … … 144 162 public function setParam($params=null) 145 163 { 164 // CLI scripts can't use prefs stored in HTTP-based protocols. 165 if (defined('_CLI') 166 && isset($params['storagetype']) 167 && in_array($params['storagetype'], array('cookie', 'session'))) { 168 $app->logMsg(sprintf('Storage type %s not available for CLI', $params['storagetype']), LOG_NOTICE, __FILE__, __LINE__); 169 } 170 171 // Convert the legacy param 'persistent' to 'storagetype=database'. 172 if (isset($params['persistent']) && $params['persistent'] && !isset($params['storagetype'])) { 173 $params['storagetype'] = 'database'; 174 } 175 146 176 if (isset($params) && is_array($params)) { 147 177 // Merge new parameters with old overriding only those passed. … … 159 189 public function getParam($param) 160 190 { 161 191 $app =& App::getInstance(); 162 192 163 193 if (isset($this->_params[$param])) { … … 190 220 * @param string $key The name of the preference to modify. 191 221 * @param string $val The new value for this preference. 192 * @param bool $persistent Save this value forever? Set to false and value will exist as long as the session is in use.193 222 */ 194 223 public function set($key, $val) … … 196 225 $app =& App::getInstance(); 197 226 198 if ('' == $key) { 199 $app->logMsg(sprintf('Key is empty (provided with value: %s)', $val), LOG_NOTICE, __FILE__, __LINE__); 227 if (!is_string($key)) { 228 $app->logMsg(sprintf('Key is not a string-compatible type (%s)', getDump($key)), LOG_NOTICE, __FILE__, __LINE__); 229 return false; 230 } 231 if ('' == trim($key)) { 232 $app->logMsg(sprintf('Key is empty (along with value: %s)', $val), LOG_NOTICE, __FILE__, __LINE__); 233 return false; 234 } 235 if (!is_scalar($val) && !is_array($val) && !is_object($val)) { 236 $app->logMsg(sprintf('Value is not a string-compatible type (%s=%s)', $key, getDump($val)), LOG_WARNING, __FILE__, __LINE__); 200 237 return false; 201 238 } … … 205 242 // - or the new value is different than the default 206 243 // - or there is a previously existing saved key. 207 if (!isset($_SESSION['_prefs'][$this->_ns]['defaults'][$key]) 208 || $_SESSION['_prefs'][$this->_ns]['defaults'][$key] != $val 209 || isset($_SESSION['_prefs'][$this->_ns]['saved'][$key])) { 210 $_SESSION['_prefs'][$this->_ns]['saved'][$key] = $val; 211 $app->logMsg(sprintf('Setting preference %s => %s', $key, truncate(getDump($val, true), 128, 'end')), LOG_DEBUG, __FILE__, __LINE__); 212 } else { 213 $app->logMsg(sprintf('Not setting preference %s => %s', $key, truncate(getDump($val, true), 128, 'end')), LOG_DEBUG, __FILE__, __LINE__); 214 } 244 switch ($this->getParam('storagetype')) { 245 case 'session': 246 case 'database': // DB prefs are saved in the session temporarily until they are saved. 247 if (!isset($_SESSION['_prefs'][$this->_ns]['defaults'][$key]) 248 || $_SESSION['_prefs'][$this->_ns]['defaults'][$key] != $val 249 || isset($_SESSION['_prefs'][$this->_ns]['saved'][$key])) { 250 $_SESSION['_prefs'][$this->_ns]['saved'][$key] = $val; 251 $app->logMsg(sprintf('Setting session preference %s => %s', $key, getDump($val, true)), LOG_DEBUG, __FILE__, __LINE__); 252 } else { 253 $app->logMsg(sprintf('Not setting session preference %s => %s', $key, getDump($val, true)), LOG_DEBUG, __FILE__, __LINE__); 254 } 255 break; 256 257 case 'cookie': 258 $name = $this->_getCookieName($key); 259 $val = json_encode($val); 260 $app->setCookie($name, $val, $this->getParam('cookie_expire'), $this->getParam('cookie_path'), $this->getParam('cookie_domain')); 261 $app->logMsg(sprintf('Setting cookie preference %s => %s', $key, $val), LOG_DEBUG, __FILE__, __LINE__); 262 break; 263 } 264 215 265 } 216 266 … … 226 276 { 227 277 $app =& App::getInstance(); 228 if (isset($_SESSION['_prefs'][$this->_ns]['saved']) && array_key_exists($key, $_SESSION['_prefs'][$this->_ns]['saved'])) { 229 $app->logMsg(sprintf('Found %s in saved', $key), LOG_DEBUG, __FILE__, __LINE__); 230 return $_SESSION['_prefs'][$this->_ns]['saved'][$key]; 231 } else if (isset($_SESSION['_prefs'][$this->_ns]['defaults']) && array_key_exists($key, $_SESSION['_prefs'][$this->_ns]['defaults'])) { 232 $app->logMsg(sprintf('Found %s in defaults', $key), LOG_DEBUG, __FILE__, __LINE__); 233 return $_SESSION['_prefs'][$this->_ns]['defaults'][$key]; 234 } else { 235 $app->logMsg(sprintf('Key not found in prefs cache: %s', $key), LOG_DEBUG, __FILE__, __LINE__); 236 return null; 278 279 switch ($this->getParam('storagetype')) { 280 case 'session': 281 case 'database': 282 if (isset($_SESSION['_prefs'][$this->_ns]['saved']) && array_key_exists($key, $_SESSION['_prefs'][$this->_ns]['saved'])) { 283 $app->logMsg(sprintf('Found %s in saved', $key), LOG_DEBUG, __FILE__, __LINE__); 284 return $_SESSION['_prefs'][$this->_ns]['saved'][$key]; 285 } else if (isset($_SESSION['_prefs'][$this->_ns]['defaults']) && array_key_exists($key, $_SESSION['_prefs'][$this->_ns]['defaults'])) { 286 $app->logMsg(sprintf('Found %s in defaults', $key), LOG_DEBUG, __FILE__, __LINE__); 287 return $_SESSION['_prefs'][$this->_ns]['defaults'][$key]; 288 } else { 289 $app->logMsg(sprintf('Key not found in prefs cache: %s', $key), LOG_DEBUG, __FILE__, __LINE__); 290 return null; 291 } 292 break; 293 294 case 'cookie': 295 $name = $this->_getCookieName($key); 296 if ($this->exists($key)) { 297 $val = json_decode($_COOKIE[$name]); 298 $app->logMsg(sprintf('Found %s in cookie: %s', $key, getDump($val)), LOG_DEBUG, __FILE__, __LINE__); 299 return $val; 300 } else { 301 $app->logMsg(sprintf('Key not found in cookie: %s', $key), LOG_DEBUG, __FILE__, __LINE__); 302 return null; 303 } 304 break; 237 305 } 238 306 } … … 246 314 public function exists($key) 247 315 { 248 return array_key_exists($key, $_SESSION['_prefs'][$this->_ns]['saved']); 316 switch ($this->getParam('storagetype')) { 317 case 'session': 318 case 'database': 319 return array_key_exists($key, $_SESSION['_prefs'][$this->_ns]['saved']); 320 321 case 'cookie': 322 $name = $this->_getCookieName($key); 323 return isset($_COOKIE[$name]); 324 } 325 249 326 } 250 327 … … 256 333 public function delete($key) 257 334 { 258 unset($_SESSION['_prefs'][$this->_ns]['saved'][$key]); 335 $app =& App::getInstance(); 336 337 switch ($this->getParam('storagetype')) { 338 case 'session': 339 case 'database': 340 unset($_SESSION['_prefs'][$this->_ns]['saved'][$key]); 341 break; 342 343 case 'cookie': 344 if ($this->exists($key)) { 345 // Just set the existing value to an empty string, which expires in the past. 346 $name = $this->_getCookieName($key); 347 $app->setCookie($name, '', time() - 86400); 348 // Also unset the received cookie value, so it is unavailable. 349 unset($_COOKIE[$name]); 350 } 351 break; 352 } 353 259 354 } 260 355 … … 265 360 public function clear($focus='all') 266 361 { 362 267 363 switch ($focus) { 268 364 case 'all' : 269 $_SESSION['_prefs'][$this->_ns] = array( 270 'loaded' => false, 271 'load_datetime' => '1970-01-01', 272 'defaults' => array(), 273 'saved' => array(), 274 ); 275 break; 276 365 switch ($this->getParam('storagetype')) { 366 case 'session': 367 case 'database': 368 $_SESSION['_prefs'][$this->_ns] = array( 369 'loaded' => false, 370 'load_datetime' => '1970-01-01', 371 'defaults' => array(), 372 'saved' => array(), 373 ); 374 break; 375 case 'cookie': 376 foreach ($_COOKIE as $key => $value) { 377 // All cookie keys with our internal prefix. Use only the last part as the key. 378 if (preg_match('/^' . preg_quote(sprintf('strangecode-%s-', $this->_ns)) . '(.+)$/i', $key, $match)) { 379 $this->delete($match[1]); 380 } 381 } 382 break; 383 } 384 break; 277 385 case 'defaults' : 278 386 $_SESSION['_prefs'][$this->_ns]['defaults'] = array(); 279 387 break; 280 281 388 case 'saved' : 282 389 $_SESSION['_prefs'][$this->_ns]['saved'] = array(); … … 298 405 { 299 406 $app =& App::getInstance(); 300 301 302 303 if (true !== $this->getParam('persistent')) {304 305 407 $db =& DB::getInstance(); 408 409 // Skip this method if not using the db. 410 if ('database' != $this->getParam('storagetype')) { 411 return true; 412 } 306 413 307 414 $this->initDB(); 308 415 309 416 // Prefs already loaded for this session. 310 311 312 417 if (!$force && $this->_isLoaded()) { 418 return true; 419 } 313 420 314 421 // User_id must not be empty. … … 322 429 323 430 // Retrieve all prefs for this user and namespace. 324 325 326 327 328 329 330 331 431 $qid = $db->query(" 432 SELECT pref_key, pref_value 433 FROM " . $db->escapeString($this->getParam('db_table')) . " 434 WHERE user_id = '" . $db->escapeString($this->getParam('user_id')) . "' 435 AND pref_namespace = '" . $db->escapeString($this->_ns) . "' 436 LIMIT 10000 437 "); 438 while (list($key, $val) = mysql_fetch_row($qid)) { 332 439 $_SESSION['_prefs'][$this->_ns]['saved'][$key] = unserialize($val); 333 334 335 336 337 338 440 } 441 442 $app->logMsg(sprintf('Loaded %s prefs from database.', mysql_num_rows($qid)), LOG_DEBUG, __FILE__, __LINE__); 443 444 // Data loaded only once per session. 445 $_SESSION['_prefs'][$this->_ns]['loaded'] = true; 339 446 $_SESSION['_prefs'][$this->_ns]['load_datetime'] = date('Y-m-d H:i:s'); 340 447 341 448 return true; 342 449 } 343 450 … … 354 461 private function _isLoaded() 355 462 { 463 if ('database' != $this->getParam('storagetype')) { 464 return true; 465 } 466 356 467 if (isset($_SESSION['_prefs'][$this->_ns]['load_datetime']) 357 468 && strtotime($_SESSION['_prefs'][$this->_ns]['load_datetime']) > time() - $this->getParam('load_timeout') … … 376 487 { 377 488 $app =& App::getInstance(); 378 379 380 381 if (true !== $this->getParam('persistent')) {382 383 489 $db =& DB::getInstance(); 490 491 // Skip this method if not using the db. 492 if ('database' != $this->getParam('storagetype')) { 493 return true; 494 } 384 495 385 496 // User_id must not be empty. … … 395 506 $db->query(" 396 507 DELETE FROM " . $db->escapeString($this->getParam('db_table')) . " 397 398 508 WHERE user_id = '" . $db->escapeString($this->getParam('user_id')) . "' 509 AND pref_namespace = '" . $db->escapeString($this->_ns) . "' 399 510 "); 400 511 … … 422 533 return false; 423 534 } 535 536 /* 537 * 538 * 539 * @access public 540 * @param 541 * @return 542 * @author Quinn Comendant <quinn@strangecode.com> 543 * @version 1.0 544 * @since 02 May 2014 18:17:04 545 */ 546 private function _getCookieName($key) 547 { 548 $app =& App::getInstance(); 549 550 if (mb_strpos($key, sprintf('strangecode-%s', $this->_ns)) === 0) { 551 $app->logMsg(sprintf('Invalid key name (%s). Leave off "strangecode-%s-" and it should work.', $key, $this->_ns), LOG_NOTICE, __FILE__, __LINE__); 552 } 553 return sprintf('strangecode-%s-%s', $this->_ns, $key); 554 } 424 555 } 425 556
Note: See TracChangeset
for help on using the changeset viewer.