Completed
Push — 1.x ( 78e4c3...8b7e48 )
by Akihito
10s
created

NamedParamMetas::getParam()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 2

Importance

Changes 0
Metric Value
dl 0
loc 4
ccs 2
cts 2
cp 1
rs 10
c 0
b 0
f 0
cc 2
eloc 2
nc 2
nop 1
crap 2
1
<?php
2
3
declare(strict_types=1);
4
/**
5
 * This file is part of the BEAR.Resource package.
6
 *
7
 * @license http://opensource.org/licenses/MIT MIT
8
 */
9
namespace BEAR\Resource;
10
11
use BEAR\Resource\Annotation\ResourceParam;
12
use Doctrine\Common\Annotations\Reader;
13
use Doctrine\Common\Cache\Cache;
14
use Ray\Di\Di\Assisted;
15
use Ray\WebContextParam\Annotation\AbstractWebContextParam;
16
17
final class NamedParamMetas implements NamedParamMetasInterface
18
{
19
    /**
20
     * @var Cache
21
     */
22
    private $cache;
23
24
    /**
25
     * @var Reader
26
     */
27
    private $reader;
28
29 102
    public function __construct(Cache $cache, Reader $reader)
30
    {
31 102
        $this->cache = $cache;
32 102
        $this->reader = $reader;
33 102
    }
34
35 71
    public function __invoke(callable $callable) : array
36
    {
37 71
        $cacheId = __CLASS__ . get_class($callable[0]) . $callable[1];
38 71
        $names = $this->cache->fetch($cacheId);
39 71
        if ($names) {
40 9
            return $names;
41
        }
42 68
        $method = new \ReflectionMethod($callable[0], $callable[1]);
43 68
        $parameters = $method->getParameters();
44 68
        $annotations = $this->reader->getMethodAnnotations($method);
45 68
        $assistedNames = $this->getAssistedNames($annotations);
46 68
        $webContext = $this->getWebContext($annotations);
47 68
        $namedParamMetas = $this->addNamedParams($parameters, $assistedNames, $webContext);
48 68
        $this->cache->save($cacheId, $namedParamMetas);
49
50 68
        return $namedParamMetas;
51
    }
52
53 68
    private function getAssistedNames(array $annotations) : array
54
    {
55 68
        $names = [];
56 68
        foreach ($annotations as $annotation) {
57 35
            if ($annotation instanceof ResourceParam) {
58 3
                $names[$annotation->param] = new AssistedResourceParam($annotation);
59
            }
60 35
            if ($annotation instanceof Assisted) {
61 35
                $names = $this->setAssistedAnnotation($names, $annotation);
62
            }
63
        }
64
65 68
        return $names;
66
    }
67
68 68
    private function getWebContext(array $annotations) : array
69
    {
70 68
        $webcontext = [];
71 68
        foreach ($annotations as $annotation) {
72 35
            if ($annotation instanceof AbstractWebContextParam) {
73 35
                $webcontext[$annotation->param] = $annotation;
74
            }
75
        }
76
77 68
        return $webcontext;
78
    }
79
80 1
    private function setAssistedAnnotation(array $names, Assisted $assisted) : array
81
    {
82
        /* @var $annotation Assisted */
83 1
        foreach ($assisted->values as $assistedParam) {
84 1
            $names[$assistedParam] = new AssistedParam;
85
        }
86
87 1
        return $names;
88
    }
89
90
    /**
91
     * @param \ReflectionParameter[] $parameters
92
     * @param array                  $assistedNames
93
     * @param array                  $webcontext
94
     *
95
     * @return ParamInterface[]
96
     */
97 68
    private function addNamedParams(array $parameters, array $assistedNames, array $webcontext) : array
98
    {
99 68
        $names = [];
100 68
        foreach ($parameters as $parameter) {
101 59
            if (isset($assistedNames[$parameter->name])) {
102 4
                $names[$parameter->name] = $assistedNames[$parameter->name];
103 4
                continue;
104
            }
105 58
            if (isset($webcontext[$parameter->name])) {
106 4
                $default = $this->getDefault($parameter);
107 4
                $names[$parameter->name] = new AssistedWebContextParam($webcontext[$parameter->name], $default);
108 4
                continue;
109
            }
110 56
            $names[$parameter->name] = $this->getParam($parameter);
111
        }
112
113 68
        return $names;
114
    }
115
116 4
    private function getDefault(\ReflectionParameter $parameter) : ParamInterface
117
    {
118 4
        return $parameter->isDefaultValueAvailable() === true ? new DefaultParam($parameter->getDefaultValue()) : new NoDefaultParam();
119
    }
120
121 56
    private function getParam(\ReflectionParameter $parameter) : ParamInterface
122
    {
123 56
        return $parameter->isDefaultValueAvailable() === true ? new OptionalParam($parameter->getDefaultValue()) : new RequiredParam;
124
    }
125
}
126