Completed
Push — 1.x ( ed8928...51f4d3 )
by Akihito
06:08 queued 04:26
created

NamedParameter::setAssistedParam()   B

Complexity

Conditions 5
Paths 9

Size

Total Lines 18
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 11
CRAP Score 5

Importance

Changes 0
Metric Value
dl 0
loc 18
ccs 11
cts 11
cp 1
rs 8.8571
c 0
b 0
f 0
cc 5
eloc 11
nc 9
nop 1
crap 5
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\ResourceParam;
10
use Doctrine\Common\Annotations\Reader;
11
use Doctrine\Common\Cache\Cache;
12
use Ray\Di\Di\Assisted;
13
use Ray\Di\InjectorInterface;
14
use Ray\WebContextParam\Annotation\AbstractWebContextParam;
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
    /**
34
     * @var array
35
     */
36
    private $globals;
37
38 92
    public function __construct(Cache $cache, Reader $reader, InjectorInterface $injector, array $globals = [])
39
    {
40 92
        $this->cache = $cache;
41 92
        $this->reader = $reader;
42 92
        $this->injector = $injector;
43 92
        $this->globals = $globals;
44 92
    }
45
46
    /**
47
     * {@inheritdoc}
48
     */
49 59
    public function getParameters(array $callable, array $query)
50
    {
51 59
        $cacheId = __CLASS__ . get_class($callable[0]) . $callable[1];
52 59
        $names = $this->cache->fetch($cacheId);
53 59
        if (! $names) {
54 58
            $names = $this->getNamedParamMetas($callable);
55 58
            $this->cache->save($cacheId, $names);
56
        }
57 59
        $parameters = $this->evaluateParams($query, $names);
58
59 52
        return $parameters;
60
    }
61
62
    /**
63
     * Return evaluated parameters
64
     *
65
     * @param array            $query caller value
66
     * @param ParamInterface[] $names Param object[] ['varName' => ParamInterface]
67
     *
68
     * @return array
69
     */
70 59
    private function evaluateParams(array $query, array $names)
71
    {
72 59
        $parameters = [];
73 59
        foreach ($names as $varName => $param) {
74
            /* @var $param ParamInterface */
75 51
            $parameters[] = $param($varName, $query, $this->injector);
76
        }
77
78 52
        return $parameters;
79
    }
80
81
    /**
82
     * Return named parameter information
83
     *
84
     * @param array $callable
85
     *
86
     * @return array
87
     */
88 58
    private function getNamedParamMetas(array $callable)
89
    {
90 58
        $method = new \ReflectionMethod($callable[0], $callable[1]);
91 58
        $parameters = $method->getParameters();
92 58
        list($names, $webcontext) = $this->setAssistedParam($method);
93 58
        foreach ($parameters as $parameter) {
94 50
            if (isset($names[$parameter->name])) {
95 4
                continue;
96
            }
97 49
            if (isset($webcontext[$parameter->name])) {
98 4
                $default = $parameter->isDefaultValueAvailable() === true ? new DefaultParam($parameter->getDefaultValue()) : new NoDefaultParam();
99 4
                $names[$parameter->name] = new AssistedWebContextParam($webcontext[$parameter->name], $default);
100 4
                continue;
101
            }
102 47
            $names[$parameter->name] = $parameter->isDefaultValueAvailable() === true ? new OptionalParam($parameter->getDefaultValue()) : new RequiredParam;
103
        }
104
105 58
        return $names;
106
    }
107
108
    /**
109
     * Set "method injection" parameter
110
     *
111
     * @return array
112
     */
113 58
    private function setAssistedParam(\ReflectionMethod $method)
114
    {
115 58
        $names = $webcontext = [];
116 58
        $annotations = $this->reader->getMethodAnnotations($method);
117 58
        foreach ($annotations as $annotation) {
118 26
            if ($annotation instanceof ResourceParam) {
119 3
                $names[$annotation->param] = new AssistedResourceParam($annotation);
120
            }
121 26
            if ($annotation instanceof Assisted) {
122 1
                $names = $this->setAssistedAnnotation($names, $annotation);
123
            }
124 26
            if ($annotation instanceof AbstractWebContextParam) {
125 4
                $webcontext[$annotation->param] = $annotation;
126
            }
127
        }
128
129 58
        return [$names, $webcontext];
130
    }
131
132
    /**
133
     * Set AssistedParam objects
134
     *
135
     * null is used for Assisted interceptor
136
     *
137
     * @return array
138
     */
139 1
    private function setAssistedAnnotation(array $names, Assisted $assisted)
140
    {
141
        /* @var $annotation Assisted */
142 1
        foreach ($assisted->values as $assistedParam) {
143 1
            $names[$assistedParam] = new AssistedParam;
144
        }
145
146 1
        return $names;
147
    }
148
}
149