Skip to content

Commit 67d67c1

Browse files
Merge branch '7.3' into 7.4
* 7.3: Fix ord()-related PHP 8.5 deprecations [FrameworkBundle] Perform-no-deep-merging on workflow transitions' from/to configs [HttpKernel] Refine Vary header check to skip special handling of 'Accept-Language' when it's the only entry and '_vary_by_language' is `true` in `CacheAttributeListener` [PropertyInfo] Fix getting type from constructor of parent class in PhpStanExtractor
2 parents 9b36ddc + 3025865 commit 67d67c1

File tree

18 files changed

+295
-36
lines changed

18 files changed

+295
-36
lines changed

src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Configuration.php

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -374,7 +374,7 @@ private function addWorkflowSection(ArrayNodeDefinition $rootNode): void
374374
$workflows = [];
375375
}
376376

377-
if (1 === \count($workflows) && isset($workflows['workflows']) && !array_is_list($workflows['workflows']) && array_diff(array_keys($workflows['workflows']), ['audit_trail', 'type', 'marking_store', 'supports', 'support_strategy', 'initial_marking', 'places', 'transitions'])) {
377+
if (1 === \count($workflows) && isset($workflows['workflows']) && !array_is_list($workflows['workflows']) && array_diff_key($workflows['workflows'], ['audit_trail' => 1, 'type' => 1, 'marking_store' => 1, 'supports' => 1, 'support_strategy' => 1, 'initial_marking' => 1, 'places' => 1, 'transitions' => 1])) {
378378
$workflows = $workflows['workflows'];
379379
}
380380

@@ -541,20 +541,21 @@ private function addWorkflowSection(ArrayNodeDefinition $rootNode): void
541541
throw new InvalidConfigurationException('The "transitions" option must be an array in workflow configuration.');
542542
}
543543

544-
// It's an indexed array, we let the validation occur
545-
if (isset($transitions[0]) && \is_array($transitions[0])) {
546-
return $transitions;
547-
}
548-
549-
foreach ($transitions as $name => $transition) {
550-
if (\is_array($transition) && \array_key_exists('name', $transition)) {
551-
continue;
544+
$normalizedTransitions = [];
545+
foreach ($transitions as $key => $transition) {
546+
if (\is_array($transition)) {
547+
if (\is_string($key = $transition['key'] ?? $key)) {
548+
$transition['name'] ??= $key;
549+
}
550+
if (!($transition['name'] ?? false)) {
551+
throw new InvalidConfigurationException('The "name" option is required for each transition in workflow configuration.');
552+
}
553+
unset($transition['key']);
552554
}
553-
$transition['name'] = $name;
554-
$transitions[$name] = $transition;
555+
$normalizedTransitions[$key] = $transition;
555556
}
556557

557-
return $transitions;
558+
return $normalizedTransitions;
558559
})
559560
->end()
560561
->isRequired()
@@ -571,6 +572,7 @@ private function addWorkflowSection(ArrayNodeDefinition $rootNode): void
571572
->example('is_fully_authenticated() and is_granted(\'ROLE_JOURNALIST\') and subject.getTitle() == \'My first article\'')
572573
->end()
573574
->arrayNode('from')
575+
->performNoDeepMerging()
574576
->beforeNormalization()
575577
->always(static fn ($from) => array_map(static fn ($v) => $v instanceof \BackedEnum ? $v->value : $v, \is_array($from) ? $from : [$from]))
576578
->end()
@@ -580,6 +582,7 @@ private function addWorkflowSection(ArrayNodeDefinition $rootNode): void
580582
->end()
581583
->end()
582584
->arrayNode('to')
585+
->performNoDeepMerging()
583586
->beforeNormalization()
584587
->always(static fn ($to) => array_map(static fn ($v) => $v instanceof \BackedEnum ? $v->value : $v, \is_array($to) ? $to : [$to]))
585588
->end()

