Skip to content

Commit

Permalink
Merge a6a1d5f into d25e05b
Browse files Browse the repository at this point in the history
  • Loading branch information
shochdoerfer committed Apr 7, 2023
2 parents d25e05b + a6a1d5f commit 96e79ab
Show file tree
Hide file tree
Showing 5 changed files with 190 additions and 1 deletion.
11 changes: 11 additions & 0 deletions docs/features.md
Expand Up @@ -61,6 +61,17 @@ parameters:
checkServiceContracts: false
```

### Resource Models should be used directly

Since Magento framework version 100.1.0 it is no longer recommended to use `\Magento\Framework\Model\AbtractModel::getResource()` for retrieving the model resource. Use [service contracts](https://devdocs.magento.com/guides/v2.4/extension-dev-guide/service-contracts/service-contracts.html) instead.

To disable this rule add the following code to your `phpstan.neon` configuration file:
```neon
parameters:
magento:
checkResourceModelsUsedDirectly: 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
Expand Down
6 changes: 5 additions & 1 deletion extension.neon
Expand Up @@ -2,6 +2,7 @@ parameters:
magento:
checkCollectionViaFactory: true
checkServiceContracts: true
checkResourceModelsUsedDirectly: true
magentoRoot: %currentWorkingDirectory%
bootstrapFiles:
- magento-autoloader.php
Expand All @@ -17,7 +18,8 @@ conditionalTags:
phpstan.rules.rule: %magento.checkCollectionViaFactory%
bitExpert\PHPStan\Magento\Rules\AbstractModelUseServiceContractRule:
phpstan.rules.rule: %magento.checkServiceContracts%

bitExpert\PHPStan\Magento\Rules\ResourceModelsShouldBeUsedDirectlyRule:
phpstan.rules.rule: %magento.checkResourceModelsUsedDirectly%
services:
-
class: bitExpert\PHPStan\Magento\Type\ObjectManagerDynamicReturnTypeExtension
Expand All @@ -43,6 +45,8 @@ services:
class: bitExpert\PHPStan\Magento\Rules\AbstractModelRetrieveCollectionViaFactoryRule
-
class: bitExpert\PHPStan\Magento\Rules\AbstractModelUseServiceContractRule
-
class: bitExpert\PHPStan\Magento\Rules\ResourceModelsShouldBeUsedDirectlyRule
fileCacheStorage:
class: bitExpert\PHPStan\Magento\Autoload\Cache\FileCacheStorage
arguments:
Expand Down
@@ -0,0 +1,73 @@
<?php

/*
* This file is part of the phpstan-magento package.
*
* (c) bitExpert AG
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
declare(strict_types=1);

namespace bitExpert\PHPStan\Magento\Rules;

use PhpParser\Node;
use PhpParser\Node\Expr\MethodCall;
use PHPStan\Analyser\Scope;
use PHPStan\Rules\Rule;
use PHPStan\ShouldNotHappenException;
use PHPStan\Type\ObjectType;
use PHPStan\Type\VerbosityLevel;

/**
* Since 100.1.0 resource models should be used directly.
*
* @implements Rule<MethodCall>
*/
class ResourceModelsShouldBeUsedDirectlyRule implements Rule
{
/**
* @phpstan-return class-string<MethodCall>
* @return string
*/
public function getNodeType(): string
{
return MethodCall::class;
}

/**
* @param Node $node
* @param Scope $scope
* @return (string|\PHPStan\Rules\RuleError)[] errors
* @throws ShouldNotHappenException
*/
public function processNode(Node $node, Scope $scope): array
{
if (!$node instanceof MethodCall) {
throw new ShouldNotHappenException();
}

if (!$node->name instanceof Node\Identifier) {
return [];
}

if (!in_array($node->name->name, ['getResource', '_getResource'], true)) {
return [];
}

$type = $scope->getType($node->var);
$isAbstractModelType = (new ObjectType('Magento\Framework\Model\AbstractModel'))->isSuperTypeOf($type);
if (!$isAbstractModelType->yes()) {
return [];
}

return [
sprintf(
'%s::%s() is deprecated. Use Resource Models directly',
$type->describe(VerbosityLevel::typeOnly()),
$node->name->name
)
];
}
}
@@ -0,0 +1,4 @@
<?php

$model = new \bitExpert\PHPStan\Magento\Rules\Helper\SampleModel();
$model->getResource();
@@ -0,0 +1,97 @@
<?php

/*
* This file is part of the phpstan-magento package.
*
* (c) bitExpert AG
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
declare(strict_types=1);

namespace bitExpert\PHPStan\Magento\Rules;

use bitExpert\PHPStan\Magento\Rules\Helper\SampleModel;
use PhpParser\Node\Expr\MethodCall;
use PhpParser\Node\Expr\Variable;
use PHPStan\Analyser\Scope;
use PHPStan\Rules\Rule;
use PHPStan\ShouldNotHappenException;
use PHPStan\Testing\RuleTestCase;

/**
* @extends \PHPStan\Testing\RuleTestCase<ResourceModelsShouldBeUsedDirectlyRule>
*/
class ResourceModelsShouldBeUsedDirectlyRuleUnitTest extends RuleTestCase
{
protected function getRule(): Rule
{
return new ResourceModelsShouldBeUsedDirectlyRule();
}

/**
* @test
*/
public function checkCaughtExceptions(): void
{
$this->analyse([__DIR__ . '/Helper/resource_model.php'], [
[
SampleModel::class . '::getResource() is deprecated. Use Resource Models directly',
4,
],
]);
}

/**
* @test
*/
public function getNodeTypeMethodReturnsMethodCall(): void
{
$rule = new ResourceModelsShouldBeUsedDirectlyRule();

self::assertSame(MethodCall::class, $rule->getNodeType());
}

/**
* @test
*/
public function processNodeThrowsExceptionForNonMethodCallNodes(): void
{
$this->expectException(ShouldNotHappenException::class);

$node = new Variable('var');
$scope = $this->createMock(Scope::class);

$rule = new ResourceModelsShouldBeUsedDirectlyRule();
$rule->processNode($node, $scope);
}

/**
* @test
*/
public function processNodeReturnsEarlyWhenNodeNameIsWrongType(): void
{
$node = new MethodCall(new Variable('var'), new Variable('wrong_node'));
$scope = $this->createMock(Scope::class);

$rule = new ResourceModelsShouldBeUsedDirectlyRule();
$return = $rule->processNode($node, $scope);

self::assertCount(0, $return);
}

/**
* @test
*/
public function processNodeReturnsEarlyWhenNodeNameIsNotSaveOrLoadOrDelete(): void
{
$node = new MethodCall(new Variable('var'), 'wrong_node_name');
$scope = $this->createMock(Scope::class);

$rule = new ResourceModelsShouldBeUsedDirectlyRule();
$return = $rule->processNode($node, $scope);

self::assertCount(0, $return);
}
}

0 comments on commit 96e79ab

Please sign in to comment.