-
-
Notifications
You must be signed in to change notification settings - Fork 9.6k
[DependencyInjection] [Routing] [Config] Recursive directory loading #11059
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
<?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\Loader; | ||
|
||
use Symfony\Component\Config\Resource\DirectoryResource; | ||
|
||
/** | ||
* DirectoryLoader is a recursive loader to go through directories | ||
* | ||
* @author Sebastien Lavoie <seb@wemakecustom.com> | ||
*/ | ||
class DirectoryLoader extends FileLoader | ||
{ | ||
/** | ||
* @param mixed $file The resource | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. should be @param string ? |
||
* @param string $type The resource type | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. should be @param string|null There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I would tend to agree with you, but I simply copied the other loaders: src/Symfony/Component/DependencyInjection/Loader There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think the phpdoc is not good, wait for an official reviewer before making changes There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think this PR should stay as is for now. Another PR could fix the phpdoc of all the loaders at the same time. If the doc gets fixed before my PR goes through, I will change it accordingly. |
||
*/ | ||
public function load($file, $type = null) | ||
{ | ||
$file = rtrim($file, '/'); | ||
$path = $this->locator->locate($file); | ||
$this->container->addResource(new DirectoryResource($path)); | ||
|
||
foreach (scandir($path) as $dir) { | ||
if ($dir[0] !== '.') { | ||
if (is_dir("$path/$dir")) { | ||
$dir .= '/'; // append / to allow recursion | ||
} | ||
|
||
$this->setCurrentDir($path); | ||
|
||
$this->import($dir, null, false, $path); | ||
} | ||
} | ||
} | ||
|
||
/** | ||
* Returns true if this class supports the given resource. | ||
* | ||
* @param mixed $resource A resource | ||
* @param string $type The resource type | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. same here string|null |
||
* | ||
* @return bool true if this class supports the given resource, false otherwise | ||
*/ | ||
public function supports($resource, $type = null) | ||
{ | ||
return 'directory' === $type || (!$type && preg_match('/\/$/', $resource) === 1); // ends with a slash | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
[parameters] | ||
ini = ini |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
parameters: | ||
yaml: yaml |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
<?php | ||
|
||
$container->setParameter('php', 'php'); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
<?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\DependencyInjection\ContainerBuilder; | ||
use Symfony\Component\DependencyInjection\Loader\PhpFileLoader; | ||
use Symfony\Component\DependencyInjection\Loader\IniFileLoader; | ||
use Symfony\Component\DependencyInjection\Loader\YamlFileLoader; | ||
use Symfony\Component\DependencyInjection\Loader\DirectoryLoader; | ||
use Symfony\Component\Config\Loader\LoaderResolver; | ||
use Symfony\Component\Config\FileLocator; | ||
|
||
class DirectoryLoaderTest extends \PHPUnit_Framework_TestCase | ||
{ | ||
protected static $fixturesPath; | ||
|
||
protected $container; | ||
protected $loader; | ||
|
||
public static function setUpBeforeClass() | ||
{ | ||
self::$fixturesPath = realpath(__DIR__.'/../Fixtures/'); | ||
} | ||
|
||
protected function setUp() | ||
{ | ||
$locator = new FileLocator(self::$fixturesPath); | ||
$this->container = new ContainerBuilder(); | ||
$this->loader = new DirectoryLoader($this->container, $locator); | ||
$resolver = new LoaderResolver(array( | ||
new PhpFileLoader($this->container, $locator), | ||
new IniFileLoader($this->container, $locator), | ||
new YamlFileLoader($this->container, $locator), | ||
$this->loader, | ||
)); | ||
$this->loader->setResolver($resolver); | ||
} | ||
|
||
/** | ||
* @covers Symfony\Component\DependencyInjection\Loader\DirectoryLoader::__construct | ||
* @covers Symfony\Component\DependencyInjection\Loader\DirectoryLoader::load | ||
*/ | ||
public function testDirectoryCanBeLoadedRecursively() | ||
{ | ||
$this->loader->load('directory/'); | ||
$this->assertEquals(array('ini' => 'ini', 'yaml' => 'yaml', 'php' => 'php'), $this->container->getParameterBag()->all(), '->load() takes a single file name as its first argument'); | ||
} | ||
|
||
/** | ||
* @covers Symfony\Component\DependencyInjection\Loader\DirectoryLoader::__construct | ||
* @covers Symfony\Component\DependencyInjection\Loader\DirectoryLoader::load | ||
* | ||
* @expectedException \InvalidArgumentException | ||
* @expectedExceptionMessage The file "foo" does not exist (in: | ||
*/ | ||
public function testExceptionIsRaisedWhenDirectoryDoesNotExist() | ||
{ | ||
$this->loader->load('foo/'); | ||
} | ||
|
||
/** | ||
* @covers Symfony\Component\DependencyInjection\Loader\DirectoryLoader::supports | ||
*/ | ||
public function testSupports() | ||
{ | ||
$loader = new DirectoryLoader(new ContainerBuilder(), new FileLocator()); | ||
|
||
$this->assertTrue($loader->supports('foo/'), '->supports() returns true if the resource is loadable'); | ||
$this->assertTrue($loader->supports('foo/', 'directory'), '->supports() returns true if the resource is loadable'); | ||
$this->assertTrue($loader->supports('foo', 'directory'), '->supports() returns true if the resource is loadable'); | ||
$this->assertFalse($loader->supports('foo'), '->supports() returns true if the resource is loadable'); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
<?php | ||
|
||
namespace Symfony\Component\Routing\Loader; | ||
|
||
use Symfony\Component\Config\Loader\FileLoader; | ||
use Symfony\Component\Routing\RouteCollection; | ||
use Symfony\Component\Config\Resource\DirectoryResource; | ||
|
||
class DirectoryLoader extends FileLoader | ||
{ | ||
private $currentDir; | ||
|
||
/** | ||
* @param mixed $file The resource | ||
* @param string $type The resource type | ||
*/ | ||
public function load($file, $type = null) | ||
{ | ||
$path = $this->locator->locate($file); | ||
|
||
$collection = new RouteCollection(); | ||
$collection->addResource(new DirectoryResource($path)); | ||
|
||
foreach (scandir($path) as $dir) { | ||
if ($dir[0] !== '.') { | ||
$this->setCurrentDir($path); | ||
|
||
$subType = is_dir("$path/$dir") ? 'directory' : null; | ||
$subCollection = $this->import("$path/$dir", $subType, false, $path); | ||
$collection->addCollection($subCollection); | ||
} | ||
} | ||
|
||
return $collection; | ||
} | ||
|
||
/** | ||
* Store here as well because FileLoader::currentDir is private | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. missing phpdoc There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I changed my mind, I decided to add |
||
*/ | ||
public function setCurrentDir($currentDir) | ||
{ | ||
$this->currentDir = $currentDir; | ||
|
||
parent::setCurrentDir($currentDir); | ||
} | ||
|
||
/** | ||
* Returns true if this class supports the given resource. | ||
* | ||
* @param mixed $resource A resource | ||
* @param string $type The resource type | ||
* | ||
* @return bool true if this class supports the given resource, false otherwise | ||
*/ | ||
public function supports($resource, $type = null) | ||
{ | ||
try { | ||
$path = $this->locator->locate($resource, $this->currentDir); | ||
} catch (\Exception $e) { | ||
return false; | ||
} | ||
|
||
return is_string($resource) && 'directory' === $type; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
route1: | ||
path: /route/1 |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
route2: | ||
path: /route/2 |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
route3: | ||
path: /route/3 |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
<?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\Routing\Tests\Loader; | ||
|
||
use Symfony\Component\Routing\Loader\DirectoryLoader; | ||
use Symfony\Component\Routing\Loader\YamlFileLoader; | ||
use Symfony\Component\Routing\Loader\AnnotationFileLoader; | ||
use Symfony\Component\Config\Loader\LoaderResolver; | ||
use Symfony\Component\Config\FileLocator; | ||
|
||
class DirectoryLoaderTest extends AbstractAnnotationLoaderTest | ||
{ | ||
protected $loader; | ||
protected $reader; | ||
|
||
protected function setUp() | ||
{ | ||
parent::setUp(); | ||
|
||
$locator = new FileLocator(); | ||
$this->reader = $this->getReader(); | ||
$this->loader = new DirectoryLoader($locator); | ||
$resolver = new LoaderResolver(array( | ||
new YamlFileLoader($locator), | ||
new AnnotationFileLoader($locator, $this->getClassLoader($this->reader)), | ||
$this->loader, | ||
)); | ||
$this->loader->setResolver($resolver); | ||
} | ||
|
||
public function testLoadDirectory() | ||
{ | ||
$collection = $this->loader->load(__DIR__.'/../Fixtures/directory', 'directory'); | ||
$routes = $collection->all(); | ||
|
||
$this->assertCount(3, $routes, 'Three routes are loaded'); | ||
$this->assertContainsOnly('Symfony\Component\Routing\Route', $routes); | ||
|
||
for ($i = 1; $i <= 3; $i++) { | ||
$this->assertSame('/route/'.$i, $routes["route".$i]->getPath()); | ||
} | ||
} | ||
|
||
public function testSupports() | ||
{ | ||
$fixturesDir = __DIR__.'/../Fixtures'; | ||
|
||
$this->assertFalse($this->loader->supports($fixturesDir), '->supports() returns true if the resource is loadable'); | ||
$this->assertFalse($this->loader->supports('foo.foo'), '->supports() returns true if the resource is loadable'); | ||
|
||
$this->assertTrue($this->loader->supports($fixturesDir, 'directory'), '->supports() checks the resource type if specified'); | ||
$this->assertFalse($this->loader->supports($fixturesDir, 'foo'), '->supports() checks the resource type if specified'); | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This could be
protected
because it is only used in a child class.