DocNormalizer::normalize()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 10
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 9
CRAP Score 1

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 7
c 1
b 0
f 0
nc 1
nop 1
dl 0
loc 10
ccs 9
cts 9
cp 1
crap 1
rs 10
1
<?php
2
namespace Yoanm\JsonRpcHttpServerOpenAPIDoc\Infra\Normalizer;
3
4
use Yoanm\JsonRpcHttpServerOpenAPIDoc\App\Helper\ArrayAppendHelperTrait;
5
use Yoanm\JsonRpcHttpServerOpenAPIDoc\App\Normalizer\Component\ExternalSchemaListDocNormalizer;
6
use Yoanm\JsonRpcHttpServerOpenAPIDoc\App\Normalizer\Component\OperationDocNormalizer;
7
use Yoanm\JsonRpcServerDoc\Domain\Model\HttpServerDoc;
8
use Yoanm\JsonRpcServerDoc\Domain\Model\TagDoc;
9
10
/**
11
 * Class DocNormalizer
12
 */
13
class DocNormalizer
14
{
15
    use ArrayAppendHelperTrait;
16
17
    /** @var ExternalSchemaListDocNormalizer */
18
    private $externalSchemaListDocNormalizer;
19
    /** @var OperationDocNormalizer */
20
    private $operationDocNormalizer;
21
22
    /**
23
     * @param ExternalSchemaListDocNormalizer $externalSchemaListDocNormalizer
24
     * @param OperationDocNormalizer          $operationDocNormalizer
25
     */
26 44
    public function __construct(
27
        ExternalSchemaListDocNormalizer $externalSchemaListDocNormalizer,
28
        OperationDocNormalizer $operationDocNormalizer
29
    ) {
30 44
        $this->externalSchemaListDocNormalizer = $externalSchemaListDocNormalizer;
31 44
        $this->operationDocNormalizer = $operationDocNormalizer;
32
    }
33
34
    /**
35
     * @param HttpServerDoc $doc
36
     *
37
     * @return array
38
     *
39
     * @throws \ReflectionException
40
     */
41 44
    public function normalize(HttpServerDoc $doc)
42
    {
43 44
        return [
44 44
                'openapi' => '3.0.0',
45 44
            ]
46 44
            + $this->infoArray($doc)
47 44
            + $this->serverArray($doc)
48 44
            + $this->tagsArray($doc)
49 44
            + $this->pathsArray($doc)
50 44
            + $this->externalSchemaListArray($doc);
51
    }
52
53
    /**
54
     * {@inheritdoc}
55
     */
56 44
    protected function infoArray(HttpServerDoc $doc)
57
    {
58 44
        $infoArray = [];
59 44
        $infoArray = $this->appendIfValueNotNull('title', $doc->getName(), $infoArray);
60 44
        $infoArray = $this->appendIfValueNotNull('version', $doc->getVersion(), $infoArray);
61
62 44
        return $this->appendIfValueHaveSiblings('info', $infoArray);
63
    }
64
65
    /**
66
     * {@inheritdoc}
67
     */
68 44
    protected function serverArray(HttpServerDoc $doc)
69
    {
70 44
        $serverList = [];
71 44
        if (null !== $doc->getHost()) {
72 5
            $host = $doc->getHost();
73 5
            if (null !== $doc->getBasePath()) {
74 3
                $host .= $doc->getBasePath();
75
            }
76 5
            $schemeList = $doc->getSchemeList();
77 5
            if (0 === count($schemeList)) {
78 3
                $schemeList[] = 'http';
79
            }
80 5
            foreach ($schemeList as $scheme) {
81 5
                $serverList[] = ['url' => sprintf('%s://%s', $scheme, $host)];
82
            }
83
        }
84
85 44
        return $this->appendIfValueHaveSiblings('servers', $serverList);
86
    }
87
88
    /**
89
     * {@inheritdoc}
90
     */
91 44
    protected function tagsArray(HttpServerDoc $doc)
92
    {
93 44
        $self = $this;
94
95 44
        return $this->appendIfValueHaveSiblings(
96 44
            'tags',
97 44
            array_map(
98 44
                function (TagDoc $tagDoc) use ($self) {
99 4
                    return $self->convertToTagDoc($tagDoc);
100 44
                },
101 44
                $doc->getTagList()
102 44
            )
103 44
        );
104
    }
105
106
    /**
107
     * {@inheritdoc}
108
     */
109 44
    protected function pathsArray(HttpServerDoc $doc)
110
    {
111 44
        $paths = [];
112 44
        foreach ($doc->getMethodList() as $method) {
113 9
            $operationDoc = $this->operationDocNormalizer->normalize($method, $doc);
114
115
            // As JSON-RPC use only one endpoint
116
            // and openApi does not handle multiple request definition for the same endpoint
117
            // => create a fake (but usable) endpoint by using method id and '/../'
118 9
            $openApiHttpEndpoint = sprintf(
119 9
                '/%s/..%s',
120 9
                str_replace('/', '-', $method->getIdentifier()),
121 9
                $doc->getEndpoint() ?? ''
122 9
            );
123
124 9
            $paths[$openApiHttpEndpoint] = ['post' => $operationDoc];
125
        }
126
127 44
        return $this->appendIfValueHaveSiblings('paths', $paths);
128
    }
129
130
    /**
131
     * @param HttpServerDoc $doc
132
     *
133
     * @return array
134
     *
135
     * @throws \ReflectionException
136
     */
137 44
    protected function externalSchemaListArray(HttpServerDoc $doc)
138
    {
139 44
        return [
140 44
            'components' => [
141 44
                'schemas' => $this->externalSchemaListDocNormalizer->normalize($doc),
142 44
            ],
143 44
        ];
144
    }
145
146
    /**
147
     * @param TagDoc $tag
148
     *
149
     * @return array
150
     */
151 4
    private function convertToTagDoc(TagDoc $tag)
152
    {
153 4
        $tagDoc = [
154 4
            'name' => $tag->getName(),
155 4
        ];
156 4
        if (null !== $tag->getDescription()) {
157 3
            $tagDoc['description'] = $tag->getDescription();
158
        }
159
160 4
        return $tagDoc;
161
    }
162
}
163