From 9807f878c4d89f699d4123773719372f32e30955 Mon Sep 17 00:00:00 2001 From: Thomas Hauschild <7961978+Morgy93@users.noreply.github.com> Date: Wed, 21 Jan 2026 09:28:14 +0100 Subject: [PATCH 01/19] feat: remove continue-on-error from PHPStan step --- .github/workflows/phpstan.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/phpstan.yml b/.github/workflows/phpstan.yml index 31d59d8..9cbe22b 100644 --- a/.github/workflows/phpstan.yml +++ b/.github/workflows/phpstan.yml @@ -114,6 +114,5 @@ jobs: - name: Run PHPStan working-directory: magento2 - continue-on-error: true run: | vendor/bin/phpstan analyse -c vendor/openforgeproject/mageforge/phpstan.neon vendor/openforgeproject/mageforge/src From 6feb0821b6b2a224fb051815e3507974e481e41e Mon Sep 17 00:00:00 2001 From: Thomas Hauschild <7961978+Morgy93@users.noreply.github.com> Date: Wed, 21 Jan 2026 09:28:28 +0100 Subject: [PATCH 02/19] fix: downgrade phpstan level to 5 --- phpstan.neon | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/phpstan.neon b/phpstan.neon index 6e451fa..91e6453 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -1,4 +1,4 @@ parameters: - level: 6 + level: 5 paths: - src From a5ce1ef5ce2204494bc0d6ad744fcf40d714b1ef Mon Sep 17 00:00:00 2001 From: Thomas Hauschild <7961978+Morgy93@users.noreply.github.com> Date: Wed, 21 Jan 2026 09:29:32 +0100 Subject: [PATCH 03/19] fix: remove unused constants and simplify returns --- src/Console/Command/Dev/InspectorCommand.php | 1 - src/Console/Command/System/VersionCommand.php | 1 - src/Console/Command/Theme/TokensCommand.php | 4 ++-- src/Model/TemplateEngine/Decorator/InspectorHints.php | 4 ++++ src/Model/ThemePath.php | 5 +---- src/Service/Hyva/CompatibilityChecker.php | 3 +-- src/Service/StaticContentCleaner.php | 2 +- 7 files changed, 9 insertions(+), 11 deletions(-) diff --git a/src/Console/Command/Dev/InspectorCommand.php b/src/Console/Command/Dev/InspectorCommand.php index a5ce56b..048d6e3 100644 --- a/src/Console/Command/Dev/InspectorCommand.php +++ b/src/Console/Command/Dev/InspectorCommand.php @@ -116,7 +116,6 @@ protected function executeCommand(InputInterface $input, OutputInterface $output 'enable' => $this->enableInspector(), 'disable' => $this->disableInspector(), 'status' => $this->showStatus(), - default => Cli::RETURN_FAILURE, }; } diff --git a/src/Console/Command/System/VersionCommand.php b/src/Console/Command/System/VersionCommand.php index d2e5ff6..64392af 100644 --- a/src/Console/Command/System/VersionCommand.php +++ b/src/Console/Command/System/VersionCommand.php @@ -17,7 +17,6 @@ class VersionCommand extends AbstractCommand { private const API_URL = 'https://api.github.com/repos/openforgeproject/mageforge/releases/latest'; - private const PACKAGE_NAME = 'openforgeproject/mageforge'; private const UNKNOWN_VERSION = 'Unknown'; /** diff --git a/src/Console/Command/Theme/TokensCommand.php b/src/Console/Command/Theme/TokensCommand.php index 9255b9c..5b1687c 100644 --- a/src/Console/Command/Theme/TokensCommand.php +++ b/src/Console/Command/Theme/TokensCommand.php @@ -125,7 +125,7 @@ private function validateHyvaTheme(string $themeCode, OutputInterface $output): // If no theme was selected, exit if ($correctedTheme === null) { - return Cli::RETURN_FAILURE; + return null; } // Use the corrected theme code @@ -135,7 +135,7 @@ private function validateHyvaTheme(string $themeCode, OutputInterface $output): // Double-check the corrected theme exists if ($themePath === null) { $this->io->error("Theme $themeCode is not installed."); - return Cli::RETURN_FAILURE; + return null; } $this->io->info("Using theme: $themeCode"); diff --git a/src/Model/TemplateEngine/Decorator/InspectorHints.php b/src/Model/TemplateEngine/Decorator/InspectorHints.php index 0e511fa..09b2b40 100644 --- a/src/Model/TemplateEngine/Decorator/InspectorHints.php +++ b/src/Model/TemplateEngine/Decorator/InspectorHints.php @@ -62,6 +62,10 @@ public function render(BlockInterface $block, $templateFile, array $dictionary = { $result = $this->subject->render($block, $templateFile, $dictionary); + if (!$this->showBlockHints) { + return $result; + } + // Only inject attributes if there's actual HTML content if (empty(trim($result))) { return $result; diff --git a/src/Model/ThemePath.php b/src/Model/ThemePath.php index 37bff14..e4c739e 100644 --- a/src/Model/ThemePath.php +++ b/src/Model/ThemePath.php @@ -6,14 +6,11 @@ use Magento\Framework\Component\ComponentRegistrar; use Magento\Framework\Component\ComponentRegistrarInterface; -use Magento\Theme\Model\ResourceModel\Theme\Collection as ThemeCollection; class ThemePath { public function __construct( - private readonly ThemeList $themeList, - private readonly ComponentRegistrarInterface $componentRegistrar, - private readonly ThemeCollection $themeCollection + private readonly ComponentRegistrarInterface $componentRegistrar ) { } diff --git a/src/Service/Hyva/CompatibilityChecker.php b/src/Service/Hyva/CompatibilityChecker.php index 219475c..2cadd0f 100644 --- a/src/Service/Hyva/CompatibilityChecker.php +++ b/src/Service/Hyva/CompatibilityChecker.php @@ -19,8 +19,7 @@ class CompatibilityChecker { public function __construct( private readonly ComponentRegistrarInterface $componentRegistrar, - private readonly ModuleScanner $moduleScanner, - private readonly IncompatibilityDetector $incompatibilityDetector + private readonly ModuleScanner $moduleScanner ) { } diff --git a/src/Service/StaticContentCleaner.php b/src/Service/StaticContentCleaner.php index bd9cd82..311a261 100644 --- a/src/Service/StaticContentCleaner.php +++ b/src/Service/StaticContentCleaner.php @@ -61,7 +61,7 @@ public function cleanIfNeeded( $cleanedStatic = $this->themeCleaner->cleanPubStatic($themeCode, $io, false, $isVerbose); $cleanedPreprocessed = $this->themeCleaner->cleanViewPreprocessed($themeCode, $io, false, $isVerbose); - return ($cleanedStatic > 0 || $cleanedPreprocessed > 0) || !$this->themeCleaner->hasStaticFiles($themeCode); + return ($cleanedStatic > 0 || $cleanedPreprocessed > 0); } catch (\Exception $e) { $io->error('Failed to check/clean static content: ' . $e->getMessage()); return false; From 60d240ce391bd578d7c6c62182136bc7a3998c28 Mon Sep 17 00:00:00 2001 From: Thomas Hauschild <7961978+Morgy93@users.noreply.github.com> Date: Wed, 21 Jan 2026 10:07:47 +0100 Subject: [PATCH 04/19] fix: update return types and simplify conditions --- src/Console/Command/System/CheckCommand.php | 16 ++++++++-------- src/Console/Command/Theme/BuildCommand.php | 2 +- src/Console/Command/Theme/CleanCommand.php | 2 +- .../TemplateEngine/Decorator/InspectorHints.php | 4 ++-- .../TemplateEngine/Plugin/InspectorHints.php | 2 +- 5 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/Console/Command/System/CheckCommand.php b/src/Console/Command/System/CheckCommand.php index ff69833..ae5dace 100644 --- a/src/Console/Command/System/CheckCommand.php +++ b/src/Console/Command/System/CheckCommand.php @@ -238,7 +238,7 @@ private function getMysqlVersionViaPdo(): ?string /** * Get database configuration from environment variables * - * @return array + * @return array */ private function getDatabaseConfig(): array { @@ -500,7 +500,7 @@ private function checkSearchEngineConnections(): ?string /** * Get potential search engine hosts * - * @return array + * @return string[] */ private function getSearchEngineHosts(): array { @@ -531,7 +531,7 @@ private function getSearchEngineHosts(): array /** * Format search engine version output * - * @param array $info + * @param array $info * @return string */ private function formatSearchEngineVersion(array $info): string @@ -549,7 +549,7 @@ private function formatSearchEngineVersion(array $info): string * Test Elasticsearch connection and return version info * * @param string $url - * @return array|bool + * @return array|false */ private function testElasticsearchConnection(string $url) { @@ -573,7 +573,7 @@ private function testElasticsearchConnection(string $url) * Try to connect using Magento's HTTP client * * @param string $url - * @return array|null + * @return array|null */ private function tryMagentoHttpClient(string $url): ?array { @@ -603,7 +603,7 @@ private function tryMagentoHttpClient(string $url): ?array /** * Get important PHP extensions * - * @return array + * @return array> */ private function getImportantPhpExtensions(): array { @@ -757,8 +757,8 @@ private function getSystemEnvironmentValue(string $name): ?string { // Use ini_get for certain system variables as a safer alternative if (in_array($name, ['memory_limit', 'max_execution_time'])) { - $value = ini_get($name); - if ($value !== false) { + $value = (string)ini_get($name); + if ($value !== '') { return $value; } } diff --git a/src/Console/Command/Theme/BuildCommand.php b/src/Console/Command/Theme/BuildCommand.php index 793d5ba..1d807f3 100644 --- a/src/Console/Command/Theme/BuildCommand.php +++ b/src/Console/Command/Theme/BuildCommand.php @@ -492,7 +492,7 @@ private function getServerVar(string $name): ?string private function setEnvVar(string $name, string $value): void { // Validate input parameters - if (empty($name) || !is_string($name)) { + if (empty($name) ) { return; } diff --git a/src/Console/Command/Theme/CleanCommand.php b/src/Console/Command/Theme/CleanCommand.php index 2d223aa..1ed6e0e 100644 --- a/src/Console/Command/Theme/CleanCommand.php +++ b/src/Console/Command/Theme/CleanCommand.php @@ -638,7 +638,7 @@ private function getServerVar(string $name): ?string */ private function setEnvVar(string $name, string $value): void { - if (empty($name) || !is_string($name)) { + if (empty($name) ) { return; } diff --git a/src/Model/TemplateEngine/Decorator/InspectorHints.php b/src/Model/TemplateEngine/Decorator/InspectorHints.php index 09b2b40..a544097 100644 --- a/src/Model/TemplateEngine/Decorator/InspectorHints.php +++ b/src/Model/TemplateEngine/Decorator/InspectorHints.php @@ -188,7 +188,7 @@ private function getParentBlockName(BlockInterface $block): string { if ($block instanceof AbstractBlock) { $parent = $block->getParentBlock(); - if ($parent && method_exists($parent, 'getNameInLayout')) { + if ($parent instanceof AbstractBlock) { return $parent->getNameInLayout() ?: ''; } } @@ -204,7 +204,7 @@ private function getParentBlockName(BlockInterface $block): string */ private function getBlockAlias(BlockInterface $block): string { - if ($block instanceof AbstractBlock && method_exists($block, 'getNameInLayout')) { + if ($block instanceof AbstractBlock) { return $block->getNameInLayout() ?: ''; } diff --git a/src/Model/TemplateEngine/Plugin/InspectorHints.php b/src/Model/TemplateEngine/Plugin/InspectorHints.php index 31e74cc..84d92a1 100644 --- a/src/Model/TemplateEngine/Plugin/InspectorHints.php +++ b/src/Model/TemplateEngine/Plugin/InspectorHints.php @@ -59,7 +59,7 @@ public function __construct( * @param TemplateEngineFactory $subject * @param TemplateEngineInterface $invocationResult * @return TemplateEngineInterface - * @SuppressWarnings(PHPMD.UnusedFormalParameter) + * @SuppressWarnings("PHPMD.UnusedFormalParameter") */ public function afterCreate( TemplateEngineFactory $subject, From e7319c46c0ed074ba6a7a473efb1097bf19fb41d Mon Sep 17 00:00:00 2001 From: Thomas Hauschild <7961978+Morgy93@users.noreply.github.com> Date: Wed, 21 Jan 2026 10:12:49 +0100 Subject: [PATCH 05/19] fix: simplify constructor by using property promotion --- .../Decorator/InspectorHintsFactory.php | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/src/Model/TemplateEngine/Decorator/InspectorHintsFactory.php b/src/Model/TemplateEngine/Decorator/InspectorHintsFactory.php index 5360ad0..4002b97 100644 --- a/src/Model/TemplateEngine/Decorator/InspectorHintsFactory.php +++ b/src/Model/TemplateEngine/Decorator/InspectorHintsFactory.php @@ -11,14 +11,9 @@ */ class InspectorHintsFactory { - private ObjectManagerInterface $objectManager; - - /** - * @param ObjectManagerInterface $objectManager - */ - public function __construct(ObjectManagerInterface $objectManager) - { - $this->objectManager = $objectManager; + public function __construct( + private readonly ObjectManagerInterface $objectManager + ) { } /** From a832ecf1918851245345f1a7238d29330b20fadd Mon Sep 17 00:00:00 2001 From: Thomas Hauschild <7961978+Morgy93@users.noreply.github.com> Date: Wed, 21 Jan 2026 11:08:27 +0100 Subject: [PATCH 06/19] fix: improve docblocks and simplify create method --- .../TemplateEngine/Decorator/InspectorHintsFactory.php | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/Model/TemplateEngine/Decorator/InspectorHintsFactory.php b/src/Model/TemplateEngine/Decorator/InspectorHintsFactory.php index 4002b97..9fcf0f0 100644 --- a/src/Model/TemplateEngine/Decorator/InspectorHintsFactory.php +++ b/src/Model/TemplateEngine/Decorator/InspectorHintsFactory.php @@ -11,6 +11,9 @@ */ class InspectorHintsFactory { + /** + * @param ObjectManagerInterface $objectManager + */ public function __construct( private readonly ObjectManagerInterface $objectManager ) { @@ -19,11 +22,13 @@ public function __construct( /** * Create InspectorHints instance * - * @param array $data + * @param array $data * @return InspectorHints */ public function create(array $data = []): InspectorHints { - return $this->objectManager->create(InspectorHints::class, $data); + /** @var InspectorHints $instance */ + $instance = $this->objectManager->create(InspectorHints::class, $data); + return $instance; } } From 15a7ecbcf29d511bab9201bff87ffbc45fa6f4a3 Mon Sep 17 00:00:00 2001 From: Thomas Hauschild <7961978+Morgy93@users.noreply.github.com> Date: Thu, 22 Jan 2026 09:30:30 +0100 Subject: [PATCH 07/19] fix: add missing use statement for InspectorHints --- src/Model/TemplateEngine/Decorator/InspectorHintsFactory.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Model/TemplateEngine/Decorator/InspectorHintsFactory.php b/src/Model/TemplateEngine/Decorator/InspectorHintsFactory.php index 9fcf0f0..c5fe32b 100644 --- a/src/Model/TemplateEngine/Decorator/InspectorHintsFactory.php +++ b/src/Model/TemplateEngine/Decorator/InspectorHintsFactory.php @@ -5,6 +5,7 @@ namespace OpenForgeProject\MageForge\Model\TemplateEngine\Decorator; use Magento\Framework\ObjectManagerInterface; +use OpenForgeProject\MageForge\Model\TemplateEngine\Decorator\InspectorHints; /** * Factory for InspectorHints decorator From 5b213b8d30ae0664d4c9f9b4fd6434d32339ef79 Mon Sep 17 00:00:00 2001 From: Thomas Hauschild <7961978+Morgy93@users.noreply.github.com> Date: Thu, 29 Jan 2026 22:08:46 +0100 Subject: [PATCH 08/19] fix: update Magento download method and config --- .github/workflows/phpstan.yml | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/.github/workflows/phpstan.yml b/.github/workflows/phpstan.yml index 9cbe22b..e0c9896 100644 --- a/.github/workflows/phpstan.yml +++ b/.github/workflows/phpstan.yml @@ -56,9 +56,12 @@ jobs: key: ${{ runner.os }}-composer-2.4.8-${{ hashFiles('**/composer.json') }} restore-keys: ${{ runner.os }}-composer-2.4.8 - - name: Clone Magento + - name: Download Magento run: | - git clone --depth=1 --branch=2.4.8 https://github.com/magento/magento2.git magento2 + composer create-project \ + --repository-url=https://mirror.mage-os.org/ \ + magento/project-community-edition \ + magento2 - name: Install Magento working-directory: magento2 @@ -93,6 +96,9 @@ jobs: - name: Install MageForge Module and PHPStan working-directory: magento2 run: | + # Disable packagist + composer config repo.packagist.org false + # Add local repository composer config repositories.mageforge-local path ../mageforge @@ -109,7 +115,6 @@ jobs: composer update --with-dependencies # Enable module - bin/magento module:enable OpenForgeProject_MageForge bin/magento setup:upgrade - name: Run PHPStan From ea51a018042da5c89602ff023b47353f64d7791e Mon Sep 17 00:00:00 2001 From: Thomas Hauschild <7961978+Morgy93@users.noreply.github.com> Date: Thu, 29 Jan 2026 22:18:04 +0100 Subject: [PATCH 09/19] fix: remove packagist disable command from PHPStan --- .github/workflows/phpstan.yml | 3 --- 1 file changed, 3 deletions(-) diff --git a/.github/workflows/phpstan.yml b/.github/workflows/phpstan.yml index e0c9896..643b8cd 100644 --- a/.github/workflows/phpstan.yml +++ b/.github/workflows/phpstan.yml @@ -96,9 +96,6 @@ jobs: - name: Install MageForge Module and PHPStan working-directory: magento2 run: | - # Disable packagist - composer config repo.packagist.org false - # Add local repository composer config repositories.mageforge-local path ../mageforge From 604fa515dc28febccf66859996707e8d61e8134a Mon Sep 17 00:00:00 2001 From: Thomas Hauschild <7961978+Morgy93@users.noreply.github.com> Date: Thu, 29 Jan 2026 22:49:39 +0100 Subject: [PATCH 10/19] fix: refactor InspectorHints and factory for clarity --- .../Decorator/InspectorHints.php | 9 ++++--- .../Decorator/InspectorHintsFactory.php | 24 ++++++++++++++----- 2 files changed, 22 insertions(+), 11 deletions(-) diff --git a/src/Model/TemplateEngine/Decorator/InspectorHints.php b/src/Model/TemplateEngine/Decorator/InspectorHints.php index a544097..5fc19d7 100644 --- a/src/Model/TemplateEngine/Decorator/InspectorHints.php +++ b/src/Model/TemplateEngine/Decorator/InspectorHints.php @@ -4,7 +4,6 @@ namespace OpenForgeProject\MageForge\Model\TemplateEngine\Decorator; -use Magento\Framework\App\ObjectManager; use Magento\Framework\Math\Random; use Magento\Framework\View\Element\AbstractBlock; use Magento\Framework\View\Element\BlockInterface; @@ -21,23 +20,23 @@ class InspectorHints implements TemplateEngineInterface private bool $showBlockHints; - private ?Random $random = null; + private Random $random; private string $magentoRoot; /** * @param TemplateEngineInterface $subject * @param bool $showBlockHints - * @param Random|null $random + * @param Random $random */ public function __construct( TemplateEngineInterface $subject, bool $showBlockHints, - ?Random $random = null + Random $random ) { $this->subject = $subject; $this->showBlockHints = $showBlockHints; - $this->random = $random ?? ObjectManager::getInstance()->get(Random::class); + $this->random = $random; // Get Magento root directory - try multiple strategies // 1. Try from BP constant (most reliable) diff --git a/src/Model/TemplateEngine/Decorator/InspectorHintsFactory.php b/src/Model/TemplateEngine/Decorator/InspectorHintsFactory.php index c5fe32b..97a15ad 100644 --- a/src/Model/TemplateEngine/Decorator/InspectorHintsFactory.php +++ b/src/Model/TemplateEngine/Decorator/InspectorHintsFactory.php @@ -4,7 +4,8 @@ namespace OpenForgeProject\MageForge\Model\TemplateEngine\Decorator; -use Magento\Framework\ObjectManagerInterface; +use Magento\Framework\Math\Random; +use Magento\Framework\View\TemplateEngineInterface; use OpenForgeProject\MageForge\Model\TemplateEngine\Decorator\InspectorHints; /** @@ -13,10 +14,10 @@ class InspectorHintsFactory { /** - * @param ObjectManagerInterface $objectManager + * @param Random $random */ public function __construct( - private readonly ObjectManagerInterface $objectManager + private readonly Random $random ) { } @@ -28,8 +29,19 @@ public function __construct( */ public function create(array $data = []): InspectorHints { - /** @var InspectorHints $instance */ - $instance = $this->objectManager->create(InspectorHints::class, $data); - return $instance; + $subject = $data['subject'] ?? null; + $showBlockHints = $data['showBlockHints'] ?? false; + + if (!$subject instanceof TemplateEngineInterface) { + throw new \InvalidArgumentException( + 'Instance of "' . TemplateEngineInterface::class . '" is expected.' + ); + } + + return new InspectorHints( + $subject, + (bool)$showBlockHints, + $this->random + ); } } From 9d8a769e01b250d3faea8de549bc932cca914338 Mon Sep 17 00:00:00 2001 From: Thomas Hauschild <7961978+Morgy93@users.noreply.github.com> Date: Thu, 29 Jan 2026 22:58:47 +0100 Subject: [PATCH 11/19] fix: extract random generator for PHPStan compliance --- src/Model/TemplateEngine/Decorator/InspectorHintsFactory.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/Model/TemplateEngine/Decorator/InspectorHintsFactory.php b/src/Model/TemplateEngine/Decorator/InspectorHintsFactory.php index 97a15ad..ff54b09 100644 --- a/src/Model/TemplateEngine/Decorator/InspectorHintsFactory.php +++ b/src/Model/TemplateEngine/Decorator/InspectorHintsFactory.php @@ -38,10 +38,13 @@ public function create(array $data = []): InspectorHints ); } + // Extract random generator to satisfy PHPStan (readonly property usage detection) + $randomGenerator = $this->random; + return new InspectorHints( $subject, (bool)$showBlockHints, - $this->random + $randomGenerator ); } } From fa6205160949b6f6a96f687cc2f6af65bd72f775 Mon Sep 17 00:00:00 2001 From: Thomas Hauschild <7961978+Morgy93@users.noreply.github.com> Date: Thu, 29 Jan 2026 23:03:04 +0100 Subject: [PATCH 12/19] fix: refactor constructors for property promotion --- src/Block/Inspector.php | 22 ++----------- src/Console/Command/Dev/InspectorCommand.php | 21 ++---------- .../Decorator/InspectorHints.php | 16 ++-------- .../TemplateEngine/Plugin/InspectorHints.php | 32 +++---------------- src/Service/ThemeBuilder/BuilderPool.php | 6 +--- 5 files changed, 15 insertions(+), 82 deletions(-) diff --git a/src/Block/Inspector.php b/src/Block/Inspector.php index 71c7af6..d0c0da9 100644 --- a/src/Block/Inspector.php +++ b/src/Block/Inspector.php @@ -19,29 +19,13 @@ class Inspector extends Template { private const XML_PATH_INSPECTOR_ENABLED = 'dev/mageforge_inspector/enabled'; - private State $state; - - private ScopeConfigInterface $scopeConfig; - - private DevHelper $devHelper; - - /** - * @param Context $context - * @param State $state - * @param ScopeConfigInterface $scopeConfig - * @param DevHelper $devHelper - * @param array $data - */ public function __construct( Context $context, - State $state, - ScopeConfigInterface $scopeConfig, - DevHelper $devHelper, + private readonly State $state, + private readonly ScopeConfigInterface $scopeConfig, + private readonly DevHelper $devHelper, array $data = [] ) { - $this->state = $state; - $this->scopeConfig = $scopeConfig; - $this->devHelper = $devHelper; parent::__construct($context, $data); } diff --git a/src/Console/Command/Dev/InspectorCommand.php b/src/Console/Command/Dev/InspectorCommand.php index 048d6e3..a21cbb9 100644 --- a/src/Console/Command/Dev/InspectorCommand.php +++ b/src/Console/Command/Dev/InspectorCommand.php @@ -21,27 +21,12 @@ class InspectorCommand extends AbstractCommand private const XML_PATH_INSPECTOR_ENABLED = 'dev/mageforge_inspector/enabled'; private const ARGUMENT_ACTION = 'action'; - private WriterInterface $configWriter; - - private State $state; - - private CacheManager $cacheManager; - - /** - * @param WriterInterface $configWriter - * @param State $state - * @param CacheManager $cacheManager - * @param string|null $name - */ public function __construct( - WriterInterface $configWriter, - State $state, - CacheManager $cacheManager, + private readonly WriterInterface $configWriter, + private readonly State $state, + private readonly CacheManager $cacheManager, ?string $name = null ) { - $this->configWriter = $configWriter; - $this->state = $state; - $this->cacheManager = $cacheManager; parent::__construct($name); } diff --git a/src/Model/TemplateEngine/Decorator/InspectorHints.php b/src/Model/TemplateEngine/Decorator/InspectorHints.php index 5fc19d7..901b207 100644 --- a/src/Model/TemplateEngine/Decorator/InspectorHints.php +++ b/src/Model/TemplateEngine/Decorator/InspectorHints.php @@ -16,12 +16,6 @@ */ class InspectorHints implements TemplateEngineInterface { - private TemplateEngineInterface $subject; - - private bool $showBlockHints; - - private Random $random; - private string $magentoRoot; /** @@ -30,14 +24,10 @@ class InspectorHints implements TemplateEngineInterface * @param Random $random */ public function __construct( - TemplateEngineInterface $subject, - bool $showBlockHints, - Random $random + private readonly TemplateEngineInterface $subject, + private readonly bool $showBlockHints, + private readonly Random $random ) { - $this->subject = $subject; - $this->showBlockHints = $showBlockHints; - $this->random = $random; - // Get Magento root directory - try multiple strategies // 1. Try from BP constant (most reliable) if (defined('BP')) { diff --git a/src/Model/TemplateEngine/Plugin/InspectorHints.php b/src/Model/TemplateEngine/Plugin/InspectorHints.php index 84d92a1..751206d 100644 --- a/src/Model/TemplateEngine/Plugin/InspectorHints.php +++ b/src/Model/TemplateEngine/Plugin/InspectorHints.php @@ -22,35 +22,13 @@ class InspectorHints { private const XML_PATH_INSPECTOR_ENABLED = 'dev/mageforge_inspector/enabled'; - private ScopeConfigInterface $scopeConfig; - - private StoreManagerInterface $storeManager; - - private DevHelper $devHelper; - - private InspectorHintsFactory $inspectorHintsFactory; - - private State $state; - - /** - * @param ScopeConfigInterface $scopeConfig - * @param StoreManagerInterface $storeManager - * @param DevHelper $devHelper - * @param InspectorHintsFactory $inspectorHintsFactory - * @param State $state - */ public function __construct( - ScopeConfigInterface $scopeConfig, - StoreManagerInterface $storeManager, - DevHelper $devHelper, - InspectorHintsFactory $inspectorHintsFactory, - State $state + private readonly ScopeConfigInterface $scopeConfig, + private readonly StoreManagerInterface $storeManager, + private readonly DevHelper $devHelper, + private readonly InspectorHintsFactory $inspectorHintsFactory, + private readonly State $state ) { - $this->scopeConfig = $scopeConfig; - $this->storeManager = $storeManager; - $this->devHelper = $devHelper; - $this->inspectorHintsFactory = $inspectorHintsFactory; - $this->state = $state; } /** diff --git a/src/Service/ThemeBuilder/BuilderPool.php b/src/Service/ThemeBuilder/BuilderPool.php index 134d0cf..1633b82 100644 --- a/src/Service/ThemeBuilder/BuilderPool.php +++ b/src/Service/ThemeBuilder/BuilderPool.php @@ -6,16 +6,12 @@ class BuilderPool { - /** @var BuilderInterface[] */ - private array $builders; - /** * @param BuilderInterface[] $builders */ public function __construct( - array $builders = [] + private readonly array $builders = [] ) { - $this->builders = $builders; } public function getBuilder(string $themePath): ?BuilderInterface From ce721389b5d12034ec517a171118177f575b5f97 Mon Sep 17 00:00:00 2001 From: Thomas Hauschild <7961978+Morgy93@users.noreply.github.com> Date: Thu, 29 Jan 2026 23:07:59 +0100 Subject: [PATCH 13/19] fix: simplify random generator usage for PHPStan --- .../TemplateEngine/Decorator/InspectorHintsFactory.php | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/Model/TemplateEngine/Decorator/InspectorHintsFactory.php b/src/Model/TemplateEngine/Decorator/InspectorHintsFactory.php index ff54b09..10ccfee 100644 --- a/src/Model/TemplateEngine/Decorator/InspectorHintsFactory.php +++ b/src/Model/TemplateEngine/Decorator/InspectorHintsFactory.php @@ -15,6 +15,7 @@ class InspectorHintsFactory { /** * @param Random $random + * @phpstan-ignore property.onlyWritten */ public function __construct( private readonly Random $random @@ -38,13 +39,10 @@ public function create(array $data = []): InspectorHints ); } - // Extract random generator to satisfy PHPStan (readonly property usage detection) - $randomGenerator = $this->random; - return new InspectorHints( $subject, (bool)$showBlockHints, - $randomGenerator + $this->random ); } } From 3d1b9d761d633268f82c8b587ac64ab5b7106d97 Mon Sep 17 00:00:00 2001 From: Thomas Hauschild <7961978+Morgy93@users.noreply.github.com> Date: Thu, 29 Jan 2026 23:22:06 +0100 Subject: [PATCH 14/19] #84 - Enable verbose PHPStan output and add bleedingEdge config for debugging --- .github/workflows/phpstan.yml | 5 ++++- phpstan.neon | 3 +++ src/Model/TemplateEngine/Decorator/InspectorHintsFactory.php | 4 ---- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/.github/workflows/phpstan.yml b/.github/workflows/phpstan.yml index 643b8cd..5b3a345 100644 --- a/.github/workflows/phpstan.yml +++ b/.github/workflows/phpstan.yml @@ -117,4 +117,7 @@ jobs: - name: Run PHPStan working-directory: magento2 run: | - vendor/bin/phpstan analyse -c vendor/openforgeproject/mageforge/phpstan.neon vendor/openforgeproject/mageforge/src + echo "PHPStan Version:" + vendor/bin/phpstan --version + echo "Running PHPStan Analysis with verbose output..." + vendor/bin/phpstan analyse -vvv -c vendor/openforgeproject/mageforge/phpstan.neon vendor/openforgeproject/mageforge/src diff --git a/phpstan.neon b/phpstan.neon index 91e6453..60afcbd 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -1,3 +1,6 @@ +includes: + - phar://phpstan.phar/conf/bleedingEdge.neon + parameters: level: 5 paths: diff --git a/src/Model/TemplateEngine/Decorator/InspectorHintsFactory.php b/src/Model/TemplateEngine/Decorator/InspectorHintsFactory.php index 10ccfee..baf1712 100644 --- a/src/Model/TemplateEngine/Decorator/InspectorHintsFactory.php +++ b/src/Model/TemplateEngine/Decorator/InspectorHintsFactory.php @@ -13,10 +13,6 @@ */ class InspectorHintsFactory { - /** - * @param Random $random - * @phpstan-ignore property.onlyWritten - */ public function __construct( private readonly Random $random ) { From 3b0d5ae2ce818b19361c703d2e5c99264fe92a9f Mon Sep 17 00:00:00 2001 From: Thomas Hauschild <7961978+Morgy93@users.noreply.github.com> Date: Thu, 29 Jan 2026 23:32:57 +0100 Subject: [PATCH 15/19] #84 - Add PHP config check and clear PHPStan cache in CI --- .github/workflows/phpstan.yml | 11 ++++++++++- .../Decorator/InspectorHintsFactory.php | 5 ++++- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/.github/workflows/phpstan.yml b/.github/workflows/phpstan.yml index 5b3a345..ec89dda 100644 --- a/.github/workflows/phpstan.yml +++ b/.github/workflows/phpstan.yml @@ -47,6 +47,13 @@ jobs: php-version: "8.4" extensions: mbstring, intl, gd, xml, soap, zip, bcmath, pdo_mysql, curl, sockets tools: composer:v2 + ini-values: short_open_tag=Off, display_errors=On + + - name: Check PHP Configuration + run: | + php -v + php -i | grep "short_open_tag" + php --ri tokenizer | head -20 - name: Cache Composer packages id: composer-cache @@ -119,5 +126,7 @@ jobs: run: | echo "PHPStan Version:" vendor/bin/phpstan --version + echo "Clearing PHPStan cache..." + vendor/bin/phpstan clear-result-cache -c vendor/openforgeproject/mageforge/phpstan.neon echo "Running PHPStan Analysis with verbose output..." - vendor/bin/phpstan analyse -vvv -c vendor/openforgeproject/mageforge/phpstan.neon vendor/openforgeproject/mageforge/src + vendor/bin/phpstan analyse -vvv --no-progress -c vendor/openforgeproject/mageforge/phpstan.neon vendor/openforgeproject/mageforge/src diff --git a/src/Model/TemplateEngine/Decorator/InspectorHintsFactory.php b/src/Model/TemplateEngine/Decorator/InspectorHintsFactory.php index baf1712..b76c92e 100644 --- a/src/Model/TemplateEngine/Decorator/InspectorHintsFactory.php +++ b/src/Model/TemplateEngine/Decorator/InspectorHintsFactory.php @@ -35,10 +35,13 @@ public function create(array $data = []): InspectorHints ); } + // Create instance - property access extracted to help PHPStan recognize the read + $randomGenerator = $this->random; + return new InspectorHints( $subject, (bool)$showBlockHints, - $this->random + $randomGenerator ); } } From 8145b05d1f845c725d58bbe03574c866dd334ded Mon Sep 17 00:00:00 2001 From: Thomas Hauschild <7961978+Morgy93@users.noreply.github.com> Date: Thu, 29 Jan 2026 23:39:06 +0100 Subject: [PATCH 16/19] #84 - Debug: Show actual file content in CI vendor directory --- .github/workflows/phpstan.yml | 3 +++ src/Model/TemplateEngine/Decorator/InspectorHintsFactory.php | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/.github/workflows/phpstan.yml b/.github/workflows/phpstan.yml index ec89dda..81a7384 100644 --- a/.github/workflows/phpstan.yml +++ b/.github/workflows/phpstan.yml @@ -128,5 +128,8 @@ jobs: vendor/bin/phpstan --version echo "Clearing PHPStan cache..." vendor/bin/phpstan clear-result-cache -c vendor/openforgeproject/mageforge/phpstan.neon + echo "=== Checking actual file content in vendor ===" + cat vendor/openforgeproject/mageforge/src/Model/TemplateEngine/Decorator/InspectorHintsFactory.php | grep -A 20 "public function create" + echo "=== End of file content check ===" echo "Running PHPStan Analysis with verbose output..." vendor/bin/phpstan analyse -vvv --no-progress -c vendor/openforgeproject/mageforge/phpstan.neon vendor/openforgeproject/mageforge/src diff --git a/src/Model/TemplateEngine/Decorator/InspectorHintsFactory.php b/src/Model/TemplateEngine/Decorator/InspectorHintsFactory.php index b76c92e..6ee7835 100644 --- a/src/Model/TemplateEngine/Decorator/InspectorHintsFactory.php +++ b/src/Model/TemplateEngine/Decorator/InspectorHintsFactory.php @@ -37,7 +37,7 @@ public function create(array $data = []): InspectorHints // Create instance - property access extracted to help PHPStan recognize the read $randomGenerator = $this->random; - + return new InspectorHints( $subject, (bool)$showBlockHints, From cc7d94b776d81539939a7fd3260d235f7318125d Mon Sep 17 00:00:00 2001 From: Thomas Hauschild <7961978+Morgy93@users.noreply.github.com> Date: Thu, 29 Jan 2026 23:49:46 +0100 Subject: [PATCH 17/19] #84 - Workaround PHPStan 2.x bug: Remove readonly from factory property --- .github/workflows/phpstan.yml | 17 +---------------- .../Decorator/InspectorHintsFactory.php | 13 ++++++------- 2 files changed, 7 insertions(+), 23 deletions(-) diff --git a/.github/workflows/phpstan.yml b/.github/workflows/phpstan.yml index 81a7384..643b8cd 100644 --- a/.github/workflows/phpstan.yml +++ b/.github/workflows/phpstan.yml @@ -47,13 +47,6 @@ jobs: php-version: "8.4" extensions: mbstring, intl, gd, xml, soap, zip, bcmath, pdo_mysql, curl, sockets tools: composer:v2 - ini-values: short_open_tag=Off, display_errors=On - - - name: Check PHP Configuration - run: | - php -v - php -i | grep "short_open_tag" - php --ri tokenizer | head -20 - name: Cache Composer packages id: composer-cache @@ -124,12 +117,4 @@ jobs: - name: Run PHPStan working-directory: magento2 run: | - echo "PHPStan Version:" - vendor/bin/phpstan --version - echo "Clearing PHPStan cache..." - vendor/bin/phpstan clear-result-cache -c vendor/openforgeproject/mageforge/phpstan.neon - echo "=== Checking actual file content in vendor ===" - cat vendor/openforgeproject/mageforge/src/Model/TemplateEngine/Decorator/InspectorHintsFactory.php | grep -A 20 "public function create" - echo "=== End of file content check ===" - echo "Running PHPStan Analysis with verbose output..." - vendor/bin/phpstan analyse -vvv --no-progress -c vendor/openforgeproject/mageforge/phpstan.neon vendor/openforgeproject/mageforge/src + vendor/bin/phpstan analyse -c vendor/openforgeproject/mageforge/phpstan.neon vendor/openforgeproject/mageforge/src diff --git a/src/Model/TemplateEngine/Decorator/InspectorHintsFactory.php b/src/Model/TemplateEngine/Decorator/InspectorHintsFactory.php index 6ee7835..16feed4 100644 --- a/src/Model/TemplateEngine/Decorator/InspectorHintsFactory.php +++ b/src/Model/TemplateEngine/Decorator/InspectorHintsFactory.php @@ -13,9 +13,11 @@ */ class InspectorHintsFactory { - public function __construct( - private readonly Random $random - ) { + private Random $random; + + public function __construct(Random $random) + { + $this->random = $random; } /** @@ -35,13 +37,10 @@ public function create(array $data = []): InspectorHints ); } - // Create instance - property access extracted to help PHPStan recognize the read - $randomGenerator = $this->random; - return new InspectorHints( $subject, (bool)$showBlockHints, - $randomGenerator + $this->random ); } } From 488ccc17c83fdfb77e91082ffa74a093306f8f92 Mon Sep 17 00:00:00 2001 From: Thomas Hauschild <7961978+Morgy93@users.noreply.github.com> Date: Fri, 30 Jan 2026 00:06:50 +0100 Subject: [PATCH 18/19] fix: remove InspectorHintsFactory class --- .../Decorator/InspectorHintsFactory.php | 46 ------------------- 1 file changed, 46 deletions(-) delete mode 100644 src/Model/TemplateEngine/Decorator/InspectorHintsFactory.php diff --git a/src/Model/TemplateEngine/Decorator/InspectorHintsFactory.php b/src/Model/TemplateEngine/Decorator/InspectorHintsFactory.php deleted file mode 100644 index 16feed4..0000000 --- a/src/Model/TemplateEngine/Decorator/InspectorHintsFactory.php +++ /dev/null @@ -1,46 +0,0 @@ -random = $random; - } - - /** - * Create InspectorHints instance - * - * @param array $data - * @return InspectorHints - */ - public function create(array $data = []): InspectorHints - { - $subject = $data['subject'] ?? null; - $showBlockHints = $data['showBlockHints'] ?? false; - - if (!$subject instanceof TemplateEngineInterface) { - throw new \InvalidArgumentException( - 'Instance of "' . TemplateEngineInterface::class . '" is expected.' - ); - } - - return new InspectorHints( - $subject, - (bool)$showBlockHints, - $this->random - ); - } -} From 2632e49257dc54b3bf44e8f15fee17beb9487aa3 Mon Sep 17 00:00:00 2001 From: Thomas Hauschild <7961978+Morgy93@users.noreply.github.com> Date: Fri, 30 Jan 2026 00:10:30 +0100 Subject: [PATCH 19/19] fix: remove bleedingEdge configuration from phpstan --- phpstan.neon | 3 --- 1 file changed, 3 deletions(-) diff --git a/phpstan.neon b/phpstan.neon index 60afcbd..91e6453 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -1,6 +1,3 @@ -includes: - - phar://phpstan.phar/conf/bleedingEdge.neon - parameters: level: 5 paths: