2015-12-06 01:52:35 +00:00
|
|
|
<?php
|
2016-02-03 22:22:56 +00:00
|
|
|
/**
|
|
|
|
* Holds the router class.
|
2016-03-08 23:07:58 +00:00
|
|
|
*
|
2016-02-03 22:22:56 +00:00
|
|
|
* @package Sakura
|
|
|
|
*/
|
|
|
|
|
2015-12-06 01:52:35 +00:00
|
|
|
namespace Sakura;
|
|
|
|
|
2016-01-30 00:18:23 +00:00
|
|
|
use Phroute\Phroute\Dispatcher;
|
2016-02-04 20:56:40 +00:00
|
|
|
use Phroute\Phroute\Exception\HttpMethodNotAllowedException;
|
2016-03-09 18:41:43 +00:00
|
|
|
use Phroute\Phroute\Exception\HttpRouteNotFoundException;
|
2016-02-04 20:56:40 +00:00
|
|
|
use Phroute\Phroute\RouteCollector;
|
2016-01-30 00:18:23 +00:00
|
|
|
|
2015-12-06 01:52:35 +00:00
|
|
|
/**
|
2016-02-02 21:04:15 +00:00
|
|
|
* Sakura Wrapper for Phroute.
|
2016-03-08 23:07:58 +00:00
|
|
|
*
|
2015-12-06 01:52:35 +00:00
|
|
|
* @package Sakura
|
2016-02-02 21:04:15 +00:00
|
|
|
* @author Julian van de Groep <me@flash.moe>
|
2015-12-06 01:52:35 +00:00
|
|
|
*/
|
|
|
|
class Router
|
|
|
|
{
|
2016-02-02 21:04:15 +00:00
|
|
|
/**
|
|
|
|
* Container for RouteCollector
|
2016-03-08 23:07:58 +00:00
|
|
|
*
|
2016-02-02 21:04:15 +00:00
|
|
|
* @var RouteCollector
|
|
|
|
*/
|
2016-01-30 00:18:23 +00:00
|
|
|
protected static $router = null;
|
|
|
|
|
2016-02-02 21:04:15 +00:00
|
|
|
/**
|
|
|
|
* Base path of the router.
|
2016-03-08 23:07:58 +00:00
|
|
|
*
|
2016-02-02 21:04:15 +00:00
|
|
|
* @var string
|
|
|
|
*/
|
2016-01-30 00:18:23 +00:00
|
|
|
protected static $basePath = null;
|
|
|
|
|
2016-02-02 21:04:15 +00:00
|
|
|
/**
|
|
|
|
* Container for the Dispatcher
|
2016-03-08 23:07:58 +00:00
|
|
|
*
|
2016-02-02 21:04:15 +00:00
|
|
|
* @var Dispatcher
|
|
|
|
*/
|
2016-01-30 00:18:23 +00:00
|
|
|
protected static $dispatcher = null;
|
|
|
|
|
2016-02-02 21:04:15 +00:00
|
|
|
/**
|
|
|
|
* Collection of handled HTTP request types.
|
2016-03-08 23:07:58 +00:00
|
|
|
*
|
2016-02-02 21:04:15 +00:00
|
|
|
* @var array
|
|
|
|
*/
|
2016-01-30 00:18:23 +00:00
|
|
|
protected static $methods = [
|
|
|
|
'GET',
|
|
|
|
'POST',
|
|
|
|
'PUT',
|
|
|
|
'PATCH',
|
|
|
|
'DELETE',
|
|
|
|
'HEAD',
|
2016-03-09 18:41:43 +00:00
|
|
|
'OPTIONS',
|
|
|
|
'ANY',
|
2016-01-30 00:18:23 +00:00
|
|
|
];
|
|
|
|
|
2016-02-02 21:04:15 +00:00
|
|
|
/**
|
|
|
|
* Method aliases for adding routes.
|
2016-03-08 23:07:58 +00:00
|
|
|
*
|
2016-02-02 21:04:15 +00:00
|
|
|
* @param string $name A HTTP method.
|
|
|
|
* @param array $args The arguments.
|
|
|
|
*/
|
2016-01-30 00:18:23 +00:00
|
|
|
public static function __callStatic($name, $args)
|
|
|
|
{
|
|
|
|
// Check if the method exists
|
|
|
|
if (in_array($name = strtoupper($name), self::$methods)) {
|
|
|
|
$path = isset($args[2]) && $args !== null ? [$args[0], $args[2]] : $args[0];
|
2016-03-28 01:18:59 +00:00
|
|
|
$handler = is_callable($args[1]) || is_array($args[1])
|
|
|
|
? $args[1]
|
|
|
|
: explode(
|
|
|
|
'@',
|
|
|
|
(
|
|
|
|
'Sakura\\Controllers\\'
|
|
|
|
. str_replace(
|
|
|
|
'.',
|
|
|
|
'\\',
|
|
|
|
$args[1]
|
|
|
|
)
|
|
|
|
)
|
|
|
|
);
|
2016-01-30 00:18:23 +00:00
|
|
|
$filter = isset($args[3]) ? $args[3] : [];
|
|
|
|
|
2016-01-30 13:25:18 +00:00
|
|
|
self::$router->addRoute($name, $path, $handler, $filter);
|
2016-01-30 00:18:23 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-02-02 21:04:15 +00:00
|
|
|
/**
|
|
|
|
* Initialisation.
|
2016-03-08 23:07:58 +00:00
|
|
|
*
|
2016-02-02 21:04:15 +00:00
|
|
|
* @param string $basePath The base path of the router.
|
|
|
|
*/
|
2016-01-30 00:18:23 +00:00
|
|
|
public static function init($basePath = '/')
|
|
|
|
{
|
|
|
|
// Set base path
|
|
|
|
self::setBasePath($basePath);
|
|
|
|
|
|
|
|
// Create router
|
|
|
|
self::$router = new RouteCollector;
|
|
|
|
}
|
|
|
|
|
2016-02-02 21:04:15 +00:00
|
|
|
/**
|
|
|
|
* Set the base path.
|
2016-03-08 23:07:58 +00:00
|
|
|
*
|
2016-02-02 21:04:15 +00:00
|
|
|
* @param string $basePath The base path of the router.
|
|
|
|
*/
|
2016-01-30 00:18:23 +00:00
|
|
|
public static function setBasePath($basePath)
|
|
|
|
{
|
|
|
|
self::$basePath = $basePath;
|
|
|
|
}
|
|
|
|
|
2016-02-02 21:04:15 +00:00
|
|
|
/**
|
|
|
|
* Parse a URL.
|
2016-03-08 23:07:58 +00:00
|
|
|
*
|
2016-02-02 21:04:15 +00:00
|
|
|
* @param string $url The URL that is to be parsed.
|
2016-03-08 23:07:58 +00:00
|
|
|
*
|
2016-02-02 21:04:15 +00:00
|
|
|
* @return string THe parsed URL.
|
|
|
|
*/
|
2016-01-30 00:18:23 +00:00
|
|
|
private static function parseUrl($url)
|
|
|
|
{
|
2016-01-30 13:25:18 +00:00
|
|
|
return parse_url($url, PHP_URL_PATH);
|
2016-01-30 00:18:23 +00:00
|
|
|
}
|
|
|
|
|
2016-02-04 20:56:40 +00:00
|
|
|
/**
|
|
|
|
* Generate the URI of a route using names.
|
2016-03-08 23:07:58 +00:00
|
|
|
*
|
2016-02-04 20:56:40 +00:00
|
|
|
* @param string $name The identifier of the route.
|
|
|
|
* @param string|array $args The route arguments.
|
2016-03-08 23:07:58 +00:00
|
|
|
*
|
2016-02-04 20:56:40 +00:00
|
|
|
* @return string The generated URI.
|
|
|
|
*/
|
2016-02-27 16:46:16 +00:00
|
|
|
public static function route($name, $args = null)
|
2016-02-04 20:56:40 +00:00
|
|
|
{
|
2016-02-27 16:46:16 +00:00
|
|
|
// Array-ify the arguments
|
|
|
|
if ($args !== null && !is_array($args)) {
|
|
|
|
$temp = $args;
|
|
|
|
$args = [];
|
|
|
|
$args[] = $temp;
|
|
|
|
}
|
|
|
|
|
|
|
|
return self::$basePath . self::$router->route($name, $args);
|
2016-02-04 20:56:40 +00:00
|
|
|
}
|
|
|
|
|
2016-03-09 18:41:43 +00:00
|
|
|
/**
|
|
|
|
* Create group.
|
|
|
|
*
|
|
|
|
* @param array $filters The filters for this group.
|
|
|
|
* @param \Closure $callback The containers
|
|
|
|
*/
|
|
|
|
public static function group($filters, $callback)
|
|
|
|
{
|
|
|
|
// Execute the inner function
|
|
|
|
self::$router->group($filters, $callback);
|
|
|
|
}
|
|
|
|
|
2016-03-26 16:36:58 +00:00
|
|
|
/**
|
|
|
|
* Create filter.
|
|
|
|
*
|
|
|
|
* string $name Identifier of the filter
|
|
|
|
* \Closure $method
|
|
|
|
*/
|
|
|
|
public static function filter($name, $method)
|
|
|
|
{
|
|
|
|
self::$router->filter($name, $method);
|
|
|
|
}
|
|
|
|
|
2016-02-02 21:04:15 +00:00
|
|
|
/**
|
|
|
|
* Handle requests.
|
2016-03-08 23:07:58 +00:00
|
|
|
*
|
2016-02-02 21:04:15 +00:00
|
|
|
* @param string $method The HTTP method used to make the request.
|
|
|
|
* @param string $url The URL the request is made to.
|
2016-03-08 23:07:58 +00:00
|
|
|
*
|
2016-02-02 21:04:15 +00:00
|
|
|
* @return mixed The response.
|
|
|
|
*/
|
2016-01-30 00:18:23 +00:00
|
|
|
public static function handle($method, $url)
|
|
|
|
{
|
|
|
|
// Check if the dispatcher is defined
|
|
|
|
if (self::$dispatcher === null) {
|
|
|
|
self::$dispatcher = new Dispatcher(self::$router->getData());
|
|
|
|
}
|
|
|
|
|
|
|
|
// Parse url
|
|
|
|
$url = self::parseUrl($url);
|
|
|
|
|
|
|
|
// Handle the request
|
2016-02-04 20:56:40 +00:00
|
|
|
try {
|
2016-02-15 21:20:46 +00:00
|
|
|
return self::$dispatcher->dispatch($method, $url);
|
|
|
|
} catch (HttpMethodNotAllowedException $e) {
|
2016-07-31 21:58:36 +00:00
|
|
|
http_response_code(403);
|
2016-02-07 19:36:13 +00:00
|
|
|
} catch (HttpRouteNotFoundException $e) {
|
2016-07-31 21:58:36 +00:00
|
|
|
http_response_code(404);
|
2016-02-07 19:36:13 +00:00
|
|
|
}
|
2016-02-04 20:56:40 +00:00
|
|
|
|
|
|
|
// Default to the not found page
|
|
|
|
return Template::render('global/notfound');
|
2016-01-30 00:18:23 +00:00
|
|
|
}
|
2015-12-06 01:52:35 +00:00
|
|
|
}
|