@@ -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 ));
@@ -101,9 +103,20 @@ public function getIterator()
101103 return ;
102104 }
103105 $ prefix = str_replace ('\\' , '/ ' , $ this ->prefix );
106+ $ paths = null ;
107+
108+ if (0 !== strpos ($ this ->prefix , 'phar:// ' ) && false === strpos ($ this ->pattern , '/**/ ' )) {
109+ if ($ this ->globBrace || false === strpos ($ this ->pattern , '{ ' )) {
110+ $ paths = glob ($ this ->prefix .$ this ->pattern , GLOB_NOSORT | $ this ->globBrace );
111+ } elseif (false === strpos ($ this ->pattern , '\\' ) || !preg_match ('/ \\\\[,{}]/ ' , $ this ->pattern )) {
112+ foreach ($ this ->expandGlob ($ this ->pattern ) as $ p ) {
113+ $ paths [] = glob ($ this ->prefix .$ p , GLOB_NOSORT );
114+ }
115+ $ paths = array_merge (...$ paths );
116+ }
117+ }
104118
105- if (0 !== strpos ($ this ->prefix , 'phar:// ' ) && false === strpos ($ this ->pattern , '/**/ ' ) && (\defined ('GLOB_BRACE ' ) || false === strpos ($ this ->pattern , '{ ' ))) {
106- $ paths = glob ($ this ->prefix .$ this ->pattern , GLOB_NOSORT | (\defined ('GLOB_BRACE ' ) ? GLOB_BRACE : 0 ));
119+ if (null !== $ paths ) {
107120 sort ($ paths );
108
8000
121 foreach ($ paths as $ path ) {
109122 if ($ this ->excludedPrefixes ) {
@@ -187,4 +200,34 @@ private function computeHash(): string
187200
188201 return hash_final ($ hash );
189202 }
203+
204+ private function expandGlob (string $ pattern ): array
205+ {
206+ $ segments = preg_split ('/\{([^{}]*+)\}/ ' , $ pattern , -1 , PREG_SPLIT_DELIM_CAPTURE );
207+ $ paths = [$ segments [0 ]];
208+ $ patterns = [];
209+
210+ for ($ i = 1 ; $ i < \count ($ segments ); $ i += 2 ) {
211+ $ patterns = [];
212+
213+ foreach (explode (', ' , $ segments [$ i ]) as $ s ) {
214+ foreach ($ paths as $ p ) {
215+ $ patterns [] = $ p .$ s .$ segments [1 + $ i ];
216+ }
217+ }
218+
219+ $ paths = $ patterns ;
220+ }
221+
222+ $ j = 0 ;
223+ foreach ($ patterns as $ i => $ p ) {
224+ if (false !== strpos ($ p , '{ ' )) {
225+ $ p = $ this ->expandGlob ($ p );
226+ array_splice ($ paths , $ i + $ j , 1 , $ p );
227+ $ j += \count ($ p ) - 1 ;
228+ }
229+ }
230+
231+ return $ paths ;
232+ }
190233}
0 commit comments