Skip to content

Commit 6fc09d9

Browse files
Merge branch '5.4' into 6.2
* 5.4: cs fix [Messenger] Fix passing options set via tags to handler descriptors random_bytes length should be an int greater than 0 enforce UTC timezone in test [DependencyInjection] Fix autocasting null env values to empty string Fix executable bit Readme: Replace Stack Overflow with GitHub Discussions [DependencyInjection] Fix annotation [String] Fix Inflector for 'status' [EventDispatcher] [EventDispatcher] Throw exception when listener method cannot be resolved
2 parents d2fbdc3 + 39d95e2 commit 6fc09d9

File tree

14 files changed

+147
-27
lines changed

14 files changed

+147
-27
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ Community
4444
---------
4545

4646
* [Join the Symfony Community][11] and meet other members at the [Symfony events][12].
47-
* [Get Symfony support][13] on Stack Overflow, Slack, IRC, etc.
47+
* [Get Symfony support][13] on GitHub Discussions, Slack, etc.
4848
* Follow us on [GitHub][14], [Twitter][15] and [Facebook][16].
4949
* Read our [Code of Conduct][24] and meet the [CARE Team][25].
5050

src/Symfony/Component/DependencyInjection/Container.php

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -354,7 +354,15 @@ protected function getEnv(string $name): mixed
354354
$prefix = 'string';
355355
$localName = $name;
356356
}
357-
$processor = $processors->has($prefix) ? $processors->get($prefix) : new EnvVarProcessor($this);
357+
358+
if ($processors->has($prefix)) {
359+
$processor = $processors->get($prefix);
360+
} else {
361+
$processor = new EnvVarProcessor($this);
362+
if (false === $i) {
363+
$prefix = '';
364+
}
365+
}
358366

359367
$this->resolving[$envName] = true;
360368
try {

src/Symfony/Component/DependencyInjection/ContainerAwareTrait.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
trait ContainerAwareTrait
2020
{
2121
/**
22-
* @var ContainerInterface
22+
* @var ContainerInterface|null
2323
*/
2424
protected $container;
2525

src/Symfony/Component/DependencyInjection/EnvVarProcessor.php

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,12 @@ public function getEnv(string $prefix, string $name, \Closure $getEnv): mixed
143143
}
144144
}
145145

146+
$returnNull = false;
147+
if ('' === $prefix) {
148+
$returnNull = true;
149+
$prefix = 'string';
150+
}
151+
146152
if (false !== $i || 'string' !== $prefix) {
147153
$env = $getEnv($name);
148154
} elseif (isset($_ENV[$name])) {
@@ -194,6 +200,10 @@ public function getEnv(string $prefix, string $name, \Closure $getEnv): mixed
194200
}
195201

196202
if (null === $env) {
203+
if ($returnNull) {
204+
return null;
205+
}
206+
197207
if (!isset($this->getProvidedTypes()[$prefix])) {
198208
throw new RuntimeException(sprintf('Unsupported env var prefix "%s".', $prefix));
199209
}

src/Symfony/Component/DependencyInjection/Tests/EnvVarProcessorTest.php

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -854,12 +854,13 @@ public static function provideGetEnvUrlPath()
854854

855855
/**
856856
* @testWith ["", "string"]
857+
* [null, ""]
857858
* [false, "bool"]
858859
* [true, "not"]
859860
* [0, "int"]
860861
* [0.0, "float"]
861862
*/
862-
public function testGetEnvCastsNull($expected, string $prefix)
863+
public function testGetEnvCastsNullBehavior($expected, string $prefix)
863864
{
864865
$processor = new EnvVarProcessor(new Container());
865866

@@ -869,4 +870,17 @@ public function testGetEnvCastsNull($expected, string $prefix)
869870
});
870871
}));
871872
}
873+
874+
public function testGetEnvWithEmptyStringPrefixCastsToString()
875+
{
876+
$processor = new EnvVarProcessor(new Container());
877+
unset($_ENV['FOO']);
878+
$_ENV['FOO'] = 4;
879+
880+
try {
881+
$this->assertSame('4', $processor->getEnv('', 'FOO', function () { $this->fail('Should not be called'); }));
882+
} finally {
883+
unset($_ENV['FOO']);
884+
}
885+
}
872886
}

