From 4a53d804fdce321ec748eba15d054ec52e547b50 Mon Sep 17 00:00:00 2001 From: Maxofil Date: Wed, 24 Jun 2020 19:51:13 +0200 Subject: [PATCH 1/4] added src files --- composer.json | 23 ++++++ src/ObserverComponent/EventMapper.php | 87 ++++++++++++++++++++ src/ObserverComponent/IEvent.php | 9 ++ src/ObserverComponent/IObservable.php | 12 +++ src/ObserverComponent/IObserverComponent.php | 16 ++++ src/ObserverComponent/TObservable.php | 20 +++++ src/ObserverComponent/TObserverComponent.php | 22 +++++ 7 files changed, 189 insertions(+) create mode 100644 composer.json create mode 100644 src/ObserverComponent/EventMapper.php create mode 100644 src/ObserverComponent/IEvent.php create mode 100644 src/ObserverComponent/IObservable.php create mode 100644 src/ObserverComponent/IObserverComponent.php create mode 100644 src/ObserverComponent/TObservable.php create mode 100644 src/ObserverComponent/TObserverComponent.php diff --git a/composer.json b/composer.json new file mode 100644 index 0000000..057723a --- /dev/null +++ b/composer.json @@ -0,0 +1,23 @@ +{ + "name": "infinityloop-dev/observer-component", + "description": "Event system for Nette framework's component model.", + "homepage": "https://www.infinityloop.dev/", + "type": "library", + "license": ["MIT"], + "authors": [ + { + "name": "Václav Pelíšek", + "homepage": "https://www.peldax.com" + } + ], + "require": { + "php": ">=7.4", + "nette/application": "^3.0", + "nette/caching": "^3.0" + }, + "autoload": { + "psr-4": { + "Infinityloop\\": "src/" + } + } +} \ No newline at end of file diff --git a/src/ObserverComponent/EventMapper.php b/src/ObserverComponent/EventMapper.php new file mode 100644 index 0000000..fd2c113 --- /dev/null +++ b/src/ObserverComponent/EventMapper.php @@ -0,0 +1,87 @@ +application = $application; + $this->storage = $storage; + $this->debugMode = \App\Bootstrap::isDebugMode(); + } + + public function registerObserver(IObserverComponent $component) : void + { + $componentPath = $component->lookupPath(\Nette\Application\IPresenter::class); + \assert(\is_string($componentPath)); + + if (!$this->debugMode && $this->isComponentRegistered($componentPath)) { + return; + } + + foreach ($component::getObservedEvents() as $eventName) { + \assert(\is_string($eventName) && \class_exists($eventName)); + + $observerList = $this->getObserverList($eventName); + + if (\in_array($componentPath, $observerList, true)) { + continue; + } + + $observerList[] = $componentPath; + $this->getEventMap()->save($eventName, $observerList); + + $registeredComponents = $this->getEventMap()->load('components') ?? []; + $registeredComponents[] = $componentPath; + $this->getEventMap()->save('components', $registeredComponents); + } + } + + public function dispatchEvent(IEvent $event) : void + { + $presenter = $this->application->getPresenter(); + \assert($presenter instanceof \Nette\Application\UI\Control); + + foreach ($this->getObserverList(\get_class($event)) as $observerPath) { + \assert(\is_string($observerPath)); + + $observer = $presenter->getComponent($observerPath); + \assert($observer instanceof IObserverComponent); + + $observer->observableUpdated($event); + } + } + + private function getObserverList(string $eventName) : array + { + return $this->getEventMap()->load($eventName) ?? []; + } + + private function isComponentRegistered(string $componentPath) : bool + { + $registeredComponents = $this->getEventMap()->load('components') ?? []; + + return \in_array($componentPath, $registeredComponents, true); + } + + private function getEventMap() : \Nette\Caching\Cache + { + if (!$this->eventMap instanceof \Nette\Caching\Cache) { + $applicationPath = \ltrim($this->application->getPresenter()->getAction(true), ':'); + $this->eventMap = new \Nette\Caching\Cache($this->storage, 'eventMapper-' . $applicationPath); + } + + return $this->eventMap; + } +} diff --git a/src/ObserverComponent/IEvent.php b/src/ObserverComponent/IEvent.php new file mode 100644 index 0000000..c5802ad --- /dev/null +++ b/src/ObserverComponent/IEvent.php @@ -0,0 +1,9 @@ +eventMapper = $eventMapper; + } + + public function notifyObservers(IEvent $event) : void + { + $this->eventMapper->dispatchEvent($event); + } +} diff --git a/src/ObserverComponent/TObserverComponent.php b/src/ObserverComponent/TObserverComponent.php new file mode 100644 index 0000000..3f91dff --- /dev/null +++ b/src/ObserverComponent/TObserverComponent.php @@ -0,0 +1,22 @@ +eventMapper = $eventMapper; + $this->onAnchor[] = function (\Nette\ComponentModel\IComponent $parent) : void { + $this->eventMapper->registerObserver($this); + }; + } +} From 8344f48e367a7d41b9e014bd3515e8518cb74ab7 Mon Sep 17 00:00:00 2001 From: Maxofil Date: Wed, 24 Jun 2020 20:15:32 +0200 Subject: [PATCH 2/4] oprava --- composer.json | 3 ++- src/ObserverComponent/EventMapper.php | 12 ++++++++---- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/composer.json b/composer.json index 057723a..10863c0 100644 --- a/composer.json +++ b/composer.json @@ -13,7 +13,8 @@ "require": { "php": ">=7.4", "nette/application": "^3.0", - "nette/caching": "^3.0" + "nette/caching": "^3.0", + "nette/utils": "^3.0" }, "autoload": { "psr-4": { diff --git a/src/ObserverComponent/EventMapper.php b/src/ObserverComponent/EventMapper.php index fd2c113..6a3e7c2 100644 --- a/src/ObserverComponent/EventMapper.php +++ b/src/ObserverComponent/EventMapper.php @@ -4,8 +4,10 @@ namespace Infinityloop\ObserverComponent; -class EventMapper +final class EventMapper { + use Nette\SmartObject; + private \Nette\Application\Application $application; private \Nette\Caching\IStorage $storage; private ?\Nette\Caching\Cache $eventMap = null; @@ -13,12 +15,13 @@ class EventMapper public function __construct( \Nette\Application\Application $application, - \Nette\Caching\IStorage $storage + \Nette\Caching\IStorage $storage, + bool $debugMode ) { $this->application = $application; $this->storage = $storage; - $this->debugMode = \App\Bootstrap::isDebugMode(); + $this->debugMode = $debugMode; } public function registerObserver(IObserverComponent $component) : void @@ -65,7 +68,8 @@ public function dispatchEvent(IEvent $event) : void private function getObserverList(string $eventName) : array { - return $this->getEventMap()->load($eventName) ?? []; + return $this->getEventMap()->load($eventName) + ?? []; } private function isComponentRegistered(string $componentPath) : bool From 4fa783fb819539e476173ced11fe6c418f37bba7 Mon Sep 17 00:00:00 2001 From: Maxofil Date: Wed, 24 Jun 2020 20:25:06 +0200 Subject: [PATCH 3/4] debugMode set default value to true --- src/ObserverComponent/EventMapper.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ObserverComponent/EventMapper.php b/src/ObserverComponent/EventMapper.php index 6a3e7c2..cf2b9a9 100644 --- a/src/ObserverComponent/EventMapper.php +++ b/src/ObserverComponent/EventMapper.php @@ -11,7 +11,7 @@ final class EventMapper private \Nette\Application\Application $application; private \Nette\Caching\IStorage $storage; private ?\Nette\Caching\Cache $eventMap = null; - private bool $debugMode; + private bool $debugMode = true; public function __construct( \Nette\Application\Application $application, From d2b53afe650c162c406931a15aef72570b959285 Mon Sep 17 00:00:00 2001 From: Maxofil Date: Wed, 24 Jun 2020 20:27:55 +0200 Subject: [PATCH 4/4] =?UTF-8?q?zm=C4=9Bna?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/ObserverComponent/EventMapper.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ObserverComponent/EventMapper.php b/src/ObserverComponent/EventMapper.php index cf2b9a9..3a2b909 100644 --- a/src/ObserverComponent/EventMapper.php +++ b/src/ObserverComponent/EventMapper.php @@ -11,12 +11,12 @@ final class EventMapper private \Nette\Application\Application $application; private \Nette\Caching\IStorage $storage; private ?\Nette\Caching\Cache $eventMap = null; - private bool $debugMode = true; + private bool $debugMode; public function __construct( \Nette\Application\Application $application, \Nette\Caching\IStorage $storage, - bool $debugMode + bool $debugMode = true ) { $this->application = $application;