Compare commits

..

52 Commits

Author SHA1 Message Date
Simon Sessingø 4975f24fee Merge pull request #285 from skipperbent/v1-development
Added \JsonSerializable interface to Response->json (issue: #284).
2017-08-31 13:05:26 +02:00
Simon Sessingø 2952f6a3b6 Added \JsonSerializable interface to Response->json (issue: #284). 2017-08-31 11:59:58 +01:00
Simon Sessingø da7348ea82 Merge pull request #127 from skipperbent/v1-development
Development
2016-11-08 18:21:41 +02:00
Simon Sessingø 16e326ad9f Development
- all() in Input class now returns correct array.
- all() now supports json data.
- Minor bugfixes.
2016-11-08 18:16:17 +02:00
Simon Sessingø 0002b45d18 Merge pull request #123 from skipperbent/v1-development
Fixed RouterGroup not pushing multiple middlewares properly
2016-11-07 04:57:30 +01:00
Simon Sessingø d9b2328e82 Fixed RouterGroup not pushing multiple middlewares properly 2016-11-07 04:56:47 +01:00
Simon Sessingø 4a03005c68 Merge pull request #122 from skipperbent/development
Fixed urls in groups not working
2016-11-06 09:04:56 +01:00
Simon Sessingø 52034411cf Merge pull request #121 from skipperbent/development
Development
2016-11-06 08:14:36 +01:00
Simon Sessingø 4c8ed5bb3d Merge pull request #120 from skipperbent/development
Development
2016-11-05 23:09:19 +01:00
Simon Sessingø 9fed6ffb3f Merge pull request #119 from skipperbent/development
Optimised for cli-usage
2016-10-28 07:41:21 +02:00
Simon Sessingø 15da599e82 Merge pull request #118 from skipperbent/development
Minor optimisations
2016-10-27 19:15:59 +02:00
Simon Sessingø 9274acb591 Merge pull request #117 from skipperbent/development
Optimisations and bugfixes
2016-10-27 17:06:24 +02:00
Simon Sessingø 5c7759ab72 Merge pull request #116 from skipperbent/development
Development
2016-10-27 16:45:29 +02:00
Simon Sessingø c7b8593185 Merge pull request #114 from skipperbent/development
Development
2016-10-20 08:38:23 +02:00
Simon Sessingø fb478f475c Merge pull request #113 from skipperbent/development
Development
2016-10-20 08:35:20 +02:00
Simon Sessingø 1142d9d4ce Merge pull request #112 from skipperbent/development
Optimised middleware load order
2016-09-28 12:30:06 +02:00
Simon Sessingø 5d5c96e802 Merge pull request #111 from skipperbent/development
Automatically push middlewares if multiple in nested group.
2016-09-28 12:24:38 +02:00
Simon Sessingø bfdaf8ac52 Merge pull request #110 from skipperbent/development
Updated documentation and added demo-project.
2016-09-26 14:39:50 +02:00
Simon Sessingø 71dc6e172f Merge pull request #108 from skipperbent/development
Allow for default parameters (including A-Z, a-z, 0-9 and "-") when p…
2016-06-14 22:21:20 +02:00
Simon Sessingø 6ee172927f Merge pull request #107 from skipperbent/development
Bugfix
2016-06-04 18:44:59 +02:00
Simon Sessingø bb5e629199 Merge pull request #106 from skipperbent/development
Development
2016-06-04 18:21:16 +02:00
Simon Sessingø 0cc0a59fd5 Merge pull request #105 from skipperbent/development
Development
2016-06-04 15:13:47 +02:00
Simon Sessingø 498fd6b07d Merge pull request #103 from skipperbent/development
Added setValue method to InputItem class.
2016-05-04 13:41:36 +02:00
Simon Sessingø 96ab22a4f8 Merge pull request #102 from skipperbent/development
Added exist method to Input class.
2016-05-03 07:21:16 +02:00
Simon Sessingø 7f528c133b Merge pull request #101 from skipperbent/development
Development
2016-05-01 02:01:47 +02:00
Simon Sessingø 5a50190293 Merge pull request #100 from skipperbent/development
Development
2016-04-25 00:41:50 +02:00
Simon Sessingø 355ef01d63 Merge pull request #99 from skipperbent/development
Development
2016-04-22 15:38:02 +02:00
Simon Sessingø d3162b5a2b Merge pull request #98 from skipperbent/development
Development
2016-04-22 14:30:40 +02:00
Simon Sessingø 810b80487d Merge pull request #97 from skipperbent/development
- Added custom ExceptionHandler example to documentation.
2016-04-21 08:30:34 +02:00
Simon Sessingø 18a9df56ca Merge pull request #96 from skipperbent/development
Development
2016-04-20 08:10:18 +02:00
Simon Sessingø 6e14ded03f Merge pull request #95 from skipperbent/development
Development
2016-04-16 23:23:56 +02:00
Simon Sessingø 899081f8d8 Merge pull request #94 from skipperbent/development
Update README.md
2016-04-16 00:01:22 +02:00
Simon Sessingø e7b9206bc9 Merge pull request #93 from skipperbent/development
Development
2016-04-15 23:21:00 +02:00
Simon Sessingø cd6e800984 Merge pull request #91 from skipperbent/development
Development
2016-04-15 23:14:55 +02:00
Simon Sessingø 11bd5a7d11 Merge pull request #89 from skipperbent/development
[BUGFIX] Fixed notice
2016-04-09 15:39:12 +02:00
Simon Sessingø be32796b01 Merge pull request #88 from skipperbent/development
[TASK] Moved group-middleware rendering to routeRequest to ensure all…
2016-04-09 15:32:45 +02:00
Simon Sessingø 8b3d71a328 Merge pull request #87 from skipperbent/development
[BUGFIX] Fixed only match group route if prefix is set
2016-04-09 10:02:22 +02:00
Simon Sessingø 1fae638aaf Merge pull request #86 from skipperbent/development
Development
2016-04-09 09:50:56 +02:00
Simon Sessingø 37c8bc9f32 Merge pull request #79 from skipperbent/development
[BUGFIX] Bugfixes and optimisations
2016-04-07 23:21:13 +02:00
Simon Sessingø 75029b330a Merge pull request #78 from skipperbent/development
[BUGFIX] Fixed nested groups not merging settings to routes
2016-04-07 19:34:02 +02:00
Simon Sessingø fd5d893040 Merge pull request #77 from skipperbent/development
[TASK] Added rewrite_uri parameter to Request class
2016-03-19 19:12:42 +01:00
Simon Sessingø c1512740af Merge pull request #76 from skipperbent/development
[BUGFIX] Readded rendering of groups
2016-03-19 18:59:01 +01:00
Simon Sessingø 212ae133de Merge pull request #75 from skipperbent/development
[TASK] Readded merging
2016-03-19 17:40:26 +01:00
Simon Sessingø ae58231fa1 Merge pull request #74 from skipperbent/development
Custom boot-managers
2016-03-19 16:29:03 +01:00
Simon Sessingø 358b25d4f1 Merge pull request #73 from skipperbent/development
Development
2016-03-18 17:55:31 +01:00
Simon Sessingø 3d45851d9b Merge pull request #72 from skipperbent/development
[BUGFIX] Only render group if prefix matches.
2016-03-16 19:58:03 +01:00
Simon Sessingø ee5c2207f8 Merge pull request #71 from skipperbent/development
Added support for x-forwarded-proto http header
2016-03-14 01:08:25 +01:00
Simon Sessingø b1ca3fc9ef Merge pull request #70 from skipperbent/development
[FEATURE] Added http code to redirect method.
2016-03-14 00:59:09 +01:00
Simon Sessingø 253c0c70d4 Merge pull request #69 from skipperbent/development
[BUGFIX] Bugfix
2016-03-01 22:52:38 +01:00
Simon Sessingø 53ba2d7ac5 Merge pull request #68 from skipperbent/development
[TASK] Fixed regex causing optional parameters to sometimes catch req…
2016-01-23 16:12:27 +01:00
Simon Sessingø 315fe05769 Merge pull request #67 from skipperbent/development
Development
2016-01-17 04:57:39 +01:00
Simon Sessingø a57113309a Merge pull request #66 from skipperbent/development
Development
2016-01-15 11:56:04 +01:00
31 changed files with 854 additions and 1085 deletions
+61 -140
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,18 +49,13 @@ This is an example of a basic ```index.php``` file:
```php
use \Pecee\SimpleRouter\SimpleRouter;
// Load external routes file
require_once 'routes.php';
require_once 'routes.php'; // change this to whatever makes sense in your project
/*
* 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');
// The apps default namespace (so we don't have to specify it each time we use MyController@home)
$defaultControllerNamespace = 'MyWebsite\\Controller';
// Start the routing
SimpleRouter::start();
// Do the routing
SimpleRouter::start($defaultControllerNamespace);
```
## Adding routes
@@ -86,9 +81,7 @@ use Pecee\SimpleRouter\SimpleRouter;
// Add CSRF support (if needed)
SimpleRouter::csrfVerifier(new \Pecee\Http\Middleware\BaseCsrfVerifier());
SimpleRouter::get('/page/404', 'ControllerPage@notFound', ['as' => 'page.notfound']);
SimpleRouter::group(['prefix' => '/v1', 'middleware' => '\MyWebsite\Middleware\SomeMiddlewareClass'], function() {
SimpleRouter::group(['prefix' => 'v1', 'middleware' => '\MyWebsite\Middleware\SomeMiddlewareClass'], function() {
SimpleRouter::group(['prefix' => '/services', 'exceptionHandler' => '\MyProject\Handler\CustomExceptionHandler'], function() {
@@ -134,14 +127,7 @@ class CustomExceptionHandler implements IExceptionHandler {
// If the error-code is 404; show another route which contains the page-not-found
if($error->getCode() === 404) {
// 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'));
// Load your custom 404-page view
}
// Output error as json if on api path.
@@ -204,33 +190,33 @@ use Pecee\SimpleRouter\SimpleRouter;
class Router extends SimpleRouter {
public static function start() {
public static function start($defaultNamespace = null) {
// 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();
parent::start('\\Demo\\Controllers');
}
}
```
## Helper functions
To simplify to use of simple-router functionality, we recommend you add these helper functions to your project.
#### Helper functions examples
**This is a basic example of a helper function for generating urls.**
```php
use Pecee\SimpleRouter\SimpleRouter;
use Pecee\SimpleRouter\RouterBase;
function url($controller, $parameters = null, $getParams = null) {
SimpleRouter::getRoute($controller, $parameters, $getParams);
RouterBase::getInstance()->getRoute($controller, $parameters, $getParams);
}
```
**This is a basic example for getting the current csrf token**
```php
/**
* Get current csrf-token
* @return null|string
@@ -239,30 +225,6 @@ 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
@@ -298,10 +260,7 @@ use Pecee\Http\Middleware\BaseCsrfVerifier;
class CsrfVerifier extends BaseCsrfVerifier {
protected $except = [
'/companies/*',
'/api'
];
protected $except = ['/companies/*', '/user/save'];
}
```
@@ -355,113 +314,62 @@ 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.
## Easily overwrite route about to be loaded
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()`.
**routes.php example:**
```php
use Pecee\SimpleRouter;
$route = SimpleRouter::router()->getLoadedRoute();
// 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.
**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();
$route->setCallback('Example\MyCustomClass@hello');
// -- or you can rewrite by doing --
// -- or --
$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 = input()->get('name');
$value = Request::getInstance()->getInput()->get('name');
```
**Return parameter object (matches both GET, POST, FILE):**
```php
$object = input()->getObject('name');
$object = Request::getInstance()->getInput()->getObject('name');
```
**Return specific GET parameter (where name is the name of your parameter):**
```php
$object = input()->get->name;
$object = input()->post->name;
$object = input()->file->name;
$object = Request::getInstance()->getInput()->get->name;
$object = Request::getInstance()->getInput()->post->name;
$object = Request::getInstance()->getInput()->file->name;
```
**Return all parameters:**
```php
// Get all
$values = input()->all();
$objects = Request::getInstance()->getInput()->all();
// Only match certain keys
$values = input()->all([
$objects = Request::getInstance()->getInput()->all([
'company_name',
'user_id'
]);
@@ -481,13 +389,26 @@ All object inherits from `InputItem` class and will always contain these methods
- `getError()` - get file upload error.
### Easy access to methods
### Easy access your input
Create a helper function to easily get access to the input elements.
Below example requires you to have the helper functions added. Please refer to the helper functions section in the documentation.
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:
```php
// Get parameter site_id or default-value 2
$siteId = input()->get('site_id', 2);
$value = input()->get('site_id', '2');
```
## Sites
@@ -1,7 +1,7 @@
<?php
namespace Demo\Controllers;
use Pecee\SimpleRouter\SimpleRouter;
use Pecee\Http\Request;
class ApiController {
@@ -9,10 +9,12 @@ 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 sprintf('DefaultController -> index (?fun=%s)', input()->get('fun'));
echo 'DefaultController -> index';
}
@@ -7,7 +7,7 @@ use Pecee\SimpleRouter\RouterEntry;
class CustomExceptionHandler implements IExceptionHandler {
public function handleError( Request $request, RouterEntry &$route = null, \Exception $error) {
public function handleError( Request $request, RouterEntry $router = null, \Exception $error) {
// Return json errors if we encounter an error on /api.
if(stripos($request->getUri(), '/api') !== false) {
@@ -3,11 +3,10 @@ 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, RouterEntry &$route = null) {
public function handle(Request $request) {
// Do authentication
$request->authenticated = true;
+3 -7
View File
@@ -13,16 +13,12 @@ class Router extends SimpleRouter {
public static function start($defaultNamespace = null) {
// Load our helpers
require_once 'helpers.php';
// Load our custom routes
// change this to whatever makes sense in your project
require_once 'routes.php';
parent::setDefaultNamespace('\Demo\Controllers');
// Do initial stuff
parent::start();
parent::start('\\Demo\\Controllers');
}
-39
View File
@@ -1,39 +0,0 @@
<?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": "2.*"
"pecee/simple-router": "1.*"
},
"require-dev": {
-1
View File
@@ -1,4 +1,3 @@
<?php
namespace Pecee\Exception;
class RouterException extends \Exception { }
+1 -7
View File
@@ -6,12 +6,6 @@ use Pecee\SimpleRouter\RouterEntry;
interface IExceptionHandler {
/**
* @param Request $request
* @param RouterEntry|null $route
* @param \Exception $error
* @return Request|null
*/
public function handleError(Request $request, RouterEntry &$route = null, \Exception $error);
public function handleError(Request $request, RouterEntry $router = 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();
+2 -20
View File
@@ -10,10 +10,9 @@ 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, $defaultValue = null) {
public function findFirst($index) {
if(count($this->data)) {
if(isset($this->data[$index])) {
@@ -27,24 +26,7 @@ class InputCollection implements \IteratorAggregate {
}
}
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;
return null;
}
/**
@@ -4,7 +4,6 @@ namespace Pecee\Http\Middleware;
use Pecee\CsrfToken;
use Pecee\Exception\TokenMismatchException;
use Pecee\Http\Request;
use Pecee\SimpleRouter\RouterEntry;
class BaseCsrfVerifier implements IMiddleware {
@@ -50,11 +49,11 @@ class BaseCsrfVerifier implements IMiddleware {
return false;
}
public function handle(Request $request, RouterEntry &$route = null) {
public function handle(Request $request) {
if($request->getMethod() !== 'get' && !$this->skip($request)) {
if($request->getMethod() != 'get' && !$this->skip($request)) {
$token = $request->getInput()->post->getValue(static::POST_KEY);
$token = (isset($_POST[static::POST_KEY])) ? $_POST[static::POST_KEY] : null;
// If the token is not posted, check headers for valid x-csrf-token
if($token === null) {
+1 -9
View File
@@ -2,15 +2,7 @@
namespace Pecee\Http\Middleware;
use Pecee\Http\Request;
use Pecee\SimpleRouter\RouterEntry;
interface IMiddleware {
/**
* @param Request $request
* @param RouterEntry $route
* @return Request|null
*/
public function handle(Request $request, RouterEntry &$route);
public function handle(Request $request);
}
+71 -71
View File
@@ -5,41 +5,45 @@ use Pecee\Http\Input\Input;
class Request {
protected $data = array();
protected $headers;
protected $host;
protected $uri;
protected $method;
protected $input;
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->parseHeaders();
$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->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 parseHeaders() {
$this->headers = array();
protected function getAllHeaders() {
$headers = array();
foreach ($_SERVER as $name => $value) {
$this->headers[strtolower($name)] = $value;
if (substr($name, 0, 5) === 'HTTP_') {
$headers[strtolower(str_replace('_', '-', substr($name, 5)))] = $value;
}
}
return $headers;
}
public function isSecure() {
if($this->getHeader('http_x_forwarded_proto') === 'https') {
public function getIsSecure() {
if(isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && strtolower($_SERVER['HTTP_X_FORWARDED_PROTO']) === 'https') {
return true;
}
if($this->getHeader('https') !== null) {
return true;
}
return ($this->getHeader('server_port') === 443);
return isset($_SERVER['HTTPS']) ? true : (isset($_SERVER['SERVER_PORT']) && $_SERVER['SERVER_PORT'] === 443);
}
/**
@@ -68,7 +72,7 @@ class Request {
* @return string|null
*/
public function getUser() {
return $this->getHeader('php_auth_user');
return (isset($_SERVER['PHP_AUTH_USER'])) ? $_SERVER['PHP_AUTH_USER']: null;
}
/**
@@ -76,11 +80,11 @@ class Request {
* @return string|null
*/
public function getPassword() {
return $this->getHeader('php_auth_pw');
return (isset($_SERVER['PHP_AUTH_PW'])) ? $_SERVER['PHP_AUTH_PW']: null;
}
/**
* Get all headers
* Get headers
* @return array
*/
public function getHeaders() {
@@ -92,15 +96,10 @@ class Request {
* @return string
*/
public function getIp() {
if($this->getHeader('http_cf_connecting_ip') !== null) {
return $this->getHeader('http_cf_connecting_ip');
if(isset($_SERVER['HTTP_CF_CONNECTING_IP'])) {
return $_SERVER['HTTP_CF_CONNECTING_IP'];
}
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');
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);
}
/**
@@ -108,7 +107,7 @@ class Request {
* @return string
*/
public function getReferer() {
return $this->getHeader('http_referer');
return isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : '';
}
/**
@@ -116,17 +115,16 @@ class Request {
* @return string
*/
public function getUserAgent() {
return $this->getHeader('http_user_agent');
return isset($_SERVER['HTTP_USER_AGENT']) ? $_SERVER['HTTP_USER_AGENT'] : '';
}
/**
* Get header value by name
* @param string $name
* @param object|null $defaultValue
* @return string|null
*/
public function getHeader($name, $defaultValue = null) {
return isset($this->headers[strtolower($name)]) ? $this->headers[strtolower($name)] : $defaultValue;
public function getHeader($name) {
return (isset($this->headers[strtolower($name)])) ? $this->headers[strtolower($name)] : null;
}
/**
@@ -137,42 +135,15 @@ class Request {
return $this->input;
}
/**
* Is format accepted
* @param string $format
* @return bool
*/
public function isFormatAccepted($format) {
return ($this->getHeader('http_accept') !== null && stripos($this->getHeader('http_accept'), $format) > -1);
return (isset($_SERVER['HTTP_ACCEPT']) && stripos($_SERVER['HTTP_ACCEPT'], $format) > -1);
}
/**
* Get accept formats
* @return array
*/
public function getAcceptFormats() {
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;
if(isset($_SERVER['HTTP_ACCEPT'])) {
return explode(',', $_SERVER['HTTP_ACCEPT']);
}
return array();
}
public function __set($name, $value = null) {
@@ -183,4 +154,33 @@ 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,17 +4,11 @@ namespace Pecee\Http;
class Response {
protected $request;
public function __construct(Request $request) {
$this->request = $request;
}
/**
* Set the http status code
*
* @param int $code
* @return static
* @return self $this
*/
public function httpCode($code) {
http_response_code($code);
@@ -37,13 +31,13 @@ class Response {
}
public function refresh() {
$this->redirect($this->request->getUri());
$this->redirect(Request::getInstance()->getUri());
}
/**
* Add http authorisation
* @param string $name
* @return static
* @return self $this
*/
public function auth($name = '') {
$this->headers([
@@ -75,19 +69,25 @@ class Response {
}
/**
* Json encode array
* @param array $value
* Json encode
* @param array|\JsonSerializable $value
* @throws \InvalidArgumentException;
*/
public function json(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.');
}
$this->header('Content-type: application/json');
echo json_encode($value);
die();
exit(0);
}
/**
* Add header to response
* @param string $value
* @return static
* @return self $this
*/
public function header($value) {
header($value);
@@ -97,7 +97,7 @@ class Response {
/**
* Add multiple headers to response
* @param array $headers
* @return static
* @return self $this
*/
public function headers(array $headers) {
foreach($headers as $header) {
@@ -1,11 +0,0 @@
<?php
namespace Pecee\SimpleRouter;
interface IControllerRoute {
public function getController();
public function setController($controller);
public function getMethod();
public function setMethod($method);
}
@@ -1,9 +0,0 @@
<?php
namespace Pecee\SimpleRouter;
interface ILoadableRoute {
public function getUrl();
public function setUrl($url);
}
-86
View File
@@ -1,86 +0,0 @@
<?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 (array_keys($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);
}
}
+144 -204
View File
@@ -5,137 +5,59 @@ 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;
/**
* 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 $currentRoute;
protected $routes;
/**
* List of
* @var array
*/
protected $processedRoutes;
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;
/**
* Csrf verifier class
* @var BaseCsrfVerifier
*/
protected $csrfVerifier;
/**
* Get exception handlers
* @var array
*/
protected $baseCsrfVerifier;
protected $exceptionHandlers;
/**
* The current loaded route
* @var RouterRoute|null
*/
protected $loadedRoute;
/**
* List over route changes (to avoid endless-looping)
* @var array
*/
protected $routeChanges = array();
// TODO: clean up - cut some of the methods down to smaller pieces
public function __construct() {
$this->reset();
}
public function reset() {
$this->processingRoute = false;
$this->request = new Request();
$this->response = new Response($this->request);
$this->request = Request::getInstance();
$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->processingRoute) {
if($this->currentRoute !== null) {
$this->backStack[] = $route;
} else {
$this->routes[] = $route;
}
return $route;
}
protected function processRoutes(array $routes, array $settings = array(), array $prefixes = array(), RouterEntry $parent = null) {
protected function processRoutes(array $routes, array $settings = array(), array $prefixes = array(), $backStack = false, $group = null) {
// Loop through each route-request
$routesCount = count($routes);
$mergedSettings = array();
/* @var $route RouterEntry */
for($i = 0; $i < count($routes); $i++) {
for($i = 0; $i < $routesCount; $i++) {
$route = $routes[$i];
$route->setData($settings);
$route->addSettings($settings);
if($parent !== null) {
if($parent instanceof RouterGroup) {
if ($parent->getPrefix() !== null && trim($parent->getPrefix(), '/') !== '') {
$prefixes[] = trim($parent->getPrefix(), '/');
}
}
$route->setParent($parent);
if($backStack) {
$route->setGroup($group);
}
if($route->getNamespace() === null && $this->defaultNamespace !== null) {
if($this->defaultNamespace && !$route->getNamespace()) {
$namespace = $this->defaultNamespace;
if ($route->getNamespace()) {
$namespace .= '\\' . $route->getNamespace();
@@ -144,45 +66,60 @@ class RouterBase {
$route->setNamespace($namespace);
}
if($route instanceof ILoadableRoute) {
$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() );
}
$route->setUrl( trim(join('/', $prefixes) . $route->getUrl(), '/') );
$this->controllerUrlMap[] = $route;
} elseif($route instanceof RouterGroup) {
}
if ($route->getCallback() !== null && is_callable($route->getCallback())) {
$this->processingRoute = true;
$route->renderRoute($this->request);
$this->processingRoute = false;
$this->currentRoute = $route;
if ($route->matchRoute($this->request)) {
if($route instanceof RouterGroup && is_callable($route->getCallback())) {
$settings = array_merge($settings, $route->getMergeableData());
$route->renderRoute($this->request);
// Add ExceptionHandler
if (count($route->getExceptionHandlers())) {
$this->exceptionHandlers = array_merge($this->exceptionHandlers, $route->getExceptionHandlers());
}
if($route->matchRoute($this->request)) {
$group = $route;
$mergedSettings = array_merge($settings, $group->getMergeableSettings());
// Add ExceptionHandler
if ($group->getExceptionHandler() !== null) {
$this->exceptionHandlers[] = $route;
}
}
}
$this->currentRoute = null;
if(count($this->backStack)) {
$backStack = $this->backStack;
$this->backStack = array();
// Route any routes added to the backstack
$this->processRoutes($backStack, $settings, $prefixes, $route);
$this->processRoutes($backStack, $mergedSettings, $newPrefixes, true, $group);
}
$prefixes = [];
}
}
public function routeRequest(Request $newRequest = null) {
public function routeRequest($original = true) {
$originalUri = $this->request->getUri();
$this->loadedRoute = null;
$routeNotAllowed = false;
try {
@@ -199,24 +136,26 @@ class RouterBase {
}
}
if($newRequest === null) {
// Loop through each route-request
$this->processRoutes($this->routes);
// Loop through each route-request
$this->processRoutes($this->routes);
if($this->csrfVerifier !== null) {
// Verify csrf token for request
$this->csrfVerifier->handle($this->request);
if($original === true) {
// Verify csrf token for request
if ($this->baseCsrfVerifier !== null) {
$this->baseCsrfVerifier->handle($this->request);
}
}
$max = count($this->controllerUrlMap);
/* @var $route RouterEntry */
for ($i = 0; $i < count($this->controllerUrlMap); $i++) {
for ($i = 0; $i < $max; $i++) {
$route = $this->controllerUrlMap[$i];
if ($route->matchRoute($this->request)) {
$routeMatch = $route->matchRoute($this->request);
if ($routeMatch) {
if (count($route->getRequestMethods()) && !in_array($this->request->getMethod(), $route->getRequestMethods())) {
$routeNotAllowed = true;
@@ -225,18 +164,13 @@ class RouterBase {
$routeNotAllowed = false;
$this->loadedRoute = $route;
$this->request->rewrite_uri = $this->request->uri;
$this->request->setUri($originalUri);
$request = clone $this->request;
$this->loadedRoute->loadMiddleware($request, $this->loadedRoute);
$this->request->loadedRoute = $route;
$route->loadMiddleware($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);
$this->request->loadedRoute->renderRoute($this->request);
break;
}
@@ -250,35 +184,38 @@ class RouterBase {
$this->handleException(new RouterException('Route or method not allowed', 403));
}
if($this->loadedRoute === null) {
if(!$this->request->loadedRoute) {
$this->handleException(new RouterException(sprintf('Route not found: %s', $this->request->getUri()), 404));
}
}
protected function handleException(\Exception $e) {
/* @var $handler IExceptionHandler */
foreach ($this->exceptionHandlers as $handler) {
$request = null;
/* @var $route RouterGroup */
foreach ($this->exceptionHandlers as $route) {
$route->loadMiddleware($this->request);
$handler = $route->getExceptionHandler();
$handler = new $handler();
if (!($handler instanceof IExceptionHandler)) {
throw new RouterException('Exception handler must implement the IExceptionHandler interface.');
}
$request = $handler->handleError($this->request, $this->loadedRoute, $e);
if($request !== null && !in_array($request->getUri(), $this->routeChanges)) {
$this->routeChanges[] = $request->getUri();
$this->routeRequest($request);
}
$request = $handler->handleError($this->request, $this->request->loadedRoute, $e);
}
if($request !== null) {
$this->request = $request;
$this->routeRequest(false);
return;
}
throw $e;
}
/**
* Get default namespace
* @return string
*/
public function getDefaultNamespace(){
@@ -286,7 +223,6 @@ class RouterBase {
}
/**
* Set the main default namespace that all routes will inherit
* @param string $defaultNamespace
* @return static
*/
@@ -296,7 +232,6 @@ class RouterBase {
}
/**
* Get bootmanagers
* @return array
*/
public function getBootManagers() {
@@ -304,21 +239,40 @@ 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
*/
@@ -336,29 +290,21 @@ class RouterBase {
}
/**
* Get response
* @return Response
*/
public function getResponse() {
return $this->response;
}
/**
* Get csrf verifier class
* Get base csrf verifier class
* @return BaseCsrfVerifier
*/
public function getCsrfVerifier() {
return $this->csrfVerifier;
public function getBaseCsrfVerifier() {
return $this->baseCsrfVerifier;
}
/**
* Set csrf verifier class
* Set base csrf verifier class
*
* @param BaseCsrfVerifier $csrfVerifier
* @return static
* @param BaseCsrfVerifier $baseCsrfVerifier
* @return self
*/
public function setCsrfVerifier(BaseCsrfVerifier $csrfVerifier) {
$this->csrfVerifier = $csrfVerifier;
public function setBaseCsrfVerifier(BaseCsrfVerifier $baseCsrfVerifier) {
$this->baseCsrfVerifier = $baseCsrfVerifier;
return $this;
}
@@ -381,31 +327,38 @@ class RouterBase {
$domain = '';
$parent = $route->getParent();
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();
}
if($parent !== null && $parent instanceof RouterGroup && count($parent->getDomains())) {
$domain = $parent->getDomains();
$domain = '//' . $domain[0];
$domain = '//' . $domain;
}
$url = $domain . '/' . trim($route->getUrl(), '/');
if($route instanceof IControllerRoute && $method !== null) {
if(($route instanceof RouterController || $route instanceof RouterResource) && $method !== null) {
$url .= $method;
}
if($route instanceof RouterController || $route instanceof RouterResource) {
if(count($parameters)) {
$url .= join('/', $parameters);
}
} else {
if($parameters !== null && is_array($parameters)) {
/* @var $route RouterEntry */
if(is_array($parameters)) {
$params = array_merge($route->getParameters(), $parameters);
} else {
$params = $route->getParameters();
}
$otherParams = array();
$i = 0;
$otherParams = [];
$i = 0;
foreach($params as $param => $value) {
$value = (isset($parameters[$param])) ? $parameters[$param] : $value;
if(stripos($url, '{' . $param. '}') !== false || stripos($url, '{' . $param . '?}') !== false) {
@@ -440,7 +393,7 @@ class RouterBase {
// Return current route if no options has been specified
if($controller === null && $parameters === null) {
$getParams = ($getParams !== null && is_array($getParams)) ? array_merge($_GET, $getParams) : $_GET;
$getParams = (is_array($getParams)) ? array_merge($_GET, $getParams) : $_GET;
$url = parse_url($this->request->getUri(), PHP_URL_PATH);
@@ -451,12 +404,13 @@ class RouterBase {
return $url;
}
if($controller === null && $this->loadedRoute !== null) {
return $this->processUrl($this->loadedRoute, $this->loadedRoute->getMethod(), $parameters, $getParams);
if($controller === null && $this->request->loadedRoute !== null) {
return $this->processUrl($this->request->loadedRoute, $this->request->loadedRoute->getMethod(), $parameters, $getParams);
}
$c = '';
$method = null;
$max = count($this->controllerUrlMap);
/* @var $route RouterRoute */
@@ -465,25 +419,14 @@ class RouterBase {
$route = $this->controllerUrlMap[$i];
// Check an alias exist, if the matches - use it
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 && $route->hasAlias($controller)) {
return $this->processUrl($route, $route->getMethod(), $parameters, $getParams);
}
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) {
@@ -498,10 +441,10 @@ class RouterBase {
$route = $this->controllerUrlMap[$i];
if($route instanceof IControllerRoute) {
$c = $route->getController();
} else if(!is_callable($route->getCallback()) && stripos($route->getCallback(), '@') !== false) {
if($route instanceof RouterRoute && !is_callable($route->getCallback()) && stripos($route->getCallback(), '@') !== false) {
$c = $route->getClass();
} else if($route instanceof RouterController || $route instanceof RouterResource) {
$c = $route->getController();
}
if(stripos($controller, '@') !== false) {
@@ -518,8 +461,10 @@ class RouterBase {
$controller = ($controller === null) ? '/' : $controller;
$url = array($controller);
if($parameters !== null && is_array($parameters) && count($parameters)) {
$url = array_merge($url, $parameters);
if(is_array($parameters)) {
foreach($parameters as $key => $value) {
array_push($url,$value);
}
}
$url = '/' . trim(join('/', $url), '/') . '/';
@@ -531,15 +476,10 @@ 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;
}
+24 -5
View File
@@ -4,20 +4,22 @@ namespace Pecee\SimpleRouter;
use Pecee\Exception\RouterException;
use Pecee\Http\Request;
class RouterController extends LoadableRoute implements IControllerRoute {
class RouterController extends RouterEntry {
const DEFAULT_METHOD = 'index';
protected $url;
protected $controller;
protected $method;
public function __construct($url, $controller) {
parent::__construct();
$this->url = $url;
$this->controller = $controller;
}
public function renderRoute(Request $request) {
if($this->getCallback() !== null && is_callable($this->getCallback())) {
if(is_object($this->getCallback()) && is_callable($this->getCallback())) {
// When the callback is a function
call_user_func_array($this->getCallback(), $this->getParameters());
@@ -42,8 +44,8 @@ class RouterController extends LoadableRoute implements IControllerRoute {
}
public function matchRoute(Request $request) {
$url = parse_url(urldecode($request->getUri()), PHP_URL_PATH);
$url = rtrim($url, '/') . '/';
$url = parse_url(urldecode($request->getUri()));
$url = rtrim($url['path'], '/') . '/';
if(strtolower($url) == strtolower($this->url) || stripos($url, $this->url) === 0) {
@@ -53,7 +55,7 @@ class RouterController extends LoadableRoute implements IControllerRoute {
if(count($path)) {
$method = (!isset($path[0]) || trim($path[0]) === '') ? static::DEFAULT_METHOD : $path[0];
$method = (!isset($path[0]) || trim($path[0]) === '') ? self::DEFAULT_METHOD : $path[0];
$this->method = $method;
array_shift($path);
@@ -68,6 +70,23 @@ class RouterController extends LoadableRoute implements IControllerRoute {
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
*/
+263 -234
View File
@@ -8,31 +8,238 @@ use Pecee\Http\Request;
abstract class RouterEntry {
const REQUEST_TYPE_GET = 'get';
const REQUEST_TYPE_POST = 'post';
const REQUEST_TYPE_GET = 'get';
const REQUEST_TYPE_PUT = 'put';
const REQUEST_TYPE_PATCH = 'patch';
const REQUEST_TYPE_OPTIONS = 'options';
const REQUEST_TYPE_DELETE = 'delete';
public static $allowedRequestTypes = [
public static $allowedRequestTypes = array(
self::REQUEST_TYPE_DELETE,
self::REQUEST_TYPE_GET,
self::REQUEST_TYPE_POST,
self::REQUEST_TYPE_PUT,
self::REQUEST_TYPE_PATCH,
self::REQUEST_TYPE_OPTIONS,
self::REQUEST_TYPE_DELETE,
];
self::REQUEST_TYPE_PATCH
);
protected $parent;
protected $settings;
protected $callback;
protected $namespace;
protected $regex;
protected $requestMethods = array();
protected $where = array();
protected $parameters = array();
protected $middlewares = array();
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 function loadClass($name) {
if(!class_exists($name)) {
@@ -77,12 +284,7 @@ abstract class RouterEntry {
} else {
$regex .= '\/?(?P<' . $parameter . '>'. $parameterRegex .')[^\/]?';
}
$parameterNames[] = [
'name' => $parameter,
'required' => $required
];
$parameterNames[] = array('name' => $parameter, 'required' => $required);
$parameter = '';
$isParameter = false;
@@ -105,19 +307,21 @@ abstract class RouterEntry {
$max = count($parameterNames);
for($i = 0; $i < $max; $i++) {
$name = $parameterNames[$i];
$parameterValue = isset($parameterValues[$name['name']]) ? $parameterValues[$name['name']] : null;
if($max) {
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) {
throw new RouterException('Missing required parameter ' . $name['name'], 404);
}
if(!$name['required'] && $parameterValue === null) {
continue;
}
$parameters[$name['name']] = $parameterValue;
}
if(!$name['required'] && $parameterValue === null) {
continue;
}
$parameters[$name['name']] = $parameterValue;
}
return $parameters;
@@ -126,22 +330,32 @@ abstract class RouterEntry {
return null;
}
public function loadMiddleware(Request $request, RouterEntry &$route) {
if(count($this->getMiddlewares())) {
foreach($this->getMiddlewares() as $middleware) {
$middleware = $this->loadClass($middleware);
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());
if (!($middleware instanceof IMiddleware)) {
throw new RouterException($middleware . ' must be instance of Middleware');
throw new RouterException($this->getMiddleware() . ' must be instance of Middleware');
}
/* @var $class IMiddleware */
$middleware->handle($request, $route);
$middleware->handle($request);
}
}
}
public function renderRoute(Request $request) {
if($this->getCallback() !== null && is_callable($this->getCallback())) {
if(is_object($this->getCallback()) && is_callable($this->getCallback())) {
// When the callback is a function
call_user_func_array($this->getCallback(), $this->getParameters());
} else {
@@ -157,7 +371,7 @@ abstract class RouterEntry {
}
$parameters = array_filter($this->getParameters(), function($var){
return ($var !== null);
return !is_null($var);
});
call_user_func_array(array($class, $method), $parameters);
@@ -172,10 +386,10 @@ abstract class RouterEntry {
* Set allowed request methods
*
* @param array $methods
* @return static $this
* @return self $this
*/
public function setRequestMethods(array $methods) {
$this->requestMethods = $methods;
$this->settings['requestMethods'] = $methods;
return $this;
}
@@ -185,204 +399,19 @@ abstract class RouterEntry {
* @return array
*/
public function getRequestMethods() {
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];
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 null;
return $this->settings['requestMethods'];
}
public function getClass() {
if(strpos($this->callback, '@') !== false) {
$tmp = explode('@', $this->callback);
return $tmp[0];
}
return null;
public function getGroup() {
return $this->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']);
}
public function setGroup($group) {
$this->group = $group;
return $this;
}
+78 -52
View File
@@ -2,25 +2,37 @@
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(count($this->domains)) {
for($i = 0; $i < count($this->domains); $i++) {
$domain = $this->domains[$i];
if($this->domain !== null) {
$parameters = $this->parseParameters($domain, $request->getHost(), '.*');
if(is_array($this->domain)) {
if($parameters !== null) {
$this->parameters = $parameters;
return true;
$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;
}
}
return false;
}
$parameters = $this->parseParameters($this->domain, $request->getHost(), '[^.]*');
if ($parameters !== null) {
$this->parameters = $parameters;
return true;
}
return false;
@@ -29,65 +41,79 @@ 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->prefix !== null && stripos($request->getUri(), $this->prefix) === false) {
if($this->getPrefix() !== null && stripos($request->getUri(), $this->getPrefix()) === false) {
return false;
}
return $this->matchDomain($request);
}
public function setExceptionHandlers(array $handlers) {
$this->exceptionHandlers = $handlers;
public function setExceptionHandler($class) {
$this->exceptionHandler = $class;
return $this;
}
public function getExceptionHandlers() {
return $this->exceptionHandlers;
public function getExceptionHandler() {
return $this->exceptionHandler;
}
public function getDomains() {
return $this->domains;
}
public function setDomains(array $domains) {
$this->domains = $domains;
return $this;
public function getDomain() {
return $this->domain;
}
/**
* @param string $prefix
* @return static
* @param array $settings
* @return self
*/
public function setPrefix($prefix) {
$this->prefix = '/' . trim($prefix, '/');
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);
}
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);
}
}
+31 -10
View File
@@ -4,17 +4,21 @@ namespace Pecee\SimpleRouter;
use Pecee\Exception\RouterException;
use Pecee\Http\Request;
class RouterResource extends LoadableRoute implements IControllerRoute {
class RouterResource extends RouterEntry {
protected $url;
protected $controller;
protected $postMethod;
public function __construct($url, $controller) {
parent::__construct();
$this->url = $url;
$this->controller = $controller;
$this->postMethod = strtolower(($_SERVER['REQUEST_METHOD'] != 'GET') ? 'post' : 'get');
}
public function renderRoute(Request $request) {
if($this->getCallback() !== null && is_callable($this->getCallback())) {
if(is_object($this->getCallback()) && is_callable($this->getCallback())) {
// When the callback is a function
call_user_func_array($this->getCallback(), $this->getParameters());
} else {
@@ -43,8 +47,8 @@ class RouterResource extends LoadableRoute implements IControllerRoute {
}
public function matchRoute(Request $request) {
$url = parse_url(urldecode($request->getUri()), PHP_URL_PATH);
$url = rtrim($url, '/') . '/';
$url = parse_url(urldecode($request->getUri()));
$url = rtrim($url['path'], '/') . '/';
$route = rtrim($this->url, '/') . '/{id?}/{action?}';
@@ -60,32 +64,32 @@ class RouterResource extends LoadableRoute implements IControllerRoute {
unset($parameters['action']);
// Delete
if($request->getMethod() === static::REQUEST_TYPE_DELETE && $request->getMethod() === static::REQUEST_TYPE_POST) {
if($request->getMethod() === self::REQUEST_TYPE_DELETE && $this->postMethod === self::REQUEST_TYPE_POST) {
return $this->call('destroy', $parameters);
}
// Update
if(in_array($request->getMethod(), array(static::REQUEST_TYPE_PATCH, static::REQUEST_TYPE_PUT)) && $request->getMethod() === static::REQUEST_TYPE_POST) {
if(in_array($request->getMethod(), array(self::REQUEST_TYPE_PATCH, self::REQUEST_TYPE_PUT)) && $this->postMethod === self::REQUEST_TYPE_POST) {
return $this->call('update', $parameters);
}
// Edit
if(isset($action) && strtolower($action) === 'edit' && $request->getMethod() === static::REQUEST_TYPE_GET) {
if(isset($action) && strtolower($action) === 'edit' && $this->postMethod === self::REQUEST_TYPE_GET) {
return $this->call('edit', $parameters);
}
// Create
if(strtolower($action) === 'create' && $request->getMethod() === static::REQUEST_TYPE_GET) {
if(strtolower($action) === 'create' && $request->getMethod() === self::REQUEST_TYPE_GET) {
return $this->call('create', $parameters);
}
// Save
if($request->getMethod() === static::REQUEST_TYPE_POST) {
if($this->postMethod === self::REQUEST_TYPE_POST) {
return $this->call('store', $parameters);
}
// Show
if(isset($parameters['id']) && $request->getMethod() === static::REQUEST_TYPE_GET) {
if(isset($parameters['id']) && $this->postMethod === self::REQUEST_TYPE_GET) {
return $this->call('show', $parameters);
}
@@ -96,6 +100,23 @@ class RouterResource extends LoadableRoute implements IControllerRoute {
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
*/
+96 -6
View File
@@ -4,22 +4,27 @@ namespace Pecee\SimpleRouter;
use Pecee\Http\Request;
class RouterRoute extends LoadableRoute {
class RouterRoute extends RouterEntry {
const PARAMETERS_REGEX_MATCH = '{([A-Za-z\-\_]*?)\?{0,1}}';
protected $url;
public function __construct($url, $callback) {
parent::__construct();
$this->setUrl($url);
$this->setCallback($callback);
}
public function matchRoute(Request $request) {
$url = parse_url(urldecode($request->getUri()), PHP_URL_PATH);
$url = rtrim($url, '/') . '/';
$url = parse_url(urldecode($request->getUri()));
$url = rtrim($url['path'], '/') . '/';
// Match on custom defined regular expression
if($this->regex !== null) {
if($this->regexMatch) {
$parameters = array();
if(preg_match('/(' . $this->regex . ')/is', $request->getHost() . $url, $parameters)) {
if(preg_match('/('.$this->regexMatch.')/is', $request->getHost() . $url, $parameters)) {
$this->parameters = (!is_array($parameters[0]) ? array($parameters[0]) : $parameters[0]);
return true;
}
@@ -32,11 +37,96 @@ class RouterRoute extends LoadableRoute {
$parameters = $this->parseParameters($route, $url);
if($parameters !== null) {
$this->parameters = array_merge($this->parameters, $parameters);
if(is_array($this->parameters)) {
$this->parameters = array_merge($this->parameters, $parameters);
} else {
$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);
}
}
+16 -43
View File
@@ -15,18 +15,11 @@ class SimpleRouter {
/**
* Start/route request
* @param null $defaultNamespace
* @throws \Pecee\Exception\RouterException
*/
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);
public static function start($defaultNamespace = null) {
RouterBase::getInstance()->setDefaultNamespace($defaultNamespace)->routeRequest();
}
/**
@@ -34,7 +27,7 @@ class SimpleRouter {
* @param BaseCsrfVerifier $baseCsrfVerifier
*/
public static function csrfVerifier(BaseCsrfVerifier $baseCsrfVerifier) {
RouterBase::getInstance()->setCsrfVerifier($baseCsrfVerifier);
RouterBase::getInstance()->setBaseCsrfVerifier($baseCsrfVerifier);
}
public static function addBootManager(RouterBootManager $bootManager) {
@@ -42,27 +35,19 @@ class SimpleRouter {
}
public static function get($url, $callback, array $settings = null) {
return static::match(['get'], $url, $callback, $settings);
return self::match(['get'], $url, $callback, $settings);
}
public static function post($url, $callback, array $settings = null) {
return static::match(['post'], $url, $callback, $settings);
return self::match(['post'], $url, $callback, $settings);
}
public static function put($url, $callback, array $settings = null) {
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);
return self::match(['put'], $url, $callback, $settings);
}
public static function delete($url, $callback, array $settings = null) {
return static::match(['delete'], $url, $callback, $settings);
return self::match(['delete'], $url, $callback, $settings);
}
public static function group($settings = array(), $callback) {
@@ -70,7 +55,7 @@ class SimpleRouter {
$group->setCallback($callback);
if($settings !== null && is_array($settings)) {
$group->setData($settings);
$group->setSettings($settings);
}
RouterBase::getInstance()->addRoute($group);
@@ -87,7 +72,7 @@ class SimpleRouter {
* @return RouterRoute
*/
public static function basic($url, $callback, array $settings = null) {
return static::match(['get', 'post'], $url, $callback, $settings);
return self::match(['get', 'post'], $url, $callback, $settings);
}
public static function match(array $requestMethods, $url, $callback, array $settings = null) {
@@ -95,7 +80,7 @@ class SimpleRouter {
$route->setRequestMethods($requestMethods);
if($settings !== null) {
$route->setData($settings);
$route->addSettings($settings);
}
RouterBase::getInstance()->addRoute($route);
@@ -107,7 +92,7 @@ class SimpleRouter {
$route = new RouterRoute($url, $callback);
if($settings !== null) {
$route->setData($settings);
$route->addSettings($settings);
}
RouterBase::getInstance()->addRoute($route);
@@ -119,7 +104,7 @@ class SimpleRouter {
$route = new RouterController($url, $controller);
if($settings !== null) {
$route->setData($settings);
$route->addSettings($settings);
}
RouterBase::getInstance()->addRoute($route);
@@ -131,28 +116,16 @@ class SimpleRouter {
$route = new RouterResource($url, $controller);
if($settings !== null) {
$route->setData($settings);
$route->addSettings($settings);
}
static::router()->addRoute($route);
RouterBase::getInstance()->addRoute($route);
return $route;
}
public static function getRoute($controller = null, $parameters = null, $getParams = null) {
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();
return RouterBase::getInstance()->getRoute($controller, $parameters, $getParams);
}
}
+1 -1
View File
@@ -7,7 +7,7 @@ use Pecee\Http\Request;
class DummyMiddleware implements IMiddleware {
public function handle(Request $request, \Pecee\SimpleRouter\RouterEntry &$route = null) {
public function handle(Request $request) {
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 &$route = null, \Exception $error){
public function handleError(\Pecee\Http\Request $request, \Pecee\SimpleRouter\RouterEntry $router = null, \Exception $error){
throw $error;
}
+9 -47
View File
@@ -7,18 +7,20 @@ class GroupTest extends PHPUnit_Framework_TestCase {
protected $result;
public function testGroupLoad() {
protected function group() {
$this->result = true;
}
public function testGroup() {
$this->result = false;
\Pecee\SimpleRouter\SimpleRouter::group(['prefix' => '/group'], function() {
$this->result = true;
});
\Pecee\SimpleRouter\SimpleRouter::group(['prefix' => '/group'], $this->group());
try {
\Pecee\SimpleRouter\SimpleRouter::start();
} catch(Exception $e) {
// ignore RouteNotFound exception
}
$this->assertTrue($this->result);
@@ -26,9 +28,8 @@ class GroupTest extends PHPUnit_Framework_TestCase {
public function testNestedGroup() {
\Pecee\SimpleRouter\RouterBase::getInstance()->reset();
\Pecee\SimpleRouter\SimpleRouter::request()->setUri('/api/v1/test');
\Pecee\SimpleRouter\SimpleRouter::request()->setMethod('get');
\Pecee\SimpleRouter\RouterBase::getInstance()->getRequest()->setUri('/api/v1/test');
\Pecee\SimpleRouter\RouterBase::getInstance()->getRequest()->setMethod('get');
\Pecee\SimpleRouter\SimpleRouter::group(['prefix' => '/api'], function() {
\Pecee\SimpleRouter\SimpleRouter::group(['prefix' => '/v1'], function() {
@@ -39,43 +40,4 @@ 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/'));
}
}
+2 -3
View File
@@ -8,9 +8,8 @@ class MiddlewareTest extends PHPUnit_Framework_TestCase {
public function testMiddlewareFound() {
\Pecee\SimpleRouter\RouterBase::getInstance()->reset();
\Pecee\SimpleRouter\SimpleRouter::request()->setMethod('get');
\Pecee\SimpleRouter\SimpleRouter::request()->setUri('/my/test/url');
\Pecee\Http\Request::getInstance()->setMethod('get');
\Pecee\Http\Request::getInstance()->setUri('/my/test/url');
\Pecee\SimpleRouter\SimpleRouter::group(['exceptionHandler' => 'ExceptionHandler'], function() {
\Pecee\SimpleRouter\SimpleRouter::get('/my/test/url', 'DummyController@start', ['middleware' => 'DummyMiddleware']);
+23 -52
View File
@@ -5,13 +5,12 @@ require_once 'Dummy/DummyController.php';
require_once 'Dummy/Handler/ExceptionHandler.php';
class RouterRouteTest extends PHPUnit_Framework_TestCase {
protected $result = false;
public function testNotFound() {
\Pecee\SimpleRouter\RouterBase::getInstance()->reset();
\Pecee\SimpleRouter\SimpleRouter::request()->setMethod('get');
\Pecee\SimpleRouter\SimpleRouter::request()->setUri('/test-param1-param2');
\Pecee\Http\Request::getInstance()->setMethod('get');
\Pecee\Http\Request::getInstance()->setUri('/test-param1-param2');
\Pecee\SimpleRouter\SimpleRouter::group(['exceptionHandler' => 'ExceptionHandler'], function() {
\Pecee\SimpleRouter\SimpleRouter::get('/non-existing-path', 'DummyController@start');
@@ -30,36 +29,33 @@ class RouterRouteTest extends PHPUnit_Framework_TestCase {
}
public function testGet() {
\Pecee\SimpleRouter\RouterBase::getInstance()->reset();
\Pecee\SimpleRouter\SimpleRouter::request()->setUri('/my/test/url');
\Pecee\SimpleRouter\SimpleRouter::request()->setMethod('get');
\Pecee\SimpleRouter\RouterBase::getInstance()->getRequest()->setUri('/my/test/url');
\Pecee\SimpleRouter\RouterBase::getInstance()->getRequest()->setMethod('get');
\Pecee\SimpleRouter\SimpleRouter::get('/my/test/url', 'DummyController@start');
\Pecee\SimpleRouter\SimpleRouter::start();
}
public function testPost() {
\Pecee\SimpleRouter\RouterBase::getInstance()->reset();
\Pecee\SimpleRouter\SimpleRouter::request()->setUri('/my/test/url');
\Pecee\SimpleRouter\SimpleRouter::request()->setMethod('post');
\Pecee\SimpleRouter\RouterBase::getInstance()->getRequest()->setUri('/my/test/url');
\Pecee\Http\Request::getInstance()->setMethod('post');
\Pecee\SimpleRouter\SimpleRouter::post('/my/test/url', 'DummyController@start');
\Pecee\SimpleRouter\SimpleRouter::start();
}
public function testPut() {
\Pecee\SimpleRouter\RouterBase::getInstance()->reset();
\Pecee\SimpleRouter\SimpleRouter::request()->setUri('/my/test/url');
\Pecee\SimpleRouter\SimpleRouter::request()->setMethod('put');
\Pecee\SimpleRouter\RouterBase::getInstance()->getRequest()->setUri('/my/test/url');
\Pecee\Http\Request::getInstance()->setMethod('put');
\Pecee\SimpleRouter\SimpleRouter::put('/my/test/url', 'DummyController@start');
\Pecee\SimpleRouter\SimpleRouter::start();
}
public function testDelete() {
\Pecee\SimpleRouter\RouterBase::getInstance()->reset();
\Pecee\SimpleRouter\SimpleRouter::request()->setUri('/my/test/url');
\Pecee\SimpleRouter\SimpleRouter::request()->setMethod('delete');
\Pecee\SimpleRouter\RouterBase::getInstance()->getRequest()->setUri('/my/test/url');
\Pecee\Http\Request::getInstance()->setMethod('delete');
\Pecee\SimpleRouter\SimpleRouter::delete('/my/test/url', 'DummyController@start');
\Pecee\SimpleRouter\SimpleRouter::start();
@@ -67,9 +63,8 @@ class RouterRouteTest extends PHPUnit_Framework_TestCase {
}
public function testMethodNotAllowed() {
\Pecee\SimpleRouter\RouterBase::getInstance()->reset();
\Pecee\SimpleRouter\SimpleRouter::request()->setUri('/my/test/url');
\Pecee\SimpleRouter\SimpleRouter::request()->setMethod('post');
\Pecee\SimpleRouter\RouterBase::getInstance()->getRequest()->setUri('/my/test/url');
\Pecee\Http\Request::getInstance()->setMethod('post');
\Pecee\SimpleRouter\SimpleRouter::get('/my/test/url', 'DummyController@start');
@@ -83,9 +78,8 @@ class RouterRouteTest extends PHPUnit_Framework_TestCase {
public function testSimpleParam() {
\Pecee\SimpleRouter\RouterBase::getInstance()->reset();
\Pecee\SimpleRouter\SimpleRouter::request()->setMethod('get');
\Pecee\SimpleRouter\SimpleRouter::request()->setUri('/test-param1');
\Pecee\Http\Request::getInstance()->setMethod('get');
\Pecee\Http\Request::getInstance()->setUri('/test-param1');
\Pecee\SimpleRouter\SimpleRouter::get('/test-{param1}', 'DummyController@param');
\Pecee\SimpleRouter\SimpleRouter::start();
@@ -94,45 +88,22 @@ class RouterRouteTest extends PHPUnit_Framework_TestCase {
public function testMultiParam() {
\Pecee\SimpleRouter\RouterBase::getInstance()->reset();
\Pecee\SimpleRouter\SimpleRouter::request()->setMethod('get');
\Pecee\SimpleRouter\SimpleRouter::request()->setUri('/test-param1-param2');
\Pecee\Http\Request::getInstance()->setMethod('get');
\Pecee\Http\Request::getInstance()->setUri('/test-param1-param2');
\Pecee\SimpleRouter\SimpleRouter::get('/test-{param1}-{param2}', 'DummyController@param');
\Pecee\SimpleRouter\SimpleRouter::start();
}
public function testPathParamRegex() {
public function testPathParam() {
\Pecee\SimpleRouter\RouterBase::getInstance()->reset();
\Pecee\SimpleRouter\SimpleRouter::request()->setMethod('get');
\Pecee\SimpleRouter\SimpleRouter::request()->setUri('/test/path/123123');
\Pecee\Http\Request::getInstance()->setMethod('get');
\Pecee\Http\Request::getInstance()->setUri('/test/path/param1');
\Pecee\SimpleRouter\SimpleRouter::get('/test/path/{myParam}', 'DummyController@param', ['where' => ['myParam' => '([0-9]+)']]);
\Pecee\SimpleRouter\SimpleRouter::get('/test/path/{param}', 'DummyController@param');
\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);
}
}