@@ -26,14 +26,19 @@ class Finder implements \IteratorAggregate
2626{
2727 use Nette \SmartObject;
2828
29- private array $ find = [];
30- private array $ in = [];
31- private array $ filters = [];
32- private array $ recurseFilters = [];
29+ /** @var FinderBatch[] */
30+ private array $ batches = [];
31+ private FinderBatch $ batch ;
3332 private bool $ selfFirst = true ;
3433 private int $ maxDepth = -1 ;
3534
3635
36+ public function __construct ()
37+ {
38+ $ this ->and ();
39+ }
40+
41+
3742 /**
3843 * Begins search for files and directories matching mask.
3944 * @param string ...$masks
@@ -80,7 +85,7 @@ public function files(string ...$masks): static
8085 if (str_starts_with ($ mask , '**/ ' )) {
8186 $ mask = substr ($ mask , 3 );
8287 }
83- $ this ->find [] = [$ mask , 'isFile ' ];
88+ $ this ->batch -> find [] = [$ mask , 'isFile ' ];
8489 }
8590
8691 return $ this ;
@@ -100,7 +105,7 @@ public function directories(string ...$masks): static
100105 if (str_starts_with ($ mask , '**/ ' )) {
101106 $ mask = substr ($ mask , 3 );
102107 }
103- $ this ->find [] = [$ mask , 'isDir ' ];
108+ $ this ->batch -> find [] = [$ mask , 'isDir ' ];
104109 }
105110
106111 return $ this ;
@@ -119,7 +124,7 @@ public function in(...$paths): static
119124 throw new Nette \InvalidArgumentException ("Invalid directory ' $ path' " );
120125 }
121126 $ path = rtrim (self ::normalizeSlashes ($ path ), '/ ' );
122- $ this ->in [] = $ path ;
127+ $ this ->batch -> in [] = $ path ;
123128 }
124129
125130 return $ this ;
@@ -138,7 +143,7 @@ public function from(...$paths): static
138143 throw new Nette \InvalidArgumentException ("Invalid directory ' $ path' " );
139144 }
140145 $ path = rtrim (self ::normalizeSlashes ($ path ), '/ ' );
141- $ this ->in [] = $ path . '/** ' ;
146+ $ this ->batch -> in [] = $ path . '/** ' ;
142147 }
143148
144149 return $ this ;
@@ -155,6 +160,16 @@ public function childFirst(): static
155160 }
156161
157162
163+ /**
164+ * Starts defining a new search group.
165+ */
166+ public function and (): static
167+ {
168+ $ this ->batches [] = $ this ->batch = new FinderBatch ;
169+ return $ this ;
170+ }
171+
172+
158173 /********************* filtering ****************d*g**/
159174
160175
@@ -185,14 +200,17 @@ public function exclude(...$masks): static
185200 }
186201
187202
203+ /********************* filtering ****************d*g**/
204+
205+
188206 /**
189207 * Restricts the search using callback.
190208 * @param callable(FileInfo): bool $callback
191209 * @param string ...$masks
192210 */
193211 public function filter (callable $ callback ): static
194212 {
195- $ this ->filters [] = $ callback ;
213+ $ this ->batch -> filters [] = $ callback ;
196214 return $ this ;
197215 }
198216
@@ -203,7 +221,7 @@ public function filter(callable $callback): static
203221 */
204222 public function recurseFilter (callable $ callback ): static
205223 {
206- $ this ->recurseFilters [] = $ callback ;
224+ $ this ->batch -> recurseFilters [] = $ callback ;
207225 return $ this ;
208226 }
209227
@@ -304,7 +322,7 @@ private function traverseDir(string $dir, array $searches, array $subDirs = []):
304322 foreach ($ searches as $ search ) {
305323 if (
306324 $ search ->recursive
307- && $ this ->invokeFilters ($ this ->recurseFilters , $ file , $ cache )
325+ && $ this ->invokeFilters ($ search -> batch ->recurseFilters , $ file , $ cache )
308326 ) {
309327 $ into [] = $ search ;
310328 }
@@ -320,7 +338,7 @@ private function traverseDir(string $dir, array $searches, array $subDirs = []):
320338 if (
321339 $ file ->{$ search ->mode }()
322340 && preg_match ($ search ->find , $ relativePathname )
323- && $ this ->invokeFilters ($ this ->filters , $ file , $ cache )
341+ && $ this ->invokeFilters ($ search -> batch ->filters , $ file , $ cache )
324342 ) {
325343 yield $ pathName => $ file ;
326344 break ;
@@ -351,17 +369,19 @@ private function invokeFilters(array $filters, FileInfo $file, array &$cache): b
351369 private function prepare (): array
352370 {
353371 $ groups = [];
354- foreach ($ this ->find as [$ mask , $ mode ]) {
355- if (FileSystem::isAbsolute ($ mask )) {
356- if ($ this ->in ) {
357- throw new Nette \InvalidStateException ("You cannot combine the absolute path in the mask ' $ mask' and the directory to search ' {$ this ->in [0 ]}'. " );
358- }
359- [$ base , $ rest , $ recursive ] = self ::splitRecursivePart ($ mask );
360- $ groups [$ base ][] = (object ) ['find ' => $ this ->buildPattern ($ rest ), 'mode ' => $ mode , 'recursive ' => $ recursive ];
361- } else {
362- foreach ($ this ->in ?: ['. ' ] as $ in ) {
363- [$ base , $ rest , $ recursive ] = self ::splitRecursivePart ($ in . '/ ' . $ mask );
364- $ groups [$ base ][] = (object ) ['find ' => $ this ->buildPattern ($ rest ), 'mode ' => $ mode , 'recursive ' => $ recursive ];
372+ foreach ($ this ->batches as $ batch ) {
373+ foreach ($ batch ->find as [$ mask , $ mode ]) {
374+ if (FileSystem::isAbsolute ($ mask )) {
375+ if ($ batch ->in ) {
376+ throw new Nette \InvalidStateException ("You cannot combine the absolute path in the mask ' $ mask' and the directory to search ' {$ batch ->in [0 ]}'. " );
377+ }
378+ [$ base , $ rest , $ recursive ] = self ::splitRecursivePart ($ mask );
379+ $ groups [$ base ][] = (object ) ['find ' => $ this ->buildPattern ($ rest ), 'mode ' => $ mode , 'recursive ' => $ recursive , 'batch ' => $ batch ];
380+ } else {
381+ foreach ($ batch ->in ?: ['. ' ] as $ in ) {
382+ [$ base , $ rest , $ recursive ] = self ::splitRecursivePart ($ in . '/ ' . $ mask );
383+ $ groups [$ base ][] = (object ) ['find ' => $ this ->buildPattern ($ rest ), 'mode ' => $ mode , 'recursive ' => $ recursive , 'batch ' => $ batch ];
384+ }
365385 }
366386 }
367387 }
0 commit comments