Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 1ebbcf7

Browse filesBrowse files
committed
added support for glob loaders in Config
1 parent c5bdfc5 commit 1ebbcf7
Copy full SHA for 1ebbcf7

File tree

6 files changed

+160
-94
lines changed
Filter options

6 files changed

+160
-94
lines changed

‎src/Symfony/Bundle/FrameworkBundle/Resources/config/routing.xml

Copy file name to clipboardExpand all lines: src/Symfony/Bundle/FrameworkBundle/Resources/config/routing.xml
+5Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,11 @@
3636
<argument type="service" id="file_locator" />
3737
</service>
3838

39+
<service id="routing.loader.glob" class="Symfony\Component\Config\Loader\GlobFileLoader" public="false">
40+
<tag name="routing.loader" />
41+
<argument type="service" id="file_locator" />
42+
</service>
43+
3944
<service id="routing.loader.directory" class="Symfony\Component\Routing\Loader\DirectoryLoader" public="false">
4045
<tag name="routing.loader" />
4146
<argument type="service" id="file_locator" />

‎src/Symfony/Component/Config/Loader/FileLoader.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/Config/Loader/FileLoader.php
+83-1Lines changed: 83 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,9 @@
1414
use Symfony\Component\Config\FileLocatorInterface;
1515
use Symfony\Component\Config\Exception\FileLoaderLoadException;
1616
use Symfony\Component\Config\Exception\FileLoaderImportCircularReferenceException;
17+
use Symfony\Component\Config\Exception\FileLocatorFileNotFoundException;
18+
use Symfony\Component\Finder\Finder;
19+
use Symfony\Component\Finder\Glob;
1720

1821
/**
1922
* FileLoader is the abstract class used by all built-in loaders that are file based.
@@ -32,7 +35,7 @@ abstract class FileLoader extends Loader
3235
*/
3336
protected $locator;
3437

35-
protected $currentDir;
38+
private $currentDir;
3639

