Use glob pattern to load config file

This commit is contained in:
Pierre du Plessis 2017-01-17 15:46:23 +02:00
parent b5d9b3b99e
commit 519180ef56
3 changed files with 117 additions and 4 deletions

View File

@ -23,6 +23,7 @@ CHANGELOG
* using the `PhpDumper` with an uncompiled `ContainerBuilder` is deprecated and
will not be supported anymore in 4.0
* deprecated the `DefinitionDecorator` class in favor of `ChildDefinition`
* allow config files to be loaded using a glob pattern
3.2.0
-----

View File

@ -11,6 +11,7 @@
namespace Symfony\Component\DependencyInjection\Loader;
use Symfony\Component\Config\Exception\FileLocatorFileNotFoundException;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Definition;
use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
@ -40,6 +41,22 @@ abstract class FileLoader extends BaseFileLoader
parent::__construct($locator);
}
/**
* {@inheritdoc}
*/
public function import($resource, $type = null, $ignoreErrors = false, $sourceResource = null)
{
try {
foreach ($this->glob($resource, false) as $path => $info) {
parent::import($path, $type, $ignoreErrors, $sourceResource);
}
} catch (FileLocatorFileNotFoundException $e) {
if (!$ignoreErrors) {
throw $e;
}
}
}
/**
* Registers a set of classes as services using PSR-4 for discovery.
*
@ -73,7 +90,7 @@ abstract class FileLoader extends BaseFileLoader
$extRegexp = defined('HHVM_VERSION') ? '/\\.(?:php|hh)$/' : '/\\.php$/';
foreach ($this->glob($resource, true, $prefixLen) as $path => $info) {
if (!preg_match($extRegexp, $path, $m) || !$info->isFile() || !$info->isReadable()) {
if (!preg_match($extRegexp, $path, $m) || !$info->isReadable()) {
continue;
}
$class = $namespace.ltrim(str_replace('/', '\\', substr($path, $prefixLen, -strlen($m[0]))), '\\');
@ -95,6 +112,11 @@ abstract class FileLoader extends BaseFileLoader
private function glob($resource, $recursive, &$prefixLen = null)
{
if (strlen($resource) === $i = strcspn($resource, '*?{[')) {
if (!$recursive) {
yield $resource => new \SplFileInfo($resource);
return;
}
$resourcePrefix = $resource;
$resource = '';
} elseif (0 === $i) {
@ -117,9 +139,11 @@ abstract class FileLoader extends BaseFileLoader
if ($recursive && is_dir($path)) {
$flags = \FilesystemIterator::SKIP_DOTS | \FilesystemIterator::FOLLOW_SYMLINKS;
foreach (new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($path, $flags)) as $path => $info) {
yield $path => $info;
if ($info->isFile()) {
yield $path => $info;
}
}
} else {
} elseif (is_file($path)) {
yield $path => new \SplFileInfo($path);
}
}
@ -138,7 +162,7 @@ abstract class FileLoader extends BaseFileLoader
}
foreach ($finder->followLinks()->in($resourcePrefix) as $path => $info) {
if (preg_match($regex, substr($path, $prefixLen))) {
if (preg_match($regex, substr($path, $prefixLen)) && $info->isFile()) {
yield $path => $info;
}
}

View File

@ -0,0 +1,88 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\DependencyInjection\Tests\Loader;
use Symfony\Component\Config\FileLocator;
use Symfony\Component\Config\Loader\LoaderResolver;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Loader\FileLoader;
use Symfony\Component\DependencyInjection\Loader\IniFileLoader;
use Symfony\Component\DependencyInjection\Loader\PhpFileLoader;
use Symfony\Component\DependencyInjection\Loader\XmlFileLoader;
use Symfony\Component\DependencyInjection\Loader\YamlFileLoader;
use Symfony\Component\DependencyInjection\Reference;
class FileLoaderTest extends \PHPUnit_Framework_TestCase
{
protected static $fixturesPath;
public static function setUpBeforeClass()
{
self::$fixturesPath = realpath(__DIR__.'/../');
}
public function testImportWithGlobPattern()
{
$container = new ContainerBuilder();
$loader = new TestFileLoader($container, new FileLocator(self::$fixturesPath));
$resolver = new LoaderResolver(array(
new IniFileLoader($container, new FileLocator(self::$fixturesPath.'/ini')),
new XmlFileLoader($container, new FileLocator(self::$fixturesPath.'/xml')),
new PhpFileLoader($container, new FileLocator(self::$fixturesPath.'/php')),
new YamlFileLoader($container, new FileLocator(self::$fixturesPath.'/yaml')),
));
$loader->setResolver($resolver);
$loader->import('{F}ixtures/{xml,yaml}/services2.{yml,xml}');
$actual = $container->getParameterBag()->all();
$expected = array(
'a string',
'foo' => 'bar',
'values' => array(
0,
'integer' => 4,
100 => null,
'true',
true,
false,
'on',
'off',
'float' => 1.3,
1000.3,
'a string',
array('foo', 'bar'),
),
'mixedcase' => array('MixedCaseKey' => 'value'),
'constant' => PHP_EOL,
'bar' => '%foo%',
'escape' => '@escapeme',
'foo_bar' => new Reference('foo_bar'),
);
$this->assertEquals(array_keys($expected), array_keys($actual), '->load() imports and merges imported files');
}
}
class TestFileLoader extends FileLoader
{
public function load($resource, $type = null)
{
return $resource;
}
public function supports($resource, $type = null)
{
return false;
}
}