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

InvariantCheckerAspect::fetchAllContracts()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 11
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 6
CRAP Score 3

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 11
ccs 6
cts 6
cp 1
rs 9.4285
cc 3
eloc 6
nc 3
nop 1
crap 3
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\Invariant;
17
use PhpDeal\Contract\Fetcher\ParentClass\InvariantFetcher;
18
use PhpDeal\Exception\ContractViolation;
19
use Go\Lang\Annotation\Around;
20
use ReflectionClass;
21
22
class InvariantCheckerAspect extends AbstractContractAspect implements Aspect
23
{
24
    /**
25
     * @var InvariantFetcher
26
     */
27
    private $invariantFetcher;
28
29
    public function __construct(Reader $reader)
30
    {
31
        parent::__construct($reader);
32
        $this->invariantFetcher = new InvariantFetcher(Invariant::class, $reader);
33
    }
34
35
    /**
36
     * Verifies invariants for contract class
37
     *
38
     * @Around("@within(PhpDeal\Annotation\Invariant) && execution(public **->*(*))")
39
     * @param MethodInvocation $invocation
40
     *
41
     * @throws ContractViolation
42
     * @return mixed
43
     */
44 7
    public function invariantContract(MethodInvocation $invocation)
45
    {
46 7
        $object = $invocation->getThis();
47 7
        $args   = $this->fetchMethodArguments($invocation);
48 7
        $class  = $invocation->getMethod()->getDeclaringClass();
49 7
        if ($class->isCloneable()) {
50 7
            $args['__old'] = clone $object;
51
        }
52
53 7
        $result = $invocation->proceed();
54 7
        $args['__result'] = $result;
55
56 7
        $allContracts = $this->fetchAllContracts($class);
57 7
        $this->ensureContracts($invocation, $allContracts, $object, $class->name, $args);
58
59 3
        return $result;
60
    }
61
62
    /**
63
     * @param ReflectionClass $class
64
     * @return array
65
     */
66 7
    private function fetchAllContracts(ReflectionClass $class)
67
    {
68 7
        $allContracts = $this->invariantFetcher->getConditions($class);
69 7
        foreach ($this->reader->getClassAnnotations($class) as $annotation) {
70 7
            if ($annotation instanceof Invariant) {
71 7
                $allContracts[] = $annotation;
72
            }
73
        }
74
75 7
        return array_unique($allContracts);
76
    }
77
}
78