From 95b977625d032928abd76a0f3be1690cb421aa0d Mon Sep 17 00:00:00 2001 From: Alexander Ebert Date: Fri, 30 Sep 2011 19:35:31 +0200 Subject: [PATCH] Added Countable and SeekableIterator to DatabaseObjectList DatabaseObjectList uses an enhanced implementation for Iterators, which is slightly different (see key() implementation) to fit our purposes. Additionally two new methods seekTo() and search() are implemented to provide easier object access. Thanks to @TimWolla for the suggestion of using SPL interfaces. Closes #206 --- .../lib/data/DatabaseObjectList.class.php | 100 +++++++++++++++++- .../lib/data/ITraversableObject.class.php | 31 ++++++ 2 files changed, 129 insertions(+), 2 deletions(-) create mode 100644 wcfsetup/install/files/lib/data/ITraversableObject.class.php diff --git a/wcfsetup/install/files/lib/data/DatabaseObjectList.class.php b/wcfsetup/install/files/lib/data/DatabaseObjectList.class.php index 11133a6736..7b50f16cde 100644 --- a/wcfsetup/install/files/lib/data/DatabaseObjectList.class.php +++ b/wcfsetup/install/files/lib/data/DatabaseObjectList.class.php @@ -13,7 +13,7 @@ use wcf\system\WCF; * @subpackage data * @category Community Framework */ -abstract class DatabaseObjectList { +abstract class DatabaseObjectList implements \Countable, ITraversableObject { /** * object class name * @var string @@ -74,6 +74,18 @@ abstract class DatabaseObjectList { */ protected $conditionBuilder = null; + /** + * current iterator index + * @var integer + */ + protected $index = 0; + + /** + * list of index to object relation + * @var array + */ + protected $indexToObject = null; + /** * Creates a new DatabaseObjectList object. */ @@ -148,7 +160,10 @@ abstract class DatabaseObjectList { // 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; } @@ -206,4 +221,85 @@ abstract class DatabaseObjectList { 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; + } + } } diff --git a/wcfsetup/install/files/lib/data/ITraversableObject.class.php b/wcfsetup/install/files/lib/data/ITraversableObject.class.php new file mode 100644 index 0000000000..2c905ac5c2 --- /dev/null +++ b/wcfsetup/install/files/lib/data/ITraversableObject.class.php @@ -0,0 +1,31 @@ + + * @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); +} -- 2.20.1