Skip to content
/ config Public

Commit ce9cb0c

Browse files
NeilPeyssardnicolas-grekas
authored andcommitted
[Config][Routing] Fix exclude option being ignored for non-glob and PSR-4 resources
1 parent 5254855 commit ce9cb0c

File tree

5 files changed

+55
-19
lines changed

5 files changed

+55
-19
lines changed

Loader/FileLoader.php

Lines changed: 29 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -72,27 +72,40 @@ public function getLocator(): FileLocatorInterface
7272
*/
7373
public function import(mixed $resource, ?string $type = null, bool $ignoreErrors = false, ?string $sourceResource = null, string|array|null $exclude = null)
7474
{
75-
if (\is_string($resource) && \strlen($resource) !== ($i = strcspn($resource, '*?{[')) && !str_contains($resource, "\n")) {
76-
$excluded = [];
77-
foreach ((array) $exclude as $pattern) {
78-
foreach ($this->glob($pattern, true, $_, false, true) as $path => $info) {
79-
// normalize Windows slashes and remove trailing slashes
80-
$excluded[rtrim(str_replace('\\', '/', $path), '/')] = true;
81-
}
75+
$excluded = [];
76+
foreach ((array) $exclude as $pattern) {
77+
foreach ($this->glob($pattern, true, $_, false, true) as $path => $info) {
78+
// normalize Windows slashes and remove trailing slashes
79+
$excluded[rtrim(str_replace('\\', '/', $path), '/')] = true;
8280
}
81+
}
8382

84-
$ret = [];
85-
$isSubpath = 0 !== $i && str_contains(substr($resource, 0, $i), '/');
86-
foreach ($this->glob($resource, false, $_, $ignoreErrors || !$isSubpath, false, $excluded) as $path => $info) {
87-
if (null !== $res = $this->doImport($path, 'glob' === $type ? null : $type, $ignoreErrors, $sourceResource)) {
88-
$ret[] = $res;
89-
}
90-
$isSubpath = true;
83+
if (\is_string($resource) && !class_exists($resource)) {
84+
$isGlobPattern = \strlen($resource) !== strcspn($resource, '*?{[');
85+
86+
if (!$isGlobPattern && $excluded) {
87+
$resource = rtrim(str_replace('\\', '/', $resource), '/');
88+
$resource .= '/**/*';
89+
$isGlobPattern = true;
9190
}
9291

93-
if ($isSubpath) {
94-
return isset($ret[1]) ? $ret : ($ret[0] ?? null);
92+
if ($isGlobPattern && !str_contains($resource, "\n")) {
93+
$ret = [];
94+
$i = strcspn($resource, '*?{[');
95+
$isSubpath = 0 !== $i && str_contains(substr($resource, 0, $i), '/');
96+
foreach ($this->glob($resource, false, $_, $ignoreErrors || !$isSubpath, false, $excluded) as $path => $info) {
97+
if (null !== $res = $this->doImport($path, 'glob' === $type ? null : $type, $ignoreErrors, $sourceResource)) {
98+
$ret[] = $res;
99+
}
100+
$isSubpath = true;
101+
}
102+
103+
if ($isSubpath) {
104+
return isset($ret[1]) ? $ret : ($ret[0] ?? null);
105+
}
95106
}
107+
} elseif (\is_array($resource) && $excluded) {
108+
$resource['_excluded'] = $excluded;
96109
}
97110

98111
return $this->doImport($resource, $type, $ignoreErrors, $sourceResource);

Tests/Fixtures/Include/SubDir/ExcludeFile.txt

Whitespace-only changes.

Tests/Fixtures/Include/SubDir/IncludeFile.txt

Whitespace-only changes.

Tests/Loader/FileLoaderTest.php

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -118,11 +118,14 @@ public function testImportWithSimpleGlob()
118118
$this->assertSame(__FILE__, strtr($loader->import('FileLoaderTest.*'), '/', \DIRECTORY_SEPARATOR));
119119
}
120120

121-
public function testImportWithExclude()
121+
/**
122+
* @dataProvider importWithExcludeProvider
123+
*/
124+
public function testImportWithExclude(string $include, string $exclude, int $expectedCount)
122125
{
123126
$loader = new TestFileLoader(new FileLocator(__DIR__.'/../Fixtures'));
124-
$loadedFiles = $loader->import('Include/*', null, false, null, __DIR__.'/../Fixtures/Include/{ExcludeFile.txt}');
125-
$this->assertCount(2, $loadedFiles);
127+
$loadedFiles = $loader->import($include, null, false, null, $exclude);
128+
$this->assertCount($expectedCount, $loadedFiles);
126129
$this->assertNotContains('ExcludeFile.txt', $loadedFiles);
127130
}
128131

@@ -137,6 +140,24 @@ public function testExcludeTrailingSlashConsistency(string $exclude)
137140
$this->assertNotContains('baz.txt', $loadedFiles);
138141
}
139142

143+
public static function importWithExcludeProvider(): iterable
144+
{
145+
yield ['Include/*', __DIR__.'/../Fixtures/Include/{ExcludeFile.txt}', 2];
146+
yield ['Include/', __DIR__.'/../Fixtures/Include/{ExcludeFile.txt}', 4];
147+
yield ['Include', __DIR__.'/../Fixtures/Include/{ExcludeFile.txt}', 4];
148+
yield ['Include/**/*', __DIR__.'/../Fixtures/Include/{ExcludeFile.txt}', 4];
149+
yield ['Include/*', __DIR__.'/../Fixtures/Include/{Exclude*.txt}', 2];
150+
yield ['Include/', __DIR__.'/../Fixtures/Include/{Exclude*.txt}', 4];
151+
yield ['Include', __DIR__.'/../Fixtures/Include/{Exclude*.txt}', 4];
152+
yield ['Include/**/*', __DIR__.'/../Fixtures/Include/{Exclude*.txt}', 4];
153+
yield ['Include/', __DIR__.'/../Fixtures/Include/**/{ExcludeFile.txt}', 3];
154+
yield ['Include', __DIR__.'/../Fixtures/Include/**/{ExcludeFile.txt}', 3];
155+
yield ['Include/**/*', __DIR__.'/../Fixtures/Include/**/{ExcludeFile.txt}', 3];
156+
yield ['Include/', __DIR__.'/../Fixtures/Include/**/{Exclude*.txt}', 3];
157+
yield ['Include', __DIR__.'/../Fixtures/Include/**/{Exclude*.txt}', 3];
158+
yield ['Include/**/*', __DIR__.'/../Fixtures/Include/**/{Exclude*.txt}', 3];
159+
}
160+
140161
public static function excludeTrailingSlashConsistencyProvider(): iterable
141162
{
142163
yield [__DIR__.'/../Fixtures/Exclude/ExcludeToo/'];

Tests/Resource/GlobResourceTest.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,8 @@ public function testBraceFallback()
173173
$expected = [
174174
$dir.'/Exclude/ExcludeToo/AnotheExcludedFile.txt',
175175
$dir.'/ExcludeTrailingSlash/exclude/baz.txt',
176+
$dir.'/Include/SubDir/ExcludeFile.txt',
177+
$dir.'/Include/SubDir/IncludeFile.txt',
176178
$dir.'/foo.xml',
177179
];
178180

0 commit comments

Comments
 (0)