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 1.2
14 * @license       https://opensource.org/licenses/mit-license.php MIT License
15 */
16
17App::uses('ComponentCollection', 'Controller');
18
19/**
20 * Base class for an individual Component. Components provide reusable bits of
21 * controller logic that can be composed into a controller. Components also
22 * provide request life-cycle callbacks for injecting logic at specific points.
23 *
24 * ## Life cycle callbacks
25 *
26 * Components can provide several callbacks that are fired at various stages of the request
27 * cycle. The available callbacks are:
28 *
29 * - `initialize()` - Fired before the controller's beforeFilter method.
30 * - `startup()` - Fired after the controller's beforeFilter method.
31 * - `beforeRender()` - Fired before the view + layout are rendered.
32 * - `shutdown()` - Fired after the action is complete and the view has been rendered
33 *    but before Controller::afterFilter().
34 * - `beforeRedirect()` - Fired before a redirect() is done.
35 *
36 * @package       Cake.Controller
37 * @link          https://book.cakephp.org/2.0/en/controllers/components.html
38 * @see Controller::$components
39 */
40class Component extends CakeObject {
41
42/**
43 * Component collection class used to lazy load components.
44 *
45 * @var ComponentCollection
46 */
47	protected $_Collection;
48
49/**
50 * Settings for this Component
51 *
52 * @var array
53 */
54	public $settings = array();
55
56/**
57 * Other Components this component uses.
58 *
59 * @var array
60 */
61	public $components = array();
62
63/**
64 * A component lookup table used to lazy load component objects.
65 *
66 * @var array
67 */
68	protected $_componentMap = array();
69
70/**
71 * Constructor
72 *
73 * @param ComponentCollection $collection A ComponentCollection this component can use to lazy load its components
74 * @param array $settings Array of configuration settings.
75 */
76	public function __construct(ComponentCollection $collection, $settings = array()) {
77		$this->_Collection = $collection;
78		$this->settings = $settings;
79		$this->_set($settings);
80		if (!empty($this->components)) {
81			$this->_componentMap = ComponentCollection::normalizeObjectArray($this->components);
82		}
83	}
84
85/**
86 * Magic method for lazy loading $components.
87 *
88 * @param string $name Name of component to get.
89 * @return mixed A Component object or null.
90 */
91	public function __get($name) {
92		if (isset($this->_componentMap[$name]) && !isset($this->{$name})) {
93			$settings = (array)$this->_componentMap[$name]['settings'] + array('enabled' => false);
94			$this->{$name} = $this->_Collection->load($this->_componentMap[$name]['class'], $settings);
95		}
96		if (isset($this->{$name})) {
97			return $this->{$name};
98		}
99	}
100
101/**
102 * Called before the Controller::beforeFilter().
103 *
104 * @param Controller $controller Controller with components to initialize
105 * @return void
106 * @link https://book.cakephp.org/2.0/en/controllers/components.html#Component::initialize
107 */
108	public function initialize(Controller $controller) {
109	}
110
111/**
112 * Called after the Controller::beforeFilter() and before the controller action
113 *
114 * @param Controller $controller Controller with components to startup
115 * @return void
116 * @link https://book.cakephp.org/2.0/en/controllers/components.html#Component::startup
117 */
118	public function startup(Controller $controller) {
119	}
120
121/**
122 * Called before the Controller::beforeRender(), and before
123 * the view class is loaded, and before Controller::render()
124 *
125 * @param Controller $controller Controller with components to beforeRender
126 * @return void
127 * @link https://book.cakephp.org/2.0/en/controllers/components.html#Component::beforeRender
128 */
129	public function beforeRender(Controller $controller) {
130	}
131
132/**
133 * Called after Controller::render() and before the output is printed to the browser.
134 *
135 * @param Controller $controller Controller with components to shutdown
136 * @return void
137 * @link https://book.cakephp.org/2.0/en/controllers/components.html#Component::shutdown
138 */
139	public function shutdown(Controller $controller) {
140	}
141
142/**
143 * Called before Controller::redirect(). Allows you to replace the URL that will
144 * be redirected to with a new URL. The return of this method can either be an array or a string.
145 *
146 * If the return is an array and contains a 'url' key. You may also supply the following:
147 *
148 * - `status` The status code for the redirect
149 * - `exit` Whether or not the redirect should exit.
150 *
151 * If your response is a string or an array that does not contain a 'url' key it will
152 * be used as the new URL to redirect to.
153 *
154 * @param Controller $controller Controller with components to beforeRedirect
155 * @param string|array $url Either the string or URL array that is being redirected to.
156 * @param int $status The status code of the redirect
157 * @param bool $exit Will the script exit.
158 * @return array|null Either an array or null.
159 * @link https://book.cakephp.org/2.0/en/controllers/components.html#Component::beforeRedirect
160 */
161	public function beforeRedirect(Controller $controller, $url, $status = null, $exit = true) {
162	}
163
164}
165