Compare commits

..

34 Commits

Author SHA1 Message Date
Simon Sessingø baab004482 Merge pull request #145 from skipperbent/v2-development
Added default null parameter value to RouterController and RouterResource
2016-11-17 16:04:38 +02:00
Simon Sessingø eb160ff7bb Added default null parameter value to RouterController and RouterResource 2016-11-17 15:03:18 +01:00
Simon Sessingø 00c0cad211 Merge pull request #143 from skipperbent/v2-development
Bugfix: set parameters to null when new url is set
2016-11-17 15:21:24 +02:00
Simon Sessingø 2db0601e20 - Fixed: set parameters to null when new url is set 2016-11-17 14:20:29 +01:00
Simon Sessingø c6e85676da Merge pull request #141 from skipperbent/v2-development
Bugfixes
2016-11-17 06:37:03 +02:00
Simon Sessingø c59ab12e1a Bugfixes 2016-11-17 05:36:44 +01:00
Simon Sessingø 5a74c9d27d Merge pull request #139 from skipperbent/v2-development
Development
2016-11-17 05:03:30 +02:00
Simon Sessingø b298665d33 Changed demo-project to use v2 router 2016-11-17 04:02:53 +01:00
Simon Sessingø 9ba531d559 Removed uncommented code 2016-11-17 04:00:59 +01:00
Simon Sessingø 73ee4521bc Bugfixes
- Array arguments are now longer automaticially merged.
- Added domain-route parameter unit-test.
2016-11-17 03:50:33 +01:00
Simon Sessingø b5f8d9410f Bugfixes 2016-11-17 03:17:11 +01:00
Simon Sessingø b5eef6f3ee Merge pull request #137 from skipperbent/v2-development
Bugfixes
2016-11-16 16:16:22 +02:00
Simon Sessingø 75566dc2ba Bugfixes 2016-11-16 15:15:51 +01:00
Simon Sessingø ad0eceb814 Merge pull request #135 from skipperbent/v2-development
Bugfixes
2016-11-16 15:32:32 +02:00
Simon Sessingø 8478899eb6 Bugfixes 2016-11-16 14:30:19 +01:00
Simon Sessingø 4bec2bc5fb Merge pull request #133 from skipperbent/v2-development
Csrf bugfixes
2016-11-15 09:46:54 +02:00
Simon Sessingø 93562bd758 Csrf bugfixes 2016-11-15 08:46:14 +01:00
Simon Sessingø 4f47463497 Merge pull request #131 from skipperbent/v2-development
V2 development
2016-11-15 08:13:09 +02:00
Simon Sessingø 9c413a3c53 Bugfixes 2016-11-15 06:38:39 +01:00
Simon Sessingø 669d318a12 Documentation updates 2016-11-15 05:57:58 +01:00
Simon Sessingø 9513e38009 Fixed to unit tests 2016-11-15 05:57:04 +01:00
Simon Sessingø a13bcd4768 Updated demo project + documentation 2016-11-15 05:48:08 +01:00
Simon Sessingø 83c73a4240 Callback, faking route and documentation updates 2016-11-15 05:44:24 +01:00
Simon Sessingø bc14790a67 Updated documentation 2016-11-15 03:55:28 +01:00
Simon Sessingø d5e7a13d89 Development + bugfixes 2016-11-15 03:43:26 +01:00
Simon Sessingø e5c86c1822 Merge pull request #129 from skipperbent/v2-development
Bugfixes
2016-11-15 01:12:41 +02:00
Simon Sessingø 6de0700e17 Bugfixes
- Removed debugging constructor.
- Updated documentation.
2016-11-15 00:11:57 +01:00
Simon Sessingø 32c305bd2c Merge pull request #124 from skipperbent/v2-development
V2 development
2016-11-08 18:22:49 +02:00
Simon Sessingø 28ffa30d3e Development
- all() in Input class now returns correct array.
- all() now supports json data.
- Minor bugfixes.
2016-11-08 18:21:21 +02:00
Simon Sessingø 540ebb31ac Updated documentation 2016-11-07 05:48:02 +01:00
Simon Sessingø 48317ded7a Updated documentation 2016-11-07 05:40:32 +01:00
Simon Sessingø 28c3370b67 Fixed group not adding multiple middlewares 2016-11-07 04:55:43 +01:00
Simon Sessingø 7ee42c98a7 Updated documentaiton 2016-11-07 04:45:18 +01:00
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
31 changed files with 1085 additions and 856 deletions
+138 -59
View File
@@ -18,7 +18,7 @@ The goal of this project is to create a router that is 100% compatible with the
### Features
- Basic routing (get, post, put, delete) with support for custom multiple verbs.
- Basic routing (`GET`, `POST`, `PUT`, `DELETE`) with support for custom multiple verbs.
- Regular Expression Constraints for parameters.
- Named routes.
- Generating url to routes.
@@ -49,13 +49,18 @@ This is an example of a basic ```index.php``` file:
```php
use \Pecee\SimpleRouter\SimpleRouter;
require_once 'routes.php'; // change this to whatever makes sense in your project
// Load external routes file
require_once 'routes.php';
// The apps default namespace (so we don't have to specify it each time we use MyController@home)
$defaultControllerNamespace = 'MyWebsite\\Controller';
/*
* The default namespace for route-callbacks, so we don't have to specify it each time.
* Can be overwritten by using the namespace config option.
*/
SimpleRouter::setDefaultNamespace('MyWebsite\Controller');
// Do the routing
SimpleRouter::start($defaultControllerNamespace);
// Start the routing
SimpleRouter::start();
```
## Adding routes
@@ -81,7 +86,9 @@ use Pecee\SimpleRouter\SimpleRouter;
// Add CSRF support (if needed)
SimpleRouter::csrfVerifier(new \Pecee\Http\Middleware\BaseCsrfVerifier());
SimpleRouter::group(['prefix' => 'v1', 'middleware' => '\MyWebsite\Middleware\SomeMiddlewareClass'], function() {
SimpleRouter::get('/page/404', 'ControllerPage@notFound', ['as' => 'page.notfound']);
SimpleRouter::group(['prefix' => '/v1', 'middleware' => '\MyWebsite\Middleware\SomeMiddlewareClass'], function() {
SimpleRouter::group(['prefix' => '/services', 'exceptionHandler' => '\MyProject\Handler\CustomExceptionHandler'], function() {
@@ -127,7 +134,14 @@ class CustomExceptionHandler implements IExceptionHandler {
// If the error-code is 404; show another route which contains the page-not-found
if($error->getCode() === 404) {
// Load your custom 404-page view
// Throw your custom 404-page view
// - or -
// load another route with our 404 page
// - or -
// you can return the $request object to ignore the error and continue on rendering the route.
return $request->setUri(url('page.notfound'));
}
// Output error as json if on api path.
@@ -190,33 +204,33 @@ use Pecee\SimpleRouter\SimpleRouter;
class Router extends SimpleRouter {
public static function start($defaultNamespace = null) {
public static function start() {
// change this to whatever makes sense in your project
require_once 'routes.php';
// change default namespace for all routes
parent::setDefaultNamespace('\Demo\Controllers');
// Do initial stuff
parent::start('\\Demo\\Controllers');
parent::start();
}
}
```
#### Helper functions examples
**This is a basic example of a helper function for generating urls.**
## Helper functions
To simplify to use of simple-router functionality, we recommend you add these helper functions to your project.
```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 +239,30 @@ 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();
}
/**
* Get input class
* @return \Pecee\Http\Input\Input
*/
function input() {
return SimpleRouter::request()->getInput();
}
```
## Getting urls
@@ -260,7 +298,10 @@ use Pecee\Http\Middleware\BaseCsrfVerifier;
class CsrfVerifier extends BaseCsrfVerifier {
protected $except = ['/companies/*', '/user/save'];
protected $except = [
'/companies/*',
'/api'
];
}
```
@@ -314,62 +355,113 @@ By doing this the route will now load the url ```/article/view/1``` instead of `
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
the ```\Pecee\SimpleRouter\Http\Request``` object.
Sometimes it can be useful to manipulate the route about to be loaded.
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\RouterBase``` instance's `loadedRoute` property.
For easy access you can use the shortcut method `\Pecee\SimpleRouter\SimpleRouter::router()`.
**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::router()->getLoadedRoute();
$route->setCallback('Example\MyCustomClass@hello');
// -- or --
// -- or you can rewrite by doing --
$route->setClass('Example\MyCustomClass');
$route->setMethod('hello');
```
### Examples
It's only possible to change the route BEFORE the route has initially been loaded. If you want to redirect to another route, we highly recommend that you
modify the `RouterEntry` object from a `Middleware` or `ExceptionHandler`, like the examples below.
#### Faking new route
The example below will cause the router to re-route the request with another url. We are using the `url()` helper function to get the uri to another route added in the `routes.php` file.
This does require the `$request` object to be returned, otherwise the `request` object will be ignored by the router.
Using the example below will NOT inherit the rules from the other route. This means that IF you are faking a route that is enabled in `post`.
**NOTE: Use this method if you want to fully load a route (middlewares, request-method etc. will be kept).**
```php
namespace demo\Middlewares;
use Pecee\Http\Middleware\IMiddleware;
use Pecee\Http\Request;
use Pecee\SimpleRouter\RouterEntry;
class CustomMiddleware implements Middleware {
public function handle(Request $request, RouterEntry &$route = null) {
return $request->setUri(url('home'));
}
}
```
#### Changing callback
You can also change the callback by modifying the `$route` parameter. This is perfect if you just want to display a view quickly - or change the callback depending
on some criteria's for the request.
The callback below will fire immediately after the `Middleware` or `ExceptionHandler` has been loaded, as they are loaded before the route is rendered.
If you wish to change the callback from outside, please have this in mind.
**NOTE: Use this method if you want to load another controller. No additional middlewares or rules will be loaded.**
```php
namespace demo\Middlewares;
use Pecee\Http\Middleware\IMiddleware;
use Pecee\Http\Request;
use Pecee\SimpleRouter\RouterEntry;
class CustomMiddleware implements Middleware {
public function handle(Request $request, RouterEntry &$route = null) {
$route->callback('DefaultController@home');
}
}
```
## Using the Input class to manage parameters
We've added the `Input` class to easy access parameters from your Controller-classes.
**Return single parameter value (matches both GET, POST, FILE):**
```php
$value = Request::getInstance()->getInput()->get('name');
$value = input()->get('name');
```
**Return parameter object (matches both GET, POST, FILE):**
```php
$object = Request::getInstance()->getInput()->getObject('name');
$object = input()->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 = input()->get->name;
$object = input()->post->name;
$object = input()->file->name;
```
**Return all parameters:**
```php
// Get all
$objects = Request::getInstance()->getInput()->all();
$values = input()->all();
// Only match certain keys
$objects = Request::getInstance()->getInput()->all([
$values = input()->all([
'company_name',
'user_id'
]);
@@ -389,26 +481,13 @@ All object inherits from `InputItem` class and will always contain these methods
- `getError()` - get file upload error.
### Easy access your input
Create a helper function to easily get access to the input elements.
### Easy access to methods
Example:
```php
/**
* Get input class
* @return \Pecee\Http\Input\Input
*/
function input() {
return \Pecee\Http\Request::getInstance()->getInput();
}
```
Then you can easily do something like this in your controller:
Below example requires you to have the helper functions added. Please refer to the helper functions section in the documentation.
```php
// Get parameter site_id or default-value 2
$value = input()->get('site_id', '2');
$siteId = input()->get('site_id', 2);
```
## Sites
@@ -1,7 +1,7 @@
<?php
namespace Demo\Controllers;
use Pecee\Http\Request;
use Pecee\SimpleRouter\SimpleRouter;
class ApiController {
@@ -9,12 +9,10 @@ class ApiController {
// The variable authenticated is set to true in the ApiVerification middleware class.
$request = Request::getInstance();
header('content-type: application/json');
echo json_encode([
'authenticated' => $request->authenticated
'authenticated' => request()->authenticated
]);
}
@@ -6,7 +6,7 @@ class DefaultController {
public function index() {
// implement
echo 'DefaultController -> index';
echo sprintf('DefaultController -> index (?fun=%s)', input()->get('fun'));
}
@@ -7,7 +7,7 @@ use Pecee\SimpleRouter\RouterEntry;
class CustomExceptionHandler implements IExceptionHandler {
public function handleError( Request $request, RouterEntry $router = null, \Exception $error) {
public function handleError( Request $request, RouterEntry &$route = null, \Exception $error) {
// Return json errors if we encounter an error on /api.
if(stripos($request->getUri(), '/api') !== false) {
@@ -3,10 +3,11 @@ namespace Demo\Middlewares;
use Pecee\Http\Middleware\IMiddleware;
use Pecee\Http\Request;
use Pecee\SimpleRouter\RouterEntry;
class ApiVerification implements IMiddleware {
public function handle(Request $request) {
public function handle(Request $request, RouterEntry &$route = null) {
// Do authentication
$request->authenticated = true;
+7 -3
View File
@@ -13,12 +13,16 @@ 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::setDefaultNamespace('\Demo\Controllers');
parent::start('\\Demo\\Controllers');
// Do initial stuff
parent::start();
}
+39
View File
@@ -0,0 +1,39 @@
<?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();
}
/**
* Get input class
* @return \Pecee\Http\Input\Input
*/
function input() {
return SimpleRouter::request()->getInput();
}
+1 -1
View File
@@ -10,7 +10,7 @@
"type": "project",
"require": {
"php": ">=5.4.0",
"pecee/simple-router": "1.*"
"pecee/simple-router": "2.*"
},
"require-dev": {
+1
View File
@@ -1,3 +1,4 @@
<?php
namespace Pecee\Exception;
class RouterException extends \Exception { }
+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);
}
+1 -1
View File
@@ -25,7 +25,7 @@ class Input {
*/
protected $request;
public function __construct(Request &$request) {
public function __construct(Request $request) {
$this->request = $request;
$this->setGet();
$this->setPost();
+20 -2
View File
@@ -10,9 +10,10 @@ class InputCollection implements \IteratorAggregate {
* Useful for searching for finding items where $index doesn't contain form name.
*
* @param string $index
* @param string|null $defaultValue
* @return mixed
*/
public function findFirst($index) {
public function findFirst($index, $defaultValue = null) {
if(count($this->data)) {
if(isset($this->data[$index])) {
@@ -26,7 +27,24 @@ class InputCollection implements \IteratorAggregate {
}
}
return null;
return $defaultValue;
}
public function getValue($index, $defaultValue = null) {
if(count($this->data)) {
if(isset($this->data[$index])) {
return $this->data[$index]->getValue();
}
foreach($this->data as $key => $value) {
if(strtolower($index) === strtolower($key)) {
return $value->getValue();
}
}
}
return $defaultValue;
}
/**
@@ -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->getValue(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 $route
* @return Request|null
*/
public function handle(Request $request, RouterEntry &$route);
}
+71 -71
View File
@@ -5,45 +5,41 @@ use Pecee\Http\Input\Input;
class Request {
protected static $instance;
protected $data = array();
protected $headers;
protected $host;
protected $uri;
protected $method;
protected $input;
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();
$this->uri = isset($_SERVER['REQUEST_URI']) ? $_SERVER['REQUEST_URI'] : array();
$this->method = (isset($_POST['_method'])) ? strtolower($_POST['_method']) : (isset($_SERVER['REQUEST_METHOD']) ? strtolower($_SERVER['REQUEST_METHOD']) : array());
$this->headers = $this->getAllHeaders();
$this->parseHeaders();
$this->input = new Input($this);
$this->host = $this->getHeader('http_host');;
$this->uri = $this->getHeader('request_uri');
$this->method = strtolower($this->input->post->findFirst('_method', $this->getHeader('request_method')));
}
protected function getAllHeaders() {
$headers = array();
protected function parseHeaders() {
$this->headers = array();
foreach ($_SERVER as $name => $value) {
if (substr($name, 0, 5) === 'HTTP_') {
$headers[strtolower(str_replace('_', '-', substr($name, 5)))] = $value;
}
$this->headers[strtolower($name)] = $value;
}
return $headers;
}
public function getIsSecure() {
if(isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && strtolower($_SERVER['HTTP_X_FORWARDED_PROTO']) === 'https') {
public function isSecure() {
if($this->getHeader('http_x_forwarded_proto') === 'https') {
return true;
}
return isset($_SERVER['HTTPS']) ? true : (isset($_SERVER['SERVER_PORT']) && $_SERVER['SERVER_PORT'] === 443);
if($this->getHeader('https') !== null) {
return true;
}
return ($this->getHeader('server_port') === 443);
}
/**
@@ -72,7 +68,7 @@ class Request {
* @return string|null
*/
public function getUser() {
return (isset($_SERVER['PHP_AUTH_USER'])) ? $_SERVER['PHP_AUTH_USER']: null;
return $this->getHeader('php_auth_user');
}
/**
@@ -80,11 +76,11 @@ class Request {
* @return string|null
*/
public function getPassword() {
return (isset($_SERVER['PHP_AUTH_PW'])) ? $_SERVER['PHP_AUTH_PW']: null;
return $this->getHeader('php_auth_pw');
}
/**
* Get headers
* Get all headers
* @return array
*/
public function getHeaders() {
@@ -96,10 +92,15 @@ class Request {
* @return string
*/
public function getIp() {
if(isset($_SERVER['HTTP_CF_CONNECTING_IP'])) {
return $_SERVER['HTTP_CF_CONNECTING_IP'];
if($this->getHeader('http_cf_connecting_ip') !== null) {
return $this->getHeader('http_cf_connecting_ip');
}
return ((isset($_SERVER['HTTP_X_FORWARDED_FOR']) && strlen($_SERVER['HTTP_X_FORWARDED_FOR'])) ? $_SERVER['HTTP_X_FORWARDED_FOR'] : isset($_SERVER['REMOTE_ADDR']) ? $_SERVER['REMOTE_ADDR'] : null);
if($this->getHeader('http_x_forwarded_for') !== null && strlen($this->getHeader('http_x_forwarded_for'))) {
return $this->getHeader('http_x_forwarded_for');
}
return $this->getHeader('remote_addr');
}
/**
@@ -107,7 +108,7 @@ class Request {
* @return string
*/
public function getReferer() {
return isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : '';
return $this->getHeader('http_referer');
}
/**
@@ -115,16 +116,17 @@ class Request {
* @return string
*/
public function getUserAgent() {
return isset($_SERVER['HTTP_USER_AGENT']) ? $_SERVER['HTTP_USER_AGENT'] : '';
return $this->getHeader('http_user_agent');
}
/**
* Get header value by name
* @param string $name
* @param object|null $defaultValue
* @return string|null
*/
public function getHeader($name) {
return (isset($this->headers[strtolower($name)])) ? $this->headers[strtolower($name)] : null;
public function getHeader($name, $defaultValue = null) {
return isset($this->headers[strtolower($name)]) ? $this->headers[strtolower($name)] : $defaultValue;
}
/**
@@ -135,15 +137,42 @@ class Request {
return $this->input;
}
/**
* Is format accepted
* @param string $format
* @return bool
*/
public function isFormatAccepted($format) {
return (isset($_SERVER['HTTP_ACCEPT']) && stripos($_SERVER['HTTP_ACCEPT'], $format) > -1);
return ($this->getHeader('http_accept') !== null && stripos($this->getHeader('http_accept'), $format) > -1);
}
/**
* Get accept formats
* @return array
*/
public function getAcceptFormats() {
if(isset($_SERVER['HTTP_ACCEPT'])) {
return explode(',', $_SERVER['HTTP_ACCEPT']);
}
return array();
return explode(',', $this->getHeader('http_accept'));
}
/**
* @param string $uri
*/
public function setUri($uri) {
$this->uri = $uri;
}
/**
* @param string $host
*/
public function setHost($host) {
$this->host = $host;
}
/**
* @param string $method
*/
public function setMethod($method) {
$this->method = $method;
}
public function __set($name, $value = null) {
@@ -154,33 +183,4 @@ class Request {
return isset($this->data[$name]) ? $this->data[$name] : null;
}
/**
* Get the currently loaded route.
* @return \Pecee\SimpleRouter\RouterEntry
*/
public function getLoadedRoute() {
return $this->loadedRoute;
}
/**
* @param mixed $uri
*/
public function setUri($uri) {
$this->uri = $uri;
}
/**
* @param mixed $host
*/
public function setHost($host) {
$this->host = $host;
}
/**
* @param mixed $method
*/
public function setMethod($method) {
$this->method = $method;
}
}
+15 -15
View File
@@ -4,11 +4,17 @@ namespace Pecee\Http;
class Response {
protected $request;
public function __construct(Request $request) {
$this->request = $request;
}
/**
* Set the http status code
*
* @param int $code
* @return self $this
* @return static
*/
public function httpCode($code) {
http_response_code($code);
@@ -31,13 +37,13 @@ class Response {
}
public function refresh() {
$this->redirect(Request::getInstance()->getUri());
$this->redirect($this->request->getUri());
}
/**
* Add http authorisation
* @param string $name
* @return self $this
* @return static
*/
public function auth($name = '') {
$this->headers([
@@ -69,25 +75,19 @@ 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();
}
/**
* Add header to response
* @param string $value
* @return self $this
* @return static
*/
public function header($value) {
header($value);
@@ -97,7 +97,7 @@ class Response {
/**
* Add multiple headers to response
* @param array $headers
* @return self $this
* @return static
*/
public function headers(array $headers) {
foreach($headers as $header) {
@@ -0,0 +1,11 @@
<?php
namespace Pecee\SimpleRouter;
interface IControllerRoute {
public function getController();
public function setController($controller);
public function getMethod();
public function setMethod($method);
}
@@ -0,0 +1,9 @@
<?php
namespace Pecee\SimpleRouter;
interface ILoadableRoute {
public function getUrl();
public function setUrl($url);
}
+84
View File
@@ -0,0 +1,84 @@
<?php
namespace Pecee\SimpleRouter;
abstract class LoadableRoute extends RouterEntry implements ILoadableRoute {
const PARAMETERS_REGEX_MATCH = '{([A-Za-z\-\_]*?)\?{0,1}}';
protected $url;
protected $alias;
public function getUrl() {
return $this->url;
}
/**
* Set url
*
* @param string $url
* @return static
*/
public function setUrl($url) {
$this->url = '/' . trim($url, '/') . '/';
if(preg_match_all('/' . static::PARAMETERS_REGEX_MATCH . '/is', $this->url, $matches)) {
if (count($matches[1])) {
foreach ($matches[1] as $key) {
$this->parameters[$key] = null;
}
}
}
return $this;
}
/**
* Get alias for the url which can be used when getting the url route.
* @return string|array
*/
public function getAlias(){
return $this->alias;
}
/**
* Check if route has given alias.
*
* @param string $name
* @return bool
*/
public function hasAlias($name) {
if ($this->getAlias() !== null) {
if (is_array($this->getAlias())) {
foreach ($this->getAlias() as $alias) {
if (strtolower($alias) === strtolower($name)) {
return true;
}
}
}
return strtolower($this->getAlias()) === strtolower($name);
}
return false;
}
/**
* Set the url alias for easier getting the url route.
* @param string|array $alias
* @return static
*/
public function setAlias($alias){
$this->alias = $alias;
return $this;
}
public function setData(array $settings) {
// Change as to alias
if(isset($settings['as'])) {
$this->setAlias($settings['as']);
}
return parent::setData($settings);
}
}
+206 -146
View File
@@ -5,59 +5,137 @@ 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;
/**
* Current request
* @var Request
*/
protected $request;
protected $currentRoute;
/**
* Response
* @var Response
*/
protected $response;
/**
* Used to keep track of whether or not a should should be added to
* the backstack-list for group-processing or not.
* @var bool
*/
protected $processingRoute;
/**
* All added routes
* @var array
*/
protected $routes;
protected $processedRoutes;
/**
* List of
* @var array
*/
protected $controllerUrlMap;
/**
* Backstack array used to keep track of sub-routes
* @var array
*/
protected $backStack;
/**
* The default namespace that all routes will inherit
* @var string
*/
protected $defaultNamespace;
/**
* List of added bootmanagers
* @var array
*/
protected $bootManagers;
protected $baseCsrfVerifier;
/**
* Csrf verifier class
* @var BaseCsrfVerifier
*/
protected $csrfVerifier;
/**
* Get exception handlers
* @var array
*/
protected $exceptionHandlers;
// TODO: clean up - cut some of the methods down to smaller pieces
/**
* The current loaded route
* @var RouterRoute|null
*/
protected $loadedRoute;
/**
* List over route changes (to avoid endless-looping)
* @var array
*/
protected $routeChanges = array();
public function __construct() {
$this->request = Request::getInstance();
$this->reset();
}
public function reset() {
$this->processingRoute = false;
$this->request = new Request();
$this->response = new Response($this->request);
$this->routes = array();
$this->bootManagers = array();
$this->backStack = array();
$this->controllerUrlMap = array();
$this->bootManagers = array();
$this->exceptionHandlers = array();
}
/**
* Add route
* @param RouterEntry $route
* @return RouterEntry
*/
public function addRoute(RouterEntry $route) {
if($this->currentRoute !== null) {
if($this->processingRoute) {
$this->backStack[] = $route;
} else {
$this->routes[] = $route;
}
return $route;
}
protected function processRoutes(array $routes, array $settings = array(), array $prefixes = array(), $backStack = false, $group = null) {
protected function processRoutes(array $routes, array $settings = array(), array $prefixes = array(), RouterEntry $parent = null) {
// Loop through each route-request
$routesCount = count($routes);
$mergedSettings = array();
/* @var $route RouterEntry */
for($i = 0; $i < $routesCount; $i++) {
for($i = 0; $i < count($routes); $i++) {
$route = $routes[$i];
$route->addSettings($settings);
$route->setData($settings);
if($backStack) {
$route->setGroup($group);
if($parent !== null) {
if($parent instanceof RouterGroup) {
if ($parent->getPrefix() !== null && trim($parent->getPrefix(), '/') !== '') {
$prefixes[] = trim($parent->getPrefix(), '/');
}
}
$route->setParent($parent);
}
if($this->defaultNamespace && !$route->getNamespace()) {
if($route->getNamespace() === null && $this->defaultNamespace !== null) {
$namespace = $this->defaultNamespace;
if ($route->getNamespace()) {
$namespace .= '\\' . $route->getNamespace();
@@ -66,60 +144,45 @@ class RouterBase {
$route->setNamespace($namespace);
}
$newPrefixes = $prefixes;
if($route->getPrefix() && trim($route->getPrefix(), '/') !== '') {
array_push($newPrefixes, trim($route->getPrefix(), '/'));
}
/* @var $group RouterGroup */
$group = null;
if(!($route instanceof RouterGroup)) {
if(is_array($newPrefixes) && count($newPrefixes) && $backStack) {
$route->setUrl( '/' . join('/', $newPrefixes) . $route->getUrl() );
}
if($route instanceof ILoadableRoute) {
$route->setUrl( trim(join('/', $prefixes) . $route->getUrl(), '/') );
$this->controllerUrlMap[] = $route;
}
} elseif($route instanceof RouterGroup) {
$this->currentRoute = $route;
if ($route->getCallback() !== null && is_callable($route->getCallback())) {
$this->processingRoute = true;
$route->renderRoute($this->request);
$this->processingRoute = false;
if($route instanceof RouterGroup && is_callable($route->getCallback())) {
if ($route->matchRoute($this->request)) {
$route->renderRoute($this->request);
$settings = array_merge($settings, $route->getMergeableData());
if($route->matchRoute($this->request)) {
$group = $route;
$mergedSettings = array_merge($settings, $group->getMergeableSettings());
// Add ExceptionHandler
if ($group->getExceptionHandler() !== null) {
$this->exceptionHandlers[] = $route;
// Add ExceptionHandler
if (count($route->getExceptionHandlers())) {
$this->exceptionHandlers = array_merge($this->exceptionHandlers, $route->getExceptionHandlers());
}
}
}
}
$this->currentRoute = null;
if(count($this->backStack)) {
$backStack = $this->backStack;
$this->backStack = array();
// Route any routes added to the backstack
$this->processRoutes($backStack, $mergedSettings, $newPrefixes, true, $group);
$this->processRoutes($backStack, $settings, $prefixes, $route);
}
$prefixes = [];
}
}
public function routeRequest($original = true) {
$originalUri = $this->request->getUri();
public function routeRequest(Request $newRequest = null) {
$this->loadedRoute = null;
$routeNotAllowed = false;
try {
@@ -136,26 +199,24 @@ class RouterBase {
}
}
// Loop through each route-request
$this->processRoutes($this->routes);
if($newRequest === null) {
if($original === true) {
// Verify csrf token for request
if ($this->baseCsrfVerifier !== null) {
$this->baseCsrfVerifier->handle($this->request);
// Loop through each route-request
$this->processRoutes($this->routes);
if($this->csrfVerifier !== null) {
// Verify csrf token for request
$this->csrfVerifier->handle($this->request);
}
}
$max = count($this->controllerUrlMap);
/* @var $route RouterEntry */
for ($i = 0; $i < $max; $i++) {
for ($i = 0; $i < count($this->controllerUrlMap); $i++) {
$route = $this->controllerUrlMap[$i];
$routeMatch = $route->matchRoute($this->request);
if ($routeMatch) {
if ($route->matchRoute($this->request)) {
if (count($route->getRequestMethods()) && !in_array($this->request->getMethod(), $route->getRequestMethods())) {
$routeNotAllowed = true;
@@ -164,13 +225,18 @@ class RouterBase {
$routeNotAllowed = false;
$this->request->rewrite_uri = $this->request->uri;
$this->request->setUri($originalUri);
$this->loadedRoute = $route;
$this->request->loadedRoute = $route;
$route->loadMiddleware($this->request);
$request = clone $this->request;
$this->loadedRoute->loadMiddleware($request, $this->loadedRoute);
$this->request->loadedRoute->renderRoute($this->request);
if($request->getUri() !== $this->request->getUri() && !in_array($request->getUri(), $this->routeChanges)) {
$this->routeChanges[] = $request->getUri();
$this->routeRequest($request);
return;
}
$this->loadedRoute->renderRoute($this->request);
break;
}
@@ -184,38 +250,35 @@ class RouterBase {
$this->handleException(new RouterException('Route or method not allowed', 403));
}
if(!$this->request->loadedRoute) {
if($this->loadedRoute === null) {
$this->handleException(new RouterException(sprintf('Route not found: %s', $this->request->getUri()), 404));
}
}
protected function handleException(\Exception $e) {
$request = null;
/* @var $route RouterGroup */
foreach ($this->exceptionHandlers as $route) {
$route->loadMiddleware($this->request);
$handler = $route->getExceptionHandler();
/* @var $handler IExceptionHandler */
foreach ($this->exceptionHandlers as $handler) {
$handler = new $handler();
if (!($handler instanceof IExceptionHandler)) {
throw new RouterException('Exception handler must implement the IExceptionHandler interface.');
}
$request = $handler->handleError($this->request, $this->request->loadedRoute, $e);
}
$request = $handler->handleError($this->request, $this->loadedRoute, $e);
if($request !== null && !in_array($request->getUri(), $this->routeChanges)) {
$this->routeChanges[] = $request->getUri();
$this->routeRequest($request);
}
if($request !== null) {
$this->request = $request;
$this->routeRequest(false);
return;
}
throw $e;
}
/**
* Get default namespace
* @return string
*/
public function getDefaultNamespace(){
@@ -223,6 +286,7 @@ class RouterBase {
}
/**
* Set the main default namespace that all routes will inherit
* @param string $defaultNamespace
* @return static
*/
@@ -232,6 +296,7 @@ class RouterBase {
}
/**
* Get bootmanagers
* @return array
*/
public function getBootManagers() {
@@ -239,40 +304,21 @@ class RouterBase {
}
/**
* Set bootmanagers
* @param array $bootManagers
*/
public function setBootManagers(array $bootManagers) {
$this->bootManagers = $bootManagers;
}
/**
* Add bootmanager
* @param RouterBootManager $bootManager
*/
public function addBootManager(RouterBootManager $bootManager) {
$this->bootManagers[] = $bootManager;
}
/**
* @return RouterEntry
*/
public function getLoadedRoute() {
if(!($this->request->loadedRoute instanceof RouterGroup)) {
return $this->request->loadedRoute;
}
return null;
}
/**
* @return array
*/
public function getBackstack() {
return $this->backStack;
}
/**
* @return RouterEntry
*/
public function getCurrentRoute(){
return $this->currentRoute;
}
/**
* @return array
*/
@@ -290,21 +336,29 @@ class RouterBase {
}
/**
* Get base csrf verifier class
* @return BaseCsrfVerifier
* Get response
* @return Response
*/
public function getBaseCsrfVerifier() {
return $this->baseCsrfVerifier;
public function getResponse() {
return $this->response;
}
/**
* Set base csrf verifier class
*
* @param BaseCsrfVerifier $baseCsrfVerifier
* @return self
* Get csrf verifier class
* @return BaseCsrfVerifier
*/
public function setBaseCsrfVerifier(BaseCsrfVerifier $baseCsrfVerifier) {
$this->baseCsrfVerifier = $baseCsrfVerifier;
public function getCsrfVerifier() {
return $this->csrfVerifier;
}
/**
* Set csrf verifier class
*
* @param BaseCsrfVerifier $csrfVerifier
* @return static
*/
public function setCsrfVerifier(BaseCsrfVerifier $csrfVerifier) {
$this->csrfVerifier = $csrfVerifier;
return $this;
}
@@ -327,38 +381,31 @@ class RouterBase {
$domain = '';
if($route->getGroup() !== null && $route->getGroup()->getDomain() !== null) {
if(is_array($route->getGroup()->getDomain())) {
$domains = $route->getGroup()->getDomain();
$domain = array_shift($domains);
} else {
$domain = $route->getGroup()->getDomain();
}
$parent = $route->getParent();
$domain = '//' . $domain;
if($parent !== null && $parent instanceof RouterGroup && count($parent->getDomains())) {
$domain = $parent->getDomains();
$domain = '//' . $domain[0];
}
$url = $domain . '/' . trim($route->getUrl(), '/');
if(($route instanceof RouterController || $route instanceof RouterResource) && $method !== null) {
if($route instanceof IControllerRoute && $method !== null) {
$url .= $method;
}
if($route instanceof RouterController || $route instanceof RouterResource) {
if(count($parameters)) {
$url .= join('/', $parameters);
}
} else {
/* @var $route RouterEntry */
if(is_array($parameters)) {
if($parameters !== null && is_array($parameters)) {
$params = array_merge($route->getParameters(), $parameters);
} else {
$params = $route->getParameters();
}
$otherParams = [];
$otherParams = array();
$i = 0;
foreach($params as $param => $value) {
$value = (isset($parameters[$param])) ? $parameters[$param] : $value;
if(stripos($url, '{' . $param. '}') !== false || stripos($url, '{' . $param . '?}') !== false) {
@@ -393,7 +440,7 @@ class RouterBase {
// Return current route if no options has been specified
if($controller === null && $parameters === null) {
$getParams = (is_array($getParams)) ? array_merge($_GET, $getParams) : $_GET;
$getParams = ($getParams !== null && is_array($getParams)) ? array_merge($_GET, $getParams) : $_GET;
$url = parse_url($this->request->getUri(), PHP_URL_PATH);
@@ -404,13 +451,12 @@ 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 = '';
$method = null;
$max = count($this->controllerUrlMap);
/* @var $route RouterRoute */
@@ -419,14 +465,25 @@ 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 LoadableRoute) {
// Check for alias
if ($route->hasAlias($controller)) {
return $this->processUrl($route, $route->getMethod(), $parameters, $getParams);
}
// Use controller name
if($route instanceof RouterController) {
$c = $route->getController();
} else {
// Use callback if it's not a function
if (stripos($route->getCallback(), '@') !== false && !is_callable($route->getCallback())) {
$c = $route->getCallback();
}
}
if($route instanceof RouterRoute && !is_callable($route->getCallback()) && stripos($route->getCallback(), '@') !== false) {
$c = $route->getCallback();
} else if($route instanceof RouterController || $route instanceof RouterResource) {
$c = $route->getController();
}
if($c === $controller || strpos($c, $controller) === 0) {
@@ -441,10 +498,10 @@ class RouterBase {
$route = $this->controllerUrlMap[$i];
if($route instanceof RouterRoute && !is_callable($route->getCallback()) && stripos($route->getCallback(), '@') !== false) {
$c = $route->getClass();
} else if($route instanceof RouterController || $route instanceof RouterResource) {
if($route instanceof IControllerRoute) {
$c = $route->getController();
} else if(!is_callable($route->getCallback()) && stripos($route->getCallback(), '@') !== false) {
$c = $route->getClass();
}
if(stripos($controller, '@') !== false) {
@@ -461,10 +518,8 @@ class RouterBase {
$controller = ($controller === null) ? '/' : $controller;
$url = array($controller);
if(is_array($parameters)) {
foreach($parameters as $key => $value) {
array_push($url,$value);
}
if($parameters !== null && is_array($parameters) && count($parameters)) {
$url = array_merge($url, $parameters);
}
$url = '/' . trim(join('/', $url), '/') . '/';
@@ -476,10 +531,15 @@ class RouterBase {
return $url;
}
/**
* Get current router instance
* @return static
*/
public static function getInstance() {
if(static::$instance === null) {
static::$instance = new static();
}
return static::$instance;
}
+6 -25
View File
@@ -4,22 +4,20 @@ namespace Pecee\SimpleRouter;
use Pecee\Exception\RouterException;
use Pecee\Http\Request;
class RouterController extends RouterEntry {
class RouterController extends LoadableRoute implements IControllerRoute {
const DEFAULT_METHOD = 'index';
protected $url;
protected $controller;
protected $method;
public function __construct($url, $controller) {
parent::__construct();
$this->url = $url;
$this->setUrl($url);
$this->controller = $controller;
}
public function renderRoute(Request $request) {
if(is_object($this->getCallback()) && is_callable($this->getCallback())) {
if($this->getCallback() !== null && is_callable($this->getCallback())) {
// When the callback is a function
call_user_func_array($this->getCallback(), $this->getParameters());
@@ -44,8 +42,8 @@ class RouterController extends RouterEntry {
}
public function matchRoute(Request $request) {
$url = parse_url(urldecode($request->getUri()));
$url = rtrim($url['path'], '/') . '/';
$url = parse_url(urldecode($request->getUri()), PHP_URL_PATH);
$url = rtrim($url, '/') . '/';
if(strtolower($url) == strtolower($this->url) || stripos($url, $this->url) === 0) {
@@ -55,7 +53,7 @@ class RouterController extends RouterEntry {
if(count($path)) {
$method = (!isset($path[0]) || trim($path[0]) === '') ? self::DEFAULT_METHOD : $path[0];
$method = (!isset($path[0]) || trim($path[0]) === '') ? static::DEFAULT_METHOD : $path[0];
$this->method = $method;
array_shift($path);
@@ -70,23 +68,6 @@ class RouterController extends RouterEntry {
return null;
}
/**
* @return string
*/
public function getUrl() {
return $this->url;
}
/**
* @param string $url
* @return static
*/
public function setUrl($url) {
$url = rtrim($url, '/') . '/';
$this->url = $url;
return $this;
}
/**
* @return string
*/
+234 -263
View File
@@ -8,238 +8,31 @@ use Pecee\Http\Request;
abstract class RouterEntry {
const REQUEST_TYPE_POST = 'post';
const REQUEST_TYPE_GET = 'get';
const REQUEST_TYPE_POST = 'post';
const REQUEST_TYPE_PUT = 'put';
const REQUEST_TYPE_PATCH = 'patch';
const REQUEST_TYPE_OPTIONS = 'options';
const REQUEST_TYPE_DELETE = 'delete';
public static $allowedRequestTypes = array(
self::REQUEST_TYPE_DELETE,
public static $allowedRequestTypes = [
self::REQUEST_TYPE_GET,
self::REQUEST_TYPE_POST,
self::REQUEST_TYPE_PUT,
self::REQUEST_TYPE_PATCH
);
self::REQUEST_TYPE_PATCH,
self::REQUEST_TYPE_OPTIONS,
self::REQUEST_TYPE_DELETE,
];
protected $settings;
protected $parent;
protected $callback;
public function __construct() {
$this->settings = array();
$this->settings['requestMethods'] = array();
$this->settings['where'] = array();
$this->settings['parameters'] = array();
}
/**
* Returns callback name/identifier for the current route based on the callback.
* Useful if you need to get a unique identifier for the loaded route, for instance
* when using translations etc.
*
* @return string
*/
public function getIdentifier() {
if(strpos($this->callback, '@') !== false) {
return $this->callback;
}
return 'function_' . md5($this->callback);
}
/**
* @param string $callback
* @return self;
*/
public function setCallback($callback) {
$this->callback = $callback;
return $this;
}
/**
* @return mixed
*/
public function getCallback() {
return $this->callback;
}
public function getMethod() {
if(strpos($this->callback, '@') !== false) {
$tmp = explode('@', $this->callback);
return $tmp[1];
}
return null;
}
public function getClass() {
if(strpos($this->callback, '@') !== false) {
$tmp = explode('@', $this->callback);
return $tmp[0];
}
return null;
}
public function setMethod($method) {
$this->callback = sprintf('%s@%s', $this->getClass(), $method);
return $this;
}
public function setClass($class) {
$this->callback = sprintf('%s@%s', $class, $this->getMethod());
return $this;
}
/**
* @param string $prefix
* @return self
*/
public function setPrefix($prefix) {
$this->prefix = '/' . ltrim($prefix, '/');
return $this;
}
/**
* @param string $middleware
* @return self
*/
public function setMiddleware($middleware) {
$this->middleware = $middleware;
return $this;
}
/**
* @param string $namespace
* @return self
*/
public function setNamespace($namespace) {
$this->namespace = $namespace;
return $this;
}
/**
* @return string
*/
public function getPrefix() {
return $this->prefix;
}
/**
* @return string|array
*/
public function getMiddleware() {
return $this->middleware;
}
/**
* @return string
*/
public function getNamespace() {
return $this->namespace;
}
/**
* @return array
*/
public function getSettings() {
return $this->settings;
}
/**
* @return mixed
*/
public function getParameters(){
return ($this->parameters === null) ? array() : $this->parameters;
}
/**
* @param mixed $parameters
* @return self
*/
public function setParameters($parameters) {
$this->parameters = $parameters;
return $this;
}
/**
* Add regular expression parameter match
*
* @param array $options
* @return self
*/
public function where(array $options) {
$this->where = array_merge($this->where, $options);
return $this;
}
/**
* Add regular expression match for url
*
* @param string $regex
* @return self
*/
public function match($regex) {
$this->regexMatch = $regex;
return $this;
}
/**
* Get settings that are allowed to be inherited by child routes.
*
* @return array
*/
public function getMergeableSettings() {
$settings = $this->settings;
if(isset($settings['prefix'])) {
unset($settings['prefix']);
}
return $settings;
}
/**
* @param array $settings
* @return self
*/
public function addSettings(array $settings = null) {
if(is_array($settings)) {
$this->settings = array_merge($this->settings, $settings);
}
return $this;
}
/**
* @param array $settings
* @return self
*/
public function setSettings($settings) {
$this->settings = $settings;
if(isset($settings['prefix'])) {
$this->setPrefix($settings['prefix']);
}
return $this;
}
/**
* Dynamically access settings value
*
* @param $name
* @return mixed|null
*/
public function __get($name) {
return (isset($this->settings[$name]) ? $this->settings[$name] : null);
}
/**
* Dynamically set settings value
*
* @param string $name
* @param mixed|null $value
*/
public function __set($name, $value = null) {
$this->settings[$name] = $value;
}
protected $namespace;
protected $regex;
protected $requestMethods = array();
protected $where = array();
protected $parameters = array();
protected $middlewares = array();
protected function loadClass($name) {
if(!class_exists($name)) {
@@ -284,7 +77,12 @@ abstract class RouterEntry {
} else {
$regex .= '\/?(?P<' . $parameter . '>'. $parameterRegex .')[^\/]?';
}
$parameterNames[] = array('name' => $parameter, 'required' => $required);
$parameterNames[] = [
'name' => $parameter,
'required' => $required
];
$parameter = '';
$isParameter = false;
@@ -307,21 +105,19 @@ abstract class RouterEntry {
$max = count($parameterNames);
if($max) {
for($i = 0; $i < $max; $i++) {
$name = $parameterNames[$i];
$parameterValue = isset($parameterValues[$name['name']]) ? $parameterValues[$name['name']] : null;
for($i = 0; $i < $max; $i++) {
$name = $parameterNames[$i];
$parameterValue = isset($parameterValues[$name['name']]) ? $parameterValues[$name['name']] : null;
if($name['required'] && $parameterValue === null) {
throw new RouterException('Missing required parameter ' . $name['name'], 404);
}
if(!$name['required'] && $parameterValue === null) {
continue;
}
$parameters[$name['name']] = $parameterValue;
if($name['required'] && $parameterValue === null) {
throw new RouterException('Missing required parameter ' . $name['name'], 404);
}
if(!$name['required'] && $parameterValue === null) {
continue;
}
$parameters[$name['name']] = $parameterValue;
}
return $parameters;
@@ -330,32 +126,22 @@ abstract class RouterEntry {
return null;
}
public function loadMiddleware(Request $request) {
if($this->getMiddleware()) {
if(is_array($this->getMiddleware())) {
foreach($this->getMiddleware() as $middleware) {
$middleware = $this->loadClass($middleware);
if (!($middleware instanceof IMiddleware)) {
throw new RouterException($middleware . ' must be instance of Middleware');
}
/* @var $class IMiddleware */
$middleware->handle($request);
}
} else {
$middleware = $this->loadClass($this->getMiddleware());
public function loadMiddleware(Request $request, RouterEntry &$route) {
if(count($this->getMiddlewares())) {
foreach($this->getMiddlewares() as $middleware) {
$middleware = $this->loadClass($middleware);
if (!($middleware instanceof IMiddleware)) {
throw new RouterException($this->getMiddleware() . ' must be instance of Middleware');
throw new RouterException($middleware . ' must be instance of Middleware');
}
/* @var $class IMiddleware */
$middleware->handle($request);
$middleware->handle($request, $route);
}
}
}
public function renderRoute(Request $request) {
if(is_object($this->getCallback()) && is_callable($this->getCallback())) {
if($this->getCallback() !== null && is_callable($this->getCallback())) {
// When the callback is a function
call_user_func_array($this->getCallback(), $this->getParameters());
} else {
@@ -371,7 +157,7 @@ abstract class RouterEntry {
}
$parameters = array_filter($this->getParameters(), function($var){
return !is_null($var);
return ($var !== null);
});
call_user_func_array(array($class, $method), $parameters);
@@ -386,10 +172,10 @@ abstract class RouterEntry {
* Set allowed request methods
*
* @param array $methods
* @return self $this
* @return static $this
*/
public function setRequestMethods(array $methods) {
$this->settings['requestMethods'] = $methods;
$this->requestMethods = $methods;
return $this;
}
@@ -399,19 +185,204 @@ abstract class RouterEntry {
* @return array
*/
public function getRequestMethods() {
if(!isset($this->settings['requestMethods']) || isset($this->settings['requestMethods']) && !is_array($this->settings['requestMethods'])) {
$value = isset($this->settings['requestMethods']) ? $this->settings['requestMethods'] : null;
return array($value);
return $this->requestMethods;
}
/**
* @return RouterEntry
*/
public function getParent() {
return $this->parent;
}
/**
* Set parent route
* @param RouterEntry $parent
* @return static $this
*/
public function setParent(RouterEntry $parent) {
$this->parent = $parent;
return $this;
}
/**
* @param string $callback
* @return static
*/
public function setCallback($callback) {
$this->callback = $callback;
return $this;
}
/**
* @return mixed
*/
public function getCallback() {
return $this->callback;
}
public function getMethod() {
if(strpos($this->callback, '@') !== false) {
$tmp = explode('@', $this->callback);
return $tmp[1];
}
return $this->settings['requestMethods'];
return null;
}
public function getGroup() {
return $this->group;
public function getClass() {
if(strpos($this->callback, '@') !== false) {
$tmp = explode('@', $this->callback);
return $tmp[0];
}
return null;
}
public function setGroup($group) {
$this->group = $group;
public function setMethod($method) {
$this->callback = sprintf('%s@%s', $this->getClass(), $method);
return $this;
}
public function setClass($class) {
$this->callback = sprintf('%s@%s', $class, $this->getMethod());
return $this;
}
/**
* @param string $middleware
* @return static
*/
public function setMiddleware($middleware) {
$this->middlewares[] = $middleware;
return $this;
}
public function setMiddlewares(array $middlewares) {
$this->middlewares = $middlewares;
return $this;
}
/**
* @param string $namespace
* @return static
*/
public function setNamespace($namespace) {
$this->namespace = $namespace;
return $this;
}
/**
* @return string|array
*/
public function getMiddlewares() {
return $this->middlewares;
}
/**
* @return string
*/
public function getNamespace() {
return $this->namespace;
}
/**
* @return array
*/
public function getParameters(){
return $this->parameters;
}
/**
* @param mixed $parameters
* @return static
*/
public function setParameters($parameters) {
$this->parameters = $parameters;
return $this;
}
/**
* Add regular expression parameter match
*
* @param array $options
* @return static
*/
public function where(array $options) {
$this->where = $options;
return $this;
}
/**
* Add regular expression match for url
*
* @param string $regex
* @return static
*/
public function match($regex) {
$this->regex = $regex;
return $this;
}
/**
* Get arguments that can be inherited by child routes.
*
* @return array
*/
public function getMergeableData() {
$output = array();
if($this->namespace !== null) {
$output['namespace'] = $this->namespace;
}
if(count($this->middlewares)) {
$output['middleware'] = $this->middlewares;
}
if(count($this->where)) {
$output['where'] = $this->where;
}
if(count($this->requestMethods)) {
$output['method'] = $this->requestMethods;
}
if(count($this->parameters)) {
$output['parameters'] = $this->parameters;
}
return $output;
}
/**
* Set arguments/data by array
*
* @param array $settings
* @return static
*/
public function setData(array $settings) {
if (isset($settings['namespace']) && $this->namespace === null) {
$this->setNamespace($settings['namespace']);
}
// Push middleware if multiple
if (isset($settings['middleware'])) {
$this->middlewares = array_merge((array)$settings['middleware'], $this->middlewares);
}
if(isset($settings['method'])) {
$this->setRequestMethods((array)$settings['method']);
}
if(isset($settings['where'])) {
$this->where($settings['where']);
}
if(isset($settings['parameters'])) {
$this->setParameters($settings['parameters']);
}
return $this;
}
+52 -78
View File
@@ -2,37 +2,25 @@
namespace Pecee\SimpleRouter;
use Pecee\Exception\RouterException;
use Pecee\Http\Request;
class RouterGroup extends RouterEntry {
protected $prefix;
protected $domains = array();
protected $exceptionHandlers = array();
public function matchDomain(Request $request) {
if($this->domain !== null) {
if(count($this->domains)) {
for($i = 0; $i < count($this->domains); $i++) {
$domain = $this->domains[$i];
if(is_array($this->domain)) {
$parameters = $this->parseParameters($domain, $request->getHost(), '.*');
$max = count($this->domain);
for($i = 0; $i < $max; $i++) {
$domain = $this->domain[$i];
$parameters = $this->parseParameters($domain, $request->getHost(), '[^.]*');
if($parameters !== null) {
$this->parameters = $parameters;
return true;
}
if($parameters !== null) {
$this->parameters = $parameters;
return true;
}
return false;
}
$parameters = $this->parseParameters($this->domain, $request->getHost(), '[^.]*');
if ($parameters !== null) {
$this->parameters = $parameters;
return true;
}
return false;
@@ -41,79 +29,65 @@ class RouterGroup extends RouterEntry {
return true;
}
public function renderRoute(Request $request) {
// Check if request method is allowed
$hasAccess = (!$this->method);
if($this->method) {
if(is_array($this->method)) {
$hasAccess = (in_array($request->getMethod(), $this->getRequestMethods()));
} else {
$hasAccess = strtolower($this->getRequestMethods()) == strtolower($request->getMethod());
}
}
if(!$hasAccess) {
throw new RouterException('Method not allowed');
}
$this->matchDomain($request);
return parent::renderRoute($request);
}
public function matchRoute(Request $request) {
// Skip if prefix doesn't match
if($this->getPrefix() !== null && stripos($request->getUri(), $this->getPrefix()) === false) {
if($this->prefix !== null && stripos($request->getUri(), $this->prefix) === false) {
return false;
}
return $this->matchDomain($request);
}
public function setExceptionHandler($class) {
$this->exceptionHandler = $class;
public function setExceptionHandlers(array $handlers) {
$this->exceptionHandlers = $handlers;
return $this;
}
public function getExceptionHandler() {
return $this->exceptionHandler;
public function getExceptionHandlers() {
return $this->exceptionHandlers;
}
public function getDomain() {
return $this->domain;
public function getDomains() {
return $this->domains;
}
public function setDomains(array $domains) {
$this->domains = $domains;
return $this;
}
/**
* @param array $settings
* @return self
* @param string $prefix
* @return static
*/
public function addSettings(array $settings = null) {
if($this->getNamespace() !== null && isset($settings['namespace'])) {
unset($settings['namespace']);
}
// Push middleware if multiple
if($this->getMiddleware() !== null && isset($settings['middleware'])) {
if(!is_array($this->getMiddleware())) {
$middlewares = [
$this->getMiddleware(),
$settings['middleware']
];
} else {
$middlewares = array_push($settings['middleware'], $this->getMiddleware());
}
$settings['middleware'] = array_unique(array_reverse($middlewares));
}
if(is_array($settings)) {
$this->settings = array_merge($this->settings, $settings);
}
public function setPrefix($prefix) {
$this->prefix = '/' . trim($prefix, '/');
return $this;
}
/**
* @return string
*/
public function getPrefix() {
return $this->prefix;
}
public function setData(array $settings) {
if(isset($settings['prefix'])) {
$this->setPrefix($settings['prefix']);
}
if(isset($settings['exceptionHandler'])) {
$this->setExceptionHandlers((array)$settings['exceptionHandler']);
}
if(isset($settings['domain'])) {
$this->setDomains((array)$settings['domain']);
}
return parent::setData($settings);
}
}
+11 -32
View File
@@ -4,21 +4,17 @@ namespace Pecee\SimpleRouter;
use Pecee\Exception\RouterException;
use Pecee\Http\Request;
class RouterResource extends RouterEntry {
class RouterResource extends LoadableRoute implements IControllerRoute {
protected $url;
protected $controller;
protected $postMethod;
public function __construct($url, $controller) {
parent::__construct();
$this->url = $url;
$this->setUrl($url);
$this->controller = $controller;
$this->postMethod = strtolower(($_SERVER['REQUEST_METHOD'] != 'GET') ? 'post' : 'get');
}
public function renderRoute(Request $request) {
if(is_object($this->getCallback()) && is_callable($this->getCallback())) {
if($this->getCallback() !== null && is_callable($this->getCallback())) {
// When the callback is a function
call_user_func_array($this->getCallback(), $this->getParameters());
} else {
@@ -47,8 +43,8 @@ class RouterResource extends RouterEntry {
}
public function matchRoute(Request $request) {
$url = parse_url(urldecode($request->getUri()));
$url = rtrim($url['path'], '/') . '/';
$url = parse_url(urldecode($request->getUri()), PHP_URL_PATH);
$url = rtrim($url, '/') . '/';
$route = rtrim($this->url, '/') . '/{id?}/{action?}';
@@ -64,32 +60,32 @@ class RouterResource extends RouterEntry {
unset($parameters['action']);
// Delete
if($request->getMethod() === self::REQUEST_TYPE_DELETE && $this->postMethod === self::REQUEST_TYPE_POST) {
if($request->getMethod() === static::REQUEST_TYPE_DELETE && $request->getMethod() === static::REQUEST_TYPE_POST) {
return $this->call('destroy', $parameters);
}
// Update
if(in_array($request->getMethod(), array(self::REQUEST_TYPE_PATCH, self::REQUEST_TYPE_PUT)) && $this->postMethod === self::REQUEST_TYPE_POST) {
if(in_array($request->getMethod(), array(static::REQUEST_TYPE_PATCH, static::REQUEST_TYPE_PUT)) && $request->getMethod() === static::REQUEST_TYPE_POST) {
return $this->call('update', $parameters);
}
// Edit
if(isset($action) && strtolower($action) === 'edit' && $this->postMethod === self::REQUEST_TYPE_GET) {
if(isset($action) && strtolower($action) === 'edit' && $request->getMethod() === static::REQUEST_TYPE_GET) {
return $this->call('edit', $parameters);
}
// Create
if(strtolower($action) === 'create' && $request->getMethod() === self::REQUEST_TYPE_GET) {
if(strtolower($action) === 'create' && $request->getMethod() === static::REQUEST_TYPE_GET) {
return $this->call('create', $parameters);
}
// Save
if($this->postMethod === self::REQUEST_TYPE_POST) {
if($request->getMethod() === static::REQUEST_TYPE_POST) {
return $this->call('store', $parameters);
}
// Show
if(isset($parameters['id']) && $this->postMethod === self::REQUEST_TYPE_GET) {
if(isset($parameters['id']) && $request->getMethod() === static::REQUEST_TYPE_GET) {
return $this->call('show', $parameters);
}
@@ -100,23 +96,6 @@ class RouterResource extends RouterEntry {
return null;
}
/**
* @return string
*/
public function getUrl() {
return $this->url;
}
/**
* @param string $url
* @return static
*/
public function setUrl($url) {
$url = rtrim($url, '/') . '/';
$this->url = $url;
return $this;
}
/**
* @return string
*/
+6 -96
View File
@@ -4,27 +4,22 @@ namespace Pecee\SimpleRouter;
use Pecee\Http\Request;
class RouterRoute extends RouterEntry {
const PARAMETERS_REGEX_MATCH = '{([A-Za-z\-\_]*?)\?{0,1}}';
protected $url;
class RouterRoute extends LoadableRoute {
public function __construct($url, $callback) {
parent::__construct();
$this->setUrl($url);
$this->setCallback($callback);
}
public function matchRoute(Request $request) {
$url = parse_url(urldecode($request->getUri()));
$url = rtrim($url['path'], '/') . '/';
$url = parse_url(urldecode($request->getUri()), PHP_URL_PATH);
$url = rtrim($url, '/') . '/';
// Match on custom defined regular expression
if($this->regexMatch) {
if($this->regex !== null) {
$parameters = array();
if(preg_match('/('.$this->regexMatch.')/is', $request->getHost() . $url, $parameters)) {
if(preg_match('/(' . $this->regex . ')/is', $request->getHost() . $url, $parameters)) {
$this->parameters = (!is_array($parameters[0]) ? array($parameters[0]) : $parameters[0]);
return true;
}
@@ -37,96 +32,11 @@ class RouterRoute extends RouterEntry {
$parameters = $this->parseParameters($route, $url);
if($parameters !== null) {
if(is_array($this->parameters)) {
$this->parameters = array_merge($this->parameters, $parameters);
} else {
$this->parameters = $parameters;
}
$this->parameters = array_merge($this->parameters, $parameters);
return true;
}
return null;
}
/**
* @return string
*/
public function getUrl() {
return $this->url;
}
/**
* @param string $url
* @return self
*/
public function setUrl($url) {
$parameters = array();
$matches = array();
if(preg_match_all('/'.self::PARAMETERS_REGEX_MATCH.'/is', $url, $matches)) {
$parameters = $matches[1];
}
if(count($parameters)) {
$tmp = array();
foreach($parameters as $param) {
$tmp[$param] = null;
}
$this->parameters = $tmp;
}
$this->url = $url;
return $this;
}
/**
* Get alias for the url which can be used when getting the url route.
* @return string|array
*/
public function getAlias(){
return $this->alias;
}
/**
* Check if route has given alias.
*
* @param $name
* @return bool
*/
public function hasAlias($name) {
if(is_array($this->alias)) {
foreach($this->alias as $alias) {
if(strtolower($alias) === strtolower($name)) {
return true;
}
}
} else {
return strtolower($this->getAlias()) === strtolower($name);
}
return false;
}
/**
* Set the url alias for easier getting the url route.
* @param string|array $alias
* @return self
*/
public function setAlias($alias){
$this->alias = $alias;
return $this;
}
public function setSettings($settings) {
// Change as to alias
if(isset($settings{'as'})) {
$this->setAlias($settings['as']);
}
return parent::setSettings($settings);
}
}
+43 -16
View File
@@ -15,11 +15,18 @@ class SimpleRouter {
/**
* Start/route request
* @param null $defaultNamespace
* @throws \Pecee\Exception\RouterException
*/
public static function start($defaultNamespace = null) {
RouterBase::getInstance()->setDefaultNamespace($defaultNamespace)->routeRequest();
public static function start() {
RouterBase::getInstance()->routeRequest();
}
/**
* Set default namespace for all routes
* @param string $defaultNamespace
*/
public static function setDefaultNamespace($defaultNamespace) {
RouterBase::getInstance()->setDefaultNamespace($defaultNamespace);
}
/**
@@ -27,7 +34,7 @@ class SimpleRouter {
* @param BaseCsrfVerifier $baseCsrfVerifier
*/
public static function csrfVerifier(BaseCsrfVerifier $baseCsrfVerifier) {
RouterBase::getInstance()->setBaseCsrfVerifier($baseCsrfVerifier);
RouterBase::getInstance()->setCsrfVerifier($baseCsrfVerifier);
}
public static function addBootManager(RouterBootManager $bootManager) {
@@ -35,19 +42,27 @@ class SimpleRouter {
}
public static function get($url, $callback, array $settings = null) {
return self::match(['get'], $url, $callback, $settings);
return static::match(['get'], $url, $callback, $settings);
}
public static function post($url, $callback, array $settings = null) {
return self::match(['post'], $url, $callback, $settings);
return static::match(['post'], $url, $callback, $settings);
}
public static function put($url, $callback, array $settings = null) {
return self::match(['put'], $url, $callback, $settings);
return static::match(['put'], $url, $callback, $settings);
}
public static function patch($url, $callback, array $settings = null) {
return static::match(['patch'], $url, $callback, $settings);
}
public static function options($url, $callback, array $settings = null) {
return static::match(['options'], $url, $callback, $settings);
}
public static function delete($url, $callback, array $settings = null) {
return self::match(['delete'], $url, $callback, $settings);
return static::match(['delete'], $url, $callback, $settings);
}
public static function group($settings = array(), $callback) {
@@ -55,7 +70,7 @@ class SimpleRouter {
$group->setCallback($callback);
if($settings !== null && is_array($settings)) {
$group->setSettings($settings);
$group->setData($settings);
}
RouterBase::getInstance()->addRoute($group);
@@ -72,7 +87,7 @@ class SimpleRouter {
* @return RouterRoute
*/
public static function basic($url, $callback, array $settings = null) {
return self::match(['get', 'post'], $url, $callback, $settings);
return static::match(['get', 'post'], $url, $callback, $settings);
}
public static function match(array $requestMethods, $url, $callback, array $settings = null) {
@@ -80,7 +95,7 @@ class SimpleRouter {
$route->setRequestMethods($requestMethods);
if($settings !== null) {
$route->addSettings($settings);
$route->setData($settings);
}
RouterBase::getInstance()->addRoute($route);
@@ -92,7 +107,7 @@ class SimpleRouter {
$route = new RouterRoute($url, $callback);
if($settings !== null) {
$route->addSettings($settings);
$route->setData($settings);
}
RouterBase::getInstance()->addRoute($route);
@@ -104,7 +119,7 @@ class SimpleRouter {
$route = new RouterController($url, $controller);
if($settings !== null) {
$route->addSettings($settings);
$route->setData($settings);
}
RouterBase::getInstance()->addRoute($route);
@@ -116,16 +131,28 @@ class SimpleRouter {
$route = new RouterResource($url, $controller);
if($settings !== null) {
$route->addSettings($settings);
$route->setData($settings);
}
RouterBase::getInstance()->addRoute($route);
static::router()->addRoute($route);
return $route;
}
public static function getRoute($controller = null, $parameters = null, $getParams = null) {
return RouterBase::getInstance()->getRoute($controller, $parameters, $getParams);
return static::router()->getRoute($controller, $parameters, $getParams);
}
public static function request() {
return static::router()->getRequest();
}
public static function response() {
return static::router()->getResponse();
}
protected static function router() {
return RouterBase::getInstance();
}
}
+1 -1
View File
@@ -7,7 +7,7 @@ use Pecee\Http\Request;
class DummyMiddleware implements IMiddleware {
public function handle(Request $request) {
public function handle(Request $request, \Pecee\SimpleRouter\RouterEntry &$route = null) {
throw new MiddlewareLoadedException('Middleware loaded!');
}
+1 -1
View File
@@ -1,7 +1,7 @@
<?php
class ExceptionHandler implements \Pecee\Handler\IExceptionHandler {
public function handleError(\Pecee\Http\Request $request, \Pecee\SimpleRouter\RouterEntry $router = null, \Exception $error){
public function handleError(\Pecee\Http\Request $request, \Pecee\SimpleRouter\RouterEntry &$route = null, \Exception $error){
throw $error;
}
+47 -9
View File
@@ -7,20 +7,18 @@ class GroupTest extends PHPUnit_Framework_TestCase {
protected $result;
protected function group() {
$this->result = true;
}
public function testGroup() {
public function testGroupLoad() {
$this->result = false;
\Pecee\SimpleRouter\SimpleRouter::group(['prefix' => '/group'], $this->group());
\Pecee\SimpleRouter\SimpleRouter::group(['prefix' => '/group'], function() {
$this->result = true;
});
try {
\Pecee\SimpleRouter\SimpleRouter::start();
} catch(Exception $e) {
// ignore RouteNotFound exception
}
$this->assertTrue($this->result);
@@ -28,8 +26,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() {
@@ -40,4 +39,43 @@ class GroupTest extends PHPUnit_Framework_TestCase {
\Pecee\SimpleRouter\SimpleRouter::start();
}
public function testManyRoutes() {
\Pecee\SimpleRouter\RouterBase::getInstance()->reset();
\Pecee\SimpleRouter\SimpleRouter::request()->setUri('/my/match');
\Pecee\SimpleRouter\SimpleRouter::request()->setMethod('get');
\Pecee\SimpleRouter\SimpleRouter::group(['prefix' => '/api'], function() {
\Pecee\SimpleRouter\SimpleRouter::group(['prefix' => '/v1'], function() {
\Pecee\SimpleRouter\SimpleRouter::get('/test', 'DummyController@start');
});
});
\Pecee\SimpleRouter\SimpleRouter::get('/my/match', 'DummyController@start');
\Pecee\SimpleRouter\SimpleRouter::group(['prefix' => '/service'], function() {
\Pecee\SimpleRouter\SimpleRouter::group(['prefix' => '/v1'], function() {
\Pecee\SimpleRouter\SimpleRouter::get('/no-match', 'DummyController@start');
});
});
\Pecee\SimpleRouter\SimpleRouter::start();
}
public function testUrls() {
\Pecee\SimpleRouter\RouterBase::getInstance()->reset();
\Pecee\SimpleRouter\SimpleRouter::request()->setUri('/my/fancy/url/1');
\Pecee\SimpleRouter\SimpleRouter::request()->setMethod('get');
\Pecee\SimpleRouter\SimpleRouter::get('/my/fancy/url/1', 'DummyController@start', ['as' => 'fancy1']);
\Pecee\SimpleRouter\SimpleRouter::get('/my/fancy/url/2', 'DummyController@start')->setAlias('fancy2');
\Pecee\SimpleRouter\SimpleRouter::start();
$this->assertTrue((\Pecee\SimpleRouter\SimpleRouter::getRoute('fancy1') === '/my/fancy/url/1/'));
$this->assertTrue((\Pecee\SimpleRouter\SimpleRouter::getRoute('fancy2') === '/my/fancy/url/2/'));
}
}
+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']);
+52 -23
View File
@@ -5,12 +5,13 @@ require_once 'Dummy/DummyController.php';
require_once 'Dummy/Handler/ExceptionHandler.php';
class RouterRouteTest extends PHPUnit_Framework_TestCase {
protected $result = false;
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 +30,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 +67,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 +83,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,22 +94,45 @@ 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();
}
public function testDomainRoute() {
\Pecee\SimpleRouter\RouterBase::getInstance()->reset();
\Pecee\SimpleRouter\SimpleRouter::request()->setMethod('get');
\Pecee\SimpleRouter\SimpleRouter::request()->setUri('/test');
\Pecee\SimpleRouter\SimpleRouter::request()->setHost('hello.world.com');
$this->result = false;
\Pecee\SimpleRouter\SimpleRouter::group(['domain' => '{subdomain}.world.com'], function() {
\Pecee\SimpleRouter\SimpleRouter::get('test', function($subdomain = null) {
$this->result = ($subdomain === 'hello');
});
});
\Pecee\SimpleRouter\SimpleRouter::start();
$this->assertTrue($this->result);
}
}