10
10
use SilverStripe \ORM \FieldType \DBFloat ;
11
11
use SilverStripe \ORM \FieldType \DBInt ;
12
12
use SilverStripe \ORM \FieldType \DBField ;
13
+ use SilverStripe \ORM \PaginatedList ;
13
14
14
15
/**
15
16
* This tracks the current scope for an SSViewer instance. It has three goals:
@@ -173,7 +174,7 @@ public function resetLocalScope()
173
174
$ this ->popIndex ,
174
175
$ this ->upIndex ,
175
176
$ this ->currentIndex
176
- ) = end ($ this ->itemStack );
177
+ ) = end ($ this ->itemStack );
177
178
}
178
179
179
180
/**
@@ -305,8 +306,8 @@ public function next()
305
306
}
306
307
307
308
if (!$ this ->itemIterator ) {
308
- // Note: it is important that getIterator() is called before count() as implemenations may rely on
309
- // this to efficiency get both the number of records and an iterator (e.g. DataList does this)
309
+ // Note: it is important that getIterator() is called before count() as implementations may rely on
310
+ // this to efficiently get both the number of records and an iterator (e.g. DataList does this)
310
311
311
312
// Item may be an array or a regular IteratorAggregate
312
313
if (is_array ($ this ->item )) {
@@ -319,11 +320,19 @@ public function next()
319
320
$ this ->itemIterator ->rewind ();
320
321
}
321
322
322
- // If the item implements Countable, use that to fetch the count, otherwise we have to inspect the
323
- // iterator and then rewind it.
324
- if ($ this ->item instanceof Countable) {
323
+ // Special case: we *don't* want to use count() on PaginatedList. This is because it'll call
324
+ // PaginatedList::count(), which currently returns the full list count rather than the count of items
325
+ // on the current page (which is what we need for the iterator count)
326
+ if ($ this ->item instanceof PaginatedList) {
327
+ // We have to re-fetch the iterator before calling getInnerIterator(): we need to count a copy of the
328
+ // inner iterator because it's a generator so can't be rewound or cloned
329
+ $ innerIterator = $ this ->item ->getIterator ()->getInnerIterator ();
330
+ $ this ->itemIteratorTotal = iterator_count ($ innerIterator );
331
+ } elseif ($ this ->item instanceof Countable) {
332
+ // If the item implements Countable, use that to fetch the count
325
333
$ this ->itemIteratorTotal = count ($ this ->item );
326
334
} else {
335
+ // Otherwise we have to inspect the iterator and then rewind it
327
336
$ this ->itemIteratorTotal = iterator_count ($ this ->itemIterator );
328
337
$ this ->itemIterator ->rewind ();
329
338
}
0 commit comments