Skip to content

Commit

Permalink
FIX: Make IsFirst and IsLast work as expected for PaginatedList (fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
kinglozzer committed Nov 15, 2024
1 parent dae7320 commit d6cb465
Showing 1 changed file with 15 additions and 6 deletions.
21 changes: 15 additions & 6 deletions src/View/SSViewer_Scope.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
use SilverStripe\ORM\FieldType\DBFloat;
use SilverStripe\ORM\FieldType\DBInt;
use SilverStripe\ORM\FieldType\DBField;
use SilverStripe\ORM\PaginatedList;

/**
* This tracks the current scope for an SSViewer instance. It has three goals:
Expand Down Expand Up @@ -173,7 +174,7 @@ public function resetLocalScope()
$this->popIndex,
$this->upIndex,
$this->currentIndex
) = end($this->itemStack);
) = end($this->itemStack);
}

/**
Expand Down Expand Up @@ -305,8 +306,8 @@ public function next()
}

if (!$this->itemIterator) {
// 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)
// Note: it is important that getIterator() is called before count() as implementations may rely on
// this to efficiently get both the number of records and an iterator (e.g. DataList does this)

// Item may be an array or a regular IteratorAggregate
if (is_array($this->item)) {
Expand All @@ -319,11 +320,19 @@ public function next()
$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) {
// Special case: we *don't* want to use count() on PaginatedList. This is because it'll call
// PaginatedList::count(), which currently returns the full list count rather than the count of items
// on the current page (which is what we need for the iterator count)
if ($this->item instanceof PaginatedList) {
// We have to re-fetch the iterator before calling getInnerIterator(): we need to count a copy of the
// inner iterator because it's a generator so can't be rewound or cloned
$innerIterator = $this->item->getIterator()->getInnerIterator();
$this->itemIteratorTotal = iterator_count($innerIterator);
} elseif ($this->item instanceof Countable) {
// If the item implements Countable, use that to fetch the count
$this->itemIteratorTotal = count($this->item);
} else {
// Otherwise we have to inspect the iterator and then rewind it
$this->itemIteratorTotal = iterator_count($this->itemIterator);
$this->itemIterator->rewind();
}
Expand Down

0 comments on commit d6cb465

Please sign in to comment.