b2evolution PHP Cross Reference Blogging Systems

Source: /inc/settings/model/_abstractsettings.class.php - 782 lines - 21975 bytes - Summary - Text - Print

Description: This file implements the AbstractSettings class designed to handle any kind of settings. This file is part of the evoCore framework - {@link http://evocore.net/} See also {@link http://sourceforge.net/projects/evocms/}.

   1  <?php
   2  /**
   3   * This file implements the AbstractSettings class designed to handle any kind of settings.
   4   *
   5   * This file is part of the evoCore framework - {@link http://evocore.net/}
   6   * See also {@link http://sourceforge.net/projects/evocms/}.
   7   *
   8   * @copyright (c)2003-2014 by Francois Planque - {@link http://fplanque.com/}
   9   * Parts of this file are copyright (c)2004-2006 by Daniel HAHLER - {@link http://thequod.de/contact}.
  10   *
  11   * {@internal License choice
  12   * - If you have received this file as part of a package, please find the license.txt file in
  13   *   the same folder or the closest folder above for complete license terms.
  14   * - If you have received this file individually (e-g: from http://evocms.cvs.sourceforge.net/)
  15   *   then you must choose one of the following licenses before using the file:
  16   *   - GNU General Public License 2 (GPL) - http://www.opensource.org/licenses/gpl-license.php
  17   *   - Mozilla Public License 1.1 (MPL) - http://www.opensource.org/licenses/mozilla1.1.php
  18   * }}
  19   *
  20   * {@internal Open Source relicensing agreement:
  21   * Daniel HAHLER grants Francois PLANQUE the right to license
  22   * Daniel HAHLER's contributions to this file and the b2evolution project
  23   * under any OSI approved OSS license (http://www.opensource.org/licenses/).
  24   * }}
  25   *
  26   * @package evocore
  27   *
  28   * {@internal Below is a list of authors who have contributed to design/coding of this file: }}
  29   * @author blueyed: Daniel HAHLER
  30   * @author fplanque: Francois PLANQUE
  31   *
  32   * @version $Id: _abstractsettings.class.php 6136 2014-03-08 07:59:48Z manuel $
  33   */
  34  if( !defined('EVO_MAIN_INIT') ) die( 'Please, do not access this page directly.' );
  35  
  36  
  37  // DEBUG: (Turn switch on or off to log debug info for specified category)
  38  $GLOBALS['debug_settings'] = false;
  39  
  40  
  41  /**
  42   * Class to handle settings in an abstract manner (to get used with either 1, 2 or 3 DB column keys).
  43   *
  44   * Arrays and Objects automatically get serialized and unserialized
  45   * (in {@link AbstractSettings::get()} and {@link AbstractSettings::dbupdate()}).
  46   *
  47   * Note: I've evaluated splitting this into single classes for performance reasons, but only
  48   *       get() is relevant performance-wise and we could now only get rid of the switch() therein,
  49   *       which is not sufficient to split it into *_base + _X classes. (blueyed, 2006-08)
  50   *
  51   * @package evocore
  52   * @abstract
  53   * @see UserSettings, GeneralSettings, PluginSettings, CollectionSettings
  54   */
  55  class AbstractSettings
  56  {
  57      /**
  58       * The DB table which stores the settings.
  59       *
  60       * @var string
  61       * @access protected
  62       */
  63      var $db_table_name;
  64  
  65      /**
  66       * Array with DB column key names.
  67       *
  68       * @var array
  69       * @access protected
  70       */
  71      var $col_key_names = array();
  72  
  73      /**
  74       * DB column name for the value.
  75       *
  76       * @var string
  77       * @access protected
  78       */
  79      var $col_value_name;
  80  
  81  
  82      /**
  83       * The number of column keys to cache by. This are the first x keys of
  84       * {@link $col_key_names}. 0 means 'load all'.
  85       *
  86       * @var integer
  87       */
  88      var $cache_by_col_keys;
  89  
  90  
  91      /**
  92       * The internal cache.
  93       *
  94       * false, if settings  could not be loaded or NULL if not initialized.
  95       *
  96        * @access protected
  97       * @var array
  98       */
  99      var $cache = NULL;
 100  
 101  
 102      /**
 103       * Do we have loaded everything?
 104       *
 105       * @var boolean
 106       */
 107      var $all_loaded = false;
 108  
 109  
 110      /**
 111       * Default settings.
 112       *
 113       * Maps last colkeyname to some default setting that will be used by
 114       * {@link get()} if no value was defined (and it is set as a default).
 115       *
 116       * @var array
 117       */
 118      var $_defaults = array();
 119  
 120  
 121      /**
 122       * Constructor.
 123       * @param string The name of the DB table with the settings stored.
 124       * @param array List of names for the DB columns keys that reference a value.
 125       * @param string The name of the DB column that holds the value.
 126       * @param integer The number of column keys to cache by. This are the first x keys of {@link $col_key_names}. 0 means 'load all'.
 127       */
 128  	function AbstractSettings( $db_table_name, $col_key_names, $col_value_name, $cache_by_col_keys = 0 )
 129      {
 130          $this->db_table_name = $db_table_name;
 131          $this->col_key_names = $col_key_names;
 132          $this->col_value_name = $col_value_name;
 133          $this->cache_by_col_keys = $cache_by_col_keys;
 134  
 135  
 136          /**
 137           * internal counter for the number of column keys
 138           * @var integer
 139           */
 140          $this->count_col_key_names = count( $this->col_key_names );
 141  
 142          if( $this->count_col_key_names > 3 || $this->count_col_key_names < 1 )
 143          {
 144              debug_die( 'Settings keycount not supported for class '.get_class() );
 145          }
 146      }
 147  
 148  
 149      /**
 150       * Load all settings, disregarding the derived classes setting of
 151       * {@link $cache_by_col_keys} - useful if you know that you want to get
 152       * all user settings for example.
 153       */
 154  	function load_all()
 155      {
 156          return $this->_load();
 157      }
 158  
 159  
 160      /**
 161       * Loads the settings. Not meant to be called directly, but gets called
 162       * when needed.
 163       *
 164       * @access protected
 165       * @param string First column key
 166       * @param string Second column key
 167       * @param string Third column key
 168       * @return boolean always true
 169       */
 170  	function _load( $arg1 = NULL, $arg2 = NULL, $arg3 = NULL )
 171      {
 172          if( $this->all_loaded )
 173          { // already all loaded
 174              return true;
 175          }
 176          global $DB;
 177  
 178          /**
 179           * The where clause - gets filled when {@link $cache_by_col_keys} is used.
 180           */
 181          $whereList = array();
 182  
 183          if( $this->cache_by_col_keys && isset($arg1) )
 184          { // The number of column keys to cache by is > 0
 185              $testCache = $this->cache;
 186              $args = array( $arg1, $arg2, $arg3 );
 187  
 188              for( $i = 0; $i < $this->cache_by_col_keys; $i++ )
 189              {
 190                  $whereList[] = $this->col_key_names[$i]." = '".$args[$i]."'";
 191  
 192                  if( ! is_array( $testCache )
 193                          || is_null($args[$i])
 194                          || ! isset( $testCache[$args[$i]] )
 195                          || ! ($testCache = & $testCache[$args[$i]]) )
 196                  {
 197                      break;
 198                  }
 199              }
 200  
 201              if( $i == $this->cache_by_col_keys )
 202              { // already loaded!
 203                  return true;
 204              }
 205          }
 206          else
 207          { // We cache everything at once!
 208              $this->all_loaded = true;
 209          }
 210  
 211  
 212          $result = $DB->get_results( '
 213              SELECT '.implode( ', ', $this->col_key_names ).', '.$this->col_value_name.'
 214              FROM '.$this->db_table_name.(
 215                  isset( $whereList[0] )
 216                  ? ' WHERE '.implode( ' AND ', $whereList )
 217                  : '' ) );
 218  
 219          switch( $this->count_col_key_names )
 220          {
 221              case 1:
 222                  if( ! $result )
 223                  { // Remember that we've tried it
 224                      $this->cache[ $arg1 ] = NULL;
 225                  }
 226                  else foreach( $result as $loop_row )
 227                  {
 228                      $this->cache[$loop_row->{$this->col_key_names[0]}] = new stdClass();
 229  
 230                      $this->cache[$loop_row->{$this->col_key_names[0]}]->value = $loop_row->{$this->col_value_name};
 231                      $this->cache[$loop_row->{$this->col_key_names[0]}]->dbUptodate = true;
 232                      $this->cache[$loop_row->{$this->col_key_names[0]}]->dbRemove = false;
 233                  }
 234                  break;
 235  
 236              case 2:
 237                  if( ! $result )
 238                  { // Remember that we've tried it
 239                      $this->cache[ $arg1 ][ $arg2 ] = NULL;
 240                  }
 241                  else foreach( $result as $loop_row )
 242                  {
 243                      $this->cache[$loop_row->{$this->col_key_names[0]}][$loop_row->{$this->col_key_names[1]}] = new stdClass();
 244  
 245                      $this->cache[$loop_row->{$this->col_key_names[0]}][$loop_row->{$this->col_key_names[1]}]->value = $loop_row->{$this->col_value_name};
 246                      $this->cache[$loop_row->{$this->col_key_names[0]}][$loop_row->{$this->col_key_names[1]}]->dbUptodate = true;
 247                      $this->cache[$loop_row->{$this->col_key_names[0]}][$loop_row->{$this->col_key_names[1]}]->dbRemove = false;
 248                  }
 249                  break;
 250  
 251              case 3:
 252                  if( ! $result )
 253                  { // Remember that we've tried it
 254                      $this->cache[ $arg1 ][ $arg2 ][ $arg3 ] = NULL;
 255                  }
 256                  else foreach( $result as $loop_row )
 257                  {
 258                      $this->cache[$loop_row->{$this->col_key_names[0]}][$loop_row->{$this->col_key_names[1]}][$loop_row->{$this->col_key_names[2]}] = new stdClass();
 259  
 260                      $this->cache[$loop_row->{$this->col_key_names[0]}][$loop_row->{$this->col_key_names[1]}][$loop_row->{$this->col_key_names[2]}]->value = $loop_row->{$this->col_value_name};
 261                      $this->cache[$loop_row->{$this->col_key_names[0]}][$loop_row->{$this->col_key_names[1]}][$loop_row->{$this->col_key_names[2]}]->dbUptodate = true;
 262                      $this->cache[$loop_row->{$this->col_key_names[0]}][$loop_row->{$this->col_key_names[1]}][$loop_row->{$this->col_key_names[2]}]->dbRemove = false;
 263                  }
 264                  break;
 265          }
 266  
 267          return true;
 268      }
 269  
 270  
 271      /**
 272       * Get a setting from the DB settings table.
 273       *
 274       * @uses get_default()
 275       * @param string First column key
 276       * @param string Second column key
 277       * @param string Third column key
 278       * @return string|false|NULL value as string on success; NULL if not found; false in case of error
 279       */
 280  	function get( $col_key1, $col_key2 = NULL, $col_key3 = NULL )
 281      {
 282          global $debug;
 283  
 284          if( $debug )
 285          {
 286              global $Debuglog, $Timer;
 287              $this_class = get_class($this);
 288              $Timer->resume('abstractsettings_'.$this_class.'_get', false );
 289          }
 290  
 291          switch( $this->count_col_key_names )
 292          {
 293              case 1:
 294                  $this->_load( $col_key1 );
 295                  if( !empty($this->cache[ $col_key1 ]->unserialized) )
 296                  {    // The value has been unserialized before:
 297                      $r = $this->cache[ $col_key1 ]->value;
 298                  }
 299                  elseif( isset($this->cache[ $col_key1 ]->value) )
 300                  {    // First attempt to access the value, we need to unserialize it:
 301                      // Try to unserialize setting (once) - this is as fast as checking an array of values that should get unserialized
 302                      if( ($r = @unserialize($this->cache[ $col_key1 ]->value)) !== false )
 303                      {
 304                          $this->cache[ $col_key1 ] = new stdClass();
 305                          $this->cache[ $col_key1 ]->value = $r;
 306                      }
 307                      else
 308                      {
 309                          $r = $this->cache[ $col_key1 ]->value;
 310                      }
 311                      $this->cache[ $col_key1 ]->unserialized = true;
 312                  }
 313                  else
 314                  {    // The value is not in the cache, we use the default:
 315                      $r = $this->get_default( $col_key1 );
 316                      $this->cache[ $col_key1 ] = new stdClass();
 317                      $this->cache[ $col_key1 ]->value = $r; // remember in cache
 318                      $this->cache[ $col_key1 ]->dbUptodate = true;
 319                      $this->cache[ $col_key1 ]->unserialized = true;
 320                      $from_default = true; // for debug
 321                  }
 322                  break;
 323  
 324              case 2:
 325                  $this->_load( $col_key1, $col_key2 );
 326  
 327                  if( isset($this->cache[ $col_key1 ][ $col_key2 ]->unserialized) )
 328                  {
 329                      $r = $this->cache[ $col_key1 ][ $col_key2 ]->value;
 330                  }
 331                  elseif( isset($this->cache[ $col_key1 ][ $col_key2 ]->value) )
 332                  {
 333                      // Try to unserialize setting (once) - this is as fast as checking an array of values that should get unserialized
 334                      if( ($r = @unserialize($this->cache[ $col_key1 ][ $col_key2 ]->value)) !== false )
 335                      {
 336                          $this->cache[ $col_key1 ][ $col_key2 ] = new stdClass();
 337                          $this->cache[ $col_key1 ][ $col_key2 ]->value = $r;
 338                      }
 339                      else
 340                      {
 341                          $r = $this->cache[ $col_key1 ][ $col_key2 ]->value;
 342                      }
 343                      $this->cache[ $col_key1 ][ $col_key2 ]->unserialized = true;
 344                  }
 345                  else
 346                  {
 347                      $r = $this->get_default( $col_key2 );
 348                      $this->cache[ $col_key1 ][ $col_key2 ] = new stdClass();
 349                      $this->cache[ $col_key1 ][ $col_key2 ]->value = $r; // remember in cache
 350                      $this->cache[ $col_key1 ][ $col_key2 ]->dbUptodate = true;
 351                      $this->cache[ $col_key1 ][ $col_key2 ]->unserialized = true;
 352                      $from_default = true; // for debug
 353                  }
 354                  break;
 355  
 356              case 3:
 357                  $this->_load( $col_key1, $col_key2, $col_key3 );
 358  
 359                  if( isset($this->cache[ $col_key1 ][ $col_key2 ][ $col_key3 ]->unserialized) )
 360                  {
 361                      $r = $this->cache[ $col_key1 ][ $col_key2 ][ $col_key3 ]->value;
 362                  }
 363                  elseif( isset($this->cache[ $col_key1 ][ $col_key2 ][ $col_key3 ]->value) )
 364                  {
 365                      // Try to unserialize setting (once) - this is as fast as checking an array of values that should get unserialized
 366                      if( ($r = @unserialize($this->cache[ $col_key1 ][ $col_key2 ][ $col_key3 ]->value)) !== false )
 367                      {
 368                          $this->cache[ $col_key1 ][ $col_key2 ][ $col_key3 ] = new stdClass();
 369                          $this->cache[ $col_key1 ][ $col_key2 ][ $col_key3 ]->value = $r;
 370                      }
 371                      else
 372                      {
 373                          $r = $this->cache[ $col_key1 ][ $col_key2 ][ $col_key3 ]->value;
 374                      }
 375                      $this->cache[ $col_key1 ][ $col_key2 ][ $col_key3 ]->unserialized = true;
 376                  }
 377                  else
 378                  {
 379                      $r = $this->get_default( $col_key3 );
 380                      $this->cache[ $col_key1 ][ $col_key2 ][ $col_key3 ] = new stdClass();
 381                      $this->cache[ $col_key1 ][ $col_key2 ][ $col_key3 ]->value = $r; // remember in cache
 382                      $this->cache[ $col_key1 ][ $col_key2 ][ $col_key3 ]->dbUptodate = true;
 383                      $this->cache[ $col_key1 ][ $col_key2 ][ $col_key3 ]->unserialized = true;
 384                      $from_default = true; // for debug
 385                  }
 386                  break;
 387          }
 388  
 389          if( $debug )
 390          {
 391              $Debuglog->add( $this_class.'::get( '.$col_key1.'/'.$col_key2.'/'.$col_key3.' ): '
 392                  .( isset($from_default) ? '[DEFAULT]: ' : '' )
 393                  .var_export( $r, true ), 'settings' );
 394              $Timer->pause('abstractsettings_'.$this_class.'_get', false );
 395          }
 396  
 397          return $r;
 398      }
 399  
 400  
 401      /**
 402       * Get the default for the last key of {@link $col_key_names}
 403       *
 404       * @param string The last column key
 405       * @return NULL|mixed NULL if no default is set, otherwise the value (should be string).
 406       */
 407  	function get_default( $last_key )
 408      {
 409          if( isset($this->_defaults[ $last_key ]) )
 410          {
 411              return $this->_defaults[ $last_key ];
 412          }
 413  
 414          return NULL;
 415      }
 416  
 417  
 418      /**
 419       * Only set the first variable (passed by reference) if we could retrieve a
 420       * setting.
 421       *
 422       * @param mixed variable to set maybe (by reference)
 423       * @param string the values for the column keys (depends on $this->col_key_names
 424       *               and must match its count and order)
 425       * @return boolean true on success (variable was set), false if not
 426       */
 427  	function get_cond( & $toset )
 428      {
 429          $args = func_get_args();
 430          array_shift( $args );
 431  
 432          $result = call_user_func_array( array( & $this, 'get' ), $args );
 433  
 434          if( $result !== NULL && $result !== false )
 435          { // No error and value retrieved
 436              $toset = $result;
 437              return true;
 438          }
 439          else
 440          {
 441              return false;
 442          }
 443      }
 444  
 445  
 446      /**
 447       * Temporarily sets a setting ({@link dbupdate()} writes it to DB).
 448       *
 449       * @param string $args,... the values for the {@link $col_key_names column keys}
 450       *                         and {@link $col_value_name column value}. Must match order and count!
 451       * @return boolean true, if the value has been set, false if it has not changed.
 452       */
 453  	function set()
 454      {
 455          global $Debuglog;
 456  
 457          $args = func_get_args();
 458          $value = array_pop($args);
 459  
 460          call_user_func_array( array(&$this, '_load'), $args );
 461  
 462          $debugMsg = get_class($this).'::set( '.implode(', ', $args ).' ): ';
 463  
 464          switch( $this->count_col_key_names )
 465          {
 466              case 1:
 467                  $atCache = & $this->cache[ $args[0] ];
 468                  break;
 469  
 470              case 2:
 471                  $atCache = & $this->cache[ $args[0] ][ $args[1] ];
 472                  break;
 473  
 474              case 3:
 475                  $atCache = & $this->cache[ $args[0] ][ $args[1] ][ $args[2] ];
 476                  break;
 477  
 478              default:
 479                  return false;
 480          }
 481  
 482          if( ! is_object($atCache) )
 483          {    // PHP 5.4 fix for "Warning: Creating default object from empty value"
 484              $atCache = new stdClass();
 485          }
 486  
 487          $atCache->dbRemove = false;
 488  
 489          if( isset($atCache->value) )
 490          {
 491              if( $atCache->value === (string)$value )
 492              { // already set
 493                  $Debuglog->add( $debugMsg.' Already set to the same value.', 'settings' );
 494                  return false;
 495              }
 496          }
 497  
 498          $atCache->value = $value;
 499          $atCache->dbUptodate = false;
 500          $atCache->unserialized = false; // We haven't tried to unserialize the value yet
 501  
 502          $Debuglog->add( $debugMsg.' SET!', 'settings' );
 503  
 504          return true;
 505      }
 506  
 507  
 508      /**
 509       * Set an array of values.
 510       *
 511       * @param array Array of parameters for {@link set()}
 512       */
 513  	function set_array( $array )
 514      {
 515          foreach( $array as $lSet )
 516          {
 517              call_user_func_array( array( & $this, 'set' ), $lSet );
 518          }
 519      }
 520  
 521  
 522      /**
 523       * Remove a setting.
 524       *
 525       * @param array List of {@link $col_key_names}
 526       * @return boolean
 527       */
 528  	function delete( $args )
 529      {
 530          $args = func_get_args();
 531  
 532          switch( $this->count_col_key_names )
 533          {
 534              case 1:
 535                  $atCache = & $this->cache[ $args[0] ];
 536                  break;
 537  
 538              case 2:
 539                  $atCache = & $this->cache[ $args[0] ][ $args[1] ];
 540                  break;
 541  
 542              case 3:
 543                  $atCache = & $this->cache[ $args[0] ][ $args[1] ][ $args[2] ];
 544                  break;
 545  
 546              default:
 547                  return false;
 548          }
 549  
 550          if( ! is_object($atCache) )
 551          {    // PHP 5.4 fix for "Warning: Creating default object from empty value"
 552              $atCache = new stdClass();
 553          }
 554  
 555          $atCache->dbRemove = true;
 556          unset($atCache->unserialized);
 557          unset($atCache->value);
 558  
 559          return true;
 560      }
 561  
 562  
 563      /**
 564       * Delete an array of values.
 565       *
 566       * @param array Array of parameters for {@link delete()}
 567       */
 568  	function delete_array( $array )
 569      {
 570          foreach( $array as $lDel )
 571          {
 572              call_user_func_array( array( & $this, 'delete' ), array($lDel) );
 573          }
 574      }
 575  
 576  
 577      /**
 578       * Delete values for {@link $_defaults default settings} in DB.
 579       *
 580       * This will use the default settings on the next {@link get()}
 581       * again.
 582       *
 583       * @return boolean true, if settings have been updated; false otherwise
 584       */
 585  	function restore_defaults()
 586      {
 587          $this->delete_array( array_keys( $this->_defaults ) );
 588  
 589          return $this->dbupdate();
 590      }
 591  
 592  
 593      /**
 594       * Commit changed settings to DB.
 595       *
 596       * @return boolean true, if settings have been updated; false otherwise
 597       */
 598  	function dbupdate()
 599      {
 600          if( empty($this->cache) )
 601          {
 602              return false;
 603          }
 604  
 605          global $DB;
 606  
 607          $query_insert = array();
 608          $query_where_delete = array();
 609  
 610          switch( $this->count_col_key_names )
 611          {
 612              case 1:
 613                  foreach( $this->cache as $key => $value )
 614                  {
 615                      if( $value === NULL )
 616                      { // Remembered as not existing
 617                          continue;
 618                      }
 619                      if( ! empty($value->dbRemove) )
 620                      {
 621                          $query_where_delete[] = "{$this->col_key_names[0]} = '$key'";
 622                          unset( $this->cache[$key] );
 623                      }
 624                      elseif( isset($value->dbUptodate) && !$value->dbUptodate )
 625                      {
 626                          $value = $value->value;
 627                          if( is_array( $value ) || is_object( $value ) )
 628                          {
 629                              $value = serialize($value);
 630                          }
 631                          $query_insert[] = "('$key', '".$DB->escape( $value )."')";
 632                          $this->cache[$key]->dbUptodate = true;
 633                      }
 634                  }
 635                  break;
 636  
 637              case 2:
 638                  foreach( $this->cache as $key => $value )
 639                  {
 640                      foreach( $value as $key2 => $value2 )
 641                      {
 642                          if( $value2 === NULL )
 643                          { // Remembered as not existing
 644                              continue;
 645                          }
 646                          if( ! empty($value2->dbRemove) )
 647                          {
 648                              $query_where_delete[] = "{$this->col_key_names[0]} = '$key' AND {$this->col_key_names[1]} = '$key2'";
 649                              unset( $this->cache[$key][$key2] );
 650                          }
 651                          elseif( isset($value2->dbUptodate) && !$value2->dbUptodate )
 652                          {
 653                              $value2 = $value2->value;
 654                              if( is_array( $value2 ) || is_object( $value2 ) )
 655                              {
 656                                  $value2 = serialize($value2);
 657                              }
 658                              $query_insert[] = "('$key', '$key2', '".$DB->escape( $value2 )."')";
 659                              $this->cache[$key][$key2]->dbUptodate = true;
 660                          }
 661                      }
 662                  }
 663                  break;
 664  
 665              case 3:
 666                  foreach( $this->cache as $key => $value )
 667                  {
 668                      foreach( $value as $key2 => $value2 )
 669                      {
 670                          foreach( $value2 as $key3 => $value3 )
 671                          {
 672                              if( $value3 === NULL )
 673                              { // Remembered as not existing
 674                                  continue;
 675                              }
 676                              if( ! empty($value3->dbRemove) )
 677                              {
 678                                  $query_where_delete[] = "{$this->col_key_names[0]} = '$key' AND {$this->col_key_names[1]} = '$key2' AND {$this->col_key_names[2]} = '$key3'";
 679                                  unset( $this->cache[$key][$key2][$key3] );
 680                              }
 681                              elseif( isset($value3->dbUptodate) && !$value3->dbUptodate )
 682                              {
 683                                  $value3 = $value3->value;
 684                                  if( is_array($value3) || is_object($value3) )
 685                                  {
 686                                      $value3 = serialize($value3);
 687                                  }
 688                                  $query_insert[] = "('$key', '$key2', '$key3', '".$DB->escape( $value3 )."')";
 689                                  $this->cache[$key][$key2][$key3]->dbUptodate = true;
 690                              }
 691                          }
 692                      }
 693                  }
 694                  break;
 695  
 696              default:
 697                  return false;
 698          }
 699  
 700  
 701          $r = false;
 702  
 703          if( ! empty($query_where_delete) )
 704          {
 705              $query = 'DELETE FROM '.$this->db_table_name." WHERE\n(".implode( ")\nOR (", $query_where_delete ).')';
 706              $r = (boolean)$DB->query( $query );
 707          }
 708  
 709  
 710          if( ! empty($query_insert) )
 711          {
 712              $query = 'REPLACE INTO '.$this->db_table_name.' ('.implode( ', ', $this->col_key_names ).', '.$this->col_value_name
 713                                  .') VALUES '.implode(', ', $query_insert);
 714              $r = $DB->query( $query ) || $r;
 715          }
 716  
 717          return $r;
 718      }
 719  
 720  
 721      /**
 722       * Reset cache (includes settings to be written to DB).
 723       *
 724       * This is useful, to rollback settings that have been made, e.g. when a Plugin
 725       * decides that his settings should not get updated.
 726       */
 727  	function reset()
 728      {
 729          $this->cache = NULL;
 730          $this->all_loaded = false;
 731      }
 732  
 733  
 734      /**
 735       * Get a param from Request and save it to Settings, or default to previously saved user setting.
 736       *
 737       * If the setting was not set before (and there's no default given that gets returned), $default gets used.
 738       *
 739       * @param string Request param name
 740       * @param string setting name. Make sure this is unique!
 741       * @param string Force value type to one of:
 742       * - integer
 743       * - float
 744       * - string (strips (HTML-)Tags, trims whitespace)
 745       * - array
 746       * - object
 747       * - null
 748       * - html (does nothing)
 749       * - '' (does nothing)
 750       * - '/^...$/' check regexp pattern match (string)
 751       * - boolean (will force type to boolean, but you can't use 'true' as a default since it has special meaning. There is no real reason to pass booleans on a URL though. Passing 0 and 1 as integers seems to be best practice).
 752       * Value type will be forced only if resulting value (probably from default then) is !== NULL
 753       * @param mixed Default value or TRUE
 754       * @param boolean Do we need to memorize this to regenerate the URL for this page?
 755       * @param boolean Override if variable already set
 756       * @return NULL|mixed NULL, if neither a param was given nor knows about it.
 757       */
 758  	function param_Request( $param_name, $set_name, $type = '', $default = '', $memorize = false, $override = false ) // we do not force setting it..
 759      {
 760          $value = param( $param_name, $type, NULL, $memorize, $override, false ); // we pass NULL here, to see if it got set at all
 761  
 762          if( $value !== false )
 763          { // we got a value
 764              $this->set( $set_name, $value );
 765              $this->dbupdate();
 766          }
 767          else
 768          { // get the value from user settings
 769              $value = $this->get($set_name);
 770  
 771              if( is_null($value) )
 772              { // it's not saved yet and there's not default defined ($_defaults)
 773                  $value = $default;
 774              }
 775          }
 776  
 777          set_param( $param_name, $value );
 778          return get_param($param_name);
 779      }
 780  }
 781  
 782  ?>

title

Description

title

Description

title

Description

title

title

Body