Completed
Pull Request — master (#35)
by
unknown
14:05
created

PreconditionCheckerAspect::preConditionContract()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 9

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 6
CRAP Score 1.0028

Importance

Changes 0
Metric Value
dl 0
loc 9
ccs 6
cts 7
cp 0.8571
rs 9.9666
c 0
b 0
f 0
cc 1
nc 1
nop 1
crap 1.0028
1
<?php
2
declare(strict_types=1);
3
4
/**
5
 * PHP Deal framework
6
 *
7
 * @copyright Copyright 2019, Lisachenko Alexander <[email protected]>
8
 *
9
 * This source file is subject to the license that is bundled
10
 * with this source code in the file LICENSE.
11
 */
12
13
namespace PhpDeal\Aspect;
14
15
use Doctrine\Common\Annotations\Reader;
16
use Go\Aop\Aspect;
17
use Go\Aop\Intercept\MethodInvocation;
18
use Go\Aop\Support\AnnotatedReflectionMethod;
19
use PhpDeal\Annotation\Verify;
20
use PhpDeal\Contract\Fetcher\Parent\MethodConditionWithInheritDocFetcher;
21
use PhpDeal\Exception\ContractViolation;
22
use Go\Lang\Annotation\Before;
23
use ReflectionException;
24
use ReflectionMethod;
25
26
class PreconditionCheckerAspect extends AbstractContractAspect implements Aspect
27
{
28
    /**
29
     * @var MethodConditionWithInheritDocFetcher
30
     */
31
    private $methodConditionFetcher;
32
33
    public function __construct(Reader $reader)
34
    {
35
        parent::__construct($reader);
36
        $this->methodConditionFetcher = new MethodConditionWithInheritDocFetcher([Verify::class], $reader);
37
    }
38
39
    /**
40
     * Verifies pre-condition contract for the method
41
     *
42
     * @param MethodInvocation $invocation
43
     * @Before("@execution(PhpDeal\Annotation\Verify)")
44
     *
45
     * @throws ContractViolation
46
     * @throws ReflectionException
47
     */
48 11
    public function preConditionContract(MethodInvocation $invocation): void
49
    {
50 11
        $object = $invocation->getThis();
51 11
        $args   = $this->fetchMethodArguments($invocation);
52 11
        $scope  = $invocation->getMethod()->getDeclaringClass()->name;
53
54 11
        $allContracts = $this->fetchAllContracts($invocation);
55 11
        $this->ensureContracts($invocation, $allContracts, $object, $scope, $args);
56
    }
57
58
    /**
59
     * @param MethodInvocation $invocation
60
     * @return array
61
     * @throws ReflectionException
62
     */
63 11
    private function fetchAllContracts(MethodInvocation $invocation): array
64
    {
65 11
        $allContracts = $this->fetchParentsContracts($invocation);
66
        /** @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...
67 11
        $reflectionMethod = $invocation->getMethod();
68
69 11
        foreach ($reflectionMethod->getAnnotations() as $annotation) {
70 11
            if ($annotation instanceof Verify) {
71 11
                $allContracts[] = $annotation;
72
            }
73
        }
74
75 11
        return \array_unique($allContracts);
76
    }
77
78
    /**
79
     * @param MethodInvocation $invocation
80
     * @return array
81
     * @throws ReflectionException
82
     */
83 11
    private function fetchParentsContracts(MethodInvocation $invocation): array
84
    {
85 11
        return $this->methodConditionFetcher->getConditions(
86 11
            $invocation->getMethod()->getDeclaringClass(),
87 11
            $invocation->getMethod()->name
88
        );
89
    }
90
}
91