Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 4ababf2

Browse filesBrowse files
committed
Merge branch '7.2' into 7.3
* 7.2: Bump Symfony version to 7.2.2 Fix resolve enum in string type resolver Update VERSION for 7.2.1 Update CHANGELOG for 7.2.1 [PropertyInfo] Upmerge #59012 [BeanstalkMessenger] Round delay to an integer to avoid deprecation warning [Console] Fix tests [PropertyInfo] Fix interface handling in `PhpStanTypeHelper` [TypeInfo] Remove useless dependency [HttpClient] Test POST to GET redirects [TypeInfo] Fix outdated README [HttpKernel] Denormalize request data using the csv format when using "#[MapQueryString]" or "#[MapRequestPayload]" (except for content data) [TypeInfo] Fix handle nullable with mixed fix: preserve and nowrap in profiler code highlighting
2 parents 981c3a2 + 3766572 commit 4ababf2
Copy full SHA for 4ababf2

File tree

Expand file treeCollapse file tree

21 files changed

+318
-32
lines changed
Filter options
Expand file treeCollapse file tree

21 files changed

+318
-32
lines changed

‎CHANGELOG-7.2.md

Copy file name to clipboardExpand all lines: CHANGELOG-7.2.md
+12Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,18 @@ in 7.2 minor versions.
77
To get the diff for a specific change, go to https://github.com/symfony/symfony/commit/XXX where XXX is the change hash
88
To get the diff between two versions, go to https://github.com/symfony/symfony/compare/v7.2.0...v7.2.1
99

10+
* 7.2.1 (2024-12-11)
11+
12+
* bug #59145 [TypeInfo] Make `Type::nullable` method no-op on every nullable type (mtarld)
13+
* bug #59122 [Notifier] fix desktop channel bus abstract arg (raphael-geffroy)
14+
* bug #59124 [FrameworkBundle] fix: notifier push channel bus abstract arg (raphael-geffroy)
15+
* bug #59069 [Console] Fix division by 0 error (Rindula)
16+
* bug #59086 [FrameworkBundle] Make uri_signer lazy and improve error when kernel.secret is empty (nicolas-grekas)
17+
* bug #59099 [sendgrid-mailer] Fix null check on region (AUDUL)
18+
* bug #59070 [PropertyInfo] evaluate access flags for properties with asymmetric visibility (xabbuh)
19+
* bug #59062 [HttpClient] Always set CURLOPT_CUSTOMREQUEST to the correct HTTP method in CurlHttpClient (KurtThiemann)
20+
* bug #59059 [TwigBridge] generate conflict-free variable names (xabbuh)
21+
1022
* 7.2.0 (2024-11-29)
1123

1224
* bug #59023 [HttpClient] Fix streaming and redirecting with NoPrivateNetworkHttpClient (nicolas-grekas)

‎src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/open.css.twig

Copy file name to clipboardExpand all lines: src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/open.css.twig
+1Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
#source .source-content ol li {
4141
margin: 0 0 2px 0;
4242
padding-left: 5px;
43+
white-space: preserve nowrap;
4344
}
4445
#source .source-content ol li::marker {
4546
color: var(--color-muted);

‎src/Symfony/Component/Console/Tests/ApplicationTest.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/Console/Tests/ApplicationTest.php
+1Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ protected function tearDown(): void
7979
pcntl_signal(\SIGTERM, \SIG_DFL);
8080
pcntl_signal(\SIGUSR1, \SIG_DFL);
8181
pcntl_signal(\SIGUSR2, \SIG_DFL);
82+
pcntl_signal(\SIGALRM, \SIG_DFL);
8283
}
8384
}
8485

‎src/Symfony/Component/Console/Tests/ConsoleEventsTest.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/Console/Tests/ConsoleEventsTest.php
+1Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ protected function tearDown(): void
3939
pcntl_signal(\SIGTERM, \SIG_DFL);
4040
pcntl_signal(\SIGUSR1, \SIG_DFL);
4141
pcntl_signal(\SIGUSR2, \SIG_DFL);
42+
pcntl_signal(\SIGALRM, \SIG_DFL);
4243
}
4344
}
4445

