Completed
Push — develop ( 92e89c...f8ec74 )
by Baptiste
08:17
created

RouteLoader   A

Complexity

Total Complexity 11

Size/Duplication

Total Lines 105
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 11

Test Coverage

Coverage 97.96%

Importance

Changes 0
Metric Value
wmc 11
lcom 1
cbo 11
dl 0
loc 105
ccs 48
cts 49
cp 0.9796
rs 10
c 0
b 0
f 0

5 Methods

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