Skip to content

Commit ccdcbbc

Browse files
committed
feature #21935 [FrameworkBundle][Workflow] Add a way to register a guard expression in the configuration (lyrixx)
This PR was merged into the 3.3-dev branch. Discussion ---------- [FrameworkBundle][Workflow] Add a way to register a guard expression in the configuration | Q | A | ------------- | --- | Branch? | master | Bug fix? | no | New feature? | yes | BC breaks? | no | Deprecations? | no | Tests pass? | yes | Fixed tickets | - | License | MIT | Doc PR | - --- Many people already asked for this feature so ... here we go 🎉 --- Usage: ```yml transitions: journalist_approval: guard: "is_fully_authenticated() and has_role('ROLE_JOURNALIST') or is_granted('POST_EDIT', subject)" from: wait_for_journalist to: approved_by_journalist publish: guard: "subject.isPublic()" from: approved_by_journalist to: published ``` Commits ------- ab3b12d6dc [FrameworkBundle][Workflow] Add a way to register a guard expression in the configuration
2 parents 47d1e4e + 7f91d84 commit ccdcbbc

File tree

3 files changed

+31
-0
lines changed

3 files changed

+31
-0
lines changed

DependencyInjection/Configuration.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -336,6 +336,11 @@ private function addWorkflowSection(ArrayNodeDefinition $rootNode)
336336
->isRequired()
337337
->cannotBeEmpty()
338338
->end()
339+
->scalarNode('guard')
340+
->cannotBeEmpty()
341+
->info('An expression to block the transition')
342+
->example('is_fully_authenticated() and has_role(\'ROLE_JOURNALIST\') and subject.getTitle() == \'My first article\'')
343+
->end()
339344
->arrayNode('from')
340345
->beforeNormalization()
341346
->ifString()

DependencyInjection/FrameworkExtension.php

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -499,6 +499,30 @@ private function registerWorkflowConfiguration(array $workflows, ContainerBuilde
499499
$listener->addArgument(new Reference('logger'));
500500
$container->setDefinition(sprintf('%s.listener.audit_trail', $workflowId), $listener);
501501
}
502+
503+
// Add Guard Listener
504+
$guard = new Definition(Workflow\EventListener\GuardListener::class);
505+
$configuration = array();
506+
foreach ($workflow['transitions'] as $transitionName => $config) {
507+
if (!isset($config['guard'])) {
508+
continue;
509+
}
510+
$eventName = sprintf('workflow.%s.guard.%s', $name, $transitionName);
511+
$guard->addTag('kernel.event_listener', array('event' => $eventName, 'method' => 'onTransition'));
512+
$configuration[$eventName] = $config['guard'];
513+
}
514+
if ($configuration) {
515+
$guard->setArguments(array(
516+
$configuration,
517+
new Reference('workflow.security.expression_language'),
518+
new Reference('security.token_storage'),
519+
new Reference('security.authorization_checker'),
520+
new Reference('security.authentication.trust_resolver'),
521+
new Reference('security.role_hierarchy'),
522+
));
523+
524+
$container->setDefinition(sprintf('%s.listener.guard', $workflowId), $guard);
525+
}
502526
}
503527
}
504528

Resources/config/workflow.xml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,5 +27,7 @@
2727
<argument type="service" id="workflow.registry" />
2828
<tag name="twig.extension" />
2929
</service>
30+
31+
<service id="workflow.security.expression_language" class="Symfony\Component\Workflow\EventListener\ExpressionLanguage" public="false" />
3032
</services>
3133
</container>

0 commit comments

Comments
 (0)