Skip to content

Commit

Permalink
[Workflow] Add some PHP attributes to register listeners and guards
Browse files Browse the repository at this point in the history
  • Loading branch information
lyrixx committed Aug 1, 2023
1 parent 7597687 commit 1b14718
Show file tree
Hide file tree
Showing 11 changed files with 388 additions and 0 deletions.
Expand Up @@ -1109,6 +1109,29 @@ private function registerWorkflowConfiguration(array $config, ContainerBuilder $
$container->setParameter('workflow.has_guard_listeners', true);
}
}

$listenerAttributes = [
Workflow\Attribute\AsAnnounceListener::class,
Workflow\Attribute\AsCompletedListener::class,
Workflow\Attribute\AsEnterListener::class,
Workflow\Attribute\AsEnteredListener::class,
Workflow\Attribute\AsGuardListener::class,
Workflow\Attribute\AsLeaveListener::class,
Workflow\Attribute\AsTransitionListener::class,
];

foreach ($listenerAttributes as $attribute) {
$container->registerAttributeForAutoconfiguration($attribute, static function (ChildDefinition $definition, AsEventListener $attribute, \ReflectionClass|\ReflectionMethod $reflector) {
$tagAttributes = get_object_vars($attribute);
if ($reflector instanceof \ReflectionMethod) {
if (isset($tagAttributes['method'])) {
throw new LogicException(sprintf('"%s" attribute cannot declare a method on "%s::%s()".', $attribute::class, $reflector->class, $reflector->name));
}
$tagAttributes['method'] = $reflector->getName();
}
$definition->addTag('kernel.event_listener', $tagAttributes);
});
}
}

private function registerDebugConfiguration(array $config, ContainerBuilder $container, PhpFileLoader $loader): void
Expand Down
33 changes: 33 additions & 0 deletions src/Symfony/Component/Workflow/Attribute/AsAnnounceListener.php
@@ -0,0 +1,33 @@
<?php

/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace Symfony\Component\Workflow\Attribute;

use Symfony\Component\EventDispatcher\Attribute\AsEventListener;

/**
* @author Grégoire Pineau <lyrixx@lyrixx.info>
*/
#[\Attribute(\Attribute::TARGET_CLASS | \Attribute::TARGET_METHOD | \Attribute::IS_REPEATABLE)]
final class AsAnnounceListener extends AsEventListener
{
use BuildEventNameTrait;

public function __construct(
string $workflow = null,
string $transition = null,
string $method = null,
int $priority = 0,
string $dispatcher = null,
) {
parent::__construct($this->buildEventName('announce', 'transition', $workflow, $transition), $method, $priority, $dispatcher);
}
}
33 changes: 33 additions & 0 deletions src/Symfony/Component/Workflow/Attribute/AsCompletedListener.php
@@ -0,0 +1,33 @@
<?php

/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace Symfony\Component\Workflow\Attribute;

use Symfony\Component\EventDispatcher\Attribute\AsEventListener;

/**
* @author Grégoire Pineau <lyrixx@lyrixx.info>
*/
#[\Attribute(\Attribute::TARGET_CLASS | \Attribute::TARGET_METHOD | \Attribute::IS_REPEATABLE)]
final class AsCompletedListener extends AsEventListener
{
use BuildEventNameTrait;

public function __construct(
string $workflow = null,
string $transition = null,
string $method = null,
int $priority = 0,
string $dispatcher = null,
) {
parent::__construct($this->buildEventName('completed', 'transition', $workflow, $transition), $method, $priority, $dispatcher);
}
}
33 changes: 33 additions & 0 deletions src/Symfony/Component/Workflow/Attribute/AsEnterListener.php
@@ -0,0 +1,33 @@
<?php

/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace Symfony\Component\Workflow\Attribute;

use Symfony\Component\EventDispatcher\Attribute\AsEventListener;

/**
* @author Grégoire Pineau <lyrixx@lyrixx.info>
*/
#[\Attribute(\Attribute::TARGET_CLASS | \Attribute::TARGET_METHOD | \Attribute::IS_REPEATABLE)]
final class AsEnterListener extends AsEventListener
{
use BuildEventNameTrait;

public function __construct(
string $workflow = null,
string $place = null,
string $method = null,
int $priority = 0,
string $dispatcher = null,
) {
parent::__construct($this->buildEventName('enter', 'place', $workflow, $place), $method, $priority, $dispatcher);
}
}
33 changes: 33 additions & 0 deletions src/Symfony/Component/Workflow/Attribute/AsEnteredListener.php
@@ -0,0 +1,33 @@
<?php

/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace Symfony\Component\Workflow\Attribute;

