Controller documentation

This commit is contained in:
Will Rossiter 2014-10-18 11:28:51 +13:00 committed by Cam Findlay
parent 5eca844c8d
commit 82b1b3d566
7 changed files with 667 additions and 302 deletions

View File

@ -1,298 +0,0 @@
# Controller
Base controller class. You will extend this to take granular control over the
actions and url handling of aspects of your SilverStripe site.
## Usage
The following example is for a simple `[api:Controller]` class. If you're using
the cms module and looking at Page_Controller instances you won't need to setup
your own routes since the cms module handles these routes.
`mysite/code/Controllers/FastFood.php`
:::php
<?php
class FastFood_Controller extends Controller {
private static $allowed_actions = array('order');
public function order(SS_HTTPRequest $request) {
print_r($request->allParams());
}
}
## Routing
`mysite/_config/routes.yml`
:::yaml
---
Name: myroutes
After: framework/routes#coreroutes
---
Director:
rules:
'fastfood//$Action/$ID/$Name': 'FastFood_Controller'
Request for `/fastfood/order/24/cheesefries` would result in the following to
the $arguments above. If needed, use `?flush=1` on the end of request after
making any code changes to your controller.
:::ss
Array
(
[Action] => order
[ID] => 24
[Name] => cheesefries
)
<div class="warning" markdown='1'>
SilverStripe automatically adds a URL routing entry based on the controller's class name,
so a `MyController` class is accessible through `http://localhost/MyController`.
</div>
## Linking to a controller
Each controller has a built-in `Link()` method,
which can be used to avoid hardcoding your routing in views etc.
The method should return a value that makes sense with your custom route (see above):
:::php
<?php
class FastFood_Controller extends Controller {
public function Link($action = null) {
return Controller::join_links('fastfood', $action);
}
}
The [api:Controller::join_links()] invocation is optional, but makes `Link()` more flexible
by allowing an `$action` argument, and concatenates the path segments with slashes.
The action should map to a method on your controller. `join_links()` also supports
## Access Control
### Through $allowed_actions
All public methods on a controller are accessible by their name through the `$Action`
part of the URL routing, so a `MyController->mymethod()` is accessible at
`http://localhost/MyController/mymethod`. This is not always desireable,
since methods can return internal information, or change state in a way
that's not intended to be used through a URL endpoint.
SilverStripe strongly recommends securing your controllers
through defining a `$allowed_actions` array on the class,
which allows whitelisting of methods, as well as a concise
way to perform checks against permission codes or custom logic.
:::php
class MyController extends Controller {
private static $allowed_actions = array(
// someaction can be accessed by anyone, any time
'someaction',
// So can otheraction
'otheraction' => true,
// restrictedaction can only be people with ADMIN privilege
'restrictedaction' => 'ADMIN',
// complexaction can only be accessed if $this->canComplexAction() returns true
'complexaction' '->canComplexAction'
);
}
There's a couple of rules guiding these checks:
* Each class is only responsible for access control on the methods it defines
* If `$allowed_actions` is an empty array or undefined, only the `index` action is allowed
* Access checks on parent classes need to be overwritten via the Config API
* Only public methods can be made accessible
* If a method on a parent class is overwritten, access control for it has to be redefined as well
* An action named "index" is whitelisted by default,
unless allowed_actions is defined as an empty array,
or the action is specifically restricted in there.
* Methods returning forms also count as actions which need to be defined
* Form action methods (targets of `FormAction`) should NOT be included in `$allowed_actions`,
they're handled separately through the form routing (see the ["forms" topic](/topics/forms))
* `$allowed_actions` can be defined on `Extension` classes applying to the controller.
If the permission check fails, SilverStripe will return a "403 Forbidden" HTTP status.
You can overwrite the default behaviour on undefined `$allowed_actions` to allow all actions,
by setting the `RequestHandler.require_allowed_actions` config value to `false` (not recommended).
### Through the action
Each method responding to a URL can also implement custom permission checks,
e.g. to handle responses conditionally on the passed request data.
:::php
class MyController extends Controller {
private static $allowed_actions = array('myaction');
public function myaction($request) {
if(!$request->getVar('apikey')) {
return $this->httpError(403, 'No API key provided');
}
return 'valid';
}
}
Unless you transform the response later in the request processing,
it'll look pretty ugly to the user. Alternatively, you can use
`ErrorPage::response_for(<status-code>)` to return a more specialized layout.
Note: This is recommended as an addition for `$allowed_actions`, in order to handle
more complex checks, rather than a replacement.
### Through the init() method
After checking for allowed_actions, each controller invokes its `init()` method,
which is typically used to set up common state in the controller, and
include JavaScript and CSS files in the output which are used for any action.
If an `init()` method returns a `SS_HTTPResponse` with either a 3xx or 4xx HTTP
status code, it'll abort execution. This behaviour can be used to implement
permission checks.
:::php
class MyController extends Controller {
private static $allowed_actions = array();
public function init() {
parent::init();
if(!Permission::check('ADMIN')) return $this->httpError(403);
}
}
## URL Handling
In the above example the URLs were configured using the `[api:Director]` rules
in the **routes.yml** file. Alternatively you can specify these in your
Controller class via the **$url_handlers** static array (which gets processed
by the `[api:RequestHandler]`).
This is useful when you want to subvert the fixed action mapping of `fastfood/order/*`
to the function **order**. In the case below we also want any orders coming
through `/fastfood/drivethrough/` to use the same order function.
`mysite/code/Controllers/FastFood.php`
:::php
class FastFood_Controller extends Controller {
private static $allowed_actions = array(
'drivethrough'
);
private static $url_handlers = array(
'drivethrough/$Action/$ID/$Name' => 'order'
);
## URL Patterns
The `[api:RequestHandler]` class will parse all rules you specify against the
following patterns.
**A rule must always start with alphabetical ([A-Za-z]) characters or a $Variable
declaration**
| Pattern | Description |
| ----------- | --------------- |
| `$` | **Param Variable** - Starts the name of a paramater variable, it is optional to match this unless ! is used |
| `!` | **Require Variable** - Placing this after a parameter variable requires data to be present for the rule to match |
| `//` | **Shift Point** - Declares that only variables denoted with a $ are parsed into the $params AFTER this point in the regex |
## Examples
See maetl's article in the Links below of a detailed explanation.
`$Action/$ID/$OtherID` - Standard URL handler for a Controller. Take whatever `URLSegment` it is set to, find
the Action to match a function in the controller, and parse two optional `$param` variables that will be named `ID` and
`OtherID`.
`admin/help//$Action/$ID` - Match an url starting with `/admin/help/`, but don't include `/help/` as part of the
action (the shift point is set to start parsing variables and the appropriate controller action AFTER the `//`)
`tag/$Tag!` - Match an URL starting with `/tag/` after the controller's `URLSegment` and require it to have something
after it. If the URLSegment is **order** then `/order/tag/34` and `/order/tag/asdf` match but `/order/tag/` will not
You can use the `debug_request=1` switch from the [urlvariabletools](/reference/urlvariabletools) to see these in action.
## Redirection
Controllers facilitate HTTP redirection.
Note: These methods have been formerly located on the `[api:Director]` class.
* `redirect("action-name")`: If there's no slash in the URL passed to redirect, then it is assumed that you want to go to a different action on the current controller.
* `redirect("relative/url")`: If there is a slash in the URL, it's taken to be a normal URL. Relative URLs
will are assumed to be relative to the site-root.
* `redirect("http://www.absoluteurl.com")`: Of course, you can pass `redirect()` absolute URLs too.
* `redirectBack()`: This will return you to the previous page.
The `redirect()` method takes an optional HTTP status code,
either `301` for permanent redirects, or `302` for temporary redirects (default).
## Access control
You can also limit access to actions on a controller using the static `$allowed_actions` array. This allows you to always allow an action, or restrict it to a specific permission or to call a method that checks if the action is allowed.
For example, the default `Controller::$allowed_actions` is
private static $allowed_actions = array(
'handleAction',
'handleIndex',
);
which allows the `handleAction` and `handleIndex` methods to be called via a URL.
To allow any action on your controller to be called you can either leave your `$allowed_actions` array empty or not have one at all. This is the default behaviour, however it is not recommended as it allows anything on your controller to be called via a URL, including view-specific methods.
The recommended approach is to explicitly state the actions that can be called via a URL. Any action not in the `$allowed_actions` array, excluding the default `index` method, is then unable to be called.
To always allow an action to be called, you can either add the name of the action to the array or add a value of `true` to the array, using the name of the method as its index. For example
private static $allowed_actions = array(
'MyAwesomeAction',
'MyOtherAction' => true
);
To require that the current user has a certain permission before being allowed to call an action you add the action to the array as an index with the value being the permission code that user must have. For example
private static $allowed_actions = array(
'MyAwesomeAction',
'MyOtherAction' => true,
'MyLimitedAction' => 'CMS_ACCESS_CMSMain',
'MyAdminAction' => 'ADMIN'
);
If neither of these are enough to decide if an action should be called, you can have the check use a method. The method must be on the controller class and return true if the action is allowed or false if it isn't. To do this add the action to the array as an index with the value being the name of the method to called preceded by '->'. You are able to pass static arguments to the method in much the same way as you can with extensions. Strings are enclosed in quotes, numeric values are written as numbers and true and false are written as true and false. For example
private static $allowed_actions = array(
'MyAwesomeAction',
'MyOtherAction' => true,
'MyLimitedAction' => 'CMS_ACCESS_CMSMain',
'MyAdminAction' => 'ADMIN',
'MyRestrictedAction' => '->myCheckerMethod("MyRestrictedAction", false, 42)',
'MyLessRestrictedAction' => '->myCheckerMethod'
);
In this example, `MyAwesomeAction` and `MyOtherAction` are always allowed, `MyLimitedAction` requires access to the CMS for the current user and `MyAdminAction` requires the current user to be an admin. `MyRestrictedAction` calls the method `myCheckerMethod`, passing in the string "MyRestrictedAction", the boolean false and the number 42. `MyLessRestrictedAction` simply calls the method `myCheckerMethod` with no arguments.
## API Documentation
`[api:Controller]`
## Links
* `[api:Director]` class
* [execution-pipeline](/reference/execution-pipeline)
* [URL Handling in Controllers](http://maetl.net/silverstripe-url-handling) by maetl

View File

@ -0,0 +1,177 @@
title: Introduction to a Controller
summary: A brief look at the definition of a Controller, creating actions and how to respond to requests.
# Introduction to Controllers
The following example is for a simple [api:Controller] class. When building off the SilverStripe Framework you will
subclass the base `Controller` class.
**mysite/code/controllers/TeamController.php**
:::php
<?php
class TeamController extends Controller {
private static $allowed_actions = array(
'players',
'index'
);
public function index(SS_HTTPRequest $request) {
// ..
}
public function players(SS_HTTPRequest $request) {
print_r($request->allParams());
}
}
## Routing
We need to define the URL that this controller can be accessed on. In our case, the `TeamsController` should be visible
at http://yoursite.com/teams/ and the `players` custom action is at http://yoursite.com/team/players/.
<div class="info" markdown="1">
If you're using the `cms` module with and dealing with `Page` objects then for your custom `Page Type` controllers you
would extend `ContentController` or `Page_Controller`. You don't need to define the routes value as the `cms` handles
routing.
</div>
<div class="alert" markdown="1">
Make sure that after you have modified the `routes.yml` file, that you clear your SilverStripe caches using `flush=1`.
</div>
**mysite/_config/routes.yml**
:::yml
---
Name: mysiteroutes
After: framework/routes#coreroutes
---
Director:
rules:
'teams//$Action/$ID/$Name': 'TeamController'
For more information about creating custom routes, see the [Routing](routing) documentation.
## Actions
Controllers respond by default to an `index` method. You don't need to define this method (as it's assumed) but you
can override the `index()` response to provide custom data back to the [Template and Views](../templates).
<div class="notice" markdown="1">
It is standard in SilverStripe for your controller actions to be `lowercasewithnospaces`
</div>
Action methods can return one of four main things:
* an array. In this case the values in the array are available in the templates and the controller completes as
usual by returning a [api:SS_HTTPResponse] with the body set to the current template.
* `HTML`. SilverStripe will wrap the `HTML` into a `SS_HTTPResponse` and set the status code to 200.
* an [api:SS_HTTPResponse] containing a manually defined `status code` and `body`.
* an [api:SS_HTTPResponse_Exception]. A special type of response which indicates a error. By returning the
exception, the execution pipeline can adapt and display any error handlers.
:::php
**mysite/code/controllers/TeamController.php**
/**
* Return some additional data to the current response that is waiting to go out, this makes $Title set to
* 'MyTeamName' and continues on with generating the response.
*/
public function index(SS_HTTPRequest $request) {
return array(
'Title' => 'My Team Name'
);
}
/**
* We can manually create a response and return that to ignore any previous data.
*/
public function someaction(SS_HTTPRequest $request) {
$this->response = new SS_HTTPResponse();
$this->response->setStatusCode(400);
$this->response->setBody('invalid');
return $this->response;
}
/**
* Or, we can modify the response that is waiting to go out.
*/
public function anotheraction(SS_HTTPRequest $request) {
$this->response->setStatusCode(400);
return $this->response;
}
/**
* We can render HTML and leave SilverStripe to set the response code and body.
*/
public function htmlaction() {
return $this->customize(new ArrayData(array(
'Title' => 'HTML Action'
)))->renderWith('MyCustomTemplate');
}
/**
* We can send stuff to the browser which isn't HTML
*/
public function ajaxaction() {
$this->response->setBody(json_encode(array(
'json' => true
)));
$this->response->addHeader("Content-type", "application/json");
return $this->response.
}
For more information on how a URL gets mapped to an action see the [Routing](routing) documentation.
## Security
See the [Access Controller](access_control) documentation.
## Templates
Controllers are automatically rendered with a template that makes their name. Our `TeamsController` would be rendered
with a `TeamsController.ss` template. Individual actions are rendered in `TeamsController_{actionname}.ss`.
If a template of that name does not exist, then SilverStripe will fall back to the `TeamsController.ss` then to
`Controller.ss`.
Controller actions can use `renderWith` to override this template selection process as in the previous example with
`htmlaction`. `MyCustomTemplate.ss` would be used rather than `TeamsController`.
For more information about templates, inheritance and how to rendering into views, See the
[Templates and Views](templates) documentation.
## Link
Each controller should define a `Link()` method. This should be used to avoid hard coding your routing in views etc.
**mysite/code/controllers/TeamController.php**
:::php
public function Link($action = null) {
return Controller::join_links('teams', $action);
}
<div class="info">
The [api:Controller::join_links] is optional, but makes `Link()` more flexible by allowing an `$action` argument, and
concatenates the path segments with slashes. The action should map to a method on your controller.
</div>
## Related Documentation
* [Execution Pipeline](../execution_pipeline)
* [Templates and Views](../templates)
## API Documentation
* [api:Controller]
* [api:Director]

View File

@ -1,2 +1,166 @@
#Routing
This is a stub to be fleshed out about routing given it is a popular topic and currently hard to find.
title: Routing
summary: A more in depth look at how to map requests to particular controllers and actions.
# Routing
Routing is the process of mapping URL's to [api:Controllers] and actions. In the introduction we defined a new custom route
for our `TeamsController` mapping any `teams` URL to our `TeamsController`
<div class="info" markdown="1">
If you're using the `cms` module with and dealing with `Page` objects then for your custom `Page Type` controllers you
would extend `ContentController` or `Page_Controller`. You don't need to define the routes value as the `cms` handles
routing.
</div>
These routes by standard, go into a `routes.yml` file in your applications `_config` folder alongside your other
[Configuration](../configuration) information.
**mysite/_config/routes.yml**
:::yml
---
Name: mysiteroutes
After: framework/routes#coreroutes
---
Director:
rules:
'teams//$Action/$ID/$Name': 'TeamController'
'player/': 'PlayerController'
'': 'HomeController'
<div class="notice" markdown="1">
To understand the syntax for the `routes.yml` file better, read the [Configuration](../configuration) documentation.
</div>
## Parameters
:::yml
'teams//$Action/$ID/$Name': 'TeamController'
This route has defined that any URL beginning with `team` should create, and be handled by a `TeamController` instance.
It also contains 3 `parameters` or `params` for short. `$Action`, `$ID` and `$Name`. These variables are placeholders
which will be filled when the user makes their request. Request parameters are available on the `SS_HTTPRequest` object
and able to be pulled out from a controller using `$this->request->param($name)`.
<div class="info" markdown="1">
All Controllers have access to `$this->request` for the request object and `$this->response` for the response.
</div>
Here is what those parameters would look like for certain requests
:::php
// GET /teams/
print_r($this->request->params());
// Array
// (
// [Action] => null
// [ID] => null
// [Name] => null
// )
// GET /teams/players/
print_r($this->request->params());
// Array
// (
// [Action] => 'players'
// [ID] => null
// [Name] => null
// )
// GET /teams/players/1
print_r($this->request->params());
// Array
// (
// [Action] => 'players'
// [ID] => 1
// [Name] => null
// )
You can also fetch one parameter at a time.
:::php
// GET /teams/players/1/
echo $this->request->param('ID');
// returns '1'
## URL Patterns
The `[api:RequestHandler]` class will parse all rules you specify against the following patterns. The most specific rule
will be the one followed for the response.
<div class="alert">
A rule must always start with alphabetical ([A-Za-z]) characters or a $Variable declaration
</div>
| Pattern | Description |
| ----------- | --------------- |
| `$` | **Param Variable** - Starts the name of a paramater variable, it is optional to match this unless ! is used |
| `!` | **Require Variable** - Placing this after a parameter variable requires data to be present for the rule to match |
| `//` | **Shift Point** - Declares that only variables denoted with a $ are parsed into the $params AFTER this point in the regex |
:::yml
'teams/$Action/$ID/$OtherID': 'TeamController'
# /teams/
# /teams/players/
# /teams/
Standard URL handler syntax. For any URL that contains 'team' this rule will match and hand over execution to the
matching controller. The `TeamsController` is passed an optional action, id and other id parameters to do any more
decision making.
:::yml
'teams/$Action!/$ID!/': 'TeamController'
This does the same matching as the previous example, any URL starting with `teams` will look at this rule **but** both
`$Action` and `$ID` are required. Any requests to `team/` will result in a `404` error rather than being handed off to
the `TeamController`.
:::yml
`admin/help//$Action/$ID`: 'AdminHelp'
Match an url starting with `/admin/help/`, but don't include `/help/` as part of the action (the shift point is set to
start parsing variables and the appropriate controller action AFTER the `//`).
## URL Handlers
In the above example the URLs were configured using the [api:Director] rules in the **routes.yml** file. Alternatively
you can specify these in your Controller class via the **$url_handlers** static array. This array is processed by the
[api:RequestHandler] at runtime once the `Controller` has been matched.
This is useful when you want to provide custom actions for the mapping of `teams/*`. Say for instance we want to respond
`coaches`, and `staff` to the one controller action `payroll`.
**mysite/code/controllers/TeamController.php**
:::php
<?php
class TeamController extends Controller {
private static $allowed_actions = array(
'payroll'
);
private static $url_handlers = array(
'staff/$ID/$Name' => 'payroll'
'coach/$ID/$Name' => 'payroll'
);
The syntax for the `$url_handlers` array users the same pattern matches as the `YAML` configuration rules.
## API Documentation
* [api:Controller]
* [api:Director]

View File

@ -0,0 +1,203 @@
title: Access Control
summary: Define allowed behavior and add permission based checks to your Controllers.
# Access Control
Within your controllers you should declare and restrict what people can see and do to ensure that users cannot run
actions on the website they shouldn't be able to.
## Allowed Actions
Any action you define on a controller must be defined in a `$allowed_actions` static array. This prevents users from
directly calling methods that they shouldn't.
:::php
<?php
class MyController extends Controller {
private static $allowed_actions = array(
// someaction can be accessed by anyone, any time
'someaction',
// So can otheraction
'otheraction' => true,
// restrictedaction can only be people with ADMIN privilege
'restrictedaction' => 'ADMIN',
// restricted to uses that have the 'CMS_ACCESS_CMSMain' access
'cmsrestrictedaction' => 'CMS_ACCESS_CMSMain',
// complexaction can only be accessed if $this->canComplexAction() returns true.
'complexaction' '->canComplexAction'
// complexactioncheck can only be accessed if $this->canComplexAction("MyRestrictedAction", false, 42) is true.
'complexactioncheck' => '->canComplexAction("MyRestrictedAction", false, 42)',
);
}
<div class="info">
If the permission check fails, SilverStripe will return a `403` Forbidden HTTP status.
</div>
An action named "index" is white listed by default, unless `allowed_actions` is defined as an empty array, or the action
is specifically restricted.
:::php
<?php
class MyController extends Controller {
public function index() {
// allowed without an $allowed_action defined
}
}
`$allowed_actions` can be defined on `Extension` classes applying to the controller.
:::php
<?php
class MyExtension extends Extension {
private static $allowed_actions = array(
'mycustomaction'
);
}
Only public methods can be made accessible.
:::php
<?php
class MyController extends Controller {
private static $allowed_actions = array(
'secure',
// secureaction won't work as it's private.
);
public function secure() {
// ..
}
private function secureaction() {
// ..
}
}
If a method on a parent class is overwritten, access control for it has to be redefined as well.
:::php
<?php
class MyController extends Controller {
private static $allowed_actions = array(
'action',
);
public function action() {
// ..
}
}
class MyChildController extends MyController {
private static $allowed_actions = array(
'action', // required as we are redefining action
);
public function action() {
}
}
<div class="notice" markdown="1">
Access checks on parent classes need to be overwritten via the [Configuration API](../configuration).
</div>
## Forms
Form action methods should **not** be included in `$allowed_actions`. However, the form method **should** be included
as an `allowed_action`.
:::php
<?php
class MyController extends Controller {
private static $allowed_actions = array(
'ContactForm' // use the Form method, not the action
);
public function ContactForm() {
return new Form(..);
}
public function doContactForm($data, $form) {
// ..
}
}
## Action Level Checks
Each method responding to a URL can also implement custom permission checks, e.g. to handle responses conditionally on
the passed request data.
:::php
<?php
class MyController extends Controller {
private static $allowed_actions = array(
'myaction'
);
public function myaction($request) {
if(!$request->getVar('apikey')) {
return $this->httpError(403, 'No API key provided');
}
return 'valid';
}
}
<div class="notice" markdown="1">
This is recommended as an addition for `$allowed_actions`, in order to handle more complex checks, rather than a
replacement.
</div>
## Controller Level Checks
After checking for allowed_actions, each controller invokes its `init()` method, which is typically used to set up
common state, If an `init()` method returns a `SS_HTTPResponse` with either a 3xx or 4xx HTTP status code, it'll abort
execution. This behavior can be used to implement permission checks.
<div class="info" markdown="1">
`init` is called for any possible action on the controller and before any specific method such as `index`.
</div>
:::php
<?php
class MyController extends Controller {
private static $allowed_actions = array();
public function init() {
parent::init();
if(!Permission::check('ADMIN')) {
return $this->httpError(403);
}
}
}
## Related Documentation
* [Security](../security)
## API Documentation
* [api:Controller]

View File

@ -0,0 +1,47 @@
title: Redirection
summary: Move users around your site using automatic redirection.
# Redirection
Controllers can facilitate redirecting users from one place to another using `HTTP` redirection using the `Location`
HTTP header.
**mysite/code/Page.php**
:::php
$this->redirect('goherenow');
// redirect to Page::goherenow(), i.e on the contact-us page this will redirect to /contact-us/goherenow/
$this->redirect('goherenow/');
// redirect to the URL on yoursite.com/goherenow/. (note the trailing slash)
$this->redirect('http://google.com');
// redirect to http://google.com
$this->redirectBack();
// go back to the previous page.
## Status Codes
The `redirect()` method takes an optional HTTP status code, either `301` for permanent redirects, or `302` for
temporary redirects (default).
:::php
$this->redirect('/', 302);
// go back to the homepage, don't cache that this page has moved
## Redirection in URL Handling
Controllers can specify redirections in the `$url_handlers` property rather than defining a method by using the '~'
operator.
:::php
private static $url_handlers = array(
'players/john' => '~>coach'
);
For more information on `$url_handlers` see the [Routing](routing) documenation.
## API Documentation
* [api:Controller]

View File

@ -0,0 +1,57 @@
title: Request Filters
summary: Create objects for modifying request and response objects across controllers.
# Request Filters
[api:RequestFilter] is an interface that provides two key methods. `preRequest` and `postRequest`. These methods are
executed before and after a request occurs to give developers a hook to modify any global state, add request tracking or
perform operations wrapped around responses and request objects. A `RequestFilter` is defined as:
**mysite/code/CustomRequestFilter.php**
:::php
<?php
class CustomRequestFilter implements RequestFilter {
public function preRequest(SS_HTTPRequest $request, Session $session, DataModel $model) {
// if(!something) {
// By returning 'false' from the preRequest method, request execution will be stopped from continuing.
// return false;
// }
// we can also set any properties onto the request that we need or add any tracking
// Foo::bar();
// return true to continue processing.
return true;
}
public function postRequest(SS_HTTPRequest $request, SS_HTTPResponse $response, DataModel $model) {
// response is about to be sent.
// any modifications or tracking to be done?
// Foo::unbar();
// return true to send the response.
return true;
}
}
After defining the `RequestFilter`, add it as an allowed `filter` through the [Configuration API](../configuration)
**mysite/_config/app.yml**
:::yml
Injector:
RequestProcessor:
properties:
filters:
- '%$CustomRequestFilter'
## API Documentation
* [api:RequestFilter]
* [api:RequestProcessor]

View File

@ -1,8 +1,23 @@
title: Controllers
summary: Controllers form the backbone of your SilverStripe application. They handle routing URLs to your templates.
introduction: In this guide you will learn how to define a Controller class and how they fit into the SilverStripe response and request cycle.
The [api:Controller] class handles the responsibility of delivering the correct outgoing [api:SS_HTTPResponse] for a
given incoming [api:SS_HTTPRequest]. A request is along the lines of a user requesting the homepage and contains
information like the URL, any parameters and where they've come from. The response on the other hand is the actual
content of the homepage and the HTTP information we want to give back to the user.
Controllers are the main handlers for functionality like interactive forms, rendering the correct templates and
performing and navigating around the permission checks on the users actions.
[CHILDREN]
## How-to
## Related Documentation
[CHILDREN How_To]
* [Execution Pipeline](../execution_pipeline)
## API Documentation
* [api:Controller]
* [api:SS_HTTPRequest]
* [api:SS_HTTPResponse]