Router::getMatchingRoute()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 7
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 6
CRAP Score 2

Importance

Changes 0
Metric Value
dl 0
loc 7
ccs 6
cts 6
cp 1
rs 9.4285
c 0
b 0
f 0
cc 2
eloc 5
nc 2
nop 1
crap 2
1
<?php
2
3
/*
4
 * Copyright (c) 2011-2015, Celestino Diaz <[email protected]>
5
 *
6
 * Permission is hereby granted, free of charge, to any person obtaining a copy
7
 * of this software and associated documentation files (the "Software"), to deal
8
 * in the Software without restriction, including without limitation the rights
9
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
 * copies of the Software, and to permit persons to whom the Software is
11
 * furnished to do so, subject to the following conditions:
12
 *
13
 * The above copyright notice and this permission notice shall be included in
14
 * all copies or substantial portions of the Software.
15
 *
16
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22
 * THE SOFTWARE.
23
 */
24
25
namespace Brickoo\Component\Routing;
26
27
use Brickoo\Component\Routing\Route\Route;
28
use Brickoo\Component\Routing\Route\RequestRoute;
29
use Brickoo\Component\Routing\Exception\NoMatchingRouteFoundException;
30
use Brickoo\Component\Routing\Exception\RouteNotFoundException;
31
use Brickoo\Component\Routing\Route\RouteCollection;
32
use Brickoo\Component\Routing\Route\Collector\RouteCollector;
33
use Brickoo\Component\Routing\Route\Matcher\RouteMatcher;
34
use Brickoo\Component\Common\Assert;
35
36
/**
37
 * Router
38
 *
39
 * Router which can return an executable matching route
40
 * and any route available based on its unique name.
41
 * For collecting the routes a collector is used.
42
 * @author Celestino Diaz <[email protected]>
43
 */
44
class Router {
45
46
    /** @var \Brickoo\Component\Routing\Route\Matcher\RouteMatcher */
47
    private $routeMatcher;
48
49
    /** @var \Brickoo\Component\Routing\Route\Collector\RouteCollector */
50
    private $routeCollector;
51
52
    /** @var null|\Brickoo\Component\Common\Collection */
53
    private $routeCollections;
54
55
    /**
56
     * Class constructor.
57
     * @param \Brickoo\Component\Routing\Route\Collector\RouteCollector $routeCollector
58
     * @param \Brickoo\Component\Routing\Route\Matcher\RouteMatcher $routeMatcher
59
     */
60 1
    public function __construct(RouteCollector $routeCollector, RouteMatcher $routeMatcher) {
61 1
        $this->routeCollector = $routeCollector;
62 1
        $this->routeMatcher = $routeMatcher;
63 1
        $this->routeCollections = null;
64 1
    }
65
66
    /**
67
     * Returns the route having the given unique name.
68
     * @param string $routeName the route unique name
69
     * @param string $collectionName the route collections name
70
     * @throws \InvalidArgumentException if an argument is not valid
71
     * @throws \Brickoo\Component\Routing\Exception\RouteNotFoundException
72
     * @return \Brickoo\Component\Routing\Route\Route
73
     */
74 3
    public function getRoute($routeName, $collectionName = "") {
75 3
        Assert::isString($routeName);
76 3
        Assert::isString($collectionName);
77
78 3
        if (!($routeCollection = $this->getResponsibleRouteCollection($routeName, $collectionName))) {
79 2
            throw new RouteNotFoundException($routeName);
80
        }
81
82 2
        return $routeCollection->getRoute($routeName);
83
    }
84
85
    /**
86
     * Checks if the route is available.
87
     * @param string $routeName the route unique name
88
     * @param string $collectionName the route collections name
89
     * @throws \InvalidArgumentException if an argument is not valid
90
     * @return boolean
91
     */
92 1
    public function hasRoute($routeName, $collectionName = "") {
93 1
        Assert::isString($collectionName);
94 1
        Assert::isString($routeName);
95
96
        try {
97 1
            $this->getRoute($routeName, $collectionName);
98 1
            return true;
99
        }
100 1
        catch (RouteNotFoundException $exception) {
101 1
            return false;
102
        }
103
    }
104
105
    /**
106
     * Returns the matching request route.
107
     * @throws \Brickoo\Component\Routing\Exception\NoMatchingRouteFoundException
108
     * @return \Brickoo\Component\Routing\Route\RequestRoute
109
     */
110 2
    public function getRequestRoute() {
111 2
        $matchingRoute = null;
112
113 2
        foreach ($this->getRouteCollections() as $routeCollection) {
114 1
            if (($matchingRoute = $this->getMatchingRoute($routeCollection))) {
115 1
                break;
116
            }
117 2
        }
118
119 2
        if (!$matchingRoute instanceof RequestRoute) {
120 1
            throw new NoMatchingRouteFoundException();
121
        }
122
123 1
        return $matchingRoute;
124
    }
125
126
    /**
127
     * Return the matching route.
128
     * @param RouteCollection $routeCollection
129
     * @return null|RequestRoute
130
     */
131 1
    private function getMatchingRoute(RouteCollection $routeCollection) {
132 1
        $matchingRoute = null;
133 1
        if ($this->routeMatcher->matchesCollection($routeCollection)) {
134 1
            $matchingRoute = $this->getMatchingRequestRouteFromCollection($routeCollection);
135 1
        }
136 1
        return $matchingRoute;
137
    }
138
139
    /**
140
     * Returns the matching route from collection if available.
141
     * @param \Brickoo\Component\Routing\Route\RouteCollection $routeCollection
142
     * @return null|RequestRoute
143
     */
144 1
    private function getMatchingRequestRouteFromCollection(RouteCollection $routeCollection) {
145 1
        $matchingRoute = null;
146 1
        foreach ($routeCollection as $route) {
147 1
            if ($this->routeMatcher->matchesRoute($route)) {
148 1
                $matchingRoute = new RequestRoute($route, $this->routeMatcher->getRouteParameters());
149 1
                break;
150
            }
151 1
        }
152 1
        return $matchingRoute;
153
    }
154
155
    /**
156
     * Return the responsible route collection
157
     * containing the searched route.
158
     * @param string $routeName
159
     * @param string $collectionName
160
     * @return null|\Brickoo\Component\Routing\Route\RouteCollection
161
     */
162 3
    private function getResponsibleRouteCollection($routeName, $collectionName) {
163 3
        $responsibleCollection = null;
164 3
        foreach ($this->getRouteCollections() as $routeCollection) {
165 2
            if ($this->isCollectionResponsible($routeName, $collectionName, $routeCollection)) {
166 2
                $responsibleCollection = $routeCollection;
167 2
                break;
168
            }
169 3
        }
170 3
        return $responsibleCollection;
171
    }
172
173
    /**
174
     * Checks if the route collection is responsible for the requested route and collection.
175
     * @param string $routeName
176
     * @param string $collectionName
177
     * @param \Brickoo\Component\Routing\Route\RouteCollection $routeCollection
178
     * @return boolean
179
     */
180 1
    private function isCollectionResponsible($routeName, $collectionName, RouteCollection $routeCollection) {
181 1
        return ((empty($collectionName) || $routeCollection->getName() == $collectionName)
182 1
            && $routeCollection->hasRoute($routeName));
183
    }
184
185
    /**
186
     * Returns an iterator from the route collector.
187
     * @return \Brickoo\Component\Common\Collection
188
     */
189 2
    private function getRouteCollections() {
190 2
        if ($this->routeCollections === null) {
191 2
            $this->routeCollections = $this->routeCollector->collect();
192 2
        }
193 2
        return $this->routeCollections;
194
    }
195
196
}
197