diff --git a/system/Filters/Filters.php b/system/Filters/Filters.php index 994c6f37c7e2..9ec268dc9394 100644 --- a/system/Filters/Filters.php +++ b/system/Filters/Filters.php @@ -154,12 +154,16 @@ private function discoverFilters(): void $files = $locator->search('Config/Filters.php'); - foreach ($files as $file) { - // The $file may not be a class file. - $className = $locator->getClassname($file); + // Don't include our main Filter configs again. They are skipped by path, + // as reading and tokenizing them to find their class is wasted work. + // APPPATH, SYSTEMPATH and the paths from search() are all real paths. + $mainFiles = [ + APPPATH . 'Config' . DIRECTORY_SEPARATOR . 'Filters.php', + SYSTEMPATH . 'Config' . DIRECTORY_SEPARATOR . 'Filters.php', + ]; - // Don't include our main Filter config again... - if ($className === FiltersConfig::class || $className === BaseFiltersConfig::class) { + foreach ($files as $file) { + if (in_array($file, $mainFiles, true)) { continue; } diff --git a/tests/system/Filters/FiltersTest.php b/tests/system/Filters/FiltersTest.php index d696498efaa2..443c79dd4c51 100644 --- a/tests/system/Filters/FiltersTest.php +++ b/tests/system/Filters/FiltersTest.php @@ -13,6 +13,7 @@ namespace CodeIgniter\Filters; +use CodeIgniter\Autoloader\FileLocator; use CodeIgniter\Config\Services; use CodeIgniter\Filters\Exceptions\FilterException; use CodeIgniter\Filters\fixtures\GoogleCurious; @@ -488,6 +489,50 @@ public function testAllCustomFiltersAreDiscoveredInConstructor(): void $this->assertContains('test-customfilter', array_keys($configFilters->aliases)); } + public function testDiscoveryDoesNotTokenizeTheDefaultFiltersConfigs(): void + { + service('superglobals')->setServer('REQUEST_METHOD', 'GET'); + + $locator = new class (service('autoloader')) extends FileLocator { + /** + * @var list + */ + public array $tokenized = []; + + public function getClassname(string $file): string + { + $this->tokenized[] = $file; + + return parent::getClassname($file); + } + }; + Services::injectMock('locator', $locator); + + $appConfig = APPPATH . 'Config' . DIRECTORY_SEPARATOR . 'Filters.php'; + $systemConfig = SYSTEMPATH . 'Config' . DIRECTORY_SEPARATOR . 'Filters.php'; + $testConfig = realpath(TESTPATH . '_support/Config/Filters.php'); + + // Discovery does find them all, so the checks below are not vacuous. + $found = $locator->search('Config/Filters.php'); + $this->assertContains($appConfig, $found); + $this->assertContains($systemConfig, $found); + $this->assertContains($testConfig, $found); + + $config = [ + 'aliases' => [], + 'globals' => [], + ]; + $filtersConfig = $this->createConfigFromArray(FiltersConfig::class, $config); + $filters = $this->createFilters($filtersConfig); + + // No discovered file is read and tokenized, the main configs are skipped + // by path and the others are simply included. + $this->assertSame([], $locator->tokenized); + + $configFilters = $this->getPrivateProperty($filters, 'config'); + $this->assertContains('test-customfilter', array_keys($configFilters->aliases)); + } + public function testRunThrowsWithInvalidClassType(): void { service('superglobals')->setServer('REQUEST_METHOD', 'GET');