PreconditionCheckerAspect   A
last analyzed

Complexity

Total Complexity 6

Size/Duplication

Total Lines 65
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 3

Test Coverage

Coverage 77.27%

Importance

Changes 0
Metric Value
wmc 6
lcom 1
cbo 3
dl 0
loc 65
ccs 17
cts 22
cp 0.7727
rs 10
c 0
b 0
f 0

4 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 5 1
A preConditionContract() 0 9 1
A fetchAllContracts() 0 14 3
A fetchParentsContracts() 0 7 1
1
<?php
2
3
/**
4
 * PHP Deal framework
5
 *
6
 * @copyright Copyright 2019, Lisachenko Alexander <[email protected]>
7
 *
8
 * This source file is subject to the license that is bundled
9
 * with this source code in the file LICENSE.
10
 */
11
12
declare(strict_types=1);
13
14
namespace PhpDeal\Aspect;
15
16
use Doctrine\Common\Annotations\Reader;
17
use Go\Aop\Aspect;
18
use Go\Aop\Intercept\MethodInvocation;
19
use Go\Aop\Support\AnnotatedReflectionMethod;
20
use PhpDeal\Annotation\Verify;
21
use PhpDeal\Contract\Fetcher\Parent\MethodConditionWithInheritDocFetcher;
22
use PhpDeal\Exception\ContractViolation;
23
use Go\Lang\Annotation\Before;
24
use ReflectionException;
25
use ReflectionMethod;
26
27
class PreconditionCheckerAspect extends AbstractContractAspect implements Aspect
28
{
29
    /**
30
     * @var MethodConditionWithInheritDocFetcher
31
     */
32
    private $methodConditionFetcher;
33
34
    public function __construct(Reader $reader)
35
    {
36
        parent::__construct($reader);
37
        $this->methodConditionFetcher = new MethodConditionWithInheritDocFetcher([Verify::class], $reader);
38
    }
39
40
    /**
41
     * Verifies pre-condition contract for the method
42
     *
43
     * @param MethodInvocation $invocation
44
     * @Before("@execution(PhpDeal\Annotation\Verify)")
45
     *
46
     * @throws ContractViolation
47
     * @throws ReflectionException
48
     */
49 11
    public function preConditionContract(MethodInvocation $invocation): void
50
    {
51 11
        $object = $invocation->getThis();
52 11
        $args   = $this->fetchMethodArguments($invocation);
53 11
        $scope  = $invocation->getMethod()->getDeclaringClass()->name;
54
55 11
        $allContracts = $this->fetchAllContracts($invocation);
56 11
        $this->ensureContracts($invocation, $allContracts, $object, $scope, $args);
57
    }
58
59
    /**
60
     * @param MethodInvocation $invocation
61
     * @return array
62
     * @throws ReflectionException
63
     */
64 11
    private function fetchAllContracts(MethodInvocation $invocation): array
65
    {
66 11
        $allContracts = $this->fetchParentsContracts($invocation);
67
        /** @var ReflectionMethod&AnnotatedReflectionMethod $reflectionMethod */
0 ignored issues
show
Documentation introduced by
The doc-type ReflectionMethod&AnnotatedReflectionMethod could not be parsed: Unknown type name "ReflectionMethod&AnnotatedReflectionMethod" at position 0. (view supported doc-types)

This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.

Loading history...
68 11
        $reflectionMethod = $invocation->getMethod();
69
70 11
        foreach ($reflectionMethod->getAnnotations() as $annotation) {
71 11
            if ($annotation instanceof Verify) {
72 11
                $allContracts[] = $annotation;
73
            }
74
        }
75
76 11
        return \array_unique($allContracts);
77
    }
78
79
    /**
80
     * @param MethodInvocation $invocation
81
     * @return array
82
     * @throws ReflectionException
83
     */
84 11
    private function fetchParentsContracts(MethodInvocation $invocation): array
85
    {
86 11
        return $this->methodConditionFetcher->getConditions(
87 11
            $invocation->getMethod()->getDeclaringClass(),
88 11
            $invocation->getMethod()->name
89
        );
90
    }
91
}
92