src/Symfony/Component/EventDispatcher/DependencyInjection/RegisterListenersPass.php

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,11 @@ public function process(ContainerBuilder $container)
8686
], function ($matches) { return strtoupper($matches[0]); }, $event['event']);
8787
$event['method'] = preg_replace('/[^a-z0-9]/i', '', $event['method']);
8888

89-
if (null !== ($class = $container->getDefinition($id)->getClass()) && ($r = $container->getReflectionClass($class, false)) && !$r->hasMethod($event['method']) && $r->hasMethod('__invoke')) {
89+
if (null !== ($class = $container->getDefinition($id)->getClass()) && ($r = $container->getReflectionClass($class, false)) && !$r->hasMethod($event['method'])) {
90+
if (!$r->hasMethod('__invoke')) {
91+
throw new InvalidArgumentException(sprintf('None of the "%s" or "__invoke" methods exist for the service "foo". Please define the "method" attribute on "kernel.event_listener" tags.', $event['method'], $id, $this->listenerTag));
92+
}
93+
9094
$event['method'] = '__invoke';
9195
}
9296
}

src/Symfony/Component/EventDispatcher/Tests/DependencyInjection/RegisterListenersPassTest.php

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -200,10 +200,20 @@ public function testEventSubscriberUnresolvableClassName()
200200
public function testInvokableEventListener()
201201
{
202202
$container = new ContainerBuilder();
203-
$container->register('foo', \stdClass::class)->addTag('kernel.event_listener', ['event' => 'foo.bar']);
203+
$container->setParameter('event_dispatcher.event_aliases', [AliasedEvent::class => 'aliased_event']);
204+
205+
$container->register('foo', \get_class(new class() {
206+
public function onFooBar()
207+
{
208+
}
209+
}))->addTag('kernel.event_listener', ['event' => 'foo.bar']);
204210
$container->register('bar', InvokableListenerService::class)->addTag('kernel.event_listener', ['event' => 'foo.bar']);
205211
$container->register('baz', InvokableListenerService::class)->addTag('kernel.event_listener', ['event' => 'event']);
206-
$container->register('zar', \stdClass::class)->addTag('kernel.event_listener', ['event' => 'foo.bar_zar']);
212+
$container->register('zar', \get_class(new class() {
213+
public function onFooBarZar()
214+
{
215+
}
216+
}))->addTag('kernel.event_listener', ['event' => 'foo.bar_zar']);
207217
$container->register('event_dispatcher', \stdClass::class);
208218

209219
$registerListenersPass = new RegisterListenersPass();
@@ -247,6 +257,20 @@ public function testInvokableEventListener()
247257
$this->assertEquals($expectedCalls, $definition->getMethodCalls());
248258
}
249259

260+
public function testItThrowsAnExceptionIfTagIsMissingMethodAndClassHasNoValidMethod()
261+
{
262+
$this->expectException(InvalidArgumentException::class);
263+
$this->expectExceptionMessage('None of the "onFooBar" or "__invoke" methods exist for the service "foo". Please define the "method" attribute on "kernel.event_listener" tags.');
264+
265+
$container = new ContainerBuilder();
266+
267+
$container->register('foo', \stdClass::class)->addTag('kernel.event_listener', ['event' => 'foo.bar']);
268+
$container->register('event_dispatcher', \stdClass::class);
269+
270+
$registerListenersPass = new RegisterListenersPass();
271+
$registerListenersPass->process($container);
272+
}
273+
250274
public function testTaggedInvokableEventListener()
251275
{
252276
$container = new ContainerBuilder();

src/Symfony/Component/Messenger/DependencyInjection/MessengerPass.php

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -99,11 +99,9 @@ private function registerHandlers(ContainerBuilder $container, array $busIds)
9999
$options = ['method' => $options];
100100
}
101101

