Completed
Push — develop ( d33b43...b8891a )
by Baptiste
04:31
created

LinkController::defaultAction()   B

Complexity

Conditions 1
Paths 1

Size

Total Lines 29
Code Lines 21

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 16
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 29
ccs 16
cts 16
cp 1
rs 8.8571
c 0
b 0
f 0
cc 1
eloc 21
nc 1
nop 2
crap 1
1
<?php
2
declare(strict_types = 1);
3
4
namespace Innmind\Rest\ServerBundle\Controller\Resource;
5
6
use Innmind\Rest\ServerBundle\Exception\InvalidArgumentException;
7
use Innmind\Rest\Server\{
8
    Response\HeaderBuilder\LinkBuilderInterface,
9
    Definition\Locator,
10
    GatewayInterface,
11
    Reference,
12
    Identity,
13
    Link\ParameterInterface,
14
    Link\Parameter
15
};
16
use Innmind\Http\{
17
    Message\ResponseInterface,
18
    Message\Response,
19
    Message\StatusCode,
20
    Message\ReasonPhrase,
21
    Headers,
22
    Header\Link,
23
    Header\LinkValue,
24
    Header\ParameterInterface as LinkParameterInterface
25
};
26
use Innmind\Filesystem\Stream\StringStream;
27
use Innmind\Immutable\{
28
    MapInterface,
29
    Map
30
};
31
use Symfony\Component\{
32
    Routing\RouterInterface,
33
    HttpFoundation\Request
34
};
35
36
final class LinkController
37
{
38
    private $gateways;
39
    private $headerBuilder;
40
    private $router;
41
    private $locator;
42
43 2
    public function __construct(
44
        MapInterface $gateways,
45
        LinkBuilderInterface $headerBuilder,
46
        RouterInterface $router,
47
        Locator $locator
48
    ) {
49
        if (
50 2
            (string) $gateways->keyType() !== 'string' ||
51 2
            (string) $gateways->valueType() !== GatewayInterface::class
52
        ) {
53 1
            throw new InvalidArgumentException;
54
        }
55
56 1
        $this->gateways = $gateways;
57 1
        $this->headerBuilder = $headerBuilder;
58 1
        $this->router = $router;
59 1
        $this->locator = $locator;
60 1
    }
61
62 1
    public function defaultAction(Request $request, $identity): ResponseInterface
63
    {
64 1
        $from = $request->attributes->get('_innmind_resource_definition');
65 1
        $request = $request->attributes->get('_innmind_request');
66 1
        $tos = $this->extractReferences($request->headers()->get('Link'));
67
68
        $linker = $this
69 1
            ->gateways
70 1
            ->get((string) $from->gateway())
71 1
            ->resourceLinker();
72 1
        $linker(
73 1
            $from = new Reference($from, new Identity($identity)),
74
            $tos
75
        );
76
77 1
        return new Response(
78 1
            $code = new StatusCode(StatusCode::codes()->get('NO_CONTENT')),
79 1
            new ReasonPhrase(ReasonPhrase::defaults()->get($code->value())),
80 1
            $request->protocolVersion(),
81 1
            new Headers(
82 1
                $this->headerBuilder->build(
83
                    $request,
84
                    $from,
85
                    $tos
86
                )
87
            ),
88 1
            new StringStream('')
89
        );
90
    }
91
92
    /**
93
     * @return MapInterface<Reference, MapInterface<string, ParameterInterface>>
1 ignored issue
show
Documentation introduced by
The doc-type MapInterface<Reference, could not be parsed: Expected "|" or "end of type", but got "<" at position 12. (view supported doc-types)

This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.

Loading history...
94
     */
95 1
    private function extractReferences(Link $header): MapInterface
96
    {
97
        return $header
98 1
            ->values()
99 1
            ->reduce(
100 1
                new Map(Reference::class, MapInterface::class),
101
                function(Map $carry, LinkValue $value): Map
102
                {
103 1
                    $infos = $this->router->match((string) $value->url());
104
105 1
                    return $carry->put(
106 1
                        new Reference(
107 1
                            $this->locator->locate($infos['_innmind_resource']),
108 1
                            new Identity($infos['identity'])
109
                        ),
110
                        $value
111 1
                            ->parameters()
112 1
                            ->reduce(
113 1
                                new Map('string', ParameterInterface::class),
114 1
                                function(Map $carry, string $name, LinkParameterInterface $param): Map {
115
                                    return $carry->put(
116
                                        $name,
117
                                        new Parameter($name, $param->value())
118
                                    );
119 1
                                }
120
                            )
121 1
                            ->put(
122 1
                                'rel',
123 1
                                new Parameter('rel', $value->relationship())
124
                            )
125
                    );
126 1
                }
127
            );
128
    }
129
}
130