Skip to content

Commit

Permalink
feature #613 Configure specific state machine component for a resourc…
Browse files Browse the repository at this point in the history
…e (loic425)

This PR was merged into the 1.11 branch.

Discussion
----------

| Q               | A
| --------------- | -----
| Bug fix?        | no
| New feature?    | yes
| BC breaks?      | no
| Deprecations?   | no
| Related tickets | 
| License         | MIT







Commits
-------

3da36b9 Configure specific state machine component for a resource
85cad9f Change state_machine to controller_state_machine
  • Loading branch information
lchrusciel authored Feb 26, 2023
2 parents 99a9869 + 85cad9f commit c64ee13
Show file tree
Hide file tree
Showing 8 changed files with 224 additions and 2 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
<?php

/*
* This file is part of the Sylius package.
*
* (c) Paweł Jędrzejewski
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

declare(strict_types=1);

namespace Sylius\Bundle\ResourceBundle\DependencyInjection\Compiler;

use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;

final class RegisterResourceStateMachinePass implements CompilerPassInterface
{
public function process(ContainerBuilder $container): void
{
if (!$container->hasParameter('sylius.resources')) {
return;
}

/** @var array $resources */
$resources = $container->getParameter('sylius.resources');

foreach ($resources as $alias => $configuration) {
[$applicationName, $resourceName] = explode('.', $alias, 2);
$stateMachineId = sprintf('%s.controller_state_machine.%s', $applicationName, $resourceName);

$stateMachineComponent = $configuration['state_machine_component'] ?? null;

if (null === $stateMachineComponent) {
$container->setAlias($stateMachineId, 'sylius.resource_controller.state_machine');

continue;
}

$specificStateMachineId = sprintf('sylius.resource_controller.state_machine.%s', $stateMachineComponent);

if (!$container->hasDefinition($specificStateMachineId)) {
throw new \LogicException(sprintf('State machine "%s" is not available.', $stateMachineComponent));
}

$container->setAlias($stateMachineId, $specificStateMachineId);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,9 @@ public function process(ContainerBuilder $container): void
$settings = $container->getParameter('sylius.resource.settings');
$stateMachine = $settings['state_machine_component'];

$this->registerWinzouStateMachine($container);
$this->registerSymfonyWorkflowStateMachine($container);

if (null !== $stateMachine) {
$this->setStateMachine($container, $stateMachine);

Expand Down Expand Up @@ -82,6 +85,28 @@ private function setWinzouAsStateMachine(ContainerBuilder $container): void
$stateMachineDefinition->addArgument(new Reference('sm.factory'));
}

private function registerWinzouStateMachine(ContainerBuilder $container): void
{
if (!$this->isWinzouStateMachineEnabled($container)) {
return;
}

$stateMachineDefinition = $container->register('sylius.resource_controller.state_machine.winzou', StateMachine::class);
$stateMachineDefinition->setPublic(false);
$stateMachineDefinition->addArgument(new Reference('sm.factory'));
}

private function registerSymfonyWorkflowStateMachine(ContainerBuilder $container): void
{
if (!$this->isSymfonyWorkflowEnabled($container)) {
return;
}

$stateMachineDefinition = $container->register('sylius.resource_controller.state_machine.symfony', Workflow::class);
$stateMachineDefinition->setPublic(false);
$stateMachineDefinition->addArgument(new Reference('workflow.registry'));
}

private function setSymfonyWorkflowAsStateMachine(ContainerBuilder $container): void
{
if (!$this->isSymfonyWorkflowEnabled($container)) {
Expand Down
1 change: 1 addition & 0 deletions src/Bundle/DependencyInjection/Configuration.php
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ private function addResourcesSection(ArrayNodeDefinition $node): void
->scalarNode('driver')->defaultValue(SyliusResourceBundle::DRIVER_DOCTRINE_ORM)->end()
->variableNode('options')->end()
->scalarNode('templates')->cannotBeEmpty()->end()
->scalarNode('state_machine_component')->defaultNull()->end()
->arrayNode('classes')
->isRequired()
->addDefaultsIfNotSet()
Expand Down
2 changes: 1 addition & 1 deletion src/Bundle/DependencyInjection/Driver/AbstractDriver.php
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ protected function addController(ContainerBuilder $container, MetadataInterface
new Reference('sylius.resource_controller.flash_helper'),
new Reference('sylius.resource_controller.authorization_checker'),
new Reference('sylius.resource_controller.event_dispatcher'),
new Reference('sylius.resource_controller.state_machine', ContainerInterface::NULL_ON_INVALID_REFERENCE),
new Reference($metadata->getServiceId('controller_state_machine'), ContainerInterface::NULL_ON_INVALID_REFERENCE),
new Reference('sylius.resource_controller.resource_update_handler'),
new Reference('sylius.resource_controller.resource_delete_handler'),
])
Expand Down
2 changes: 2 additions & 0 deletions src/Bundle/SyliusResourceBundle.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
use Sylius\Bundle\ResourceBundle\DependencyInjection\Compiler\RegisterFqcnControllersPass;
use Sylius\Bundle\ResourceBundle\DependencyInjection\Compiler\RegisterResourceRepositoryPass;
use Sylius\Bundle\ResourceBundle\DependencyInjection\Compiler\RegisterResourcesPass;
use Sylius\Bundle\ResourceBundle\DependencyInjection\Compiler\RegisterResourceStateMachinePass;
use Sylius\Bundle\ResourceBundle\DependencyInjection\Compiler\RegisterStateMachinePass;
use Sylius\Bundle\ResourceBundle\DependencyInjection\Compiler\TwigPass;
use Sylius\Bundle\ResourceBundle\DependencyInjection\Compiler\WinzouStateMachinePass;
Expand Down Expand Up @@ -50,6 +51,7 @@ public function build(ContainerBuilder $container): void
$container->addCompilerPass(new RegisterResourceRepositoryPass());
$container->addCompilerPass(new RegisterResourcesPass());
$container->addCompilerPass(new RegisterStateMachinePass());
$container->addCompilerPass(new RegisterResourceStateMachinePass());
$container->addCompilerPass(new TwigPass());
$container->addCompilerPass(new WinzouStateMachinePass());

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
<?php

/*
* This file is part of the Sylius package.
*
* (c) Paweł Jędrzejewski
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

declare(strict_types=1);

namespace DependencyInjection\Compiler;

use Matthias\SymfonyDependencyInjectionTest\PhpUnit\AbstractCompilerPassTestCase;
use Sylius\Bundle\ResourceBundle\Controller\StateMachine;
use Sylius\Bundle\ResourceBundle\Controller\Workflow;
use Sylius\Bundle\ResourceBundle\DependencyInjection\Compiler\RegisterResourceStateMachinePass;
use Sylius\Bundle\ResourceBundle\Tests\DependencyInjection\Compiler\AuthorClass;
use Sylius\Bundle\ResourceBundle\Tests\DependencyInjection\Compiler\BookClass;
use Sylius\Bundle\ResourceBundle\Tests\DependencyInjection\Compiler\PullRequestClass;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Definition;

final class RegisterResourceStateMachinePassTest extends AbstractCompilerPassTestCase
{
/** @test */
public function it_registers_state_machine_components_for_resources(): void
{
$this->registerService('sylius.resource_controller.state_machine', StateMachine::class);
$this->makeSymfonyWorkflowAvailable();
$this->makeWinzouStateMachineAvailable();

$this->setDefinition('sylius.resource_registry', new Definition());

$this->setParameter(
'sylius.resources',
[
'app.book' => ['state_machine_component' => 'symfony', 'classes' => ['model' => BookClass::class]],
'app.author' => ['state_machine_component' => 'winzou', 'classes' => ['model' => AuthorClass::class]],
'app.pull_request' => ['classes' => ['model' => PullRequestClass::class]],
],
);

$this->compile();

$this->assertContainerBuilderHasAlias('app.controller_state_machine.book', 'sylius.resource_controller.state_machine.symfony');
$this->assertContainerBuilderHasAlias('app.controller_state_machine.author', 'sylius.resource_controller.state_machine.winzou');
$this->assertContainerBuilderHasAlias('app.controller_state_machine.pull_request', 'sylius.resource_controller.state_machine');
}

/** @test */
public function it_throws_an_exception_when_specific_symfony_state_machine_component_is_not_available(): void
{
$this->registerService('sylius.resource_controller.state_machine', StateMachine::class);
$this->makeWinzouStateMachineAvailable();

$this->setDefinition('sylius.resource_registry', new Definition());

$this->setParameter(
'sylius.resources',
[
'app.book' => ['state_machine_component' => 'symfony', 'classes' => ['model' => BookClass::class]],
'app.author' => ['state_machine_component' => 'winzou', 'classes' => ['model' => AuthorClass::class]],
'app.pull_request' => ['classes' => ['model' => PullRequestClass::class]],
],
);

$error = false;

try {
$this->compile();
} catch (\LogicException $exception) {
$error = true;
$message = $exception->getMessage();
}

$this->assertTrue($error, 'Should not compile');
$this->assertEquals('State machine "symfony" is not available.', $message);
}

/** @test */
public function it_throws_an_exception_when_specific_winzou_state_machine_component_is_not_available(): void
{
$this->registerService('sylius.resource_controller.state_machine', Workflow::class);
$this->makeSymfonyWorkflowAvailable();

$this->setDefinition('sylius.resource_registry', new Definition());

$this->setParameter(
'sylius.resources',
[
'app.book' => ['state_machine_component' => 'symfony', 'classes' => ['model' => BookClass::class]],
'app.author' => ['state_machine_component' => 'winzou', 'classes' => ['model' => AuthorClass::class]],
'app.pull_request' => ['classes' => ['model' => PullRequestClass::class]],
],
);

$error = false;

try {
$this->compile();
} catch (\LogicException $exception) {
$error = true;
$message = $exception->getMessage();
}

$this->assertTrue($error, 'Should not compile');
$this->assertEquals('State machine "winzou" is not available.', $message);
}

protected function registerCompilerPass(ContainerBuilder $container): void
{
$container->addCompilerPass(new RegisterResourceStateMachinePass());
}

private function makeWinzouStateMachineAvailable(): void
{
$this->registerService('sylius.resource_controller.state_machine.winzou', StateMachine::class);
}

private function makeSymfonyWorkflowAvailable(): void
{
$this->registerService('sylius.resource_controller.state_machine.symfony', Workflow::class);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -70,3 +70,7 @@ class BookClass extends AbstractResource
class AuthorClass extends AbstractResource
{
}

class PullRequestClass extends AbstractResource
{
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,15 @@
final class RegisterStateMachinePassTest extends AbstractCompilerPassTestCase
{
/** @test */
public function it_does_nothing_when_no_state_machine_are_available_and_no_state_machine_is_configured(): void
public function it_does_nothing_when_no_state_machine_are_available(): void
{
$this->setParameter('sylius.resource.settings', ['state_machine_component' => null]);

$this->compile();

$this->assertContainerBuilderNotHasService('sylius.resource_controller.state_machine');
$this->assertContainerBuilderNotHasService('sylius.resource_controller.state_machine.symfony');
$this->assertContainerBuilderNotHasService('sylius.resource_controller.state_machine.winzou');
}

/** @test */
Expand All @@ -44,6 +46,8 @@ public function it_registers_state_machine_controller_with_symfony_workflow_when
$this->compile();

$this->assertContainerBuilderHasService('sylius.resource_controller.state_machine', Workflow::class);
$this->assertContainerBuilderHasService('sylius.resource_controller.state_machine.symfony', Workflow::class);
$this->assertContainerBuilderNotHasService('sylius.resource_controller.state_machine.winzou');
}

/** @test */
Expand All @@ -55,6 +59,8 @@ public function it_registers_state_machine_controller_with_winzou_when_its_confi
$this->compile();

$this->assertContainerBuilderHasService('sylius.resource_controller.state_machine', StateMachine::class);
$this->assertContainerBuilderHasService('sylius.resource_controller.state_machine.winzou', StateMachine::class);
$this->assertContainerBuilderNotHasService('sylius.resource_controller.state_machine.symfony');
}

/** @test */
Expand All @@ -66,6 +72,8 @@ public function it_registers_state_machine_controller_with_symfony_workflow_by_d
$this->compile();

$this->assertContainerBuilderHasService('sylius.resource_controller.state_machine', Workflow::class);
$this->assertContainerBuilderHasService('sylius.resource_controller.state_machine.symfony', Workflow::class);
$this->assertContainerBuilderNotHasService('sylius.resource_controller.state_machine.winzou');
}

/** @test */
Expand All @@ -77,6 +85,8 @@ public function it_registers_state_machine_controller_with_winzou_by_default_whe
$this->compile();

$this->assertContainerBuilderHasService('sylius.resource_controller.state_machine', StateMachine::class);
$this->assertContainerBuilderHasService('sylius.resource_controller.state_machine.winzou', StateMachine::class);
$this->assertContainerBuilderNotHasService('sylius.resource_controller.state_machine.symfony');
}

/** @test */
Expand All @@ -89,6 +99,8 @@ public function it_registers_state_machine_controller_with_winzou_by_default_whe
$this->compile();

$this->assertContainerBuilderHasService('sylius.resource_controller.state_machine', StateMachine::class);
$this->assertContainerBuilderHasService('sylius.resource_controller.state_machine.winzou', StateMachine::class);
$this->assertContainerBuilderHasService('sylius.resource_controller.state_machine.symfony', Workflow::class);
}

protected function registerCompilerPass(ContainerBuilder $container): void
Expand Down

0 comments on commit c64ee13

Please sign in to comment.