‎src/Symfony/Component/Console/Tests/SignalRegistry/SignalRegistryTest.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/Console/Tests/SignalRegistry/SignalRegistryTest.php
+1Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ protected function tearDown(): void
2727
pcntl_signal(\SIGTERM, \SIG_DFL);
2828
pcntl_signal(\SIGUSR1, \SIG_DFL);
2929
pcntl_signal(\SIGUSR2, \SIG_DFL);
30+
pcntl_signal(\SIGALRM, \SIG_DFL);
3031
}
3132

3233
public function testOneCallbackForASignalSignalIsHandled()

‎src/Symfony/Component/HttpClient/Tests/HttpClientTestCase.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/HttpClient/Tests/HttpClientTestCase.php
+22Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -678,4 +678,26 @@ public function testHeadRequestWithClosureBody()
678678
$this->assertIsArray($vars);
679679
$this->assertSame('HEAD', $vars['REQUEST_METHOD']);
680680
}
681+
682+
/**
683+
* @testWith [301]
684+
* [302]
685+
* [303]
686+
*/
687+
public function testPostToGetRedirect(int $status)
688+
{
689+
$p = TestHttpServer::start(8067);
690+
691+
try {
692+
$client = $this->getHttpClient(__FUNCTION__);
693+
694+
$response = $client->request('POST', 'http://localhost:8057/custom?status=' . $status . '&headers[]=Location%3A%20%2F');
695+
$body = $response->toArray();
696+
} finally {
697+
$p->stop();
698+
}
699+
700+
$this->assertSame('GET', $body['REQUEST_METHOD']);
701+
$this->assertSame('/', $body['REQUEST_URI']);
702+
}
681703
}

‎src/Symfony/Component/HttpKernel/Controller/ArgumentResolver/RequestPayloadValueResolver.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/HttpKernel/Controller/ArgumentResolver/RequestPayloadValueResolver.php
+2-4Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -46,11 +46,9 @@
4646
class RequestPayloadValueResolver implements ValueResolverInterface, EventSubscriberInterface
4747
{
4848
/**
49-
* @see \Symfony\Component\Serializer\Normalizer\AbstractObjectNormalizer::DISABLE_TYPE_ENFORCEMENT
5049
* @see DenormalizerInterface::COLLECT_DENORMALIZATION_ERRORS
5150
*/
5251
private const CONTEXT_DENORMALIZE = [
53-
'disable_type_enforcement' => true,
5452
'collect_denormalization_errors' => true,
5553
];
5654

@@ -190,7 +188,7 @@ private function mapQueryString(Request $request, ArgumentMetadata $argument, Ma
190188
return null;
191189
}
192190

193-
return $this->serializer->denormalize($data, $argument->getType(), null, $attribute->serializationContext + self::CONTEXT_DENORMALIZE + ['filter_bool' => true]);
191+
return $this->serializer->denormalize($data, $argument->getType(), 'csv', $attribute->serializationContext + self::CONTEXT_DENORMALIZE + ['filter_bool' => true]);
194192
}
195193

196194
private function mapRequestPayload(Request $request, ArgumentMetadata $argument, MapRequestPayload $attribute): object|array|null
@@ -210,7 +208,7 @@ private function mapRequestPayload(Request $request, ArgumentMetadata $argument,
210208
}
211209

212210
if ($data = $request->request->all()) {
213-
return $this->serializer->denormalize($data, $type, null, $attribute->serializationContext + self::CONTEXT_DENORMALIZE + ('form' === $format ? ['filter_bool' => true] : []));
211+
return $this->serializer->denormalize($data, $type, 'csv', $attribute->serializationContext + self::CONTEXT_DENORMALIZE + ('form' === $format ? ['filter_bool' => true] : []));
214212
}
215213

