Passed
Push — trunk ( ad06ea...8f56e6 )
by Christian
23:45 queued 17s
created

validateDomainExceptionClass()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 23
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 4
eloc 11
c 1
b 0
f 0
nc 4
nop 2
dl 0
loc 23
rs 9.9
1
<?php declare(strict_types=1);
2
3
namespace Shopware\Core\DevOps\StaticAnalyze\PHPStan\Rules;
4
5
use PhpParser\Node;
6
use PhpParser\Node\Stmt\Throw_;
7
use PHPStan\Analyser\Scope;
0 ignored issues
show
Bug introduced by
The type PHPStan\Analyser\Scope was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
8
use PHPStan\Rules\Rule;
0 ignored issues
show
Bug introduced by
The type PHPStan\Rules\Rule was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
9
use PHPStan\Rules\RuleErrorBuilder;
0 ignored issues
show
Bug introduced by
The type PHPStan\Rules\RuleErrorBuilder was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
10
use Shopware\Core\Framework\HttpException;
11
use Shopware\Core\Framework\Log\Package;
12
use Shopware\Core\Framework\Plugin\Exception\DecorationPatternException;
13
14
/**
15
 * @internal
16
 *
17
 * @implements Rule<Throw_>
18
 */
19
#[Package('core')]
20
class DomainExceptionRule implements Rule
21
{
22
    use InTestClassTrait;
23
24
    public function getNodeType(): string
25
    {
26
        return Throw_::class;
27
    }
28
29
    public function processNode(Node $node, Scope $scope): array
30
    {
31
        if ($this->isInTestClass($scope) || !$scope->isInClass()) {
32
            return [];
33
        }
34
35
        if ($scope->getClassReflection()->getName() === DecorationPatternException::class) {
36
            return [];
37
        }
38
39
        if (!$node instanceof Throw_) {
40
            return [];
41
        }
42
43
        if ($node->expr instanceof Node\Expr\StaticCall) {
44
            return $this->validateDomainExceptionClass($node->expr, $scope);
45
        }
46
47
        if (!$node->expr instanceof Node\Expr\New_) {
48
            return [];
49
        }
50
51
        return [
52
            RuleErrorBuilder::message('Throwing new exceptions within classes are not allowed. Please use domain exception pattern. See https://github.com/shopware/platform/blob/v6.4.20.0/adr/2022-02-24-domain-exceptions.md')->build(),
53
        ];
54
    }
55
56
    private function validateDomainExceptionClass(Node\Expr\StaticCall $node, Scope $scope): array
57
    {
58
        if (!is_subclass_of($node->class->toString(), HttpException::class)) {
0 ignored issues
show
Bug introduced by
The method toString() does not exist on PhpParser\Node\Expr. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

58
        if (!is_subclass_of($node->class->/** @scrutinizer ignore-call */ toString(), HttpException::class)) {

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
59
            return [
60
                RuleErrorBuilder::message(\sprintf('Domain exception class %s has extend the \Shopware\Core\Framework\HttpException class', $node->class->toString()))->build(),
61
            ];
62
        }
63
64
        if (!\str_starts_with($node->class->toString(), 'Shopware\\Core\\')) {
65
            return [];
66
        }
67
68
        $parts = \explode('\\', $scope->getClassReflection()->getName());
69
70
        $expected = \sprintf('Shopware\\Core\\%s\\%s\\%sException', $parts[2], $parts[3], $parts[3]);
71
72
        if ($node->class->toString() !== $expected) {
73
            return [
74
                RuleErrorBuilder::message(\sprintf('Expected domain exception class %s, got %s', $expected, $node->class->toString()))->build(),
75
            ];
76
        }
77
78
        return [];
79
    }
80
}
81