mirror of
https://github.com/silverstripe/silverstripe-framework
synced 2024-10-22 14:05:37 +02:00
FIX Provide alternatives to session for storing GridField_FormAction state
This commit is contained in:
parent
41dc9229bf
commit
b4c8f699eb
6
_config/gridfield.yml
Normal file
6
_config/gridfield.yml
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
---
|
||||||
|
Name: gridfieldconfig
|
||||||
|
---
|
||||||
|
SilverStripe\Core\Injector\Injector:
|
||||||
|
SilverStripe\Forms\GridField\FormAction\StateStore:
|
||||||
|
class: SilverStripe\Forms\GridField\FormAction\SessionStore
|
51
src/Forms/GridField/FormAction/AttributeStore.php
Normal file
51
src/Forms/GridField/FormAction/AttributeStore.php
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
<?php
|
||||||
|
namespace SilverStripe\Forms\GridField\FormAction;
|
||||||
|
|
||||||
|
use SilverStripe\Control\HTTPRequest;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stores GridField action state on an attribute on the action and then analyses request parameters to load it back
|
||||||
|
*/
|
||||||
|
class AttributeStore implements StateStore
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var HTTPRequest
|
||||||
|
*/
|
||||||
|
protected $request;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param HTTPRequest $request
|
||||||
|
*/
|
||||||
|
public function __construct(HTTPRequest $request)
|
||||||
|
{
|
||||||
|
$this->request = $request;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Save the given state against the given ID returning an associative array to be added as attributes on the form
|
||||||
|
* action
|
||||||
|
*
|
||||||
|
* @param string $id
|
||||||
|
* @param array $state
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function save($id, array $state)
|
||||||
|
{
|
||||||
|
// Just save the state in the attributes of the action
|
||||||
|
return [
|
||||||
|
'data-action-state' => json_encode($state),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Load state for a given ID
|
||||||
|
*
|
||||||
|
* @param string $id
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
public function load($id)
|
||||||
|
{
|
||||||
|
// Check the request
|
||||||
|
return json_decode($this->request->requestVar('ActionState'), true);
|
||||||
|
}
|
||||||
|
}
|
50
src/Forms/GridField/FormAction/SessionStore.php
Normal file
50
src/Forms/GridField/FormAction/SessionStore.php
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
<?php
|
||||||
|
namespace SilverStripe\Forms\GridField\FormAction;
|
||||||
|
|
||||||
|
use SilverStripe\Control\HTTPRequest;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stores GridField action state in the session in exactly the same way it has in the past
|
||||||
|
*/
|
||||||
|
class SessionStore implements StateStore
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var HTTPRequest
|
||||||
|
*/
|
||||||
|
protected $request;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param HTTPRequest $request
|
||||||
|
*/
|
||||||
|
public function __construct(HTTPRequest $request)
|
||||||
|
{
|
||||||
|
$this->request = $request;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Save the given state against the given ID returning an associative array to be added as attributes on the form
|
||||||
|
* action
|
||||||
|
*
|
||||||
|
* @param string $id
|
||||||
|
* @param array $state
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function save($id, array $state)
|
||||||
|
{
|
||||||
|
$this->request->getSession()->set($id, $state);
|
||||||
|
|
||||||
|
// This adapter does not require any additional attributes...
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Load state for a given ID
|
||||||
|
*
|
||||||
|
* @param string $id
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
public function load($id)
|
||||||
|
{
|
||||||
|
return $this->request->getSession()->get($id);
|
||||||
|
}
|
||||||
|
}
|
30
src/Forms/GridField/FormAction/StateStore.php
Normal file
30
src/Forms/GridField/FormAction/StateStore.php
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
<?php
|
||||||
|
namespace SilverStripe\Forms\GridField\FormAction;
|
||||||
|
|
||||||
|
use SilverStripe\Control\HTTPRequest;
|
||||||
|
|
||||||
|
interface StateStore
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @param HTTPRequest $request
|
||||||
|
*/
|
||||||
|
public function __construct(HTTPRequest $request);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Save the given state against the given ID returning an associative array to be added as attributes on the form
|
||||||
|
* action
|
||||||
|
*
|
||||||
|
* @param string $id
|
||||||
|
* @param array $state
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function save($id, array $state);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Load state for a given ID
|
||||||
|
*
|
||||||
|
* @param string $id
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
public function load($id);
|
||||||
|
}
|
@ -9,8 +9,11 @@ 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\RequestHandler;
|
use SilverStripe\Control\RequestHandler;
|
||||||
|
use SilverStripe\Core\Injector\Injector;
|
||||||
use SilverStripe\Forms\Form;
|
use SilverStripe\Forms\Form;
|
||||||
use SilverStripe\Forms\FormField;
|
use SilverStripe\Forms\FormField;
|
||||||
|
use SilverStripe\Forms\GridField\FormAction\SessionStore;
|
||||||
|
use SilverStripe\Forms\GridField\FormAction\StateStore;
|
||||||
use SilverStripe\ORM\ArrayList;
|
use SilverStripe\ORM\ArrayList;
|
||||||
use SilverStripe\ORM\DataList;
|
use SilverStripe\ORM\DataList;
|
||||||
use SilverStripe\ORM\DataObject;
|
use SilverStripe\ORM\DataObject;
|
||||||
@ -1009,9 +1012,14 @@ class GridField extends FormField
|
|||||||
$state->setValue($fieldData['GridState']);
|
$state->setValue($fieldData['GridState']);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Fetch the store for the "state" of actions (not the GridField)
|
||||||
|
/** @var StateStore $store */
|
||||||
|
$store = Injector::inst()->create(StateStore::class . '.' . $this->getName(), $request);
|
||||||
|
|
||||||
foreach ($data as $dataKey => $dataValue) {
|
foreach ($data as $dataKey => $dataValue) {
|
||||||
if (preg_match('/^action_gridFieldAlterAction\?StateID=(.*)/', $dataKey, $matches)) {
|
if (preg_match('/^action_gridFieldAlterAction\?StateID=(.*)/', $dataKey, $matches)) {
|
||||||
$stateChange = $request->getSession()->get($matches[1]);
|
$stateChange = $store->load($matches[1]);
|
||||||
|
|
||||||
$actionName = $stateChange['actionName'];
|
$actionName = $stateChange['actionName'];
|
||||||
|
|
||||||
$arguments = array();
|
$arguments = array();
|
||||||
|
@ -3,8 +3,10 @@
|
|||||||
namespace SilverStripe\Forms\GridField;
|
namespace SilverStripe\Forms\GridField;
|
||||||
|
|
||||||
use SilverStripe\Control\Controller;
|
use SilverStripe\Control\Controller;
|
||||||
|
use SilverStripe\Core\Injector\Injector;
|
||||||
use SilverStripe\Forms\Form;
|
use SilverStripe\Forms\Form;
|
||||||
use SilverStripe\Forms\FormAction;
|
use SilverStripe\Forms\FormAction;
|
||||||
|
use SilverStripe\Forms\GridField\FormAction\StateStore;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class is the base class when you want to have an action that alters the state of the
|
* This class is the base class when you want to have an action that alters the state of the
|
||||||
@ -12,6 +14,11 @@ use SilverStripe\Forms\FormAction;
|
|||||||
*/
|
*/
|
||||||
class GridField_FormAction extends FormAction
|
class GridField_FormAction extends FormAction
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* A common string prefix for keys generated to store form action "state" against
|
||||||
|
*/
|
||||||
|
const STATE_KEY_PREFIX = 'gf_';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var GridField
|
* @var GridField
|
||||||
*/
|
*/
|
||||||
@ -80,29 +87,39 @@ class GridField_FormAction extends FormAction
|
|||||||
*/
|
*/
|
||||||
public function getAttributes()
|
public function getAttributes()
|
||||||
{
|
{
|
||||||
// Store state in session, and pass ID to client side.
|
// Determine the state that goes with this action
|
||||||
$state = array(
|
$state = array(
|
||||||
'grid' => $this->getNameFromParent(),
|
'grid' => $this->getNameFromParent(),
|
||||||
'actionName' => $this->actionName,
|
'actionName' => $this->actionName,
|
||||||
'args' => $this->args,
|
'args' => $this->args,
|
||||||
);
|
);
|
||||||
|
|
||||||
// Ensure $id doesn't contain only numeric characters
|
// Generate a key and attach it to the action name
|
||||||
$id = 'gf_' . substr(md5(serialize($state)), 0, 8);
|
$key = static::STATE_KEY_PREFIX . substr(md5(serialize($state)), 0, 8);
|
||||||
|
// Note: This field needs to be less than 65 chars, otherwise Suhosin security patch will strip it
|
||||||
|
$name = 'action_gridFieldAlterAction?StateID=' . $key;
|
||||||
|
|
||||||
$session = Controller::curr()->getRequest()->getSession();
|
// Define attributes
|
||||||
$session->set($id, $state);
|
$attributes = array(
|
||||||
$actionData['StateID'] = $id;
|
'name' => $name,
|
||||||
|
|
||||||
return array_merge(
|
|
||||||
parent::getAttributes(),
|
|
||||||
array(
|
|
||||||
// Note: This field needs to be less than 65 chars, otherwise Suhosin security patch
|
|
||||||
// will strip it from the requests
|
|
||||||
'name' => 'action_gridFieldAlterAction' . '?' . http_build_query($actionData),
|
|
||||||
'data-url' => $this->gridField->Link(),
|
'data-url' => $this->gridField->Link(),
|
||||||
'type' => "button",
|
'type' => "button",
|
||||||
)
|
);
|
||||||
|
|
||||||
|
// Create a "store" for the "state" of this action
|
||||||
|
/** @var StateStore $store */
|
||||||
|
$store = Injector::inst()->create(
|
||||||
|
StateStore::class . '.' . $this->gridField->getName(),
|
||||||
|
// For some reason `getRequest` on GridField_FormAction does not return the correct request
|
||||||
|
Controller::curr()->getRequest()
|
||||||
|
);
|
||||||
|
// Store the state and update attributes as required
|
||||||
|
$attributes += $store->save($key, $state);
|
||||||
|
|
||||||
|
// Return attributes
|
||||||
|
return array_merge(
|
||||||
|
parent::getAttributes(),
|
||||||
|
$attributes
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user