3740
/**
3841
* Constructor.
@@ -78,6 +81,85 @@ public function getLocator()
7881
* @throws FileLoaderImportCircularReferenceException
7982
*/
8083
public function import($resource, $type = null, $ignoreErrors = false, $sourceResource = null)
84+
{
85+
$ret = array();
86+
$ct = 0;
87+
foreach ($this->glob($resource, false, $_, $ignoreErrors) as $resource => $info) {
88+
++$ct;
89+
$ret[] = $this->doImport($resource, $type, $ignoreErrors, $sourceResource);
90+
}
91+
92+
return $ct > 1 ? $ret : isset($ret[0]) ? $ret[0] : null;
93+
}
94+
95+
/**
96+
* @internal
97+
*/
98+
protected function glob($resource, $recursive, &$prefix = null, $ignoreErrors = false)
99+
{
100+
if (strlen($resource) === $i = strcspn($resource, '*?{[')) {
101+
if (!$recursive) {
102+
yield $resource => new \SplFileInfo($resource);
103+
104+
return;
105+
}
106+
$prefix = $resource;
107+
$resource = '';
108+
} elseif (0 === $i) {
109+
$prefix = '.';
110+
$resource = '/'.$resource;
111+
} else {
112+
$prefix = dirname(substr($resource, 0, 1 + $i));
113+
$resource = substr($resource, strlen($prefix));
114+
}
115+
116+
try {
117+
$prefix = $this->locator->locate($prefix, $this->currentDir, true);
118+
} catch (FileLocatorFileNotFoundException $e) {
119+
if (!$ignoreErrors) {
120+
throw $e;
121+
}
122+
123+
return;
124+
}
125+
$prefix = realpath($prefix) ?: $prefix;
126+
127+
if (false === strpos($resource, '/**/') && (defined('GLOB_BRACE') || false === strpos($resource, '{'))) {
128+
foreach (glob($prefix.$resource, defined('GLOB_BRACE') ? GLOB_BRACE : 0) as $path) {
129+
if ($recursive && is_dir($path)) {
130+
$flags = \FilesystemIterator::SKIP_DOTS | \FilesystemIterator::FOLLOW_SYMLINKS;
131+
foreach (new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($path, $flags)) as $path => $info) {
132+
if ($info->isFile()) {
133+
yield $path => $info;
134+
}
135+
}
136+
} elseif (is_file($path)) {
137+
yield $path => new \SplFileInfo($path);
138+
}
139+
}
140+
141+
return;
142+
}
143+
144+
if (!class_exists(Finder::class)) {
145+
throw new LogicException(sprintf('Extended glob pattern "%s" cannot be used as the Finder component is not installed.', $resource));
146+
}
147+
148+
$finder = new Finder();
149+
$regex = Glob::toRegex($resource);
150+
if ($recursive) {
151+
$regex = substr_replace($regex, '(/|$)', -2, 1);
152+
}
153+
154+
$prefixLen = strlen($prefix);
155+
foreach ($finder->followLinks()->in($prefix) as $path => $info) {
156+
if (preg_match($regex, substr($path, $prefixLen)) && $info->isFile()) {
157+
yield $path => $info;
158+
}
159+
}
160+
}
161+
162+
private function doImport($resource, $type = null, $ignoreErrors = false, $sourceResource = null)
81163
{
82164
try {
83165
$loader = $this->resolve($resource, $type);
+36Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
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\Config\Loader;
13+
14+
/**
15+
* GlobFileLoader loads files from a glob pattern.
16+
*
17+
* @author Fabien Potencier <fabien@symfony.com>
18+
*/
19+
class GlobFileLoader extends FileLoader
20+
{
21+
/**
22+
* {@inheritdoc}
23+
*/
24+
public function load($resource, $type = null)
25+
{
26+
return $this->import($resource, null, true);
27+
}
28+
29+
/**
30+
* {@inheritdoc}
31+
*/
32+
public function supports($resource, $type = null)
33+
{
34+
return 'glob' === $type;
35+
}
36+
}

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

Copy file name to clipboardExpand all lines: src/Symfony/Component/DependencyInjection/Loader/FileLoader.php
+9-79Lines changed: 9 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -11,15 +11,11 @@
1111

1212
namespace Symfony\Component\DependencyInjection\Loader;
1313

14-
use Symfony\Component\Config\Exception\FileLocatorFileNotFoundException;
1514
use Symfony\Component\DependencyInjection\ContainerBuilder;
1615
use Symfony\Component\DependencyInjection\Definition;
1716
use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
18-
use Symfony\Component\DependencyInjection\Exception\LogicException;
1917
use Symfony\Component\Config\Loader\FileLoader as BaseFileLoader;
2018
use Symfony\Component\Config\FileLocatorInterface;
21-
use Symfony\Component\Finder\Finder;
22-
use Symfony\Component\Finder\Glob;
2319

2420
/**
2521
* FileLoader is the abstract class used by all built-in loaders that are file based.
@@ -41,22 +37,6 @@ public function __construct(ContainerBuilder $container, FileLocatorInterface $l
4137
parent::__construct($locator);
4238
}
4339

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-
6040
/**
6141
* Registers a set of classes as services using PSR-4 for discovery.
6242
*
@@ -88,8 +68,12 @@ private function findClasses($namespace, $resource)
8868
{
8969
$classes = array();
9070
$extRegexp = defined('HHVM_VERSION') ? '/\\.(?:php|hh)$/' : '/\\.php$/';
71+
$prefixLen = null;
72+
foreach ($this->glob($resource, true, $prefix) as $path => $info) {
73+
if (null === $prefixLen) {
74+
$prefixLen = strlen($prefix);
75+
}
9176

92-
foreach ($this->glob($resource, true, $prefixLen) as $path => $info) {
9377
if (!preg_match($extRegexp, $path, $m) || !$info->isReadable()) {
9478
continue;
9579
}
@@ -106,65 +90,11 @@ private function findClasses($namespace, $resource)
10690
}
10791
}
10892

109-
return $classes;
110-
}
111-
112-
private function glob($resource, $recursive, &$prefixLen = null)
113-
{
114-
if (strlen($resource) === $i = strcspn($resource, '*?{[')) {
115-
if (!$recursive) {
116-
yield $resource => new \SplFileInfo($resource);
117-
118-
return;
119-
}
120-
$resourcePrefix = $resource;
121-
$resource = '';
122-
} elseif (0 === $i) {
123-
$resourcePrefix = '.';
124-
$resource = '/'.$resource;
125-
} else {
126-
$resourcePrefix = dirname(substr($resource, 0, 1 + $i));
127-
$resource = substr($resource, strlen($resourcePrefix));
128-
}
129-
130-
$resourcePrefix = $this->locator->locate($resourcePrefix, $this->currentDir, true);
131-
$resourcePrefix = realpath($resourcePrefix) ?: $resourcePrefix;
132-
$prefixLen = strlen($resourcePrefix);
133-
134-
// track directories only for new & removed files
135-
$this->container->fileExists($resourcePrefix, '/^$/');
136-
137-
if (false === strpos($resource, '/**/') && (defined('GLOB_BRACE') || false === strpos($resource, '{'))) {
138-
foreach (glob($resourcePrefix.$resource, defined('GLOB_BRACE') ? GLOB_BRACE : 0) as $path) {
139-
if ($recursive && is_dir($path)) {
140-
$flags = \FilesystemIterator::SKIP_DOTS | \FilesystemIterator::FOLLOW_SYMLINKS;
141-
foreach (new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($path, $flags)) as $path => $info) {
142-
if ($info->isFile()) {
143-
yield $path => $info;
144-
}
145-
}
146-
} elseif (is_file($path)) {
147-
yield $path => new \SplFileInfo($path);
148-
}
149-
}
150-
151-
return;
152-
}
153-
154-
if (!class_exists(Finder::class)) {
155-
throw new LogicException(sprintf('Extended glob pattern "%s" cannot be used as the Finder component is not installed.', $resource));
156-
}
157-
158-
$finder = new Finder();
159-
$regex = Glob::toRegex($resource);
160-
if ($recursive) {
161-
$regex = substr_replace($regex, '(/|$)', -2, 1);
93+
if (null !== $prefix) {
94+
// track directories only for new & removed files
95+
$this->container->fileExists($prefix, '/^$/');
16296
}
16397

164-
foreach ($finder->followLinks()->in($resourcePrefix) as $path => $info) {
165-
if (preg_match($regex, substr($path, $prefixLen)) && $info->isFile()) {
166-
yield $path => $info;
167-
}
168-
}
98+
return $classes;
16999
}
170100
}

