Controller.php 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720
  1. <?php
  2. /**
  3. * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
  4. * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
  5. *
  6. * Licensed under The MIT License
  7. * For full copyright and license information, please see the LICENSE.txt
  8. * Redistributions of files must retain the above copyright notice.
  9. *
  10. * @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
  11. * @link http://cakephp.org CakePHP(tm) Project
  12. * @since 0.2.9
  13. * @license http://www.opensource.org/licenses/mit-license.php MIT License
  14. */
  15. namespace Cake\Controller;
  16. use Cake\Controller\Exception\MissingActionException;
  17. use Cake\Controller\Exception\PrivateActionException;
  18. use Cake\Event\Event;
  19. use Cake\Event\EventListener;
  20. use Cake\Event\EventManagerTrait;
  21. use Cake\Log\LogTrait;
  22. use Cake\Model\ModelAwareTrait;
  23. use Cake\Network\Request;
  24. use Cake\Network\Response;
  25. use Cake\ORM\TableRegistry;
  26. use Cake\Routing\RequestActionTrait;
  27. use Cake\Routing\Router;
  28. use Cake\Utility\Inflector;
  29. use Cake\Utility\MergeVariablesTrait;
  30. use Cake\View\ViewVarsTrait;
  31. use LogicException;
  32. /**
  33. * Application controller class for organization of business logic.
  34. * Provides basic functionality, such as rendering views inside layouts,
  35. * automatic model availability, redirection, callbacks, and more.
  36. *
  37. * Controllers should provide a number of 'action' methods. These are public methods on the controller
  38. * that are not prefixed with a '_' and not part of Controller. Each action serves as an endpoint for
  39. * performing a specific action on a resource or collection of resources. For example adding or editing a new
  40. * object, or listing a set of objects.
  41. *
  42. * You can access request parameters, using `$this->request`. The request object contains all the POST, GET and FILES
  43. * that were part of the request.
  44. *
  45. * After performing the required actions, controllers are responsible for creating a response. This usually
  46. * takes the form of a generated View, or possibly a redirection to another controller action. In either case
  47. * `$this->response` allows you to manipulate all aspects of the response.
  48. *
  49. * Controllers are created by Dispatcher based on request parameters and routing. By default controllers and actions
  50. * use conventional names. For example `/posts/index` maps to `PostsController::index()`. You can re-map URLs
  51. * using Router::connect().
  52. *
  53. * ### Life cycle callbacks
  54. *
  55. * CakePHP fires a number of life cycle callbacks during each request. By implementing a method
  56. * you can receive the related events. The available callbacks are:
  57. *
  58. * - `beforeFilter(Event $event)` - Called before each action. This is a good place to
  59. * do general logic that applies to all actions.
  60. * - `beforeRender(Event $event)` - Called before the view is rendered.
  61. * - `beforeRedirect(Cake\Event\Event $event $url, Cake\Network\Response $response)` - Called before
  62. * a redirect is done.
  63. * - `afterFilter(Event $event)` - Called after each action is complete and after the view is rendered.
  64. *
  65. * @property \Cake\Controller\Component\AuthComponent $Auth
  66. * @property \Cake\Controller\Component\CookieComponent $Cookie
  67. * @property \Cake\Controller\Component\CsrfComponent $Csrf
  68. * @property \Cake\Controller\Component\PaginatorComponent $Paginator
  69. * @property \Cake\Controller\Component\RequestHandlerComponent $RequestHandler
  70. * @property \Cake\Controller\Component\SecurityComponent $Security
  71. * @property \Cake\Controller\Component\SessionComponent $Session
  72. * @link http://book.cakephp.org/2.0/en/controllers.html
  73. */
  74. class Controller implements EventListener {
  75. use EventManagerTrait;
  76. use LogTrait;
  77. use MergeVariablesTrait;
  78. use ModelAwareTrait;
  79. use RequestActionTrait;
  80. use ViewVarsTrait;
  81. /**
  82. * The name of this controller. Controller names are plural, named after the model they manipulate.
  83. *
  84. * Set automatically using conventions in Controller::__construct().
  85. *
  86. * @var string
  87. * @link http://book.cakephp.org/2.0/en/controllers.html#controller-attributes
  88. */
  89. public $name = null;
  90. /**
  91. * An array containing the names of helpers this controller uses. The array elements should
  92. * not contain the "Helper" part of the class name.
  93. *
  94. * Example: `public $helpers = ['Form', 'Html', 'Time'];`
  95. *
  96. * @var mixed
  97. * @link http://book.cakephp.org/2.0/en/controllers.html#components-helpers-and-uses
  98. */
  99. public $helpers = array();
  100. /**
  101. * An instance of a Cake\Network\Request object that contains information about the current request.
  102. * This object contains all the information about a request and several methods for reading
  103. * additional information about the request.
  104. *
  105. * @var \Cake\Network\Request
  106. * @link http://book.cakephp.org/2.0/en/controllers/request-response.html#Request
  107. */
  108. public $request;
  109. /**
  110. * An instance of a Response object that contains information about the impending response
  111. *
  112. * @var \Cake\Network\Response
  113. * @link http://book.cakephp.org/2.0/en/controllers/request-response.html#cakeresponse
  114. */
  115. public $response;
  116. /**
  117. * The class name to use for creating the response object.
  118. *
  119. * @var string
  120. */
  121. protected $_responseClass = 'Cake\Network\Response';
  122. /**
  123. * Settings for pagination.
  124. *
  125. * Used to pre-configure pagination preferences for the various
  126. * tables your controller will be paginating.
  127. *
  128. * @var array
  129. * @see \Cake\Controller\Component\PaginatorComponent
  130. */
  131. public $paginate = [];
  132. /**
  133. * Set to true to automatically render the view
  134. * after action logic.
  135. *
  136. * @var bool
  137. */
  138. public $autoRender = true;
  139. /**
  140. * Instance of ComponentRegistry used to create Components
  141. *
  142. * @var \Cake\Controller\ComponentRegistry
  143. */
  144. protected $_components = null;
  145. /**
  146. * Array containing the names of components this controller uses. Component names
  147. * should not contain the "Component" portion of the class name.
  148. *
  149. * Example: `public $components = array('Session', 'RequestHandler', 'Acl');`
  150. *
  151. * @var array
  152. * @link http://book.cakephp.org/2.0/en/controllers/components.html
  153. */
  154. public $components = array();
  155. /**
  156. * The name of the View class this controller sends output to.
  157. *
  158. * @var string
  159. */
  160. public $viewClass = 'Cake\View\View';
  161. /**
  162. * The path to this controllers view templates.
  163. * Example `Articles`
  164. *
  165. * Set automatically using conventions in Controller::__construct().
  166. *
  167. * @var string
  168. */
  169. public $viewPath;
  170. /**
  171. * The name of the view file to render. The name specified
  172. * is the filename in /app/Template/<SubFolder> without the .ctp extension.
  173. *
  174. * @var string
  175. */
  176. public $view = null;
  177. /**
  178. * Instance of the View created during rendering. Won't be set until after
  179. * Controller::render() is called.
  180. *
  181. * @var \Cake\View\View
  182. */
  183. public $View;
  184. /**
  185. * These Controller properties will be passed from the Controller to the View as options.
  186. *
  187. * @var array
  188. * @see \Cake\View\View
  189. */
  190. protected $_validViewOptions = [
  191. 'viewVars', 'autoLayout', 'helpers', 'view', 'layout', 'name', 'theme', 'layoutPath',
  192. 'viewPath', 'plugin', 'passedArgs'
  193. ];
  194. /**
  195. * Automatically set to the name of a plugin.
  196. *
  197. * @var string
  198. */
  199. public $plugin = null;
  200. /**
  201. * Holds all passed params.
  202. *
  203. * @var mixed
  204. */
  205. public $passedArgs = array();
  206. /**
  207. * Holds current methods of the controller. This is a list of all the methods reachable
  208. * via URL. Modifying this array, will allow you to change which methods can be reached.
  209. *
  210. * @var array
  211. */
  212. public $methods = array();
  213. /**
  214. * Constructor.
  215. *
  216. * Sets a number of properties based on conventions if they are empty. To override the
  217. * conventions CakePHP uses you can define properties in your class declaration.
  218. *
  219. * @param \Cake\Network\Request $request Request object for this controller. Can be null for testing,
  220. * but expect that features that use the request parameters will not work.
  221. * @param \Cake\Network\Response $response Response object for this controller.
  222. * @param string $name Override the name useful in testing when using mocks.
  223. * @param \Cake\Event\EventManager $eventManager The event manager. Defaults to a new instance.
  224. */
  225. public function __construct(Request $request = null, Response $response = null, $name = null, $eventManager = null) {
  226. if ($this->name === null && $name === null) {
  227. list(, $name) = namespaceSplit(get_class($this));
  228. $name = substr($name, 0, -10);
  229. }
  230. if ($name !== null) {
  231. $this->name = $name;
  232. }
  233. if (!$this->viewPath) {
  234. $viewPath = $this->name;
  235. if (isset($request->params['prefix'])) {
  236. $viewPath = Inflector::camelize($request->params['prefix']) . DS . $viewPath;
  237. }
  238. $this->viewPath = $viewPath;
  239. }
  240. $childMethods = get_class_methods($this);
  241. $baseMethods = get_class_methods('Cake\Controller\Controller');
  242. $this->methods = array_diff($childMethods, $baseMethods);
  243. if ($request instanceof Request) {
  244. $this->setRequest($request);
  245. }
  246. if ($response instanceof Response) {
  247. $this->response = $response;
  248. }
  249. if ($eventManager) {
  250. $this->eventManager($eventManager);
  251. }
  252. $this->modelFactory('Table', ['Cake\ORM\TableRegistry', 'get']);
  253. $modelClass = ($this->plugin ? $this->plugin . '.' : '') . $this->name;
  254. $this->_setModelClass($modelClass);
  255. $this->initialize();
  256. $this->_mergeControllerVars();
  257. $this->_loadComponents();
  258. $this->eventManager()->attach($this);
  259. }
  260. /**
  261. * Initialization hook method.
  262. *
  263. * Implement this method to avoid having to overwrite
  264. * the constructor and call parent.
  265. *
  266. * @return void
  267. */
  268. public function initialize() {
  269. }
  270. /**
  271. * Get the component registry for this controller.
  272. *
  273. * @return \Cake\Controller\ComponentRegistry
  274. */
  275. public function components() {
  276. if ($this->_components === null) {
  277. $this->_components = new ComponentRegistry($this);
  278. }
  279. return $this->_components;
  280. }
  281. /**
  282. * Add a component to the controller's registry.
  283. *
  284. * This method will also set the component to a property.
  285. * For example:
  286. *
  287. * `$this->addComponent('Acl.Acl');`
  288. *
  289. * Will result in a `Toolbar` property being set.
  290. *
  291. * @param string $name The name of the component to load.
  292. * @param array $config The config for the component.
  293. * @return \Cake\Controller\Component
  294. */
  295. public function addComponent($name, array $config = []) {
  296. list(, $prop) = pluginSplit($name);
  297. $this->{$prop} = $this->components()->load($name, $config);
  298. return $this->{$prop};
  299. }
  300. /**
  301. * Magic accessor for model autoloading.
  302. *
  303. * @param string $name Property name
  304. * @return bool
  305. */
  306. public function __get($name) {
  307. list($plugin, $class) = pluginSplit($this->modelClass, true);
  308. if ($class === $name) {
  309. $this->loadModel($plugin . $class);
  310. return $this->{$class};
  311. }
  312. return false;
  313. }
  314. /**
  315. * Sets the request objects and configures a number of controller properties
  316. * based on the contents of the request. Controller acts as a proxy for certain View variables
  317. * which must also be updated here. The properties that get set are:
  318. *
  319. * - $this->request - To the $request parameter
  320. * - $this->plugin - To the $request->params['plugin']
  321. * - $this->autoRender - To false if $request->params['return'] == 1
  322. * - $this->passedArgs - The the combined results of params['named'] and params['pass]
  323. * - View::$passedArgs - $this->passedArgs
  324. * - View::$plugin - $this->plugin
  325. * - View::$view - To the $request->params['action']
  326. * - View::$autoLayout - To the false if $request->params['bare']; is set.
  327. *
  328. * @param \Cake\Network\Request $request Request instance.
  329. * @return void
  330. */
  331. public function setRequest(Request $request) {
  332. $this->request = $request;
  333. $this->plugin = isset($request->params['plugin']) ? $request->params['plugin'] : null;
  334. $this->view = isset($request->params['action']) ? $request->params['action'] : null;
  335. if (isset($request->params['pass'])) {
  336. $this->passedArgs = $request->params['pass'];
  337. }
  338. if (!empty($request->params['return']) && $request->params['return'] == 1) {
  339. $this->autoRender = false;
  340. }
  341. if (!empty($request->params['bare'])) {
  342. $this->autoLayout = false;
  343. }
  344. }
  345. /**
  346. * Dispatches the controller action. Checks that the action
  347. * exists and isn't private.
  348. *
  349. * @return mixed The resulting response.
  350. * @throws \LogicException When request is not set.
  351. * @throws \Cake\Controller\Exception\PrivateActionException When actions are not public or prefixed by _
  352. * @throws \Cake\Controller\Exception\MissingActionException When actions are not defined.
  353. */
  354. public function invokeAction() {
  355. try {
  356. $request = $this->request;
  357. if (!isset($request)) {
  358. throw new LogicException('No Request object configured. Cannot invoke action');
  359. }
  360. $method = new \ReflectionMethod($this, $request->params['action']);
  361. if ($this->_isPrivateAction($method, $request)) {
  362. throw new PrivateActionException(array(
  363. 'controller' => $this->name . "Controller",
  364. 'action' => $request->params['action'],
  365. 'prefix' => isset($request->params['prefix']) ? $request->params['prefix'] : '',
  366. 'plugin' => $request->params['plugin'],
  367. ));
  368. }
  369. return $method->invokeArgs($this, $request->params['pass']);
  370. } catch (\ReflectionException $e) {
  371. throw new MissingActionException(array(
  372. 'controller' => $this->name . "Controller",
  373. 'action' => $request->params['action'],
  374. 'prefix' => isset($request->params['prefix']) ? $request->params['prefix'] : '',
  375. 'plugin' => $request->params['plugin'],
  376. ));
  377. }
  378. }
  379. /**
  380. * Check if the request's action is a public method.
  381. *
  382. * @param \ReflectionMethod $method The method to be invoked.
  383. * @return bool
  384. */
  385. protected function _isPrivateAction(\ReflectionMethod $method) {
  386. return (
  387. !$method->isPublic() ||
  388. !in_array($method->name, $this->methods)
  389. );
  390. }
  391. /**
  392. * Merge components, helpers vars from
  393. * parent classes.
  394. *
  395. * @return void
  396. */
  397. protected function _mergeControllerVars() {
  398. $this->_mergeVars(
  399. ['components', 'helpers'],
  400. ['associative' => ['components', 'helpers']]
  401. );
  402. }
  403. /**
  404. * Returns a list of all events that will fire in the controller during it's lifecycle.
  405. * You can override this function to add you own listener callbacks
  406. *
  407. * @return array
  408. */
  409. public function implementedEvents() {
  410. return array(
  411. 'Controller.initialize' => 'beforeFilter',
  412. 'Controller.beforeRender' => 'beforeRender',
  413. 'Controller.beforeRedirect' => 'beforeRedirect',
  414. 'Controller.shutdown' => 'afterFilter',
  415. );
  416. }
  417. /**
  418. * No-op for backwards compatibility.
  419. *
  420. * The code that used to live here is now in Controller::__construct().
  421. *
  422. * @deprecated 3.0.0 Will be removed in 3.0.0.
  423. * @return void
  424. */
  425. public function constructClasses() {
  426. trigger_error(
  427. 'Controller::constructClasses() is deprecated and will be removed in the first RC release',
  428. E_USER_DEPRECATED
  429. );
  430. }
  431. /**
  432. * Loads the defined components using the Component factory.
  433. *
  434. * @return void
  435. */
  436. protected function _loadComponents() {
  437. if (empty($this->components)) {
  438. return;
  439. }
  440. $registry = $this->components();
  441. $components = $registry->normalizeArray($this->components);
  442. foreach ($components as $properties) {
  443. list(, $class) = pluginSplit($properties['class']);
  444. $this->{$class} = $registry->load($properties['class'], $properties['config']);
  445. }
  446. }
  447. /**
  448. * Perform the startup process for this controller.
  449. * Fire the Components and Controller callbacks in the correct order.
  450. *
  451. * - Initializes components, which fires their `initialize` callback
  452. * - Calls the controller `beforeFilter`.
  453. * - triggers Component `startup` methods.
  454. *
  455. * @return void|\Cake\Network\Response
  456. */
  457. public function startupProcess() {
  458. $event = $this->dispatchEvent('Controller.initialize');
  459. if ($event->result instanceof Response) {
  460. return $event->result;
  461. }
  462. $event = $this->dispatchEvent('Controller.startup');
  463. if ($event->result instanceof Response) {
  464. return $event->result;
  465. }
  466. }
  467. /**
  468. * Perform the various shutdown processes for this controller.
  469. * Fire the Components and Controller callbacks in the correct order.
  470. *
  471. * - triggers the component `shutdown` callback.
  472. * - calls the Controller's `afterFilter` method.
  473. *
  474. * @return void|\Cake\Network\Response
  475. */
  476. public function shutdownProcess() {
  477. $event = $this->dispatchEvent('Controller.shutdown');
  478. if ($event->result instanceof Response) {
  479. return $event->result;
  480. }
  481. }
  482. /**
  483. * Redirects to given $url, after turning off $this->autoRender.
  484. * Script execution is halted after the redirect.
  485. *
  486. * @param string|array $url A string or array-based URL pointing to another location within the app,
  487. * or an absolute URL
  488. * @param int $status Optional HTTP status code (eg: 404)
  489. * @return void|\Cake\Network\Response
  490. * @link http://book.cakephp.org/3.0/en/controllers.html#Controller::redirect
  491. */
  492. public function redirect($url, $status = null) {
  493. $this->autoRender = false;
  494. $response = $this->response;
  495. if ($status && $response->statusCode() === 200) {
  496. $response->statusCode($status);
  497. }
  498. $event = $this->dispatchEvent('Controller.beforeRedirect', [$url, $response]);
  499. if ($event->result instanceof Response) {
  500. return $event->result;
  501. }
  502. if ($event->isStopped()) {
  503. return;
  504. }
  505. if ($url !== null && !$response->location()) {
  506. $response->location(Router::url($url, true));
  507. }
  508. return $response;
  509. }
  510. /**
  511. * Internally redirects one action to another. Does not perform another HTTP request unlike Controller::redirect()
  512. *
  513. * Examples:
  514. *
  515. * {{{
  516. * setAction('another_action');
  517. * setAction('action_with_parameters', $parameter1);
  518. * }}}
  519. *
  520. * @param string $action The new action to be 'redirected' to.
  521. * Any other parameters passed to this method will be passed as parameters to the new action.
  522. * @return mixed Returns the return value of the called action
  523. */
  524. public function setAction($action) {
  525. $this->request->params['action'] = $action;
  526. $this->view = $action;
  527. $args = func_get_args();
  528. unset($args[0]);
  529. return call_user_func_array(array(&$this, $action), $args);
  530. }
  531. /**
  532. * Instantiates the correct view class, hands it its data, and uses it to render the view output.
  533. *
  534. * @param string $view View to use for rendering
  535. * @param string $layout Layout to use
  536. * @return \Cake\Network\Response A response object containing the rendered view.
  537. * @link http://book.cakephp.org/2.0/en/controllers.html#Controller::render
  538. */
  539. public function render($view = null, $layout = null) {
  540. $event = $this->dispatchEvent('Controller.beforeRender');
  541. if ($event->result instanceof Response) {
  542. $this->autoRender = false;
  543. return $event->result;
  544. }
  545. if ($event->isStopped()) {
  546. $this->autoRender = false;
  547. return $this->response;
  548. }
  549. $this->View = $this->createView();
  550. $this->autoRender = false;
  551. $this->response->body($this->View->render($view, $layout));
  552. return $this->response;
  553. }
  554. /**
  555. * Returns the referring URL for this request.
  556. *
  557. * @param string $default Default URL to use if HTTP_REFERER cannot be read from headers
  558. * @param bool $local If true, restrict referring URLs to local server
  559. * @return string Referring URL
  560. * @link http://book.cakephp.org/2.0/en/controllers.html#Controller::referer
  561. */
  562. public function referer($default = null, $local = false) {
  563. if (!$this->request) {
  564. return '/';
  565. }
  566. $referer = $this->request->referer($local);
  567. if ($referer === '/' && $default) {
  568. return Router::url($default, !$local);
  569. }
  570. return $referer;
  571. }
  572. /**
  573. * Handles pagination of records in Table objects.
  574. *
  575. * Will load the referenced Table object, and have the PaginatorComponent
  576. * paginate the query using the request date and settings defined in `$this->paginate`.
  577. *
  578. * This method will also make the PaginatorHelper available in the view.
  579. *
  580. * @param \Cake\ORM\Table|string|\Cake\ORM\Query $object Table to paginate
  581. * (e.g: Table instance, 'TableName' or a Query object)
  582. * @return \Cake\ORM\ResultSet Query results
  583. * @link http://book.cakephp.org/3.0/en/controllers.html#Controller::paginate
  584. * @throws \RuntimeException When no compatible table object can be found.
  585. */
  586. public function paginate($object = null) {
  587. if (is_object($object)) {
  588. $table = $object;
  589. }
  590. if (is_string($object) || $object === null) {
  591. $try = [$object, $this->modelClass];
  592. foreach ($try as $tableName) {
  593. if (empty($tableName)) {
  594. continue;
  595. }
  596. $table = TableRegistry::get($tableName);
  597. break;
  598. }
  599. }
  600. $this->addComponent('Paginator');
  601. if (
  602. !in_array('Paginator', $this->helpers) &&
  603. !array_key_exists('Paginator', $this->helpers)
  604. ) {
  605. $this->helpers[] = 'Paginator';
  606. }
  607. if (empty($table)) {
  608. throw new \RuntimeException('Unable to locate an object compatible with paginate.');
  609. }
  610. return $this->Paginator->paginate($table, $this->paginate);
  611. }
  612. /**
  613. * Called before the controller action. You can use this method to configure and customize components
  614. * or perform logic that needs to happen before each controller action.
  615. *
  616. * @param Event $event An Event instance
  617. * @return void
  618. * @link http://book.cakephp.org/2.0/en/controllers.html#request-life-cycle-callbacks
  619. */
  620. public function beforeFilter(Event $event) {
  621. }
  622. /**
  623. * Called after the controller action is run, but before the view is rendered. You can use this method
  624. * to perform logic or set view variables that are required on every request.
  625. *
  626. * @param Event $event An Event instance
  627. * @return void
  628. * @link http://book.cakephp.org/2.0/en/controllers.html#request-life-cycle-callbacks
  629. */
  630. public function beforeRender(Event $event) {
  631. }
  632. /**
  633. * The beforeRedirect method is invoked when the controller's redirect method is called but before any
  634. * further action.
  635. *
  636. * If the event is stopped the controller will not continue on to redirect the request.
  637. * The $url and $status variables have same meaning as for the controller's method.
  638. * You can set the event result to response instance or modify the redirect location
  639. * using controller's response instance.
  640. *
  641. * @param Event $event An Event instance
  642. * @param string|array $url A string or array-based URL pointing to another location within the app,
  643. * or an absolute URL
  644. * @param \Cake\Network\Response $response The response object.
  645. * @return void
  646. * @link http://book.cakephp.org/2.0/en/controllers.html#request-life-cycle-callbacks
  647. */
  648. public function beforeRedirect(Event $event, $url, Response $response) {
  649. }
  650. /**
  651. * Called after the controller action is run and rendered.
  652. *
  653. * @param Event $event An Event instance
  654. * @return void
  655. * @link http://book.cakephp.org/2.0/en/controllers.html#request-life-cycle-callbacks
  656. */
  657. public function afterFilter(Event $event) {
  658. }
  659. }