Flysystem Filter is a lightweight and intuitive filtering layer for League/Flysystem. It provides an easy-to-use FilterBuilder for logical and chainable filtering of filesystem contents (DirectoryListing).
- Simple Filtering: Filter filesystem contents without writing complex callback functions.
- Logical Expressions: Combine conditions using
and(),or(),group_start(), andgroup_end(). - Chainable API: Build complex filters with a readable, chainable syntax.
- Integration with Flysystem: Works seamlessly with League/Flysystem's
DirectoryListing.
Install via Composer:
composer require marktaborosi/flysystem-filterHere's a basic example that filters only files:
use League\Flysystem\Filesystem;
use League\Flysystem\Local\LocalFilesystemAdapter;
use Marktaborosi\FlysystemFilter\FilterBuilder;
use Marktaborosi\FlysystemFilter\FlysystemFilter;
require 'vendor/autoload.php';
$adapter = new LocalFilesystemAdapter(__DIR__ . '/tests/Storage/');
$flysystem = new Filesystem($adapter);
$flysystemContents = $flysystem->listContents('', true);
$filter = new FilterBuilder();
$filter->isFile();
$flysystemFilter = new FlysystemFilter();
$filteredResults = $flysystemFilter->filter($flysystemContents, $filter);
foreach ($filteredResults as $result) {
echo $result->path() . PHP_EOL;
}Filter files with advanced conditions:
$filter = new FilterBuilder();
$filter
->extensionEquals(['txt', 'log'])
->and()
->isPublic()
->and()
->sizeLt('1G');
$flysytemFilter = new FlysystemFilter();
$filteredResults = $flysystemFilter->filter($flysystemContents, $filter);You can group conditions to create complex expressions:
$filter = new FilterBuilder();
$filter
->group_start()
->extensionContains(['log', 'txt'])
->and()
->isFile()
->group_end()
->or()
->pathMatchesRegex('/debug/');
$flysytemFilter = new FlysystemFilter();
$filteredResults = $flysystemFilter->filter($flysystemContents, $filter);From v3.0.0, Flysystem Filter ships with native Laravel support — including a Service Provider and a Facade — for seamless integration into your Laravel projects.
If installed via Composer in a Laravel application, the package will be automatically discovered thanks to Laravel's package auto-discovery.
composer.json (auto-discovery config — already included in this package):
{
"extra": {
"laravel": {
"providers": [
"Marktaborosi\\FlysystemFilter\\Laravel\\FlysystemFilterServiceProvider"
],
"aliases": {
"FlysystemFilter": "Marktaborosi\\FlysystemFilter\\Laravel\\FlysystemFilterFacade"
}
}
}
}If you have disabled auto-discovery, register them manually in config/app.php:
'providers' => [
Marktaborosi\FlysystemFilter\Laravel\FlysystemFilterServiceProvider::class,
],
'aliases' => [
'FlysystemFilter' => Marktaborosi\FlysystemFilter\Laravel\FlysystemFilterFacade::class,
],use Illuminate\Support\Facades\Storage;
use Marktaborosi\FlysystemFilter\FilterBuilder;
use FlysystemFilter; // Facade alias
Route::get('/filtered-files', function () {
$listing = Storage::disk('local')->listContents('', true);
$builder = (new FilterBuilder())
->isFile()
->group_start()
->filenameContains('console')
->or()
->filenameContains('file')
->group_end();
$filtered = FlysystemFilter::filter($listing, $builder);
return $filtered->map(fn($i) => $i->path())->toArray();
});use Illuminate\Support\Facades\Storage;
use League\Flysystem\StorageAttributes;
use FlysystemFilter;
Route::get('/log-files', function () {
$listing = Storage::disk('local')->listContents('', true);
// Callable allows custom filter logic without building a `FilterBuilder`
$callable = static fn(StorageAttributes $item): bool =>
str_ends_with($item->path(), '.log');
$filtered = FlysystemFilter::filter($listing, $callable);
return $filtered->map(fn($i) => $i->path())->toArray();
});FlysystemFilter::filter()is now an instance method (since v3.0.0) — the Facade makes it look static in Laravel, but under the hood it is resolved from the container.- All filtering logic and method signatures remain the same as in standalone usage.
- Non-
StorageAttributesentries in the listing are automatically skipped.
isFile(): Matches file entries.isDirectory(): Matches directory entries.
pathEquals($paths): Matches exact paths. Acceptsstringorarray.pathContains($substrings): Matches paths containing specific substrings.pathNotContains($substrings): Excludes paths containing any given substrings.pathMatchesRegex($pattern): Matches paths using a regular expression.pathStartsWith($prefixes): Matches paths starting with specific prefix(es).pathEndsWith($suffixes): Matches paths ending with specific suffix(es).
filenameEquals($filenames): Matches exact filenames (excluding extensions). Acceptsstringorarray.filenameNotEquals($filenames): Excludes filenames that match exactly.filenameContains($substrings): Matches filenames containing any of the substrings.filenameNotContains($substrings): Excludes filenames containing any of the substrings.filenameStartsWith($prefixes): Matches filenames starting with any of the specified prefix(es).filenameEndsWith($suffixes): Matches filenames ending with any of the specified suffix(es).filenameMatchesRegex($pattern): Matches filenames via regular expression.
basenameEquals($basenames): Matches the full filename (including extension) exactly.basenameNotEquals($basenames): Excludes files with exact matching basenames.basenameContains($substrings): Matches basenames containing any of the substrings.basenameNotContains($substrings): Excludes basenames containing any of the substrings.basenameStartsWith($prefixes): Matches basenames that start with the given prefix(es).basenameEndsWith($suffixes): Matches basenames that end with the given suffix(es).
extensionEquals($extensions): Matches files with one or more exact extensions.extensionNotEquals($extensions): Excludes files with the specified extensions.extensionContains($substrings): Matches files whose extension contains any given substring.extensionNotContains($substrings): Excludes files whose extension contains any given substring.
sizeEquals($size): Matches files with an exact size.sizeGt($size): Matches files larger than a specific size.sizeGte($size): Matches files larger than or equal to a specific size.sizeLt($size): Matches files smaller than a specific size.sizeLte($size): Matches files smaller than or equal to a specific size.sizeBetween($min, $max): Matches files within a size range.
📌 Note: Size units can be specified as B, K, M, G, T (e.g., '512K', '1G').
lastModifiedBefore($timestamp): Matches files modified before a given timestamp orCarboninstance.lastModifiedAfter($timestamp): Matches files modified after a given timestamp orCarboninstance.lastModifiedBetween($start, $end): Matches files modified within a date range.
mimeTypeEquals($mimeTypes): Matches files with exact MIME types.mimeTypeNotEquals($mimeTypes): Excludes files with specific MIME types.mimeTypeContains($substrings): Matches files where the MIME type contains any substring.mimeTypeNotContains($substrings): Excludes files whose MIME type contains specific substrings.
📌 Note: MIME types are detected from file extensions using league/mime-type-detection. No file contents are read.
isPublic(): Matches files with'public'visibility.isPrivate(): Matches files with'private'visibility.visibilityEquals($visibilities): Matches files with exact visibility values.visibilityContains($substrings): Matches files whose visibility string contains given substring(s).
depthEquals($depth): Matches items with an exact directory depth.depthGt($depth): Matches items with a depth greater than the specified value.depthLt($depth): Matches items with a depth less than the specified value.
and(): Combines conditions with logical AND.or(): Combines conditions with logical OR.group_start() / group_end(): Groups conditions for logical precedence (like parentheses).
- PHP 8.2 or higher
- League/Flysystem 3.29 or higher
Run the tests:
composer testFeel free to contribute to the project by submitting issues or pull requests on GitHub.
This project is licensed under the MIT License. See the LICENSE file for details.
Made with ❤️ by Mark Taborosi