102-
if (!isset($options['from_transport']) && isset($tag['from_transport'])) {
103-
$options['from_transport'] = $tag['from_transport'];
104-
}
105-
106-
$priority = $tag['priority'] ?? $options['priority'] ?? 0;
102+
$options += array_filter($tag);
103+
unset($options['handles']);
104+
$priority = $options['priority'] ?? 0;
107105
$method = $options['method'] ?? '__invoke';
108106

109107
if (isset($options['bus'])) {
@@ -112,7 +110,7 @@ private function registerHandlers(ContainerBuilder $container, array $busIds)
112110
// $messageLocation = isset($tag['handles']) ? 'declared in your tag attribute "handles"' : sprintf('used as argument type in method "%s::%s()"', $r->getName(), $method);
113111
$messageLocation = isset($tag['handles']) ? 'declared in your tag attribute "handles"' : ($r->implementsInterface(MessageSubscriberInterface::class) ? sprintf('returned by method "%s::getHandledMessages()"', $r->getName()) : sprintf('used as argument type in method "%s::%s()"', $r->getName(), $method));
114112

115-
throw new RuntimeException(sprintf('Invalid configuration "%s" for message "%s": bus "%s" does not exist.', $messageLocation, $message, $options['bus']));
113+
throw new RuntimeException(sprintf('Invalid configuration '.$messageLocation.' for message "%s": bus "%s" does not exist.', $message, $options['bus']));
116114
}
117115

118116
$buses = [$options['bus']];
@@ -123,7 +121,7 @@ private function registerHandlers(ContainerBuilder $container, array $busIds)
123121
// $messageLocation = isset($tag['handles']) ? 'declared in your tag attribute "handles"' : sprintf('used as argument type in method "%s::%s()"', $r->getName(), $method);
124122
$messageLocation = isset($tag['handles']) ? 'declared in your tag attribute "handles"' : ($r->implementsInterface(MessageSubscriberInterface::class) ? sprintf('returned by method "%s::getHandledMessages()"', $r->getName()) : sprintf('used as argument type in method "%s::%s()"', $r->getName(), $method));
125123

126-
throw new RuntimeException(sprintf('Invalid handler service "%s": class or interface "%s" "%s" not found.', $serviceId, $message, $messageLocation));
124+
throw new RuntimeException(sprintf('Invalid handler service "%s": class or interface "%s" '.$messageLocation.' not found.', $serviceId, $message));
127125
}
128126

129127
if (!$r->hasMethod($method)) {

src/Symfony/Component/Messenger/Tests/DependencyInjection/MessengerPassTest.php

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -268,13 +268,15 @@ public function testProcessHandlersByBus()
268268
$container,
269269
$commandBusHandlersLocatorDefinition->getArgument(0),
270270
MultipleBusesMessage::class,
271-
[MultipleBusesMessageHandler::class]
271+
[MultipleBusesMessageHandler::class],
272+
[['bus' => $commandBusId]]
272273
);
273274
$this->assertHandlerDescriptor(
274275
$container,
275276
$commandBusHandlersLocatorDefinition->getArgument(0),
276277
DummyCommand::class,
277-
[DummyCommandHandler::class]
278+
[DummyCommandHandler::class],
279+
[['bus' => $commandBusId]]
278280
);
279281

