Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Configure specific state machine component for a resource #613

Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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.state_machine.%s', $applicationName, $resourceName);
loic425 marked this conversation as resolved.
Show resolved Hide resolved

$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);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Won't workflow be a better naming?

Suggested change
$stateMachineDefinition = $container->register('sylius.resource_controller.state_machine.symfony', Workflow::class);
$stateMachineDefinition = $container->register('sylius.resource_controller.state_machine.workflow', Workflow::class);

Copy link
Member Author

@loic425 loic425 Feb 26, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We name it symfony previously cause we named winzou the other one and we don't know if a future component from another owner could be named workflow too. Moreover symfony/workflow use both state machines or workflow, I think it can be confusing with type.
Capture d’écran du 2023-02-27 09-44-34

$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('state_machine'), ContainerInterface::NULL_ON_INVALID_REFERENCE),
loic425 marked this conversation as resolved.
Show resolved Hide resolved
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.state_machine.book', 'sylius.resource_controller.state_machine.symfony');
$this->assertContainerBuilderHasAlias('app.state_machine.author', 'sylius.resource_controller.state_machine.winzou');
$this->assertContainerBuilderHasAlias('app.state_machine.pull_request', 'sylius.resource_controller.state_machine');
loic425 marked this conversation as resolved.
Show resolved Hide resolved
}

/** @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