Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit adc8a55

Browse files
Merge branch '5.4' into 6.0
* 5.4: [HttpClient] fix resetting DNS/etc when calling CurlHttpClient::reset() Fix invalid guess with enumType [HttpClient] Remove deprecated usage of GuzzleHttp\Promise\promise_for
2 parents 97d36c6 + a4d5fb8 commit adc8a55

File tree

13 files changed

+216
-84
lines changed

13 files changed

+216
-84
lines changed

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

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -135,14 +135,17 @@ 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+
138143
$typeOfField = $metadata->getTypeOfField($property);
139144

140145
if (!$builtinType = $this->getPhpType($typeOfField)) {
141146
return null;
142147
}
143148

144-
$nullable = $metadata instanceof ClassMetadataInfo && $metadata->isNullable($property);
145-
146149
switch ($builtinType) {
147150
case Type::BUILTIN_TYPE_OBJECT:
148151
switch ($typeOfField) {
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <[email protected]>
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\Bridge\Doctrine\Tests\Fixtures;
13+
14+
use Doctrine\ORM\Mapping as ORM;
15+
16+
/**
17+
* @ORM\Entity
18+
*/
19+
class DoctrineLoaderEnum
20+
{
21+
/**
22+
* @ORM\Id
23+
* @ORM\Column
24+
*/
25+
public $id;
26+
27+
/**
28+
* @ORM\Column(type="string", enumType="Symfony\Bridge\Doctrine\Tests\PropertyInfo\Fixtures\EnumString", length=1)
29+
*/
30+
public $enumString;
31+
32+
/**
33+
* @ORM\Column(type="integer", enumType="Symfony\Bridge\Doctrine\Tests\PropertyInfo\Fixtures\EnumInt")
34+
*/
35+
public $enumInt;
36+
}

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

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,16 @@
1414
use Doctrine\Common\Collections\Collection;
1515
use Doctrine\DBAL\Types\Type as DBALType;
1616
use Doctrine\ORM\EntityManager;
17+
use Doctrine\ORM\Mapping\Column;
1718
use Doctrine\ORM\Tools\Setup;
1819
use PHPUnit\Framework\TestCase;
1920
use Symfony\Bridge\Doctrine\PropertyInfo\DoctrineExtractor;
2021
use Symfony\Bridge\Doctrine\Tests\PropertyInfo\Fixtures\DoctrineDummy;
22+
use Symfony\Bridge\Doctrine\Tests\PropertyInfo\Fixtures\DoctrineEnum;
2123
use Symfony\Bridge\Doctrine\Tests\PropertyInfo\Fixtures\DoctrineGeneratedValue;
2224
use Symfony\Bridge\Doctrine\Tests\PropertyInfo\Fixtures\DoctrineRelation;
25+
use Symfony\Bridge\Doctrine\Tests\PropertyInfo\Fixtures\EnumInt;
26+
use Symfony\Bridge\Doctrine\Tests\PropertyInfo\Fixtures\EnumString;
2327
use Symfony\Component\PropertyInfo\Type;
2428

2529
/**
@@ -124,6 +128,18 @@ public function testExtractWithEmbedded()
124128
$this->assertEquals($expectedTypes, $actualTypes);
125129
}
126130

131+
/**
132+
* @requires PHP 8.1
133+
*/
134+
public function testExtractEnum()
135+
{
136+
if (!property_exists(Column::class, 'enumType')) {
137+
$this->markTestSkipped('The "enumType" requires doctrine/orm 2.11.');
138+
}
139+
$this->assertEquals([new Type(Type::BUILTIN_TYPE_OBJECT, false, EnumString::class)], $this->createExtractor()->getTypes(DoctrineEnum::class, 'enumString', []));
140+
$this->assertEquals([new Type(Type::BUILTIN_TYPE_OBJECT, false, EnumInt::class)], $this->createExtractor()->getTypes(DoctrineEnum::class, 'enumInt', []));
141+
}
142+
127143
public function typesProvider()
128144
{
129145
$provider = [
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <[email protected]>
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\Bridge\Doctrine\Tests\PropertyInfo\Fixtures;
13+
14+
use Doctrine\ORM\Mapping\Id;
15+
use Doctrine\ORM\Mapping\Column;
16+
use Doctrine\ORM\Mapping\Entity;
17+
18+
/**
19+
* @Entity
20+
*/
21+
class DoctrineEnum
22+
{
23+
/**
24+
* @Id
25+
* @Column(type="smallint")
26+
*/
27+
public $id;
28+
29+
/**
30+
* @Column(type="string", enumType="Symfony\Bridge\Doctrine\Tests\PropertyInfo\Fixtures\EnumString")
31+
*/
32+
protected $enumString;
33+
34+
/**
35+
* @Column(type="integer", enumType="Symfony\Bridge\Doctrine\Tests\PropertyInfo\Fixtures\EnumInt")
36+
*/
37+
protected $enumInt;
38+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <[email protected]>
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\Bridge\Doctrine\Tests\PropertyInfo\Fixtures;
13+
14+
enum EnumInt: int
15+
{
16+
case Foo = 0;
17+
case Bar = 1;
18+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <[email protected]>
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\Bridge\Doctrine\Tests\PropertyInfo\Fixtures;
13+
14+
enum EnumString: string
15+
{
16+
case Foo = 'f';
17+
case Bar = 'b';
18+
}

src/Symfony/Bridge/Doctrine/Tests/Validator/DoctrineLoaderTest.php

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,13 @@
1111

1212
namespace Symfony\Bridge\Doctrine\Tests\Validator;
1313

14+
use Doctrine\ORM\Mapping\Column;
1415
use PHPUnit\Framework\TestCase;
1516
use Symfony\Bridge\Doctrine\Tests\DoctrineTestHelper;
1617
use Symfony\Bridge\Doctrine\Tests\Fixtures\BaseUser;
1718
use Symfony\Bridge\Doctrine\Tests\Fixtures\DoctrineLoaderEmbed;
1819
use Symfony\Bridge\Doctrine\Tests\Fixtures\DoctrineLoaderEntity;
20+
use Symfony\Bridge\Doctrine\Tests\Fixtures\DoctrineLoaderEnum;
1921
use Symfony\Bridge\Doctrine\Tests\Fixtures\DoctrineLoaderNestedEmbed;
2022
use Symfony\Bridge\Doctrine\Tests\Fixtures\DoctrineLoaderNoAutoMappingEntity;
2123
use Symfony\Bridge\Doctrine\Tests\Fixtures\DoctrineLoaderParentEntity;
@@ -149,6 +151,31 @@ public function testLoadClassMetadata()
149151
$this->assertSame(AutoMappingStrategy::DISABLED, $noAutoMappingMetadata[0]->getAutoMappingStrategy());
150152
}
151153

154+
/**
155+
* @requires PHP 8.1
156+
*/
157+
public function testExtractEnum()
158+
{
159+
if (!property_exists(Column::class, 'enumType')) {
160+
$this->markTestSkipped('The "enumType" requires doctrine/orm 2.11.');
161+
}
162+
163+
$validator = Validation::createValidatorBuilder()
164+
->addMethodMapping('loadValidatorMetadata')
165+
->enableAnnotationMapping()
166+
->addLoader(new DoctrineLoader(DoctrineTestHelper::createTestEntityManager(), '{^Symfony\\\\Bridge\\\\Doctrine\\\\Tests\\\\Fixtures\\\\DoctrineLoader}'))
167+
->getValidator()
168+
;
169+
170+
$classMetadata = $validator->getMetadataFor(new DoctrineLoaderEnum());
171+
172+
$enumStringMetadata = $classMetadata->getPropertyMetadata('enumString');
173+
$this->assertCount(0, $enumStringMetadata); // asserts the length constraint is not added to an enum
174+
175+
$enumStringMetadata = $classMetadata->getPropertyMetadata('enumInt');
176+
$this->assertCount(0, $enumStringMetadata); // asserts the length constraint is not added to an enum
177+
}
178+
152179
public function testFieldMappingsConfiguration()
153180
{
154181
$validator = Validation::createValidatorBuilder()

src/Symfony/Bridge/Doctrine/Validator/DoctrineLoader.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
use Doctrine\ORM\Mapping\MappingException as OrmMappingException;
1717
use Doctrine\Persistence\Mapping\MappingException;
1818
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
19+
use Symfony\Component\PropertyInfo\Type;
1920
use Symfony\Component\Validator\Constraints\Length;
2021
use Symfony\Component\Validator\Constraints\Valid;
2122
use Symfony\Component\Validator\Mapping\AutoMappingStrategy;
@@ -99,7 +100,7 @@ public function loadClassMetadata(ClassMetadata $metadata): bool
99100
$loaded = true;
100101
}
101102

102-
if (null === ($mapping['length'] ?? null) || !\in_array($mapping['type'], ['string', 'text'], true)) {
103+
if (null === ($mapping['length'] ?? null) || null !== ($mapping['enumType'] ?? null) || !\in_array($mapping['type'], ['string', 'text'], true)) {
103104
continue;
104105
}
105106

src/Symfony/Component/HttpClient/CurlHttpClient.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,6 @@ public function request(string $method, string $url, array $options = []): Respo
166166

167167
if ($resolve && 0x072A00 > CurlClientState::$curlVersion['version_number']) {
168168
// DNS cache removals require curl 7.42 or higher
169-
// On lower versions, we have to create a new multi handle
170169
$this->multi->reset();
171170
}
172171

@@ -283,6 +282,7 @@ public function request(string $method, string $url, array $options = []): Respo
283282
if (!$pushedResponse) {
284283
$ch = curl_init();
285284
$this->logger && $this->logger->info(sprintf('Request: "%s %s"', $method, $url));
285+
$curlopts += [\CURLOPT_SHARE => $this->multi->share];
286286
}
287287

288288
foreach ($curlopts as $opt => $value) {
@@ -304,9 +304,9 @@ public function stream(ResponseInterface|iterable $responses, float $timeout = n
304304
$responses = [$responses];
305305
}
306306

307-
if (($mh = $this->multi->handles[0] ?? null) instanceof \CurlMultiHandle) {
307+
if ($this->multi->handle instanceof \CurlMultiHandle) {
308308
$active = 0;
309-
while (\CURLM_CALL_MULTI_PERFORM === curl_multi_exec($mh, $active)) {
309+
while (\CURLM_CALL_MULTI_PERFORM === curl_multi_exec($this->multi->handle, $active)) {
310310
}
311311
}
312312

src/Symfony/Component/HttpClient/Internal/CurlClientState.php

Lines changed: 18 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -23,39 +23,35 @@
2323
*/
2424
final class CurlClientState extends ClientState
2525
{
26-
/** @var array<\CurlMultiHandle> */
27-
public array $handles = [];
26+
public \CurlMultiHandle $handle;
27+
public \CurlShareHandle $share;
2828
/** @var PushedResponse[] */
2929
public array $pushedResponses = [];
30-
public $dnsCache;
30+
public DnsCache $dnsCache;
3131
/** @var float[] */
3232
public array $pauseExpiries = [];
3333
public int $execCounter = \PHP_INT_MIN;
3434
public ?LoggerInterface $logger = null;
3535

3636
public static array $curlVersion;
3737

38-
private int $maxHostConnections;
39-
private int $maxPendingPushes;
40-
4138
public function __construct(int $maxHostConnections, int $maxPendingPushes)
4239
{
4340
self::$curlVersion = self::$curlVersion ?? curl_version();
4441

45-
array_unshift($this->handles, $mh = curl_multi_init());
42+
$this->handle = curl_multi_init();
4643
$this->dnsCache = new DnsCache();
47-
$this->maxHostConnections = $maxHostConnections;
48-
$this->maxPendingPushes = $maxPendingPushes;
44+
$this->reset();
4945

5046
// Don't enable HTTP/1.1 pipelining: it forces responses to be sent in order
5147
if (\defined('CURLPIPE_MULTIPLEX')) {
52-
curl_multi_setopt($mh, \CURLMOPT_PIPELINING, \CURLPIPE_MULTIPLEX);
48+
curl_multi_setopt($this->handle, \CURLMOPT_PIPELINING, \CURLPIPE_MULTIPLEX);
5349
}
5450
if (\defined('CURLMOPT_MAX_HOST_CONNECTIONS')) {
55-
$maxHostConnections = curl_multi_setopt($mh, \CURLMOPT_MAX_HOST_CONNECTIONS, 0 < $maxHostConnections ? $maxHostConnections : \PHP_INT_MAX) ? 0 : $maxHostConnections;
51+
$maxHostConnections = curl_multi_setopt($this->handle, \CURLMOPT_MAX_HOST_CONNECTIONS, 0 < $maxHostConnections ? $maxHostConnections : \PHP_INT_MAX) ? 0 : $maxHostConnections;
5652
}
5753
if (\defined('CURLMOPT_MAXCONNECTS') && 0 < $maxHostConnections) {
58-
curl_multi_setopt($mh, \CURLMOPT_MAXCONNECTS, $maxHostConnections);
54+
curl_multi_setopt($this->handle, \CURLMOPT_MAXCONNECTS, $maxHostConnections);
5955
}
6056

6157
// Skip configuring HTTP/2 push when it's unsupported or buggy, see https://bugs.php.net/77535
@@ -68,40 +64,31 @@ public function __construct(int $maxHostConnections, int $maxPendingPushes)
6864
return;
6965
}
7066

71-
// Clone to prevent a circular reference
72-
$multi = clone $this;
73-
$multi->handles = [$mh];
74-
$multi->pushedResponses = &$this->pushedResponses;
75-
$multi->logger = &$this->logger;
76-
$multi->handlesActivity = &$this->handlesActivity;
77-
$multi->openHandles = &$this->openHandles;
78-
$multi->lastTimeout = &$this->lastTimeout;
79-
80-
curl_multi_setopt($mh, \CURLMOPT_PUSHFUNCTION, static function ($parent, $pushed, array $requestHeaders) use ($multi, $maxPendingPushes) {
81-
return $multi->handlePush($parent, $pushed, $requestHeaders, $maxPendingPushes);
67+
curl_multi_setopt($this->handle, \CURLMOPT_PUSHFUNCTION, function ($parent, $pushed, array $requestHeaders) use ($maxPendingPushes) {
68+
return $this->handlePush($parent, $pushed, $requestHeaders, $maxPendingPushes);
8269
});
8370
}
8471

8572
public function reset()
8673
{
8774
foreach ($this->pushedResponses as $url => $response) {
8875
$this->logger && $this->logger->debug(sprintf('Unused pushed response: "%s"', $url));
89-
90-
foreach ($this->handles as $mh) {
91-
curl_multi_remove_handle($mh, $response->handle);
92-
}
76+
curl_multi_remove_handle($this->handle, $response->handle);
9377
curl_close($response->handle);
9478
}
9579

9680
$this->pushedResponses = [];
9781
$this->dnsCache->evictions = $this->dnsCache->evictions ?: $this->dnsCache->removals;
9882
$this->dnsCache->removals = $this->dnsCache->hostnames = [];
9983

100-
if (\defined('CURLMOPT_PUSHFUNCTION')) {
101-
curl_multi_setopt($this->handles[0], \CURLMOPT_PUSHFUNCTION, null);
102-
}
84+
$this->share = curl_share_init();
85+
86+
curl_share_setopt($this->share, \CURLSHOPT_SHARE, \CURL_LOCK_DATA_DNS);
87+
curl_share_setopt($this->share, \CURLSHOPT_SHARE, \CURL_LOCK_DATA_SSL_SESSION);
10388

104-
$this->__construct($this->maxHostConnections, $this->maxPendingPushes);
89+
if (\defined('CURL_LOCK_DATA_CONNECT')) {
90+
curl_share_setopt($this->share, \CURLSHOPT_SHARE, \CURL_LOCK_DATA_CONNECT);
91+
}
10592
}
10693

10794
private function handlePush($parent, $pushed, array $requestHeaders, int $maxPendingPushes): int

0 commit comments

Comments
 (0)