Store StaticRoutes to separate hash array in Router
Add StaticRouteInterface
This commit is contained in:
parent
6ae85398db
commit
78fe57d736
|
|
@ -0,0 +1,28 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* pjdietz\WellRESTed\Interfaces\ResponseInterface
|
||||||
|
*
|
||||||
|
* @author PJ Dietz <pj@pjdietz.com>
|
||||||
|
* @copyright Copyright 2014 by PJ Dietz
|
||||||
|
* @license MIT
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace pjdietz\WellRESTed\Interfaces\Routes;
|
||||||
|
|
||||||
|
interface StaticRouteInterface
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Returns the target class this maps to.
|
||||||
|
*
|
||||||
|
* @return string Fully qualified name for a HandlerInterface
|
||||||
|
*/
|
||||||
|
public function getHandler();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the paths this maps to a target handler.
|
||||||
|
*
|
||||||
|
* @return array Array of paths.
|
||||||
|
*/
|
||||||
|
public function getPaths();
|
||||||
|
}
|
||||||
|
|
@ -14,7 +14,7 @@ use pjdietz\WellRESTed\Exceptions\HttpExceptions\HttpException;
|
||||||
use pjdietz\WellRESTed\Interfaces\HandlerInterface;
|
use pjdietz\WellRESTed\Interfaces\HandlerInterface;
|
||||||
use pjdietz\WellRESTed\Interfaces\RequestInterface;
|
use pjdietz\WellRESTed\Interfaces\RequestInterface;
|
||||||
use pjdietz\WellRESTed\Interfaces\ResponseInterface;
|
use pjdietz\WellRESTed\Interfaces\ResponseInterface;
|
||||||
use pjdietz\WellRESTed\Routes\StaticRoute;
|
use pjdietz\WellRESTed\Interfaces\Routes\StaticRouteInterface;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Router
|
* Router
|
||||||
|
|
@ -25,6 +25,10 @@ class Router implements HandlerInterface
|
||||||
{
|
{
|
||||||
/** @var array Array of Route objects */
|
/** @var array Array of Route objects */
|
||||||
private $routes;
|
private $routes;
|
||||||
|
|
||||||
|
/** @var array Hash array mapping exact paths to handlers */
|
||||||
|
private $staticRoutes;
|
||||||
|
|
||||||
/** @var array Hash array of status code => qualified HandlerInterface names for error handling. */
|
/** @var array Hash array of status code => qualified HandlerInterface names for error handling. */
|
||||||
private $errorHandlers;
|
private $errorHandlers;
|
||||||
|
|
||||||
|
|
@ -32,30 +36,10 @@ class Router implements HandlerInterface
|
||||||
public function __construct()
|
public function __construct()
|
||||||
{
|
{
|
||||||
$this->routes = array();
|
$this->routes = array();
|
||||||
|
$this->staticRoutes = array();
|
||||||
$this->errorHandlers = array();
|
$this->errorHandlers = array();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Wraps the getResponse method in a try-catch.
|
|
||||||
*
|
|
||||||
* @param HandlerInterface $handler The Route or Handle to try.
|
|
||||||
* @param RequestInterface $request The incoming request.
|
|
||||||
* @param array $args The array of arguments.
|
|
||||||
* @return null|Response
|
|
||||||
*/
|
|
||||||
private function tryResponse($handler, $request, $args)
|
|
||||||
{
|
|
||||||
$response = null;
|
|
||||||
try {
|
|
||||||
$response = $handler->getResponse($request, $args);
|
|
||||||
} catch (HttpException $e) {
|
|
||||||
$response = new Response();
|
|
||||||
$response->setStatusCode($e->getCode());
|
|
||||||
$response->setBody($e->getMessage());
|
|
||||||
}
|
|
||||||
return $response;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the response built by the handler based on the request
|
* Return the response built by the handler based on the request
|
||||||
*
|
*
|
||||||
|
|
@ -65,21 +49,8 @@ class Router implements HandlerInterface
|
||||||
*/
|
*/
|
||||||
public function getResponse(RequestInterface $request, array $args = null)
|
public function getResponse(RequestInterface $request, array $args = null)
|
||||||
{
|
{
|
||||||
$path = $request->getPath();
|
$response = $this->getResponseFromRoutes($request, $args);
|
||||||
if (array_key_exists($path, $this->routes)) {
|
if ($response) {
|
||||||
$handler = new $this->routes[$path]();
|
|
||||||
$response = $this->tryResponse($handler, $request, $args);
|
|
||||||
} else {
|
|
||||||
foreach ($this->routes as $path => $route) {
|
|
||||||
// Only take elements that are not $path => $handler mapped.
|
|
||||||
if (is_int($path)) {
|
|
||||||
/** @var HandlerInterface $route */
|
|
||||||
$response = $this->tryResponse($route, $request, $args);
|
|
||||||
if ($response) break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (isset($response) and $response) {
|
|
||||||
// Check if the router has an error handler for this status code.
|
// Check if the router has an error handler for this status code.
|
||||||
$status = $response->getStatusCode();
|
$status = $response->getStatusCode();
|
||||||
if (array_key_exists($status, $this->errorHandlers)) {
|
if (array_key_exists($status, $this->errorHandlers)) {
|
||||||
|
|
@ -92,9 +63,8 @@ class Router implements HandlerInterface
|
||||||
}
|
}
|
||||||
return $errorHandler->getResponse($request, $errorArgs);
|
return $errorHandler->getResponse($request, $errorArgs);
|
||||||
}
|
}
|
||||||
return $response;
|
|
||||||
}
|
}
|
||||||
return null;
|
return $response;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -104,11 +74,8 @@ class Router implements HandlerInterface
|
||||||
*/
|
*/
|
||||||
public function addRoute(HandlerInterface $route)
|
public function addRoute(HandlerInterface $route)
|
||||||
{
|
{
|
||||||
if ($route instanceof StaticRoute) {
|
if ($route instanceof StaticRouteInterface) {
|
||||||
$handler = $route->getHandler();
|
$this->setStaticRoute($route->getPaths(), $route->getHandler());
|
||||||
foreach ($route->getPaths() as $path) {
|
|
||||||
$this->routes[$path] = $handler;
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
$this->routes[] = $route;
|
$this->routes[] = $route;
|
||||||
}
|
}
|
||||||
|
|
@ -128,6 +95,22 @@ class Router implements HandlerInterface
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A route for an exact match to a path.
|
||||||
|
*
|
||||||
|
* @param string|array $paths Path component of the URI or a list of paths
|
||||||
|
* @param string $handler Fully qualified name to an autoloadable handler class.
|
||||||
|
*/
|
||||||
|
public function setStaticRoute($paths, $handler)
|
||||||
|
{
|
||||||
|
if (is_string($paths)) {
|
||||||
|
$paths = array($paths);
|
||||||
|
}
|
||||||
|
foreach ($paths as $path) {
|
||||||
|
$this->staticRoutes[$path] = $handler;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add a custom error handler.
|
* Add a custom error handler.
|
||||||
*
|
*
|
||||||
|
|
@ -180,4 +163,62 @@ class Router implements HandlerInterface
|
||||||
return $response;
|
return $response;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private function getStaticHandler($path)
|
||||||
|
{
|
||||||
|
if (array_key_exists($path, $this->staticRoutes)) {
|
||||||
|
return new $this->staticRoutes[$path]();
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function getResponseFromRoutes(RequestInterface $request, array $args = null)
|
||||||
|
{
|
||||||
|
$response = null;
|
||||||
|
|
||||||
|
$path = $request->getPath();
|
||||||
|
|
||||||
|
// First check if there is a handler for this exact path.
|
||||||
|
$handler = $this->getStaticHandler($path);
|
||||||
|
if ($handler) {
|
||||||
|
$reponse = $this->tryResponse($handler, $request, $args);
|
||||||
|
if ($reponse) {
|
||||||
|
return $reponse;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Try each of the routes.
|
||||||
|
foreach ($this->routes as $route) {
|
||||||
|
/** @var HandlerInterface $route */
|
||||||
|
$response = $this->tryResponse($route, $request, $args);
|
||||||
|
if ($response) {
|
||||||
|
return $response;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Wraps the getResponse method in a try-catch.
|
||||||
|
*
|
||||||
|
* In an HttpException is caught while trying to get a response, the method returns a response based on the
|
||||||
|
* HttpException's error code and message.
|
||||||
|
*
|
||||||
|
* @param HandlerInterface $handler The Route or Handler to try.
|
||||||
|
* @param RequestInterface $request The incoming request.
|
||||||
|
* @param array $args The array of arguments.
|
||||||
|
* @return null|Response
|
||||||
|
*/
|
||||||
|
private function tryResponse($handler, $request, $args)
|
||||||
|
{
|
||||||
|
$response = null;
|
||||||
|
try {
|
||||||
|
$response = $handler->getResponse($request, $args);
|
||||||
|
} catch (HttpException $e) {
|
||||||
|
$response = new Response();
|
||||||
|
$response->setStatusCode($e->getCode());
|
||||||
|
$response->setBody($e->getMessage());
|
||||||
|
}
|
||||||
|
return $response;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -11,12 +11,14 @@
|
||||||
namespace pjdietz\WellRESTed\Routes;
|
namespace pjdietz\WellRESTed\Routes;
|
||||||
|
|
||||||
use InvalidArgumentException;
|
use InvalidArgumentException;
|
||||||
|
use pjdietz\WellRESTed\Interfaces\HandlerInterface;
|
||||||
use pjdietz\WellRESTed\Interfaces\RequestInterface;
|
use pjdietz\WellRESTed\Interfaces\RequestInterface;
|
||||||
|
use pjdietz\WellRESTed\Interfaces\Routes\StaticRouteInterface;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Maps a list of static URI paths to a Handler
|
* Maps a list of static URI paths to a Handler
|
||||||
*/
|
*/
|
||||||
class StaticRoute extends BaseRoute
|
class StaticRoute extends BaseRoute implements StaticRouteInterface
|
||||||
{
|
{
|
||||||
/** @var array List of static URI paths */
|
/** @var array List of static URI paths */
|
||||||
protected $paths;
|
protected $paths;
|
||||||
|
|
@ -67,7 +69,7 @@ class StaticRoute extends BaseRoute
|
||||||
/**
|
/**
|
||||||
* Returns the target class this maps to.
|
* Returns the target class this maps to.
|
||||||
*
|
*
|
||||||
* @return HandlerInterface
|
* @return string Fully qualified name for a HandlerInterface
|
||||||
*/
|
*/
|
||||||
public function getHandler()
|
public function getHandler()
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -48,6 +48,20 @@ class RouterTest extends \PHPUnit_Framework_TestCase
|
||||||
$this->assertEquals(200, $resp->getStatusCode());
|
$this->assertEquals(200, $resp->getStatusCode());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testTryRoutesAfterNullStaticRoute()
|
||||||
|
{
|
||||||
|
$mockRequest = $this->getMock('\pjdietz\WellRESTed\Interfaces\RequestInterface');
|
||||||
|
$mockRequest->expects($this->any())
|
||||||
|
->method('getPath')
|
||||||
|
->will($this->returnValue("/cat/"));
|
||||||
|
|
||||||
|
$router = new Router();
|
||||||
|
$router->setStaticRoute("/cat/", __NAMESPACE__ . '\\NullResponseHandler');
|
||||||
|
$router->addRoute(new TemplateRoute("/cat/*", __NAMESPACE__ . '\\RouterTestHandler'));
|
||||||
|
$resp = $router->getResponse($mockRequest);
|
||||||
|
$this->assertEquals(200, $resp->getStatusCode());
|
||||||
|
}
|
||||||
|
|
||||||
public function testRespondWithDefaultErrorForException()
|
public function testRespondWithDefaultErrorForException()
|
||||||
{
|
{
|
||||||
$mockRequest = $this->getMock('\pjdietz\WellRESTed\Interfaces\RequestInterface');
|
$mockRequest = $this->getMock('\pjdietz\WellRESTed\Interfaces\RequestInterface');
|
||||||
|
|
@ -348,3 +362,11 @@ class InjectionHandler implements HandlerInterface
|
||||||
return $response;
|
return $response;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class NullResponseHandler implements HandlerInterface
|
||||||
|
{
|
||||||
|
public function getResponse(RequestInterface $request, array $args = null)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue