mirror of
https://github.com/silverstripe/silverstripe-framework
synced 2024-09-19 07:56:38 +02:00
Further work on Loz’ solution
This commit is contained in:
parent
850482138b
commit
9c7ecb1f79
@ -33,7 +33,7 @@ use LogicException;
|
|||||||
*
|
*
|
||||||
* Subclasses of DataList may add other methods that have the same effect.
|
* 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
|
* Returns the Query result for this DataList. Repeated calls will return
|
||||||
* a cached result, unless the DataQuery underlying this list has been
|
* a cached result, unless the DataQuery underlying this list has been
|
||||||
* modified
|
* modified
|
||||||
*
|
*
|
||||||
* @return SilverStripe\ORM\Connect\Query
|
* @return SilverStripe\ORM\Connect\Query
|
||||||
|
* @internal This API may change in minor releases
|
||||||
*/
|
*/
|
||||||
protected function getFinalisedQuery()
|
protected function getFinalisedQuery()
|
||||||
{
|
{
|
||||||
|
@ -290,26 +290,27 @@ class SSViewer_Scope
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!$this->itemIterator) {
|
if (!$this->itemIterator) {
|
||||||
// TemplateIterator provides methods for extracting the count and iterator directly
|
// Note: it is important that getIterator() is called before count() as implemenations may rely on
|
||||||
if ($this->item instanceof TemplateIterator) {
|
// this to efficiency get both the number of records and an iterator (e.g. DataList does this)
|
||||||
$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();
|
|
||||||
}
|
|
||||||
|
|
||||||
// If the item implements Countable, use that to fetch the count, otherwise we have to inspect the
|
// Item may be an array or a regular IteratorAggregate
|
||||||
// iterator and then rewind it
|
if (is_array($this->item)) {
|
||||||
if ($this->item instanceof Countable) {
|
$this->itemIterator = new ArrayIterator($this->item);
|
||||||
$this->itemIteratorTotal = count($this->item);
|
} else {
|
||||||
} else {
|
$this->itemIterator = $this->item->getIterator();
|
||||||
$this->itemIteratorTotal = iterator_count($this->itemIterator);
|
|
||||||
$this->itemIterator->rewind();
|
// 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;
|
$this->itemStack[$this->localIndex][SSViewer_Scope::ITEM_ITERATOR] = $this->itemIterator;
|
||||||
|
@ -1,24 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace SilverStripe\View;
|
|
||||||
|
|
||||||
use IteratorAggregate;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A special iterator type used by the template engine. The template engine
|
|
||||||
* needs to know the total number of items before iterating (to save rewinding
|
|
||||||
* database queries), which is impossible with a natural Generator, so this
|
|
||||||
* interface allows implementors to pre-compute the total number of items
|
|
||||||
*/
|
|
||||||
interface TemplateIterator extends IteratorAggregate
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* @return Iterator|Generator
|
|
||||||
*/
|
|
||||||
public function getTemplateIterator();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return int
|
|
||||||
*/
|
|
||||||
public function getTemplateIteratorCount();
|
|
||||||
}
|
|
Loading…
Reference in New Issue
Block a user