8000 Use glob pattern to load config file · symfony/symfony@519180e · GitHub
[go: up one dir, main page]

Skip to content

Commit 519180e

Browse files
committed
Use glob pattern to load config file
1 parent b5d9b3b commit 519180e

File tree

3 files changed

+117
-4
lines changed

3 files changed

+117
-4
lines changed

src/Symfony/Component/DependencyInjection/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ CHANGELOG
2323
* using the `PhpDumper` with an uncompiled `ContainerBuilder` is deprecated and
2424
will not be supported anymore in 4.0
2525
* deprecated the `DefinitionDecorator` class in favor of `ChildDefinition`
26+
* allow config files to be loaded using a glob pattern
2627

2728
3.2.0
2829
-----

src/Symfony/Component/DependencyInjection/Loader/FileLoader.php

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
namespace Symfony\Component\DependencyInjection\Loader;
1313

14+
use Symfony\Component\Config\Exception\FileLocatorFileNotFoundException;
1415
use Symfony\Component\DependencyInjection\ContainerBuilder;
1516
use Symfony\Component\DependencyInjection\Definition;
1617
use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
@@ -40,6 +41,22 @@ public function __construct(ContainerBuilder $container, FileLocatorInterface $l
4041
parent::__construct($locator);
4142
}
4243

44+
/**
45+
* {@inheritdoc}
46+
*/
47+
public function import($resource, $type = null, $ignoreErrors = false, $sourceResource = null)
48+
{
49+
try {
50+
foreach ($this->glob($resource, false) as $path => $info) {
51+
parent::import($path, $type, $ignoreErrors, $sourceResource);
52+
}
53+
} catch (FileLocatorFileNotFoundException $e) {
54+
if (!$ignoreErrors) {
55+
throw $e;
56+
}
57+
}
58+
}
59+
4360
/**
4461
* Registers a set of classes as services using PSR-4 for discovery.
4562
*
@@ -73,7 +90,7 @@ private function findClasses($namespace, $resource)
7390
$extRegexp = defined('HHVM_VERSION') ? '/\\.(?:php|hh)$/' : '/\\.php$/';
7491

7592
foreach ($this->glob($resource, true, $prefixLen) as $path => $info) {
76-
if (!preg_match($extRegexp, $path, $m) || !$info->isFile() || !$info->isReadable()) {
93+
if (!preg_match($extRegexp, $path, $m) || !$info->isReadable()) {
7794
continue;
7895
}
7996
8000 $class = $namespace.ltrim(str_replace('/', '\\', substr($path, $prefixLen, -strlen($m[0]))), '\\');
@@ -95,6 +112,11 @@ private function findClasses($namespace, $resource)
95112
private function glob($resource, $recursive, &$prefixLen = null)
96113
{
97114
if (strlen($resource) === $i = strcspn($resource, '*?{[')) {
115+
if (!$recursive) {
116+
yield $resource => new \SplFileInfo($resource);
117+
118+
return;
119+
}
98120
$resourcePrefix = $resource;
99121
$resource = '';
100122
} elseif (0 === $i) {
@@ -117,9 +139,11 @@ private function glob($resource, $recursive, &$prefixLen = null)
117139
if ($recursive && is_dir($path)) {
118140
$flags = \FilesystemIterator::SKIP_DOTS | \FilesystemIterator::FOLLOW_SYMLINKS;
119141
foreach (new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($path, $flags)) as $path => $info) {
120-
yield $path => $info;
142+
if ($info->isFile()) {
143+
yield $path => $info;
144+
}
121145
}
122-
} else {
146+
} elseif (is_file($path)) {
123147
yield $path => new \SplFileInfo($path);
124148
}
125149
}
@@ -138,7 +162,7 @@ private function glob($resource, $recursive, &$prefixLen = null)
138162
}
139163

140164
foreach ($finder->followLinks()->in($resourcePrefix) as $path => $info) {
141-
if (preg_match($regex, substr($path, $prefixLen))) {
165+
if (preg_match($regex, substr($path, $prefixLen)) && $info->isFile()) {
142166
yield $path => $info;
143167
}
144168
}
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\DependencyInjection\Tests\Loader;
13+
14+
use Symfony\Component\Config\FileLocator;
15+
use Symfony\Component\Config\Loader\LoaderResolver;
16+
use Symfony\Component\DependencyInjection\ContainerBuilder;
17+
use Symfony\Component\DependencyInjection\Loader\FileLoader;
18+
use Symfony\Component\DependencyInjection\Loader\IniFileLoader;
19+
use Symfony\Component\DependencyInjection\Loader\PhpFileLoader;
20+
use Symfony\Component\DependencyInjection\Loader\XmlFileLoader;
21+
use Symfony\Component\DependencyInjection\Loader\YamlFileLoader;
22+
use Symfony\Component\DependencyInjection\Reference;
23+
24+
class FileLoaderTest extends \PHPUnit_Framework_TestCase
25+
{
26+
protected static $fixturesPath;
27+
28+
public static function setUpBeforeClass()
29+
{
30+
self::$fixturesPath = realpath(__DIR__.'/../');
31+
}
32+
33+
public function testImportWithGlobPattern()
34+
{
35+
$container = new ContainerBuilder();
36+
$loader = new TestFileLoader($container, new FileLocator(self::$fixturesPath));
37+
38+
$resolver = new LoaderResolver(array(
39+
new IniFileLoader($container, new FileLocator(self::$fixturesPath.'/ini')),
40+
new XmlFileLoader($container, new FileLocator(self::$fixturesPath.'/xml')),
41+
new PhpFileLoader($container, new FileLocator(self::$fixturesPath.'/php')),
42+
new YamlFileLoader($container, new FileLocator(self::$fixturesPath.'/yaml')),
43+
));
44+
45+
$loader->setResolver($resolver);
46+
$loader->import('{F}ixtures/{xml,yaml}/services2.{yml,xml}');
47+
48+
$actual = $container->getParameterBag()->all();
49+
$expected = array(
50+
'a string',
51+
'foo' => 'bar',
52+
'values' => array(
53+
0,
54+
'integer' => 4,
55+
100 => null,
56+
'true',
57+
true,
58+
false,
59+
'on',
60+
'off',
61+
'float' => 1.3,
62+
1000.3,
63+
'a string',
64+
array('foo', 'bar'),
65+
),
66+
'mixedcase' => array('MixedCaseKey' => 'value'),
67+
'constant' => PHP_EOL,
68+
'bar' => '%foo%',
69+
'escape' => '@escapeme',
70+
'foo_bar' => new Reference('foo_bar'),
71+
);
72+
73+
$this->assertEquals(array_keys($expected), array_keys($actual), '->load() imports and merges imported files');
74+
}
75+
}
76+
77+
class TestFileLoader extends FileLoader
78+
{
79+
public function load($resource, $type = null)
80+
{
81+
return $resource;
82+
}
83+
84+
public function supports($resource, $type = null)
85+
{
86+
return false;
87+
}
88+
}

0 commit comments

Comments
 (0)
0