Completed
Push — master ( 56c4be...a1e3bd )
by Alexander
7s
created

fetchParentsContracts()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 7
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 1

Importance

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