8000 Merge branch '6.2' into 6.3 · symfony/symfony@6d2594e · GitHub
[go: up one dir, main page]

Skip to content

Commit 6d2594e

Browse files
committed
Merge branch '6.2' into 6.3
* 6.2: Fix generated changelog for v6.2.1 [DependencyInjection] Generate different classes for ghost objects and virtual proxies [FrameworkBundle] fix removing commands if console not available [DoctrineBridge] Skip resolving entities when the corresponding request attribute is already an object
2 parents 6dc7330 + 0d95f41 commit 6d2594e

File tree

14 files changed

+106
-121
lines changed

14 files changed

+106
-121
lines changed

CHANGELOG-6.2.md

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,6 @@ To get the diff between two versions, go to https://github.com/symfony/symfony/c
2222
* bug #48046 [WebProfilerBundle] Remove redundant code from logger template (HypeMC)
2323
* bug #48428 Fixed undefined variable error (Kevin Meijer)
2424
* bug #48416 [FrameworkBundle] don't register the MailerTestCommand symfony/console is not installed (xabbuh)
25-
* bug #48395 [String] Fix AsciiSlugger with emojis (fancyweb)
26-
* bug #48385 [Security] Reuse `AbstractFactory`'s config tree in `AccessTokenFactory` (chalasr)
27-
* bug #48292 [Security] [LoginLink] Throw InvalidLoginLinkException on missing parameter (MatTheCat)
2825

2926
* 6.2.0 (2022-11-30)
3027

src/Symfony/Bridge/Doctrine/ArgumentResolver/EntityValueResolver.php

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,13 @@ public function __construct(
4040

4141
public function resolve(Request $request, ArgumentMetadata $argument): array
4242
{
43-
$options = $t A3E2 his->getMapEntityAttribute($argument);
43+
if (\is_object($request->attributes->get($argument->getName()))) {
44+
return [];
45+
}
46+
47+
$options = $argument->getAttributes(MapEntity::class, ArgumentMetadata::IS_INSTANCEOF);
48+
$options = ($options[0] ?? $this->defaults)->withDefaults($this->defaults, $argument->getType());
49+
4450
if (!$options->class || $options->disabled) {
4551
return [];
4652
}
@@ -201,12 +207,4 @@ private function findViaExpression(ObjectManager $manager, Request $request, Map
201207
return null;
202208
}
203209
}
204-
205-
private function getMapEntityAttribute(ArgumentMetadata $argument): MapEntity
206-
{
207-
/** @var MapEntity $options */
208-
$options = $argument->getAttributes(MapEntity::class, ArgumentMetadata::IS_INSTANCEOF)[0] ?? $this->defaults;
209-
210-
return $options->withDefaults($this->defaults, $argument->getType());
211-
}
212210
}
F438

src/Symfony/Bridge/Doctrine/Tests/ArgumentResolver/EntityValueResolverTest.php

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -373,6 +373,20 @@ public function testExpressionSyntaxErrorThrowsException()
373373
$resolver->resolve($request, $argument);
374374
}
375375

