Completed
Push — master ( 088857...dfef6d )
by Alexander
02:43
created

AbstractContractAspect::fetchMethodArguments()   B

Complexity

Conditions 5
Paths 5

Size

Total Lines 19
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 10
CRAP Score 5.0187

Importance

Changes 0
Metric Value
dl 0
loc 19
ccs 10
cts 11
cp 0.9091
rs 8.8571
c 0
b 0
f 0
cc 5
eloc 11
nc 5
nop 1
crap 5.0187
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\Annotation;
14
use Doctrine\Common\Annotations\Reader;
15
use DomainException;
16
use Go\Aop\Intercept\MethodInvocation;
17
use PhpDeal\Exception\ContractViolation;
18
19
abstract class AbstractContractAspect
20
{
21
    /**
22
     * @var Reader
23
     */
24
    protected $reader;
25
26
    /**
27
     * @param Reader $reader Annotation reader
28
     */
29
    public function __construct(Reader $reader)
30
    {
31
        $this->reader = $reader;
32
    }
33
34
    /**
35
     * Returns an associative list of arguments for the method invocation
36
     *
37
     * @param MethodInvocation $invocation
38
     * @return array
39
     */
40 49
    protected function fetchMethodArguments(MethodInvocation $invocation)
41
    {
42 49
        $result         = [];
43 49
        $parameters     = $invocation->getMethod()->getParameters();
44 49
        $argumentValues = $invocation->getArguments();
45
46
        // Number of arguments can be less than number of parameters because of default values
47 49
        foreach ($parameters as $parameterIndex => $reflectionParameter) {
48 48
            $hasArgumentValue = array_key_exists($parameterIndex, $argumentValues);
49 48
            $argumentValue    = $hasArgumentValue ? $argumentValues[$parameterIndex] : null;
50 48
            if (!$hasArgumentValue && $reflectionParameter->isDefaultValueAvailable()) {
51
                $argumentValue = $reflectionParameter->getDefaultValue();
52
            }
53 48
            $result[$reflectionParameter->name] = $argumentValue;
54
0 ignored issues
show
Coding Style introduced by
Blank line found at end of control structure
Loading history...
55
        }
56
57 49
        return $result;
58
    }
59
60
    /**
61
     * Performs verification of contracts for given invocation
62
     *
63
     * @param MethodInvocation $invocation Current invocation
64
     * @param array|Annotation[] $contracts Contract annotation
65
     * @param object|string $instance Invocation instance or string for static class
66
     * @param string $scope Scope of method
67
     * @param array $args List of arguments for the method
68
     *
69
     * @throws DomainException
70
     */
71 49
    protected function ensureContracts(MethodInvocation $invocation, array $contracts, $instance, $scope, array $args)
72
    {
73 49
        static $invoker = null;
74 49
        if (!$invoker) {
75 49
            $invoker = function () {
76 49
                extract(func_get_arg(0));
0 ignored issues
show
Bug introduced by
func_get_arg(0) cannot be passed to extract() as the parameter $var_array expects a reference.
Loading history...
77
78 49
                return eval('return ' . func_get_arg(1) . '; ?>');
79 3
            };
80
        }
81
82
        $instance     = is_object($instance) ? $instance : null;
83
        $boundInvoker = $invoker->bindTo($instance, $scope);
84
85
        foreach ($contracts as $contract) {
86
            $contractExpression = $contract->value;
87
            try {
88
                $invocationResult = $boundInvoker->__invoke($args, $contractExpression);
89
90
                // we accept as a result only true or null
91
                // null may be a result of assertions from beberlei/assert which passed
92
                if ($invocationResult !== null && $invocationResult !== true) {
93
                    $errorMessage = 'Invalid return value received from the assertion body,'
94
                        . ' only boolean or void can be returned';
95
                    throw new DomainException($errorMessage);
96
                }
97
0 ignored issues
show
Coding Style introduced by
Blank line found at end of control structure
Loading history...
98
            } catch (\Error $internalError) {
0 ignored issues
show
Bug introduced by
The class Error does not exist. Did you forget a USE statement, or did you not list all dependencies?

Scrutinizer analyzes your composer.json/composer.lock file if available to determine the classes, and functions that are defined by your dependencies.

It seems like the listed class was neither found in your dependencies, nor was it found in the analyzed files in your repository. If you are using some other form of dependency management, you might want to disable this analysis.

Loading history...
99
                // PHP-7 friendly interceptor for fatal errors
100
                throw new ContractViolation($invocation, $contractExpression, $internalError);
101
            } catch (\Exception $internalException) {
102
                throw new ContractViolation($invocation, $contractExpression, $internalException);
103
            }
104
        }
105
    }
106
}
107