From b29f2ce37daa30ae303ed2f839ce0da645a2920b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20Sessing=C3=B8?= Date: Sat, 19 Mar 2016 16:14:36 +0100 Subject: [PATCH 1/4] [FEATURE] Added custom boot managers --- README.md | 88 +++++++++++++++----- src/Pecee/Http/Request.php | 25 ++++-- src/Pecee/Http/Response.php | 2 +- src/Pecee/SimpleRouter/IRouteEntry.php | 7 -- src/Pecee/SimpleRouter/RouterBase.php | 37 +++++++- src/Pecee/SimpleRouter/RouterBootManager.php | 10 +++ src/Pecee/SimpleRouter/SimpleRouter.php | 4 + 7 files changed, 131 insertions(+), 42 deletions(-) delete mode 100644 src/Pecee/SimpleRouter/IRouteEntry.php create mode 100644 src/Pecee/SimpleRouter/RouterBootManager.php diff --git a/README.md b/README.md index cb773b7..d0b5b50 100644 --- a/README.md +++ b/README.md @@ -1,18 +1,11 @@ # Simple PHP router -Simple, fast and yet powerful PHP router that is easy to get integrated and in any project. Heavily inspired by the way Laravel handles routing. +Simple, fast and yet powerful PHP router that is easy to get integrated and in any project. Heavily inspired by the way Laravel handles routing, with both simplicity and expandability in mind. ## Installation -Add the latest version of Simple PHP Router to your ```composer.json``` +Add the latest version of Simple PHP Router running this command. -```json -{ - "require": { - "pecee/simple-php-router": "1.*" - }, - "require-dev": { - "pecee/simple-php-router": "1.*" - } -} +``` +composer require pecee/framework ``` ## Notes @@ -32,10 +25,7 @@ The goal of this project is to create a router that is 100% compatible with the - CSRF protection. - Optional parameters - Sub-domain routing - -### Features currently "in-the-works" - -- Global Constraints +- Custom boot managers to redirect urls to other routes ## Initialising the router @@ -77,7 +67,7 @@ SimpleRouter::group(['prefix' => 'v1', 'middleware' => '\MyWebsite\Middleware\So SimpleRouter::group(['prefix' => '/services', 'exceptionHandler' => '\MyProject\Handler\CustomExceptionHandler'], function() { SimpleRouter::get('/answers/{id}', 'ControllerAnswers@show')->where(['id' => '[0-9]+'); - + // Optional parameter SimpleRouter::get('/answers/{id?}', 'ControllerAnswers@show'); @@ -175,10 +165,10 @@ class Router extends SimpleRouter { $exceptionHandler = null; // Load and use exception-handler defined on group - + if($route && $route->getGroup()) { $exceptionHandler = $route->getGroup()->getExceptionHandler(); - + if($exceptionHandler !== null) { $class = new $exceptionHandler(); $class->handleError(RouterBase::getInstance()->getRequest(), $route, $e); @@ -186,7 +176,7 @@ class Router extends SimpleRouter { } // Otherwise use the fallback default exceptions handler - + if(self::$defaultExceptionHandler !== null) { $class = new self::$defaultExceptionHandler(); $class->handleError(RouterBase::getInstance()->getRequest(), $route, $e); @@ -270,9 +260,63 @@ Register the new class in your ```routes.php```, custom ```Router``` class or wh SimpleRouter::csrfVerifier(new \Demo\Middleware\CsrfVerifier()); ``` +## Using router bootmanager to make custom rewrite rules + +Sometimes it can be necessary to keep urls stored in the database, file or similar. In this example, we want the url ```/my-cat-is-beatiful``` to load the route ```/article/view/1``` which the router knows, because it's defined in the ```routes.php``` file. + +To interfere with the router, we create a class that inherits from ```RouterBootManager```. This class will be loaded before any other rules in ```routes.php``` and allow us to "change" the current route, if any of our criteria are fulfilled (like comming from the url ```/my-cat-is-beatiful```). + +```php + +use Pecee\Http\Request; +use Pecee\SimpleRouter\RouterBootManager; + +class CustomRouterRules extends RouterBootManager{ + + public function boot(Request $request) { + + $rewriteRules = [ + '/my-cat-is-beatiful' => '/article/view/1', + '/horses-are-great' => '/article/view/2' + ]; + + foreach($rewriteRules as $url => $rule) { + + // If the current uri matches the url, we use our custom route + + if($request->getUri() === $url) { + $request->setUri($rule); + } + } + + return $request; + } + +} + +``` + +The above should be pretty selvexplanatory and can easily be changed to loop through urls store in the database, file or cache. + +Basicly what happens if that if the current route matches the route defined in the index of our array, we set the route to the array value instead. + +By doing this the route will now goto the url ```/article/view/1``` instead of ```/my-cat-is-beatiful```. + +The last thing we need to do, is to add our custom boot-manager to the ```routes.php``` file. You can create as many bootmanagers as you like and easily add them in your ```routes.php``` file. + +**routes.php example:** + +```php +// Add new bootmanager +SimpleRouter::addBootManager(new CustomRouterRules()); + +// This rule is what our custom bootmanager will use. +SimpleRouter::get('/article/view/{id}', 'ControllerArticle@view'); +``` + ## Easily overwrite route about to be loaded -Sometimes it can be useful to manipulate the route that's about to be loaded, for instance if a user is not authenticated or if an error occurred within your Middleware that requires -some other route to be initialised. Simple PHP Router allows you to easily change the route about to be executed. All information about the current route is stored in +Sometimes it can be useful to manipulate the route that's about to be loaded, for instance if a user is not authenticated or if an error occurred within your Middleware that requires +some other route to be initialised. Simple PHP Router allows you to easily change the route about to be executed. All information about the current route is stored in the ```\Pecee\SimpleRouter\Http\Request``` object. **Note:** Please note that it's only possible to change the route BEFORE any route has initially been loaded, so doing this in your custom ExceptionHandler or Middleware is highly recommended. @@ -297,7 +341,7 @@ http://laravel.com/docs/5.1/routing The router can be easily extended to customize your needs. ## Ideas and issues -If you want a great new feature or experience any issues what-so-ever, please feel free to leave an issue and i'll look into it whenever possible. +If you want a great new feature or experience any issues what-so-ever, please feel free to leave an issue and i'll look into it whenever possible. ## The MIT License (MIT) diff --git a/src/Pecee/Http/Request.php b/src/Pecee/Http/Request.php index 33dc175..7f1e8ca 100644 --- a/src/Pecee/Http/Request.php +++ b/src/Pecee/Http/Request.php @@ -1,8 +1,6 @@ loadedRoute; } - public function isFormatAccepted($format) { - return (isset($_SERVER['HTTP_ACCEPT']) && stripos($_SERVER['HTTP_ACCEPT'], $format) > -1); + /** + * @param mixed $uri + */ + public function setUri($uri) { + $this->uri = $uri; } - public function getAcceptFormats() { - if(isset($_SERVER['HTTP_ACCEPT'])) { - return explode(',', $_SERVER['HTTP_ACCEPT']); - } + /** + * @param mixed $host + */ + public function setHost($host) { + $this->host = $host; + } - return array(); + /** + * @param mixed $method + */ + public function setMethod($method) { + $this->method = $method; } } \ No newline at end of file diff --git a/src/Pecee/Http/Response.php b/src/Pecee/Http/Response.php index 1815d63..c60743d 100644 --- a/src/Pecee/Http/Response.php +++ b/src/Pecee/Http/Response.php @@ -26,7 +26,7 @@ class Response { $this->httpCode($httpCode); } - $this->header('Location: ' . $url); + $this->header('location: ' . $url); die(); } diff --git a/src/Pecee/SimpleRouter/IRouteEntry.php b/src/Pecee/SimpleRouter/IRouteEntry.php deleted file mode 100644 index d13e752..0000000 --- a/src/Pecee/SimpleRouter/IRouteEntry.php +++ /dev/null @@ -1,7 +0,0 @@ -backStack = array(); $this->controllerUrlMap = array(); $this->baseCsrfVerifier = new BaseCsrfVerifier(); - $this->request = Request::getInstance(); + $this->request = new Request(); + $this->bootManagers = array(); $csrf = new CsrfToken(); $token = ($csrf->hasToken()) ? $csrf->getToken() : $csrf->generateToken(); @@ -106,6 +107,18 @@ class RouterBase { public function routeRequest() { + // Initialize boot-managers + if(count($this->bootManagers)) { + /* @var $manager RouterBootManager */ + foreach($this->bootManagers as $manager) { + $this->request = $manager->boot($this->request); + + if(!($this->request instanceof Request)) { + throw new RouterException('Custom router bootmanager "'. get_class($manager) .'" must return instance of Request.'); + } + } + } + // Verify csrf token for request if($this->baseCsrfVerifier !== null) { /* @var $csrfVerifier BaseCsrfVerifier */ @@ -168,6 +181,24 @@ class RouterBase { $this->defaultNamespace = $defaultNamespace; } + /** + * @return array + */ + public function getBootManagers() { + return $this->bootManagers; + } + + /** + * @param array $bootManagers + */ + public function setBootManagers(array $bootManagers) { + $this->bootManagers = $bootManagers; + } + + public function addBootManager(RouterBootManager $bootManager) { + $this->bootManagers[] = $bootManager; + } + /** * @return RouterEntry */ diff --git a/src/Pecee/SimpleRouter/RouterBootManager.php b/src/Pecee/SimpleRouter/RouterBootManager.php new file mode 100644 index 0000000..0358972 --- /dev/null +++ b/src/Pecee/SimpleRouter/RouterBootManager.php @@ -0,0 +1,10 @@ +setBaseCsrfVerifier($baseCsrfVerifier); } + public static function addBootManager(RouterBootManager $bootManager) { + RouterBase::getInstance()->addBootManager($bootManager); + } + public static function get($url, $callback, array $settings = null) { $route = new RouterRoute($url, $callback); $route->addSettings($settings); From 060479f1fe6fb164f1e5ad2090b1793ab33c399b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20Sessing=C3=B8?= Date: Sat, 19 Mar 2016 16:18:33 +0100 Subject: [PATCH 2/4] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 23b0caa..b4ce627 100644 --- a/README.md +++ b/README.md @@ -345,7 +345,7 @@ If you want a great new feature or experience any issues what-so-ever, please fe ## The MIT License (MIT) -Copyright (c) 2015 Simon Sessingø / simple-php-router +Copyright (c) 2016 Simon Sessingø / simple-php-router Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal From 6395801a06ace3c90649f7b15f7eaab77968ed4d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20Sessing=C3=B8?= Date: Sat, 19 Mar 2016 16:19:04 +0100 Subject: [PATCH 3/4] [OPTIMISATIONS] Documentation --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index d0b5b50..23b0caa 100644 --- a/README.md +++ b/README.md @@ -296,11 +296,11 @@ class CustomRouterRules extends RouterBootManager{ ``` -The above should be pretty selvexplanatory and can easily be changed to loop through urls store in the database, file or cache. +The above should be pretty self-explanatory and can easily be changed to loop through urls store in the database, file or cache. -Basicly what happens if that if the current route matches the route defined in the index of our array, we set the route to the array value instead. +What happens is that if the current route matches the route defined in the index of our ```$rewriteRules``` array, we set the route to the array value instead. -By doing this the route will now goto the url ```/article/view/1``` instead of ```/my-cat-is-beatiful```. +By doing this the route will now load the url ```/article/view/1``` instead of ```/my-cat-is-beatiful```. The last thing we need to do, is to add our custom boot-manager to the ```routes.php``` file. You can create as many bootmanagers as you like and easily add them in your ```routes.php``` file. From 1bafbab56b7f07d4849d6abd6497aa1e792c1610 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20Sessing=C3=B8?= Date: Sat, 19 Mar 2016 16:27:25 +0100 Subject: [PATCH 4/4] [TASK] Moved RouterException. Readded lost stuff from Request. --- .../RouterException.php | 2 +- src/Pecee/Http/Request.php | 16 +++++++++++----- src/Pecee/SimpleRouter/RouterBase.php | 3 ++- src/Pecee/SimpleRouter/RouterController.php | 1 + src/Pecee/SimpleRouter/RouterEntry.php | 1 + src/Pecee/SimpleRouter/RouterGroup.php | 1 + src/Pecee/SimpleRouter/RouterResource.php | 1 + 7 files changed, 18 insertions(+), 7 deletions(-) rename src/Pecee/{SimpleRouter => Exception}/RouterException.php (62%) diff --git a/src/Pecee/SimpleRouter/RouterException.php b/src/Pecee/Exception/RouterException.php similarity index 62% rename from src/Pecee/SimpleRouter/RouterException.php rename to src/Pecee/Exception/RouterException.php index c8ca241..5432c66 100644 --- a/src/Pecee/SimpleRouter/RouterException.php +++ b/src/Pecee/Exception/RouterException.php @@ -1,3 +1,3 @@ -1); + } + + public function getAcceptFormats() { + if(isset($_SERVER['HTTP_ACCEPT'])) { + return explode(',', $_SERVER['HTTP_ACCEPT']); + } + return array(); + } + public function __set($name, $value = null) { $this->data[$name] = $value; } diff --git a/src/Pecee/SimpleRouter/RouterBase.php b/src/Pecee/SimpleRouter/RouterBase.php index 1dd6400..926d648 100644 --- a/src/Pecee/SimpleRouter/RouterBase.php +++ b/src/Pecee/SimpleRouter/RouterBase.php @@ -2,6 +2,7 @@ namespace Pecee\SimpleRouter; use Pecee\CsrfToken; +use Pecee\Exception\RouterException; use Pecee\Http\Middleware\BaseCsrfVerifier; use Pecee\Http\Request; @@ -18,7 +19,7 @@ class RouterBase { protected $defaultNamespace; protected $bootManagers; protected $baseCsrfVerifier; - + // TODO: clean up - cut some of the methods down to smaller pieces public function __construct() { diff --git a/src/Pecee/SimpleRouter/RouterController.php b/src/Pecee/SimpleRouter/RouterController.php index b05db29..14230b5 100644 --- a/src/Pecee/SimpleRouter/RouterController.php +++ b/src/Pecee/SimpleRouter/RouterController.php @@ -1,6 +1,7 @@