Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Kdyby/Events #posobota

Kdyby/Events #posobota

The Kdyby/Events extension provides a robust events system for the Nette Framework.

Filip Procházka

September 30, 2014
Tweet

More Decks by Filip Procházka

Other Decks in Technology

Transcript

  1. Kdyby/Events @ProchazkaFilip

  2. Co si povíme? • teorie kolem eventů • jak to

    funguje v Nette • eventy v komponentách • Kdyby/Events prakticky • diskuze? připravte si otázky!
  3. Teorie kolem eventů

  4. Co jsou eventy/hooky? • modulárnost • rozšiřitelnost • znovupoužitelnost

  5. Eventy v Nette? class Circle extends Nette\Object { public $onChange

    = []; public function setRadius($radius) { $this->radius = max(0, $radius); $this->onChange($this, $this->radius); }
  6. Eventy v Nette? $circle = new Circle; $circle->onChange[] = function($circle,

    $newValue) { echo 'there was a change!'; }; $circle->setRadius(10);
  7. Nette magic class Nette\Object { public function __call($name, $args) {

    foreach ($this->{"on$name"} as $cb) { call_user_func_array($cb, $args); } }
  8. Eventy v komponentách

  9. Co je problém? class MyControl extends UI\Control { public function

    handleFoo() { // logic $this->presenter->flashMessage('Yatta!'); $this->redirect('Foo:'); } }
  10. Řešení? class MyControl extends UI\Control { public $onSuccess = [];

    public function handleFoo() { // logic $this->onSuccess($this, $arg); } }
  11. Řešení? $control->onSuccess[] = function () { $this->presenter->flashMessage('Yatta!'); $this->redirect('Foo:'); };

  12. Kdyby/Events

  13. Naco další event systém? • není to lazy • kompatibilita

    s otatními systémy ◦ doctrine\orm ◦ symfony\event-dispatcher
  14. Lazy eventy? $circle->onChange[] = function($arg) use ($foo) { $foo->hardWork($arg); };

    $circle->onChange[] = function($arg) use ($bar) { $bar->hardWork($arg); };
  15. Doctrine ORM? class Listener implements EventSubscriber { function getSubscribedEvents() {

    return ['onFoo', 'onBar']; } function onFoo($args) { // ... }
  16. Doctrine ORM? $evm = new EventManager(); $evm->addEventSubscriber( new Listener() );

  17. Doctrine ORM? $evm->dispatch( 'onFoo', new Args($foo, $radius) );

  18. Symfony? class Listener implements EventSubscriberInterface { function getSubscribedEvents() { return

    ['onFoo', 'onBar']; } function onFoo($args) { // ... }
  19. Symfony? $evd = new EventDispatcher(); $evd->addSubscriber( new Listener() );

  20. Symfony? $evm->dispatch( 'onFoo', new Event($foo, $radius) );

  21. Co takhle, Kdyby se všechny systémy daly používat dohromady?

  22. xkcd.com/927

  23. Kdyby/Events = Nette events (+ Doctrine EventManager)? (+ Symfony EventDispatcher)?

  24. Pojďme vyřešit problém z praxe class OrderProcess { function openOrder();

    function addItem($item); function finish(Order $order);
  25. Nějaké ty basic závislosti public function __construct( EntityManager $em, Nette\Security\User

    $user, Nette\Http\Session $session ){
  26. Požadavek: “Po dokončení objednávky se bude posílat email”

  27. Přidáme posílání emailů... public function __construct( EntityManager $em, Nette\Security\User $user,

    Nette\Http\Session $session, Nette\Mail\IMailer $mailer ){
  28. Požadavek: “Přidej mi tam kredity za objednávky”

  29. Přidáme kredity.. public function __construct( EntityManager $em, Nette\Security\User $user, Nette\Http\Session

    $session, Nette\Mail\IMailer $mailer, My\CreditsRewarder $rewarder ){
  30. Požadavek: “Jeden partner chce objednávky posílat do svého pokladního systému”

  31. 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 ){
  32. Požadavek: “Budeme posílat smsky”

  33. 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 ){
  34. Požadavek: “V příštích 6 hodinách vracej 50% hodnoty objednávky v

    kreditech, za všechny objednané burgery”
  35. SRP (Single Responsibility Principle)

  36. Vraťme se na začátek... public function __construct( EntityManager $em, Nette\Security\User

    $user, Nette\Http\Session $session ){
  37. … a přidejme si jeden event class OrderProcess public $onFinish

    = []; function finish(Order $order) { // ... $this->onFinish($this, $order); }
  38. … a napíšeme si listenery class OrderMailerListener implements Subscriber {

    function getSubscribedEvents() { return [ 'OrderProcess::onFinish' ]; }
  39. … a napíšeme si listenery class OrderMailerListener function __construct(IMailer $mailer);

    function onFinish(Order $order) { // .. $this->mailer->send($message); }
  40. … 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); }
  41. … a napíšeme si listenery class SmsSenderListener function __construct(Sms\Sender $sender);

    function onFinish(Order $order) { // .. $this->sender->send($message); }
  42. Nezapomenout registrovat events: subscribers: - OrderMailerListener - CreditsRewardListener - SmsSenderListener

  43. Profit!

  44. 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?
  45. A co nějaké nevýhody? • Nevíme vůbec co se zavolá

    • IDE s tím neumí pracovat
  46. PhpStorm ❤ Kdyby/Events

  47. None
  48. None
  49. None
  50. Go follow @juznacz & @matej_21

  51. A co ty message queue? Dáme demo?

  52. Závěrem? Eventy nejsou silver bullet, užívejte s rozumem.

  53. Dotazy?

  54. Díky za pozornost! filip-prochazka.com Follow me maybe? @ProchazkaFilip