From dd00df14de55e4c054fe8a95e7841502c49964ae Mon Sep 17 00:00:00 2001 From: kenjis Date: Sun, 8 Oct 2023 15:11:28 +0900 Subject: [PATCH 01/18] feat: add FileLocatorCached class --- system/Autoloader/FileLocatorCached.php | 180 ++++++++++++++++++++++++ 1 file changed, 180 insertions(+) create mode 100644 system/Autoloader/FileLocatorCached.php diff --git a/system/Autoloader/FileLocatorCached.php b/system/Autoloader/FileLocatorCached.php new file mode 100644 index 000000000000..55f0b7bc4b51 --- /dev/null +++ b/system/Autoloader/FileLocatorCached.php @@ -0,0 +1,180 @@ + + * + * For the full copyright and license information, please view + * the LICENSE file that was distributed with this source code. + */ + +namespace CodeIgniter\Autoloader; + +use CodeIgniter\Cache\CacheInterface; +use CodeIgniter\Cache\FactoriesCache\FileVarExportHandler; + +/** + * FileLocator with Cache + * + * There is no FileLocator interface, so this extends FileLocator. + */ +final class FileLocatorCached extends FileLocator +{ + private FileLocator $locator; + + /** + * @var CacheInterface|FileVarExportHandler + */ + private $cacheHandler; + + /** + * Cache data + * + * [method => data] + * E.g., + * [ + * 'search' => [$path => $foundPaths], + * ] + */ + private array $cache = []; + + /** + * Is the cache updated? + */ + private bool $cacheUpdated = false; + + private string $cacheKey = 'FileLocatorCache'; + + /** + * @param CacheInterface|FileVarExportHandler|null $cache + */ + public function __construct(FileLocator $locator, $cache = null) + { + // Do not call parent constructor. + + $this->cacheHandler = $cache ?? new FileVarExportHandler(); + $this->locator = $locator; + + $this->loadCache(); + } + + private function loadCache(): void + { + $data = $this->cacheHandler->get($this->cacheKey); + + if (is_array($data)) { + $this->cache = $data; + } + } + + public function __destruct() + { + $this->saveCache(); + } + + private function saveCache(): void + { + if ($this->cacheUpdated) { + $this->cacheHandler->save($this->cacheKey, $this->cache, 3600 * 24); + } + } + + protected function getNamespaces() + { + if (isset($this->cache['getNamespaces'])) { + return $this->cache['getNamespaces']; + } + + $namespaces = $this->locator->getNamespaces(); + + $this->cache['getNamespaces'] = $namespaces; + $this->cacheUpdated = true; + + return $namespaces; + } + + public function findQualifiedNameFromPath(string $path): false|string + { + if (isset($this->cache['findQualifiedNameFromPath'][$path])) { + return $this->cache['findQualifiedNameFromPath'][$path]; + } + + $classname = $this->locator->findQualifiedNameFromPath($path); + + $this->cache['findQualifiedNameFromPath'][$path] = $classname; + $this->cacheUpdated = true; + + return $classname; + } + + public function getClassname(string $file): string + { + if (isset($this->cache['getClassname'][$file])) { + return $this->cache['getClassname'][$file]; + } + + $classname = $this->locator->getClassname($file); + + $this->cache['getClassname'][$file] = $classname; + $this->cacheUpdated = true; + + return $classname; + } + + public function search(string $path, string $ext = 'php', bool $prioritizeApp = true): array + { + if (isset($this->cache['search'][$path][$ext][$prioritizeApp])) { + return $this->cache['search'][$path][$ext][$prioritizeApp]; + } + + $foundPaths = $this->locator->search($path, $ext, $prioritizeApp); + + $this->cache['search'][$path][$ext][$prioritizeApp] = $foundPaths; + $this->cacheUpdated = true; + + return $foundPaths; + } + + public function listFiles(string $path): array + { + if (isset($this->cache['listFiles'][$path])) { + return $this->cache['listFiles'][$path]; + } + + $files = $this->locator->listFiles($path); + + $this->cache['listFiles'][$path] = $files; + $this->cacheUpdated = true; + + return $files; + } + + public function listNamespaceFiles(string $prefix, string $path): array + { + if (isset($this->cache['listNamespaceFiles'][$prefix][$path])) { + return $this->cache['listNamespaceFiles'][$prefix][$path]; + } + + $files = $this->locator->listNamespaceFiles($prefix, $path); + + $this->cache['listNamespaceFiles'][$prefix][$path] = $files; + $this->cacheUpdated = true; + + return $files; + } + + public function locateFile(string $file, ?string $folder = null, string $ext = 'php') + { + if (isset($this->cache['locateFile'][$file][$folder][$ext])) { + return $this->cache['locateFile'][$file][$folder][$ext]; + } + + $files = $this->locator->locateFile($file, $folder, $ext); + + $this->cache['locateFile'][$file][$folder][$ext] = $files; + $this->cacheUpdated = true; + + return $files; + } +} From 236d8e4537ce2194c6ba9ed59fd2e27a68f1d295 Mon Sep 17 00:00:00 2001 From: kenjis Date: Sun, 8 Oct 2023 16:23:18 +0900 Subject: [PATCH 02/18] docs: add docs --- user_guide_src/source/concepts/autoloader.rst | 47 +++++++++++++++++++ .../source/concepts/autoloader/004.php | 25 ++++++++++ 2 files changed, 72 insertions(+) create mode 100644 user_guide_src/source/concepts/autoloader/004.php diff --git a/user_guide_src/source/concepts/autoloader.rst b/user_guide_src/source/concepts/autoloader.rst index cc47162e5c0c..4136ecaac271 100644 --- a/user_guide_src/source/concepts/autoloader.rst +++ b/user_guide_src/source/concepts/autoloader.rst @@ -140,3 +140,50 @@ autoloader will be the first one to get a chance to locate the file. .. note:: Prior to v4.5.0, if the same namespace was defined in both CodeIgniter and Composer, CodeIgniter's autoloader was the first one to get a chance to locate the file. + +.. _file-locator-caching: + +FileLocator Caching +******************* + +.. versionadded:: 4.5.0 + +**FileLocator** is responsible for finding files or getting a classname from a file, +which cannot be achieved with PHP autoloading. + +To improve its performance, FileLocator Caching has been implemented. + +How It Works +============ + +- Save the all found data by FileLocator into a cache file when destructing, + if the cache data is updated. +- Restore cached data when instantiating if cached data is available. + +The cached data are used permanently. + +How to Delete Cached Data +========================= + +Once stored, the cached data never expire. + +So if you add or remove files or change existing file paths, or namespaces, old +cached data will be returned and your app may not work properly. + +In that case, you must manually delete the cache file. If you add a CodeIgniter +package via Composer, you also need to delete the cache file. + +You can use the ``spark cache:clear`` command: + +.. code-block:: console + + php spark cache:clear + +Or simply delete the **writable/cache/FileLocatorCache** file. + +How to Enable FileLocator Caching +================================= + +Add the following code in **app/Config/Services.php**: + +.. literalinclude:: autoloader/004.php diff --git a/user_guide_src/source/concepts/autoloader/004.php b/user_guide_src/source/concepts/autoloader/004.php new file mode 100644 index 000000000000..090149e6486c --- /dev/null +++ b/user_guide_src/source/concepts/autoloader/004.php @@ -0,0 +1,25 @@ + Date: Sun, 8 Oct 2023 16:23:31 +0900 Subject: [PATCH 03/18] docs: add changelog --- user_guide_src/source/changelogs/v4.5.0.rst | 8 +++++--- user_guide_src/source/concepts/autoloader.rst | 1 + 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/user_guide_src/source/changelogs/v4.5.0.rst b/user_guide_src/source/changelogs/v4.5.0.rst index 89910fa84f3d..669fe74a856c 100644 --- a/user_guide_src/source/changelogs/v4.5.0.rst +++ b/user_guide_src/source/changelogs/v4.5.0.rst @@ -123,9 +123,11 @@ Helpers and Functions Others ====== -- **Autoloader:** Autoloading performance when using Composer has been improved. - Adding the ``App`` namespace in the ``autoload.psr4`` setting in **composer.json** - may also improve the performance of your app. See :ref:`autoloader-application-namespace`. +- **Autoloader:** + - Autoloading performance when using Composer has been improved. + Adding the ``App`` namespace in the ``autoload.psr4`` setting in **composer.json** + may also improve the performance of your app. See :ref:`autoloader-application-namespace`. + - FileLocator Caching implemented. See :ref:`file-locator-caching` for details. - **CodeIgniter:** Added a pseudo-variable ``{memory_usage}`` to show your memory usage in your view files, which was supported by CodeIgniter 3. diff --git a/user_guide_src/source/concepts/autoloader.rst b/user_guide_src/source/concepts/autoloader.rst index 4136ecaac271..62aa0f157cf3 100644 --- a/user_guide_src/source/concepts/autoloader.rst +++ b/user_guide_src/source/concepts/autoloader.rst @@ -143,6 +143,7 @@ autoloader will be the first one to get a chance to locate the file. .. _file-locator-caching: +******************* FileLocator Caching ******************* From 0cde9174ed9dd892605abe6b02a06ca847c281a4 Mon Sep 17 00:00:00 2001 From: kenjis Date: Sun, 8 Oct 2023 16:47:40 +0900 Subject: [PATCH 04/18] test: add FileLocatorCachedTest --- .../Autoloader/FileLocatorCachedTest.php | 55 +++++++++++++++++++ tests/system/Autoloader/FileLocatorTest.php | 5 +- 2 files changed, 58 insertions(+), 2 deletions(-) create mode 100644 tests/system/Autoloader/FileLocatorCachedTest.php diff --git a/tests/system/Autoloader/FileLocatorCachedTest.php b/tests/system/Autoloader/FileLocatorCachedTest.php new file mode 100644 index 000000000000..4f8a8b2e2b23 --- /dev/null +++ b/tests/system/Autoloader/FileLocatorCachedTest.php @@ -0,0 +1,55 @@ + + * + * For the full copyright and license information, please view + * the LICENSE file that was distributed with this source code. + */ + +namespace CodeIgniter\Autoloader; + +use CodeIgniter\Cache\FactoriesCache\FileVarExportHandler; +use Config\Autoload; +use Config\Modules; + +/** + * @internal + * + * @group Others + */ +final class FileLocatorCachedTest extends FileLocatorTest +{ + private FileVarExportHandler $handler; + protected FileLocator $locator; + + protected function setUp(): void + { + parent::setUp(); + + $autoloader = new Autoloader(); + $autoloader->initialize(new Autoload(), new Modules()); + $autoloader->addNamespace([ + 'Unknown' => '/i/do/not/exist', + 'Tests/Support' => TESTPATH . '_support/', + 'App' => APPPATH, + 'CodeIgniter' => [ + TESTPATH, + SYSTEMPATH, + ], + 'Errors' => APPPATH . 'Views/errors', + 'System' => SUPPORTPATH . 'Autoloader/system', + 'CodeIgniter\\Devkit' => [ + TESTPATH . '_support/', + ], + 'Acme\SampleProject' => TESTPATH . '_support', + 'Acme\Sample' => TESTPATH . '_support/does/not/exists', + ]); + + $this->handler = new FileVarExportHandler(); + $fileLocator = new FileLocator($autoloader); + $this->locator = new FileLocatorCached($fileLocator, $this->handler); + } +} diff --git a/tests/system/Autoloader/FileLocatorTest.php b/tests/system/Autoloader/FileLocatorTest.php index 0d084280f520..b4ff6d1c9910 100644 --- a/tests/system/Autoloader/FileLocatorTest.php +++ b/tests/system/Autoloader/FileLocatorTest.php @@ -20,10 +20,11 @@ * @internal * * @group Others + * @no-final */ -final class FileLocatorTest extends CIUnitTestCase +class FileLocatorTest extends CIUnitTestCase { - private FileLocator $locator; + protected FileLocator $locator; protected function setUp(): void { From 63220ceaab0838876c198f307741245d1bd24eff Mon Sep 17 00:00:00 2001 From: kenjis Date: Sun, 8 Oct 2023 16:54:21 +0900 Subject: [PATCH 05/18] feat: add FileLocatorCached::deleteCache() --- system/Autoloader/FileLocatorCached.php | 10 +++++++ .../Autoloader/FileLocatorCachedTest.php | 28 +++++++++++++++++++ 2 files changed, 38 insertions(+) diff --git a/system/Autoloader/FileLocatorCached.php b/system/Autoloader/FileLocatorCached.php index 55f0b7bc4b51..e89e7f7364ca 100644 --- a/system/Autoloader/FileLocatorCached.php +++ b/system/Autoloader/FileLocatorCached.php @@ -18,6 +18,8 @@ * FileLocator with Cache * * There is no FileLocator interface, so this extends FileLocator. + * + * @see \CodeIgniter\Autoloader\FileLocatorCachedTest */ final class FileLocatorCached extends FileLocator { @@ -80,6 +82,14 @@ private function saveCache(): void } } + /** + * Delete cache data + */ + public function deleteCache(): void + { + $this->cacheHandler->delete($this->cacheKey); + } + protected function getNamespaces() { if (isset($this->cache['getNamespaces'])) { diff --git a/tests/system/Autoloader/FileLocatorCachedTest.php b/tests/system/Autoloader/FileLocatorCachedTest.php index 4f8a8b2e2b23..2a5a185d6b6e 100644 --- a/tests/system/Autoloader/FileLocatorCachedTest.php +++ b/tests/system/Autoloader/FileLocatorCachedTest.php @@ -25,6 +25,18 @@ final class FileLocatorCachedTest extends FileLocatorTest private FileVarExportHandler $handler; protected FileLocator $locator; + public static function tearDownAfterClass(): void + { + parent::tearDownAfterClass(); + + // Delete cache file. + $autoloader = new Autoloader(); + $handler = new FileVarExportHandler(); + $fileLocator = new FileLocator($autoloader); + $locator = new FileLocatorCached($fileLocator, $handler); + $locator->deleteCache(); + } + protected function setUp(): void { parent::setUp(); @@ -52,4 +64,20 @@ protected function setUp(): void $fileLocator = new FileLocator($autoloader); $this->locator = new FileLocatorCached($fileLocator, $this->handler); } + + protected function tearDown(): void + { + $this->locator->__destruct(); + + parent::tearDown(); + } + + public function testDeleteCache() + { + $this->assertNotSame([], $this->handler->get('FileLocatorCache')); + + $this->locator->deleteCache(); + + $this->assertFalse($this->handler->get('FileLocatorCache')); + } } From 6b3cdabb5005914a7a17bf82e39e644cb0bf01bc Mon Sep 17 00:00:00 2001 From: kenjis Date: Sun, 8 Oct 2023 17:32:15 +0900 Subject: [PATCH 06/18] refactor: remove unused method The protected method is never called by caller. --- system/Autoloader/FileLocatorCached.php | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/system/Autoloader/FileLocatorCached.php b/system/Autoloader/FileLocatorCached.php index e89e7f7364ca..76423e89f768 100644 --- a/system/Autoloader/FileLocatorCached.php +++ b/system/Autoloader/FileLocatorCached.php @@ -90,20 +90,6 @@ public function deleteCache(): void $this->cacheHandler->delete($this->cacheKey); } - protected function getNamespaces() - { - if (isset($this->cache['getNamespaces'])) { - return $this->cache['getNamespaces']; - } - - $namespaces = $this->locator->getNamespaces(); - - $this->cache['getNamespaces'] = $namespaces; - $this->cacheUpdated = true; - - return $namespaces; - } - public function findQualifiedNameFromPath(string $path): false|string { if (isset($this->cache['findQualifiedNameFromPath'][$path])) { From 0ed38320ebf1910824791b89cb54c48f3ba77c8c Mon Sep 17 00:00:00 2001 From: kenjis Date: Fri, 13 Oct 2023 10:24:20 +0900 Subject: [PATCH 07/18] feat: add FileLocatorInterface --- system/Autoloader/FileLocatorInterface.php | 80 ++++++++++++++++++++++ 1 file changed, 80 insertions(+) create mode 100644 system/Autoloader/FileLocatorInterface.php diff --git a/system/Autoloader/FileLocatorInterface.php b/system/Autoloader/FileLocatorInterface.php new file mode 100644 index 000000000000..8f7b551bb02f --- /dev/null +++ b/system/Autoloader/FileLocatorInterface.php @@ -0,0 +1,80 @@ + + * + * For the full copyright and license information, please view + * the LICENSE file that was distributed with this source code. + */ + +namespace CodeIgniter\Autoloader; + +/** + * Allows loading non-class files in a namespaced manner. + * Works with Helpers, Views, etc. + */ +interface FileLocatorInterface +{ + /** + * Attempts to locate a file by examining the name for a namespace + * and looking through the PSR-4 namespaced files that we know about. + * + * @param string $file The relative file path or namespaced file to + * locate. If not namespaced, search in the app + * folder. + * @param string|null $folder The folder within the namespace that we should + * look for the file. If $file does not contain + * this value, it will be appended to the namespace + * folder. + * @param string $ext The file extension the file should have. + * + * @return false|string The path to the file, or false if not found. + */ + public function locateFile(string $file, ?string $folder = null, string $ext = 'php'); + + /** + * Examines a file and returns the fully qualified class name. + */ + public function getClassname(string $file): string; + + /** + * Searches through all of the defined namespaces looking for a file. + * Returns an array of all found locations for the defined file. + * + * Example: + * + * $locator->search('Config/Routes.php'); + * // Assuming PSR4 namespaces include foo and bar, might return: + * [ + * 'app/Modules/foo/Config/Routes.php', + * 'app/Modules/bar/Config/Routes.php', + * ] + */ + public function search(string $path, string $ext = 'php', bool $prioritizeApp = true): array; + + /** + * Find the qualified name of a file according to + * the namespace of the first matched namespace path. + * + * @return false|string The qualified name or false if the path is not found + */ + public function findQualifiedNameFromPath(string $path); + + /** + * Scans the defined namespaces, returning a list of all files + * that are contained within the subpath specified by $path. + * + * @return string[] List of file paths + */ + public function listFiles(string $path): array; + + /** + * Scans the provided namespace, returning a list of all files + * that are contained within the sub path specified by $path. + * + * @return string[] List of file paths + */ + public function listNamespaceFiles(string $prefix, string $path): array; +} From a645716b8b4a2f03bb342f477ac0ff426821ee65 Mon Sep 17 00:00:00 2001 From: kenjis Date: Fri, 13 Oct 2023 10:25:08 +0900 Subject: [PATCH 08/18] refactor: use FileLocatorInterface --- system/Autoloader/FileLocator.php | 2 +- system/Autoloader/FileLocatorCached.php | 2 +- system/Config/BaseService.php | 3 ++- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/system/Autoloader/FileLocator.php b/system/Autoloader/FileLocator.php index 6f241e847be3..8a6640d986d0 100644 --- a/system/Autoloader/FileLocator.php +++ b/system/Autoloader/FileLocator.php @@ -17,7 +17,7 @@ * * @see \CodeIgniter\Autoloader\FileLocatorTest */ -class FileLocator +class FileLocator implements FileLocatorInterface { /** * The Autoloader to use. diff --git a/system/Autoloader/FileLocatorCached.php b/system/Autoloader/FileLocatorCached.php index 76423e89f768..e801b2504b89 100644 --- a/system/Autoloader/FileLocatorCached.php +++ b/system/Autoloader/FileLocatorCached.php @@ -21,7 +21,7 @@ * * @see \CodeIgniter\Autoloader\FileLocatorCachedTest */ -final class FileLocatorCached extends FileLocator +final class FileLocatorCached implements FileLocatorInterface { private FileLocator $locator; diff --git a/system/Config/BaseService.php b/system/Config/BaseService.php index b66b8c9f535e..0a5df0ffec4c 100644 --- a/system/Config/BaseService.php +++ b/system/Config/BaseService.php @@ -13,6 +13,7 @@ use CodeIgniter\Autoloader\Autoloader; use CodeIgniter\Autoloader\FileLocator; +use CodeIgniter\Autoloader\FileLocatorInterface; use CodeIgniter\Cache\CacheInterface; use CodeIgniter\Cache\ResponseCache; use CodeIgniter\CLI\Commands; @@ -226,7 +227,7 @@ public static function autoloader(bool $getShared = true) * within namespaced folders, as well as convenience methods for * loading 'helpers', and 'libraries'. * - * @return FileLocator + * @return FileLocatorInterface */ public static function locator(bool $getShared = true) { From 28bf53383cf0de31dc9390a047e6aeb2f36f8a67 Mon Sep 17 00:00:00 2001 From: kenjis Date: Fri, 13 Oct 2023 10:27:45 +0900 Subject: [PATCH 09/18] docs: remove outdated comment --- system/Autoloader/FileLocatorCached.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/system/Autoloader/FileLocatorCached.php b/system/Autoloader/FileLocatorCached.php index e801b2504b89..bd92ca02d5a1 100644 --- a/system/Autoloader/FileLocatorCached.php +++ b/system/Autoloader/FileLocatorCached.php @@ -53,8 +53,6 @@ final class FileLocatorCached implements FileLocatorInterface */ public function __construct(FileLocator $locator, $cache = null) { - // Do not call parent constructor. - $this->cacheHandler = $cache ?? new FileVarExportHandler(); $this->locator = $locator; From baa1ae8e6f842577ff8236bd33b32f6b49cb7762 Mon Sep 17 00:00:00 2001 From: kenjis Date: Fri, 13 Oct 2023 10:28:02 +0900 Subject: [PATCH 10/18] refactor: add missing return types --- system/Autoloader/FileLocatorCached.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/system/Autoloader/FileLocatorCached.php b/system/Autoloader/FileLocatorCached.php index bd92ca02d5a1..4bc474fcd497 100644 --- a/system/Autoloader/FileLocatorCached.php +++ b/system/Autoloader/FileLocatorCached.php @@ -158,7 +158,7 @@ public function listNamespaceFiles(string $prefix, string $path): array return $files; } - public function locateFile(string $file, ?string $folder = null, string $ext = 'php') + public function locateFile(string $file, ?string $folder = null, string $ext = 'php'): false|string { if (isset($this->cache['locateFile'][$file][$folder][$ext])) { return $this->cache['locateFile'][$file][$folder][$ext]; From effe87235c9d8f6ea1c5e7f712811487b8754c59 Mon Sep 17 00:00:00 2001 From: kenjis Date: Fri, 13 Oct 2023 10:32:13 +0900 Subject: [PATCH 11/18] refactor!: change FileLocator to FileLocatorInterface --- system/Commands/Utilities/Routes/ControllerFinder.php | 4 ++-- system/Router/RouteCollection.php | 6 +++--- system/View/Parser.php | 4 ++-- system/View/View.php | 5 +++-- 4 files changed, 10 insertions(+), 9 deletions(-) diff --git a/system/Commands/Utilities/Routes/ControllerFinder.php b/system/Commands/Utilities/Routes/ControllerFinder.php index f801d531fa92..1528996968f1 100644 --- a/system/Commands/Utilities/Routes/ControllerFinder.php +++ b/system/Commands/Utilities/Routes/ControllerFinder.php @@ -11,7 +11,7 @@ namespace CodeIgniter\Commands\Utilities\Routes; -use CodeIgniter\Autoloader\FileLocator; +use CodeIgniter\Autoloader\FileLocatorInterface; use CodeIgniter\Config\Services; /** @@ -26,7 +26,7 @@ final class ControllerFinder */ private string $namespace; - private FileLocator $locator; + private FileLocatorInterface $locator; /** * @param string $namespace namespace to search diff --git a/system/Router/RouteCollection.php b/system/Router/RouteCollection.php index ca080152ff28..d38faa41278d 100644 --- a/system/Router/RouteCollection.php +++ b/system/Router/RouteCollection.php @@ -12,7 +12,7 @@ namespace CodeIgniter\Router; use Closure; -use CodeIgniter\Autoloader\FileLocator; +use CodeIgniter\Autoloader\FileLocatorInterface; use CodeIgniter\Router\Exceptions\RouterException; use Config\App; use Config\Modules; @@ -245,7 +245,7 @@ class RouteCollection implements RouteCollectionInterface /** * Handle to the file locator to use. * - * @var FileLocator + * @var FileLocatorInterface */ protected $fileLocator; @@ -283,7 +283,7 @@ class RouteCollection implements RouteCollectionInterface /** * Constructor */ - public function __construct(FileLocator $locator, Modules $moduleConfig, Routing $routing) + public function __construct(FileLocatorInterface $locator, Modules $moduleConfig, Routing $routing) { $this->fileLocator = $locator; $this->moduleConfig = $moduleConfig; diff --git a/system/View/Parser.php b/system/View/Parser.php index 120570079d2b..462058e42a9d 100644 --- a/system/View/Parser.php +++ b/system/View/Parser.php @@ -11,7 +11,7 @@ namespace CodeIgniter\View; -use CodeIgniter\Autoloader\FileLocator; +use CodeIgniter\Autoloader\FileLocatorInterface; use CodeIgniter\View\Exceptions\ViewException; use Config\View as ViewConfig; use ParseError; @@ -79,7 +79,7 @@ class Parser extends View /** * Constructor * - * @param FileLocator|null $loader + * @param FileLocatorInterface|null $loader */ public function __construct(ViewConfig $config, ?string $viewPath = null, $loader = null, ?bool $debug = null, ?LoggerInterface $logger = null) { diff --git a/system/View/View.php b/system/View/View.php index e8fdf5f18f7e..15ff3082be91 100644 --- a/system/View/View.php +++ b/system/View/View.php @@ -12,6 +12,7 @@ namespace CodeIgniter\View; use CodeIgniter\Autoloader\FileLocator; +use CodeIgniter\Autoloader\FileLocatorInterface; use CodeIgniter\Debug\Toolbar\Collectors\Views; use CodeIgniter\Filters\DebugToolbar; use CodeIgniter\View\Exceptions\ViewException; @@ -63,7 +64,7 @@ class View implements RendererInterface * we need to attempt to find a view * that's not in standard place. * - * @var FileLocator + * @var FileLocatorInterface */ protected $loader; @@ -141,7 +142,7 @@ class View implements RendererInterface */ protected $sectionStack = []; - public function __construct(ViewConfig $config, ?string $viewPath = null, ?FileLocator $loader = null, ?bool $debug = null, ?LoggerInterface $logger = null) + public function __construct(ViewConfig $config, ?string $viewPath = null, ?FileLocatorInterface $loader = null, ?bool $debug = null, ?LoggerInterface $logger = null) { $this->config = $config; $this->viewPath = rtrim($viewPath, '\\/ ') . DIRECTORY_SEPARATOR; From fe2cc3f007d533c90200fc409e78d3789d16baea Mon Sep 17 00:00:00 2001 From: kenjis Date: Fri, 13 Oct 2023 10:39:53 +0900 Subject: [PATCH 12/18] style: break long line --- system/View/View.php | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/system/View/View.php b/system/View/View.php index 15ff3082be91..da23b67d912a 100644 --- a/system/View/View.php +++ b/system/View/View.php @@ -142,8 +142,13 @@ class View implements RendererInterface */ protected $sectionStack = []; - public function __construct(ViewConfig $config, ?string $viewPath = null, ?FileLocatorInterface $loader = null, ?bool $debug = null, ?LoggerInterface $logger = null) - { + public function __construct( + ViewConfig $config, + ?string $viewPath = null, + ?FileLocatorInterface $loader = null, + ?bool $debug = null, + ?LoggerInterface $logger = null + ) { $this->config = $config; $this->viewPath = rtrim($viewPath, '\\/ ') . DIRECTORY_SEPARATOR; $this->loader = $loader ?? Services::locator(); From 0cdc5afd2f7777a77f86194438f166c53162b899 Mon Sep 17 00:00:00 2001 From: kenjis Date: Fri, 13 Oct 2023 10:50:43 +0900 Subject: [PATCH 13/18] docs: add changelog --- user_guide_src/source/changelogs/v4.5.0.rst | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/user_guide_src/source/changelogs/v4.5.0.rst b/user_guide_src/source/changelogs/v4.5.0.rst index 669fe74a856c..f7728e7cf9e1 100644 --- a/user_guide_src/source/changelogs/v4.5.0.rst +++ b/user_guide_src/source/changelogs/v4.5.0.rst @@ -51,6 +51,14 @@ Interface Changes Method Signature Changes ======================== +FileLocatorInterface +-------------------- + +- **Router:** The first parameter of the ``RouteCollection`` constructor has been changed + from ``FileLocator`` to ``FileLocatorInterface``. +- **View:** The third parameter of the ``View`` constructor has been changed + from ``FileLocator`` to ``FileLocatorInterface``. + Return Type Changes ------------------- @@ -128,6 +136,7 @@ Others Adding the ``App`` namespace in the ``autoload.psr4`` setting in **composer.json** may also improve the performance of your app. See :ref:`autoloader-application-namespace`. - FileLocator Caching implemented. See :ref:`file-locator-caching` for details. + - ``FileLocatorInterface`` has been added. - **CodeIgniter:** Added a pseudo-variable ``{memory_usage}`` to show your memory usage in your view files, which was supported by CodeIgniter 3. From d0d1c012359a10fb4e8b461fea124f387acf8e21 Mon Sep 17 00:00:00 2001 From: kenjis Date: Fri, 13 Oct 2023 10:58:11 +0900 Subject: [PATCH 14/18] docs: remove outdated comment --- system/Autoloader/FileLocatorCached.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/system/Autoloader/FileLocatorCached.php b/system/Autoloader/FileLocatorCached.php index 4bc474fcd497..8bc8d1e85ee9 100644 --- a/system/Autoloader/FileLocatorCached.php +++ b/system/Autoloader/FileLocatorCached.php @@ -17,8 +17,6 @@ /** * FileLocator with Cache * - * There is no FileLocator interface, so this extends FileLocator. - * * @see \CodeIgniter\Autoloader\FileLocatorCachedTest */ final class FileLocatorCached implements FileLocatorInterface From ca0082f8ff85b5ed4a6669b18dd645a08956f513 Mon Sep 17 00:00:00 2001 From: kenjis Date: Fri, 13 Oct 2023 11:00:05 +0900 Subject: [PATCH 15/18] refactor: use FileLocatorInterface --- system/CLI/Commands.php | 4 ++-- system/Publisher/Publisher.php | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/system/CLI/Commands.php b/system/CLI/Commands.php index df28e533a354..bc4d1befc6fb 100644 --- a/system/CLI/Commands.php +++ b/system/CLI/Commands.php @@ -11,7 +11,7 @@ namespace CodeIgniter\CLI; -use CodeIgniter\Autoloader\FileLocator; +use CodeIgniter\Autoloader\FileLocatorInterface; use CodeIgniter\Log\Logger; use ReflectionClass; use ReflectionException; @@ -87,7 +87,7 @@ public function discoverCommands() return; } - /** @var FileLocator $locator */ + /** @var FileLocatorInterface $locator */ $locator = service('locator'); $files = $locator->listFiles('Commands/'); diff --git a/system/Publisher/Publisher.php b/system/Publisher/Publisher.php index e40a14c88905..ca9b4eb09a79 100644 --- a/system/Publisher/Publisher.php +++ b/system/Publisher/Publisher.php @@ -11,7 +11,7 @@ namespace CodeIgniter\Publisher; -use CodeIgniter\Autoloader\FileLocator; +use CodeIgniter\Autoloader\FileLocatorInterface; use CodeIgniter\Files\FileCollection; use CodeIgniter\HTTP\URI; use CodeIgniter\Publisher\Exceptions\PublisherException; @@ -105,7 +105,7 @@ final public static function discover(string $directory = 'Publishers'): array self::$discovered[$directory] = []; - /** @var FileLocator $locator */ + /** @var FileLocatorInterface $locator */ $locator = service('locator'); if ([] === $files = $locator->listFiles($directory)) { From c04e905d4389e0e7b91cae2082e2bd4d8ae78d30 Mon Sep 17 00:00:00 2001 From: kenjis Date: Fri, 13 Oct 2023 11:00:57 +0900 Subject: [PATCH 16/18] refactor: remove unused `use CodeIgniter\Autoloader\FileLocator;` --- system/View/View.php | 1 - 1 file changed, 1 deletion(-) diff --git a/system/View/View.php b/system/View/View.php index da23b67d912a..ffb734779de1 100644 --- a/system/View/View.php +++ b/system/View/View.php @@ -11,7 +11,6 @@ namespace CodeIgniter\View; -use CodeIgniter\Autoloader\FileLocator; use CodeIgniter\Autoloader\FileLocatorInterface; use CodeIgniter\Debug\Toolbar\Collectors\Views; use CodeIgniter\Filters\DebugToolbar; From f0f9f31bf81f2471e32e2e8ddad6d74b2a84ab44 Mon Sep 17 00:00:00 2001 From: kenjis Date: Fri, 13 Oct 2023 11:03:51 +0900 Subject: [PATCH 17/18] style: break long line --- system/View/Parser.php | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/system/View/Parser.php b/system/View/Parser.php index 462058e42a9d..a948579e8f8f 100644 --- a/system/View/Parser.php +++ b/system/View/Parser.php @@ -81,8 +81,13 @@ class Parser extends View * * @param FileLocatorInterface|null $loader */ - public function __construct(ViewConfig $config, ?string $viewPath = null, $loader = null, ?bool $debug = null, ?LoggerInterface $logger = null) - { + public function __construct( + ViewConfig $config, + ?string $viewPath = null, + $loader = null, + ?bool $debug = null, + ?LoggerInterface $logger = null + ) { // Ensure user plugins override core plugins. $this->plugins = $config->plugins; From dc87b0de60f8d42b2b310396aea94c7377149d24 Mon Sep 17 00:00:00 2001 From: kenjis Date: Fri, 13 Oct 2023 11:31:31 +0900 Subject: [PATCH 18/18] test: use FileLocatorInterface --- tests/system/Autoloader/FileLocatorCachedTest.php | 2 +- tests/system/Autoloader/FileLocatorTest.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/system/Autoloader/FileLocatorCachedTest.php b/tests/system/Autoloader/FileLocatorCachedTest.php index 2a5a185d6b6e..f3871713d171 100644 --- a/tests/system/Autoloader/FileLocatorCachedTest.php +++ b/tests/system/Autoloader/FileLocatorCachedTest.php @@ -23,7 +23,7 @@ final class FileLocatorCachedTest extends FileLocatorTest { private FileVarExportHandler $handler; - protected FileLocator $locator; + protected FileLocatorInterface $locator; public static function tearDownAfterClass(): void { diff --git a/tests/system/Autoloader/FileLocatorTest.php b/tests/system/Autoloader/FileLocatorTest.php index b4ff6d1c9910..14c512493d26 100644 --- a/tests/system/Autoloader/FileLocatorTest.php +++ b/tests/system/Autoloader/FileLocatorTest.php @@ -24,7 +24,7 @@ */ class FileLocatorTest extends CIUnitTestCase { - protected FileLocator $locator; + protected FileLocatorInterface $locator; protected function setUp(): void {