Completed
Push — develop ( 960a7a...f8a065 )
by Baptiste
06:45
created

ResourceController::listAction()   B

Complexity

Conditions 6
Paths 8

Size

Total Lines 66
Code Lines 45

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 28
CRAP Score 6.0106

Importance

Changes 0
Metric Value
dl 0
loc 66
ccs 28
cts 30
cp 0.9333
rs 8.6045
c 0
b 0
f 0
cc 6
eloc 45
nc 8
nop 1
crap 6.0106

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

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
    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
    Header\HeaderInterface,
26
    Header\ContentType,
27
    Header\ContentTypeValue,
28
    Header\ParameterInterface,
29
    Exception\Http\RangeNotSatisfiableException
30
};
31
use Innmind\Filesystem\Stream\StringStream;
32
use Innmind\Immutable\{
33
    Map,
34
    MapInterface
35
};
36
use Symfony\Component\{
37
    HttpFoundation\Request,
38
    Serializer\SerializerInterface
39
};
40
41
final class ResourceController
42
{
43
    private $format;
44
    private $serializer;
45
    private $rangeExtractor;
46
    private $specificationBuilder;
47
    private $gateways;
48
    private $listHeaderBuilder;
49
50 4
    public function __construct(
51
        Format $format,
52
        SerializerInterface $serializer,
53
        ExtractorInterface $rangeExtractor,
54
        BuilderInterface $specificationBuilder,
55
        MapInterface $gateways,
56
        ListBuilderInterface $listHeaderBuilder
57
    ) {
58
        if (
59 4
            (string) $gateways->keyType() !== 'string' ||
60 4
            (string) $gateways->valueType() !== GatewayInterface::class
61
        ) {
62
            throw new InvalidArgumentException;
63
        }
64
65 4
        $this->format = $format;
66 4
        $this->serializer = $serializer;
67 4
        $this->rangeExtractor = $rangeExtractor;
68 4
        $this->specificationBuilder = $specificationBuilder;
69 4
        $this->gateways = $gateways;
70 4
        $this->listHeaderBuilder = $listHeaderBuilder;
71 4
    }
72
73 3
    public function listAction(Request $request): ResponseInterface
74
    {
75 3
        $definition = $request->attributes->get('_innmind_resource_definition');
76 3
        $request = $request->attributes->get('_innmind_request');
77
78
        try {
79 3
            $range = $this->rangeExtractor->extract($request);
80 1
        } catch (RangeNotFoundException $e) {
81 1
            $range = null;
82
        }
83
84
        try {
85 3
            $specification = $this->specificationBuilder->buildFrom(
86
                $request,
87
                $definition
88
            );
89
        } catch (NoFilterFoundException $e) {
90
            $specification = null;
91
        }
92
93
        $accessor = $this
94 3
            ->gateways
95 3
            ->get((string) $definition->gateway())
96 3
            ->resourceListAccessor();
97 3
        $identities = $accessor(
98
            $definition,
99
            $specification,
100
            $range
101
        );
102
103
        if (
104 3
            $identities->size() === 0 &&
105 3
            $range instanceof Range
106
        ) {
107 1
            throw new RangeNotSatisfiableException;
108
        }
109
110 2
        return new Response(
111 2
            $code = new StatusCode(StatusCode::codes()->get(
112 2
                $range instanceof Range ? 'PARTIAL_CONTENT' : 'OK'
113
            )),
114 2
            new ReasonPhrase(ReasonPhrase::defaults()->get($code->value())),
115 2
            $request->protocolVersion(),
116 2
            new Headers(
117 2
                $this->listHeaderBuilder->build(
118
                    $identities,
119
                    $request,
120
                    $definition,
121
                    $specification,
122
                    $range
123
                )
124
            ),
125 2
            new StringStream(
126 2
                $this->serializer->serialize(
127
                    $identities,
128 2
                    $this->format->acceptable($request)->name(),
129
                    [
130 2
                        'request' => $request,
131 2
                        'definition' => $definition,
132 2
                        'specification' => $specification,
133 2
                        'range' => $range,
134
                    ]
135
                )
136
            )
137
        );
138
    }
139
140 1
    public function optionsAction(Request $request): ResponseInterface
141
    {
142 1
        $definition = $request->attributes->get('_innmind_resource_definition');
143 1
        $request = $request->attributes->get('_innmind_request');
144 1
        $format = $this->format->acceptable($request);
145 1
        $mediaType = $format->preferredMediaType();
146
147 1
        return new Response(
148 1
            $code = new StatusCode(StatusCode::codes()->get('OK')),
149 1
            new ReasonPhrase(ReasonPhrase::defaults()->get($code->value())),
150 1
            $request->protocolVersion(),
151 1
            new Headers(
152 1
                (new Map('string', HeaderInterface::class))
153 1
                    ->put(
154 1
                        'Content-Type',
155 1
                        new ContentType(
156 1
                            new ContentTypeValue(
157 1
                                $mediaType->topLevel(),
158 1
                                $mediaType->subType(),
159 1
                                new Map('string', ParameterInterface::class)
160
                            )
161
                        )
162
                    )
163
            ),
164 1
            new StringStream(
165 1
                $this->serializer->serialize(
166
                    $definition,
167 1
                    $format->name()
168
                )
169
            )
170
        );
171
    }
172
}
173