diff --git a/src/ORM/DataList.php b/src/ORM/DataList.php index af7b73d93..2a3437847 100644 --- a/src/ORM/DataList.php +++ b/src/ORM/DataList.php @@ -33,7 +33,7 @@ use LogicException; * * Subclasses of DataList may add other methods that have the same effect. */ -class DataList extends ViewableData implements SS_List, Filterable, Sortable, Limitable, TemplateIterator +class DataList extends ViewableData implements SS_List, Filterable, Sortable, Limitable { /** @@ -883,30 +883,13 @@ class DataList extends ViewableData implements SS_List, Filterable, Sortable, Li } } - /** - * @return Generator|DataObject[] - */ - public function getTemplateIterator() - { - foreach ($this->getFinalisedQuery() as $row) { - yield $this->createDataObject($row); - } - } - - /** - * @return int - */ - public function getTemplateIteratorCount() - { - return $this->getFinalisedQuery()->numRecords(); - } - /** * Returns the Query result for this DataList. Repeated calls will return * a cached result, unless the DataQuery underlying this list has been * modified * * @return SilverStripe\ORM\Connect\Query + * @internal This API may change in minor releases */ protected function getFinalisedQuery() { diff --git a/src/View/SSViewer_Scope.php b/src/View/SSViewer_Scope.php index 8f7814c43..28d1b541f 100644 --- a/src/View/SSViewer_Scope.php +++ b/src/View/SSViewer_Scope.php @@ -290,26 +290,27 @@ class SSViewer_Scope } if (!$this->itemIterator) { - // TemplateIterator provides methods for extracting the count and iterator directly - if ($this->item instanceof TemplateIterator) { - $this->itemIterator = $this->item->getTemplateIterator(); - $this->itemIteratorTotal = $this->item->getTemplateIteratorCount(); - } else { - // Item may be an array or a regular IteratorAggregate - if (is_array($this->item)) { - $this->itemIterator = new ArrayIterator($this->item); - } else { - $this->itemIterator = $this->item->getIterator(); - } + // Note: it is important that getIterator() is called before count() as implemenations may rely on + // this to efficiency get both the number of records and an iterator (e.g. DataList does this) - // If the item implements Countable, use that to fetch the count, otherwise we have to inspect the - // iterator and then rewind it - if ($this->item instanceof Countable) { - $this->itemIteratorTotal = count($this->item); - } else { - $this->itemIteratorTotal = iterator_count($this->itemIterator); - $this->itemIterator->rewind(); - } + // Item may be an array or a regular IteratorAggregate + if (is_array($this->item)) { + $this->itemIterator = new ArrayIterator($this->item); + } else { + $this->itemIterator = $this->item->getIterator(); + + // This will execute code in a generator up to the first yield. For example, this ensures that + // DataList::getIterator() is called before Datalist::count() + $this->itemIterator->rewind(); + } + + // If the item implements Countable, use that to fetch the count, otherwise we have to inspect the + // iterator and then rewind it. + if ($this->item instanceof Countable) { + $this->itemIteratorTotal = count($this->item); + } else { + $this->itemIteratorTotal = iterator_count($this->itemIterator); + $this->itemIterator->rewind(); } $this->itemStack[$this->localIndex][SSViewer_Scope::ITEM_ITERATOR] = $this->itemIterator; diff --git a/src/View/TemplateIterator.php b/src/View/TemplateIterator.php deleted file mode 100644 index bc076e55b..000000000 --- a/src/View/TemplateIterator.php +++ /dev/null @@ -1,24 +0,0 @@ -