diff --git a/src/Annotations/Events/ListensFor.php b/src/Annotations/Events/ListensFor.php new file mode 100644 index 0000000..60b8f2e --- /dev/null +++ b/src/Annotations/Events/ListensFor.php @@ -0,0 +1,15 @@ +pushed = new Collection(); + $this->registerListeners(); + } + + /** + * Register event listeners based on the ListensFor attribute. + * + * @return void + */ + private function registerListeners(): void + { + // traverse the Listeners directory and register all listeners + $listenersPath = __DIR__ . '/Listeners'; + $iterator = new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($listenersPath)); + + foreach ($iterator as $file) { + if ($file->isFile() && $file->getExtension() === 'php') { + $relativePath = str_replace($listenersPath . '/', '', $file->getPathname()); + $className = self::LISTENERS_NAMESPACE . str_replace(['/', '.php'], ['\\', ''], $relativePath); + if (class_exists($className)) { + $reflectionClass = new \ReflectionClass($className); + $attributes = $reflectionClass->getAttributes(ListensFor::class); + foreach ($attributes as $attribute) { + $instance = $attribute->newInstance(); + $eventClass = $instance->eventClass; + $this->listen($eventClass, new $className()); + } + } + } + } + } + + /** + * Register a listener for the given events. + * + * @param $events + * @param $listener + * @return void + */ + public function listen($events, $listener = null): void + { + $this->listeners[$events][] = $listener; + } + + /** + * Check if there are listeners for the given event. + * + * @param $eventName + * @return bool + */ + public function hasListeners($eventName): bool + { + return isset($this->listeners[$eventName]) && !empty($this->listeners[$eventName]); + } + + /** + * Subscribe a subscriber to the dispatcher. + * + * @param Arrayable $subscriber + * @return void + */ + public function subscribe($subscriber): void + { + $this->listeners = array_merge($this->listeners, (array) $subscriber); + } + + /** + * Dispatch an event and halt on the first non-null response. + * + * @param $event + * @param array $payload + * @return array|null + */ + public function until($event, $payload = []): array|null + { + return $this->dispatch($event, $payload, true); + } + + /** + * Dispatch an event to its listeners. + * + * @param $event + * @param array $payload + * @param bool $halt + * @return array|null + */ + public function dispatch($event, $payload = [], $halt = false): array|null + { + if (is_object($event)) { + $eventClass = get_class($event); + } else { + $eventClass = $event; + } + + $listeners = $this->listeners[$eventClass] ?? null; + + if ($listeners === null) { + return null; + } + + $responses = []; + + foreach ($listeners as $listener) { + $response = $listener($event, $payload); + $responses[] = $response; + + if ($halt && $response !== null) { + return $response; + } + } + + return $responses; + } + + /** + * Push an event to be dispatched later. + * + * @param $event + * @param array $payload + * @return void + */ + public function push($event, $payload = []): void + { + $this->pushed->put($event, $payload); + } + + /** + * Flush a pushed event, dispatching it if it exists. + * + * @param $event + * @return void + */ + public function flush($event): void + { + if ($this->pushed->has($event)) { + $payload = $this->pushed->get($event); + $this->dispatch($event, $payload); + $this->pushed->forget([$event]); + } + } + + /** + * Forget a pushed event without dispatching it. + * + * @param $event + * @return void + */ + public function forget($event): void + { + $this->pushed->forget([$event]); + } + + /** + * Forget all pushed events. + * + * @return void + */ + public function forgetPushed(): void + { + $this->pushed = new Collection(); + } + + public function toArray(): array + { + return $this->listeners; + } +} diff --git a/src/Events/Listeners/Database/Connected.php b/src/Events/Listeners/Database/Connected.php new file mode 100644 index 0000000..e0c3cb5 --- /dev/null +++ b/src/Events/Listeners/Database/Connected.php @@ -0,0 +1,28 @@ +connectionName]); + + return null; + } +} diff --git a/src/Events/Listeners/Listener.php b/src/Events/Listeners/Listener.php new file mode 100644 index 0000000..ba21dbb --- /dev/null +++ b/src/Events/Listeners/Listener.php @@ -0,0 +1,9 @@ +setEventDispatcher(Dispatcher::getFacadeRoot()); $capsule->addConnection(Config::get('db')); $capsule->setAsGlobal(); $capsule->bootEloquent(); diff --git a/src/Services/Facades/Dispatcher.php b/src/Services/Facades/Dispatcher.php new file mode 100644 index 0000000..9fec1dd --- /dev/null +++ b/src/Services/Facades/Dispatcher.php @@ -0,0 +1,35 @@ +app->singleton(Dispatcher::class, function () { + return new Dispatcher(); + }); + } +}