Magento specific extension for phpstan

Overview

bitexpert/phpstan-magento

This package provides some additional features for PHPStan to make it work for Magento 2 projects.

Build Status Coverage Status

Installation

The preferred way of installing bitexpert/phpstan-magento is through Composer. You can add bitexpert/phpstan-magento as a dev dependency, as follows:

composer.phar require --dev bitexpert/phpstan-magento

Include extension.neon and the autoloader.php file in your project's PHPStan config:

parameters:
	bootstrapFiles:
		- vendor/bitexpert/phpstan-magento/autoload.php
includes:
	- vendor/bitexpert/phpstan-magento/extension.neon

⚠️ When you use a version of phpstan/phpstan lower than 0.12.26 you should replace bootstrapFiles with autoload_files in the configuration mentioned above.

Features

Class generator for factory & proxy classes

The extension adds a class generator for factory & proxy classes similar as Magento does it. When running PHPStan in context of a Magento application this is not needed if you point PHPStan also to the generated files folder. When running Magento in the context of a module, this is required so that PHPStan gets the full picture of all classes needed.

Mocked classes autoloader

The extension adds an autoloader for "mocked" classes. These are classes that replace the Magento specific implementations to fix problems with type hints or missing methods in interfaces and such. The autoloader will check if a class, interface, or trait exists locally in the extension's folder of mocks. If so, it will load the local version instead of the one being shipped by Magento. Once those problems are fixed in Magento, those mocks can be removed again.

TestFramework autoloader

The extension provides an autoloader for Magento\TestFramework classes to let you run PHPStan also against your test classes.

TestFramework ObjectManager type hints

A type extension was added so that Magento\Framework\TestFramework\Unit\Helper\ObjectManager calls return the correct return type. Additionally, a PHPStan rule was added to check that only Magento\Framework\Data\Collection sub classes can be passed to
Magento\Framework\TestFramework\Unit\Helper\ObjectManager::getCollectionMock().

ObjectManager type hints

A type extension was added so that Magento\Framework\App\ObjectManager calls return the correct return type.

Support for magic method calls

For some classes like the Magento\Framework\DataObject or Magento\Framework\Session\SessionManager logic was added to be able to support magic method calls.

PHPStan rules

The following rules are available to run checks against your codebase, e.g. if your implementation adheres to the service contracts specification. Each of the rules can be disabled if needed.

Service contracts

Since Magento framework version 100.1.0 entities must not be responsible for their own loading, service contracts should be used to persist entities.

To disable this rule add the following code to your phpstan.neon configuration file:

parameters:
    magento:
        checkServiceContracts: false

Collections should be used directly via factory

Since Magento framework version 101.0.0 Collections should be used directly via factory instead of calling \Magento\Framework\Model\AbstractModel::getCollection() directly.

To disable this rule add the following code to your phpstan.neon configuration file:

parameters:
    magento:
        checkCollectionViaFactory: false

Contribute

Please feel free to fork and extend existing or add new features and send a pull request with your changes! To establish a consistent code quality, please provide unit tests for all your changes and adapt the documentation.

Want To Contribute?

If you feel that you have something to share, then we’d love to have you. Check out the contributing guide to find out how, as well as what we expect from you.

License

PHPStan Magento Extension is released under the MIT License.

