RouteLoader::buildResourceRoutes()   B
last analyzed

Complexity

Conditions 3
Paths 1

Size

Total Lines 24
Code Lines 16

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 13
CRAP Score 3

Importance

Changes 0
Metric Value
dl 0
loc 24
ccs 13
cts 13
cp 1
rs 8.9713
c 0
b 0
f 0
cc 3
eloc 16
nc 1
nop 2
crap 3
1
<?php
2
declare(strict_types = 1);
3
4
namespace Innmind\Rest\ServerBundle\Routing;
5
6
use Innmind\Rest\ServerBundle\Exception\RouteLoaderLoadedMultipleTimes;
7
use Innmind\Rest\Server\{
8
    Definition\Directory,
9
    Definition\HttpResource,
10
    Action
11
};
12
use Innmind\Http\Message\Method;
13
use Innmind\Immutable\MapInterface;
14
use Symfony\Component\{
15
    Config\Loader\Loader,
16
    Routing\RouteCollection,
17
    Routing\Route
18
};
19
20
final class RouteLoader extends Loader
21
{
22
    private $directories;
23
    private $routeFactory;
24
    private $imported = false;
25
26 16
    public function __construct(
27
        MapInterface $directories,
28
        RouteFactory $routeFactory
29
    ) {
30
        if (
31 16
            (string) $directories->keyType() !== 'string' ||
32 16
            (string) $directories->valueType() !== Directory::class
33
        ) {
34 2
            throw new \TypeError(sprintf(
35 2
                'Argument 1 must be of type MapInterface<string, %s>',
36 2
                Directory::class
37
            ));
38
        }
39
40 16
        $this->directories = $directories;
41 16
        $this->routeFactory = $routeFactory;
42 16
    }
43
44
    /**
45
     * {@inheritdoc}
46
     */
47 8
    public function load($resource, $type = null)
48
    {
49 8
        if ($this->imported === true) {
50 2
            throw new RouteLoaderLoadedMultipleTimes;
51
        }
52
53 8
        $routes = new RouteCollection;
54
55 8
        foreach ($this->directories as $directory) {
56 8
            $routes->addCollection(
57 8
                $this->buildDirectoryRoutes($directory)
58
            );
59
        }
60
61 8
        $routes->add(
62 8
            'innmind_rest_server_capabilities',
63 8
            new Route(
64 8
                '/*',
65 8
                ['_controller' => 'innmind_rest_server.controller.capabilities:capabilitiesAction'],
66 8
                [],
67 8
                [],
68 8
                '',
69 8
                [],
70 8
                [Method::OPTIONS]
71
            )
72
        );
73
74 8
        $this->imported = true;
75
76 8
        return $routes;
77
    }
78
79
    /**
80
     * {@inheritdoc}
81
     */
82 2
    public function supports($resource, $type = null)
83
    {
84 2
        return $type === 'innmind_rest';
85
    }
86
87 8
    private function buildDirectoryRoutes(Directory $directory): RouteCollection
88
    {
89
        return $directory
90 8
            ->flatten()
91 8
            ->reduce(
92 8
                new RouteCollection,
93 8
                function(RouteCollection $routes, string $name, HttpResource $definition) {
94 8
                    $routes->addCollection(
95 8
                        $this->buildResourceRoutes($name, $definition)
96
                    );
97
98 8
                    return $routes;
99 8
                }
100
            );
101
    }
102
103 8
    private function buildResourceRoutes(
104
        string $name,
105
        HttpResource $definition
106
    ): RouteCollection {
107 8
        return Action::all()
108 8
            ->reduce(
109 8
                new RouteCollection,
110 8
                function(RouteCollection $carry, Action $action) use ($name, $definition) {
111
                    if (
112 8
                        $definition->options()->contains('actions') &&
113 8
                        !in_array((string) $action, $definition->options()->get('actions'))
114
                    ) {
115 8
                        return $carry;
116
                    }
117
118 8
                    $carry->add(
119 8
                        $this->routeFactory->makeName($name, $action),
120 8
                        $this->routeFactory->makeRoute($name, $action)
121
                    );
122
123 8
                    return $carry;
124 8
                }
125
            );
126
    }
127
}
128