Skip to content

Instantly share code, notes, and snippets.

@dannykopping
Created August 10, 2019 12:30
Show Gist options
  • Save dannykopping/fa036f5f8d28b957ebf69af4d568a80b to your computer and use it in GitHub Desktop.
Save dannykopping/fa036f5f8d28b957ebf69af4d568a80b to your computer and use it in GitHub Desktop.
<?php
require 'vendor/autoload.php';
use Psr\Log\LoggerInterface;
use Symfony\Component\EventDispatcher\EventDispatcher;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\Workflow\DefinitionBuilder;
use Symfony\Component\Workflow\Event\Event;
use Symfony\Component\Workflow\Event\GuardEvent;
use Symfony\Component\Workflow\EventListener\AuditTrailListener;
use Symfony\Component\Workflow\Exception\NotEnabledTransitionException;
use Symfony\Component\Workflow\MarkingStore\MethodMarkingStore;
use Symfony\Component\Workflow\StateMachine;
use Symfony\Component\Workflow\SupportStrategy\InstanceOfSupportStrategy;
use Symfony\Component\Workflow\Tests\EventListener\Logger;
use Symfony\Component\Workflow\Transition;
use Symfony\Component\Workflow\TransitionBlocker;
class BlogPost
{
protected $id;
protected $subject;
protected $title;
/**
* @return mixed
*/
public function getTitle()
{
return $this->title;
}
/**
* @param mixed $title
*/
public function setTitle($title): void
{
$this->title = $title;
}
protected $currentState = 'draft';
/**
* @return mixed
*/
public function getSubject()
{
return $this->subject;
}
/**
* @param mixed $subject
*/
public function setSubject($subject): void
{
$this->subject = $subject;
}
/**
* BlogPost constructor.
* @param $id
*/
public function __construct($id)
{
$this->id = $id;
}
/**
* @return mixed
*/
public function getId()
{
return $this->id;
}
/**
* @param mixed $id
*/
public function setId($id): void
{
$this->id = $id;
}
/**
* @return string
*/
public function getCurrentState(): string
{
return $this->currentState;
}
/**
* @param string $currentState
*/
public function setCurrentState(string $currentState): void
{
var_dump('setting: '.$currentState);
$this->currentState = $currentState;
}
}
class WorkflowLogger implements EventSubscriberInterface
{
private $logger;
public function __construct(LoggerInterface $logger)
{
$this->logger = $logger;
}
public function guardPublish(GuardEvent $event)
{
var_dump('attempting transition', [
'current' => $event->getSubject()->getCurrentState(),
'transition' => $event->getTransition()->getName(),
]);
/** @var BlogPost $post */
$post = $event->getSubject();
$title = $post->getTitle();
if (empty($title)) {
$event->addTransitionBlocker(new TransitionBlocker('Blocked', 0, ['bob' => 'hello']));
$event->setBlocked(true);
return;
}
}
public static function getSubscribedEvents()
{
return [
'workflow.blog_publishing.guard.publish' => ['guardPublish'],
];
}
}
$definitionBuilder = new DefinitionBuilder();
$definition = $definitionBuilder->addPlaces(['draft', 'reviewed', 'rejected', 'published'])
// Transitions are defined with a unique name, an origin place and a destination place
->addTransition(new Transition('to_review', 'draft', 'reviewed'))
->addTransition(new Transition('publish', 'reviewed', 'published'))
->addTransition(new Transition('reject', 'reviewed', 'rejected'))
->build()
;
$singleState = true; // true if the subject can be in only one state at a given time
$property = 'currentState'; // subject property name where the state is stored
$marking = new MethodMarkingStore($singleState, $property);
$logger = new Logger();
$ed = new EventDispatcher();
$ed->addSubscriber(new AuditTrailListener($logger));
$ed->addSubscriber(new WorkflowLogger($logger));
$workflow = new StateMachine($definition, $marking, $ed, 'blog_publishing');
$registry = new \Symfony\Component\Workflow\Registry();
$registry->addWorkflow($workflow, new InstanceOfSupportStrategy(BlogPost::class));
$blogPost = new BlogPost(19);
$workflow = $registry->get($blogPost);
$workflow->apply($blogPost, 'to_review'); // $blogPost is now in place "reviewed"
try{
// $workflow->apply($blogPost, 'publish'); // $blogPost is now in place "reviewed"
} catch(NotEnabledTransitionException $e) {
foreach($e->getTransitionBlockerList() as $blocker) {
var_dump($blocker);
}
}
var_dump($logger->logs);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment