Skip to content

Instantly share code, notes, and snippets.

@ArrayIterator
Created December 2, 2022 19:25
Show Gist options
  • Select an option

  • Save ArrayIterator/24c9acc33f2ac4690ab6afad6c347014 to your computer and use it in GitHub Desktop.

Select an option

Save ArrayIterator/24c9acc33f2ac4690ab6afad6c347014 to your computer and use it in GitHub Desktop.
Simple Event Dispatcher
<?php
declare(strict_types=1);
namespace Events;
use Closure;
class Simple
{
/**
* @var array
*/
private array $eventsList = [];
/**
* @param string $eventName
* @param Closure $callback
* @param int $priority
*/
public function add(string $eventName, Closure $callback, int $priority = 10)
{
$id = spl_object_hash($callback);
$this->eventsList[$priority][$eventName][] = [$id, $callback];
ksort($this->eventsList, SORT_ASC);
}
/**
* @param string $name
* @param ?Closure $callback
* @param ?int $priority
*
* @return int
*/
public function remove(string $name, ?Closure $callback = null, ?int $priority = null): int
{
$id = $callback ? spl_object_hash($callback) : null;
$usePriority = $priority !== null;
$removed = 0;
foreach ($this->eventsList as $p => $eventList) {
if ($usePriority && $p !== $priority) {
continue;
}
foreach ($eventList as $eventName => $events) {
if ($name !== $eventName) {
continue;
}
if ($id === null) {
$removed += count($this->eventsList[$p][$eventName]);
unset($this->eventsList[$p][$eventName]);
break;
}
foreach ($events as $k => $event) {
if ($event[0] !== $id) {
continue;
}
$removed++;
unset($this->eventsList[$p][$eventName][$k]);
}
if (count($this->eventsList[$p][$eventName]) === 0) {
unset($this->eventsList[$p][$eventName]);
continue;
}
$this->eventsList[$p][$eventName] = array_values(
$this->eventsList[$p][$eventName]
);
}
if (count($this->eventsList[$p]) === 0) {
unset($this->eventsList[$p]);
}
}
return $removed;
}
/**
* @param string $name
* @param ?Closure $callback
* @param ?int $priority
*
* @return bool
*/
public function has(string $name, ?Closure $callback = null, ?int $priority = null): bool
{
$id = $callback ? spl_object_hash($callback) : null;
$usePriority = $priority !== null;
foreach ($this->eventsList as $p => $eventList) {
if ($usePriority && $p !== $priority) {
continue;
}
if (!isset($eventList[$name])) {
continue;
}
if ($id === null) {
return true;
}
foreach ($eventList[$name] as $event) {
if ($event[0] === $id) {
return true;
}
}
}
return false;
}
/**
* @param string $name
* @param mixed|null $param
* @param ...$args
*
* @return mixed
*/
public function dispatch(string $name, mixed $param = null, ...$args): mixed
{
$originalParam = $param;
foreach ($this->eventsList as $eventLists) {
if (!isset($eventLists[$name])) {
continue;
}
foreach ($eventLists[$name] as $event) {
$param = $event[1]($param, $originalParam, ...$args);
}
}
return $param;
}
/**
* Clear All Events
*/
public function clearAll()
{
$this->eventsList = [];
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment