TYPO3 API  SVNRelease
ObjectStorage.php
Go to the documentation of this file.
00001 <?php
00002 /***************************************************************
00003 *  Copyright notice
00004 *
00005 *  (c) 2009 Jochen Rau <jochen.rau@typoplanet.de>
00006 *  All rights reserved
00007 *
00008 *  This script is part of the TYPO3 project. The TYPO3 project is
00009 *  free software; you can redistribute it and/or modify
00010 *  it under the terms of the GNU General Public License as published by
00011 *  the Free Software Foundation; either version 2 of the License, or
00012 *  (at your option) any later version.
00013 *
00014 *  The GNU General Public License can be found at
00015 *  http://www.gnu.org/copyleft/gpl.html.
00016 *
00017 *  This script is distributed in the hope that it will be useful,
00018 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00019 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00020 *  GNU General Public License for more details.
00021 *
00022 *  This copyright notice MUST APPEAR in all copies of the script!
00023 ***************************************************************/
00024 
00025 /**
00026  * The storage for objects. It ensures the uniqueness of an object in the storage. It's a remake of the
00027  * SplObjectStorage introduced in PHP 5.3.
00028  * 
00029  * Opposed to the SplObjectStorage the ObjectStorage does not implement the Serializable interface.
00030  *
00031  * @package Extbase
00032  * @subpackage Persistence
00033  * @version $ID:$
00034  */
00035 class Tx_Extbase_Persistence_ObjectStorage implements Countable, Iterator, ArrayAccess, Tx_Extbase_Persistence_ObjectMonitoringInterface {
00036 
00037     /**
00038      * This field is only needed to make debugging easier:
00039      * If you call current() on a class that implements Iterator, PHP will return the first field of the object
00040      * instead of calling the current() method of the interface.
00041      * We use this unusual behavior of PHP to return the warning below in this case.
00042      *
00043      * @var string
00044      */
00045     private $warning = 'You should never see this warning. If you do, you probably used PHP array functions like current() on the Tx_Extbase_Persistence_ObjectStorage. To retrieve the first result, you can use the getFirst() method.';
00046 
00047     /**
00048      * An array holding the objects and the stored information. The key of the array items ist the 
00049      * spl_object_hash of the given object.
00050      *
00051      * array(
00052      *  spl_object_hash =>
00053      *      array(
00054      *          'obj' => $object,
00055      *          'inf' => $information
00056      *      )
00057      * )
00058      *
00059      * @var array
00060      */
00061     protected $storage = array();
00062 
00063     /**
00064      * A flag indication if the object storage was modified after reconstitution (eg. by adding a new object)
00065      * @var bool
00066      */
00067     protected $isModified = FALSE;
00068         
00069     /**
00070      * Rewind the iterator to the first storage element.
00071      *
00072      * @return void
00073      */
00074     public function rewind() {
00075         reset($this->storage);
00076     }
00077 
00078     /**
00079      * Checks if the array pointer of the storage points to a valid position
00080      *
00081      * @return void
00082      */
00083     public function valid() {
00084         return current($this->storage);
00085     }
00086 
00087     /**
00088      * Returns the index at which the iterator currently is. This is different from the SplObjectStorage 
00089      * as the key in this implementation is the object hash.
00090      *
00091      * @return string The index corresponding to the position of the iterator.
00092      */
00093     public function key() {
00094         return key($this->storage);
00095     }
00096 
00097     /**
00098      * Returns the current storage entry.
00099      *
00100      * @return object The object at the current iterator position.
00101      */
00102     public function current() {
00103         $item = current($this->storage);
00104         return $item['obj'];
00105     }
00106 
00107     /**
00108      * Moves the iterator to the next object in the storage.
00109      *
00110      * @return void
00111      */
00112     public function next() {
00113         next($this->storage);
00114     }
00115 
00116     /**
00117      * Counts the number of objects in the storage.
00118      *
00119      * @return int The number of objects in the storage.
00120      */
00121     public function count() {
00122         return count($this->storage);
00123     }
00124 
00125     /**
00126      * Associate data to an object in the storage. offsetSet() is an alias of attach(). 
00127      *
00128      * @param object $object The object to add.
00129      * @param mixed $information The data to associate with the object.
00130      * @return void
00131      */
00132     public function offsetSet($object, $information) {
00133         $this->isModified = TRUE;
00134         $this->storage[spl_object_hash($object)] = array('obj' => $object, 'inf' => $information);
00135     }
00136 
00137     /**
00138      * Checks whether an object exists in the storage.
00139      *
00140      * @param string $object The object to look for.
00141      * @return boolean Returns TRUE if the object exists in the storage, and FALSE otherwise.
00142      */
00143     public function offsetExists($object) {
00144         return isset($this->storage[spl_object_hash($object)]);
00145     }
00146 
00147     /**
00148      * Removes an object from the storage. offsetUnset() is an alias of detach().
00149      *
00150      * @param Object $object The object to remove.
00151      * @return void
00152      */
00153     public function offsetUnset($object) {
00154         $this->isModified = TRUE;
00155         unset($this->storage[spl_object_hash($object)]);
00156     }
00157 
00158     /**
00159      * Returns the data associated with an object in the storage.
00160      *
00161      * @param string $object The object to look for.
00162      * @return mixed The data previously associated with the object in the storage. 
00163      */
00164     public function offsetGet($object) {
00165         return $this->storage[spl_object_hash($object)]['inf'];
00166     }
00167 
00168     /**
00169      * Checks if the storage contains the object provided.
00170      *
00171      * @param Object $object The object to look for.
00172      * @return boolean Returns TRUE if the object is in the storage, FALSE otherwise.
00173      */
00174     public function contains($object) {
00175         return $this->offsetExists($object);
00176     }
00177 
00178     /**
00179      * Adds an object inside the storage, and optionaly associate it to some data.
00180      *
00181      * @param object $object The object to add.
00182      * @param mixed $information The data to associate with the object.
00183      * @return void
00184      */
00185     public function attach($object, $information = NULL) {
00186         $this->offsetSet($object, $information);
00187     }
00188 
00189     /**
00190      * Removes the object from the storage.
00191      *
00192      * @param Object $object The object to remove.
00193      * @return void
00194      */
00195     public function detach($object) {
00196         $this->offsetUnset($object);
00197     }
00198     
00199     /**
00200      * Returns the data, or info, associated with the object pointed by the current iterator position.
00201      *
00202      * @return mixed The data associated with the current iterator position.
00203      */
00204     public function getInfo() {
00205         $item = current($this->storage);
00206         return $item['inf'];
00207     }
00208     
00209     public function setInfo($data) {
00210         $this->isModified = TRUE;
00211         $key = key($this->storage);
00212         $this->storage[$key]['inf']  = $data;
00213     }
00214 
00215     /**
00216      * Adds all objects-data pairs from a different storage in the current storage.
00217      *
00218      * @param Tx_Extbase_Persistence_ObjectStorage $storage The storage you want to import.
00219      * @return void
00220      */
00221     public function addAll(Tx_Extbase_Persistence_ObjectStorage $storage) {
00222         foreach ($storage as $object) {
00223             $this->attach($object, $storage->getInfo());
00224         }
00225     }
00226 
00227     /**
00228      * Removes objects contained in another storage from the current storage.
00229      *
00230      * @param Tx_Extbase_Persistence_ObjectStorage $storage The storage containing the elements to remove.
00231      * @return void
00232      */
00233     public function removeAll(Tx_Extbase_Persistence_ObjectStorage $storage) {
00234         foreach ($storage as $object) {
00235             $this->detach($object);
00236         }
00237     }
00238     
00239     /**
00240      * Returns this object storage as an array
00241      *
00242      * @return array The object storage
00243      */
00244     public function toArray() {
00245         $array = array();
00246         foreach ($this->storage as $item) {
00247             $array[] = $item['obj'];
00248         }
00249         return $array;
00250     }
00251 
00252     public function serialize() {
00253         throw new RuntimeException('An ObjectStorage instance cannot be serialized.', 1267700868);
00254     }
00255 
00256     public function unserialize($serialized) {
00257         throw new RuntimeException('A ObjectStorage instance cannot be unserialized.', 1267700870);
00258     }
00259     
00260     /**
00261      * Register an object's clean state, e.g. after it has been reconstituted
00262      * from the database
00263      *
00264      * @return void
00265      */
00266     public function _memorizeCleanState() {
00267         $this->isModified = FALSE;
00268     }
00269 
00270     /**
00271      * Returns TRUE if the properties were modified after reconstitution
00272      *
00273      * @return boolean
00274      */
00275     public function _isDirty() {
00276         return $this->isModified;
00277     }
00278     
00279 }
00280 
00281 ?>