Last active
December 31, 2015 23:49
-
-
Save dadamssg/8062159 to your computer and use it in GitHub Desktop.
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 | |
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