Completed
Push — 1.x ( 5c4b05...48f04b )
by Akihito
12s
created

NamedParameter::overrideAssistedParam()   B

Complexity

Conditions 5
Paths 9

Size

Total Lines 17
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 9
CRAP Score 5.025

Importance

Changes 0
Metric Value
dl 0
loc 17
c 0
b 0
f 0
ccs 9
cts 10
cp 0.9
rs 8.8571
cc 5
eloc 10
nc 9
nop 2
crap 5.025
1
<?php
2
/**
3
 * This file is part of the BEAR.Resource package.
4
 *
5
 * @license http://opensource.org/licenses/MIT MIT
6
 */
7
namespace BEAR\Resource;
8
9
use BEAR\Resource\Annotation\AbstracAsssistedParam;
10
use BEAR\Resource\Annotation\ResourceParam;
11
use Doctrine\Common\Annotations\Reader;
12
use Doctrine\Common\Cache\Cache;
13
use Ray\Di\Di\Assisted;
14
use Ray\Di\InjectorInterface;
15
16
final class NamedParameter implements NamedParameterInterface
17
{
18
    /**
19
     * @var Cache
20
     */
21
    private $cache;
22
23
    /**
24
     * @var Reader
25
     */
26
    private $reader;
27
28
    /**
29
     * @var InjectorInterface
30
     */
31
    private $injector;
32
33 87
    public function __construct(Cache $cache, Reader $reader, InjectorInterface $injector)
34
    {
35 87
        $this->cache = $cache;
36 87
        $this->reader = $reader;
37 87
        $this->injector = $injector;
38 87
    }
39
40
    /**
41
     * {@inheritdoc}
42
     */
43 55
    public function getParameters(array $callable, array $query)
44
    {
45 55
        $cacheId = __CLASS__ . get_class($callable[0]) . $callable[1];
46 55
        $names = $this->cache->fetch($cacheId);
47 55
        if (! $names) {
48 54
            $names = $this->getNamedParamMetas($callable);
49 54
            $this->cache->save($cacheId, $names);
50
        }
51 55
        $parameters = $this->evaluateParams($query, $names);
52
53 50
        return $parameters;
54
    }
55
56
    /**
57
     * Return evaluated parameters
58
     *
59
     * @param array            $query caller value
60
     * @param ParamInterface[] $names Param object[] ['varName' => ParamInterface]
61
     *
62
     * @return array
63
     */
64 55
    private function evaluateParams(array $query, array $names)
65
    {
66 55
        $parameters = [];
67 55
        foreach ($names as $varName => $param) {
68
            /* @var $param ParamInterface */
69 47
            $parameters[] = $param($varName, $query, $this->injector);
70
        }
71
72 50
        return $parameters;
73
    }
74
75
    /**
76
     * Return named parameter information
77
     *
78
     * @param array $callable
79
     *
80
     * @return array
81
     */
82 54
    private function getNamedParamMetas(array $callable)
83
    {
84 54
        $method = new \ReflectionMethod($callable[0], $callable[1]);
85 54
        $parameters = $method->getParameters();
86 54
        $names = [];
87 54
        foreach ($parameters as $parameter) {
88 46
            $names[$parameter->name] = $parameter->isDefaultValueAvailable() === true ? new OptionalParam($parameter->getDefaultValue()) : new RequiredParam;
89
        }
90 54
        $names = $this->overrideAssistedParam($method, $names);
91
92 54
        return $names;
93
    }
94
95
    /**
96
     * Set "method injection" parameter
97
     *
98
     * @return array
99
     */
100 54
    private function overrideAssistedParam(\ReflectionMethod $method, array $names)
101
    {
102 54
        $annotations = $this->reader->getMethodAnnotations($method);
103 54
        foreach ($annotations as $annotation) {
104 22
            if ($annotation instanceof ResourceParam) {
105 3
                $names[$annotation->param] = new AssistedResourceParam($annotation);
106
            }
107 22
            if ($annotation instanceof Assisted) {
108 1
                $names = $this->setAssistedAnnotation($names, $annotation);
109
            }
110 22
            if ($annotation instanceof AbstracAsssistedParam) {
111
                $names = $this->setAssistedParam($names, $annotation);
112
            }
113
        }
114
115 54
        return $names;
116
    }
117
118
    /**
119
     * Set AssistedParam objects
120
     *
121
     * null is used for Assisted interceptor
122
     *
123
     * @return array
124
     */
125 1
    private function setAssistedAnnotation(array $names, Assisted $assisted)
126
    {
127
        /* @var $annotation Assisted */
128 1
        foreach ($assisted->values as $assistedParam) {
129 1
            $names[$assistedParam] = new AssistedParam;
130
        }
131
132 1
        return $names;
133
    }
134
135
    /**
136
     * @return array
137
     */
138
    private function setAssistedParam(array $names, AbstracAsssistedParam $asssistedParam)
139
    {
140
        $names[$asssistedParam->param] = new AssistedParam;
141
142
        return $names;
143
    }
144
}
145