Completed
Push — develop ( 02617c...96603c )
by Baptiste
05:33
created

RouteLoader::__construct()   A

Complexity

Conditions 3
Paths 2

Size

Total Lines 17
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 9
CRAP Score 3

Importance

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