CakePHP
  • Documentation
    • Book
    • API
    • Videos
    • Reporting Security Issues
    • Privacy Policy
    • Logos & Trademarks
  • Business Solutions
  • Swag
  • Road Trip
  • Team
  • Community
    • Community
    • Get Involved
    • Issues (GitHub)
    • Bakery
    • Featured Resources
    • Training
    • Meetups
    • My CakePHP
    • CakeFest
    • Newsletter
    • Linkedin
    • YouTube
    • Facebook
    • Twitter
    • Mastodon
    • Help & Support
    • Forum
    • Stack Overflow
    • Slack
    • Paid Support
CakePHP

C CakePHP 2.10 API

  • Overview
  • Tree
  • Deprecated
  • Version:
    • 2.10
      • 4.2
      • 4.1
      • 4.0
      • 3.9
      • 3.8
      • 3.7
      • 3.6
      • 3.5
      • 3.4
      • 3.3
      • 3.2
      • 3.1
      • 3.0
      • 2.10
      • 2.9
      • 2.8
      • 2.7
      • 2.6
      • 2.5
      • 2.4
      • 2.3
      • 2.2
      • 2.1
      • 2.0
      • 1.3
      • 1.2

Packages

  • Cake
    • Cache
      • Engine
    • Configure
    • Console
      • Command
        • Task
    • Controller
      • Component
        • Acl
        • Auth
    • Core
    • Error
    • Event
    • I18n
    • Log
      • Engine
    • Model
      • Behavior
      • Datasource
        • Database
        • Session
      • Validator
    • Network
      • Email
      • Http
    • Routing
      • Filter
      • Route
    • TestSuite
      • Coverage
      • Fixture
      • Reporter
    • Utility
    • View
      • Helper
  • None

