3 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
4 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
5 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
6 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
7 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
8 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
9 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
10 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
11 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
12 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
13 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
15 * This software consists of voluntary contributions made by many individuals
16 * and is licensed under the MIT license.
21 use PHPRouter\RouteCollection;
24 * Routing class to match request URL's against given routes and map them to a controller action.
29 * Array that holds all Route objects
32 private $routes = array();
35 * Array to store named routes in, used for reverse routing.
38 private $namedRoutes = array();
41 * The base REQUEST_URI. Gets prepended to all route url's.
44 private $basePath = '';
47 * @param RouteCollection $collection
49 public function __construct(RouteCollection $collection)
51 $this->routes = $collection;
55 * Set the base _url - gets prepended to all route _url's.
58 public function setBasePath($basePath)
60 $this->basePath = (string) $basePath;
64 * Matches the current request against mapped routes
66 public function matchCurrentRequest()
69 isset($_POST['_method'])
70 && ($_method = strtoupper($_POST['_method']))
71 && in_array($_method, array('PUT', 'DELETE'))
72 ) ? $_method : $_SERVER['REQUEST_METHOD'];
74 $requestUrl = $_SERVER['REQUEST_URI'];
76 // strip GET variables from URL
77 if (($pos = strpos($requestUrl, '?')) !== false) {
78 $requestUrl = substr($requestUrl, 0, $pos);
81 return $this->match($requestUrl, $requestMethod);
85 * Match given request _url and request method and see if a route has been defined for it
86 * If so, return route's target
87 * If called multiple times
89 * @param string $requestUrl
90 * @param string $requestMethod
93 public function match($requestUrl, $requestMethod = 'GET')
95 foreach ($this->routes->all() as $routes) {
97 // compare server request method with route's allowed http methods
98 if (! in_array($requestMethod, (array) $routes->getMethods())) {
102 // check if request _url matches route regex. if not, return false.
103 if (! preg_match("@^".$this->basePath.$routes->getRegex()."*$@i", $requestUrl, $matches)) {
109 if (preg_match_all("/:([\w-%]+)/", $routes->getUrl(), $argument_keys)) {
111 // grab array with matches
112 $argument_keys = $argument_keys[1];
114 // loop trough parameter names, store matching value in $params array
115 foreach ($argument_keys as $key => $name) {
116 if (isset($matches[$key + 1])) {
117 $params[$name] = $matches[$key + 1];
123 $routes->setParameters($params);
134 * Reverse route a named route
137 * @param array $params Optional array of parameters to use in URL
140 * @internal param string $route_name The name of the route to reverse route.
141 * @return string The url to the route
143 public function generate($routeName, array $params = array())
145 // Check if route exists
146 if (! isset($this->namedRoutes[$routeName])) {
147 throw new Exception("No route with the name $routeName has been found.");
150 $route = $this->namedRoutes[$routeName];
151 $url = $route->getUrl();
153 // replace route url with given parameters
154 if ($params && preg_match_all("/:(\w+)/", $url, $param_keys)) {
155 // grab array with matches
156 $param_keys = $param_keys[1];
158 // loop trough parameter names, store matching value in $params array
159 foreach ($param_keys as $key) {
160 if (isset($params[$key])) {
161 $url = preg_replace("/:(\w+)/", $params[$key], $url, 1);
171 * Create routes by array, and return a Router object
173 * @param array $config provide by Config::loadFromFile()
176 public static function parseConfig(array $config)
178 $collection = new RouteCollection();
179 foreach ($config['routes'] as $name => $route) {
180 $collection->attachRoute(new Route($route[0], array(
181 '_controller' => str_replace('.', '::', $route[1]),
182 'methods' => $route[2]
186 $router = new Router($collection);
187 if (isset($config['base_path'])) {
188 $router->setBasePath($config['base_path']);