8000 Merge branch '6.1' into 6.2 · upyx/symfony@8570ce0 · GitHub
[go: up one dir, main page]

Skip to content

Commit 8570ce0

Browse files
committed
Merge branch '6.1' into 6.2
* 6.1: remove no longer needed PHP version requirements from tests remove no longer needed PHP version requirements from tests [Validator] [Security] Add Norwegian translations add tests covering union types in MessengerPass [Messenger] Support for custom handler method containing a Union type tagged with #[AsMessageHandler] [HttpFoundation] Prevent BinaryFileResponse::prepare from adding content type if no content is sent
2 parents 58117d7 + b45d86f commit 8570ce0

File tree

15 files changed

+273
-41
lines changed

15 files changed

+273
-41
lines changed

src/Symfony/Component/HttpFoundation/BinaryFileResponse.php

Lines changed: 40 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -179,22 +179,25 @@ public function setContentDisposition(string $disposition, string $filename = ''
179179

180180
public function prepare(Request $request): static
181181
{
182-
if (!$this->headers->has('Content-Type')) {
183-
$this->headers->set('Content-Type', $this->file->getMimeType() ?: 'application/octet-stream');
184-
}
182+
parent::prepare($request);
185183

186-
if ('HTTP/1.0' !== $request->server->get('SERVER_PROTOCOL')) {
187-
$this->setProtocolVersion('1.1');
184+
if ($this->isInformational() || $this->isEmpty()) {
185+
$this->maxlen = 0;
186+
187+
return $this;
188188
}
189189

190-
$this->ensureIEOverSSLCompatibility($request);
190+
if (!$this->headers->has('Content-Type')) {
191+
$this->headers->set('Content-Type', $this->file->getMimeType() ?: 'application/octet-stream');
192+
}
191193

192194
$this->offset = 0;
193195
$this->maxlen = -1;
194196

195197
if (false === $fileSize = $this->file->getSize()) {
196198
return $this;
197199
}
200+
$this->headers->remove('Transfer-Encoding');
198201
$this->headers->set('Content-Length', $fileSize);
199202

200203
if (!$this->headers->has('Accept-Ranges')) {
@@ -264,6 +267,10 @@ public function prepare(Request $request): static
264267
}
265268
}
266269

270+
if ($request->isMethod('HEAD')) {
271+
$this->maxlen = 0;
272+
}
273+
267274
return $this;
268275
}
269276

@@ -282,40 +289,42 @@ private function hasValidIfRangeHeader(?string $header): bool
282289

283290
public function sendContent(): static
284291
{
285-
if (!$this->isSuccessful()) {
286-
return parent::sendContent();
287-
}
292+
try {
293+
if (!$this->isSuccessful()) {
294+
return parent::sendContent();
295+
}
288296

289-
if (0 === $this->maxlen) {
290-
return $this;
291-
}
297+
if (0 === $this->maxlen) {
298+
return $this;
299+
}
292300

293-
$out = fopen('php://output', 'w');
294-
$file = fopen($this->file->getPathname(), 'r');
301+
$out = fopen('php://output', 'w');
302+
$file = fopen($this->file->getPathname(), 'r');
295303

296-
ignore_user_abort(true);
304+
ignore_user_abort(true);
297305

298-
if (0 !== $this->offset) {
299-
fseek($file, $this->offset);
300-
}
306+
if (0 !== $this->offset) {
307+
fseek($file, $this->offset);
308+
}
301309

302-
$length = $this->maxlen;
303-
while ($length && !feof($file)) {
304-
$read = ($length > $this->chunkSize) ? $this->chunkSize : $length;
305-
$length -= $read;
310+
$length = $this->maxlen;
311+
while ($length && !feof($file)) {
312+
$read = ($length > $this->chunkSize) ? $this->chunkSize : $length;
313+
$length -= $read;
306314

307-
stream_copy_to_stream($file, $out, $read);
315+
stream_copy_to_stream($file, $out, $read);
308316

309-
if (connection_aborted()) {
310-
break;
317+
if (connection_aborted()) {
318+
break;
319+
}
311320
}
312-
}
313321

314-
fclose($out);
315-
fclose($file);
316-
317-
if ($this->deleteFileAfterSend && is_file($this->file->getPathname())) {
318-
unlink($this->file->getPathname());
322+
fclose($out);
323+
fclose($file);
324+
} finally {
325+
if ($this->deleteFileAfterSend && is_file($this->file->getPathname())) {
326+
unlink($this->file->getPathname());
327+
}
319328
}
320329

321330
return $this;

src/Symfony/Component/HttpFoundation/Tests/BinaryFileResponseTest.php

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -372,6 +372,21 @@ public function testStream()
372372
$this->assertNull($response->headers->get('Content-Length'));
373373
}
374374

375+
public function testPrepareNotAddingContentTypeHeaderIfNoContentResponse()
376+
{
377+
$request = Request::create('/');
378+
$request->headers->set('If-Modified-Since', date('D, d M Y H:i:s').' GMT');
379+
380+
$response = new BinaryFileResponse(__DIR__.'/File/Fixtures/test.gif', 200, ['Content-Type' => 'application/octet-stream']);
381+
$response->setLastModified(new \DateTimeImmutable('-1 day'));
382+
$response->isNotModified($request);
383+
384+
$response->prepare($request);
385+
386+
$this->assertSame(BinaryFileResponse::HTTP_NOT_MODIFIED, $response->getStatusCode());
387+
$this->assertFalse($response->headers->has('Content-Type'));
388+
}
389+
375390
protected function provideResponse()
376391
{
377392
return new BinaryFileResponse(__DIR__.'/../README.md', 200, ['Content-Type' => 'application/octet-stream']);

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

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -221,15 +221,20 @@ private function guessHandledClasses(\ReflectionClass $handlerClass, string $ser
221221

222222
if ($type instanceof \ReflectionUnionType) {
223223
$types = [];
224+
$invalidTypes = [];
224225
foreach ($type->getTypes() as $type) {
225226
if (!$type->isBuiltin()) {
226227
$types[] = (string) $type;
228+
} else {
229+
$invalidTypes[] = (string) $type;
227230
}
228231
}
229232

230233
if ($types) {
231-
return $types;
234+
return ('__invoke' === $methodName) ? $types : array_fill_keys($types, $methodName);
232235
}
236+
237+
throw new RuntimeException(sprintf('Invalid handler service "%s": type-hint of argument "$%s" in method "%s::__invoke()" must be a class , "%s" given.', $serviceId, $parameters[0]->getName(), $handlerClass->getName(), implode('|', $invalidTypes)));
233238
}
234239

235240
if ($type->isBuiltin()) {

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

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
use Symfony\Component\Messenger\Middleware\HandleMessageMiddleware;
4040
use Symfony\Component\Messenger\Middleware\MiddlewareInterface;
4141
use Symfony\Component\Messenger\Middleware\StackInterface;
42+
use Symfony\Component\Messenger\Tests\Fixtures\ChildDummyMessage;
4243
use Symfony\Component\Messenger\Tests\Fixtures\DummyCommand;
4344
use Symfony\Component\Messenger\Tests\Fixtures\DummyCommandHandler;
4445
use Symfony\Component\Messenger\Tests\Fixtures\DummyHandlerWithCustomMethods;
@@ -49,6 +50,11 @@
4950
use Symfony\Component\Messenger\Tests\Fixtures\MultipleBusesMessageHandler;
5051
use Symfony\Component\Messenger\Tests\Fixtures\SecondMessage;
5152
use Symfony\Component\Messenger\Tests\Fixtures\TaggedDummyHandler;
53+
use Symfony\Component\Messenger\Tests\Fixtures\TaggedDummyHandlerWithUnionTypes;
54+
use Symfony\Component\Messenger\Tests\Fixtures\UnionBuiltinTypeArgumentHandler;
55+
use Symfony\Component\Messenger\Tests\Fixtures\UnionTypeArgumentHandler;
56+
use Symfony\Component\Messenger\Tests\Fixtures\UnionTypeOneMessage;
57+
use Symfony\Component\Messenger\Tests\Fixtures\UnionTypeTwoMessage;
5258
use Symfony\Component\Messenger\Transport\Receiver\ReceiverInterface;
5359

5460
class MessengerPassTest extends TestCase
@@ -180,6 +186,54 @@ public function testTaggedMessageHandler()
180186
);
181187
}
182188

189+
public function testTaggedMessageHandlerWithUnionTypes()
190+
{
191+
$container = $this->getContainerBuilder($busId = 'message_bus');
192+
$container->registerAttributeForAutoconfiguration(AsMessageHandler::class, static function (ChildDefinition $definition, AsMessageHandler $attribute, \ReflectionClass|\ReflectionMethod $reflector): void {
193+
$tagAttributes = get_object_vars($attribute);
194+
$tagAttributes['from_transport'] = $tagAttributes['fromTransport'];
195+
unset($tagAttributes['fromTransport']);
196+
if ($reflector instanceof \ReflectionMethod) {
197+
if (isset($tagAttributes['method'])) {
198+
throw new LogicException(sprintf('AsMessageHandler attribute cannot declare a method on "%s::%s()".', $reflector->class, $reflector->name));
199+
}
200+
$tagAttributes['method'] = $reflector->getName();
201+
}
202+
203+
$definition->addTag('messenger.message_handler', $tagAttributes);
204+
});
205+
$container
206+
->register(TaggedDummyHandlerWithUnionTypes::class, TaggedDummyHandlerWithUnionTypes::class)
207+
->setAutoconfigured(true)
208+
;
209+
210+
(new AttributeAutoconfigurationPass())->process($container);
211+
(new ResolveInstanceofConditionalsPass())->process($container);
212+
(new MessengerPass())->process($container);
213+
214+
$handlersLocatorDefinition = $container->getDefinition($busId.'.messenger.handlers_locator');
215+
$this->assertSame(HandlersLocator::class, $handlersLocatorDefinition->getClass());
216+
217+
$handlerDescriptionMapping = $handlersLocatorDefinition->getArgument(0);
218+
219+
$this->assertCount(4, $handlerDescriptionMapping);
220+
221+
$this->assertHandlerDescriptor($container, $handlerDescriptionMapping, DummyMessage::class, [TaggedDummyHandlerWithUnionTypes::class], [[]]);
222+
$this->assertHandlerDescriptor($container, $handlerDescriptionMapping, SecondMessage::class, [TaggedDummyHandlerWithUnionTypes::class], [[]]);
223+
$this->assertHandlerDescriptor(
224+
$container,
225+
$handlerDescriptionMapping,
226+
UnionTypeOneMessage::class,
227+
[[TaggedDummyHandlerWithUnionTypes::class, 'handleUnionTypeMessage']]
228+
);
229+
$this->assertHandlerDescriptor(
230+
$container,
231+
$handlerDescriptionMapping,
232+
UnionTypeTwoMessage::class,
233+
[[TaggedDummyHandlerWithUnionTypes::class, 'handleUnionTypeMessage']]
234+
);
235+
}
236+
183237
public function testProcessHandlersByBus()
184238
{
185239
$container = $this->getContainerBuilder($commandBusId = 'command_bus');
@@ -584,6 +638,37 @@ public function testBuiltinArgumentTypeHandler()
584638
(new MessengerPass())->process($container);
585639
}
586640

641+
public function testUnionTypeArgumentsTypeHandler()
642+
{
643+
$container = $this->getContainerBuilder($busId = 'message_bus');
644+
$container
645+
->register(UnionTypeArgumentHandler::class, UnionTypeArgumentHandler::class)
646+
->addTag('messenger.message_handler')
647+
;
648+
649+
(new MessengerPass())->process($container);
650+
651+
$handlersMapping = $container->getDefinition($busId.'.messenger.handlers_locator')->getArgument(0);
652+
653+
$this->assertArrayHasKey(ChildDummyMessage::class, $handlersMapping);
654+
$this->assertArrayHasKey(DummyMessage::class, $handlersMapping);
655+
$this->assertHandlerDescriptor($container, $handlersMapping, ChildDummyMessage::class, [UnionTypeArgumentHandler::class]);
656+
$this->assertHandlerDescriptor($container, $handlersMapping, DummyMessage::class, [UnionTypeArgumentHandler::class]);
657+
}
658+
659+
public function testUnionBuiltinArgumentTypeHandler()
660+
{
661+
$this->expectException(RuntimeException::class);
662+
$this->expectExceptionMessage(sprintf('Invalid handler service "%s": type-hint of argument "$message" in method "%s::__invoke()" must be a class , "string|int" given.', UnionBuiltinTypeArgumentHandler::class, UnionBuiltinTypeArgumentHandler::class));
663+
$container = $this->getContainerBuilder();
664+
$container
665+
->register(UnionBuiltinTypeArgumentHandler::class, UnionBuiltinTypeArgumentHandler::class)
666+
->addTag('messenger.message_handler')
667+
;
668+
669+
(new MessengerPass())->process($container);
670+
}
671+
587672
public function testNeedsToHandleAtLeastOneMessage()
588673
{
589674
$this->expectException(RuntimeException::class);
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
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\Component\Messenger\Tests\Fixtures;
13+
14+
use Symfony\Component\Messenger\Attribute\AsMessageHandler;
15+
16+
#[AsMessageHandler]
17+
class TaggedDummyHandlerWithUnionTypes
18+
{
19+
public function __invoke(DummyMessage|SecondMessage $message)
20+
{
21+
}
22+
23+
#[AsMessageHandler]
24+
public function handleUnionTypeMessage(UnionTypeOneMessage|UnionTypeTwoMessage $message)
25+
{
26+
}
27+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
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\Component\Messenger\Tests\Fixtures;
13+
14+
class UnionBuiltinTypeArgumentHandler
15+
{
16+
public function __invoke(string|int $message): void
17+
{
18+
}
19+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
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\Component\Messenger\Tests\Fixtures;
13+
14+
class UnionTypeArgumentHandler
15+
{
16+
public function __invoke(ChildDummyMessage|DummyMessage $message): void
17+
{
18+
}
19+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
<?php
2+
3+
namespace Symfony\Component\Messenger\Tests\Fixtures;
4+
5+
class UnionTypeOneMessage
6+
{
7+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
<?php
2+
3+
namespace Symfony\Component\Messenger\Tests\Fixtures;
4+
5+
class UnionTypeTwoMessage
6+
{
7+
}

src/Symfony/Component/Security/Core/Resources/translations/security.nb.xlf

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,14 @@
7070
<source>Invalid or expired login link.</source>
7171
<target>Ugyldig eller utløpt påloggingskobling.</target>
7272
</trans-unit>
73+
<trans-unit id="19">
74+
<source>Too many failed login attempts, please try again in %minutes% minute.</source>
75+
<target>For mange mislykkede påloggingsforsøk, prøv igjen om %minutes% minutt.</target>
76+
</trans-unit>
77+
<trans-unit id="20">
78+
<source>Too many failed login attempts, please try again in %minutes% minutes.</source>
79+
<target>For mange mislykkede påloggingsforsøk, prøv igjen om %minutes% minutter.</target>
80+
</trans-unit>
7381
</body>
7482
</file>
7583
</xliff>

0 commit comments

Comments
 (0)
0