Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Newer
Older
100644 271 lines (248 sloc) 10.465 kB
e7f3c31 @gwoo going lithium
gwoo authored
1 <?php
2 /**
3 * Lithium: the most rad php framework
4 *
14de7bf @gwoo Happy 2012!
gwoo authored
5 * @copyright Copyright 2012, Union of RAD (http://union-of-rad.org)
e7f3c31 @gwoo going lithium
gwoo authored
6 * @license http://opensource.org/licenses/bsd-license.php The BSD License
7 */
8
9 namespace lithium\core;
10
a12db0c @nateabele Making `\core\Libraries::instance()` filterable, and refactoring `\co…
nateabele authored
11 use lithium\core\Libraries;
6fb3f64 @daschl change _use lithium_ commands and remove the prefixed slash
daschl authored
12 use lithium\util\collection\Filters;
e7f3c31 @gwoo going lithium
gwoo authored
13
14 /**
00ad303 @nateabele Updating documentation for `\core\Object` and `\core\StaticObject`.
nateabele authored
15 * Base class in Lithium's hierarchy, from which all concrete classes inherit. This class defines
3c2bc5d @nateabele Adding, updating and fixing documentation in `\core\Object`.
nateabele authored
16 * several conventions for how classes in Lithium should be structured:
e7f3c31 @gwoo going lithium
gwoo authored
17 *
3c2bc5d @nateabele Adding, updating and fixing documentation in `\core\Object`.
nateabele authored
18 * - **Universal constructor**: Any class which defines a `__construct()` method should take
19 * exactly one parameter (`$config`), and that parameter should always be an array. Any settings
20 * passed to the constructor will be stored in the `$_config` property of the object.
21 * - **Initialization / automatic configuration**: After the constructor, the `_init()` method is
22 * called. This method can be used to initialize the object, keeping complex logic and
23 * high-overhead or difficult to test operations out of the constructor. This method is called
24 * automatically by `Object::__construct()`, but may be disabled by passing `'init' => false` to
25 * the constructor. The initializer is also used for automatically assigning object properties.
e282896 @Ciaro Fixed some typos in the docblocks of core/Object
Ciaro authored
26 * See the documentation on the `_init()` method for more details.
3c2bc5d @nateabele Adding, updating and fixing documentation in `\core\Object`.
nateabele authored
27 * - **Filters**: The `Object` class implements two methods which allow an object to easily
28 * implement filterable methods. The `_filter()` method allows methods to be implemented as
29 * filterable, and the `applyFilter()` method allows filters to be wrapped around them.
30 * - **Testing / misc.**: The `__set_state()` method provides a default implementation of the PHP
31 * magic method (works with `var_export()`) which can instantiate an object with a static method
32 * call. Finally, the `_stop()` method may be used instead of `exit()`, as it can be overridden
33 * for testing purposes.
00ad303 @nateabele Updating documentation for `\core\Object` and `\core\StaticObject`.
nateabele authored
34 *
35 * @see lithium\core\StaticObject
e7f3c31 @gwoo going lithium
gwoo authored
36 */
37 class Object {
38
39 /**
40 * Stores configuration information for object instances at time of construction.
41 * **Do not override.** Pass any additional variables to `parent::__construct()`.
42 *
43 * @var array
44 */
45 protected $_config = array();
46
188aff6 @niel New docblocks.
niel authored
47 /**
3c2bc5d @nateabele Adding, updating and fixing documentation in `\core\Object`.
nateabele authored
48 * Holds an array of values that should be processed on initialization. Each value should have
49 * a matching protected property (prefixed with `_`) defined in the class. If the property is
50 * an array, the property name should be the key and the value should be `'merge'`. See the
51 * `_init()` method for more details.
188aff6 @niel New docblocks.
niel authored
52 *
3c2bc5d @nateabele Adding, updating and fixing documentation in `\core\Object`.
nateabele authored
53 * @see lithium\core\Object::_init()
188aff6 @niel New docblocks.
niel authored
54 * @var array
55 */
e7f3c31 @gwoo going lithium
gwoo authored
56 protected $_autoConfig = array();
57
3c2bc5d @nateabele Adding, updating and fixing documentation in `\core\Object`.
nateabele authored
58 /**
59 * Contains a 2-dimensional array of filters applied to this object's methods, indexed by method
60 * name. See the associated methods for more details.
61 *
62 * @see lithium\core\Object::_filter()
63 * @see lithium\core\Object::applyFilter()
64 * @var array
65 */
e7f3c31 @gwoo going lithium
gwoo authored
66 protected $_methodFilters = array();
67
b0c7ef6 Docblocks for lithium\core.
psychic authored
68 /**
69 * Parents of the current class.
70 *
71 * @see lithium\core\Object::_parents()
72 * @var array
73 */
e7f3c31 @gwoo going lithium
gwoo authored
74 protected static $_parents = array();
75
188aff6 @niel New docblocks.
niel authored
76 /**
3236a9d @nateabele Adding clarifying documentation to `\core\Object::__construct()`.
nateabele authored
77 * Initializes class configuration (`$_config`), and assigns object properties using the
a2603d2 @nateabele Amending previous commit.
nateabele authored
78 * `_init()` method, unless otherwise specified by configuration. See below for details.
188aff6 @niel New docblocks.
niel authored
79 *
3236a9d @nateabele Adding clarifying documentation to `\core\Object::__construct()`.
nateabele authored
80 * @see lithium\core\Object::$_config
81 * @see lithium\core\Object::_init()
3c2bc5d @nateabele Adding, updating and fixing documentation in `\core\Object`.
nateabele authored
82 * @param array $config The configuration options which will be assigned to the `$_config`
83 * property. This method accepts one configuration option:
84 * - `'init'` _boolean_: Controls constructor behavior for calling the `_init()`
85 * method. If `false`, the method is not called, otherwise it is. Defaults to
86 * `true`.
188aff6 @niel New docblocks.
niel authored
87 */
f80098d @nateabele Adding type hinting to constructor `$config` arrays and all applicabl…
nateabele authored
88 public function __construct(array $config = array()) {
e7f3c31 @gwoo going lithium
gwoo authored
89 $defaults = array('init' => true);
3c2bc5d @nateabele Adding, updating and fixing documentation in `\core\Object`.
nateabele authored
90 $this->_config = $config + $defaults;
e7f3c31 @gwoo going lithium
gwoo authored
91
92 if ($this->_config['init']) {
93 $this->_init();
94 }
95 }
96
97 /**
e282896 @Ciaro Fixed some typos in the docblocks of core/Object
Ciaro authored
98 * Initializer function called by the constructor unless the constructor `'init'` flag is set
99 * to `false`. May be used for testing purposes, where objects need to be manipulated in an
100 * un-initialized state, or for high-overhead operations that require more control than the
3c2bc5d @nateabele Adding, updating and fixing documentation in `\core\Object`.
nateabele authored
101 * constructor provides. Additionally, this method iterates over the `$_autoConfig` property
102 * to automatically assign configuration settings to their corresponding properties.
e7f3c31 @gwoo going lithium
gwoo authored
103 *
3c2bc5d @nateabele Adding, updating and fixing documentation in `\core\Object`.
nateabele authored
104 * For example, given the following: {{{
105 * class Bar extends \lithium\core\Object {
106 * protected $_autoConfig = array('foo');
107 * protected $_foo;
108 * }
109 *
110 * $instance = new Bar(array('foo' => 'value'));
111 * }}}
112 *
113 * The `$_foo` property of `$instance` would automatically be set to `'value'`. If `$_foo` was
114 * an array, `$_autoConfig` could be set to `array('foo' => 'merge')`, and the constructor value
115 * of `'foo'` would be merged with the default value of `$_foo` and assigned to it.
116 *
117 * @see lithium\core\Object::$_autoConfig
e7f3c31 @gwoo going lithium
gwoo authored
118 * @return void
119 */
120 protected function _init() {
00775ba @nateabele Minor optimizations and removal of unused use cases in `\core\Object:…
nateabele authored
121 foreach ($this->_autoConfig as $key => $flag) {
8b4207f @jperras Optimizing Object::_init() a bit further.
jperras authored
122 if (!isset($this->_config[$key]) && !isset($this->_config[$flag])) {
e7f3c31 @gwoo going lithium
gwoo authored
123 continue;
124 }
30ab4c1 @daschl QA: Miscc QA fixes, including trailing commas, param documentation an…
daschl authored
125
8b4207f @jperras Optimizing Object::_init() a bit further.
jperras authored
126 if ($flag === 'merge') {
e282896 @Ciaro Fixed some typos in the docblocks of core/Object
Ciaro authored
127 $this->{"_{$key}"} = $this->_config[$key] + $this->{"_{$key}"};
1c7a5cf @nateabele Minor optimizations and removal of unused use cases in `\core\Object:…
nateabele authored
128 } else {
da4fa3a @jperras Removing dead test case. Another small optimization to Object::_init().
jperras authored
129 $this->{"_$flag"} = $this->_config[$flag];
e7f3c31 @gwoo going lithium
gwoo authored
130 }
131 }
132 }
133
134 /**
135 * Apply a closure to a method of the current object instance.
136 *
ce3ede1 @gwoo adding Object::_instance() and StaticObject::_instance()
gwoo authored
137 * @see lithium\core\Object::_filter()
138 * @see lithium\util\collection\Filters
285b34d @daschl QA: replacing spaces with tabs where appropriate.
daschl authored
139 * @param mixed $method The name of the method to apply the closure to. Can either be a single
2f0d2a9 @niel Updating dockblocks to reflect changes to documentation standards.
niel authored
140 * method name as a string, or an array of method names.
840f361 @nateabele Implementing `\util\collection\Filters::apply()` to enable applying f…
nateabele authored
141 * @param closure $filter The closure that is used to filter the method(s).
e7f3c31 @gwoo going lithium
gwoo authored
142 * @return void
143 */
840f361 @nateabele Implementing `\util\collection\Filters::apply()` to enable applying f…
nateabele authored
144 public function applyFilter($method, $filter = null) {
9decac0 @alkemann insert space after type casting parenthesis
alkemann authored
145 foreach ((array) $method as $m) {
e7f3c31 @gwoo going lithium
gwoo authored
146 if (!isset($this->_methodFilters[$m])) {
147 $this->_methodFilters[$m] = array();
148 }
840f361 @nateabele Implementing `\util\collection\Filters::apply()` to enable applying f…
nateabele authored
149 $this->_methodFilters[$m][] = $filter;
e7f3c31 @gwoo going lithium
gwoo authored
150 }
151 }
152
153 /**
154 * Calls a method on this object with the given parameters. Provides an OO wrapper
155 * for call_user_func_array, and improves performance by using straight method calls
156 * in most cases.
157 *
158 * @param string $method Name of the method to call
159 * @param array $params Parameter list to use when calling $method
160 * @return mixed Returns the result of the method call
161 */
162 public function invokeMethod($method, $params = array()) {
163 switch (count($params)) {
164 case 0:
165 return $this->{$method}();
166 case 1:
167 return $this->{$method}($params[0]);
168 case 2:
169 return $this->{$method}($params[0], $params[1]);
170 case 3:
171 return $this->{$method}($params[0], $params[1], $params[2]);
172 case 4:
173 return $this->{$method}($params[0], $params[1], $params[2], $params[3]);
174 case 5:
175 return $this->{$method}($params[0], $params[1], $params[2], $params[3], $params[4]);
176 default:
177 return call_user_func_array(array(&$this, $method), $params);
178 }
179 }
180
181 /**
e826388 @nateabele Implementing magic `__set_state()` method in `core\Object`.
nateabele authored
182 * PHP magic method used in conjunction with `var_export()` to allow objects to be
183 * re-instantiated with their pre-existing properties and values intact. This method can be
184 * called statically on any class that extends `Object` to return an instance of it.
185 *
186 * @param array $data An array of properties and values with which to re-instantiate the object.
2f0d2a9 @niel Updating dockblocks to reflect changes to documentation standards.
niel authored
187 * These properties can be both public and protected.
e826388 @nateabele Implementing magic `__set_state()` method in `core\Object`.
nateabele authored
188 * @return object Returns an instance of the requested object with the given properties set.
189 */
190 public static function __set_state($data) {
191 $class = get_called_class();
192 $object = new $class();
193
194 foreach ($data as $property => $value) {
195 $object->{$property} = $value;
196 }
197 return $object;
198 }
199
200 /**
ce3ede1 @gwoo adding Object::_instance() and StaticObject::_instance()
gwoo authored
201 * Returns an instance of a class with given `config`. The `name` could be a key from the
202 * `classes` array, a fully-namespaced class name, or an object. Typically this method is used
203 * in `_init` to create the dependencies used in the current class.
204 *
205 * @param string|object $name A `classes` key or fully-namespaced class name.
a12db0c @nateabele Making `\core\Libraries::instance()` filterable, and refactoring `\co…
nateabele authored
206 * @param array $options The configuration passed to the constructor.
207 * @return object
ce3ede1 @gwoo adding Object::_instance() and StaticObject::_instance()
gwoo authored
208 */
a12db0c @nateabele Making `\core\Libraries::instance()` filterable, and refactoring `\co…
nateabele authored
209 protected function _instance($name, array $options = array()) {
210 if (is_string($name) && isset($this->_classes[$name])) {
ce3ede1 @gwoo adding Object::_instance() and StaticObject::_instance()
gwoo authored
211 $name = $this->_classes[$name];
212 }
a12db0c @nateabele Making `\core\Libraries::instance()` filterable, and refactoring `\co…
nateabele authored
213 return Libraries::instance(null, $name, $options);
ce3ede1 @gwoo adding Object::_instance() and StaticObject::_instance()
gwoo authored
214 }
215
216 /**
e7f3c31 @gwoo going lithium
gwoo authored
217 * Executes a set of filters against a method by taking a method's main implementation as a
3c2bc5d @nateabele Adding, updating and fixing documentation in `\core\Object`.
nateabele authored
218 * callback, and iteratively wrapping the filters around it. This, along with the `Filters`
219 * class, is the core of Lithium's filters system. This system allows you to "reach into" an
220 * object's methods which are marked as _filterable_, and intercept calls to those methods,
221 * optionally modifying parameters or return values.
e7f3c31 @gwoo going lithium
gwoo authored
222 *
3c2bc5d @nateabele Adding, updating and fixing documentation in `\core\Object`.
nateabele authored
223 * @see lithium\core\Object::applyFilter()
224 * @see lithium\util\collection\Filters
225 * @param string $method The name of the method being executed, usually the value of
226 * `__METHOD__`.
e7f3c31 @gwoo going lithium
gwoo authored
227 * @param array $params An associative array containing all the parameters passed into
3c2bc5d @nateabele Adding, updating and fixing documentation in `\core\Object`.
nateabele authored
228 * the method.
e7f3c31 @gwoo going lithium
gwoo authored
229 * @param Closure $callback The method's implementation, wrapped in a closure.
2f0d2a9 @niel Updating dockblocks to reflect changes to documentation standards.
niel authored
230 * @param array $filters Additional filters to apply to the method for this call only.
3c2bc5d @nateabele Adding, updating and fixing documentation in `\core\Object`.
nateabele authored
231 * @return mixed Returns the return value of `$callback`, modified by any filters passed in
232 * `$filters` or applied with `applyFilter()`.
e7f3c31 @gwoo going lithium
gwoo authored
233 */
234 protected function _filter($method, $params, $callback, $filters = array()) {
177e488 @nateabele Refactoring `StaticObject::_filter()` and `Object::_filter()`, fixing…
nateabele authored
235 list($class, $method) = explode('::', $method);
e7f3c31 @gwoo going lithium
gwoo authored
236
237 if (empty($this->_methodFilters[$method]) && empty($filters)) {
e9b1a18 @nateabele Minor optimization in filter implementation.
nateabele authored
238 return $callback($this, $params, null);
e7f3c31 @gwoo going lithium
gwoo authored
239 }
240
177e488 @nateabele Refactoring `StaticObject::_filter()` and `Object::_filter()`, fixing…
nateabele authored
241 $f = isset($this->_methodFilters[$method]) ? $this->_methodFilters[$method] : array();
244646c @nateabele Adding test for `\data\Source`. Refactoring classes in `\data` into "…
nateabele authored
242 $data = array_merge($f, $filters, array($callback));
243 return Filters::run($this, $params, compact('data', 'class', 'method'));
e7f3c31 @gwoo going lithium
gwoo authored
244 }
245
3c2bc5d @nateabele Adding, updating and fixing documentation in `\core\Object`.
nateabele authored
246 /**
247 * Gets and caches an array of the parent methods of a class.
248 *
249 * @return array Returns an array of parent classes for the current class.
250 */
e7f3c31 @gwoo going lithium
gwoo authored
251 protected static function _parents() {
252 $class = get_called_class();
253
254 if (!isset(self::$_parents[$class])) {
255 self::$_parents[$class] = class_parents($class);
256 }
257 return self::$_parents[$class];
258 }
259
260 /**
ce3ede1 @gwoo adding Object::_instance() and StaticObject::_instance()
gwoo authored
261 * Exit immediately. Primarily used for overrides during testing.
e7f3c31 @gwoo going lithium
gwoo authored
262 *
ce3ede1 @gwoo adding Object::_instance() and StaticObject::_instance()
gwoo authored
263 * @param integer|string $status integer range 0 to 254, string printed on exit
e7f3c31 @gwoo going lithium
gwoo authored
264 * @return void
265 */
ce3ede1 @gwoo adding Object::_instance() and StaticObject::_instance()
gwoo authored
266 protected function _stop($status = 0) {
267 exit($status);
e7f3c31 @gwoo going lithium
gwoo authored
268 }
269 }
270
271 ?>
Something went wrong with that request. Please try again.