Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions UPGRADE-7.4.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,11 @@ Cache

* Bump ext-redis to 6.2 and ext-relay to 0.11 minimum

Config
------

* Deprecate accessing the internal scope of the loader in PHP config files, use only its public API instead

Console
-------

Expand All @@ -29,6 +34,7 @@ DependencyInjection
* Add argument `$target` to `ContainerBuilder::registerAliasForArgument()`
* Add argument `$throwOnAbstract` to `ContainerBuilder::findTaggedResourceIds()`
* Deprecate registering a service without a class when its id is a non-existing FQCN
* Deprecate using `$this` or its internal scope from PHP config files; use the `$loader` variable instead

DoctrineBridge
--------------
Expand Down Expand Up @@ -87,6 +93,7 @@ Routing

* Deprecate class aliases in the `Annotation` namespace, use attributes instead
* Deprecate getters and setters in attribute classes in favor of public properties
* Deprecate accessing the internal scope of the loader in PHP config files, use only its public API instead

Security
--------
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?php

$this->load('container1.php');
$loader->load('container1.php');

$container->loadFromExtension('security', [
'password_hashers' => [
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?php

$this->load('container1.php');
$loader->load('container1.php');

$container->loadFromExtension('security', [
'password_hashers' => [
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?php

$this->load('merge_import.php');
$loader->load('merge_import.php');

$container->loadFromExtension('security', [
'providers' => [
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?php

$this->load('container1.php');
$loader->load('container1.php');

$container->loadFromExtension('security', [
'password_hashers' => [
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?php

$this->load('container1.php');
$loader->load('container1.php');

$container->loadFromExtension('security', [
'password_hashers' => [
Expand Down
1 change: 1 addition & 0 deletions src/Symfony/Component/Config/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ CHANGELOG
* Add support for `defaultNull()` on `ArrayNodeDefinition`
* Add `ArrayNodeDefinition::acceptAndWrap()` to list alternative types that should be accepted and wrapped in an array
* Add array-shapes to generated config builders
* Deprecate accessing the internal scope of the loader in PHP config files, use only its public API instead

7.3
---
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,19 @@ public function load(mixed $resource, ?string $type = null): mixed
// the closure forbids access to the private scope in the included file
$load = \Closure::bind(static function ($file) use ($loader) {
return include $file;
}, null, ProtectedDefinitionFileLoader::class);
}, null, null);

$callback = $load($path);
try {
$callback = $load($path);
} catch (\Error $e) {
$load = \Closure::bind(static function ($file) use ($loader) {
return include $file;
}, null, ProtectedDefinitionFileLoader::class);

$callback = $load($path);

trigger_deprecation('symfony/config', '7.4', 'Accessing the internal scope of the loader in config files is deprecated, use only its public API instead in "%s" on line %d.', $e->getFile(), $e->getLine());
}

if (\is_object($callback) && \is_callable($callback)) {
$this->executeCallback($callback, new DefinitionConfigurator($this->treeBuilder, $this, $path, $resource), $path);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@

namespace Symfony\Component\Config\Tests\Definition\Loader;

use PHPUnit\Framework\Attributes\Group;
use PHPUnit\Framework\Attributes\IgnoreDeprecations;
use PHPUnit\Framework\TestCase;
use Symfony\Component\Config\Definition\BaseNode;
use Symfony\Component\Config\Definition\Builder\TreeBuilder;
Expand Down Expand Up @@ -39,4 +41,15 @@ public function testLoad()
$this->assertInstanceOf(BaseNode::class, $children['foo']);
$this->assertSame('test.foo', $children['foo']->getPath(), '->load() loads a PHP file resource');
}

#[IgnoreDeprecations]
#[Group('legacy')]
public function testTriggersDeprecationWhenAccessingLoaderInternalScope()
{
$loader = new DefinitionFileLoader(new TreeBuilder('test'), new FileLocator(__DIR__.'/../../Fixtures/Loader'));

$this->expectUserDeprecationMessageMatches('{^Since symfony/config 7.4: Accessing the internal scope of the loader in config files is deprecated, use only its public API instead in ".+" on line \d+\.$}');

$loader->load('legacy_internal_scope.php');
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
<?php

// access the loader's internal scope to trigger deprecation
$loader->resolver;
1 change: 1 addition & 0 deletions src/Symfony/Component/DependencyInjection/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ CHANGELOG
* Deprecate registering a service without a class when its id is a non-existing FQCN
* Allow multiple `#[AsDecorator]` attributes
* Handle returning arrays and config-builders from config files
* Deprecate using `$this` or its internal scope from PHP config files; use the `$loader` variable instead

7.3
---
Expand Down
20 changes: 16 additions & 4 deletions src/Symfony/Component/DependencyInjection/Loader/PhpFileLoader.php
Original file line number Diff line number Diff line change
Expand Up @@ -61,13 +61,25 @@ public function load(mixed $resource, ?string $type = null): mixed
class_exists(ContainerConfigurator::class);

// the closure forbids access to the private scope in the included file
$load = \Closure::bind(function ($path, $env) use ($container, $loader, $resource, $type) {
$load = \Closure::bind(static function ($path, $env) use ($container, $loader, $resource, $type) {
return include $path;
}, $this, ProtectedPhpFileLoader::class);
}, null, null);

try {
if (1 === $result = $load($path, $this->env)) {
$result = null;
try {
if (1 === $result = $load($path, $this->env)) {
$result = null;
}
} catch (\Error $e) {
$load = \Closure::bind(function ($path, $env) use ($container, $loader, $resource, $type) {
return include $path;
}, $this, ProtectedPhpFileLoader::class);

if (1 === $result = $load($path, $this->env)) {
$result = null;
}

trigger_deprecation('symfony/dependency-injection', '8.1', 'Using `$this` or its internal scope in config files is deprecated, use the `$loader` variable instead in "%s" on line %d.', $e->getFile(), $e->getLine());
}

if (\is_object($result) && \is_callable($result)) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
<?php

// access the loader's internal scope to trigger deprecation
$this->supports('dummy.php');
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
require_once __DIR__.'/../Fixtures/includes/fixture_app_services.php';

use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\Attributes\Group;
use PHPUnit\Framework\Attributes\IgnoreDeprecations;
use PHPUnit\Framework\TestCase;
use Symfony\Component\Config\Builder\ConfigBuilderGenerator;
use Symfony\Component\Config\FileLocator;
Expand Down Expand Up @@ -365,4 +367,16 @@ public function testReturnsGenerator()
$loader->load('return_generator.php');
$this->assertSame([['color' => 'red']], $container->getExtensionConfig('acme'));
}

#[IgnoreDeprecations]
#[Group('legacy')]
public function testTriggersDeprecationWhenAccessingLoaderInternalScope()
{
$fixtures = realpath(__DIR__.'/../Fixtures');
$loader = new PhpFileLoader(new ContainerBuilder(), new FileLocator($fixtures.'/config'));

$this->expectUserDeprecationMessageMatches('{^Since symfony/dependency-injection 8.1: Using \`\$this\` or its internal scope in config files is deprecated, use the \`\$loader\` variable instead in ".+" on line \d+\.$}');

$loader->load('legacy_internal_scope.php');
}
}
1 change: 1 addition & 0 deletions src/Symfony/Component/Routing/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ CHANGELOG
* Add argument `$parameters` to `RequestContext`'s constructor
* Deprecate class aliases in the `Annotation` namespace, use attributes instead
* Deprecate getters and setters in attribute classes in favor of public properties
* Deprecate accessing the internal scope of the loader in PHP config files, use only its public API instead

7.3
---
Expand Down
14 changes: 12 additions & 2 deletions src/Symfony/Component/Routing/Loader/PhpFileLoader.php
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,19 @@ public function load(mixed $file, ?string $type = null): RouteCollection
$loader = $this;
$load = \Closure::bind(static function ($file) use ($loader) {
return include $file;
}, null, ProtectedPhpFileLoader::class);
}, null, null);

$result = $load($path);
try {
$result = $load($path);
} catch (\Error $e) {
$load = \Closure::bind(static function ($file) use ($loader) {
return include $file;
}, null, ProtectedPhpFileLoader::class);

$result = $load($path);

trigger_deprecation('symfony/routing', '7.4', 'Accessing the internal scope of the loader in config files is deprecated, use only its public API instead in "%s" on line %d.', $e->getFile(), $e->getLine());
}

if (\is_object($result) && \is_callable($result)) {
$collection = $this->callConfigurator($result, $path, $file);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<?php

use Symfony\Component\Routing\RouteCollection;

// access the loader's internal scope to trigger deprecation
$loader->callConfigurator(static fn () => 'dummy', 'dummy.php', 'dummy.php');

return new RouteCollection();
16 changes: 16 additions & 0 deletions src/Symfony/Component/Routing/Tests/Loader/PhpFileLoaderTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
namespace Symfony\Component\Routing\Tests\Loader;

use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\Attributes\Group;
use PHPUnit\Framework\Attributes\IgnoreDeprecations;
use PHPUnit\Framework\TestCase;
use Symfony\Component\Config\FileLocator;
use Symfony\Component\Config\Loader\LoaderResolver;
Expand Down Expand Up @@ -258,6 +260,20 @@ public function testRoutingConfiguratorCanImportGlobPatterns()
$this->assertSame('AppBundle:Baz:view', $route->getDefault('_controller'));
}

#[IgnoreDeprecations]
#[Group('legacy')]
public function testTriggersDeprecationWhenAccessingLoaderInternalScope()
{
$locator = new FileLocator([__DIR__.'/../Fixtures']);
$loader = new PhpFileLoader($locator);

$this->expectUserDeprecationMessageMatches('{^Since symfony/routing 7.4: Accessing the internal scope of the loader in config files is deprecated, use only its public API instead in ".+" on line \d+\.$}');

$routes = $loader->load('legacy_internal_scope.php');

$this->assertInstanceOf(RouteCollection::class, $routes);
}

public function testRoutingI18nConfigurator()
{
$locator = new FileLocator([__DIR__.'/../Fixtures']);
Expand Down
Loading