10000 Merge branch '6.1' into 6.2 · symfony/symfony@2894680 · GitHub
[go: up one dir, main page]

Skip to content

Commit 2894680

Browse files
Merge branch '6.1' into 6.2
* 6.1: (26 commits) Exclude from baseline generation deprecations triggered in legacy test [HttpFoundation] Update "[Session] Overwrite invalid session id" to only validate when files session storage is used [HttpClient] Fix Copy as curl with base uri [DoctrineBridge] Add missing break [PropertyInfo] CS fix [Serializer] Try all possible denormalization route with union types when ALLOW_EXTRA_ATTRIBUTES=false CS fix [Cache] Respect $save option in ChainAdapter [ExpressionLanguage] fix tests (bis) [ExpressionLanguage] fix tests Allow passing null in twig_is_selected_choice [Cache] Respect $save option in ArrayAdapter [HttpKernel] Disable session tracking while collecting profiler data [MonologBridge] Fixed support of elasticsearch 7.+ in ElasticsearchLogstashHandler Fix HttpClientTrait::jsonEncode flags usage [DoctrineBridge] Extend type guessing on enum fields [FrameworkBundle] Lower JsonSerializableNormalizer priority [WebProfilerBundle] Bump http-kernel requirement to ^6.1 [Messenger] move resetting services at worker stopped into ResetServicesListener [PropertyInfo] Fix multi phpdoc covered promoted properties ...
2 parents 3be9bfb + 4173688 commit 2894680

File tree

44 files changed

+424
-87
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

44 files changed

+424
-87
lines changed

CHANGELOG-6.1.md

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,36 @@ in 6.1 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/v6.1.0...v6.1.1
99

10+
* 6.1.1 (2022-06-09)
11+
12+
* bug #46570 [HttpClient][WebProfilerBundle] Catch errors when encoding body for c… (Phillip Look)
13+
* bug #46583 [HttpClient] Copy as curl fixes (HypeMC)
14+
* bug #46625 [FrameworkBundle] Disable Serializer data collect by default (chalasr)
15+
* bug #46545 Fix getting class constraints on debug command (loic425)
16+
* bug #46548 [Mime] Allow url as a path in the DataPart::fromPath (wkania)
17+
* bug #46576 Fix choice filter error when loading mix of grouped and non-grouped choices (BreyndotEchse)
18+
* bug #46594 [FrameworkBundle] Fix XML cache config (HeahDude)
19+
* bug #46610 [Messenger] use the outermost wrapping DBAL connection (xabbuh)
20+
* bug #46595 [Console] Escape in command name & description from getDefaultName() (ogizanagi)
21+
* bug #46608 [Console] Fix deprecation when description is null (HypeMC)
22+
* bug #46586 [HttpKernel] Fix BackedEnumValueResolver already resolved enum value (janatjak)
23+
* bug #46574 [Console] Escape in command name & description from PHP (getDefault* methods) (ogizanagi)
24+
* bug #46577 [Serializer] Fix ignore attribute in Xml files (alamirault)
25+
* bug #46565 [WebProfilerBundle] Fix dark theme selected line highlight color & reuse css vars (ogizanagi)
26+
* bug #46553 [WebProfilerBundle] normalizer and encoder can be undefined in template (kor3k)
27+
* bug #46538 [FrameworkBundle][HtmlSanitizer] Fix calling `allowStaticElements` when setting `allow_all_static_elements: true` (norkunas)
28+
* bug #46525 [Serializer] Get attributeContext after converting name (zenas1210)
29+
* bug #46535 [Mime] Check that the path is a file in the DataPart::fromPath (wkania)
30+
* bug #46543 [Cache] do not pass null to strlen() (xabbuh)
31+
* bug #46523 [HttpFoundation] Revert "Send `Content-Length` when calling `Response::send()` and the content is a non-empty string" (nicolas-grekas)
32+
* bug #46526 [Serializer] Added missing __call to TraceableEncoder (danielburger1337)
33+
* bug #46527 [Serializer] Forget partially collected traces (mtarld)
34+
* bug #46515 [PropertyInfo] Fix extracting int range type (norkunas)
35+
* bug #46511 [Serializer] Added missing __call to TraceableNormalizer and TraceableSerializer (danielburger1337)
36+
* bug #46478 [Contracts] remove static cache from `ServiceSubscriberTrait` (kbond)
37+
* bug #46480 [FrameworkBundle][TwigBundle] Fix registering html-sanitizer services (nicolas-grekas)
38+
* bug #46475 [MonologBridge] ensure that the $response property is initialized before being read (xabbuh)
39+
1040
* 6.1.0 (2022-05-27)
1141