use Symfony\Component\EventDispatcher\Attribute\AsEventListener;

/**
* @author Grégoire Pineau <lyrixx@lyrixx.info>
*/
#[\Attribute(\Attribute::TARGET_CLASS | \Attribute::TARGET_METHOD | \Attribute::IS_REPEATABLE)]
final class AsEnteredListener extends AsEventListener
{
use BuildEventNameTrait;

public function __construct(
string $workflow = null,
string $place = null,
string $method = null,
int $priority = 0,
string $dispatcher = null,
) {
parent::__construct($this->buildEventName('entered', 'place', $workflow, $place), $method, $priority, $dispatcher);
}
}
33 changes: 33 additions & 0 deletions src/Symfony/Component/Workflow/Attribute/AsGuardListener.php
@@ -0,0 +1,33 @@
<?php

/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace Symfony\Component\Workflow\Attribute;

use Symfony\Component\EventDispatcher\Attribute\AsEventListener;

/**
* @author Grégoire Pineau <lyrixx@lyrixx.info>
*/
#[\Attribute(\Attribute::TARGET_CLASS | \Attribute::TARGET_METHOD | \Attribute::IS_REPEATABLE)]
final class AsGuardListener extends AsEventListener
{
use BuildEventNameTrait;

public function __construct(
string $workflow = null,
string $transition = null,
string $method = null,
int $priority = 0,
string $dispatcher = null,
) {
parent::__construct($this->buildEventName('guard', 'transition', $workflow, $transition), $method, $priority, $dispatcher);
}
}
33 changes: 33 additions & 0 deletions src/Symfony/Component/Workflow/Attribute/AsLeaveListener.php
@@ -0,0 +1,33 @@
<?php

/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace Symfony\Component\Workflow\Attribute;

use Symfony\Component\EventDispatcher\Attribute\AsEventListener;

/**
* @author Grégoire Pineau <lyrixx@lyrixx.info>
*/
#[\Attribute(\Attribute::TARGET_CLASS | \Attribute::TARGET_METHOD | \Attribute::IS_REPEATABLE)]
final class AsLeaveListener extends AsEventListener
{
use BuildEventNameTrait;

public function __construct(
string $workflow = null,
string $place = null,
string $method = null,
int $priority = 0,
string $dispatcher = null,
) {
parent::__construct($this->buildEventName('leave', 'place', $workflow, $place), $method, $priority, $dispatcher);
}
}
33 changes: 33 additions & 0 deletions src/Symfony/Component/Workflow/Attribute/AsTransitionListener.php
@@ -0,0 +1,33 @@
<?php

/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace Symfony\Component\Workflow\Attribute;

use Symfony\Component\EventDispatcher\Attribute\AsEventListener;

/**
* @author Grégoire Pineau <lyrixx@lyrixx.info>
*/
#[\Attribute(\Attribute::TARGET_CLASS | \Attribute::TARGET_METHOD | \Attribute::IS_REPEATABLE)]
final class AsTransitionListener extends AsEventListener
{
use BuildEventNameTrait;

public function __construct(
string $workflow = null,
string $transition = null,
string $method = null,
int $priority = 0,
string $dispatcher = null,
) {
parent::__construct($this->buildEventName('transition', 'transition', $workflow, $transition), $method, $priority, $dispatcher);
}
}
37 changes: 37 additions & 0 deletions src/Symfony/Component/Workflow/Attribute/BuildEventNameTrait.php
@@ -0,0 +1,37 @@
<?php

/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace Symfony\Component\Workflow\Attribute;

/**
* @author Grégoire Pineau <lyrixx@lyrixx.info>
*
* @internal
*/
trait BuildEventNameTrait
{
private function buildEventName(string $keyword, string $argument, string $workflow = null, string $node = null)
{
if (null === $workflow) {
if (null !== $node) {
throw new \LogicException(sprintf('The "%s" argument of "%s" cannot be used without a "workflow" argument.', $argument, self::class));
}

return sprintf('workflow.%s', $keyword);
}

if (null === $node) {
return sprintf('workflow.%s.%s', $workflow, $keyword);
}

return sprintf('workflow.%s.%s.%s', $workflow, $keyword, $node);
}
}
1 change: 1 addition & 0 deletions src/Symfony/Component/Workflow/CHANGELOG.md
Expand Up @@ -8,6 +8,7 @@ CHANGELOG
transitions and workflow's metadata into dumped graph
* Add support for storing marking in a property
* Add a profiler
* Add some PHP attributes to register listeners and guards

6.2
---
Expand Down

0 comments on commit 1b14718

Please sign in to comment.