Skip to content

Commit 1bb4dda

Browse files
Merge branch '7.3' into 7.4
* 7.3: fall back to legacy options handling if configured named arguments do not match [DependencyInjection] Fix optimizing ClassExistenceResource
2 parents bde5221 + e7c41fe commit 1bb4dda

File tree

5 files changed

+89
-29
lines changed

5 files changed

+89
-29
lines changed

src/Symfony/Component/DependencyInjection/ContainerBuilder.php

Lines changed: 38 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -273,46 +273,58 @@ public function addResource(ResourceInterface $resource): static
273273
if ($resource instanceof DirectoryResource && $this->inVendors($resource->getResource())) {
274274
return $this;
275275
}
276-
if ($resource instanceof ClassExistenceResource) {
277-
$class = $resource->getResource();
276+
if (!$resource instanceof ClassExistenceResource) {
277+
$this->resources[(string) $resource] = $resource;
278278

279-
$inVendor = false;
280-
foreach (spl_autoload_functions() as $autoloader) {
281-
if (!\is_array($autoloader)) {
282-
continue;
283-
}
279+
return $this;
280+
}
284281

285-
if ($autoloader[0] instanceof DebugClassLoader) {
286-
$autoloader = $autoloader[0]->getClassLoader();
287-
}
282+
$class = $resource->getResource();
283+
284+
if (!(new ClassExistenceResource($class, false))->isFresh(1)) {
285+
if (!$this->inVendors((new \ReflectionClass($class))->getFileName())) {
286+
$this->resources[$class] = $resource;
287+
}
288+
289+
return $this;
290+
}
291+
292+
$inVendor = true;
293+
foreach (spl_autoload_functions() as $autoloader) {
294+
if (!\is_array($autoloader)) {
295+
$inVendor = false;
296+
break;
297+
}
298+
299+
if ($autoloader[0] instanceof DebugClassLoader) {
300+
$autoloader = $autoloader[0]->getClassLoader();
301+
}
288302

289-
if (!\is_array($autoloader) || !$autoloader[0] instanceof ClassLoader || !$autoloader[0]->findFile(__CLASS__)) {
303+
if (!\is_array($autoloader) || !$autoloader[0] instanceof ClassLoader) {
304+
$inVendor = false;
305+
break;
306+
}
307+
308+
foreach ($autoloader[0]->getPrefixesPsr4() as $prefix => $dirs) {
309+
if (!str_starts_with($class, $prefix)) {
290310
continue;
291311
}
292312

293-
foreach ($autoloader[0]->getPrefixesPsr4() as $prefix => $dirs) {
294-
if ('' === $prefix || !str_starts_with($class, $prefix)) {
313+
foreach ($dirs as $dir) {
314+
if (!$dir = realpath($dir)) {
295315
continue;
296316
}
297317

298-
foreach ($dirs as $dir) {
299-
if (!$dir = realpath($dir)) {
300-
continue;
301-
}
302-
303-
if (!$inVendor = $this->inVendors($dir)) {
304-
break 3;
305-
}
318+
if (!$inVendor = $this->inVendors($dir)) {
319+
break 3;
306320
}
307321
}
308322
}
309-
310-
if ($inVendor) {
311-
return $this;
312-
}
313323
}
314324

315-
$this->resources[(string) $resource] = $resource;
325+
if (!$inVendor) {
326+
$this->resources[$class] = $resource;
327+
}
316328

317329
return $this;
318330
}

src/Symfony/Component/DependencyInjection/Tests/ContainerBuilderTest.php

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1225,7 +1225,10 @@ public function testGetReflectionClass()
12251225
$r2 = $container->getReflectionClass('BarClass');
12261226
$r3 = $container->getReflectionClass('BarClass');
12271227

1228-
$this->assertNull($container->getReflectionClass('BarMissingClass'));
1228+
$this->assertNull($container->getReflectionClass(BarMissingClass::class));
1229+
1230+
// No resource should be added for this class because no autoloader would be able to load it
1231+
$this->assertNull($container->getReflectionClass(\BarMissingClass::class));
12291232

12301233
$this->assertEquals($r1, $r2);
12311234
$this->assertSame($r2, $r3);
@@ -1235,7 +1238,7 @@ public function testGetReflectionClass()
12351238
$this->assertCount(2, $resources);
12361239

12371240
$this->assertSame('reflection.BarClass', (string) $resources[0]);
1238-
$this->assertSame('BarMissingClass', (string) end($resources));
1241+
$this->assertSame(BarMissingClass::class, (string) end($resources));
12391242
}
12401243

12411244
public function testGetReflectionClassOnInternalTypes()

src/Symfony/Component/Validator/Mapping/Loader/AbstractLoader.php

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,15 @@ protected function newConstraint(string $name, mixed $options = null): Constrain
101101
return new $className($options);
102102
}
103103

104-
return new $className(...$options);
104+
try {
105+
return new $className(...$options);
106+
} catch (\Error $e) {
107+
if (str_starts_with($e->getMessage(), 'Unknown named parameter ')) {
108+
return new $className($options);
109+
}
110+
111+
throw $e;
112+
}
105113
}
106114

107115
if ($options) {

src/Symfony/Component/Validator/Tests/Mapping/Loader/XmlFileLoaderTest.php

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
use Symfony\Component\Validator\Constraints\Choice;
2020
use Symfony\Component\Validator\Constraints\Collection;
2121
use Symfony\Component\Validator\Constraints\IsTrue;
22+
use Symfony\Component\Validator\Constraints\Length;
2223
use Symfony\Component\Validator\Constraints\NotNull;
2324
use Symfony\Component\Validator\Constraints\Range;
2425
use Symfony\Component\Validator\Constraints\Regex;
@@ -201,4 +202,23 @@ public function testLoadConstraintWithoutNamedArgumentsSupport()
201202

202203
$loader->loadClassMetadata($metadata);
203204
}
205+
206+
/**
207+
* @group legacy
208+
*/
209+
public function testLengthConstraintValueOptionTriggersDeprecation()
210+
{
211+
$loader = new XmlFileLoader(__DIR__.'/constraint-mapping-exactly-value.xml');
212+
$metadata = new ClassMetadata(Entity_81::class);
213+
214+
$this->expectUserDeprecationMessage(\sprintf('Since symfony/validator 7.3: Passing an array of options to configure the "%s" constraint is deprecated, use named arguments instead.', Length::class));
215+
216+
$loader->loadClassMetadata($metadata);
217+
$constraints = $metadata->getPropertyMetadata('title')[0]->constraints;
218+
219+
self::assertCount(1, $constraints);
220+
self::assertInstanceOf(Length::class, $constraints[0]);
221+
self::assertSame(6, $constraints[0]->min);
222+
self::assertSame(6, $constraints[0]->max);
223+
}
204224
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<constraint-mapping xmlns="http://symfony.com/schema/dic/constraint-mapping"
3+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4+
xsi:schemaLocation="http://symfony.com/schema/dic/constraint-mapping
5+
https://symfony.com/schema/dic/constraint-mapping/constraint-mapping-1.0.xsd">
6+
7+
<class name="Symfony\Component\Validator\Tests\Fixtures\Entity_81">
8+
<property name="title">
9+
<constraint name="Length">
10+
<option name="value">6</option>
11+
<option name="groups">
12+
<value>Foo</value>
13+
</option>
14+
</constraint>
15+
</property>
16+
</class>
17+
</constraint-mapping>

0 commit comments

Comments
 (0)