bug #22985 [Config] Allow empty globs (nicolas-grekas)

This PR was merged into the 3.3 branch.

Discussion
----------

[Config] Allow empty globs

| Q             | A
| ------------- | ---
| Branch?       | 3.3
| Bug fix?      | yes
| New feature?  | no
| BC breaks?    | no
| Deprecations? | no
| Tests pass?   | yes
| Fixed tickets | #22950
| License       | MIT
| Doc PR        | -

This considers globs as valid even if they return no matches when they have a prefix (and when that prefix exists, according to `$ignoreErrors`).
This means there is an edge-case:
`*.abc` with at least one match is OK, but when it has no match, it falls back to regular import, then usually will fil.
But rewriting this to `./*.abc` resolves the ambiguity and turns this into a glob that won't fail if no matches are found.

This should provide the expected behavior in most cases (but ambiguous described one of course).

Commits
-------

c5b9c1a8c8 [Config] Allow empty globs
This commit is contained in:
Fabien Potencier 2017-05-31 11:07:24 -07:00
commit b13671957b
2 changed files with 27 additions and 6 deletions

View File

@ -83,13 +83,18 @@ abstract class FileLoader extends Loader
*/
public function import($resource, $type = null, $ignoreErrors = false, $sourceResource = null)
{
if (is_string($resource) && false !== strpbrk($resource, '*?{[')) {
if (is_string($resource) && strlen($resource) !== $i = strcspn($resource, '*?{[')) {
$ret = array();
foreach ($this->glob($resource, false, $_, true) as $path => $info) {
$ret[] = $this->doImport($path, $type, $ignoreErrors, $sourceResource);
$isSubpath = 0 !== $i && false !== strpos(substr($resource, 0, $i), '/');
foreach ($this->glob($resource, false, $_, $ignoreErrors || !$isSubpath) as $path => $info) {
if (null !== $res = $this->doImport($path, $type, $ignoreErrors, $sourceResource)) {
$ret[] = $res;
}
$isSubpath = true;
}
if ($ret) {
return count($ret) > 1 ? $ret : $ret[0];
if ($isSubpath) {
return isset($ret[1]) ? $ret : (isset($ret[0]) ? $ret[0] : null);
}
}
@ -104,7 +109,7 @@ abstract class FileLoader extends Loader
if (strlen($pattern) === $i = strcspn($pattern, '*?{[')) {
$prefix = $pattern;
$pattern = '';
} elseif (0 === $i) {
} elseif (0 === $i || false === strpos(substr($pattern, 0, $i), '/')) {
$prefix = '.';
$pattern = '/'.$pattern;
} else {

View File

@ -12,6 +12,7 @@
namespace Symfony\Component\Config\Tests\Loader;
use PHPUnit\Framework\TestCase;
use Symfony\Component\Config\FileLocator;
use Symfony\Component\Config\Loader\FileLoader;
use Symfony\Component\Config\Loader\LoaderResolver;
@ -74,6 +75,21 @@ class FileLoaderTest extends TestCase
$this->assertSame('[foo]', $loader->import('[foo]'));
}
public function testImportWithNoGlobMatch()
{
$locatorMock = $this->getMockBuilder('Symfony\Component\Config\FileLocatorInterface')->getMock();
$loader = new TestFileLoader($locatorMock);
$this->assertNull($loader->import('./*.abc'));
}
public function testImportWithSimpleGlob()
{
$loader = new TestFileLoader(new FileLocator(__DIR__));
$this->assertSame(__FILE__, strtr($loader->import('FileLoaderTest.*'), '/', DIRECTORY_SEPARATOR));
}
}
class TestFileLoader extends FileLoader