Skip to content

Commit

Permalink
feat: add filter for files (#10)
Browse files Browse the repository at this point in the history
  • Loading branch information
alleknalle authored Feb 7, 2024
1 parent df454e4 commit 84f8533
Show file tree
Hide file tree
Showing 8 changed files with 114 additions and 3 deletions.
7 changes: 7 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,13 @@ You can filter classes using the methods exposed by `FinderInterface`:
- `inNamespace(array $namespaces)`: Searches only in given namespaces.
- `filter(callable $callback)`: Custom filtering callback.

#### Specific finder filters

##### RecursiveFinder

- `fileFilter(callable $callback)`: Custom filtering callback for loading files.


## License

This library is released under the MIT license.
Expand Down
9 changes: 9 additions & 0 deletions data/Recursive/Bar.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<?php
declare(strict_types=1);

namespace Kcs\ClassFinder\Fixtures\Recursive;

class Bar
{

}
9 changes: 9 additions & 0 deletions data/Recursive/Foo.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<?php
declare(strict_types=1);

namespace Kcs\ClassFinder\Fixtures\Recursive;

class Foo
{

}
9 changes: 9 additions & 0 deletions data/Recursive/class-foo-bar.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<?php
declare(strict_types=1);

namespace Kcs\ClassFinder\Fixtures\Recursive;

class FooBar
{

}
12 changes: 11 additions & 1 deletion lib/Finder/RecursiveFinder.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@ final class RecursiveFinder implements FinderInterface

private string $path;

/** @var callable|null */
private $iteratorCallback = null;

public function __construct(string $path)
{
$path = PathNormalizer::resolvePath($path);
Expand All @@ -24,6 +27,13 @@ public function __construct(string $path)
/** @return Traversable<class-string, ReflectionClass> */
public function getIterator(): Traversable
{
return $this->applyFilters(new RecursiveIterator($this->path));
return $this->applyFilters(new RecursiveIterator($this->path, 0, $this->iteratorCallback));
}

public function fileFilter(callable|null $callback): self
{
$this->iteratorCallback = $callback;

return $this;
}
}
11 changes: 10 additions & 1 deletion lib/Iterator/RecursiveIterator.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,15 @@ final class RecursiveIterator extends ClassIterator
{
use RecursiveIteratorTrait;

public function __construct(string $path, int $flags = 0)
/** @var callable|null */
private $callback = null;

public function __construct(string $path, int $flags = 0, callable|null $callback = null)
{
$this->path = PathNormalizer::resolvePath($path);

$this->callback = $callback;

parent::__construct($flags);
}

Expand All @@ -37,6 +42,10 @@ protected function getGenerator(): Generator
continue;
}

if($this->callback && !call_user_func($this->callback, $path, $info)) {
continue;
}

require_once $path;
$includedFiles[] = $path;
}
Expand Down
18 changes: 17 additions & 1 deletion tests/Finder/RecursiveFinderTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,11 @@
use Kcs\ClassFinder\Finder\RecursiveFinder;
use Kcs\ClassFinder\Fixtures\Psr0;
use Kcs\ClassFinder\Fixtures\Psr4;
use Kcs\ClassFinder\Fixtures\Recursive;
use PHPUnit\Framework\TestCase;
use ReflectionClass;
use SplFileInfo;
use Traversable;

use function iterator_to_array;

class RecursiveFinderTest extends TestCase
Expand Down Expand Up @@ -107,4 +108,19 @@ public function testFinderShouldFilterByCallback(): void
Psr4\AbstractClass::class => new ReflectionClass(Psr4\AbstractClass::class),
], iterator_to_array($finder));
}

public function testFinderShouldFilterByIteratorCallback(): void
{
$finder = new RecursiveFinder(__DIR__ . '/../../data/Recursive');
$finder->fileFilter(static function (string $path, SplFileInfo $info): bool {
return !str_starts_with($info->getFilename(), 'class-');
});

$classes = iterator_to_array($finder);

self::assertEquals([
Recursive\Bar::class => new ReflectionClass(Recursive\Bar::class),
Recursive\Foo::class => new ReflectionClass(Recursive\Foo::class),
], $classes);
}
}
42 changes: 42 additions & 0 deletions tests/Iterator/RecursiveIteratorTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
<?php

declare(strict_types=1);

namespace Kcs\ClassFinder\Tests\Iterator;

use Kcs\ClassFinder\Fixtures\Recursive\Bar;
use Kcs\ClassFinder\Fixtures\Recursive\Foo;
use Kcs\ClassFinder\Fixtures\Recursive\FooBar;
use Kcs\ClassFinder\Iterator\RecursiveIterator;
use PHPUnit\Framework\TestCase;
use ReflectionClass;
use SplFileInfo;
use function iterator_to_array;

class RecursiveIteratorTest extends TestCase
{
public function testRecursiveIteratorShouldSearchInDirectory(): void
{
$iterator = new RecursiveIterator(__DIR__ . '/../../data/Recursive');

self::assertEquals([
Bar::class => new ReflectionClass(Bar::class),
FooBar::class => new ReflectionClass(FooBar::class),
Foo::class => new ReflectionClass(Foo::class),
], iterator_to_array($iterator));
}

public function testRecursiveIteratorShouldSkipFilesThatDoNotMatchFilter(): void
{
$iterator = new RecursiveIterator(
__DIR__ . '/../../data/Recursive',
0,
static function ( string $path, SplFileInfo $info ): bool {
return str_starts_with( $info->getFilename(), 'class-' );
});

self::assertEquals([
FooBar::class => new ReflectionClass(FooBar::class),
], iterator_to_array($iterator));
}
}

0 comments on commit 84f8533

Please sign in to comment.