Hoa central
Event.php
Go to the documentation of this file.
1 <?php
2 
37 namespace Hoa\Core\Event;
38 
39 use Hoa\Core;
40 
49 interface Source
50 {
51 }
52 
61 class Bucket
62 {
68  protected $_source = null;
69 
75  protected $_data = null;
76 
77 
78 
85  public function __construct($data = null)
86  {
87  $this->setData($data);
88 
89  return;
90  }
91 
100  public function send($eventId, Source $source)
101  {
102  return Event::notify($eventId, $source, $this);
103  }
104 
111  public function setSource(Source $source)
112  {
113  $old = $this->_source;
114  $this->_source = $source;
115 
116  return $old;
117  }
118 
124  public function getSource()
125  {
126  return $this->_source;
127  }
128 
135  public function setData($data)
136  {
137  $old = $this->_data;
138  $this->_data = $data;
139 
140  return $old;
141  }
142 
148  public function getData()
149  {
150  return $this->_data;
151  }
152 }
153 
164 class Event
165 {
172  private static $_register = [];
173 
179  protected $_callable = [];
180 
181 
182 
188  private function __construct()
189  {
190  return;
191  }
192 
200  public static function getEvent($eventId)
201  {
202  if (!isset(self::$_register[$eventId][0])) {
203  self::$_register[$eventId] = [
204  0 => new self(),
205  1 => null
206  ];
207  }
208 
209  return self::$_register[$eventId][0];
210  }
211 
221  public static function register($eventId, $source)
222  {
223  if (true === self::eventExists($eventId)) {
224  throw new Core\Exception(
225  'Cannot redeclare an event with the same ID, i.e. the event ' .
226  'ID %s already exists.',
227  0,
228  $eventId
229  );
230  }
231 
232  if (is_object($source) && !($source instanceof Source)) {
233  throw new Core\Exception(
234  'The source must implement \Hoa\Core\Event\Source ' .
235  'interface; given %s.',
236  1,
237  get_class($source)
238  );
239  } else {
240  $reflection = new \ReflectionClass($source);
241 
242  if (false === $reflection->implementsInterface('\Hoa\Core\Event\Source')) {
243  throw new Core\Exception(
244  'The source must implement \Hoa\Core\Event\Source ' .
245  'interface; given %s.',
246  2,
247  $source
248  );
249  }
250  }
251 
252  if (!isset(self::$_register[$eventId][0])) {
253  self::$_register[$eventId][0] = new self();
254  }
255 
256  self::$_register[$eventId][1] = $source;
257 
258  return;
259  }
260 
269  public static function unregister($eventId, $hard = false)
270  {
271  if (false !== $hard) {
272  unset(self::$_register[$eventId]);
273  } else {
274  self::$_register[$eventId][1] = null;
275  }
276 
277  return;
278  }
279 
288  public function attach($callable)
289  {
290  $callable = xcallable($callable);
291  $this->_callable[$callable->getHash()] = $callable;
292 
293  return $this;
294  }
295 
303  public function detach($callable)
304  {
305  unset($this->_callable[xcallable($callable)->getHash()]);
306 
307  return $this;
308  }
309 
315  public function isListened()
316  {
317  return !empty($this->_callable);
318  }
319 
329  public static function notify($eventId, Source $source, Bucket $data)
330  {
331  if (false === self::eventExists($eventId)) {
332  throw new Core\Exception(
333  'Event ID %s does not exist, cannot send notification.',
334  3,
335  $eventId
336  );
337  }
338 
339  $data->setSource($source);
340  $event = self::getEvent($eventId);
341 
342  foreach ($event->_callable as $callable) {
343  $callable($data);
344  }
345 
346  return;
347  }
348 
355  public static function eventExists($eventId)
356  {
357  return
358  array_key_exists($eventId, self::$_register) &&
359  self::$_register[$eventId][1] !== null;
360  }
361 }
362 
371 interface Listenable extends Source
372 {
381  public function on($listenerId, $callable);
382 }
383 
393 class Listener
394 {
400  protected $_source = null;
401 
407  protected $_listen = null;
408 
409 
410 
418  public function __construct(Listenable $source, Array $ids)
419  {
420  $this->_source = $source;
421  $this->addIds($ids);
422 
423  return;
424  }
425 
432  public function addIds(Array $ids)
433  {
434  foreach ($ids as $id) {
435  $this->_listen[$id] = [];
436  }
437 
438  return;
439  }
440 
449  public function attach($listenerId, $callable)
450  {
451  if (false === $this->listenerExists($listenerId)) {
452  throw new Core\Exception(
453  'Cannot listen %s because it is not defined.',
454  0,
455  $listenerId
456  );
457  }
458 
459  $callable = xcallable($callable);
460  $this->_listen[$listenerId][$callable->getHash()] = $callable;
461 
462  return $this;
463  }
464 
472  public function detach($listenerId, $callable)
473  {
474  unset($this->_callable[$listenerId][xcallable($callable)->getHash()]);
475 
476  return $this;
477  }
478 
485  public function detachAll($listenerId)
486  {
487  unset($this->_callable[$listenerId]);
488 
489  return $this;
490  }
491 
498  public function listenerExists($listenerId)
499  {
500  return array_key_exists($listenerId, $this->_listen);
501  }
502 
511  public function fire($listenerId, Bucket $data)
512  {
513  if (false === $this->listenerExists($listenerId)) {
514  throw new Core\Exception(
515  'Cannot fire on %s because it is not defined.',
516  1
517  );
518  }
519 
520  $data->setSource($this->_source);
521  $out = [];
522 
523  foreach ($this->_listen[$listenerId] as $callable) {
524  $out[] = $callable($data);
525  }
526 
527  return $out;
528  }
529 }
530 
534 class_alias('Hoa\Core\Event\Event', 'Hoa\Core\Event');
listenerExists($listenerId)
Definition: Event.php:498
static getEvent($eventId)
Definition: Event.php:200
detachAll($listenerId)
Definition: Event.php:485
__construct(Listenable $source, Array $ids)
Definition: Event.php:418
on($listenerId, $callable)
static notify($eventId, Source $source, Bucket $data)
Definition: Event.php:329
attach($listenerId, $callable)
Definition: Event.php:449
static eventExists($eventId)
Definition: Event.php:355
__construct($data=null)
Definition: Event.php:85
setSource(Source $source)
Definition: Event.php:111
attach($callable)
Definition: Event.php:288
detach($callable)
Definition: Event.php:303
send($eventId, Source $source)
Definition: Event.php:100
static unregister($eventId, $hard=false)
Definition: Event.php:269
fire($listenerId, Bucket $data)
Definition: Event.php:511
detach($listenerId, $callable)
Definition: Event.php:472
addIds(Array $ids)
Definition: Event.php:432