From c45a892b478586ad2b92714591a135b1ac970ee7 Mon Sep 17 00:00:00 2001 From: Jasper Smet Date: Tue, 13 Jan 2026 12:11:08 +0100 Subject: [PATCH 1/3] Introduce 5.4 migration guide --- en/appendices/5-4-migration-guide.rst | 36 +++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 en/appendices/5-4-migration-guide.rst diff --git a/en/appendices/5-4-migration-guide.rst b/en/appendices/5-4-migration-guide.rst new file mode 100644 index 0000000000..e64265bd15 --- /dev/null +++ b/en/appendices/5-4-migration-guide.rst @@ -0,0 +1,36 @@ +5.4 Migration Guide +################### + +The 5.4.0 release is a backwards compatible with 5.0. It adds new functionality +and introduces new deprecations. Any functionality deprecated in 5.x will be +removed in 6.0.0. + +Upgrade Tool +============ + +The :doc:`upgrade tool ` provides rector rules for +automating some of the migration work. Run rector before updating your +``composer.json`` dependencies:: + + bin/cake upgrade rector --rules cakephp54 + +Behavior Changes +================ + +- WIP + +Deprecations +============ + +- WIP + +New Features +============ + +Utility +------- + +- New ``Cake\Utility\Fs\Finder`` class provides a fluent, iterator-based API for + discovering files and directories with support for pattern matching, depth + control, and custom filters. The ``Cake\Utility\Fs\Path`` class offers + cross-platform utilities for path manipulation. From 369396a67861b0efe586ad78af83ead6e7f9f356 Mon Sep 17 00:00:00 2001 From: Jasper Smet Date: Tue, 13 Jan 2026 12:15:21 +0100 Subject: [PATCH 2/3] Mention guide in toctree --- en/appendices/5-4-migration-guide.rst | 2 +- en/appendices/migration-guides.rst | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/en/appendices/5-4-migration-guide.rst b/en/appendices/5-4-migration-guide.rst index e64265bd15..1437364290 100644 --- a/en/appendices/5-4-migration-guide.rst +++ b/en/appendices/5-4-migration-guide.rst @@ -1,7 +1,7 @@ 5.4 Migration Guide ################### -The 5.4.0 release is a backwards compatible with 5.0. It adds new functionality +The 5.4.0 release is backwards compatible with 5.0. It adds new functionality and introduces new deprecations. Any functionality deprecated in 5.x will be removed in 6.0.0. diff --git a/en/appendices/migration-guides.rst b/en/appendices/migration-guides.rst index 44e76fd61c..74b88e91c1 100644 --- a/en/appendices/migration-guides.rst +++ b/en/appendices/migration-guides.rst @@ -34,4 +34,5 @@ to ensure the tool can resolve class names correctly. ./5-1-migration-guide ./5-2-migration-guide ./5-3-migration-guide + ./5-4-migration-guide ./phpunit10 From 22e92d5f5597c2520a91cbf14c6e53af1f93e468 Mon Sep 17 00:00:00 2001 From: Jasper Smet Date: Tue, 13 Jan 2026 12:29:37 +0100 Subject: [PATCH 3/3] Add filesystem documentation page --- en/contents.rst | 1 + en/core-libraries/filesystem.rst | 292 +++++++++++++++++++++++++++++++ 2 files changed, 293 insertions(+) create mode 100644 en/core-libraries/filesystem.rst diff --git a/en/contents.rst b/en/contents.rst index 9ccea509b6..08809ecbb7 100644 --- a/en/contents.rst +++ b/en/contents.rst @@ -56,6 +56,7 @@ Contents core-libraries/app core-libraries/collections + core-libraries/filesystem core-libraries/hash core-libraries/httpclient core-libraries/inflector diff --git a/en/core-libraries/filesystem.rst b/en/core-libraries/filesystem.rst new file mode 100644 index 0000000000..34c12cca65 --- /dev/null +++ b/en/core-libraries/filesystem.rst @@ -0,0 +1,292 @@ +Filesystem +########## + +.. php:namespace:: Cake\Utility\Fs + +CakePHP provides filesystem utilities for working with files and directories efficiently. +These utilities are split into two main classes: + +- **Finder** - A fluent, iterator-based API for discovering files and directories +- **Path** - Static utilities for path manipulation + +Finder +====== + +.. php:class:: Finder + +The ``Finder`` class provides a lazy, iterator-based approach to discovering files and directories +with a fluent interface for building complex queries. It's memory-efficient and works consistently +across different operating systems. + +Available Methods +----------------- + +Location & Type +~~~~~~~~~~~~~~~ + +.. php:method:: in(string $directory) + + Add a directory to search in. Can be called multiple times. + +.. php:method:: files() + + Find only files (returns iterator). + +.. php:method:: directories() + + Find only directories (returns iterator). + +.. php:method:: all() + + Find both files and directories (returns iterator). + +.. php:method:: recursive(bool $recursive = true) + + Enable or disable recursive directory traversal. Default is ``true``. + +Filtering by Name +~~~~~~~~~~~~~~~~~ + +.. php:method:: name(string $pattern) + + Include files/directories matching a glob pattern. Multiple calls use OR logic. + +.. php:method:: notName(string $pattern) + + Exclude files/directories matching a glob pattern. Multiple calls use OR logic. + +Filtering by Path +~~~~~~~~~~~~~~~~~ + +.. php:method:: path(string $pattern) + + Include files whose relative path matches a pattern (substring or regex). Multiple calls use OR logic. + +.. php:method:: notPath(string $pattern) + + Exclude files whose relative path matches a pattern (substring or regex). Multiple calls use OR logic. + +.. php:method:: pattern(string $globPattern) + + Include files matching a glob pattern against the full relative path. Supports ``**`` for recursive matching. + +.. php:method:: exclude(string $directory) + + Exclude specific directories from traversal. More efficient than filtering. + +Depth Control +~~~~~~~~~~~~~ + +.. php:method:: depth(int $depth, DepthOperator $operator = DepthOperator::EQUAL) + + Filter by directory depth using operators like EQUAL, LESS_THAN, GREATER_THAN, etc. + +Custom Filtering +~~~~~~~~~~~~~~~~ + +.. php:method:: filter(callable $callback) + + Apply custom filter callback. Receives ``SplFileInfo`` and relative path. Multiple calls use AND logic. + +.. php:method:: ignoreHiddenFiles() + + Exclude hidden files (files starting with ``.``). + +Basic Usage +----------- + +Finding Files and Directories +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Find all PHP files in a directory:: + + use Cake\Utility\Fs\Finder; + + $finder = (new Finder()) + ->in('src') + ->name('*.php') + ->files(); + + foreach ($files as $file) { + echo $file->getPathname(); + } + +Find directories while excluding certain ones:: + + $directories = (new Finder()) + ->in('src') + ->exclude('vendor') + ->exclude('tmp') + ->directories(); + +By default, the Finder searches recursively. Use ``recursive(false)`` for top-level only:: + + $finder = (new Finder()) + ->in('src') + ->recursive(false) + ->files(); + +Filtering Examples +------------------ + +By Filename Pattern +~~~~~~~~~~~~~~~~~~~ + +Include and exclude specific filename patterns:: + + $finder = (new Finder()) + ->in('src') + ->name('*.php') // Include all PHP files + ->notName('*Test.php') // Exclude test files + ->notName('*Fixture.php') // Exclude fixtures + ->files(); + +By Path Pattern +~~~~~~~~~~~~~~~ + +Filter by path containing specific strings or regex patterns:: + + $finder = (new Finder()) + ->in('src') + ->path('Controller') // Include paths containing "Controller" + ->notPath('Test') // Exclude paths containing "Test" + ->path('/Controller\.php$/') // Or use regex patterns + ->files(); + +By Depth +~~~~~~~~ + +Control traversal depth using type-safe operators:: + + use Cake\Utility\Fs\Enum\DepthOperator; + + // Maximum depth of 3 + $finder = (new Finder()) + ->in('src') + ->depth(3, DepthOperator::LESS_THAN) + ->files(); + + // Depth range (1, 2, or 3) + $finder = (new Finder()) + ->in('src') + ->depth(0, DepthOperator::GREATER_THAN) + ->depth(4, DepthOperator::LESS_THAN) + ->files(); + +Available depth operators: ``EQUAL``, ``NOT_EQUAL``, ``LESS_THAN``, ``GREATER_THAN``, +``LESS_THAN_OR_EQUAL``, ``GREATER_THAN_OR_EQUAL``. + +Using Glob Patterns +~~~~~~~~~~~~~~~~~~~ + +Use glob patterns with ``**`` for recursive matching:: + + $finder = (new Finder()) + ->in('.') + ->pattern('src/**/*Controller.php') + ->pattern('tests/**/*Test.php') + ->files(); + +Glob syntax: ``*`` matches any characters except ``/``, ``**`` matches including ``/``, +``?`` matches single character, ``[abc]`` matches any character in set. + +Custom Filters +~~~~~~~~~~~~~~ + +For complex filtering, use custom callbacks:: + + use SplFileInfo; + + $finder = (new Finder()) + ->in('src') + ->filter(fn(SplFileInfo $file) => $file->getSize() > 1024) + ->filter(fn(SplFileInfo $file) => $file->getMTime() > strtotime('-1 week')) + ->files(); + +The callback receives ``SplFileInfo`` and the relative path:: + + $finder = (new Finder()) + ->in('.') + ->filter(function (SplFileInfo $file, string $relativePath) { + return str_starts_with($relativePath, 'src/Controller') + || str_starts_with($relativePath, 'src/Model'); + }) + ->files(); + +Complete Example +---------------- + +Combining multiple filters:: + + use Cake\Utility\Fs\Finder; + use Cake\Utility\Fs\Enum\DepthOperator; + + $finder = (new Finder()) + ->in('src') + ->in('plugins') + ->name('*.php') + ->notName('*Test.php') + ->exclude('vendor') + ->exclude('tmp') + ->path('Controller') + ->depth(5, DepthOperator::LESS_THAN) + ->ignoreHiddenFiles() + ->files(); + + foreach ($finder as $file) { + echo $file->getRealPath() . PHP_EOL; + } + +Path +==== + +.. php:class:: Path + +The ``Path`` class provides static utilities for path manipulation. + +Available Methods +----------------- + +.. php:staticmethod:: normalize(string $path) + + Convert paths to use forward slashes. + +.. php:staticmethod:: makeRelative(string $path, string $base) + + Convert an absolute path to a relative path based on a base directory. + +.. php:staticmethod:: join(string ...$segments) + + Join multiple path segments into a single path. + +.. php:staticmethod:: matches(string $pattern, string $path) + + Test if a path matches a glob pattern. Supports ``*``, ``**``, ``?``, and ``[abc]`` syntax. + +Examples +-------- + +:: + + use Cake\Utility\Fs\Path; + + // Normalize path separators + Path::normalize('path\\to\\file.php'); + // Returns: 'path/to/file.php' + + // Make relative paths + Path::makeRelative('/var/www/app/src/Controller/UsersController.php', '/var/www/app'); + // Returns: 'src/Controller/UsersController.php' + + // Join path segments + Path::join('src', 'Controller', 'UsersController.php'); + // Returns: 'src/Controller/UsersController.php' + + // Match glob patterns + Path::matches('*.php', 'test.php'); // true + Path::matches('src/**/*.php', 'src/Controller/UsersController.php'); // true + Path::matches('src/**/Test/*.php', 'src/Controller/UsersController.php'); // false + +.. meta:: + :title lang=en: Filesystem + :keywords lang=en: finder,filesystem,files,directories,glob,path,iterator,fluent interface,cross-platform