mirror of
https://github.com/skipperbent/simple-php-router.git
synced 2026-06-17 16:57:53 +00:00
Compare commits
53 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| c5c63671ef | |||
| d279d5598d | |||
| 6e247f811f | |||
| be39010be3 | |||
| 8111de48fd | |||
| 79c82c90cc | |||
| 0dbc4e6ba2 | |||
| 6d7d07669b | |||
| a4dfa59a66 | |||
| 98bf95bfc9 | |||
| b051bcf02b | |||
| b8d5106f4e | |||
| 2c9d996437 | |||
| cfc9ac138a | |||
| 98ce5f7635 | |||
| a25be983b8 | |||
| 69bb570c73 | |||
| a0c5bbdcc0 | |||
| 50c6499efb | |||
| c80b23e9d4 | |||
| 55a96a441e | |||
| 9d88bf10d2 | |||
| dfa4a9aa6c | |||
| 6b8c823427 | |||
| 7c789ea0f8 | |||
| 3ba9dd01f0 | |||
| 932dfbf2b7 | |||
| 8d87aab35b | |||
| 14360b6779 | |||
| bbb81333b4 | |||
| fc2e2e1e82 | |||
| 161fbf6ccf | |||
| 9a7b598880 | |||
| 71518431a9 | |||
| cec240ab0c | |||
| 4d2b584936 | |||
| a102c70700 | |||
| 1486095e9f | |||
| 2db20dce6b | |||
| f2d106c649 | |||
| 7cb416cfc8 | |||
| a570322e25 | |||
| feb6c8bd41 | |||
| 276f213ccc | |||
| 56457448e4 | |||
| 8ce1540771 | |||
| 3b305ceb00 | |||
| 1f00cf50e6 | |||
| 32bc46be81 | |||
| 1ee71b9ec3 | |||
| 0b8931a2e1 | |||
| 2472079642 | |||
| 4409fbcf4e |
@@ -1,45 +1,18 @@
|
||||
# Simple PHP router
|
||||
Simple, fast and yet powerful PHP router that is easy to get integrated and in any project. Heavily inspired by the way Laravel handles routing, with both simplicity and expandability in mind.
|
||||
|
||||
**Note: this documentation is currently work-in-progress. Feel free to contribute.**
|
||||
|
||||
### Notes
|
||||
|
||||
The goal of this project is to create a router that is more or less 100% compatible with the Laravel documentation, while remaining as simple as possible, and as easy to integrate and change without compromising either speed or complexity. Being lightweight is the #1 priority.
|
||||
|
||||
### Feedback and development
|
||||
|
||||
If you are missing a feature, experience problems or have ideas or feedback that you want us to hear, please feel free to create an issue.
|
||||
|
||||
###### Issues guidelines
|
||||
|
||||
- Please be as detailed as possible in the description when creating a new issue. This will help others to more easily understand- and solve your issue.
|
||||
For example: if you are experiencing issues, you should provide the necessary steps to reproduce the error within your description.
|
||||
|
||||
- We love to hear out any ideas or feedback to the library.
|
||||
|
||||
[Create a new issue here](https://github.com/skipperbent/simple-php-router/issues/new)
|
||||
|
||||
###### Contribution development guidelines
|
||||
|
||||
- Please try to follow the PSR-2 codestyle guidelines.
|
||||
|
||||
- Please create your pull requests to the development base that matches the version number you want to change.
|
||||
For example when pushing changes to version 3, the pull request should use the `v3-development` base/branch.
|
||||
|
||||
- Create detailed descriptions for your commits, as these will be used in the changelog for new releases.
|
||||
|
||||
- When changing existing functionality, please ensure that the unit-tests working.
|
||||
|
||||
- When adding new stuff, please remember to add new unit-tests for the functionality.
|
||||
**Please note that this documentation is currently work-in-progress. Feel free to contribute.**
|
||||
|
||||
---
|
||||
|
||||
## Table of Contents
|
||||
|
||||
- [Getting started](#getting-started)
|
||||
- [Requirements](#requirements)
|
||||
- [Notes](#notes-1)
|
||||
- [Requirements](#requirements)
|
||||
- [Feedback and development](#feedback-and-development)
|
||||
- [Issues guidelines](#issues-guidelines)
|
||||
- [Contribution development guidelines](#contribution-development-guidelines)
|
||||
- [Features](#features)
|
||||
- [Installation](#installation)
|
||||
- [Setting up Apache](#setting-up-apache)
|
||||
@@ -47,7 +20,6 @@ For example when pushing changes to version 3, the pull request should use the `
|
||||
- [Setting up IIS](#setting-up-iis)
|
||||
- [Configuration](#configuration)
|
||||
- [Helper functions](#helper-functions)
|
||||
|
||||
- [Routes](#routes)
|
||||
- [Basic routing](#basic-routing)
|
||||
- [Available methods](#available-methods)
|
||||
@@ -99,8 +71,7 @@ For example when pushing changes to version 3, the pull request should use the `
|
||||
|
||||
- [Advanced](#advanced)
|
||||
- [Url rewriting](#url-rewriting)
|
||||
- [Rewrite using callback](#rewrite-using-callback)
|
||||
- [Rewrite using url](#rewrite-using-url)
|
||||
- [Changing current route](#changing-current-route)
|
||||
- [Bootmanager: loading routes dynamically](#bootmanager-loading-routes-dynamically)
|
||||
- [Adding routes manually](#adding-routes-manually)
|
||||
- [Parameters](#parameters)
|
||||
@@ -119,12 +90,10 @@ Add the latest version of Simple PHP Router running this command.
|
||||
composer require pecee/simple-router
|
||||
```
|
||||
|
||||
## Requirements
|
||||
|
||||
- PHP 5.5 or greater
|
||||
|
||||
## Notes
|
||||
|
||||
The goal of this project is to create a router that is more or less 100% compatible with the Laravel documentation, while remaining as simple as possible, and as easy to integrate and change without compromising either speed or complexity. Being lightweight is the #1 priority.
|
||||
|
||||
We've included a simple demo project for the router which can be found in the `demo-project` folder. This project should give you a basic understanding of how to setup and use simple-php-router project.
|
||||
|
||||
Please note that the demo-project only covers how to integrate the `simple-php-router` in a project without an existing framework. If you are using a framework in your project, the implementation might vary.
|
||||
@@ -143,6 +112,36 @@ You can find the demo-project here: [https://github.com/skipperbent/simple-route
|
||||
- How to get ExceptionHandlers, Middlewares and Controllers working.
|
||||
- How to setup your webservers.
|
||||
|
||||
## Requirements
|
||||
|
||||
- PHP 5.5 or greater
|
||||
|
||||
### Feedback and development
|
||||
|
||||
If you are missing a feature, experience problems or have ideas or feedback that you want us to hear, please feel free to create an issue.
|
||||
|
||||
###### Issues guidelines
|
||||
|
||||
- Please be as detailed as possible in the description when creating a new issue. This will help others to more easily understand- and solve your issue.
|
||||
For example: if you are experiencing issues, you should provide the necessary steps to reproduce the error within your description.
|
||||
|
||||
- We love to hear out any ideas or feedback to the library.
|
||||
|
||||
[Create a new issue here](https://github.com/skipperbent/simple-php-router/issues/new)
|
||||
|
||||
###### Contribution development guidelines
|
||||
|
||||
- Please try to follow the PSR-2 codestyle guidelines.
|
||||
|
||||
- Please create your pull requests to the development base that matches the version number you want to change.
|
||||
For example when pushing changes to version 3, the pull request should use the `v3-development` base/branch.
|
||||
|
||||
- Create detailed descriptions for your commits, as these will be used in the changelog for new releases.
|
||||
|
||||
- When changing existing functionality, please ensure that the unit-tests working.
|
||||
|
||||
- When adding new stuff, please remember to add new unit-tests for the functionality.
|
||||
|
||||
## Features
|
||||
|
||||
- Basic routing (`GET`, `POST`, `PUT`, `PATCH`, `UPDATE`, `DELETE`) with support for custom multiple verbs.
|
||||
@@ -598,9 +597,9 @@ SimpleRouter::group(['namespace' => 'Admin'], function () {
|
||||
});
|
||||
```
|
||||
|
||||
### Sub domain-routing
|
||||
### Subdomain-routing
|
||||
|
||||
Route groups may also be used to handle sub-domain routing. Sub-domains may be assigned route parameters just like route URIs, allowing you to capture a portion of the sub-domain for usage in your route or controller. The sub-domain may be specified using the `domain` key on the group attribute array:
|
||||
Route groups may also be used to handle sub-domain routing. Sub-domains may be assigned route parameters just like route urls, allowing you to capture a portion of the sub-domain for usage in your route or controller. The sub-domain may be specified using the `domain` key on the group attribute array:
|
||||
|
||||
```php
|
||||
SimpleRouter::group(['domain' => '{account}.myapp.com'], function () {
|
||||
@@ -612,7 +611,7 @@ SimpleRouter::group(['domain' => '{account}.myapp.com'], function () {
|
||||
|
||||
### Route prefixes
|
||||
|
||||
The `prefix` group attribute may be used to prefix each route in the group with a given URI. For example, you may want to prefix all route URIs within the group with `admin`:
|
||||
The `prefix` group attribute may be used to prefix each route in the group with a given url. For example, you may want to prefix all route urls within the group with `admin`:
|
||||
|
||||
```php
|
||||
SimpleRouter::group(['prefix' => '/admin'], function () {
|
||||
@@ -894,7 +893,7 @@ class CustomExceptionHandler implements IExceptionHandler
|
||||
|
||||
/* You can use the exception handler to format errors depending on the request and type. */
|
||||
|
||||
if (stripos($request->getUri()->getPath(), '/api') !== false) {
|
||||
if (stripos($request->getUrl()->getPath(), '/api') !== false) {
|
||||
|
||||
response()->json([
|
||||
'error' => $error->getMessage(),
|
||||
@@ -1135,126 +1134,22 @@ $siteId = input('site_id', 2, ['post', 'get']);
|
||||
# Advanced
|
||||
|
||||
## Url rewriting
|
||||
|
||||
### Changing current route
|
||||
|
||||
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.
|
||||
simple-php-router allows you to easily manipulate and change the routes which are about to be rendered.
|
||||
All information about the current route is stored in the `\Pecee\SimpleRouter\Router` instance's `loadedRoute` property.
|
||||
|
||||
For easy access you can use the shortcut method `\Pecee\SimpleRouter\SimpleRouter::router()`.
|
||||
For easy access you can use the shortcut helper function `request()` instead of calling the class directly `\Pecee\SimpleRouter\SimpleRouter::router()`.
|
||||
|
||||
|
||||
```php
|
||||
use Pecee\SimpleRouter;
|
||||
$request = SimpleRouter::request();
|
||||
$request->setRewriteCallback('Example\MyCustomClass@hello');
|
||||
request()->setRewriteCallback('Example\MyCustomClass@hello');
|
||||
|
||||
// -- or you can rewrite by url --
|
||||
|
||||
$request->setRewriteUrl('/my-rewrite-url');
|
||||
```
|
||||
|
||||
**Note:** It's only possible to change the route BEFORE the route has initially been rendered. You can use the `Request` object to manipulate the route which are about to be loaded.
|
||||
|
||||
### Rewrite using callback
|
||||
|
||||
This method is most efficient, as it will render the route immediately.
|
||||
|
||||
This method is useful for rendering 404-pages etc.
|
||||
|
||||
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.
|
||||
|
||||
The example below will render `DefaultController@notFound` regardless of the url.
|
||||
|
||||
**NOTE: Use this method if you want to load another controller. No additional middlewares or rules will be loaded.**
|
||||
|
||||
##### Middleware example
|
||||
|
||||
```php
|
||||
namespace Demo\Middlewares;
|
||||
|
||||
use Pecee\Http\Middleware\IMiddleware;
|
||||
use Pecee\Http\Request;
|
||||
|
||||
class CustomMiddleware implements IMiddleware {
|
||||
|
||||
public function handle(Request $request) {
|
||||
|
||||
$request->setRewriteCallback('Demo\Controllers\DefaultController@notFound');
|
||||
return $request;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
##### Exception handler example
|
||||
|
||||
```php
|
||||
namespace Demo\Handlers;
|
||||
|
||||
use Pecee\Handlers\IExceptionHandler;
|
||||
use Pecee\Http\Request;
|
||||
use Pecee\SimpleRouter\Exceptions\NotFoundHttpException;
|
||||
|
||||
class CustomExceptionHandler implements IExceptionHandler
|
||||
{
|
||||
public function handleError(Request $request, \Exception $error)
|
||||
{
|
||||
/* The router will throw the NotFoundHttpException on 404 */
|
||||
if($error instanceof NotFoundHttpException) {
|
||||
|
||||
/*
|
||||
* Render your own custom 404-view, rewrite the request to another route,
|
||||
* or simply return the $request object to ignore the error and continue on rendering the route.
|
||||
*
|
||||
* The code below will make the router render our page.notfound route.
|
||||
*/
|
||||
|
||||
$request->setRewriteCallback('Demo\Controllers\DefaultController@notFound');
|
||||
return $request;
|
||||
|
||||
}
|
||||
|
||||
throw $error;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
### Rewrite using url
|
||||
|
||||
The example below will cause the router to reload the request and reinitialize all the routes. This method is slower, but will ensure that all middlewares and rules for the route is loaded.
|
||||
|
||||
This method is useful if you want to redirect a url to another-url which is dependent on a middleware. You can also add a custom rule by calling `$request->setRewriteRoute($route)` if
|
||||
you want to customize request-methods or use another route-type like `RouteController` etc.
|
||||
|
||||
We are using the `url()` helper function to get the uri to another route added in the `routes.php` file.
|
||||
|
||||
**NOTE: Use this method if you want to fully load another route using it's settings (request method, middlewares etc).**
|
||||
|
||||
##### Middleware example
|
||||
|
||||
The example below will redirect the request to the `home`-route.
|
||||
|
||||
```php
|
||||
namespace Demo\Middlewares;
|
||||
|
||||
use Pecee\Http\Middleware\IMiddleware;
|
||||
use Pecee\Http\Request;
|
||||
|
||||
class CustomMiddleware implements IMiddleware {
|
||||
|
||||
public function handle(Request $request) {
|
||||
|
||||
$request->setRewriteUrl(url('home'));
|
||||
return $request;
|
||||
|
||||
}
|
||||
}
|
||||
request()->setRewriteUrl('/my-rewrite-url');
|
||||
```
|
||||
|
||||
### Bootmanager: loading routes dynamically
|
||||
@@ -1278,11 +1173,10 @@ class CustomRouterRules implement IRouterBootManager {
|
||||
|
||||
foreach($rewriteRules as $url => $rule) {
|
||||
|
||||
// If the current uri matches the url, we use our custom route
|
||||
// If the current url matches the rewrite url, we use our custom route
|
||||
|
||||
if($request->getUri()->getPath() === $url) {
|
||||
if($request->getUrl()->getPath() === $url) {
|
||||
$request->setRewriteUrl($rule);
|
||||
return $request;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+6
-1
@@ -9,7 +9,12 @@
|
||||
"simple-php-router",
|
||||
"laravel",
|
||||
"pecee",
|
||||
"php"
|
||||
"php",
|
||||
"framework",
|
||||
"url-handling",
|
||||
"input-handler",
|
||||
"routing-engine",
|
||||
"request-handler"
|
||||
],
|
||||
"license": "MIT",
|
||||
"support": {
|
||||
|
||||
@@ -18,6 +18,7 @@ use Pecee\SimpleRouter\SimpleRouter as Router;
|
||||
* @param string|array|null $parameters
|
||||
* @param array|null $getParams
|
||||
* @return string
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
function url($name = null, $parameters = null, $getParams = null)
|
||||
{
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
<?php
|
||||
namespace Pecee\Exceptions;
|
||||
|
||||
class InvalidArgumentException extends \InvalidArgumentException {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
<?php
|
||||
|
||||
namespace Pecee\Http\Exceptions;
|
||||
|
||||
class MalformedUrlException extends \Exception
|
||||
{
|
||||
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
<?php
|
||||
|
||||
namespace Pecee\Http\Input;
|
||||
|
||||
interface IInputItem
|
||||
@@ -14,6 +15,8 @@ interface IInputItem
|
||||
|
||||
public function getValue();
|
||||
|
||||
public function setValue($value);
|
||||
|
||||
public function __toString();
|
||||
|
||||
}
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
namespace Pecee\Http\Input;
|
||||
|
||||
use Pecee\Exceptions\InvalidArgumentException;
|
||||
use Pecee\Http\Request;
|
||||
|
||||
class Input
|
||||
@@ -26,6 +27,10 @@ class Input
|
||||
*/
|
||||
protected $request;
|
||||
|
||||
/**
|
||||
* Input constructor.
|
||||
* @param Request $request
|
||||
*/
|
||||
public function __construct(Request $request)
|
||||
{
|
||||
$this->request = $request;
|
||||
@@ -33,6 +38,10 @@ class Input
|
||||
$this->parseInputs();
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse input values
|
||||
*
|
||||
*/
|
||||
public function parseInputs()
|
||||
{
|
||||
/* Parse get requests */
|
||||
@@ -57,6 +66,9 @@ class Input
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function parseFiles()
|
||||
{
|
||||
$list = [];
|
||||
@@ -66,7 +78,11 @@ class Input
|
||||
// Handle array input
|
||||
if (is_array($value['name']) === false) {
|
||||
$values['index'] = $key;
|
||||
$list[$key] = InputFile::createFromArray($values + $value);
|
||||
try {
|
||||
$list[$key] = InputFile::createFromArray($values + $value);
|
||||
} catch(InvalidArgumentException $e ){
|
||||
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -97,22 +113,28 @@ class Input
|
||||
|
||||
if (is_array($original['name'][$key]) === false) {
|
||||
|
||||
$file = InputFile::createFromArray([
|
||||
'index' => (empty($key) === true && empty($originalIndex) === false) ? $originalIndex : $key,
|
||||
'name' => $original['name'][$key],
|
||||
'error' => $original['error'][$key],
|
||||
'tmp_name' => $original['tmp_name'][$key],
|
||||
'type' => $original['type'][$key],
|
||||
'size' => $original['size'][$key],
|
||||
]);
|
||||
try {
|
||||
|
||||
if (isset($output[$key]) === true) {
|
||||
$output[$key][] = $file;
|
||||
$file = InputFile::createFromArray([
|
||||
'index' => (empty($key) === true && empty($originalIndex) === false) ? $originalIndex : $key,
|
||||
'name' => $original['name'][$key],
|
||||
'error' => $original['error'][$key],
|
||||
'tmp_name' => $original['tmp_name'][$key],
|
||||
'type' => $original['type'][$key],
|
||||
'size' => $original['size'][$key],
|
||||
]);
|
||||
|
||||
if (isset($output[$key]) === true) {
|
||||
$output[$key][] = $file;
|
||||
continue;
|
||||
}
|
||||
|
||||
$output[$key] = $file;
|
||||
continue;
|
||||
}
|
||||
|
||||
$output[$key] = $file;
|
||||
continue;
|
||||
} catch(InvalidArgumentException $e) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
$index[] = $key;
|
||||
@@ -254,7 +276,7 @@ class Input
|
||||
*/
|
||||
public function all(array $filter = null)
|
||||
{
|
||||
$output = $_GET;
|
||||
$output = $_GET + $_POST;
|
||||
|
||||
if ($this->request->getMethod() === 'post') {
|
||||
|
||||
@@ -263,7 +285,7 @@ class Input
|
||||
if (strpos(trim($contents), '{') === 0) {
|
||||
$post = json_decode($contents, true);
|
||||
if ($post !== false) {
|
||||
$output = array_merge($output, $post);
|
||||
$output += $post;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
|
||||
namespace Pecee\Http\Input;
|
||||
|
||||
use Pecee\Exceptions\InvalidArgumentException;
|
||||
|
||||
class InputFile implements IInputItem
|
||||
{
|
||||
public $index;
|
||||
@@ -9,13 +11,15 @@ class InputFile implements IInputItem
|
||||
public $filename;
|
||||
public $size;
|
||||
public $type;
|
||||
public $error;
|
||||
public $errors;
|
||||
public $tmpName;
|
||||
|
||||
public function __construct($index)
|
||||
{
|
||||
$this->index = $index;
|
||||
|
||||
$this->errors = 0;
|
||||
|
||||
// Make the name human friendly, by replace _ with space
|
||||
$this->name = ucfirst(str_replace('_', ' ', strtolower($this->index)));
|
||||
}
|
||||
@@ -24,13 +28,13 @@ class InputFile implements IInputItem
|
||||
* Create from array
|
||||
*
|
||||
* @param array $values
|
||||
* @throws \InvalidArgumentException
|
||||
* @throws InvalidArgumentException
|
||||
* @return static
|
||||
*/
|
||||
public static function createFromArray(array $values)
|
||||
{
|
||||
if (isset($values['index']) === false) {
|
||||
throw new \InvalidArgumentException('Index key is required');
|
||||
throw new InvalidArgumentException('Index key is required');
|
||||
}
|
||||
|
||||
/* Easy way of ensuring that all indexes-are set and not filling the screen with isset() */
|
||||
@@ -216,7 +220,7 @@ class InputFile implements IInputItem
|
||||
*/
|
||||
public function getError()
|
||||
{
|
||||
return $this->error;
|
||||
return $this->errors;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -227,7 +231,7 @@ class InputFile implements IInputItem
|
||||
*/
|
||||
public function setError($error)
|
||||
{
|
||||
$this->error = (int)$error;
|
||||
$this->errors = (int)$error;
|
||||
|
||||
return $this;
|
||||
}
|
||||
@@ -262,6 +266,17 @@ class InputFile implements IInputItem
|
||||
return $this->getFilename();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $value
|
||||
* @return static
|
||||
*/
|
||||
public function setValue($value)
|
||||
{
|
||||
$this->filename = $value;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function toArray()
|
||||
{
|
||||
return [
|
||||
@@ -269,7 +284,7 @@ class InputFile implements IInputItem
|
||||
'type' => $this->type,
|
||||
'size' => $this->size,
|
||||
'name' => $this->name,
|
||||
'error' => $this->error,
|
||||
'error' => $this->errors,
|
||||
'filename' => $this->filename,
|
||||
];
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
<?php
|
||||
|
||||
namespace Pecee\Http\Input;
|
||||
|
||||
class InputItem implements IInputItem
|
||||
|
||||
@@ -15,6 +15,10 @@ class BaseCsrfVerifier implements IMiddleware
|
||||
protected $except;
|
||||
protected $tokenProvider;
|
||||
|
||||
/**
|
||||
* BaseCsrfVerifier constructor.
|
||||
* @throws \Pecee\Http\Security\Exceptions\SecurityException
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->tokenProvider = new CookieTokenProvider();
|
||||
@@ -39,9 +43,9 @@ class BaseCsrfVerifier implements IMiddleware
|
||||
$url = rtrim($url, '/');
|
||||
if ($url[strlen($url) - 1] === '*') {
|
||||
$url = rtrim($url, '*');
|
||||
$skip = (stripos($request->getUri()->getPath(), $url) === 0);
|
||||
$skip = (stripos($request->getUrl()->getOriginalUrl(), $url) === 0);
|
||||
} else {
|
||||
$skip = ($url === $request->getUri()->getPath());
|
||||
$skip = ($url === $request->getUrl()->getOriginalUrl());
|
||||
}
|
||||
|
||||
if ($skip === true) {
|
||||
|
||||
+49
-15
@@ -12,10 +12,12 @@ class Request
|
||||
private $data = [];
|
||||
protected $headers;
|
||||
protected $host;
|
||||
protected $uri;
|
||||
protected $url;
|
||||
protected $method;
|
||||
protected $input;
|
||||
|
||||
protected $hasRewrite = false;
|
||||
|
||||
/**
|
||||
* @var ILoadableRoute|null
|
||||
*/
|
||||
@@ -27,16 +29,20 @@ class Request
|
||||
*/
|
||||
protected $loadedRoute;
|
||||
|
||||
/**
|
||||
* Request constructor.
|
||||
* @throws \Pecee\Http\Exceptions\MalformedUrlException
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->parseHeaders();
|
||||
$this->setHost($this->getHeader('http-host'));
|
||||
|
||||
// Check if special IIS header exist, otherwise use default.
|
||||
$this->setUri(new Uri($this->getHeader('unencoded-url', $this->getHeader('request-uri'))));
|
||||
$this->setUrl($this->getHeader('unencoded-url', $this->getHeader('request-uri')));
|
||||
|
||||
$this->input = new Input($this);
|
||||
$this->method = strtolower($this->input->get('_method', $this->getHeader('request-method'), 'post'));
|
||||
$this->method = strtolower($this->input->get('_method', $this->getHeader('request-method')));
|
||||
}
|
||||
|
||||
protected function parseHeaders()
|
||||
@@ -56,11 +62,11 @@ class Request
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Uri
|
||||
* @return Url
|
||||
*/
|
||||
public function getUri()
|
||||
public function getUrl()
|
||||
{
|
||||
return $this->uri;
|
||||
return $this->url;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -186,6 +192,16 @@ class Request
|
||||
return ($this->getHeader('http-accept') !== null && stripos($this->getHeader('http-accept'), $format) > -1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the request is made through Ajax
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isAjax()
|
||||
{
|
||||
return (strtolower($this->getHeader('http-x-requested-with')) === 'xmlhttprequest');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get accept formats
|
||||
* @return array
|
||||
@@ -196,15 +212,12 @@ class Request
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Uri|string $uri
|
||||
* @param string|Url $url
|
||||
* @throws \Pecee\Http\Exceptions\MalformedUrlException
|
||||
*/
|
||||
public function setUri($uri)
|
||||
public function setUrl($url)
|
||||
{
|
||||
if (is_string($uri) === true) {
|
||||
$uri = new Uri($uri);
|
||||
}
|
||||
|
||||
$this->uri = $uri;
|
||||
$this->url = ($url instanceof Url) ? $url : new Url($url);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -231,6 +244,7 @@ class Request
|
||||
*/
|
||||
public function setRewriteRoute(ILoadableRoute $route)
|
||||
{
|
||||
$this->hasRewrite = true;
|
||||
$this->rewriteRoute = SimpleRouter::addDefaultNamespace($route);
|
||||
|
||||
return $this;
|
||||
@@ -264,7 +278,8 @@ class Request
|
||||
*/
|
||||
public function setRewriteUrl($rewriteUrl)
|
||||
{
|
||||
$this->rewriteUrl = $rewriteUrl;
|
||||
$this->hasRewrite = true;
|
||||
$this->rewriteUrl = rtrim($rewriteUrl, '/') . '/';
|
||||
|
||||
return $this;
|
||||
}
|
||||
@@ -276,7 +291,9 @@ class Request
|
||||
*/
|
||||
public function setRewriteCallback($callback)
|
||||
{
|
||||
return $this->setRewriteRoute(new RouteUrl($this->uri, $callback));
|
||||
$this->hasRewrite = true;
|
||||
|
||||
return $this->setRewriteRoute(new RouteUrl($this->getUrl()->getPath(), $callback));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -301,6 +318,23 @@ class Request
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function hasRewrite()
|
||||
{
|
||||
return $this->hasRewrite;
|
||||
}
|
||||
|
||||
public function setHasRewrite($value)
|
||||
{
|
||||
$this->hasRewrite = $value;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function isRewrite($url)
|
||||
{
|
||||
return ($this->rewriteUrl === $url);
|
||||
}
|
||||
|
||||
public function __isset($name)
|
||||
{
|
||||
return array_key_exists($name, $this->data);
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
|
||||
namespace Pecee\Http;
|
||||
|
||||
use Pecee\Exceptions\InvalidArgumentException;
|
||||
|
||||
class Response
|
||||
{
|
||||
protected $request;
|
||||
@@ -37,12 +39,12 @@ class Response
|
||||
}
|
||||
|
||||
$this->header('location: ' . $url);
|
||||
die();
|
||||
exit(0);
|
||||
}
|
||||
|
||||
public function refresh()
|
||||
{
|
||||
$this->redirect($this->request->getUri()->getPath());
|
||||
$this->redirect($this->request->getUrl()->getOriginalUrl());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -87,12 +89,12 @@ class Response
|
||||
* @param array|\JsonSerializable $value
|
||||
* @param int $options JSON options Bitmask consisting of JSON_HEX_QUOT, JSON_HEX_TAG, JSON_HEX_AMP, JSON_HEX_APOS, JSON_NUMERIC_CHECK, JSON_PRETTY_PRINT, JSON_UNESCAPED_SLASHES, JSON_FORCE_OBJECT, JSON_PRESERVE_ZERO_FRACTION, JSON_UNESCAPED_UNICODE, JSON_PARTIAL_OUTPUT_ON_ERROR.
|
||||
* @param int $dept JSON debt.
|
||||
* @throws \InvalidArgumentException
|
||||
* @throws InvalidArgumentException
|
||||
*/
|
||||
public function json($value, $options = null, $dept = 512)
|
||||
{
|
||||
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.');
|
||||
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; charset=utf-8');
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
|
||||
namespace Pecee\Http\Security;
|
||||
|
||||
use Pecee\Http\Security\Exceptions\SecurityException;
|
||||
|
||||
class CookieTokenProvider implements ITokenProvider
|
||||
{
|
||||
const CSRF_KEY = 'CSRF-TOKEN';
|
||||
@@ -9,6 +11,10 @@ class CookieTokenProvider implements ITokenProvider
|
||||
protected $token;
|
||||
protected $cookieTimeoutMinutes = 120;
|
||||
|
||||
/**
|
||||
* CookieTokenProvider constructor.
|
||||
* @throws SecurityException
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->token = $this->getToken();
|
||||
@@ -21,20 +27,24 @@ class CookieTokenProvider implements ITokenProvider
|
||||
/**
|
||||
* Generate random identifier for CSRF token
|
||||
*
|
||||
* @throws \RuntimeException|\Exception
|
||||
* @return string
|
||||
* @throws SecurityException
|
||||
*/
|
||||
public function generateToken()
|
||||
{
|
||||
if (function_exists('random_bytes') === true) {
|
||||
return bin2hex(random_bytes(32));
|
||||
try {
|
||||
return bin2hex(random_bytes(32));
|
||||
} catch(\Exception $e) {
|
||||
throw new SecurityException($e->getMessage(), (int)$e->getCode(), $e->getPrevious());
|
||||
}
|
||||
}
|
||||
|
||||
$isSourceStrong = false;
|
||||
|
||||
$random = openssl_random_pseudo_bytes(32, $isSourceStrong);
|
||||
if ($isSourceStrong === false || $random === false) {
|
||||
throw new \RuntimeException('IV generation failed');
|
||||
throw new SecurityException('IV generation failed');
|
||||
}
|
||||
|
||||
return $random;
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
<?php
|
||||
namespace Pecee\Http\Security\Exceptions;
|
||||
|
||||
class SecurityException extends \Exception {
|
||||
|
||||
}
|
||||
@@ -2,7 +2,9 @@
|
||||
|
||||
namespace Pecee\Http;
|
||||
|
||||
class Uri
|
||||
use Pecee\Http\Exceptions\MalformedUrlException;
|
||||
|
||||
class Url
|
||||
{
|
||||
private $originalUrl;
|
||||
private $data = [
|
||||
@@ -16,6 +18,11 @@ class Uri
|
||||
'fragment' => null,
|
||||
];
|
||||
|
||||
/**
|
||||
* Url constructor.
|
||||
* @param string $url
|
||||
* @throws MalformedUrlException
|
||||
*/
|
||||
public function __construct($url)
|
||||
{
|
||||
$this->originalUrl = $url;
|
||||
@@ -129,7 +136,7 @@ class Uri
|
||||
* UTF-8 aware parse_url() replacement.
|
||||
* @param string $url
|
||||
* @param int $component
|
||||
* @throws \InvalidArgumentException
|
||||
* @throws MalformedUrlException
|
||||
* @return array
|
||||
*/
|
||||
public function parseUrl($url, $component = -1)
|
||||
@@ -145,7 +152,7 @@ class Uri
|
||||
$parts = parse_url($encodedUrl, $component);
|
||||
|
||||
if ($parts === false) {
|
||||
throw new \InvalidArgumentException('Malformed URL: ' . $url);
|
||||
throw new MalformedUrlException('Malformed URL: ' . $url);
|
||||
}
|
||||
|
||||
return array_map('urldecode', $parts);
|
||||
@@ -28,15 +28,7 @@ abstract class LoadableRoute extends Route implements ILoadableRoute
|
||||
*/
|
||||
public function loadMiddleware(Request $request)
|
||||
{
|
||||
$max = count($this->getMiddlewares());
|
||||
|
||||
if ($max === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
for ($i = 0; $i < $max; $i++) {
|
||||
|
||||
$middleware = $this->getMiddlewares()[$i];
|
||||
foreach ($this->getMiddlewares() as $middleware) {
|
||||
|
||||
if (is_object($middleware) === false) {
|
||||
$middleware = $this->loadClass($middleware);
|
||||
@@ -58,7 +50,7 @@ abstract class LoadableRoute extends Route implements ILoadableRoute
|
||||
return null;
|
||||
}
|
||||
|
||||
return (preg_match($this->regex, $request->getHost() . $url) > 0);
|
||||
return ((bool)preg_match($this->regex, $request->getHost() . $url) !== false);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -75,7 +67,7 @@ abstract class LoadableRoute extends Route implements ILoadableRoute
|
||||
|
||||
$regex = sprintf(static::PARAMETERS_REGEX_FORMAT, $this->paramModifiers[0], $this->paramOptionalSymbol, $this->paramModifiers[1]);
|
||||
|
||||
if (preg_match_all('/' . $regex . '/u', $this->url, $matches) > 0) {
|
||||
if ((bool)preg_match_all('/' . $regex . '/u', $this->url, $matches) !== false) {
|
||||
$this->parameters = array_fill_keys($matches[1], null);
|
||||
}
|
||||
}
|
||||
@@ -119,11 +111,8 @@ abstract class LoadableRoute extends Route implements ILoadableRoute
|
||||
/* Replace any {parameter} in the url with the correct value */
|
||||
|
||||
$params = $this->getParameters();
|
||||
$max = count($params) - 1;
|
||||
$keys = array_keys($params);
|
||||
|
||||
for ($i = $max; $i >= 0; $i--) {
|
||||
$param = $keys[$i];
|
||||
foreach (array_keys($params) as $param) {
|
||||
|
||||
if ($parameters === '' || (is_array($parameters) === true && count($parameters) === 0)) {
|
||||
$value = '';
|
||||
@@ -145,8 +134,7 @@ abstract class LoadableRoute extends Route implements ILoadableRoute
|
||||
}
|
||||
}
|
||||
|
||||
$url = '/' . ltrim($url, '/');
|
||||
$url .= implode('/', $unknownParams);
|
||||
$url = '/' . ltrim($url, '/') . implode('/', $unknownParams);
|
||||
|
||||
return rtrim($url, '/') . '/';
|
||||
}
|
||||
|
||||
@@ -33,7 +33,7 @@ abstract class Route implements IRoute
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $filterEmptyParams = false;
|
||||
protected $filterEmptyParams = true;
|
||||
|
||||
/**
|
||||
* Default regular expression used for parsing parameters.
|
||||
@@ -86,12 +86,20 @@ abstract class Route implements IRoute
|
||||
return null;
|
||||
}
|
||||
|
||||
$parameters = $this->getParameters();
|
||||
|
||||
/* Filter parameters with null-value */
|
||||
|
||||
if ($this->filterEmptyParams === true) {
|
||||
$parameters = array_filter($parameters, function ($var) {
|
||||
return ($var !== null);
|
||||
});
|
||||
}
|
||||
|
||||
/* Render callback function */
|
||||
if (is_callable($callback) === true) {
|
||||
|
||||
/* When the callback is a function */
|
||||
return call_user_func_array($callback, $this->getParameters());
|
||||
|
||||
return call_user_func_array($callback, $parameters);
|
||||
}
|
||||
|
||||
/* When the callback is a class + method */
|
||||
@@ -108,16 +116,6 @@ abstract class Route implements IRoute
|
||||
throw new NotFoundHttpException(sprintf('Method "%s" does not exist in class "%s"', $method, $className), 404);
|
||||
}
|
||||
|
||||
$parameters = $this->getParameters();
|
||||
|
||||
/* Filter parameters with null-value */
|
||||
|
||||
if ($this->filterEmptyParams === true) {
|
||||
$parameters = array_filter($parameters, function ($var) {
|
||||
return ($var !== null);
|
||||
});
|
||||
}
|
||||
|
||||
return call_user_func_array([$class, $method], $parameters);
|
||||
}
|
||||
|
||||
@@ -130,7 +128,9 @@ abstract class Route implements IRoute
|
||||
// Ensures that hostnames/domains will work with parameters
|
||||
$url = '/' . ltrim($url, '/');
|
||||
|
||||
if (preg_match_all('/' . $regex . '/u', $route, $parameters) > 0) {
|
||||
if ((bool)preg_match_all('/' . $regex . '/u', $route, $parameters) === false) {
|
||||
$urlRegex = preg_quote($route, '/');
|
||||
} else {
|
||||
|
||||
$urlParts = preg_split('/((\-?\/?)\{[^}]+\})/', $route);
|
||||
|
||||
@@ -156,7 +156,6 @@ abstract class Route implements IRoute
|
||||
}
|
||||
|
||||
$regex = sprintf('(?:\/|\-)%1$s(?P<%2$s>%3$s)%1$s', $parameters[2][$key], $name, $regex);
|
||||
|
||||
}
|
||||
|
||||
$urlParts[$key] = preg_quote($t, '/') . $regex;
|
||||
@@ -164,26 +163,23 @@ abstract class Route implements IRoute
|
||||
|
||||
$urlRegex = implode('', $urlParts);
|
||||
|
||||
} else {
|
||||
$urlRegex = preg_quote($route, '/');
|
||||
}
|
||||
|
||||
if (preg_match(sprintf($this->urlRegex, $urlRegex), $url, $matches) > 0) {
|
||||
if ((bool)preg_match(sprintf($this->urlRegex, $urlRegex), $url, $matches) === false) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$values = [];
|
||||
$values = [];
|
||||
|
||||
if (isset($parameters[1]) === true) {
|
||||
if (isset($parameters[1]) === true) {
|
||||
|
||||
/* Only take matched parameters with name */
|
||||
foreach ((array)$parameters[1] as $name) {
|
||||
$values[$name] = (isset($matches[$name]) && $matches[$name] !== '') ? $matches[$name] : null;
|
||||
}
|
||||
/* Only take matched parameters with name */
|
||||
foreach ((array)$parameters[1] as $name) {
|
||||
$values[$name] = (isset($matches[$name]) && $matches[$name] !== '') ? $matches[$name] : null;
|
||||
}
|
||||
|
||||
return $values;
|
||||
}
|
||||
|
||||
return null;
|
||||
return $values;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -253,6 +249,9 @@ abstract class Route implements IRoute
|
||||
{
|
||||
$this->group = $group;
|
||||
|
||||
/* Add/merge parent settings with child */
|
||||
$this->setSettings($group->toArray(), true);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
@@ -545,7 +544,7 @@ abstract class Route implements IRoute
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string|array
|
||||
* @return array
|
||||
*/
|
||||
public function getMiddlewares()
|
||||
{
|
||||
|
||||
@@ -88,6 +88,10 @@ class RouteController extends LoadableRoute implements IControllerRoute
|
||||
|
||||
public function matchRoute($url, Request $request)
|
||||
{
|
||||
if($this->getGroup() !== null && $this->getGroup()->matchRoute($url, $request) === false) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Match global regular-expression for route */
|
||||
$regexMatch = $this->matchRegex($request, $url);
|
||||
|
||||
|
||||
@@ -48,6 +48,10 @@ class RouteGroup extends Route implements IGroupRoute
|
||||
*/
|
||||
public function matchRoute($url, Request $request)
|
||||
{
|
||||
if($this->getGroup() !== null && $this->getGroup()->matchRoute($url, $request) === false) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Skip if prefix doesn't match */
|
||||
if ($this->prefix !== null && stripos($url, $this->prefix) === false) {
|
||||
return false;
|
||||
|
||||
@@ -17,6 +17,10 @@ class RoutePartialGroup extends RouteGroup implements IPartialGroupRoute
|
||||
*/
|
||||
public function matchRoute($url, Request $request)
|
||||
{
|
||||
if($this->getGroup() !== null && $this->getGroup()->matchRoute($url, $request) === false) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($this->prefix !== null) {
|
||||
/* Parse parameters from current route */
|
||||
$parameters = $this->parseParameters($this->prefix, $url);
|
||||
|
||||
@@ -79,6 +79,10 @@ class RouteResource extends LoadableRoute implements IControllerRoute
|
||||
|
||||
public function matchRoute($url, Request $request)
|
||||
{
|
||||
if($this->getGroup() !== null && $this->getGroup()->matchRoute($url, $request) === false) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Match global regular-expression for route */
|
||||
$regexMatch = $this->matchRegex($request, $url);
|
||||
|
||||
|
||||
@@ -14,6 +14,10 @@ class RouteUrl extends LoadableRoute
|
||||
|
||||
public function matchRoute($url, Request $request)
|
||||
{
|
||||
if($this->getGroup() !== null && $this->getGroup()->matchRoute($url, $request) === false) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Match global regular-expression for route */
|
||||
$regexMatch = $this->matchRegex($request, $url);
|
||||
|
||||
|
||||
+120
-116
@@ -2,6 +2,7 @@
|
||||
|
||||
namespace Pecee\SimpleRouter;
|
||||
|
||||
use Pecee\Exceptions\InvalidArgumentException;
|
||||
use Pecee\Handlers\IExceptionHandler;
|
||||
use Pecee\Http\Middleware\BaseCsrfVerifier;
|
||||
use Pecee\Http\Request;
|
||||
@@ -16,12 +17,6 @@ use Pecee\SimpleRouter\Route\IRoute;
|
||||
class Router
|
||||
{
|
||||
|
||||
/**
|
||||
* The instance of this class
|
||||
* @var static
|
||||
*/
|
||||
protected static $instance;
|
||||
|
||||
/**
|
||||
* Current request
|
||||
* @var Request
|
||||
@@ -71,11 +66,18 @@ class Router
|
||||
*/
|
||||
protected $exceptionHandlers;
|
||||
|
||||
/**
|
||||
* Router constructor.
|
||||
* @throws \Pecee\Http\Exceptions\MalformedUrlException
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->reset();
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws \Pecee\Http\Exceptions\MalformedUrlException
|
||||
*/
|
||||
public function reset()
|
||||
{
|
||||
$this->processingRoute = false;
|
||||
@@ -95,52 +97,64 @@ class Router
|
||||
public function addRoute(IRoute $route)
|
||||
{
|
||||
/*
|
||||
* If a route is currently being processed, that means that the
|
||||
* route being added are rendered from the parent routes callback,
|
||||
* so we add them to the stack instead.
|
||||
* If a route is currently being processed, that means that the route being added are rendered from the parent
|
||||
* routes callback, so we add them to the stack instead.
|
||||
*/
|
||||
if ($this->processingRoute === true) {
|
||||
$this->routeStack[] = $route;
|
||||
} else {
|
||||
$this->routes[] = $route;
|
||||
return $route;
|
||||
}
|
||||
|
||||
$this->routes[] = $route;
|
||||
return $route;
|
||||
}
|
||||
|
||||
/**
|
||||
* Render and process any new routes added.
|
||||
*
|
||||
* @param IRoute $route
|
||||
* @throws NotFoundHttpException
|
||||
*/
|
||||
protected function renderAndProcess(IRoute $route) {
|
||||
|
||||
$this->processingRoute = true;
|
||||
$route->renderRoute($this->request);
|
||||
$this->processingRoute = false;
|
||||
|
||||
if (count($this->routeStack) !== 0) {
|
||||
|
||||
/* Pop and grab the routes added when executing group callback earlier */
|
||||
$stack = $this->routeStack;
|
||||
$this->routeStack = [];
|
||||
|
||||
/* Route any routes added to the stack */
|
||||
$this->processRoutes($stack, $route);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Process added routes.
|
||||
*
|
||||
* @param array $routes
|
||||
* @param IGroupRoute|null $group
|
||||
* @param IRoute|null $parent
|
||||
* @throws NotFoundHttpException
|
||||
*/
|
||||
protected function processRoutes(array $routes, IGroupRoute $group = null, IRoute $parent = null)
|
||||
protected function processRoutes(array $routes, IGroupRoute $group = null)
|
||||
{
|
||||
// Loop through each route-request
|
||||
$max = count($routes) - 1;
|
||||
|
||||
$exceptionHandlers = [];
|
||||
|
||||
$url = ($this->request->getRewriteUrl() !== null) ? $this->request->getRewriteUrl() : $this->request->getUri()->getPath();
|
||||
// Stop processing routes if no valid route is found.
|
||||
if($this->request->getRewriteRoute() === null && $this->request->getUrl() === null) {
|
||||
return;
|
||||
}
|
||||
|
||||
for ($i = $max; $i >= 0; $i--) {
|
||||
$url = ($this->request->getRewriteUrl() !== null) ? $this->request->getRewriteUrl() : $this->request->getUrl()->getPath();
|
||||
|
||||
$route = $routes[$i];
|
||||
|
||||
if ($parent !== null) {
|
||||
|
||||
/* Add the parent route */
|
||||
$route->setParent($parent);
|
||||
|
||||
/* Add/merge parent settings with child */
|
||||
$route->setSettings($parent->toArray(), true);
|
||||
|
||||
}
|
||||
/* @var $route IRoute */
|
||||
foreach ($routes as $route) {
|
||||
|
||||
if ($group !== null) {
|
||||
|
||||
/* Add the parent group */
|
||||
$route->setGroup($group);
|
||||
}
|
||||
@@ -148,8 +162,6 @@ class Router
|
||||
/* @var $route IGroupRoute */
|
||||
if ($route instanceof IGroupRoute) {
|
||||
|
||||
$group = $route;
|
||||
|
||||
if ($route->matchRoute($url, $this->request) === true) {
|
||||
|
||||
/* Add exception handlers */
|
||||
@@ -159,36 +171,24 @@ class Router
|
||||
}
|
||||
|
||||
/* Only render partial group if it matches */
|
||||
if ($route instanceof IPartialGroupRoute) {
|
||||
$this->processingRoute = true;
|
||||
$route->renderRoute($this->request);
|
||||
$this->processingRoute = false;
|
||||
if ($route instanceof IPartialGroupRoute === true) {
|
||||
$this->renderAndProcess($route);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (($route instanceof IPartialGroupRoute) === false) {
|
||||
$this->processingRoute = true;
|
||||
$route->renderRoute($this->request);
|
||||
$this->processingRoute = false;
|
||||
if ($route instanceof IPartialGroupRoute === false) {
|
||||
$this->renderAndProcess($route);
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($route instanceof ILoadableRoute) {
|
||||
if ($route instanceof ILoadableRoute === true) {
|
||||
|
||||
/* Add the route to the map, so we can find the active one when all routes has been loaded */
|
||||
$this->processedRoutes[] = $route;
|
||||
}
|
||||
|
||||
if (count($this->routeStack) !== 0) {
|
||||
|
||||
/* Pop and grab the routes added when executing group callback earlier */
|
||||
$stack = $this->routeStack;
|
||||
$this->routeStack = [];
|
||||
|
||||
/* Route any routes added to the stack */
|
||||
$this->processRoutes($stack, $route, $group);
|
||||
}
|
||||
}
|
||||
|
||||
$this->exceptionHandlers = array_merge($exceptionHandlers, $this->exceptionHandlers);
|
||||
@@ -202,15 +202,9 @@ class Router
|
||||
public function loadRoutes()
|
||||
{
|
||||
/* Initialize boot-managers */
|
||||
if (count($this->bootManagers) !== 0) {
|
||||
|
||||
$max = count($this->bootManagers) - 1;
|
||||
|
||||
/* @var $manager IRouterBootManager */
|
||||
for ($i = $max; $i >= 0; $i--) {
|
||||
$manager = $this->bootManagers[$i];
|
||||
$manager->boot($this->request);
|
||||
}
|
||||
/* @var $manager IRouterBootManager */
|
||||
foreach ($this->bootManagers as $manager) {
|
||||
$manager->boot($this->request);
|
||||
}
|
||||
|
||||
/* Loop through each route-request */
|
||||
@@ -239,16 +233,14 @@ class Router
|
||||
/* Verify csrf token for request */
|
||||
$this->csrfVerifier->handle($this->request);
|
||||
}
|
||||
} else {
|
||||
$this->request->setHasRewrite(false);
|
||||
}
|
||||
|
||||
$url = ($this->request->getRewriteUrl() !== null) ? $this->request->getRewriteUrl() : $this->request->getUri()->getPath();
|
||||
|
||||
$max = count($this->processedRoutes) - 1;
|
||||
$url = ($this->request->getRewriteUrl() !== null) ? $this->request->getRewriteUrl() : $this->request->getUrl()->getPath();
|
||||
|
||||
/* @var $route ILoadableRoute */
|
||||
for ($i = $max; $i >= 0; $i--) {
|
||||
|
||||
$route = $this->processedRoutes[$i];
|
||||
foreach ($this->processedRoutes as $key => $route) {
|
||||
|
||||
/* If the route matches */
|
||||
if ($route->matchRoute($url, $this->request) === true) {
|
||||
@@ -261,29 +253,28 @@ class Router
|
||||
|
||||
$route->loadMiddleware($this->request);
|
||||
|
||||
$rewriteRoute = $this->request->getRewriteRoute();
|
||||
|
||||
if ($rewriteRoute !== null) {
|
||||
$rewriteRoute->loadMiddleware($this->request);
|
||||
|
||||
return $rewriteRoute->renderRoute($this->request);
|
||||
}
|
||||
|
||||
/* If the request has changed */
|
||||
$rewriteUrl = $this->request->getRewriteUrl();
|
||||
|
||||
if ($rewriteUrl !== null && $rewriteUrl !== $url) {
|
||||
unset($this->processedRoutes[$i]);
|
||||
$this->processedRoutes = array_values($this->processedRoutes);
|
||||
if ($this->hasRewrite($url) === true) {
|
||||
unset($this->processedRoutes[$key]);
|
||||
|
||||
return $this->routeRequest(true);
|
||||
}
|
||||
|
||||
/* Render route */
|
||||
$routeNotAllowed = false;
|
||||
|
||||
$this->request->setLoadedRoute($route);
|
||||
|
||||
return $route->renderRoute($this->request);
|
||||
$output = $route->renderRoute($this->request);
|
||||
|
||||
if ($output !== null) {
|
||||
return $output;
|
||||
}
|
||||
|
||||
if ($this->hasRewrite($url) === true) {
|
||||
unset($this->processedRoutes[$key]);
|
||||
|
||||
return $this->routeRequest(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -292,7 +283,7 @@ class Router
|
||||
}
|
||||
|
||||
if ($routeNotAllowed === true) {
|
||||
$message = sprintf('Route "%s" or method "%s" not allowed.', $this->request->getUri()->getPath(), $this->request->getMethod());
|
||||
$message = sprintf('Route "%s" or method "%s" not allowed.', $this->request->getUrl()->getPath(), $this->request->getMethod());
|
||||
$this->handleException(new HttpException($message, 403));
|
||||
}
|
||||
|
||||
@@ -301,9 +292,9 @@ class Router
|
||||
$rewriteUrl = $this->request->getRewriteUrl();
|
||||
|
||||
if ($rewriteUrl !== null) {
|
||||
$message = sprintf('Route not found: "%s" (rewrite from: "%s")', $rewriteUrl, $this->request->getUri()->getPath());
|
||||
$message = sprintf('Route not found: "%s" (rewrite from: "%s")', $rewriteUrl, $this->request->getUrl()->getPath());
|
||||
} else {
|
||||
$message = sprintf('Route not found: "%s"', $this->request->getUri()->getPath());
|
||||
$message = sprintf('Route not found: "%s"', $this->request->getUrl()->getPath());
|
||||
}
|
||||
|
||||
$this->handleException(new NotFoundHttpException($message, 404));
|
||||
@@ -312,6 +303,31 @@ class Router
|
||||
return null;
|
||||
}
|
||||
|
||||
protected function hasRewrite($url)
|
||||
{
|
||||
|
||||
/* If the request has changed */
|
||||
if ($this->request->hasRewrite() === true) {
|
||||
|
||||
if ($this->request->getRewriteRoute() !== null) {
|
||||
/* Render rewrite-route */
|
||||
$this->processedRoutes[] = $this->request->getRewriteRoute();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($this->request->isRewrite($url) === false) {
|
||||
|
||||
/* Render rewrite-url */
|
||||
$this->processedRoutes = array_values($this->processedRoutes);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \Exception $e
|
||||
* @throws HttpException
|
||||
@@ -320,8 +336,6 @@ class Router
|
||||
*/
|
||||
protected function handleException(\Exception $e)
|
||||
{
|
||||
$url = ($this->request->getRewriteUrl() !== null) ? $this->request->getRewriteUrl() : $this->request->getUri()->getPath();
|
||||
|
||||
/* @var $handler IExceptionHandler */
|
||||
foreach ($this->exceptionHandlers as $key => $handler) {
|
||||
|
||||
@@ -335,25 +349,13 @@ class Router
|
||||
|
||||
try {
|
||||
|
||||
if ($handler->handleError($this->request, $e) !== null) {
|
||||
$handler->handleError($this->request, $e);
|
||||
|
||||
$rewriteRoute = $this->request->getRewriteRoute();
|
||||
if ($this->request->hasRewrite() === true) {
|
||||
unset($this->exceptionHandlers[$key]);
|
||||
$this->exceptionHandlers = array_values($this->exceptionHandlers);
|
||||
|
||||
if ($rewriteRoute !== null) {
|
||||
$rewriteRoute->loadMiddleware($this->request);
|
||||
|
||||
return $rewriteRoute->renderRoute($this->request);
|
||||
}
|
||||
|
||||
$rewriteUrl = $this->request->getRewriteUrl();
|
||||
|
||||
/* If the request has changed */
|
||||
if ($rewriteUrl !== null && $rewriteUrl !== $url) {
|
||||
unset($this->exceptionHandlers[$key]);
|
||||
$this->exceptionHandlers = array_values($this->exceptionHandlers);
|
||||
|
||||
return $this->routeRequest(true);
|
||||
}
|
||||
return $this->routeRequest(true);
|
||||
}
|
||||
|
||||
} catch (\Exception $e) {
|
||||
@@ -388,12 +390,8 @@ class Router
|
||||
*/
|
||||
public function findRoute($name)
|
||||
{
|
||||
$max = count($this->processedRoutes) - 1;
|
||||
|
||||
/* @var $route ILoadableRoute */
|
||||
for ($i = $max; $i >= 0; $i--) {
|
||||
|
||||
$route = $this->processedRoutes[$i];
|
||||
foreach ($this->processedRoutes as $route) {
|
||||
|
||||
/* Check if the name matches with a name on the route. Should match either router alias or controller alias. */
|
||||
if ($route->hasName($name)) {
|
||||
@@ -447,13 +445,13 @@ class Router
|
||||
* @param string|null $name
|
||||
* @param string|array|null $parameters
|
||||
* @param array|null $getParams
|
||||
* @throws \InvalidArgumentException
|
||||
* @throws InvalidArgumentException
|
||||
* @return string
|
||||
*/
|
||||
public function getUrl($name = null, $parameters = null, $getParams = null)
|
||||
{
|
||||
if ($getParams !== null && is_array($getParams) === false) {
|
||||
throw new \InvalidArgumentException('Invalid type for getParams. Must be array or null');
|
||||
throw new InvalidArgumentException('Invalid type for getParams. Must be array or null');
|
||||
}
|
||||
|
||||
if ($name === '' && $parameters === '') {
|
||||
@@ -469,7 +467,7 @@ class Router
|
||||
|
||||
/* Return current route if no options has been specified */
|
||||
if ($name === null && $parameters === null) {
|
||||
return $this->request->getUri()->getPath() . $this->arrayToParams($getParams);
|
||||
return $this->request->getUrl()->getPath() . $this->arrayToParams($getParams);
|
||||
}
|
||||
|
||||
$loadedRoute = $this->request->getLoadedRoute();
|
||||
@@ -492,12 +490,8 @@ class Router
|
||||
|
||||
/* Loop through all the routes to see if we can find a match */
|
||||
|
||||
$max = count($this->processedRoutes) - 1;
|
||||
|
||||
/* @var $route ILoadableRoute */
|
||||
for ($i = $max; $i >= 0; $i--) {
|
||||
|
||||
$route = $this->processedRoutes[$i];
|
||||
foreach ($this->processedRoutes as $route) {
|
||||
|
||||
/* Check if the route contains the name/alias */
|
||||
if ($route->hasName($controller) === true) {
|
||||
@@ -545,6 +539,16 @@ class Router
|
||||
$this->bootManagers[] = $bootManager;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get routes that has been processed.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getProcessedRoutes()
|
||||
{
|
||||
return $this->processedRoutes;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
@@ -598,4 +602,4 @@ class Router
|
||||
return $this;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -10,11 +10,11 @@
|
||||
|
||||
namespace Pecee\SimpleRouter;
|
||||
|
||||
use Pecee\Exceptions\InvalidArgumentException;
|
||||
use Pecee\Handlers\CallbackExceptionHandler;
|
||||
use Pecee\Http\Middleware\BaseCsrfVerifier;
|
||||
use Pecee\Http\Response;
|
||||
use Pecee\SimpleRouter\Exceptions\HttpException;
|
||||
use Pecee\SimpleRouter\Exceptions\NotFoundHttpException;
|
||||
use Pecee\SimpleRouter\Route\IRoute;
|
||||
use Pecee\SimpleRouter\Route\RoutePartialGroup;
|
||||
use Pecee\SimpleRouter\Route\RouteController;
|
||||
@@ -43,9 +43,9 @@ class SimpleRouter
|
||||
protected static $router;
|
||||
|
||||
/**
|
||||
* Start/route request
|
||||
*
|
||||
* @throws HttpException|NotFoundHttpException|\Exception
|
||||
* @throws \Pecee\Http\Exceptions\MalformedUrlException
|
||||
* @throws HttpException
|
||||
* @throws \Exception
|
||||
*/
|
||||
public static function start()
|
||||
{
|
||||
@@ -66,6 +66,7 @@ class SimpleRouter
|
||||
* Base CSRF verifier
|
||||
*
|
||||
* @param BaseCsrfVerifier $baseCsrfVerifier
|
||||
* @throws \Pecee\Http\Exceptions\MalformedUrlException
|
||||
*/
|
||||
public static function csrfVerifier(BaseCsrfVerifier $baseCsrfVerifier)
|
||||
{
|
||||
@@ -77,6 +78,7 @@ class SimpleRouter
|
||||
* Perfect if you want to load pretty-urls from a file or database.
|
||||
*
|
||||
* @param IRouterBootManager $bootManager
|
||||
* @throws \Pecee\Http\Exceptions\MalformedUrlException
|
||||
*/
|
||||
public static function addBootManager(IRouterBootManager $bootManager)
|
||||
{
|
||||
@@ -89,7 +91,9 @@ class SimpleRouter
|
||||
* @param string $url
|
||||
* @param string|\Closure $callback
|
||||
* @param array|null $settings
|
||||
*
|
||||
* @return RouteUrl
|
||||
* @throws \Pecee\Http\Exceptions\MalformedUrlException
|
||||
*/
|
||||
public static function get($url, $callback, array $settings = null)
|
||||
{
|
||||
@@ -103,6 +107,7 @@ class SimpleRouter
|
||||
* @param string|\Closure $callback
|
||||
* @param array|null $settings
|
||||
* @return RouteUrl
|
||||
* @throws \Pecee\Http\Exceptions\MalformedUrlException
|
||||
*/
|
||||
public static function post($url, $callback, array $settings = null)
|
||||
{
|
||||
@@ -116,6 +121,7 @@ class SimpleRouter
|
||||
* @param string|\Closure $callback
|
||||
* @param array|null $settings
|
||||
* @return RouteUrl
|
||||
* @throws \Pecee\Http\Exceptions\MalformedUrlException
|
||||
*/
|
||||
public static function put($url, $callback, array $settings = null)
|
||||
{
|
||||
@@ -129,6 +135,7 @@ class SimpleRouter
|
||||
* @param string|\Closure $callback
|
||||
* @param array|null $settings
|
||||
* @return RouteUrl
|
||||
* @throws \Pecee\Http\Exceptions\MalformedUrlException
|
||||
*/
|
||||
public static function patch($url, $callback, array $settings = null)
|
||||
{
|
||||
@@ -142,6 +149,7 @@ class SimpleRouter
|
||||
* @param string|\Closure $callback
|
||||
* @param array|null $settings
|
||||
* @return RouteUrl
|
||||
* @throws \Pecee\Http\Exceptions\MalformedUrlException
|
||||
*/
|
||||
public static function options($url, $callback, array $settings = null)
|
||||
{
|
||||
@@ -155,6 +163,7 @@ class SimpleRouter
|
||||
* @param string|\Closure $callback
|
||||
* @param array|null $settings
|
||||
* @return RouteUrl
|
||||
* @throws \Pecee\Http\Exceptions\MalformedUrlException
|
||||
*/
|
||||
public static function delete($url, $callback, array $settings = null)
|
||||
{
|
||||
@@ -166,13 +175,14 @@ class SimpleRouter
|
||||
*
|
||||
* @param array $settings
|
||||
* @param \Closure $callback
|
||||
* @throws \InvalidArgumentException
|
||||
* @return RouteGroup
|
||||
* @throws \Pecee\Http\Exceptions\MalformedUrlException
|
||||
* @throws InvalidArgumentException
|
||||
*/
|
||||
public static function group(array $settings = [], \Closure $callback)
|
||||
{
|
||||
if (is_callable($callback) === false) {
|
||||
throw new \InvalidArgumentException('Invalid callback provided. Only functions or methods supported');
|
||||
throw new InvalidArgumentException('Invalid callback provided. Only functions or methods supported');
|
||||
}
|
||||
|
||||
$group = new RouteGroup();
|
||||
@@ -189,15 +199,16 @@ class SimpleRouter
|
||||
* parameters and which are only rendered when the url matches.
|
||||
*
|
||||
* @param string $url
|
||||
* @param array $settings
|
||||
* @param \Closure $callback
|
||||
* @throws \InvalidArgumentException
|
||||
* @param array $settings
|
||||
* @return RoutePartialGroup
|
||||
* @throws \Pecee\Http\Exceptions\MalformedUrlException
|
||||
* @throws InvalidArgumentException
|
||||
*/
|
||||
public static function partialGroup($url, \Closure $callback, array $settings = [])
|
||||
{
|
||||
if (is_callable($callback) === false) {
|
||||
throw new \InvalidArgumentException('Invalid callback provided. Only functions or methods supported');
|
||||
throw new InvalidArgumentException('Invalid callback provided. Only functions or methods supported');
|
||||
}
|
||||
|
||||
$settings['prefix'] = $url;
|
||||
@@ -219,6 +230,7 @@ class SimpleRouter
|
||||
* @param array|null $settings
|
||||
* @see SimpleRouter::form
|
||||
* @return RouteUrl
|
||||
* @throws \Pecee\Http\Exceptions\MalformedUrlException
|
||||
*/
|
||||
public static function basic($url, $callback, array $settings = null)
|
||||
{
|
||||
@@ -234,6 +246,7 @@ class SimpleRouter
|
||||
* @param array|null $settings
|
||||
* @see SimpleRouter::form
|
||||
* @return RouteUrl
|
||||
* @throws \Pecee\Http\Exceptions\MalformedUrlException
|
||||
*/
|
||||
public static function form($url, $callback, array $settings = null)
|
||||
{
|
||||
@@ -248,6 +261,7 @@ class SimpleRouter
|
||||
* @param string|\Closure $callback
|
||||
* @param array|null $settings
|
||||
* @return RouteUrl|IRoute
|
||||
* @throws \Pecee\Http\Exceptions\MalformedUrlException
|
||||
*/
|
||||
public static function match(array $requestMethods, $url, $callback, array $settings = null)
|
||||
{
|
||||
@@ -271,6 +285,7 @@ class SimpleRouter
|
||||
* @param string|\Closure $callback
|
||||
* @param array|null $settings
|
||||
* @return RouteUrl|IRoute
|
||||
* @throws \Pecee\Http\Exceptions\MalformedUrlException
|
||||
*/
|
||||
public static function all($url, $callback, array $settings = null)
|
||||
{
|
||||
@@ -293,6 +308,7 @@ class SimpleRouter
|
||||
* @param string $controller
|
||||
* @param array|null $settings
|
||||
* @return RouteController|IRoute
|
||||
* @throws \Pecee\Http\Exceptions\MalformedUrlException
|
||||
*/
|
||||
public static function controller($url, $controller, array $settings = null)
|
||||
{
|
||||
@@ -315,6 +331,7 @@ class SimpleRouter
|
||||
* @param string $controller
|
||||
* @param array|null $settings
|
||||
* @return RouteResource|IRoute
|
||||
* @throws \Pecee\Http\Exceptions\MalformedUrlException
|
||||
*/
|
||||
public static function resource($url, $controller, array $settings = null)
|
||||
{
|
||||
@@ -335,6 +352,7 @@ class SimpleRouter
|
||||
*
|
||||
* @param \Closure $callback
|
||||
* @return CallbackExceptionHandler $callbackHandler
|
||||
* @throws \Pecee\Http\Exceptions\MalformedUrlException
|
||||
*/
|
||||
public static function error(\Closure $callback)
|
||||
{
|
||||
@@ -367,8 +385,9 @@ class SimpleRouter
|
||||
* @param string|null $name
|
||||
* @param string|array|null $parameters
|
||||
* @param array|null $getParams
|
||||
* @throws \Exception
|
||||
* @throws \Pecee\Exceptions\InvalidArgumentException
|
||||
* @return string
|
||||
* @throws \Pecee\Http\Exceptions\MalformedUrlException
|
||||
*/
|
||||
public static function getUrl($name = null, $parameters = null, $getParams = null)
|
||||
{
|
||||
@@ -379,6 +398,7 @@ class SimpleRouter
|
||||
* Get the request
|
||||
*
|
||||
* @return \Pecee\Http\Request
|
||||
* @throws \Pecee\Http\Exceptions\MalformedUrlException
|
||||
*/
|
||||
public static function request()
|
||||
{
|
||||
@@ -389,6 +409,7 @@ class SimpleRouter
|
||||
* Get the response object
|
||||
*
|
||||
* @return Response
|
||||
* @throws \Pecee\Http\Exceptions\MalformedUrlException
|
||||
*/
|
||||
public static function response()
|
||||
{
|
||||
@@ -403,6 +424,7 @@ class SimpleRouter
|
||||
* Returns the router instance
|
||||
*
|
||||
* @return Router
|
||||
* @throws \Pecee\Http\Exceptions\MalformedUrlException
|
||||
*/
|
||||
public static function router()
|
||||
{
|
||||
|
||||
@@ -7,7 +7,7 @@ class ExceptionHandlerFirst implements \Pecee\Handlers\IExceptionHandler
|
||||
global $stack;
|
||||
$stack[] = static::class;
|
||||
|
||||
$request->setUri(new \Pecee\Http\Uri('/'));
|
||||
$request->setUrl('/');
|
||||
return $request;
|
||||
}
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ class ExceptionHandlerSecond implements \Pecee\Handlers\IExceptionHandler
|
||||
global $stack;
|
||||
$stack[] = static::class;
|
||||
|
||||
$request->setUri(new \Pecee\Http\Uri('/'));
|
||||
$request->setUrl('/');
|
||||
return $request;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
<?php
|
||||
|
||||
use Pecee\Http\Middleware\IMiddleware;
|
||||
use Pecee\Http\Request;
|
||||
|
||||
class RewriteMiddleware implements IMiddleware {
|
||||
|
||||
public function handle(Request $request) {
|
||||
|
||||
$request->setRewriteCallback(function() {
|
||||
return 'ok';
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -3,18 +3,18 @@
|
||||
class TestRouter extends \Pecee\SimpleRouter\SimpleRouter
|
||||
{
|
||||
|
||||
public static function debugNoReset($testUri, $testMethod = 'get')
|
||||
public static function debugNoReset($testUrl, $testMethod = 'get')
|
||||
{
|
||||
static::request()->setUri(new \Pecee\Http\Uri($testUri));
|
||||
static::request()->setUrl($testUrl);
|
||||
static::request()->setMethod($testMethod);
|
||||
|
||||
static::start();
|
||||
}
|
||||
|
||||
public static function debug($testUri, $testMethod = 'get')
|
||||
public static function debug($testUrl, $testMethod = 'get')
|
||||
{
|
||||
try {
|
||||
static::debugNoReset($testUri, $testMethod);
|
||||
static::debugNoReset($testUrl, $testMethod);
|
||||
} catch(\Exception $e) {
|
||||
static::router()->reset();
|
||||
throw $e;
|
||||
@@ -24,13 +24,13 @@ class TestRouter extends \Pecee\SimpleRouter\SimpleRouter
|
||||
|
||||
}
|
||||
|
||||
public static function debugOutput($testUri, $testMethod = 'get')
|
||||
public static function debugOutput($testUrl, $testMethod = 'get')
|
||||
{
|
||||
$response = null;
|
||||
|
||||
// Route request
|
||||
ob_start();
|
||||
static::debug($testUri, $testMethod);
|
||||
static::debug($testUrl, $testMethod);
|
||||
$response = ob_get_contents();
|
||||
ob_end_clean();
|
||||
|
||||
|
||||
+104
-5
@@ -5,6 +5,7 @@ require_once 'Dummy/Handler/ExceptionHandlerFirst.php';
|
||||
require_once 'Dummy/Handler/ExceptionHandlerSecond.php';
|
||||
require_once 'Dummy/Handler/ExceptionHandlerThird.php';
|
||||
require_once 'Helpers/TestRouter.php';
|
||||
require_once 'Dummy/Middlewares/RewriteMiddleware.php';
|
||||
|
||||
class RouteRewriteTest extends PHPUnit_Framework_TestCase
|
||||
{
|
||||
@@ -33,9 +34,9 @@ class RouteRewriteTest extends PHPUnit_Framework_TestCase
|
||||
global $stack;
|
||||
$stack = [];
|
||||
|
||||
TestRouter::group(['exceptionHandler' => [ExceptionHandlerFirst::class, ExceptionHandlerSecond::class]], function () {
|
||||
TestRouter::group(['exceptionHandler' => [ExceptionHandlerFirst::class, ExceptionHandlerSecond::class]], function () use ($stack) {
|
||||
|
||||
TestRouter::group(['exceptionHandler' => ExceptionHandlerThird::class], function () {
|
||||
TestRouter::group(['exceptionHandler' => ExceptionHandlerThird::class], function () use ($stack) {
|
||||
|
||||
TestRouter::get('/my-path', 'DummyController@method1');
|
||||
|
||||
@@ -64,10 +65,8 @@ class RouteRewriteTest extends PHPUnit_Framework_TestCase
|
||||
|
||||
TestRouter::error(function (\Pecee\Http\Request $request, \Exception $error) {
|
||||
|
||||
if (strtolower($request->getUri()->getPath()) == '/my/test') {
|
||||
if (strtolower($request->getUrl()->getPath()) === '/my/test/') {
|
||||
$request->setRewriteUrl('/another-non-existing');
|
||||
|
||||
return $request;
|
||||
}
|
||||
|
||||
});
|
||||
@@ -75,4 +74,104 @@ class RouteRewriteTest extends PHPUnit_Framework_TestCase
|
||||
TestRouter::debug('/my/test', 'get');
|
||||
}
|
||||
|
||||
public function testRewriteUrlFromRoute()
|
||||
{
|
||||
|
||||
TestRouter::get('/old', function () {
|
||||
TestRouter::request()->setRewriteUrl('/new');
|
||||
});
|
||||
|
||||
TestRouter::get('/new', function () {
|
||||
echo 'ok';
|
||||
});
|
||||
|
||||
TestRouter::get('/new1', function () {
|
||||
echo 'ok';
|
||||
});
|
||||
|
||||
TestRouter::get('/new2', function () {
|
||||
echo 'ok';
|
||||
});
|
||||
|
||||
$output = TestRouter::debugOutput('/old');
|
||||
|
||||
$this->assertEquals('ok', $output);
|
||||
|
||||
}
|
||||
|
||||
public function testRewriteCallbackFromRoute()
|
||||
{
|
||||
|
||||
TestRouter::get('/old', function () {
|
||||
TestRouter::request()->setRewriteUrl('/new');
|
||||
});
|
||||
|
||||
TestRouter::get('/new', function () {
|
||||
return 'ok';
|
||||
});
|
||||
|
||||
TestRouter::get('/new1', function () {
|
||||
return 'fail';
|
||||
});
|
||||
|
||||
TestRouter::get('/new/2', function () {
|
||||
return 'fail';
|
||||
});
|
||||
|
||||
$output = TestRouter::debugOutput('/old');
|
||||
|
||||
TestRouter::router()->reset();
|
||||
|
||||
$this->assertEquals('ok', $output);
|
||||
|
||||
}
|
||||
|
||||
public function testRewriteRouteFromRoute()
|
||||
{
|
||||
|
||||
TestRouter::get('/match', function () {
|
||||
TestRouter::request()->setRewriteRoute(new \Pecee\SimpleRouter\Route\RouteUrl('/match', function () {
|
||||
return 'ok';
|
||||
}));
|
||||
});
|
||||
|
||||
TestRouter::get('/old1', function () {
|
||||
return 'fail';
|
||||
});
|
||||
|
||||
TestRouter::get('/old/2', function () {
|
||||
return 'fail';
|
||||
});
|
||||
|
||||
TestRouter::get('/new2', function () {
|
||||
return 'fail';
|
||||
});
|
||||
|
||||
$output = TestRouter::debugOutput('/match');
|
||||
|
||||
TestRouter::router()->reset();
|
||||
|
||||
$this->assertEquals('ok', $output);
|
||||
|
||||
}
|
||||
|
||||
public function testMiddlewareRewrite()
|
||||
{
|
||||
|
||||
TestRouter::group(['middleware' => 'RewriteMiddleware'], function () {
|
||||
TestRouter::get('/', function () {
|
||||
return 'fail';
|
||||
});
|
||||
|
||||
TestRouter::get('no/match', function () {
|
||||
return 'fail';
|
||||
});
|
||||
});
|
||||
|
||||
$output = TestRouter::debugOutput('/');
|
||||
|
||||
$this->assertEquals('ok', $output);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -125,6 +125,20 @@ class RouterRouteTest extends PHPUnit_Framework_TestCase
|
||||
TestRouter::debug('/my/custom-path', 'get');
|
||||
}
|
||||
|
||||
public function testParameterDefaultValue() {
|
||||
|
||||
$defaultVariable = null;
|
||||
|
||||
TestRouter::get('/my/{path?}', function($path = 'working') use(&$defaultVariable) {
|
||||
$defaultVariable = $path;
|
||||
});
|
||||
|
||||
TestRouter::debug('/my/');
|
||||
|
||||
$this->assertEquals('working', $defaultVariable);
|
||||
|
||||
}
|
||||
|
||||
public function testDefaultParameterRegex()
|
||||
{
|
||||
TestRouter::get('/my/{path}', 'DummyController@param', ['defaultParameterRegex' => '[\w\-]+']);
|
||||
|
||||
Reference in New Issue
Block a user