-
Notifications
You must be signed in to change notification settings - Fork 824
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
Normalise the signature of controller actions in core code #10466
Comments
Side note. The return type doesn't have to be HTTPResponse. It can be:
|
Not sure what to do with the strict return type and the warning. Might need more feedback from @silverstripe/core-team. |
Enforcing the HTTPRequest paramater seems good. If any projects break on upgrade, it's an easy fix, just update the method signature (or call, I'm not 100% sure which it is, either way it's easy) I'd be inclined to leave the return type blank, or change it to mixed (functionally identical), or a union type (probably best) Otherwise we're taking away functionality. For instance, one of the current use cases is: If we restricted this to HTTPResponse, then we've taken away the "values in the array are available in the templates" functionality, which some current projects may rely on, so we're adding upgrade pain for, I'm really not sure what value? |
I'm going to propose splitting this into 4 + 1 issues: 1. Update core classes to extend ContentController instead of PageController
2. Update non-core classes to extend ContentController instead of PageController
3. Update methods signature that implement
4. As above, though for non-core modules
5. Update
|
IMO |
IMO the existing way of have a project PageController be the base page for core classes it's a very bad piece of architecture that should be rectified in this major release |
Right. What I'm saying is that that's a departure from what is expected and from the way I'm not against removing that paradigm but that should be a very conscious and intentional decision, probably including the removal of the un-namespaced |
OK I've split this off as a spike #10537 |
With the mandatory request, what will be the recommended approach to using controller actions from CLI tasks? Create an empty request and pass that through? |
In my humble opinion, that feels like a bit of a code smell - wouldn't that method be better placed on either a (Either way, yeah I suppose the workaround is to pass through a blank object via |
Imo controllers are exactly the right place for most cli actions - in fact if Silverstripe was more strictly MVC there would be very little logic on models at all. But I also agree that passing an empty request to a controller is a bit of a smell. A Maybe having a mandatory request object passed in isn't the best way forward. Or perhaps we need some higher level request type that |
The actual functionality/code can be a part of a service, a controller, or a static method on a model, but it still needs to be invoked somehow — through a controller, possibly using a route. There's a workaround of doing it as a dev task or a build task, but some actions definitely can be invoked both via browser, e.g. a health check ping from a monitoring service such as Pingdom, or through CLI via cronjob. |
As noted on the issue I split off the strongly type I've written some simple code to hopefully clarify this: PageController.php <?php
class PageController extends SilverStripe\CMS\Controllers\ContentController
{
private static $allowed_actions = [ 'myaction' ];
public function myaction($request)
{
return array_merge(['xyz' => 123], ['abc' => $request->getVar('abc')]);
}
} MyTask.php <?php
class MyTask extends SilverStripe\Dev\BuildTask
{
public function run($request)
{
echo get_class($request) . "\n";
echo $request->getVar('abc') . "\n";
echo PageController::create()->myaction($request)['xyz'] . "\n";
echo PageController::create()->myaction($request)['abc'] . "\n";
}
}
|
You made a strong argument in #10466 (comment) that we should be looser with the return types than explicitly |
In the PRs above all I've effectively done is add strong typing to a bunch of internal methods. This meets the following two acceptance critiera
In regards to the other Acceptance criteria
You can still do this in a project: class PageController extends SilverStripe\CMS\Controllers\ContentController
{
private static $allowed_actions = ['someaction'];
public function someaction()
{
return 'this is my action';
} It worth nothing that everything will go via the following catch-all Inside that catch-all there will be calls to things such Which itself will call Which is what will call the action method on project controllers. There is no type checking done here. |
"All internal Silverstripe action use the official signature" I think the latter is potentially better as it allows, as I mentioned, for developers to override core methods and return any of those types - but if you still think explicitly |
Also @michalkleiner do you still have concerns about the CLI or has Steve addressed that? |
Yes Note: it's not really that "official" This PR is really just me refactoring to add strong typing to a bunch of things that are called internally. I ran into quite a few instances where methods wanted to return something that wasn't an HTTPResponse, so I left them as they were. That's fine, ultimately everything gets converted to HTTPResponse before going to the browser in People are still free to using whatever dynamic signature they want on their own controller actions in their project |
All good with me, thanks for checking. We already used creating a new request so not a big change for us. I also realised that our other use case was running build tasks from queued jobs from the |
You'll also need a docs PR to point out these changes in the changelog. |
Have made changes to PRs, added changelog, and updated and re-run the installer CI using vendor-patches https://github.com/creative-commoners/silverstripe-installer/actions/runs/3262595239 |
PRS merged - please update the draft PR now |
All PRs merged |
The standard signature for our controller action should be something like this:
or
Currently you can choose not to expect the first parameter which has caused us occasional problem.
We should normalise all our actions to expect to official signature.
Maybe we should throw exception/warning if your controller action don't match the expected signature.
Acceptance criteria
Notes
Related
New issues created
PRs
Shared run of silverstripe/installer containing PRs above (excluding frameworktest)
The text was updated successfully, but these errors were encountered: