Completed
Push — develop ( 245283...87c85a )
by Baptiste
04:30
created

ListController   B

Complexity

Total Complexity 9

Size/Duplication

Total Lines 99
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 16

Test Coverage

Coverage 0%

Importance

Changes 0
Metric Value
wmc 9
lcom 1
cbo 16
dl 0
loc 99
c 0
b 0
f 0
ccs 0
cts 82
cp 0
rs 8.4614

2 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 22 3
B defaultAction() 0 66 6
1
<?php
2
declare(strict_types = 1);
3
4
namespace Innmind\Rest\ServerBundle\Controller\Resource;
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
    GatewayInterface,
15
    Request\Range,
16
    Exception\RangeNotFoundException,
17
    Exception\NoFilterFoundException
18
};
19
use Innmind\Http\{
20
    Message\ResponseInterface,
21
    Message\Response,
22
    Message\StatusCode,
23
    Message\ReasonPhrase,
24
    Headers,
25
    Exception\Http\RangeNotSatisfiableException
26
};
27
use Innmind\Filesystem\Stream\StringStream;
28
use Innmind\Immutable\MapInterface;
29
use Symfony\Component\{
30
    HttpFoundation\Request,
31
    Serializer\SerializerInterface
32
};
33
34
final class ListController
35
{
36
    private $format;
37
    private $serializer;
38
    private $rangeExtractor;
39
    private $specificationBuilder;
40
    private $gateways;
41
    private $headerBuilder;
42
43
    public function __construct(
44
        Format $format,
45
        SerializerInterface $serializer,
46
        ExtractorInterface $rangeExtractor,
47
        BuilderInterface $specificationBuilder,
48
        MapInterface $gateways,
49
        ListBuilderInterface $headerBuilder
50
    ) {
51
        if (
52
            (string) $gateways->keyType() !== 'string' ||
53
            (string) $gateways->valueType() !== GatewayInterface::class
54
        ) {
55
            throw new InvalidArgumentException;
56
        }
57
58
        $this->format = $format;
59
        $this->serializer = $serializer;
60
        $this->rangeExtractor = $rangeExtractor;
61
        $this->specificationBuilder = $specificationBuilder;
62
        $this->gateways = $gateways;
63
        $this->headerBuilder = $headerBuilder;
64
    }
65
66
    public function defaultAction(Request $request): ResponseInterface
67
    {
68
        $definition = $request->attributes->get('_innmind_resource_definition');
69
        $request = $request->attributes->get('_innmind_request');
70
71
        try {
72
            $range = $this->rangeExtractor->extract($request);
73
        } catch (RangeNotFoundException $e) {
74
            $range = null;
75
        }
76
77
        try {
78
            $specification = $this->specificationBuilder->buildFrom(
79
                $request,
80
                $definition
81
            );
82
        } catch (NoFilterFoundException $e) {
83
            $specification = null;
84
        }
85
86
        $accessor = $this
87
            ->gateways
88
            ->get((string) $definition->gateway())
89
            ->resourceListAccessor();
90
        $identities = $accessor(
91
            $definition,
92
            $specification,
93
            $range
94
        );
95
96
        if (
97
            $identities->size() === 0 &&
98
            $range instanceof Range
99
        ) {
100
            throw new RangeNotSatisfiableException;
101
        }
102
103
        return new Response(
104
            $code = new StatusCode(StatusCode::codes()->get(
105
                $range instanceof Range ? 'PARTIAL_CONTENT' : 'OK'
106
            )),
107
            new ReasonPhrase(ReasonPhrase::defaults()->get($code->value())),
108
            $request->protocolVersion(),
109
            new Headers(
110
                $this->headerBuilder->build(
111
                    $identities,
112
                    $request,
113
                    $definition,
114
                    $specification,
115
                    $range
116
                )
117
            ),
118
            new StringStream(
119
                $this->serializer->serialize(
120
                    $identities,
121
                    $this->format->acceptable($request)->name(),
122
                    [
123
                        'request' => $request,
124
                        'definition' => $definition,
125
                        'specification' => $specification,
126
                        'range' => $range,
127
                    ]
128
                )
129
            )
130
        );
131
    }
132
}
133