* @subpackage data
* @category Community Framework
*/
-abstract class DatabaseObjectList {
+abstract class DatabaseObjectList implements \Countable, ITraversableObject {
/**
* object class name
* @var string
*/
protected $conditionBuilder = null;
+ /**
+ * current iterator index
+ * @var integer
+ */
+ protected $index = 0;
+
+ /**
+ * list of index to object relation
+ * @var array<integer>
+ */
+ protected $indexToObject = null;
+
/**
* Creates a new DatabaseObjectList object.
*/
// use table index as array index
$objects = array();
foreach($this->objects as $object) {
- $objects[$object->{$this->getDatabaseTableIndexName()}] = $object;
+ $objectID = $object->{$this->getDatabaseTableIndexName()};
+ $objects[$objectID] = $object;
+
+ $this->indexToObject[] = $objectID;
}
$this->objects = $objects;
}
public function getDatabaseTableAlias() {
return call_user_func(array($this->className, 'getDatabaseTableAlias'));
}
+
+ /**
+ * @see \Countable::count()
+ */
+ public function count() {
+ return count($this->objects);
+ }
+
+ /**
+ * @see \Iterator::current()
+ */
+ public function current() {
+ $objectID = $this->indexToObject[$this->index];
+ return $this->objects[$objectID];
+ }
+
+ /**
+ * CAUTION: This methods does not return the current iterator index,
+ * rather than the object key which maps to that index.
+ *
+ * @see \Iterator::key()
+ */
+ public function key() {
+ return $this->indexToObject[$this->index];
+ }
+
+ /**
+ * @see \Iterator::next()
+ */
+ public function next() {
+ ++$this->index;
+ }
+
+ /**
+ * @see \Iterator::rewind()
+ */
+ public function rewind() {
+ $this->index = 0;
+ }
+
+ /**
+ * @see \Iterator::valid()
+ */
+ public function valid() {
+ return isset($this->indexToObject[$this->index]);
+ }
+
+ /**
+ * @see \SeekableIterator::seek()
+ */
+ public function seek($index) {
+ $this->index = $index;
+
+ if (!$this->valid()) {
+ throw new \OutOfBoundsException();
+ }
+ }
+
+ /**
+ * @see wcf\data\ITraversableObject::seekTo()
+ */
+ public function seekTo($objectID) {
+ $this->index = array_search($objectID, $this->indexToObject);
+
+ if ($this->index === false) {
+ throw new SystemException("object id '".$objectID."' is invalid");
+ }
+ }
+
+ /**
+ * @see wcf\data\ItraversableObject::search()
+ */
+ public function search($objectID) {
+ try {
+ $this->seekTo($objectID);
+ return $this->current();
+ }
+ catch (SystemException $e) {
+ return null;
+ }
+ }
}
--- /dev/null
+<?php
+namespace wcf\data;
+
+/**
+ * Interface for enhanced iteration support.
+ *
+ * @author Alexander Ebert
+ * @copyright 2001-2011 WoltLab GmbH
+ * @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
+ * @package com.woltlab.wcf
+ * @subpackage data
+ * @category Community Framework
+ */
+interface ITraversableObject extends \SeekableIterator {
+ /**
+ * Sets internal iterator pointer based upon related object id.
+ *
+ * @param integer $objectID
+ */
+ public function seekTo($objectID);
+
+ /**
+ * Searches a specific object by object id and setting internal
+ * iterator pointer to found item. Returns null if object id is
+ * not found.
+ *
+ * @param integer $objectID
+ * @return wcf\data\DatabaseObject
+ */
+ public function search($objectID);
+}