diff --git a/.gitignore b/.gitignore
index f3bdaaa..8dc5dfc 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,3 +1,4 @@
composer.lock
vendor/
-tests/tmp/*
\ No newline at end of file
+tests/tmp/*
+.idea/
\ No newline at end of file
diff --git a/.idea/.gitignore b/.idea/.gitignore
deleted file mode 100644
index 73f69e0..0000000
--- a/.idea/.gitignore
+++ /dev/null
@@ -1,8 +0,0 @@
-# Default ignored files
-/shelf/
-/workspace.xml
-# Datasource local storage ignored files
-/dataSources/
-/dataSources.local.xml
-# Editor-based HTTP Client requests
-/httpRequests/
diff --git a/.idea/codeStyles/codeStyleConfig.xml b/.idea/codeStyles/codeStyleConfig.xml
deleted file mode 100644
index 91dfc80..0000000
--- a/.idea/codeStyles/codeStyleConfig.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/dictionaries/simon.xml b/.idea/dictionaries/simon.xml
deleted file mode 100644
index 87f7ef2..0000000
--- a/.idea/dictionaries/simon.xml
+++ /dev/null
@@ -1,12 +0,0 @@
-
-
-
- bootmanager
- bootmanagers
- csrf
- middlewares
- pecee
- urldecode
-
-
-
\ No newline at end of file
diff --git a/.idea/encodings.xml b/.idea/encodings.xml
deleted file mode 100644
index 15a15b2..0000000
--- a/.idea/encodings.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-
-
-
-
\ No newline at end of file
diff --git a/.idea/markdown-navigator.xml b/.idea/markdown-navigator.xml
deleted file mode 100644
index e41dd85..0000000
--- a/.idea/markdown-navigator.xml
+++ /dev/null
@@ -1,72 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/markdown-navigator/profiles_settings.xml b/.idea/markdown-navigator/profiles_settings.xml
deleted file mode 100644
index 57927c5..0000000
--- a/.idea/markdown-navigator/profiles_settings.xml
+++ /dev/null
@@ -1,3 +0,0 @@
-
-
-
\ No newline at end of file
diff --git a/.idea/modules.xml b/.idea/modules.xml
deleted file mode 100644
index a5ba0c2..0000000
--- a/.idea/modules.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/php-test-framework.xml b/.idea/php-test-framework.xml
deleted file mode 100644
index 82ec95c..0000000
--- a/.idea/php-test-framework.xml
+++ /dev/null
@@ -1,14 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/php.xml b/.idea/php.xml
deleted file mode 100644
index 868ac8c..0000000
--- a/.idea/php.xml
+++ /dev/null
@@ -1,53 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/simple-php-router.iml b/.idea/simple-php-router.iml
deleted file mode 100644
index f342345..0000000
--- a/.idea/simple-php-router.iml
+++ /dev/null
@@ -1,52 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
deleted file mode 100644
index 94a25f7..0000000
--- a/.idea/vcs.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/workspace.xml b/.idea/workspace.xml
deleted file mode 100644
index b3aaabb..0000000
--- a/.idea/workspace.xml
+++ /dev/null
@@ -1,877 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- $PROJECT_DIR$/composer.json
-
-
-
-
-
-
-
- options
- parent::set
- parseParameters
- stripos
- setPrefix
- var_dum
- parse
- getParams
- setQuery
- contains
- matchRoute
- ->getValue
- ->find
- function find
- Req
- value(
- file(
- setUrl
- TODO
- input()->get
- function get
- REQUEST_TYPE_
- or method
- setDebugEnabled
- debugEnabled
- optiona
- \/
- requirements
- ler = new I
- csrf_token
-
-
- D:\Workspace\simple-php-router\src\Pecee\SimpleRouter\Route
- D:\Workspace\simple-php-router\src
- D:\Workspace\simple-php-router\tests\Pecee\SimpleRouter\Dummy
- D:\Workspace\simple-php-router
- E:\Workspace\simple-php-router\tests
- E:\Workspace\simple-php-router\src\Pecee
- E:\Workspace\simple-php-router\tests\Pecee\SimpleRouter
- E:\Workspace\simple-php-router\src\Pecee\SimpleRouter\Route
- E:\Workspace\simple-php-router\src\Pecee\SimpleRouter
- E:\Workspace\simple-php-router\src
- E:\Workspace\simple-php-router
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- false
-
- false
- false
- true
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 1502498236860
-
-
- 1502498236860
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/README.md b/README.md
index ab5dc2a..9f96203 100644
--- a/README.md
+++ b/README.md
@@ -33,6 +33,7 @@ You can donate any amount of your choice by [clicking here](https://www.paypal.c
- [Helper functions](#helper-functions)
- [Routes](#routes)
- [Basic routing](#basic-routing)
+ - [Class hinting](#class-hinting)
- [Available methods](#available-methods)
- [Multiple HTTP-verbs](#multiple-http-verbs)
- [Route parameters](#route-parameters)
@@ -123,7 +124,7 @@ composer require pecee/simple-router
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.
+We've included a simple demo project for the router which can be found [here](https://github.com/skipperbent/simple-router-demo). 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.
@@ -404,6 +405,14 @@ SimpleRouter::get('/', function() {
});
```
+### Class hinting
+
+You can use class hinting to load a class & method like this:
+
+```php
+SimpleRouter::get('/', [MyClass::class, 'myMethod']);
+```
+
### Available methods
Here you can see a list over all available routes:
@@ -785,12 +794,17 @@ SimpleRouter::group(['middleware' => \Demo\Middlewares\Site::class, 'exceptionHa
SimpleRouter::get('/answers/{id}', 'ControllerAnswers@show', ['where' => ['id' => '[0-9]+']]);
+ /**
+ * Class hinting is supported too
+ */
+
+ SimpleRouter::get('/answers/{id}', [ControllerAnswers::class, 'show'], ['where' => ['id' => '[0-9]+']]);
/**
* Restful resource (see IRestController interface for available methods)
*/
- SimpleRouter::resource('/rest', ControllerRessource::class);
+ SimpleRouter::resource('/rest', ControllerResource::class);
/**
@@ -811,7 +825,6 @@ SimpleRouter::group(['middleware' => \Demo\Middlewares\Site::class, 'exceptionHa
});
SimpleRouter::get('/page/404', 'ControllerPage@notFound', ['as' => 'page.notfound']);
-
```
---
diff --git a/src/Pecee/Http/Input/InputHandler.php b/src/Pecee/Http/Input/InputHandler.php
index 662df21..e485505 100644
--- a/src/Pecee/Http/Input/InputHandler.php
+++ b/src/Pecee/Http/Input/InputHandler.php
@@ -27,6 +27,24 @@ class InputHandler
*/
protected $request;
+ /**
+ * Original post variables
+ * @var array
+ */
+ protected $originalPost = [];
+
+ /**
+ * Original get/params variables
+ * @var array
+ */
+ protected $originalParams = [];
+
+ /**
+ * Get original file variables
+ * @var array
+ */
+ protected $originalFile = [];
+
/**
* Input constructor.
* @param Request $request
@@ -46,22 +64,34 @@ class InputHandler
{
/* Parse get requests */
if (\count($_GET) !== 0) {
- $this->get = $this->parseInputItem($_GET);
+ $this->originalParams = $_GET;
+ $this->get = $this->parseInputItem($this->originalParams);
}
/* Parse post requests */
- $postVars = $_POST;
+ $this->originalPost = $_POST;
- if (\in_array($this->request->getMethod(), ['put', 'patch', 'delete'], false) === true) {
- parse_str(file_get_contents('php://input'), $postVars);
+ if (\in_array($this->request->getMethod(), Request::$requestTypesPost, false) === true) {
+
+ $contents = file_get_contents('php://input');
+
+ // Append any PHP-input json
+ if (strpos(trim($contents), '{') === 0) {
+ $post = json_decode($contents, true);
+
+ if ($post !== false) {
+ $this->originalPost += $post;
+ }
+ }
}
- if (\count($postVars) !== 0) {
- $this->post = $this->parseInputItem($postVars);
+ if (\count($this->originalPost) !== 0) {
+ $this->post = $this->parseInputItem($this->originalPost);
}
/* Parse get requests */
if (\count($_FILES) !== 0) {
+ $this->originalFile = $_FILES;
$this->file = $this->parseFiles();
}
}
@@ -192,11 +222,11 @@ class InputHandler
{
$element = null;
- if (\count($methods) === 0 || \in_array('get', $methods, true) === true) {
+ if (\count($methods) === 0 || \in_array(Request::REQUEST_TYPE_GET, $methods, true) === true) {
$element = $this->get($index);
}
- if (($element === null && \count($methods) === 0) || (\count($methods) !== 0 && \in_array('post', $methods, true) === true)) {
+ if (($element === null && \count($methods) === 0) || (\count($methods) !== 0 && \in_array(Request::REQUEST_TYPE_POST, $methods, true) === true)) {
$element = $this->post($index);
}
@@ -288,24 +318,7 @@ class InputHandler
*/
public function all(array $filter = []): array
{
- $output = $_GET;
-
- if ($this->request->getMethod() === 'post') {
-
- // Append POST data
- $output += $_POST;
- $contents = file_get_contents('php://input');
-
- // Append any PHP-input json
- if (strpos(trim($contents), '{') === 0) {
- $post = json_decode($contents, true);
-
- if ($post !== false) {
- $output += $post;
- }
- }
- }
-
+ $output = $this->originalParams + $this->originalPost + $this->originalFile;
$output = (\count($filter) > 0) ? array_intersect_key($output, array_flip($filter)) : $output;
foreach ($filter as $filterKey) {
@@ -350,4 +363,64 @@ class InputHandler
$this->file[$key] = $item;
}
+ /**
+ * Get original post variables
+ * @return array
+ */
+ public function getOriginalPost(): array
+ {
+ return $this->originalPost;
+ }
+
+ /**
+ * Set original post variables
+ * @param array $post
+ * @return static $this
+ */
+ public function setOriginalPost(array $post): self
+ {
+ $this->originalPost = $post;
+ return $this;
+ }
+
+ /**
+ * Get original get variables
+ * @return array
+ */
+ public function getOriginalParams(): array
+ {
+ return $this->originalParams;
+ }
+
+ /**
+ * Set original get-variables
+ * @param array $params
+ * @return static $this
+ */
+ public function setOriginalParams(array $params): self
+ {
+ $this->originalParams = $params;
+ return $this;
+ }
+
+ /**
+ * Get original file variables
+ * @return array
+ */
+ public function getOriginalFile(): array
+ {
+ return $this->originalFile;
+ }
+
+ /**
+ * Set original file posts variables
+ * @param array $file
+ * @return static $this
+ */
+ public function setOriginalFile(array $file): self
+ {
+ $this->originalFile = $file;
+ return $this;
+ }
+
}
\ No newline at end of file
diff --git a/src/Pecee/Http/Input/InputItem.php b/src/Pecee/Http/Input/InputItem.php
index bd8667e..19ed96d 100644
--- a/src/Pecee/Http/Input/InputItem.php
+++ b/src/Pecee/Http/Input/InputItem.php
@@ -2,9 +2,6 @@
namespace Pecee\Http\Input;
-use Exception;
-use Traversable;
-
class InputItem implements IInputItem, \IteratorAggregate
{
public $index;
@@ -81,7 +78,7 @@ class InputItem implements IInputItem, \IteratorAggregate
return (\is_array($value) === true) ? json_encode($value) : $value;
}
- public function getIterator()
+ public function getIterator(): \ArrayIterator
{
return new \ArrayIterator($this->getValue());
}
diff --git a/src/Pecee/Http/Middleware/BaseCsrfVerifier.php b/src/Pecee/Http/Middleware/BaseCsrfVerifier.php
index 4815e8c..f137504 100644
--- a/src/Pecee/Http/Middleware/BaseCsrfVerifier.php
+++ b/src/Pecee/Http/Middleware/BaseCsrfVerifier.php
@@ -63,13 +63,12 @@ class BaseCsrfVerifier implements IMiddleware
*/
public function handle(Request $request): void
{
-
- if ($this->skip($request) === false && \in_array($request->getMethod(), ['post', 'put', 'delete'], true) === true) {
+ if ($this->skip($request) === false && \in_array($request->getMethod(), Request::$requestTypesPost, true) === true) {
$token = $request->getInputHandler()->value(
static::POST_KEY,
$request->getHeader(static::HEADER_KEY),
- 'post'
+ Request::$requestTypesPost
);
if ($this->tokenProvider->validate((string)$token) === false) {
@@ -80,7 +79,6 @@ class BaseCsrfVerifier implements IMiddleware
// Refresh existing token
$this->tokenProvider->refresh();
-
}
public function getTokenProvider(): ITokenProvider
diff --git a/src/Pecee/Http/Request.php b/src/Pecee/Http/Request.php
index 6a7b883..d10c48b 100644
--- a/src/Pecee/Http/Request.php
+++ b/src/Pecee/Http/Request.php
@@ -4,12 +4,46 @@ namespace Pecee\Http;
use Pecee\Http\Exceptions\MalformedUrlException;
use Pecee\Http\Input\InputHandler;
+use Pecee\Http\Middleware\BaseCsrfVerifier;
use Pecee\SimpleRouter\Route\ILoadableRoute;
use Pecee\SimpleRouter\Route\RouteUrl;
use Pecee\SimpleRouter\SimpleRouter;
class Request
{
+ public const REQUEST_TYPE_GET = 'get';
+ public const REQUEST_TYPE_POST = 'post';
+ public const REQUEST_TYPE_PUT = 'put';
+ public const REQUEST_TYPE_PATCH = 'patch';
+ public const REQUEST_TYPE_OPTIONS = 'options';
+ public const REQUEST_TYPE_DELETE = 'delete';
+ public const REQUEST_TYPE_HEAD = 'head';
+
+ /**
+ * All request-types
+ * @var string[]
+ */
+ public static $requestTypes = [
+ self::REQUEST_TYPE_GET,
+ self::REQUEST_TYPE_POST,
+ self::REQUEST_TYPE_PUT,
+ self::REQUEST_TYPE_PATCH,
+ self::REQUEST_TYPE_OPTIONS,
+ self::REQUEST_TYPE_DELETE,
+ self::REQUEST_TYPE_HEAD,
+ ];
+
+ /**
+ * Post request-types.
+ * @var string[]
+ */
+ public static $requestTypesPost = [
+ self::REQUEST_TYPE_POST,
+ self::REQUEST_TYPE_PUT,
+ self::REQUEST_TYPE_PATCH,
+ self::REQUEST_TYPE_DELETE,
+ ];
+
/**
* Additional data
*
@@ -77,14 +111,14 @@ class Request
{
foreach ($_SERVER as $key => $value) {
$this->headers[strtolower($key)] = $value;
- $this->headers[strtolower(str_replace('_', '-', $key))] = $value;
+ $this->headers[str_replace('_', '-', strtolower($key))] = $value;
}
$this->setHost($this->getHeader('http-host'));
// Check if special IIS header exist, otherwise use default.
$this->setUrl(new Url($this->getHeader('unencoded-url', $this->getHeader('request-uri'))));
-
+
$this->method = strtolower($this->getHeader('request-method'));
$this->inputHandler = new InputHandler($this);
$this->method = strtolower($this->inputHandler->value('_method', $this->getHeader('request-method')));
@@ -147,6 +181,15 @@ class Request
return $this->getHeader('php-auth-pw');
}
+ /**
+ * Get the csrf token
+ * @return string|null
+ */
+ public function getCsrfToken(): ?string
+ {
+ return $this->getHeader(BaseCsrfVerifier::HEADER_KEY);
+ }
+
/**
* Get all headers
* @return array
@@ -165,6 +208,13 @@ class Request
*/
public function getIp(bool $safe = false): ?string
{
+ return $this->getHeader(
+ 'http-cf-connecting-ip',
+ $this->getHeader(
+ 'http-x-forwarded-for',
+ $this->getHeader('remote-addr')
+ )
+ );
$client_header = null;
if(!$safe){
if ($this->getHeader('http-cf-connecting-ip') !== null) {
@@ -212,14 +262,28 @@ class Request
/**
* Get header value by name
*
- * @param string $name
- * @param string|null $defaultValue
+ * @param string $name Name of the header.
+ * @param string|null $defaultValue Value to be returned if header is not found.
+ * @param bool $tryParse When enabled the method will try to find the header from both from client (http) and server-side variants, if the header is not found.
*
* @return string|null
*/
- public function getHeader($name, $defaultValue = null): ?string
+ public function getHeader(string $name, $defaultValue = null, $tryParse = true): ?string
{
- return $this->headers[strtolower($name)] ?? $defaultValue;
+ $name = strtolower($name);
+ $header = $this->headers[$name] ?? null;
+
+ if ($tryParse === true && $header === null) {
+ if (strpos($name, 'http-') === 0) {
+ // Trying to find client header variant which was not found, searching for header variant without http- prefix.
+ $header = $this->headers[str_replace('http-', '', $name)] ?? null;
+ } else {
+ // Trying to find server variant which was not found, searching for client variant with http- prefix.
+ $header = $this->headers['http-' . $name] ?? null;
+ }
+ }
+
+ return $header ?? $defaultValue;
}
/**
diff --git a/src/Pecee/SimpleRouter/ClassLoader/ClassLoader.php b/src/Pecee/SimpleRouter/ClassLoader/ClassLoader.php
index c73c7a8..c928339 100644
--- a/src/Pecee/SimpleRouter/ClassLoader/ClassLoader.php
+++ b/src/Pecee/SimpleRouter/ClassLoader/ClassLoader.php
@@ -48,7 +48,7 @@ class ClassLoader implements IClassLoader
/**
* Load closure
*
- * @param \Closure $closure
+ * @param Callable $closure
* @param array $parameters
* @return mixed
* @throws NotFoundHttpException
diff --git a/src/Pecee/SimpleRouter/Route/IRoute.php b/src/Pecee/SimpleRouter/Route/IRoute.php
index 4654e1f..1af8fe8 100644
--- a/src/Pecee/SimpleRouter/Route/IRoute.php
+++ b/src/Pecee/SimpleRouter/Route/IRoute.php
@@ -22,8 +22,8 @@ interface IRoute
*
* @param Request $request
* @param Router $router
- * @throws \Pecee\SimpleRouter\Exceptions\NotFoundHttpException
* @return string
+ * @throws \Pecee\SimpleRouter\Exceptions\NotFoundHttpException
*/
public function renderRoute(Request $request, Router $router): ?string;
@@ -82,7 +82,7 @@ interface IRoute
/**
* Set callback
*
- * @param string $callback
+ * @param string|array|\Closure $callback
* @return static
*/
public function setCallback($callback): self;
@@ -206,4 +206,18 @@ interface IRoute
*/
public function setMiddlewares(array $middlewares): self;
+ /**
+ * If enabled parameters containing null-value will not be passed along to the callback.
+ *
+ * @param bool $enabled
+ * @return static $this
+ */
+ public function setFilterEmptyParams(bool $enabled): self;
+
+ /**
+ * Status if filtering of empty params is enabled or disabled
+ * @return bool
+ */
+ public function getFilterEmptyParams(): bool;
+
}
\ No newline at end of file
diff --git a/src/Pecee/SimpleRouter/Route/LoadableRoute.php b/src/Pecee/SimpleRouter/Route/LoadableRoute.php
index 536c415..ba03159 100644
--- a/src/Pecee/SimpleRouter/Route/LoadableRoute.php
+++ b/src/Pecee/SimpleRouter/Route/LoadableRoute.php
@@ -60,7 +60,7 @@ abstract class LoadableRoute extends Route implements ILoadableRoute
return null;
}
- return ((bool)preg_match($this->regex, $request->getHost() . $url) !== false);
+ return ((bool)preg_match($this->regex, $url) !== false);
}
/**
diff --git a/src/Pecee/SimpleRouter/Route/Route.php b/src/Pecee/SimpleRouter/Route/Route.php
index de3ba74..3e9370c 100644
--- a/src/Pecee/SimpleRouter/Route/Route.php
+++ b/src/Pecee/SimpleRouter/Route/Route.php
@@ -10,25 +10,7 @@ use Pecee\SimpleRouter\Router;
abstract class Route implements IRoute
{
protected const PARAMETERS_REGEX_FORMAT = '%s([\w]+)(\%s?)%s';
- protected const PARAMETERS_DEFAULT_REGEX = '[\w\-]+';
-
- public const REQUEST_TYPE_GET = 'get';
- public const REQUEST_TYPE_POST = 'post';
- public const REQUEST_TYPE_PUT = 'put';
- public const REQUEST_TYPE_PATCH = 'patch';
- public const REQUEST_TYPE_OPTIONS = 'options';
- public const REQUEST_TYPE_DELETE = 'delete';
- public const REQUEST_TYPE_HEAD = 'head';
-
- public static $requestTypes = [
- self::REQUEST_TYPE_GET,
- self::REQUEST_TYPE_POST,
- self::REQUEST_TYPE_PUT,
- self::REQUEST_TYPE_PATCH,
- self::REQUEST_TYPE_OPTIONS,
- self::REQUEST_TYPE_DELETE,
- self::REQUEST_TYPE_HEAD,
- ];
+ protected const PARAMETERS_DEFAULT_REGEX = '[\w-]+';
/**
* If enabled parameters containing null-value
@@ -99,22 +81,19 @@ abstract class Route implements IRoute
return $router->getClassLoader()->loadClosure($callback, $parameters);
}
- /* When the callback is a class + method */
- $controller = explode('@', $callback);
+ $controller = $this->getClass();
+ $method = $this->getMethod();
$namespace = $this->getNamespace();
-
- $className = ($namespace !== null && $controller[0][0] !== '\\') ? $namespace . '\\' . $controller[0] : $controller[0];
+ $className = ($namespace !== null && $controller[0] !== '\\') ? $namespace . '\\' . $controller : $controller;
$router->debug('Loading class %s', $className);
$class = $router->getClassLoader()->loadClass($className);
- if (\count($controller) === 1) {
+ if ($method === null) {
$controller[1] = '__invoke';
}
- $method = $controller[1];
-
if (method_exists($class, $method) === false) {
throw new NotFoundHttpException(sprintf('Method "%s" does not exist in class "%s"', $method, $className), 404);
}
@@ -144,7 +123,7 @@ abstract class Route implements IRoute
$urlRegex = preg_quote($route, '/');
} else {
- foreach (preg_split('/((\-?\/?)\{[^}]+\})/', $route) as $key => $t) {
+ foreach (preg_split('/((-?\/?){[^}]+})/', $route) as $key => $t) {
$regex = '';
@@ -159,7 +138,7 @@ abstract class Route implements IRoute
$regex = $parameterRegex ?? $this->defaultParameterRegex ?? static::PARAMETERS_DEFAULT_REGEX;
}
- $regex = sprintf('((\/|\-)(?P<%2$s>%3$s))%1$s', $parameters[2][$key], $name, $regex);
+ $regex = sprintf('((\/|-)(?P<%2$s>%3$s))%1$s', $parameters[2][$key], $name, $regex);
}
$urlRegex .= preg_quote($t, '/') . $regex;
@@ -271,7 +250,7 @@ abstract class Route implements IRoute
/**
* Set callback
*
- * @param string $callback
+ * @param string|array\Closure $callback
* @return static
*/
public function setCallback($callback): IRoute
@@ -291,6 +270,10 @@ abstract class Route implements IRoute
public function getMethod(): ?string
{
+ if (\is_array($this->callback) === true && \count($this->callback) > 1) {
+ return $this->callback[1];
+ }
+
if (\is_string($this->callback) === true && strpos($this->callback, '@') !== false) {
$tmp = explode('@', $this->callback);
@@ -302,6 +285,10 @@ abstract class Route implements IRoute
public function getClass(): ?string
{
+ if (\is_array($this->callback) === true && \count($this->callback) > 0) {
+ return $this->callback[0];
+ }
+
if (\is_string($this->callback) === true && strpos($this->callback, '@') !== false) {
$tmp = explode('@', $this->callback);
@@ -313,14 +300,14 @@ abstract class Route implements IRoute
public function setMethod(string $method): IRoute
{
- $this->callback = sprintf('%s@%s', $this->getClass(), $method);
+ $this->callback = [$this->getClass(), $method];
return $this;
}
public function setClass(string $class): IRoute
{
- $this->callback = sprintf('%s@%s', $class, $this->getMethod());
+ $this->callback = [$class, $this->getMethod()];
return $this;
}
@@ -456,9 +443,9 @@ abstract class Route implements IRoute
* Add regular expression parameter match.
* Alias for LoadableRoute::where()
*
- * @see LoadableRoute::where()
* @param array $options
* @return static
+ * @see LoadableRoute::where()
*/
public function where(array $options)
{
@@ -506,9 +493,9 @@ abstract class Route implements IRoute
/**
* Add middleware class-name
*
- * @deprecated This method is deprecated and will be removed in the near future.
* @param IMiddleware|string $middleware
* @return static
+ * @deprecated This method is deprecated and will be removed in the near future.
*/
public function setMiddleware($middleware)
{
@@ -575,4 +562,25 @@ abstract class Route implements IRoute
return $this->defaultParameterRegex;
}
+ /**
+ * If enabled parameters containing null-value will not be passed along to the callback.
+ *
+ * @param bool $enabled
+ * @return static $this
+ */
+ public function setFilterEmptyParams(bool $enabled): IRoute
+ {
+ $this->filterEmptyParams = $enabled;
+ return $this;
+ }
+
+ /**
+ * Status if filtering of empty params is enabled or disabled
+ * @return bool
+ */
+ public function getFilterEmptyParams(): bool
+ {
+ return $this->filterEmptyParams;
+ }
+
}
\ No newline at end of file
diff --git a/src/Pecee/SimpleRouter/Route/RouteController.php b/src/Pecee/SimpleRouter/Route/RouteController.php
index 09091f1..551ddbb 100644
--- a/src/Pecee/SimpleRouter/Route/RouteController.php
+++ b/src/Pecee/SimpleRouter/Route/RouteController.php
@@ -64,7 +64,7 @@ class RouteController extends LoadableRoute implements IControllerRoute
if ($method !== null) {
/* Remove requestType from method-name, if it exists */
- foreach (static::$requestTypes as $requestType) {
+ foreach (Request::$requestTypes as $requestType) {
if (stripos($method, $requestType) === 0) {
$method = (string)substr($method, \strlen($requestType));
@@ -110,7 +110,7 @@ class RouteController extends LoadableRoute implements IControllerRoute
$this->parameters = \array_slice($path, 1);
// Set callback
- $this->setCallback($this->controller . '@' . $this->method);
+ $this->setCallback([$this->controller, $this->method]);
return true;
}
diff --git a/src/Pecee/SimpleRouter/Route/RouteGroup.php b/src/Pecee/SimpleRouter/Route/RouteGroup.php
index 1c4cc33..e3fc8ac 100644
--- a/src/Pecee/SimpleRouter/Route/RouteGroup.php
+++ b/src/Pecee/SimpleRouter/Route/RouteGroup.php
@@ -52,8 +52,16 @@ class RouteGroup extends Route implements IGroupRoute
return false;
}
+ // Parse parameter
+
+ $prefix = $this->prefix;
+
+ foreach($this->getParameters() as $parameter => $value) {
+ $prefix = str_ireplace('{' . $parameter . '}', $value, $prefix);
+ }
+
/* Skip if prefix doesn't match */
- if ($this->prefix !== null && stripos($url, $this->prefix) === false) {
+ if ($this->prefix !== null && stripos($url, $prefix) === false) {
return false;
}
diff --git a/src/Pecee/SimpleRouter/Route/RouteResource.php b/src/Pecee/SimpleRouter/Route/RouteResource.php
index 6c79f40..7ae692c 100644
--- a/src/Pecee/SimpleRouter/Route/RouteResource.php
+++ b/src/Pecee/SimpleRouter/Route/RouteResource.php
@@ -78,7 +78,7 @@ class RouteResource extends LoadableRoute implements IControllerRoute
protected function call($method): bool
{
- $this->setCallback($this->controller . '@' . $method);
+ $this->setCallback([$this->controller, $method]);
return true;
}
@@ -115,32 +115,32 @@ class RouteResource extends LoadableRoute implements IControllerRoute
$method = $request->getMethod();
// Delete
- if ($method === static::REQUEST_TYPE_DELETE && $id !== null) {
+ if ($method === Request::REQUEST_TYPE_DELETE && $id !== null) {
return $this->call($this->methodNames['destroy']);
}
// Update
- if ($id !== null && \in_array($method, [static::REQUEST_TYPE_PATCH, static::REQUEST_TYPE_PUT], true) === true) {
+ if ($id !== null && \in_array($method, [Request::REQUEST_TYPE_PATCH, Request::REQUEST_TYPE_PUT], true) === true) {
return $this->call($this->methodNames['update']);
}
// Edit
- if ($method === static::REQUEST_TYPE_GET && $id !== null && $action === 'edit') {
+ if ($method === Request::REQUEST_TYPE_GET && $id !== null && $action === 'edit') {
return $this->call($this->methodNames['edit']);
}
// Create
- if ($method === static::REQUEST_TYPE_GET && $id === 'create') {
+ if ($method === Request::REQUEST_TYPE_GET && $id === 'create') {
return $this->call($this->methodNames['create']);
}
// Save
- if ($method === static::REQUEST_TYPE_POST) {
+ if ($method === Request::REQUEST_TYPE_POST) {
return $this->call($this->methodNames['store']);
}
// Show
- if ($method === static::REQUEST_TYPE_GET && $id !== null) {
+ if ($method === Request::REQUEST_TYPE_GET && $id !== null) {
return $this->call($this->methodNames['show']);
}
diff --git a/src/Pecee/SimpleRouter/Router.php b/src/Pecee/SimpleRouter/Router.php
index 8b1378e..758204f 100644
--- a/src/Pecee/SimpleRouter/Router.php
+++ b/src/Pecee/SimpleRouter/Router.php
@@ -305,8 +305,8 @@ class Router
* Start the routing
*
* @return string|null
- * @throws \Pecee\SimpleRouter\Exceptions\NotFoundHttpException
- * @throws \Pecee\Http\Middleware\Exceptions\TokenMismatchException
+ * @throws NotFoundHttpException
+ * @throws TokenMismatchException
* @throws HttpException
* @throws \Exception
*/
diff --git a/src/Pecee/SimpleRouter/SimpleRouter.php b/src/Pecee/SimpleRouter/SimpleRouter.php
index b8f4d06..284078b 100644
--- a/src/Pecee/SimpleRouter/SimpleRouter.php
+++ b/src/Pecee/SimpleRouter/SimpleRouter.php
@@ -12,7 +12,6 @@ namespace Pecee\SimpleRouter;
use DI\Container;
use Pecee\Exceptions\InvalidArgumentException;
-use Pecee\Http\Exceptions\MalformedUrlException;
use Pecee\Http\Middleware\BaseCsrfVerifier;
use Pecee\Http\Request;
use Pecee\Http\Response;
@@ -76,7 +75,6 @@ class SimpleRouter
ob_start();
static::router()->setDebugEnabled(true)->start();
$routerOutput = ob_get_clean();
- ob_end_clean();
} catch (\Exception $e) {
}
@@ -178,79 +176,79 @@ class SimpleRouter
* Route the given url to your callback on GET request method.
*
* @param string $url
- * @param string|\Closure $callback
+ * @param string|array|\Closure $callback
* @param array|null $settings
*
* @return RouteUrl
*/
public static function get(string $url, $callback, array $settings = null): IRoute
{
- return static::match(['get'], $url, $callback, $settings);
+ return static::match([Request::REQUEST_TYPE_GET], $url, $callback, $settings);
}
/**
* Route the given url to your callback on POST request method.
*
* @param string $url
- * @param string|\Closure $callback
+ * @param string|array|\Closure $callback
* @param array|null $settings
* @return RouteUrl
*/
public static function post(string $url, $callback, array $settings = null): IRoute
{
- return static::match(['post'], $url, $callback, $settings);
+ return static::match([Request::REQUEST_TYPE_POST], $url, $callback, $settings);
}
/**
* Route the given url to your callback on PUT request method.
*
* @param string $url
- * @param string|\Closure $callback
+ * @param string|array|\Closure $callback
* @param array|null $settings
* @return RouteUrl
*/
public static function put(string $url, $callback, array $settings = null): IRoute
{
- return static::match(['put'], $url, $callback, $settings);
+ return static::match([Request::REQUEST_TYPE_PUT], $url, $callback, $settings);
}
/**
* Route the given url to your callback on PATCH request method.
*
* @param string $url
- * @param string|\Closure $callback
+ * @param string|array|\Closure $callback
* @param array|null $settings
* @return RouteUrl
*/
public static function patch(string $url, $callback, array $settings = null): IRoute
{
- return static::match(['patch'], $url, $callback, $settings);
+ return static::match([Request::REQUEST_TYPE_PATCH], $url, $callback, $settings);
}
/**
* Route the given url to your callback on OPTIONS request method.
*
* @param string $url
- * @param string|\Closure $callback
+ * @param string|array|\Closure $callback
* @param array|null $settings
* @return RouteUrl
*/
public static function options(string $url, $callback, array $settings = null): IRoute
{
- return static::match(['options'], $url, $callback, $settings);
+ return static::match([Request::REQUEST_TYPE_OPTIONS], $url, $callback, $settings);
}
/**
* Route the given url to your callback on DELETE request method.
*
* @param string $url
- * @param string|\Closure $callback
+ * @param string|array|\Closure $callback
* @param array|null $settings
* @return RouteUrl
*/
public static function delete(string $url, $callback, array $settings = null): IRoute
{
- return static::match(['delete'], $url, $callback, $settings);
+ return static::match([Request::REQUEST_TYPE_DELETE], $url, $callback, $settings);
}
/**
@@ -307,14 +305,14 @@ class SimpleRouter
* Alias for the form method
*
* @param string $url
- * @param callable $callback
+ * @param string|array|\Closure $callback
* @param array|null $settings
* @see SimpleRouter::form
* @return RouteUrl
*/
public static function basic(string $url, $callback, array $settings = null): IRoute
{
- return static::match(['get', 'post'], $url, $callback, $settings);
+ return static::form($url, $callback, $settings);
}
/**
@@ -322,14 +320,17 @@ class SimpleRouter
* Route the given url to your callback on POST and GET request method.
*
* @param string $url
- * @param string|\Closure $callback
+ * @param string|array|\Closure $callback
* @param array|null $settings
* @see SimpleRouter::form
* @return RouteUrl
*/
public static function form(string $url, $callback, array $settings = null): IRoute
{
- return static::match(['get', 'post'], $url, $callback, $settings);
+ return static::match([
+ Request::REQUEST_TYPE_GET,
+ Request::REQUEST_TYPE_POST
+ ], $url, $callback, $settings);
}
/**
@@ -337,7 +338,7 @@ class SimpleRouter
*
* @param array $requestMethods
* @param string $url
- * @param string|\Closure $callback
+ * @param string|array|\Closure $callback
* @param array|null $settings
* @return RouteUrl|IRoute
*/
@@ -358,7 +359,7 @@ class SimpleRouter
* This type will route the given url to your callback and allow any type of request method
*
* @param string $url
- * @param string|\Closure $callback
+ * @param string|array|\Closure $callback
* @param array|null $settings
* @return RouteUrl|IRoute
*/
@@ -382,7 +383,7 @@ class SimpleRouter
* @param array|null $settings
* @return RouteController|IRoute
*/
- public static function controller(string $url, $controller, array $settings = null)
+ public static function controller(string $url, string $controller, array $settings = null)
{
$route = new RouteController($url, $controller);
$route = static::addDefaultNamespace($route);
@@ -402,7 +403,7 @@ class SimpleRouter
* @param array|null $settings
* @return RouteResource|IRoute
*/
- public static function resource(string $url, $controller, array $settings = null)
+ public static function resource(string $url, string $controller, array $settings = null)
{
$route = new RouteResource($url, $controller);
$route = static::addDefaultNamespace($route);
@@ -465,7 +466,7 @@ class SimpleRouter
/**
* Get the request
*
- * @return \Pecee\Http\Request
+ * @return Request
*/
public static function request(): Request
{
diff --git a/tests/Pecee/SimpleRouter/Dummy/DummyController.php b/tests/Pecee/SimpleRouter/Dummy/DummyController.php
index 8e38c2d..4150118 100644
--- a/tests/Pecee/SimpleRouter/Dummy/DummyController.php
+++ b/tests/Pecee/SimpleRouter/Dummy/DummyController.php
@@ -2,6 +2,12 @@
class DummyController
{
+ public function index()
+ {
+
+ }
+
+
public function method1()
{
diff --git a/tests/Pecee/SimpleRouter/Dummy/ResourceController.php b/tests/Pecee/SimpleRouter/Dummy/ResourceController.php
index 0a70e6f..bd36ab3 100644
--- a/tests/Pecee/SimpleRouter/Dummy/ResourceController.php
+++ b/tests/Pecee/SimpleRouter/Dummy/ResourceController.php
@@ -4,43 +4,36 @@ class ResourceController implements \Pecee\Controllers\IResourceController
public function index() : ?string
{
- echo 'index';
- return null;
+ return 'index';
}
public function show($id) : ?string
{
- echo 'show ' . $id;
- return null;
+ return 'show ' . $id;
}
public function store() : ?string
{
- echo 'store';
- return null;
+ return 'store';
}
public function create() : ?string
{
- echo 'create';
- return null;
+ return 'create';
}
public function edit($id) : ?string
{
- echo 'edit ' . $id;
- return null;
+ return 'edit ' . $id;
}
public function update($id) : ?string
{
- echo 'update ' . $id;
- return null;
+ return 'update ' . $id;
}
public function destroy($id) : ?string
{
- echo 'destroy ' . $id;
- return null;
+ return 'destroy ' . $id;
}
}
\ No newline at end of file
diff --git a/tests/Pecee/SimpleRouter/InputHandlerTest.php b/tests/Pecee/SimpleRouter/InputHandlerTest.php
index 9732c19..7fcb87b 100644
--- a/tests/Pecee/SimpleRouter/InputHandlerTest.php
+++ b/tests/Pecee/SimpleRouter/InputHandlerTest.php
@@ -6,23 +6,29 @@ require_once 'Dummy/Handler/ExceptionHandler.php';
class InputHandlerTest extends \PHPUnit\Framework\TestCase
{
+ protected $names = [
+ 'Lester',
+ 'Michael',
+ 'Franklin',
+ 'Trevor',
+ ];
+
+ protected $brands = [
+ 'Samsung',
+ 'Apple',
+ 'HP',
+ 'Canon',
+ ];
+
+ protected $day = 'monday';
public function testPost()
{
global $_POST;
- $names = [
- 'Lester',
- 'Michael',
- 'Franklin',
- 'Trevor',
- ];
-
- $day = 'monday';
-
$_POST = [
- 'names' => $names,
- 'day' => $day,
+ 'names' => $this->names,
+ 'day' => $this->day,
];
$router = TestRouter::router();
@@ -31,11 +37,12 @@ class InputHandlerTest extends \PHPUnit\Framework\TestCase
$handler = TestRouter::request()->getInputHandler();
- $this->assertEquals($names, $handler->value('names'));
- $this->assertEquals($names, $handler->all(['names'])['names']);
- $this->assertEquals($day, $handler->value('day'));
+ $this->assertEquals($this->names, $handler->value('names'));
+ $this->assertEquals($this->names, $handler->all(['names'])['names']);
+ $this->assertEquals($this->day, $handler->value('day'));
$this->assertInstanceOf(\Pecee\Http\Input\InputItem::class, $handler->find('day'));
$this->assertInstanceOf(\Pecee\Http\Input\InputItem::class, $handler->post('day'));
+ $this->assertInstanceOf(\Pecee\Http\Input\InputItem::class, $handler->find('day', 'post'));
// Check non-existing and wrong request-type
$this->assertCount(1, $handler->all(['non-existing']));
@@ -53,9 +60,10 @@ class InputHandlerTest extends \PHPUnit\Framework\TestCase
/* @var $object \Pecee\Http\Input\InputItem */
foreach($objects as $i => $object) {
$this->assertInstanceOf(\Pecee\Http\Input\InputItem::class, $object);
- $this->assertEquals($names[$i], $object->getValue());
+ $this->assertEquals($this->names[$i], $object->getValue());
}
+ // Reset
$_POST = [];
}
@@ -63,18 +71,9 @@ class InputHandlerTest extends \PHPUnit\Framework\TestCase
{
global $_GET;
- $names = [
- 'Lester',
- 'Michael',
- 'Franklin',
- 'Trevor',
- ];
-
- $day = 'monday';
-
$_GET = [
- 'names' => $names,
- 'day' => $day,
+ 'names' => $this->names,
+ 'day' => $this->day,
];
$router = TestRouter::router();
@@ -83,9 +82,9 @@ class InputHandlerTest extends \PHPUnit\Framework\TestCase
$handler = TestRouter::request()->getInputHandler();
- $this->assertEquals($names, $handler->value('names'));
- $this->assertEquals($names, $handler->all(['names'])['names']);
- $this->assertEquals($day, $handler->value('day'));
+ $this->assertEquals($this->names, $handler->value('names'));
+ $this->assertEquals($this->names, $handler->all(['names'])['names']);
+ $this->assertEquals($this->day, $handler->value('day'));
$this->assertInstanceOf(\Pecee\Http\Input\InputItem::class, $handler->find('day'));
$this->assertInstanceOf(\Pecee\Http\Input\InputItem::class, $handler->get('day'));
@@ -105,25 +104,73 @@ class InputHandlerTest extends \PHPUnit\Framework\TestCase
/* @var $object \Pecee\Http\Input\InputItem */
foreach($objects as $i => $object) {
$this->assertInstanceOf(\Pecee\Http\Input\InputItem::class, $object);
- $this->assertEquals($names[$i], $object->getValue());
+ $this->assertEquals($this->names[$i], $object->getValue());
}
+ // Reset
$_GET = [];
}
public function testFile()
{
+ // TODO: implement test-file
$this->assertEquals(true, true);
}
public function testFiles()
{
+ // TODO: implement test-files
$this->assertEquals(true, true);
}
public function testAll()
{
- $this->assertEquals(true, true);
+ global $_POST;
+ global $_GET;
+
+ $_POST = [
+ 'names' => $this->names,
+ 'is_sad' => true,
+ ];
+
+ $_GET = [
+ 'brands' => $this->brands,
+ 'is_happy' => true,
+ ];
+
+ $router = TestRouter::router();
+ $router->reset();
+ $router->getRequest()->setMethod('post');
+
+ $handler = TestRouter::request()->getInputHandler();
+
+ // GET
+ $brandsFound = $handler->all(['brands', 'nothing']);
+
+ $this->assertArrayHasKey('brands', $brandsFound);
+ $this->assertArrayHasKey('nothing', $brandsFound);
+ $this->assertEquals($this->brands, $brandsFound['brands']);
+ $this->assertNull($brandsFound['nothing']);
+
+ // POST
+ $namesFound = $handler->all(['names', 'nothing']);
+
+ $this->assertArrayHasKey('names', $namesFound);
+ $this->assertArrayHasKey('nothing', $namesFound);
+ $this->assertEquals($this->names, $namesFound['names']);
+ $this->assertNull($namesFound['nothing']);
+
+ // DEFAULT VALUE
+ $nonExisting = $handler->all([
+ 'non-existing'
+ ]);
+
+ $this->assertArrayHasKey('non-existing', $nonExisting);
+ $this->assertNull($nonExisting['non-existing']);
+
+ // Reset
+ $_GET = [];
+ $_POST = [];
}
}
\ No newline at end of file
diff --git a/tests/Pecee/SimpleRouter/RouterPartialGroupTest.php b/tests/Pecee/SimpleRouter/RouterPartialGroupTest.php
index 21c9fe2..40e288a 100644
--- a/tests/Pecee/SimpleRouter/RouterPartialGroupTest.php
+++ b/tests/Pecee/SimpleRouter/RouterPartialGroupTest.php
@@ -25,4 +25,49 @@ class RouterPartialGroupTest extends \PHPUnit\Framework\TestCase
$this->assertEquals('param2', $result2);
}
+ /**
+ * Fixed issue with partial routes not loading child groups.
+ * Reported in issue: #456
+ */
+ public function testPartialGroupWithGroup() {
+
+ $lang = null;
+
+ $route1 = '/lang/da/test/';
+ $route2 = '/lang/da/auth';
+ $route3 = '/lang/da/auth/test';
+
+ TestRouter::partialGroup(
+ '/lang/{test}/',
+ function ($lang = 'en') use($route1, $route2, $route3) {
+
+ TestRouter::get('/test/', function () use($route1) {
+ return $route1;
+ });
+
+ TestRouter::group(['prefix' => '/auth/'], function () use($route2, $route3) {
+
+ TestRouter::get('/', function() use($route2) {
+ return $route2;
+ });
+
+ TestRouter::get('/test', function () use($route3){
+ return $route3;
+ });
+
+ });
+
+ }
+ );
+
+ $test1 = TestRouter::debugOutput('/lang/da/test', 'get', false);
+ $test2 = TestRouter::debugOutput('/lang/da/auth', 'get', false);
+ $test3 = TestRouter::debugOutput('/lang/da/auth/test', 'get', false);
+
+ $this->assertEquals($test1, $route1);
+ $this->assertEquals($test2, $route2);
+ $this->assertEquals($test3, $route3);
+
+ }
+
}
\ No newline at end of file
diff --git a/tests/Pecee/SimpleRouter/RouterRouteTest.php b/tests/Pecee/SimpleRouter/RouterRouteTest.php
index 35b88af..e92bd37 100644
--- a/tests/Pecee/SimpleRouter/RouterRouteTest.php
+++ b/tests/Pecee/SimpleRouter/RouterRouteTest.php
@@ -101,7 +101,7 @@ class RouterRouteTest extends \PHPUnit\Framework\TestCase
public function testPathParamRegex()
{
- TestRouter::get('/{lang}/productscategories/{name}', 'DummyController@param', ['where' => ['lang' => '[a-z]+', 'name' => '[A-Za-z0-9\-]+']]);
+ TestRouter::get('/{lang}/productscategories/{name}', 'DummyController@param', ['where' => ['lang' => '[a-z]+', 'name' => '[A-Za-z0-9-]+']]);
$response = TestRouter::debugOutput('/it/productscategories/system', 'get');
$this->assertEquals('it, system', $response);
@@ -144,7 +144,7 @@ class RouterRouteTest extends \PHPUnit\Framework\TestCase
public function testRegEx()
{
- TestRouter::get('/my/{path}', 'DummyController@method1')->where(['path' => '[a-zA-Z\-]+']);
+ TestRouter::get('/my/{path}', 'DummyController@method1')->where(['path' => '[a-zA-Z-]+']);
TestRouter::debug('/my/custom-path', 'get');
$this->assertTrue(true);
@@ -182,7 +182,7 @@ class RouterRouteTest extends \PHPUnit\Framework\TestCase
public function testDefaultParameterRegex()
{
- TestRouter::get('/my/{path}', 'DummyController@param', ['defaultParameterRegex' => '[\w\-]+']);
+ TestRouter::get('/my/{path}', 'DummyController@param', ['defaultParameterRegex' => '[\w-]+']);
$output = TestRouter::debugOutput('/my/custom-regex', 'get');
$this->assertEquals('custom-regex', $output);
@@ -190,7 +190,7 @@ class RouterRouteTest extends \PHPUnit\Framework\TestCase
public function testDefaultParameterRegexGroup()
{
- TestRouter::group(['defaultParameterRegex' => '[\w\-]+'], function () {
+ TestRouter::group(['defaultParameterRegex' => '[\w-]+'], function () {
TestRouter::get('/my/{path}', 'DummyController@param');
});
@@ -199,4 +199,15 @@ class RouterRouteTest extends \PHPUnit\Framework\TestCase
$this->assertEquals('custom-regex', $output);
}
+ public function testClassHint()
+ {
+ TestRouter::get('/my/test/url', ['DummyController', 'method1']);
+ TestRouter::all('/my/test/url', ['DummyController', 'method1']);
+ TestRouter::match(['put', 'get', 'post'], '/my/test/url', ['DummyController', 'method1']);
+
+ TestRouter::debug('/my/test/url', 'get');
+
+ $this->assertTrue(true);
+ }
+
}
\ No newline at end of file
diff --git a/tests/Pecee/SimpleRouter/RouterUrlTest.php b/tests/Pecee/SimpleRouter/RouterUrlTest.php
index cd6c1a1..2aa4706 100644
--- a/tests/Pecee/SimpleRouter/RouterUrlTest.php
+++ b/tests/Pecee/SimpleRouter/RouterUrlTest.php
@@ -78,10 +78,11 @@ class RouterUrlTest extends \PHPUnit\Framework\TestCase
public function testSimilarUrls()
{
// Match normal route on alias
- TestRouter::resource('/url11', 'DummyController@method1');
- TestRouter::resource('/url1', 'DummyController@method1', ['as' => 'match']);
+ TestRouter::get('/url11', 'DummyController@method1');
+ TestRouter::get('/url22', 'DummyController@method2');
+ TestRouter::get('/url33', 'DummyController@method2')->name('match');
- TestRouter::debugNoReset('/url1', 'get');
+ TestRouter::debugNoReset('/url33', 'get');
$this->assertEquals(TestRouter::getUrl('match'), TestRouter::getUrl());
@@ -170,4 +171,16 @@ class RouterUrlTest extends \PHPUnit\Framework\TestCase
}
+ public function testCustomRegex()
+ {
+ TestRouter::request()->setHost('google.com');
+
+ TestRouter::get('/admin/', function() {
+ return 'match';
+ })->setMatch('/^\/admin\/?(.*)/i');
+
+ $output = TestRouter::debugOutput('/admin/asd/bec/123', 'get');
+ $this->assertEquals('match', $output);
+ }
+
}
\ No newline at end of file
diff --git a/tests/TestRouter.php b/tests/TestRouter.php
index a6a5321..1a1b4c1 100644
--- a/tests/TestRouter.php
+++ b/tests/TestRouter.php
@@ -3,6 +3,11 @@
class TestRouter extends \Pecee\SimpleRouter\SimpleRouter
{
+ public function __construct()
+ {
+ static::request()->setHost('testhost.com');
+ }
+
public static function debugNoReset($testUrl, $testMethod = 'get')
{
$request = static::request();
@@ -13,7 +18,7 @@ class TestRouter extends \Pecee\SimpleRouter\SimpleRouter
static::start();
}
- public static function debug($testUrl, $testMethod = 'get')
+ public static function debug($testUrl, $testMethod = 'get', bool $reset = true)
{
try {
static::debugNoReset($testUrl, $testMethod);
@@ -22,19 +27,20 @@ class TestRouter extends \Pecee\SimpleRouter\SimpleRouter
throw $e;
}
- static::router()->reset();
+ if($reset === true) {
+ static::router()->reset();
+ }
}
- public static function debugOutput($testUrl, $testMethod = 'get')
+ public static function debugOutput($testUrl, $testMethod = 'get', bool $reset = true)
{
$response = null;
// Route request
ob_start();
- static::debug($testUrl, $testMethod);
- $response = ob_get_contents();
- ob_end_clean();
+ static::debug($testUrl, $testMethod, $reset);
+ $response = ob_get_clean();
// Return response
return $response;