[ Index ]
 

Code source de b2evolution 2.1.0-beta

Accédez au Source d'autres logiciels libres

Classes | Fonctions | Variables | Constantes | Tables

title

Body

[fermer]

/blogs/inc/_core/model/dataobjects/ -> _dataobjectcache.class.php (source)

   1  <?php
   2  /**

   3   * This file implements the DataObjectCache class.

   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-2007 by Francois PLANQUE - {@link http://fplanque.net/}

   9   * Parts of this file are copyright (c)2004-2006 by Daniel HAHLER - {@link http://thequod.de/contact}.

  10   * Parts of this file are copyright (c)2005-2006 by PROGIDISTRI - {@link http://progidistri.com/}.

  11   *

  12   * {@internal License choice

  13   * - If you have received this file as part of a package, please find the license.txt file in

  14   *   the same folder or the closest folder above for complete license terms.

  15   * - If you have received this file individually (e-g: from http://evocms.cvs.sourceforge.net/)

  16   *   then you must choose one of the following licenses before using the file:

  17   *   - GNU General Public License 2 (GPL) - http://www.opensource.org/licenses/gpl-license.php

  18   *   - Mozilla Public License 1.1 (MPL) - http://www.opensource.org/licenses/mozilla1.1.php

  19   * }}

  20   *

  21   * {@internal Open Source relicensing agreement:

  22   * Daniel HAHLER grants Francois PLANQUE the right to license

  23   * Daniel HAHLER's contributions to this file and the b2evolution project

  24   * under any OSI approved OSS license (http://www.opensource.org/licenses/).

  25   *

  26   * PROGIDISTRI S.A.S. grants Francois PLANQUE the right to license

  27   * PROGIDISTRI S.A.S.'s contributions to this file and the b2evolution project

  28   * under any OSI approved OSS license (http://www.opensource.org/licenses/).

  29   * }}

  30   *

  31   * @package evocore

  32   *

  33   * {@internal Below is a list of authors who have contributed to design/coding of this file: }}

  34   * @author blueyed: Daniel HAHLER.

  35   * @author fplanque: Francois PLANQUE

  36   *

  37   * @version $Id: _dataobjectcache.class.php,v 1.1 2007/06/25 10:58:56 fplanque Exp $

  38   */
  39  if( !defined('EVO_MAIN_INIT') ) die( 'Please, do not access this page directly.' );
  40  
  41  /**

  42   * Data Object Cache Class

  43   *

  44   * @todo dh> Provide iteration "interface"!

  45   *

  46   * @package evocore

  47   * @version beta

  48   */
  49  class DataObjectCache
  50  {
  51      var $dbtablename;
  52      var $dbprefix;
  53      var $dbIDname;
  54  
  55      /**

  56       * Class name of objects in this cache:

  57       */
  58      var $objtype;
  59  
  60      /**

  61       * Object array by ID

  62       */
  63      var $cache = array();
  64  
  65      /**

  66       * Copy of previous object array

  67       * @see DataObjectCache::clear()

  68       */
  69      var $shadow_cache = NULL;
  70  
  71      /**

  72       * NON indexed object array

  73       * @var array of DataObjects

  74       */
  75      var $DataObject_array = array();
  76  
  77    /**

  78       * Index of current iteration

  79       * @see DataObjectCache::get_next()

  80       */
  81      var $current_idx = NULL;
  82  
  83      var $load_all = false;
  84      var $all_loaded = false;
  85  
  86  
  87      var $name_field;
  88      var $order_by;
  89  
  90      /**

  91       * The text that gets used for the "None" option in the objects options list.

  92       *

  93       * This is especially useful for i18n, because there are several "None"s!

  94       *

  95       * @var string

  96       */
  97      var $none_option_text;
  98  
  99  
 100      /**

 101       * Constructor

 102       *

 103       * @param string Name of DataObject class we are cacheing

 104       * @param boolean true if it's OK to just load all items!

 105       * @param string Name of table in database

 106       * @param string Prefix of fields in the table

 107       * @param string Name of the ID field (including prefix)

 108       * @param string Name of the name field (including prefix)

 109       * @param string field names or NULL to use name field

 110       * @param string The text that gets used for the "None" option in the objects options list (Default: T_('None')).

 111       */
 112  	function DataObjectCache( $objtype, $load_all, $tablename, $prefix = '', $dbIDname, $name_field = NULL, $order_by = '', $allow_none_text = NULL )
 113      {
 114          $this->objtype = $objtype;
 115          $this->load_all = $load_all;
 116          $this->dbtablename = $tablename;
 117          $this->dbprefix = $prefix;
 118          $this->dbIDname = $dbIDname;
 119          $this->name_field = $name_field;
 120  
 121          if( empty( $order_by ) )
 122          {
 123              if( empty( $name_field ) )
 124              {
 125                  $this->order_by = $dbIDname;
 126              }
 127              else
 128              {
 129                  $this->order_by = $name_field;
 130              }
 131          }
 132          else
 133          {
 134              $this->order_by = $order_by;
 135          }
 136  
 137          if( isset($allow_none_text) )
 138          {
 139              $this->none_option_text = $allow_none_text;
 140          }
 141          else
 142          {
 143              $this->none_option_text = /* TRANS: the default value for option lists where "None" is allowed */ T_('None');
 144          }
 145      }
 146  
 147  
 148      /**

 149       * Instanciate a new object within this cache

 150       */
 151      function & new_obj( $row = NULL )
 152      {
 153          $objtype = $this->objtype;
 154  
 155          // Instantiate a custom object

 156          $obj = new $objtype( $row ); // COPY !!

 157  
 158          return $obj;
 159      }
 160  
 161  
 162      /**

 163       * Load the cache **extensively**

 164       */
 165  	function load_all()
 166      {
 167          /**

 168           * @var DB

 169           */
 170          global $DB;
 171          global $Debuglog;
 172  
 173          if( $this->all_loaded )
 174          { // Already loaded
 175              return false;
 176          }
 177  
 178          $this->clear( true );
 179  
 180          $Debuglog->add( get_class($this).' - Loading <strong>'.$this->objtype.'(ALL)</strong> into cache', 'dataobjects' );
 181          $sql = 'SELECT *
 182                              FROM '.$this->dbtablename.'
 183                           ORDER BY '.$this->order_by;
 184  
 185          foreach( $DB->get_results( $sql, OBJECT, 'Loading '.$this->objtype.'(ALL) into cache' ) as $row )
 186          {
 187              // Instantiate a custom object

 188              $this->instantiate( $row );
 189          }
 190  
 191          $this->all_loaded = true;
 192  
 193          return true;
 194      }
 195  
 196  
 197      /**

 198       * Load a list of objects into the cache

 199       *

 200       * @param string list of IDs of objects to load

 201       */
 202  	function load_list( $req_list )
 203      {
 204          global $DB, $Debuglog;
 205  
 206          $Debuglog->add( "Loading <strong>$this->objtype($req_list)</strong> into cache", 'dataobjects' );
 207  
 208          if( empty( $req_list ) )
 209          {
 210              return false;
 211          }
 212  
 213          $sql = "SELECT *
 214                    FROM $this->dbtablename
 215                   WHERE $this->dbIDname IN ($req_list)";
 216  
 217          foreach( $DB->get_results( $sql ) as $row )
 218          {
 219              // Instantiate a custom object

 220              $this->instantiate( $row );
 221          }
 222      }
 223  
 224  
 225      /**

 226       * Get an array of all (loaded) IDs.

 227       *

 228       * @return array

 229       */
 230  	function get_ID_array()
 231      {
 232          $IDs = array();
 233  
 234          foreach( $this->cache as $obj )
 235          {
 236              $IDs[] = $obj->ID;
 237          }
 238  
 239          return $IDs;
 240      }
 241  
 242  
 243      /**

 244       * Add a dataobject to the cache

 245       */
 246  	function add( & $Obj )
 247      {
 248          global $Debuglog;
 249  
 250          if( is_null($Obj->ID) )    // value 0 is used by item preview
 251          {
 252              $Debuglog->add( 'No object to add!', 'dataobjects' );
 253              return false;
 254          }
 255  
 256          // fplanque: I don't want an extra (and expensive) comparison here. $this->cache[$Obj->ID] === $Obj.

 257          // If you need this you're probably misusing the cache.

 258          if( isset($this->cache[$Obj->ID]) )
 259          {
 260              $Debuglog->add( $this->objtype.': Object with ID '.$Obj->ID.' is already cached', 'dataobjects' );
 261              return false;
 262          }
 263  
 264          // If the object is valid and not already cached:

 265          // Add object to cache:

 266          $this->cache[$Obj->ID] = & $Obj;
 267          // Add a reference in the object list:

 268          $this->DataObject_array[] = & $Obj;
 269  
 270          return true;
 271      }
 272  
 273  
 274      /**

 275       * Instantiate a DataObject from a table row and then cache it.

 276       *

 277       * @param Object Database row

 278       * @return Object

 279       */
 280      function & instantiate( & $db_row )
 281      {
 282          // Get ID of the object we'ere preparing to instantiate...

 283          $obj_ID = $db_row->{$this->dbIDname};
 284  
 285          if( is_null($obj_ID) )    // value 0 is used for item preview
 286          {
 287              $Obj = NULL;
 288              return $Obj;
 289          }
 290  
 291          if( isset( $this->cache[$obj_ID] ) )
 292          { // Already in cache, do nothing!
 293          }
 294          elseif( isset( $this->shadow_cache[$obj_ID] ) )
 295          {    // Already in shadow, recycle object:
 296              // echo "adding shadow {$this->objtype} $obj_ID ";

 297              $this->add( $this->shadow_cache[$obj_ID] );
 298          }
 299          else
 300          { // Not already cached, add new object:
 301              // echo "adding new {$this->objtype} $obj_ID ";

 302              $this->add( $this->new_obj( $db_row ) );
 303          }
 304  
 305          return $this->cache[$obj_ID];
 306      }
 307  
 308  
 309      /**

 310       * Clear the cache **extensively**

 311       *

 312       */
 313  	function clear( $keep_shadow = false )
 314      {
 315          if( $keep_shadow )
 316          {    // Keep copy of cache in case we try to re instantiate previous object:
 317              $this->shadow_cache = $this->cache;
 318          }
 319          else
 320          {
 321              $this->shadow_cache = NULL;
 322          }
 323  
 324          $this->cache = array();
 325          $this->DataObject_array = array();
 326          $this->all_loaded = false;
 327          $this->current_idx = NULL;
 328      }
 329  
 330  
 331    /**

 332       * This provides a simple interface for looping over the contents of the Cache.

 333       *

 334       * This should only be used for basic enumeration.

 335       * If you need complex filtering of the cache contents, you should probablt use a DataObjectList instead.

 336       *

 337       * @see DataObject::get_next()

 338       *

 339       * @return DataObject

 340       */
 341      function & get_first()
 342      {
 343          $this->load_all();
 344  
 345          $this->current_idx = -1;
 346          return $this->get_next();
 347      }
 348  
 349  
 350    /**

 351       * This provides a simple interface for looping over the contents of the Cache.

 352       *

 353       * This should only be used for basic enumeration.

 354       * If you need complex filtering of the cache contents, you should probablt use a DataObjectList instead.

 355       *

 356       * @see DataObject::get_first()

 357       *

 358       * @return DataObject

 359       */
 360      function & get_next()
 361      {
 362          $this->current_idx++;
 363          // echo 'getting idx:'.$this->current_idx;

 364  
 365          if( ! isset( $this->DataObject_array[$this->current_idx] ) )
 366          {
 367              $this->current_idx = NULL;
 368              $r = NULL;
 369              return $r;
 370          }
 371  
 372          return $this->DataObject_array[$this->current_idx];
 373      }
 374  
 375  
 376      /**

 377       * Get an object from cache by ID

 378       *

 379       * Load the cache if necessary (all at once if allowed).

 380       *

 381       * @param integer ID of object to load

 382       * @param boolean true if function should die on error

 383       * @param boolean true if function should die on empty/null

 384       * @return DataObject reference on cached object

 385       */
 386      function & get_by_ID( $req_ID, $halt_on_error = true, $halt_on_empty = true )
 387      {
 388          global $DB, $Debuglog;
 389  
 390          if( empty($req_ID) )
 391          {
 392              if($halt_on_empty)
 393              {
 394                  debug_die( "Requested $this->objtype from $this->dbtablename without ID!" );
 395              }
 396              $r = NULL;
 397              return $r;
 398          }
 399  
 400          if( !empty( $this->cache[ $req_ID ] ) )
 401          { // Already in cache
 402              // $Debuglog->add( "Accessing $this->objtype($req_ID) from cache", 'dataobjects' );

 403              return $this->cache[ $req_ID ];
 404          }
 405          elseif( !$this->all_loaded )
 406          { // Not in cache, but not everything is loaded yet
 407              if( $this->load_all )
 408              { // It's ok to just load everything:
 409                  $this->load_all();
 410              }
 411              else
 412              { // Load just the requested object:
 413                  $Debuglog->add( "Loading <strong>$this->objtype($req_ID)</strong> into cache", 'dataobjects' );
 414                  // Note: $req_ID MUST be an unsigned integer. This is how DataObject works.

 415                  $sql = "SELECT *
 416                            FROM $this->dbtablename
 417                           WHERE $this->dbIDname = $req_ID";
 418                  if( $row = $DB->get_row( $sql, OBJECT, 0, 'DataObjectCache::get_by_ID()' ) )
 419                  {
 420                      if( ! $this->instantiate( $row ) )
 421                      {
 422                          $Debuglog->add( 'Could not add() object to cache!', 'dataobjects' );
 423                      }
 424                  }
 425                  else
 426                  {
 427                      $Debuglog->add( 'Could not get DataObject by ID. Query: '.$sql, 'dataobjects' );
 428                  }
 429              }
 430          }
 431  
 432          if( empty( $this->cache[ $req_ID ] ) )
 433          { // Requested object does not exist
 434              // $Debuglog->add( 'failure', 'dataobjects' );

 435              if( $halt_on_error )
 436              {
 437                  debug_die( "Requested $this->objtype does not exist!" );
 438              }
 439              $r = false;
 440              return $r;
 441          }
 442  
 443          return $this->cache[ $req_ID ];
 444      }
 445  
 446  
 447      /**

 448       * Get an object from cache by name

 449       *

 450       * Load the cache if necessary (all at once if allowed).

 451       *

 452       * @param integer ID of object to load

 453       * @param boolean true if function should die on error

 454       * @param boolean true if function should die on empty/null

 455       * @return reference on cached object

 456       */
 457      function & get_by_name( $req_name, $halt_on_error = true, $halt_on_empty = true )
 458      {
 459          global $DB, $Debuglog;
 460  
 461          if( empty( $this->name_field ) )
 462          {
 463              debug_die( 'DataObjectCache::get_by_name() : No name field to query on' );
 464          }
 465  
 466          if( empty($req_name) )
 467          {
 468              if($halt_on_empty) { debug_die( "Requested $this->objtype from $this->dbtablename without name!" ); }
 469              $r = NULL;
 470              return $r;
 471          }
 472  
 473          // Load just the requested object:

 474          $Debuglog->add( "Loading <strong>$this->objtype($req_name)</strong>", 'dataobjects' );
 475          $sql = "SELECT *
 476                            FROM $this->dbtablename
 477                           WHERE $this->name_field = ".$DB->quote($req_name);
 478  
 479          if( $db_row = $DB->get_row( $sql, OBJECT, 0, 'DataObjectCache::get_by_name()' ) )
 480          {
 481              $resolved_ID = $db_row->{$this->dbIDname};
 482              $Debuglog->add( 'success; ID = '.$resolved_ID, 'dataobjects' );
 483              if( ! isset( $this->cache[$resolved_ID] ) )
 484              {    // Object is not already in cache:
 485                  $Debuglog->add( 'Adding to cache...', 'dataobjects' );
 486                  //$Obj = new $this->objtype( $row ); // COPY !!

 487                  //if( ! $this->add( $this->new_obj( $db_row ) ) )

 488                  if( ! $this->add( $this->new_obj( $db_row ) ) )
 489                  {    // could not add
 490                      $Debuglog->add( 'Could not add() object to cache!', 'dataobjects' );
 491                  }
 492              }
 493              return $this->cache[$resolved_ID];
 494          }
 495          else
 496          {
 497              $Debuglog->add( 'Could not get DataObject by name.', 'dataobjects' );
 498              if( $halt_on_error )
 499              {
 500                  debug_die( "Requested $this->objtype does not exist!" );
 501              }
 502              $r = NULL;
 503              return $r;
 504          }
 505      }
 506  
 507  
 508      /**

 509       * Remove an object from cache by ID

 510       *

 511       * @param integer ID of object to remove

 512       */
 513  	function remove_by_ID( $req_ID )
 514      {
 515          unset( $this->cache[$req_ID] );
 516      }
 517  
 518  
 519      /**

 520       * Delete an object from DB by ID.

 521       *

 522       * @param integer ID of object to delete

 523       * @return boolean

 524       */
 525  	function dbdelete_by_ID( $req_ID )
 526      {
 527          if( isset( $this->cache[$req_ID] ) )
 528          {
 529              // Delete from db

 530              $this->cache[$req_ID]->dbdelete();
 531  
 532              // Remove from cache

 533              $this->remove_by_ID( $req_ID );
 534  
 535              return true;
 536          }
 537          else
 538          {
 539              return false;
 540          }
 541      }
 542  
 543  
 544      /**

 545       * Returns form option list with cache contents

 546       *

 547       * Load the cache if necessary

 548       *

 549       * @param integer selected ID

 550       * @param boolean provide a choice for "none" with ID ''

 551       * @param string Callback method name

 552       * @return string

 553       */
 554  	function get_option_list( $default = 0, $allow_none = false, $method = 'get_name' )
 555      {
 556          if( (! $this->all_loaded) && $this->load_all )
 557          { // We have not loaded all items so far, but we're allowed to... so let's go:
 558              $this->load_all();
 559          }
 560  
 561          $r = '';
 562  
 563          if( $allow_none )
 564          {
 565              $r .= '<option value=""';
 566              if( empty($default) ) $r .= ' selected="selected"';
 567              $r .= '>'.format_to_output($this->none_option_text).'</option>'."\n";
 568          }
 569  
 570          foreach( $this->cache as $loop_Obj )
 571          {
 572              $r .=  '<option value="'.$loop_Obj->ID.'"';
 573              if( $loop_Obj->ID == $default ) $r .= ' selected="selected"';
 574              $r .= '>';
 575              $r .= format_to_output( $loop_Obj->$method(), 'htmlbody' );
 576              $r .=  '</option>'."\n";
 577          }
 578  
 579          return $r;
 580      }
 581  
 582  }
 583  
 584  
 585  /*

 586   * $Log: _dataobjectcache.class.php,v $

 587   * Revision 1.1  2007/06/25 10:58:56  fplanque

 588   * MODULES (refactored MVC)

 589   *

 590   * Revision 1.31  2007/05/09 01:00:39  fplanque

 591   * minor

 592   *

 593   * Revision 1.30  2007/04/26 00:11:09  fplanque

 594   * (c) 2007

 595   *

 596   * Revision 1.29  2007/02/12 15:42:40  fplanque

 597   * public interface for looping over a cache

 598   *

 599   * Revision 1.28  2006/12/29 01:10:06  fplanque

 600   * basic skin registering

 601   *

 602   * Revision 1.27  2006/12/24 01:09:55  fplanque

 603   * Rollback. Non geeks do not know how to use select multiple.

 604   * Checkbox lists should be used instead.

 605   * The core does. There is not reason for plugins not to do so also.

 606   *

 607   * Revision 1.24  2006/12/12 02:53:56  fplanque

 608   * Activated new item/comments controllers + new editing navigation

 609   * Some things are unfinished yet. Other things may need more testing.

 610   *

 611   * Revision 1.23  2006/12/05 01:35:27  blueyed

 612   * Hooray for less complexity and the 8th param for DataObjectCache()

 613   *

 614   * Revision 1.22  2006/12/05 00:59:46  fplanque

 615   * doc

 616   *

 617   * Revision 1.21  2006/12/05 00:34:39  blueyed

 618   * Implemented custom "None" option text in DataObjectCache; Added for $ItemStatusCache, $GroupCache, UserCache and BlogCache; Added custom text for Item::priority_options()

 619   *

 620   * Revision 1.20  2006/11/24 18:27:24  blueyed

 621   * Fixed link to b2evo CVS browsing interface in file docblocks

 622   *

 623   * Revision 1.19  2006/11/10 20:14:42  blueyed

 624   * TODO

 625   *

 626   * Revision 1.18  2006/10/13 09:58:53  blueyed

 627   * Removed bogus unset()

 628   */
 629  ?>


Généré le : Thu Nov 29 23:58:50 2007 par Balluche grâce à PHPXref 0.7
  Clicky Web Analytics