Skip to content

Commit 3080164

Browse files
committed
feature #14700 [DependencyInjection] [Routing] [Config] Recursive directory loading (lavoiesl, nicolas-grekas)
This PR was merged into the 2.8 branch. Discussion ---------- [DependencyInjection] [Routing] [Config] Recursive directory loading | Q | A | ------------- | --- | Bug fix? | no | New feature? | yes | BC breaks? | no | Deprecations? | no | Tests pass? | yes | Fixed tickets | #13246, #11045, #11059 | License | MIT | Doc PR | - Commits ------- 60b1c5b Added CHANGELOG entries, cleanups 73f0ee2 [DI][Routing] recursive directory loading
2 parents 58544c9 + 4d19cc2 commit 3080164

File tree

7 files changed

+149
-0
lines changed

7 files changed

+149
-0
lines changed

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
CHANGELOG
22
=========
33

4+
2.8.0
5+
-----
6+
7+
* allowed specifying a directory to recursively load all configuration files it contains
8+
49
2.7.0
510
-----
611

Loader/DirectoryLoader.php

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
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\Loader;
13+
14+
use Symfony\Component\Config\Resource\DirectoryResource;
15+
16+
/**
17+
* DirectoryLoader is a recursive loader to go through directories.
18+
*
19+
* @author Sebastien Lavoie <seb@wemakecustom.com>
20+
*/
21+
class DirectoryLoader extends FileLoader
22+
{
23+
/**
24+
* {@inheritdoc}
25+
*/
26+
public function load($file, $type = null)
27+
{
28+
$file = rtrim($file, '/');
29+
$path = $this->locator->locate($file);
30+
$this->container->addResource(new DirectoryResource($path));
31+
32+
foreach (scandir($path) as $dir) {
33+
if ('.' !== $dir[0]) {
34+
if (is_dir($path.'/'.$dir)) {
35+
$dir .= '/'; // append / to allow recursion
36+
}
37+
38+
$this->setCurrentDir($path);
39+
40+
$this->import($dir, null, false, $path);
41+
}
42+
}
43+
}
44+
45+
/**
46+
* {@inheritdoc}
47+
*/
48+
public function supports($resource, $type = null)
49+
{
50+
if ('directory' === $type) {
51+
return true;
52+
}
53+
54+
return null === $type && is_string($resource) && '/' === substr($resource, -1);
55+
}
56+
}
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
imports:
2+
- { resource: ../recurse/ }
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
[parameters]
2+
ini = ini
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
parameters:
2+
yaml: yaml

Tests/Fixtures/directory/simple.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
<?php
2+
3+
$container->setParameter('php', 'php');

Tests/Loader/DirectoryLoaderTest.php

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
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\DependencyInjection\ContainerBuilder;
15+
use Symfony\Component\DependencyInjection\Loader\PhpFileLoader;
16+
use Symfony\Component\DependencyInjection\Loader\IniFileLoader;
17+
use Symfony\Component\DependencyInjection\Loader\YamlFileLoader;
18+
use Symfony\Component\DependencyInjection\Loader\DirectoryLoader;
19+
use Symfony\Component\Config\Loader\LoaderResolver;
20+
use Symfony\Component\Config\FileLocator;
21+
22+
class DirectoryLoaderTest extends \PHPUnit_Framework_TestCase
23+
{
24+
private static $fixturesPath;
25+
26+
private $container;
27+
private $loader;
28+
29+
public static function setUpBeforeClass()
30+
{
31+
self::$fixturesPath = realpath(__DIR__.'/../Fixtures/');
32+
}
33+
34+
protected function setUp()
35+
{
36+
$locator = new FileLocator(self::$fixturesPath);
37+
$this->container = new ContainerBuilder();
38+
$this->loader = new DirectoryLoader($this->container, $locator);
39+
$resolver = new LoaderResolver(array(
40+
new PhpFileLoader($this->container, $locator),
41+
new IniFileLoader($this->container, $locator),
42+
new YamlFileLoader($this->container, $locator),
43+
$this->loader,
44+
));
45+
$this->loader->setResolver($resolver);
46+
}
47+
48+
public function testDirectoryCanBeLoadedRecursively()
49+
{
50+
$this->loader->load('directory/');
51+
$this->assertEquals(array('ini' => 'ini', 'yaml' => 'yaml', 'php' => 'php'), $this->container->getParameterBag()->all(), '->load() takes a single directory');
52+
}
53+
54+
public function testImports()
55+
{
56+
$this->loader->resolve('directory/import/import.yml')->load('directory/import/import.yml');
57+
$this->assertEquals(array('ini' => 'ini', 'yaml' => 'yaml'), $this->container->getParameterBag()->all(), '->load() takes a single file that imports a directory');
58+
}
59+
60+
/**
61+
* @expectedException \InvalidArgumentException
62+
* @expectedExceptionMessage The file "foo" does not exist (in:
63+
*/
64+
public function testExceptionIsRaisedWhenDirectoryDoesNotExist()
65+
{
66+
$this->loader->load('foo/');
67+
}
68+
69+
public function testSupports()
70+
{
71+
$loader = new DirectoryLoader(new ContainerBuilder(), new FileLocator());
72+
73+
$this->assertTrue($loader->supports('directory/'), '->supports("directory/") returns true');
74+
$this->assertTrue($loader->supports('directory/', 'directory'), '->supports("directory/", "directory") returns true');
75+
$this->assertFalse($loader->supports('directory'), '->supports("directory") returns false');
76+
$this->assertTrue($loader->supports('directory', 'directory'), '->supports("directory", "directory") returns true');
77+
$this->assertFalse($loader->supports('directory', 'foo'), '->supports("directory, "foo") returns false');
78+
}
79+
}

0 commit comments

Comments
 (0)