Completed
Push — fake_json ( 3414f8...1903bd )
by Akihito
09:01 queued 07:08
created

OptionsMethods::getMethodExtras()   A

Complexity

Conditions 4
Paths 5

Size

Total Lines 15

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 15
rs 9.7666
c 0
b 0
f 0
cc 4
nc 5
nop 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace BEAR\Resource;
6
7
use BEAR\Resource\Annotation\Embed;
8
use BEAR\Resource\Annotation\JsonSchema;
9
use BEAR\Resource\Annotation\Link;
10
use Doctrine\Common\Annotations\Reader;
11
use Ray\Di\Di\Named;
12
use Ray\WebContextParam\Annotation\AbstractWebContextParam;
13
use Ray\WebContextParam\Annotation\CookieParam;
14
use Ray\WebContextParam\Annotation\EnvParam;
15
use Ray\WebContextParam\Annotation\FormParam;
16
use Ray\WebContextParam\Annotation\QueryParam;
17
use Ray\WebContextParam\Annotation\ServerParam;
18
19
final class OptionsMethods
20
{
21
    /**
22
     * Constants for annotation name and "in" name
23
     *
24
     * @var array
25
     */
26
    const WEB_CONTEXT_NAME = [
27
        CookieParam::class => 'cookie',
28
        EnvParam::class => 'env',
29
        FormParam::class => 'formData',
30
        QueryParam::class => 'query',
31
        ServerParam::class => 'server'
32
    ];
33
34
    private $reader;
35
36
    /**
37
     * @var string
38
     */
39
    private $schemaDir;
40
41
    /**
42
     * @Named("schemaDir=json_schema_dir")
43
     */
44
    public function __construct(Reader $reader, string $schemaDir = '')
45
    {
46
        $this->reader = $reader;
47
        $this->schemaDir = $schemaDir;
48
    }
49
50
    public function __invoke(ResourceObject $ro, string $requestMethod) : array
51
    {
52
        $method = new \ReflectionMethod(get_class($ro), 'on' . $requestMethod);
53
        $ins = $this->getInMap($method);
54
        list($doc, $paramDoc) = (new OptionsMethodDocBolck)($method);
55
        $methodOption = $doc;
56
        $paramMetas = (new OptionsMethodRequest($this->reader))($method, $paramDoc, $ins);
57
        $schema = $this->getJsonSchema($method);
58
        $request = $paramMetas ? ['request' => $paramMetas] : [];
59
        $methodOption += $request;
60
        if (! empty($schema)) {
61
            $methodOption += ['schema' => $schema];
62
        }
63
        $extras = $this->getMethodExtras($method);
64
        if (! empty($extras)) {
65
            $methodOption += $extras;
66
        }
67
68
        return $methodOption;
69
    }
70
71
    private function getMethodExtras(\ReflectionMethod $method) : array
72
    {
73
        $extras = [];
74
        $annotations = $this->reader->getMethodAnnotations($method);
75
        foreach ($annotations as $annotation) {
76
            if ($annotation instanceof Link) {
77
                $extras['links'][] = $annotation;
78
            }
79
            if ($annotation instanceof Embed) {
80
                $extras['embed'][] = $annotation;
81
            }
82
        }
83
84
        return $extras;
85
    }
86
87
    private function getInMap(\ReflectionMethod $method) : array
88
    {
89
        $ins = [];
90
        $annotations = $this->reader->getMethodAnnotations($method);
91
        foreach ($annotations as $annotation) {
92
            if ($annotation instanceof AbstractWebContextParam) {
93
                $ins[$annotation->param] = self::WEB_CONTEXT_NAME[get_class($annotation)];
94
            }
95
        }
96
97
        return $ins;
98
    }
99
100
    private function getJsonSchema(\ReflectionMethod $method) : array
101
    {
102
        $schema = $this->reader->getMethodAnnotation($method, JsonSchema::class);
103
        if (! $schema instanceof JsonSchema) {
104
            return [];
105
        }
106
        $schemaFile = $this->schemaDir . '/' . $schema->schema;
107
        if (! file_exists($schemaFile)) {
108
            return [];
109
        }
110
111
        return (array) json_decode(file_get_contents($schemaFile));
112
    }
113
}
114