-
Notifications
You must be signed in to change notification settings - Fork 821
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
FIX Provide alternatives to session for storing GridField_FormAction state #8627
FIX Provide alternatives to session for storing GridField_FormAction state #8627
Conversation
ee733a1
to
7a49b69
Compare
public function load($id) | ||
{ | ||
// Check the request | ||
return json_decode($this->request->requestVar('ActionState'), true); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It might be worth casting the requestVar as a string, since json_decode(true, true)
would return int(1)
. Maybe also update the PHPdoc to be explicit about what it can return instead of "mixed"
/** | ||
* @param HTTPRequest $request | ||
*/ | ||
public function __construct(HTTPRequest $request); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm in two minds about whether it's a good idea to have the constructor in this interface
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've just read this and now believe we should remove the constructor: https://www.alainschlesser.com/including-constructor-interface/
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah at the time I wasn't really happy with this code either. I need the request in both implementations of the interface and I don't think it's a good pattern to fetch the request from global state (Controller::curr
or Injector
). I'll just suck it up though; remove the constructor and use Controller::curr
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You could always give it a setter and use injector calls to provide it
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Or put the constructor in an abstract parent class - separating the implementation from the interface entirely
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah having the constructor in an abstract is a possibility but then I'll have to do some introspection on the type of object configured for the interface which sounds pretty hard. I think I'll make an abstract but just use private static $dependencies
. This would be much better with constructor DI 😉
* Load state for a given ID | ||
* | ||
* @param string $id | ||
* @return mixed |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should be more specific than this - are we expecting an array?
There are also some minimal docs that could use a nudge too: https://docs.silverstripe.org/en/4/developer_guides/forms/field_types/gridfield/#saving-the-gridfield-state |
205c4f7
to
8283481
Compare
Thanks for the heads up. The I'll add a section about configuring it to use attributes/request params instead of session. Otherwise I'm done with implementation now. |
8283481
to
f092a96
Compare
Docs pushed 🙂 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I had a look to make sure Session wasn't being referenced by GrdiFields outside of SessionStore
.
- Needs a changelog entry.
- If practical, could we have some unit test for the following:
SessionStore
AttributeStore
GridField_FormAction::getAttribute()
Didn't quite get to run locally to confirm the change work as expected. I'll do that tomorrow.
/** | ||
* Stores GridField action state on an attribute on the action and then analyses request parameters to load it back | ||
*/ | ||
class AttributeStore extends AbstractRequestAwareStore implements StateStore |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shouldn't AbstractRequestAwareStore
be the class implementing the StateStore
interface, instead of its child class? Is there a case where you would want a RequestAwareStore
that wasn't a StateStore
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fair call. I'll change this and add some tests hopefully tomorrow.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Me happy. SessionStore is still implementing StateStore. Feel free to address this or not.
/** | ||
* Stores GridField action state in the session in exactly the same way it has in the past | ||
*/ | ||
class SessionStore extends AbstractRequestAwareStore implements StateStore |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
AbstractRequestAwareStore
is implementing StateStore
now. This implements statement is kind of redundant.
…idFieldFilterHeader to add required attributes
85af377
to
c7b5b1e
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Still happy.
@ScopeyNZ The Travis fail isn't related to behat. It's something about the History Viewer controller. Is this related to this PR? |
I think this was just resolved in CMS. Rerunning the job. |
Cool ... I'll merge on green. |
Fixes #8589
Currently the session is used to store GridField action state. This PR doesn't change that by default. I've abstracted the storage method into an interface and provided an alternate that will just pass down the state to the DOM and then route it back when a request is built to perform an action.
I tried to go down the path of invalidating this action state but it's hard to tell exactly when the user navigates away from the GridField - especially as multiple GridFields can exist on one page, and some are loaded through AJAX requests.
Relies on silverstripe/silverstripe-admin#757