Last active
December 31, 2015 07:59
-
-
Save guillemcanal/7957949 to your computer and use it in GitHub Desktop.
ServiceLayer with event dispatching
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"name": "starfleet/voyager", | |
"authors": [ | |
{ | |
"name": "Guillem CANAL", | |
"email": "nobody@nowhere.tld" | |
} | |
], | |
"require": { | |
"symfony/event-dispatcher": "~2.4" | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
use Symfony\Component\EventDispatcher\Event as EventBase; | |
use Symfony\Component\EventDispatcher\EventDispatcher; | |
use Symfony\Component\EventDispatcher\EventDispatcherInterface; | |
use Symfony\Component\EventDispatcher\EventSubscriberInterface; | |
require 'vendor/autoload.php'; | |
// Courtesy of GuzzlePHP | |
// @see https://github.com/guzzle/guzzle/blob/master/src/Guzzle/Common/AbstractHasDispatcher.php | |
// @licence https://github.com/guzzle/guzzle/blob/master/LICENSE | |
trait Dispatcher | |
{ | |
protected $eventDispatcher; | |
public static function getAllEvents() | |
{ | |
return array(); | |
} | |
public function setEventDispatcher(EventDispatcherInterface $eventDispatcher) | |
{ | |
$this->eventDispatcher = $eventDispatcher; | |
return $this; | |
} | |
public function getEventDispatcher() | |
{ | |
if (!$this->eventDispatcher) { | |
$this->eventDispatcher = new EventDispatcher(); | |
} | |
return $this->eventDispatcher; | |
} | |
public function dispatch($eventName, array $context = array()) | |
{ | |
return $this->getEventDispatcher()->dispatch($eventName, new Event($context)); | |
} | |
public function addSubscriber(EventSubscriberInterface $subscriber) | |
{ | |
$this->getEventDispatcher()->addSubscriber($subscriber); | |
return $this; | |
} | |
} | |
class Event extends EventBase | |
{ | |
protected $context; | |
public function __construct(array $context) | |
{ | |
$this->context = $context; | |
} | |
public function __get($name) | |
{ | |
if (!isset($this->context[$name])) { | |
throw new Exception(sprintf('The "%s" context does not exist')); | |
} | |
return $this->context[$name]; | |
} | |
} | |
class NarratorSubscriber implements EventSubscriberInterface | |
{ | |
public static function getSubscribedEvents() | |
{ | |
return array( | |
'episode.before_create' => array('onBeforeCreate', -255), | |
'episode.after_create' => array('onAfterCreate', 255), | |
'episode.create' => array('onCreate', 0) | |
); | |
} | |
public function onBeforeCreate(Event $event) | |
{ | |
printf("[START]: StarDate %s...\n", self::generateStarDate()); | |
} | |
public function onAfterCreate(Event $event) | |
{ | |
printf("[END]: The end... Or is it?\n"); | |
} | |
public function onCreate(Event $event) | |
{ | |
$episode = $event->episode; | |
printf("[TITLE]: %s\n", $episode->getTitle()); | |
} | |
/** | |
* Generate StarDate | |
* @see http://trekguide.com/Stardates.htm | |
* @return float | |
*/ | |
public static function generateStarDate() | |
{ | |
$period = iterator_to_array(new DatePeriod(new DateTime('2371-01-01'), new DateInterval('P1M'), new DateTime('2378-04-06'))); | |
$index = rand(0, count($period) -1); | |
$starDateZero = new DateTime('July 5, 2318 12:00:00'); | |
$seconds = ($period[$index]->getTimestamp() - $starDateZero->getTimestamp()); | |
$findStarYear = $seconds / 34367.0564; | |
$findStarYear = floor($findStarYear * 100); | |
$findStarYear = $findStarYear / 100; | |
return $findStarYear; | |
} | |
} | |
class AssimilationNotification extends Exception {} | |
class BorgCubeSubscriber implements EventSubscriberInterface | |
{ | |
public static function getSubscribedEvents() | |
{ | |
return array( | |
'episode.create' => array('onCreate', 255) | |
); | |
} | |
public function onCreate(Event $event) | |
{ | |
// The odds of a Bord Ship encounter in this sector are about 50% | |
if (rand(0, 1) % 2) { | |
throw new AssimilationNotification("[Borg Cube]: We are the borgs... Prepare to be assimilated... Resistance is futile", 0); | |
} | |
} | |
} | |
class USSVoyagerCrewMembersSubscriber implements EventSubscriberInterface | |
{ | |
public static function getSubscribedEvents() | |
{ | |
return array( | |
'episode.create' => array('randomDialog', 0), | |
'episode.exception' => array('onException', 255) | |
); | |
} | |
public function randomDialog(Event $event) | |
{ | |
switch(rand(1, 3)) { | |
case 1 : $message = '[Janeway]: At ease, Ensign, before you sprain something'; break; | |
case 2 : $message = '[Neelix]: Mr. Vulcan, nice to meet you!'; break; | |
case 3 : $message = '[Doctor]: Please state the nature of the medical emergency'; break; | |
} | |
print $message . PHP_EOL; | |
} | |
public function onException(Event $event) | |
{ | |
$exception = $event->exception; | |
if ($exception instanceof AssimilationNotification) { | |
print $exception->getMessage() . PHP_EOL; | |
print "[Janeway]: Stand-by red alert... Lieutenant Paris, " . | |
"evasive maneuver! Commander Tuvok, modulate the shield frequency to escape their tractor beam" . PHP_EOL; | |
$event->stopPropagation(); | |
} | |
} | |
} | |
class Episode | |
{ | |
protected $id; | |
protected $title; | |
public function setTitle($title) | |
{ | |
$this->title = $title; | |
} | |
public function getTitle() | |
{ | |
return $this->title; | |
} | |
public function setId($id) | |
{ | |
$this->id = $id; | |
} | |
public function getId() | |
{ | |
return $this->id; | |
} | |
} | |
class EpisodeService | |
{ | |
use Dispatcher; | |
public function create($name) | |
{ | |
$this->dispatch('episode.before_create'); | |
$episode = new Episode(); | |
$episode->setTitle($name); | |
try { | |
$episode->setId(1); | |
$this->dispatch('episode.create', array('episode' => $episode)); | |
} catch (Exception $e) { | |
$this->dispatch('episode.exception', array('exception' => $e)); | |
return NULL; | |
} | |
$this->dispatch('episode.after_create', array('episode' => $episode)); | |
return $episode; | |
} | |
} | |
$userService = new EpisodeService(); | |
$userService->addSubscriber(new NarratorSubscriber()); | |
// Uncomment the line below to send borg cube in the vicinity of Voyager | |
// $userService->addSubscriber(new BorgCubeSubscriber()); | |
$userService->addSubscriber(new USSVoyagerCrewMembersSubscriber()); | |
$userService->create('My Episode'); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment