Sprout admin controllers have a surprisingly long history. Over time they have accumulated some cruft, sharp edges, and their behaviours can be - at times - perplexing. This PR attempts to resolve some of that ambiguity.
First some basics:
admin controllers have two names; a class name and a 'short' name (used for URLs)
additional admin controllers can be registered (from modules)
sprout provides permission management for some controllers (per-subsite or per-record)
Some issues:
short names have to be duplicated (and matching) for both the Register::adminControllers() and ManagedAdminController::$controller_name
$controller_name is never used for URL discovery, instead using registered short name except for (some) core controllers (these have their own magic)
however, $controller_name is used to produce URLs for controllers
some controllers are blacklisted from the permission management, but which?
Unification of short names
So $controller_name still exists, but it's no longer required to specify when creating a controller. If empty it will populate from the register. All short names can now be declared in one place (the register). This also means all core controllers are now registered (more on this later).
Content controllers
There was a weak description of a 'content controller' - one that permits per-record and per-subsite permissions. This is loosely defined by Register::coreContentControllers() and some inheritance filters. All module controllers are implicitly a content controller.
So content controllers were:
core controllers that are registered
all modules controllers
except anything that is a Category controller
except per-record content, which excludes NoRecord controllers + a fixed set of hardcoded names
We now have a clear filtering system. Controllers have a _getContentsPermissionGroups() helper that returns boolean map to inform the permission controllers if they have these features enables.
URL discovery
The process was this:
Look up a controller class using it's registered short name
It may make sense, but it can be a surprising behaviour considering how modules and URL creation is performed.
Having resolved categorisation of 'content controllers' means all core controllers can be registered and their short names are also in one place. We now have an admin_load.php in the sprout app folder to achieve this.
The process is now:
Look up a controller class using it's registered short name
That's it.
Some perks
Controller registration doesn't need to conform to the SproutModules\Author\Module\Controllers\Admin\ pattern. This was required to properly register the core controllers. However this same functionality was required for the upcoming external modules support - so yay.
Friendly names, navigation names, table names - these are all now generated on construct (if empty). Their behaviour generally is also now a little more consistent. I would like to make these static so we don't have to do stupid reflection things all over the place.
Category controllers will naturally create all their own handles/names based on the expected structures. A basic category controller can be declared like this:
JsonForms have always bothered me. Too much of their logic lives in the base controller class - something that isn't relevant to frontend controllers. This code should live in the ManagedAdminController class or a different helper, possibly a trait. An external helper poses challenges because how tightly the action log and table_name is tied into the controller classes.
Might still rework name helpers into static methods.
This is part of Sprout 4.0
Sprout admin controllers have a surprisingly long history. Over time they have accumulated some cruft, sharp edges, and their behaviours can be - at times - perplexing. This PR attempts to resolve some of that ambiguity.
First some basics:
Some issues:
Register::adminControllers()
andManagedAdminController::$controller_name
$controller_name
is never used for URL discovery, instead using registered short name except for (some) core controllers (these have their own magic)$controller_name
is used to produce URLs for controllersUnification of short names
So
$controller_name
still exists, but it's no longer required to specify when creating a controller. If empty it will populate from the register. All short names can now be declared in one place (the register). This also means all core controllers are now registered (more on this later).Content controllers
There was a weak description of a 'content controller' - one that permits per-record and per-subsite permissions. This is loosely defined by
Register::coreContentControllers()
and some inheritance filters. All module controllers are implicitly a content controller.So content controllers were:
We now have a clear filtering system. Controllers have a
_getContentsPermissionGroups()
helper that returns boolean map to inform the permission controllers if they have these features enables.URL discovery
The process was this:
It may make sense, but it can be a surprising behaviour considering how modules and URL creation is performed.
Having resolved categorisation of 'content controllers' means all core controllers can be registered and their short names are also in one place. We now have an
admin_load.php
in the sprout app folder to achieve this.The process is now:
Some perks
Controller registration doesn't need to conform to the
SproutModules\Author\Module\Controllers\Admin\
pattern. This was required to properly register the core controllers. However this same functionality was required for the upcoming external modules support - so yay.Friendly names, navigation names, table names - these are all now generated on construct (if empty). Their behaviour generally is also now a little more consistent. I would like to make these static so we don't have to do stupid reflection things all over the place.
Category controllers will naturally create all their own handles/names based on the expected structures. A basic category controller can be declared like this:
Related future work
JsonForms have always bothered me. Too much of their logic lives in the base controller class - something that isn't relevant to frontend controllers. This code should live in the ManagedAdminController class or a different helper, possibly a trait. An external helper poses challenges because how tightly the action log and table_name is tied into the controller classes.
Might still rework name helpers into static methods.