b2evolution PHP Cross Reference Blogging Systems

Source: /inc/chapters/model/_chaptercache.class.php - 351 lines - 9678 bytes - Summary - Text - Print

Description: This file implements the ChapterCache class. 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 ChapterCache 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-2014 by Francois Planque - {@link http://fplanque.com/}
   9   *
  10   * {@internal License choice
  11   * - If you have received this file as part of a package, please find the license.txt file in
  12   *   the same folder or the closest folder above for complete license terms.
  13   * - If you have received this file individually (e-g: from http://evocms.cvs.sourceforge.net/)
  14   *   then you must choose one of the following licenses before using the file:
  15   *   - GNU General Public License 2 (GPL) - http://www.opensource.org/licenses/gpl-license.php
  16   *   - Mozilla Public License 1.1 (MPL) - http://www.opensource.org/licenses/mozilla1.1.php
  17   * }}
  18   *
  19   * @package evocore
  20   *
  21   * @author fplanque: Francois PLANQUE
  22   *
  23   * @version $Id: _chaptercache.class.php 6136 2014-03-08 07:59:48Z manuel $
  24   */
  25  if( !defined('EVO_MAIN_INIT') ) die( 'Please, do not access this page directly.' );
  26  
  27  load_class( 'generic/model/_genericcategorycache.class.php', 'GenericCategoryCache' );
  28  load_class( 'chapters/model/_chapter.class.php', 'Chapter' );
  29  
  30  /**
  31   * ChapterCache Class
  32   *
  33   * @package evocore
  34   */
  35  class ChapterCache extends GenericCategoryCache
  36  {
  37      /**
  38       * Lazy filled index of url titles
  39       */
  40      var $urlname_index = array();
  41  
  42  
  43      /**
  44       * Constructor
  45       */
  46  	function ChapterCache()
  47      {
  48          global $Settings;
  49  
  50          if( $Settings->get('chapter_ordering') == 'manual' )
  51          {    // Manual order
  52              $select_temp_order = 'IF( cat_order IS NULL, 999999999, cat_order ) AS temp_order';
  53              $order_by = 'temp_order';
  54          }
  55          else
  56          {    // Alphabetic order
  57              $select_temp_order = '';
  58              $order_by = 'cat_name';
  59          }
  60  
  61          parent::GenericCategoryCache( 'Chapter', false, 'T_categories', 'cat_', 'cat_ID', 'cat_name', 'blog_ID', $order_by, NULL, '', $select_temp_order );
  62      }
  63  
  64  
  65      /**
  66       * Empty/reset the cache
  67       */
  68  	function clear()
  69      {
  70          $this->urlname_index = array();
  71          parent::clear();
  72      }
  73  
  74  
  75      /**
  76       * Get an object from cache by ID
  77       *
  78       * Load the cache if necessary (all at once if allowed).
  79       *
  80       * @param integer ID of object to load
  81       * @param boolean true if function should die on error
  82       * @param boolean true if function should die on empty/null
  83        * @param integer|NULL NULL for all subsets
  84       * @return Chapter Reference on cached object or false.
  85       */
  86      function & get_by_ID( $req_ID, $halt_on_error = true, $halt_on_empty = true, $subset_ID = NULL )
  87      {
  88          global $DB, $Debuglog;
  89  
  90          if( empty($req_ID) )
  91          {
  92              if($halt_on_empty)
  93              {
  94                  debug_die( "Requested Chapter from $this->dbtablename without ID!" );
  95              }
  96              $r = NULL;
  97              return $r;
  98          }
  99  
 100          if( !empty( $this->cache[ $req_ID ] ) )
 101          { // Already in cache
 102              $Debuglog->add( "Accessing Chapter($req_ID) from cache", 'dataobjects' );
 103              return $this->cache[ $req_ID ];
 104          }
 105          elseif( !$this->all_loaded )
 106          { // Not in cache, but not everything is loaded yet
 107              if( $this->load_all || is_null($subset_ID) )
 108              { // It's ok to just load everything:
 109                  $this->load_all();
 110              }
 111              else
 112              { // Load just the requested object:
 113                  $Debuglog->add( "Loading <strong>$this->objtype($req_ID)</strong> into cache", 'dataobjects' );
 114                  // Note: $req_ID MUST be an unsigned integer. This is how DataObject works.
 115                  $sql = "SELECT *
 116                            FROM T_categories
 117                           WHERE cat_ID = $req_ID
 118                             AND cat_blog_ID = ".$subset_ID;
 119  
 120                  if( $row = $DB->get_row( $sql, OBJECT, 0, 'ChapterCache::get_by_ID()' ) )
 121                  {
 122                      if( ! $this->instantiate( $row ) )
 123                      {
 124                          $Debuglog->add( 'Could not add() object to cache!', 'dataobjects' );
 125                      }
 126                  }
 127                  else
 128                  {
 129                      $Debuglog->add( 'Could not get DataObject by ID. Query: '.$sql, 'dataobjects' );
 130                  }
 131              }
 132          }
 133  
 134          if( empty( $this->cache[ $req_ID ] ) )
 135          { // Requested object does not exist
 136              // $Debuglog->add( 'failure', 'dataobjects' );
 137              if( $halt_on_error )
 138              {
 139                  debug_die( "Requested $this->objtype does not exist!" );
 140              }
 141              $r = false;
 142              return $r;
 143          }
 144  
 145          return $this->cache[ $req_ID ];
 146      }
 147  
 148  
 149  
 150      /**
 151       * Get an object from cache by urlname
 152       *
 153       * Load the cache if necessary (all at once if allowed).
 154       *
 155       * @param string ID of object to load
 156       * @param boolean true if function should die on error
 157       * @return reference on cached object
 158       */
 159      function & get_by_urlname( $req_urlname, $halt_on_error = true )
 160      {
 161          global $DB, $Debuglog;
 162  
 163          if( !isset( $this->urlname_index[$req_urlname] ) )
 164          { // not yet in cache:
 165              // Load just the requested object:
 166              $Debuglog->add( "Loading <strong>$this->objtype($req_urlname)</strong> into cache", 'dataobjects' );
 167              $sql = "SELECT *
 168                        FROM $this->dbtablename
 169                       WHERE cat_urlname = ".$DB->quote($req_urlname);
 170              $row = $DB->get_row( $sql );
 171              if( empty( $row ) )
 172              {    // Requested object does not exist
 173                  if( $halt_on_error ) debug_die( "Requested $this->objtype does not exist!" );
 174                  // put into index:
 175                  $this->urlname_index[$req_urlname] = false;
 176  
 177                  return $this->urlname_index[$req_urlname];
 178              }
 179  
 180              $this->instantiate( $row );
 181  
 182              // put into index:
 183              $this->urlname_index[$req_urlname] = & $this->cache[ $row->cat_ID ];
 184          }
 185          else
 186          {
 187              $Debuglog->add( "Retrieving <strong>$this->objtype($req_urlname)</strong> from cache" );
 188          }
 189  
 190          return $this->urlname_index[$req_urlname];
 191      }
 192  
 193  
 194      /**
 195       * Load a list of chapter referenced by their urlname into the cache
 196       *
 197       * @param array of urlnames of Chapters to load
 198       */
 199  	function load_urlname_array( $req_array )
 200      {
 201          global $DB, $Debuglog;
 202  
 203          $req_list = $DB->quote( $req_array );
 204          $Debuglog->add( "Loading <strong>$this->objtype($req_list)</strong> into cache", 'dataobjects' );
 205          $sql = "SELECT * FROM $this->dbtablename WHERE cat_urlname IN ( $req_list )";
 206          $dbIDname = $this->dbIDname;
 207          $objtype = $this->objtype;
 208          foreach( $DB->get_results( $sql ) as $row )
 209          {
 210              $this->cache[ $row->$dbIDname ] = new $objtype( $row ); // COPY!
 211  
 212              // put into index:
 213              $this->urlname_index[$row->cat_urlname] = & $this->cache[ $row->$dbIDname ];
 214  
 215              $Debuglog->add( "Cached <strong>$this->objtype($row->cat_urlname)</strong>" );
 216          }
 217      }
 218  
 219  
 220  
 221      /**
 222       * Load a keyed subset of the cache
 223       *
 224        * @param integer|NULL NULL for all subsets
 225        * @param string Force 'order by' setting ('manual' = 'ORDER BY cat_order')
 226       */
 227  	function load_subset( $subset_ID, $force_order_by = '' )
 228      {
 229          global $DB, $Debuglog, $Settings;
 230  
 231          if( $this->all_loaded || isset( $this->loaded_subsets[$subset_ID] ) )
 232          { // Already loaded
 233              return false;
 234          }
 235  
 236          // fp> TODO: This kills other subsets. BAD if we want to handle multiple subsets independently
 237          $this->clear( true );
 238  
 239          $Debuglog->add( 'ChapterCache - Loading <strong>chapters('.$subset_ID.')</strong> into cache', 'dataobjects' );
 240          if( $Settings->get('chapter_ordering') == 'manual' || $force_order_by == 'manual' )
 241          {    // Manual order
 242              $select_temp_order = ', IF( cat_order IS NULL, 999999999, cat_order ) AS temp_order';
 243              $sql_order = ' ORDER BY temp_order';
 244          }
 245          else
 246          {    // Alphabetic order
 247              $select_temp_order = '';
 248              $sql_order = ' ORDER BY cat_name';
 249          }
 250          $sql = 'SELECT *'.$select_temp_order.'
 251                              FROM T_categories
 252                           WHERE cat_blog_ID = '.$subset_ID
 253                          .$sql_order;
 254  
 255          foreach( $DB->get_results( $sql, OBJECT, 'Loading chapters('.$subset_ID.') into cache' ) as $row )
 256          {
 257              // Instantiate a custom object
 258              $this->instantiate( $row );
 259          }
 260  
 261          $this->loaded_subsets[$subset_ID] = true;
 262  
 263          return true;
 264      }
 265  
 266  
 267      /**
 268       * Move a chapter and its descendants to a different collection
 269       *
 270       * @param integer
 271       * @param integer
 272       * @param integer
 273       */
 274  	function move_Chapter_subtree( $chapter_ID, $src_collection_ID, $dest_collection_ID )
 275      {
 276          /**
 277           * @var DB
 278           */
 279          global $DB;
 280  
 281          // Make sure children have been revealed for specific subset:
 282          $this->reveal_children( $src_collection_ID );
 283  
 284          // fp>We get the Chapter AFTER reveal_children, because something is wrong with reveal_children or get_by_ID
 285          // I don't know what right now, but if we get Chapter earlier, we'll be stuck with an old copy of it that does NOT have the children
 286          // TODO: find out what's freakin wrong
 287          $Chapter = $this->get_by_ID($chapter_ID);
 288  
 289          $chapters_to_move = array();
 290          // Get $chapters_to_move:
 291          $this->recurse_move_subtree( $Chapter, $chapters_to_move );
 292          // pre_dump( $chapters_to_move );
 293  
 294          $DB->begin();
 295  
 296          // Move to root:
 297          if( $parent_Chapter = $Chapter->get_parent_Chapter() )
 298          {    // Was not already at root, cut it and move it:
 299              // echo 'Move to root';
 300              $Chapter->set( 'parent_ID', NULL );
 301              $Chapter->dbupdate();
 302          }
 303  
 304          // Move Chapters to new Blog:
 305          $sql = 'UPDATE T_categories
 306                               SET cat_blog_ID = '.$dest_collection_ID.'
 307                           WHERE cat_blog_ID = '.$src_collection_ID /* extra security */ .'
 308                                AND cat_ID IN ('.implode( ',', $chapters_to_move ).')';
 309          $DB->query( $sql );
 310  
 311          $DB->commit();
 312  
 313          // Now the cache is badly screwed. Reseting it is fair enough, because this won't happen very often.
 314          $this->clear();
 315      }
 316  
 317  
 318      /**
 319       * Support function for move_Chapter_subtree
 320       *
 321       * @param Chapter
 322       * @param array
 323       */
 324  	function recurse_move_subtree( & $Chapter, & $list_array )
 325      {
 326          // Add this to the list:
 327          $list_array[] = $Chapter->ID;
 328  
 329          foreach( $Chapter->children as $child_Chapter )
 330          {
 331              $this->recurse_move_subtree( $child_Chapter, $list_array );
 332          }
 333      }
 334  
 335  
 336      /**
 337       * Instanciate a new object within this cache
 338        *
 339        * @param object|NULL
 340        * @param integer|NULL subset to use for new object
 341       */
 342      function & new_obj( $row = NULL, $subset_ID = NULL )
 343      {
 344          // Instantiate a custom object
 345          $Chapter = new Chapter( $row, $subset_ID ); // Copy
 346  
 347          return $Chapter;
 348      }
 349  }
 350  
 351  ?>

title

Description

title

Description

title

Description

title

title

Body