Skip to content

Commit 5284b7f

Browse files
committed
Merge branch '5.4' into 6.0
* 5.4: [Console] Restore psr/log >= 3.0 conflict [Security] Make the abstract Voter class implement CacheableVoterInterface Add generic types to traversable implementations [Security] Fix TypeError message [Security] Fix deprecation layer [FrameworkBundle] Add completion for workflow:dump Fix cancel button Fix misleading error on missing provider with authenticator manager Don't limit retries of toolbar loading
2 parents bf9d0d4 + e89716f commit 5284b7f

File tree

3 files changed

+84
-14
lines changed

3 files changed

+84
-14
lines changed

Command/WorkflowDumpCommand.php

Lines changed: 39 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@
1313

1414
use Symfony\Component\Console\Attribute\AsCommand;
1515
use Symfony\Component\Console\Command\Command;
16+
use Symfony\Component\Console\Completion\CompletionInput;
17+
use Symfony\Component\Console\Completion\CompletionSuggestions;
1618
use Symfony\Component\Console\Exception\InvalidArgumentException;
1719
use Symfony\Component\Console\Input\InputArgument;
1820
use Symfony\Component\Console\Input\InputInterface;
@@ -32,6 +34,21 @@
3234
#[AsCommand(name: 'workflow:dump', description: 'Dump a workflow')]
3335
class WorkflowDumpCommand extends Command
3436
{
37+
private array $workflows = [];
38+
39+
private const DUMP_FORMAT_OPTIONS = [
40+
'puml',
41+
'mermaid',
42+
'dot',
43+
];
44+
45+
public function __construct(array $workflows)
46+
{
47+
parent::__construct();
48+
49+
$this->workflows = $workflows;
50+
}
51+
3552
/**
3653
* {@inheritdoc}
3754
*/
@@ -42,7 +59,7 @@ protected function configure()
4259
new InputArgument('name', InputArgument::REQUIRED, 'A workflow name'),
4360
new InputArgument('marking', InputArgument::IS_ARRAY, 'A marking (a list of places)'),
4461
new InputOption('label', 'l', InputOption::VALUE_REQUIRED, 'Label a graph'),
45-
new InputOption('dump-format', null, InputOption::VALUE_REQUIRED, 'The dump format [dot|puml]', 'dot'),
62+
new InputOption('dump-format', null, InputOption::VALUE_REQUIRED, 'The dump format ['.implode('|', self::DUMP_FORMAT_OPTIONS).']', 'dot'),
4663
])
4764
->setHelp(<<<'EOF'
4865
The <info>%command.name%</info> command dumps the graphical representation of a
@@ -61,19 +78,14 @@ protected function configure()
6178
*/
6279
protected function execute(InputInterface $input, OutputInterface $output): int
6380
{
64-
$container = $this->getApplication()->getKernel()->getContainer();
65-
$serviceId = $input->getArgument('name');
66-
67-
if ($container->has('workflow.'.$serviceId)) {
68-
$workflow = $container->get('workflow.'.$serviceId);
69-
$type = 'workflow';
70-
} elseif ($container->has('state_machine.'.$serviceId)) {
71-
$workflow = $container->get('state_machine.'.$serviceId);
72-
$type = 'state_machine';
73-
} else {
74-
throw new InvalidArgumentException(sprintf('No service found for "workflow.%1$s" nor "state_machine.%1$s".', $serviceId));
81+
$workflowId = $input->getArgument('name');
82+
83+
if (!\in_array($workflowId, array_keys($this->workflows), true)) {
84+
throw new InvalidArgumentException(sprintf('No service found for "workflow.%1$s" nor "state_machine.%1$s".', $workflowId));
7585
}
7686

87+
$type = explode('.', $workflowId)[0];
88+
7789
switch ($input->getOption('dump-format')) {
7890
case 'puml':
7991
$transitionType = 'workflow' === $type ? PlantUmlDumper::WORKFLOW_TRANSITION : PlantUmlDumper::STATEMACHINE_TRANSITION;
@@ -96,15 +108,28 @@ protected function execute(InputInterface $input, OutputInterface $output): int
96108
$marking->mark($place);
97109
}
98110

111+
$workflow = $this->workflows[$workflowId];
112+
99113
$options = [
100-
'name' => $serviceId,
114+
'name' => $workflowId,
101115
'nofooter' => true,
102116
'graph' => [
103117
'label' => $input->getOption('label'),
104118
],
105119
];
106-
$output->writeln($dumper->dump($workflow->getDefinition(), $marking, $options));
120+
$output->writeln($dumper->dump($workflow, $marking, $options));
107121

108122
return 0;
109123
}
124+
125+
public function complete(CompletionInput $input, CompletionSuggestions $suggestions): void
126+
{
127+
if ($input->mustSuggestArgumentValuesFor('name')) {
128+
$suggestions->suggestValues(array_keys($this->workflows));
129+
}
130+
131+
if ($input->mustSuggestOptionValuesFor('dump-format')) {
132+
$suggestions->suggestValues(self::DUMP_FORMAT_OPTIONS);
133+
}
134+
}
110135
}

DependencyInjection/FrameworkExtension.php

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -789,6 +789,8 @@ private function registerWorkflowConfiguration(array $config, ContainerBuilder $
789789

790790
$registryDefinition = $container->getDefinition('workflow.registry');
791791

792+
$workflows = [];
793+
792794
foreach ($config['workflows'] as $name => $workflow) {
793795
$type = $workflow['type'];
794796
$workflowId = sprintf('%s.%s', $type, $name);
@@ -876,6 +878,8 @@ private function registerWorkflowConfiguration(array $config, ContainerBuilder $
876878
$definitionDefinition->addArgument($initialMarking);
877879
$definitionDefinition->addArgument(new Reference(sprintf('%s.metadata_store', $workflowId)));
878880

881+
$workflows[$workflowId] = $definitionDefinition;
882+
879883
// Create MarkingStore
880884
if (isset($workflow['marking_store']['type'])) {
881885
$markingStoreDefinition = new ChildDefinition('workflow.marking_store.method');
@@ -963,6 +967,9 @@ private function registerWorkflowConfiguration(array $config, ContainerBuilder $
963967
$container->setParameter('workflow.has_guard_listeners', true);
964968
}
965969
}
970+
971+
$commandDumpDefinition = $container->getDefinition('console.command.workflow_dump');
972+
$commandDumpDefinition->setArgument(0, $workflows);
966973
}
967974

968975
private function registerDebugConfiguration(array $config, ContainerBuilder $container, PhpFileLoader $loader)
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <[email protected]>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Bundle\FrameworkBundle\Tests\Command;
13+
14+
use PHPUnit\Framework\TestCase;
15+
use Symfony\Bundle\FrameworkBundle\Command\WorkflowDumpCommand;
16+
use Symfony\Component\Console\Application;
17+
use Symfony\Component\Console\Tester\CommandCompletionTester;
18+
19+
class WorkflowDumpCommandTest extends TestCase
20+
{
21+
/**
22+
* @dataProvider provideCompletionSuggestions
23+
*/
24+
public function testComplete(array $input, array $expectedSuggestions)
25+
{
26+
$application = new Application();
27+
$application->add(new WorkflowDumpCommand([]));
28+
29+
$tester = new CommandCompletionTester($application->find('workflow:dump'));
30+
$suggestions = $tester->complete($input, 2);
31+
$this->assertSame($expectedSuggestions, $suggestions);
32+
}
33+
34+
public function provideCompletionSuggestions(): iterable
35+
{
36+
yield 'option --dump-format' => [['--dump-format', ''], ['puml', 'mermaid', 'dot']];
37+
}
38+
}

0 commit comments

Comments
 (0)