b2evolution

Multilingual multiuser multiblog engine

b2evolution Technical Documentation (Version 2.4) [ class tree: evocore ] [ index: evocore ] [ all elements ]

Source for file _dataobjectcache.class.php

Documentation is available at _dataobjectcache.class.php

  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-2008 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.2.2.2 2008/12/22 01:19:53 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. {
  50.     var $dbtablename;
  51.     var $dbprefix;
  52.     var $dbIDname;
  53.  
  54.     /**
  55.      * Class name of objects in this cache:
  56.      */
  57.     var $objtype;
  58.  
  59.     /**
  60.      * Object array by ID
  61.      */
  62.     var $cache = array();
  63.  
  64.     /**
  65.      * Copy of previous object array
  66.      * @see DataObjectCache::clear()
  67.      */
  68.     var $shadow_cache = NULL;
  69.  
  70.     /**
  71.      * NON indexed object array
  72.      * @var array of DataObjects
  73.      */
  74.     var $DataObject_array = array();
  75.  
  76.   /**
  77.      * Index of current iteration
  78.      * @see DataObjectCache::get_next()
  79.      */
  80.     var $current_idx = NULL;
  81.  
  82.     var $load_all = false;
  83.     var $all_loaded = false;
  84.  
  85.  
  86.     var $name_field;
  87.     var $order_by;
  88.  
  89.     /**
  90.      * The text that gets used for the "None" option in the objects options list.
  91.      *
  92.      * This is especially useful for i18n, because there are several "None"s!
  93.      *
  94.      * @var string 
  95.      */
  96.     var $none_option_text;
  97.  
  98.  
  99.     /**
  100.      * Constructor
  101.      *
  102.      * @param string Name of DataObject class we are cacheing
  103.      * @param boolean true if it's OK to just load all items!
  104.      * @param string Name of table in database
  105.      * @param string Prefix of fields in the table
  106.      * @param string Name of the ID field (including prefix)
  107.      * @param string Name of the name field (including prefix)
  108.      * @param string field names or NULL to use name field
  109.      * @param string The text that gets used for the "None" option in the objects options list (Default: T_('None')).
  110.      */
  111.     function DataObjectCache$objtype$load_all$tablename$prefix ''$dbIDname$name_field NULL$order_by ''$allow_none_text NULL )
  112.     {
  113.         $this->objtype = $objtype;
  114.         $this->load_all = $load_all;
  115.         $this->dbtablename = $tablename;
  116.         $this->dbprefix = $prefix;
  117.         $this->dbIDname = $dbIDname;
  118.         $this->name_field = $name_field;
  119.  
  120.         ifempty$order_by ) )
  121.         {
  122.             ifempty$name_field ) )
  123.             {
  124.                 $this->order_by = $dbIDname;
  125.             }
  126.             else
  127.             {
  128.                 $this->order_by = $name_field;
  129.             }
  130.         }
  131.         else
  132.         {
  133.             $this->order_by = $order_by;
  134.         }
  135.  
  136.         ifisset($allow_none_text) )
  137.         {
  138.             $this->none_option_text = $allow_none_text;
  139.         }
  140.         else
  141.         {
  142.             $this->none_option_text = /* TRANS: the default value for option lists where "None" is allowed */ T_('None');
  143.         }
  144.     }
  145.  
  146.  
  147.     /**
  148.      * Instanciate a new object within this cache
  149.      */
  150.     function new_obj$row NULL )
  151.     {
  152.         $objtype $this->objtype;
  153.  
  154.         // Instantiate a custom object
  155.         $obj new $objtype$row )// COPY !!
  156.  
  157.         return $obj;
  158.     }
  159.  
  160.  
  161.     /**
  162.      * Load the cache **extensively**
  163.      */
  164.     function load_all()
  165.     {
  166.         /**
  167.          * @var DB
  168.          */
  169.         global $DB;
  170.         global $Debuglog;
  171.  
  172.         if$this->all_loaded )
  173.         // Already loaded
  174.             return false;
  175.         }
  176.  
  177.         $this->cleartrue );
  178.  
  179.         $Debuglog->addget_class($this).' - Loading <strong>'.$this->objtype.'(ALL)</strong> into cache''dataobjects' );
  180.         $sql 'SELECT *
  181.                             FROM '.$this->dbtablename.'
  182.                          ORDER BY '.$this->order_by;
  183.  
  184.         foreach$DB->get_results$sqlOBJECT'Loading '.$this->objtype.'(ALL) into cache' as $row )
  185.         {
  186.             // Instantiate a custom object
  187.             $this->instantiate$row );
  188.         }
  189.  
  190.         $this->all_loaded = true;
  191.  
  192.         return true;
  193.     }
  194.  
  195.  
  196.     /**
  197.      * Load a list of objects into the cache
  198.      *
  199.      * @param string list of IDs of objects to load
  200.      */
  201.     function load_list$req_list )
  202.     {
  203.         global $DB$Debuglog;
  204.  
  205.         $Debuglog->add"Loading <strong>$this->objtype($req_list)</strong> into cache"'dataobjects' );
  206.  
  207.         ifempty$req_list ) )
  208.         {
  209.             return false;
  210.         }
  211.  
  212.         $sql "SELECT *
  213.                   FROM $this->dbtablename
  214.                  WHERE $this->dbIDname IN ($req_list)";
  215.  
  216.         foreach$DB->get_results$sql as $row )
  217.         {
  218.             // Instantiate a custom object
  219.             $this->instantiate$row );
  220.         }
  221.     }
  222.  
  223.  
  224.     /**
  225.      * Get an array of all (loaded) IDs.
  226.      *
  227.      * @return array 
  228.      */
  229.     function get_ID_array()
  230.     {
  231.         $IDs array();
  232.  
  233.         foreach$this->cache as $obj )
  234.         {
  235.             $IDs[$obj->ID;
  236.         }
  237.  
  238.         return $IDs;
  239.     }
  240.  
  241.  
  242.     /**
  243.      * Add a dataobject to the cache
  244.      */
  245.     function add$Obj )
  246.     {
  247.         global $Debuglog;
  248.  
  249.         ifis_null($Obj->ID) )    // value 0 is used by item preview
  250.         {
  251.             $Debuglog->add'No object to add!''dataobjects' );
  252.             return false;
  253.         }
  254.  
  255.         // fplanque: I don't want an extra (and expensive) comparison here. $this->cache[$Obj->ID] === $Obj.
  256.         // If you need this you're probably misusing the cache.
  257.         ifisset($this->cache[$Obj->ID]) )
  258.         {
  259.             $Debuglog->add$this->objtype.': Object with ID '.$Obj->ID.' is already cached''dataobjects' );
  260.             return false;
  261.         }
  262.  
  263.         // If the object is valid and not already cached:
  264.         // Add object to cache:
  265.         $this->cache[$Obj->ID$Obj;
  266.         // Add a reference in the object list:
  267.         $this->DataObject_array[$Obj;
  268.  
  269.         return true;
  270.     }
  271.  
  272.  
  273.     /**
  274.      * Instantiate a DataObject from a table row and then cache it.
  275.      *
  276.      * @param Object Database row
  277.      * @return Object 
  278.      */
  279.     function instantiate$db_row )
  280.     {
  281.         ifis_null($db_row) )
  282.         {    // we can't access NULL as an object
  283.             return $db_row;
  284.         }
  285.         
  286.         // Get ID of the object we'ere preparing to instantiate...
  287.         $obj_ID $db_row->{$this->dbIDname};
  288.  
  289.         ifis_null($obj_ID) )    // value 0 is used for item preview
  290.         {
  291.             $Obj NULL;
  292.             return $Obj;
  293.         }
  294.  
  295.         ifisset$this->cache[$obj_ID) )
  296.         // Already in cache, do nothing!
  297.         }
  298.         elseifisset$this->shadow_cache[$obj_ID) )
  299.         {    // Already in shadow, recycle object:
  300.             // echo "adding shadow {$this->objtype} $obj_ID ";
  301.             $this->add$this->shadow_cache[$obj_ID);
  302.         }
  303.         else
  304.         // Not already cached, add new object:
  305.             // echo "adding new {$this->objtype} $obj_ID ";
  306.             $this->add$this->new_obj$db_row ) );
  307.         }
  308.  
  309.         return $this->cache[$obj_ID];
  310.     }
  311.  
  312.  
  313.     /**
  314.      * Clear the cache **extensively**
  315.      *
  316.      */
  317.     function clear$keep_shadow false )
  318.     {
  319.         if$keep_shadow )
  320.         {    // Keep copy of cache in case we try to re instantiate previous object:
  321.             $this->shadow_cache = $this->cache;
  322.         }
  323.         else
  324.         {
  325.             $this->shadow_cache = NULL;
  326.         }
  327.  
  328.         $this->cache = array();
  329.         $this->DataObject_array = array();
  330.         $this->all_loaded = false;
  331.         $this->current_idx = NULL;
  332.     }
  333.  
  334.  
  335.   /**
  336.      * This provides a simple interface for looping over the contents of the Cache.
  337.      *
  338.      * This should only be used for basic enumeration.
  339.      * If you need complex filtering of the cache contents, you should probablt use a DataObjectList instead.
  340.      *
  341.      * @see DataObject::get_next()
  342.      *
  343.      * @return DataObject 
  344.      */
  345.     function get_first()
  346.     {
  347.         $this->load_all();
  348.  
  349.         $this->current_idx = -1;
  350.         return $this->get_next();
  351.     }
  352.  
  353.  
  354.   /**
  355.      * This provides a simple interface for looping over the contents of the Cache.
  356.      *
  357.      * This should only be used for basic enumeration.
  358.      * If you need complex filtering of the cache contents, you should probablt use a DataObjectList instead.
  359.      *
  360.      * @see DataObject::get_first()
  361.      *
  362.      * @return DataObject 
  363.      */
  364.     function get_next()
  365.     {
  366.         $this->current_idx++;
  367.         // echo 'getting idx:'.$this->current_idx;
  368.  
  369.         ifisset$this->DataObject_array[$this->current_idx) )
  370.         {
  371.             $this->current_idx = NULL;
  372.             $r NULL;
  373.             return $r;
  374.         }
  375.  
  376.         return $this->DataObject_array[$this->current_idx];
  377.     }
  378.  
  379.  
  380.     /**
  381.      * Get an object from cache by ID
  382.      *
  383.      * Load the cache if necessary (all at once if allowed).
  384.      *
  385.      * @param integer ID of object to load
  386.      * @param boolean true if function should die on error
  387.      * @param boolean true if function should die on empty/null
  388.      * @return DataObject reference on cached object
  389.      */
  390.     function get_by_ID$req_ID$halt_on_error true$halt_on_empty true )
  391.     {
  392.         global $DB$Debuglog;
  393.  
  394.         ifempty($req_ID) )
  395.         {
  396.             if($halt_on_empty)
  397.             {
  398.                 debug_die"Requested $this->objtype from $this->dbtablename without ID!);
  399.             }
  400.             $r NULL;
  401.             return $r;
  402.         }
  403.  
  404.         if!empty$this->cache$req_ID ) )
  405.         // Already in cache
  406.             // $Debuglog->add( "Accessing $this->objtype($req_ID) from cache", 'dataobjects' );
  407.             return $this->cache$req_ID ];
  408.         }
  409.         elseif!$this->all_loaded )
  410.         // Not in cache, but not everything is loaded yet
  411.             if$this->load_all )
  412.             // It's ok to just load everything:
  413.                 $this->load_all();
  414.             }
  415.             else
  416.             // Load just the requested object:
  417.                 $Debuglog->add"Loading <strong>$this->objtype($req_ID)</strong> into cache"'dataobjects' );
  418.                 // Note: $req_ID MUST be an unsigned integer. This is how DataObject works.
  419.                 $sql "SELECT *
  420.                           FROM $this->dbtablename
  421.                          WHERE $this->dbIDname = $req_ID";
  422.                 if$row $DB->get_row$sqlOBJECT0'DataObjectCache::get_by_ID()' ) )
  423.                 {
  424.                     if$this->instantiate$row ) )
  425.                     {
  426.                         $Debuglog->add'Could not add() object to cache!''dataobjects' );
  427.                     }
  428.                 }
  429.                 else
  430.                 {
  431.                     $Debuglog->add'Could not get DataObject by ID. Query: '.$sql'dataobjects' );
  432.                 }
  433.             }
  434.         }
  435.  
  436.         ifempty$this->cache$req_ID ) )
  437.         // Requested object does not exist
  438.             // $Debuglog->add( 'failure', 'dataobjects' );
  439.             if$halt_on_error )
  440.             {
  441.                 debug_die"Requested $this->objtype does not exist!);
  442.             }
  443.             $r false;
  444.             return $r;
  445.         }
  446.  
  447.         return $this->cache$req_ID ];
  448.     }
  449.  
  450.  
  451.     /**
  452.      * Get an object from cache by name
  453.      *
  454.      * Load the cache if necessary (all at once if allowed).
  455.      *
  456.      * @param integer ID of object to load
  457.      * @param boolean true if function should die on error
  458.      * @param boolean true if function should die on empty/null
  459.      * @return reference on cached object
  460.      */
  461.     function get_by_name$req_name$halt_on_error true$halt_on_empty true )
  462.     {
  463.         global $DB$Debuglog;
  464.  
  465.         ifempty$this->name_field ) )
  466.         {
  467.             debug_die'DataObjectCache::get_by_name() : No name field to query on' );
  468.         }
  469.  
  470.         ifempty($req_name) )
  471.         {
  472.             if($halt_on_emptydebug_die"Requested $this->objtype from $this->dbtablename without name!)}
  473.             $r NULL;
  474.             return $r;
  475.         }
  476.  
  477.         // Load just the requested object:
  478.         $Debuglog->add"Loading <strong>$this->objtype($req_name)</strong>"'dataobjects' );
  479.         $sql "SELECT *
  480.                           FROM $this->dbtablename
  481.                          WHERE $this->name_field = ".$DB->quote($req_name);
  482.  
  483.         if$db_row $DB->get_row$sqlOBJECT0'DataObjectCache::get_by_name()' ) )
  484.         {
  485.             $resolved_ID $db_row->{$this->dbIDname};
  486.             $Debuglog->add'success; ID = '.$resolved_ID'dataobjects' );
  487.             ifisset$this->cache[$resolved_ID) )
  488.             {    // Object is not already in cache:
  489.                 $Debuglog->add'Adding to cache...''dataobjects' );
  490.                 //$Obj = new $this->objtype( $row ); // COPY !!
  491.                 //if( ! $this->add( $this->new_obj( $db_row ) ) )
  492.                 if$this->add$this->new_obj$db_row ) ) )
  493.                 {    // could not add
  494.                     $Debuglog->add'Could not add() object to cache!''dataobjects' );
  495.                 }
  496.             }
  497.             return $this->cache[$resolved_ID];
  498.         }
  499.         else
  500.         {
  501.             $Debuglog->add'Could not get DataObject by name.''dataobjects' );
  502.             if$halt_on_error )
  503.             {
  504.                 debug_die"Requested $this->objtype does not exist!);
  505.             }
  506.             $r NULL;
  507.             return $r;
  508.         }
  509.     }
  510.  
  511.  
  512.     /**
  513.      * Remove an object from cache by ID
  514.      *
  515.      * @param integer ID of object to remove
  516.      */
  517.     function remove_by_ID$req_ID )
  518.     {
  519.         unset$this->cache[$req_ID);
  520.     }
  521.  
  522.  
  523.     /**
  524.      * Delete an object from DB by ID.
  525.      *
  526.      * @param integer ID of object to delete
  527.      * @return boolean 
  528.      */
  529.     function dbdelete_by_ID$req_ID )
  530.     {
  531.         ifisset$this->cache[$req_ID) )
  532.         {
  533.             // Delete from db
  534.             $this->cache[$req_ID]->dbdelete();
  535.  
  536.             // Remove from cache
  537.             $this->remove_by_ID$req_ID );
  538.  
  539.             return true;
  540.         }
  541.         else
  542.         {
  543.             return false;
  544.         }
  545.     }
  546.  
  547.  
  548.     /**
  549.      * Returns form option list with cache contents
  550.      *
  551.      * Load the cache if necessary
  552.      *
  553.      * @param integer selected ID
  554.      * @param boolean provide a choice for "none" with ID ''
  555.      * @param string Callback method name
  556.      * @return string 
  557.      */
  558.     function get_option_list$default 0$allow_none false$method 'get_name' )
  559.     {
  560.         if( ($this->all_loaded&& $this->load_all )
  561.         // We have not loaded all items so far, but we're allowed to... so let's go:
  562.             $this->load_all();
  563.         }
  564.  
  565.         $r '';
  566.  
  567.         if$allow_none )
  568.         {
  569.             $r .= '<option value=""';
  570.             ifempty($default) ) $r .= ' selected="selected"';
  571.             $r .= '>'.format_to_output($this->none_option_text).'</option>'."\n";
  572.         }
  573.  
  574.         foreach$this->cache as $loop_Obj )
  575.         {
  576.             $r .=  '<option value="'.$loop_Obj->ID.'"';
  577.             if$loop_Obj->ID == $default $r .= ' selected="selected"';
  578.             $r .= '>';
  579.             $r .= format_to_output$loop_Obj->$method()'htmlbody' );
  580.             $r .=  '</option>'."\n";
  581.         }
  582.  
  583.         return $r;
  584.     }
  585.  
  586. }
  587.  
  588.  
  589. /*
  590.  * $Log: _dataobjectcache.class.php,v $
  591.  * Revision 1.2.2.2  2008/12/22 01:19:53  fplanque
  592.  * minor
  593.  *
  594.  * Revision 1.2.2.1  2008/09/26 18:34:04  tblue246
  595.  * Do not instantiate NULL "objects" in the cache
  596.  *
  597.  * Revision 1.2  2008/01/21 09:35:24  fplanque
  598.  * (c) 2008
  599.  *
  600.  * Revision 1.1  2007/06/25 10:58:56  fplanque
  601.  * MODULES (refactored MVC)
  602.  *
  603.  * Revision 1.31  2007/05/09 01:00:39  fplanque
  604.  * minor
  605.  *
  606.  * Revision 1.30  2007/04/26 00:11:09  fplanque
  607.  * (c) 2007
  608.  *
  609.  * Revision 1.29  2007/02/12 15:42:40  fplanque
  610.  * public interface for looping over a cache
  611.  *
  612.  * Revision 1.28  2006/12/29 01:10:06  fplanque
  613.  * basic skin registering
  614.  *
  615.  * Revision 1.27  2006/12/24 01:09:55  fplanque
  616.  * Rollback. Non geeks do not know how to use select multiple.
  617.  * Checkbox lists should be used instead.
  618.  * The core does. There is not reason for plugins not to do so also.
  619.  *
  620.  * Revision 1.24  2006/12/12 02:53:56  fplanque
  621.  * Activated new item/comments controllers + new editing navigation
  622.  * Some things are unfinished yet. Other things may need more testing.
  623.  *
  624.  * Revision 1.23  2006/12/05 01:35:27  blueyed
  625.  * Hooray for less complexity and the 8th param for DataObjectCache()
  626.  *
  627.  * Revision 1.22  2006/12/05 00:59:46  fplanque
  628.  * doc
  629.  *
  630.  * Revision 1.21  2006/12/05 00:34:39  blueyed
  631.  * Implemented custom "None" option text in DataObjectCache; Added for $ItemStatusCache, $GroupCache, UserCache and BlogCache; Added custom text for Item::priority_options()
  632.  *
  633.  * Revision 1.20  2006/11/24 18:27:24  blueyed
  634.  * Fixed link to b2evo CVS browsing interface in file docblocks
  635.  *
  636.  * Revision 1.19  2006/11/10 20:14:42  blueyed
  637.  * TODO
  638.  *
  639.  * Revision 1.18  2006/10/13 09:58:53  blueyed
  640.  * Removed bogus unset()
  641.  */
  642. ?>

Documentation generated on Sat, 06 Mar 2010 03:31:01 +0100 by phpDocumentor 1.4.2. This site is hosted and maintained by Daniel HAHLER (Contact).