src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1112,16 +1112,16 @@ private function registerWorkflowConfiguration(array $config, ContainerBuilder $
11121112
$transitionCounter = 0;
11131113
foreach ($workflow['transitions'] as $transition) {
11141114
if ('workflow' === $type) {
1115-
$transitionDefinition = new Definition(Workflow\Transition::class, [$transition['name'], $transition['from'], $transition['to']]);
11161115
$transitionId = \sprintf('.%s.transition.%s', $workflowId, $transitionCounter++);
1117-
$container->setDefinition($transitionId, $transitionDefinition);
1116+
$container->register($transitionId, Workflow\Transition::class)
1117+
->setArguments([$transition['name'], $transition['from'], $transition['to']]);
11181118
$transitions[] = new Reference($transitionId);
11191119
if (isset($transition['guard'])) {
1120-
$configuration = new Definition(Workflow\EventListener\GuardExpression::class);
1121-
$configuration->addArgument(new Reference($transitionId));
1122-
$configuration->addArgument($transition['guard']);
11231120
$eventName = \sprintf('workflow.%s.guard.%s', $name, $transition['name']);
1124-
$guardsConfiguration[$eventName][] = $configuration;
1121+
$guardsConfiguration[$eventName][] = new Definition(
1122+
Workflow\EventListener\GuardExpression::class,
1123+
[new Reference($transitionId), $transition['guard']]
1124+
);
11251125
}
11261126
if ($transition['metadata']) {
11271127
$transitionsMetadataDefinition->addMethodCall('offsetSet', [
@@ -1132,16 +1132,16 @@ private function registerWorkflowConfiguration(array $config, ContainerBuilder $
11321132
} elseif ('state_machine' === $type) {
11331133
foreach ($transition['from'] as $from) {
11341134
foreach ($transition['to'] as $to) {
1135-
$transitionDefinition = new Definition(Workflow\Transition::class, [$transition['name'], $from, $to]);
11361135
$transitionId = \sprintf('.%s.transition.%s', $workflowId, $transitionCounter++);
1137-
$container->setDefinition($transitionId, $transitionDefinition);
1136+
$container->register($transitionId, Workflow\Transition::class)
1137+
->setArguments([$transition['name'], $from, $to]);
11381138
$transitions[] = new Reference($transitionId);
11391139
if (isset($transition['guard'])) {
1140-
$configuration = new Definition(Workflow\EventListener\GuardExpression::class);
1141-
$configuration->addArgument(new Reference($transitionId));
1142-
$configuration->addArgument($transition['guard']);
11431140
$eventName = \sprintf('workflow.%s.guard.%s', $name, $transition['name']);
1144-
$guardsConfiguration[$eventName][] = $configuration;
1141+
$guardsConfiguration[$eventName][] = new Definition(
1142+
Workflow\EventListener\GuardExpression::class,
1143+
[new Reference($transitionId), $transition['guard']]
1144+
);
11451145
}
11461146
if ($transition['metadata']) {
11471147
$transitionsMetadataDefinition->addMethodCall('offsetSet', [

src/Symfony/Bundle/FrameworkBundle/Resources/config/schema/symfony-1.0.xsd

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -523,7 +523,8 @@
523523
<xsd:element name="metadata" type="metadata" minOccurs="0" maxOccurs="unbounded" />
524524
<xsd:element name="guard" type="xsd:string" minOccurs="0" maxOccurs="unbounded" />
525525
</xsd:sequence>
526-
<xsd:attribute name="name" type="xsd:string" use="required" />
526+
<xsd:attribute name="name" type="xsd:string" />
527+
<xsd:attribute name="key" type="xsd:string" />
527528
</xsd:complexType>
528529

529530
<xsd:complexType name="place" mixed="true">
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
<?php
2+
3+
return function (Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator $container) {
4+
$container->services()->alias('test_workflow', 'workflow.test_workflow')->public();
5+
$container->extension('framework', [
6+
'http_method_override' => false,
7+
'handle_all_throwables' => true,
8+
'annotations' => [
9+
'enabled' => false,
10+
],
11+
'php_errors' => [
12+
'log' => true,
13+
],
14+
'workflows' => [
15+
'test_workflow' => [
16+
'type' => 'workflow',
17+
'supports' => [
18+
'Symfony\Bundle\FrameworkBundle\Tests\DependencyInjection\FrameworkExtensionTestCase',
19+
],
20+
'initial_marking' => ['start'],
21+
'places' => [
22+
'start',
23+
'middle',
24+
'end',
25+
'alternative',
26+
],
27+
'transitions' => [
28+
'base_transition' => [
29+
'from' => ['start'],
30+
'to' => ['end'],
31+
],
32+
],
33+
],
34+
],
35+
]);
36+
};
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
<?php
2+
3+
return function (Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator $container) {
4+
$container->extension('framework', [
5+
'http_method_override' => false,
6+
'handle_all_throwables' => true,
7+
'annotations' => [
8+
'enabled' => false,
9+
],
10+
'php_errors' => [
11+
'log' => true,
12+
],
13+
'workflows' => [
14+
'test_workflow' => [
15+
'type' => 'workflow',
16+
'supports' => [
17+
'Symfony\Bundle\FrameworkBundle\Tests\DependencyInjection\FrameworkExtensionTestCase',
18+
],
19+
'initial_marking' => ['start'],
20+
'places' => [
21+
'start',
22+
'middle',
23+
'end',
24+
'alternative',
25+
],
26+
'transitions' => [
27+
'base_transition' => [
28+
'from' => ['middle'],
29+
'to' => ['alternative'],
30+
],
31+
],
32+
],
33+
],
34+
]);
35+
};
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
<?xml version="1.0" encoding="UTF-8" ?>
2+
<container xmlns="http://symfony.com/schema/dic/services"
3+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4+
xmlns:framework="http://symfony.com/schema/dic/symfony"
5+
xsi:schemaLocation="http://symfony.com/schema/dic/services https://symfony.com/schema/dic/services/services-1.0.xsd
6+
http://symfony.com/schema/dic/symfony https://symfony.com/schema/dic/symfony/symfony-1.0.xsd">
7+
8+
<services>
9+
<service id="test_workflow" alias="workflow.test_workflow" public="true" />
10+
</services>
11+
<framework:config http-method-override="false" handle-all-throwables="true">
12+
<framework:annotations enabled="false" />
13+
<framework:php-errors log="true" />
14+
<framework:workflow name="test_workflow" type="workflow">
15+
<framework:initial-marking>start</framework:initial-marking>
16+
<framework:support>Symfony\Bundle\FrameworkBundle\Tests\DependencyInjection\FrameworkExtensionTestCase</framework:support>
17+
<framework:place>start</framework:place>
18+
<framework:place>middle</framework:place>
19+
<framework:place>end</framework:place>
20+
<framework:place>alternative</framework:place>
21+
<framework:transition key="base_transition">
22+
<framework:from>start</framework:from>
23+
<framework:to>end</framework:to>
24+
</framework:transition>
25+
</framework:workflow>
26+
</framework:config>
27+
</container>
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
<?xml version="1.0" encoding="UTF-8" ?>
2+
<container xmlns="http://symfony.com/schema/dic/services"
3+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4+
xmlns:framework="http://symfony.com/schema/dic/symfony"
5+
xsi:schemaLocation="http://symfony.com/schema/dic/services https://symfony.com/schema/dic/services/services-1.0.xsd
6+
http://symfony.com/schema/dic/symfony https://symfony.com/schema/dic/symfony/symfony-1.0.xsd">
7+
8+
<framework:config http-method-override="false" handle-all-throwables="true">
9+
<framework:annotations enabled="false" />
10+
<framework:php-errors log="true" />
11+
<framework:workflow name="test_workflow" type="workflow">
12+
<framework:transition key="base_transition">
13+
<framework:from>middle</framework:from>
14+
<framework:to>alternative</framework:to>
15+
</framework:transition>
16+
</framework:workflow>
17+
</framework:config>
18+
</container>
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
services:
2+
test_workflow:
3+
alias: workflow.test_workflow
4+
public: true
5+
framework:
6+
http_method_override: false
7+
handle_all_throwables: true
8+
annotations:
9+
enabled: false
10+
php_errors:
11+
log: true
12+
workflows:
13+
test_workflow:
14+
type: workflow
15+
supports:
16+
- Symfony\Bundle\FrameworkBundle\Tests\DependencyInjection\FrameworkExtensionTestCase
17+
initial_marking: [start]
18+
places:
19+
- start
20+
- middle
21+
- end
22+
- alternative
23+
transitions:
24+
base_transition:
25+
from: [start]
26+
to: [end]
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
framework:
2+
http_method_override: false
3+
handle_all_throwables: true
4+
annotations:
5+
enabled: false
6+
php_errors:
7+
log: true
8+
workflows:
9+
test_workflow:
10+
transitions:
11+
base_transition:
12+
from: [middle]
13+
to: [alternative]

src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTestCase.php

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -602,6 +602,27 @@ public function testWorkflowsWithSpecifiedDispatchedEvents()
602602
$this->assertSame([WorkflowEvents::LEAVE, WorkflowEvents::COMPLETED], $eventsToDispatch);
603603
}
604604

605+
public function testWorkflowTransitionsPerformNoDeepMerging()
606+
{
607+
$container = $this->createContainer(['kernel.charset' => 'UTF-8', 'kernel.secret' => 'secret', 'kernel.runtime_environment' => 'test']);
608+
$container->registerExtension(new FrameworkExtension());
609+
610+
$this->loadFromFile($container, 'workflow_base_config');
611+
612+
$this->loadFromFile($container, 'workflow_override_config');
613+
614+
$container->compile();
615+
616+
$transitions = [];
617+
618+
foreach ($container->getDefinition('test_workflow')->getArgument(0)->getArgument(1) as $transitionDefinition) {
619+
$transitions[] = $transitionDefinition->getArguments();
620+
}
621+
622+
$this->assertCount(1, $transitions);
623+
$this->assertSame(['base_transition', ['middle'], ['alternative']], $transitions[0]);
624+
}
625+
605626
public function testEnabledPhpErrorsConfig()
606627
{
607628
$container = $this->createContainerFromFile('php_errors_enabled');

0 commit comments

Comments
 (0)