Completed
Push — master ( bde278...56c4be )
by Alexander
9s
created

InvariantContract   A

Complexity

Total Complexity 7

Size/Duplication

Total Lines 67
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 4

Test Coverage

Coverage 83.33%

Importance

Changes 3
Bugs 1 Features 0
Metric Value
wmc 7
c 3
b 1
f 0
lcom 1
cbo 4
dl 0
loc 67
ccs 20
cts 24
cp 0.8333
rs 10

4 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 5 1
A check() 0 17 2
A fetchAllContracts() 0 11 3
A fetchParentsContracts() 0 7 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\Contract;
12
13
use Doctrine\Common\Annotations\Reader;
14
use Go\Aop\Intercept\MethodInvocation;
15
use PhpDeal\Contract\Fetcher\ParentClass\InvariantFetcher;
16
use PhpDeal\Exception\ContractViolation;
17
use PhpDeal\Annotation\Invariant;
18
use ReflectionClass;
19
20
class InvariantContract extends Contract
21
{
22
    /**
23
     * @var InvariantFetcher
24
     */
25
    private $invariantFetcher;
26
27
    public function __construct(Reader $reader)
28
    {
29
        parent::__construct($reader);
30
        $this->invariantFetcher = new InvariantFetcher(Invariant::class);
31
    }
32
33
    /**
34
     * Verifies invariants for contract class
35
     *
36
     * @Around("@within(PhpDeal\Annotation\Invariant) && execution(public **->*(*))")
37
     * @param MethodInvocation $invocation
38
     * @throws ContractViolation
39
     * @return mixed
40
     */
41 7
    public function check(MethodInvocation $invocation)
42
    {
43 7
        $object = $invocation->getThis();
44 7
        $args   = $this->getMethodArguments($invocation);
45 7
        $class  = $invocation->getMethod()->getDeclaringClass();
46 7
        if ($class->isCloneable()) {
47 7
            $args['__old'] = clone $object;
48
        }
49
50 7
        $result = $invocation->proceed();
51 7
        $args['__result'] = $result;
52
53 7
        $allContracts = $this->makeContractsUnique($this->fetchAllContracts($class));
54 7
        $this->fulfillContracts($allContracts, $object, $class->name, $args, $invocation);
55
56 3
        return $result;
57
    }
58
59
    /**
60
     * @param ReflectionClass $class
61
     * @return array
62
     */
63 7
    private function fetchAllContracts(ReflectionClass $class)
64
    {
65 7
        $allContracts = $this->fetchParentsContracts($class);
66 7
        foreach ($this->reader->getClassAnnotations($class) as $annotation) {
67 7
            if ($annotation instanceof Invariant) {
68 7
                $allContracts[] = $annotation;
69
            }
70
        }
71
72 7
        return $allContracts;
73
    }
74
75
    /**
76
     * @param ReflectionClass $class
77
     * @return array
78
     */
79 7
    private function fetchParentsContracts(ReflectionClass $class)
80
    {
81 7
        return $this->invariantFetcher->getConditions(
82
            $class,
83 7
            $this->reader
84
        );
85
    }
86
}
87