Skip to content

Commit b005c06

Browse files
Merge pull request #11711 from creative-commoners/pulls/5.4/cache-gfd
ENH Cache result of GridFieldDetailForm_ItemRequest::getGridFieldItemAdjacencies()
2 parents f758f91 + 61f741a commit b005c06

2 files changed

Lines changed: 75 additions & 9 deletions

File tree

src/Forms/GridField/GridFieldDetailForm_ItemRequest.php

Lines changed: 37 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,11 @@ class GridFieldDetailForm_ItemRequest extends RequestHandler
9696
'' => 'edit',
9797
];
9898

99+
/**
100+
* Used to cache the results of getGridFieldItemAdjacencies();
101+
*/
102+
private array $cachedGridFieldItemAdjacencies = [];
103+
99104
/**
100105
*
101106
* @param GridField $gridField
@@ -188,6 +193,7 @@ public function edit($request)
188193
*/
189194
public function ItemEditForm()
190195
{
196+
$this->resetAdjacenciesCache();
191197
$list = $this->gridField->getList();
192198

193199
if (empty($this->record)) {
@@ -627,18 +633,30 @@ public function getEditLink($id)
627633
*/
628634
private function getGridFieldItemAdjacencies(): array
629635
{
630-
$list = $this->getGridField()->getManipulatedList();
631-
$paginator = $this->getGridFieldPaginatorState();
632-
if (!$paginator) {
636+
$paginatorState = $this->getGridFieldPaginatorState();
637+
if (!$paginatorState) {
633638
return [];
634639
}
635-
$currentPage = $paginator->getData('currentPage');
636-
$itemsPerPage = $paginator->getData('itemsPerPage');
637-
640+
$keyStr = '';
641+
$data = $this->getGridField()->getState()->toArray();
642+
array_walk_recursive($data, function ($v, $k) use (&$keyStr) {
643+
if (is_scalar($k) && is_scalar($v)) {
644+
$keyStr .= $k . $v;
645+
}
646+
});
647+
$key = md5($keyStr);
648+
if (array_key_exists($key, $this->cachedGridFieldItemAdjacencies)) {
649+
return $this->cachedGridFieldItemAdjacencies[$key];
650+
}
651+
$currentPage = $paginatorState->getData('currentPage');
652+
$itemsPerPage = $paginatorState->getData('itemsPerPage');
638653
$limit = $itemsPerPage + 2;
639-
$limitOffset = max(0, $itemsPerPage * ($currentPage-1) -1);
640-
641-
return $list->limit($limit, $limitOffset)->column('ID');
654+
$limitOffset = max(0, $itemsPerPage * ($currentPage - 1) - 1);
655+
$this->cachedGridFieldItemAdjacencies[$key] = $this->getGridField()
656+
->getManipulatedList()
657+
->limit($limit, $limitOffset)
658+
->column('ID');
659+
return $this->cachedGridFieldItemAdjacencies[$key];
642660
}
643661

644662
/**
@@ -736,6 +754,7 @@ private function getNumPages(GridField $gridField): int
736754
*/
737755
public function getPreviousRecordID()
738756
{
757+
$this->resetAdjacenciesCache();
739758
return $this->getAdjacentRecordID(-1);
740759
}
741760

@@ -746,6 +765,7 @@ public function getPreviousRecordID()
746765
*/
747766
public function getNextRecordID()
748767
{
768+
$this->resetAdjacenciesCache();
749769
return $this->getAdjacentRecordID(1);
750770
}
751771

@@ -1003,4 +1023,12 @@ private function getResponseNegotiator(DBHTMLText $renderedForm): PjaxResponseNe
10031023
}
10041024
], $this->getToplevelController()->getResponse());
10051025
}
1026+
1027+
/**
1028+
* Reset the cache used for getGridFieldItemAdjacencies()
1029+
*/
1030+
private function resetAdjacenciesCache()
1031+
{
1032+
$this->cachedGridFieldItemAdjacencies = [];
1033+
}
10061034
}

tests/php/Forms/GridField/GridFieldDetailForm_ItemRequestTest.php

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,10 @@
33
namespace SilverStripe\Forms\Tests\GridField;
44

55
use LogicException;
6+
use ReflectionMethod;
7+
use ReflectionProperty;
68
use SilverStripe\Control\Controller;
9+
use SilverStripe\Control\HTTPRequest;
710
use SilverStripe\Dev\SapphireTest;
811
use SilverStripe\Forms\GridField\GridField;
912
use SilverStripe\Forms\GridField\GridFieldConfig_Base;
@@ -31,4 +34,39 @@ public function testItemEditFormThrowsException()
3134

3235
$itemRequest->ItemEditForm();
3336
}
37+
38+
public function testGetGridFieldItemAdjacencies(): void
39+
{
40+
$list = new ArrayList([
41+
new ArrayData(['ID' => 101]),
42+
new ArrayData(['ID' => 102]),
43+
new ArrayData(['ID' => 103]),
44+
new ArrayData(['ID' => 104]),
45+
new ArrayData(['ID' => 105]),
46+
new ArrayData(['ID' => 106]),
47+
new ArrayData(['ID' => 107]),
48+
new ArrayData(['ID' => 108]),
49+
new ArrayData(['ID' => 109]),
50+
]);
51+
$gridField = new GridField('dummy', 'dummy', $list, new GridFieldConfig_Base());
52+
$modelClass = ArrayData::class;
53+
$gridField->setModelClass($modelClass);
54+
$itemRequest = new GridFieldDetailForm_ItemRequest($gridField, new GridFieldDetailForm(), new ArrayData(), new Controller(), '');
55+
$request = new HTTPRequest('GET', '/', [
56+
'gridState-dummy-0' => '{"GridFieldPaginator":{"currentPage":2,"itemsPerPage":3}}'
57+
]);
58+
$itemRequest->setRequest($request);
59+
// Assert method
60+
$refl = new ReflectionMethod($itemRequest, 'getGridFieldItemAdjacencies');
61+
$refl->setAccessible(true);
62+
$expectedData = [103, 104, 105, 106, 107];
63+
$this->assertSame($expectedData, $refl->invoke($itemRequest));
64+
// Assert cache
65+
$refl = new ReflectionProperty($itemRequest, 'cachedGridFieldItemAdjacencies');
66+
$refl->setAccessible(true);
67+
$this->assertSame(
68+
['9cffefcf339420d11129b3220eccf141' => $expectedData],
69+
$refl->getValue($itemRequest)
70+
);
71+
}
3472
}

0 commit comments

Comments
 (0)