1242
* bug #46453 [PropertyInfo] Fix resolution of partially docblock covered constructors (ostrolucky)

src/Symfony/Bridge/Doctrine/PropertyInfo/DoctrineExtractor.php

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -135,17 +135,18 @@ public function getTypes(string $class, string $property, array $context = []):
135135
}
136136

137137
if ($metadata->hasField($property)) {
138-
$nullable = $metadata instanceof ClassMetadataInfo && $metadata->isNullable($property);
139-
if (null !== $enumClass = $metadata->getFieldMapping($property)['enumType'] ?? null) {
140-
return [new Type(Type::BUILTIN_TYPE_OBJECT, $nullable, $enumClass)];
141-
}
142-
143138
$typeOfField = $metadata->getTypeOfField($property);
144139

145140
if (!$builtinType = $this->getPhpType($typeOfField)) {
146141
return null;
147142
}
148143

144+
$nullable = $metadata instanceof ClassMetadataInfo && $metadata->isNullable($property);
145+
$enumType = null;
146+
if (null !== $enumClass = $metadata->getFieldMapping($property)['enumType'] ?? null) {
147+
$enumType = new Type(Type::BUILTIN_TYPE_OBJECT, $nullable, $enumClass);
148+
}
149+
149150
switch ($builtinType) {
150151
case Type::BUILTIN_TYPE_OBJECT:
151152
switch ($typeOfField) {
@@ -171,11 +172,23 @@ public function getTypes(string $class, string $property, array $context = []):
171172
switch ($typeOfField) {
172173
case Types::ARRAY:
173174
case 'json_array':
175+
// return null if $enumType is set, because we can't determine if collectionKeyType is string or int
176+
if ($enumType) {
177+
return null;
178+
}
179+
174180
return [new Type(Type::BUILTIN_TYPE_ARRAY, $nullable, null, true)];
175181

176182
case Types::SIMPLE_ARRAY:
177183
return [new Type(Type::BUILTIN_TYPE_ARRAY, $nullable, null, true, new Type(Type::BUILTIN_TYPE_INT), new Type(Type::BUILTIN_TYPE_STRING))];
178184
}
185+
break;
186+
case Type::BUILTIN_TYPE_INT:
187+
case Type::BUILTIN_TYPE_STRING:
188+
if ($enumType) {
189+
return [$enumType];
190+
}
191+
break;
179192
}
180193

181194
return [new Type($builtinType, $nullable)];

src/Symfony/Bridge/Doctrine/Tests/PropertyInfo/DoctrineExtractorTest.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,9 @@ public function testExtractEnum()
127127
}
128128
$this->assertEquals([new Type(Type::BUILTIN_TYPE_OBJECT, false, EnumString::class)], $this->createExtractor()->getTypes(DoctrineEnum::class, 'enumString', []));
129129
$this->assertEquals([new Type(Type::BUILTIN_TYPE_OBJECT, false, EnumInt::class)], $this->createExtractor()->getTypes(DoctrineEnum::class, 'enumInt', []));
130+
$this->assertEquals(null, $this->createExtractor()->getTypes(DoctrineEnum::class, 'enumStringArray', []));
131+
$this->assertEquals([new Type(Type::BUILTIN_TYPE_ARRAY, false, null, true, new Type(Type::BUILTIN_TYPE_INT), new Type(Type::BUILTIN_TYPE_OBJECT, false, EnumInt::class))], $this->createExtractor()->getTypes(DoctrineEnum::class, 'enumIntArray', []));
132+
$this->assertEquals(null, $this->createExtractor()->getTypes(DoctrineEnum::class, 'enumCustom', []));
130133
}
131134

