-
Notifications
You must be signed in to change notification settings - Fork 239
/
Filters.php
252 lines (230 loc) · 10 KB
/
Filters.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
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
<?php
/**
* li₃: the most RAD framework for PHP (http://li3.me)
*
* Copyright 2009, Union of RAD. All rights reserved. This source
* code is distributed under the terms of the BSD 3-Clause License.
* The full license text can be found in the LICENSE.txt file.
*/
namespace lithium\util\collection;
$message = 'The `lithium\util\collection\Filters` class has been deprecated in favor of ';
$message .= '`lithium\aop\Filters`. All old methods keep on working and are forwared to ';
$message .= 'the new ones.';
trigger_error($message, E_USER_DEPRECATED);
use lithium\aop\Filters as NewFilters;
/**
* The `Filters` class is the basis of Lithium's method filtering system: an efficient way to enable
* event-driven communication between classes without tight coupling and without depending on a
* centralized publish/subscribe system.
*
* In Lithium itself, when creating a method that can be filtered, a method is implemented as
* a closure and is passed to either `Object::_filter()` or `StaticObject::_filter()`. Each
* object internally maintains its own list of filters, which are applied in these methods and
* passed to `Filters::run()`.
*
* When implementing a custom filter system outside of Lithium, you can create your own list of
* filters, and pass it to `$options['data']` in the `run()` method.
*
* When creating a filter to apply to a method, you need the name of the method you want to call,
* along with a **closure**, that defines what you want the filter to do. All filters take the same
* 3 parameters: `$self`,`$params`, and `$chain`.
*
* - `$self`: If the filter is applied on an object instance, then `$self` will be that instance. If
* applied to a static class, then `$self` will be a string containing the fully-namespaced class
* name.
*
* - `$params`: Contains an associative array of the parameters that are passed into the method. You
* can modify or inspect these parameters before allowing the method to continue.
*
* - `$chain`: Finally, `$chain` contains the list of filters in line to be executed (as an
* instance of the `Filters` class). At the bottom of `$chain` is the method itself. This is why
* most filters contain a line that looks like this:
*
* ```
* return $chain->next($self, $params, $chain);
* ```
*
* This passes control to the next filter in the chain, and finally, to the method itself. This
* allows you to interact with the return value as well as the parameters.
*
* Within the framework, you can call `applyFilter()` on any object (static or instantiated) and
* pass the name of the method you would like to filter, along with the filter itself. For example:
*
* ```
* use lithium\action\Dispatcher;
*
* Dispatcher::applyFilter('run', function($self, $params, $chain) {
* // Custom pre-dispatch logic goes here
* $response = $chain->next($self, $params, $chain);
*
* // $response now contains a Response object with the result of the dispatched request,
* // and can be modified as appropriate
* // ...
* return $response;
* });
* ```
*
* The logic in the closure will now be executed on every call to `Dispatcher::run()`, and
* `$response` will always be modified by any custom logic present before being returned from
* `run()`.
*
* @deprecated Replaced by `\lithium\aop\Filters` and `\lithium\aop\Chain`.
* @link http://php.net/functions.anonymous.php
* @see lithium\util\collection\Filters::run()
* @see lithium\core\Object::_filter()
* @see lithium\core\StaticObject::_filter()
* @see lithium\core\Object::applyFilter()
* @see lithium\core\StaticObject::applyFilter()
*/
class Filters extends \lithium\util\Collection {
/**
* An array of filters indexed by class and method name, stored so that they can be lazily
* applied to classes which are not loaded yet.
*
* @deprecated
* @var array
*/
protected static $_lazyFilters = [];
/**
* This is the list of configuration settings that will be automatically applied to the
* properties of each `Filters` instance.
*
* @deprecated
* @var array
*/
protected $_autoConfig = ['data', 'class', 'method'];
/**
* The fully-namespaced class name of the class containing the method being filtered.
*
* @deprecated
* @see lithium\util\collection\Filters::method()
* @var string
*/
protected $_class = null;
/**
* The name of the method being filtered by the current instance of `Filters`.
*
* @deprecated
* @see lithium\util\collection\Filters::method()
* @var string
*/
protected $_method = null;
/**
* Lazily applies a filter to a method of a static class.
*
* This method is useful if you want to apply a filter inside a global bootstrap file to a
* static class which may or may not be loaded during every request, or which may be loaded
* lazily elsewhere in your application. If the class is already loaded, the filter will be
* applied immediately.
*
* However, if the class has not been loaded, the filter will be stored and applied to the class
* the first time the method specified in `$method` is called. This works for any class which
* extends `StaticObject`.
*
* @deprecated Forwards to new implementation.
* @see lithium\core\StaticObject
* @param string $class The fully namespaced name of a **static** class to which the filter will
* be applied. The class name specified in `$class` **must** extend
* `StaticObject`, or else statically implement the `applyFilter()` method.
* @param string $method The method to which the filter will be applied.
* @param \Closure $filter The filter to apply to the class method.
* @return void
*/
public static function apply($class, $method, $filter) {
$message = '`\lithium\util\collection\Filters::apply()` has been deprecated ';
$message .= 'in favor of `\lithium\aop\Filters::apply()`';
trigger_error($message, E_USER_DEPRECATED);
NewFilters::apply($class, $method, $filter);
}
/**
* Checks to see if the given class / method has any filters which have been applied lazily,
* and not yet attached.
*
* If a filter has been lazily applied (using `Filters::apply()`) to a class which is/was not
* yet loaded, checks to see if the filter is still being held, or has been applied. The filter
* will not be applied until the method being filtered has been called.
*
* @deprecated Now always returns `false`.
* @see lithium\util\collection\Filters::apply()
* @param string $class Fully-namespaced class name.
* @param string $method Method name.
* @return boolean
*/
public static function hasApplied($class, $method) {
$message = '`\lithium\util\collection\Filters::hasApplied()` has been deprecated.';
trigger_error($message, E_USER_DEPRECATED);
return false;
}
/**
* Collects a set of filters to iterate. Creates a filter chain for the given class/method,
* executes it, and returns the value.
*
* @deprecated Forwards to new implementation.
* @param mixed $class The class for which this filter chain is being created. If this is the
* result of a static method call, `$class` should be a string. Otherwise, it should
* be the instance of the object making the call.
* @param array $params An associative array of the given method's parameters.
* @param array $options The configuration options with which to create the filter chain.
* Mainly, these options allow the `Filters` object to be queried for details such as
* which class / method initiated it. Available keys:
* - `'class'`: The name of the class that initiated the filter chain.
* - `'method'`: The name of the method that initiated the filter chain.
* - `'data'` _array_: An array of callable objects (usually closures) to be iterated
* through. By default, execution will be nested such that the first item will be
* executed first, and will be the last to return.
* @return Returns the value returned by the first closure in `$options['data`]`.
*/
public static function run($class, $params, array $options = []) {
$message = '`\lithium\util\collection\Filters::run()` has been deprecated ';
$message .= 'in favor of `\lithium\aop\Filters::run()`';
trigger_error($message, E_USER_DEPRECATED);
$defaults = ['class' => null, 'method' => null, 'data' => []];
$options += $defaults;
$callback = array_pop($options['data']);
foreach ($options['data'] as $filter) {
NewFilters::apply($class, $options['method'], $filter);
}
return NewFilters::run($class, $options['method'], $params, $callback);
}
/**
* Provides short-hand convenience syntax for filter chaining.
*
* @deprecated Not used here anymore.
* @see lithium\core\Object::applyFilter()
* @see lithium\core\Object::_filter()
* @param object $self The object instance that owns the filtered method.
* @param array $params An associative array containing the parameters passed to the filtered
* method.
* @param array $chain The Filters object instance containing this chain of filters.
* @return mixed Returns the return value of the next filter in the chain.
*/
public function next(/* $self, $params, $chain */) {
if (func_num_args() !== 3) {
trigger_error('Missing argument/s.', E_USER_WARNING);
return;
}
list($self, $params, $chain) = func_get_args();
$message = '`\lithium\util\collection\Filters::next()` has been deprecated ';
$message .= 'in favor of `\lithium\aop\Chain::next()`';
trigger_error($message, E_USER_DEPRECATED);
if (empty($self) || empty($chain)) {
return parent::next();
}
$next = parent::next();
return $next($self, $params, $chain);
}
/**
* Gets the method name associated with this filter chain. This is the method being filtered.
*
* @deprecated Not used here anymore.
* @param boolean $full Whether to return the method name including the class name or not.
* @return string
*/
public function method($full = false) {
$message = '`\lithium\util\collection\Filters::method()` has been deprecated ';
$message .= 'in favor of `\lithium\aop\Chain::method()`';
trigger_error($message, E_USER_DEPRECATED);
return $full ? $this->_class . '::' . $this->_method : $this->_method;
}
}
?>