/
object_collection.php
204 lines (192 loc) · 6.19 KB
/
object_collection.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
<?php
/**
* Deals with Collections of objects. Keeping registries of those objects,
* loading and constructing new objects and triggering callbacks.
*
* PHP 5
*
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
* Copyright 2005-2010, Cake Software Foundation, Inc. (http://cakefoundation.org)
*
* Licensed under The MIT License
* Redistributions of files must retain the above copyright notice.
*
* @copyright Copyright 2005-2010, Cake Software Foundation, Inc. (http://cakefoundation.org)
* @link http://cakephp.org CakePHP(tm) Project
* @package cake
* @subpackage cake.cake.libs.view
* @since CakePHP(tm) v 0.10.0.1076
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
*/
abstract class ObjectCollection {
/**
* List of the currently-enabled objects
*
* @var array
* @access protected
*/
protected $_enabled = array();
/**
* A hash of loaded objects, indexed by name
*
* @var array
*/
protected $_loaded = array();
/**
* Loads a new object onto the collection. Can throw a variety of exceptions
*
* @param string $name Name of object to load.
* @param array $options Array of configuration options for the object to be constructed.
* @param boolean $enable Whether or not this helper should be enabled by default
* @return object the constructed object
*/
abstract public function load($name, $options = array(), $enable = true);
/**
* Trigger a callback method on every object in the collection.
* Used to trigger methods on objects in the collection. Will fire the methods in the
* order they were attached.
*
* ### Options
*
* - `breakOn` Set to the value or values you want the callback propagation to stop on.
* Defaults to `false`
* - `break` Set to true to enabled breaking. Defaults to `false`.
* - `collectReturn` Set to true to collect the return of each object into an array.
* This array of return values will be returned from the trigger() call. Defaults to `false`.
*
* @param string $callback Method to fire on all the objects. Its assumed all the objects implement
* the method you are calling.
* @param array $params Array of parameters for the triggered callback.
* @param array $options Array of options.
* @return mixed true.
*/
public function trigger($callback, $params = array(), $options = array()) {
if (empty($this->_enabled)) {
return true;
}
$options = array_merge(
array('break' => false, 'breakOn' => false, 'collectReturn' => false),
$options
);
$collected = array();
foreach ($this->_enabled as $name) {
$result = call_user_func_array(array(&$this->_loaded[$name], $callback), $params);
if ($options['collectReturn'] === true) {
$collected[] = $result;
}
if (
$options['break'] && ($result === $options['breakOn'] ||
(is_array($options['breakOn']) && in_array($result, $options['breakOn'], true)))
) {
return ($options['collectReturn'] === true) ? $collected : $result;
}
}
return $options['collectReturn'] ? $collected : true;
}
/**
* Provide public read access to the loaded objects
*
* @param string $name Name of property to read
* @return mixed
*/
public function __get($name) {
if (isset($this->_loaded[$name])) {
return $this->_loaded[$name];
}
return null;
}
/**
* Provide isset access to _loaded
*
* @param sting $name Name of object being checked.
* @return boolean
*/
public function __isset($name) {
return isset($this->_loaded[$name]);
}
/**
* Enables callbacks on an object or array of objects
*
* @param mixed $name CamelCased name of the object(s) to enable (string or array)
* @return void
*/
public function enable($name) {
foreach ((array)$name as $object) {
if (isset($this->_loaded[$object]) && array_search($object, $this->_enabled) === false) {
$this->_enabled[] = $object;
}
}
}
/**
* Disables callbacks on a object or array of objects. Public object methods are still
* callable as normal.
*
* @param mixed $name CamelCased name of the objects(s) to disable (string or array)
* @return void
*/
public function disable($name) {
foreach ((array)$name as $object) {
$index = array_search($object, $this->_enabled);
unset($this->_enabled[$index]);
}
$this->_enabled = array_values($this->_enabled);
}
/**
* Gets the list of currently-enabled objects, or, the current status of a single objects
*
* @param string $name Optional. The name of the object to check the status of. If omitted,
* returns an array of currently-enabled object
* @return mixed If $name is specified, returns the boolean status of the corresponding object.
* Otherwise, returns an array of all enabled objects.
*/
public function enabled($name = null) {
if (!empty($name)) {
return in_array($name, $this->_enabled);
}
return $this->_enabled;
}
/**
* Gets the list of attached behaviors, or, whether the given behavior is attached
*
* @param string $name Optional. The name of the behavior to check the status of. If omitted,
* returns an array of currently-attached behaviors
* @return mixed If $name is specified, returns the boolean status of the corresponding behavior.
* Otherwise, returns an array of all attached behaviors.
*/
public function attached($name = null) {
if (!empty($name)) {
return isset($this->_loaded[$name]);
}
return array_keys($this->_loaded);
}
/**
* Name of the object to remove from the collection
*
* @param string $name Name of the object to delete.
* @return void
*/
public function unload($name) {
list($plugin, $name) = pluginSplit($name);
unset($this->_loaded[$name]);
$this->_enabled = array_values(array_diff($this->_enabled, (array)$name));
}
/**
* Normalizes an object array, creates an array that makes lazy loading
* easier
*
* @param array $objects Array of child objects to normalize.
* @return array Array of normalized objects.
*/
public static function normalizeObjectArray($objects) {
$normal = array();
foreach ($objects as $i => $objectName) {
$options = array();
if (!is_int($i)) {
list($options, $objectName) = array($objectName, $i);
}
list($plugin, $name) = pluginSplit($objectName);
$normal[$name] = array('class' => $objectName, 'settings' => $options);
}
return $normal;
}
}