Completed
Push — develop ( f8a065...99d87a )
by Baptiste
03:38
created

ResourceController   C

Complexity

Total Complexity 11

Size/Duplication

Total Lines 175
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 21

Test Coverage

Coverage 96.39%

Importance

Changes 0
Metric Value
wmc 11
lcom 1
cbo 21
dl 0
loc 175
ccs 80
cts 83
cp 0.9639
rs 6.1111
c 0
b 0
f 0

4 Methods

Rating   Name   Duplication   Size   Complexity  
B __construct() 0 24 3
B listAction() 0 66 6
B getAction() 0 39 1
B optionsAction() 0 32 1
1
<?php
2
declare(strict_types = 1);
3
4
namespace Innmind\Rest\ServerBundle\Controller;
5
6
use Innmind\Rest\ServerBundle\{
7
    Format,
8
    Exception\InvalidArgumentException
9
};
10
use Innmind\Rest\Server\{
11
    RangeExtractor\ExtractorInterface,
12
    SpecificationBuilder\BuilderInterface,
13
    Response\HeaderBuilder\ListBuilderInterface,
14
    Response\HeaderBuilder\GetBuilderInterface,
15
    GatewayInterface,
16
    Request\Range,
17
    Exception\RangeNotFoundException,
18
    Exception\NoFilterFoundException,
19
    Identity
20
};
21
use Innmind\Http\{
22
    Message\ResponseInterface,
23
    Message\Response,
24
    Message\StatusCode,
25
    Message\ReasonPhrase,
26
    Headers,
27
    Header\HeaderInterface,
28
    Header\ContentType,
29
    Header\ContentTypeValue,
30
    Header\ParameterInterface,
31
    Exception\Http\RangeNotSatisfiableException
32
};
33
use Innmind\Filesystem\Stream\StringStream;
34
use Innmind\Immutable\{
35
    Map,
36
    MapInterface
37
};
38
use Symfony\Component\{
39
    HttpFoundation\Request,
40
    Serializer\SerializerInterface
41
};
42
43
final class ResourceController
44
{
45
    private $format;
46
    private $serializer;
47
    private $rangeExtractor;
48
    private $specificationBuilder;
49
    private $gateways;
50
    private $listHeaderBuilder;
51
    private $getHeaderBuilder;
52
53 5
    public function __construct(
54
        Format $format,
55
        SerializerInterface $serializer,
56
        ExtractorInterface $rangeExtractor,
57
        BuilderInterface $specificationBuilder,
58
        MapInterface $gateways,
59
        ListBuilderInterface $listHeaderBuilder,
60
        GetBuilderInterface $getHeaderBuilder
61
    ) {
62
        if (
63 5
            (string) $gateways->keyType() !== 'string' ||
64 5
            (string) $gateways->valueType() !== GatewayInterface::class
65
        ) {
66
            throw new InvalidArgumentException;
67
        }
68
69 5
        $this->format = $format;
70 5
        $this->serializer = $serializer;
71 5
        $this->rangeExtractor = $rangeExtractor;
72 5
        $this->specificationBuilder = $specificationBuilder;
73 5
        $this->gateways = $gateways;
74 5
        $this->listHeaderBuilder = $listHeaderBuilder;
75 5
        $this->getHeaderBuilder = $getHeaderBuilder;
76 5
    }
77
78 3
    public function listAction(Request $request): ResponseInterface
79
    {
80 3
        $definition = $request->attributes->get('_innmind_resource_definition');
81 3
        $request = $request->attributes->get('_innmind_request');
82
83
        try {
84 3
            $range = $this->rangeExtractor->extract($request);
85 1
        } catch (RangeNotFoundException $e) {
86 1
            $range = null;
87
        }
88
89
        try {
90 3
            $specification = $this->specificationBuilder->buildFrom(
91
                $request,
92
                $definition
93
            );
94
        } catch (NoFilterFoundException $e) {
95
            $specification = null;
96
        }
97
98
        $accessor = $this
99 3
            ->gateways
100 3
            ->get((string) $definition->gateway())
101 3
            ->resourceListAccessor();
102 3
        $identities = $accessor(
103
            $definition,
104
            $specification,
105
            $range
106
        );
107
108
        if (
109 3
            $identities->size() === 0 &&
110 3
            $range instanceof Range
111
        ) {
112 1
            throw new RangeNotSatisfiableException;
113
        }
114
115 2
        return new Response(
116 2
            $code = new StatusCode(StatusCode::codes()->get(
117 2
                $range instanceof Range ? 'PARTIAL_CONTENT' : 'OK'
118
            )),
119 2
            new ReasonPhrase(ReasonPhrase::defaults()->get($code->value())),
120 2
            $request->protocolVersion(),
121 2
            new Headers(
122 2
                $this->listHeaderBuilder->build(
123
                    $identities,
124
                    $request,
125
                    $definition,
126
                    $specification,
127
                    $range
128
                )
129
            ),
130 2
            new StringStream(
131 2
                $this->serializer->serialize(
132
                    $identities,
133 2
                    $this->format->acceptable($request)->name(),
134
                    [
135 2
                        'request' => $request,
136 2
                        'definition' => $definition,
137 2
                        'specification' => $specification,
138 2
                        'range' => $range,
139
                    ]
140
                )
141
            )
142
        );
143
    }
144
145 1
    public function getAction(Request $request, $identity): ResponseInterface
146
    {
147 1
        $definition = $request->attributes->get('_innmind_resource_definition');
148 1
        $request = $request->attributes->get('_innmind_request');
149
150
        $accessor = $this
151 1
            ->gateways
152 1
            ->get((string) $definition->gateway())
153 1
            ->resourceAccessor();
154 1
        $resource = $accessor(
155
            $definition,
156 1
            $identity = new Identity($identity)
157
        );
158
159 1
        return new Response(
160 1
            $code = new StatusCode(StatusCode::codes()->get('OK')),
161 1
            new ReasonPhrase(ReasonPhrase::defaults()->get($code->value())),
162 1
            $request->protocolVersion(),
163 1
            new Headers(
164 1
                $this->getHeaderBuilder->build(
165
                    $resource,
166
                    $request,
167
                    $definition,
168
                    $identity
169
                )
170
            ),
171 1
            new StringStream(
172 1
                $this->serializer->serialize(
173
                    $resource,
174 1
                    $this->format->acceptable($request)->name(),
175
                    [
176 1
                        'request' => $request,
177 1
                        'definition' => $definition,
178 1
                        'identity' => $identity,
179
                    ]
180
                )
181
            )
182
        );
183
    }
184
185 1
    public function optionsAction(Request $request): ResponseInterface
186
    {
187 1
        $definition = $request->attributes->get('_innmind_resource_definition');
188 1
        $request = $request->attributes->get('_innmind_request');
189 1
        $format = $this->format->acceptable($request);
190 1
        $mediaType = $format->preferredMediaType();
191
192 1
        return new Response(
193 1
            $code = new StatusCode(StatusCode::codes()->get('OK')),
194 1
            new ReasonPhrase(ReasonPhrase::defaults()->get($code->value())),
195 1
            $request->protocolVersion(),
196 1
            new Headers(
197 1
                (new Map('string', HeaderInterface::class))
198 1
                    ->put(
199 1
                        'Content-Type',
200 1
                        new ContentType(
201 1
                            new ContentTypeValue(
202 1
                                $mediaType->topLevel(),
203 1
                                $mediaType->subType(),
204 1
                                new Map('string', ParameterInterface::class)
205
                            )
206
                        )
207
                    )
208
            ),
209 1
            new StringStream(
210 1
                $this->serializer->serialize(
211
                    $definition,
212 1
                    $format->name()
213
                )
214
            )
215
        );
216
    }
217
}
218