Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save Nek-/e689b8fa0e3303800aeb05c56a20edc5 to your computer and use it in GitHub Desktop.
Save Nek-/e689b8fa0e3303800aeb05c56a20edc5 to your computer and use it in GitHub Desktop.
Add mirror previous transitions
<?php
namespace App\Application\Symfony\CompilerPass;
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Definition;
use Symfony\Component\Workflow;
class PreviousWorkflowTransitionCompilerPass implements CompilerPassInterface
{
const PREFIX = 'previous_';
public function process(ContainerBuilder $container)
{
$workflowDefinitionIds = $container->findTaggedServiceIds('workflow.definition');
foreach ($workflowDefinitionIds as $serviceId => $tags) {
$this->addPreviousTransitions($container->getDefinition($serviceId), reset($tags)['type']);
}
}
private function addPreviousTransitions(Definition $definition, string $type)
{
// This method supports only state machine workflow.
if ($type !== 'state_machine') {
return;
}
/** @var Definition[] $transitionsDefinitions */
$transitionsDefinitions = $definition->getArgument(1);
$result = [];
foreach ($transitionsDefinitions as $transitionDefinition) {
$result[] = $transitionDefinition;
$args = $transitionDefinition->getArguments();
$result[] = new Definition(Workflow\Transition::class, [
self::PREFIX . $args[0],
$args[2],
$args[1]
]);
}
$definition->setArgument(1, $result);
}
}
<?php
namespace App\Tests\Application\Symfony\CompilerPass;
use App\Application\Symfony\CompilerPass\PreviousWorkflowTransitionCompilerPass;
use PHPUnit\Framework\TestCase;
use Symfony\Component\DependencyInjection\ChildDefinition;
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Definition;
use Symfony\Component\DependencyInjection\Reference;
use Symfony\Component\Workflow;
class PreviousWorkflowTransitionCompilerPassTest extends TestCase
{
public function testItIsASymfonyCompilerPass()
{
$pass = new PreviousWorkflowTransitionCompilerPass();
$this->assertInstanceOf(CompilerPassInterface::class, $pass);
}
public function testItAddsTransitionsToWorkflow()
{
// Some of this is extracted from FrameworkExtension::registerWorkflowConfiguration
$container = new ContainerBuilder();
$transitionDefinition = new Definition(Workflow\Transition::class, ['to_bar', 'foo', 'bar']);
$definitionDefinition = new Definition(Workflow\Definition::class);
$definitionDefinition->setPublic(false);
$definitionDefinition->addArgument(['foo', 'bar']); // Places
$definitionDefinition->addArgument([$transitionDefinition]); // Transitions
$definitionDefinition->addTag('workflow.definition', array(
'name' => 'adp_lead',
'type' => 'state_machine',
'marking_store' => 'single_state',
));
$definitionDefinition->addArgument('foo'); // initial place
$markingStoreDefinition = new Definition(Workflow\MarkingStore\SingleStateMarkingStore::class, [
'state'
]);
$workflowId = sprintf('%s.%s', 'state_machine', 'adp_lead');
$workflowDefinition = new Definition(Workflow\Workflow::class, [
new Reference(sprintf('%s.definition', $workflowId)),
$markingStoreDefinition,
null,
'adp_lead'
]);
$workflowDefinition->setPublic(true);
$container->setDefinition($workflowId, $workflowDefinition);
$container->setDefinition(sprintf('%s.definition', $workflowId), $definitionDefinition);
$container->addCompilerPass(new PreviousWorkflowTransitionCompilerPass());
$container->compile();
$object = new Foo();
$container->get($workflowId)->apply($object, 'to_bar');
$this->assertEquals('bar', $object->getState());
$container->get($workflowId)->apply($object, PreviousWorkflowTransitionCompilerPass::PREFIX . 'to_bar');
$this->assertEquals('foo', $object->getState());
}
}
class Foo
{
private $state;
public function __construct()
{
$this->state = 'foo';
}
public function setState($state)
{
$this->state = $state;
}
public function getState()
{
return $this->state;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment