web/lib/Zend/Db/Table/Rowset/Abstract.php
changeset 64 162c1de6545a
parent 19 1c2f13fd785c
child 68 ecaf28ffe26e
equal deleted inserted replaced
63:5b37998e522e 64:162c1de6545a
       
     1 <?php
       
     2 /**
       
     3  * Zend Framework
       
     4  *
       
     5  * LICENSE
       
     6  *
       
     7  * This source file is subject to the new BSD license that is bundled
       
     8  * with this package in the file LICENSE.txt.
       
     9  * It is also available through the world-wide-web at this URL:
       
    10  * http://framework.zend.com/license/new-bsd
       
    11  * If you did not receive a copy of the license and are unable to
       
    12  * obtain it through the world-wide-web, please send an email
       
    13  * to license@zend.com so we can send you a copy immediately.
       
    14  *
       
    15  * @category   Zend
       
    16  * @package    Zend_Db
       
    17  * @subpackage Table
       
    18  * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
       
    19  * @license    http://framework.zend.com/license/new-bsd     New BSD License
       
    20  * @version    $Id: Abstract.php 23380 2010-11-18 22:22:28Z ralph $
       
    21  */
       
    22 
       
    23 /**
       
    24  * @category   Zend
       
    25  * @package    Zend_Db
       
    26  * @subpackage Table
       
    27  * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
       
    28  * @license    http://framework.zend.com/license/new-bsd     New BSD License
       
    29  */
       
    30 abstract class Zend_Db_Table_Rowset_Abstract implements SeekableIterator, Countable, ArrayAccess
       
    31 {
       
    32     /**
       
    33      * The original data for each row.
       
    34      *
       
    35      * @var array
       
    36      */
       
    37     protected $_data = array();
       
    38 
       
    39     /**
       
    40      * Zend_Db_Table_Abstract object.
       
    41      *
       
    42      * @var Zend_Db_Table_Abstract
       
    43      */
       
    44     protected $_table;
       
    45 
       
    46     /**
       
    47      * Connected is true if we have a reference to a live
       
    48      * Zend_Db_Table_Abstract object.
       
    49      * This is false after the Rowset has been deserialized.
       
    50      *
       
    51      * @var boolean
       
    52      */
       
    53     protected $_connected = true;
       
    54 
       
    55     /**
       
    56      * Zend_Db_Table_Abstract class name.
       
    57      *
       
    58      * @var string
       
    59      */
       
    60     protected $_tableClass;
       
    61 
       
    62     /**
       
    63      * Zend_Db_Table_Row_Abstract class name.
       
    64      *
       
    65      * @var string
       
    66      */
       
    67     protected $_rowClass = 'Zend_Db_Table_Row';
       
    68 
       
    69     /**
       
    70      * Iterator pointer.
       
    71      *
       
    72      * @var integer
       
    73      */
       
    74     protected $_pointer = 0;
       
    75 
       
    76     /**
       
    77      * How many data rows there are.
       
    78      *
       
    79      * @var integer
       
    80      */
       
    81     protected $_count;
       
    82 
       
    83     /**
       
    84      * Collection of instantiated Zend_Db_Table_Row objects.
       
    85      *
       
    86      * @var array
       
    87      */
       
    88     protected $_rows = array();
       
    89 
       
    90     /**
       
    91      * @var boolean
       
    92      */
       
    93     protected $_stored = false;
       
    94 
       
    95     /**
       
    96      * @var boolean
       
    97      */
       
    98     protected $_readOnly = false;
       
    99 
       
   100     /**
       
   101      * Constructor.
       
   102      *
       
   103      * @param array $config
       
   104      */
       
   105     public function __construct(array $config)
       
   106     {
       
   107         if (isset($config['table'])) {
       
   108             $this->_table      = $config['table'];
       
   109             $this->_tableClass = get_class($this->_table);
       
   110         }
       
   111         if (isset($config['rowClass'])) {
       
   112             $this->_rowClass   = $config['rowClass'];
       
   113         }
       
   114         if (!class_exists($this->_rowClass)) {
       
   115             require_once 'Zend/Loader.php';
       
   116             Zend_Loader::loadClass($this->_rowClass);
       
   117         }
       
   118         if (isset($config['data'])) {
       
   119             $this->_data       = $config['data'];
       
   120         }
       
   121         if (isset($config['readOnly'])) {
       
   122             $this->_readOnly   = $config['readOnly'];
       
   123         }
       
   124         if (isset($config['stored'])) {
       
   125             $this->_stored     = $config['stored'];
       
   126         }
       
   127 
       
   128         // set the count of rows
       
   129         $this->_count = count($this->_data);
       
   130 
       
   131         $this->init();
       
   132     }
       
   133 
       
   134     /**
       
   135      * Store data, class names, and state in serialized object
       
   136      *
       
   137      * @return array
       
   138      */
       
   139     public function __sleep()
       
   140     {
       
   141         return array('_data', '_tableClass', '_rowClass', '_pointer', '_count', '_rows', '_stored',
       
   142                      '_readOnly');
       
   143     }
       
   144 
       
   145     /**
       
   146      * Setup to do on wakeup.
       
   147      * A de-serialized Rowset should not be assumed to have access to a live
       
   148      * database connection, so set _connected = false.
       
   149      *
       
   150      * @return void
       
   151      */
       
   152     public function __wakeup()
       
   153     {
       
   154         $this->_connected = false;
       
   155     }
       
   156 
       
   157     /**
       
   158      * Initialize object
       
   159      *
       
   160      * Called from {@link __construct()} as final step of object instantiation.
       
   161      *
       
   162      * @return void
       
   163      */
       
   164     public function init()
       
   165     {
       
   166     }
       
   167 
       
   168     /**
       
   169      * Return the connected state of the rowset.
       
   170      *
       
   171      * @return boolean
       
   172      */
       
   173     public function isConnected()
       
   174     {
       
   175         return $this->_connected;
       
   176     }
       
   177 
       
   178     /**
       
   179      * Returns the table object, or null if this is disconnected rowset
       
   180      *
       
   181      * @return Zend_Db_Table_Abstract
       
   182      */
       
   183     public function getTable()
       
   184     {
       
   185         return $this->_table;
       
   186     }
       
   187 
       
   188     /**
       
   189      * Set the table object, to re-establish a live connection
       
   190      * to the database for a Rowset that has been de-serialized.
       
   191      *
       
   192      * @param Zend_Db_Table_Abstract $table
       
   193      * @return boolean
       
   194      * @throws Zend_Db_Table_Row_Exception
       
   195      */
       
   196     public function setTable(Zend_Db_Table_Abstract $table)
       
   197     {
       
   198         $this->_table = $table;
       
   199         $this->_connected = false;
       
   200         // @todo This works only if we have iterated through
       
   201         // the result set once to instantiate the rows.
       
   202         foreach ($this as $row) {
       
   203             $connected = $row->setTable($table);
       
   204             if ($connected == true) {
       
   205                 $this->_connected = true;
       
   206             }
       
   207         }
       
   208         return $this->_connected;
       
   209     }
       
   210 
       
   211     /**
       
   212      * Query the class name of the Table object for which this
       
   213      * Rowset was created.
       
   214      *
       
   215      * @return string
       
   216      */
       
   217     public function getTableClass()
       
   218     {
       
   219         return $this->_tableClass;
       
   220     }
       
   221 
       
   222     /**
       
   223      * Rewind the Iterator to the first element.
       
   224      * Similar to the reset() function for arrays in PHP.
       
   225      * Required by interface Iterator.
       
   226      *
       
   227      * @return Zend_Db_Table_Rowset_Abstract Fluent interface.
       
   228      */
       
   229     public function rewind()
       
   230     {
       
   231         $this->_pointer = 0;
       
   232         return $this;
       
   233     }
       
   234 
       
   235     /**
       
   236      * Return the current element.
       
   237      * Similar to the current() function for arrays in PHP
       
   238      * Required by interface Iterator.
       
   239      *
       
   240      * @return Zend_Db_Table_Row_Abstract current element from the collection
       
   241      */
       
   242     public function current()
       
   243     {
       
   244         if ($this->valid() === false) {
       
   245             return null;
       
   246         }
       
   247 
       
   248         // return the row object
       
   249         return $this->_loadAndReturnRow($this->_pointer);
       
   250     }
       
   251 
       
   252     /**
       
   253      * Return the identifying key of the current element.
       
   254      * Similar to the key() function for arrays in PHP.
       
   255      * Required by interface Iterator.
       
   256      *
       
   257      * @return int
       
   258      */
       
   259     public function key()
       
   260     {
       
   261         return $this->_pointer;
       
   262     }
       
   263 
       
   264     /**
       
   265      * Move forward to next element.
       
   266      * Similar to the next() function for arrays in PHP.
       
   267      * Required by interface Iterator.
       
   268      *
       
   269      * @return void
       
   270      */
       
   271     public function next()
       
   272     {
       
   273         ++$this->_pointer;
       
   274     }
       
   275 
       
   276     /**
       
   277      * Check if there is a current element after calls to rewind() or next().
       
   278      * Used to check if we've iterated to the end of the collection.
       
   279      * Required by interface Iterator.
       
   280      *
       
   281      * @return bool False if there's nothing more to iterate over
       
   282      */
       
   283     public function valid()
       
   284     {
       
   285         return $this->_pointer >= 0 && $this->_pointer < $this->_count;
       
   286     }
       
   287 
       
   288     /**
       
   289      * Returns the number of elements in the collection.
       
   290      *
       
   291      * Implements Countable::count()
       
   292      *
       
   293      * @return int
       
   294      */
       
   295     public function count()
       
   296     {
       
   297         return $this->_count;
       
   298     }
       
   299 
       
   300     /**
       
   301      * Take the Iterator to position $position
       
   302      * Required by interface SeekableIterator.
       
   303      *
       
   304      * @param int $position the position to seek to
       
   305      * @return Zend_Db_Table_Rowset_Abstract
       
   306      * @throws Zend_Db_Table_Rowset_Exception
       
   307      */
       
   308     public function seek($position)
       
   309     {
       
   310         $position = (int) $position;
       
   311         if ($position < 0 || $position >= $this->_count) {
       
   312             require_once 'Zend/Db/Table/Rowset/Exception.php';
       
   313             throw new Zend_Db_Table_Rowset_Exception("Illegal index $position");
       
   314         }
       
   315         $this->_pointer = $position;
       
   316         return $this;
       
   317     }
       
   318 
       
   319     /**
       
   320      * Check if an offset exists
       
   321      * Required by the ArrayAccess implementation
       
   322      *
       
   323      * @param string $offset
       
   324      * @return boolean
       
   325      */
       
   326     public function offsetExists($offset)
       
   327     {
       
   328         return isset($this->_data[(int) $offset]);
       
   329     }
       
   330 
       
   331     /**
       
   332      * Get the row for the given offset
       
   333      * Required by the ArrayAccess implementation
       
   334      *
       
   335      * @param string $offset
       
   336      * @return Zend_Db_Table_Row_Abstract
       
   337      */
       
   338     public function offsetGet($offset)
       
   339     {
       
   340         $offset = (int) $offset;
       
   341         if ($offset < 0 || $offset >= $this->_count) {
       
   342             require_once 'Zend/Db/Table/Rowset/Exception.php';
       
   343             throw new Zend_Db_Table_Rowset_Exception("Illegal index $offset");
       
   344         }
       
   345         $this->_pointer = $offset;
       
   346 
       
   347         return $this->current();
       
   348     }
       
   349 
       
   350     /**
       
   351      * Does nothing
       
   352      * Required by the ArrayAccess implementation
       
   353      *
       
   354      * @param string $offset
       
   355      * @param mixed $value
       
   356      */
       
   357     public function offsetSet($offset, $value)
       
   358     {
       
   359     }
       
   360 
       
   361     /**
       
   362      * Does nothing
       
   363      * Required by the ArrayAccess implementation
       
   364      *
       
   365      * @param string $offset
       
   366      */
       
   367     public function offsetUnset($offset)
       
   368     {
       
   369     }
       
   370 
       
   371     /**
       
   372      * Returns a Zend_Db_Table_Row from a known position into the Iterator
       
   373      *
       
   374      * @param int $position the position of the row expected
       
   375      * @param bool $seek wether or not seek the iterator to that position after
       
   376      * @return Zend_Db_Table_Row
       
   377      * @throws Zend_Db_Table_Rowset_Exception
       
   378      */
       
   379     public function getRow($position, $seek = false)
       
   380     {
       
   381         try {
       
   382             $row = $this->_loadAndReturnRow($position);
       
   383         } catch (Zend_Db_Table_Rowset_Exception $e) {
       
   384             require_once 'Zend/Db/Table/Rowset/Exception.php';
       
   385             throw new Zend_Db_Table_Rowset_Exception('No row could be found at position ' . (int) $position, 0, $e);
       
   386         }
       
   387         
       
   388         if ($seek == true) {
       
   389             $this->seek($position);
       
   390         }
       
   391         
       
   392         return $row;
       
   393     }
       
   394 
       
   395     /**
       
   396      * Returns all data as an array.
       
   397      *
       
   398      * Updates the $_data property with current row object values.
       
   399      *
       
   400      * @return array
       
   401      */
       
   402     public function toArray()
       
   403     {
       
   404         // @todo This works only if we have iterated through
       
   405         // the result set once to instantiate the rows.
       
   406         foreach ($this->_rows as $i => $row) {
       
   407             $this->_data[$i] = $row->toArray();
       
   408         }
       
   409         return $this->_data;
       
   410     }
       
   411     
       
   412     protected function _loadAndReturnRow($position)
       
   413     {
       
   414         if (!isset($this->_data[$position])) {
       
   415             require_once 'Zend/Db/Table/Rowset/Exception.php';
       
   416             throw new Zend_Db_Table_Rowset_Exception("Data for provided position does not exist");
       
   417         }
       
   418         
       
   419         // do we already have a row object for this position?
       
   420         if (empty($this->_rows[$position])) {
       
   421             $this->_rows[$position] = new $this->_rowClass(
       
   422                 array(
       
   423                     'table'    => $this->_table,
       
   424                     'data'     => $this->_data[$position],
       
   425                     'stored'   => $this->_stored,
       
   426                     'readOnly' => $this->_readOnly
       
   427                 )
       
   428             );
       
   429         }
       
   430 
       
   431         // return the row object
       
   432         return $this->_rows[$position];
       
   433     }
       
   434 
       
   435 }