280282
$queryBusHandlersLocatorDefinition = $container->getDefinition($queryBusId.'.messenger.handlers_locator');
@@ -283,13 +285,15 @@ public function testProcessHandlersByBus()
283285
$container,
284286
$queryBusHandlersLocatorDefinition->getArgument(0),
285287
DummyQuery::class,
286-
[DummyQueryHandler::class]
288+
[DummyQueryHandler::class],
289+
[['bus' => $queryBusId]]
287290
);
288291
$this->assertHandlerDescriptor(
289292
$container,
290293
$queryBusHandlersLocatorDefinition->getArgument(0),
291294
MultipleBusesMessage::class,
292-
[MultipleBusesMessageHandler::class]
295+
[MultipleBusesMessageHandler::class],
296+
[['bus' => $queryBusId]]
293297
);
294298
}
295299

@@ -559,7 +563,7 @@ public function testItRegistersHandlersOnDifferentBuses()
559563
public function testItThrowsAnExceptionOnUnknownBus()
560564
{
561565
$this->expectException(RuntimeException::class);
562-
$this->expectExceptionMessage('Invalid configuration "returned by method "Symfony\Component\Messenger\Tests\DependencyInjection\HandlerOnUndefinedBus::getHandledMessages()"" for message "Symfony\Component\Messenger\Tests\Fixtures\DummyMessage": bus "some_undefined_bus" does not exist.');
566+
$this->expectExceptionMessage('Invalid configuration returned by method "Symfony\Component\Messenger\Tests\DependencyInjection\HandlerOnUndefinedBus::getHandledMessages()" for message "Symfony\Component\Messenger\Tests\Fixtures\DummyMessage": bus "some_undefined_bus" does not exist.');
563567
$container = $this->getContainerBuilder();
564568
$container
565569
->register(HandlerOnUndefinedBus::class, HandlerOnUndefinedBus::class)
@@ -572,7 +576,7 @@ public function testItThrowsAnExceptionOnUnknownBus()
572576
public function testUndefinedMessageClassForHandler()
573577
{
574578
$this->expectException(RuntimeException::class);
575-
$this->expectExceptionMessage('Invalid handler service "Symfony\Component\Messenger\Tests\DependencyInjection\UndefinedMessageHandler": class or interface "Symfony\Component\Messenger\Tests\DependencyInjection\UndefinedMessage" "used as argument type in method "Symfony\Component\Messenger\Tests\DependencyInjection\UndefinedMessageHandler::__invoke()"" not found.');
579+
$this->expectExceptionMessage('Invalid handler service "Symfony\Component\Messenger\Tests\DependencyInjection\UndefinedMessageHandler": class or interface "Symfony\Component\Messenger\Tests\DependencyInjection\UndefinedMessage" used as argument type in method "Symfony\Component\Messenger\Tests\DependencyInjection\UndefinedMessageHandler::__invoke()" not found.');
576580
$container = $this->getContainerBuilder();
577581
$container
578582
->register(UndefinedMessageHandler::class, UndefinedMessageHandler::class)
@@ -588,7 +592,7 @@ public function testUndefinedMessageClassForHandler()
588592
public function testUndefinedMessageClassForHandlerImplementingMessageHandlerInterface()
589593
{
590594
$this->expectException(RuntimeException::class);
591-
$this->expectExceptionMessage('Invalid handler service "Symfony\Component\Messenger\Tests\DependencyInjection\UndefinedMessageHandlerViaHandlerInterface": class or interface "Symfony\Component\Messenger\Tests\DependencyInjection\UndefinedMessage" "used as argument type in method "Symfony\Component\Messenger\Tests\DependencyInjection\UndefinedMessageHandlerViaHandlerInterface::__invoke()"" not found.');
595+
$this->expectExceptionMessage('Invalid handler service "Symfony\Component\Messenger\Tests\DependencyInjection\UndefinedMessageHandlerViaHandlerInterface": class or interface "Symfony\Component\Messenger\Tests\DependencyInjection\UndefinedMessage" used as argument type in method "Symfony\Component\Messenger\Tests\DependencyInjection\UndefinedMessageHandlerViaHandlerInterface::__invoke()" not found.');
592596
$container = $this->getContainerBuilder();
593597
$container
594598
->register(UndefinedMessageHandlerViaHandlerInterface::class, UndefinedMessageHandlerViaHandlerInterface::class)
@@ -604,7 +608,7 @@ public function testUndefinedMessageClassForHandlerImplementingMessageHandlerInt
604608
public function testUndefinedMessageClassForHandlerImplementingMessageSubscriberInterface()
605609
{
606610
$this->expectException(RuntimeException::class);
607-
$this->expectExceptionMessage('Invalid handler service "Symfony\Component\Messenger\Tests\DependencyInjection\UndefinedMessageHandlerViaSubscriberInterface": class or interface "Symfony\Component\Messenger\Tests\DependencyInjection\UndefinedMessage" "returned by method "Symfony\Component\Messenger\Tests\DependencyInjection\UndefinedMessageHandlerViaSubscriberInterface::getHandledMessages()"" not found.');
611+
$this->expectExceptionMessage('Invalid handler service "Symfony\Component\Messenger\Tests\DependencyInjection\UndefinedMessageHandlerViaSubscriberInterface": class or interface "Symfony\Component\Messenger\Tests\DependencyInjection\UndefinedMessage" returned by method "Symfony\Component\Messenger\Tests\DependencyInjection\UndefinedMessageHandlerViaSubscriberInterface::getHandledMessages()" not found.');
608612
$container = $this->getContainerBuilder();
609613
$container
610614
->register(UndefinedMessageHandlerViaSubscriberInterface::class, UndefinedMessageHandlerViaSubscriberInterface::class)
@@ -833,12 +837,12 @@ public function testItRegistersTheDebugCommand()
833837

834838
$this->assertEquals([
835839
$commandBusId => [
836-
DummyCommand::class => [[DummyCommandHandler::class, []]],
837-
MultipleBusesMessage::class => [[MultipleBusesMessageHandler::class, []]],
840+
DummyCommand::class => [[DummyCommandHandler::class, ['bus' => $commandBusId]]],
841+
MultipleBusesMessage::class => [[MultipleBusesMessageHandler::class, ['bus' => $commandBusId]]],
838842
],
839843
$queryBusId => [
840-
DummyQuery::class => [[DummyQueryHandler::class, []]],
841-
MultipleBusesMessage::class => [[MultipleBusesMessageHandler::class, []]],
844+
DummyQuery::class => [[DummyQueryHandler::class, ['bus' => $queryBusId]]],
845+
MultipleBusesMessage::class => [[MultipleBusesMessageHandler::class, ['bus' => $queryBusId]]],
842846
],
843847
$emptyBus => [],
844848
], $container->getDefinition('console.command.messenger_debug')->getArgument(0));

src/Symfony/Component/Security/Csrf/Tests/TokenGenerator/UriSafeTokenGeneratorTest.php

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,4 +57,28 @@ public function testGenerateToken()
5757
$this->assertStringNotMatchesFormat('%S/%S', $token, 'is URI safe');
5858
$this->assertStringNotMatchesFormat('%S=%S', $token, 'is URI safe');
5959
}
60+
61+
/**
62+
* @dataProvider validDataProvider
63+
*/
64+
public function testValidLength(int $entropy, int $length)
65+
{
66+
$generator = new UriSafeTokenGenerator($entropy);
67+
$token = $generator->generateToken();
68+
$this->assertSame($length, \strlen($token));
69+
}
70+
71+
public static function validDataProvider(): \Iterator
72+
{
73+
yield [24, 4];
74+
yield 'Float length' => [20, 3];
75+
}
76+
77+
public function testInvalidLength()
78+
{
79+
$this->expectException(\InvalidArgumentException::class);
80+
$this->expectExceptionMessage('Entropy should be greater than 7.');
81+
82+
new UriSafeTokenGenerator(7);
83+
}
6084
}

0 commit comments

Comments
 (0)