Comment on page
Controllers
Controllers contain methods which are executed when a route is accessed. To learn how to map a route to a controller method, see the routing documentation.
An application controller responds to requests from the front application. Notice that application controllers extend
sa\application\controller
.<?php
use sa\application\controller;
class UserController extends controller {
/**
* Lists all users.
*/
public function index() {
// <implementation code>
}
}
Siteadmin controllers should be used for responding to routes that should only be accessible from Siteadmin. All routes that map to this type of controller will automatically require the user to be logged into their siteadmin dashboard.
The classsaController
extendscontroller
and therefore inherits all of the behavior you would expect from a regular application controller.By convention, all classes that extendssaController
should be have aSa
prefix (i.e. SaUserController instead of UserController).
<?php
use sa\application\controller;
class SaUserController extends saController {
/**
* Lists all users.
*/
public function index() {
// <implementation code>
}
}
A
resource controller
responds to routing requests from resourceRoutes
. These controllers serve assets, such as stylesheets, images, files, or javascript files which are specific to the module the controller belongs to.Notice the resource controller extendscontroller
, just as a regular controller. All controllers inherit the following methods:css()
,js()
, andimg()
. Therefore, all controllers are resource controllers. It is still best practice to have a dedicated controller to handle all of your module's assets. This allows both application and administrative controllers to share the same assets.css()
method will search/{module name}/src/css/
for your stylesheets.js()
method will search/{module name}/src/js/
for your javascript files.img()
method will search/{module name}/src/img/
for your images.These methods can be overwritten to fetch assets from other locations on the server.
To create a resource controller, simply extend
controller
. Your new resource controller will automatically inherit the necessary methods (mentioned in the note above) to render resources for you.<?php
use sa\application\controller;
/**
* Responds to requests for static assets relevant to the user module.
*/
class UserResourceController extends controller {
}
You can change the directory where each method searches for your resources by defining custom methods, or overriding any of the existing methods.
<?php
use sa\application\controller;
/**
* Responds to requests for static assets relevant to the user module.
*/
class UserResourceController extends controller {
public function css($view)
{
// change location of css files to /stylesheets
$view = new assetView($view, static::assetLocation('stylesheets'));
$view->display();
}
public function js($view)
{
// change location of js files in /javascript
$view = new assetView($view, static::assetLocation('javascript'));
$view->display();
}
public function img($view)
{
//change location of images in /images
$view = new assetView($view, static::moduleLocation('images'));
$view->display();
}
/**
* If your module needs to access files which are outside the
* scope of css, js, or images, you can create a custom resource
* method. A resource route must be mapped to this method for this
* to work.
*/
public function docs($view) {
$view = new assetView($view, static::moduleLocation('documents'));
$view->display();
}
}
Resource controllers are isolated on their own for good reason. When you extend a controller or override its
IOC_NAME
reference, the css()
, js()
, and img()
methods will search the extended module's directories for assets instead of in the core module. Since your extended module likely won't have the same CSS/JS/image files as the parent module, all your assets will return a 404
response when accessed.With this in mind, you should never extend a resource controller. Doing so will result in assets breaking in the parent module.
But can't the assets from the parent module be copied into the extended module?
...yes, but don't do this either unless you want a massive headache every time the parent module adds a new asset, rolls out a bug fix for an asset, or implements a new feature in JS a file. You'll have to copy & paste all the assets to your extended module every...single...time.
Instead, your extended module should have its own uniquely named resource controller. The module's resource routes should also be unique to avoid conflicting with the parent module's assets.
URL parameters from dynamic routes are passed into the controller as method parameters. The following route contains 2 URL parameters. The first represents a user ID, the second is an invoice ID.
^/user/[0-9]/invoice/[0-9]$
These parameters are passed into the
getUser()
method in the same order as they were defined in the route.<?php
class UserController extends controller {
public function getUser($userId, $invoiceId) {
// <implementation code>
}
}
URL parameters are often ID's which represent real entities in the database. It is bad practice to query the database manually from the controller method. Instead, you should add a docBlock above the method definition, which specifies the object type of the entity associated with the ID.
<?php
class UserController extends controller {
public function getUser($userId, $invoiceId) {
$user = app::$entityManager->find('saUser', $userId);
$invoice = app::$entityManager->find('invoice', $invoiceId);
// <implementation code>
}
}
<?php
class UserController extends controller {
/**
* @param saUser $user
* @param Invoice $invoice
*/
public function getUser($user, $invoice) {
// <implementation code>
}
}
Last modified 4yr ago