mirror of
https://github.com/silverstripe/silverstripe-framework
synced 2024-10-22 14:05:37 +02:00
Merge pull request #10331 from creative-commoners/pulls/4/gridfield-keep-state
ENH Restore gridfield state from get vars (POC)
This commit is contained in:
commit
c7504aa337
@ -4,10 +4,13 @@ namespace SilverStripe\Forms\GridField;
|
|||||||
|
|
||||||
use InvalidArgumentException;
|
use InvalidArgumentException;
|
||||||
use LogicException;
|
use LogicException;
|
||||||
|
use SilverStripe\Control\Controller;
|
||||||
use SilverStripe\Control\HasRequestHandler;
|
use SilverStripe\Control\HasRequestHandler;
|
||||||
|
use SilverStripe\Control\HTTP;
|
||||||
use SilverStripe\Control\HTTPRequest;
|
use SilverStripe\Control\HTTPRequest;
|
||||||
use SilverStripe\Control\HTTPResponse;
|
use SilverStripe\Control\HTTPResponse;
|
||||||
use SilverStripe\Control\HTTPResponse_Exception;
|
use SilverStripe\Control\HTTPResponse_Exception;
|
||||||
|
use SilverStripe\Control\NullHTTPRequest;
|
||||||
use SilverStripe\Control\RequestHandler;
|
use SilverStripe\Control\RequestHandler;
|
||||||
use SilverStripe\Core\Convert;
|
use SilverStripe\Core\Convert;
|
||||||
use SilverStripe\Core\Injector\Injector;
|
use SilverStripe\Core\Injector\Injector;
|
||||||
@ -45,6 +48,8 @@ use SilverStripe\View\HTML;
|
|||||||
*/
|
*/
|
||||||
class GridField extends FormField
|
class GridField extends FormField
|
||||||
{
|
{
|
||||||
|
use GridFieldStateAware;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var array
|
* @var array
|
||||||
*/
|
*/
|
||||||
@ -435,6 +440,8 @@ class GridField extends FormField
|
|||||||
{
|
{
|
||||||
$this->state = new GridState($this);
|
$this->state = new GridState($this);
|
||||||
|
|
||||||
|
$this->addStateFromRequest();
|
||||||
|
|
||||||
$data = $this->state->getData();
|
$data = $this->state->getData();
|
||||||
|
|
||||||
foreach ($this->getComponents() as $item) {
|
foreach ($this->getComponents() as $item) {
|
||||||
@ -444,6 +451,56 @@ class GridField extends FormField
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds state for this gridfield from the request variables.
|
||||||
|
*
|
||||||
|
* If there is state already set on this GridField, that takes precedent
|
||||||
|
* over state from the request.
|
||||||
|
*/
|
||||||
|
private function addStateFromRequest(): void
|
||||||
|
{
|
||||||
|
$request = $this->getRequest();
|
||||||
|
if (($request instanceof NullHTTPRequest) && Controller::has_curr()) {
|
||||||
|
$request = Controller::curr()->getRequest();
|
||||||
|
}
|
||||||
|
|
||||||
|
$stateStr = $this->getStateManager()->getStateFromRequest($this, $request);
|
||||||
|
if ($stateStr) {
|
||||||
|
$oldState = $this->getState(false);
|
||||||
|
// Create a dummy state so that we can merge the current state with the request state.
|
||||||
|
$newState = new GridState($this, $stateStr);
|
||||||
|
// Put the current state on top of the request state.
|
||||||
|
$newState->setValue($oldState->Value());
|
||||||
|
$this->state = $newState;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add GET and POST parameters pertaining to other gridfield's state to the URL.
|
||||||
|
* Also add this gridfield's own state to the URL.
|
||||||
|
*/
|
||||||
|
public function addAllStateToUrl(string $link): string
|
||||||
|
{
|
||||||
|
$request = $this->getRequest();
|
||||||
|
if ($request->param('Action')) {
|
||||||
|
$requestVars = $request->requestVars();
|
||||||
|
$params = [];
|
||||||
|
foreach ($requestVars as $key => $val) {
|
||||||
|
// Get gridfield states that are for other gridfields
|
||||||
|
if (stripos($key, 'gridState') === 0
|
||||||
|
&& $key !== $this->getStateManager()->getStateKey($this)
|
||||||
|
) {
|
||||||
|
$params[$key] = $val;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
foreach ($params as $key => $val) {
|
||||||
|
$link = HTTP::setGetVar($key, $val, $link);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->getStateManager()->addStateToURL($this, $link);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the whole gridfield rendered with all the attached components.
|
* Returns the whole gridfield rendered with all the attached components.
|
||||||
*
|
*
|
||||||
|
@ -481,7 +481,7 @@ class GridFieldDetailForm_ItemRequest extends RequestHandler
|
|||||||
$backlink = $toplevelController->Link();
|
$backlink = $toplevelController->Link();
|
||||||
}
|
}
|
||||||
|
|
||||||
return $backlink;
|
return $this->gridField->addAllStateToUrl($backlink);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -817,6 +817,12 @@ class GridFieldDetailForm_ItemRequest extends RequestHandler
|
|||||||
]));
|
]));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
foreach ($items as $item) {
|
||||||
|
if ($item->Link) {
|
||||||
|
$item->Link = $this->gridField->addAllStateToUrl($item->Link);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
$this->extend('updateBreadcrumbs', $items);
|
$this->extend('updateBreadcrumbs', $items);
|
||||||
return $items;
|
return $items;
|
||||||
}
|
}
|
||||||
|
@ -61,6 +61,7 @@ class GridFieldEditButton extends AbstractGridFieldComponent implements GridFiel
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @inheritdoc
|
* @inheritdoc
|
||||||
|
* @param bool $addState DEPRECATED: Should be removed in major release
|
||||||
*/
|
*/
|
||||||
public function getUrl($gridField, $record, $columnName, $addState = true)
|
public function getUrl($gridField, $record, $columnName, $addState = true)
|
||||||
{
|
{
|
||||||
@ -70,11 +71,7 @@ class GridFieldEditButton extends AbstractGridFieldComponent implements GridFiel
|
|||||||
'edit'
|
'edit'
|
||||||
);
|
);
|
||||||
|
|
||||||
if ($addState) {
|
return $gridField->addAllStateToUrl($link, $addState);
|
||||||
$link = $this->getStateManager()->addStateToURL($gridField, $link);
|
|
||||||
}
|
|
||||||
|
|
||||||
return $link;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -44,7 +44,8 @@ class GridFieldViewButton extends AbstractGridFieldComponent implements GridFiel
|
|||||||
*/
|
*/
|
||||||
public function getUrl($gridField, $record, $columnName)
|
public function getUrl($gridField, $record, $columnName)
|
||||||
{
|
{
|
||||||
return Controller::join_links($gridField->Link('item'), $record->ID, 'view');
|
$link = Controller::join_links($gridField->Link('item'), $record->ID, 'view');
|
||||||
|
return $gridField->addAllStateToUrl($link);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function augmentColumns($field, &$columns)
|
public function augmentColumns($field, &$columns)
|
||||||
|
@ -341,10 +341,11 @@ class GridFieldDetailFormTest extends FunctionalTest
|
|||||||
);
|
);
|
||||||
$this->assertEquals(
|
$this->assertEquals(
|
||||||
sprintf(
|
sprintf(
|
||||||
'GridFieldDetailFormTest_GroupController/Form/field/testfield/item/%d/ItemEditForm/field/People'
|
'/GridFieldDetailFormTest_GroupController/Form/field/testfield/item/%d/ItemEditForm/field/People'
|
||||||
. '/item/%d/edit',
|
. '/item/%d/edit%s',
|
||||||
$group->ID,
|
$group->ID,
|
||||||
$person->ID
|
$person->ID,
|
||||||
|
'?gridState-People-1=%7B%22GridFieldAddRelation%22%3Anull%7D'
|
||||||
),
|
),
|
||||||
(string)$personEditLink[0]['href']
|
(string)$personEditLink[0]['href']
|
||||||
);
|
);
|
||||||
@ -359,11 +360,12 @@ class GridFieldDetailFormTest extends FunctionalTest
|
|||||||
);
|
);
|
||||||
$this->assertEquals(
|
$this->assertEquals(
|
||||||
sprintf(
|
sprintf(
|
||||||
'GridFieldDetailFormTest_GroupController/Form/field/testfield/item/%d/ItemEditForm/field/People'
|
'/GridFieldDetailFormTest_GroupController/Form/field/testfield/item/%d/ItemEditForm/field/People'
|
||||||
. '/item/%d/ItemEditForm/field/Categories/item/%d/edit',
|
. '/item/%d/ItemEditForm/field/Categories/item/%d/edit%s',
|
||||||
$group->ID,
|
$group->ID,
|
||||||
$person->ID,
|
$person->ID,
|
||||||
$category->ID
|
$category->ID,
|
||||||
|
'?gridState-Categories-2=%7B%22GridFieldAddRelation%22%3Anull%7D'
|
||||||
),
|
),
|
||||||
(string)$categoryEditLink[0]['href']
|
(string)$categoryEditLink[0]['href']
|
||||||
);
|
);
|
||||||
|
@ -4,6 +4,8 @@ namespace SilverStripe\Forms\Tests\GridField;
|
|||||||
|
|
||||||
use InvalidArgumentException;
|
use InvalidArgumentException;
|
||||||
use LogicException;
|
use LogicException;
|
||||||
|
use SilverStripe\Control\Controller;
|
||||||
|
use SilverStripe\Control\HTTPRequest;
|
||||||
use SilverStripe\Dev\CSSContentParser;
|
use SilverStripe\Dev\CSSContentParser;
|
||||||
use SilverStripe\Dev\SapphireTest;
|
use SilverStripe\Dev\SapphireTest;
|
||||||
use SilverStripe\Forms\FieldList;
|
use SilverStripe\Forms\FieldList;
|
||||||
@ -659,4 +661,69 @@ class GridFieldTest extends SapphireTest
|
|||||||
$gridfieldOutput = $gridField->FieldHolder();
|
$gridfieldOutput = $gridField->FieldHolder();
|
||||||
$this->assertStringNotContainsString('<p class="message ' . ValidationResult::TYPE_ERROR . '">', $gridfieldOutput);
|
$this->assertStringNotContainsString('<p class="message ' . ValidationResult::TYPE_ERROR . '">', $gridfieldOutput);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testAddRequestToURL()
|
||||||
|
{
|
||||||
|
$gridField = new GridField('testfield', 'testfield');
|
||||||
|
$link = Controller::join_links('class-name', 'item', '1');
|
||||||
|
|
||||||
|
// The actual URL path here is arbitrary
|
||||||
|
$request = new HTTPRequest(
|
||||||
|
'POST',
|
||||||
|
'admin/gridfield',
|
||||||
|
[
|
||||||
|
'gridState-Test-0' => [
|
||||||
|
'State' => [
|
||||||
|
'Column' => 'Name'
|
||||||
|
],
|
||||||
|
]
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'action_gridFieldAlterAction?StateID=1',
|
||||||
|
'ActionState' => json_encode([
|
||||||
|
'grid' => $gridField->getName(),
|
||||||
|
'actionName' => 'edit',
|
||||||
|
'args' => [],
|
||||||
|
]),
|
||||||
|
'gridState-Test-1' => [
|
||||||
|
'State' => [
|
||||||
|
'Column' => 'Name'
|
||||||
|
],
|
||||||
|
]
|
||||||
|
]
|
||||||
|
);
|
||||||
|
|
||||||
|
$request->setRouteParams(['Action' => 'edit']);
|
||||||
|
$gridField->setRequest($request);
|
||||||
|
|
||||||
|
$this->assertEquals(
|
||||||
|
$gridField->addAllStateToUrl($link),
|
||||||
|
'/class-name/item/1?gridState-Test-0%5BState%5D%5BColumn%5D=Name&gridState-Test-1%5BState%5D%5BColumn%5D=Name'
|
||||||
|
);
|
||||||
|
// The actual URL path here is arbitrary
|
||||||
|
$request = new HTTPRequest(
|
||||||
|
'GET',
|
||||||
|
'admin/gridfield',
|
||||||
|
[
|
||||||
|
'action_gridFieldAlterAction?StateID=1',
|
||||||
|
'ActionState' => json_encode([
|
||||||
|
'grid' => $gridField->getName(),
|
||||||
|
'actionName' => 'edit',
|
||||||
|
'args' => [],
|
||||||
|
]),
|
||||||
|
'gridState-Test' => [
|
||||||
|
'State' => [
|
||||||
|
'Column' => 'Name'
|
||||||
|
],
|
||||||
|
]
|
||||||
|
]
|
||||||
|
);
|
||||||
|
$request->setRouteParams(['Action' => 'edit']);
|
||||||
|
$gridField->setRequest($request);
|
||||||
|
|
||||||
|
$this->assertEquals(
|
||||||
|
$gridField->addAllStateToUrl($link),
|
||||||
|
'/class-name/item/1?gridState-Test%5BState%5D%5BColumn%5D=Name'
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user