Compare commits

..

1 Commits

Author SHA1 Message Date
Simon Sessingø 8740db9582 Development
- Isolated Http classes from router.
- Removed getInstance from Request object - current router request should now be obtained through SimpleRouter::request().
- Fixed broken test cases.
- Added test for regular expression match.
- Updated documentation to reflect changes.
- Added more helper examples to documentation.
- Added helpers to demo-project.
- Optimisations.
2016-11-07 04:40:28 +01:00
13 changed files with 180 additions and 119 deletions
+31 -16
View File
@@ -208,15 +208,12 @@ class Router extends SimpleRouter {
**This is a basic example of a helper function for generating urls.**
```php
use Pecee\SimpleRouter\RouterBase;
use Pecee\SimpleRouter\SimpleRouter;
function url($controller, $parameters = null, $getParams = null) {
RouterBase::getInstance()->getRoute($controller, $parameters, $getParams);
SimpleRouter::getRoute($controller, $parameters, $getParams);
}
```
**This is a basic example for getting the current csrf token**
```php
/**
* Get current csrf-token
* @return null|string
@@ -225,6 +222,22 @@ function csrf_token() {
$token = new \Pecee\CsrfToken();
return $token->getToken();
}
/**
* Get request object
* @return \Pecee\Http\Request
*/
function request() {
return SimpleRouter::request();
}
/**
* Get response object
* @return \Pecee\Http\Response
*/
function response() {
return SimpleRouter::response();
}
```
## Getting urls
@@ -327,12 +340,14 @@ 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
the ```\Pecee\SimpleRouter\Http\Request``` object.
the ```\Pecee\SimpleRouter\Http\Request``` object. All information about the current route is as a ```\Pecee\SimpleRouter\Http\Request``` object which can always be obtained on
the `RouterBase` instance. For easy access you can use the shortcut method `\Pecee\SimpleRouter\SimpleRouter::request()`.
**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.
```php
$route = Request::getInstance()->getLoadedRoute();
use Pecee\SimpleRouter;
$route = SimpleRouter::request()->getLoadedRoute();
$route->setCallback('Example\MyCustomClass@hello');
@@ -348,28 +363,28 @@ We've added the `Input` class to easy access parameters from your Controller-cla
**Return single parameter value (matches both GET, POST, FILE):**
```php
$value = Request::getInstance()->getInput()->get('name');
$value = SimpleRouter::request()->getInput()->get('name');
```
**Return parameter object (matches both GET, POST, FILE):**
```php
$object = Request::getInstance()->getInput()->getObject('name');
$object = SimpleRouter::request()->getInput()->getObject('name');
```
**Return specific GET parameter (where name is the name of your parameter):**
```php
$object = Request::getInstance()->getInput()->get->name;
$object = Request::getInstance()->getInput()->post->name;
$object = Request::getInstance()->getInput()->file->name;
$object = SimpleRouter::request()->getInput()->get->name;
$object = SimpleRouter::request()->getInput()->post->name;
$object = SimpleRouter::request()->getInput()->file->name;
```
**Return all parameters:**
```php
// Get all
$objects = Request::getInstance()->getInput()->all();
$objects = SimpleRouter::request()->getInput()->all();
// Only match certain keys
$objects = Request::getInstance()->getInput()->all([
$objects = SimpleRouter::request()->getInput()->all([
'company_name',
'user_id'
]);
@@ -400,7 +415,7 @@ Example:
* @return \Pecee\Http\Input\Input
*/
function input() {
return \Pecee\Http\Request::getInstance()->getInput();
return SimpleRouter::request()->getInput();
}
```
@@ -1,7 +1,7 @@
<?php
namespace Demo\Controllers;
use Pecee\Http\Request;
use Pecee\SimpleRouter\SimpleRouter;
class ApiController {
@@ -9,7 +9,7 @@ class ApiController {
// The variable authenticated is set to true in the ApiVerification middleware class.
$request = Request::getInstance();
$request = SimpleRouter::request();
header('content-type: application/json');
+4 -2
View File
@@ -13,11 +13,13 @@ class Router extends SimpleRouter {
public static function start($defaultNamespace = null) {
// change this to whatever makes sense in your project
// Load our helpers
require_once 'helpers.php';
// Load our custom routes
require_once 'routes.php';
// Do initial stuff
parent::start('\\Demo\\Controllers');
}
+31
View File
@@ -0,0 +1,31 @@
<?php
use \Pecee\SimpleRouter\SimpleRouter;
function url($controller, $parameters = null, $getParams = null) {
SimpleRouter::getRoute($controller, $parameters, $getParams);
}
/**
* Get current csrf-token
* @return null|string
*/
function csrf_token() {
$token = new \Pecee\CsrfToken();
return $token->getToken();
}
/**
* Get request object
* @return \Pecee\Http\Request
*/
function request() {
return SimpleRouter::request();
}
/**
* Get response object
* @return \Pecee\Http\Response
*/
function response() {
return SimpleRouter::response();
}
+20 -32
View File
@@ -38,31 +38,17 @@ class Input {
* @return array
*/
public function all(array $filter = null) {
$output = $_POST;
if($this->request->getMethod() === 'post') {
$contents = file_get_contents('php://input');
if (stripos(trim($contents), '{') === 0) {
$output = json_decode($contents, true);
if($output === false) {
$output = array();
}
}
}
$output = array_merge($_GET, $output);
$output = $this->get->getData();
$output = array_merge($output, $this->post->getData());
if($filter !== null) {
$output = array_filter($output, function ($key) use ($filter) {
if (in_array($key, $filter)) {
return true;
$tmp = array();
foreach($output as $key => $val) {
if(in_array($key, $filter)) {
$tmp[$key] = $val;
}
return false;
}, ARRAY_FILTER_USE_KEY);
}
return $tmp;
}
return $output;
@@ -107,7 +93,7 @@ class Input {
if($item !== null) {
if($item instanceof InputCollection || $item instanceof InputFile) {
if(is_array($item) || $item instanceof InputFile) {
return $item;
}
@@ -131,10 +117,10 @@ class Input {
continue;
}
$output = new InputCollection();
$output = array();
foreach($get as $k => $g) {
$output->{$k} = new InputItem($k, $g);
$output[$k] = new InputItem($k, $g);
}
$this->get->{$key} = $output;
@@ -145,10 +131,12 @@ class Input {
public function setPost() {
$this->post = new InputCollection();
$postVars = $_POST;
$postVars = array();
if(in_array($this->request->getMethod(), ['put', 'patch', 'delete'])) {
if(isset($_SERVER['REQUEST_METHOD']) && in_array($_SERVER['REQUEST_METHOD'], ['PUT', 'PATCH', 'DELETE'])) {
parse_str(file_get_contents('php://input'), $postVars);
} else {
$postVars = $_POST;
}
if(count($postVars)) {
@@ -159,10 +147,10 @@ class Input {
continue;
}
$output = new InputCollection();
$output = array();
foreach($post as $k => $p) {
$output->{$k} = new InputItem($k, $p);
foreach($post as $k=>$p) {
$output[$k] = new InputItem($k, $p);
}
$this->post->{strtolower($key)} = $output;
@@ -190,7 +178,7 @@ class Input {
continue;
}
$output = new InputCollection();
$output = array();
foreach($value['name'] as $k=>$val) {
// Strip empty values
@@ -201,7 +189,7 @@ class Input {
$file->setType($value['type'][$k]);
$file->setTmpName($value['tmp_name'][$k]);
$file->setError($value['error'][$k]);
$output->{$k} = $file;
$output[$k] = $file;
}
}
-13
View File
@@ -5,21 +5,8 @@ use Pecee\Http\Input\Input;
class Request {
protected static $instance;
protected $data;
/**
* Return new instance
* @return static
*/
public static function getInstance() {
if(self::$instance === null) {
self::$instance = new static();
}
return self::$instance;
}
public function __construct() {
$this->data = array();
$this->host = isset($_SERVER['HTTP_HOST']) ? $_SERVER['HTTP_HOST'] : array();
+11 -11
View File
@@ -4,6 +4,12 @@ namespace Pecee\Http;
class Response {
protected $request;
public function __construct(Request &$request) {
$this->request = $request;
}
/**
* Set the http status code
*
@@ -31,7 +37,7 @@ class Response {
}
public function refresh() {
$this->redirect(Request::getInstance()->getUri());
$this->redirect($this->request->getUri());
}
/**
@@ -69,19 +75,13 @@ class Response {
}
/**
* Json encode
* @param array|\JsonSerializable $value
* @throws \InvalidArgumentException;
* Json encode array
* @param array $value
*/
public function json($value) {
if(($value instanceof \JsonSerializable) === false && is_array($value) === false) {
throw new \InvalidArgumentException('Invalid type for parameter "value". Must be of type array or object implementing the \JsonSerializable interface.');
}
public function json(array $value) {
$this->header('Content-type: application/json');
echo json_encode($value);
exit(0);
die();
}
/**
+31 -11
View File
@@ -5,12 +5,14 @@ use Pecee\Exception\RouterException;
use Pecee\Handler\IExceptionHandler;
use Pecee\Http\Middleware\BaseCsrfVerifier;
use Pecee\Http\Request;
use Pecee\Http\Response;
class RouterBase {
protected static $instance;
protected $request;
protected $response;
protected $currentRoute;
protected $routes;
protected $processedRoutes;
@@ -21,10 +23,13 @@ class RouterBase {
protected $baseCsrfVerifier;
protected $exceptionHandlers;
// TODO: clean up - cut some of the methods down to smaller pieces
public function __construct() {
$this->request = Request::getInstance();
$this->reset();
}
public function reset() {
$this->request = new Request();
$this->response = new Response($this->request);
$this->routes = array();
$this->backStack = array();
$this->controllerUrlMap = array();
@@ -289,6 +294,14 @@ class RouterBase {
return $this->request;
}
/**
* Get response
* @return Response
*/
public function getResponse() {
return $this->response;
}
/**
* Get base csrf verifier class
* @return BaseCsrfVerifier
@@ -341,10 +354,10 @@ class RouterBase {
$url = $domain . '/' . trim($route->getUrl(), '/');
if(($route instanceof RouterController || $route instanceof RouterResource) && $method !== null) {
$url .= $method;
}
if($method !== null) {
$url .= $method;
}
if($route instanceof RouterController || $route instanceof RouterResource) {
if(count($parameters)) {
$url .= join('/', $parameters);
}
@@ -419,12 +432,15 @@ class RouterBase {
$route = $this->controllerUrlMap[$i];
// Check an alias exist, if the matches - use it
if($route instanceof RouterRoute && $route->hasAlias($controller)) {
return $this->processUrl($route, $route->getMethod(), $parameters, $getParams);
}
if($route instanceof RouterRoute) {
if($route instanceof RouterRoute && !is_callable($route->getCallback()) && stripos($route->getCallback(), '@') !== false) {
$c = $route->getCallback();
if($route->hasAlias($controller)) {
return $this->processUrl($route, $route->getMethod(), $parameters, $getParams);
}
if(!is_callable($route->getCallback()) && stripos($route->getCallback(), '@') !== false) {
$c = $route->getCallback();
}
} else if($route instanceof RouterController || $route instanceof RouterResource) {
$c = $route->getController();
}
@@ -476,6 +492,10 @@ class RouterBase {
return $url;
}
/**
* Get current router instance
* @return static
*/
public static function getInstance() {
if(static::$instance === null) {
static::$instance = new static();
+2 -5
View File
@@ -97,12 +97,9 @@ class RouterGroup extends RouterEntry {
if($this->getMiddleware() !== null && isset($settings['middleware'])) {
if(!is_array($this->getMiddleware())) {
$middlewares = [
$this->getMiddleware(),
$settings['middleware']
];
$middlewares = [$this->getMiddleware(), $settings['middleware']];
} else {
$middlewares = array_push($settings['middleware'], $this->getMiddleware());
$middlewares = array_push($settings['middleware']);
}
$settings['middleware'] = array_unique(array_reverse($middlewares));
+12
View File
@@ -13,6 +13,10 @@ use Pecee\Http\Middleware\BaseCsrfVerifier;
class SimpleRouter {
public function __construct() {
die('test');
}
/**
* Start/route request
* @param null $defaultNamespace
@@ -128,4 +132,12 @@ class SimpleRouter {
return RouterBase::getInstance()->getRoute($controller, $parameters, $getParams);
}
public static function request() {
return RouterBase::getInstance()->getRequest();
}
public static function response() {
return RouterBase::getInstance()->getResponse();
}
}
+3 -2
View File
@@ -28,8 +28,9 @@ class GroupTest extends PHPUnit_Framework_TestCase {
public function testNestedGroup() {
\Pecee\SimpleRouter\RouterBase::getInstance()->getRequest()->setUri('/api/v1/test');
\Pecee\SimpleRouter\RouterBase::getInstance()->getRequest()->setMethod('get');
\Pecee\SimpleRouter\RouterBase::getInstance()->reset();
\Pecee\SimpleRouter\SimpleRouter::request()->setUri('/api/v1/test');
\Pecee\SimpleRouter\SimpleRouter::request()->setMethod('get');
\Pecee\SimpleRouter\SimpleRouter::group(['prefix' => '/api'], function() {
\Pecee\SimpleRouter\SimpleRouter::group(['prefix' => '/v1'], function() {
+3 -2
View File
@@ -8,8 +8,9 @@ class MiddlewareTest extends PHPUnit_Framework_TestCase {
public function testMiddlewareFound() {
\Pecee\Http\Request::getInstance()->setMethod('get');
\Pecee\Http\Request::getInstance()->setUri('/my/test/url');
\Pecee\SimpleRouter\RouterBase::getInstance()->reset();
\Pecee\SimpleRouter\SimpleRouter::request()->setMethod('get');
\Pecee\SimpleRouter\SimpleRouter::request()->setUri('/my/test/url');
\Pecee\SimpleRouter\SimpleRouter::group(['exceptionHandler' => 'ExceptionHandler'], function() {
\Pecee\SimpleRouter\SimpleRouter::get('/my/test/url', 'DummyController@start', ['middleware' => 'DummyMiddleware']);
+30 -23
View File
@@ -5,12 +5,12 @@ require_once 'Dummy/DummyController.php';
require_once 'Dummy/Handler/ExceptionHandler.php';
class RouterRouteTest extends PHPUnit_Framework_TestCase {
public function testNotFound() {
\Pecee\Http\Request::getInstance()->setMethod('get');
\Pecee\Http\Request::getInstance()->setUri('/test-param1-param2');
\Pecee\SimpleRouter\RouterBase::getInstance()->reset();
\Pecee\SimpleRouter\SimpleRouter::request()->setMethod('get');
\Pecee\SimpleRouter\SimpleRouter::request()->setUri('/test-param1-param2');
\Pecee\SimpleRouter\SimpleRouter::group(['exceptionHandler' => 'ExceptionHandler'], function() {
\Pecee\SimpleRouter\SimpleRouter::get('/non-existing-path', 'DummyController@start');
@@ -29,33 +29,36 @@ class RouterRouteTest extends PHPUnit_Framework_TestCase {
}
public function testGet() {
\Pecee\SimpleRouter\RouterBase::getInstance()->getRequest()->setUri('/my/test/url');
\Pecee\SimpleRouter\RouterBase::getInstance()->getRequest()->setMethod('get');
\Pecee\SimpleRouter\RouterBase::getInstance()->reset();
\Pecee\SimpleRouter\SimpleRouter::request()->setUri('/my/test/url');
\Pecee\SimpleRouter\SimpleRouter::request()->setMethod('get');
\Pecee\SimpleRouter\SimpleRouter::get('/my/test/url', 'DummyController@start');
\Pecee\SimpleRouter\SimpleRouter::start();
}
public function testPost() {
\Pecee\SimpleRouter\RouterBase::getInstance()->getRequest()->setUri('/my/test/url');
\Pecee\Http\Request::getInstance()->setMethod('post');
\Pecee\SimpleRouter\RouterBase::getInstance()->reset();
\Pecee\SimpleRouter\SimpleRouter::request()->setUri('/my/test/url');
\Pecee\SimpleRouter\SimpleRouter::request()->setMethod('post');
\Pecee\SimpleRouter\SimpleRouter::post('/my/test/url', 'DummyController@start');
\Pecee\SimpleRouter\SimpleRouter::start();
}
public function testPut() {
\Pecee\SimpleRouter\RouterBase::getInstance()->getRequest()->setUri('/my/test/url');
\Pecee\Http\Request::getInstance()->setMethod('put');
\Pecee\SimpleRouter\RouterBase::getInstance()->reset();
\Pecee\SimpleRouter\SimpleRouter::request()->setUri('/my/test/url');
\Pecee\SimpleRouter\SimpleRouter::request()->setMethod('put');
\Pecee\SimpleRouter\SimpleRouter::put('/my/test/url', 'DummyController@start');
\Pecee\SimpleRouter\SimpleRouter::start();
}
public function testDelete() {
\Pecee\SimpleRouter\RouterBase::getInstance()->getRequest()->setUri('/my/test/url');
\Pecee\Http\Request::getInstance()->setMethod('delete');
\Pecee\SimpleRouter\RouterBase::getInstance()->reset();
\Pecee\SimpleRouter\SimpleRouter::request()->setUri('/my/test/url');
\Pecee\SimpleRouter\SimpleRouter::request()->setMethod('delete');
\Pecee\SimpleRouter\SimpleRouter::delete('/my/test/url', 'DummyController@start');
\Pecee\SimpleRouter\SimpleRouter::start();
@@ -63,8 +66,9 @@ class RouterRouteTest extends PHPUnit_Framework_TestCase {
}
public function testMethodNotAllowed() {
\Pecee\SimpleRouter\RouterBase::getInstance()->getRequest()->setUri('/my/test/url');
\Pecee\Http\Request::getInstance()->setMethod('post');
\Pecee\SimpleRouter\RouterBase::getInstance()->reset();
\Pecee\SimpleRouter\SimpleRouter::request()->setUri('/my/test/url');
\Pecee\SimpleRouter\SimpleRouter::request()->setMethod('post');
\Pecee\SimpleRouter\SimpleRouter::get('/my/test/url', 'DummyController@start');
@@ -78,8 +82,9 @@ class RouterRouteTest extends PHPUnit_Framework_TestCase {
public function testSimpleParam() {
\Pecee\Http\Request::getInstance()->setMethod('get');
\Pecee\Http\Request::getInstance()->setUri('/test-param1');
\Pecee\SimpleRouter\RouterBase::getInstance()->reset();
\Pecee\SimpleRouter\SimpleRouter::request()->setMethod('get');
\Pecee\SimpleRouter\SimpleRouter::request()->setUri('/test-param1');
\Pecee\SimpleRouter\SimpleRouter::get('/test-{param1}', 'DummyController@param');
\Pecee\SimpleRouter\SimpleRouter::start();
@@ -88,20 +93,22 @@ class RouterRouteTest extends PHPUnit_Framework_TestCase {
public function testMultiParam() {
\Pecee\Http\Request::getInstance()->setMethod('get');
\Pecee\Http\Request::getInstance()->setUri('/test-param1-param2');
\Pecee\SimpleRouter\RouterBase::getInstance()->reset();
\Pecee\SimpleRouter\SimpleRouter::request()->setMethod('get');
\Pecee\SimpleRouter\SimpleRouter::request()->setUri('/test-param1-param2');
\Pecee\SimpleRouter\SimpleRouter::get('/test-{param1}-{param2}', 'DummyController@param');
\Pecee\SimpleRouter\SimpleRouter::start();
}
public function testPathParam() {
public function testPathParamRegex() {
\Pecee\Http\Request::getInstance()->setMethod('get');
\Pecee\Http\Request::getInstance()->setUri('/test/path/param1');
\Pecee\SimpleRouter\RouterBase::getInstance()->reset();
\Pecee\SimpleRouter\SimpleRouter::request()->setMethod('get');
\Pecee\SimpleRouter\SimpleRouter::request()->setUri('/test/path/123123');
\Pecee\SimpleRouter\SimpleRouter::get('/test/path/{param}', 'DummyController@param');
\Pecee\SimpleRouter\SimpleRouter::get('/test/path/{myParam}', 'DummyController@param', ['where' => ['myParam' => '([0-9]+)']]);
\Pecee\SimpleRouter\SimpleRouter::start();
}