216214
if ('' === ($data = $request->getContent()) && ($argument->isNullable() || $argument->hasDefaultValue())) {

‎src/Symfony/Component/HttpKernel/Tests/Controller/ArgumentResolver/RequestPayloadValueResolverTest.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/HttpKernel/Tests/Controller/ArgumentResolver/RequestPayloadValueResolverTest.php
+65Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
use Symfony\Component\HttpKernel\Exception\HttpException;
2323
use Symfony\Component\HttpKernel\Exception\NearMissValueResolverException;
2424
use Symfony\Component\HttpKernel\HttpKernelInterface;
25+
use Symfony\Component\PropertyInfo\Extractor\ReflectionExtractor;
2526
use Symfony\Component\Serializer\Encoder\JsonEncoder;
2627
use Symfony\Component\Serializer\Encoder\XmlEncoder;
2728
use Symfony\Component\Serializer\Exception\NotNormalizableValueException;
@@ -395,6 +396,38 @@ public function testQueryStringValidationPassed()
395396
$this->assertEquals([$payload], $event->getArguments());
396397
}
397398

399+
public function testQueryStringParameterTypeMismatch()
400+
{
401+
$query = ['price' => 'not a float'];
402+
403+
$normalizer = new ObjectNormalizer(null, null, null, new ReflectionExtractor());
404+
$serializer = new Serializer([$normalizer], ['json' => new JsonEncoder()]);
405+
406+
$validator = $this->createMock(ValidatorInterface::class);
407+
$validator->expects($this->never())->method('validate');
408+
409+
$resolver = new RequestPayloadValueResolver($serializer, $validator);
410+
411+
$argument = new ArgumentMetadata('invalid', RequestPayload::class, false, false, null, false, [
412+
MapQueryString::class => new MapQueryString(),
413+
]);
414+
415+
$request = Request::create('/', 'GET', $query);
416+
417+
$kernel = $this->createMock(HttpKernelInterface::class);
418+
$arguments = $resolver->resolve($request, $argument);
419+
$event = new ControllerArgumentsEvent($kernel, function () {}, $arguments, $request, HttpKernelInterface::MAIN_REQUEST);
420+
421+
try {
422+
$resolver->onKernelControllerArguments($event);
423+
$this->fail(sprintf('Expected "%s" to be thrown.', HttpException::class));
424+
} catch (HttpException $e) {
425+
$validationFailedException = $e->getPrevious();
426+
$this->assertInstanceOf(ValidationFailedException::class, $validationFailedException);
427+
$this->assertSame('This value should be of type float.', $validationFailedException->getViolations()[0]->getMessage());
428+
}
429+
}
430+
398431
public function testRequestInputValidationPassed()
399432
{
400433
$input = ['price' => '50'];
@@ -457,6 +490,38 @@ public function testRequestArrayDenormalization()
457490
$this->assertEquals([$payload], $event->getArguments());
458491
}
459492

