@@ -31,6 +31,7 @@ class GlobResource implements \IteratorAggregate, SelfCheckingResourceInterface
3131 private $ hash ;
3232 private $ forExclusion ;
3333 private $ excludedPrefixes ;
34+ private $ globBrace ;
3435
3536 /**
3637 * @param string $prefix A directory prefix
@@ -47,6 +48,7 @@ public function __construct(string $prefix, string $pattern, bool $recursive, bo
4748 $ this ->recursive = $ recursive ;
4849 $ this ->forExclusion = $ forExclusion ;
4950 $ this ->excludedPrefixes = $ excludedPrefixes ;
51+ $ this ->globBrace = \defined ('GLOB_BRACE ' ) ? GLOB_BRACE : 0 ;
5052
5153 if (false === $ this ->prefix ) {
5254 throw new \InvalidArgumentException (sprintf ('The path "%s" does not exist. ' , $ prefix ));
@@ -98,9 +100,20 @@ public function getIterator(): \Traversable
98100 return ;
99101 }
100102 $ prefix = str_replace ('\\' , '/ ' , $ this ->prefix );
103+ $ paths = null ;
104+
105+ if (0 !== strpos ($ this ->prefix , 'phar:// ' ) && false === strpos ($ this ->pattern , '/**/ ' )) {
106+ if ($ this ->globBrace || false === strpos ($ this ->pattern , '{ ' )) {
107+ $ paths = glob ($ this ->prefix .$ this ->pattern , GLOB_NOSORT | $ this ->globBrace );
108+ } elseif (false === strpos ($ this ->pattern , '\\' ) || !preg_match ('/ \\\\[,{}]/ ' , $ this ->pattern )) {
109+ foreach ($ this ->expandGlob ($ this ->pattern ) as $ p ) {
110+ $ paths [] = glob ($ this ->prefix .$ p , GLOB_NOSORT );
111+ }
112+ $ paths = array_merge (...$ paths );
113+ }
114+ }
101115
102- if (0 !== strpos ($ this ->prefix , 'phar:// ' ) && false === strpos ($ this ->pattern , '/**/ ' ) && (\defined ('GLOB_BRACE ' ) || false === strpos ($ this ->pattern , '{ ' ))) {
103- $ paths = glob ($ this ->prefix .$ this ->pattern , GLOB_NOSORT | (\defined ('GLOB_BRACE ' ) ? GLOB_BRACE : 0 ));
116+ if (null !== $ paths ) {
104117 sort ($ paths );
105118 foreach ($ paths as $ path ) {
106119 if ($ this ->excludedPrefixes ) {
@@ -184,4 +197,34 @@ private function computeHash(): string
184197
185198 return hash_final ($ hash );
186199 }
200+
201+ private function expandGlob (string $ pattern ): array
202+ {
203+ $ segments = preg_split ('/\{([^{}]*+)\}/ ' , $ pattern , -1 , PREG_SPLIT_DELIM_CAPTURE );
204+ $ paths = [$ segments [0 ]];
205+ $ patterns = [];
206+
207+ for ($ i = 1 ; $ i < \count ($ segments ); $ i += 2 ) {
208+ $ patterns = [];
209+
210+ foreach (explode (', ' , $ segments [$ i ]) as $ s ) {
211+ foreach ($ paths as $ p ) {
212+ $ patterns [] = $ p .$ s .$ segments [1 + $ i ];
213+ }
214+ }
215+
216+ $ paths = $ patterns ;
217+ }
218+
219+ $ j = 0 ;
220+ foreach ($ patterns as $ i => $ p ) {
221+ if (false !== strpos ($ p , '{ ' )) {
222+ $ p = $ this ->expandGlob ($ p );
223+ array_splice ($ paths , $ i + $ j , 1 , $ p );
224+ $ j += \count ($ p ) - 1 ;
225+ }
226+ }
227+
228+ return $ paths ;
229+ }
187230}
0 commit comments