mirror of
https://github.com/skipperbent/simple-php-router.git
synced 2026-07-10 22:32:13 +00:00
Compare commits
35 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 5ef9349b18 | |||
| efd5159604 | |||
| 264f0a7b0f | |||
| bdfc36ed5c | |||
| 5197ae2990 | |||
| d921ae8105 | |||
| 9c701aabee | |||
| af2be14ccb | |||
| 2b0821a557 | |||
| fae2e84c98 | |||
| afc81d7005 | |||
| c90c74b88f | |||
| 05f2493304 | |||
| 0856caa9de | |||
| 35dc26d741 | |||
| 496d3e7182 | |||
| f2819f866e | |||
| b9aa348b38 | |||
| c29c52ae16 | |||
| 6547c07113 | |||
| 1fd13ed2aa | |||
| fde77969c0 | |||
| c3072e8886 | |||
| 9d5c4a2ed1 | |||
| 97753f5370 | |||
| b8634bcf79 | |||
| 6ad22a3816 | |||
| ed41cd55af | |||
| ebeca952cf | |||
| 0672e85fd7 | |||
| 927f8d7b3c | |||
| 74177a2082 | |||
| 2221bced4f | |||
| 6559278511 | |||
| 8b9698229d |
@@ -7,9 +7,31 @@ Simple, fast and yet powerful PHP router that is easy to get integrated and in a
|
|||||||
|
|
||||||
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.
|
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.
|
||||||
|
|
||||||
### Ideas and issues
|
### Feedback and development
|
||||||
|
|
||||||
If you want a great new feature or experience any issues what-so-ever, please feel free to leave an issue and i'll look into it whenever possible.
|
If you 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.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -51,6 +73,8 @@ If you want a great new feature or experience any issues what-so-ever, please fe
|
|||||||
- [CSRF-protection](#csrf-protection)
|
- [CSRF-protection](#csrf-protection)
|
||||||
- [Adding CSRF-verifier](#adding-csrf-verifier)
|
- [Adding CSRF-verifier](#adding-csrf-verifier)
|
||||||
- [Getting CSRF-token](#getting-csrf-token)
|
- [Getting CSRF-token](#getting-csrf-token)
|
||||||
|
- [Custom CSRF-verifier](#custom-csrf-verifier)
|
||||||
|
- [Custom Token-provider](#custom-token-provider)
|
||||||
|
|
||||||
- [Middlewares](#middlewares)
|
- [Middlewares](#middlewares)
|
||||||
- [Example](#example)
|
- [Example](#example)
|
||||||
@@ -212,6 +236,24 @@ Simply create a new `web.config` file in your projects `public` directory and pa
|
|||||||
</configuration>
|
</configuration>
|
||||||
```
|
```
|
||||||
|
|
||||||
|
#### Troubleshooting
|
||||||
|
|
||||||
|
If you do not have a `favicon.ico` file in your project, you can get a `NotFoundHttpException` (404 - not found).
|
||||||
|
To add `favicon.ico` to the IIS ignore-list, add the following line to the `<conditions>` group:
|
||||||
|
```
|
||||||
|
<add input="{REQUEST_FILENAME}" negate="true" pattern="favicon.ico" ignoreCase="true" />
|
||||||
|
```
|
||||||
|
|
||||||
|
You can also make one exception for files with some extensions:
|
||||||
|
```
|
||||||
|
<add input="{REQUEST_FILENAME}" pattern="\.ico|\.png|\.css|\.jpg" negate="true" ignoreCase="true" />
|
||||||
|
```
|
||||||
|
|
||||||
|
If you are using `$_SERVER['ORIG_PATH_INFO']`, you will get `\index.php\` as part of the returned value. For example:
|
||||||
|
```
|
||||||
|
/index.php/test/mypage.php
|
||||||
|
```
|
||||||
|
|
||||||
### Configuration
|
### Configuration
|
||||||
|
|
||||||
Create a new file, name it `routes.php` and place it in your library folder. This will be the file where you define all the routes for your project.
|
Create a new file, name it `routes.php` and place it in your library folder. This will be the file where you define all the routes for your project.
|
||||||
@@ -669,11 +711,57 @@ SimpleRouter::get('/page/404', 'ControllerPage@notFound', ['as' => 'page.notfoun
|
|||||||
|
|
||||||
# CSRF Protection
|
# CSRF Protection
|
||||||
|
|
||||||
Any forms posting to `POST`, `PUT` or `DELETE` routes should include the CSRF-token. We strongly recommend that you create your enable CSRF-verification on your site.
|
Any forms posting to `POST`, `PUT` or `DELETE` routes should include the CSRF-token. We strongly recommend that you enable CSRF-verification on your site to maximize security.
|
||||||
|
|
||||||
Create a new class and extend the ```BaseCsrfVerifier``` middleware class provided with simple-php-router.
|
You can use the `BaseCsrfVerifier` to enable CSRF-validation on all request. If you need to disable verification for specific urls, please refer to the "Custom CSRF-verifier" section below.
|
||||||
|
|
||||||
Add the property ```except``` with an array of the urls to the routes you would like to exclude/whitelist from the CSRF validation. Using ```*``` at the end for the url will match the entire url.
|
By default simple-php-router will use the `CookieTokenProvider` class. This provider will store the security-token in a cookie on the clients machine.
|
||||||
|
If you want to store the token elsewhere, please refer to the "Creating custom Token Provider" section below.
|
||||||
|
|
||||||
|
## Adding CSRF-verifier
|
||||||
|
|
||||||
|
When you've created your CSRF-verifier you need to tell simple-php-router that it should use it. You can do this by adding the following line in your `routes.php` file:
|
||||||
|
|
||||||
|
```php
|
||||||
|
Router::csrfVerifier(new \Demo\Middlewares\CsrfVerifier());
|
||||||
|
```
|
||||||
|
|
||||||
|
## Getting CSRF-token
|
||||||
|
|
||||||
|
When posting to any of the urls that has CSRF-verification enabled, you need post your CSRF-token or else the request will get rejected.
|
||||||
|
|
||||||
|
You can get the CSRF-token by calling the helper method:
|
||||||
|
|
||||||
|
```php
|
||||||
|
csrf_token();
|
||||||
|
```
|
||||||
|
|
||||||
|
You can also get the token directly:
|
||||||
|
|
||||||
|
```php
|
||||||
|
return Router::router()->getCsrfVerifier()->getTokenProvider()->getToken();
|
||||||
|
```
|
||||||
|
|
||||||
|
The default name/key for the input-field is `csrf_token` and is defined in the `POST_KEY` constant in the `BaseCsrfVerifier` class.
|
||||||
|
You can change the key by overwriting the constant in your own CSRF-verifier class.
|
||||||
|
|
||||||
|
**Example:**
|
||||||
|
|
||||||
|
The example below will post to the current url with a hidden field "`csrf_token`".
|
||||||
|
|
||||||
|
```html
|
||||||
|
<form method="post" action="<?= url(); ?>">
|
||||||
|
<input type="hidden" name="csrf_token" value="<?= csrf_token(); ?>">
|
||||||
|
<!-- other input elements here -->
|
||||||
|
</form>
|
||||||
|
```
|
||||||
|
|
||||||
|
## Custom CSRF-verifier
|
||||||
|
|
||||||
|
Create a new class and extend the `BaseCsrfVerifier` middleware class provided by default with the simple-php-router library.
|
||||||
|
|
||||||
|
Add the property `except` with an array of the urls to the routes you want to exclude/whitelist from the CSRF validation.
|
||||||
|
Using ```*``` at the end for the url will match the entire url.
|
||||||
|
|
||||||
**Here's a basic example on a CSRF-verifier class:**
|
**Here's a basic example on a CSRF-verifier class:**
|
||||||
|
|
||||||
@@ -691,36 +779,45 @@ class CsrfVerifier extends BaseCsrfVerifier
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
## Adding CSRF-verifier
|
## Custom Token Provider
|
||||||
|
|
||||||
When you've created your CSRF verifier - you need to tell simple-php-router that it should use it. You can do this by adding the following line in your `routes.php` file:
|
By default the `BaseCsrfVerifier` will use the `CookieTokenProvider` to store the token in a cookie on the clients machine.
|
||||||
|
|
||||||
|
If you need to store the token elsewhere, you can do that by creating your own class and implementing the `ITokenProvider` class.
|
||||||
|
|
||||||
```php
|
```php
|
||||||
Router::csrfVerifier(new \Demo\Middlewares\CsrfVerifier());
|
class SessionTokenProvider implements ITokenProvider
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Refresh existing token
|
||||||
|
*/
|
||||||
|
public function refresh()
|
||||||
|
{
|
||||||
|
// Implement your own functionality here...
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validate valid CSRF token
|
||||||
|
*
|
||||||
|
* @param string $token
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function validate($token)
|
||||||
|
{
|
||||||
|
// Implement your own functionality here...
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
## Getting CSRF-token
|
Next you need to set your custom `ITokenProvider` implementation on your `BaseCsrfVerifier` class in your routes file:
|
||||||
|
|
||||||
When posting to any of the urls that has CSRF-verification enabled, you need post your CSRF-token or else the request will get rejected.
|
|
||||||
|
|
||||||
You can get the CSRF-token by calling the helper method:
|
|
||||||
|
|
||||||
```php
|
```php
|
||||||
csrf_token();
|
$verifier = new \dscuz\Middleware\CsrfVerifier();
|
||||||
```
|
$verifier->setTokenProvider(new SessionTokenProvider());
|
||||||
|
|
||||||
The default name/key for the input-field is `csrf_token` and is defined in the `POST_KEY` constant in the `BaseCsrfVerifier` class.
|
Router::csrfVerifier($verifier);
|
||||||
You can change the key by overwriting the constant in your own CSRF-verifier class.
|
|
||||||
|
|
||||||
**Example:**
|
|
||||||
|
|
||||||
The example below will post to the current url with a hidden field "`csrf_token`".
|
|
||||||
|
|
||||||
```html
|
|
||||||
<form method="post" action="<?= url(); ?>">
|
|
||||||
<input type="hidden" name="csrf_token" value="<?= csrf_token(); ?>">
|
|
||||||
<!-- other input elements here -->
|
|
||||||
</form>
|
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
@@ -1016,6 +1113,7 @@ All object implements the `IInputItem` interface and will always contain these m
|
|||||||
- `getValue()` - returns the value of the input.
|
- `getValue()` - returns the value of the input.
|
||||||
|
|
||||||
`InputFile` has the same methods as above along with some other file-specific methods like:
|
`InputFile` has the same methods as above along with some other file-specific methods like:
|
||||||
|
- `getFilename` - get the filename.
|
||||||
- `getTmpName()` - get file temporary name.
|
- `getTmpName()` - get file temporary name.
|
||||||
- `getSize()` - get file size.
|
- `getSize()` - get file size.
|
||||||
- `move($destination)` - move file to destination.
|
- `move($destination)` - move file to destination.
|
||||||
@@ -1039,7 +1137,7 @@ $siteId = input('site_id', 2, ['post', 'get']);
|
|||||||
## Url rewriting
|
## Url rewriting
|
||||||
Sometimes it can be useful to manipulate the 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.
|
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\Router``` instance's `loadedRoute` property.
|
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 method `\Pecee\SimpleRouter\SimpleRouter::router()`.
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -73,7 +73,7 @@ function csrf_token()
|
|||||||
{
|
{
|
||||||
$baseVerifier = Router::router()->getCsrfVerifier();
|
$baseVerifier = Router::router()->getCsrfVerifier();
|
||||||
if ($baseVerifier !== null) {
|
if ($baseVerifier !== null) {
|
||||||
return $baseVerifier->getToken();
|
return $baseVerifier->getTokenProvider()->getToken();
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
|
|||||||
@@ -1,79 +0,0 @@
|
|||||||
<?php
|
|
||||||
namespace Pecee;
|
|
||||||
|
|
||||||
class CsrfToken
|
|
||||||
{
|
|
||||||
const CSRF_KEY = 'CSRF-TOKEN';
|
|
||||||
|
|
||||||
protected $token;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Generate random identifier for CSRF token
|
|
||||||
*
|
|
||||||
* @throws \RuntimeException
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
public static function generateToken()
|
|
||||||
{
|
|
||||||
if (function_exists('random_bytes')) {
|
|
||||||
return bin2hex(random_bytes(32));
|
|
||||||
}
|
|
||||||
|
|
||||||
$isSourceStrong = false;
|
|
||||||
|
|
||||||
$random = openssl_random_pseudo_bytes(32, $isSourceStrong);
|
|
||||||
if ($isSourceStrong === false || $random === false) {
|
|
||||||
throw new \RuntimeException('IV generation failed');
|
|
||||||
}
|
|
||||||
|
|
||||||
return $random;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Validate valid CSRF token
|
|
||||||
*
|
|
||||||
* @param string $token
|
|
||||||
* @return bool
|
|
||||||
*/
|
|
||||||
public function validate($token)
|
|
||||||
{
|
|
||||||
if ($token !== null && $this->getToken() !== null) {
|
|
||||||
return hash_equals($token, $this->getToken());
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set csrf token cookie
|
|
||||||
*
|
|
||||||
* @param $token
|
|
||||||
*/
|
|
||||||
public function setToken($token)
|
|
||||||
{
|
|
||||||
setcookie(static::CSRF_KEY, $token, time() + 60 * 120, '/');
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get csrf token
|
|
||||||
* @return string|null
|
|
||||||
*/
|
|
||||||
public function getToken()
|
|
||||||
{
|
|
||||||
if ($this->hasToken() === true) {
|
|
||||||
return $_COOKIE[static::CSRF_KEY];
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns whether the csrf token has been defined
|
|
||||||
* @return bool
|
|
||||||
*/
|
|
||||||
public function hasToken()
|
|
||||||
{
|
|
||||||
return isset($_COOKIE[static::CSRF_KEY]);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace Pecee\Http\Input;
|
namespace Pecee\Http\Input;
|
||||||
|
|
||||||
use Pecee\Http\Request;
|
use Pecee\Http\Request;
|
||||||
@@ -35,7 +36,7 @@ class Input
|
|||||||
public function parseInputs()
|
public function parseInputs()
|
||||||
{
|
{
|
||||||
/* Parse get requests */
|
/* Parse get requests */
|
||||||
if (count($_GET) > 0) {
|
if (count($_GET) !== 0) {
|
||||||
$this->get = $this->handleGetPost($_GET);
|
$this->get = $this->handleGetPost($_GET);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -46,12 +47,12 @@ class Input
|
|||||||
parse_str(file_get_contents('php://input'), $postVars);
|
parse_str(file_get_contents('php://input'), $postVars);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (count($postVars) > 0) {
|
if (count($postVars) !== 0) {
|
||||||
$this->post = $this->handleGetPost($postVars);
|
$this->post = $this->handleGetPost($postVars);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Parse get requests */
|
/* Parse get requests */
|
||||||
if (count($_FILES) > 0) {
|
if (count($_FILES) !== 0) {
|
||||||
$this->file = $this->parseFiles();
|
$this->file = $this->parseFiles();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -65,15 +66,15 @@ class Input
|
|||||||
// Handle array input
|
// Handle array input
|
||||||
if (is_array($value['name']) === false) {
|
if (is_array($value['name']) === false) {
|
||||||
$values['index'] = $key;
|
$values['index'] = $key;
|
||||||
$list[$key] = InputFile::createFromArray(array_merge($value, $values));
|
$list[$key] = InputFile::createFromArray($values + $value);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
$keys = [];
|
$keys = [$key];
|
||||||
|
|
||||||
$files = $this->rearrangeFiles($value['name'], $keys, $value);
|
$files = $this->rearrangeFiles($value['name'], $keys, $value);
|
||||||
|
|
||||||
if (isset($list[$key])) {
|
if (isset($list[$key]) === true) {
|
||||||
$list[$key][] = $files;
|
$list[$key][] = $files;
|
||||||
} else {
|
} else {
|
||||||
$list[$key] = $files;
|
$list[$key] = $files;
|
||||||
@@ -87,40 +88,30 @@ class Input
|
|||||||
protected function rearrangeFiles(array $values, &$index, $original)
|
protected function rearrangeFiles(array $values, &$index, $original)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
$originalIndex = $index[0];
|
||||||
|
array_shift($index);
|
||||||
|
|
||||||
$output = [];
|
$output = [];
|
||||||
|
|
||||||
$getItem = function ($key, $property = 'name') use ($original, $index) {
|
|
||||||
|
|
||||||
$path = $original[$property];
|
|
||||||
|
|
||||||
$fileValues = array_values($index);
|
|
||||||
|
|
||||||
foreach ($fileValues as $i) {
|
|
||||||
$path = $path[$i];
|
|
||||||
}
|
|
||||||
|
|
||||||
return $path[$key];
|
|
||||||
};
|
|
||||||
|
|
||||||
foreach ($values as $key => $value) {
|
foreach ($values as $key => $value) {
|
||||||
|
|
||||||
if (is_array($getItem($key)) === false) {
|
if (is_array($original['name'][$key]) === false) {
|
||||||
|
|
||||||
$file = InputFile::createFromArray([
|
$file = InputFile::createFromArray([
|
||||||
'index' => $key,
|
'index' => (empty($key) === true && empty($originalIndex) === false) ? $originalIndex : $key,
|
||||||
'filename' => $getItem($key),
|
'name' => $original['name'][$key],
|
||||||
'error' => $getItem($key, 'error'),
|
'error' => $original['error'][$key],
|
||||||
'tmp_name' => $getItem($key, 'tmp_name'),
|
'tmp_name' => $original['tmp_name'][$key],
|
||||||
'type' => $getItem($key, 'type'),
|
'type' => $original['type'][$key],
|
||||||
'size' => $getItem($key, 'size'),
|
'size' => $original['size'][$key],
|
||||||
]);
|
]);
|
||||||
|
|
||||||
if (isset($output[$key])) {
|
if (isset($output[$key]) === true) {
|
||||||
$output[$key][] = $file;
|
$output[$key][] = $file;
|
||||||
} else {
|
continue;
|
||||||
$output[$key] = $file;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$output[$key] = $file;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -128,7 +119,7 @@ class Input
|
|||||||
|
|
||||||
$files = $this->rearrangeFiles($value, $index, $original);
|
$files = $this->rearrangeFiles($value, $index, $original);
|
||||||
|
|
||||||
if (isset($output[$key])) {
|
if (isset($output[$key]) === true) {
|
||||||
$output[$key][] = $files;
|
$output[$key][] = $files;
|
||||||
} else {
|
} else {
|
||||||
$output[$key] = $files;
|
$output[$key] = $files;
|
||||||
@@ -143,13 +134,7 @@ class Input
|
|||||||
{
|
{
|
||||||
$list = [];
|
$list = [];
|
||||||
|
|
||||||
$max = count($array) - 1;
|
foreach ($array as $key => $value) {
|
||||||
$keys = array_keys($array);
|
|
||||||
|
|
||||||
for ($i = $max; $i >= 0; $i--) {
|
|
||||||
|
|
||||||
$key = $keys[$i];
|
|
||||||
$value = $array[$key];
|
|
||||||
|
|
||||||
// Handle array input
|
// Handle array input
|
||||||
if (is_array($value) === false) {
|
if (is_array($value) === false) {
|
||||||
@@ -217,15 +202,15 @@ class Input
|
|||||||
|
|
||||||
$element = null;
|
$element = null;
|
||||||
|
|
||||||
if ($methods === null || in_array('get', $methods)) {
|
if ($methods === null || in_array('get', $methods, false) === true) {
|
||||||
$element = $this->findGet($index);
|
$element = $this->findGet($index);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (($element === null && $methods === null) || ($methods !== null && in_array('post', $methods))) {
|
if (($element === null && $methods === null) || ($methods !== null && in_array('post', $methods, false) === true)) {
|
||||||
$element = $this->findPost($index);
|
$element = $this->findPost($index);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (($element === null && $methods === null) || ($methods !== null && in_array('file', $methods))) {
|
if (($element === null && $methods === null) || ($methods !== null && in_array('file', $methods, false) === true)) {
|
||||||
$element = $this->findFile($index);
|
$element = $this->findFile($index);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace Pecee\Http\Input;
|
namespace Pecee\Http\Input;
|
||||||
|
|
||||||
class InputFile implements IInputItem
|
class InputFile implements IInputItem
|
||||||
@@ -16,7 +17,7 @@ class InputFile implements IInputItem
|
|||||||
$this->index = $index;
|
$this->index = $index;
|
||||||
|
|
||||||
// Make the name human friendly, by replace _ with space
|
// Make the name human friendly, by replace _ with space
|
||||||
$this->name = ucfirst(str_replace('_', ' ', $this->index));
|
$this->name = ucfirst(str_replace('_', ' ', strtolower($this->index)));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -28,19 +29,19 @@ class InputFile implements IInputItem
|
|||||||
*/
|
*/
|
||||||
public static function createFromArray(array $values)
|
public static function createFromArray(array $values)
|
||||||
{
|
{
|
||||||
if (!isset($values['index'])) {
|
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() */
|
/* Easy way of ensuring that all indexes-are set and not filling the screen with isset() */
|
||||||
|
|
||||||
$values = array_merge([
|
$values += [
|
||||||
'tmp_name' => null,
|
'tmp_name' => null,
|
||||||
'type' => null,
|
'type' => null,
|
||||||
'size' => null,
|
'size' => null,
|
||||||
'name' => null,
|
'name' => null,
|
||||||
'error' => null,
|
'error' => null,
|
||||||
], $values);
|
];
|
||||||
|
|
||||||
return (new static($values['index']))
|
return (new static($values['index']))
|
||||||
->setSize($values['size'])
|
->setSize($values['size'])
|
||||||
@@ -267,8 +268,9 @@ class InputFile implements IInputItem
|
|||||||
'tmp_name' => $this->tmpName,
|
'tmp_name' => $this->tmpName,
|
||||||
'type' => $this->type,
|
'type' => $this->type,
|
||||||
'size' => $this->size,
|
'size' => $this->size,
|
||||||
'name' => $this->filename,
|
'name' => $this->name,
|
||||||
'error' => $this->error,
|
'error' => $this->error,
|
||||||
|
'filename' => $this->filename,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ class InputItem implements IInputItem
|
|||||||
$this->value = $value;
|
$this->value = $value;
|
||||||
|
|
||||||
// Make the name human friendly, by replace _ with space
|
// Make the name human friendly, by replace _ with space
|
||||||
$this->name = ucfirst(str_replace('_', ' ', $this->index));
|
$this->name = ucfirst(str_replace('_', ' ', strtolower($this->index)));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -2,9 +2,10 @@
|
|||||||
|
|
||||||
namespace Pecee\Http\Middleware;
|
namespace Pecee\Http\Middleware;
|
||||||
|
|
||||||
use Pecee\CsrfToken;
|
|
||||||
use Pecee\Http\Middleware\Exceptions\TokenMismatchException;
|
use Pecee\Http\Middleware\Exceptions\TokenMismatchException;
|
||||||
use Pecee\Http\Request;
|
use Pecee\Http\Request;
|
||||||
|
use Pecee\Http\Security\CookieTokenProvider;
|
||||||
|
use Pecee\Http\Security\ITokenProvider;
|
||||||
|
|
||||||
class BaseCsrfVerifier implements IMiddleware
|
class BaseCsrfVerifier implements IMiddleware
|
||||||
{
|
{
|
||||||
@@ -12,15 +13,11 @@ class BaseCsrfVerifier implements IMiddleware
|
|||||||
const HEADER_KEY = 'X-CSRF-TOKEN';
|
const HEADER_KEY = 'X-CSRF-TOKEN';
|
||||||
|
|
||||||
protected $except;
|
protected $except;
|
||||||
protected $csrfToken;
|
protected $tokenProvider;
|
||||||
protected $token;
|
|
||||||
|
|
||||||
public function __construct()
|
public function __construct()
|
||||||
{
|
{
|
||||||
$this->csrfToken = new CsrfToken();
|
$this->tokenProvider = new CookieTokenProvider();
|
||||||
|
|
||||||
// Generate or get the CSRF-Token from Cookie.
|
|
||||||
$this->token = ($this->hasToken() === false) ? $this->generateToken() : $this->csrfToken->getToken();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -30,7 +27,7 @@ class BaseCsrfVerifier implements IMiddleware
|
|||||||
*/
|
*/
|
||||||
protected function skip(Request $request)
|
protected function skip(Request $request)
|
||||||
{
|
{
|
||||||
if ($this->except === null || is_array($this->except) === false) {
|
if ($this->except === null || count($this->except) === 0) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -67,34 +64,29 @@ class BaseCsrfVerifier implements IMiddleware
|
|||||||
$token = $request->getHeader(static::HEADER_KEY);
|
$token = $request->getHeader(static::HEADER_KEY);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($this->csrfToken->validate($token) === false) {
|
if ($this->tokenProvider->validate($token) === false) {
|
||||||
throw new TokenMismatchException('Invalid csrf-token.');
|
throw new TokenMismatchException('Invalid CSRF-token.');
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Refresh existing token
|
||||||
|
$this->tokenProvider->refresh();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function generateToken()
|
public function getTokenProvider()
|
||||||
{
|
{
|
||||||
$token = CsrfToken::generateToken();
|
return $this->tokenProvider;
|
||||||
$this->csrfToken->setToken($token);
|
|
||||||
|
|
||||||
return $token;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function hasToken()
|
/**
|
||||||
|
* Set token provider
|
||||||
|
* @param ITokenProvider $provider
|
||||||
|
*/
|
||||||
|
public function setTokenProvider(ITokenProvider $provider)
|
||||||
{
|
{
|
||||||
if ($this->token !== null) {
|
$this->tokenProvider = $provider;
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return $this->csrfToken->hasToken();
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getToken()
|
|
||||||
{
|
|
||||||
return $this->token;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace Pecee\Http;
|
namespace Pecee\Http;
|
||||||
|
|
||||||
use Pecee\Http\Input\Input;
|
use Pecee\Http\Input\Input;
|
||||||
@@ -42,13 +43,7 @@ class Request
|
|||||||
{
|
{
|
||||||
$this->headers = [];
|
$this->headers = [];
|
||||||
|
|
||||||
$max = count($_SERVER) - 1;
|
foreach ($_SERVER as $key => $value) {
|
||||||
$keys = array_keys($_SERVER);
|
|
||||||
|
|
||||||
for ($i = $max; $i >= 0; $i--) {
|
|
||||||
$key = $keys[$i];
|
|
||||||
$value = $_SERVER[$key];
|
|
||||||
|
|
||||||
$this->headers[strtolower($key)] = $value;
|
$this->headers[strtolower($key)] = $value;
|
||||||
$this->headers[strtolower(str_replace('_', '-', $key))] = $value;
|
$this->headers[strtolower(str_replace('_', '-', $key))] = $value;
|
||||||
}
|
}
|
||||||
@@ -167,24 +162,7 @@ class Request
|
|||||||
*/
|
*/
|
||||||
public function getHeader($name, $defaultValue = null)
|
public function getHeader($name, $defaultValue = null)
|
||||||
{
|
{
|
||||||
if (array_key_exists(strtolower($name), $this->headers) === true) {
|
return isset($this->headers[strtolower($name)]) ? $this->headers[strtolower($name)] : $defaultValue;
|
||||||
return $this->headers[strtolower($name)];
|
|
||||||
}
|
|
||||||
|
|
||||||
$max = count($_SERVER) - 1;
|
|
||||||
$keys = array_keys($_SERVER);
|
|
||||||
|
|
||||||
for ($i = $max; $i >= 0; $i--) {
|
|
||||||
|
|
||||||
$key = $keys[$i];
|
|
||||||
$name = $_SERVER[$key];
|
|
||||||
|
|
||||||
if ($key === $name) {
|
|
||||||
return $name;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return $defaultValue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -249,26 +227,7 @@ class Request
|
|||||||
*/
|
*/
|
||||||
public function setRewriteRoute(ILoadableRoute $route)
|
public function setRewriteRoute(ILoadableRoute $route)
|
||||||
{
|
{
|
||||||
$this->rewriteRoute = $route;
|
$this->rewriteRoute = SimpleRouter::addDefaultNamespace($route);
|
||||||
|
|
||||||
$callback = $route->getCallback();
|
|
||||||
|
|
||||||
/* Only add default namespace on relative callbacks */
|
|
||||||
if ($callback === null || $callback[0] !== '\\') {
|
|
||||||
|
|
||||||
$namespace = SimpleRouter::getDefaultNamespace();
|
|
||||||
|
|
||||||
if ($namespace !== null) {
|
|
||||||
|
|
||||||
if ($this->rewriteRoute->getNamespace() !== null) {
|
|
||||||
$namespace .= '\\' . $this->rewriteRoute->getNamespace();
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->rewriteRoute->setDefaultNamespace($namespace);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,119 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Pecee\Http\Security;
|
||||||
|
|
||||||
|
class CookieTokenProvider implements ITokenProvider
|
||||||
|
{
|
||||||
|
const CSRF_KEY = 'CSRF-TOKEN';
|
||||||
|
|
||||||
|
protected $token;
|
||||||
|
protected $cookieTimeoutMinutes = 120;
|
||||||
|
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
$this->token = $this->getToken();
|
||||||
|
|
||||||
|
if ($this->token === null) {
|
||||||
|
$this->token = $this->generateToken();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generate random identifier for CSRF token
|
||||||
|
*
|
||||||
|
* @throws \RuntimeException
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function generateToken()
|
||||||
|
{
|
||||||
|
if (function_exists('random_bytes') === true) {
|
||||||
|
return bin2hex(random_bytes(32));
|
||||||
|
}
|
||||||
|
|
||||||
|
$isSourceStrong = false;
|
||||||
|
|
||||||
|
$random = openssl_random_pseudo_bytes(32, $isSourceStrong);
|
||||||
|
if ($isSourceStrong === false || $random === false) {
|
||||||
|
throw new \RuntimeException('IV generation failed');
|
||||||
|
}
|
||||||
|
|
||||||
|
return $random;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validate valid CSRF token
|
||||||
|
*
|
||||||
|
* @param string $token
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function validate($token)
|
||||||
|
{
|
||||||
|
if ($token !== null && $this->getToken() !== null) {
|
||||||
|
return hash_equals($token, $this->getToken());
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set csrf token cookie
|
||||||
|
* Overwrite this method to save the token to another storage like session etc.
|
||||||
|
*
|
||||||
|
* @param string $token
|
||||||
|
*/
|
||||||
|
public function setToken($token)
|
||||||
|
{
|
||||||
|
$this->token = $token;
|
||||||
|
setcookie(static::CSRF_KEY, $token, time() + 60 * $this->cookieTimeoutMinutes, '/');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get csrf token
|
||||||
|
* @param string|null $defaultValue
|
||||||
|
* @return string|null
|
||||||
|
*/
|
||||||
|
public function getToken($defaultValue = null)
|
||||||
|
{
|
||||||
|
$this->token = ($this->hasToken() === true) ? $_COOKIE[static::CSRF_KEY] : null;
|
||||||
|
|
||||||
|
return ($this->token !== null) ? $this->token : $defaultValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Refresh existing token
|
||||||
|
*/
|
||||||
|
public function refresh()
|
||||||
|
{
|
||||||
|
if ($this->token !== null) {
|
||||||
|
$this->setToken($this->token);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns whether the csrf token has been defined
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function hasToken()
|
||||||
|
{
|
||||||
|
return isset($_COOKIE[static::CSRF_KEY]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get timeout for cookie in minutes
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
public function getCookieTimeoutMinutes()
|
||||||
|
{
|
||||||
|
return $this->cookieTimeoutMinutes;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set cookie timeout in minutes
|
||||||
|
* @param $minutes
|
||||||
|
*/
|
||||||
|
public function setCookieTimeoutMinutes($minutes)
|
||||||
|
{
|
||||||
|
$this->cookieTimeoutMinutes = $minutes;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Pecee\Http\Security;
|
||||||
|
|
||||||
|
interface ITokenProvider
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Refresh existing token
|
||||||
|
*/
|
||||||
|
public function refresh();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validate valid CSRF token
|
||||||
|
*
|
||||||
|
* @param string $token
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function validate($token);
|
||||||
|
|
||||||
|
}
|
||||||
@@ -6,20 +6,20 @@ class Uri
|
|||||||
{
|
{
|
||||||
private $originalUrl;
|
private $originalUrl;
|
||||||
private $data = [
|
private $data = [
|
||||||
'scheme',
|
'scheme' => null,
|
||||||
'host',
|
'host' => null,
|
||||||
'port',
|
'port' => null,
|
||||||
'user',
|
'user' => null,
|
||||||
'pass',
|
'pass' => null,
|
||||||
'path',
|
'path' => null,
|
||||||
'query',
|
'query' => null,
|
||||||
'fragment',
|
'fragment' => null,
|
||||||
];
|
];
|
||||||
|
|
||||||
public function __construct($url)
|
public function __construct($url)
|
||||||
{
|
{
|
||||||
$this->originalUrl = $url;
|
$this->originalUrl = $url;
|
||||||
$this->data = array_merge($this->data, $this->parseUrl(urldecode($url)));
|
$this->data = $this->parseUrl($url) + $this->data;
|
||||||
|
|
||||||
if (isset($this->data['path']) === true && $this->data['path'] !== '/') {
|
if (isset($this->data['path']) === true && $this->data['path'] !== '/') {
|
||||||
$this->data['path'] = rtrim($this->data['path'], '/') . '/';
|
$this->data['path'] = rtrim($this->data['path'], '/') . '/';
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ abstract class LoadableRoute extends Route implements ILoadableRoute
|
|||||||
{
|
{
|
||||||
$max = count($this->getMiddlewares());
|
$max = count($this->getMiddlewares());
|
||||||
|
|
||||||
if ($max > 0) {
|
if ($max !== 0) {
|
||||||
|
|
||||||
for ($i = 0; $i < $max; $i++) {
|
for ($i = 0; $i < $max; $i++) {
|
||||||
|
|
||||||
@@ -74,7 +74,7 @@ abstract class LoadableRoute extends Route implements ILoadableRoute
|
|||||||
|
|
||||||
$regex = sprintf(static::PARAMETERS_REGEX_FORMAT, $this->paramModifiers[0], $this->paramOptionalSymbol, $this->paramModifiers[1]);
|
$regex = sprintf(static::PARAMETERS_REGEX_FORMAT, $this->paramModifiers[0], $this->paramOptionalSymbol, $this->paramModifiers[1]);
|
||||||
|
|
||||||
if (preg_match_all('/' . $regex . '/u', $this->url, $matches)) {
|
if (preg_match_all('/' . $regex . '/u', $this->url, $matches) > 0) {
|
||||||
$this->parameters = array_fill_keys($matches[1], null);
|
$this->parameters = array_fill_keys($matches[1], null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -102,7 +102,7 @@ abstract class LoadableRoute extends Route implements ILoadableRoute
|
|||||||
|
|
||||||
$group = $this->getGroup();
|
$group = $this->getGroup();
|
||||||
|
|
||||||
if ($group !== null && count($group->getDomains()) > 0) {
|
if ($group !== null && count($group->getDomains()) !== 0) {
|
||||||
$url = '//' . $group->getDomains()[0] . $url;
|
$url = '//' . $group->getDomains()[0] . $url;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -124,7 +124,7 @@ abstract class LoadableRoute extends Route implements ILoadableRoute
|
|||||||
for ($i = $max; $i >= 0; $i--) {
|
for ($i = $max; $i >= 0; $i--) {
|
||||||
$param = $keys[$i];
|
$param = $keys[$i];
|
||||||
|
|
||||||
if ($parameters === '' || (is_array($parameters) && count($parameters) === 0)) {
|
if ($parameters === '' || (is_array($parameters) === true && count($parameters) === 0)) {
|
||||||
$value = '';
|
$value = '';
|
||||||
} else {
|
} else {
|
||||||
$p = (array)$parameters;
|
$p = (array)$parameters;
|
||||||
@@ -229,15 +229,18 @@ abstract class LoadableRoute extends Route implements ILoadableRoute
|
|||||||
*/
|
*/
|
||||||
public function setSettings(array $values, $merge = false)
|
public function setSettings(array $values, $merge = false)
|
||||||
{
|
{
|
||||||
if (isset($values['as'])) {
|
if (isset($values['as']) === true) {
|
||||||
|
|
||||||
|
$name = $values['as'];
|
||||||
|
|
||||||
if ($this->name !== null && $merge !== false) {
|
if ($this->name !== null && $merge !== false) {
|
||||||
$this->setName($values['as'] . '.' . $this->name);
|
$name .= '.' . $this->name;
|
||||||
} else {
|
|
||||||
$this->setName($values['as']);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$this->setName($name);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isset($values['prefix'])) {
|
if (isset($values['prefix']) === true) {
|
||||||
$this->setUrl($values['prefix'] . $this->getUrl());
|
$this->setUrl($values['prefix'] . $this->getUrl());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -117,7 +117,7 @@ abstract class Route implements IRoute
|
|||||||
// Ensures that hostnames/domains will work with parameters
|
// Ensures that hostnames/domains will work with parameters
|
||||||
$url = '/' . ltrim($url, '/');
|
$url = '/' . ltrim($url, '/');
|
||||||
|
|
||||||
if (preg_match_all('/' . $regex . '/u', $route, $parameters)) {
|
if (preg_match_all('/' . $regex . '/u', $route, $parameters) > 0) {
|
||||||
|
|
||||||
$urlParts = preg_split('/((\-?\/?)\{[^}]+\})/', rtrim($route, '/'));
|
$urlParts = preg_split('/((\-?\/?)\{[^}]+\})/', rtrim($route, '/'));
|
||||||
|
|
||||||
@@ -361,15 +361,15 @@ abstract class Route implements IRoute
|
|||||||
$values['namespace'] = $this->namespace;
|
$values['namespace'] = $this->namespace;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (count($this->requestMethods) > 0) {
|
if (count($this->requestMethods) !== 0) {
|
||||||
$values['method'] = $this->requestMethods;
|
$values['method'] = $this->requestMethods;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (count($this->where) > 0) {
|
if (count($this->where) !== 0) {
|
||||||
$values['where'] = $this->where;
|
$values['where'] = $this->where;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (count($this->middlewares) > 0) {
|
if (count($this->middlewares) !== 0) {
|
||||||
$values['middleware'] = $this->middlewares;
|
$values['middleware'] = $this->middlewares;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -389,28 +389,28 @@ abstract class Route implements IRoute
|
|||||||
*/
|
*/
|
||||||
public function setSettings(array $values, $merge = false)
|
public function setSettings(array $values, $merge = false)
|
||||||
{
|
{
|
||||||
if ($this->namespace === null && isset($values['namespace'])) {
|
if ($this->namespace === null && isset($values['namespace']) === true) {
|
||||||
$this->setNamespace($values['namespace']);
|
$this->setNamespace($values['namespace']);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isset($values['method'])) {
|
if (isset($values['method']) === true) {
|
||||||
$this->setRequestMethods(array_merge($this->requestMethods, (array)$values['method']));
|
$this->setRequestMethods(array_merge($this->requestMethods, (array)$values['method']));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isset($values['where'])) {
|
if (isset($values['where']) === true) {
|
||||||
$this->setWhere(array_merge($this->where, (array)$values['where']));
|
$this->setWhere(array_merge($this->where, (array)$values['where']));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isset($values['parameters'])) {
|
if (isset($values['parameters']) === true) {
|
||||||
$this->setParameters(array_merge($this->parameters, (array)$values['parameters']));
|
$this->setParameters(array_merge($this->parameters, (array)$values['parameters']));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Push middleware if multiple
|
// Push middleware if multiple
|
||||||
if (isset($values['middleware'])) {
|
if (isset($values['middleware']) === true) {
|
||||||
$this->setMiddlewares(array_merge((array)$values['middleware'], $this->middlewares));
|
$this->setMiddlewares(array_merge((array)$values['middleware'], $this->middlewares));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isset($values['defaultParameterRegex'])) {
|
if (isset($values['defaultParameterRegex']) === true) {
|
||||||
$this->setDefaultParameterRegex($values['defaultParameterRegex']);
|
$this->setDefaultParameterRegex($values['defaultParameterRegex']);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -463,7 +463,7 @@ abstract class Route implements IRoute
|
|||||||
/* Sort the parameters after the user-defined param order, if any */
|
/* Sort the parameters after the user-defined param order, if any */
|
||||||
$parameters = [];
|
$parameters = [];
|
||||||
|
|
||||||
if (count($this->originalParameters) > 0) {
|
if (count($this->originalParameters) !== 0) {
|
||||||
$parameters = $this->originalParameters;
|
$parameters = $this->originalParameters;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -482,7 +482,7 @@ abstract class Route implements IRoute
|
|||||||
* If this is the first time setting parameters we store them so we
|
* If this is the first time setting parameters we store them so we
|
||||||
* later can organize the array, in case somebody tried to sort the array.
|
* later can organize the array, in case somebody tried to sort the array.
|
||||||
*/
|
*/
|
||||||
if (count($parameters) > 0 && count($this->originalParameters) === 0) {
|
if (count($parameters) !== 0 && count($this->originalParameters) === 0) {
|
||||||
$this->originalParameters = $parameters;
|
$this->originalParameters = $parameters;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace Pecee\SimpleRouter\Route;
|
namespace Pecee\SimpleRouter\Route;
|
||||||
|
|
||||||
use Pecee\Http\Request;
|
use Pecee\Http\Request;
|
||||||
@@ -76,7 +77,7 @@ class RouteController extends LoadableRoute implements IControllerRoute
|
|||||||
|
|
||||||
$group = $this->getGroup();
|
$group = $this->getGroup();
|
||||||
|
|
||||||
if ($group !== null && count($group->getDomains()) > 0) {
|
if ($group !== null && count($group->getDomains()) !== 0) {
|
||||||
$url .= '//' . $group->getDomains()[0];
|
$url .= '//' . $group->getDomains()[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -97,7 +98,7 @@ class RouteController extends LoadableRoute implements IControllerRoute
|
|||||||
$strippedUrl = trim(str_ireplace($this->url, '/', $url), '/');
|
$strippedUrl = trim(str_ireplace($this->url, '/', $url), '/');
|
||||||
$path = explode('/', $strippedUrl);
|
$path = explode('/', $strippedUrl);
|
||||||
|
|
||||||
if (count($path) > 0) {
|
if (count($path) !== 0) {
|
||||||
|
|
||||||
$method = (isset($path[0]) === false || trim($path[0]) === '') ? $this->defaultMethod : $path[0];
|
$method = (isset($path[0]) === false || trim($path[0]) === '') ? $this->defaultMethod : $path[0];
|
||||||
$this->method = $request->getMethod() . ucfirst($method);
|
$this->method = $request->getMethod() . ucfirst($method);
|
||||||
@@ -168,7 +169,7 @@ class RouteController extends LoadableRoute implements IControllerRoute
|
|||||||
*/
|
*/
|
||||||
public function setSettings(array $values, $merge = false)
|
public function setSettings(array $values, $merge = false)
|
||||||
{
|
{
|
||||||
if (isset($values['names'])) {
|
if (isset($values['names']) === true) {
|
||||||
$this->names = $values['names'];
|
$this->names = $values['names'];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ class RouteGroup extends Route implements IGroupRoute
|
|||||||
|
|
||||||
$parameters = $this->parseParameters($domain, $request->getHost(), '.*');
|
$parameters = $this->parseParameters($domain, $request->getHost(), '.*');
|
||||||
|
|
||||||
if ($parameters !== null && count($parameters) > 0) {
|
if ($parameters !== null && count($parameters) !== 0) {
|
||||||
|
|
||||||
$this->parameters = $parameters;
|
$this->parameters = $parameters;
|
||||||
|
|
||||||
@@ -146,24 +146,27 @@ class RouteGroup extends Route implements IGroupRoute
|
|||||||
public function setSettings(array $values, $merge = false)
|
public function setSettings(array $values, $merge = false)
|
||||||
{
|
{
|
||||||
|
|
||||||
if (isset($values['prefix'])) {
|
if (isset($values['prefix']) === true) {
|
||||||
$this->setPrefix($values['prefix'] . $this->prefix);
|
$this->setPrefix($values['prefix'] . $this->prefix);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($merge === false && isset($values['exceptionHandler'])) {
|
if ($merge === false && isset($values['exceptionHandler']) === true) {
|
||||||
$this->setExceptionHandlers((array)$values['exceptionHandler']);
|
$this->setExceptionHandlers((array)$values['exceptionHandler']);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($merge === false && isset($values['domain'])) {
|
if ($merge === false && isset($values['domain']) === true) {
|
||||||
$this->setDomains((array)$values['domain']);
|
$this->setDomains((array)$values['domain']);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isset($values['as'])) {
|
if (isset($values['as']) === true) {
|
||||||
|
|
||||||
|
$name = $values['as'];
|
||||||
|
|
||||||
if ($this->name !== null && $merge !== false) {
|
if ($this->name !== null && $merge !== false) {
|
||||||
$this->name = $values['as'] . '.' . $this->name;
|
$name .= '.' . $this->name;
|
||||||
} else {
|
|
||||||
$this->name = $values['as'];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$this->name = $name;
|
||||||
}
|
}
|
||||||
|
|
||||||
parent::setSettings($values, $merge);
|
parent::setSettings($values, $merge);
|
||||||
@@ -188,7 +191,7 @@ class RouteGroup extends Route implements IGroupRoute
|
|||||||
$values['as'] = $this->name;
|
$values['as'] = $this->name;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (count($this->parameters) > 0) {
|
if (count($this->parameters) !== 0) {
|
||||||
$values['parameters'] = $this->parameters;
|
$values['parameters'] = $this->parameters;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -206,11 +206,11 @@ class RouteResource extends LoadableRoute implements IControllerRoute
|
|||||||
*/
|
*/
|
||||||
public function setSettings(array $values, $merge = false)
|
public function setSettings(array $values, $merge = false)
|
||||||
{
|
{
|
||||||
if (isset($values['names'])) {
|
if (isset($values['names']) === true) {
|
||||||
$this->names = $values['names'];
|
$this->names = $values['names'];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isset($values['methods'])) {
|
if (isset($values['methods']) === true) {
|
||||||
$this->methodNames = $values['methods'];
|
$this->methodNames = $values['methods'];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -154,7 +154,7 @@ class Router
|
|||||||
if ($route->matchRoute($url, $this->request) === true) {
|
if ($route->matchRoute($url, $this->request) === true) {
|
||||||
|
|
||||||
/* Add exception handlers */
|
/* Add exception handlers */
|
||||||
if (count($route->getExceptionHandlers()) > 0) {
|
if (count($route->getExceptionHandlers()) !== 0) {
|
||||||
/** @noinspection AdditionOperationOnArraysInspection */
|
/** @noinspection AdditionOperationOnArraysInspection */
|
||||||
$exceptionHandlers += $route->getExceptionHandlers();
|
$exceptionHandlers += $route->getExceptionHandlers();
|
||||||
}
|
}
|
||||||
@@ -181,7 +181,7 @@ class Router
|
|||||||
$this->processedRoutes[] = $route;
|
$this->processedRoutes[] = $route;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (count($this->routeStack) > 0) {
|
if (count($this->routeStack) !== 0) {
|
||||||
|
|
||||||
/* Pop and grab the routes added when executing group callback earlier */
|
/* Pop and grab the routes added when executing group callback earlier */
|
||||||
$stack = $this->routeStack;
|
$stack = $this->routeStack;
|
||||||
@@ -203,7 +203,7 @@ class Router
|
|||||||
public function loadRoutes()
|
public function loadRoutes()
|
||||||
{
|
{
|
||||||
/* Initialize boot-managers */
|
/* Initialize boot-managers */
|
||||||
if (count($this->bootManagers) > 0) {
|
if (count($this->bootManagers) !== 0) {
|
||||||
|
|
||||||
$max = count($this->bootManagers) - 1;
|
$max = count($this->bootManagers) - 1;
|
||||||
|
|
||||||
@@ -247,7 +247,7 @@ class Router
|
|||||||
if ($route->matchRoute($url, $this->request) === true) {
|
if ($route->matchRoute($url, $this->request) === true) {
|
||||||
|
|
||||||
/* Check if request method matches */
|
/* Check if request method matches */
|
||||||
if (count($route->getRequestMethods()) > 0 && in_array($this->request->getMethod(), $route->getRequestMethods(), false) === false) {
|
if (count($route->getRequestMethods()) !== 0 && in_array($this->request->getMethod(), $route->getRequestMethods(), false) === false) {
|
||||||
$routeNotAllowed = true;
|
$routeNotAllowed = true;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -285,7 +285,7 @@ class Router
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ($routeNotAllowed === true) {
|
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->getUri()->getPath(), $this->request->getMethod());
|
||||||
$this->handleException(new HttpException($message, 403));
|
$this->handleException(new HttpException($message, 403));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -363,7 +363,7 @@ class Router
|
|||||||
|
|
||||||
public function arrayToParams(array $getParams = [], $includeEmpty = true)
|
public function arrayToParams(array $getParams = [], $includeEmpty = true)
|
||||||
{
|
{
|
||||||
if (count($getParams) > 0) {
|
if (count($getParams) !== 0) {
|
||||||
|
|
||||||
if ($includeEmpty === false) {
|
if ($includeEmpty === false) {
|
||||||
$getParams = array_filter($getParams, function ($item) {
|
$getParams = array_filter($getParams, function ($item) {
|
||||||
@@ -497,7 +497,7 @@ class Router
|
|||||||
$route = $this->processedRoutes[$i];
|
$route = $this->processedRoutes[$i];
|
||||||
|
|
||||||
/* Check if the route contains the name/alias */
|
/* Check if the route contains the name/alias */
|
||||||
if ($route->hasName($controller)) {
|
if ($route->hasName($controller) === true) {
|
||||||
return $route->findUrl($method, $parameters, $name) . $this->arrayToParams($getParams);
|
return $route->findUrl($method, $parameters, $name) . $this->arrayToParams($getParams);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -420,14 +420,14 @@ class SimpleRouter
|
|||||||
* @param IRoute $route
|
* @param IRoute $route
|
||||||
* @return IRoute
|
* @return IRoute
|
||||||
*/
|
*/
|
||||||
protected static function addDefaultNamespace(IRoute $route)
|
public static function addDefaultNamespace(IRoute $route)
|
||||||
{
|
{
|
||||||
if (static::$defaultNamespace !== null) {
|
if (static::$defaultNamespace !== null) {
|
||||||
|
|
||||||
$callback = $route->getCallback();
|
$callback = $route->getCallback();
|
||||||
|
|
||||||
/* Only add default namespace on relative callbacks */
|
/* Only add default namespace on relative callbacks */
|
||||||
if ($callback === null || $callback[0] !== '\\') {
|
if ($callback === null || (is_string($callback) === true && $callback[0] !== '\\')) {
|
||||||
|
|
||||||
$namespace = static::$defaultNamespace;
|
$namespace = static::$defaultNamespace;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user