8000 Merge branch '6.0' into 6.1 · symfony/symfony@4173688 · GitHub
[go: up one dir, main page]

Skip to content
10000

Commit 4173688

Browse files
Merge branch '6.0' into 6.1
* 6.0: 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 [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 [DoctrineBridge] Extend type guessing on enum fields [FrameworkBundle] Lower JsonSerializableNormalizer priority [Messenger] move resetting services at worker stopped into ResetServicesListener [Mailer] Fix Error Handling for OhMySMTP Bridge Fix for missing sender name in case with usage of the EnvelopeListener
2 parents 6b44dc6 + a701c81 commit 4173688

File tree

32 files changed

+352
-68
lines changed

32 files changed

+352
-68
lines changed

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
@@ -98,7 +98,7 @@
9898

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

103103
->set('serializer.normalizer.problem', ProblemNormalizer::class)
104104
->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/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().';');

src/Symfony/Component/Form/Extension/Core/Type/FileType.php

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -193,11 +193,8 @@ private static function getMaxFilesize(): int|float
193193

194194
switch (substr($iniMax, -1)) {
195195
case 't': $max *= 1024;
196-
// no break
197196
case 'g': $max *= 1024;
198-
// no break
199197
case 'm': $max *= 1024;
200-
// no break
201198
case 'k': $max *= 1024;
202199
}
203200

src/Symfony/Component/Form/Util/ServerParams.php

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -58,11 +58,8 @@ public function getPostMaxSize(): int|float|null
5858

5959
switch (substr($iniMax, -1)) {
6060
case 't': $max *= 1024;
61-
// no break
6261
case 'g': $max *= 1024;
63-
// no break
6462
case 'm': $max *= 1024;
65-
// no break
6663
case 'k': $max *= 1024;
6764
}
6865

src/Symfony/Component/HttpFoundation/File/UploadedFile.php

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -234,11 +234,8 @@ private static function parseFilesize(string $size): int|float
234234

235235
switch (substr($size, -1)) {
236236
case 't': $max *= 1024;
237-
// no break
238237
case 'g': $max *= 1024;
239-
// no break
240238
case 'm': $max *= 1024;
241-
// no break
242239
case 'k': $max *= 1024;
243240
}
244241

src/Symfony/Component/HttpFoundation/Session/Storage/NativeSessionStorage.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,7 @@ public function start(): bool
136136
}
137137

138138
$sessionId = $_COOKIE[session_name()] ?? null;
139-
if ($sessionId && !preg_match('/^[a-zA-Z0-9,-]{22,}$/', $sessionId)) {
139+
if ($sessionId && $this->saveHandler instanceof AbstractProxy && 'files' === $this->saveHandler->getSaveHandlerName() && !preg_match('/^[a-zA-Z0-9,-]{22,}$/', $sessionId)) {
140140
// the session ID in the header is invalid, create a new one
141141
session_id(session_create_id());
142142
}

0 commit comments

Comments
 (0)
0