Controller.php 23 KB

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