493+
public function testRequestInputTypeMismatch()
494+
{
495+
$input = ['price' => 'not a float'];
496+
497+
$normalizer = new ObjectNormalizer(null, null, null, new ReflectionExtractor());
498+
$serializer = new Serializer([$normalizer], ['json' => new JsonEncoder()]);
499+
500+
$validator = $this->createMock(ValidatorInterface::class);
501+
$validator->expects($this->never())->method('validate');
502+
503+
$resolver = new RequestPayloadValueResolver($serializer, $validator);
504+
505+
$argument = new ArgumentMetadata('invalid', RequestPayload::class, false, false, null, false, [
506+
MapRequestPayload::class => new MapRequestPayload(),
507+
]);
508+
509+
$request = Request::create('/', 'POST', $input);
510+
511+
$kernel = $this->createMock(HttpKernelInterface::class);
512+
$arguments = $resolver->resolve($request, $argument);
513+
$event = new ControllerArgumentsEvent($kernel, function () {}, $arguments, $request, HttpKernelInterface::MAIN_REQUEST);
514+
515+
try {
516+
$resolver->onKernelControllerArguments($event);
517+
$this->fail(sprintf('Expected "%s" to be thrown.', HttpException::class));
518+
} catch (HttpException $e) {
519+
$validationFailedException = $e->getPrevious();
520+
$this->assertInstanceOf(ValidationFailedException::class, $validationFailedException);
521+
$this->assertSame('This value should be of type float.', $validationFailedException->getViolations()[0]->getMessage());
522+
}
523+
}
524+
460525
public function testItThrowsOnMissingAttributeType()
461526
{
462527
$serializer = new Serializer();

‎src/Symfony/Component/Messenger/Bridge/Beanstalkd/Tests/Transport/ConnectionTest.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/Messenger/Bridge/Beanstalkd/Tests/Transport/ConnectionTest.php
+21Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -363,4 +363,25 @@ public function testKeepaliveWhenABeanstalkdExceptionOccurs()
363363
$this->expectExceptionObject(new TransportException($exception->getMessage(), 0, $exception));
364364
$connection->keepalive((string) $id);
365365
}
366+
367+
public function testSendWithRoundedDelay()
368+
{
369+
$tube = 'xyz';
370+
$body = 'foo';
371+
$headers = ['test' => 'bar'];
372+
$delay = 920;
373+
$expectedDelay = 0;
374+
375+
$client = $this->createMock(PheanstalkInterface::class);
376+
$client->expects($this->once())->method('useTube')->with($tube)->willReturn($client);
377+
$client->expects($this->once())->method('put')->with(
378+
$this->anything(),
379+
$this->anything(),
380+
$expectedDelay,
381+
$this->anything(),
382+
);
383+
384+
$connection = new Connection(['tube_name' => $tube], $client);
385+
$connection->send($body, $headers, $delay);
386+
}
366387
}

‎src/Symfony/Component/Messenger/Bridge/Beanstalkd/Transport/Connection.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/Messenger/Bridge/Beanstalkd/Transport/Connection.php
+1-1Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@ public function send(string $body, array $headers, int $delay = 0): string
124124
$job = $this->client->useTube($this->tube)->put(
125125
$message,
126126
PheanstalkInterface::DEFAULT_PRIORITY,
127-
$delay / 1000,
127+
(int) ($delay / 1000),
128128
$this->ttr
129129
);
130130
} catch (Exception $exception) {

‎src/Symfony/Component/PropertyInfo/Tests/Extractor/PhpStanExtractorTest.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/PropertyInfo/Tests/Extractor/PhpStanExtractorTest.php
+109-1Lines changed: 109 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,15 +14,18 @@
1414
use PHPUnit\Framework\TestCase;
1515
use Symfony\Component\PropertyInfo\Extractor\PhpDocExtractor;
1616
use Symfony\Component\PropertyInfo\Extractor\PhpStanExtractor;
17+
use Symfony\Component\PropertyInfo\Tests\Fixtures\Clazz;
1718
use Symfony\Component\PropertyInfo\Tests\Fixtures\ConstructorDummy;
1819
use Symfony\Component\PropertyInfo\Tests\Fixtures\ConstructorDummyWithoutDocBlock;
1920
use Symfony\Component\PropertyInfo\Tests\Fixtures\DefaultValue;
2021
use Symfony\Component\PropertyInfo\Tests\Fixtures\DockBlockFallback;
2122
use Symfony\Component\PropertyInfo\Tests\Fixtures\Dummy;
2223
use Symfony\Component\PropertyInfo\Tests\Fixtures\DummyCollection;
24+
use Symfony\Component\PropertyInfo\Tests\Fixtures\DummyGeneric;
2325
use Symfony\Component\PropertyInfo\Tests\Fixtures\DummyNamespace;
2426
use Symfony\Component\PropertyInfo\Tests\Fixtures\DummyPropertyAndGetterWithDifferentTypes;
2527
use Symfony\Component\PropertyInfo\Tests\Fixtures\DummyUnionType;
28+
use Symfony\Component\PropertyInfo\Tests\Fixtures\IFace;
2629
use Symfony\Component\PropertyInfo\Tests\Fixtures\IntRangeDummy;
2730
use Symfony\Component\PropertyInfo\Tests\Fixtures\InvalidDummy;
2831
use Symfony\Component\PropertyInfo\Tests\Fixtures\ParentDummy;
@@ -552,6 +555,77 @@ public static function allowPrivateAccessLegacyProvider(): array
552555
];
553556
}
554557

558+
/**
559+
* @param list<LegacyType> $expectedTypes
560+
*
561+
* @dataProvider legacyGenericsProvider
562+
*/
563+
public function testGenericsLegacy(string $property, array $expectedTypes)
564+
{
565+
$this->assertEquals($expectedTypes, $this->extractor->getTypes(DummyGeneric::class, $property));
566+
}
567+
568+
/**
569+
* @return iterable<array{0: string, 1: list<LegacyType>}>
570+
*/
571+
public static function legacyGenericsProvider(): iterable
572+
{
573+
yield [
574+
'basicClass',
575+
[
576+
new LegacyType(
577+
builtinType: LegacyType::BUILTIN_TYPE_OBJECT,
578+
class: Clazz::class,
579+
collectionValueType: new LegacyType(
580+
builtinType: LegacyType::BUILTIN_TYPE_OBJECT,
581+
class: Dummy::class,
582+
)
583+
),
584+
],
585+
];
586+
yield [
587+
'nullableClass',
588+
[
589+
new LegacyType(
590+
builtinType: LegacyType::BUILTIN_TYPE_OBJECT,
591+
class: Clazz::class,
592+
nullable: true,
593+
collectionValueType: new LegacyType(
594+
builtinType: LegacyType::BUILTIN_TYPE_OBJECT,
595+
class: Dummy::class,
596+
)
597+
),
598+
],
599+
];
600+
yield [
601+
'basicInterface',
602+
[
603+
new LegacyType(
604+
builtinType: LegacyType::BUILTIN_TYPE_OBJECT,
605+
class: IFace::class,
606+
collectionValueType: new LegacyType(
607+
builtinType: LegacyType::BUILTIN_TYPE_OBJECT,
608+
class: Dummy::class,
609+
)
610+
),
611+
],
612+
];
613+
yield [
614+
'nullableInterface',
615+
[
616+
new LegacyType(
617+
builtinType: LegacyType::BUILTIN_TYPE_OBJECT,
618+
class: IFace::class,
619+
nullable: true,
620+
collectionValueType: new LegacyType(
621+
builtinType: LegacyType::BUILTIN_TYPE_OBJECT,
622+
class: Dummy::class,
623+
)
624+
),
625+
],
626+
];
627+
}
628+
555629
/**
556630
* @dataProvider typesProvider
557631
*/
@@ -968,7 +1042,41 @@ public static function allowPrivateAccessProvider(): array
9681042

9691043
public function testGenericInterface()
9701044
{
971-
$this->assertNull($this->extractor->getTypes(Dummy::class, 'genericInterface'));
1045+
$this->assertEquals(
1046+
Type::generic(Type::object(\BackedEnum::class), Type::string()),
1047+
$this->extractor->getType(Dummy::class, 'genericInterface'),
1048+
);
1049+
}
1050+
1051+
/**
1052+
* @dataProvider genericsProvider
1053+
*/
1054+
public function testGenerics(string $property, Type $expectedType)
1055+
{
1056+
$this->assertEquals($expectedType, $this->extractor->getType(DummyGeneric::class, $property));
1057+
}
1058+
1059+
/**
1060+
* @return iterable<array{0: string, 1: Type}>
1061+
*/
1062+
public static function genericsProvider(): iterable
1063+
{
1064+
yield [
1065+
'basicClass',
1066+
Type::generic(Type::object(Clazz::class), Type::object(Dummy::class)),
1067+
];
1068+
yield [
1069+
'nullableClass',
1070+
Type::nullable(Type::generic(Type::object(Clazz::class), Type::object(Dummy::class))),
1071+
];
1072+
yield [
1073+
'basicInterface',
1074+
Type::generic(Type::object(IFace::class), Type::object(Dummy::class)),
1075+
];
1076+
yield [
1077+
'nullableInterface',
1078+
Type::nullable(Type::generic(Type::object(IFace::class), Type::object(Dummy::class))),
1079+
];
9721080
}
9731081
}
9741082

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.