1
|
|
|
<?php |
2
|
|
|
/** |
3
|
|
|
* Phossa Project |
4
|
|
|
* |
5
|
|
|
* PHP version 5.4 |
6
|
|
|
* |
7
|
|
|
* @category Library |
8
|
|
|
* @package Phossa2\Event |
9
|
|
|
* @copyright Copyright (c) 2016 phossa.com |
10
|
|
|
* @license http://mit-license.org/ MIT License |
11
|
|
|
* @link http://www.phossa.com/ |
12
|
|
|
*/ |
13
|
|
|
/*# declare(strict_types=1); */ |
14
|
|
|
|
15
|
|
|
namespace Phossa2\Event; |
16
|
|
|
|
17
|
|
|
use Phossa2\Event\Message\Message; |
18
|
|
|
use Phossa2\Shared\Base\ObjectAbstract; |
19
|
|
|
use Phossa2\Event\Interfaces\EventInterface; |
20
|
|
|
use Phossa2\Event\Exception\InvalidArgumentException; |
21
|
|
|
|
22
|
|
|
/** |
23
|
|
|
* Event |
24
|
|
|
* |
25
|
|
|
* Basic implementation of EventInterface with array access to properties |
26
|
|
|
* |
27
|
|
|
* ```php |
28
|
|
|
* // create event |
29
|
|
|
* $evt = new Event( |
30
|
|
|
* 'login.attempt', // event name |
31
|
|
|
* $this, // event context |
32
|
|
|
* ['username' => 'phossa'] // event properties |
33
|
|
|
* ); |
34
|
|
|
* |
35
|
|
|
* // get/set event property |
36
|
|
|
* if ('phossa' === $evt['username']) { |
37
|
|
|
* $evt['username'] = 'phossa2'; |
38
|
|
|
* } |
39
|
|
|
* |
40
|
|
|
* // stop event |
41
|
|
|
* $evt->stopPropagation(); |
42
|
|
|
* ``` |
43
|
|
|
* |
44
|
|
|
* @package Phossa2\Event |
45
|
|
|
* @author Hong Zhang <[email protected]> |
46
|
|
|
* @see ObjectAbstract |
47
|
|
|
* @see EventInterface |
48
|
|
|
* @version 2.0.0 |
49
|
|
|
* @since 2.0.0 added |
50
|
|
|
*/ |
51
|
|
|
class Event extends ObjectAbstract implements EventInterface |
52
|
|
|
{ |
53
|
|
|
/** |
54
|
|
|
* event name |
55
|
|
|
* |
56
|
|
|
* @var string |
57
|
|
|
* @access protected |
58
|
|
|
*/ |
59
|
|
|
protected $name; |
60
|
|
|
|
61
|
|
|
/** |
62
|
|
|
* event context |
63
|
|
|
* |
64
|
|
|
* an object OR static class name (string) |
65
|
|
|
* |
66
|
|
|
* @var object|string |
67
|
|
|
* @access protected |
68
|
|
|
*/ |
69
|
|
|
protected $context; |
70
|
|
|
|
71
|
|
|
/** |
72
|
|
|
* event properties |
73
|
|
|
* |
74
|
|
|
* @var array |
75
|
|
|
* @access protected |
76
|
|
|
*/ |
77
|
|
|
protected $properties; |
78
|
|
|
|
79
|
|
|
/** |
80
|
|
|
* Results from the handlers |
81
|
|
|
* |
82
|
|
|
* @var array |
83
|
|
|
* @access protected |
84
|
|
|
*/ |
85
|
|
|
protected $results = []; |
86
|
|
|
|
87
|
|
|
/** |
88
|
|
|
* stop propagation |
89
|
|
|
* |
90
|
|
|
* @var bool |
91
|
|
|
* @access protected |
92
|
|
|
*/ |
93
|
|
|
protected $stopped = false; |
94
|
|
|
|
95
|
|
|
/** |
96
|
|
|
* Constructor |
97
|
|
|
* |
98
|
|
|
* @param string $eventName event name |
99
|
|
|
* @param string|object $context event context, object or static classname |
100
|
|
|
* @param array $properties (optional) event properties |
101
|
|
|
* @throws InvalidArgumentException if arguments not right |
102
|
|
|
* @access public |
103
|
|
|
* @api |
104
|
|
|
*/ |
105
|
|
|
public function __construct( |
106
|
|
|
/*# string */ $eventName, |
107
|
|
|
$context = null, |
108
|
|
|
array $properties = [] |
109
|
|
|
) { |
110
|
|
|
$this->__invoke($eventName, $context, $properties); |
111
|
|
|
} |
112
|
|
|
|
113
|
|
|
/** |
114
|
|
|
* {@inheritDoc} |
115
|
|
|
*/ |
116
|
|
|
public function __invoke( |
117
|
|
|
/*# string */ $eventName, |
118
|
|
|
$context = null, |
119
|
|
|
array $properties = [] |
120
|
|
|
) { |
121
|
|
|
return $this->setName($eventName) |
122
|
|
|
->setContext($context) |
|
|
|
|
123
|
|
|
->setProperties($properties); |
124
|
|
|
} |
125
|
|
|
|
126
|
|
|
/** |
127
|
|
|
* {@inheritDoc} |
128
|
|
|
*/ |
129
|
|
|
public function setName(/*# string */ $eventName) |
130
|
|
|
{ |
131
|
|
|
if (!is_string($eventName) || empty($eventName)) { |
132
|
|
|
throw new InvalidArgumentException( |
133
|
|
|
Message::get(Message::EVT_NAME_INVALID, $eventName), |
134
|
|
|
Message::EVT_NAME_INVALID |
135
|
|
|
); |
136
|
|
|
} |
137
|
|
|
$this->name = $eventName; |
138
|
|
|
|
139
|
|
|
return $this; |
140
|
|
|
} |
141
|
|
|
|
142
|
|
|
/** |
143
|
|
|
* {@inheritDoc} |
144
|
|
|
*/ |
145
|
|
|
public function getName()/*# : string */ |
146
|
|
|
{ |
147
|
|
|
return $this->name; |
148
|
|
|
} |
149
|
|
|
|
150
|
|
|
/** |
151
|
|
|
* {@inheritDoc} |
152
|
|
|
*/ |
153
|
|
|
public function setContext($context) |
154
|
|
|
{ |
155
|
|
|
if (is_null($context) || |
156
|
|
|
is_object($context) || |
157
|
|
|
is_string($context) && class_exists($context, false)) { |
158
|
|
|
$this->context = $context; |
159
|
|
|
return $this; |
160
|
|
|
} |
161
|
|
|
throw new InvalidArgumentException( |
162
|
|
|
Message::get(Message::EVT_CONTEXT_INVALID, $context), |
163
|
|
|
Message::EVT_CONTEXT_INVALID |
164
|
|
|
); |
165
|
|
|
} |
166
|
|
|
|
167
|
|
|
/** |
168
|
|
|
* {@inheritDoc} |
169
|
|
|
*/ |
170
|
|
|
public function getContext() |
171
|
|
|
{ |
172
|
|
|
return $this->context; |
173
|
|
|
} |
174
|
|
|
|
175
|
|
|
/** |
176
|
|
|
* {@inheritDoc} |
177
|
|
|
*/ |
178
|
|
|
public function hasProperty(/*# string */ $name)/*#: bool */ |
179
|
|
|
{ |
180
|
|
|
return isset($this->properties[(string) $name]); |
181
|
|
|
} |
182
|
|
|
|
183
|
|
|
/** |
184
|
|
|
* {@inheritDoc} |
185
|
|
|
*/ |
186
|
|
|
public function getProperty(/*# string */ $name) |
187
|
|
|
{ |
188
|
|
|
if ($this->hasProperty($name)) { |
189
|
|
|
return $this->properties[(string) $name]; |
190
|
|
|
} |
191
|
|
|
return null; |
192
|
|
|
} |
193
|
|
|
|
194
|
|
|
/** |
195
|
|
|
* {@inheritDoc} |
196
|
|
|
*/ |
197
|
|
|
public function setProperty(/*# string */ $name, $value) |
198
|
|
|
{ |
199
|
|
|
if (null === $value) { |
200
|
|
|
unset($this->properties[(string) $name]); |
201
|
|
|
} else { |
202
|
|
|
$this->properties[(string) $name] = $value; |
203
|
|
|
} |
204
|
|
|
return $this; |
205
|
|
|
} |
206
|
|
|
|
207
|
|
|
/** |
208
|
|
|
* {@inheritDoc} |
209
|
|
|
*/ |
210
|
|
|
public function getProperties()/*# : array */ |
211
|
|
|
{ |
212
|
|
|
return $this->properties; |
213
|
|
|
} |
214
|
|
|
|
215
|
|
|
/** |
216
|
|
|
* {@inheritDoc} |
217
|
|
|
*/ |
218
|
|
|
public function setProperties(array $properties) |
219
|
|
|
{ |
220
|
|
|
$this->properties = $properties; |
221
|
|
|
return $this; |
222
|
|
|
} |
223
|
|
|
|
224
|
|
|
/** |
225
|
|
|
* {@inheritDoc} |
226
|
|
|
*/ |
227
|
|
|
public function addResult($result) |
228
|
|
|
{ |
229
|
|
|
$this->results[] = $result; |
230
|
|
|
return $this; |
231
|
|
|
} |
232
|
|
|
|
233
|
|
|
/** |
234
|
|
|
* {@inheritDoc} |
235
|
|
|
*/ |
236
|
|
|
public function getResults()/*# : array */ |
237
|
|
|
{ |
238
|
|
|
return $this->results; |
239
|
|
|
} |
240
|
|
|
|
241
|
|
|
/** |
242
|
|
|
* {@inheritDoc} |
243
|
|
|
*/ |
244
|
|
|
public function stopPropagation(/*# bool */ $stop = true) |
245
|
|
|
{ |
246
|
|
|
$this->stopped = (bool) $stop; |
247
|
|
|
return $this; |
248
|
|
|
} |
249
|
|
|
|
250
|
|
|
/** |
251
|
|
|
* {@inheritDoc} |
252
|
|
|
*/ |
253
|
|
|
public function isPropagationStopped()/*# : bool */ |
254
|
|
|
{ |
255
|
|
|
return $this->stopped; |
256
|
|
|
} |
257
|
|
|
|
258
|
|
|
/** |
259
|
|
|
* {@inheritDoc} |
260
|
|
|
*/ |
261
|
|
|
public function offsetExists($offset)/*# : bool */ |
262
|
|
|
{ |
263
|
|
|
return $this->hasProperty($offset); |
264
|
|
|
} |
265
|
|
|
|
266
|
|
|
/** |
267
|
|
|
* {@inheritDoc} |
268
|
|
|
*/ |
269
|
|
|
public function offsetGet($offset) |
270
|
|
|
{ |
271
|
|
|
return $this->getProperty($offset); |
272
|
|
|
} |
273
|
|
|
|
274
|
|
|
/** |
275
|
|
|
* {@inheritDoc} |
276
|
|
|
*/ |
277
|
|
|
public function offsetSet($offset, $value) |
278
|
|
|
{ |
279
|
|
|
$this->setProperty($offset, $value); |
280
|
|
|
} |
281
|
|
|
|
282
|
|
|
/** |
283
|
|
|
* {@inheritDoc} |
284
|
|
|
*/ |
285
|
|
|
public function offsetUnset($offset) |
286
|
|
|
{ |
287
|
|
|
$this->setProperty($offset, null); |
288
|
|
|
} |
289
|
|
|
} |
290
|
|
|
|
This check looks at variables that have been passed in as parameters and are passed out again to other methods.
If the outgoing method call has stricter type requirements than the method itself, an issue is raised.
An additional type check may prevent trouble.