Writing Extensible Code Using Event Dispatcher

D3e3f4ac37c02289f5dfed115949fc88?s=47 John Kary
October 20, 2012

Writing Extensible Code Using Event Dispatcher

Demonstrate refactoring a typical Controller to using Symfony2 EventDispatcher component to make writing decoupled code easier.

D3e3f4ac37c02289f5dfed115949fc88?s=128

John Kary

October 20, 2012
Tweet

Transcript

  1. 2.

    ABOUT PHP since 2005 Contract PHP Developer in Lawrence Education

    & Trucking Industry Previously of University of Kansas - IT
  2. 4.

    Overview 1. Procedural PHP 2. Refactor to Object-Oriented PHP 3.

    Extensibility 4. Controllers in Model View Controller 5. EventDispatcher concept 6. Refactor to using an EventDispatcher 7. EventDispatcher caveats
  3. 5.

    Maybe you know about... JavaScript Events Basics of Object-Oriented Programming

    Inheritance Polymorphism Encapsulation Abstraction Delegation Dependency Injection Single Responsibility Principle Separation of Concerns MVC
  4. 6.
  5. 8.

    John, Customers are unhappy. Send them a “Welcome!” email after

    they register on the web site. Tell them we are glad to have them as a customer. That’ll teach ‘em. Do it now. The Boss The Boss
  6. 13.

    Procedural PHP $_POST = array( 'name' => 'John Kary', 'email'

    => 'john@johnkary.net', ); $to = $_POST['email']; $subject = 'New Account'; $message = "Welcome " . $_POST['name'] . "! Your new space has been created! Use this link to login: https://activate.demcrookidwidgitz.com/code/Sq9284tWBnWgpjw Thanks! DemCrookidWigitz"; $headers = array(); $headers[] = 'From: accounts@demcrookidwigitz.com'; $headers[] = 'Reply-To: contact@demcrookidwigitz.com'; $headers[] = 'X-Mailer: PHP/' . phpversion(); mail($to, $subject, $message, implode($headers, "\r\n"));
  7. 15.

    Object-Oriented PHP $_POST = array( 'name' => 'John Kary', 'email'

    => 'john@johnkary.net', ); $to = $_POST['email']; $subject = 'New Account'; $message = "Welcome " . $_POST['name'] . "! Your new space has been created! Use this link to login: https://activate.demcrookidwidgitz.com/code/Sq9284tWBnWgpjw Thanks! DemCrookidWigitz"; $headers = array(); $headers[] = 'From: accounts@demcrookidwigitz.com'; $headers[] = 'Reply-To: contact@demcrookidwigitz.com'; $headers[] = 'X-Mailer: PHP/' . phpversion(); mail($to, $subject, $message, implode($headers, "\r\n")); Customer
  8. 16.

    Object-Oriented PHP class Customer { public function __construct(array $data) {

    $this->name = $data['name']; $this->email = $data['email']; } public function getName() { return $this->name; } public function getEmail() { return $this->email; } }
  9. 17.

    Object-Oriented PHP $_POST = array( 'name' => 'John Kary', 'email'

    => 'john@johnkary.net', ); $to = $_POST['email']; $subject = 'New Account'; $message = "Welcome " . $_POST['name'] . "! Your new space has been created! Use this link to login: https://activate.demcrookidwidgitz.com/code/Sq9284tWBnWgpjw Thanks! DemCrookidWigitz"; $headers = array(); $headers[] = 'From: accounts@demcrookidwigitz.com'; $headers[] = 'Reply-To: contact@demcrookidwigitz.com'; $headers[] = 'X-Mailer: PHP/' . phpversion(); mail($to, $subject, $message, implode($headers, "\r\n")); Customer WelcomeEmail
  10. 18.

    class WelcomeEmail { public function send($to, $name) { return mail($to,

    $this->getSubject(), $this->getMessage($name), $this->getHeaders()); } protected function getSubject() { return 'New Account'; } protected function getMessage($name) { return "Welcome " . $name . "! Your new space has been created! Use this link to login: https://activate.demcrookidwigitz.com/code/Sq9284tWBnWgpjw Thanks! DemCrookidWigitz"; } protected function getHeaders() { $headers = array(); $headers[] = 'From: accounts@demcrookidwigitz.com'; $headers[] = 'Reply-To: help@demcrookidwigitz.com'; $headers[] = 'X-Mailer: PHP/' . phpversion(); return implode($headers, "\r\n"); } }
  11. 19.

    Object-Oriented PHP $_POST = array( 'name' => 'John Kary', 'email'

    => 'john@johnkary.net', ); $to = $_POST['email']; $subject = 'New Account'; $message = "Welcome " . $_POST['name'] . "! Your new space has been created! Use this link to login: https://activate.demcrookidwidgitz.com/code/Sq9284tWBnWgpjw Thanks! DemCrookidWigitz"; $headers = array(); $headers[] = 'From: accounts@demcrookidwigitz.com'; $headers[] = 'Reply-To: contact@demcrookidwigitz.com'; $headers[] = 'X-Mailer: PHP/' . phpversion(); mail($to, $subject, $message, implode($headers, "\r\n")); Customer WelcomeEmail Controller
  12. 20.

    class Controller { // POST http://demcrookidwigitz.com/person public function newCustomer() {

    $customer = new Customer($_POST); $email = new WelcomeEmail(); $email->send($customer->getEmail(), $customer->getName()); } } Object-Oriented PHP
  13. 21.

    John, Advertising wants to know how many new customers we’re

    getting. Setup some logging. I don’t want their grubby hands on the database. That’ll teach ‘em. Do it now. The Boss The Boss
  14. 23.

    Disk Logging class Controller { public function newCustomer() { $customer

    = new Customer($_POST); $email = new WelcomeEmail(); $email->send($customer->getEmail()); $dLog = new DiskLogger('/logs/prod.log'); $msg = 'Sent welcome email to '.$customer->getName(). ' at '.$customer->getEmail(); $dLog->log($msg); } }
  15. 24.
  16. 25.

    John, Marketing wants to run statistics on orders. Keep them

    away from the database too. Just add to that other log file we setup for Advertising. That’ll teach ‘em. Do it now. The Boss The Boss
  17. 27.

    More Disk Logging class Controller { public function newCustomer() {

    // ... $dLog = new DiskLogger('/logs/prod.log'); $msg = 'Sent welcome email to '.$customer->getName(). ' at '.$customer->getEmail(); $dLog->log($msg); } public function createOrder() { // ... $dLog = new DiskLogger('/logs/prod.log'); $dLog->log('Created order ' . $number); } public function cancelOrder() { // ... $dLog = new DiskLogger('/logs/prod.log'); $dLog->log('Cancelled order number ' . $number); } }
  18. 28.
  19. 30.

    class Controller { public function newCustomer() { // ... $dLog

    = new DiskLogger('/logs/prod.log'); $msg = 'Sent welcome email to '.$customer->getName(). ' at '.$customer->getEmail(); $dLog->log($msg); $eLog = new EmailLogger('boss@demcrookidwigitz.com'); $eLog->log($customer->getName() . ' has registered!'); } public function createOrder() { // ... $dLog = new DiskLogger('/logs/prod.log'); $dLog->log('Created order ' . $number); } public function cancelOrder() { // ... $dLog = new DiskLogger('/logs/prod.log'); $dLog->log('Cancelled order number ' . $number); $eLog = new EmailLogger('boss@demcrookidwigitz.com'); $eLog->log($customer->getName() . ' cancelled their order...'); } }
  20. 31.

    class Controller { public function newCustomer() { // ... $dLog

    = new DiskLogger('/logs/prod.log'); $msg = 'Sent welcome email to '.$customer->getName(). ' at '.$customer->getEmail(); $dLog->log($msg); $eLog = new EmailLogger('boss@demcrookidwigitz.com'); $eLog->log($customer->getName() . ' has registered!'); } public function createOrder() { // ... $dLog = new DiskLogger('/logs/prod.log'); $dLog->log('Created order ' . $number); $twitter = new Twitter('demcrookidwigitz', 'b3@tb0Xpr0$'); $twitter->tweet($customer->getName().' just ordered from us!'); } public function cancelOrder() { // ... $dLog = new DiskLogger('/logs/prod.log'); $dLog->log('Cancelled order number ' . $number); $eLog = new EmailLogger('boss@demcrookidwigitz.com'); $eLog->log($customer->getName() . ' cancelled their order...');
  21. 33.

    ?

  22. 34.

    class Controller { public function newCustomer() { $customer = new

    Customer($_POST); $email = new WelcomeEmail(); $email->send($customer->getEmail()); $dLog = new DiskLogger('/logs/prod.log'); $msg = 'Sent welcome email to '.$customer->getName(); $dLog->log($msg); $eLog = new EmailLogger('boss@demcrookidwigitz.com'); $eLog->log($customer->getName() . ' has registered!'); } public function createOrder() { // ... $dLog = new DiskLogger('/logs/prod.log'); $dLog->log('Created order ' . $number); $twitter = new Twitter('demcrookidwigitz', 'b3@tb0Xpr0$'); $twitter->tweet($customer->getName() . ' just ordered from us!'); } public function cancelOrder() { // ... $dLog = new DiskLogger('/logs/prod.log'); $dLog->log('Cancelled order number ' . $number); $eLog = new EmailLogger('boss@demcrookidwigitz.com'); $eLog->log($customer->getName() . ' cancelled their order...'); } }
  23. 35.

    class Controller { public function newCustomer() { $customer = new

    Customer($_POST); $email = new WelcomeEmail(); $email->send($customer->getEmail()); $dLog = new DiskLogger('/logs/prod.log'); $msg = 'Sent welcome email to '.$customer->getName(); $dLog->log($msg); $eLog = new EmailLogger('boss@demcrookidwigitz.com'); $eLog->log($customer->getName() . ' has registered!'); } public function createOrder() { // ... $dLog = new DiskLogger('/logs/prod.log'); $dLog->log('Created order ' . $number); $twitter = new Twitter('demcrookidwigitz', 'b3@tb0Xpr0$'); $twitter->tweet($customer->getName() . ' just ordered from us!'); } public function cancelOrder() { // ... $dLog = new DiskLogger('/logs/prod.log'); $dLog->log('Cancelled order number ' . $number); $eLog = new EmailLogger('boss@demcrookidwigitz.com'); $eLog->log($customer->getName() . ' cancelled their order...'); } }
  24. 36.

    class Controller { public function newCustomer() { $customer = new

    Customer($_POST); $email = new WelcomeEmail(); $email->send($customer->getEmail()); $dLog = new DiskLogger('/logs/prod.log'); $msg = 'Sent welcome email to '.$customer->getName(); $dLog->log($msg); $eLog = new EmailLogger('boss@demcrookidwigitz.com'); $eLog->log($customer->getName() . ' has registered!'); } public function createOrder() { // ... $dLog = new DiskLogger('/logs/prod.log'); $dLog->log('Created order ' . $number); $twitter = new Twitter('demcrookidwigitz', 'b3@tb0Xpr0$'); $twitter->tweet($customer->getName() . ' just ordered from us!'); } public function cancelOrder() { // ... $dLog = new DiskLogger('/logs/prod.log'); $dLog->log('Cancelled order number ' . $number); $eLog = new EmailLogger('boss@demcrookidwigitz.com'); $eLog->log($customer->getName() . ' cancelled their order...'); } }
  25. 37.

    class Controller { public function newCustomer() { $customer = new

    Customer($_POST); $email = new WelcomeEmail(); $email->send($customer->getEmail()); $dLog = new DiskLogger('/logs/prod.log'); $msg = 'Sent welcome email to '.$customer->getName(); $dLog->log($msg); $eLog = new EmailLogger('boss@demcrookidwigitz.com'); $eLog->log($customer->getName() . ' has registered!'); } public function createOrder() { // ... $dLog = new DiskLogger('/logs/prod.log'); $dLog->log('Created order ' . $number); $twitter = new Twitter('demcrookidwigitz', 'b3@tb0Xpr0$'); $twitter->tweet($customer->getName() . ' just ordered from us!'); } public function cancelOrder() { // ... $dLog = new DiskLogger('/logs/prod.log'); $dLog->log('Cancelled order number ' . $number); $eLog = new EmailLogger('boss@demcrookidwigitz.com'); $eLog->log($customer->getName() . ' cancelled their order...'); } }
  26. 38.

    Extensibility [A] system design principle where the implementation takes into

    consideration future growth. Extensibility - Wikipedia http://en.wikipedia.org/wiki/Extensibility
  27. 39.

    class Controller { public function newCustomer() { $customer = new

    Customer($_POST); $email = new WelcomeEmail(); $email->send($customer->getEmail()); $dLog = new DiskLogger('/logs/prod.log'); $msg = 'Sent welcome email to '.$customer->getName(); $dLog->log($msg); $eLog = new EmailLogger('boss@demcrookidwigitz.com'); $eLog->log($customer->getName() . ' has registered!'); } public function createOrder() { // ... $dLog = new DiskLogger('/logs/prod.log'); $dLog->log('Created order ' . $number); $twitter = new Twitter('demcrookidwigitz', 'b3@tb0Xpr0$'); $twitter->tweet($customer->getName() . ' just ordered from us!'); } public function cancelOrder() { // ... $dLog = new DiskLogger('/logs/prod.log'); $dLog->log('Cancelled order number ' . $number); $eLog = new EmailLogger('boss@demcrookidwigitz.com'); $eLog->log($customer->getName() . ' cancelled their order...'); } }
  28. 40.

    class Controller { public function newCustomer() { $customer = new

    Customer($_POST); $email = new WelcomeEmail(); $email->send($customer->getEmail()); $dLog = new DiskLogger('/logs/prod.log'); $msg = 'Sent welcome email to '.$customer->getName(); $dLog->log($msg); $eLog = new EmailLogger('boss@demcrookidwigitz.com'); $eLog->log($customer->getName() . ' has registered!'); } public function createOrder() { // ... $dLog = new DiskLogger('/logs/prod.log'); $dLog->log('Created order ' . $number); $twitter = new Twitter('demcrookidwigitz', 'b3@tb0Xpr0$'); $twitter->tweet($customer->getName() . ' just ordered from us!'); } public function cancelOrder() { // ... $dLog = new DiskLogger('/logs/prod.log'); $dLog->log('Cancelled order number ' . $number); $eLog = new EmailLogger('boss@demcrookidwigitz.com'); $eLog->log($customer->getName() . ' cancelled their order...'); } } NOT EXTENSIBLE!
  29. 58.

    Event Dispatcher - Register Listeners CartListener:: onAddToCart() EventDispatcher cart.add CustomerListener::

    onRegister() customer.register CartListener:: grantDiscount() cart.checkout
  30. 59.

    Event Dispatcher - Register Listeners use Symfony\Component\EventDispatcher\EventDispatcher; $dispatcher = new

    EventDispatcher(); $listener = new CustomerListener(); $dispatcher->addListener('customer.register', array($listener, 'onRegister')); // Register more listeners class CustomerListener { public function onRegister(CustomerEvent $event) { // Do some work } } Any PHP Callable true === is_callable()
  31. 60.

    Event Dispatcher - Register Listeners use Symfony\Component\EventDispatcher\EventDispatcher; $dispatcher = new

    EventDispatcher(); $dispatcher->addListener('customer.register', array('CustomerListener', 'onRegister')); // Register more listeners class CustomerListener { public static function onRegister(CustomerEvent $event) { // Do some work } }
  32. 61.

    Event Dispatcher - Register Listeners use Symfony\Component\EventDispatcher\EventDispatcher; $dispatcher = new

    EventDispatcher(); $dispatcher->addListener('customer.register', function(CustomerEvent $event) { // Do some work });
  33. 64.

    Request Response Event Dispatcher - Dispatch an Event EventDispatcher “customer.register”

    CustomerListener:: onRegister() “cart.add” CartListener:: onAddToCart() “cart.checkout” CartListener:: grantDiscount()
  34. 65.

    Request Response CustomerEvent “customer.register” Customer Event Dispatcher - Dispatch an

    Event EventDispatcher “customer.register” CustomerListener:: onRegister() “cart.add” CartListener:: onAddToCart() “cart.checkout” CartListener:: grantDiscount()
  35. 66.

    Request Response CustomerEvent “customer.register” Customer Event Dispatcher - Dispatch an

    Event EventDispatcher “customer.register” CustomerListener:: onRegister() “cart.add” CartListener:: onAddToCart() “cart.checkout” CartListener:: grantDiscount()
  36. 67.

    Event Dispatcher - Dispatch an Event use Symfony\Component\EventDispatcher\EventDispatcher; class CustomerController

    { public function __construct(EventDispatcher $dispatcher) { $this->dispatcher = $dispatcher; } public function newCustomer() { $customer = new Customer(array( 'first_name' => 'Bob', 'last_name' => 'Smith', 'email' => 'bobsmith@gmail.com', )); $event = new CustomerEvent($customer); $this->dispatcher->dispatch('customer.register', $event); } } Customer Event Event Name
  37. 68.

    Request Response CustomerEvent “customer.register” Customer Event Dispatcher - Dispatch an

    Event EventDispatcher “customer.register” CustomerListener:: onRegister() “cart.add” CartListener:: onAddToCart() “cart.checkout” CartListener:: grantDiscount()
  38. 69.

    Request Response CustomerEvent “customer.register” Customer Event Dispatcher - Dispatch an

    Event EventDispatcher “customer.register” CustomerListener:: onRegister() “cart.add” CartListener:: onAddToCart() “cart.checkout” CartListener:: grantDiscount() $this->dispatcher->dispatch('customer.register', $event);
  39. 70.

    Request Response CustomerEvent “customer.register” Customer Event Dispatcher - Dispatch an

    Event EventDispatcher “customer.register” CustomerListener:: onRegister() “cart.add” CartListener:: onAddToCart() “cart.checkout” CartListener:: grantDiscount()
  40. 71.

    Request Response CustomerEvent “customer.register” Customer Event Dispatcher - Dispatch an

    Event EventDispatcher “customer.register” CustomerListener:: onRegister() “cart.add” CartListener:: onAddToCart() “cart.checkout” CartListener:: grantDiscount() “customer.register” CustomerListener:: onRegister()
  41. 72.

    Event Dispatcher - Handle the Event class CustomerListener { public

    function onRegister(CustomerEvent $event) { $customer = $event->getCustomer(); $name = $event->getName(); $dispatcher = $event->getDispatcher(); // Do something with Customer object } } CustomerEvent “customer.register” Customer
  42. 73.

    Event Dispatcher - Handle the Event class CustomerListener { public

    function onRegister(CustomerEvent $event) { $customer = $event->getCustomer(); $name = $event->getName(); $dispatcher = $event->getDispatcher(); // Do something with Customer object } }
  43. 74.

    Event Dispatcher - Handle the Event use Symfony\Component\EventDispatcher\Event; class CustomerEvent

    extends Event { protected $customer; public function __construct(Customer $customer) { $this->customer = $customer; } public function getCustomer() { return $this->customer; } }
  44. 77.

    Event Dispatcher - All together now! CartListener:: onAddToCart() CustomerListener:: onRegister()

    CartListener:: grantDiscount() EventDispatcher cart.checkout cart.add customer.register
  45. 78.

    Event Dispatcher - All together now! CartListener:: onAddToCart() CustomerListener:: onRegister()

    CartListener:: grantDiscount() EventDispatcher “cart.checkout” CartListener:: grantDiscount() “cart.add” CartListener:: onAddToCart() “customer.register” CustomerListener:: onRegister()
  46. 79.

    CustomerEvent “customer.register” Customer Event Dispatcher - All together now! CartListener::

    onAddToCart() CustomerListener:: onRegister() CartListener:: grantDiscount() EventDispatcher “cart.checkout” CartListener:: grantDiscount() “cart.add” CartListener:: onAddToCart() “customer.register” CustomerListener:: onRegister()
  47. 80.

    CustomerEvent “customer.register” Customer Event Dispatcher - All together now! CartListener::

    onAddToCart() CustomerListener:: onRegister() CartListener:: grantDiscount() EventDispatcher “cart.checkout” CartListener:: grantDiscount() “cart.add” CartListener:: onAddToCart() “customer.register” CustomerListener:: onRegister() $this->dispatcher->dispatch('customer.register', $event);
  48. 81.

    CustomerEvent “customer.register” Customer Event Dispatcher - All together now! CartListener::

    onAddToCart() CustomerListener:: onRegister() CartListener:: grantDiscount() EventDispatcher “cart.checkout” CartListener:: grantDiscount() “cart.add” CartListener:: onAddToCart() “customer.register” CustomerListener:: onRegister()
  49. 82.

    CustomerEvent “customer.register” Customer Event Dispatcher - All together now! CartListener::

    onAddToCart() CustomerListener:: onRegister() CartListener:: grantDiscount() EventDispatcher “cart.checkout” CartListener:: grantDiscount() “cart.add” CartListener:: onAddToCart() “customer.register” CustomerListener:: onRegister() “customer.register” CustomerListener:: onRegister()
  50. 83.

    CustomerEvent “customer.register” Customer Event Dispatcher - All together now! CartListener::

    onAddToCart() CustomerListener:: onRegister() CartListener:: grantDiscount() EventDispatcher “cart.checkout” CartListener:: grantDiscount() “cart.add” CartListener:: onAddToCart() “customer.register” CustomerListener:: onRegister() “customer.register” CustomerListener:: onRegister() That’s Event Dispatcher!
  51. 85.

    class Controller { public function newCustomer() { $customer = new

    Customer($_POST); $email = new WelcomeEmail(); $email->send($customer->getEmail()); $dLog = new DiskLogger('/logs/prod.log'); $msg = 'Sent welcome email to '.$customer->getName(); $dLog->log($msg); $eLog = new EmailLogger('boss@demcrookidwigitz.com'); $eLog->log($customer->getName() . ' has registered!'); } public function createOrder() { // ... $dLog = new DiskLogger('/logs/prod.log'); $dLog->log('Created order ' . $number); $twitter = new Twitter('demcrookidwigitz', 'b3@tb0Xpr0$'); $twitter->tweet($customer->getName() . ' just ordered from us!'); } public function cancelOrder() { // ... $dLog = new DiskLogger('/logs/prod.log'); $dLog->log('Cancelled order number ' . $number); $eLog = new EmailLogger('boss@demcrookidwigitz.com'); $eLog->log($customer->getName() . ' cancelled their order...'); } } START
  52. 86.

    class Controller { public function __construct(EventDispatcher $dispatcher) { $this->dispatcher =

    $dispatcher; } public function newCustomer() { $customer = new Customer($_POST); $event = new CustomerEvent($customer); $this->dispatcher->dispatch('customer.register', $event); } public function createOrder() { // ... $event = new OrderEvent($order); $this->dispatcher->dispatch('order.new', $event); $event = new CustomerEvent($customer); $this->dispatcher->dispatch('customer.order.new', $event); } public function cancelOrder() { // ... $event = new OrderEvent($order); $this->dispatcher->dispatch('order.cancel', $event); $event = new CustomerEvent($customer); $this->dispatcher->dispatch('customer.order.cancel', $event); } } FINISH
  53. 88.

    class Controller { public function __construct(EventDispatcher $dispatcher) { $this->dispatcher =

    $dispatcher; } public function newCustomer() { $customer = new Customer($_POST); $email = new WelcomeEmail(); $email->send($customer->getEmail()); $dLog = new DiskLogger('/logs/prod.log'); $msg = 'Sent welcome email to '.$customer->getName(); $dLog->log($msg); $eLog = new EmailLogger('boss@demcrookidwigitz.com'); $eLog->log($customer->getName() . ' has registered!'); } public function createOrder() { // ... $dLog = new DiskLogger('/logs/prod.log'); $dLog->log('Created order ' . $number); $twitter = new Twitter('demcrookidwigitz', 'b3@tb0Xpr0$'); $twitter->tweet($customer->getName() . ' just ordered from us!'); } public function cancelOrder() { // ... $dLog = new DiskLogger('/logs/prod.log'); $dLog->log('Cancelled order number ' . $number); $eLog = new EmailLogger('boss@demcrookidwigitz.com');
  54. 90.

    class Controller { public function __construct(EventDispatcher $dispatcher) { $this->dispatcher =

    $dispatcher; } public function newCustomer() { $customer = new Customer($_POST); $email = new WelcomeEmail(); $email->send($customer->getEmail()); $dLog = new DiskLogger('/logs/prod.log'); $msg = 'Sent welcome email to '.$customer->getName(); $dLog->log($msg); $eLog = new EmailLogger('boss@demcrookidwigitz.com'); $eLog->log($customer->getName() . ' has registered!'); } public function createOrder() { // ... $dLog = new DiskLogger('/logs/prod.log'); $dLog->log('Created order ' . $number); $twitter = new Twitter('demcrookidwigitz', 'b3@tb0Xpr0$'); $twitter->tweet($customer->getName() . ' just ordered from us!'); } public function cancelOrder() { // ... $dLog = new DiskLogger('/logs/prod.log'); $dLog->log('Cancelled order number ' . $number); $eLog = new EmailLogger('boss@demcrookidwigitz.com');
  55. 91.

    class Controller { public function __construct(EventDispatcher $dispatcher) { $this->dispatcher =

    $dispatcher; } public function newCustomer() { $customer = new Customer($_POST); $event = new CustomerEvent($customer); $this->dispatcher->dispatch('customer.register', $event); $dLog = new DiskLogger('/logs/prod.log'); $msg = 'Sent welcome email to '.$customer->getName(); $dLog->log($msg); $eLog = new EmailLogger('boss@demcrookidwigitz.com'); $eLog->log($customer->getName() . ' has registered!'); } public function createOrder() { // ... $dLog = new DiskLogger('/logs/prod.log'); $dLog->log('Created order ' . $number); $twitter = new Twitter('demcrookidwigitz', 'b3@tb0Xpr0$'); $twitter->tweet($customer->getName() . ' just ordered from us!'); } public function cancelOrder() { // ... $dLog = new DiskLogger('/logs/prod.log'); $dLog->log('Cancelled order number ' . $number); $eLog = new EmailLogger('boss@demcrookidwigitz.com');
  56. 92.

    use Symfony\Component\EventDispatcher\Event; class CustomerEvent extends Event { protected $customer; public

    function __construct(Customer $customer) { $this->customer = $customer; } public function getCustomer() { return $this->customer; } }
  57. 93.

    use Symfony\Component\EventDispatcher\EventDispatcher; $dispatcher = new EventDispatcher(); // Wire listeners $listener

    = new CustomerEmailListener(new WelcomeEmail()); $dispatcher->addListener('customer.register', array($listener, 'onRegister')); class WelcomeEmail { public function send($to, $name) { return mail($to, $this->getSubject(), $this->getMessage($name), $this->getHeaders()); } protected function getSubject() { return 'New Account'; } protected function getMessage($name) { return "Welcome " . $name . "! Your new space has been created! Use this link to login: https://activate.demcrookidwigitz.com/code/Sq9284tWBnWgpjw Thanks! DemCrookidWigitz"; } protected function getHeaders() { $headers = array(); $headers[] = 'From: accounts@demcrookidwigitz.com';
  58. 94.

    use Symfony\Component\EventDispatcher\EventDispatcher; $dispatcher = new EventDispatcher(); // Wire listeners $listener

    = new CustomerEmailListener(new WelcomeEmail()); $dispatcher->addListener('customer.register', array($listener, 'onRegister'));
  59. 95.

    use Symfony\Component\EventDispatcher\EventDispatcher; $dispatcher = new EventDispatcher(); // Wire listeners $listener

    = new CustomerEmailListener(new WelcomeEmail()); $dispatcher->addListener('customer.register', array($listener, 'onRegister'));
  60. 96.

    use Symfony\Component\EventDispatcher\EventDispatcher; $dispatcher = new EventDispatcher(); // Wire listeners $listener

    = new CustomerEmailListener(new WelcomeEmail()); $dispatcher->addListener('customer.register', array($listener, 'onRegister')); class CustomerEmailListener { public function __construct(WelcomeEmail $email) { $this->email = $email; } public function onRegister(CustomerEvent $event) { $customer = $event->getCustomer(); $this->email->send($customer->getEmail(), $customer->getName()); } }
  61. 97.

    use Symfony\Component\EventDispatcher\EventDispatcher; $dispatcher = new EventDispatcher(); // Wire listeners $listener

    = new CustomerEmailListener(new WelcomeEmail()); $dispatcher->addListener('customer.register', array($listener, 'onRegister')); class CustomerEmailListener { public function __construct(WelcomeEmail $email) { $this->email = $email; } public function onRegister(CustomerEvent $event) { $customer = $event->getCustomer(); $this->email->send($customer->getEmail(), $customer->getName()); } }
  62. 98.

    use Symfony\Component\EventDispatcher\EventDispatcher; $dispatcher = new EventDispatcher(); // Wire listeners $listener

    = new CustomerEmailListener(new WelcomeEmail()); $dispatcher->addListener('customer.register', array($listener, 'onRegister')); class CustomerEmailListener { public function __construct(WelcomeEmail $email) { $this->email = $email; } public function onRegister(CustomerEvent $event) { $customer = $event->getCustomer(); $this->email->send($customer->getEmail(), $customer->getName()); } } class WelcomeEmail { public function send($to, $name) { return mail($to, $this->getSubject(), $this->getMessage($name), $this->getHeaders()); } }
  63. 99.

    use Symfony\Component\EventDispatcher\EventDispatcher; $dispatcher = new EventDispatcher(); // Wire listeners $listener

    = new CustomerEmailListener(new WelcomeEmail()); $dispatcher->addListener('customer.register', array($listener, 'onRegister')); class CustomerEmailListener { public function __construct(WelcomeEmail $email) { $this->email = $email; } public function onRegister(CustomerEvent $event) { $customer = $event->getCustomer(); $this->email->send($customer->getEmail(), $customer->getName()); } } class WelcomeEmail { public function send($to, $name) { return mail($to, $this->getSubject(), $this->getMessage($name), $this->getHeaders()); } }
  64. 101.

    class Controller { public function __construct(EventDispatcher $dispatcher) { $this->dispatcher =

    $dispatcher; } public function newCustomer() { $customer = new Customer($_POST); $event = new CustomerEvent($customer); $this->dispatcher->dispatch('customer.register', $event); $dLog = new DiskLogger('/logs/prod.log'); $msg = 'Sent welcome email to '.$customer->getName(); $dLog->log($msg); $eLog = new EmailLogger('boss@demcrookidwigitz.com'); $eLog->log($customer->getName() . ' has registered!'); } public function createOrder() { // ... $dLog = new DiskLogger('/logs/prod.log'); $dLog->log('Created order ' . $number); $twitter = new Twitter('demcrookidwigitz', 'b3@tb0Xpr0$'); $twitter->tweet($customer->getName() . ' just ordered from us!'); } public function cancelOrder() { // ... $dLog = new DiskLogger('/logs/prod.log'); $dLog->log('Cancelled order number ' . $number); $eLog = new EmailLogger('boss@demcrookidwigitz.com');
  65. 102.

    use Symfony\Component\EventDispatcher\EventDispatcher; $dispatcher = new EventDispatcher(); $diskLogger = new DiskLogger('/logs/prod.log');

    // Wire listeners $listener = new CustomerEmailListener(new WelcomeEmail(), $diskLogger); $dispatcher->addListener('customer.register', array($listener, 'onRegister'));
  66. 103.

    use Symfony\Component\EventDispatcher\EventDispatcher; $dispatcher = new EventDispatcher(); $diskLogger = new DiskLogger('/logs/prod.log');

    // Wire listeners $listener = new CustomerEmailListener(new WelcomeEmail(), $diskLogger); $dispatcher->addListener('customer.register', array($listener, 'onRegister'));
  67. 104.

    use Symfony\Component\EventDispatcher\EventDispatcher; $dispatcher = new EventDispatcher(); $diskLogger = new DiskLogger('/logs/prod.log');

    // Wire listeners $listener = new CustomerEmailListener(new WelcomeEmail(), $diskLogger); $dispatcher->addListener('customer.register', array($listener, 'onRegister')); class CustomerEmailListener { public function __construct(WelcomeEmail $email) { $this->email = $email; } public function onRegister(CustomerEvent $event) { $customer = $event->getCustomer(); $this->email->send($customer->getEmail(), $customer->getName()); } }
  68. 105.

    use Symfony\Component\EventDispatcher\EventDispatcher; $dispatcher = new EventDispatcher(); $diskLogger = new DiskLogger('/logs/prod.log');

    // Wire listeners $listener = new CustomerEmailListener(new WelcomeEmail(), $diskLogger); $dispatcher->addListener('customer.register', array($listener, 'onRegister')); class CustomerEmailListener { public function __construct(WelcomeEmail $email) { $this->email = $email; } public function onRegister(CustomerEvent $event) { $customer = $event->getCustomer(); $this->email->send($customer->getEmail(), $customer->getName()); } } class CustomerEmailListener { public function __construct(WelcomeEmail $email, DiskLogger $logger) { $this->email = $email; $this->logger = $logger; } public function onRegister(CustomerEvent $event) { $customer = $event->getCustomer(); $this->email->send($customer->getEmail(), $customer->getName()); } }
  69. 106.

    use Symfony\Component\EventDispatcher\EventDispatcher; $dispatcher = new EventDispatcher(); $diskLogger = new DiskLogger('/logs/prod.log');

    // Wire listeners $listener = new CustomerEmailListener(new WelcomeEmail(), $diskLogger); $dispatcher->addListener('customer.register', array($listener, 'onRegister')); class CustomerEmailListener { public function __construct(WelcomeEmail $email) { $this->email = $email; } public function onRegister(CustomerEvent $event) { $customer = $event->getCustomer(); $this->email->send($customer->getEmail(), $customer->getName()); } } class CustomerEmailListener { public function __construct(WelcomeEmail $email, DiskLogger $logger) { $this->email = $email; $this->logger = $logger; } public function onRegister(CustomerEvent $event) { $customer = $event->getCustomer(); $this->email->send($customer->getEmail(), $customer->getName()); } }
  70. 107.

    use Symfony\Component\EventDispatcher\EventDispatcher; $dispatcher = new EventDispatcher(); $diskLogger = new DiskLogger('/logs/prod.log');

    // Wire listeners $listener = new CustomerEmailListener(new WelcomeEmail(), $diskLogger); $dispatcher->addListener('customer.register', array($listener, 'onRegister')); class CustomerEmailListener { public function __construct(WelcomeEmail $email) { $this->email = $email; } public function onRegister(CustomerEvent $event) { $customer = $event->getCustomer(); $this->email->send($customer->getEmail(), $customer->getName()); } } class CustomerEmailListener { public function __construct(WelcomeEmail $email, DiskLogger $logger) { $this->email = $email; $this->logger = $logger; } public function onRegister(CustomerEvent $event) { $customer = $event->getCustomer(); $this->email->send($customer->getEmail(), $customer->getName()); } } class CustomerEmailListener { public function __construct(WelcomeEmail $email, DiskLogger $logger) { $this->email = $email; $this->logger = $logger; } public function onRegister(CustomerEvent $event) { $customer = $event->getCustomer(); $this->email->send($customer->getEmail(), $customer->getName()); $this->logger->log('Sent welcome email to ' . $customer->getName()); } }
  71. 108.

    use Symfony\Component\EventDispatcher\EventDispatcher; $dispatcher = new EventDispatcher(); $diskLogger = new DiskLogger('/logs/prod.log');

    // Wire listeners $listener = new CustomerEmailListener(new WelcomeEmail(), $diskLogger); $dispatcher->addListener('customer.register', array($listener, 'onRegister')); class CustomerEmailListener { public function __construct(WelcomeEmail $email) { $this->email = $email; } public function onRegister(CustomerEvent $event) { $customer = $event->getCustomer(); $this->email->send($customer->getEmail(), $customer->getName()); } } class CustomerEmailListener { public function __construct(WelcomeEmail $email, DiskLogger $logger) { $this->email = $email; $this->logger = $logger; } public function onRegister(CustomerEvent $event) { $customer = $event->getCustomer(); $this->email->send($customer->getEmail(), $customer->getName()); } } class CustomerEmailListener { public function __construct(WelcomeEmail $email, DiskLogger $logger) { $this->email = $email; $this->logger = $logger; } public function onRegister(CustomerEvent $event) { $customer = $event->getCustomer(); $this->email->send($customer->getEmail(), $customer->getName()); $this->logger->log('Sent welcome email to ' . $customer->getName()); } }
  72. 109.

    class Controller { public function __construct(EventDispatcher $dispatcher) { $this->dispatcher =

    $dispatcher; } public function newCustomer() { $customer = new Customer($_POST); $event = new CustomerEvent($customer); $this->dispatcher->dispatch('customer.register', $event); $dLog = new DiskLogger('/logs/prod.log'); $msg = 'Sent welcome email to '.$customer->getName(); $dLog->log($msg); $eLog = new EmailLogger('boss@demcrookidwigitz.com'); $eLog->log($customer->getName() . ' has registered!'); } public function createOrder() { // ... $dLog = new DiskLogger('/logs/prod.log'); $dLog->log('Created order ' . $number); $twitter = new Twitter('demcrookidwigitz', 'b3@tb0Xpr0$'); $twitter->tweet($customer->getName() . ' just ordered from us!'); } public function cancelOrder() { // ... $dLog = new DiskLogger('/logs/prod.log'); $dLog->log('Cancelled order number ' . $number); $eLog = new EmailLogger('boss@demcrookidwigitz.com');
  73. 110.

    class Controller { public function __construct(EventDispatcher $dispatcher) { $this->dispatcher =

    $dispatcher; } public function newCustomer() { $customer = new Customer($_POST); $event = new CustomerEvent($customer); $this->dispatcher->dispatch('customer.register', $event); $dLog = new DiskLogger('/logs/prod.log'); $msg = 'Sent welcome email to '.$customer->getName(); $dLog->log($msg); $eLog = new EmailLogger('boss@demcrookidwigitz.com'); $eLog->log($customer->getName() . ' has registered!'); } public function createOrder() { // ... $dLog = new DiskLogger('/logs/prod.log'); $dLog->log('Created order ' . $number); $twitter = new Twitter('demcrookidwigitz', 'b3@tb0Xpr0$'); $twitter->tweet($customer->getName() . ' just ordered from us!'); } public function cancelOrder() { // ... $dLog = new DiskLogger('/logs/prod.log'); $dLog->log('Cancelled order number ' . $number); $eLog = new EmailLogger('boss@demcrookidwigitz.com'); class Controller { public function __construct(EventDispatcher $dispatcher) { $this->dispatcher = $dispatcher; } public function newCustomer() { $customer = new Customer($_POST); $event = new CustomerEvent($customer); $this->dispatcher->dispatch('customer.register', $event); $eLog = new EmailLogger('boss@demcrookidwigitz.com'); $eLog->log($customer->getName() . ' has registered!'); } public function createOrder() { // ... $dLog = new DiskLogger('/logs/prod.log'); $dLog->log('Created order ' . $number); $twitter = new Twitter('demcrookidwigitz', 'b3@tb0Xpr0$'); $twitter->tweet($customer->getName() . ' just ordered from us!'); } public function cancelOrder() { // ... $dLog = new DiskLogger('/logs/prod.log'); $dLog->log('Cancelled order number ' . $number); $eLog = new EmailLogger('boss@demcrookidwigitz.com'); $eLog->log($customer->getName() . ' cancelled their order...'); } }
  74. 111.

    class Controller { public function __construct(EventDispatcher $dispatcher) { $this->dispatcher =

    $dispatcher; } public function newCustomer() { $customer = new Customer($_POST); $event = new CustomerEvent($customer); $this->dispatcher->dispatch('customer.register', $event); $dLog = new DiskLogger('/logs/prod.log'); $msg = 'Sent welcome email to '.$customer->getName(); $dLog->log($msg); $eLog = new EmailLogger('boss@demcrookidwigitz.com'); $eLog->log($customer->getName() . ' has registered!'); } public function createOrder() { // ... $dLog = new DiskLogger('/logs/prod.log'); $dLog->log('Created order ' . $number); $twitter = new Twitter('demcrookidwigitz', 'b3@tb0Xpr0$'); $twitter->tweet($customer->getName() . ' just ordered from us!'); } public function cancelOrder() { // ... $dLog = new DiskLogger('/logs/prod.log'); $dLog->log('Cancelled order number ' . $number); $eLog = new EmailLogger('boss@demcrookidwigitz.com'); class Controller { public function __construct(EventDispatcher $dispatcher) { $this->dispatcher = $dispatcher; } public function newCustomer() { $customer = new Customer($_POST); $event = new CustomerEvent($customer); $this->dispatcher->dispatch('customer.register', $event); $eLog = new EmailLogger('boss@demcrookidwigitz.com'); $eLog->log($customer->getName() . ' has registered!'); } public function createOrder() { // ... $dLog = new DiskLogger('/logs/prod.log'); $dLog->log('Created order ' . $number); $twitter = new Twitter('demcrookidwigitz', 'b3@tb0Xpr0$'); $twitter->tweet($customer->getName() . ' just ordered from us!'); } public function cancelOrder() { // ... $dLog = new DiskLogger('/logs/prod.log'); $dLog->log('Cancelled order number ' . $number); $eLog = new EmailLogger('boss@demcrookidwigitz.com'); $eLog->log($customer->getName() . ' cancelled their order...'); } }
  75. 112.

    use Symfony\Component\EventDispatcher\EventDispatcher; $dispatcher = new EventDispatcher(); $bossEmail = 'boss@demcrookidwigitz.com'; //

    Wire listeners // ... $listener = new BossNewCustomerEmailListener(new BossNewCustomerEmail($bossEmail)); $dispatcher->addListener('customer.register', array($listener, 'onCustomerRegister'));
  76. 113.

    use Symfony\Component\EventDispatcher\EventDispatcher; $dispatcher = new EventDispatcher(); $bossEmail = 'boss@demcrookidwigitz.com'; //

    Wire listeners // ... $listener = new BossNewCustomerEmailListener(new BossNewCustomerEmail($bossEmail)); $dispatcher->addListener('customer.register', array($listener, 'onCustomerRegister'));
  77. 114.

    use Symfony\Component\EventDispatcher\EventDispatcher; $dispatcher = new EventDispatcher(); $bossEmail = 'boss@demcrookidwigitz.com'; //

    Wire listeners // ... $listener = new BossNewCustomerEmailListener(new BossNewCustomerEmail($bossEmail)); $dispatcher->addListener('customer.register', array($listener, 'onCustomerRegister'));
  78. 115.

    use Symfony\Component\EventDispatcher\EventDispatcher; $dispatcher = new EventDispatcher(); $bossEmail = 'boss@demcrookidwigitz.com'; //

    Wire listeners // ... $listener = new BossNewCustomerEmailListener(new BossNewCustomerEmail($bossEmail)); $dispatcher->addListener('customer.register', array($listener, 'onCustomerRegister')); class BossNewCustomerEmail { public function __construct($bossEmail) { $this->bossEmail = $bossEmail; } public function send($name) { return mail($this->bossEmail, $this->getSubject(), $this->getMessage($name), $this->getHeaders()); } protected function getSubject() { return 'New Customer Registered!'; } protected function getMessage($name) { return "Boss! " . $name . " just registered! Sweet, huh?"; } // ... }
  79. 116.

    use Symfony\Component\EventDispatcher\EventDispatcher; $dispatcher = new EventDispatcher(); $bossEmail = 'boss@demcrookidwigitz.com'; //

    Wire listeners // ... $listener = new BossNewCustomerEmailListener(new BossNewCustomerEmail($bossEmail)); $dispatcher->addListener('customer.register', array($listener, 'onCustomerRegister'));
  80. 117.

    use Symfony\Component\EventDispatcher\EventDispatcher; $dispatcher = new EventDispatcher(); $bossEmail = 'boss@demcrookidwigitz.com'; //

    Wire listeners // ... $listener = new BossNewCustomerEmailListener(new BossNewCustomerEmail($bossEmail)); $dispatcher->addListener('customer.register', array($listener, 'onCustomerRegister')); class BossNewCustomerEmailListener { public function __construct(BossNewCustomerEmail $email) { $this->email = $email; } public function onCustomerRegister(CustomerEvent $event) { $customer = $event->getCustomer(); $this->email->send($customer->getName()); } }
  81. 118.

    use Symfony\Component\EventDispatcher\EventDispatcher; $dispatcher = new EventDispatcher(); $bossEmail = 'boss@demcrookidwigitz.com'; //

    Wire listeners // ... $listener = new BossNewCustomerEmailListener(new BossNewCustomerEmail($bossEmail)); $dispatcher->addListener('customer.register', array($listener, 'onCustomerRegister')); class BossNewCustomerEmailListener { public function __construct(BossNewCustomerEmail $email) { $this->email = $email; } public function onCustomerRegister(CustomerEvent $event) { $customer = $event->getCustomer(); $this->email->send($customer->getName()); } }
  82. 119.

    class Controller { public function __construct(EventDispatcher $dispatcher) { $this->dispatcher =

    $dispatcher; } public function newCustomer() { $customer = new Customer($_POST); $event = new CustomerEvent($customer); $this->dispatcher->dispatch('customer.register', $event); $eLog = new EmailLogger('boss@demcrookidwigitz.com'); $eLog->log($customer->getName() . ' has registered!'); } public function createOrder() { // ... $dLog = new DiskLogger('/logs/prod.log'); $dLog->log('Created order ' . $number); $twitter = new Twitter('demcrookidwigitz', 'b3@tb0Xpr0$'); $twitter->tweet($customer->getName() . ' just ordered from us!'); } public function cancelOrder() { // ... $dLog = new DiskLogger('/logs/prod.log'); $dLog->log('Cancelled order number ' . $number); $eLog = new EmailLogger('boss@demcrookidwigitz.com'); $eLog->log($customer->getName() . ' cancelled their order...'); } }
  83. 120.

    class Controller { public function __construct(EventDispatcher $dispatcher) { $this->dispatcher =

    $dispatcher; } public function newCustomer() { $customer = new Customer($_POST); $event = new CustomerEvent($customer); $this->dispatcher->dispatch('customer.register', $event); $eLog = new EmailLogger('boss@demcrookidwigitz.com'); $eLog->log($customer->getName() . ' has registered!'); } public function createOrder() { // ... $dLog = new DiskLogger('/logs/prod.log'); $dLog->log('Created order ' . $number); $twitter = new Twitter('demcrookidwigitz', 'b3@tb0Xpr0$'); $twitter->tweet($customer->getName() . ' just ordered from us!'); } public function cancelOrder() { // ... $dLog = new DiskLogger('/logs/prod.log'); $dLog->log('Cancelled order number ' . $number); $eLog = new EmailLogger('boss@demcrookidwigitz.com'); $eLog->log($customer->getName() . ' cancelled their order...'); } } class Controller { public function __construct(EventDispatcher $dispatcher) { $this->dispatcher = $dispatcher; } public function newCustomer() { $customer = new Customer($_POST); $event = new CustomerEvent($customer); $this->dispatcher->dispatch('customer.register', $event); } public function createOrder() { // ... $dLog = new DiskLogger('/logs/prod.log'); $dLog->log('Created order ' . $number); $twitter = new Twitter('demcrookidwigitz', 'b3@tb0Xpr0$'); $twitter->tweet($customer->getName() . ' just ordered from us!'); } public function cancelOrder() { // ... $dLog = new DiskLogger('/logs/prod.log'); $dLog->log('Cancelled order number ' . $number); $eLog = new EmailLogger('boss@demcrookidwigitz.com'); $eLog->log($customer->getName() . ' cancelled their order...'); } }
  84. 122.

    class Controller { public function __construct(EventDispatcher $dispatcher) { $this->dispatcher =

    $dispatcher; } public function newCustomer() { $customer = new Customer($_POST); $event = new CustomerEvent($customer); $this->dispatcher->dispatch('customer.register', $event); } public function createOrder() { // ... $dLog = new DiskLogger('/logs/prod.log'); $dLog->log('Created order ' . $number); $twitter = new Twitter('demcrookidwigitz', 'b3@tb0Xpr0$'); $twitter->tweet($customer->getName() . ' just ordered from us!'); } public function cancelOrder() { // ... $dLog = new DiskLogger('/logs/prod.log'); $dLog->log('Cancelled order number ' . $number); $eLog = new EmailLogger('boss@demcrookidwigitz.com'); $eLog->log($customer->getName() . ' cancelled their order...'); } }
  85. 123.

    class Controller { public function __construct(EventDispatcher $dispatcher) { $this->dispatcher =

    $dispatcher; } public function newCustomer() { $customer = new Customer($_POST); $event = new CustomerEvent($customer); $this->dispatcher->dispatch('customer.register', $event); } public function createOrder() { // ... $dLog = new DiskLogger('/logs/prod.log'); $dLog->log('Created order ' . $number); $twitter = new Twitter('demcrookidwigitz', 'b3@tb0Xpr0$'); $twitter->tweet($customer->getName() . ' just ordered from us!'); } public function cancelOrder() { // ... $dLog = new DiskLogger('/logs/prod.log'); $dLog->log('Cancelled order number ' . $number); $eLog = new EmailLogger('boss@demcrookidwigitz.com'); $eLog->log($customer->getName() . ' cancelled their order...'); } } class Controller { public function __construct(EventDispatcher $dispatcher) { $this->dispatcher = $dispatcher; } public function newCustomer() { $customer = new Customer($_POST); $event = new CustomerEvent($customer); $this->dispatcher->dispatch('customer.register', $event); } public function createOrder() { // ... $dLog = new DiskLogger('/logs/prod.log'); $dLog->log('Created order ' . $number); $event = new CustomerEvent($customer); $this->dispatcher->dispatch('customer.order.new', $event); } public function cancelOrder() { // ... $dLog = new DiskLogger('/logs/prod.log'); $dLog->log('Cancelled order number ' . $number); $eLog = new EmailLogger('boss@demcrookidwigitz.com'); $eLog->log($customer->getName() . ' cancelled their order...'); } }
  86. 124.

    use Symfony\Component\EventDispatcher\EventDispatcher; $dispatcher = new EventDispatcher(); $twitter = new Twitter('demcrookidwigitz',

    'b3@tb0Xpr0$'); // Wire listeners $listener = new TwitterListener($twitter); $dispatcher->addListener('order.new', array($listener, 'tweetAtOrderer'));
  87. 125.

    use Symfony\Component\EventDispatcher\EventDispatcher; $dispatcher = new EventDispatcher(); $twitter = new Twitter('demcrookidwigitz',

    'b3@tb0Xpr0$'); // Wire listeners $listener = new TwitterListener($twitter); $dispatcher->addListener('order.new', array($listener, 'tweetAtOrderer')); class TwitterListener { public function __construct(Twitter $twitter) { $this->twitter = $twitter; } public function tweetAtOrderer(CustomerEvent $event) { $customer = $event->getOrder(); $msg = $customer->getTwitterHandle().' Thanks for ordering from us!'; $this->twitter->tweet($msg); } }
  88. 126.

    class Controller { public function __construct(EventDispatcher $dispatcher) { $this->dispatcher =

    $dispatcher; } public function newCustomer() { $customer = new Customer($_POST); $event = new CustomerEvent($customer); $this->dispatcher->dispatch('customer.register', $event); } public function createOrder() { // ... $dLog = new DiskLogger('/logs/prod.log'); $dLog->log('Created order ' . $number); $event = new CustomerEvent($customer); $this->dispatcher->dispatch('customer.order.new', $event); } public function cancelOrder() { // ... $dLog = new DiskLogger('/logs/prod.log'); $dLog->log('Cancelled order number ' . $number); $eLog = new EmailLogger('boss@demcrookidwigitz.com'); $eLog->log($customer->getName() . ' cancelled their order...'); } }
  89. 127.

    use Symfony\Component\EventDispatcher\EventDispatcher; $dispatcher = new EventDispatcher(); $bossEmail = 'boss@demcrookidwigitz.com'; //

    Wire listeners // ... $listener = new BossCancelOrderEmailListener(new BossCancelOrderEmail($bossEmail)); $dispatcher->addListener('customer.order.cancel', array($listener, 'onCancelOrder')); class BossCancelOrderEmail { public function __construct($bossEmail) { $this->bossEmail = $bossEmail; } public function send($name) { return mail($this->bossEmail, $this->getSubject(), $this->getMessage($name), $this->getHeaders()); } protected function getSubject() { return 'Customer Order Cancelled'; } protected function getMessage($name) { return "Boss! " . $name . " cancelled their order. Bummer!"; } // ... }
  90. 128.

    use Symfony\Component\EventDispatcher\EventDispatcher; $dispatcher = new EventDispatcher(); $bossEmail = 'boss@demcrookidwigitz.com'; //

    Wire listeners // ... $listener = new BossCancelOrderEmailListener(new BossCancelOrderEmail($bossEmail)); $dispatcher->addListener('customer.order.cancel', array($listener, 'onCancelOrder')); class BossCancelOrderEmailListener { public function __construct(BossCancelOrderEmail $email) { $this->email = $email; } public function onCancelOrder(CustomerEvent $event) { $customer = $event->getCustomer(); $this->email->send($customer->getName()); } }
  91. 129.

    class Controller { public function __construct(EventDispatcher $dispatcher) { $this->dispatcher =

    $dispatcher; } public function newCustomer() { $customer = new Customer($_POST); $event = new CustomerEvent($customer); $this->dispatcher->dispatch('customer.register', $event); } public function createOrder() { // ... $dLog = new DiskLogger('/logs/prod.log'); $dLog->log('Created order ' . $number); $event = new CustomerEvent($customer); $this->dispatcher->dispatch('customer.order.new', $event); } public function cancelOrder() { // ... $dLog = new DiskLogger('/logs/prod.log'); $dLog->log('Cancelled order number ' . $number); $event = new CustomerEvent($customer); $this->dispatcher->dispatch('customer.order.cancel', $event); } }
  92. 131.

    class Controller { public function __construct(EventDispatcher $dispatcher) { $this->dispatcher =

    $dispatcher; } public function newCustomer() { $customer = new Customer($_POST); $event = new CustomerEvent($customer); $this->dispatcher->dispatch('customer.register', $event); } public function createOrder() { // ... $dLog = new DiskLogger('/logs/prod.log'); $dLog->log('Created order ' . $number); $event = new CustomerEvent($customer); $this->dispatcher->dispatch('customer.order.new', $event); } public function cancelOrder() { // ... $dLog = new DiskLogger('/logs/prod.log'); $dLog->log('Cancelled order number ' . $number); $event = new CustomerEvent($customer); $this->dispatcher->dispatch('customer.order.cancel', $event); } }
  93. 132.

    class Controller { public function __construct(EventDispatcher $dispatcher) { $this->dispatcher =

    $dispatcher; } public function newCustomer() { $customer = new Customer($_POST); $event = new CustomerEvent($customer); $this->dispatcher->dispatch('customer.register', $event); } public function createOrder() { // ... $dLog = new DiskLogger('/logs/prod.log'); $dLog->log('Created order ' . $number); $event = new CustomerEvent($customer); $this->dispatcher->dispatch('customer.order.new', $event); } public function cancelOrder() { // ... $dLog = new DiskLogger('/logs/prod.log'); $dLog->log('Cancelled order number ' . $number); $event = new CustomerEvent($customer); $this->dispatcher->dispatch('customer.order.cancel', $event); } } class Controller { public function __construct(EventDispatcher $dispatcher) { $this->dispatcher = $dispatcher; } public function newCustomer() { $customer = new Customer($_POST); $event = new CustomerEvent($customer); $this->dispatcher->dispatch('customer.register', $event); } public function createOrder() { // ... $event = new OrderEvent($order); $this->dispatcher->dispatch('order.new', $event); $event = new CustomerEvent($customer); $this->dispatcher->dispatch('customer.order.new', $event); } public function cancelOrder() { // ... $event = new OrderEvent($order); $this->dispatcher->dispatch('order.cancel', $event); $event = new CustomerEvent($customer); $this->dispatcher->dispatch('customer.order.cancel', $event); } }
  94. 133.

    use Symfony\Component\EventDispatcher\Event; class OrderEvent extends Event { protected $order; public

    function __construct(Order $order) { $this->order = $order; } public function getOrder() { return $this->order; } }
  95. 134.

    use Symfony\Component\EventDispatcher\EventDispatcher; $dispatcher = new EventDispatcher(); $diskLogger = new DiskLogger('/logs/prod.log');

    // Wire listeners $listener = new OrderLoggerListener($diskLogger); $dispatcher->addListener('order.new', array($listener, 'onNewOrder')); class OrderLoggerListener { public function __construct(DiskLogger $logger) { $this->logger = $logger; } public function onNewOrder(OrderEvent $event) { $order = $event->getOrder(); $this->logger->log('Created order number ' . $order->getNumber()); } }
  96. 135.

    use Symfony\Component\EventDispatcher\EventDispatcher; $dispatcher = new EventDispatcher(); $diskLogger = new DiskLogger('/logs/prod.log');

    // Wire listeners $listener = new OrderLoggerListener($diskLogger); $dispatcher->addListener('order.new', array($listener, 'onNewOrder')); $dispatcher->addListener('order.cancel', array($listener, 'onCancelOrder')); class OrderLoggerListener { public function __construct(DiskLogger $logger) { $this->logger = $logger; } public function onNewOrder(OrderEvent $event) { $order = $event->getOrder(); $this->logger->log('Created order number ' . $order->getNumber()); } public function onCancelOrder(OrderEvent $event) { $order = $event->getOrder(); $this->logger->log('Cancelled order number ' . $order->getNumber()); } }
  97. 136.

    class Controller { public function __construct(EventDispatcher $dispatcher) { $this->dispatcher =

    $dispatcher; } public function newCustomer() { $customer = new Customer($_POST); $event = new CustomerEvent($customer); $this->dispatcher->dispatch('customer.register', $event); } public function createOrder() { // ... $event = new OrderEvent($order); $this->dispatcher->dispatch('order.new', $event); $event = new CustomerEvent($customer); $this->dispatcher->dispatch('customer.order.new', $event); } public function cancelOrder() { // ... $event = new OrderEvent($order); $this->dispatcher->dispatch('order.cancel', $event); $event = new CustomerEvent($customer); $this->dispatcher->dispatch('customer.order.cancel', $event); } } FINISH
  98. 137.

    use Symfony\Component\EventDispatcher\EventDispatcher; $dispatcher = new EventDispatcher(); $diskLogger = new DiskLogger('/logs/prod.log');

    $twitter = new Twitter('demcrookidwigitz', 'b3@tb0Xpr0$'); $bossEmail = 'boss@demcrookidwigitz.com'; // Wire listeners $listener = new CustomerEmailListener(new WelcomeEmail()); $dispatcher->addListener('customer.register', array($listener, 'onRegister')); $listener = new BossNewCustomerEmailListener(new BossNewCustomerEmail($bossEmail)); $dispatcher->addListener('customer.register', array($listener, 'onCustomerRegister')); $listener = new BossCancelOrderEmailListener(new BossCancelOrderEmail($bossEmail)); $dispatcher->addListener('customer.order.cancel', array($listener, 'onCancelOrder')); $listener = new OrderLoggerListener($diskLogger); $dispatcher->addListener('order.new', array($listener, 'onNewOrder')); $dispatcher->addListener('order.cancel', array($listener, 'onCancelOrder')); $listener = new TwitterListener($twitter); $dispatcher->addListener('order.new', array($listener, 'tweetAtOrderer')); FINISH
  99. 138.
  100. 140.

    Caveat - Priority use Symfony\Component\EventDispatcher\EventDispatcher; $dispatcher = new EventDispatcher(); $dispatcher->addListener('customer.register',

    function(CustomerEvent $event) { // First }); $dispatcher->addListener('customer.register', function(CustomerEvent $event) { // Second }); $customer = new Customer(); $customer->setEmail('mikesmith@gmail.com'); $event = new CustomerEvent($customer); $dispatcher->dispatch('customer.register', $event); First Second
  101. 142.

    Caveat - Priority use Symfony\Component\EventDispatcher\EventDispatcher; $dispatcher = new EventDispatcher(); $dispatcher->addListener('customer.register',

    function(CustomerEvent $event) { // Second }, 100); $dispatcher->addListener('customer.register', function(CustomerEvent $event) { // First }, 200); $customer = new Customer(); $customer->setEmail('mikesmith@gmail.com'); $event = new CustomerEvent($customer); $dispatcher->dispatch('customer.register', $event); First Second
  102. 143.

    Caveat - Priority use Symfony\Component\EventDispatcher\EventDispatcher; $dispatcher = new EventDispatcher(); $dispatcher->addListener('customer.register',

    function(CustomerEvent $event) { // Third }, 100); $dispatcher->addListener('customer.register', function(CustomerEvent $event) { // First }, 200); $dispatcher->addListener('customer.register', function(CustomerEvent $event) { // Second }, 200); $customer = new Customer(); $customer->setEmail('mikesmith@gmail.com'); $event = new CustomerEvent($customer); $dispatcher->dispatch('customer.register', $event); First Third Second
  103. 147.

    Caveat - Side Effects use Symfony\Component\EventDispatcher\EventDispatcher; $dispatcher = new EventDispatcher();

    $dispatcher->addListener('customer.register', function(CustomerEvent $event) { echo $event->getCustomer()->getEmail(); // mikesmith@gmail.com $event->getCustomer()->setEmail('changed@gmail.com'); }); $dispatcher->addListener('customer.register', function(CustomerEvent $event) { echo $event->getCustomer()->getEmail(); // changed@gmail.com }); $customer = new Customer(); $customer->setEmail('mikesmith@gmail.com'); $event = new CustomerEvent($customer); $dispatcher->dispatch('customer.register', $event); 1. Set Email 2. Get Email 3. Update Email 4. Email not the same
  104. 153.

    Ideas for Utilizing Events • Logging • Offloading expensive operations

    to a message queue • Email, PDF generation, file system access • Setting “created_at” or “updated_at” on an entity • Updating a search index when persisting an entity • Allowing users of your plug-ins to extend their functionality without modifying your code • What ideas have you come up with?
  105. 154.

    Further Reading • Introduction to Symfony2 EventDispatcher http://bit.ly/sf2-event-dispatcher • An

    Introduction to Zend Framework 2 Event Manager http://bit.ly/zf2-event-manater • The S.O.L.I.D. Principles of OO and Agile Design http://bit.ly/uncle-bob-oo-insights
  106. 155.

    Sources • http://lampwww.epfl.ch/~imaier/pub/DeprecatingObserversTR2010.pdf • http://stlab.adobe.com/wiki/index.php/File:2008_07_25_google.pdf Photo Credits • http://www.flickr.com/photos/pedromourapinheiro/2456410959/ •

    http://www.flickr.com/photos/seat850/3893504473/ • http://www.flickr.com/photos/slworking/5170065748/ • http://www.flickr.com/photos/33037982@N04/3727397261/ • http://www.flickr.com/photos/factoryjoe/26967479/
  107. 156.

    John Kary johnkary@ gmail.com @ johnkary Slides @ http://johnkary.net/talks WRITING

    EXTENSIBLE CODE USING EVENT DISPATCHER https://joind.in/7551