Classes

  • CakeErrorController
  • Component
  • ComponentCollection
  • Controller
  • Scaffold
   1: <?php
   2: /**
   3:  * CakePHP(tm) : Rapid Development Framework (https://cakephp.org)
   4:  * Copyright (c) Cake Software Foundation, Inc. (https://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. (https://cakefoundation.org)
  11:  * @link          https://cakephp.org CakePHP(tm) Project
  12:  * @package       Cake.Controller
  13:  * @since         CakePHP(tm) v 0.2.9
  14:  * @license       https://opensource.org/licenses/mit-license.php MIT License
  15:  */
  16: 
  17: App::uses('CakeResponse', 'Network');
  18: App::uses('ClassRegistry', 'Utility');
  19: App::uses('ComponentCollection', 'Controller');
  20: App::uses('View', 'View');
  21: App::uses('CakeEvent', 'Event');
  22: App::uses('CakeEventListener', 'Event');
  23: App::uses('CakeEventManager', 'Event');
  24: 
  25: /**
  26:  * Application controller class for organization of business logic.
  27:  * Provides basic functionality, such as rendering views inside layouts,
  28:  * automatic model availability, redirection, callbacks, and more.
  29:  *
  30:  * Controllers should provide a number of 'action' methods. These are public methods on the controller
  31:  * that are not prefixed with a '_' and not part of Controller. Each action serves as an endpoint for
  32:  * performing a specific action on a resource or collection of resources. For example: adding or editing a new
  33:  * object, or listing a set of objects.
  34:  *
  35:  * You can access request parameters, using `$this->request`. The request object contains all the POST, GET and FILES
  36:  * that were part of the request.
  37:  *
  38:  * After performing the required actions, controllers are responsible for creating a response. This usually
  39:  * takes the form of a generated View, or possibly a redirection to another controller action. In either case
  40:  * `$this->response` allows you to manipulate all aspects of the response.
  41:  *
  42:  * Controllers are created by Dispatcher based on request parameters and routing. By default controllers and actions
  43:  * use conventional names. For example `/posts/index` maps to `PostsController::index()`. You can re-map URLs
  44:  * using Router::connect().
  45:  *
  46:  * @package       Cake.Controller
  47:  * @property      AclComponent $Acl
  48:  * @property      AuthComponent $Auth
  49:  * @property      CookieComponent $Cookie
  50:  * @property      EmailComponent $Email
  51:  * @property      FlashComponent $Flash
  52:  * @property      PaginatorComponent $Paginator
  53:  * @property      RequestHandlerComponent $RequestHandler
  54:  * @property      SecurityComponent $Security
  55:  * @property      SessionComponent $Session
  56:  * @property      string $action  The action handling the current request. Deprecated, use CakeRequest::$action instead.
  57:  * @property      string $base    Base URL path. Deprecated, use CakeRequest::$base instead.
  58:  * @property      array $data     POST data. Deprecated, use CakeRequest::$data instead.
  59:  * @property      string $here    The full address to the current request. Deprecated, use CakeRequest::$here instead.
  60:  * @property      array $paginate Pagination settings.
  61:  * @property      array $params   Array of parameters parsed from the URL. Deprecated, use CakeRequest::$params instead.
  62:  * @property      string $webroot Webroot path segment for the request.
  63:  * @link          https://book.cakephp.org/2.0/en/controllers.html
  64:  */
  65: class Controller extends CakeObject implements CakeEventListener {
  66: 
  67: /**
  68:  * The name of this controller. Controller names are plural, named after the model they manipulate.
  69:  *
  70:  * @var string
  71:  * @link https://book.cakephp.org/2.0/en/controllers.html#controller-attributes
  72:  */
  73:     public $name = null;
  74: 
  75: /**
  76:  * An array containing the class names of models this controller uses.
  77:  *
  78:  * Example: `public $uses = array('Product', 'Post', 'Comment');`
  79:  *
  80:  * Can be set to several values to express different options:
  81:  *
  82:  * - `true` Use the default inflected model name.
  83:  * - `array()` Use only models defined in the parent class.
  84:  * - `false` Use no models at all, do not merge with parent class either.
  85:  * - `array('Post', 'Comment')` Use only the Post and Comment models. Models
  86:  *   Will also be merged with the parent class.
  87:  *
  88:  * The default value is `true`.
  89:  *
  90:  * @var bool|array
  91:  * @link https://book.cakephp.org/2.0/en/controllers.html#components-helpers-and-uses
  92:  */
  93:     public $uses = true;
  94: 
  95: /**
  96:  * An array containing the names of helpers this controller uses. The array elements should
  97:  * not contain the "Helper" part of the class name.
  98:  *
  99:  * Example: `public $helpers = array('Html', 'Js', 'Time', 'Ajax');`
 100:  *
 101:  * @var mixed
 102:  * @link https://book.cakephp.org/2.0/en/controllers.html#components-helpers-and-uses
 103:  */
 104:     public $helpers = array();
 105: 
 106: /**
 107:  * An instance of a CakeRequest object that contains information about the current request.
 108:  * This object contains all the information about a request and several methods for reading
 109:  * additional information about the request.
 110:  *
 111:  * @var CakeRequest
 112:  * @link https://book.cakephp.org/2.0/en/controllers/request-response.html#cakerequest
 113:  */
 114:     public $request;
 115: 
 116: /**
 117:  * An instance of a CakeResponse object that contains information about the impending response
 118:  *
 119:  * @var CakeResponse
 120:  * @link https://book.cakephp.org/2.0/en/controllers/request-response.html#cakeresponse
 121:  */
 122:     public $response;
 123: 
 124: /**
 125:  * The class name to use for creating the response object.
 126:  *
 127:  * @var string
 128:  */
 129:     protected $_responseClass = 'CakeResponse';
 130: 
 131: /**
 132:  * The name of the views subfolder containing views for this controller.
 133:  *
 134:  * @var string
 135:  */
 136:     public $viewPath = null;
 137: 
 138: /**
 139:  * The name of the layouts subfolder containing layouts for this controller.
 140:  *
 141:  * @var string
 142:  */
 143:     public $layoutPath = null;
 144: 
 145: /**
 146:  * Contains variables to be handed to the view.
 147:  *
 148:  * @var array
 149:  */
 150:     public $viewVars = array();
 151: 
 152: /**
 153:  * The name of the view file to render. The name specified
 154:  * is the filename in /app/View/<SubFolder> without the .ctp extension.
 155:  *
 156:  * @var string
 157:  */
 158:     public $view = null;
 159: 
 160: /**
 161:  * The name of the layout file to render the view inside of. The name specified
 162:  * is the filename of the layout in /app/View/Layouts without the .ctp
 163:  * extension. If `false` then no layout is rendered.
 164:  *
 165:  * @var string|bool
 166:  */
 167:     public $layout = 'default';
 168: 
 169: /**
 170:  * Set to true to automatically render the view
 171:  * after action logic.
 172:  *
 173:  * @var bool
 174:  */
 175:     public $autoRender = true;
 176: 
 177: /**
 178:  * Set to true to automatically render the layout around views.
 179:  *
 180:  * @var bool
 181:  */
 182:     public $autoLayout = true;
 183: 
 184: /**
 185:  * Instance of ComponentCollection used to handle callbacks.
 186:  *
 187:  * @var ComponentCollection
 188:  */
 189:     public $Components = null;
 190: 
 191: /**
 192:  * Array containing the names of components this controller uses. Component names
 193:  * should not contain the "Component" portion of the class name.
 194:  *
 195:  * Example: `public $components = array('Session', 'RequestHandler', 'Acl');`
 196:  *
 197:  * @var array
 198:  * @link https://book.cakephp.org/2.0/en/controllers/components.html
 199:  */
 200:     public $components = array('Session', 'Flash');
 201: 
 202: /**
 203:  * The name of the View class this controller sends output to.
 204:  *
 205:  * @var string
 206:  */
 207:     public $viewClass = 'View';
 208: 
 209: /**
 210:  * Instance of the View created during rendering. Won't be set until after
 211:  * Controller::render() is called.
 212:  *
 213:  * @var View
 214:  */
 215:     public $View;
 216: 
 217: /**
 218:  * File extension for view templates. Defaults to CakePHP's conventional ".ctp".
 219:  *
 220:  * @var string
 221:  */
 222:     public $ext = '.ctp';
 223: 
 224: /**
 225:  * Automatically set to the name of a plugin.
 226:  *
 227:  * @var string
 228:  */
 229:     public $plugin = null;
 230: 
 231: /**
 232:  * Used to define methods a controller that will be cached. To cache a
 233:  * single action, the value is set to an array containing keys that match
 234:  * action names and values that denote cache expiration times (in seconds).
 235:  *
 236:  * Example:
 237:  *
 238:  * ```
 239:  * public $cacheAction = array(
 240:  *      'view/23/' => 21600,
 241:  *      'recalled/' => 86400
 242:  *  );
 243:  * ```
 244:  *
 245:  * $cacheAction can also be set to a strtotime() compatible string. This
 246:  * marks all the actions in the controller for view caching.
 247:  *
 248:  * @var mixed
 249:  * @link https://book.cakephp.org/2.0/en/core-libraries/helpers/cache.html#additional-configuration-options
 250:  */
 251:     public $cacheAction = false;
 252: 
 253: /**
 254:  * Holds all params passed and named.
 255:  *
 256:  * @var mixed
 257:  */
 258:     public $passedArgs = array();
 259: 
 260: /**
 261:  * Triggers Scaffolding
 262:  *
 263:  * @var mixed
 264:  * @link https://book.cakephp.org/2.0/en/controllers/scaffolding.html
 265:  */
 266:     public $scaffold = false;
 267: 
 268: /**
 269:  * Holds current methods of the controller. This is a list of all the methods reachable
 270:  * via URL. Modifying this array will allow you to change which methods can be reached.
 271:  *
 272:  * @var array
 273:  */
 274:     public $methods = array();
 275: 
 276: /**
 277:  * This controller's primary model class name, the Inflector::singularize()'ed version of
 278:  * the controller's $name property.
 279:  *
 280:  * Example: For a controller named 'Comments', the modelClass would be 'Comment'
 281:  *
 282:  * @var string
 283:  */
 284:     public $modelClass = null;
 285: 
 286: /**
 287:  * This controller's model key name, an underscored version of the controller's $modelClass property.
 288:  *
 289:  * Example: For a controller named 'ArticleComments', the modelKey would be 'article_comment'
 290:  *
 291:  * @var string
 292:  */
 293:     public $modelKey = null;
 294: 
 295: /**
 296:  * Holds any validation errors produced by the last call of the validateErrors() method.
 297:  * Contains `false` if no validation errors happened.
 298:  *
 299:  * @var array|bool
 300:  */
 301:     public $validationErrors = null;
 302: 
 303: /**
 304:  * The class name of the parent class you wish to merge with.
 305:  * Typically this is AppController, but you may wish to merge vars with a different
 306:  * parent class.
 307:  *
 308:  * @var string
 309:  */
 310:     protected $_mergeParent = 'AppController';
 311: 
 312: /**
 313:  * Instance of the CakeEventManager this controller is using
 314:  * to dispatch inner events.
 315:  *
 316:  * @var CakeEventManager
 317:  */
 318:     protected $_eventManager = null;
 319: 
 320: /**
 321:  * Constructor.
 322:  *
 323:  * @param CakeRequest $request Request object for this controller. Can be null for testing,
 324:  *  but expect that features that use the request parameters will not work.
 325:  * @param CakeResponse $response Response object for this controller.
 326:  */
 327:     public function __construct($request = null, $response = null) {
 328:         if ($this->name === null) {
 329:             $this->name = substr(get_class($this), 0, -10);
 330:         }
 331: 
 332:         if (!$this->viewPath) {
 333:             $this->viewPath = $this->name;
 334:         }
 335: 
 336:         $this->modelClass = Inflector::singularize($this->name);
 337:         $this->modelKey = Inflector::underscore($this->modelClass);
 338:         $this->Components = new ComponentCollection();
 339: 
 340:         $childMethods = get_class_methods($this);
 341:         $parentMethods = get_class_methods('Controller');
 342: 
 343:         $this->methods = array_diff($childMethods, $parentMethods);
 344: 
 345:         if ($request instanceof CakeRequest) {
 346:             $this->setRequest($request);
 347:         }
 348:         if ($response instanceof CakeResponse) {
 349:             $this->response = $response;
 350:         }
 351:         parent::__construct();
 352:     }
 353: 
 354: /**
 355:  * Provides backwards compatibility to avoid problems with empty and isset to alias properties.
 356:  * Lazy loads models using the loadModel() method if declared in $uses
 357:  *
 358:  * @param string $name Property name to check.
 359:  * @return bool
 360:  */
 361:     public function __isset($name) {
 362:         switch ($name) {
 363:             case 'base':
 364:             case 'here':
 365:             case 'webroot':
 366:             case 'data':
 367:             case 'action':
 368:             case 'params':
 369:                 return true;
 370:         }
 371: 
 372:         if (is_array($this->uses)) {
 373:             foreach ($this->uses as $modelClass) {
 374:                 list($plugin, $class) = pluginSplit($modelClass, true);
 375:                 if ($name === $class) {
 376:                     return $this->loadModel($modelClass);
 377:                 }
 378:             }
 379:         }
 380: 
 381:         if ($name === $this->modelClass) {
 382:             list($plugin, $class) = pluginSplit($name, true);
 383:             if (!$plugin) {
 384:                 $plugin = $this->plugin ? $this->plugin . '.' : null;
 385:             }
 386:             return $this->loadModel($plugin . $this->modelClass);
 387:         }
 388: 
 389:         return false;
 390:     }
 391: 
 392: /**
 393:  * Provides backwards compatibility access to the request object properties.
 394:  * Also provides the params alias.
 395:  *
 396:  * @param string $name The name of the requested value
 397:  * @return mixed The requested value for valid variables/aliases else null
 398:  */
 399:     public function __get($name) {
 400:         switch ($name) {
 401:             case 'base':
 402:             case 'here':
 403:             case 'webroot':
 404:             case 'data':
 405:                 return $this->request->{$name};
 406:             case 'action':
 407:                 return isset($this->request->params['action']) ? $this->request->params['action'] : '';
 408:             case 'params':
 409:                 return $this->request;
 410:             case 'paginate':
 411:                 return $this->Components->load('Paginator')->settings;
 412:         }
 413: 
 414:         if (isset($this->{$name})) {
 415:             return $this->{$name};
 416:         }
 417: 
 418:         return null;
 419:     }
 420: 
 421: /**
 422:  * Provides backwards compatibility access for setting values to the request object.
 423:  *
 424:  * @param string $name Property name to set.
 425:  * @param mixed $value Value to set.
 426:  * @return void
 427:  */
 428:     public function __set($name, $value) {
 429:         switch ($name) {
 430:             case 'base':
 431:             case 'here':
 432:             case 'webroot':
 433:             case 'data':
 434:                 $this->request->{$name} = $value;
 435:                 return;
 436:             case 'action':
 437:                 $this->request->params['action'] = $value;
 438:                 return;
 439:             case 'params':
 440:                 $this->request->params = $value;
 441:                 return;
 442:             case 'paginate':
 443:                 $this->Components->load('Paginator')->settings = $value;
 444:                 return;
 445:         }
 446:         $this->{$name} = $value;
 447:     }
 448: 
 449: /**
 450:  * Sets the request objects and configures a number of controller properties
 451:  * based on the contents of the request. The properties that get set are
 452:  *
 453:  * - $this->request - To the $request parameter
 454:  * - $this->plugin - To the $request->params['plugin']
 455:  * - $this->view - To the $request->params['action']
 456:  * - $this->autoLayout - To the false if $request->params['bare']; is set.
 457:  * - $this->autoRender - To false if $request->params['return'] == 1
 458:  * - $this->passedArgs - The the combined results of params['named'] and params['pass]
 459:  *
 460:  * @param CakeRequest $request Request instance.
 461:  * @return void
 462:  */
 463:     public function setRequest(CakeRequest $request) {
 464:         $this->request = $request;
 465:         $this->plugin = isset($request->params['plugin']) ? Inflector::camelize($request->params['plugin']) : null;
 466:         $this->view = isset($request->params['action']) ? $request->params['action'] : null;
 467:         if (isset($request->params['pass']) && isset($request->params['named'])) {
 468:             $this->passedArgs = array_merge($request->params['pass'], $request->params['named']);
 469:         }
 470: 
 471:         if (!empty($request->params['return']) && $request->params['return'] == 1) {
 472:             $this->autoRender = false;
 473:         }
 474:         if (!empty($request->params['bare'])) {
 475:             $this->autoLayout = false;
 476:         }
 477:     }
 478: 
 479: /**
 480:  * Dispatches the controller action. Checks that the action
 481:  * exists and isn't private.
 482:  *
 483:  * @param CakeRequest $request Request instance.
 484:  * @return mixed The resulting response.
 485:  * @throws PrivateActionException When actions are not public or prefixed by _
 486:  * @throws MissingActionException When actions are not defined and scaffolding is
 487:  *    not enabled.
 488:  */
 489:     public function invokeAction(CakeRequest $request) {
 490:         try {
 491:             $method = new ReflectionMethod($this, $request->params['action']);
 492: 
 493:             if ($this->_isPrivateAction($method, $request)) {
 494:                 throw new PrivateActionException(array(
 495:                     'controller' => $this->name . "Controller",
 496:                     'action' => $request->params['action']
 497:                 ));
 498:             }
 499:             return $method->invokeArgs($this, $request->params['pass']);
 500: 
 501:         } catch (ReflectionException $e) {
 502:             if ($this->scaffold !== false) {
 503:                 return $this->_getScaffold($request);
 504:             }
 505:             throw new MissingActionException(array(
 506:                 'controller' => $this->name . "Controller",
 507:                 'action' => $request->params['action']
 508:             ));
 509:         }
 510:     }
 511: 
 512: /**
 513:  * Check if the request's action is marked as private, with an underscore,
 514:  * or if the request is attempting to directly accessing a prefixed action.
 515:  *
 516:  * @param ReflectionMethod $method The method to be invoked.
 517:  * @param CakeRequest $request The request to check.
 518:  * @return bool
 519:  */
 520:     protected function _isPrivateAction(ReflectionMethod $method, CakeRequest $request) {
 521:         $privateAction = (
 522:             $method->name[0] === '_' ||
 523:             !$method->isPublic() ||
 524:             !in_array($method->name, $this->methods)
 525:         );
 526:         $prefixes = array_map('strtolower', Router::prefixes());
 527: 
 528:         if (!$privateAction && !empty($prefixes)) {
 529:             if (empty($request->params['prefix']) && strpos($request->params['action'], '_') > 0) {
 530:                 list($prefix) = explode('_', $request->params['action']);
 531:                 $privateAction = in_array(strtolower($prefix), $prefixes);
 532:             }
 533:         }
 534:         return $privateAction;
 535:     }
 536: 
 537: /**
 538:  * Returns a scaffold object to use for dynamically scaffolded controllers.
 539:  *
 540:  * @param CakeRequest $request Request instance.
 541:  * @return Scaffold
 542:  */
 543:     protected function _getScaffold(CakeRequest $request) {
 544:         return new Scaffold($this, $request);
 545:     }
 546: 
 547: /**
 548:  * Merge components, helpers, and uses vars from
 549:  * Controller::$_mergeParent and PluginAppController.
 550:  *
 551:  * @return void
 552:  */
 553:     protected function _mergeControllerVars() {
 554:         $pluginController = $pluginDot = null;
 555:         $mergeParent = is_subclass_of($this, $this->_mergeParent);
 556:         $pluginVars = array();
 557:         $appVars = array();
 558: 
 559:         if (!empty($this->plugin)) {
 560:             $pluginController = $this->plugin . 'AppController';
 561:             if (!is_subclass_of($this, $pluginController)) {
 562:                 $pluginController = null;
 563:             }
 564:             $pluginDot = $this->plugin . '.';
 565:         }
 566: 
 567:         if ($pluginController) {
 568:             $merge = array('components', 'helpers');
 569:             $this->_mergeVars($merge, $pluginController);
 570:         }
 571: 
 572:         if ($mergeParent || !empty($pluginController)) {
 573:             $appVars = get_class_vars($this->_mergeParent);
 574:             $merge = array('components', 'helpers');
 575:             $this->_mergeVars($merge, $this->_mergeParent, true);
 576:         }
 577: 
 578:         if ($this->uses === null) {
 579:             $this->uses = false;
 580:         }
 581:         if ($this->uses === true) {
 582:             $this->uses = array($pluginDot . $this->modelClass);
 583:         }
 584:         if (is_array($this->uses) && isset($appVars['uses']) && $appVars['uses'] === $this->uses) {
 585:             array_unshift($this->uses, $pluginDot . $this->modelClass);
 586:         }
 587:         if ($pluginController) {
 588:             $pluginVars = get_class_vars($pluginController);
 589:         }
 590:         if ($this->uses !== false) {
 591:             $this->_mergeUses($pluginVars);
 592:             $this->_mergeUses($appVars);
 593:         } else {
 594:             $this->uses = array();
 595:             $this->modelClass = '';
 596:         }
 597:     }
 598: 
 599: /**
 600:  * Helper method for merging the $uses property together.
 601:  *
 602:  * Merges the elements not already in $this->uses into
 603:  * $this->uses.
 604:  *
 605:  * @param array $merge The data to merge in.
 606:  * @return void
 607:  */
 608:     protected function _mergeUses($merge) {
 609:         if (!isset($merge['uses']) || $merge['uses'] === true || !is_array($this->uses)) {
 610:             return;
 611:         }
 612:         $this->uses = array_merge(
 613:             $this->uses,
 614:             array_diff($merge['uses'], $this->uses)
 615:         );
 616:     }
 617: 
 618: /**
 619:  * Returns a list of all events that will fire in the controller during its lifecycle.
 620:  * You can override this function to add your own listener callbacks
 621:  *
 622:  * @return array
 623:  */
 624:     public function implementedEvents() {
 625:         return array(
 626:             'Controller.initialize' => 'beforeFilter',
 627:             'Controller.beforeRender' => 'beforeRender',
 628:             'Controller.beforeRedirect' => array('callable' => 'beforeRedirect', 'passParams' => true),
 629:             'Controller.shutdown' => 'afterFilter'
 630:         );
 631:     }
 632: 
 633: /**
 634:  * Loads Model classes based on the uses property
 635:  * see Controller::loadModel(); for more info.
 636:  * Loads Components and prepares them for initialization.
 637:  *
 638:  * @return mixed true if models found and instance created.
 639:  * @see Controller::loadModel()
 640:  * @link https://book.cakephp.org/2.0/en/controllers.html#Controller::constructClasses
 641:  * @throws MissingModelException
 642:  */
 643:     public function constructClasses() {
 644:         $this->_mergeControllerVars();
 645:         if ($this->uses) {
 646:             $this->uses = (array)$this->uses;
 647:             list(, $this->modelClass) = pluginSplit(reset($this->uses));
 648:         }
 649:         $this->Components->init($this);
 650:         return true;
 651:     }
 652: 
 653: /**
 654:  * Returns the CakeEventManager manager instance that is handling any callbacks.
 655:  * You can use this instance to register any new listeners or callbacks to the
 656:  * controller events, or create your own events and trigger them at will.
 657:  *
 658:  * @return CakeEventManager
 659:  */
 660:     public function getEventManager() {
 661:         if (empty($this->_eventManager)) {
 662:             $this->_eventManager = new CakeEventManager();
 663:             $this->_eventManager->attach($this->Components);
 664:             $this->_eventManager->attach($this);
 665:         }
 666:         return $this->_eventManager;
 667:     }
 668: 
 669: /**
 670:  * Perform the startup process for this controller.
 671:  * Fire the Components and Controller callbacks in the correct order.
 672:  *
 673:  * - Initializes components, which fires their `initialize` callback
 674:  * - Calls the controller `beforeFilter`.
 675:  * - triggers Component `startup` methods.
 676:  *
 677:  * @return void
 678:  * @triggers Controller.initialize $this
 679:  * @triggers Controller.startup $this
 680:  */
 681:     public function startupProcess() {
 682:         $this->getEventManager()->dispatch(new CakeEvent('Controller.initialize', $this));
 683:         $this->getEventManager()->dispatch(new CakeEvent('Controller.startup', $this));
 684:     }
 685: 
 686: /**
 687:  * Perform the various shutdown processes for this controller.
 688:  * Fire the Components and Controller callbacks in the correct order.
 689:  *
 690:  * - triggers the component `shutdown` callback.
 691:  * - calls the Controller's `afterFilter` method.
 692:  *
 693:  * @return void
 694:  * @triggers Controller.shutdown $this
 695:  */
 696:     public function shutdownProcess() {
 697:         $this->getEventManager()->dispatch(new CakeEvent('Controller.shutdown', $this));
 698:     }
 699: 
 700: /**
 701:  * Queries & sets valid HTTP response codes & messages.
 702:  *
 703:  * @param int|array $code If $code is an integer, then the corresponding code/message is
 704:  *        returned if it exists, null if it does not exist. If $code is an array,
 705:  *        then the 'code' and 'message' keys of each nested array are added to the default
 706:  *        HTTP codes. Example:
 707:  *
 708:  *        httpCodes(404); // returns array(404 => 'Not Found')
 709:  *
 710:  *        httpCodes(array(
 711:  *            701 => 'Unicorn Moved',
 712:  *            800 => 'Unexpected Minotaur'
 713:  *        )); // sets these new values, and returns true
 714:  *
 715:  * @return array|null|true Associative array of the HTTP codes as keys, and the message
 716:  *    strings as values, or null of the given $code does not exist.
 717:  * @deprecated 3.0.0 Since 2.4. Will be removed in 3.0. Use CakeResponse::httpCodes().
 718:  */
 719:     public function httpCodes($code = null) {
 720:         return $this->response->httpCodes($code);
 721:     }
 722: 
 723: /**
 724:  * Loads and instantiates models required by this controller.
 725:  * If the model is non existent, it will throw a missing database table error, as CakePHP generates
 726:  * dynamic models for the time being.
 727:  *
 728:  * @param string $modelClass Name of model class to load
 729:  * @param int|string $id Initial ID the instanced model class should have
 730:  * @return bool True if the model was found
 731:  * @throws MissingModelException if the model class cannot be found.
 732:  */
 733:     public function loadModel($modelClass = null, $id = null) {
 734:         if ($modelClass === null) {
 735:             $modelClass = $this->modelClass;
 736:         }
 737: 
 738:         $this->uses = ($this->uses) ? (array)$this->uses : array();
 739:         if (!in_array($modelClass, $this->uses, true)) {
 740:             $this->uses[] = $modelClass;
 741:         }
 742: 
 743:         list($plugin, $modelClass) = pluginSplit($modelClass, true);
 744: 
 745:         $this->{$modelClass} = ClassRegistry::init(array(
 746:             'class' => $plugin . $modelClass, 'alias' => $modelClass, 'id' => $id
 747:         ));
 748:         if (!$this->{$modelClass}) {
 749:             throw new MissingModelException($modelClass);
 750:         }
 751:         return true;
 752:     }
 753: 
 754: /**
 755:  * Redirects to given $url, after turning off $this->autoRender.
 756:  * Script execution is halted after the redirect.
 757:  *
 758:  * @param string|array $url A string or array-based URL pointing to another location within the app,
 759:  *     or an absolute URL
 760:  * @param int|array|null|string $status HTTP status code (eg: 301). Defaults to 302 when null is passed.
 761:  * @param bool $exit If true, exit() will be called after the redirect
 762:  * @return CakeResponse|null
 763:  * @triggers Controller.beforeRedirect $this, array($url, $status, $exit)
 764:  * @link https://book.cakephp.org/2.0/en/controllers.html#Controller::redirect
 765:  */
 766:     public function redirect($url, $status = null, $exit = true) {
 767:         $this->autoRender = false;
 768: 
 769:         if (is_array($status)) {
 770:             extract($status, EXTR_OVERWRITE);
 771:         }
 772:         $event = new CakeEvent('Controller.beforeRedirect', $this, array($url, $status, $exit));
 773: 
 774:         list($event->break, $event->breakOn, $event->collectReturn) = array(true, false, true);
 775:         $this->getEventManager()->dispatch($event);
 776: 
 777:         if ($event->isStopped()) {
 778:             return null;
 779:         }
 780:         $response = $event->result;
 781:         extract($this->_parseBeforeRedirect($response, $url, $status, $exit), EXTR_OVERWRITE);
 782: 
 783:         if ($url !== null) {
 784:             $this->response->header('Location', Router::url($url, true));
 785:         }
 786: 
 787:         if (is_string($status)) {
 788:             $codes = array_flip($this->response->httpCodes());
 789:             if (isset($codes[$status])) {
 790:                 $status = $codes[$status];
 791:             }
 792:         }
 793: 
 794:         if ($status === null) {
 795:             $status = 302;
 796:         }
 797:         $this->response->statusCode($status);
 798: 
 799:         if ($exit) {
 800:             $this->response->send();
 801:             $this->_stop();
 802:         }
 803: 
 804:         return $this->response;
 805:     }
 806: 
 807: /**
 808:  * Parse beforeRedirect Response
 809:  *
 810:  * @param mixed $response Response from beforeRedirect callback
 811:  * @param string|array $url The same value of beforeRedirect
 812:  * @param int $status The same value of beforeRedirect
 813:  * @param bool $exit The same value of beforeRedirect
 814:  * @return array Array with keys url, status and exit
 815:  */
 816:     protected function _parseBeforeRedirect($response, $url, $status, $exit) {
 817:         if (is_array($response) && array_key_exists(0, $response)) {
 818:             foreach ($response as $resp) {
 819:                 if (is_array($resp) && isset($resp['url'])) {
 820:                     extract($resp, EXTR_OVERWRITE);
 821:                 } elseif ($resp !== null) {
 822:                     $url = $resp;
 823:                 }
 824:             }
 825:         } elseif (is_array($response)) {
 826:             extract($response, EXTR_OVERWRITE);
 827:         }
 828:         return compact('url', 'status', 'exit');
 829:     }
 830: 
 831: /**
 832:  * Convenience and object wrapper method for CakeResponse::header().
 833:  *
 834:  * @param string $status The header message that is being set.
 835:  * @return void
 836:  * @deprecated 3.0.0 Will be removed in 3.0. Use CakeResponse::header().
 837:  */
 838:     public function header($status) {
 839:         $this->response->header($status);
 840:     }
 841: 
 842: /**
 843:  * Saves a variable for use inside a view template.
 844:  *
 845:  * @param string|array $one A string or an array of data.
 846:  * @param mixed $two Value in case $one is a string (which then works as the key).
 847:  *   Unused if $one is an associative array, otherwise serves as the values to $one's keys.
 848:  * @return void
 849:  * @link https://book.cakephp.org/2.0/en/controllers.html#interacting-with-views
 850:  */
 851:     public function set($one, $two = null) {
 852:         if (is_array($one)) {
 853:             if (is_array($two)) {
 854:                 $data = array_combine($one, $two);
 855:             } else {
 856:                 $data = $one;
 857:             }
 858:         } else {
 859:             $data = array($one => $two);
 860:         }
 861:         $this->viewVars = $data + $this->viewVars;
 862:     }
 863: 
 864: /**
 865:  * Internally redirects one action to another. Does not perform another HTTP request unlike Controller::redirect()
 866:  *
 867:  * Examples:
 868:  *
 869:  * ```
 870:  * setAction('another_action');
 871:  * setAction('action_with_parameters', $parameter1);
 872:  * ```
 873:  *
 874:  * @param string $action The new action to be 'redirected' to.
 875:  *   Any other parameters passed to this method will be passed as parameters to the new action.
 876:  * @return mixed Returns the return value of the called action
 877:  */
 878:     public function setAction($action) {
 879:         $this->request->params['action'] = $action;
 880:         $this->view = $action;
 881:         $args = func_get_args();
 882:         unset($args[0]);
 883:         return call_user_func_array(array(&$this, $action), $args);
 884:     }
 885: 
 886: /**
 887:  * Returns number of errors in a submitted FORM.
 888:  *
 889:  * @return int Number of errors
 890:  * @deprecated 3.0.0 This method will be removed in 3.0
 891:  */
 892:     public function validate() {
 893:         $args = func_get_args();
 894:         $errors = call_user_func_array(array(&$this, 'validateErrors'), $args);
 895: 
 896:         if ($errors === false) {
 897:             return 0;
 898:         }
 899:         return count($errors);
 900:     }
 901: 
 902: /**
 903:  * Validates models passed by parameters. Takes a list of models as a variable argument.
 904:  * Example:
 905:  *
 906:  * `$errors = $this->validateErrors($this->Article, $this->User);`
 907:  *
 908:  * @return array|false Validation errors, or false if none
 909:  * @deprecated 3.0.0 This method will be removed in 3.0
 910:  */
 911:     public function validateErrors() {
 912:         $objects = func_get_args();
 913: 
 914:         if (empty($objects)) {
 915:             return false;
 916:         }
 917: 
 918:         $errors = array();
 919:         foreach ($objects as $object) {
 920:             if (isset($this->{$object->alias})) {
 921:                 $object = $this->{$object->alias};
 922:             }
 923:             $object->set($object->data);
 924:             $errors = array_merge($errors, $object->invalidFields());
 925:         }
 926: 
 927:         return $this->validationErrors = (!empty($errors) ? $errors : false);
 928:     }
 929: 
 930: /**
 931:  * Instantiates the correct view class, hands it its data, and uses it to render the view output.
 932:  *
 933:  * @param bool|string $view View to use for rendering
 934:  * @param string $layout Layout to use
 935:  * @return CakeResponse A response object containing the rendered view.
 936:  * @triggers Controller.beforeRender $this
 937:  * @link https://book.cakephp.org/2.0/en/controllers.html#Controller::render
 938:  */
 939:     public function render($view = null, $layout = null) {
 940:         $event = new CakeEvent('Controller.beforeRender', $this);
 941:         $this->getEventManager()->dispatch($event);
 942:         if ($event->isStopped()) {
 943:             $this->autoRender = false;
 944:             return $this->response;
 945:         }
 946: 
 947:         if (!empty($this->uses) && is_array($this->uses)) {
 948:             foreach ($this->uses as $model) {
 949:                 list($plugin, $className) = pluginSplit($model);
 950:                 $this->request->params['models'][$className] = compact('plugin', 'className');
 951:             }
 952:         }
 953: 
 954:         $this->View = $this->_getViewObject();
 955: 
 956:         $models = ClassRegistry::keys();
 957:         foreach ($models as $currentModel) {
 958:             $currentObject = ClassRegistry::getObject($currentModel);
 959:             if ($currentObject instanceof Model) {
 960:                 $className = get_class($currentObject);
 961:                 list($plugin) = pluginSplit(App::location($className));
 962:                 $this->request->params['models'][$currentObject->alias] = compact('plugin', 'className');
 963:                 $this->View->validationErrors[$currentObject->alias] =& $currentObject->validationErrors;
 964:             }
 965:         }
 966: 
 967:         $this->autoRender = false;
 968:         $this->response->body($this->View->render($view, $layout));
 969:         return $this->response;
 970:     }
 971: 
 972: /**
 973:  * Returns the referring URL for this request.
 974:  *
 975:  * @param string $default Default URL to use if HTTP_REFERER cannot be read from headers
 976:  * @param bool $local If true, restrict referring URLs to local server
 977:  * @return string Referring URL
 978:  * @link https://book.cakephp.org/2.0/en/controllers.html#Controller::referer
 979:  */
 980:     public function referer($default = null, $local = false) {
 981:         if (!$this->request) {
 982:             return '/';
 983:         }
 984: 
 985:         $referer = $this->request->referer($local);
 986:         if ($referer === '/' && $default && $default !== $referer) {
 987:             return Router::url($default, !$local);
 988:         }
 989:         return $referer;
 990:     }
 991: 
 992: /**
 993:  * Forces the user's browser not to cache the results of the current request.
 994:  *
 995:  * @return void
 996:  * @link https://book.cakephp.org/2.0/en/controllers.html#Controller::disableCache
 997:  * @deprecated 3.0.0 Will be removed in 3.0. Use CakeResponse::disableCache().
 998:  */
 999:     public function disableCache() {
1000:         $this->response->disableCache();
1001:     }
1002: 
1003: /**
1004:  * Shows a message to the user for $pause seconds, then redirects to $url.
1005:  * Uses flash.ctp as the default layout for the message.
1006:  * Does not work if the current debug level is higher than 0.
1007:  *
1008:  * @param string $message Message to display to the user
1009:  * @param string|array $url Relative string or array-based URL to redirect to after the time expires
1010:  * @param int $pause Time to show the message
1011:  * @param string $layout Layout you want to use, defaults to 'flash'
1012:  * @return void
1013:  * @link https://book.cakephp.org/2.0/en/controllers.html#Controller::flash
1014:  * @deprecated 3.0.0 Will be removed in 3.0. Use Flash::set() with version 2.7+ or Session::setFlash() prior to 2.7.
1015:  */
1016:     public function flash($message, $url, $pause = 1, $layout = 'flash') {
1017:         $this->autoRender = false;
1018:         $this->set('url', Router::url($url));
1019:         $this->set('message', $message);
1020:         $this->set('pause', $pause);
1021:         $this->set('pageTitle', $message);
1022:         $this->render(false, $layout);
1023:     }
1024: 
1025: /**
1026:  * Converts POST'ed form data to a model conditions array.
1027:  *
1028:  * If combined with SecurityComponent these conditions could be suitable
1029:  * for use in a Model::find() call. Without SecurityComponent this method
1030:  * is vulnerable creating conditions containing SQL injection. While we
1031:  * attempt to raise exceptions.
1032:  *
1033:  * @param array $data POST'ed data organized by model and field
1034:  * @param string|array $op A string containing an SQL comparison operator, or an array matching operators
1035:  *        to fields
1036:  * @param string $bool SQL boolean operator: AND, OR, XOR, etc.
1037:  * @param bool $exclusive If true, and $op is an array, fields not included in $op will not be
1038:  *        included in the returned conditions
1039:  * @return array|null An array of model conditions
1040:  * @deprecated 3.0.0 Will be removed in 3.0.
1041:  * @throws RuntimeException when unsafe operators are found.
1042:  */
1043:     public function postConditions($data = array(), $op = null, $bool = 'AND', $exclusive = false) {
1044:         if (!is_array($data) || empty($data)) {
1045:             if (!empty($this->request->data)) {
1046:                 $data = $this->request->data;
1047:             } else {
1048:                 return null;
1049:             }
1050:         }
1051:         $cond = array();
1052: 
1053:         if ($op === null) {
1054:             $op = '';
1055:         }
1056: 
1057:         $allowedChars = '#[^a-zA-Z0-9_ ]#';
1058:         $arrayOp = is_array($op);
1059:         foreach ($data as $model => $fields) {
1060:             if (preg_match($allowedChars, $model)) {
1061:                 throw new RuntimeException("Unsafe operator found in {$model}");
1062:             }
1063:             foreach ($fields as $field => $value) {
1064:                 if (preg_match($allowedChars, $field)) {
1065:                     throw new RuntimeException("Unsafe operator found in {$model}.{$field}");
1066:                 }
1067:                 $key = $model . '.' . $field;
1068:                 $fieldOp = $op;
1069:                 if ($arrayOp) {
1070:                     if (array_key_exists($key, $op)) {
1071:                         $fieldOp = $op[$key];
1072:                     } elseif (array_key_exists($field, $op)) {
1073:                         $fieldOp = $op[$field];
1074:                     } else {
1075:                         $fieldOp = false;
1076:                     }
1077:                 }
1078:                 if ($exclusive && $fieldOp === false) {
1079:                     continue;
1080:                 }
1081:                 $fieldOp = strtoupper(trim($fieldOp));
1082:                 if ($fieldOp === 'LIKE') {
1083:                     $key = $key . ' LIKE';
1084:                     $value = '%' . $value . '%';
1085:                 } elseif ($fieldOp && $fieldOp !== '=') {
1086:                     $key = $key . ' ' . $fieldOp;
1087:                 }
1088:                 $cond[$key] = $value;
1089:             }
1090:         }
1091:         if ($bool && strtoupper($bool) !== 'AND') {
1092:             $cond = array($bool => $cond);
1093:         }
1094:         return $cond;
1095:     }
1096: 
1097: /**
1098:  * Handles automatic pagination of model records.
1099:  *
1100:  * @param Model|string $object Model to paginate (e.g: model instance, or 'Model', or 'Model.InnerModel')
1101:  * @param string|array $scope Conditions to use while paginating
1102:  * @param array $whitelist List of allowed options for paging
1103:  * @return array Model query results
1104:  * @link https://book.cakephp.org/2.0/en/controllers.html#Controller::paginate
1105:  */
1106:     public function paginate($object = null, $scope = array(), $whitelist = array()) {
1107:         return $this->Components->load('Paginator', $this->paginate)->paginate($object, $scope, $whitelist);
1108:     }
1109: 
1110: /**
1111:  * Called before the controller action. You can use this method to configure and customize components
1112:  * or perform logic that needs to happen before each controller action.
1113:  *
1114:  * @return void
1115:  * @link https://book.cakephp.org/2.0/en/controllers.html#request-life-cycle-callbacks
1116:  */
1117:     public function beforeFilter() {
1118:     }
1119: 
1120: /**
1121:  * Called after the controller action is run, but before the view is rendered. You can use this method
1122:  * to perform logic or set view variables that are required on every request.
1123:  *
1124:  * @return void
1125:  * @link https://book.cakephp.org/2.0/en/controllers.html#request-life-cycle-callbacks
1126:  */
1127:     public function beforeRender() {
1128:     }
1129: 
1130: /**
1131:  * The beforeRedirect method is invoked when the controller's redirect method is called but before any
1132:  * further action.
1133:  *
1134:  * If this method returns false the controller will not continue on to redirect the request.
1135:  * The $url, $status and $exit variables have same meaning as for the controller's method. You can also
1136:  * return a string which will be interpreted as the URL to redirect to or return associative array with
1137:  * key 'url' and optionally 'status' and 'exit'.
1138:  *
1139:  * @param string|array $url A string or array-based URL pointing to another location within the app,
1140:  *     or an absolute URL
1141:  * @param int $status Optional HTTP status code (eg: 404)
1142:  * @param bool $exit If true, exit() will be called after the redirect
1143:  * @return mixed
1144:  *   false to stop redirection event,
1145:  *   string controllers a new redirection URL or
1146:  *   array with the keys url, status and exit to be used by the redirect method.
1147:  * @link https://book.cakephp.org/2.0/en/controllers.html#request-life-cycle-callbacks
1148:  */
1149:     public function beforeRedirect($url, $status = null, $exit = true) {
1150:     }
1151: 
1152: /**
1153:  * Called after the controller action is run and rendered.
1154:  *
1155:  * @return void
1156:  * @link https://book.cakephp.org/2.0/en/controllers.html#request-life-cycle-callbacks
1157:  */
1158:     public function afterFilter() {
1159:     }
1160: 
1161: /**
1162:  * This method should be overridden in child classes.
1163:  *
1164:  * @param string $method name of method called example index, edit, etc.
1165:  * @return bool Success
1166:  * @link https://book.cakephp.org/2.0/en/controllers.html#callbacks
1167:  */
1168:     public function beforeScaffold($method) {
1169:         return true;
1170:     }
1171: 
1172: /**
1173:  * Alias to beforeScaffold()
1174:  *
1175:  * @param string $method Method name.
1176:  * @return bool
1177:  * @see Controller::beforeScaffold()
1178:  * @deprecated 3.0.0 Will be removed in 3.0.
1179:  */
1180:     protected function _beforeScaffold($method) {
1181:         return $this->beforeScaffold($method);
1182:     }
1183: 
1184: /**
1185:  * This method should be overridden in child classes.
1186:  *
1187:  * @param string $method name of method called either edit or update.
1188:  * @return bool Success
1189:  * @link https://book.cakephp.org/2.0/en/controllers.html#callbacks
1190:  */
1191:     public function afterScaffoldSave($method) {
1192:         return true;
1193:     }
1194: 
1195: /**
1196:  * Alias to afterScaffoldSave()
1197:  *
1198:  * @param string $method Method name.
1199:  * @return bool
1200:  * @see Controller::afterScaffoldSave()
1201:  * @deprecated 3.0.0 Will be removed in 3.0.
1202:  */
1203:     protected function _afterScaffoldSave($method) {
1204:         return $this->afterScaffoldSave($method);
1205:     }
1206: 
1207: /**
1208:  * This method should be overridden in child classes.
1209:  *
1210:  * @param string $method name of method called either edit or update.
1211:  * @return bool Success
1212:  * @link https://book.cakephp.org/2.0/en/controllers.html#callbacks
1213:  */
1214:     public function afterScaffoldSaveError($method) {
1215:         return true;
1216:     }
1217: 
1218: /**
1219:  * Alias to afterScaffoldSaveError()
1220:  *
1221:  * @param string $method Method name.
1222:  * @return bool
1223:  * @see Controller::afterScaffoldSaveError()
1224:  * @deprecated 3.0.0 Will be removed in 3.0.
1225:  */
1226:     protected function _afterScaffoldSaveError($method) {
1227:         return $this->afterScaffoldSaveError($method);
1228:     }
1229: 
1230: /**
1231:  * This method should be overridden in child classes.
1232:  * If not it will render a scaffold error.
1233:  * Method MUST return true in child classes
1234:  *
1235:  * @param string $method name of method called example index, edit, etc.
1236:  * @return bool Success
1237:  * @link https://book.cakephp.org/2.0/en/controllers.html#callbacks
1238:  */
1239:     public function scaffoldError($method) {
1240:         return false;
1241:     }
1242: 
1243: /**
1244:  * Alias to scaffoldError()
1245:  *
1246:  * @param string $method Method name.
1247:  * @return bool
1248:  * @see Controller::scaffoldError()
1249:  * @deprecated 3.0.0 Will be removed in 3.0.
1250:  */
1251:     protected function _scaffoldError($method) {
1252:         return $this->scaffoldError($method);
1253:     }
1254: 
1255: /**
1256:  * Constructs the view class instance based on the controller property
1257:  *
1258:  * @return View
1259:  */
1260:     protected function _getViewObject() {
1261:         $viewClass = $this->viewClass;
1262:         if ($this->viewClass !== 'View') {
1263:             list($plugin, $viewClass) = pluginSplit($viewClass, true);
1264:             $viewClass = $viewClass . 'View';
1265:             App::uses($viewClass, $plugin . 'View');
1266:         }
1267: 
1268:         return new $viewClass($this);
1269:     }
1270: 
1271: }
1272: 
OpenHub
Rackspace
Rackspace
  • Business Solutions
  • Showcase
  • Documentation
  • Book
  • API
  • Videos
  • Reporting Security Issues
  • Privacy Policy
  • Logos & Trademarks
  • Community
  • Get Involved
  • Issues (GitHub)
  • Bakery
  • Featured Resources
  • Training
  • Meetups
  • My CakePHP
  • CakeFest
  • Newsletter
  • Linkedin
  • YouTube
  • Facebook
  • Twitter
  • Mastodon
  • Help & Support
  • Forum
  • Stack Overflow
  • Slack
  • Paid Support

Generated using CakePHP API Docs