Comments
  • Generated class ProductExtension is passed on incorrectly to phpstan

    Generated class ProductExtension is passed on incorrectly to phpstan

    Hi there! Just updated from v0.23.1 (and phpstan 1.7) to v0.24.0 (and phpstan 1.8). Since the update I'm getting the following error when running phpstan:

    Child process error (exit code 255): PHP Fatal error:  Declaration of      
         Magento\Catalog\Api\Data\ProductExtension::setWebsiteIds(?array            
         $websiteIds) must be compatible with                                       
         Magento\Catalog\Api\Data\ProductExtensionInterface::setWebsiteIds($websit  
         eIds) in                                                                   
         /tmp/phpstan/cache/PHPStan/95/c3/95c3cd23c340083ec99b41a2ad173115a2e32d1c  
         .php on line 109                                                           
         Fatal error: Declaration of                                                
         Magento\Catalog\Api\Data\ProductExtension::setWebsiteIds(?array            
         $websiteIds) must be compatible with                                       
         Magento\Catalog\Api\Data\ProductExtensionInterface::setWebsiteIds($websit  
         eIds) in                                                                   
         /tmp/phpstan/cache/PHPStan/95/c3/95c3cd23c340083ec99b41a2ad173115a2e32d1c  
         .php on line 109             
    

    Those are two generated classes from Magento: ProductExtensionInterface

    <?php
    namespace Magento\Catalog\Api\Data;
    
    /**
     * ExtensionInterface class for @see \Magento\Catalog\Api\Data\ProductInterface
     */
    interface ProductExtensionInterface extends \Magento\Framework\Api\ExtensionAttributesInterface
    {
        /**
         * @return int[]|null
         */
        public function getWebsiteIds();
    
        /**
         * @param int[] $websiteIds
         * @return $this
         */
        public function setWebsiteIds($websiteIds);
    

    ProductExtension

    <?php
    namespace Magento\Catalog\Api\Data;
    
    /**
     * Extension class for @see \Magento\Catalog\Api\Data\ProductInterface
     */
    class ProductExtension extends \Magento\Framework\Api\AbstractSimpleObject implements ProductExtensionInterface
    {
        /**
         * @return int[]|null
         */
        public function getWebsiteIds()
        {
            return $this->_get('website_ids');
        }
    
        /**
         * @param int[] $websiteIds
         * @return $this
         */
        public function setWebsiteIds($websiteIds)
        {
            $this->setData('website_ids', $websiteIds);
            return $this;
        }
    
    

    As we can see both classes are generated correctly. In the error message it says that Magento\Catalog\Api\Data\ProductExtension::setWebsiteIds(?array $websiteIds) must be compatible with its interface declaration but in the actual code there is no typed parameter ?array so it has to be somehow generated and passed to phpstan virtually.

    FYI: I deleted the phpstan cache before running phpstan.

    opened by oneserv-heuser 30
  • Factory Generator Overrides Concrete Factory

    Factory Generator Overrides Concrete Factory

    Description

    The factory generation logic does not check if the factory actually exists as a concrete class before generating it, which causes the concrete factory to be overridden by the generated factory. This results in PHPStan marking the code as having an error stating that the wrong parameters are being passed.

    Expected Result

    • No error is shown for code that instantiates factory class

    Actual Result

    • Error is shown for code the instantiates factory class

    Example output

    $ vendor/bin/phpstan analyse
    Note: Using configuration file /Volumes/Development/Extensions/PaymentMethod/phpstan.neon.
     78/78 [▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓] 100%
    
     ------ -------------------------------------------------------------------------------------------------------------------------------------------------
      Line   Model/Payment/Method/Adapter/PaymentMethod.php
     ------ -------------------------------------------------------------------------------------------------------------------------------------------------
      132    Parameter #1 $data of method Magento\Payment\Gateway\Data\PaymentDataObjectFactory::create() expects array, Magento\Payment\Model\InfoInterface
             given.
      167    Parameter #1 $data of method Magento\Payment\Gateway\Data\PaymentDataObjectFactory::create() expects array, Magento\Payment\Model\InfoInterface
             given.
     ------ -------------------------------------------------------------------------------------------------------------------------------------------------
    
    
    
     [ERROR] Found 2 errors
    

    Steps to Reproduce

    1. Write a class that either uses an existing factory (e.g. Magento\Payment\Gateway\Data\PaymentDataObjectFactory) or create your own factory class
    2. Run vendor/bin/phpstan analyse on your code
    opened by JosephLeedy 24
  • Mismatch between requirements

    Mismatch between requirements

    It is not possible to update to magento 2.4.0 community edition because your module requires phpstan/phpstan: ^0.12.24, while magento requires phpstan/phpstan: >=0.12.3 <=0.12.23 (https://packagist.org/packages/magento/community-edition).

    opened by BorisovskiP 24
  • Feature request: Add objectManager type hints for Unit tests

    Feature request: Add objectManager type hints for Unit tests

    Hi! You already have the nice feature with the ObjectManager type hints. But magento also provides another ObjectManager for unit tests. The problem is that the class ObjectManagerDynamicReturnTypeExtension just provides support for the default magento objectmanager as seen here.

    So now when assigning the return value of the getObject() function to an class property with phpDoc the following phpstan error occurs: Property Oneserv\TestFramework\Test\Unit\Test::$testClass (Oneserv\TestFramework\Test\Unit\TestClass) does not accept object as the return type of the function is just object.

    Here is a minium example:

    <?php
    
    declare(strict_types=1);
    
    namespace Oneserv\TestFramework\Test\Unit;
    
    /**
     * Class Test
     */
    class Test extends AbstractTestCase
    {
        /** @var TestClass */
        protected $testClass;
    
        /**
         * @inheritDoc
         */
        protected function setUp(): void
        {
            parent::setUp();
    
            $this->testClass = $this->objectManager->getObject(TestClass::class);
        }
    }
    
    

    I would love having this feature to avoid ignoring the error!

    opened by oneserv-heuser 12
  • extension_attribute type not handled correctly

    extension_attribute type not handled correctly

    I passed an array of SalesChannelInterfaces to the setSalesChannelInterface function: $stockExtensionAttribute->setSalesChannels([$salesChannelInterface]);

    So I receive the following error from phpstan:

    Parameter #1 $salesChannels of method Magento\InventoryApi\Api\Data\StockExtensionInterface::setSalesChannels() expects Magento\InventorySalesApi\Api\Data\SalesChannelInterface, array<int,
             Magento\InventorySalesApi\Api\Data\SalesChannelInterface> given.
    

    The extension_attribute is defined here:

        <extension_attributes for="Magento\InventoryApi\Api\Data\StockInterface">
            <attribute code="sales_channels" type="Magento\InventorySalesApi\Api\Data\SalesChannelInterface[]" />
        </extension_attributes>
    

    And the interface \Magento\InventoryApi\Api\Data\StockExtensionInterface looks like this:

        /**
         * @param \Magento\InventorySalesApi\Api\Data\SalesChannelInterface[]|null $salesChannels
         * @return void
         */
        public function setSalesChannels(?array $salesChannels): void;
    

    So maybe phpstan handles the type of the extension_attribute not correctly?

    opened by torhoehn 11
  • Add support for laminas/laminas-code 4.5 (which is a dependency of Magento 2.4.4)

    Add support for laminas/laminas-code 4.5 (which is a dependency of Magento 2.4.4)

    Hi!

    Thanks again for this module!

    I was trying to prepare a module of mine to test it with Magento 2.4.4 (of which I have bèta access), but due to dependency constraint conflicts this currently does not work.

    • bitexpert/phpstan-magento version 0.17.0 relies on: "laminas/laminas-code": "~3.3.0 || ~3.4.1 || ~3.5.1"
    • magento/framework version 103.0.4-beta4 relies on: "laminas/laminas-code": "~4.5.0"

    I don't know how easy it would be to expand the version constraints in this module to allow for the same constraint as Magento's? Preferably - if possible - without dropping the older versions to allow this module to be installed on older Magento versions as well.

    Thanks!

    opened by hostep 10
  • Use Magento root for TestFrameworkAutoloader

    Use Magento root for TestFrameworkAutoloader

    I have all QA packages in a separate folder installed using composer. This to avoid version problems with the many Magento packages.

    /qa/ /magento/

    To run, for instance PHP Stan, I do:

    cd magento
    ../qa/vendor/bin/phpstan analyse -c .phpstan.neon
    

    This works fine, but I saw that the autoloader TestFrameworkAutoloader reads the vendor map in QA and not in Magento. I suggest using the $magentoRoot as you do in https://github.com/bitExpert/phpstan-magento/blob/master/src/bitExpert/PHPStan/Magento/Autoload/DataProvider/ClassLoaderProvider.php#L28

    opened by evs-xsarus 8
  • Upgrade to PHPStan 1.0

    Upgrade to PHPStan 1.0

    PHPStan 1.0 got released today: https://phpstan.org/blog/phpstan-1-0-released

    Check how "compatible" it is with the 0.x version we use and decide if it is worth upgrading. The downside of upgrading would be that the extension will be incompatible with the current Composer requirements in Magento 2.4 "phpstan/phpstan": "^0.12.77".

    opened by shochdoerfer 8
  • Releases and Changelog

    Releases and Changelog

    Thanks for all your work on making this compatible with the latest version of PHPStan! Much appreciated!

    Is there any reason why this package does not have proper versioning? It would be nice to have tagged versions and changelogs for them :)

    opened by sprankhub 8
  • Add support to generate proxies for interfaces

    Add support to generate proxies for interfaces

    The following message will be shown by phpstan while analyzing.

    Class Magento\Catalog\Api\ProductRepositoryInterface\Magento\Catalog\Api\ProductRepositoryInterface not found and could not be autoloaded.

    The file that was analyzed by phpstan had this a constructor.

    /**
     * @param ProductRepositoryInterface\Proxy $productRepository
    */
    public function __construct(
        \Magento\Catalog\Api\ProductRepositoryInterface\Proxy $productRepository
    ) {}
    

    This can be fixed by prefixing the extended Classname with a backslash.

    $template .= "class {PROXY_CLASSNAME} extends {CLASSNAME} implements {MARKER_INTERFACE}\n"; in ProxyAutoloader.php:34 becomes $template .= "class {PROXY_CLASSNAME} extends \{CLASSNAME} implements {MARKER_INTERFACE}\n";

    After that a fatal error gets thrown because it will try to extend an Interface. PHP Fatal error: Class Magento\Catalog\Api\ProductRepositoryInterface\Proxy cannot extend from interface Magento\Catalog\Api\ProductRepositoryInterface in /tmp/PSMPnSgzZV on line 6

    <?php
    namespace Magento\Catalog\Api\ProductRepositoryInterface;
    /**
     * Proxy class for @see Magento\Catalog\Api\ProductRepositoryInterface
     */
    class Proxy extends \Magento\Catalog\Api\ProductRepositoryInterface implements \Magento\Framework\ObjectManager\NoninterceptableInterface
    {
        /**
         * @return array
         */
        public function __sleep() {}
        /**
         * Retrieve ObjectManager from global scope
         */
        public function __wakeup() {}
        /**
         * Clone proxied instance
         */
        public function __clone() {}
    }
    
    opened by nicojust 7
  • Store interface gives errors

    Store interface gives errors

    I'm experiencing the error below when trying to make a commit. I'm using the setup with Grumphp.

    Fatal error: Class Magento\Store\Model\Store contains 2 abstract methods and must therefore be declared abstract or implement the remaining methods (Magento\Store\Api\Data\StoreInterface::setIsActive, Magento\Store\Api\Data\StoreInterface::getIsActive) in vendor/magento/module-store/Model/Store.php on line 38

    The replacement interface in vendor/bitexpert/phpstan-magento/src/Magento/Store/Api/Data/StoreInterface.php defines methods setIsActive and getIsActive which are not in Magento\Store\Model\Store.

    setIsActive is mentioned as a docblock but setIsActive isn't mentioned at all.

    I'm working on 2.2.8. Removing the two methods from the replacement interface make the error go away.

    opened by rikwillems 7
  • Missing Interface class

    Missing Interface class

    When running phpstan in the newest version, I get the following error:

     Internal error: Internal error: Magento\MediaStorage\Model\File\Validator\NotProtectedInterface does not exist and has no extension interface in file                                                             
         /var/www/html/src/XXX/YYY/Service/SaveOrderAttachmentService.php                                                                                                                                         
                                                                                                                                                                                                                           
         Post the following stack trace to https://github.com/phpstan/phpstan/issues/new?template=Bug_report.md:                                                                                                           
         #0 /var/www/html/vendor/bitexpert/phpstan-magento/src/bitExpert/PHPStan/Magento/Autoload/ExtensionInterfaceAutoloader.php(69):                                                                                    
         bitExpert\PHPStan\Magento\Autoload\ExtensionInterfaceAutoloader->getFileContents('Magento\\MediaSt...')                                                                                                           
         #1 [internal function]: bitExpert\PHPStan\Magento\Autoload\ExtensionInterfaceAutoloader->autoload('Magento\\MediaSt...')                                                                                          
         #2 /tmp/phpstan/cache/PHPStan/7d/6b/7d6bd484079da112a565e263fa30749650fde76b.php(5): spl_autoload_call('Magento\\MediaSt...')                                                                                     
         #3 /var/www/html/vendor/bitexpert/phpstan-magento/src/bitExpert/PHPStan/Magento/Autoload/ExtensionAutoloader.php(66): require_once('/tmp/phpstan/ca...')                                                          
         #4 phar:///var/www/html/vendor/phpstan/phpstan/phpstan.phar/src/Reflection/BetterReflection/SourceLocator/AutoloadFunctionsSourceLocator.php(41):                                                                 
         bitExpert\PHPStan\Magento\Autoload\ExtensionAutoloader->autoload('Magento\\MediaSt...')                                                                                                                           
         #5 phar:///var/www/html/vendor/phpstan/phpstan/phpstan.phar/vendor/ondrejmirtes/better-reflection/src/SourceLocator/Type/AggregateSourceLocator.php(26):                                                          
         PHPStan\Reflection\BetterReflection\SourceLocator\AutoloadFunctionsSourceLocator->locateIdentifier(Object(PHPStan\BetterReflection\Reflector\DefaultReflector),                                                   
         Object(PHPStan\BetterReflection\Identifier\Identifier))                                                                                                                                                           
         #6 phar:///var/www/html/vendor/phpstan/phpstan/phpstan.phar/vendor/ondrejmirtes/better-reflection/src/SourceLocator/Type/MemoizingSourceLocator.php(33):                                                          
         PHPStan\BetterReflection\SourceLocator\Type\AggregateSourceLocator->locateIdentifier(Object(PHPStan\BetterReflection\Reflector\DefaultReflector), Object(PHPStan\BetterReflection\Identifier\Identifier))         
         #7 phar:///var/www/html/vendor/phpstan/phpstan/phpstan.phar/vendor/ondrejmirtes/better-reflection/src/Reflector/DefaultReflector.php(32):                                                                         
         PHPStan\BetterReflection\SourceLocator\Type\MemoizingSourceLocator->locateIdentifier(Object(PHPStan\BetterReflection\Reflector\DefaultReflector), Object(PHPStan\BetterReflection\Identifier\Identifier))         
         #8 phar:///var/www/html/vendor/phpstan/phpstan/phpstan.phar/src/Reflection/BetterReflection/Reflector/MemoizingReflector.php(45):                                                                                 
         PHPStan\BetterReflection\Reflector\DefaultReflector->reflectClass('Magento\\MediaSt...')                                                                                                                          
         #9 phar:///var/www/html/vendor/phpstan/phpstan/phpstan.phar/src/Reflection/BetterReflection/BetterReflectionProvider.php(149):                                                                                    
         PHPStan\Reflection\BetterReflection\Reflector\MemoizingReflector->reflectClass('Magento\\MediaSt...')                                                                                                             
         #10 phar:///var/www/html/vendor/phpstan/phpstan/phpstan.phar/src/Reflection/ReflectionProvider/MemoizingReflectionProvider.php(35):                                                                               
         PHPStan\Reflection\BetterReflection\BetterReflectionProvider->hasClass('Magento\\MediaSt...')                                                                                                                     
         #11 phar:///var/www/html/vendor/phpstan/phpstan/phpstan.phar/src/Rules/ClassCaseSensitivityCheck.php(34): PHPStan\Reflection\ReflectionProvider\MemoizingReflectionProvider->hasClass('Magento\\MediaSt...')      
         #12 phar:///var/www/html/vendor/phpstan/phpstan/phpstan.phar/src/Rules/Namespaces/ExistingNamesInUseRule.php(107): PHPStan\Rules\ClassCaseSensitivityCheck->checkClassNames(Array)                                
         #13 phar:///var/www/html/vendor/phpstan/phpstan/phpstan.phar/src/Rules/Namespaces/ExistingNamesInUseRule.php(61): PHPStan\Rules\Namespaces\ExistingNamesInUseRule->checkClasses(Array)                            
         #14 phar:///var/www/html/vendor/phpstan/phpstan/phpstan.phar/src/Analyser/FileAnalyser.php(106): PHPStan\Rules\Namespaces\ExistingNamesInUseRule->processNode(Object(PhpParser\Node\Stmt\Use_),                   
         Object(PHPStan\Analyser\MutatingScope))                                                                                                                                                                           
         #15 phar:///var/www/html/vendor/phpstan/phpstan/phpstan.phar/src/Analyser/NodeScopeResolver.php(415): PHPStan\Analyser\FileAnalyser->PHPStan\Analyser\{closure}(Object(PhpParser\Node\Stmt\Use_),                 
         Object(PHPStan\Analyser\MutatingScope))                                                                                                                                                                           
         #16 phar:///var/www/html/vendor/phpstan/phpstan/phpstan.phar/src/Analyser/NodeScopeResolver.php(360): PHPStan\Analyser\NodeScopeResolver->processStmtNode(Object(PhpParser\Node\Stmt\Use_),                       
         Object(PHPStan\Analyser\MutatingScope), Object(Closure), Object(PHPStan\Analyser\StatementContext))                                                                                                               
         #17 phar:///var/www/html/vendor/phpstan/phpstan/phpstan.phar/src/Analyser/NodeScopeResolver.php(571): PHPStan\Analyser\NodeScopeResolver->processStmtNodes(Object(PhpParser\Node\Stmt\Namespace_), Array,         
         Object(PHPStan\Analyser\MutatingScope), Object(Closure), Object(PHPStan\Analyser\StatementContext))                                                                                                               
         #18 phar:///var/www/html/vendor/phpstan/phpstan/phpstan.phar/src/Analyser/NodeScopeResolver.php(327): PHPStan\Analyser\NodeScopeResolver->processStmtNode(Object(PhpParser\Node\Stmt\Namespace_),                 
         Object(PHPStan\Analyser\MutatingScope), Object(Closure), Object(PHPStan\Analyser\StatementContext))                                                                                                               
         #19 phar:///var/www/html/vendor/phpstan/phpstan/phpstan.phar/src/Analyser/FileAnalyser.php(175): PHPStan\Analyser\NodeScopeResolver->processNodes(Array, Object(PHPStan\Analyser\MutatingScope),                  
         Object(Closure))                                                                                                                                                                                                  
         #20 phar:///var/www/html/vendor/phpstan/phpstan/phpstan.phar/src/Command/WorkerCommand.php(147): PHPStan\Analyser\FileAnalyser->analyseFile('/var/www/html/s...', Array, Object(PHPStan\Rules\LazyRegistry),      
         Object(PHPStan\Collectors\Registry), NULL)                                                                                                                                                                        
         #21 phar:///var/www/html/vendor/phpstan/phpstan/phpstan.phar/vendor/evenement/evenement/src/Evenement/EventEmitterTrait.php(97): PHPStan\Command\WorkerCommand->PHPStan\Command\{closure}(Array)                  
         #22 phar:///var/www/html/vendor/phpstan/phpstan/phpstan.phar/vendor/clue/ndjson-react/src/Decoder.php(110): _PHPStan_0f7d3d695\Evenement\EventEmitter->emit('data', Array)                                        
         #23 phar:///var/www/html/vendor/phpstan/phpstan/phpstan.phar/vendor/evenement/evenement/src/Evenement/EventEmitterTrait.php(97): _PHPStan_0f7d3d695\Clue\React\NDJson\Decoder->handleData(Array)                  
         #24 phar:///var/www/html/vendor/phpstan/phpstan/phpstan.phar/vendor/react/stream/src/Util.php(62): _PHPStan_0f7d3d695\Evenement\EventEmitter->emit('data', Array)                                                 
         #25 phar:///var/www/html/vendor/phpstan/phpstan/phpstan.phar/vendor/evenement/evenement/src/Evenement/EventEmitterTrait.php(97):                                                                                  
         _PHPStan_0f7d3d695\React\Stream\Util::_PHPStan_0f7d3d695\React\Stream\{closure}('{"action":"anal...')                                                                                                             
         #26 phar:///var/www/html/vendor/phpstan/phpstan/phpstan.phar/vendor/react/stream/src/DuplexResourceStream.php(154): _PHPStan_0f7d3d695\Evenement\EventEmitter->emit('data', Array)                                
         #27 phar:///var/www/html/vendor/phpstan/phpstan/phpstan.phar/vendor/react/event-loop/src/StreamSelectLoop.php(201): _PHPStan_0f7d3d695\React\Stream\DuplexResourceStream->handleData(Resource id #8300)           
         #28 phar:///var/www/html/vendor/phpstan/phpstan/phpstan.phar/vendor/react/event-loop/src/StreamSelectLoop.php(173): _PHPStan_0f7d3d695\React\EventLoop\StreamSelectLoop->waitForStreamActivity(NULL)              
         #29 phar:///var/www/html/vendor/phpstan/phpstan/phpstan.phar/src/Command/WorkerCommand.php(107): _PHPStan_0f7d3d695\React\EventLoop\StreamSelectLoop->run()                                                       
         #30 phar:///var/www/html/vendor/phpstan/phpstan/phpstan.phar/vendor/symfony/console/Command/Command.php(259):                                                                                                     
         PHPStan\Command\WorkerCommand->execute(Object(_PHPStan_0f7d3d695\Symfony\Component\Console\Input\ArgvInput), Object(_PHPStan_0f7d3d695\Symfony\Component\Console\Output\ConsoleOutput))                           
         #31 phar:///var/www/html/vendor/phpstan/phpstan/phpstan.phar/vendor/symfony/console/Application.php(868):                                                                                                         
         _PHPStan_0f7d3d695\Symfony\Component\Console\Command\Command->run(Object(_PHPStan_0f7d3d695\Symfony\Component\Console\Input\ArgvInput),                                                                           
         Object(_PHPStan_0f7d3d695\Symfony\Component\Console\Output\ConsoleOutput))                                                                                                                                        
         #32 phar:///var/www/html/vendor/phpstan/phpstan/phpstan.phar/vendor/symfony/console/Application.php(259):                                                                                                         
         _PHPStan_0f7d3d695\Symfony\Component\Console\Application->doRunCommand(Object(PHPStan\Command\WorkerCommand), Object(_PHPStan_0f7d3d695\Symfony\Component\Console\Input\ArgvInput),                               
         Object(_PHPStan_0f7d3d695\Symfony\Component\Console\Output\ConsoleOutput))                                                                                                                                        
         #33 phar:///var/www/html/vendor/phpstan/phpstan/phpstan.phar/vendor/symfony/console/Application.php(157):                                                                                                         
         _PHPStan_0f7d3d695\Symfony\Component\Console\Application->doRun(Object(_PHPStan_0f7d3d695\Symfony\Component\Console\Input\ArgvInput), Object(_PHPStan_0f7d3d695\Symfony\Component\Console\Output\ConsoleOutput))  
         #34 phar:///var/www/html/vendor/phpstan/phpstan/phpstan.phar/bin/phpstan(124): _PHPStan_0f7d3d695\Symfony\Component\Console\Application->run()                                                                    
         #35 phar:///var/www/html/vendor/phpstan/phpstan/phpstan.phar/bin/phpstan(125): _PHPStan_0f7d3d695\{closure}()                                                                                                     
         #36 /var/www/html/vendor/phpstan/phpstan/phpstan(7): require('phar:///var/www...')                                                                                                                                
         #37 /var/www/html/vendor/bin/phpstan(115): include('/var/www/html/v...')                                                                                                                                          
         #38 {main}                                                                                                                                                                                                        
         Child process error (exit code 1):             
    

    In the mentioned class I only have a dependency on Magento\MediaStorage\Model\File\Validator\NotProtectedExtension, which definitely exists. Don't really understand how he then goes to Magento\MediaStorage\Model\File\Validator\NotProtectedInterface. Might it be, that there is something wrong with the autoloader here? I'm using 'bitexpert/phpstan-magento' in version v0.27.0and phpstan/phpstan in version 1.9.3 on Magento 2.4.5-p1.

    opened by norgeindian 2
  • Integration tests needed for CI pipeline

    Integration tests needed for CI pipeline

    The problem in #243 shows that we need integration tests to detect real-world problems with newer PHPStan releases. Since we have some dependencies deeper in PHPStan's core, things can break.

    Ideally, we'd have a demo Magento module that covers all the different features the extension offers. This would also simplify my testing as currently, I am running the dev versions against multiple modules.

    opened by shochdoerfer 3
  • missing check when using factory, di inyection and preference

    missing check when using factory, di inyection and preference

    My current module has a preference over a class set on the di.xml file.

    I'm using the factory on the constructor of a overwrite.

    When using a method that only exists on the overwrited class that is created through the Factory, PHPStan reports the method as not existent.

    di.xml

    <preference for="Magento\Framework\View\Result\Page"                 type="ClassA" />
    <preference for="Magento\Framework\View\Page\Config\Renderer" type="ClassB" />
    

    Class with factory on constructor:

    class ClassA extends Magento\Framework\View\Result\Page  {
    public function __construct(
     ....
     classBFactory $pageConfigRendererFactory
    ) {
     ...
     parent::__construct(.... );
    }
    
    public function overwritenFunction( .... ) {
      ....
      $this->pageConfigRenderer->onlyOnThisClassMethod();
      ....
    }
    

    Class B:

    class ClassB extends \Magento\Framework\View\Page\Config\Renderer 
    {
      public function onlyOnThisClassMethod() { .... }
    }
    

    This is reported as: Call to an undefined method Magento\\Framework\\View\\Page\\Config\\RendererInterface::renderExtraFooter()

    Complete code has been tested and battle proven on production, so it works as expected.

    For now I'm just ignoring the issue reported.

    opened by esteban-serfe 2
  • Feature Request: Add tips for rule errors

    Feature Request: Add tips for rule errors

    Similar to what happens in PHPStan core, add tips to the rule errors we output to provide some more background information on why the rule was triggered and how to fix it. For the depreciation rules, we could additionally link to the Magento Devdocs.

    See RuleErrorBuilder::tip().

    opened by shochdoerfer 0
  • Feature Request: Do not use setTemplate in Block classes

    Feature Request: Do not use setTemplate in Block classes

    The Magento ExtDN people have a Codesniffer sniff in place to detect calls to the setTemplate() method in a block class. Read about their reasoning here. It probably makes sense to port this rule also to this project.

    opened by shochdoerfer 0
  • Feature Request: Add rule for

    Feature Request: Add rule for "resource models should be used directly"

    Add a PHPStan rule to detect calls for getResource() in Model classes. Calling getResource() is marked as deprecated since it's not considered a good practice any more, see this thread on StackOverflow.

    In the Magento source code, you'll find a few deprecated notices like "@deprecated 102.0.6 because resource models should be used directly". Those could be used to find out how to properly implement this rule.

    opened by shochdoerfer 0
Releases(v0.27.0)
  • v0.27.0(Nov 12, 2022)

  • v0.26.0(Nov 12, 2022)

  • v0.25.0(Oct 4, 2022)

  • v0.24.0(Aug 13, 2022)

    Added

    • #269 Add Magento 2.4.5 to CI pipeline
    • #267 Use Magento root for TestFrameworkAutoloader

    Deprecated

    • Nothing.

    Removed

    • Nothing.

    Fixed

    • #268 Autoloaders prefer local classes
    • #261 Update phpstan/phpstan requirement from ~1.7.2 to ~1.8.2
    Source code(tar.gz)
    Source code(zip)
  • v0.23.1(Aug 6, 2022)

  • v0.23.0(May 27, 2022)

  • v0.22.0(May 26, 2022)

    Added

    • #243 Do not yet require PHPStan 1.7
    • #242 Add link to related blog post
    • #239 Update madewithlove/license-checker requirement from to ^1.2

    Deprecated

    • Nothing.

    Removed

    • Nothing.

    Fixed

    • Nothing.

    Due to some incompatibilities with PHPStan 1.7, this version will only install on the 1.6 version line. Sadly, we can't yet do anything to make the extension compatible with PHPStan 1.7. as we have to wait for some adaptions in PHPStan core.

    Source code(tar.gz)
    Source code(zip)
  • v0.21.0(Apr 27, 2022)

  • v0.20.0(Apr 22, 2022)

    Added

    • #238 Bump phpstan/phpstan to 1.5.7
    • #232 Bump league/commonmark to 2.3.0
    • #231 Support for 2.4.4
    • #230 Bump phpunit/phpunit to 9.5.20

    Deprecated

    • Nothing.

    Removed

    • Nothing.

    Fixed

    • Nothing.

    Thanks @BrentRobert for helping with Magento 2.4.4 support!

    Source code(tar.gz)
    Source code(zip)
  • v0.19.0(Mar 25, 2022)

  • v0.18.0(Mar 25, 2022)

    Added

    • #221 Feature/packagist downloads
    • #220 Add documenation for composer plugins
    • #219 Bump phpunit/phpunit to 9.5.19
    • #218 Bump phpstan/phpstan to 1.4.10
    • #216 Bump nette/neon to 3.3.3
    • #212 Bump captainhook/captainhook to 5.10.8
    • #210 Bump league/commonmark to 2.2.3
    • #201 Bump captainhook/plugin-composer to 5.3.3
    • #202 Bump symfony/finder to 5.4.3

    Deprecated

    • Nothing.

    Removed

    • Nothing.

    Fixed

    • Nothing.

    Thanks @torhoehn for your contribution!

    Source code(tar.gz)
    Source code(zip)
  • v0.17.0(Jan 15, 2022)

  • v0.16.0(Jan 15, 2022)

    Added

    • #191 Add autoloader for extension classes
    • #190 Check if classes referenced in neon config exist
    • #188 Automatically register the autoloader file

    Deprecated

    • Nothing.

    Removed

    • Nothing.

    Fixed

    • Nothing.
    Source code(tar.gz)
    Source code(zip)
  • v0.15.0(Jan 8, 2022)

  • v0.14.0(Jan 8, 2022)

    Added

    • #186 Bump captainhook/captainhook to 5.10.6
    • #181 Bump league/commonmark to 2.1.1
    • #178 Bump phpunit/phpunit to 9.5.11
    • #175 Lint neon files in CI pipeline

    Deprecated

    • Nothing.

    Removed

    • Nothing.

    Fixed

    • #179 Rework extension attribute handling for standalone modules
    Source code(tar.gz)
    Source code(zip)
  • v0.13.0(Dec 23, 2021)

  • v0.12.0(Dec 23, 2021)

    Added

    • #171 Improve docs
    • #170 Throw exception in autoloader
    • #169 Bump captainhook/captainhook to 5.10.5
    • #168 Bump squizlabs/php_codesniffer to 3.6.2
    • #164 Bump nikic/php-parser to 4.13.2
    • #163 Determine tmpDir path relative to config file when appropriate
    • #162 Support for extension attributes
    • #159 Bump phpstan/phpstan-strict-rules to 1.1.0
    • #158 Bump phpstan/phpstan to 1.2.0

    Deprecated

    • Nothing.

    Removed

    • #171 Remove nette/neon dependency

    Fixed

    • Nothing.

    Thank you @mattwellss for your contributions!

    Source code(tar.gz)
    Source code(zip)
  • v0.11.0(Nov 13, 2021)

  • v0.10.0(Nov 13, 2021)

    Added

    • #155 Composer dependency upgrade
    • #154 Bump nette/neon to 3.3.1
    • #153 Bump nikic/php-parser to 4.13.1
    • #150 Bump captainhook/plugin-composer to 5.3.2
    • #149 Bump composer/composer to 2.1.9
    • #148 Bump squizlabs/php_codesniffer to 3.6.1
    • #146 Bump mikey179/vfsstream to 1.6.10
    • #145 Bump phpunit/phpunit to 9.5.10
    • #141 Bump phpstan/phpstan to 0.12.99
    • #140 Bump captainhook/captainhook to 5.10.2
    • #135 Bump phpstan/phpstan-strict-rules to 0.12.11
    • #134 Bump phpstan/phpstan-phpunit to 0.12.22

    Deprecated

    • Nothing.

    Removed

    • Nothing.

    Fixed

    • Nothing.
    Source code(tar.gz)
    Source code(zip)
  • v0.9.0(Aug 7, 2021)

    Added

    • #131 Bump phpstan/phpstan to 0.12.94
    • #130 Bump phpunit/phpunit to 9.5.8
    • #129 Bump nikic/php-parser to 4.12.0
    • #126 Bump mikey179/vfsstream to 1.6.9
    • #125 Bump phpstan/phpstan-phpunit to 0.12.21
    • #123 Bump phpstan/phpstan-strict-rules to 0.12.10
    • #119 Add more unit tests
    • #118 Turn magento/framework into dev dependency
    • #117 Switch to Composer 2 for CI workflow

    Deprecated

    • Nothing.

    Removed

    • Nothing.

    Fixed

    • #133 Omit namespace for non-namespace Proxy
    • #132 Omit namespace for non-namespace Factory

    Thank you @jbrada for your contribution!

    Source code(tar.gz)
    Source code(zip)
  • v0.8.0(Jun 18, 2021)

    Added

    • #116 Add license checker to CI workflow
    • #115 Upgrade Composer dependencies
    • #114 Bump phpstan/phpstan-phpunit to 0.12.20
    • #111 Bump phpstan/phpstan to 0.12.89
    • #110 Bump phpunit/phpunit to 9.5.5
    • #109 Bump captainhook/captainhook to 5.10.1
    • #108 Bump captainhook/plugin-composer to 5.3.1
    • #100 Bump nikic/php-parser to 4.10.5
    • #98 Upgrade to GitHub-native Dependabot
    • #96 Bump composer/composer to 2.0.13
    • #90 Bump squizlabs/php_codesniffer to 3.6.0

    Deprecated

    • Nothing.

    Removed

    • Nothing.

    Fixed

    • Nothing.
    Source code(tar.gz)
    Source code(zip)
  • v0.7.0(Mar 13, 2021)

    Added

    • #80 Update Composer dependencies
    • #79 Bump phpstan/phpstan from 0.12.80 to 0.12.81
    • #78 Bump phpstan/phpstan-phpunit from 0.12.17 to 0.12.18
    • #77 Bump captainhook/captainhook from 5.4.4 to 5.4.5
    • #76 Bump captainhook/plugin-composer from 5.2.3 to 5.2.4
    • #74 Bump nette/neon from 3.2.1 to 3.2.2
    • #67 Add phpstan/phpstan-strict-rules
    • #64 PHPStan extensions run on max
    • #63 Bump magento/framework from 103.0.1 to 103.0.2
    • #59 Bump phpunit/phpunit from 9.5.1 to 9.5.2

    Deprecated

    • Nothing.

    Removed

    • #60 Replace Phing with Composer scripts

    Fixed

    • #70 Install matching lowest version of strict rules
    Source code(tar.gz)
    Source code(zip)
  • v0.6.0(Jan 22, 2021)

  • v0.5.0(Jan 6, 2021)

    Added

    • #47 Add type for ObjectManager helper for tests
    • #48 Fix proxy generation

    Deprecated

    • Nothing.

    Removed

    • Nothing.

    Fixed

    • Nothing.

    Thanks @xi-ao & @oneserv-heuser for your support!

    Source code(tar.gz)
    Source code(zip)
  • v0.4.1(Oct 27, 2020)

    Added

    • Nothing.

    Deprecated

    • Nothing.

    Removed

    • Nothing.

    Fixed

    • #41 Removes upper version constraint of phpstan

    Thanks, @hostep & @sprankhub for getting this sorted out. Very much appreciated!

    Source code(tar.gz)
    Source code(zip)
  • v0.4.0(Oct 16, 2020)

    Added

    • #40 Use same constraint as latest Magento release
    • #39 Apply phpstan.rules.rule tag dynamically via DI
    • #36 Add deprecation rules for AbstractModel classe

    Deprecated

    • #40 Deprecated Config Option autoload_files

    Removed

    • Nothing.

    Fixed

    • Nothing.

    Thank you @sprankhub, @torhoehn, @hostep and Mr. PHPStan @ondrejmirtes himself! :)

    Source code(tar.gz)
    Source code(zip)
  • v0.3.0(May 29, 2020)

  • v0.2.0(May 17, 2020)

  • v0.1.1(May 12, 2020)

  • v0.1.0(Apr 18, 2020)

    Added

    • #29 Improve code generation for factories & proxies

    Deprecated

    • Nothing.

    Removed

    • Nothing.

    Fixed

    • Nothing.

    This is the first "official" release of the bitexpert/phpstan-magento package. Thanks to @sprankhub for the push in this direction :)

    Source code(tar.gz)
    Source code(zip)
