Admin controllers
- Home
- Developing modules
- Admin controllers
Admin controllers are located within the Controllers\Admin
namespace and corresponding directory in the module.
The methods of this controller are not called directly, but instead are provided via the main AdminController
and corresponding admin routes. The controller class extends ManagedAdminController
which provides a mixture of abstract methods and default methods for commonly implemented features.
In the above diagram, the green areas are provided by the core framework, and the blue portions are provided by module code.
An example of how it works:
- The browser requests one of the admin routes, such as
admin/edit/blog_post/42
- The route is directed to the
edit
method of the mainAdminController
within core - The admin controller looks up
blog_post
in the admin controller registrations, and finds the module-provided admin controller, in this case it's theBlogPostAdminController
. - The controller is instanced, and the
_getEditForm
method is called, which returns the page title and the main content html - The main admin controller wraps the resulting title and html into the admin template, which is returned to the browser
A similar scenario occurs for saving of edits:
- The browser requests the edit save route, such as
admin/edit_save/blog_post/42
- The route is directed to the
editSave
method of the main admin controller - Like last time, admin controller looks up
blog_post
in the admin controller registrations, and again the module-providedBlogPostAdminController
is found and instanced. - The
_editSave
method is called, returning true on success or false on failure. - The main admin controller redirects the browser back to the edit form and shows a confirmation message.
Like this, all other activities -- listing records, adding, deleting, importing, exporting -- have an admin route and a corresponding behind-the-scenes method which does the bulk of the work.
Admin controller registration
Admin controllers are registered using the Register::adminControllers
method in the admin_load.php
file in the module directory.
This registration links a unique slug (e.g. blog_post
) to the underlying namespace and controller (e.g. SproutModules\AcmeInc\Blogs\Controllers\Admin\BlogPostAdminController
) which makes urls much shorter, especially considering the length of a fully namespaced controller name!
Registration can be for multiple controllers in the same function call.
modules/Blogs/admin_load.php
Register::adminControllers('AcmeInc\Blogs', [ 'blog_post' => 'Admin\\BlogPostAdminController', 'blog_post_category' => 'Admin\\BlogPostCategoryAdminController', 'blog_author' => 'Admin\\BlogAuthorAdminController', ]);
You'll notice that some of the nibbles in the namespace are implied.
Base controller
To avoid vast amounts of duplicated code, the base ManagedAdminController
provides many default methods which in many cases can be used directly, but if required can be overwritten with custom code.
There are additional base classes which can be used which provide even more specialised behaviours:
- HasCategoriesAdminController - a set of records which are organised into categories (e.g. blog posts)
- CategoryAdminController - the sister controller for managing the categories themselves (e.g. blog post categories)
- ListAdminController - a short list of records without categories (e.g. blog authors)
- TreeAdminController - a tree structure with parent and children records (e.g. pages)
- NoRecordsAdminController - a utility-only controller which doesn't manage records
As well as the various overridable methods, there are also some overrideable protected properties. These provide the parameters which the default methods need, such as the name of the table to work with.
Some of the methods in these controllers are for specific tasks, such as record adding and editing, and others affect the behaviour in the admin, such as _getNavigation
which returns the html for the navigation sidebar area.
modules/Blogs/Controllers/Admin/BlogPostAdminController.php
class BlogPostAdminController extends HasCategoriesAdminController { protected $controller_name = 'blog_post'; // Registered controller slug protected $friendly_name = 'Blog posts'; // Shown in admin protected $table_name = 'blog_posts'; // Optional; plural form of slug // The rest of the code goes here }
As it's extending HasCategoriesAdminController
, this class is almost ready to go.
With the other main base admin controllers - ManagedAdminController
, TreeAdminController
, and ListAdminController
- there are a few abstract methods which need to be implemented, but almost everything else will be ready-to-go as required. Admin controllers which don't have any database backend (e.g. those which provide tools to check external connectivity, manage upgrades, or other functions which aren't database-related) should extend NoRecordsAdminController
, which also has a few abstract methods to be extended.
Note that some base controllers such as CategoryAdminController
don't have any abstract methods, and therefore can be defined with only a few lines of code:
modules/Blogs/Controllers/Admin/BlogPostCategoryAdminController.php
class BlogPostCategoryAdminController extends CategoryAdminController { protected $controller_name = 'blog_post_category'; protected $friendly_name = 'Blog post categories'; protected $navigation_name = 'Blog posts'; protected $main_columns = null; }
The full reference of available properties and methods is also available.