HummingBirdAnimeClient/app/Base/Router.php

232 lines
4.8 KiB
PHP
Raw Normal View History

2015-05-22 12:36:26 -04:00
<?php
/**
* Routing logic
*/
2015-05-22 12:36:26 -04:00
namespace AnimeClient\Base;
2015-06-26 16:39:10 -04:00
/**
* Basic routing/ dispatch
*/
2015-05-22 12:36:26 -04:00
class Router {
/**
* The route-matching object
* @var object $router
*/
protected $router;
/**
* The global configuration object
* @var object $config
*/
protected $config;
/**
* Class wrapper for input superglobals
* @var object
*/
protected $request;
2015-06-29 09:46:49 -04:00
/**
* Array containing request and response objects
* @var array $web
*/
protected $web;
/**
* Routes added to router
* @var array $output_routes
*/
protected $output_routes;
/**
* Constructor
2015-06-29 09:46:49 -04:00
*
* @param
*/
2015-06-29 09:46:49 -04:00
public function __construct(Config $config, \Aura\Router\Router $router, \Aura\Web\Request $request, \Aura\Web\Response $response)
2015-05-22 12:36:26 -04:00
{
$this->config = $config;
2015-06-29 09:46:49 -04:00
$this->router = $router;
$this->request = $request;
2015-06-29 09:46:49 -04:00
$this->web = [$request, $response];
2015-05-22 12:36:26 -04:00
$this->output_routes = $this->_setup_routes();
2015-05-22 12:36:26 -04:00
}
/**
* Get the current route object, if one matches
*
* @return object
*/
public function get_route()
{
global $defaultHandler;
$raw_route = parse_url($this->request->server->get('REQUEST_URI'), \PHP_URL_PATH);
$route_path = str_replace([$this->config->anime_path, $this->config->manga_path], '', $raw_route);
$route_path = "/" . trim($route_path, '/');
/*$defaultHandler->addDataTable('Route Info', [
'route_path' => $route_path
]);*/
$route = $this->router->match($route_path, $_SERVER);
2015-05-22 12:36:26 -04:00
return $route;
}
/**
* Get list of routes applied
*
* @return array
*/
public function get_output_routes()
{
return $this->output_routes;
}
2015-05-22 12:36:26 -04:00
/**
* Handle the current route
*
* @codeCoverageIgnore
2015-05-22 12:36:26 -04:00
* @param [object] $route
* @return void
*/
public function dispatch($route = NULL)
{
2015-05-27 09:03:42 -04:00
global $defaultHandler;
2015-05-22 12:36:26 -04:00
if (is_null($route))
{
$route = $this->get_route();
}
if ( ! $route)
{
2015-05-27 09:03:42 -04:00
$failure = $this->router->getFailedRoute();
$defaultHandler->addDataTable('failed_route', (array)$failure);
2015-05-22 12:36:26 -04:00
}
else
{
2015-06-17 08:50:01 -04:00
list($controller_name, $action_method) = $route->params['action'];
2015-05-22 12:36:26 -04:00
$params = (isset($route->params['params'])) ? $route->params['params'] : [];
if ( ! empty($route->tokens))
{
foreach($route->tokens as $key => $v)
{
if (array_key_exists($key, $route->params))
{
$params[$key] = $route->params[$key];
}
}
}
2015-05-22 12:36:26 -04:00
}
2015-06-29 09:46:49 -04:00
$controller = new $controller_name($this->config, $this->web);
2015-05-22 12:36:26 -04:00
// Run the appropriate controller method
$defaultHandler->addDataTable('controller_args', $params);
2015-05-22 12:36:26 -04:00
call_user_func_array([$controller, $action_method], $params);
}
/**
* Get the type of route, to select the current controller
*
* @return string
*/
public function get_route_type()
{
$route_type = $this->config->default_list;
$host = $this->request->server->get("HTTP_HOST");
$request_uri = $this->request->server->get('REQUEST_URI');
// Host-based controller selection
if ($this->config->route_by === "host")
{
if (strtolower($host) === strtolower($this->config->anime_host))
{
$route_type = "anime";
}
if (strtolower($host) === strtolower($this->config->manga_host))
{
$route_type = "manga";
}
}
// Path-based controller selection
if ($this->config->route_by === "path")
{
$path = trim($request_uri, '/');
if (stripos($path, trim($this->config->anime_path, '/')) === 0)
{
$route_type = "anime";
}
if (stripos($path, trim($this->config->manga_path, '/')) === 0)
{
$route_type = "manga";
}
}
return $route_type;
}
/**
* Select controller based on the current url, and apply its relevent routes
*
* @return array
*/
public function _setup_routes()
2015-05-22 12:36:26 -04:00
{
$route_map = [
'anime' => '\\AnimeClient\\Controller\\Anime',
'manga' => '\\AnimeClient\\Controller\\Manga',
];
2015-05-22 12:36:26 -04:00
$output_routes = [];
$route_type = $this->get_route_type();
// Return early if invalid route array
if ( ! array_key_exists($route_type, $this->config->routes)) return [];
2015-05-22 12:36:26 -04:00
$applied_routes = array_merge($this->config->routes['common'], $this->config->routes[$route_type]);
2015-05-22 12:36:26 -04:00
// Add routes
foreach($applied_routes as $name => &$route)
2015-05-22 12:36:26 -04:00
{
$path = $route['path'];
unset($route['path']);
// Prepend the controller to the route parameters
array_unshift($route['action'], $route_map[$route_type]);
2015-06-17 08:50:01 -04:00
// Select the appropriate router method based on the http verb
$add = (array_key_exists('verb', $route)) ? "add" . ucfirst(strtolower($route['verb'])) : "addGet";
2015-06-17 08:50:01 -04:00
// Add the route to the router object
if ( ! array_key_exists('tokens', $route))
{
$output_routes[] = $this->router->$add($name, $path)->addValues($route);
}
else
{
$tokens = $route['tokens'];
unset($route['tokens']);
2015-06-17 08:50:01 -04:00
$output_routes[] = $this->router->$add($name, $path)
->addValues($route)
->addTokens($tokens);
2015-06-17 08:50:01 -04:00
}
}
return $output_routes;
2015-05-22 12:36:26 -04:00
}
}
// End of Router.php