132135
public function typesProvider()

src/Symfony/Bridge/Doctrine/Tests/PropertyInfo/Fixtures/DoctrineEnum.php

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,4 +35,19 @@ class DoctrineEnum
3535
* @Column(type="integer", enumType="Symfony\Bridge\Doctrine\Tests\PropertyInfo\Fixtures\EnumInt")
3636
*/
3737
protected $enumInt;
38+
39+
/**
40+
* @Column(type="array", enumType="Symfony\Bridge\Doctrine\Tests\PropertyInfo\Fixtures\EnumString")
41+
*/
42+
protected $enumStringArray;
43+
44+
/**
45+
* @Column(type="simple_array", enumType="Symfony\Bridge\Doctrine\Tests\PropertyInfo\Fixtures\EnumInt")
46+
*/
47+
protected $enumIntArray;
48+
49+
/**
50+
* @Column(type="custom_foo", enumType="Symfony\Bridge\Doctrine\Tests\PropertyInfo\Fixtures\EnumInt")
51+
*/
52+
protected $enumCustom;
3853
}

src/Symfony/Bridge/Monolog/Handler/ElasticsearchLogstashHandler.php

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -54,13 +54,14 @@ class ElasticsearchLogstashHandler extends AbstractHandler
5454
private string $endpoint;
5555
private string $index;
5656
private HttpClientInterface $client;
57+
private string $elasticsearchVersion;
5758

5859
/**
5960
* @var \SplObjectStorage<ResponseInterface, null>
6061
*/
6162
private \SplObjectStorage $responses;
6263

63-
public function __construct(string $endpoint = 'http://127.0.0.1:9200', string $index = 'monolog', HttpClientInterface $client = null, string|int|Level $level = Logger::DEBUG, bool $bubble = true)
64+
public function __construct(string $endpoint = 'http://127.0.0.1:9200', string $index = 'monolog', HttpClientInterface $client = null, string|int|Level $level = Logger::DEBUG, bool $bubble = true, string $elasticsearchVersion = '1.0.0')
6465
{
6566
if (!interface_exists(HttpClientInterface::class)) {
6667
throw new \LogicException(sprintf('The "%s" handler needs an HTTP client. Try running "composer require symfony/http-client".', __CLASS__));
@@ -71,6 +72,7 @@ public function __construct(string $endpoint = 'http://127.0.0.1:9200', string $
7172
$this->index = $index;
7273
$this->client = $client ?: HttpClient::create(['timeout' => 1]);
7374
$this->responses = new \SplObjectStorage();
75+
$this->elasticsearchVersion = $elasticsearchVersion;
7476
}
7577

7678
private function doHandle(array|LogRecord $record): bool
@@ -108,18 +110,28 @@ private function sendToElasticsearch(array $records)
108110
{
109111
$formatter = $this->getFormatter();
110112

113+
if (version_compare($this->elasticsearchVersion, '7', '>=')) {
114+
$headers = json_encode([
115+
'index' => [
116+
'_index' => $this->index,
117+
],
118+
]);
119+
} else {
120+
$headers = json_encode([
121+
'index' => [
122+
'_index' => $this->index,
123+
'_type' => '_doc',
124+
],
125+
]);
126+
}
127+
111128
$body = '';
112129
foreach ($records as $record) {
113130
foreach ($this->processors as $processor) {
114131
$record = $processor($record);
115132
}
116133

117-
$body .= json_encode([
118-
'index' => [
119-
'_index' => $this->index,
120-
'_type' => '_doc',
121-
],
122-
]);
134+
$body .= $headers;
123135
$body .= "\n";
124136
$body .= $formatter->format($record);
125137
$body .= "\n";

src/Symfony/Bridge/Monolog/Tests/Handler/ElasticsearchLogstashHandlerTest.php

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,49 @@ public function testHandle()
5858
$this->assertSame(1, $callCount);
5959
}
6060

61+
public function testHandleWithElasticsearch8()
62+
{
63+
$callCount = 0;
64+
$responseFactory = function ($method, $url, $options) use (&$callCount) {
65+
$body = <<<EOBODY
66+
{"index":{"_index":"log"}}
67+
{"@timestamp":"2020-01-01T00:00:00.000000+01:00","@version":1,"host":"my hostname","message":"My info message","type":"application","channel":"app","level":"INFO","monolog_level":200}
68+
69+
70+
EOBODY;
71+
72+
// Monolog 1X
73+
if (\defined(LogstashFormatter::class.'::V1')) {
74+
$body = str_replace(',"monolog_level":200', '', $body);
75+
$body = str_replace(',"monolog_level":300', '', $body);
76+
}
77+
78+
$this->assertSame('POST', $method);
79+
$this->assertSame('http://es:9200/_bulk', $url);
80+
$this->assertSame($body, $options['body']);
81+
$this->assertSame('Content-Type: application/json', $options['normalized_headers']['content-type'][0]);
82+
++$callCount;
83+
84+
return new MockResponse();
85+
};
86+
87+
$handler = new ElasticsearchLogstashHandlerWithHardCodedHostname('http://es:9200', 'log', new MockHttpClient($responseFactory), Logger::DEBUG, true, '8.0.0');
88+
89+
$record = [
90+
'message' => 'My info message',
91+
'context' => [],
92+
'level' => Logger::INFO,
93+
'level_name' => Logger::getLevelName(Logger::INFO),
94+
'channel' => 'app',
95+
'datetime' => new \DateTime('2020-01-01T00:00:00+01:00'),
96+
'extra' => [],
97+
];
98+
99+
$handler->handle($record);
100+
101+
$this->assertSame(1, $callCount);
102+
}
103+
61104
public function testHandleBatch()
62105
{
63106
$callCount = 0;

src/Symfony/Bridge/PhpUnit/DeprecationErrorHandler/Configuration.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -208,6 +208,10 @@ public function isIgnoredDeprecation(Deprecation $deprecation): bool
208208
*/
209209
public function isBaselineDeprecation(Deprecation $deprecation)
210210
{
211+
if ($deprecation->isLegacy()) {
212+
return false;
213+
}
214+
211215
if ($deprecation->originatesFromAnObject()) {
212216
$location = $deprecation->originatingClass().'::'.$deprecation->originatingMethod();
213217
} else {

src/Symfony/Bridge/Twig/Extension/FormExtension.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -191,7 +191,7 @@ private function createFieldTranslation(?string $value, array $parameters, strin
191191
*
192192
* @see ChoiceView::isSelected()
193193
*/
194-
function twig_is_selected_choice(ChoiceView $choice, string|array $selectedValue): bool
194+
function twig_is_selected_choice(ChoiceView $choice, string|array|null $selectedValue): bool
195195
{
196196
if (\is_array($selectedValue)) {
197197
return \in_array($choice->value, $selectedValue, true);

src/Symfony/Bundle/FrameworkBundle/Resources/config/serializer.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@
9999

100100
->set('serializer.normalizer.json_serializable', JsonSerializableNormalizer::class)
101101
->args([null, null])
102-
->tag('serializer.normalizer', ['priority' => -900])
102+
->tag('serializer.normalizer', ['priority' => -950])
103103

104104
->set('serializer.normalizer.problem', ProblemNormalizer::class)
105105
->args([param('kernel.debug')])

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1438,7 +1438,7 @@ public function testJsonSerializableNormalizerRegistered()
14381438
$tag = $definition->getTag('serializer.normalizer');
14391439

14401440
$this->assertEquals(JsonSerializableNormalizer::class, $definition->getClass());
1441-
$this->assertEquals(-900, $tag[0]['priority']);
1441+
$this->assertEquals(-950, $tag[0]['priority']);
14421442
}
14431443

14441444
public function testObjectNormalizerRegistered()

src/Symfony/Bundle/WebProfilerBundle/composer.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
"php": ">=8.1",
2020
"symfony/config": "^5.4|^6.0",
2121
"symfony/framework-bundle": "^5.4|^6.0",
22-
"symfony/http-kernel": "^5.4|^6.0",
22+
"symfony/http-kernel": "^6.1",
2323
"symfony/routing": "^5.4|^6.0",
2424
"symfony/twig-bundle": "^5.4|^6.0",
2525
"twig/twig": "^2.13|^3.0.4"

src/Symfony/Component/Cache/Adapter/ArrayAdapter.php

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,10 @@ public function get(string $key, callable $callback, float $beta = null, array &
8585
// ArrayAdapter works in memory, we don't care about stampede protection
8686
if (\INF === $beta || !$item->isHit()) {
8787
$save = true;
88-
$this->save($item->set($callback($item, $save)));
88+
$item->set($callback($item, $save));
89+
if ($save) {
90+
$this->save($item);
91+
}
8992
}
9093

9194
return $item->get();

src/Symfony/Component/Cache/Adapter/ChainAdapter.php

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,9 +93,17 @@ static function ($sourceItem, $item, $defaultLifetime, $sourceMetadata = null) {
9393
*/
9494
public function get(string $key, callable $callback, float $beta = null, array &$metadata = null): mixed
9595
{
96+
$doSave = true;
97+
$callback = static function (CacheItem $item, bool &$save) use ($callback, &$doSave) {
98+
$value = $callback($item, $save);
99+
$doSave = $save;
100+
101+
return $value;
102+
};
103+
96104
$lastItem = null;
97105
$i = 0;
98-
$wrap = function (CacheItem $item = null) use ($key, $callback, $beta, &$wrap, &$i, &$lastItem, &$metadata) {
106+
$wrap = function (CacheItem $item = null, bool &$save = true) use ($key, $callback, $beta, &$wrap, &$i, &$doSave, &$lastItem, &$metadata) {
99107
$adapter = $this->adapters[$i];
100108
if (isset($this->adapters[++$i])) {
101109
$callback = $wrap;
@@ -109,6 +117,7 @@ public function get(string $key, callable $callback, float $beta = null, array &
109117
if (null !== $item) {
110118
(self::$syncItem)($lastItem ??= $item, $item, $this->defaultLifetime, $metadata);
111119
}
120+
$save = $doSave;
112121

113122
return $value;
114123
};

src/Symfony/Component/Cache/Tests/Adapter/AdapterTestCase.php

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,31 @@ public function testRecursiveGet()
108108
$this->assertSame(1, $cache->get('k2', function () { return 2; }));
109109
}
110110

111+
public function testDontSaveWhenAskedNotTo()
112+
{
113+
if (isset($this->skippedTests[__FUNCTION__])) {
114+
$this->markTestSkipped($this->skippedTests[__FUNCTION__]);
115+
}
116+
117+
$cache = $this->createCachePool(0, __FUNCTION__);
118+
119+
$v1 = $cache->get('some-key', function($item, &$save){
120+
$save = false;
121+
return 1;
122+
});
123+
$this->assertSame($v1, 1);
124+
125+
$v2 = $cache->get('some-key', function(){
126+
return 2;
127+
});
128+
$this->assertSame($v2, 2, 'First value was cached and should not have been');
129+
130+
$v3 = $cache->get('some-key', function(){
131+
$this->fail('Value should have come from cache');
132+
});
133+
$this->assertSame($v3, 2);
134+
}
135+
111136
public function testGetMetadata()
112137
{
113138
if (isset($this->skippedTests[__FUNCTION__])) {

src/Symfony/Component/Cache/Tests/Adapter/PhpArrayAdapterTest.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ class PhpArrayAdapterTest extends AdapterTestCase
2525
{
2626
protected $skippedTests = [
2727
'testGet' => 'PhpArrayAdapter is read-only.',
28+
'testDontSaveWhenAskedNotTo' => 'PhpArrayAdapter is read-only.',
2829
'testRecursiveGet' => 'PhpArrayAdapter is read-only.',
2930
'testBasicUsage' => 'PhpArrayAdapter is read-only.',
3031
'testBasicUsageWithLongKey' => 'PhpArrayAdapter is read-only.',

src/Symfony/Component/ExpressionLanguage/Tests/Node/BinaryNodeTest.php

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -180,23 +180,26 @@ public function testEvaluateMatchesWithInvalidRegexp()
180180
{
181181
$node = new BinaryNode('matches', new ConstantNode('abc'), new ConstantNode('this is not a regexp'));
182182

183-
$this->expectExceptionObject(new SyntaxError('Regexp "this is not a regexp" passed to "matches" is not valid: Delimiter must not be alphanumeric or backslash'));
183+
$this->expectException(SyntaxError::class);
184+
$this->expectExceptionMessage('Regexp "this is not a regexp" passed to "matches" is not valid: Delimiter must not be alphanumeric');
184185
$node->evaluate([], []);
185186
}
186187

187188
public function testEvaluateMatchesWithInvalidRegexpAsExpression()
188189
{
189190
$node = new BinaryNode('matches', new ConstantNode('abc'), new NameNode('regexp'));
190191

191-
$this->expectExceptionObject(new SyntaxError('Regexp "this is not a regexp" passed to "matches" is not valid: Delimiter must not be alphanumeric or backslash'));
192+
$this->expectException(SyntaxError::class);
193+
$this->expectExceptionMessage('Regexp "this is not a regexp" passed to "matches" is not valid: Delimiter must not be alphanumeric');
192194
$node->evaluate([], ['regexp' => 'this is not a regexp']);
193195
}
194196

195197
public function testCompileMatchesWithInvalidRegexp()
196198
{
197199
$node = new BinaryNode('matches', new ConstantNode('abc'), new ConstantNode('this is not a regexp'));
198200

199-
$this->expectExceptionObject(new SyntaxError('Regexp "this is not a regexp" passed to "matches" is not valid: Delimiter must not be alphanumeric or backslash'));
201+
$this->expectException(SyntaxError::class);
202+
$this->expectExceptionMessage('Regexp "this is not a regexp" passed to "matches" is not valid: Delimiter must not be alphanumeric');
200203
$compiler = new Compiler([]);
201204
$node->compile($compiler);
202205
}
@@ -205,7 +208,8 @@ public function testCompileMatchesWithInvalidRegexpAsExpression()
205208
{
206209
$node = new BinaryNode('matches', new ConstantNode('abc'), new NameNode('regexp'));
207210

208-
$this->expectExceptionObject(new SyntaxError('Regexp "this is not a regexp" passed to "matches" is not valid: Delimiter must not be alphanumeric or backslash'));
211+
$this->expectException(SyntaxError::class);
212+
$this->expectExceptionMessage('Regexp "this is not a regexp" passed to "matches" is not valid: Delimiter must not be alphanumeric');
209213
$compiler = new Compiler([]);
210214
$node->compile($compiler);
211215
eval('$regexp = "this is not a regexp"; '.$compiler->getSource().';');

0 commit comments

Comments
 (0)
0