Kdyby/Events @ProchazkaFilip
Co si povíme? teorie kolem eventů jak to funguje v Nette Kdyby/Events prakticky diskuze? připravte si otázky!
Teorie kolem eventů
Co jsou eventy/hooky? modulárnost rozšiřitelnost znovupoužitelnost
Eventy v Nette? class Circle extends Nette\Object { public $onchange = []; public function setradius($radius) { $this->radius = max(0, $radius); $this->onchange($this, $this->radius); }
Eventy v Nette? $circle = new Circle; $circle->onchange[] = function($circle, $newvalue) { echo 'there was a change!'; }; $circle->setradius(10);
Nette magic class Nette\Object { public function call($name, $args) { foreach ($this->{"on$name"} as $cb) { call_user_func_array($cb, $args); } }
Naco další event systém? není to lazy kompatibilita s otatními systémy doctrine\orm symfony\event-dispatcher
Lazy eventy? $circle->onchange[] = function($arg) use ($foo) { $foo->hardwork($arg); }; $circle->onchange[] = function($arg) use ($bar) { $bar->hardwork($arg); };
Doctrine ORM? class Listener implements EventSubscriber { function getsubscribedevents() { return ['onfoo', 'onbar']; } function onfoo($args) { } //...
Doctrine ORM? $evm = new EventManager(); $evm->addeventsubscriber( new Listener() );
Doctrine ORM? $evm->dispatch( 'onfoo', new Args($foo, $radius) );
Symfony? class Listener implements EventSubscriberInterface { function getsubscribedevents() { return ['onfoo', 'onbar']; } function onfoo($args) { //... }
Symfony? $evd = new EventDispatcher(); $evd->addsubscriber( new Listener() );
Symfony? $evm->dispatch( 'onfoo', new Event($foo, $radius) );
Co takhle, Kdyby se všechny systémy daly používat dohromady?
xkcd.com/927
Kdyby/Events = Nette events (+ Doctrine EventManager)? (+ Symfony EventDispatcher)?
Pojďme vyřešit problém z praxe class OrderProcess { function openorder(); function additem($item); function finish(order $order);
Přidáme posílání emailů... public function construct( EntityManager $em, Nette\Security\User $user, Nette\Http\Session $session ){
Požadavek: Po dokončení objednávky se bude posílat email
Přidáme posílání emailů... public function construct( EntityManager $em, Nette\Security\User $user, Nette\Http\Session $session, Nette\Mail\IMailer $mailer ){
Požadavek: Přidej mi tam kredity za objednávky
Přidáme kredity.. public function construct( EntityManager $em, Nette\Security\User $user, Nette\Http\Session $session, Nette\Mail\IMailer $mailer, My\CreditsRewarder $rewarder ){
Požadavek: Jeden partner chce objednávky posílat do svého pokladního systému
Externí pokladní systém.. public function construct( EntityManager $em, Nette\Security\User $user, Nette\Http\Session $session, Nette\Mail\IMailer $mailer, My\CreditsRewarder $rewarder, Partner\CashRegisterClient $partner ){
Požadavek: Budeme posílat smsky
Posílání smsek... public function construct( EntityManager $em, Nette\Security\User $user, Nette\Http\Session $session, Nette\Mail\IMailer $mailer, My\CreditsRewarder $rewarder, Partner\CashRegisterClient $partner, My\Sms\Sender $smssender ){
Požadavek: V příštích 6 hodinách vracej 50% hodnoty objednávky v kreditech, za všechny objednané burgery
SRP (Single Responsibility Principle)
Vraťme se na začátek... public function construct( EntityManager $em, Nette\Security\User $user, Nette\Http\Session $session ){
a přidejme si jeden event class OrderProcess public $onfinish = []; function finish(order $order) { //... $this->onfinish($this, $order); }
a napíšeme si listenery class OrderMailerListener implements Subscriber { function getsubscribedevents() { return [ 'OrderProcess::onFinish' ]; }
a napíšeme si listenery class OrderMailerListener function construct(imailer $mailer); function onfinish(order $order) { //.. $this->mailer->send($message); }
a napíšeme si listenery class CreditsRewardListener function construct( Rewarder $r, User $user); function onfinish(order $order) { $this->rewarder->reward( $this->user->id, $order->price * 0.05); }
a napíšeme si listenery class SmsSenderListener function construct(sms\sender $sender); function onfinish(order $order) { //.. $this->sender->send($message); }
Nezapomenout registrovat events: subscribers: - OrderMailerListener - CreditsRewardListener - SmsSenderListener
Profit!
Poslední nejasnosti Jak se $onfinish dostane k listenerům? Nemělo to být lazy? Můžu naslouchat na více událostí v jednom listeneru? - Jistě!
A co nějaké nevýhody? Nevíme vůbec co se zavolá IDE s tím neumí pracovat
PhpStorm Kdyby/Events & @juznacz FTW!
Dejte @juznacz follow je to borec
A co ty message queue?
Závěrem? Eventy nejsou silver bullet, užívejte s rozumem.
Dotazy?
Díky za pozornost! filip-prochazka.com Follow me maybe? @ProchazkaFilip