From ca6127aed990968ffe4fc786bbc617f4b990cc5b Mon Sep 17 00:00:00 2001 From: Justin Beaty Date: Mon, 9 Dec 2024 08:17:46 -0800 Subject: [PATCH 1/8] Use new PHPStan plugin --- .phpstan.dist.neon | 4 +++- app/Mage.php | 5 +++-- composer.json | 5 ++++- 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/.phpstan.dist.neon b/.phpstan.dist.neon index 0917bc73c1d..c55e7ae8e70 100644 --- a/.phpstan.dist.neon +++ b/.phpstan.dist.neon @@ -1,9 +1,11 @@ includes: - - vendor/macopedia/phpstan-magento1/extension.neon + - vendor/mahocommerce/maho-phpstan-plugin/extension.neon - .phpstan.dist.baseline.neon - phar://phpstan.phar/conf/bleedingEdge.neon parameters: magentoRootPath: %currentWorkingDirectory% + bootstrapFiles: + - app/Mage.php fileExtensions: - php - phtml diff --git a/app/Mage.php b/app/Mage.php index bc55f3ae05b..a2ba9f5b07f 100644 --- a/app/Mage.php +++ b/app/Mage.php @@ -14,8 +14,9 @@ * @license https://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) */ -define('DS', DIRECTORY_SEPARATOR); -define('PS', PATH_SEPARATOR); +defined('DS') || define('DS', DIRECTORY_SEPARATOR); +defined('PS') || define('PS', PATH_SEPARATOR); + define('BP', dirname(__DIR__)); Mage::register('original_include_path', get_include_path()); diff --git a/composer.json b/composer.json index e900f684dfb..2af6943fe99 100644 --- a/composer.json +++ b/composer.json @@ -6,6 +6,9 @@ "AFL-3.0" ], "type": "magento-source", + "repositories": [ + { "type": "git", "url": "https://github.com/justinbeaty/maho-phpstan-plugin.git" } + ], "require": { "php": ">=7.4 <8.5", "ext-ctype": "*", @@ -50,8 +53,8 @@ "composer/composer": "^2.7", "dealerdirect/phpcodesniffer-composer-installer": "^1.0.0", "friendsofphp/php-cs-fixer": "^3.4", - "macopedia/phpstan-magento1": "^1.0.5", "magento-ecg/coding-standard": "^4.5", + "mahocommerce/maho-phpstan-plugin": "dev-topic-v3", "openmage/dev-meta-package": "^1.0.5", "perftools/php-profiler": "^1.1", "phpcompatibility/php-compatibility": "^9.3", From 3adb997158ebb7b537cc66657f2c9bc4407f0b70 Mon Sep 17 00:00:00 2001 From: Justin Beaty Date: Mon, 9 Dec 2024 08:24:00 -0800 Subject: [PATCH 2/8] Allow passing `'is_installed' => false` to Mage::init to disable loading local.xml --- app/Mage.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/Mage.php b/app/Mage.php index a2ba9f5b07f..f7e7e81df4f 100644 --- a/app/Mage.php +++ b/app/Mage.php @@ -785,8 +785,8 @@ public static function run($code = '', $type = 'store', $options = []) */ private static function _setIsInstalled($options = []) { - if (isset($options['is_installed']) && $options['is_installed']) { - self::$_isInstalled = true; + if (isset($options['is_installed'])) { + self::$_isInstalled = (bool) $options['is_installed']; } } From ff0ca3d4c329cbbc6f6705dd0a9292a694203260 Mon Sep 17 00:00:00 2001 From: Justin Beaty Date: Mon, 9 Dec 2024 08:38:24 -0800 Subject: [PATCH 3/8] Bring some exceptions under control & cleanup get instance methods --- app/Mage.php | 166 +++++++----- .../Mage/Core/Controller/Varien/Front.php | 2 +- app/code/core/Mage/Core/Model/Config.php | 237 ++++++++++-------- app/code/core/Mage/Core/Model/Layout.php | 61 ++--- app/code/core/Mage/Sales/Model/Config.php | 4 +- 5 files changed, 258 insertions(+), 212 deletions(-) diff --git a/app/Mage.php b/app/Mage.php index f7e7e81df4f..44c8a99e874 100644 --- a/app/Mage.php +++ b/app/Mage.php @@ -279,7 +279,7 @@ public static function register($key, $value, $graceful = false) if ($graceful) { return; } - self::throwException('Mage registry key "' . $key . '" already exists'); + self::throwException("Mage registry key $key already exists"); } self::$_registry[$key] = $value; } @@ -332,7 +332,7 @@ public static function setRoot($appRoot = '') if (is_dir($appRoot) && is_readable($appRoot)) { self::$_appRoot = $appRoot; } else { - self::throwException($appRoot . ' is not a directory or not readable by this user'); + self::throwException("$appRoot is not a directory or not readable by this user"); } } @@ -494,14 +494,18 @@ public static function getConfig() * @param callback $callback * @param array $data * @param string $observerName - * @param string $observerClass + * @param class-string|'' $observerClass * @return Varien_Event_Collection + * @throws Mage_Core_Exception */ public static function addObserver($eventName, $callback, $data = [], $observerName = '', $observerClass = '') { if ($observerClass == '') { $observerClass = 'Varien_Event_Observer'; } + if (!class_exists($observerClass)) { + self::throwException("Invalid observer class: $observerClass"); + } $observer = new $observerClass(); $observer->setName($observerName)->addData($data)->setEventName($eventName)->setCallback($callback); return self::getEvents()->addObserver($observer); @@ -525,128 +529,157 @@ public static function dispatchEvent($name, array $data = []) } /** - * Retrieve model object + * Retrieve helper singleton by alias * - * @link Mage_Core_Model_Config::getModelInstance - * @param string $modelClass - * @param array|string|object $arguments - * @return Mage_Core_Model_Abstract|false + * ```php + * $helper = Mage::helper('core'); // Mage_Core_Helper_Data + * $helper = Mage::helper('core/url'); // Mage_Core_Helper_Url + * ``` + * + * @param string $helperAlias + * @return Mage_Core_Helper_Abstract|false */ - public static function getModel($modelClass = '', $arguments = []) + public static function helper($helperAlias) { - return self::getConfig()->getModelInstance($modelClass, $arguments); + $registryKey = '_helper/' . $helperAlias; + if (!isset(self::$_registry[$registryKey])) { + self::register($registryKey, self::getConfig()->getHelperInstance($helperAlias)); + } + return self::$_registry[$registryKey]; } /** - * Retrieve model object singleton + * Retrieve model instance by alias + * + * ```php + * $model = Mage::getModel('core/store'); // Mage_Core_Model_Store + * ``` * - * @param string $modelClass - * @return Mage_Core_Model_Abstract|false + * @param string $modelAlias + * @param array|string|object $arguments + * @return Mage_Core_Model_Abstract|false */ - public static function getSingleton($modelClass = '', array $arguments = []) + public static function getModel($modelAlias, $arguments = []) { - $registryKey = '_singleton/' . $modelClass; - if (!isset(self::$_registry[$registryKey])) { - self::register($registryKey, self::getModel($modelClass, $arguments)); - } - return self::$_registry[$registryKey]; + return self::getConfig()->getModelInstance($modelAlias, $arguments); } /** - * Retrieve object of resource model + * Retrieve model singleton by alias + * + * ```php + * $model = Mage::getModel('core/session'); // Mage_Core_Model_Session + * ``` * - * @param string $modelClass - * @param array $arguments - * @return Mage_Core_Model_Resource_Db_Collection_Abstract|false + * @param string $modelAlias + * @return Mage_Core_Model_Abstract|false */ - public static function getResourceModel($modelClass, $arguments = []) + public static function getSingleton($modelAlias, array $arguments = []) { - return self::getConfig()->getResourceModelInstance($modelClass, $arguments); + $registryKey = '_singleton/' . $modelAlias; + if (!isset(self::$_registry[$registryKey])) { + self::register($registryKey, self::getModel($modelAlias, $arguments)); + } + return self::$_registry[$registryKey]; } /** - * Retrieve Controller instance by ClassName + * Retrieve resource model by alias * - * @param string $class - * @param Mage_Core_Controller_Request_Http $request - * @param Mage_Core_Controller_Response_Http $response - * @return Mage_Core_Controller_Front_Action + * ```php + * $model = Mage::getResourceModel('core/store_collection'); // Mage_Core_Model_Resource_Store_Collection + * ``` + * + * @param string $modelAlias + * @param array $arguments + * @return Mage_Core_Model_Resource_Db_Collection_Abstract|false */ - public static function getControllerInstance($class, $request, $response, array $invokeArgs = []) + public static function getResourceModel($modelAlias, $arguments = []) { - return new $class($request, $response, $invokeArgs); + return self::getConfig()->getResourceModelInstance($modelAlias, $arguments); } /** - * Retrieve resource model object singleton + * Retrieve resource model singleton by alias * - * @param string $modelClass - * @return object + * ```php + * $model = Mage::getResourceSingleton('core/session'); // Mage_Core_Model_Resource_Session + * ``` + * + * @param string $modelAlias + * @return Mage_Core_Model_Resource_Db_Collection_Abstract|false */ - public static function getResourceSingleton($modelClass = '', array $arguments = []) + public static function getResourceSingleton($modelAlias, array $arguments = []) { - $registryKey = '_resource_singleton/' . $modelClass; + $registryKey = '_resource_singleton/' . $modelAlias; if (!isset(self::$_registry[$registryKey])) { - self::register($registryKey, self::getResourceModel($modelClass, $arguments)); + self::register($registryKey, self::getResourceModel($modelAlias, $arguments)); } return self::$_registry[$registryKey]; } /** - * Retrieve block object + * Retrieve resource helper model singleton * - * @param string $type - * @return Mage_Core_Block_Abstract|false + * ```php + * $model = Mage::getResourceHelper('core'); // Mage_Core_Model_Resource_Helper_Mysql4 + * ``` + * + * @param string $moduleAlias + * @return Mage_Core_Model_Resource_Helper_Abstract|false */ - public static function getBlockSingleton($type) + public static function getResourceHelper($moduleAlias) { - $action = self::app()->getFrontController()->getAction(); - return $action ? $action->getLayout()->getBlockSingleton($type) : false; + $registryKey = '_resource_helper/' . $moduleAlias; + if (!isset(self::$_registry[$registryKey])) { + self::register($registryKey, self::getConfig()->getResourceHelperInstance($moduleAlias)); + } + return self::$_registry[$registryKey]; } /** - * Retrieve helper object + * Retrieve Controller instance by ClassName * - * @param string $name the helper name - * @return Mage_Core_Helper_Abstract + * @param class-string $class + * @param Mage_Core_Controller_Request_Http $request + * @param Mage_Core_Controller_Response_Http $response + * @return Mage_Core_Controller_Front_Action + * @throws Mage_Core_Exception */ - public static function helper($name) + public static function getControllerInstance($class, $request, $response, array $invokeArgs = []) { - $registryKey = '_helper/' . $name; - if (!isset(self::$_registry[$registryKey])) { - $helperClass = self::getConfig()->getHelperClassName($name); - self::register($registryKey, new $helperClass()); + if (!class_exists($class)) { + self::throwException("Invalid controller class: $class"); } - return self::$_registry[$registryKey]; + return new $class($request, $response, $invokeArgs); } /** - * Retrieve resource helper object + * Retrieve block object * - * @param string $moduleName - * @return Mage_Core_Model_Resource_Helper_Abstract + * @param string $type + * @return Mage_Core_Block_Abstract|false */ - public static function getResourceHelper($moduleName) + public static function getBlockSingleton($type) { - $registryKey = '_resource_helper/' . $moduleName; - if (!isset(self::$_registry[$registryKey])) { - $helperClass = self::getConfig()->getResourceHelper($moduleName); - self::register($registryKey, $helperClass); - } - return self::$_registry[$registryKey]; + $action = self::app()->getFrontController()->getAction(); + return $action ? $action->getLayout()->getBlockSingleton($type) : false; } /** * Return new exception by module to be thrown * - * @param string $module + * @param string $moduleName * @param string $message * @param integer $code * @return Mage_Core_Exception */ - public static function exception($module = 'Mage_Core', $message = '', $code = 0) + public static function exception($moduleName = 'Mage_Core', $message = '', $code = 0) { - $className = $module . '_Exception'; + $className = $moduleName . '_Exception'; + if (!class_exists($className)) { + $className = 'Mage_Core_Exception'; + } return new $className($message, $code); } @@ -655,6 +688,7 @@ public static function exception($module = 'Mage_Core', $message = '', $code = 0 * * @param string $message * @param string $messageStorage + * @return never * @throws Mage_Core_Exception */ public static function throwException($message, $messageStorage = null) diff --git a/app/code/core/Mage/Core/Controller/Varien/Front.php b/app/code/core/Mage/Core/Controller/Varien/Front.php index 6f9081e8a8f..cec0b688d48 100644 --- a/app/code/core/Mage/Core/Controller/Varien/Front.php +++ b/app/code/core/Mage/Core/Controller/Varien/Front.php @@ -18,7 +18,7 @@ * @category Mage * @package Mage_Core * - * @method Mage_Core_Controller_Varien_Action getAction() + * @method Mage_Core_Controller_Varien_Action|null getAction() * @method $this setAction(Mage_Core_Controller_Varien_Action $value) * @method bool getNoRender() */ diff --git a/app/code/core/Mage/Core/Model/Config.php b/app/code/core/Mage/Core/Model/Config.php index dcc7b2f8941..8a9b5ecc6ef 100644 --- a/app/code/core/Mage/Core/Model/Config.php +++ b/app/code/core/Mage/Core/Model/Config.php @@ -1164,31 +1164,6 @@ public function getModuleConfig($moduleName = '') } } - /** - * Get module setup class instance. - * - * Defaults to Mage_Core_Setup - * - * @param string|Mage_Core_Model_Config_Element $module - * @return object - */ - public function getModuleSetup($module = '') - { - $className = 'Mage_Core_Setup'; - if ($module !== '') { - if (is_string($module)) { - $module = $this->getModuleConfig($module); - } - if (isset($module->setup)) { - $moduleClassName = $module->setup->getClassName(); - if (!empty($moduleClassName)) { - $className = $moduleClassName; - } - } - } - return new $className($module); - } - /** * Get base filesystem directory. depends on $type * @@ -1329,21 +1304,49 @@ public function getPathVars($args = null) return $path; } + /** + * Retrieve class name from config.xml node + */ + public function getNodeClassName(string $path): string + { + $config = Mage::getConfig()->getNode($path); + if (!$config) { + return false; + } + return $config->getClassName(); + } + + /** + * Retrieve class instance from config.xml node + * + * @param string $path + * @return Mage_Core_Model_Abstract|false + */ + public function getNodeClassInstance($path) + { + $className = $this->getNodeClassName($path); + if ($className === false || !class_exists($className)) { + return false; + } + // phpcs:ignore Ecg.Classes.ObjectInstantiation.DirectInstantiation + return new $className(); + } + /** * Retrieve class name by class group * * @param string $groupType currently supported model, block, helper - * @param string $classId slash separated class identifier, ex. group/class + * @param string $classAlias slash separated class identifier, ex. group/class * @param string $groupRootNode optional config path for group config * @return string */ - public function getGroupedClassName($groupType, $classId, $groupRootNode = null) + public function getGroupedClassName($groupType, $classAlias, $groupRootNode = null) { if (empty($groupRootNode)) { $groupRootNode = 'global/' . $groupType . 's'; } - $classArr = explode('/', trim($classId)); + $classArr = explode('/', trim($classAlias)); $group = $classArr[0]; $class = !empty($classArr[1]) ? $classArr[1] : null; @@ -1395,8 +1398,8 @@ public function getGroupedClassName($groupType, $classId, $groupRootNode = null) /** * Retrieve block class name * - * @param string $blockType - * @return string + * @param string $blockType + * @return string */ public function getBlockClassName($blockType) { @@ -1409,109 +1412,144 @@ public function getBlockClassName($blockType) /** * Retrieve helper class name * - * @param string $helperName - * @return string + * @param string $helperAlias + * @return string */ - public function getHelperClassName($helperName) + public function getHelperClassName($helperAlias) { - if (!str_contains($helperName, '/')) { - $helperName .= '/data'; + if (!str_contains($helperAlias, '/')) { + $helperAlias .= '/data'; } - return $this->getGroupedClassName('helper', $helperName); + return $this->getGroupedClassName('helper', $helperAlias); } /** - * Retrieve resource helper instance - * - * Example: - * $config->getResourceHelper('cms') - * will instantiate Mage_Cms_Model_Resource_Helper_ - * - * @param string $moduleName - * @return Mage_Core_Model_Resource_Helper_Abstract|false + * Retrieve helper instance */ - public function getResourceHelper($moduleName) + public function getHelperInstance(string $helperAlias): Mage_Core_Helper_Abstract|false { - $connectionModel = $this->_getResourceConnectionModel($moduleName); - $helperClass = sprintf('%s/helper_%s', $moduleName, $connectionModel); - $helperClassName = $this->_getResourceModelFactoryClassName($helperClass); - if ($helperClassName) { - return $this->getModelInstance($helperClassName, $moduleName); + $className = $this->getHelperClassName($helperAlias); + if (!class_exists($className)) { + return false; } - - return false; + Varien_Profiler::start('CORE::create_object_of::' . $className); + // phpcs:ignore Ecg.Classes.ObjectInstantiation.DirectInstantiation + $obj = new $className(); + Varien_Profiler::stop('CORE::create_object_of::' . $className); + return $obj; } /** - * Retrieve module class name + * Retrieve model class name * - * @param string $modelClass - * @return string + * @param string $modelAlias + * @return string */ - public function getModelClassName($modelClass) + public function getModelClassName($modelAlias) { - $modelClass = trim($modelClass); - if (!str_contains($modelClass, '/')) { - return $modelClass; + $modelAlias = trim($modelAlias); + if (!str_contains($modelAlias, '/')) { + return $modelAlias; } - return $this->getGroupedClassName('model', $modelClass); + return $this->getGroupedClassName('model', $modelAlias); } /** - * Get model class instance. - * - * Example: - * $config->getModelInstance('catalog/product') + * Retrieve model instance * - * Will instantiate Mage_Catalog_Model_Resource_Product - * - * @param string $modelClass + * @param string $modelAlias * @param array|object $constructArguments * @return Mage_Core_Model_Abstract|false - * @see Mage_Catalog_Model_Resource_Product */ - public function getModelInstance($modelClass = '', $constructArguments = []) + public function getModelInstance($modelAlias, $constructArguments = []) { - $className = $this->getModelClassName($modelClass); - if (class_exists($className)) { - Varien_Profiler::start('CORE::create_object_of::' . $className); - $obj = new $className($constructArguments); - Varien_Profiler::stop('CORE::create_object_of::' . $className); - return $obj; - } else { + $className = $this->getModelClassName($modelAlias); + if (!class_exists($className)) { return false; } + Varien_Profiler::start('CORE::create_object_of::' . $className); + // phpcs:ignore Ecg.Classes.ObjectInstantiation.DirectInstantiation + $obj = new $className($constructArguments); + Varien_Profiler::stop('CORE::create_object_of::' . $className); + return $obj; } /** - * @param string $path - * @return bool + * Retrieve resource model class name + * + * @param string $modelAlias + * @return string|false */ - public function getNodeClassInstance($path) + public function getResourceModelClassName($modelAlias) { - $config = Mage::getConfig()->getNode($path); - if (!$config) { - return false; - } else { - $className = $config->getClassName(); - return new $className(); + $factoryName = $this->_getResourceModelFactoryClassName($modelAlias); + if ($factoryName) { + return $this->getModelClassName($factoryName); } + return false; } /** - * Get resource model object by alias + * Retrieve resource model instance * - * @param string $modelClass - * @param array $constructArguments + * @param string $modelAlias + * @param array $constructArguments * @return Mage_Core_Model_Resource_Db_Collection_Abstract|false */ - public function getResourceModelInstance($modelClass = '', $constructArguments = []) + public function getResourceModelInstance($modelAlias, $constructArguments = []) + { + $className = $this->getResourceModelClassName($modelAlias); + if ($className === false || !class_exists($className)) { + return false; + } + Varien_Profiler::start('CORE::create_object_of::' . $className); + // phpcs:ignore Ecg.Classes.ObjectInstantiation.DirectInstantiation + $obj = new $className($constructArguments); + Varien_Profiler::stop('CORE::create_object_of::' . $className); + return $obj; + } + + /** + * Retrieve resource helper class name + */ + public function getResourceHelperClassName(string $moduleAlias): string|false + { + $connectionModel = $this->_getResourceConnectionModel($moduleAlias); + $modelClass = sprintf('%s/helper_%s', $moduleAlias, $connectionModel); + + return $this->getResourceModelClassName($modelClass); + } + + /** + * Retrieve resource helper instance + * + * @param string $moduleAlias + * @return Mage_Core_Model_Resource_Helper_Abstract|false + */ + public function getResourceHelperInstance(string $moduleAlias): Mage_Core_Model_Resource_Helper_Abstract|false { - $factoryName = $this->_getResourceModelFactoryClassName($modelClass); - if (!$factoryName) { + $className = $this->getResourceHelperClassName($moduleAlias); + if ($className === false || !class_exists($className)) { return false; } - return $this->getModelInstance($factoryName, $constructArguments); + Varien_Profiler::start('CORE::create_object_of::' . $className); + // phpcs:ignore Ecg.Classes.ObjectInstantiation.DirectInstantiation + $obj = new $className(); + Varien_Profiler::stop('CORE::create_object_of::' . $className); + return $obj; + } + + /** + * Retrieve resource helper instance + * + * @param string $moduleAlias + * @return Mage_Core_Model_Resource_Helper_Abstract|false + * @deprecated Use getResourceHelperInstance() method instead + * @see Mage_Core_Model_Config::getResourceHelperInstance() + */ + public function getResourceHelper($moduleAlias) + { + return $this->getResourceHelperInstance($moduleAlias); } /** @@ -1774,21 +1812,6 @@ protected function _getResourceModelFactoryClassName($modelClass) return $resourceModel . '/' . $model; } - /** - * Get a resource model class name - * - * @param string $modelClass - * @return string|false - */ - public function getResourceModelClassName($modelClass) - { - $factoryName = $this->_getResourceModelFactoryClassName($modelClass); - if ($factoryName) { - return $this->getModelClassName($factoryName); - } - return false; - } - /** * Makes all events to lower-case * diff --git a/app/code/core/Mage/Core/Model/Layout.php b/app/code/core/Mage/Core/Model/Layout.php index ec76702f1d3..229ee599de4 100644 --- a/app/code/core/Mage/Core/Model/Layout.php +++ b/app/code/core/Mage/Core/Model/Layout.php @@ -443,17 +443,21 @@ public function unsetBlock($name) /** * Block Factory * - * @param string $type - * @param string|null $name - * @return Mage_Core_Block_Abstract|false + * @param string|Mage_Core_Block_Abstract $type + * @param string $name + * @return Mage_Core_Block_Abstract|false */ public function createBlock($type, $name = '', array $attributes = []) { - try { - $block = $this->_getBlockInstance($type, $attributes); - } catch (Exception $e) { - Mage::logException($e); - return false; + if ($type instanceof Mage_Core_Block_Abstract) { + $block = $type; + } else { + try { + $block = $this->_getBlockInstance($type, $attributes); + } catch (Exception $e) { + Mage::logException($e); + return false; + } } if (empty($name) || $name[0] === '.') { @@ -462,8 +466,6 @@ public function createBlock($type, $name = '', array $attributes = []) $block->setAnonSuffix(substr($name, 1)); } $name = 'ANONYMOUS_' . count($this->_blocks); - } elseif (isset($this->_blocks[$name]) && Mage::getIsDeveloperMode()) { - //Mage::throwException(Mage::helper('core')->__('Block with name "%s" already exists', $name)); } $block->setType($type); @@ -491,24 +493,20 @@ public function addBlock($block, $blockName) /** * Create block object instance based on block type * - * @param string $block + * @param string $type * @return Mage_Core_Block_Abstract + * @throws Mage_Core_Exception */ protected function _getBlockInstance($block, array $attributes = []) { - if (is_string($block)) { - if (str_contains($block, '/')) { - if (!$block = Mage::getConfig()->getBlockClassName($block)) { - Mage::throwException(Mage::helper('core')->__('Invalid block type: %s', $block)); - } - } - if (class_exists($block, false) || mageFindClassFile($block)) { - // phpcs:ignore Ecg.Classes.ObjectInstantiation.DirectInstantiation - $block = new $block($attributes); - } + $className = Mage::getConfig()->getBlockClassName($type); + if ($className === false || !class_exists($className)) { + Mage::throwException(Mage::helper('core')->__('Invalid block type: %s', $type)); } + // phpcs:ignore Ecg.Classes.ObjectInstantiation.DirectInstantiation + $block = new $className($attributes); if (!$block instanceof Mage_Core_Block_Abstract) { - Mage::throwException(Mage::helper('core')->__('Invalid block type: %s', $block)); + Mage::throwException(Mage::helper('core')->__('Invalid block type: %s', $type)); } return $block; } @@ -592,23 +590,14 @@ public function getMessagesBlock() /** * @param string $type * @return Mage_Core_Block_Abstract + * @throws Mage_Core_Exception */ public function getBlockSingleton($type) { if (!isset($this->_helpers[$type])) { - $className = Mage::getConfig()->getBlockClassName($type); - if (!$className) { - Mage::throwException(Mage::helper('core')->__('Invalid block type: %s', $type)); - } - - // phpcs:ignore Ecg.Classes.ObjectInstantiation.DirectInstantiation - $helper = new $className(); - if ($helper) { - if ($helper instanceof Mage_Core_Block_Abstract) { - $helper->setLayout($this); - } - $this->_helpers[$type] = $helper; - } + $helper = $this->_getBlockInstance($type); + $helper->setLayout($this); + $this->_helpers[$type] = $helper; } return $this->_helpers[$type]; } @@ -622,7 +611,7 @@ public function getBlockSingleton($type) public function helper($name) { $helper = Mage::helper($name); - if (!$helper) { + if ($helper === false) { return false; } return $helper->setLayout($this); diff --git a/app/code/core/Mage/Sales/Model/Config.php b/app/code/core/Mage/Sales/Model/Config.php index bdcb055623a..5ff9e74fc41 100644 --- a/app/code/core/Mage/Sales/Model/Config.php +++ b/app/code/core/Mage/Sales/Model/Config.php @@ -24,7 +24,7 @@ class Mage_Sales_Model_Config /** * @param string $type - * @return bool + * @return Mage_Core_Model_Abstract|false */ public function getQuoteRuleConditionInstance($type) { @@ -33,7 +33,7 @@ public function getQuoteRuleConditionInstance($type) /** * @param string $type - * @return bool + * @return Mage_Core_Model_Abstract|false */ public function getQuoteRuleActionInstance($type) { From ad45f4bb53a9c0cb2532fe9c00c7929560d84717 Mon Sep 17 00:00:00 2001 From: Justin Beaty Date: Mon, 9 Dec 2024 09:14:38 -0800 Subject: [PATCH 4/8] fixes --- app/code/core/Mage/Core/Model/Config.php | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/app/code/core/Mage/Core/Model/Config.php b/app/code/core/Mage/Core/Model/Config.php index 8a9b5ecc6ef..0b7df8bf4c9 100644 --- a/app/code/core/Mage/Core/Model/Config.php +++ b/app/code/core/Mage/Core/Model/Config.php @@ -1306,8 +1306,10 @@ public function getPathVars($args = null) /** * Retrieve class name from config.xml node + * + * @return string|false */ - public function getNodeClassName(string $path): string + public function getNodeClassName(string $path) { $config = Mage::getConfig()->getNode($path); if (!$config) { @@ -1425,8 +1427,10 @@ public function getHelperClassName($helperAlias) /** * Retrieve helper instance + * + * @return Mage_Core_Helper_Abstract|false */ - public function getHelperInstance(string $helperAlias): Mage_Core_Helper_Abstract|false + public function getHelperInstance(string $helperAlias) { $className = $this->getHelperClassName($helperAlias); if (!class_exists($className)) { @@ -1523,10 +1527,9 @@ public function getResourceHelperClassName(string $moduleAlias): string|false /** * Retrieve resource helper instance * - * @param string $moduleAlias * @return Mage_Core_Model_Resource_Helper_Abstract|false */ - public function getResourceHelperInstance(string $moduleAlias): Mage_Core_Model_Resource_Helper_Abstract|false + public function getResourceHelperInstance(string $moduleAlias) { $className = $this->getResourceHelperClassName($moduleAlias); if ($className === false || !class_exists($className)) { From 6a3a965382537ef6ae9beed886321ecd1b79e14c Mon Sep 17 00:00:00 2001 From: Justin Beaty Date: Mon, 9 Dec 2024 13:35:20 -0800 Subject: [PATCH 5/8] fixes --- app/code/core/Mage/Core/Model/Config.php | 2 +- app/code/core/Mage/Core/Model/Layout.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/code/core/Mage/Core/Model/Config.php b/app/code/core/Mage/Core/Model/Config.php index 0b7df8bf4c9..f956cb83d28 100644 --- a/app/code/core/Mage/Core/Model/Config.php +++ b/app/code/core/Mage/Core/Model/Config.php @@ -1537,7 +1537,7 @@ public function getResourceHelperInstance(string $moduleAlias) } Varien_Profiler::start('CORE::create_object_of::' . $className); // phpcs:ignore Ecg.Classes.ObjectInstantiation.DirectInstantiation - $obj = new $className(); + $obj = new $className($moduleAlias); Varien_Profiler::stop('CORE::create_object_of::' . $className); return $obj; } diff --git a/app/code/core/Mage/Core/Model/Layout.php b/app/code/core/Mage/Core/Model/Layout.php index 229ee599de4..fe27d08466b 100644 --- a/app/code/core/Mage/Core/Model/Layout.php +++ b/app/code/core/Mage/Core/Model/Layout.php @@ -497,7 +497,7 @@ public function addBlock($block, $blockName) * @return Mage_Core_Block_Abstract * @throws Mage_Core_Exception */ - protected function _getBlockInstance($block, array $attributes = []) + protected function _getBlockInstance($type, array $attributes = []) { $className = Mage::getConfig()->getBlockClassName($type); if ($className === false || !class_exists($className)) { From ea2f44106103b85e439d8ad237aab3a2794d2e5c Mon Sep 17 00:00:00 2001 From: Justin Beaty Date: Tue, 10 Dec 2024 16:42:55 -0800 Subject: [PATCH 6/8] fix --- app/code/core/Mage/Core/Model/Config.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app/code/core/Mage/Core/Model/Config.php b/app/code/core/Mage/Core/Model/Config.php index f956cb83d28..3f93ab1661b 100644 --- a/app/code/core/Mage/Core/Model/Config.php +++ b/app/code/core/Mage/Core/Model/Config.php @@ -1515,8 +1515,10 @@ public function getResourceModelInstance($modelAlias, $constructArguments = []) /** * Retrieve resource helper class name + * + * @return string|false */ - public function getResourceHelperClassName(string $moduleAlias): string|false + public function getResourceHelperClassName(string $moduleAlias) { $connectionModel = $this->_getResourceConnectionModel($moduleAlias); $modelClass = sprintf('%s/helper_%s', $moduleAlias, $connectionModel); From 4586539eb8d45b99255c06eff548391f25f62287 Mon Sep 17 00:00:00 2001 From: Justin Beaty Date: Thu, 26 Dec 2024 07:36:09 -0800 Subject: [PATCH 7/8] change plugin fork --- .phpstan.dist.neon | 4 +--- composer.json | 20 ++++++++++++++++++-- composer.lock | 38 ++++++++------------------------------ 3 files changed, 27 insertions(+), 35 deletions(-) diff --git a/.phpstan.dist.neon b/.phpstan.dist.neon index c55e7ae8e70..0917bc73c1d 100644 --- a/.phpstan.dist.neon +++ b/.phpstan.dist.neon @@ -1,11 +1,9 @@ includes: - - vendor/mahocommerce/maho-phpstan-plugin/extension.neon + - vendor/macopedia/phpstan-magento1/extension.neon - .phpstan.dist.baseline.neon - phar://phpstan.phar/conf/bleedingEdge.neon parameters: magentoRootPath: %currentWorkingDirectory% - bootstrapFiles: - - app/Mage.php fileExtensions: - php - phtml diff --git a/composer.json b/composer.json index 2af6943fe99..a45b9571d2c 100644 --- a/composer.json +++ b/composer.json @@ -7,7 +7,23 @@ ], "type": "magento-source", "repositories": [ - { "type": "git", "url": "https://github.com/justinbeaty/maho-phpstan-plugin.git" } + { + "type": "package", + "package": { + "name": "macopedia/phpstan-magento1", + "version": "dev-topic-om", + "source": { + "url": "https://github.com/justinbeaty/maho-phpstan-plugin.git", + "type": "git", + "reference": "topic-om" + }, + "autoload": { + "psr-4": { + "PHPStanMagento1\\": "src/" + } + } + } + } ], "require": { "php": ">=7.4 <8.5", @@ -53,8 +69,8 @@ "composer/composer": "^2.7", "dealerdirect/phpcodesniffer-composer-installer": "^1.0.0", "friendsofphp/php-cs-fixer": "^3.4", + "macopedia/phpstan-magento1": "dev-topic-om", "magento-ecg/coding-standard": "^4.5", - "mahocommerce/maho-phpstan-plugin": "dev-topic-v3", "openmage/dev-meta-package": "^1.0.5", "perftools/php-profiler": "^1.1", "phpcompatibility/php-compatibility": "^9.3", diff --git a/composer.lock b/composer.lock index 2d5867d6a6a..cbd0032c3cc 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "726cec3c24c9211dd8f0eeeed8901420", + "content-hash": "637bdcb23971cd3c7048f1af60c2baf7", "packages": [ { "name": "colinmollenhour/cache-backend-redis", @@ -3796,42 +3796,18 @@ }, { "name": "macopedia/phpstan-magento1", - "version": "v1.1.0", + "version": "dev-topic-om", "source": { "type": "git", - "url": "https://github.com/macopedia/phpstan-magento1.git", - "reference": "01418cc9a536ffbf298fdf7ea3b9fac1f87a0508" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/macopedia/phpstan-magento1/zipball/01418cc9a536ffbf298fdf7ea3b9fac1f87a0508", - "reference": "01418cc9a536ffbf298fdf7ea3b9fac1f87a0508", - "shasum": "" - }, - "require": { - "php": ">= 7.4", - "phpstan/phpstan": "^1.12.11 | ^2.0.2" - }, - "replace": { - "inviqa/phpstan-magento1": "0.1.5", - "vianetz/phpstan-magento1": "0.1.5" + "url": "https://github.com/justinbeaty/maho-phpstan-plugin.git", + "reference": "topic-om" }, "type": "library", "autoload": { "psr-4": { "PHPStanMagento1\\": "src/" } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "description": "Extension for PHPStan to allow analysis of Magento 1 code.", - "support": { - "issues": "https://github.com/macopedia/phpstan-magento1/issues", - "source": "https://github.com/macopedia/phpstan-magento1/tree/v1.1.0" - }, - "time": "2024-11-19T10:50:38+00:00" + } }, { "name": "magento-ecg/coding-standard", @@ -7489,7 +7465,9 @@ ], "aliases": [], "minimum-stability": "dev", - "stability-flags": {}, + "stability-flags": { + "macopedia/phpstan-magento1": 20 + }, "prefer-stable": true, "prefer-lowest": false, "platform": { From 37edae109e5c4fedad0e9d835cf24b5d7ed44f62 Mon Sep 17 00:00:00 2001 From: Justin Beaty Date: Fri, 27 Dec 2024 08:42:46 -0800 Subject: [PATCH 8/8] Fix getBlockSingleton --- app/code/core/Mage/Core/Model/Layout.php | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/app/code/core/Mage/Core/Model/Layout.php b/app/code/core/Mage/Core/Model/Layout.php index fe27d08466b..1acfa2ea6ef 100644 --- a/app/code/core/Mage/Core/Model/Layout.php +++ b/app/code/core/Mage/Core/Model/Layout.php @@ -595,8 +595,15 @@ public function getMessagesBlock() public function getBlockSingleton($type) { if (!isset($this->_helpers[$type])) { - $helper = $this->_getBlockInstance($type); - $helper->setLayout($this); + $className = Mage::getConfig()->getBlockClassName($type); + if ($className === false || !class_exists($className)) { + Mage::throwException(Mage::helper('core')->__('Invalid block type: %s', $type)); + } + // phpcs:ignore Ecg.Classes.ObjectInstantiation.DirectInstantiation + $helper = new $className(); + if ($helper instanceof Mage_Core_Block_Abstract) { + $helper->setLayout($this); + } $this->_helpers[$type] = $helper; } return $this->_helpers[$type];