Callback, faking route and documentation updates

This commit is contained in:
Simon Sessingø
2016-11-15 05:44:24 +01:00
parent bc14790a67
commit 83c73a4240
8 changed files with 131 additions and 50 deletions
+7 -1
View File
@@ -6,6 +6,12 @@ use Pecee\SimpleRouter\RouterEntry;
interface IExceptionHandler {
public function handleError(Request $request, RouterEntry $router = null, \Exception $error);
/**
* @param Request $request
* @param RouterEntry|null $route
* @param \Exception $error
* @return Request|null
*/
public function handleError(Request $request, RouterEntry &$route = null, \Exception $error);
}
@@ -4,6 +4,7 @@ namespace Pecee\Http\Middleware;
use Pecee\CsrfToken;
use Pecee\Exception\TokenMismatchException;
use Pecee\Http\Request;
use Pecee\SimpleRouter\RouterEntry;
class BaseCsrfVerifier implements IMiddleware {
@@ -49,11 +50,11 @@ class BaseCsrfVerifier implements IMiddleware {
return false;
}
public function handle(Request $request) {
public function handle(Request $request, RouterEntry &$route = null) {
if($request->getMethod() != 'get' && !$this->skip($request)) {
if($request->getMethod() !== 'get' && !$this->skip($request)) {
$token = (isset($_POST[static::POST_KEY])) ? $_POST[static::POST_KEY] : null;
$token = $request->getInput()->post->findFirst(static::POST_KEY);
// If the token is not posted, check headers for valid x-csrf-token
if($token === null) {
+9 -1
View File
@@ -2,7 +2,15 @@
namespace Pecee\Http\Middleware;
use Pecee\Http\Request;
use Pecee\SimpleRouter\RouterEntry;
interface IMiddleware {
public function handle(Request $request);
/**
* @param Request $request
* @param RouterEntry|null $route
* @return Request|null
*/
public function handle(Request $request, RouterEntry &$route = null);
}
+50 -33
View File
@@ -71,6 +71,14 @@ class RouterBase {
*/
protected $exceptionHandlers;
/**
* The current loaded route
* @var RouterRoute|null
*/
protected $loadedRoute;
protected $routeChanges;
public function __construct() {
$this->reset();
}
@@ -83,6 +91,7 @@ class RouterBase {
$this->controllerUrlMap = array();
$this->bootManagers = array();
$this->exceptionHandlers = array();
$this->routeChanges = array();
}
/**
@@ -173,18 +182,21 @@ class RouterBase {
}
}
public function routeRequest($original = true) {
public function routeRequest(Request $newRequest = null) {
$originalUri = $this->request->getUri();
$this->loadedRoute = null;
$routeNotAllowed = false;
// Create a fictive request - so it can be changed in the middleware or exceptionhandler later on...
$request = clone $this->request;
try {
// Initialize boot-managers
if(count($this->bootManagers)) {
/* @var $manager RouterBootManager */
foreach($this->bootManagers as $manager) {
$this->request = $manager->boot($this->request);
$request = $manager->boot($request);
if(!($this->request instanceof Request)) {
throw new RouterException('Custom router bootmanager "'. get_class($manager) .'" must return instance of Request.');
@@ -192,35 +204,42 @@ class RouterBase {
}
}
// Loop through each route-request
$this->processRoutes($this->routes);
if($newRequest === null && $this->csrfVerifier !== null) {
// Loop through each route-request
$this->processRoutes($this->routes);
if($original === true && $this->csrfVerifier !== null) {
// Verify csrf token for request
$this->csrfVerifier->handle($this->request);
}
$request = ($newRequest !== null) ? $newRequest : $request;
/* @var $route RouterEntry */
for ($i = 0; $i < count($this->controllerUrlMap); $i++) {
$route = $this->controllerUrlMap[$i];
if ($route->matchRoute($this->request)) {
if ($route->matchRoute($request)) {
if (count($route->getRequestMethods()) && !in_array($this->request->getMethod(), $route->getRequestMethods())) {
if (count($route->getRequestMethods()) && !in_array($request->getMethod(), $route->getRequestMethods())) {
$routeNotAllowed = true;
continue;
}
$routeNotAllowed = false;
$this->request->rewrite_uri = $this->request->getUri();
$this->request->setUri($originalUri);
$this->loadedRoute = $route;
$request = $this->loadedRoute->loadMiddleware($request, $this->loadedRoute);
$request = ($request === null) ? $this->request : $request;
$this->request->loadedRoute = $route;
$this->request->loadedRoute->loadMiddleware($this->request);
if($request !== null && $request->getUri() !== $this->request->getUri() && !in_array($request->getUri(), $this->routeChanges)) {
$this->routeChanges[] = $request->getUri();
$this->routeRequest($request);
return;
}
$this->request->loadedRoute->renderRoute($this->request);
$this->loadedRoute->renderRoute($request);
break;
}
@@ -234,18 +253,17 @@ class RouterBase {
$this->handleException(new RouterException('Route or method not allowed', 403));
}
if(!$this->request->loadedRoute) {
$this->handleException(new RouterException(sprintf('Route not found: %s', $this->request->getUri()), 404));
if($this->loadedRoute === null) {
$this->handleException(new RouterException(sprintf('Route not found: %s', $request->getUri()), 404));
}
}
protected function handleException(\Exception $e) {
$request = null;
$request = clone $this->request;
/* @var $route RouterGroup */
foreach ($this->exceptionHandlers as $route) {
$route->loadMiddleware($this->request);
$handler = $route->getExceptionHandler();
$handler = new $handler();
@@ -253,13 +271,20 @@ class RouterBase {
throw new RouterException('Exception handler must implement the IExceptionHandler interface.');
}
$request = $handler->handleError($this->request, $this->request->loadedRoute, $e);
}
$request = $handler->handleError($request, $this->loadedRoute, $e);
$request = ($request === null) ? $this->request : $request;
if(!in_array($request->getUri(), $this->routeChanges)) {
$this->routeChanges[] = $request->getUri();
if($request->getUri() !== $this->request->getUri()) {
$this->routeRequest($request);
} else {
$this->routeChanges[] = $request->getUri();
$this->loadedRoute->renderRoute($request);
}
return;
}
if($request !== null) {
$this->request = $request;
$this->routeRequest(false);
return;
}
throw $e;
@@ -307,14 +332,6 @@ class RouterBase {
$this->bootManagers[] = $bootManager;
}
/**
* Get the loaded route
* @return RouterEntry
*/
public function getLoadedRoute() {
return $this->request->loadedRoute;
}
/**
* @return array
*/
@@ -451,8 +468,8 @@ class RouterBase {
return $url;
}
if($controller === null && $this->request->loadedRoute !== null) {
return $this->processUrl($this->request->loadedRoute, $this->request->loadedRoute->getMethod(), $parameters, $getParams);
if($controller === null && $this->loadedRoute !== null) {
return $this->processUrl($this->loadedRoute, $this->loadedRoute->getMethod(), $parameters, $getParams);
}
$c = '';
+2 -2
View File
@@ -291,7 +291,7 @@ abstract class RouterEntry {
return null;
}
public function loadMiddleware(Request $request) {
public function loadMiddleware(Request $request, RouterRoute &$route) {
if(count($this->getMiddleware())) {
foreach($this->getMiddleware() as $middleware) {
$middleware = $this->loadClass($middleware);
@@ -300,7 +300,7 @@ abstract class RouterEntry {
}
/* @var $class IMiddleware */
$middleware->handle($request);
$middleware->handle($request, $route);
}
}
}
+2 -2
View File
@@ -113,8 +113,8 @@ class RouterGroup extends RouterEntry {
// Push middleware if multiple
if ($this->getMiddleware() !== null && isset($settings['middleware'])) {
if (!is_array($this->getMiddleware())) {
$settings['middleware'] = array($this->getMiddleware(), $settings['middleware']);
if (!is_array($settings['middleware'])) {
$settings['middleware'] = array_merge($this->getMiddleware(), array($settings['middleware']));
} else {
$settings['middleware'][] = $this->getMiddleware();
}