Owner
bitExpert AG
Grundprinzip & Erfolgsformel: Innovation, Qualität & Professionalität dank einem motivierten & erfahrenen Team. Impressum: https://www.bitexpert.de/kontakt/
bitExpert AG
PHPStan extension to support #[Readonly] constructor properties

icanhazstring/phpstan-readonly-property Support #[Readonly] promoted constructor properties for PHPStan. This library is used to have a full transitio

Andreas Frömer 4 Apr 5, 2022
The main scope of this extension is to help phpstan to detect the type of object after the Assert\Assertion validation.

PHPStan beberlei/assert extension PHPStan beberlei/assert Description The main scope of this extension is to help phpstan to detect the type of object

PHPStan 33 Jan 2, 2023
PHPStan extension for webmozart/assert

PHPStan webmozart/assert extension PHPStan webmozart/assert Description The main scope of this extension is to help phpstan to detect the type of obje

PHPStan 139 Dec 22, 2022
An extension for PHPStan for adding analysis for PHP Language Extensions.

PHPStan PHP Language Extensions (currently in BETA) This is an extension for PHPStan for adding analysis for PHP Language Extensions. Language feature

Dave Liddament 9 Nov 30, 2022
PHPStan extension for sealed classes and interfaces.

Sealed classes with PHPStan This extension adds support for sealed classes and interfaces to PHPStan. Installation To use this extension, require it v

Jiří Pudil 14 Nov 28, 2022
Extension for PHPStan to allow analysis of Drupal code.

phpstan-drupal Extension for PHPStan to allow analysis of Drupal code. Sponsors Would you like to sponsor? Usage When you are using phpstan/extension-

Matt Glaman 154 Jan 2, 2023
Magento 2 Extension to cleanup admin menu and Store > Configuration area by arranging third party extension items.

Clean Admin Menu - Magento 2 Extension It will merge all 3rd party extension's menu items in backend's primary menu to a common menu item named "Exten

RedChamps 109 Jan 3, 2023
This Magento 2 extension integrates EasyTranslate into Magento 2.

EasyTranslate Magento 2 Connector This Magento 2 extension integrates EasyTranslate into Magento 2. Mind that you need to have an account with EasyTra

Easytranslate ApS 0 Oct 7, 2022
This Magento extension provides a Real Full Page Caching for Magento powered by Varnish with support of Session-Based information caching (Cart, Customer Accounts, ...) via ESI includes

This Magento extension provides a Real Full Page Caching (FPC) for Magento powered by Varnish with support of Session-Based information caching (Cart, Customer Accounts, ...) via ESI includes

Hugues Alary 95 Feb 11, 2022
Magento 2 specific tasks for Capistrano 3

