Completed
Push — code201 ( 677523...68154a )
by Akihito
08:44 queued 05:59
created

OptionsMethodRequest   A

Complexity

Total Complexity 29

Size/Duplication

Total Lines 146
Duplicated Lines 0 %

Coupling/Cohesion

Components 2
Dependencies 3

Test Coverage

Coverage 100%

Importance

Changes 0
Metric Value
wmc 29
lcom 2
cbo 3
dl 0
loc 146
ccs 67
cts 67
cp 1
rs 10
c 0
b 0
f 0

11 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 4 1
A __invoke() 0 7 1
A getParameterType() 0 10 4
A getParamMetas() 0 17 4
A getRequired() 0 11 3
A paramDefault() 0 9 3
A paramType() 0 9 2
A getType() 0 9 2
A ignoreAnnotatedPrameter() 0 15 4
A ignorreAssisted() 0 9 2
A setParamMetas() 0 12 3
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 Ray\Di\Di\Assisted;
12
13
final class OptionsMethodRequest
14
{
15
    private $reader;
16
17 7
    public function __construct(Reader $reader)
18
    {
19 7
        $this->reader = $reader;
20 7
    }
21
22 7
    public function __invoke(\ReflectionMethod $method, array $paramDoc, array $ins) : array
23
    {
24 7
        $paramMetas = $this->getParamMetas($method->getParameters(), $paramDoc, $ins);
25 7
        $paramMetas = $this->ignoreAnnotatedPrameter($method, $paramMetas);
26
27 7
        return $paramMetas;
28
    }
29
30
    /**
31
     * @param \ReflectionParameter $parameter
32
     * @param array                $paramDoc
33
     * @param string               $name
34
     *
35
     * @return string|null
36
     */
37 7
    private function getParameterType(\ReflectionParameter $parameter, array $paramDoc, string $name)
38
    {
39 7
        $hasType = method_exists($parameter, 'getType') && $parameter->getType();
40 7
        if ($hasType) {
41 1
            return $this->getType($parameter);
42
        }
43 7
        if (isset($paramDoc[$name]['type'])) {
44 3
            return $paramDoc[$name]['type'];
45
        }
46 4
    }
47
48 7
    private function getParamMetas(array $parameters, array $paramDoc, array $ins) : array
49
    {
50 7
        foreach ($parameters as $parameter) {
51 7
            if (isset($ins[$parameter->name])) {
52 2
                $paramDoc[$parameter->name]['in'] = $ins[$parameter->name];
53
            }
54 7
            if (! isset($paramDoc[$parameter->name])) {
55 4
                $paramDoc[$parameter->name] = [];
56
            }
57 7
            $paramDoc = $this->paramType($paramDoc, $parameter);
58 7
            $paramDoc = $this->paramDefault($paramDoc, $parameter);
59
        }
60 7
        $required = $this->getRequired($parameters);
61 7
        $paramMetas = $this->setParamMetas($paramDoc, $required);
62
63 7
        return $paramMetas;
64
    }
65
66
    /**
67
     * @param \ReflectionParameter[] $parameters
68
     */
69 7
    private function getRequired(array $parameters) : array
70
    {
71 7
        $required = [];
72 7
        foreach ($parameters as $parameter) {
73 7
            if (! $parameter->isOptional()) {
74 7
                $required[] = $parameter->name;
75
            }
76
        }
77
78 7
        return $required;
79
    }
80
81 7
    private function paramDefault(array $paramDoc, \ReflectionParameter $parameter) : array
82
    {
83 7
        $hasDefault = $parameter->isDefaultValueAvailable() && $parameter->getDefaultValue() !== null;
84 7
        if ($hasDefault) {
85 2
            $paramDoc[$parameter->name]['default'] = (string) $parameter->getDefaultValue();
86
        }
87
88 7
        return $paramDoc;
89
    }
90
91 7
    private function paramType(array $paramDoc, \ReflectionParameter $parameter) : array
92
    {
93 7
        $type = $this->getParameterType($parameter, $paramDoc, $parameter->name);
94 7
        if (is_string($type)) {
95 3
            $paramDoc[$parameter->name]['type'] = $type;
96
        }
97
98 7
        return $paramDoc;
99
    }
100
101
    /**
102
     * @param \ReflectionParameter $parameter
103
     */
104 1
    private function getType(\ReflectionParameter $parameter) : string
105
    {
106 1
        $type = (string) $parameter->getType();
107 1
        if ($type === 'int') {
108 1
            $type = 'integer';
109
        }
110
111 1
        return $type;
112
    }
113
114
    /**
115
     * Ignore @ Assisted @ ResourceParam parameter
116
     */
117 7
    private function ignoreAnnotatedPrameter(\ReflectionMethod $method, array $paramMetas) : array
118
    {
119 7
        $annotations = $this->reader->getMethodAnnotations($method);
120 7
        foreach ($annotations as $annotation) {
121 5
            if ($annotation instanceof ResourceParam) {
122 1
                unset($paramMetas['parameters'][$annotation->param]);
123 1
                $paramMetas['required'] = array_values(array_diff($paramMetas['required'], [$annotation->param]));
124
            }
125 5
            if ($annotation instanceof Assisted) {
126 5
                $paramMetas = $this->ignorreAssisted($paramMetas, $annotation);
127
            }
128
        }
129
130 7
        return $paramMetas;
131
    }
132
133
    /**
134
     * Ignore @ Assisted parameter
135
     */
136 1
    private function ignorreAssisted(array $paramMetas, Assisted $annotation) : array
137
    {
138 1
        $paramMetas['required'] = array_values(array_diff($paramMetas['required'], $annotation->values));
139 1
        foreach ($annotation->values as $varName) {
140 1
            unset($paramMetas['parameters'][$varName]);
141
        }
142
143 1
        return $paramMetas;
144
    }
145
146 7
    private function setParamMetas(array $paramDoc, array $required) : array
147
    {
148 7
        $paramMetas = [];
149 7
        if ((bool) $paramDoc) {
150 7
            $paramMetas['parameters'] = $paramDoc;
151
        }
152 7
        if ((bool) $required) {
153 7
            $paramMetas['required'] = $required;
154
        }
155
156 7
        return $paramMetas;
157
    }
158
}
159