ListController::__construct()   B
last analyzed

Complexity

Conditions 3
Paths 2

Size

Total Lines 25
Code Lines 19

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 13
CRAP Score 3

Importance

Changes 0
Metric Value
dl 0
loc 25
ccs 13
cts 13
cp 1
rs 8.8571
c 0
b 0
f 0
cc 3
eloc 19
nc 2
nop 6
crap 3
1
<?php
2
declare(strict_types = 1);
3
4
namespace Innmind\Rest\ServerBundle\Controller\Resource;
5
6
use Innmind\Rest\ServerBundle\Format;
7
use Innmind\Rest\Server\{
8
    RangeExtractor\Extractor,
9
    SpecificationBuilder\Builder,
10
    Response\HeaderBuilder\ListBuilder,
11
    Gateway,
12
    Request\Range,
13
    Exception\RangeNotFound,
14
    Exception\NoFilterFound
15
};
16
use Innmind\Http\{
17
    Message\Response,
18
    Message\StatusCode\StatusCode,
19
    Message\ReasonPhrase\ReasonPhrase,
20
    Headers\Headers,
21
    Exception\Http\RangeNotSatisfiable
22
};
23
use Innmind\Filesystem\Stream\StringStream;
24
use Innmind\Immutable\MapInterface;
25
use Symfony\Component\{
26
    HttpFoundation\Request,
27
    Serializer\SerializerInterface
28
};
29
30
final class ListController
31
{
32
    private $format;
33
    private $serializer;
34
    private $extractRange;
35
    private $buildSpecification;
36
    private $gateways;
37
    private $buildHeader;
38
39 8
    public function __construct(
40
        Format $format,
41
        SerializerInterface $serializer,
42
        Extractor $rangeExtractor,
43
        Builder $specificationBuilder,
44
        MapInterface $gateways,
45
        ListBuilder $headerBuilder
46
    ) {
47
        if (
48 8
            (string) $gateways->keyType() !== 'string' ||
49 8
            (string) $gateways->valueType() !== Gateway::class
50
        ) {
51 2
            throw new \TypeError(sprintf(
52 2
                'Argument 5 must be of type MapInterface<string, %s>',
53 2
                Gateway::class
54
            ));
55
        }
56
57 8
        $this->format = $format;
58 8
        $this->serializer = $serializer;
59 8
        $this->extractRange = $rangeExtractor;
60 8
        $this->buildSpecification = $specificationBuilder;
61 8
        $this->gateways = $gateways;
62 8
        $this->buildHeader = $headerBuilder;
63 8
    }
64
65 6
    public function defaultAction(Request $request): Response
66
    {
67 6
        $definition = $request->attributes->get('_innmind_resource_definition');
68 6
        $request = $request->attributes->get('_innmind_request');
69
70
        try {
71 6
            $range = ($this->extractRange)($request);
72 2
        } catch (RangeNotFound $e) {
73 2
            $range = null;
74
        }
75
76
        try {
77 6
            $specification = ($this->buildSpecification)($request, $definition);
78
        } catch (NoFilterFound $e) {
79
            $specification = null;
80
        }
81
82
        $accessor = $this
83 6
            ->gateways
84 6
            ->get((string) $definition->gateway())
85 6
            ->resourceListAccessor();
86 6
        $identities = $accessor(
87 6
            $definition,
88 6
            $specification,
89 6
            $range
90
        );
91
92
        if (
93 6
            $identities->size() === 0 &&
94 6
            $range instanceof Range
95
        ) {
96 2
            throw new RangeNotSatisfiable;
97
        }
98
99 4
        return new Response\Response(
100 4
            $code = new StatusCode(StatusCode::codes()->get(
101 4
                $range instanceof Range ? 'PARTIAL_CONTENT' : 'OK'
102
            )),
103 4
            new ReasonPhrase(ReasonPhrase::defaults()->get($code->value())),
104 4
            $request->protocolVersion(),
105 4
            new Headers(
106 4
                ($this->buildHeader)(
107 4
                    $identities,
108 4
                    $request,
109 4
                    $definition,
110 4
                    $specification,
111 4
                    $range
112
                )
113
            ),
114 4
            new StringStream(
115 4
                $this->serializer->serialize(
116 4
                    $identities,
117 4
                    $this->format->acceptable($request)->name(),
118
                    [
119 4
                        'request' => $request,
120 4
                        'definition' => $definition,
121 4
                        'specification' => $specification,
122 4
                        'range' => $range,
123
                    ]
124
                )
125
            )
126
        );
127
    }
128
}
129