Skip to content

Commit 3025865

Browse files
Merge branch '6.4' into 7.3
* 6.4: 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`
2 parents 1ed06ec + e33fcd6 commit 3025865

File tree

15 files changed

+281
-36
lines changed

15 files changed

+281
-36
lines changed

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

Lines changed: 17 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -370,7 +370,7 @@ private function addWorkflowSection(ArrayNodeDefinition $rootNode): void
370370
->arrayNode('workflows')
371371
->canBeEnabled()
372372
->beforeNormalization()
373-
->always(function ($v) {
373+
->always(static function ($v) {
374374
if (\is_array($v) && true === $v['enabled']) {
375375
$workflows = $v;
376376
unset($workflows['enabled']);
@@ -379,7 +379,7 @@ private function addWorkflowSection(ArrayNodeDefinition $rootNode): void
379379
$workflows = [];
380380
}
381381

382-
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'])) {
382+
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])) {
383383
$workflows = $workflows['workflows'];
384384
}
385385

@@ -530,26 +530,26 @@ private function addWorkflowSection(ArrayNodeDefinition $rootNode): void
530530
->end()
531531
->arrayNode('transitions')
532532
->beforeNormalization()
533-
->always()
534-
->then(static function ($transitions) {
533+
->always(static function ($transitions) {
535534
if (!\is_array($transitions)) {
536535
throw new InvalidConfigurationException('The "transitions" option must be an array in workflow configuration.');
537536
}
538537

539-
// It's an indexed array, we let the validation occur
540-
if (isset($transitions[0]) && \is_array($transitions[0])) {
541-
return $transitions;
542-
}
543-
544-
foreach ($transitions as $name => $transition) {
545-
if (\is_array($transition) && \array_key_exists('name', $transition)) {
546-
continue;
538+
$normalizedTransitions = [];
539+
foreach ($transitions as $key => $transition) {
540+
if (\is_array($transition)) {
541+
if (\is_string($key = $transition['key'] ?? $key)) {
542+
$transition['name'] ??= $key;
543+
}
544+
if (!($transition['name'] ?? false)) {
545+
throw new InvalidConfigurationException('The "name" option is required for each transition in workflow configuration.');
546+
}
547+
unset($transition['key']);
547548
}
548-
$transition['name'] = $name;
549-
$transitions[$name] = $transition;
549+
$normalizedTransitions[$key] = $transition;
550550
}
551551

552-
return $transitions;
552+
return $normalizedTransitions;
553553
})
554554
->end()
555555
->isRequired()
@@ -566,13 +566,15 @@ private function addWorkflowSection(ArrayNodeDefinition $rootNode): void
566566
->example('is_fully_authenticated() and is_granted(\'ROLE_JOURNALIST\') and subject.getTitle() == \'My first article\'')
567567
->end()
568568
->arrayNode('from')
569+
->performNoDeepMerging()
569570
->beforeNormalization()->castToArray()->end()
570571
->requiresAtLeastOneElement()
571572
->prototype('scalar')
572573
->cannotBeEmpty()
573574
->end()
574575
->end()
575576
->arrayNode('to')
577+
->performNoDeepMerging()
576578
->beforeNormalization()->castToArray()->end()
577579
->requiresAtLeastOneElement()
578580
->prototype('scalar')

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

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1086,16 +1086,16 @@ private function registerWorkflowConfiguration(array $config, ContainerBuilder $
10861086
$transitionCounter = 0;
10871087
foreach ($workflow['transitions'] as $transition) {
10881088
if ('workflow' === $type) {
1089-
$transitionDefinition = new Definition(Workflow\Transition::class, [$transition['name'], $transition['from'], $transition['to']]);
10901089
$transitionId = \sprintf('.%s.transition.%s', $workflowId, $transitionCounter++);
1091-
$container->setDefinition($transitionId, $transitionDefinition);
1090+
$container->register($transitionId, Workflow\Transition::class)
1091+
->setArguments([$transition['name'], $transition['from'], $transition['to']]);
10921092
$transitions[] = new Reference($transitionId);
10931093
if (isset($transition['guard'])) {
1094-
$configuration = new Definition(Workflow\EventListener\GuardExpression::class);
1095-
$configuration->addArgument(new Reference($transitionId));
1096-
$configuration->addArgument($transition['guard']);
10971094
$eventName = \sprintf('workflow.%s.guard.%s', $name, $transition['name']);
1098-
$guardsConfiguration[$eventName][] = $configuration;
1095+
$guardsConfiguration[$eventName][] = new Definition(
1096+
Workflow\EventListener\GuardExpression::class,
1097+
[new Reference($transitionId), $transition['guard']]
1098+
);
10991099
}
11001100
if ($transition['metadata']) {
11011101
$transitionsMetadataDefinition->addMethodCall('offsetSet', [
@@ -1106,16 +1106,16 @@ private function registerWorkflowConfiguration(array $config, ContainerBuilder $
11061106
} elseif ('state_machine' === $type) {
11071107
foreach ($transition['from'] as $from) {
11081108
foreach ($transition['to'] as $to) {
1109-
$transitionDefinition = new Definition(Workflow\Transition::class, [$transition['name'], $from, $to]);
11101109
$transitionId = \sprintf('.%s.transition.%s', $workflowId, $transitionCounter++);
1111-
$container->setDefinition($transitionId, $transitionDefinition);
1110+
$container->register($transitionId, Workflow\Transition::class)
1111+
->setArguments([$transition['name'], $from, $to]);
11121112
$transitions[] = new Reference($transitionId);
11131113
if (isset($transition['guard'])) {
1114-
$configuration = new Definition(Workflow\EventListener\GuardExpression::class);
1115-
$configuration->addArgument(new Reference($transitionId));
1116-
$configuration->addArgument($transition['guard']);
11171114
$eventName = \sprintf('workflow.%s.guard.%s', $name, $transition['name']);
1118-
$guardsConfiguration[$eventName][] = $configuration;
1115+
$guardsConfiguration[$eventName][] = new Definition(
1116+
Workflow\EventListener\GuardExpression::class,
1117+
[new Reference($transitionId), $transition['guard']]
1118+
);
11191119
}
11201120
if ($transition['metadata']) {
11211121
$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
@@ -511,7 +511,8 @@
511511
<xsd:element name="metadata" type="metadata" minOccurs="0" maxOccurs="unbounded" />
512512
<xsd:element name="guard" type="xsd:string" minOccurs="0" maxOccurs="unbounded" />
513513
</xsd:sequence>
514-
<xsd:attribute name="name" type="xsd:string" use="required" />
514+
<xsd:attribute name="name" type="xsd:string" />
515+
<xsd:attribute name="key" type="xsd:string" />
515516
</xsd:complexType>
516517

517518
<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
@@ -576,6 +576,27 @@ public function testWorkflowsWithSpecifiedDispatchedEvents()
576576
$this->assertSame([WorkflowEvents::LEAVE, WorkflowEvents::COMPLETED], $eventsToDispatch);
577577
}
578578

579+
public function testWorkflowTransitionsPerformNoDeepMerging()
580+
{
581+
$container = $this->createContainer(['kernel.charset' => 'UTF-8', 'kernel.secret' => 'secret', 'kernel.runtime_environment' => 'test']);
582+
$container->registerExtension(new FrameworkExtension());
583+
584+
$this->loadFromFile($container, 'workflow_base_config');
585+
586+
$this->loadFromFile($container, 'workflow_override_config');
587+
588+
$container->compile();
589+
590+
$transitions = [];
591+
592+
foreach ($container->getDefinition('test_workflow')->getArgument(0)->getArgument(1) as $transitionDefinition) {
593+
$transitions[] = $transitionDefinition->getArguments();
594+
}
595+
596+
$this->assertCount(1, $transitions);
597+
$this->assertSame(['base_transition', ['middle'], ['alternative']], $transitions[0]);
598+
}
599+
579600
public function testEnabledPhpErrorsConfig()
580601
{
581602
$container = $this->createContainerFromFile('php_errors_enabled');

0 commit comments

Comments
 (0)