Skip to content

Instantly share code, notes, and snippets.

@dadamssg
Last active December 31, 2015 23:49
Show Gist options
  • Save dadamssg/8062159 to your computer and use it in GitHub Desktop.
Save dadamssg/8062159 to your computer and use it in GitHub Desktop.
<?php
namespace Acme\DemoBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Acme\DemoBundle\Form\ContactType;
// these import the "@Route" and "@Template" annotations
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;
class DemoController extends Controller
{
/**
* @Route("/", name="_demo")
* @Template()
*/
public function indexAction()
{
return array();
}
/**
* @Route("/hello/{name}", name="_demo_hello")
* @Template()
*/
public function helloAction($name)
{
$x = '';
$obj = new \stdClass;
$obj->x = '';
$first = function() use ($obj) {
$obj->x .= ' 1 ';
yield ControlFlow::NEXT;
$obj->x .= ' 2 ';
};
$second = function() use ($obj){
$obj->x .= ' 3 ';
yield ControlFlow::NEXT;
$obj->x .= ' 4 ';
};
$third = function() use ($obj){
$obj->x .= ' 5 ';
return ControlFlow::NEXT;
};
$fourth = function() use ($obj){
$obj->x .= ' 6 ';
return ControlFlow::NEXT;
};
$flow = new ControlFlow;
$flow->queue($first())
->queue($second())
->queue($third)
->queue($fourth);
$flow->run();
return array('name' => $name, 'x' => $obj->x);
}
/**
* @Route("/contact", name="_demo_contact")
* @Template()
*
public function contactAction()
{
$form = $this->get('form.factory')->create(new ContactType());
$request = $this->get('request');
if ($request->isMethod('POST')) {
$form->submit($request);
if ($form->isValid()) {
$mailer = $this->get('mailer');
// .. setup a message and send it
// http://symfony.com/doc/current/cookbook/email.html
$this->get('session')->getFlashBag()->set('notice', 'Message sent!');
return new RedirectResponse($this->generateUrl('_demo'));
}
}
return array('form' => $form->createView());
}
*/
}
class ControlFlow
{
const NEXT = 'NEXT';
/**
* @var array
*/
protected $queued = [];
/**
* @var array
*/
protected $initiated = [];
/**
* Add to the ControlFlow
*
* @param \Closure|\Generator $item
* @return $this
* @throws \InvalidArgumentException
*/
public function queue($item)
{
if ( ! $item instanceof \Closure && ! $item instanceof \Generator) {
throw new \InvalidArgumentException('Queued item must be a \Closure or \Generator');
}
$this->queued[] = $item;
return $this;
}
/**
* Run all queued
*
* @return void
*/
public function run()
{
foreach ($this->queued as $queued) {
$this->runQueued($queued);
}
$this->flush();
}
/**
* Run a queued \Closure or \Generator
*
* @param \Closure|\Generator $queued
* @return void
*/
private function runQueued($queued)
{
if (in_array($queued, $this->initiated, true)) return;
$this->initiated[] = $queued;
if ($queued instanceof \Generator) {
$this->runGenerator($queued);
} elseif ($queued instanceof \Closure) {
$this->runClosure($queued);
}
}
/**
* Run a queued closure
*
* @param \Closure $closure
* @return void
*/
private function runClosure(\Closure $closure)
{
if ($closure() === self::NEXT) {
$this->initiateNext();
}
}
/**
* Run a queued Generator
*
* @param \Generator $generator
* @return void
*/
private function runGenerator(\Generator $generator)
{
foreach ($generator as $result) {
if ($result === self::NEXT) {
$this->initiateNext();
}
}
}
/**
* Initiate the next queued
*
* @return void
*/
private function initiateNext()
{
$next = current($this->queued);
next($this->queued);
$this->runQueued($next);
}
/**
* Empty the ControlFlow
*
* @return void
*/
public function flush()
{
$this->queued = [];
$this->initiated = [];
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment