diff --git a/src/Forms/GridField/SessionGridFieldStateManager.php b/src/Forms/GridField/SessionGridFieldStateManager.php index 10ade3bec..750c1f336 100644 --- a/src/Forms/GridField/SessionGridFieldStateManager.php +++ b/src/Forms/GridField/SessionGridFieldStateManager.php @@ -18,7 +18,7 @@ class SessionGridFieldStateManager implements GridFieldStateManagerInterface, Gr protected function getStateID(GridField $gridField, $create = false): ?string { $requestVar = $this->getStateRequestVar(); - $sessionStateID = $gridField->getForm()->getRequestHandler()->getRequest()->requestVar($requestVar); + $sessionStateID = $gridField->getForm()?->getRequestHandler()->getRequest()->requestVar($requestVar); if (!$sessionStateID) { $sessionStateID = Controller::curr()->getRequest()->requestVar($requestVar); } @@ -63,7 +63,7 @@ class SessionGridFieldStateManager implements GridFieldStateManagerInterface, Gr */ public function getStateKey(GridField $gridField): string { - $record = $gridField->getForm()->getRecord(); + $record = $gridField->getForm()?->getRecord(); return $gridField->getName() . '-' . ($record ? $record->ID : 0); } diff --git a/tests/php/Forms/GridField/SessionGridFieldStateManagerTest.php b/tests/php/Forms/GridField/SessionGridFieldStateManagerTest.php new file mode 100644 index 000000000..a296260d3 --- /dev/null +++ b/tests/php/Forms/GridField/SessionGridFieldStateManagerTest.php @@ -0,0 +1,131 @@ +ID = 1; + $form2 = new Form($controller, 'form2', new FieldList(), new FieldList()); + $form2->loadDataFrom($testObject); + + $grid1 = new GridField('A'); + $grid2 = new GridField('B'); + $grid1->setForm($form1); + $grid2->setForm($form2); + $this->assertEquals('A-0', $manager->getStateKey($grid1)); + $this->assertEquals('B-1', $manager->getStateKey($grid2)); + } + + public function testAddStateToURL() + { + $manager = new SessionGridFieldStateManager(); + $grid = new GridField('TestGrid'); + $grid->getState()->testValue = 'foo'; + $stateRequestVar = $manager->getStateRequestVar(); + $link = '/link-to/something'; + $this->assertTrue( + preg_match( + "|^$link\?{$stateRequestVar}=[a-zA-Z0-9]+$|", + $manager->addStateToURL($grid, $link) + ) == 1 + ); + + $link = '/link-to/something-else?someParam=somevalue'; + $this->assertTrue( + preg_match( + "|^/link-to/something-else\?someParam=somevalue&{$stateRequestVar}=[a-zA-Z0-9]+$|", + $manager->addStateToURL($grid, $link) + ) == 1 + ); + } + + public function testGetStateFromRequest() + { + $manager = new SessionGridFieldStateManager(); + + $session = new Session([]); + $request = new HTTPRequest( + 'GET', + '/link-to/something', + [ + $manager->getStateRequestVar() => 'testGetStateFromRequest' + ] + ); + $request->setSession($session); + + $controller = new Controller(); + $controller->setRequest($request); + $controller->pushCurrent(); + $form = new Form($controller, 'form1', new FieldList(), new FieldList()); + $grid = new GridField('TestGrid'); + $grid->setForm($form); + + $grid->getState()->testValue = 'foo'; + $state = $grid->getState(false)->Value() ?? '{}'; + $result = $manager->getStateFromRequest($grid, $request); + + $this->assertEquals($state, $result); + $controller->popCurrent(); + } + + public function testDefaultStateLeavesURLUnchanged() + { + $manager = new SessionGridFieldStateManager(); + $grid = new GridField('DefaultStateGrid'); + $grid->getState(false)->getData()->testValue->initDefaults(['foo' => 'bar']); + $link = '/link-to/something'; + + $this->assertEquals('{}', $grid->getState(false)->Value()); + + $this->assertEquals( + '/link-to/something', + $manager->addStateToURL($grid, $link) + ); + } + + public function testStoreState() + { + $manager = new SessionGridFieldStateManager(); + + $session = new Session([]); + $request = new HTTPRequest( + 'GET', + '/link-to/something', + [ + $manager->getStateRequestVar() => 'testStoreState' + ] + ); + $request->setSession($session); + + $controller = new Controller(); + $controller->setRequest($request); + $controller->pushCurrent(); + $form = new Form($controller, 'form1', new FieldList(), new FieldList()); + $grid = new GridField('TestGrid'); + $grid->setForm($form); + + $grid->getState()->testValue = 'foo'; + $state = $grid->getState(false)->Value() ?? '{}'; + + $manager->storeState($grid); + $this->assertEquals($state, $session->get('testStoreState')['TestGrid-0']); + + $controller->popCurrent(); + } +}