Capistrano::Magento2 A Capistrano extension for Magento 2 deployments. Takes care of specific Magento 2 requirements and adds tasks specific to the Ma

David Alger 223 Dec 2, 2022
Package to send customer specific prices to Magento from a Laravel application using a configurable source.

Laravel Magento Customer Prices This package provides a way to add customer specific prices to Magento from a Laravel app. By default, it uses the Mag

JustBetter 14 Nov 4, 2022
A tool that allows to quickly export data from Magento 1 and Magento 2 store and import it back into Magento 2

Simple Import / Export tool A tool that allows to quickly export data from Magento 1 and Magento 2 store and import it back into Magento 2. Table data

EcomDev B.V. 51 Dec 5, 2022
Analyzes PHPStan baseline files and creates aggregated error trend-reports

Analyzes phpstan baseline files Analyzes PHPStan baseline files and creates aggregated error trend-reports.

Markus Staab 22 Dec 23, 2022
Sandbox project for the PHPStan workshop

Sandbox project for a PHPStan workshop Installation Requirements Docker Engine Docker Compose Git Bash Getting started Clone this repository (git clon

Matthias Noback 4 Oct 17, 2022
A PHPStan package that supports working with Extbase

PHPStan for Extbase This package provides a couple of stubs and services to make your life easier when working with PHPStan and Extbase. Examples clas

Alexander Schnitzler 7 Dec 10, 2021
Custom PHPStan rules

phpstan-rules Provides additional rules for phpstan/phpstan. Installation Run $ composer require --dev alister/phpstan-rules Usage All of the rules pr

Alister Bulman 1 Nov 4, 2021
Doctrine extensions for PHPStan

Doctrine extensions for PHPStan PHPStan Doctrine This extension provides following features: DQL validation for parse errors, unknown entity classes a

PHPStan 478 Jan 3, 2023