From bfad0ed99615123718fd63b0de27bac04702bb7c Mon Sep 17 00:00:00 2001 From: Abdul Malik Ikhsan Date: Sat, 12 Sep 2026 20:06:02 +0700 Subject: [PATCH 1/5] chore: cherry-pick structarmed.php from 4.8 to develop and use baseline config --- structarmed-baseline.php | 20 +++++++++++ structarmed.php | 72 ++++++++++++++++++++++++---------------- 2 files changed, 63 insertions(+), 29 deletions(-) create mode 100644 structarmed-baseline.php diff --git a/structarmed-baseline.php b/structarmed-baseline.php new file mode 100644 index 000000000000..eede90ce7048 --- /dev/null +++ b/structarmed-baseline.php @@ -0,0 +1,20 @@ + 'base_classes.must_be_abstract', + 'message' => 'Extended class [CodeIgniter\Config\BaseService] must be declared abstract or instantiated', + 'file' => 'system/Config/BaseService.php', + 'class' => 'CodeIgniter\Config\BaseService', + 'layer' => 'Source', + ], + [ + 'rule' => 'base_classes.must_be_abstract', + 'message' => 'Extended class [CodeIgniter\Debug\Toolbar\Collectors\BaseCollector] must be declared abstract or instantiated', + 'file' => 'system/Debug/Toolbar/Collectors/BaseCollector.php', + 'class' => 'CodeIgniter\Debug\Toolbar\Collectors\BaseCollector', + 'layer' => 'Source', + ], +]; diff --git a/structarmed.php b/structarmed.php index 88932d17cdd0..35bd7e4d740f 100644 --- a/structarmed.php +++ b/structarmed.php @@ -10,35 +10,39 @@ * For the full copyright and license information, please view * the LICENSE file that was distributed with this source code. */ -use Boundwize\StructArmed\Rule\Rules\Function_\MustHaveReturnTypeFunctionRule; + +use Boundwize\StructArmed\Architecture; +use Boundwize\StructArmed\Preset\Preset; use Boundwize\StructArmed\Preset\Presets\CodeQualityPreset; +use Boundwize\StructArmed\Preset\Presets\Psr4Preset; +use Boundwize\StructArmed\Rule\Rules\Class_\ExtendedClassMustBeAbstractOrInstantiatedRule; +use Boundwize\StructArmed\Rule\Rules\Function_\MustHaveReturnTypeFunctionRule; use CodeIgniter\Cache\ResponseCache; +use CodeIgniter\Database\BaseResult; +use CodeIgniter\DataCaster\DataCaster; +use CodeIgniter\DataConverter\DataConverter; +use CodeIgniter\Entity\Cast\CastInterface; +use CodeIgniter\Entity\Cast\URICast; +use CodeIgniter\Entity\Entity; +use CodeIgniter\Entity\Exceptions\CastException; use CodeIgniter\HTTP\CLIRequest; +use CodeIgniter\HTTP\DownloadResponse; use CodeIgniter\HTTP\Header; use CodeIgniter\HTTP\IncomingRequest; +use CodeIgniter\HTTP\RedirectResponse; +use CodeIgniter\HTTP\Response; use CodeIgniter\HTTP\ResponseInterface; -use CodeIgniter\DataCaster\DataCaster; -use CodeIgniter\Entity\Cast\CastInterface; -use CodeIgniter\Entity\Exceptions\CastException; -use CodeIgniter\DataConverter\DataConverter; -use CodeIgniter\Entity\Entity; -use CodeIgniter\Entity\Cast\URICast; +use CodeIgniter\HTTP\ResponseTrait; +use CodeIgniter\HTTP\SSEResponse; +use CodeIgniter\HTTP\StreamResponse; use CodeIgniter\HTTP\URI; use CodeIgniter\Log\Handlers\ChromeLoggerHandler; -use CodeIgniter\Security\CheckPhpIni; -use CodeIgniter\View\Table; -use CodeIgniter\Database\BaseResult; -use CodeIgniter\View\Plugins; -use CodeIgniter\HTTP\ResponseTrait; use CodeIgniter\Pager\PagerInterface; -use CodeIgniter\HTTP\Response; -use CodeIgniter\HTTP\RedirectResponse; -use CodeIgniter\HTTP\DownloadResponse; +use CodeIgniter\Security\CheckPhpIni; use CodeIgniter\Validation\Validation; +use CodeIgniter\View\Plugins; use CodeIgniter\View\RendererInterface; -use Boundwize\StructArmed\Architecture; -use Boundwize\StructArmed\Preset\Preset; -use Boundwize\StructArmed\Preset\Presets\Psr4Preset; +use CodeIgniter\View\Table; return Architecture::define() ->skip([ @@ -56,6 +60,8 @@ ->layer('Helpers', __DIR__ . '/system/Helpers') ->rule('helpers.functions_must_have_return_type', new MustHaveReturnTypeFunctionRule('Helpers')) + ->rule('base_classes.must_be_abstract', new ExtendedClassMustBeAbstractOrInstantiatedRule('Source', '/^CodeIgniter\\\\.*Base.*$/')) + // Resolve CodeIgniter layers from class names because several layers share directories. ->layerPattern('API', '/^CodeIgniter\\\\API\\\\.*$/') ->layerPattern('Cache', '/^CodeIgniter\\\\Cache\\\\.*$/') @@ -72,11 +78,13 @@ ->layerPattern('Filters', '/^CodeIgniter\\\\Filters\\\\Filter.*$/') ->layerPattern('Format', '/^CodeIgniter\\\\Format\\\\.*$/') ->layerPattern('Honeypot', '/^CodeIgniter\\\\.*Honeypot.*$/') + ->layerPattern('Input', '/^CodeIgniter\\\\Input\\\\.*$/') ->layerPattern('URI', '/^CodeIgniter\\\\HTTP\\\\URI$/') ->layerPattern('HTTP', '/^CodeIgniter\\\\HTTP\\\\.*$/', '/(Exception|URI)/') ->layerPattern('I18n', '/^CodeIgniter\\\\I18n\\\\.*$/') ->layerPattern('Images', '/^CodeIgniter\\\\Images\\\\.*$/') ->layerPattern('Language', '/^CodeIgniter\\\\Language\\\\.*$/') + ->layerPattern('Lock', '/^CodeIgniter\\\\Lock\\\\.*$/') ->layerPattern('Log', '/^CodeIgniter\\\\Log\\\\.*$/') ->layerPattern('Model', '/^CodeIgniter\\\\.*Model$/') ->layerPattern('Modules', '/^CodeIgniter\\\\Modules\\\\.*$/') @@ -96,26 +104,28 @@ 'Controller' => ['HTTP', 'Validation'], 'Cookie' => ['I18n'], 'Database' => ['Entity', 'Events', 'I18n'], - 'DataCaster' => ['I18n', 'URI', 'Database'], + 'DataCaster' => ['I18n', 'URI', 'Database', 'Encryption'], 'DataConverter' => ['DataCaster'], 'Email' => ['I18n', 'Events'], 'Entity' => ['DataCaster', 'I18n'], 'Files' => ['I18n'], 'Filters' => ['HTTP'], 'Honeypot' => ['Filters', 'HTTP'], - 'HTTP' => ['Cookie', 'Files', 'I18n', 'Security', 'URI'], + 'HTTP' => ['Cookie', 'Files', 'I18n', 'Input', 'Security', 'URI'], + 'Input' => ['I18n'], 'Images' => ['Files', 'I18n'], + 'Lock' => ['Cache'], 'Model' => ['Database', 'DataCaster', 'DataConverter', 'Entity', 'I18n', 'Pager', 'Validation'], 'Pager' => ['URI', 'View'], 'Publisher' => ['Files', 'URI'], // +API = API + its allowed layers; +Controller = Controller + its allowed layers - 'RESTful' => ['+API', '+Controller'], - 'Router' => ['HTTP', 'I18n'], - 'Security' => ['Cookie', 'HTTP', 'I18n', 'Session'], - 'Session' => ['Cookie', 'Database', 'HTTP', 'I18n'], - 'Throttle' => ['Cache', 'I18n'], - 'Validation' => ['Database', 'HTTP', 'Helpers'], - 'View' => ['Cache'], + 'RESTful' => ['+API', '+Controller'], + 'Router' => ['HTTP', 'I18n'], + 'Security' => ['Cookie', 'HTTP', 'I18n', 'Session'], + 'Session' => ['Cookie', 'Database', 'HTTP', 'I18n'], + 'Throttle' => ['Cache', 'I18n'], + 'Validation' => ['Database', 'HTTP', 'Helpers', 'I18n', 'Input'], + 'View' => ['Cache'], ]) ->skipPathsForRuleset(['*test*']) // Skip violations for class-specific dependencies. @@ -129,7 +139,7 @@ CastInterface::class, CastException::class, ]) - ->skipClassViolation(\CodeIgniter\DataCaster\Exceptions\CastException::class, [ + ->skipClassViolation(CodeIgniter\DataCaster\Exceptions\CastException::class, [ CastException::class, ]) ->skipClassViolation(DataConverter::class, [ @@ -157,4 +167,8 @@ ->skipClassViolation(Response::class, [PagerInterface::class]) ->skipClassViolation(RedirectResponse::class, [PagerInterface::class]) ->skipClassViolation(DownloadResponse::class, [PagerInterface::class]) - ->skipClassViolation(Validation::class, [RendererInterface::class]); + ->skipClassViolation(SSEResponse::class, [PagerInterface::class]) + ->skipClassViolation(StreamResponse::class, [PagerInterface::class]) + ->skipClassViolation(Validation::class, [RendererInterface::class]) + + ->baseline(__DIR__ . '/structarmed-baseline.php'); From 4db2f5a8bfbb298b8b6714b7338129a304f68260 Mon Sep 17 00:00:00 2001 From: Abdul Malik Ikhsan Date: Sat, 12 Sep 2026 20:11:35 +0700 Subject: [PATCH 2/5] clean copy --- structarmed.php | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/structarmed.php b/structarmed.php index 35bd7e4d740f..ddabe03a51a0 100644 --- a/structarmed.php +++ b/structarmed.php @@ -169,6 +169,4 @@ ->skipClassViolation(DownloadResponse::class, [PagerInterface::class]) ->skipClassViolation(SSEResponse::class, [PagerInterface::class]) ->skipClassViolation(StreamResponse::class, [PagerInterface::class]) - ->skipClassViolation(Validation::class, [RendererInterface::class]) - - ->baseline(__DIR__ . '/structarmed-baseline.php'); + ->skipClassViolation(Validation::class, [RendererInterface::class]); From afd7a36f3a0223b90ecf0c1ad67b8f1c6a1f10a7 Mon Sep 17 00:00:00 2001 From: Abdul Malik Ikhsan Date: Sat, 12 Sep 2026 20:13:30 +0700 Subject: [PATCH 3/5] register baseline --- structarmed.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/structarmed.php b/structarmed.php index ddabe03a51a0..244cc1a14a5f 100644 --- a/structarmed.php +++ b/structarmed.php @@ -169,4 +169,5 @@ ->skipClassViolation(DownloadResponse::class, [PagerInterface::class]) ->skipClassViolation(SSEResponse::class, [PagerInterface::class]) ->skipClassViolation(StreamResponse::class, [PagerInterface::class]) - ->skipClassViolation(Validation::class, [RendererInterface::class]); + ->skipClassViolation(Validation::class, [RendererInterface::class]) + ->baseline(__DIR__ . '/structarmed-baseline.php'); From 954ede8c022b67677bf9389b42ac2d6c64b818aa Mon Sep 17 00:00:00 2001 From: Abdul Malik Ikhsan Date: Sat, 12 Sep 2026 20:15:08 +0700 Subject: [PATCH 4/5] register baseline --- structarmed.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/structarmed.php b/structarmed.php index 244cc1a14a5f..990f039601bc 100644 --- a/structarmed.php +++ b/structarmed.php @@ -54,6 +54,7 @@ __DIR__ . '/system/View/Cells/Cell.php', ], ]) + ->baseline(__DIR__ . '/structarmed-baseline.php') ->cacheDirectory(is_dir('/tmp') ? '/tmp/structarmed' : null) ->withPresets(Preset::PSR4(), Preset::CODEQUALITY()) @@ -169,5 +170,4 @@ ->skipClassViolation(DownloadResponse::class, [PagerInterface::class]) ->skipClassViolation(SSEResponse::class, [PagerInterface::class]) ->skipClassViolation(StreamResponse::class, [PagerInterface::class]) - ->skipClassViolation(Validation::class, [RendererInterface::class]) - ->baseline(__DIR__ . '/structarmed-baseline.php'); + ->skipClassViolation(Validation::class, [RendererInterface::class]); From 5b2083c9e5cdfd659acd8650ca31dc2c22551f22 Mon Sep 17 00:00:00 2001 From: Abdul Malik Ikhsan Date: Sat, 12 Sep 2026 20:19:23 +0700 Subject: [PATCH 5/5] register structarmed-baseline.php to .gitattributes --- .gitattributes | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitattributes b/.gitattributes index d87cc8aa8cf2..02a23de3322d 100644 --- a/.gitattributes +++ b/.gitattributes @@ -22,6 +22,7 @@ utils/ export-ignore .php-cs-fixer.no-header.php export-ignore .php-cs-fixer.tests.php export-ignore .php-cs-fixer.user-guide.php export-ignore +structarmed-baseline.php export-ignore structarmed.php export-ignore phpmetrics.json export-ignore phpstan-baseline.php export-ignore