File indexing completed on 2025-01-19 05:21:03
0001 <?php 0002 /** 0003 * Zend Framework 0004 * 0005 * LICENSE 0006 * 0007 * This source file is subject to the new BSD license that is bundled 0008 * with this package in the file LICENSE.txt. 0009 * It is also available through the world-wide-web at this URL: 0010 * http://framework.zend.com/license/new-bsd 0011 * If you did not receive a copy of the license and are unable to 0012 * obtain it through the world-wide-web, please send an email 0013 * to license@zend.com so we can send you a copy immediately. 0014 * 0015 * @category Zend 0016 * @package Zend_Db 0017 * @subpackage Table 0018 * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) 0019 * @license http://framework.zend.com/license/new-bsd New BSD License 0020 * @version $Id$ 0021 */ 0022 0023 /** 0024 * @category Zend 0025 * @package Zend_Db 0026 * @subpackage Table 0027 * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) 0028 * @license http://framework.zend.com/license/new-bsd New BSD License 0029 */ 0030 abstract class Zend_Db_Table_Rowset_Abstract implements SeekableIterator, Countable, ArrayAccess 0031 { 0032 /** 0033 * The original data for each row. 0034 * 0035 * @var array 0036 */ 0037 protected $_data = array(); 0038 0039 /** 0040 * Zend_Db_Table_Abstract object. 0041 * 0042 * @var Zend_Db_Table_Abstract 0043 */ 0044 protected $_table; 0045 0046 /** 0047 * Connected is true if we have a reference to a live 0048 * Zend_Db_Table_Abstract object. 0049 * This is false after the Rowset has been deserialized. 0050 * 0051 * @var boolean 0052 */ 0053 protected $_connected = true; 0054 0055 /** 0056 * Zend_Db_Table_Abstract class name. 0057 * 0058 * @var string 0059 */ 0060 protected $_tableClass; 0061 0062 /** 0063 * Zend_Db_Table_Row_Abstract class name. 0064 * 0065 * @var string 0066 */ 0067 protected $_rowClass = 'Zend_Db_Table_Row'; 0068 0069 /** 0070 * Iterator pointer. 0071 * 0072 * @var integer 0073 */ 0074 protected $_pointer = 0; 0075 0076 /** 0077 * How many data rows there are. 0078 * 0079 * @var integer 0080 */ 0081 protected $_count; 0082 0083 /** 0084 * Collection of instantiated Zend_Db_Table_Row objects. 0085 * 0086 * @var array 0087 */ 0088 protected $_rows = array(); 0089 0090 /** 0091 * @var boolean 0092 */ 0093 protected $_stored = false; 0094 0095 /** 0096 * @var boolean 0097 */ 0098 protected $_readOnly = false; 0099 0100 /** 0101 * Constructor. 0102 * 0103 * @param array $config 0104 */ 0105 public function __construct(array $config) 0106 { 0107 if (isset($config['table'])) { 0108 $this->_table = $config['table']; 0109 $this->_tableClass = get_class($this->_table); 0110 } 0111 if (isset($config['rowClass'])) { 0112 $this->_rowClass = $config['rowClass']; 0113 } 0114 if (!class_exists($this->_rowClass)) { 0115 // require_once 'Zend/Loader.php'; 0116 Zend_Loader::loadClass($this->_rowClass); 0117 } 0118 if (isset($config['data'])) { 0119 $this->_data = $config['data']; 0120 } 0121 if (isset($config['readOnly'])) { 0122 $this->_readOnly = $config['readOnly']; 0123 } 0124 if (isset($config['stored'])) { 0125 $this->_stored = $config['stored']; 0126 } 0127 0128 // set the count of rows 0129 $this->_count = count($this->_data); 0130 0131 $this->init(); 0132 } 0133 0134 /** 0135 * Store data, class names, and state in serialized object 0136 * 0137 * @return array 0138 */ 0139 public function __sleep() 0140 { 0141 return array('_data', '_tableClass', '_rowClass', '_pointer', '_count', '_rows', '_stored', 0142 '_readOnly'); 0143 } 0144 0145 /** 0146 * Setup to do on wakeup. 0147 * A de-serialized Rowset should not be assumed to have access to a live 0148 * database connection, so set _connected = false. 0149 * 0150 * @return void 0151 */ 0152 public function __wakeup() 0153 { 0154 $this->_connected = false; 0155 } 0156 0157 /** 0158 * Initialize object 0159 * 0160 * Called from {@link __construct()} as final step of object instantiation. 0161 * 0162 * @return void 0163 */ 0164 public function init() 0165 { 0166 } 0167 0168 /** 0169 * Return the connected state of the rowset. 0170 * 0171 * @return boolean 0172 */ 0173 public function isConnected() 0174 { 0175 return $this->_connected; 0176 } 0177 0178 /** 0179 * Returns the table object, or null if this is disconnected rowset 0180 * 0181 * @return Zend_Db_Table_Abstract 0182 */ 0183 public function getTable() 0184 { 0185 return $this->_table; 0186 } 0187 0188 /** 0189 * Set the table object, to re-establish a live connection 0190 * to the database for a Rowset that has been de-serialized. 0191 * 0192 * @param Zend_Db_Table_Abstract $table 0193 * @return boolean 0194 * @throws Zend_Db_Table_Row_Exception 0195 */ 0196 public function setTable(Zend_Db_Table_Abstract $table) 0197 { 0198 $this->_table = $table; 0199 $this->_connected = false; 0200 // @todo This works only if we have iterated through 0201 // the result set once to instantiate the rows. 0202 foreach ($this as $row) { 0203 $connected = $row->setTable($table); 0204 if ($connected == true) { 0205 $this->_connected = true; 0206 } 0207 } 0208 $this->rewind(); 0209 return $this->_connected; 0210 } 0211 0212 /** 0213 * Query the class name of the Table object for which this 0214 * Rowset was created. 0215 * 0216 * @return string 0217 */ 0218 public function getTableClass() 0219 { 0220 return $this->_tableClass; 0221 } 0222 0223 /** 0224 * Rewind the Iterator to the first element. 0225 * Similar to the reset() function for arrays in PHP. 0226 * Required by interface Iterator. 0227 * 0228 * @return Zend_Db_Table_Rowset_Abstract Fluent interface. 0229 */ 0230 public function rewind() 0231 { 0232 $this->_pointer = 0; 0233 return $this; 0234 } 0235 0236 /** 0237 * Return the current element. 0238 * Similar to the current() function for arrays in PHP 0239 * Required by interface Iterator. 0240 * 0241 * @return Zend_Db_Table_Row_Abstract current element from the collection 0242 */ 0243 public function current() 0244 { 0245 if ($this->valid() === false) { 0246 return null; 0247 } 0248 0249 // return the row object 0250 return $this->_loadAndReturnRow($this->_pointer); 0251 } 0252 0253 /** 0254 * Return the identifying key of the current element. 0255 * Similar to the key() function for arrays in PHP. 0256 * Required by interface Iterator. 0257 * 0258 * @return int 0259 */ 0260 public function key() 0261 { 0262 return $this->_pointer; 0263 } 0264 0265 /** 0266 * Move forward to next element. 0267 * Similar to the next() function for arrays in PHP. 0268 * Required by interface Iterator. 0269 * 0270 * @return void 0271 */ 0272 public function next() 0273 { 0274 ++$this->_pointer; 0275 } 0276 0277 /** 0278 * Check if there is a current element after calls to rewind() or next(). 0279 * Used to check if we've iterated to the end of the collection. 0280 * Required by interface Iterator. 0281 * 0282 * @return bool False if there's nothing more to iterate over 0283 */ 0284 public function valid() 0285 { 0286 return $this->_pointer >= 0 && $this->_pointer < $this->_count; 0287 } 0288 0289 /** 0290 * Returns the number of elements in the collection. 0291 * 0292 * Implements Countable::count() 0293 * 0294 * @return int 0295 */ 0296 public function count() 0297 { 0298 return $this->_count; 0299 } 0300 0301 /** 0302 * Take the Iterator to position $position 0303 * Required by interface SeekableIterator. 0304 * 0305 * @param int $position the position to seek to 0306 * @return Zend_Db_Table_Rowset_Abstract 0307 * @throws Zend_Db_Table_Rowset_Exception 0308 */ 0309 public function seek($position) 0310 { 0311 $position = (int) $position; 0312 if ($position < 0 || $position >= $this->_count) { 0313 // require_once 'Zend/Db/Table/Rowset/Exception.php'; 0314 throw new Zend_Db_Table_Rowset_Exception("Illegal index $position"); 0315 } 0316 $this->_pointer = $position; 0317 return $this; 0318 } 0319 0320 /** 0321 * Check if an offset exists 0322 * Required by the ArrayAccess implementation 0323 * 0324 * @param string $offset 0325 * @return boolean 0326 */ 0327 public function offsetExists($offset) 0328 { 0329 return isset($this->_data[(int) $offset]); 0330 } 0331 0332 /** 0333 * Get the row for the given offset 0334 * Required by the ArrayAccess implementation 0335 * 0336 * @param string $offset 0337 * @return Zend_Db_Table_Row_Abstract 0338 */ 0339 public function offsetGet($offset) 0340 { 0341 $offset = (int) $offset; 0342 if ($offset < 0 || $offset >= $this->_count) { 0343 // require_once 'Zend/Db/Table/Rowset/Exception.php'; 0344 throw new Zend_Db_Table_Rowset_Exception("Illegal index $offset"); 0345 } 0346 $this->_pointer = $offset; 0347 0348 return $this->current(); 0349 } 0350 0351 /** 0352 * Does nothing 0353 * Required by the ArrayAccess implementation 0354 * 0355 * @param string $offset 0356 * @param mixed $value 0357 */ 0358 public function offsetSet($offset, $value) 0359 { 0360 } 0361 0362 /** 0363 * Does nothing 0364 * Required by the ArrayAccess implementation 0365 * 0366 * @param string $offset 0367 */ 0368 public function offsetUnset($offset) 0369 { 0370 } 0371 0372 /** 0373 * Returns a Zend_Db_Table_Row from a known position into the Iterator 0374 * 0375 * @param int $position the position of the row expected 0376 * @param bool $seek wether or not seek the iterator to that position after 0377 * @return Zend_Db_Table_Row 0378 * @throws Zend_Db_Table_Rowset_Exception 0379 */ 0380 public function getRow($position, $seek = false) 0381 { 0382 try { 0383 $row = $this->_loadAndReturnRow($position); 0384 } catch (Zend_Db_Table_Rowset_Exception $e) { 0385 // require_once 'Zend/Db/Table/Rowset/Exception.php'; 0386 throw new Zend_Db_Table_Rowset_Exception('No row could be found at position ' . (int) $position, 0, $e); 0387 } 0388 0389 if ($seek == true) { 0390 $this->seek($position); 0391 } 0392 0393 return $row; 0394 } 0395 0396 /** 0397 * Returns all data as an array. 0398 * 0399 * Updates the $_data property with current row object values. 0400 * 0401 * @return array 0402 */ 0403 public function toArray() 0404 { 0405 // @todo This works only if we have iterated through 0406 // the result set once to instantiate the rows. 0407 foreach ($this->_rows as $i => $row) { 0408 $this->_data[$i] = $row->toArray(); 0409 } 0410 return $this->_data; 0411 } 0412 0413 protected function _loadAndReturnRow($position) 0414 { 0415 if (!isset($this->_data[$position])) { 0416 // require_once 'Zend/Db/Table/Rowset/Exception.php'; 0417 throw new Zend_Db_Table_Rowset_Exception("Data for provided position does not exist"); 0418 } 0419 0420 // do we already have a row object for this position? 0421 if (empty($this->_rows[$position])) { 0422 $this->_rows[$position] = new $this->_rowClass( 0423 array( 0424 'table' => $this->_table, 0425 'data' => $this->_data[$position], 0426 'stored' => $this->_stored, 0427 'readOnly' => $this->_readOnly 0428 ) 0429 ); 0430 0431 if ( $this->_table instanceof Zend_Db_Table_Abstract ) { 0432 $info = $this->_table->info(); 0433 0434 if ( $this->_rows[$position] instanceof Zend_Db_Table_Row_Abstract ) { 0435 if ($info['cols'] == array_keys($this->_data[$position])) { 0436 $this->_rows[$position]->setTable($this->getTable()); 0437 } 0438 } 0439 } else { 0440 $this->_rows[$position]->setTable(null); 0441 } 0442 } 0443 0444 // return the row object 0445 return $this->_rows[$position]; 0446 } 0447 0448 }