diff --git a/UPGRADE-4.4.md b/UPGRADE-4.4.md index d8bea4dd0490..7d19467d8044 100644 --- a/UPGRADE-4.4.md +++ b/UPGRADE-4.4.md @@ -143,6 +143,12 @@ HttpKernel As many bundles must be compatible with a range of Symfony versions, the current directory convention is not deprecated yet, but it will be in the future. + * Deprecated the second and third argument of `KernelInterface::locateResource` + * Deprecated the second and third argument of `FileLocator::__construct` + * Deprecated loading resources from `%kernel.root_dir%/Resources` and `%kernel.root_dir%` as + fallback directories. Resources like service definitions are usually loaded relative to the + current directory or with a glob pattern. The fallback directories have never been advocated + so you likely do not use those in any app based on the SF Standard or Flex edition. Lock ---- diff --git a/UPGRADE-5.0.md b/UPGRADE-5.0.md index 6ccb845144e4..c6da522603b1 100644 --- a/UPGRADE-5.0.md +++ b/UPGRADE-5.0.md @@ -333,6 +333,10 @@ HttpKernel As many bundles must be compatible with a range of Symfony versions, the current directory convention is not deprecated yet, but it will be in the future. + * Removed the second and third argument of `KernelInterface::locateResource` + * Removed the second and third argument of `FileLocator::__construct` + * Removed loading resources from `%kernel.root_dir%/Resources` and `%kernel.root_dir%` as + fallback directories. Intl ---- diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/config/services.xml b/src/Symfony/Bundle/FrameworkBundle/Resources/config/services.xml index 10e641c83dd1..e8a11ad2428e 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Resources/config/services.xml +++ b/src/Symfony/Bundle/FrameworkBundle/Resources/config/services.xml @@ -91,6 +91,7 @@ %kernel.root_dir% + false diff --git a/src/Symfony/Component/HttpKernel/CHANGELOG.md b/src/Symfony/Component/HttpKernel/CHANGELOG.md index 4087d4f66a9a..3fc49b0fc510 100644 --- a/src/Symfony/Component/HttpKernel/CHANGELOG.md +++ b/src/Symfony/Component/HttpKernel/CHANGELOG.md @@ -6,6 +6,12 @@ CHANGELOG * The `DebugHandlersListener` class has been marked as `final` * Added new Bundle directory convention consistent with standard skeletons + * Deprecated the second and third argument of `KernelInterface::locateResource` + * Deprecated the second and third argument of `FileLocator::__construct` + * Deprecated loading resources from `%kernel.root_dir%/Resources` and `%kernel.root_dir%` as + fallback directories. Resources like service definitions are usually loaded relative to the + current directory or with a glob pattern. The fallback directories have never been advocated + so you likely do not use those in any app based on the SF Standard or Flex edition. 4.3.0 ----- diff --git a/src/Symfony/Component/HttpKernel/Config/FileLocator.php b/src/Symfony/Component/HttpKernel/Config/FileLocator.php index 0d9652ac14dd..8683a3eefe54 100644 --- a/src/Symfony/Component/HttpKernel/Config/FileLocator.php +++ b/src/Symfony/Component/HttpKernel/Config/FileLocator.php @@ -22,18 +22,28 @@ class FileLocator extends BaseFileLocator { private $kernel; - private $path; /** - * @param string|null $path The path the global resource directory - * @param array $paths An array of paths where to look for resources + * @deprecated since Symfony 4.4 */ - public function __construct(KernelInterface $kernel, string $path = null, array $paths = []) + private $path; + + public function __construct(KernelInterface $kernel/*, string $path = null, array $paths = [], bool $triggerDeprecation = true*/) { $this->kernel = $kernel; - if (null !== $path) { - $this->path = $path; - $paths[] = $path; + + if (2 <= \func_num_args()) { + $this->path = func_get_arg(1); + $paths = 3 <= \func_num_args() ? func_get_arg(2) : []; + if (null !== $this->path) { + $paths[] = $this->path; + } + + if (4 !== \func_num_args() || func_get_arg(3)) { + @trigger_error(sprintf('Passing more than one argument to %s is deprecated since Symfony 4.4 and will be removed in 5.0.', __METHOD__), E_USER_DEPRECATED); + } + } else { + $paths = []; } parent::__construct($paths); @@ -45,9 +55,32 @@ public function __construct(KernelInterface $kernel, string $path = null, array public function locate($file, $currentPath = null, $first = true) { if (isset($file[0]) && '@' === $file[0]) { - return $this->kernel->locateResource($file, $this->path, $first); + return $this->kernel->locateResource($file, $this->path, $first, false); + } + + $locations = parent::locate($file, $currentPath, $first); + + if (isset($file[0]) && !( + '/' === $file[0] || '\\' === $file[0] + || (\strlen($file) > 3 && ctype_alpha($file[0]) && ':' === $file[1] && ('\\' === $file[2] || '/' === $file[2])) + || null !== parse_url($file, PHP_URL_SCHEME) + )) { + // no need to trigger deprecations when the loaded file is given as absolute path + foreach ($this->paths as $deprecatedPath) { + if (\is_array($locations)) { + foreach ($locations as $location) { + if (0 === strpos($location, $deprecatedPath) && (null === $currentPath || false === strpos($location, $currentPath))) { + @trigger_error(sprintf('Loading the file "%s" from the global resource directory "%s" is deprecated since Symfony 4.4 and will be removed in 5.0.', $file, $deprecatedPath), E_USER_DEPRECATED); + } + } + } else { + if (0 === strpos($locations, $deprecatedPath) && (null === $currentPath || false === strpos($locations, $currentPath))) { + @trigger_error(sprintf('Loading the file "%s" from the global resource directory "%s" is deprecated since Symfony 4.4 and will be removed in 5.0.', $file, $deprecatedPath), E_USER_DEPRECATED); + } + } + } } - return parent::locate($file, $currentPath, $first); + return $locations; } } diff --git a/src/Symfony/Component/HttpKernel/Kernel.php b/src/Symfony/Component/HttpKernel/Kernel.php index c776932813e5..99c73a9f4b89 100644 --- a/src/Symfony/Component/HttpKernel/Kernel.php +++ b/src/Symfony/Component/HttpKernel/Kernel.php @@ -236,11 +236,21 @@ public function getBundle($name) /** * {@inheritdoc} - * - * @throws \RuntimeException if a custom resource is hidden by a resource in a derived bundle */ - public function locateResource($name, $dir = null, $first = true) + public function locateResource($name/*, $dir = null, $first = true, $triggerDeprecation = true*/) { + if (2 <= \func_num_args()) { + $dir = func_get_arg(1); + $first = 3 <= \func_num_args() ? func_get_arg(2) : true; + + if (4 !== \func_num_args() || func_get_arg(3)) { + @trigger_error(sprintf('Passing more than one argument to %s is deprecated since Symfony 4.4 and will be removed in 5.0.', __METHOD__), E_USER_DEPRECATED); + } + } else { + $dir = null; + $first = true; + } + if ('@' !== $name[0]) { throw new \InvalidArgumentException(sprintf('A resource name must start with @ ("%s" given).', $name)); } @@ -262,6 +272,9 @@ public function locateResource($name, $dir = null, $first = true) if ($isResource && file_exists($file = $dir.'/'.$bundle->getName().$overridePath)) { $files[] = $file; + + // see https://symfony.com/doc/current/bundles/override.html on how to overwrite parts of a bundle + @trigger_error(sprintf('Overwriting the resource "%s" with "%s" is deprecated since Symfony 4.4 and will be removed in 5.0.', $name, $file), E_USER_DEPRECATED); } if (file_exists($file = $bundle->getPath().'/'.$path)) { diff --git a/src/Symfony/Component/HttpKernel/KernelInterface.php b/src/Symfony/Component/HttpKernel/KernelInterface.php index ead6920e7736..103dd9f86460 100644 --- a/src/Symfony/Component/HttpKernel/KernelInterface.php +++ b/src/Symfony/Component/HttpKernel/KernelInterface.php @@ -80,23 +80,14 @@ public function getBundle($name); * where BundleName is the name of the bundle * and the remaining part is the relative path in the bundle. * - * If $dir is passed, and the first segment of the path is "Resources", - * this method will look for a file named: + * @param string $name A resource name to locate * - * $dir//path/without/Resources - * - * before looking in the bundle resource folder. - * - * @param string $name A resource name to locate - * @param string $dir A directory where to look for the resource first - * @param bool $first Whether to return the first path or paths for all matching bundles - * - * @return string|array The absolute path of the resource or an array if $first is false + * @return string|array The absolute path of the resource or an array if $first is false (array return value is deprecated) * * @throws \InvalidArgumentException if the file cannot be found or the name is not valid * @throws \RuntimeException if the name contains invalid/unsafe characters */ - public function locateResource($name, $dir = null, $first = true); + public function locateResource($name/*, $dir = null, $first = true*/); /** * Gets the name of the kernel. diff --git a/src/Symfony/Component/HttpKernel/Tests/Config/FileLocatorTest.php b/src/Symfony/Component/HttpKernel/Tests/Config/FileLocatorTest.php index 72b38c672ada..6bfaeca2f52c 100644 --- a/src/Symfony/Component/HttpKernel/Tests/Config/FileLocatorTest.php +++ b/src/Symfony/Component/HttpKernel/Tests/Config/FileLocatorTest.php @@ -34,6 +34,9 @@ public function testLocate() $locator->locate('/some/path'); } + /** + * @group legacy + */ public function testLocateWithGlobalResourcePath() { $kernel = $this->getMockBuilder('Symfony\Component\HttpKernel\KernelInterface')->getMock(); diff --git a/src/Symfony/Component/HttpKernel/Tests/KernelTest.php b/src/Symfony/Component/HttpKernel/Tests/KernelTest.php index 978f83f80b90..12827c33d9a6 100644 --- a/src/Symfony/Component/HttpKernel/Tests/KernelTest.php +++ b/src/Symfony/Component/HttpKernel/Tests/KernelTest.php @@ -389,6 +389,9 @@ public function testLocateResourceReturnsTheFirstThatMatches() $this->assertEquals(__DIR__.'/Fixtures/Bundle1Bundle/foo.txt', $kernel->locateResource('@Bundle1Bundle/foo.txt')); } + /** + * @group legacy + */ public function testLocateResourceIgnoresDirOnNonResource() { $kernel = $this->getKernel(['getBundle']); @@ -404,6 +407,9 @@ public function testLocateResourceIgnoresDirOnNonResource() ); } + /** + * @group legacy + */ public function testLocateResourceReturnsTheDirOneForResources() { $kernel = $this->getKernel(['getBundle']); @@ -419,7 +425,10 @@ public function testLocateResourceReturnsTheDirOneForResources() ); } - public function testLocateResourceOnDirectories() + /** + * @group legacy + */ + public function testLocateResourceOnDirectoriesWithOverwrite() { $kernel = $this->getKernel(['getBundle']); $kernel @@ -436,7 +445,10 @@ public function testLocateResourceOnDirectories() __DIR__.'/Fixtures/Resources/FooBundle', $kernel->locateResource('@FooBundle/Resources', __DIR__.'/Fixtures/Resources') ); + } + public function testLocateResourceOnDirectories() + { $kernel = $this->getKernel(['getBundle']); $kernel ->expects($this->exactly(2))