Abstract.php 10 KB

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