376+
public function testAlreadyResolved()
377+
{
378+
$manager = $this->getMockBuilder(ObjectManager::class)->getMock();
379+
$registry = $this->createRegistry($manager);
380+
$resolver = new EntityValueResolver($registry);
381+
382+
$request = new Request();
383+
$request->attributes->set('arg', new \stdClass());
384+
385+
$argument = $this->createArgument('stdClass', name: 'arg');
386+
387+
$this->assertSame([], $resolver->resolve($request, $argument));
388+
}
389+
376390
private function createArgument(string $class = null, MapEntity $entity = null, string $name = 'arg', bool $isNullable = false): ArgumentMetadata
377391
{
378392
return new ArgumentMetadata($name, $class ?? \stdClass::class, false, false, null, $isNullable, $entity ? [$entity] : []);

src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -398,7 +398,7 @@ public function load(array $configs, ContainerBuilder $container)
398398
if ($this->readConfigEnabled('mailer', $container, $config['mailer'])) {
399399
$this->registerMailerConfiguration($config['mailer'], $container, $loader);
400400

401-
if (!class_exists(MailerTestCommand::class) || !$this->hasConsole()) {
401+
if (!$this->hasConsole() || !class_exists(MailerTestCommand::class)) {
402402
$container->removeDefinition('console.command.mailer_test');
403403
}
404404
}
@@ -1979,7 +1979,7 @@ private function registerMessengerConfiguration(array $config, ContainerBuilder
19791979
throw new LogicException('Messenger support cannot be enabled as the Messenger component is not installed. Try running "composer require symfony/messenger".');
19801980
}
19811981

1982-
if (!class_exists(StatsCommand::class)) {
1982+
if (!$this->hasConsole() || !class_exists(StatsCommand::class)) {
19831983
$container->removeDefinition('console.command.messenger_stats');
19841984
}
19851985

src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -567,10 +567,10 @@ private function generateProxyClasses(): array
567567
if (!$definition = $this->isProxyCandidate($definition, $asGhostObject, $id)) {
568568
continue;
569569
}
570-
if (isset($alreadyGenerated[$class = $definition->getClass()])) {
570+
if (isset($alreadyGenerated[$asGhostObject][$class = $definition->getClass()])) {
571571
continue;
572572
}
573-
$alreadyGenerated[$class] = true;
573+
$alreadyGenerated[$asGhostObject][$class] = true;
574574
// register class' reflector for resource tracking
575575
$this->container->getReflectionClass($class);
576576
if ("\n" === $proxyCode = "\n".$proxyDumper->getProxyCode($definition, $id)) {

src/Symfony/Component/DependencyInjection/LazyProxy/Instantiator/LazyServiceInstantiator.php

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@
1313

1414
use Symfony\Component\DependencyInjection\ContainerInterface;
1515
use Symfony\Component\DependencyInjection\Definition;
16+
use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
1617
use Symfony\Component\DependencyInjection\LazyProxy\PhpDumper\LazyServiceDumper;
17-
use Symfony\Component\VarExporter\LazyGhostTrait;
1818

1919
/**
2020
* @author Nicolas Grekas <p@tchwork.com>
@@ -25,10 +25,14 @@ public function instantiateProxy(ContainerInterface $container, Definition $defi
2525
{
2626
$dumper = new LazyServiceDumper();
2727

28-
if (!class_exists($proxyClass = $dumper->getProxyClass($definition, $class), false)) {
28+
if (!$dumper->isProxyCandidate($definition, $asGhostObject, $id)) {
29+
throw new InvalidArgumentException(sprintf('Cannot instantiate lazy proxy for service "%s".', $id));
30+
}
31+
32+
if (!class_exists($proxyClass = $dumper->getProxyClass($definition, $asGhostObject, $class), false)) {
2933
eval($dumper->getProxyCode($definition, $id));
3034
}
3135

32-
return isset(class_uses($proxyClass)[LazyGhostTrait::class]) ? $proxyClass::createLazyGhost($realInstantiator) : $proxyClass::createLazyProxy($realInstantiator);
36+
return $asGhostObject ? $proxyClass::createLazyGhost($realInstantiator) : $proxyClass::createLazyProxy($realInstantiator);
3337
}
3438
}

src/Symfony/Component/DependencyInjection/LazyProxy/PhpDumper/LazyServiceDumper.php

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -72,9 +72,10 @@ public function getProxyFactoryCode(Definition $definition, string $id, string $
7272
$instantiation .= sprintf(' $this->%s[%s] =', $definition->isPublic() && !$definition->isPrivate() ? 'services' : 'privates', var_export($id, true));
7373
}
7474

75-
$proxyClass = $this->getProxyClass($definition);
75+
$asGhostObject = str_contains($factoryCode, '$proxy');
76+
$proxyClass = $this->getProxyClass($definition, $asGhostObject);
7677

77-
if (!str_contains($factoryCode, '$proxy')) {
78+
if (!$asGhostObject) {
7879
return <<<EOF
7980
if (true === \$lazyLoad) {
8081
$instantiation \$this->createProxy('$proxyClass', fn () => \\$proxyClass::createLazyProxy(fn () => $factoryCode));
@@ -104,7 +105,7 @@ public function getProxyCode(Definition $definition, string $id = null): string
104105
if (!$this->isProxyCandidate($definition, $asGhostObject, $id)) {
105106
throw new InvalidArgumentException(sprintf('Cannot instantiate lazy proxy for service "%s".', $id ?? $definition->getClass()));
106107
}
107-
$proxyClass = $this->getProxyClass($definition, $class);
108+
$proxyClass = $this->getProxyClass($definition, $asGhostObject, $class);
108109

109110
if ($asGhostObject) {
110111
try {
@@ -142,10 +143,12 @@ public function getProxyCode(Definition $definition, string $id = null): string
142143
}
143144
}
144145

145-
public function getProxyClass(Definition $definition, \ReflectionClass &$class = null): string
146+
public function getProxyClass(Definition $definition, bool $asGhostObject, \ReflectionClass &$class = null): string
146147
{
147148
$class = new \ReflectionClass($definition->getClass());
148149

149-
return preg_replace('/^.*\\\\/', '', $class->name).'_'.substr(hash('sha256', $this->salt.'+'.$class->name), -7);
150+
return preg_replace('/^.*\\\\/', '', $class->name)
151+
.($asGhostObject ? 'Ghost' : 'Proxy')
152+
.ucfirst(substr(hash('sha256', $this->salt.'+'.$class->name), -7));
150153
}
151154
}

src/Symfony/Component/DependencyInjection/Tests/Dumper/PhpDumperTest.php

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -768,24 +768,18 @@ public function testCircularReferenceAllowanceForLazyServices()
768768
$dumper->dump();
769769
}
770770

771-
/**
772-
* @testWith [false]
773-
* [true]
774-
*/
775-
public function testDedupLazyProxy(bool $asGhostObject)
771+
public function testDedupLazyProxy()
776772
{
777773
$container = new ContainerBuilder();
778774
$container->register('foo', 'stdClass')->setLazy(true)->setPublic(true);
779775
$container->register('bar', 'stdClass')->setLazy(true)->setPublic(true);
776+
$container->register('baz', 'stdClass')->setLazy(true)->setPublic(true)->setFactory('foo_bar');
777+
$container->register('buz', 'stdClass')->setLazy(true)->setPublic(true)->setFactory('foo_bar');
780778
$container->compile();
781779

782780
$dumper = new PhpDumper($container);
783781

784-
if (!$asGhostObject) {
785-
$dumper->setProxyDumper(new \DummyProxyDumper());
786-
}
787-
788-
$this->assertStringEqualsFile(self::$fixturesPath.'/php/services_dedup_lazy'.($asGhostObject ? '_ghost' : '_proxy').'.php', $dumper->dump());
782+
$this->assertStringEqualsFile(self::$fixturesPath.'/php/services_dedup_lazy.php', $dumper->dump());
789783
}
790784

791785
public function testLazyArgumentProvideGenerator()

src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services9_lazy_inlined_factories.txt

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,11 @@ namespace Container%s;
66

77
include_once $this->targetDir.''.'/Fixtures/includes/foo.php';
88

9-
class FooClass_2b16075 extends \Bar\FooClass implements \Symfony\Component\VarExporter\LazyObjectInterface
9+
class FooClassGhost2b16075 extends \Bar\FooClass implements \Symfony\Component\VarExporter\LazyObjectInterface
1010
%A
1111

12-
if (!\class_exists('FooClass_%s', false)) {
13-
\class_alias(__NAMESPACE__.'\\FooClass_%s', 'FooClass_%s', false);
12+
if (!\class_exists('FooClassGhost2b16075', false)) {
13+
\class_alias(__NAMESPACE__.'\\FooClassGhost2b16075', 'FooClassGhost2b16075', false);
1414
}
1515

1616
[Container%s/ProjectServiceContainer.php] => <?php
@@ -78,7 +78,7 @@ class ProjectServiceContainer extends Container
7878
protected function getLazyFooService($lazyLoad = true)
7979
{
8080
if (true === $lazyLoad) {
81-
return $this->services['lazy_foo'] = $this->createProxy('FooClass_2b16075', fn () => \FooClass_2b16075::createLazyGhost($this->getLazyFooService(...)));
81+
return $this->services['lazy_foo'] = $this->createProxy('FooClassGhost2b16075', fn () => \FooClassGhost2b16075::createLazyGhost($this->getLazyFooService(...)));
8282
}
8383

8484
include_once $this->targetDir.''.'/Fixtures/includes/foo_lazy.php';

src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services_dedup_lazy_ghost.php renamed to src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services_dedup_lazy.php

Lines changed: 48 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ public function __construct()
2121
$this->services = $this->privates = [];
2222
$this->methodMap = [
2323
'bar' => 'getBarService',
24+
'baz' => 'getBazService',
25+
'buz' => 'getBuzService',
2426
'foo' => 'getFooService',
2527
];
2628

@@ -50,12 +52,40 @@ protected function createProxy($class, \Closure $factory)
5052
protected function getBarService($lazyLoad = true)
5153
{
5254
if (true === $lazyLoad) {
53-
return $this->services['bar'] = $this->createProxy('stdClass_5a8a5eb', fn () => \stdClass_5a8a5eb::createLazyGhost($this->getBarService(...)));
55+
return $this->services['bar'] = $this->createProxy('stdClassGhost5a8a5eb', fn () => \stdClassGhost5a8a5eb::createLazyGhost($this->getBarService(...)));
5456
}
5557

5658
return $lazyLoad;
5759
}
5860

61+
/**
62+
* Gets the public 'baz' shared service.
63+
*
64+
* @return \stdClass
65+
*/
66+
protected function getBazService($lazyLoad = true)
67+
{
68+
if (true === $lazyLoad) {
69+
return $this->services['baz'] = $this->createProxy('stdClassProxy5a8a5eb', fn () => \stdClassProxy5a8a5eb::createLazyProxy(fn () => $this->getBazService(false)));
70+
}
71+
72+
return \foo_bar();
73+
}
74+
75+
/**
76+
* Gets the public 'buz' shared service.
77+
*
78+
* @return \stdClass
79+
*/
80+
protected function getBuzService($lazyLoad = true)
81+
{
82+
if (true === $lazyLoad) {
83+
return $this->services['buz'] = $this->createProxy('stdClassProxy5a8a5eb', fn () => \stdClassProxy5a8a5eb::createLazyProxy(fn () => $this->getBuzService(false)));
84+
}
85+
86+
return \foo_bar();
87+
}
88+
5989
/**
6090
* Gets the public 'foo' shared service.
6191
*
@@ -64,14 +94,14 @@ protected function getBarService($lazyLoad = true)
6494
protected function getFooService($lazyLoad = true)
6595
{
6696
if (true === $lazyLoad) {
67-
return $this->services['foo'] = $this->createProxy('stdClass_5a8a5eb', fn () => \stdClass_5a8a5eb::createLazyGhost($this->getFooService(...)));
97+
return $this->services['foo'] = $this->createProxy('stdClassGhost5a8a5eb', fn () => \stdClassGhost5a8a5eb::createLazyGhost($this->getFooService(...)));
6898
}
6999

70100
return $lazyLoad;
71101
}
72102
}
73103

74-
class stdClass_5a8a5eb extends \stdClass implements \Symfony\Component\VarExporter\LazyObjectInterface
104+
class stdClassGhost5a8a5eb extends \stdClass implements \Symfony\Component\VarExporter\LazyObjectInterface
75105
{
76106
use \Symfony\Component\VarExporter\LazyGhostTrait;
77107

@@ -82,3 +112,18 @@ class stdClass_5a8a5eb extends \stdClass implements \Symfony\Component\VarExport
82112
class_exists(\Symfony\Component\VarExporter\Internal\Hydrator::class);
83113
class_exists(\Symfony\Component\VarExporter\Internal\LazyObjectRegistry::class);
84114
class_exists(\Symfony\Component\VarExporter\Internal\LazyObjectState::class);
115+
116+
class stdClassProxy5a8a5eb extends \stdClass implements \Symfony\Component\VarExporter\LazyObjectInterface
117+
{
118+
use \Symfony\Component\VarExporter\LazyProxyTrait;
119+
120+
private const LAZY_OBJECT_PROPERTY_SCOPES = [
121+
'lazyObjectReal' => [self::class, 'lazyObjectReal', null],
122+
"\0".self::class."\0lazyObjectReal" => [self::class, 'lazyObjectReal', null],
123+
];
124+
}
125+
126+
// Help opcache.preload discover always-needed symbols
127+
class_exists(\Symfony\Component\VarExporter\Internal\Hydrator::class);
128+
class_exists(\Symfony\Component\VarExporter\Internal\LazyObjectRegistry::class);
129+
class_exists(\Symfony\Component\VarExporter\Internal\LazyObjectState::class);

src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services_dedup_lazy_proxy.php

Lines changed: 0 additions & 70 deletions
This file was deleted.

0 commit comments

Comments
 (0)
0