‎src/Symfony/Component/HttpKernel/Kernel.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/HttpKernel/Kernel.php
+2Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
use Symfony\Component\HttpKernel\Config\FileLocator;
3030
use Symfony\Component\HttpKernel\DependencyInjection\MergeExtensionConfigurationPass;
3131
use Symfony\Component\HttpKernel\DependencyInjection\AddClassesToCachePass;
32+
use Symfony\Component\Config\Loader\GlobFileLoader;
3233
use Symfony\Component\Config\Loader\LoaderResolver;
3334
use Symfony\Component\Config\Loader\DelegatingLoader;
3435
use Symfony\Component\Config\ConfigCache;
@@ -686,6 +687,7 @@ protected function getContainerLoader(ContainerInterface $container)
686687
new YamlFileLoader($container, $locator),
687688
new IniFileLoader($container, $locator),
688689
new PhpFileLoader($container, $locator),
690+
new GlobFileLoader($locator),
689691
new DirectoryLoader($container, $locator),
690692
new ClosureLoader($container),
691693
));

‎src/Symfony/Component/Routing/RouteCollectionBuilder.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/Routing/RouteCollectionBuilder.php
+25-14Lines changed: 25 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -61,21 +61,28 @@ public function __construct(LoaderInterface $loader = null)
6161
*/
6262
public function import($resource, $prefix = '/', $type = null)
6363
{
64-
/** @var RouteCollection $collection */
65-
$collection = $this->load($resource, $type);
64+
/** @var RouteCollection[] $collection */
65+
$collections = $this->load($resource, $type);
6666

6767
// create a builder from the RouteCollection
6868
$builder = $this->createBuilder();
69-
foreach ($collection->all() as $name => $route) {
70-
$builder->addRoute($route, $name);
71-
}
7269

73-
foreach ($collection->getResources() as $resource) {
74-
$builder->addResource($resource);
75-
}
70+
foreach ($collections as $collection) {
71+
if (null === $collection) {
72+
continue;
73+
}
7674

77-
// mount into this builder
78-
$this->mount($prefix, $builder);
75+
foreach ($collection->all() as $name => $route) {
76+
$builder->addRoute($route, $name);
77+
}
78+
79+
foreach ($collection->getResources() as $resource) {
80+
$builder->addResource($resource);
81+
}
82+
83+
// mount into this builder
84+
$this->mount($prefix, $builder);
85+
}
7986

8087
return $builder;
8188
}
@@ -201,7 +208,7 @@ public function setRequirement($key, $regex)
201208
}
202209

203210
/**
204-
* Sets an opiton that will be added to all embedded routes (unless that
211+
* Sets an option that will be added to all embedded routes (unless that
205212
* option is already set).
206213
*
207214
* @param string $key
@@ -345,7 +352,7 @@ private function generateRouteName(Route $route)
345352
* @param mixed $resource A resource
346353
* @param string|null $type The resource type or null if unknown
347354
*
348-
* @return RouteCollection
355+
* @return RouteCollection[]
349356
*
350357
* @throws FileLoaderLoadException If no loader is found
351358
*/
@@ -356,7 +363,9 @@ private function load($resource, $type = null)
356363
}
357364

358365
if ($this->loader->supports($resource, $type)) {
359-
return $this->loader->load($resource, $type);
366+
$collections = $this->loader->load($resource, $type);
367+
368+
return is_array($collections) ? $collections : array($collections);
360369
}
361370

362371
if (null === $resolver = $this->loader->getResolver()) {
@@ -367,6 +376,8 @@ private function load($resource, $type = null)
367376
throw new FileLoaderLoadException($resource);
368377
}
369378

370-
return $loader->load($resource, $type);
379+
$collections = $loader->load($resource, $type);
380+
381+
return is_array($collections) ? $collections : array($collections);
371382
}
372383
}

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.