Skip to content

Instantly share code, notes, and snippets.

@guillemcanal
Last active December 31, 2015 07:59
Show Gist options
  • Save guillemcanal/7957949 to your computer and use it in GitHub Desktop.
Save guillemcanal/7957949 to your computer and use it in GitHub Desktop.
ServiceLayer with event dispatching
{
"name": "starfleet/voyager",
"authors": [
{
"name": "Guillem CANAL",
"email": "nobody@nowhere.tld"
}
],
"require": {
"symfony/event-dispatcher": "~2.4"
}
}
<?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