From cb141314f70d2354c86b90d9d435539c39a9d91e Mon Sep 17 00:00:00 2001 From: Karel Wintersky Date: Mon, 28 Jan 2019 17:43:11 +0300 Subject: [PATCH 001/117] Update README.md fix https://github.com/skipperbent/simple-php-router/issues/444 --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index e5f4f93..82adb72 100644 --- a/README.md +++ b/README.md @@ -484,13 +484,13 @@ SimpleRouter::get('/user/{name}', function ($name) { // ... do stuff -})->where('name', '[A-Za-z]+'); +})->where([ 'name' => '[A-Za-z]+' ]); SimpleRouter::get('/user/{id}', function ($id) { // ... do stuff -})->where('id', '[0-9]+'); +})->where([ 'id' => '[0-9]+' ]); SimpleRouter::get('/user/{id}/{name}', function ($id, $name) { From 2a3238f30a7527b9cc93780e7f4cf4851ad76fbb Mon Sep 17 00:00:00 2001 From: Juan Antonio Tubio Date: Fri, 8 Feb 2019 21:36:58 +0100 Subject: [PATCH 002/117] Update ClassLoader.php Fix 'must be an instance of Closure, array given' error when $closure is a object method. --- src/Pecee/SimpleRouter/ClassLoader/ClassLoader.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Pecee/SimpleRouter/ClassLoader/ClassLoader.php b/src/Pecee/SimpleRouter/ClassLoader/ClassLoader.php index caea1a5..c73c7a8 100644 --- a/src/Pecee/SimpleRouter/ClassLoader/ClassLoader.php +++ b/src/Pecee/SimpleRouter/ClassLoader/ClassLoader.php @@ -53,7 +53,7 @@ class ClassLoader implements IClassLoader * @return mixed * @throws NotFoundHttpException */ - public function loadClosure(\Closure $closure, array $parameters) + public function loadClosure(Callable $closure, array $parameters) { if ($this->useDependencyInjection === true) { $container = $this->getContainer(); @@ -115,4 +115,4 @@ class ClassLoader implements IClassLoader return $this->useDependencyInjection; } -} \ No newline at end of file +} From b21feca1fc291253dc5517a8721d1938614e2df9 Mon Sep 17 00:00:00 2001 From: Juan Antonio Tubio Date: Fri, 8 Feb 2019 21:40:04 +0100 Subject: [PATCH 003/117] Update IClassLoader.php Fix 'must be an instance of Closure, array given' error when $closure is a object method. --- src/Pecee/SimpleRouter/ClassLoader/IClassLoader.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Pecee/SimpleRouter/ClassLoader/IClassLoader.php b/src/Pecee/SimpleRouter/ClassLoader/IClassLoader.php index d978ac1..f9c00a4 100644 --- a/src/Pecee/SimpleRouter/ClassLoader/IClassLoader.php +++ b/src/Pecee/SimpleRouter/ClassLoader/IClassLoader.php @@ -7,6 +7,6 @@ interface IClassLoader public function loadClass(string $class); - public function loadClosure(\Closure $closure, array $parameters); + public function loadClosure(Callable $closure, array $parameters); -} \ No newline at end of file +} From 11df7ca18c63f4c986a09e25b73a6ebdb0a3b107 Mon Sep 17 00:00:00 2001 From: Stefan Warnat Date: Sat, 9 Feb 2019 11:04:07 +0100 Subject: [PATCH 004/117] Fix warning, because of wrong calculated cookie expiration timestamp --- src/Pecee/Http/Security/CookieTokenProvider.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Pecee/Http/Security/CookieTokenProvider.php b/src/Pecee/Http/Security/CookieTokenProvider.php index cb6da8f..c078faa 100644 --- a/src/Pecee/Http/Security/CookieTokenProvider.php +++ b/src/Pecee/Http/Security/CookieTokenProvider.php @@ -63,7 +63,7 @@ class CookieTokenProvider implements ITokenProvider public function setToken(string $token): void { $this->token = $token; - setcookie(static::CSRF_KEY, $token, (time() + 60) * $this->cookieTimeoutMinutes, '/', ini_get('session.cookie_domain'), ini_get('session.cookie_secure'), ini_get('session.cookie_httponly')); + setcookie(static::CSRF_KEY, $token, time() + (60 * $this->cookieTimeoutMinutes), '/', ini_get('session.cookie_domain'), ini_get('session.cookie_secure'), ini_get('session.cookie_httponly')); } /** From 1c5701a297f2d27a66507632004202dd096e184b Mon Sep 17 00:00:00 2001 From: Stefan Warnat Date: Sun, 19 May 2019 11:02:09 +0200 Subject: [PATCH 005/117] Update compsoer.json --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 5d285cd..d456c98 100644 --- a/composer.json +++ b/composer.json @@ -1,5 +1,5 @@ { - "name": "pecee/simple-router", + "name": "RedooNetworks/simple-router", "description": "Simple, fast PHP router that is easy to get integrated and in almost any project. Heavily inspired by the Laravel router.", "keywords": [ "router", From 572ba1695b8cb9d7df6738c38488eb1830d626aa Mon Sep 17 00:00:00 2001 From: Alex Blackham Date: Fri, 21 Jun 2019 10:44:31 +0100 Subject: [PATCH 006/117] The input()->all method will now set every key specified in the filter. If the key doesn't exist it will be set to null. --- src/Pecee/Http/Input/InputHandler.php | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/Pecee/Http/Input/InputHandler.php b/src/Pecee/Http/Input/InputHandler.php index f05bf10..07c68d1 100644 --- a/src/Pecee/Http/Input/InputHandler.php +++ b/src/Pecee/Http/Input/InputHandler.php @@ -303,13 +303,22 @@ class InputHandler // Append any PHP-input json if (strpos(trim($contents), '{') === 0) { $post = json_decode($contents, true); + if ($post !== false) { $output += $post; } } } - return (\count($filter) > 0) ? array_intersect_key($output, array_flip($filter)) : $output; + $output = (\count($filter) > 0) ? array_intersect_key($output, array_flip($filter)) : $output; + + foreach ($filter as $value) { + if (!array_key_exists($value, $output)) { + $output[$value] = null; + } + } + + return $output; } /** From 93c0622b9da90bc688d26197ffaabd0a14a626be Mon Sep 17 00:00:00 2001 From: Alex Blackham Date: Fri, 21 Jun 2019 10:45:57 +0100 Subject: [PATCH 007/117] Altered variable name in foreach to be less ambiguous. --- src/Pecee/Http/Input/InputHandler.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Pecee/Http/Input/InputHandler.php b/src/Pecee/Http/Input/InputHandler.php index 07c68d1..69690dc 100644 --- a/src/Pecee/Http/Input/InputHandler.php +++ b/src/Pecee/Http/Input/InputHandler.php @@ -312,9 +312,9 @@ class InputHandler $output = (\count($filter) > 0) ? array_intersect_key($output, array_flip($filter)) : $output; - foreach ($filter as $value) { - if (!array_key_exists($value, $output)) { - $output[$value] = null; + foreach ($filter as $filterKey) { + if (!array_key_exists($filterKey, $output)) { + $output[$filterKey] = null; } } From 27cd8b8a1f13930f5a2e7f23a70f97d78d27dc5f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20Sessing=C3=B8?= Date: Wed, 17 Mar 2021 15:43:00 +0100 Subject: [PATCH 008/117] Added support for objects like array etc as default-value. Value is now less strict. --- .idea/.gitignore | 8 ++ .idea/php.xml | 2 +- .idea/workspace.xml | 121 ++------------------------ src/Pecee/Http/Input/InputHandler.php | 4 +- 4 files changed, 18 insertions(+), 117 deletions(-) create mode 100644 .idea/.gitignore diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..73f69e0 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,8 @@ +# 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/php.xml b/.idea/php.xml index 02facb2..868ac8c 100644 --- a/.idea/php.xml +++ b/.idea/php.xml @@ -47,7 +47,7 @@ - + \ No newline at end of file diff --git a/.idea/workspace.xml b/.idea/workspace.xml index c262aba..41fc7a4 100644 --- a/.idea/workspace.xml +++ b/.idea/workspace.xml @@ -5,14 +5,10 @@ - - - - + - $PROJECT_DIR$/composer.json + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - options @@ -283,7 +184,7 @@ - + @@ -384,18 +285,6 @@ - - - @@ -592,6 +481,10 @@ + + + diff --git a/src/Pecee/Http/Input/IInputItem.php b/src/Pecee/Http/Input/IInputItem.php index cc5a4e0..b4ddef9 100644 --- a/src/Pecee/Http/Input/IInputItem.php +++ b/src/Pecee/Http/Input/IInputItem.php @@ -13,7 +13,7 @@ interface IInputItem public function setName(string $name): self; - public function getValue(): ?string; + public function getValue(); public function setValue(string $value): self; diff --git a/src/Pecee/Http/Input/InputHandler.php b/src/Pecee/Http/Input/InputHandler.php index ea6c6e8..662df21 100644 --- a/src/Pecee/Http/Input/InputHandler.php +++ b/src/Pecee/Http/Input/InputHandler.php @@ -171,14 +171,11 @@ class InputHandler foreach ($array as $key => $value) { // Handle array input - if (\is_array($value) === false) { - $list[$key] = new InputItem($key, $value); - continue; + if (\is_array($value) === true) { + $value = $this->parseInputItem($value); } - $output = $this->parseInputItem($value); - - $list[$key] = $output; + $list[$key] = new InputItem($key, $value); } return $list; @@ -222,19 +219,18 @@ class InputHandler { $input = $this->find($index, ...$methods); - $output = []; - /* Handle collection */ if (\is_array($input) === true) { + $output = []; /* @var $item InputItem */ foreach ($input as $item) { - $output[] = $item->getValue(); + $output[] = \is_array($item) ? $item : $item->getValue(); } return (\count($output) === 0) ? $defaultValue : $output; } - return ($input === null || ($input !== null && trim($input->getValue()) === '')) ? $defaultValue : $input->getValue(); + return ($input === null || (\is_string($input->getValue()) && trim($input->getValue()) === '')) ? $defaultValue : $input->getValue(); } /** @@ -354,4 +350,4 @@ class InputHandler $this->file[$key] = $item; } -} +} \ No newline at end of file diff --git a/src/Pecee/Http/Input/InputItem.php b/src/Pecee/Http/Input/InputItem.php index 6c677b8..a6e0fd8 100644 --- a/src/Pecee/Http/Input/InputItem.php +++ b/src/Pecee/Http/Input/InputItem.php @@ -2,13 +2,16 @@ namespace Pecee\Http\Input; -class InputItem implements IInputItem +use Exception; +use Traversable; + +class InputItem implements IInputItem, \IteratorAggregate { public $index; public $name; public $value; - public function __construct(string $index, ?string $value = null) + public function __construct(string $index, $value = null) { $this->index = $index; $this->value = $value; @@ -53,10 +56,19 @@ class InputItem implements IInputItem } /** - * @return string + * @return mixed */ - public function getValue(): ?string + public function getValue() { + /*if(is_array($this->value) === true) { + $output = []; + foreach($this->value as $key => $val) { + $output[$key] = $val->getValue(); + } + + return $output; + }*/ + return $this->value; } @@ -74,7 +86,12 @@ class InputItem implements IInputItem public function __toString(): string { - return (string)$this->value; + $value = $this->getValue(); + return (\is_array($value) === true) ? json_encode($value) : $value; } + public function getIterator() + { + return new \ArrayIterator($this->getValue()); + } } \ No newline at end of file diff --git a/tests/Pecee/SimpleRouter/InputHandlerTest.php b/tests/Pecee/SimpleRouter/InputHandlerTest.php index ae53ac6..9732c19 100644 --- a/tests/Pecee/SimpleRouter/InputHandlerTest.php +++ b/tests/Pecee/SimpleRouter/InputHandlerTest.php @@ -47,6 +47,7 @@ class InputHandlerTest extends \PHPUnit\Framework\TestCase $objects = $handler->find('names'); + $this->assertInstanceOf(\Pecee\Http\Input\InputItem::class, $objects); $this->assertCount(4, $objects); /* @var $object \Pecee\Http\Input\InputItem */ @@ -98,6 +99,7 @@ class InputHandlerTest extends \PHPUnit\Framework\TestCase $objects = $handler->find('names'); + $this->assertInstanceOf(\Pecee\Http\Input\InputItem::class, $objects); $this->assertCount(4, $objects); /* @var $object \Pecee\Http\Input\InputItem */ From e78040aabd8f4a32c2a2b138992746e9c8d075d0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20Sessing=C3=B8?= Date: Thu, 18 Mar 2021 21:58:40 +0100 Subject: [PATCH 017/117] Fixed existing unit-tests. --- .idea/workspace.xml | 5 +---- src/Pecee/Http/Input/InputItem.php | 9 --------- 2 files changed, 1 insertion(+), 13 deletions(-) diff --git a/.idea/workspace.xml b/.idea/workspace.xml index 8491a4e..b3aaabb 100644 --- a/.idea/workspace.xml +++ b/.idea/workspace.xml @@ -6,10 +6,7 @@ - - - diff --git a/src/Pecee/Http/Input/InputItem.php b/src/Pecee/Http/Input/InputItem.php index a6e0fd8..bd8667e 100644 --- a/src/Pecee/Http/Input/InputItem.php +++ b/src/Pecee/Http/Input/InputItem.php @@ -60,15 +60,6 @@ class InputItem implements IInputItem, \IteratorAggregate */ public function getValue() { - /*if(is_array($this->value) === true) { - $output = []; - foreach($this->value as $key => $val) { - $output[$key] = $val->getValue(); - } - - return $output; - }*/ - return $this->value; } From 21d180ebc953b421ada32c1cd845789309e41749 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20Sessing=C3=B8?= Date: Sun, 21 Mar 2021 05:55:18 +0100 Subject: [PATCH 018/117] [FEATURE] Added support for class hinting on routes as requested by #491 --- .idea/workspace.xml | 12 +++++++- README.md | 17 +++++++++-- src/Pecee/SimpleRouter/Route/IRoute.php | 2 +- src/Pecee/SimpleRouter/Route/Route.php | 29 ++++++++++--------- .../SimpleRouter/Route/RouteController.php | 2 +- .../SimpleRouter/Route/RouteResource.php | 2 +- src/Pecee/SimpleRouter/SimpleRouter.php | 25 ++++++++-------- tests/Pecee/SimpleRouter/RouterRouteTest.php | 11 +++++++ tests/Pecee/SimpleRouter/RouterUrlTest.php | 4 +-- 9 files changed, 69 insertions(+), 35 deletions(-) diff --git a/.idea/workspace.xml b/.idea/workspace.xml index b3aaabb..5a47253 100644 --- a/.idea/workspace.xml +++ b/.idea/workspace.xml @@ -6,7 +6,14 @@ - + + + + + + + + @@ -525,6 +534,7 @@ + diff --git a/README.md b/README.md index ab5dc2a..f528de4 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) @@ -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/SimpleRouter/Route/IRoute.php b/src/Pecee/SimpleRouter/Route/IRoute.php index 4654e1f..e7fa944 100644 --- a/src/Pecee/SimpleRouter/Route/IRoute.php +++ b/src/Pecee/SimpleRouter/Route/IRoute.php @@ -82,7 +82,7 @@ interface IRoute /** * Set callback * - * @param string $callback + * @param string|array|\Closure $callback * @return static */ public function setCallback($callback): self; diff --git a/src/Pecee/SimpleRouter/Route/Route.php b/src/Pecee/SimpleRouter/Route/Route.php index de3ba74..82a6089 100644 --- a/src/Pecee/SimpleRouter/Route/Route.php +++ b/src/Pecee/SimpleRouter/Route/Route.php @@ -95,26 +95,22 @@ abstract class Route implements IRoute $router->debug('Executing callback'); /* When the callback is a function */ - 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); } @@ -271,7 +267,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 +287,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,9 +302,12 @@ 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); - return $tmp[0]; } @@ -313,15 +316,13 @@ 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; } diff --git a/src/Pecee/SimpleRouter/Route/RouteController.php b/src/Pecee/SimpleRouter/Route/RouteController.php index 09091f1..aa179c3 100644 --- a/src/Pecee/SimpleRouter/Route/RouteController.php +++ b/src/Pecee/SimpleRouter/Route/RouteController.php @@ -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/RouteResource.php b/src/Pecee/SimpleRouter/Route/RouteResource.php index 6c79f40..b80aaa9 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; } diff --git a/src/Pecee/SimpleRouter/SimpleRouter.php b/src/Pecee/SimpleRouter/SimpleRouter.php index b8f4d06..88b7420 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; @@ -178,7 +177,7 @@ 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 @@ -192,7 +191,7 @@ class SimpleRouter * 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 */ @@ -205,7 +204,7 @@ class SimpleRouter * 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 */ @@ -218,7 +217,7 @@ class SimpleRouter * 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 */ @@ -231,7 +230,7 @@ class SimpleRouter * 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 */ @@ -244,7 +243,7 @@ class SimpleRouter * 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 */ @@ -307,7 +306,7 @@ 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 @@ -322,7 +321,7 @@ 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 @@ -337,7 +336,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 +357,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 +381,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 +401,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); diff --git a/tests/Pecee/SimpleRouter/RouterRouteTest.php b/tests/Pecee/SimpleRouter/RouterRouteTest.php index 35b88af..a7bce6c 100644 --- a/tests/Pecee/SimpleRouter/RouterRouteTest.php +++ b/tests/Pecee/SimpleRouter/RouterRouteTest.php @@ -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..091ddfe 100644 --- a/tests/Pecee/SimpleRouter/RouterUrlTest.php +++ b/tests/Pecee/SimpleRouter/RouterUrlTest.php @@ -78,8 +78,8 @@ 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::resource('/url1', 'ResourceController', ['as' => 'match']); TestRouter::debugNoReset('/url1', 'get'); From d70b153189f95f7acbf46eba6d4d4b9b0b825a04 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20Sessing=C3=B8?= Date: Sun, 21 Mar 2021 07:39:17 +0100 Subject: [PATCH 019/117] [BUGFIX] Fixed issue with child groups not loading when using partialGroups (issue: #456) --- .idea/workspace.xml | 15 ++++--- src/Pecee/SimpleRouter/Route/RouteGroup.php | 10 ++++- .../SimpleRouter/RouterPartialGroupTest.php | 45 +++++++++++++++++++ tests/TestRouter.php | 10 +++-- 4 files changed, 69 insertions(+), 11 deletions(-) diff --git a/.idea/workspace.xml b/.idea/workspace.xml index b3aaabb..c188330 100644 --- a/.idea/workspace.xml +++ b/.idea/workspace.xml @@ -6,7 +6,9 @@ - + + + - - - + + + @@ -326,18 +328,18 @@ - + + - @@ -525,6 +527,7 @@ + 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/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/TestRouter.php b/tests/TestRouter.php index a6a5321..c6acbca 100644 --- a/tests/TestRouter.php +++ b/tests/TestRouter.php @@ -13,7 +13,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,17 +22,19 @@ 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); + static::debug($testUrl, $testMethod, $reset); $response = ob_get_contents(); ob_end_clean(); From 38ce2e6bbad91189b5e4d889e3a003429c7571fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20Sessing=C3=B8?= Date: Sun, 21 Mar 2021 08:02:41 +0100 Subject: [PATCH 020/117] Unit test fixes --- .idea/workspace.xml | 16 +++----------- .../SimpleRouter/Dummy/ResourceController.php | 21 +++++++------------ 2 files changed, 10 insertions(+), 27 deletions(-) diff --git a/.idea/workspace.xml b/.idea/workspace.xml index dcb28f9..fb0d5a8 100644 --- a/.idea/workspace.xml +++ b/.idea/workspace.xml @@ -6,17 +6,7 @@ - - - - - - - - - - - + - + @@ -343,8 +333,8 @@ - + 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 From 3970ad85c4e3563098a89d19f2e8994cb60241a8 Mon Sep 17 00:00:00 2001 From: Marius Karstedt Date: Sun, 21 Mar 2021 10:47:49 +0100 Subject: [PATCH 021/117] remove .idea files --- .gitignore | 3 +- .idea/.gitignore | 8 - .idea/codeStyles/codeStyleConfig.xml | 5 - .idea/dictionaries/simon.xml | 12 - .idea/encodings.xml | 4 - .idea/markdown-navigator.xml | 72 -- .../markdown-navigator/profiles_settings.xml | 3 - .idea/modules.xml | 8 - .idea/php-test-framework.xml | 14 - .idea/php.xml | 53 -- .idea/simple-php-router.iml | 52 -- .idea/vcs.xml | 6 - .idea/workspace.xml | 877 ------------------ 13 files changed, 2 insertions(+), 1115 deletions(-) delete mode 100644 .idea/.gitignore delete mode 100644 .idea/codeStyles/codeStyleConfig.xml delete mode 100644 .idea/dictionaries/simon.xml delete mode 100644 .idea/encodings.xml delete mode 100644 .idea/markdown-navigator.xml delete mode 100644 .idea/markdown-navigator/profiles_settings.xml delete mode 100644 .idea/modules.xml delete mode 100644 .idea/php-test-framework.xml delete mode 100644 .idea/php.xml delete mode 100644 .idea/simple-php-router.iml delete mode 100644 .idea/vcs.xml delete mode 100644 .idea/workspace.xml 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 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file From 05e5461acbccc09c91ad38530e5bf91338ff166e Mon Sep 17 00:00:00 2001 From: Marius Karstedt Date: Sun, 21 Mar 2021 11:40:37 +0100 Subject: [PATCH 022/117] get csrf token in request; Test for prefix 'http-' in csrf token header --- src/Pecee/Http/Middleware/BaseCsrfVerifier.php | 2 +- src/Pecee/Http/Request.php | 9 +++++++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/src/Pecee/Http/Middleware/BaseCsrfVerifier.php b/src/Pecee/Http/Middleware/BaseCsrfVerifier.php index 4815e8c..8baaade 100644 --- a/src/Pecee/Http/Middleware/BaseCsrfVerifier.php +++ b/src/Pecee/Http/Middleware/BaseCsrfVerifier.php @@ -68,7 +68,7 @@ class BaseCsrfVerifier implements IMiddleware $token = $request->getInputHandler()->value( static::POST_KEY, - $request->getHeader(static::HEADER_KEY), + $request->getHeader(static::HEADER_KEY) ?? $request->getHeader('HTTP-' . static::HEADER_KEY), 'post' ); diff --git a/src/Pecee/Http/Request.php b/src/Pecee/Http/Request.php index e2bccae..c695008 100644 --- a/src/Pecee/Http/Request.php +++ b/src/Pecee/Http/Request.php @@ -147,6 +147,15 @@ class Request return $this->getHeader('php-auth-pw'); } + /** + * Get the csrf token + * @return string|null + */ + public function getCsrfToken(): ?string + { + return $this->getHeader('x-csrf-token') ?? $this->getHeader('http-x-csrf-token'); + } + /** * Get all headers * @return array From 31b4b4673e5c31e9d9944fa09c1cf8adf943d0e3 Mon Sep 17 00:00:00 2001 From: Marius Karstedt Date: Sun, 21 Mar 2021 12:20:57 +0100 Subject: [PATCH 023/117] add csrf token check for patch --- src/Pecee/Http/Middleware/BaseCsrfVerifier.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Pecee/Http/Middleware/BaseCsrfVerifier.php b/src/Pecee/Http/Middleware/BaseCsrfVerifier.php index 8baaade..e92310e 100644 --- a/src/Pecee/Http/Middleware/BaseCsrfVerifier.php +++ b/src/Pecee/Http/Middleware/BaseCsrfVerifier.php @@ -64,7 +64,7 @@ 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(), ['post', 'put', 'patch', 'delete'], true) === true) { $token = $request->getInputHandler()->value( static::POST_KEY, From f45e0bd12a017dde97b97f1ce699121fc32641d3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20Sessing=C3=B8?= Date: Sun, 21 Mar 2021 13:59:35 +0100 Subject: [PATCH 024/117] Removed .idea folder and removed "index" output from the unit-tests. --- .gitignore | 3 +- .idea/.gitignore | 8 - .idea/codeStyles/codeStyleConfig.xml | 5 - .idea/dictionaries/simon.xml | 12 - .idea/encodings.xml | 4 - .idea/markdown-navigator.xml | 72 -- .../markdown-navigator/profiles_settings.xml | 3 - .idea/modules.xml | 8 - .idea/php-test-framework.xml | 14 - .idea/php.xml | 53 -- .idea/simple-php-router.iml | 52 -- .idea/vcs.xml | 6 - .idea/workspace.xml | 880 ------------------ .../SimpleRouter/Dummy/DummyController.php | 6 + tests/Pecee/SimpleRouter/RouterUrlTest.php | 5 +- 15 files changed, 11 insertions(+), 1120 deletions(-) delete mode 100644 .idea/.gitignore delete mode 100644 .idea/codeStyles/codeStyleConfig.xml delete mode 100644 .idea/dictionaries/simon.xml delete mode 100644 .idea/encodings.xml delete mode 100644 .idea/markdown-navigator.xml delete mode 100644 .idea/markdown-navigator/profiles_settings.xml delete mode 100644 .idea/modules.xml delete mode 100644 .idea/php-test-framework.xml delete mode 100644 .idea/php.xml delete mode 100644 .idea/simple-php-router.iml delete mode 100644 .idea/vcs.xml delete mode 100644 .idea/workspace.xml 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 fb0d5a8..0000000 --- a/.idea/workspace.xml +++ /dev/null @@ -1,880 +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 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file 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/RouterUrlTest.php b/tests/Pecee/SimpleRouter/RouterUrlTest.php index 091ddfe..267a8fb 100644 --- a/tests/Pecee/SimpleRouter/RouterUrlTest.php +++ b/tests/Pecee/SimpleRouter/RouterUrlTest.php @@ -79,9 +79,10 @@ class RouterUrlTest extends \PHPUnit\Framework\TestCase { // Match normal route on alias TestRouter::get('/url11', 'DummyController@method1'); - TestRouter::resource('/url1', 'ResourceController', ['as' => 'match']); + 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()); From e8a1eac167f65c63b3efd8a30afa3484c498953a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20Sessing=C3=B8?= Date: Sun, 21 Mar 2021 14:52:34 +0100 Subject: [PATCH 025/117] Development - Moved request-types constants from abstract Route class to global Request-class and changed references. - Changed code to use new global request-type constants. - Optimized InputHandler class so it only parses inputs once when calling all-method. - Forced csrf-token post-value are now availible in all requestTypePost methods. --- src/Pecee/Http/Input/InputHandler.php | 65 +++++++++++-------- .../Http/Middleware/BaseCsrfVerifier.php | 6 +- src/Pecee/Http/Request.php | 33 ++++++++++ src/Pecee/SimpleRouter/Route/Route.php | 20 +----- .../SimpleRouter/Route/RouteController.php | 2 +- .../SimpleRouter/Route/RouteResource.php | 12 ++-- src/Pecee/SimpleRouter/SimpleRouter.php | 19 +++--- 7 files changed, 93 insertions(+), 64 deletions(-) diff --git a/src/Pecee/Http/Input/InputHandler.php b/src/Pecee/Http/Input/InputHandler.php index 662df21..b40f917 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 variables + * @var array + */ + protected $originalGet = []; + + /** + * 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->originalGet = $_GET; + $this->get = $this->parseInputItem($this->originalGet); } /* 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->originalGet + $this->originalPost; $output = (\count($filter) > 0) ? array_intersect_key($output, array_flip($filter)) : $output; foreach ($filter as $filterKey) { diff --git a/src/Pecee/Http/Middleware/BaseCsrfVerifier.php b/src/Pecee/Http/Middleware/BaseCsrfVerifier.php index e92310e..92c7617 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', 'patch', '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) ?? $request->getHeader('HTTP-' . 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 c695008..bc187c9 100644 --- a/src/Pecee/Http/Request.php +++ b/src/Pecee/Http/Request.php @@ -10,6 +10,39 @@ 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 * diff --git a/src/Pecee/SimpleRouter/Route/Route.php b/src/Pecee/SimpleRouter/Route/Route.php index 82a6089..516a03f 100644 --- a/src/Pecee/SimpleRouter/Route/Route.php +++ b/src/Pecee/SimpleRouter/Route/Route.php @@ -12,24 +12,6 @@ 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, - ]; - /** * If enabled parameters containing null-value * will not be passed along to the callback. @@ -140,7 +122,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 = ''; diff --git a/src/Pecee/SimpleRouter/Route/RouteController.php b/src/Pecee/SimpleRouter/Route/RouteController.php index aa179c3..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)); diff --git a/src/Pecee/SimpleRouter/Route/RouteResource.php b/src/Pecee/SimpleRouter/Route/RouteResource.php index b80aaa9..7ae692c 100644 --- a/src/Pecee/SimpleRouter/Route/RouteResource.php +++ b/src/Pecee/SimpleRouter/Route/RouteResource.php @@ -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/SimpleRouter.php b/src/Pecee/SimpleRouter/SimpleRouter.php index 88b7420..826621b 100644 --- a/src/Pecee/SimpleRouter/SimpleRouter.php +++ b/src/Pecee/SimpleRouter/SimpleRouter.php @@ -184,7 +184,7 @@ class SimpleRouter */ 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); } /** @@ -197,7 +197,7 @@ class SimpleRouter */ 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); } /** @@ -210,7 +210,7 @@ class SimpleRouter */ 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); } /** @@ -223,7 +223,7 @@ class SimpleRouter */ 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); } /** @@ -236,7 +236,7 @@ class SimpleRouter */ 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); } /** @@ -249,7 +249,7 @@ class SimpleRouter */ 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); } /** @@ -313,7 +313,7 @@ class SimpleRouter */ 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); } /** @@ -328,7 +328,10 @@ class SimpleRouter */ 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); } /** From 8254c5b1009167bf27ff6c963385a6121fe1df91 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20Sessing=C3=B8?= Date: Sun, 21 Mar 2021 15:19:27 +0100 Subject: [PATCH 026/117] Development - Removed unused class references. - Removed escape from `-` in reg-ex as it's only required when next to character-class. - Added `$_FILE` support for `all` method. - Bugfixes. --- src/Pecee/Http/Input/InputHandler.php | 70 +++++++++++++++++-- src/Pecee/Http/Input/InputItem.php | 5 +- .../SimpleRouter/ClassLoader/ClassLoader.php | 2 +- src/Pecee/SimpleRouter/Route/Route.php | 6 +- tests/Pecee/SimpleRouter/RouterRouteTest.php | 8 +-- 5 files changed, 74 insertions(+), 17 deletions(-) diff --git a/src/Pecee/Http/Input/InputHandler.php b/src/Pecee/Http/Input/InputHandler.php index b40f917..e485505 100644 --- a/src/Pecee/Http/Input/InputHandler.php +++ b/src/Pecee/Http/Input/InputHandler.php @@ -34,10 +34,10 @@ class InputHandler protected $originalPost = []; /** - * Original get variables + * Original get/params variables * @var array */ - protected $originalGet = []; + protected $originalParams = []; /** * Get original file variables @@ -64,8 +64,8 @@ class InputHandler { /* Parse get requests */ if (\count($_GET) !== 0) { - $this->originalGet = $_GET; - $this->get = $this->parseInputItem($this->originalGet); + $this->originalParams = $_GET; + $this->get = $this->parseInputItem($this->originalParams); } /* Parse post requests */ @@ -318,7 +318,7 @@ class InputHandler */ public function all(array $filter = []): array { - $output = $this->originalGet + $this->originalPost; + $output = $this->originalParams + $this->originalPost + $this->originalFile; $output = (\count($filter) > 0) ? array_intersect_key($output, array_flip($filter)) : $output; foreach ($filter as $filterKey) { @@ -363,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/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/Route.php b/src/Pecee/SimpleRouter/Route/Route.php index 516a03f..54858a1 100644 --- a/src/Pecee/SimpleRouter/Route/Route.php +++ b/src/Pecee/SimpleRouter/Route/Route.php @@ -10,7 +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\-]+'; + protected const PARAMETERS_DEFAULT_REGEX = '[\w-]+'; /** * If enabled parameters containing null-value @@ -122,7 +122,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 = ''; @@ -137,7 +137,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; diff --git a/tests/Pecee/SimpleRouter/RouterRouteTest.php b/tests/Pecee/SimpleRouter/RouterRouteTest.php index a7bce6c..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'); }); From 0aeefa1cbacf3f39009ec216810c3701b57e4e14 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20Sessing=C3=B8?= Date: Sun, 21 Mar 2021 15:22:35 +0100 Subject: [PATCH 027/117] Removed ob_end_clean when using ob_get_clean. --- src/Pecee/SimpleRouter/SimpleRouter.php | 1 - tests/TestRouter.php | 3 +-- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/src/Pecee/SimpleRouter/SimpleRouter.php b/src/Pecee/SimpleRouter/SimpleRouter.php index 826621b..8fe6118 100644 --- a/src/Pecee/SimpleRouter/SimpleRouter.php +++ b/src/Pecee/SimpleRouter/SimpleRouter.php @@ -75,7 +75,6 @@ class SimpleRouter ob_start(); static::router()->setDebugEnabled(true)->start(); $routerOutput = ob_get_clean(); - ob_end_clean(); } catch (\Exception $e) { } diff --git a/tests/TestRouter.php b/tests/TestRouter.php index c6acbca..7bf86da 100644 --- a/tests/TestRouter.php +++ b/tests/TestRouter.php @@ -35,8 +35,7 @@ class TestRouter extends \Pecee\SimpleRouter\SimpleRouter // Route request ob_start(); static::debug($testUrl, $testMethod, $reset); - $response = ob_get_contents(); - ob_end_clean(); + $response = ob_get_clean(); // Return response return $response; From e77b723db3dccab08bc093109ef4ede43f7115bd Mon Sep 17 00:00:00 2001 From: Marius Karstedt Date: Mon, 22 Mar 2021 10:57:58 +0100 Subject: [PATCH 028/117] Add http-client-ip header --- src/Pecee/Http/Request.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/Pecee/Http/Request.php b/src/Pecee/Http/Request.php index e2bccae..7d7cb46 100644 --- a/src/Pecee/Http/Request.php +++ b/src/Pecee/Http/Request.php @@ -166,6 +166,10 @@ class Request return $this->getHeader('http-cf-connecting-ip'); } + if($this->getHeader('http-client-ip') !== null){ + return $this->getHeader('http-client-ip'); + } + if ($this->getHeader('http-x-forwarded-for') !== null) { return $this->getHeader('http-x-forwarded-for'); } From 9897f66a25b8f22415c5f0b6df911f717152b704 Mon Sep 17 00:00:00 2001 From: Marius Karstedt Date: Mon, 22 Mar 2021 11:04:33 +0100 Subject: [PATCH 029/117] Add $safe --- src/Pecee/Http/Request.php | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/src/Pecee/Http/Request.php b/src/Pecee/Http/Request.php index 7d7cb46..cbce8bd 100644 --- a/src/Pecee/Http/Request.php +++ b/src/Pecee/Http/Request.php @@ -158,22 +158,24 @@ class Request /** * Get id address + * If $safe is false, this function will detect Proxys. But the user can edit this header to whatever he wants! + * https://stackoverflow.com/questions/3003145/how-to-get-the-client-ip-address-in-php#comment-25086804 + * @param bool $safe * @return string|null */ - public function getIp(): ?string + public function getIp(bool $safe = false): ?string { if ($this->getHeader('http-cf-connecting-ip') !== null) { return $this->getHeader('http-cf-connecting-ip'); } - - if($this->getHeader('http-client-ip') !== null){ - return $this->getHeader('http-client-ip'); + if(!$safe){ + if($this->getHeader('http-client-ip') !== null){ + return $this->getHeader('http-client-ip'); + } + if($this->getHeader('http-x-forwarded-for') !== null){ + return $this->getHeader('http-x-forwarded-for'); + } } - - if ($this->getHeader('http-x-forwarded-for') !== null) { - return $this->getHeader('http-x-forwarded-for'); - } - return $this->getHeader('remote-addr'); } From 90a0ca2ee89342fb0e77578f17744673df726dd2 Mon Sep 17 00:00:00 2001 From: Marius Karstedt Date: Mon, 22 Mar 2021 11:06:33 +0100 Subject: [PATCH 030/117] Add cf ip header to none save call --- src/Pecee/Http/Request.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Pecee/Http/Request.php b/src/Pecee/Http/Request.php index cbce8bd..d72ee3f 100644 --- a/src/Pecee/Http/Request.php +++ b/src/Pecee/Http/Request.php @@ -165,10 +165,10 @@ class Request */ public function getIp(bool $safe = false): ?string { - if ($this->getHeader('http-cf-connecting-ip') !== null) { - return $this->getHeader('http-cf-connecting-ip'); - } if(!$safe){ + if ($this->getHeader('http-cf-connecting-ip') !== null) { + return $this->getHeader('http-cf-connecting-ip'); + } if($this->getHeader('http-client-ip') !== null){ return $this->getHeader('http-client-ip'); } From d2b3ea4f542933cc9c90ec631bada625e24d2ba1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20Sessing=C3=B8?= Date: Mon, 22 Mar 2021 11:14:22 +0100 Subject: [PATCH 031/117] Added better header parsing to Request-class. - Added `tryParse` argument to the `getHeader` method. When enabled the method will try to parse headers from both server and client-side (enabled by default). - Simplified references that checks for both variants of header (http/non http). - Simplified getIp method of the Request-class. --- .../Http/Middleware/BaseCsrfVerifier.php | 2 +- src/Pecee/Http/Request.php | 45 ++++++++++++------- src/Pecee/SimpleRouter/Router.php | 4 +- src/Pecee/SimpleRouter/SimpleRouter.php | 2 +- 4 files changed, 33 insertions(+), 20 deletions(-) diff --git a/src/Pecee/Http/Middleware/BaseCsrfVerifier.php b/src/Pecee/Http/Middleware/BaseCsrfVerifier.php index 92c7617..f137504 100644 --- a/src/Pecee/Http/Middleware/BaseCsrfVerifier.php +++ b/src/Pecee/Http/Middleware/BaseCsrfVerifier.php @@ -67,7 +67,7 @@ class BaseCsrfVerifier implements IMiddleware $token = $request->getInputHandler()->value( static::POST_KEY, - $request->getHeader(static::HEADER_KEY) ?? $request->getHeader('HTTP-' . static::HEADER_KEY), + $request->getHeader(static::HEADER_KEY), Request::$requestTypesPost ); diff --git a/src/Pecee/Http/Request.php b/src/Pecee/Http/Request.php index bc187c9..8d6dab9 100644 --- a/src/Pecee/Http/Request.php +++ b/src/Pecee/Http/Request.php @@ -4,6 +4,7 @@ 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; @@ -110,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'))); @@ -186,7 +187,7 @@ class Request */ public function getCsrfToken(): ?string { - return $this->getHeader('x-csrf-token') ?? $this->getHeader('http-x-csrf-token'); + return $this->getHeader(BaseCsrfVerifier::HEADER_KEY); } /** @@ -204,15 +205,13 @@ class Request */ public function getIp(): ?string { - if ($this->getHeader('http-cf-connecting-ip') !== null) { - return $this->getHeader('http-cf-connecting-ip'); - } - - if ($this->getHeader('http-x-forwarded-for') !== null) { - return $this->getHeader('http-x-forwarded-for'); - } - - return $this->getHeader('remote-addr'); + return $this->getHeader( + 'http-cf-connecting-ip', + $this->getHeader( + 'http-x-forwarded-for', + $this->getHeader('remote-addr') + ) + ); } /** @@ -247,14 +246,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/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 8fe6118..284078b 100644 --- a/src/Pecee/SimpleRouter/SimpleRouter.php +++ b/src/Pecee/SimpleRouter/SimpleRouter.php @@ -466,7 +466,7 @@ class SimpleRouter /** * Get the request * - * @return \Pecee\Http\Request + * @return Request */ public static function request(): Request { From 24f7e3ab13815de24749e6e93c3421c7c3cf0c99 Mon Sep 17 00:00:00 2001 From: Marius Karstedt Date: Mon, 22 Mar 2021 11:15:47 +0100 Subject: [PATCH 032/117] Validate IP header --- src/Pecee/Http/Request.php | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/Pecee/Http/Request.php b/src/Pecee/Http/Request.php index d72ee3f..1ec099d 100644 --- a/src/Pecee/Http/Request.php +++ b/src/Pecee/Http/Request.php @@ -165,17 +165,18 @@ class Request */ public function getIp(bool $safe = false): ?string { + $client_header = null; if(!$safe){ if ($this->getHeader('http-cf-connecting-ip') !== null) { - return $this->getHeader('http-cf-connecting-ip'); - } - if($this->getHeader('http-client-ip') !== null){ - return $this->getHeader('http-client-ip'); - } - if($this->getHeader('http-x-forwarded-for') !== null){ - return $this->getHeader('http-x-forwarded-for'); + $client_header = $this->getHeader('http-cf-connecting-ip'); + }else if($this->getHeader('http-client-ip') !== null){ + $client_header = $this->getHeader('http-client-ip'); + }else if($this->getHeader('http-x-forwarded-for') !== null){ + $client_header = $this->getHeader('http-x-forwarded-for'); } } + if($client_header !== null && filter_var($client_header, FILTER_VALIDATE_IP)) + return $client_header; return $this->getHeader('remote-addr'); } From 1e0417b249339b4111961aff6600a822c8feb22a Mon Sep 17 00:00:00 2001 From: Marius Karstedt Date: Mon, 22 Mar 2021 11:18:16 +0100 Subject: [PATCH 033/117] also check remote-addr (can be edited https://stackoverflow.com/questions/5092563/how-to-fake-serverremote-addr-variable) --- src/Pecee/Http/Request.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Pecee/Http/Request.php b/src/Pecee/Http/Request.php index 1ec099d..6a7b883 100644 --- a/src/Pecee/Http/Request.php +++ b/src/Pecee/Http/Request.php @@ -175,9 +175,9 @@ class Request $client_header = $this->getHeader('http-x-forwarded-for'); } } - if($client_header !== null && filter_var($client_header, FILTER_VALIDATE_IP)) - return $client_header; - return $this->getHeader('remote-addr'); + if($client_header === null) + $client_header = $this->getHeader('remote-addr'); + return filter_var($client_header, FILTER_VALIDATE_IP) ? $client_header : null; } /** From 8a0f30c05e5c96773a4bc886c499b95c2f3e2a25 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20Sessing=C3=B8?= Date: Mon, 22 Mar 2021 14:09:27 +0100 Subject: [PATCH 034/117] Custom regex fix - Fixed issue with custom-regex maching both host-name and url (issue: #503). - Changed TestRouter so host-name is always set. --- src/Pecee/SimpleRouter/Route/LoadableRoute.php | 2 +- tests/Pecee/SimpleRouter/RouterUrlTest.php | 12 ++++++++++++ tests/TestRouter.php | 5 +++++ 3 files changed, 18 insertions(+), 1 deletion(-) 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/tests/Pecee/SimpleRouter/RouterUrlTest.php b/tests/Pecee/SimpleRouter/RouterUrlTest.php index 267a8fb..2aa4706 100644 --- a/tests/Pecee/SimpleRouter/RouterUrlTest.php +++ b/tests/Pecee/SimpleRouter/RouterUrlTest.php @@ -171,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 7bf86da..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(); From 87e9c19edb3af5bfb76c65bc2450451e864291e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20Sessing=C3=B8?= Date: Mon, 22 Mar 2021 14:49:33 +0100 Subject: [PATCH 035/117] Added unit-tests for input->all() method. --- tests/Pecee/SimpleRouter/InputHandlerTest.php | 109 +++++++++++++----- 1 file changed, 78 insertions(+), 31 deletions(-) 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 From 11fffd9a7b90592810226afa2372853e004e10b0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20Sessing=C3=B8?= Date: Mon, 22 Mar 2021 15:06:20 +0100 Subject: [PATCH 036/117] [FEATURE] Added option to get/set the filterEmptyParams option on IRoute classes (as requested by: #453). --- src/Pecee/SimpleRouter/Route/IRoute.php | 16 +++++++++++- src/Pecee/SimpleRouter/Route/Route.php | 33 ++++++++++++++++++++++--- 2 files changed, 44 insertions(+), 5 deletions(-) diff --git a/src/Pecee/SimpleRouter/Route/IRoute.php b/src/Pecee/SimpleRouter/Route/IRoute.php index e7fa944..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; @@ -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/Route.php b/src/Pecee/SimpleRouter/Route/Route.php index 54858a1..3e9370c 100644 --- a/src/Pecee/SimpleRouter/Route/Route.php +++ b/src/Pecee/SimpleRouter/Route/Route.php @@ -77,6 +77,7 @@ abstract class Route implements IRoute $router->debug('Executing callback'); /* When the callback is a function */ + return $router->getClassLoader()->loadClosure($callback, $parameters); } @@ -269,7 +270,7 @@ abstract class Route implements IRoute public function getMethod(): ?string { - if(\is_array($this->callback) === true && \count($this->callback) > 1) { + if (\is_array($this->callback) === true && \count($this->callback) > 1) { return $this->callback[1]; } @@ -284,12 +285,13 @@ abstract class Route implements IRoute public function getClass(): ?string { - if(\is_array($this->callback) === true && \count($this->callback) > 0) { + 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); + return $tmp[0]; } @@ -299,12 +301,14 @@ abstract class Route implements IRoute public function setMethod(string $method): IRoute { $this->callback = [$this->getClass(), $method]; + return $this; } public function setClass(string $class): IRoute { $this->callback = [$class, $this->getMethod()]; + return $this; } @@ -439,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) { @@ -489,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) { @@ -558,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 From fd585e8b9d8418aae057fc2ba27262902660b15c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20Sessing=C3=B8?= Date: Mon, 22 Mar 2021 16:41:20 +0100 Subject: [PATCH 037/117] [FEATURE] Changed behavior for default-namespace after issue #446 - Router::setDefaultNamespace() no longer has to be set in the beginning of routes.php. - Default namespace are now set once the router is started (Router::start()). - [WIP] Added unit-tests for custom-namespaces. --- src/Pecee/Http/Input/InputHandler.php | 2 +- src/Pecee/SimpleRouter/SimpleRouter.php | 38 ++++++++++------------ tests/Pecee/SimpleRouter/RouterUrlTest.php | 22 +++++++++++++ 3 files changed, 41 insertions(+), 21 deletions(-) diff --git a/src/Pecee/Http/Input/InputHandler.php b/src/Pecee/Http/Input/InputHandler.php index e485505..c6a000d 100644 --- a/src/Pecee/Http/Input/InputHandler.php +++ b/src/Pecee/Http/Input/InputHandler.php @@ -319,7 +319,7 @@ class InputHandler public function all(array $filter = []): array { $output = $this->originalParams + $this->originalPost + $this->originalFile; - $output = (\count($filter) > 0) ? array_intersect_key($output, array_flip($filter)) : $output; + $output = (\count($filter) > 0) ? \array_intersect_key($output, \array_flip($filter)) : $output; foreach ($filter as $filterKey) { if (array_key_exists($filterKey, $output) === false) { diff --git a/src/Pecee/SimpleRouter/SimpleRouter.php b/src/Pecee/SimpleRouter/SimpleRouter.php index 284078b..5d87c4c 100644 --- a/src/Pecee/SimpleRouter/SimpleRouter.php +++ b/src/Pecee/SimpleRouter/SimpleRouter.php @@ -59,6 +59,11 @@ class SimpleRouter */ public static function start(): void { + // Set default namespaces + foreach (static::router()->getRoutes() as $route) { + static::addDefaultNamespace($route); + } + echo static::router()->start(); } @@ -307,8 +312,8 @@ class SimpleRouter * @param string $url * @param string|array|\Closure $callback * @param array|null $settings - * @see SimpleRouter::form * @return RouteUrl + * @see SimpleRouter::form */ public static function basic(string $url, $callback, array $settings = null): IRoute { @@ -322,14 +327,14 @@ class SimpleRouter * @param string $url * @param string|array|\Closure $callback * @param array|null $settings - * @see SimpleRouter::form * @return RouteUrl + * @see SimpleRouter::form */ public static function form(string $url, $callback, array $settings = null): IRoute { return static::match([ Request::REQUEST_TYPE_GET, - Request::REQUEST_TYPE_POST + Request::REQUEST_TYPE_POST, ], $url, $callback, $settings); } @@ -346,7 +351,6 @@ class SimpleRouter { $route = new RouteUrl($url, $callback); $route->setRequestMethods($requestMethods); - $route = static::addDefaultNamespace($route); if ($settings !== null) { $route->setSettings($settings); @@ -366,7 +370,6 @@ class SimpleRouter public static function all(string $url, $callback, array $settings = null) { $route = new RouteUrl($url, $callback); - $route = static::addDefaultNamespace($route); if ($settings !== null) { $route->setSettings($settings); @@ -386,7 +389,6 @@ class SimpleRouter public static function controller(string $url, string $controller, array $settings = null) { $route = new RouteController($url, $controller); - $route = static::addDefaultNamespace($route); if ($settings !== null) { $route->setSettings($settings); @@ -406,7 +408,6 @@ class SimpleRouter public static function resource(string $url, string $controller, array $settings = null) { $route = new RouteResource($url, $controller); - $route = static::addDefaultNamespace($route); if ($settings !== null) { $route->setSettings($settings); @@ -511,22 +512,19 @@ class SimpleRouter { if (static::$defaultNamespace !== null) { - $callback = $route->getCallback(); + $ns = static::$defaultNamespace; + $namespace = $route->getNamespace(); - /* Only add default namespace on relative callbacks */ - if ($callback === null || (\is_string($callback) === true && $callback[0] !== '\\')) { - - $namespace = static::$defaultNamespace; - - $currentNamespace = $route->getNamespace(); - - if ($currentNamespace !== null) { - $namespace .= '\\' . $currentNamespace; + if ($namespace !== null) { + // Don't overwrite namespaces that starts with \ + if ($namespace[0] !== '\\') { + $ns .= '\\' . $namespace; + } else { + $ns = $namespace; } - - $route->setDefaultNamespace($namespace); - } + + $route->setNamespace($ns); } return $route; diff --git a/tests/Pecee/SimpleRouter/RouterUrlTest.php b/tests/Pecee/SimpleRouter/RouterUrlTest.php index 2aa4706..2d67e49 100644 --- a/tests/Pecee/SimpleRouter/RouterUrlTest.php +++ b/tests/Pecee/SimpleRouter/RouterUrlTest.php @@ -183,4 +183,26 @@ class RouterUrlTest extends \PHPUnit\Framework\TestCase $this->assertEquals('match', $output); } + public function testDefaultNamespace() + { + TestRouter::setDefaultNamespace('\\TestRoutersss'); + + TestRouter::get('/', 'DummyController@method1', ['as' => 'home']); + TestRouter::get('/about', 'DummyController@about'); + + TestRouter::group([ + 'prefix' => '/horses', + ], function() { + + TestRouter::get('/about', 'DummyController@about'); + + }); + + + TestRouter::debugNoReset('/horses/about'); + + + $routes = TestRouter::router()->getRoutes(); + } + } \ No newline at end of file From fa83d2f74bbb11db202abfe0fc1d90803164405a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20Sessing=C3=B8?= Date: Mon, 22 Mar 2021 17:03:22 +0100 Subject: [PATCH 038/117] Default-namespace changes. - Added new ClassNotFoundHttpException thrown when class is not found. - ClassNotFoundHttpException is now thrown when class/method is not found (backwards compatible). - Added unit-tests for default-namespace tests (rewrite + append cases). --- .../SimpleRouter/ClassLoader/ClassLoader.php | 3 +- .../Exceptions/ClassNotFoundHttpException.php | 38 +++++++++++++++ src/Pecee/SimpleRouter/Route/Route.php | 3 +- tests/Pecee/SimpleRouter/RouterUrlTest.php | 46 +++++++++++++++---- 4 files changed, 79 insertions(+), 11 deletions(-) create mode 100644 src/Pecee/SimpleRouter/Exceptions/ClassNotFoundHttpException.php diff --git a/src/Pecee/SimpleRouter/ClassLoader/ClassLoader.php b/src/Pecee/SimpleRouter/ClassLoader/ClassLoader.php index c928339..40cb3b6 100644 --- a/src/Pecee/SimpleRouter/ClassLoader/ClassLoader.php +++ b/src/Pecee/SimpleRouter/ClassLoader/ClassLoader.php @@ -3,6 +3,7 @@ namespace Pecee\SimpleRouter\ClassLoader; use DI\Container; +use Pecee\SimpleRouter\Exceptions\ClassNotFoundHttpException; use Pecee\SimpleRouter\Exceptions\NotFoundHttpException; class ClassLoader implements IClassLoader @@ -28,7 +29,7 @@ class ClassLoader implements IClassLoader public function loadClass(string $class) { if (class_exists($class) === false) { - throw new NotFoundHttpException(sprintf('Class "%s" does not exist', $class), 404); + throw new ClassNotFoundHttpException(sprintf('Class "%s" does not exist', $class), 404, null, $class); } if ($this->useDependencyInjection === true) { diff --git a/src/Pecee/SimpleRouter/Exceptions/ClassNotFoundHttpException.php b/src/Pecee/SimpleRouter/Exceptions/ClassNotFoundHttpException.php new file mode 100644 index 0000000..d283874 --- /dev/null +++ b/src/Pecee/SimpleRouter/Exceptions/ClassNotFoundHttpException.php @@ -0,0 +1,38 @@ +class = $class; + $this->method = $method; + } + + /** + * Get class name + * @return string + */ + public function getClass(): string + { + return $this->class; + } + + /** + * Get method + * @return string|null + */ + public function getMethod(): ?string + { + return $this->method; + } + +} \ No newline at end of file diff --git a/src/Pecee/SimpleRouter/Route/Route.php b/src/Pecee/SimpleRouter/Route/Route.php index 3e9370c..574c412 100644 --- a/src/Pecee/SimpleRouter/Route/Route.php +++ b/src/Pecee/SimpleRouter/Route/Route.php @@ -4,6 +4,7 @@ namespace Pecee\SimpleRouter\Route; use Pecee\Http\Middleware\IMiddleware; use Pecee\Http\Request; +use Pecee\SimpleRouter\Exceptions\ClassNotFoundHttpException; use Pecee\SimpleRouter\Exceptions\NotFoundHttpException; use Pecee\SimpleRouter\Router; @@ -95,7 +96,7 @@ abstract class Route implements IRoute } if (method_exists($class, $method) === false) { - throw new NotFoundHttpException(sprintf('Method "%s" does not exist in class "%s"', $method, $className), 404); + throw new ClassNotFoundHttpException(sprintf('Method "%s" does not exist in class "%s"', $method, $className), 404, null, $className, $method); } $router->debug('Executing callback'); diff --git a/tests/Pecee/SimpleRouter/RouterUrlTest.php b/tests/Pecee/SimpleRouter/RouterUrlTest.php index 2d67e49..b360973 100644 --- a/tests/Pecee/SimpleRouter/RouterUrlTest.php +++ b/tests/Pecee/SimpleRouter/RouterUrlTest.php @@ -11,7 +11,7 @@ class RouterUrlTest extends \PHPUnit\Framework\TestCase { TestRouter::get('/', 'DummyController@method1'); TestRouter::get('/page/{id?}', 'DummyController@method1'); - TestRouter::get('/test-output', function() { + TestRouter::get('/test-output', function () { return 'return value'; }); @@ -175,7 +175,7 @@ class RouterUrlTest extends \PHPUnit\Framework\TestCase { TestRouter::request()->setHost('google.com'); - TestRouter::get('/admin/', function() { + TestRouter::get('/admin/', function () { return 'match'; })->setMatch('/^\/admin\/?(.*)/i'); @@ -185,24 +185,52 @@ class RouterUrlTest extends \PHPUnit\Framework\TestCase public function testDefaultNamespace() { - TestRouter::setDefaultNamespace('\\TestRoutersss'); + TestRouter::setDefaultNamespace('\\Default\\Namespace'); TestRouter::get('/', 'DummyController@method1', ['as' => 'home']); - TestRouter::get('/about', 'DummyController@about'); TestRouter::group([ - 'prefix' => '/horses', - ], function() { + 'namespace' => 'Appended\Namespace', + 'prefix' => '/horses', + ], function () { - TestRouter::get('/about', 'DummyController@about'); + TestRouter::get('/', 'DummyController@method1'); + TestRouter::group([ + 'namespace' => '\\New\\Namespace', + 'prefix' => '/race', + ], function () { + + TestRouter::get('/', 'DummyController@method1'); + + }); }); + // Test appended namespace - TestRouter::debugNoReset('/horses/about'); + $class = null; + try { + TestRouter::debugNoReset('/horses/'); + } catch (\Pecee\SimpleRouter\Exceptions\ClassNotFoundHttpException $e) { + $class = $e->getClass(); + } - $routes = TestRouter::router()->getRoutes(); + $this->assertEquals('\\Default\\Namespace\\Appended\Namespace\\DummyController', $class); + + // Test overwritten namespace + + $class = null; + + try { + TestRouter::debugNoReset('/horses/race'); + } catch (\Pecee\SimpleRouter\Exceptions\ClassNotFoundHttpException $e) { + $class = $e->getClass(); + } + + $this->assertEquals('\\New\\Namespace\\DummyController', $class); + + TestRouter::router()->reset(); } } \ No newline at end of file From 801f1e68ccfbaa8cb704579a108dd5fd606c7b59 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20Sessing=C3=B8?= Date: Mon, 22 Mar 2021 18:05:27 +0100 Subject: [PATCH 039/117] [BUGFIX] BootManager findRoute not working. - Fixed findRoute not working in BootManager as reported by issue: #448 - Added more comprehensive php-unit tests for bootmanagers including findUrl. --- README.md | 2 +- src/Pecee/SimpleRouter/Router.php | 14 +++--- tests/Pecee/SimpleRouter/BootManagerTest.php | 49 +++++++++++++++++++ .../Dummy/Managers/FindUrlBootManager.php | 26 ++++++++++ .../Dummy/Managers/TestBootManager.php | 12 ++--- tests/Pecee/SimpleRouter/EventHandlerTest.php | 5 +- 6 files changed, 90 insertions(+), 18 deletions(-) create mode 100644 tests/Pecee/SimpleRouter/BootManagerTest.php create mode 100644 tests/Pecee/SimpleRouter/Dummy/Managers/FindUrlBootManager.php diff --git a/README.md b/README.md index f528de4..c250220 100644 --- a/README.md +++ b/README.md @@ -1495,7 +1495,7 @@ class CustomRouterRules implement IRouterBootManager // If the current url matches the rewrite url, we use our custom route - if($request->getUrl()->getPath() === $url) { + if($request->getUrl()->contains($url)) { $request->setRewriteUrl($rule); } } diff --git a/src/Pecee/SimpleRouter/Router.php b/src/Pecee/SimpleRouter/Router.php index 758204f..1b0f231 100644 --- a/src/Pecee/SimpleRouter/Router.php +++ b/src/Pecee/SimpleRouter/Router.php @@ -269,6 +269,13 @@ class Router { $this->debug('Loading routes'); + $this->fireEvents(EventHandler::EVENT_LOAD_ROUTES, [ + 'routes' => $this->routes, + ]); + + /* Loop through each route-request */ + $this->processRoutes($this->routes); + $this->fireEvents(EventHandler::EVENT_BOOT, [ 'bootmanagers' => $this->bootManagers, ]); @@ -291,13 +298,6 @@ class Router $this->debug('Finished rendering bootmanager "%s"', $className); } - $this->fireEvents(EventHandler::EVENT_LOAD_ROUTES, [ - 'routes' => $this->routes, - ]); - - /* Loop through each route-request */ - $this->processRoutes($this->routes); - $this->debug('Finished loading routes'); } diff --git a/tests/Pecee/SimpleRouter/BootManagerTest.php b/tests/Pecee/SimpleRouter/BootManagerTest.php new file mode 100644 index 0000000..925ea97 --- /dev/null +++ b/tests/Pecee/SimpleRouter/BootManagerTest.php @@ -0,0 +1,49 @@ + '/about', + '/contact' => '/', + ])); + + TestRouter::debug('/contact'); + + $this->assertTrue($result); + } + + public function testFindUrlFromBootManager() + { + TestRouter::get('/', 'DummyController@method1'); + TestRouter::get('/about', 'DummyController@method2')->name('about'); + TestRouter::get('/contact', 'DummyController@method3')->name('contact'); + + $result = false; + + // Add boot-manager + TestRouter::addBootManager(new FindUrlBootManager($result)); + + TestRouter::debug('/'); + + $this->assertTrue($result); + } + +} \ No newline at end of file diff --git a/tests/Pecee/SimpleRouter/Dummy/Managers/FindUrlBootManager.php b/tests/Pecee/SimpleRouter/Dummy/Managers/FindUrlBootManager.php new file mode 100644 index 0000000..f8bdcf3 --- /dev/null +++ b/tests/Pecee/SimpleRouter/Dummy/Managers/FindUrlBootManager.php @@ -0,0 +1,26 @@ +result = &$result; + } + + /** + * Called when router loads it's routes + * + * @param \Pecee\SimpleRouter\Router $router + * @param \Pecee\Http\Request $request + */ + public function boot(\Pecee\SimpleRouter\Router $router, \Pecee\Http\Request $request): void + { + $contact = $router->findRoute('contact'); + + if($contact !== null) { + $this->result = true; + } + } +} \ No newline at end of file diff --git a/tests/Pecee/SimpleRouter/Dummy/Managers/TestBootManager.php b/tests/Pecee/SimpleRouter/Dummy/Managers/TestBootManager.php index 8516aae..1617b46 100644 --- a/tests/Pecee/SimpleRouter/Dummy/Managers/TestBootManager.php +++ b/tests/Pecee/SimpleRouter/Dummy/Managers/TestBootManager.php @@ -3,13 +3,11 @@ class TestBootManager implements \Pecee\SimpleRouter\IRouterBootManager { - protected $routes; - protected $aliasUrl; + protected $rewrite; - public function __construct(array $routes, string $aliasUrl) + public function __construct(array $rewrite) { - $this->routes = $routes; - $this->aliasUrl = $aliasUrl; + $this->rewrite = $rewrite; } /** @@ -20,11 +18,11 @@ class TestBootManager implements \Pecee\SimpleRouter\IRouterBootManager */ public function boot(\Pecee\SimpleRouter\Router $router, \Pecee\Http\Request $request): void { - foreach ($this->routes as $url) { + foreach ($this->rewrite as $url => $rewrite) { // If the current url matches the rewrite url, we use our custom route if ($request->getUrl()->contains($url) === true) { - $request->setRewriteUrl($this->aliasUrl); + $request->setRewriteUrl($rewrite); } } diff --git a/tests/Pecee/SimpleRouter/EventHandlerTest.php b/tests/Pecee/SimpleRouter/EventHandlerTest.php index 8fa873d..faaa5d9 100644 --- a/tests/Pecee/SimpleRouter/EventHandlerTest.php +++ b/tests/Pecee/SimpleRouter/EventHandlerTest.php @@ -50,8 +50,8 @@ class EventHandlerTest extends \PHPUnit\Framework\TestCase // Add boot-manager TestRouter::addBootManager(new TestBootManager([ - '/test', - ], '/')); + '/test' => '/', + ])); // Start router TestRouter::debug('/non-existing'); @@ -61,7 +61,6 @@ class EventHandlerTest extends \PHPUnit\Framework\TestCase public function testAllEvent() { - $status = false; $eventHandler = new EventHandler(); From 2fb59854be44575bad7a5012b0dda27e110e5249 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20Sessing=C3=B8?= Date: Mon, 22 Mar 2021 18:33:16 +0100 Subject: [PATCH 040/117] [BUGFIX] Issue #439: Fixed multiple request-type on same routes. --- src/Pecee/SimpleRouter/Router.php | 15 ++++++++++----- tests/Pecee/SimpleRouter/RouterRouteTest.php | 12 ++++++++++++ 2 files changed, 22 insertions(+), 5 deletions(-) diff --git a/src/Pecee/SimpleRouter/Router.php b/src/Pecee/SimpleRouter/Router.php index 758204f..d9e642b 100644 --- a/src/Pecee/SimpleRouter/Router.php +++ b/src/Pecee/SimpleRouter/Router.php @@ -262,8 +262,8 @@ class Router /** * Load routes - * @throws NotFoundHttpException * @return void + * @throws NotFoundHttpException */ public function loadRoutes(): void { @@ -350,7 +350,7 @@ class Router { $this->debug('Routing request'); - $methodNotAllowed = false; + $methodNotAllowed = null; try { $url = $this->request->getRewriteUrl() ?? $this->request->getUrl()->getPath(); @@ -370,7 +370,12 @@ class Router /* Check if request method matches */ if (\count($route->getRequestMethods()) !== 0 && \in_array($this->request->getMethod(), $route->getRequestMethods(), true) === false) { $this->debug('Method "%s" not allowed', $this->request->getMethod()); - $methodNotAllowed = true; + + // Only set method not allowed is not already set + if ($methodNotAllowed === null) { + $methodNotAllowed = true; + } + continue; } @@ -475,9 +480,9 @@ class Router /** * @param \Exception $e - * @throws HttpException - * @throws \Exception * @return string|null + * @throws \Exception + * @throws HttpException */ protected function handleException(\Exception $e): ?string { diff --git a/tests/Pecee/SimpleRouter/RouterRouteTest.php b/tests/Pecee/SimpleRouter/RouterRouteTest.php index e92bd37..c416ecc 100644 --- a/tests/Pecee/SimpleRouter/RouterRouteTest.php +++ b/tests/Pecee/SimpleRouter/RouterRouteTest.php @@ -210,4 +210,16 @@ class RouterRouteTest extends \PHPUnit\Framework\TestCase $this->assertTrue(true); } + public function testSameRoutes() + { + + TestRouter::get('/recipe', 'DummyController@method1')->name('add'); + TestRouter::post('/recipe', 'DummyController@method2')->name('edit'); + + TestRouter::debugNoReset('/recipe', 'post'); + TestRouter::debug('/recipe', 'get'); + + $this->assertTrue(true); + } + } \ No newline at end of file From f74252e8cc4ba567f07ff045ee64153ea22a04e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20Sessing=C3=B8?= Date: Mon, 22 Mar 2021 18:34:14 +0100 Subject: [PATCH 041/117] Removed newline --- tests/Pecee/SimpleRouter/RouterRouteTest.php | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/Pecee/SimpleRouter/RouterRouteTest.php b/tests/Pecee/SimpleRouter/RouterRouteTest.php index c416ecc..28a7b4e 100644 --- a/tests/Pecee/SimpleRouter/RouterRouteTest.php +++ b/tests/Pecee/SimpleRouter/RouterRouteTest.php @@ -212,7 +212,6 @@ class RouterRouteTest extends \PHPUnit\Framework\TestCase public function testSameRoutes() { - TestRouter::get('/recipe', 'DummyController@method1')->name('add'); TestRouter::post('/recipe', 'DummyController@method2')->name('edit'); From 1d2e5f47d99cd0e04ff406309bb8a949de7ec2f6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20Sessing=C3=B8?= Date: Mon, 22 Mar 2021 19:34:55 +0100 Subject: [PATCH 042/117] [FEATURE] Option to disable multi-route rendering - Added option to disable multi-route rendering by calling `Router::setRenderMultipleRoutes($bool)`. - Added alias for easier access `SimpleRouter::enableMultiRouteRendering($bool)`. - Added php-unit tests for multi-routing enabled and disabled. --- src/Pecee/SimpleRouter/Router.php | 43 ++++++++++++++++++---- src/Pecee/SimpleRouter/SimpleRouter.php | 12 ++++++ tests/Pecee/SimpleRouter/RouterUrlTest.php | 42 ++++++++++++++++++++- 3 files changed, 88 insertions(+), 9 deletions(-) diff --git a/src/Pecee/SimpleRouter/Router.php b/src/Pecee/SimpleRouter/Router.php index d9e642b..6f8781d 100644 --- a/src/Pecee/SimpleRouter/Router.php +++ b/src/Pecee/SimpleRouter/Router.php @@ -110,6 +110,13 @@ class Router */ protected $classLoader; + /** + * When enabled the router will render all routes that matches. + * When disabled the router will stop execution when first route is found. + * @var bool + */ + protected $renderMultipleRoutes = true; + /** * Router constructor. */ @@ -399,14 +406,21 @@ class Router 'route' => $route, ]); - $output = $route->renderRoute($this->request, $this); - if ($output !== null) { - return $output; - } + $routeOutput = $route->renderRoute($this->request, $this); - $output = $this->handleRouteRewrite($key, $url); - if ($output !== null) { - return $output; + if ($this->renderMultipleRoutes === true) { + if ($routeOutput !== null) { + return $routeOutput; + } + + $output = $this->handleRouteRewrite($key, $url); + if ($output !== null) { + return $output; + } + } else { + $output = $this->handleRouteRewrite($key, $url); + + return $output ?? $routeOutput; } } } @@ -912,4 +926,19 @@ class Router return $this->debugList; } + /** + * Changes the rendering behavior of the router. + * When enabled the router will render all routes that matches. + * When disabled the router will stop rendering at the first route that matches. + * + * @param bool $bool + * @return $this + */ + public function setRenderMultipleRoutes(bool $bool): self + { + $this->renderMultipleRoutes = $bool; + + return $this; + } + } \ No newline at end of file diff --git a/src/Pecee/SimpleRouter/SimpleRouter.php b/src/Pecee/SimpleRouter/SimpleRouter.php index 284078b..2e79055 100644 --- a/src/Pecee/SimpleRouter/SimpleRouter.php +++ b/src/Pecee/SimpleRouter/SimpleRouter.php @@ -532,6 +532,18 @@ class SimpleRouter return $route; } + /** + * Changes the rendering behavior of the router. + * When enabled the router will render all routes that matches. + * When disabled the router will stop rendering at the first route that matches. + * + * @param bool $bool + */ + public static function enableMultiRouteRendering(bool $bool): void + { + static::router()->setRenderMultipleRoutes($bool); + } + /** * Enable or disable dependency injection * diff --git a/tests/Pecee/SimpleRouter/RouterUrlTest.php b/tests/Pecee/SimpleRouter/RouterUrlTest.php index 2aa4706..8a1d1fa 100644 --- a/tests/Pecee/SimpleRouter/RouterUrlTest.php +++ b/tests/Pecee/SimpleRouter/RouterUrlTest.php @@ -11,7 +11,7 @@ class RouterUrlTest extends \PHPUnit\Framework\TestCase { TestRouter::get('/', 'DummyController@method1'); TestRouter::get('/page/{id?}', 'DummyController@method1'); - TestRouter::get('/test-output', function() { + TestRouter::get('/test-output', function () { return 'return value'; }); @@ -175,7 +175,7 @@ class RouterUrlTest extends \PHPUnit\Framework\TestCase { TestRouter::request()->setHost('google.com'); - TestRouter::get('/admin/', function() { + TestRouter::get('/admin/', function () { return 'match'; })->setMatch('/^\/admin\/?(.*)/i'); @@ -183,4 +183,42 @@ class RouterUrlTest extends \PHPUnit\Framework\TestCase $this->assertEquals('match', $output); } + public function testRenderMultipleRoutesDisabled() + { + TestRouter::router()->setRenderMultipleRoutes(false); + + $result = false; + + TestRouter::get('/', function () use (&$result) { + $result = true; + }); + + TestRouter::get('/', function () use (&$result) { + $result = false; + }); + + TestRouter::debug('/'); + + $this->assertTrue($result); + } + + public function testRenderMultipleRoutesEnabled() + { + TestRouter::router()->setRenderMultipleRoutes(true); + + $result = []; + + TestRouter::get('/', function () use (&$result) { + $result[] = 'route1'; + }); + + TestRouter::get('/', function () use (&$result) { + $result[] = 'route2'; + }); + + TestRouter::debug('/'); + + $this->assertCount(2, $result); + } + } \ No newline at end of file From 5c8ff17aeca4b36c5d78d156f7546915c5b49ed4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20Sessing=C3=B8?= Date: Mon, 22 Mar 2021 19:43:13 +0100 Subject: [PATCH 043/117] Updated documentation for information about multi-route-rendering. --- README.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/README.md b/README.md index f528de4..21dfc5a 100644 --- a/README.md +++ b/README.md @@ -86,6 +86,7 @@ You can donate any amount of your choice by [clicking here](https://www.paypal.c - [Registering new event](#registering-new-event) - [Custom EventHandlers](#custom-eventhandlers) - [Advanced](#advanced) + - [Disable multiple route rendering](#disable-multiple-route-rendering) - [Url rewriting](#url-rewriting) - [Changing current route](#changing-current-route) - [Bootmanager: loading routes dynamically](#bootmanager-loading-routes-dynamically) @@ -1444,6 +1445,12 @@ class DatabaseDebugHandler implements IEventHandler # Advanced +## Disable multiple route rendering + +By default the router will try to execute all routes that matches a given url. To stop the router from executing any further routes any method can return a value. + +This behavior can be easily disabled by setting `SimpleRouter::enableMultiRouteRendering(false)` in your `routes.php` file. This is the same behavior as version 3 and below. + ## Url rewriting ### Changing current route From 6686de46b964d15bbd7683da9b5326b85784bd6a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20Sessing=C3=B8?= Date: Mon, 22 Mar 2021 20:35:42 +0100 Subject: [PATCH 044/117] Updated link to simple-router demo. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index f528de4..9f96203 100644 --- a/README.md +++ b/README.md @@ -124,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. From 5508c73e856a09d1653b5055e58556cba91b62da Mon Sep 17 00:00:00 2001 From: DeveloperMarius Date: Mon, 22 Mar 2021 22:25:59 +0100 Subject: [PATCH 045/117] getIp() update to new header method --- src/Pecee/Http/Request.php | 24 ++++++++++-------------- 1 file changed, 10 insertions(+), 14 deletions(-) diff --git a/src/Pecee/Http/Request.php b/src/Pecee/Http/Request.php index d10c48b..35746ad 100644 --- a/src/Pecee/Http/Request.php +++ b/src/Pecee/Http/Request.php @@ -208,22 +208,18 @@ 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) { - $client_header = $this->getHeader('http-cf-connecting-ip'); - }else if($this->getHeader('http-client-ip') !== null){ - $client_header = $this->getHeader('http-client-ip'); - }else if($this->getHeader('http-x-forwarded-for') !== null){ - $client_header = $this->getHeader('http-x-forwarded-for'); - } + $client_header = $this->getHeader( + 'http-cf-connecting-ip', + $this->getHeader( + 'http-client-ip', + $this->getHeader( + 'http-x-forwarded-for', + $this->getHeader('remote-addr') + ) + ) + ); } if($client_header === null) $client_header = $this->getHeader('remote-addr'); From 533dd08217d39a1e6c369921283a8746b7d9ef77 Mon Sep 17 00:00:00 2001 From: DeveloperMarius Date: Mon, 22 Mar 2021 22:58:53 +0100 Subject: [PATCH 046/117] Github Actions CI on push --- .github/workflows/ci.yml | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 .github/workflows/ci.yml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..30de95a --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,21 @@ +name: CI + +on: [push] + +jobs: + build-test: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v2 + + - uses: php-actions/composer@v5 + + - name: PHPUnit Tests + uses: php-actions/phpunit@v6 + with: + bootstrap: tests/bootstrap.php + php_version: 7.4 + php_extensions: json + configuration: phpunit.xml + args: --coverage-text \ No newline at end of file From cb2cb91a0a36a048c60d8e3b8992db8d73ec0cbd Mon Sep 17 00:00:00 2001 From: DeveloperMarius Date: Mon, 22 Mar 2021 23:00:39 +0100 Subject: [PATCH 047/117] Add on pull request --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 30de95a..4b5ddb9 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1,6 +1,6 @@ name: CI -on: [push] +on: [push, pull_request] jobs: build-test: From deb6922d0cdfe49765ad0400ce8e3ce161ef2d68 Mon Sep 17 00:00:00 2001 From: DeveloperMarius Date: Mon, 22 Mar 2021 23:10:20 +0100 Subject: [PATCH 048/117] change php version to 7.1 --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 4b5ddb9..b74627d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -15,7 +15,7 @@ jobs: uses: php-actions/phpunit@v6 with: bootstrap: tests/bootstrap.php - php_version: 7.4 + php_version: 7.1 php_extensions: json configuration: phpunit.xml args: --coverage-text \ No newline at end of file From 70138223581085347404afa48bfe7d78e2052f66 Mon Sep 17 00:00:00 2001 From: DeveloperMarius Date: Mon, 22 Mar 2021 23:13:05 +0100 Subject: [PATCH 049/117] changed bootstrap file --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b74627d..5e45670 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -14,7 +14,7 @@ jobs: - name: PHPUnit Tests uses: php-actions/phpunit@v6 with: - bootstrap: tests/bootstrap.php + bootstrap: vendor/autoload.php php_version: 7.1 php_extensions: json configuration: phpunit.xml From 21710c083cbb6f8bcab72d8cd946ed235575ee95 Mon Sep 17 00:00:00 2001 From: DeveloperMarius Date: Mon, 22 Mar 2021 23:19:18 +0100 Subject: [PATCH 050/117] Trying to fix docker build error --- .github/workflows/ci.yml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 5e45670..cd82176 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -8,14 +8,12 @@ jobs: steps: - uses: actions/checkout@v2 - - uses: php-actions/composer@v5 - - name: PHPUnit Tests uses: php-actions/phpunit@v6 with: bootstrap: vendor/autoload.php php_version: 7.1 - php_extensions: json + version: 1 configuration: phpunit.xml args: --coverage-text \ No newline at end of file From c67c6759a8dadafbd3dce97e78c94076ab88704c Mon Sep 17 00:00:00 2001 From: DeveloperMarius Date: Mon, 22 Mar 2021 23:28:16 +0100 Subject: [PATCH 051/117] Try without unit tests --- .github/workflows/ci.yml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index cd82176..9b32593 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -8,12 +8,10 @@ jobs: steps: - uses: actions/checkout@v2 - - uses: php-actions/composer@v5 - name: PHPUnit Tests - uses: php-actions/phpunit@v6 + uses: php-actions/composer@v5 with: bootstrap: vendor/autoload.php php_version: 7.1 - version: 1 configuration: phpunit.xml args: --coverage-text \ No newline at end of file From 029739f24140e65fb5b773a5c59c615e908f76b6 Mon Sep 17 00:00:00 2001 From: DeveloperMarius Date: Mon, 22 Mar 2021 23:31:39 +0100 Subject: [PATCH 052/117] Just install composer without tests --- .github/workflows/ci.yml | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 9b32593..9c3d96e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -8,10 +8,7 @@ jobs: steps: - uses: actions/checkout@v2 - - name: PHPUnit Tests + - name: Setup composer uses: php-actions/composer@v5 with: - bootstrap: vendor/autoload.php - php_version: 7.1 - configuration: phpunit.xml - args: --coverage-text \ No newline at end of file + php_version: 7.1 \ No newline at end of file From 3c8740769a571bb2704632f45cf5295488b81723 Mon Sep 17 00:00:00 2001 From: DeveloperMarius Date: Mon, 22 Mar 2021 23:36:32 +0100 Subject: [PATCH 053/117] No try to add unit tests --- .github/workflows/ci.yml | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 9c3d96e..c4d8f0a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -11,4 +11,10 @@ jobs: - name: Setup composer uses: php-actions/composer@v5 with: - php_version: 7.1 \ No newline at end of file + php_version: 7.1 + - name: PHPUnit tests + uses: php-actions/phpunit@v2 + with: + php_version: 7.1 + bootstrap: tests/bootstrap.php + configuration: phpunit.xml \ No newline at end of file From 791ba3199d85852ad415717ef3085f473792fc15 Mon Sep 17 00:00:00 2001 From: DeveloperMarius Date: Mon, 22 Mar 2021 23:38:23 +0100 Subject: [PATCH 054/117] Error says phpunit needs PHP >= 7.3, let's try it --- .github/workflows/ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c4d8f0a..447277d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -11,10 +11,10 @@ jobs: - name: Setup composer uses: php-actions/composer@v5 with: - php_version: 7.1 + php_version: 7.3 - name: PHPUnit tests uses: php-actions/phpunit@v2 with: - php_version: 7.1 + php_version: 7.3 bootstrap: tests/bootstrap.php configuration: phpunit.xml \ No newline at end of file From 0e58d556f04ce0915907130fb371abfb00b22bdf Mon Sep 17 00:00:00 2001 From: DeveloperMarius Date: Mon, 22 Mar 2021 23:45:37 +0100 Subject: [PATCH 055/117] Maby have to add args? --- .github/workflows/ci.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 447277d..bbeb7b3 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -17,4 +17,5 @@ jobs: with: php_version: 7.3 bootstrap: tests/bootstrap.php - configuration: phpunit.xml \ No newline at end of file + configuration: phpunit.xml + args: --coverage-text \ No newline at end of file From eebd537749a6a6798df8698752e566befb5e416c Mon Sep 17 00:00:00 2001 From: DeveloperMarius Date: Mon, 22 Mar 2021 23:55:11 +0100 Subject: [PATCH 056/117] removed syntaxCheck (throws error) https://stackoverflow.com/questions/44328114/phpunit-what-does-syntaxcheck-configuration-parameter-stands-for-exactly/44331140#44331140 --- phpunit.xml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/phpunit.xml b/phpunit.xml index 6e8f0c6..7aa2ef4 100644 --- a/phpunit.xml +++ b/phpunit.xml @@ -9,8 +9,7 @@ convertNoticesToExceptions="true" convertWarningsToExceptions="true" processIsolation="false" - stopOnFailure="false" - syntaxCheck="false"> + stopOnFailure="false"> tests/Pecee/SimpleRouter/ From f9c0c83b7092f4e34a178607dd0774777b647cd3 Mon Sep 17 00:00:00 2001 From: DeveloperMarius Date: Tue, 23 Mar 2021 00:09:45 +0100 Subject: [PATCH 057/117] migrate configuration --- .github/workflows/ci.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index bbeb7b3..bc039ed 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -12,6 +12,7 @@ jobs: uses: php-actions/composer@v5 with: php_version: 7.3 + - run: ./vendor/bin/phpunit --migrate-configuration - name: PHPUnit tests uses: php-actions/phpunit@v2 with: From 4adfa4f32204c61d202bd0574eef9f87039f63cc Mon Sep 17 00:00:00 2001 From: DeveloperMarius Date: Tue, 23 Mar 2021 00:18:14 +0100 Subject: [PATCH 058/117] Rollback to warning: 'Suggestion: Migrate your XML configuration using --migrate-configuration!' --- .github/workflows/ci.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index bc039ed..bbeb7b3 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -12,7 +12,6 @@ jobs: uses: php-actions/composer@v5 with: php_version: 7.3 - - run: ./vendor/bin/phpunit --migrate-configuration - name: PHPUnit tests uses: php-actions/phpunit@v2 with: From a44a93d70522800785cfad01c62f2680b63a3a52 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20Sessing=C3=B8?= Date: Tue, 23 Mar 2021 00:46:17 +0100 Subject: [PATCH 059/117] [!!!][FEATURE] Removed php-di as suggested by #477 NOTE: Custom class-loader should be used to create custom integrations with frameworks like php-di. See documentation for more information. - Removed all references to php-cli from composer + code. - Added ClassLoader php-unit tests. --- composer.json | 3 +- .../SimpleRouter/ClassLoader/ClassLoader.php | 82 +------------------ .../SimpleRouter/Handlers/EventHandler.php | 2 +- src/Pecee/SimpleRouter/Route/Route.php | 3 +- src/Pecee/SimpleRouter/Router.php | 2 +- src/Pecee/SimpleRouter/SimpleRouter.php | 14 +--- tests/Pecee/SimpleRouter/ClassLoaderTest.php | 30 +++++++ .../SimpleRouter/DependencyInjectionTest.php | 53 ------------ .../Dummy/ClassLoader/CustomClassLoader.php | 14 ++++ .../SimpleRouter/Dummy/DummyController.php | 5 ++ 10 files changed, 58 insertions(+), 150 deletions(-) create mode 100644 tests/Pecee/SimpleRouter/ClassLoaderTest.php delete mode 100644 tests/Pecee/SimpleRouter/DependencyInjectionTest.php create mode 100644 tests/Pecee/SimpleRouter/Dummy/ClassLoader/CustomClassLoader.php diff --git a/composer.json b/composer.json index 5d285cd..8514aee 100644 --- a/composer.json +++ b/composer.json @@ -28,8 +28,7 @@ ], "require": { "php": ">=7.1", - "ext-json": "*", - "php-di/php-di": "^6.0" + "ext-json": "*" }, "require-dev": { "phpunit/phpunit": "^6.0", diff --git a/src/Pecee/SimpleRouter/ClassLoader/ClassLoader.php b/src/Pecee/SimpleRouter/ClassLoader/ClassLoader.php index c928339..87d2e70 100644 --- a/src/Pecee/SimpleRouter/ClassLoader/ClassLoader.php +++ b/src/Pecee/SimpleRouter/ClassLoader/ClassLoader.php @@ -2,22 +2,10 @@ namespace Pecee\SimpleRouter\ClassLoader; -use DI\Container; use Pecee\SimpleRouter\Exceptions\NotFoundHttpException; class ClassLoader implements IClassLoader { - /** - * Dependency injection enabled - * @var bool - */ - protected $useDependencyInjection = false; - - /** - * @var Container|null - */ - protected $container; - /** * Load class * @@ -27,21 +15,10 @@ class ClassLoader implements IClassLoader */ public function loadClass(string $class) { - if (class_exists($class) === false) { + if (\class_exists($class) === false) { throw new NotFoundHttpException(sprintf('Class "%s" does not exist', $class), 404); } - if ($this->useDependencyInjection === true) { - $container = $this->getContainer(); - if ($container !== null) { - try { - return $container->get($class); - } catch (\Exception $e) { - throw new NotFoundHttpException($e->getMessage(), (int)$e->getCode(), $e->getPrevious()); - } - } - } - return new $class(); } @@ -55,64 +32,7 @@ class ClassLoader implements IClassLoader */ public function loadClosure(Callable $closure, array $parameters) { - if ($this->useDependencyInjection === true) { - $container = $this->getContainer(); - if ($container !== null) { - try { - return $container->call($closure, $parameters); - } catch (\Exception $e) { - throw new NotFoundHttpException($e->getMessage(), (int)$e->getCode(), $e->getPrevious()); - } - } - } - return \call_user_func_array($closure, $parameters); } - /** - * Get dependency injector container. - * - * @return Container|null - */ - public function getContainer(): ?Container - { - return $this->container; - } - - /** - * Set the dependency-injector container. - * - * @param Container $container - * @return ClassLoader - */ - public function setContainer(Container $container): self - { - $this->container = $container; - - return $this; - } - - /** - * Enable or disable dependency injection. - * - * @param bool $enabled - * @return static - */ - public function useDependencyInjection(bool $enabled): self - { - $this->useDependencyInjection = $enabled; - - return $this; - } - - /** - * Return true if dependency injection is enabled. - * - * @return bool - */ - public function isDependencyInjectionEnabled(): bool - { - return $this->useDependencyInjection; - } - } diff --git a/src/Pecee/SimpleRouter/Handlers/EventHandler.php b/src/Pecee/SimpleRouter/Handlers/EventHandler.php index 9ac42ec..70b37b3 100644 --- a/src/Pecee/SimpleRouter/Handlers/EventHandler.php +++ b/src/Pecee/SimpleRouter/Handlers/EventHandler.php @@ -143,7 +143,7 @@ class EventHandler implements IEventHandler * Get events. * * @param string|null $name Filter events by name. - * @param array ...$names Add multiple names... + * @param array|string ...$names Add multiple names... * @return array */ public function getEvents(?string $name, ...$names): array diff --git a/src/Pecee/SimpleRouter/Route/Route.php b/src/Pecee/SimpleRouter/Route/Route.php index 3e9370c..8dc45bf 100644 --- a/src/Pecee/SimpleRouter/Route/Route.php +++ b/src/Pecee/SimpleRouter/Route/Route.php @@ -77,7 +77,6 @@ abstract class Route implements IRoute $router->debug('Executing callback'); /* When the callback is a function */ - return $router->getClassLoader()->loadClosure($callback, $parameters); } @@ -250,7 +249,7 @@ abstract class Route implements IRoute /** * Set callback * - * @param string|array\Closure $callback + * @param string|array|\Closure $callback * @return static */ public function setCallback($callback): IRoute diff --git a/src/Pecee/SimpleRouter/Router.php b/src/Pecee/SimpleRouter/Router.php index 758204f..af37c50 100644 --- a/src/Pecee/SimpleRouter/Router.php +++ b/src/Pecee/SimpleRouter/Router.php @@ -306,7 +306,7 @@ class Router * * @return string|null * @throws NotFoundHttpException - * @throws TokenMismatchException + * @throws \Pecee\Http\Middleware\Exceptions\TokenMismatchException * @throws HttpException * @throws \Exception */ diff --git a/src/Pecee/SimpleRouter/SimpleRouter.php b/src/Pecee/SimpleRouter/SimpleRouter.php index 284078b..ffea26a 100644 --- a/src/Pecee/SimpleRouter/SimpleRouter.php +++ b/src/Pecee/SimpleRouter/SimpleRouter.php @@ -10,7 +10,6 @@ namespace Pecee\SimpleRouter; -use DI\Container; use Pecee\Exceptions\InvalidArgumentException; use Pecee\Http\Middleware\BaseCsrfVerifier; use Pecee\Http\Request; @@ -533,17 +532,12 @@ class SimpleRouter } /** - * Enable or disable dependency injection - * - * @param Container $container - * @return IClassLoader + * Set custom class-loader class used. + * @param IClassLoader $classLoader */ - public static function enableDependencyInjection(Container $container): IClassLoader + public static function setCustomClassLoader(IClassLoader $classLoader): void { - return static::router() - ->getClassLoader() - ->useDependencyInjection(true) - ->setContainer($container); + static::router()->setClassLoader($classLoader); } /** diff --git a/tests/Pecee/SimpleRouter/ClassLoaderTest.php b/tests/Pecee/SimpleRouter/ClassLoaderTest.php new file mode 100644 index 0000000..79f6095 --- /dev/null +++ b/tests/Pecee/SimpleRouter/ClassLoaderTest.php @@ -0,0 +1,30 @@ +assertEquals('method3', $classLoaderClass); + $this->assertTrue($result); + + TestRouter::router()->reset(); + } + +} \ No newline at end of file diff --git a/tests/Pecee/SimpleRouter/DependencyInjectionTest.php b/tests/Pecee/SimpleRouter/DependencyInjectionTest.php deleted file mode 100644 index 8863f19..0000000 --- a/tests/Pecee/SimpleRouter/DependencyInjectionTest.php +++ /dev/null @@ -1,53 +0,0 @@ -useAutowiring(true) - ->ignorePhpDocErrors(true) - ->build(); - - TestRouter::enableDependencyInjection($container); - - $className = null; - - TestRouter::get('/', function (DummyMiddleware $url) use (&$className) { - $className = \get_class($url); - }); - - TestRouter::debug('/'); - - $this->assertEquals(DummyMiddleware::class, $className); - } - - public function testDependencyInjectionProduction() - { - $cacheDir = dirname(__DIR__, 2) . '/tmp'; - - $builder = new \DI\ContainerBuilder(); - $builder - ->enableCompilation($cacheDir) - ->writeProxiesToFile(true, $cacheDir . '/proxies') - ->ignorePhpDocErrors(true) - ->useAutowiring(true); - - $container = $builder->build(); - - TestRouter::enableDependencyInjection($container); - - $className = null; - - TestRouter::get('/', function (DummyMiddleware $url) use (&$className) { - $className = \get_class($url); - }); - - TestRouter::debug('/'); - - $this->assertEquals(DummyMiddleware::class, $className); - } -} \ No newline at end of file diff --git a/tests/Pecee/SimpleRouter/Dummy/ClassLoader/CustomClassLoader.php b/tests/Pecee/SimpleRouter/Dummy/ClassLoader/CustomClassLoader.php new file mode 100644 index 0000000..17bff54 --- /dev/null +++ b/tests/Pecee/SimpleRouter/Dummy/ClassLoader/CustomClassLoader.php @@ -0,0 +1,14 @@ + true]); + } +} \ No newline at end of file diff --git a/tests/Pecee/SimpleRouter/Dummy/DummyController.php b/tests/Pecee/SimpleRouter/Dummy/DummyController.php index 4150118..3b25e5d 100644 --- a/tests/Pecee/SimpleRouter/Dummy/DummyController.php +++ b/tests/Pecee/SimpleRouter/Dummy/DummyController.php @@ -16,6 +16,11 @@ class DummyController public function method2() { + } + + public function method3() + { + return 'method3'; } public function param($params = null) From 67211e53321b2a145dfa5b776c8553b5d9a64a4a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20Sessing=C3=B8?= Date: Tue, 23 Mar 2021 01:24:17 +0100 Subject: [PATCH 060/117] Updated readme + gitignore --- .gitignore | 1 - README.md | 206 ++++++++++-------- .../SimpleRouter/ClassLoader/ClassLoader.php | 3 +- .../SimpleRouter/ClassLoader/IClassLoader.php | 12 + 4 files changed, 132 insertions(+), 90 deletions(-) diff --git a/.gitignore b/.gitignore index 8dc5dfc..6e51a97 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,3 @@ composer.lock vendor/ -tests/tmp/* .idea/ \ No newline at end of file diff --git a/README.md b/README.md index 9f96203..5a4459c 100644 --- a/README.md +++ b/README.md @@ -14,8 +14,7 @@ SimpleRouter::get('/', function() { ### Support the project -If you like simple-router and wish to see the continued development and maintenance of the project, -please consider showing your support by buying me a coffee. Supporters will be listed under the credits section of this documentation. +If you like simple-router and wish to see the continued development and maintenance of the project, please consider showing your support by buying me a coffee. Supporters will be listed under the credits section of this documentation. You can donate any amount of your choice by [clicking here](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=NNX4D2RUSALCN). @@ -52,9 +51,6 @@ You can donate any amount of your choice by [clicking here](https://www.paypal.c - [Partial groups](#partial-groups) - [Form Method Spoofing](#form-method-spoofing) - [Accessing The Current Route](#accessing-the-current-route) - - [Dependency injection](#dependency-injection) - - [Enabling dependency injection](#enabling-dependency-injection) - - [More reading](#more-reading) - [Other examples](#other-examples) - [CSRF-protection](#csrf-protection) - [Adding CSRF-verifier](#adding-csrf-verifier) @@ -90,6 +86,8 @@ You can donate any amount of your choice by [clicking here](https://www.paypal.c - [Changing current route](#changing-current-route) - [Bootmanager: loading routes dynamically](#bootmanager-loading-routes-dynamically) - [Adding routes manually](#adding-routes-manually) + - [Custom class-loader](#custom-class-loader) + - [Integrating with php-di](#Integrating-with-php-di) - [Parameters](#parameters) - [Extending](#extending) - [Help and support](#help-and-support) @@ -251,6 +249,7 @@ To add `favicon.ico` to the IIS ignore-list, add the following line to the ` ``` @@ -258,6 +257,7 @@ You can also make one exception for files with some extensions: If you are using `$_SERVER['ORIG_PATH_INFO']`, you will get `\index.php\` as part of the returned value. **Example:** + ``` /index.php/test/mypage.php ``` @@ -696,88 +696,6 @@ SimpleRouter::request()->getLoadedRoute(); request()->getLoadedRoute(); ``` -## Dependency injection - -simple-router supports dependency injection using the [`php-di`](http://php-di.org/) library. - -Dependency injection allows the framework to automatically "inject" (load) classes added as parameters. This can simplify your code, as you can avoid creating new instances of objects you are using often in your `Controllers` etc. - -Here's a basic example of a controller class using dependency injection: - -```php -namespace Demo\Controllers; - -class DefaultController { - - public function login(User $user): string - { - // ... - } - -} -``` - -The example above will automatically create a new instance of the `User` from the `$user` parameter. This means that the `$user` class contains a new instance of the `User` class and we won't need to create a new instance our self. - -**WARNING:** dependency injection can have some negative impact in performance. If you experience any performance issues, we recommend disabling this functionality. - -### Enabling dependency injection - -Dependency injection is disabled per default to avoid any performance issues. - -Before enabling dependency injection, we recommend that you read the [Container configuration](http://php-di.org/doc/container-configuration.html) section of the php-di documentation. This section covers how to configure php-di to different environments and speed-up the performance. - -#### Enabling for development environment - -The example below should ONLY be used on a development environment. - -```php -// Create our new php-di container -$container = (new \DI\ContainerBuilder()) - ->useAutowiring(true) - ->build(); - -// Add our container to simple-router and enable dependency injection -SimpleRouter::enableDependencyInjection($container); -``` - -Please check the [More reading](#more-reading) section of the documentation for useful php-di links and tutorials. - -#### Enabling for production environment - -The example below compiles the injections, which can help speed up performance. - -**Note:** You should change the `$cacheDir` to a cache-storage within your project. - -```php -// Cache directory -$cacheDir = sys_get_temp_dir('simple-router'); - -// Create our new php-di container -$container = (new \DI\ContainerBuilder()) - ->enableCompilation($cacheDir) - ->writeProxiesToFile(true, $cacheDir . '/proxies') - ->useAutowiring(true) - ->build(); - -// Add our container to simple-router and enable dependency injection -SimpleRouter::enableDependencyInjection($container); -``` - -Please check the [More reading](#more-reading) section of the documentation for useful php-di links and tutorials. - -### More reading - -For more information about dependency injection, configuration and settings - we recommend that you check the php-di documentation or some of the useful links we've gathered below. - -#### Useful links - -- [php-di documentation](http://php-di.org/doc/) -- [Understanding dependency injection](http://php-di.org/doc/understanding-di.html) -- [Best practices guide](http://php-di.org/doc/best-practices.html) -- [Configuring the container](http://php-di.org/doc/container-configuration.html) -- [Definitions](http://php-di.org/doc/definition.html) - ## Other examples You can find many more examples in the `routes.php` example-file below: @@ -1543,6 +1461,120 @@ $route->setPrefix('v1'); $router->addRoute($route); ``` +## Custom class loader + +You can easily extend simple-router to support custom injection frameworks like php-di by taking advantage of the ability to add your custom class-loader. + +Class-loaders must inherit the `IClassLoader` interface. + +**Example:** + +```php +class MyCustomClassLoader implements IClassLoader +{ + /** + * Load class + * + * @param string $class + * @return object + * @throws NotFoundHttpException + */ + public function loadClass(string $class) + { + if (\class_exists($class) === false) { + throw new NotFoundHttpException(sprintf('Class "%s" does not exist', $class), 404); + } + + return new $class(); + } + + /** + * Load closure + * + * @param Callable $closure + * @param array $parameters + * @return mixed + */ + public function loadClosure(Callable $closure, array $parameters) + { + return \call_user_func_array($closure, $parameters); + } + +} +``` + +Next, we need to configure our `routes.php` so the router uses our `MyCustomClassLoader` class for loading classes. This can be done by adding the following line to your `routes.php` file. + +```php +SimpleRouter::setCustomClassLoader(new MyCustomClassLoader()); +``` + +### Integrating with php-di + +php-di support was discontinued by version 4.3, however you can easily add it again by creating your own class-loader like the example below: + +```php +class MyCustomClassLoader implements IClassLoader +{ + + protected $container; + + public function __construct() + { + // Setup php-di + // Create our new php-di container + $container = (new \DI\ContainerBuilder()) + ->useAutowiring(true) + ->build(); + } + + /** + * Load class + * + * @param string $class + * @return object + * @throws NotFoundHttpException + */ + public function loadClass(string $class) + { + if (class_exists($class) === false) { + throw new NotFoundHttpException(sprintf('Class "%s" does not exist', $class), 404); + } + + if ($this->container !== null) { + try { + return $this->container->get($class); + } catch (\Exception $e) { + throw new NotFoundHttpException($e->getMessage(), (int)$e->getCode(), $e->getPrevious()); + } + } + + return new $class(); + } + + /** + * Load closure + * + * @param Callable $closure + * @param array $parameters + * @return mixed + */ + public function loadClosure(Callable $closure, array $parameters) + { + if ($this->container !== null) { + try { + return $this->container->call($closure, $parameters); + } catch (\Exception $e) { + throw new NotFoundHttpException($e->getMessage(), (int)$e->getCode(), $e->getPrevious()); + } + } + + return \call_user_func_array($closure, $parameters); + } + +} +``` + ## Parameters This section contains advanced tips & tricks on extending the usage for parameters. diff --git a/src/Pecee/SimpleRouter/ClassLoader/ClassLoader.php b/src/Pecee/SimpleRouter/ClassLoader/ClassLoader.php index 87d2e70..8c431a2 100644 --- a/src/Pecee/SimpleRouter/ClassLoader/ClassLoader.php +++ b/src/Pecee/SimpleRouter/ClassLoader/ClassLoader.php @@ -10,7 +10,7 @@ class ClassLoader implements IClassLoader * Load class * * @param string $class - * @return mixed + * @return object * @throws NotFoundHttpException */ public function loadClass(string $class) @@ -28,7 +28,6 @@ class ClassLoader implements IClassLoader * @param Callable $closure * @param array $parameters * @return mixed - * @throws NotFoundHttpException */ public function loadClosure(Callable $closure, array $parameters) { diff --git a/src/Pecee/SimpleRouter/ClassLoader/IClassLoader.php b/src/Pecee/SimpleRouter/ClassLoader/IClassLoader.php index f9c00a4..8eb8cd1 100644 --- a/src/Pecee/SimpleRouter/ClassLoader/IClassLoader.php +++ b/src/Pecee/SimpleRouter/ClassLoader/IClassLoader.php @@ -5,8 +5,20 @@ namespace Pecee\SimpleRouter\ClassLoader; interface IClassLoader { + /** + * Called when loading class + * @param string $class + * @return object + */ public function loadClass(string $class); + /** + * Called when loading method + * + * @param callable $closure + * @param array $parameters + * @return mixed + */ public function loadClosure(Callable $closure, array $parameters); } From e721a921561cd54343765421768f502e03f0e470 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20Sessing=C3=B8?= Date: Tue, 23 Mar 2021 01:25:57 +0100 Subject: [PATCH 061/117] Updated readme --- README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/README.md b/README.md index 5a4459c..42122f2 100644 --- a/README.md +++ b/README.md @@ -1521,7 +1521,6 @@ class MyCustomClassLoader implements IClassLoader public function __construct() { - // Setup php-di // Create our new php-di container $container = (new \DI\ContainerBuilder()) ->useAutowiring(true) From 90b0747dbdca65004c062e030206f5be319ca494 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20Sessing=C3=B8?= Date: Tue, 23 Mar 2021 01:36:23 +0100 Subject: [PATCH 062/117] [BUGFIX] Add support for mixed value types in InputItem as requested by #438 --- src/Pecee/Http/Input/IInputItem.php | 2 +- src/Pecee/Http/Input/InputItem.php | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Pecee/Http/Input/IInputItem.php b/src/Pecee/Http/Input/IInputItem.php index b4ddef9..0c851c8 100644 --- a/src/Pecee/Http/Input/IInputItem.php +++ b/src/Pecee/Http/Input/IInputItem.php @@ -15,7 +15,7 @@ interface IInputItem public function getValue(); - public function setValue(string $value): self; + public function setValue($value): self; public function __toString(): string; diff --git a/src/Pecee/Http/Input/InputItem.php b/src/Pecee/Http/Input/InputItem.php index 19ed96d..2322bd3 100644 --- a/src/Pecee/Http/Input/InputItem.php +++ b/src/Pecee/Http/Input/InputItem.php @@ -62,10 +62,10 @@ class InputItem implements IInputItem, \IteratorAggregate /** * Set input value - * @param string $value + * @param mixed $value * @return static */ - public function setValue(string $value): IInputItem + public function setValue($value): IInputItem { $this->value = $value; From aa8211a273ebb99a0bd04428d79460d6a0da9a7e Mon Sep 17 00:00:00 2001 From: Marius Karstedt Date: Tue, 23 Mar 2021 03:23:18 +0100 Subject: [PATCH 063/117] added tests to composer --- .github/workflows/ci.yml | 7 +------ composer.json | 5 +++++ 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index bbeb7b3..c7f7797 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -13,9 +13,4 @@ jobs: with: php_version: 7.3 - name: PHPUnit tests - uses: php-actions/phpunit@v2 - with: - php_version: 7.3 - bootstrap: tests/bootstrap.php - configuration: phpunit.xml - args: --coverage-text \ No newline at end of file + cmd: composer test \ No newline at end of file diff --git a/composer.json b/composer.json index 5d285cd..b472a9b 100644 --- a/composer.json +++ b/composer.json @@ -35,6 +35,11 @@ "phpunit/phpunit": "^6.0", "mockery/mockery": "^1" }, + "scripts": { + "test": [ + "phpunit tests" + ] + }, "autoload": { "psr-4": { "Pecee\\": "src/Pecee/" From 656946fbb26bd56d1c78f54d4e07364bbc0a7157 Mon Sep 17 00:00:00 2001 From: Marius Karstedt Date: Tue, 23 Mar 2021 03:33:51 +0100 Subject: [PATCH 064/117] Used cmd instead of run --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c7f7797..f9d228a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -13,4 +13,4 @@ jobs: with: php_version: 7.3 - name: PHPUnit tests - cmd: composer test \ No newline at end of file + run: composer test \ No newline at end of file From d7a295cb5c877e01aaed6b1d740f4b207cb8b03f Mon Sep 17 00:00:00 2001 From: DeveloperMarius Date: Tue, 23 Mar 2021 11:53:29 +0100 Subject: [PATCH 065/117] Change php version and test execution --- .github/workflows/ci.yml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f9d228a..cb658cd 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -11,6 +11,10 @@ jobs: - name: Setup composer uses: php-actions/composer@v5 with: - php_version: 7.3 + php_version: 7.4.6 + - name: PHPUnit version + run: phpunit --version - name: PHPUnit tests + run: phpunit tests + - name: PHPUnit tests 2 run: composer test \ No newline at end of file From 577c87c5275a7d202d828bf2f147205d583b4672 Mon Sep 17 00:00:00 2001 From: DeveloperMarius Date: Tue, 23 Mar 2021 11:57:03 +0100 Subject: [PATCH 066/117] Try to run phpunit from composer --- .github/workflows/ci.yml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index cb658cd..2cff725 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -15,6 +15,4 @@ jobs: - name: PHPUnit version run: phpunit --version - name: PHPUnit tests - run: phpunit tests - - name: PHPUnit tests 2 - run: composer test \ No newline at end of file + run: vendor/bin/phpunit tests \ No newline at end of file From 554d562e5631832b343db0717242081e14f3163c Mon Sep 17 00:00:00 2001 From: DeveloperMarius Date: Tue, 23 Mar 2021 12:04:10 +0100 Subject: [PATCH 067/117] Seem to get no error local, test on actions --- .github/workflows/ci.yml | 2 +- composer.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 2cff725..9c06f5e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -13,6 +13,6 @@ jobs: with: php_version: 7.4.6 - name: PHPUnit version - run: phpunit --version + run: vendor/bin/phpunit --version - name: PHPUnit tests run: vendor/bin/phpunit tests \ No newline at end of file diff --git a/composer.json b/composer.json index b472a9b..07e2bf4 100644 --- a/composer.json +++ b/composer.json @@ -32,7 +32,7 @@ "php-di/php-di": "^6.0" }, "require-dev": { - "phpunit/phpunit": "^6.0", + "phpunit/phpunit": "^8.5", "mockery/mockery": "^1" }, "scripts": { From 26a1659734354f2b078fa1d192c4682fcb2d01bd Mon Sep 17 00:00:00 2001 From: DeveloperMarius Date: Tue, 23 Mar 2021 12:07:53 +0100 Subject: [PATCH 068/117] Try to fix failures --- tests/Pecee/SimpleRouter/RouterResourceTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Pecee/SimpleRouter/RouterResourceTest.php b/tests/Pecee/SimpleRouter/RouterResourceTest.php index 0b6f5fb..af8ea85 100644 --- a/tests/Pecee/SimpleRouter/RouterResourceTest.php +++ b/tests/Pecee/SimpleRouter/RouterResourceTest.php @@ -9,7 +9,7 @@ class RouterResourceTest extends \PHPUnit\Framework\TestCase { TestRouter::resource('/resource', 'ResourceController'); $response = TestRouter::debugOutput('/resource', 'post'); - + echo '$response: '.json_encode($response); $this->assertEquals('store', $response); } From 37228d2bac6cd3415b8841ad862219cc9776feee Mon Sep 17 00:00:00 2001 From: DeveloperMarius Date: Tue, 23 Mar 2021 12:47:24 +0100 Subject: [PATCH 069/117] revert change --- tests/Pecee/SimpleRouter/RouterResourceTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Pecee/SimpleRouter/RouterResourceTest.php b/tests/Pecee/SimpleRouter/RouterResourceTest.php index af8ea85..0b6f5fb 100644 --- a/tests/Pecee/SimpleRouter/RouterResourceTest.php +++ b/tests/Pecee/SimpleRouter/RouterResourceTest.php @@ -9,7 +9,7 @@ class RouterResourceTest extends \PHPUnit\Framework\TestCase { TestRouter::resource('/resource', 'ResourceController'); $response = TestRouter::debugOutput('/resource', 'post'); - echo '$response: '.json_encode($response); + $this->assertEquals('store', $response); } From 87985841ded6c216f2a9ec53532a71cef8006f5f Mon Sep 17 00:00:00 2001 From: DeveloperMarius Date: Tue, 23 Mar 2021 12:48:49 +0100 Subject: [PATCH 070/117] complete change of tests --- .github/workflows/ci.yml | 81 +++++++++++++++++++++++++++++++++++----- composer.json | 2 +- 2 files changed, 73 insertions(+), 10 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 9c06f5e..0eb24af 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -4,15 +4,78 @@ on: [push, pull_request] jobs: build-test: - runs-on: ubuntu-latest + runs-on: ${{ matrix.os }} + env: + PHP_EXTENSIONS: json + PHP_INI_VALUES: assert.exception=1, zend.assertions=1 + + strategy: + fail-fast: false + matrix: + os: + - ubuntu-latest + - windows-latest + php-version: + - 7.3 + - 7.4 + phpunit-version: + - 8.5.2 + dependencies: + - lowest + - highest + include: + - os: ubuntu-latest + php-version: '7.2' + phpunit-version: '8.5.2' + name: PHPUnit Tests steps: - - uses: actions/checkout@v2 - - name: Setup composer - uses: php-actions/composer@v5 + - name: Configure git to avoid issues with line endings + if: matrix.os == 'windows-latest' + run: git config --global core.autocrlf false + - name: Checkout + uses: actions/checkout@v2 + - name: Setup PHP + uses: shivammathur/setup-php@v2 with: - php_version: 7.4.6 - - name: PHPUnit version - run: vendor/bin/phpunit --version - - name: PHPUnit tests - run: vendor/bin/phpunit tests \ No newline at end of file + php-version: ${{ matrix.php-version }} +# tools: phpunit:${{ matrix.phpunit-versions }} + coverage: xdebug + extensions: ${{ env.PHP_EXTENSIONS }} + ini-values: ${{ env.PHP_INI_VALUES }} +# - name: Get composer cache directory +# id: composer-cache +# run: echo "::set-output name=dir::$(composer config cache-files-dir)" + - name: Determine composer cache directory on Linux + if: matrix.os == 'ubuntu-latest' + run: echo "COMPOSER_CACHE_DIR=$(./tools/composer config cache-dir)" >> $GITHUB_ENV + - name: Determine composer cache directory on Windows + if: matrix.os == 'windows-latest' + run: ECHO "COMPOSER_CACHE_DIR=~\AppData\Local\Composer" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append + - name: Cache dependencies + uses: actions/cache@v2 + with: + path: ${{ env.COMPOSER_CACHE_DIR }} + key: php${{ matrix.php-version }}-composer-${{ matrix.dependencies }}-${{ hashFiles('**/composer.json') }} + restore-keys: | + php${{ matrix.php-version }}-composer-${{ matrix.dependencies }}- + - name: Install lowest dependencies with composer + if: matrix.dependencies == 'lowest' + run: php ./tools/composer update --no-ansi --no-interaction --no-progress --prefer-lowest + - name: Install highest dependencies with composer + if: matrix.dependencies == 'highest' + run: php ./tools/composer update --no-ansi --no-interaction --no-progress +# - name: Install dependencies +# run: composer install --prefer-dist + - name: Run tests with phpunit + run: php ./phpunit + + +# - name: Setup composer +# uses: php-actions/composer@v5 +# with: +# php_version: 7.4.6 +# - name: PHPUnit version +# run: vendor/bin/phpunit --version +# - name: PHPUnit tests +# run: vendor/bin/phpunit tests \ No newline at end of file diff --git a/composer.json b/composer.json index 07e2bf4..a94ed5b 100644 --- a/composer.json +++ b/composer.json @@ -37,7 +37,7 @@ }, "scripts": { "test": [ - "phpunit tests" + "php ./phpunit tests" ] }, "autoload": { From 9029a84fddb3b76ee987420429c586024bf7451e Mon Sep 17 00:00:00 2001 From: DeveloperMarius Date: Tue, 23 Mar 2021 13:04:59 +0100 Subject: [PATCH 071/117] reduced platforms and version for test & added composer --- .github/workflows/ci.yml | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 0eb24af..baf8ac4 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -15,15 +15,15 @@ jobs: matrix: os: - ubuntu-latest - - windows-latest +# - windows-latest php-version: - - 7.3 +# - 7.3 - 7.4 phpunit-version: - 8.5.2 - dependencies: - - lowest - - highest +# dependencies: +# - lowest +# - highest include: - os: ubuntu-latest php-version: '7.2' @@ -39,6 +39,7 @@ jobs: uses: shivammathur/setup-php@v2 with: php-version: ${{ matrix.php-version }} + tools: composer:v5 # tools: phpunit:${{ matrix.phpunit-versions }} coverage: xdebug extensions: ${{ env.PHP_EXTENSIONS }} From 537d607b9fc709f1d0d77531ea262adc7d1eb9f7 Mon Sep 17 00:00:00 2001 From: DeveloperMarius Date: Tue, 23 Mar 2021 13:17:07 +0100 Subject: [PATCH 072/117] Try to fix caching bugg --- .github/workflows/ci.yml | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index baf8ac4..a9d444b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -44,19 +44,20 @@ jobs: coverage: xdebug extensions: ${{ env.PHP_EXTENSIONS }} ini-values: ${{ env.PHP_INI_VALUES }} -# - name: Get composer cache directory -# id: composer-cache -# run: echo "::set-output name=dir::$(composer config cache-files-dir)" - - name: Determine composer cache directory on Linux - if: matrix.os == 'ubuntu-latest' - run: echo "COMPOSER_CACHE_DIR=$(./tools/composer config cache-dir)" >> $GITHUB_ENV - - name: Determine composer cache directory on Windows - if: matrix.os == 'windows-latest' - run: ECHO "COMPOSER_CACHE_DIR=~\AppData\Local\Composer" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append + - name: Get composer cache directory + id: composer-cache + run: echo "::set-output name=dir::$(composer config cache-files-dir)" +# - name: Determine composer cache directory on Linux +# if: matrix.os == 'ubuntu-latest' +# run: echo "COMPOSER_CACHE_DIR=$(./tools/composer config cache-dir)" >> $GITHUB_ENV +# - name: Determine composer cache directory on Windows +# if: matrix.os == 'windows-latest' +# run: ECHO "COMPOSER_CACHE_DIR=~\AppData\Local\Composer" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append - name: Cache dependencies uses: actions/cache@v2 with: - path: ${{ env.COMPOSER_CACHE_DIR }} +# path: ${{ env.COMPOSER_CACHE_DIR }} + path: ${{ steps.composer-cache.outputs.dir }} key: php${{ matrix.php-version }}-composer-${{ matrix.dependencies }}-${{ hashFiles('**/composer.json') }} restore-keys: | php${{ matrix.php-version }}-composer-${{ matrix.dependencies }}- From 4725b330fed471dbaf83a77c24d0020b5ce24867 Mon Sep 17 00:00:00 2001 From: DeveloperMarius Date: Tue, 23 Mar 2021 13:19:36 +0100 Subject: [PATCH 073/117] change test command & phpunit file update --- .github/workflows/ci.yml | 2 +- phpunit.xml | 9 +++++---- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a9d444b..c27bc1e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -70,7 +70,7 @@ jobs: # - name: Install dependencies # run: composer install --prefer-dist - name: Run tests with phpunit - run: php ./phpunit + run: phpunit tests # - name: Setup composer diff --git a/phpunit.xml b/phpunit.xml index 7aa2ef4..6841e44 100644 --- a/phpunit.xml +++ b/phpunit.xml @@ -15,9 +15,10 @@ tests/Pecee/SimpleRouter/ - - + + src - - + + From 5eadb79c64745fd7b698a6814b088626ef7d446d Mon Sep 17 00:00:00 2001 From: DeveloperMarius Date: Tue, 23 Mar 2021 13:20:29 +0100 Subject: [PATCH 074/117] add phpunit tool --- .github/workflows/ci.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c27bc1e..680ee3b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -39,8 +39,7 @@ jobs: uses: shivammathur/setup-php@v2 with: php-version: ${{ matrix.php-version }} - tools: composer:v5 -# tools: phpunit:${{ matrix.phpunit-versions }} + tools: composer:v5, phpunit:${{ matrix.phpunit-versions }} coverage: xdebug extensions: ${{ env.PHP_EXTENSIONS }} ini-values: ${{ env.PHP_INI_VALUES }} From 495cfba613cb0b9b9ad3cd0dda764303ef905b78 Mon Sep 17 00:00:00 2001 From: DeveloperMarius Date: Tue, 23 Mar 2021 13:22:32 +0100 Subject: [PATCH 075/117] Added relative path --- tests/bootstrap.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/bootstrap.php b/tests/bootstrap.php index 22f8cd2..5258258 100644 --- a/tests/bootstrap.php +++ b/tests/bootstrap.php @@ -1,4 +1,4 @@ Date: Tue, 23 Mar 2021 13:25:44 +0100 Subject: [PATCH 076/117] Try to fix composer install missing --- .github/workflows/ci.yml | 4 ++-- tests/bootstrap.php | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 680ee3b..b635062 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -21,8 +21,8 @@ jobs: - 7.4 phpunit-version: - 8.5.2 -# dependencies: -# - lowest + dependencies: + - lowest # - highest include: - os: ubuntu-latest diff --git a/tests/bootstrap.php b/tests/bootstrap.php index 5258258..22f8cd2 100644 --- a/tests/bootstrap.php +++ b/tests/bootstrap.php @@ -1,4 +1,4 @@ Date: Tue, 23 Mar 2021 13:27:18 +0100 Subject: [PATCH 077/117] correct composer exec path --- .github/workflows/ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b635062..a20492f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -62,10 +62,10 @@ jobs: php${{ matrix.php-version }}-composer-${{ matrix.dependencies }}- - name: Install lowest dependencies with composer if: matrix.dependencies == 'lowest' - run: php ./tools/composer update --no-ansi --no-interaction --no-progress --prefer-lowest + run: php composer update --no-ansi --no-interaction --no-progress --prefer-lowest - name: Install highest dependencies with composer if: matrix.dependencies == 'highest' - run: php ./tools/composer update --no-ansi --no-interaction --no-progress + run: php composer update --no-ansi --no-interaction --no-progress # - name: Install dependencies # run: composer install --prefer-dist - name: Run tests with phpunit From a103c711632034b9f9c42b5281f20cfdfd5d597e Mon Sep 17 00:00:00 2001 From: DeveloperMarius Date: Tue, 23 Mar 2021 13:28:17 +0100 Subject: [PATCH 078/117] Try to fix composer install missing --- .github/workflows/ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a20492f..e3c354e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -62,10 +62,10 @@ jobs: php${{ matrix.php-version }}-composer-${{ matrix.dependencies }}- - name: Install lowest dependencies with composer if: matrix.dependencies == 'lowest' - run: php composer update --no-ansi --no-interaction --no-progress --prefer-lowest + run: composer update --no-ansi --no-interaction --no-progress --prefer-lowest - name: Install highest dependencies with composer if: matrix.dependencies == 'highest' - run: php composer update --no-ansi --no-interaction --no-progress + run: composer update --no-ansi --no-interaction --no-progress # - name: Install dependencies # run: composer install --prefer-dist - name: Run tests with phpunit From 69fdfb3560fdb9562fc82acf17d6dbbbd6e7d97d Mon Sep 17 00:00:00 2001 From: DeveloperMarius Date: Tue, 23 Mar 2021 13:30:57 +0100 Subject: [PATCH 079/117] remove matrix include & PHPUnit requires PHP >= 7.3 --- .github/workflows/ci.yml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index e3c354e..73fdb12 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -15,19 +15,19 @@ jobs: matrix: os: - ubuntu-latest -# - windows-latest + - windows-latest php-version: -# - 7.3 - 7.4 + - 8.1 phpunit-version: - 8.5.2 dependencies: - lowest -# - highest - include: - - os: ubuntu-latest - php-version: '7.2' - phpunit-version: '8.5.2' + - highest +# include: +# - os: ubuntu-latest +# php-version: '7.2' +# phpunit-version: '8.5.2' name: PHPUnit Tests steps: - name: Configure git to avoid issues with line endings From c408f79d8a13df968740db89f4438e36fd25aa9d Mon Sep 17 00:00:00 2001 From: DeveloperMarius Date: Tue, 23 Mar 2021 13:34:55 +0100 Subject: [PATCH 080/117] changed to PHP >= 3 & run test via composer test --- .github/workflows/ci.yml | 3 +-- composer.json | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 73fdb12..b7fa3a1 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -18,7 +18,6 @@ jobs: - windows-latest php-version: - 7.4 - - 8.1 phpunit-version: - 8.5.2 dependencies: @@ -69,7 +68,7 @@ jobs: # - name: Install dependencies # run: composer install --prefer-dist - name: Run tests with phpunit - run: phpunit tests + run: composer test # - name: Setup composer diff --git a/composer.json b/composer.json index a94ed5b..84520bb 100644 --- a/composer.json +++ b/composer.json @@ -27,7 +27,7 @@ } ], "require": { - "php": ">=7.1", + "php": ">=7.3", "ext-json": "*", "php-di/php-di": "^6.0" }, From 9f0373938dcec58875c7c6f004f7c9aed5c0c0f1 Mon Sep 17 00:00:00 2001 From: DeveloperMarius Date: Tue, 23 Mar 2021 13:35:57 +0100 Subject: [PATCH 081/117] fix composer test command --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 84520bb..d4f109c 100644 --- a/composer.json +++ b/composer.json @@ -37,7 +37,7 @@ }, "scripts": { "test": [ - "php ./phpunit tests" + "phpunit tests" ] }, "autoload": { From 08008ca847b8a174e69ccafed524476277e464be Mon Sep 17 00:00:00 2001 From: DeveloperMarius Date: Tue, 23 Mar 2021 13:40:08 +0100 Subject: [PATCH 082/117] Add PHP 7.3 check --- .github/workflows/ci.yml | 15 ++------------- 1 file changed, 2 insertions(+), 13 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b7fa3a1..e176f09 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -17,6 +17,7 @@ jobs: - ubuntu-latest - windows-latest php-version: + - 7.3 - 7.4 phpunit-version: - 8.5.2 @@ -65,17 +66,5 @@ jobs: - name: Install highest dependencies with composer if: matrix.dependencies == 'highest' run: composer update --no-ansi --no-interaction --no-progress -# - name: Install dependencies -# run: composer install --prefer-dist - name: Run tests with phpunit - run: composer test - - -# - name: Setup composer -# uses: php-actions/composer@v5 -# with: -# php_version: 7.4.6 -# - name: PHPUnit version -# run: vendor/bin/phpunit --version -# - name: PHPUnit tests -# run: vendor/bin/phpunit tests \ No newline at end of file + run: composer test \ No newline at end of file From 62f5e5cbbdba8f7676e41e78fb7b19712fb102da Mon Sep 17 00:00:00 2001 From: DeveloperMarius Date: Tue, 23 Mar 2021 13:40:22 +0100 Subject: [PATCH 083/117] Add Failing test --- tests/Pecee/SimpleRouter/RouterResourceTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Pecee/SimpleRouter/RouterResourceTest.php b/tests/Pecee/SimpleRouter/RouterResourceTest.php index 0b6f5fb..6f01545 100644 --- a/tests/Pecee/SimpleRouter/RouterResourceTest.php +++ b/tests/Pecee/SimpleRouter/RouterResourceTest.php @@ -10,7 +10,7 @@ class RouterResourceTest extends \PHPUnit\Framework\TestCase TestRouter::resource('/resource', 'ResourceController'); $response = TestRouter::debugOutput('/resource', 'post'); - $this->assertEquals('store', $response); + $this->assertNotEquals('store', $response); } public function testResourceCreate() From 5275653606c25bf4294505e756c95aaef010bc7c Mon Sep 17 00:00:00 2001 From: DeveloperMarius Date: Tue, 23 Mar 2021 13:41:27 +0100 Subject: [PATCH 084/117] Correct test to succeed --- tests/Pecee/SimpleRouter/RouterResourceTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Pecee/SimpleRouter/RouterResourceTest.php b/tests/Pecee/SimpleRouter/RouterResourceTest.php index 6f01545..0b6f5fb 100644 --- a/tests/Pecee/SimpleRouter/RouterResourceTest.php +++ b/tests/Pecee/SimpleRouter/RouterResourceTest.php @@ -10,7 +10,7 @@ class RouterResourceTest extends \PHPUnit\Framework\TestCase TestRouter::resource('/resource', 'ResourceController'); $response = TestRouter::debugOutput('/resource', 'post'); - $this->assertNotEquals('store', $response); + $this->assertEquals('store', $response); } public function testResourceCreate() From 5095b1abc9d6c778ba90cb4abf21417e2da93f9d Mon Sep 17 00:00:00 2001 From: DeveloperMarius Date: Tue, 23 Mar 2021 13:54:00 +0100 Subject: [PATCH 085/117] cleanup --- .github/workflows/ci.yml | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index e176f09..e7f3549 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -24,10 +24,6 @@ jobs: dependencies: - lowest - highest -# include: -# - os: ubuntu-latest -# php-version: '7.2' -# phpunit-version: '8.5.2' name: PHPUnit Tests steps: - name: Configure git to avoid issues with line endings @@ -46,16 +42,9 @@ jobs: - name: Get composer cache directory id: composer-cache run: echo "::set-output name=dir::$(composer config cache-files-dir)" -# - name: Determine composer cache directory on Linux -# if: matrix.os == 'ubuntu-latest' -# run: echo "COMPOSER_CACHE_DIR=$(./tools/composer config cache-dir)" >> $GITHUB_ENV -# - name: Determine composer cache directory on Windows -# if: matrix.os == 'windows-latest' -# run: ECHO "COMPOSER_CACHE_DIR=~\AppData\Local\Composer" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append - name: Cache dependencies uses: actions/cache@v2 with: -# path: ${{ env.COMPOSER_CACHE_DIR }} path: ${{ steps.composer-cache.outputs.dir }} key: php${{ matrix.php-version }}-composer-${{ matrix.dependencies }}-${{ hashFiles('**/composer.json') }} restore-keys: | From 6be9d1003c93a267636fa3e577cfc702b5a7cd89 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20Sessing=C3=B8?= Date: Tue, 23 Mar 2021 14:33:25 +0100 Subject: [PATCH 086/117] Updated travis.xml --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 72c98f1..aa11649 100644 --- a/.travis.yml +++ b/.travis.yml @@ -10,4 +10,4 @@ before_script: - php composer.phar install --prefer-source --no-interaction script: - - ./vendor/bin/phpunit + - ./vendor/bin/phpunit --configuration ./phpunit.xml ./tests --teamcity From 8670af356b936abcddd659bed2e944c827800613 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20Sessing=C3=B8?= Date: Tue, 23 Mar 2021 14:37:04 +0100 Subject: [PATCH 087/117] Updated travis.yml --- .travis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index aa11649..24c3e5d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,11 +3,11 @@ sudo: false language: php php: - - 7.1 + - 7.3 before_script: - curl -sS http://getcomposer.org/installer | php - php composer.phar install --prefer-source --no-interaction script: - - ./vendor/bin/phpunit --configuration ./phpunit.xml ./tests --teamcity + - ./vendor/bin/phpunit --configuration ./phpunit.xml From 7ba864420e1ec5f631a60097e67c855925b32863 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20Sessing=C3=B8?= Date: Tue, 23 Mar 2021 14:47:11 +0100 Subject: [PATCH 088/117] Updated travis.yml --- .travis.yml | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index 24c3e5d..0595845 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,11 +3,25 @@ sudo: false language: php php: - - 7.3 + - 7.2 before_script: - - curl -sS http://getcomposer.org/installer | php - - php composer.phar install --prefer-source --no-interaction + - mkdir -p _clover + - ls -al script: - - ./vendor/bin/phpunit --configuration ./phpunit.xml + - ./vendor/bin/phpunit --coverage-clover _clover/clover.xml + +install: + # Install composer packages + - travis_retry composer install --no-interaction --no-suggest + # Install coveralls.phar + - wget -c -nc --retry-connrefused --tries=0 https://github.com/php-coveralls/php-coveralls/releases/download/v2.0.0/php-coveralls.phar -O coveralls.phar + - chmod +x coveralls.phar + - php coveralls.phar --version + +after_success: + # Submit coverage report to Coveralls servers, see .coveralls.yml + - travis_retry php coveralls.phar -v + # Submit coverage report to codecov.io + - bash <(curl -s https://codecov.io/bash) \ No newline at end of file From 635b12735745859b2a9188d1a164aaaffbdd06f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20Sessing=C3=B8?= Date: Tue, 23 Mar 2021 15:06:21 +0100 Subject: [PATCH 089/117] Fixed correct return type for InputFile. --- src/Pecee/Http/Input/InputFile.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Pecee/Http/Input/InputFile.php b/src/Pecee/Http/Input/InputFile.php index 2919187..c2c345f 100644 --- a/src/Pecee/Http/Input/InputFile.php +++ b/src/Pecee/Http/Input/InputFile.php @@ -261,16 +261,16 @@ class InputFile implements IInputItem return $this->getTmpName(); } - public function getValue(): ?string + public function getValue() { return $this->getFilename(); } /** - * @param string $value + * @param mixed $value * @return static */ - public function setValue(string $value): IInputItem + public function setValue($value): IInputItem { $this->filename = $value; From 7920188956e419a38a4afa1433e0cab85bfdaac4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20Sessing=C3=B8?= Date: Tue, 23 Mar 2021 15:11:44 +0100 Subject: [PATCH 090/117] Updated travis.yml --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 0595845..540b3b2 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,7 +3,7 @@ sudo: false language: php php: - - 7.2 + - 7.4 before_script: - mkdir -p _clover From df52ec3df753230410426be821f7ba43fccd51e6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20Sessing=C3=B8?= Date: Tue, 23 Mar 2021 15:15:58 +0100 Subject: [PATCH 091/117] Updated travis.yml --- .travis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 540b3b2..2560aa1 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,14 +3,14 @@ sudo: false language: php php: - - 7.4 + - 7.3 before_script: - mkdir -p _clover - ls -al script: - - ./vendor/bin/phpunit --coverage-clover _clover/clover.xml + - ./vendor/phpunit/phpunit/phpunit --configuration ./phpunit.xml install: # Install composer packages From db63aff668e6be90434f5dbb32e90b4bc90b49df Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20Sessing=C3=B8?= Date: Tue, 23 Mar 2021 15:20:05 +0100 Subject: [PATCH 092/117] Updated php-unit to version 9 --- .phpunit.result.cache | 1 + .travis.yml | 2 +- composer.json | 2 +- phpunit.xml | 8 +------- tests/Pecee/SimpleRouter/RouterRewriteTest.php | 2 +- 5 files changed, 5 insertions(+), 10 deletions(-) create mode 100644 .phpunit.result.cache diff --git a/.phpunit.result.cache b/.phpunit.result.cache new file mode 100644 index 0000000..5deaa32 --- /dev/null +++ b/.phpunit.result.cache @@ -0,0 +1 @@ +C:37:"PHPUnit\Runner\DefaultTestResultCache":3429:{a:2:{s:7:"defects";a:0:{}s:5:"times";a:70:{s:38:"BootManagerTest::testBootManagerRoutes";d:0.007;s:43:"BootManagerTest::testFindUrlFromBootManager";d:0;s:38:"ClassLoaderTest::testCustomClassLoader";d:0;s:39:"EventHandlerTest::testAllEventTriggered";d:0.002;s:30:"EventHandlerTest::testAllEvent";d:0;s:33:"EventHandlerTest::testPrefixEvent";d:0;s:24:"GroupTest::testGroupLoad";d:0;s:26:"GroupTest::testNestedGroup";d:0;s:29:"GroupTest::testMultipleRoutes";d:0;s:19:"GroupTest::testUrls";d:0;s:26:"InputHandlerTest::testPost";d:0.001;s:25:"InputHandlerTest::testGet";d:0;s:26:"InputHandlerTest::testFile";d:0;s:27:"InputHandlerTest::testFiles";d:0;s:25:"InputHandlerTest::testAll";d:0;s:35:"MiddlewareTest::testMiddlewareFound";d:0.001;s:44:"MiddlewareTest::testNestedMiddlewareDontLoad";d:0;s:64:"RouterCallbackExceptionHandlerTest::testCallbackExceptionHandler";d:0;s:29:"RouterControllerTest::testGet";d:0.001;s:30:"RouterControllerTest::testPost";d:0;s:29:"RouterControllerTest::testPut";d:0;s:38:"RouterPartialGroupTest::testParameters";d:0;s:49:"RouterPartialGroupTest::testPartialGroupWithGroup";d:0.001;s:37:"RouterResourceTest::testResourceStore";d:0.001;s:38:"RouterResourceTest::testResourceCreate";d:0;s:37:"RouterResourceTest::testResourceIndex";d:0;s:39:"RouterResourceTest::testResourceDestroy";d:0;s:36:"RouterResourceTest::testResourceEdit";d:0;s:38:"RouterResourceTest::testResourceUpdate";d:0;s:35:"RouterResourceTest::testResourceGet";d:0;s:45:"RouteRewriteTest::testExceptionHandlerRewrite";d:0;s:45:"RouteRewriteTest::testRewriteExceptionMessage";d:0;s:41:"RouteRewriteTest::testRewriteUrlFromRoute";d:0;s:46:"RouteRewriteTest::testRewriteCallbackFromRoute";d:0;s:43:"RouteRewriteTest::testRewriteRouteFromRoute";d:0;s:39:"RouteRewriteTest::testMiddlewareRewrite";d:0;s:43:"RouterRouteTest::testOptionalCharacterRoute";d:0;s:31:"RouterRouteTest::testMultiParam";d:0;s:29:"RouterRouteTest::testNotFound";d:0;s:24:"RouterRouteTest::testGet";d:0;s:25:"RouterRouteTest::testPost";d:0;s:24:"RouterRouteTest::testPut";d:0;s:27:"RouterRouteTest::testDelete";d:0;s:37:"RouterRouteTest::testMethodNotAllowed";d:0;s:32:"RouterRouteTest::testSimpleParam";d:0;s:35:"RouterRouteTest::testPathParamRegex";d:0;s:39:"RouterRouteTest::testDomainAllowedRoute";d:0;s:42:"RouterRouteTest::testDomainNotAllowedRoute";d:0;s:26:"RouterRouteTest::testRegEx";d:0;s:41:"RouterRouteTest::testParametersWithDashes";d:0;s:42:"RouterRouteTest::testParameterDefaultValue";d:0;s:42:"RouterRouteTest::testDefaultParameterRegex";d:0;s:47:"RouterRouteTest::testDefaultParameterRegexGroup";d:0;s:30:"RouterRouteTest::testClassHint";d:0;s:31:"RouterRouteTest::testSameRoutes";d:0;s:27:"RouterUrlTest::testIssue253";d:0;s:36:"RouterUrlTest::testUnicodeCharacters";d:0;s:37:"RouterUrlTest::testOptionalParameters";d:0.001;s:30:"RouterUrlTest::testSimilarUrls";d:0;s:23:"RouterUrlTest::testUrls";d:0.001;s:30:"RouterUrlTest::testCustomRegex";d:0;s:47:"RouterUrlTest::testRenderMultipleRoutesDisabled";d:0;s:46:"RouterUrlTest::testRenderMultipleRoutesEnabled";d:0;s:35:"RouterUrlTest::testDefaultNamespace";d:0;s:46:"RouterRewriteTest::testExceptionHandlerRewrite";d:0;s:46:"RouterRewriteTest::testRewriteExceptionMessage";d:0;s:42:"RouterRewriteTest::testRewriteUrlFromRoute";d:0;s:47:"RouterRewriteTest::testRewriteCallbackFromRoute";d:0;s:44:"RouterRewriteTest::testRewriteRouteFromRoute";d:0;s:40:"RouterRewriteTest::testMiddlewareRewrite";d:0;}}} \ No newline at end of file diff --git a/.travis.yml b/.travis.yml index 2560aa1..a5a5064 100644 --- a/.travis.yml +++ b/.travis.yml @@ -10,7 +10,7 @@ before_script: - ls -al script: - - ./vendor/phpunit/phpunit/phpunit --configuration ./phpunit.xml + - ./vendor/bin/phpunit --coverage-clover _clover/clover.xml install: # Install composer packages diff --git a/composer.json b/composer.json index 8514aee..a3f0b54 100644 --- a/composer.json +++ b/composer.json @@ -31,7 +31,7 @@ "ext-json": "*" }, "require-dev": { - "phpunit/phpunit": "^6.0", + "phpunit/phpunit": "^9.0", "mockery/mockery": "^1" }, "autoload": { diff --git a/phpunit.xml b/phpunit.xml index 6e8f0c6..8aa0a67 100644 --- a/phpunit.xml +++ b/phpunit.xml @@ -9,16 +9,10 @@ convertNoticesToExceptions="true" convertWarningsToExceptions="true" processIsolation="false" - stopOnFailure="false" - syntaxCheck="false"> + stopOnFailure="false"> tests/Pecee/SimpleRouter/ - - - src - - diff --git a/tests/Pecee/SimpleRouter/RouterRewriteTest.php b/tests/Pecee/SimpleRouter/RouterRewriteTest.php index c0692c1..5764638 100644 --- a/tests/Pecee/SimpleRouter/RouterRewriteTest.php +++ b/tests/Pecee/SimpleRouter/RouterRewriteTest.php @@ -6,7 +6,7 @@ require_once 'Dummy/Handler/ExceptionHandlerSecond.php'; require_once 'Dummy/Handler/ExceptionHandlerThird.php'; require_once 'Dummy/Middleware/RewriteMiddleware.php'; -class RouteRewriteTest extends \PHPUnit\Framework\TestCase +class RouterRewriteTest extends \PHPUnit\Framework\TestCase { /** From c466af556e541d35e70822b5b608022af115d0f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20Sessing=C3=B8?= Date: Tue, 23 Mar 2021 15:22:31 +0100 Subject: [PATCH 093/117] Updated travis.yml --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index a5a5064..263fec2 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,7 +3,7 @@ sudo: false language: php php: - - 7.3 + - 7.4.2 before_script: - mkdir -p _clover From 57936b785747f317782e8a6a6105dfd392fd5f22 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20Sessing=C3=B8?= Date: Tue, 23 Mar 2021 15:26:57 +0100 Subject: [PATCH 094/117] Reverted back php-unit version --- .phpunit.result.cache | 1 - composer.json | 2 +- phpunit.xml | 8 +++++++- 3 files changed, 8 insertions(+), 3 deletions(-) delete mode 100644 .phpunit.result.cache diff --git a/.phpunit.result.cache b/.phpunit.result.cache deleted file mode 100644 index 5deaa32..0000000 --- a/.phpunit.result.cache +++ /dev/null @@ -1 +0,0 @@ -C:37:"PHPUnit\Runner\DefaultTestResultCache":3429:{a:2:{s:7:"defects";a:0:{}s:5:"times";a:70:{s:38:"BootManagerTest::testBootManagerRoutes";d:0.007;s:43:"BootManagerTest::testFindUrlFromBootManager";d:0;s:38:"ClassLoaderTest::testCustomClassLoader";d:0;s:39:"EventHandlerTest::testAllEventTriggered";d:0.002;s:30:"EventHandlerTest::testAllEvent";d:0;s:33:"EventHandlerTest::testPrefixEvent";d:0;s:24:"GroupTest::testGroupLoad";d:0;s:26:"GroupTest::testNestedGroup";d:0;s:29:"GroupTest::testMultipleRoutes";d:0;s:19:"GroupTest::testUrls";d:0;s:26:"InputHandlerTest::testPost";d:0.001;s:25:"InputHandlerTest::testGet";d:0;s:26:"InputHandlerTest::testFile";d:0;s:27:"InputHandlerTest::testFiles";d:0;s:25:"InputHandlerTest::testAll";d:0;s:35:"MiddlewareTest::testMiddlewareFound";d:0.001;s:44:"MiddlewareTest::testNestedMiddlewareDontLoad";d:0;s:64:"RouterCallbackExceptionHandlerTest::testCallbackExceptionHandler";d:0;s:29:"RouterControllerTest::testGet";d:0.001;s:30:"RouterControllerTest::testPost";d:0;s:29:"RouterControllerTest::testPut";d:0;s:38:"RouterPartialGroupTest::testParameters";d:0;s:49:"RouterPartialGroupTest::testPartialGroupWithGroup";d:0.001;s:37:"RouterResourceTest::testResourceStore";d:0.001;s:38:"RouterResourceTest::testResourceCreate";d:0;s:37:"RouterResourceTest::testResourceIndex";d:0;s:39:"RouterResourceTest::testResourceDestroy";d:0;s:36:"RouterResourceTest::testResourceEdit";d:0;s:38:"RouterResourceTest::testResourceUpdate";d:0;s:35:"RouterResourceTest::testResourceGet";d:0;s:45:"RouteRewriteTest::testExceptionHandlerRewrite";d:0;s:45:"RouteRewriteTest::testRewriteExceptionMessage";d:0;s:41:"RouteRewriteTest::testRewriteUrlFromRoute";d:0;s:46:"RouteRewriteTest::testRewriteCallbackFromRoute";d:0;s:43:"RouteRewriteTest::testRewriteRouteFromRoute";d:0;s:39:"RouteRewriteTest::testMiddlewareRewrite";d:0;s:43:"RouterRouteTest::testOptionalCharacterRoute";d:0;s:31:"RouterRouteTest::testMultiParam";d:0;s:29:"RouterRouteTest::testNotFound";d:0;s:24:"RouterRouteTest::testGet";d:0;s:25:"RouterRouteTest::testPost";d:0;s:24:"RouterRouteTest::testPut";d:0;s:27:"RouterRouteTest::testDelete";d:0;s:37:"RouterRouteTest::testMethodNotAllowed";d:0;s:32:"RouterRouteTest::testSimpleParam";d:0;s:35:"RouterRouteTest::testPathParamRegex";d:0;s:39:"RouterRouteTest::testDomainAllowedRoute";d:0;s:42:"RouterRouteTest::testDomainNotAllowedRoute";d:0;s:26:"RouterRouteTest::testRegEx";d:0;s:41:"RouterRouteTest::testParametersWithDashes";d:0;s:42:"RouterRouteTest::testParameterDefaultValue";d:0;s:42:"RouterRouteTest::testDefaultParameterRegex";d:0;s:47:"RouterRouteTest::testDefaultParameterRegexGroup";d:0;s:30:"RouterRouteTest::testClassHint";d:0;s:31:"RouterRouteTest::testSameRoutes";d:0;s:27:"RouterUrlTest::testIssue253";d:0;s:36:"RouterUrlTest::testUnicodeCharacters";d:0;s:37:"RouterUrlTest::testOptionalParameters";d:0.001;s:30:"RouterUrlTest::testSimilarUrls";d:0;s:23:"RouterUrlTest::testUrls";d:0.001;s:30:"RouterUrlTest::testCustomRegex";d:0;s:47:"RouterUrlTest::testRenderMultipleRoutesDisabled";d:0;s:46:"RouterUrlTest::testRenderMultipleRoutesEnabled";d:0;s:35:"RouterUrlTest::testDefaultNamespace";d:0;s:46:"RouterRewriteTest::testExceptionHandlerRewrite";d:0;s:46:"RouterRewriteTest::testRewriteExceptionMessage";d:0;s:42:"RouterRewriteTest::testRewriteUrlFromRoute";d:0;s:47:"RouterRewriteTest::testRewriteCallbackFromRoute";d:0;s:44:"RouterRewriteTest::testRewriteRouteFromRoute";d:0;s:40:"RouterRewriteTest::testMiddlewareRewrite";d:0;}}} \ No newline at end of file diff --git a/composer.json b/composer.json index a3f0b54..8514aee 100644 --- a/composer.json +++ b/composer.json @@ -31,7 +31,7 @@ "ext-json": "*" }, "require-dev": { - "phpunit/phpunit": "^9.0", + "phpunit/phpunit": "^6.0", "mockery/mockery": "^1" }, "autoload": { diff --git a/phpunit.xml b/phpunit.xml index 8aa0a67..6e8f0c6 100644 --- a/phpunit.xml +++ b/phpunit.xml @@ -9,10 +9,16 @@ convertNoticesToExceptions="true" convertWarningsToExceptions="true" processIsolation="false" - stopOnFailure="false"> + stopOnFailure="false" + syntaxCheck="false"> tests/Pecee/SimpleRouter/ + + + src + + From dbd8d381e712f3b05aa1feea8e4919d7e198ace0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20Sessing=C3=B8?= Date: Tue, 23 Mar 2021 15:31:47 +0100 Subject: [PATCH 095/117] Updated travis.yml --- .travis.yml | 22 +++------------------- 1 file changed, 3 insertions(+), 19 deletions(-) diff --git a/.travis.yml b/.travis.yml index 263fec2..d3645cb 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,27 +1,11 @@ -sudo: false - language: php php: - 7.4.2 before_script: - - mkdir -p _clover - - ls -al + - curl -sS http://getcomposer.org/installer | php + - php composer.phar install --prefer-source --no-interaction script: - - ./vendor/bin/phpunit --coverage-clover _clover/clover.xml - -install: - # Install composer packages - - travis_retry composer install --no-interaction --no-suggest - # Install coveralls.phar - - wget -c -nc --retry-connrefused --tries=0 https://github.com/php-coveralls/php-coveralls/releases/download/v2.0.0/php-coveralls.phar -O coveralls.phar - - chmod +x coveralls.phar - - php coveralls.phar --version - -after_success: - # Submit coverage report to Coveralls servers, see .coveralls.yml - - travis_retry php coveralls.phar -v - # Submit coverage report to codecov.io - - bash <(curl -s https://codecov.io/bash) \ No newline at end of file + - ./vendor/bin/phpunit \ No newline at end of file From 42633ec453318ee9b806a89358671cff1923111b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20Sessing=C3=B8?= Date: Tue, 23 Mar 2021 15:38:10 +0100 Subject: [PATCH 096/117] php-unit updates --- .travis.yml | 20 +++++++++++++++++--- composer.json | 2 +- phpunit.xml | 14 +++++++------- 3 files changed, 25 insertions(+), 11 deletions(-) diff --git a/.travis.yml b/.travis.yml index d3645cb..a3d4148 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,8 +4,22 @@ php: - 7.4.2 before_script: - - curl -sS http://getcomposer.org/installer | php - - php composer.phar install --prefer-source --no-interaction + - mkdir -p _clover + - ls -al script: - - ./vendor/bin/phpunit \ No newline at end of file + - ./vendor/phpunit/phpunit/phpunit --configuration ./phpunit.xml ./tests + +install: + # Install composer packages + - travis_retry composer install --no-interaction --no-suggest + # Install coveralls.phar + - wget -c -nc --retry-connrefused --tries=0 https://github.com/php-coveralls/php-coveralls/releases/download/v2.0.0/php-coveralls.phar -O coveralls.phar + - chmod +x coveralls.phar + - php coveralls.phar --version + +after_success: + # Submit coverage report to Coveralls servers, see .coveralls.yml + - travis_retry php coveralls.phar -v + # Submit coverage report to codecov.io + - bash <(curl -s https://codecov.io/bash) \ No newline at end of file diff --git a/composer.json b/composer.json index 8514aee..4f4ee6f 100644 --- a/composer.json +++ b/composer.json @@ -31,7 +31,7 @@ "ext-json": "*" }, "require-dev": { - "phpunit/phpunit": "^6.0", + "phpunit/phpunit": "^8.0", "mockery/mockery": "^1" }, "autoload": { diff --git a/phpunit.xml b/phpunit.xml index 6e8f0c6..bad4398 100644 --- a/phpunit.xml +++ b/phpunit.xml @@ -9,16 +9,16 @@ convertNoticesToExceptions="true" convertWarningsToExceptions="true" processIsolation="false" - stopOnFailure="false" - syntaxCheck="false"> + stopOnFailure="false"> tests/Pecee/SimpleRouter/ - - + + src - - - + + + \ No newline at end of file From cfc8b5db43e0c195f74ce33986ffbf906739fab4 Mon Sep 17 00:00:00 2001 From: DeveloperMarius Date: Tue, 23 Mar 2021 15:44:43 +0100 Subject: [PATCH 097/117] Test PHP Version 7.1 with PHPUnit 7 --- .github/workflows/ci.yml | 3 ++- composer.json | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index e7f3549..08f61c4 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -20,7 +20,8 @@ jobs: - 7.3 - 7.4 phpunit-version: - - 8.5.2 +# - 8.5.2 + - 7 dependencies: - lowest - highest diff --git a/composer.json b/composer.json index 7677496..7b18724 100644 --- a/composer.json +++ b/composer.json @@ -31,7 +31,7 @@ "ext-json": "*" }, "require-dev": { - "phpunit/phpunit": "^8.0", + "phpunit/phpunit": "^7", "mockery/mockery": "^1" }, "scripts": { From 61fee760b0dfa98e6f7e6556cc72b1238ba880f6 Mon Sep 17 00:00:00 2001 From: DeveloperMarius Date: Tue, 23 Mar 2021 15:46:22 +0100 Subject: [PATCH 098/117] use phpunit version 7.5.20 like composer --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 08f61c4..fa1f9b0 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -21,7 +21,7 @@ jobs: - 7.4 phpunit-version: # - 8.5.2 - - 7 + - 7.5.20 dependencies: - lowest - highest From 1d480349102708de967077d292388939ee480e56 Mon Sep 17 00:00:00 2001 From: DeveloperMarius Date: Tue, 23 Mar 2021 15:48:36 +0100 Subject: [PATCH 099/117] code cleanup --- .github/workflows/ci.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index fa1f9b0..6f44c1f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -20,7 +20,6 @@ jobs: - 7.3 - 7.4 phpunit-version: -# - 8.5.2 - 7.5.20 dependencies: - lowest From 0892f5b6f331685e083dedea31f155805c3732c2 Mon Sep 17 00:00:00 2001 From: DeveloperMarius Date: Tue, 23 Mar 2021 15:49:32 +0100 Subject: [PATCH 100/117] replaced php version 7.3 with with 7.1 --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 6f44c1f..e2ccc7b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -17,7 +17,7 @@ jobs: - ubuntu-latest - windows-latest php-version: - - 7.3 + - 7.1 - 7.4 phpunit-version: - 7.5.20 From 543e550dafb3401e02f013b34894c4a3d69f0ff5 Mon Sep 17 00:00:00 2001 From: DeveloperMarius Date: Wed, 24 Mar 2021 11:48:29 +0100 Subject: [PATCH 101/117] PHPUnit fix: Element 'coverage': This element is not expected. --- phpunit.xml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/phpunit.xml b/phpunit.xml index 6841e44..49b5e9e 100644 --- a/phpunit.xml +++ b/phpunit.xml @@ -15,10 +15,10 @@ tests/Pecee/SimpleRouter/ - - + + src - - + + From 5624c4b2bbd52ec6634f98c98e9d8b2432c2b5e0 Mon Sep 17 00:00:00 2001 From: DeveloperMarius Date: Wed, 24 Mar 2021 13:11:07 +0100 Subject: [PATCH 102/117] testFiles and test file content on server --- tests/Pecee/SimpleRouter/InputHandlerTest.php | 32 +++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/tests/Pecee/SimpleRouter/InputHandlerTest.php b/tests/Pecee/SimpleRouter/InputHandlerTest.php index 7fcb87b..99bd83e 100644 --- a/tests/Pecee/SimpleRouter/InputHandlerTest.php +++ b/tests/Pecee/SimpleRouter/InputHandlerTest.php @@ -113,6 +113,38 @@ class InputHandlerTest extends \PHPUnit\Framework\TestCase public function testFile() { + global $_FILES; + + $_FILES = array( + 'test' => array( + 'name' => 'test.txt', + 'type' => 'text/plain', + 'tmp_name' => '/tmp/phpYfWUiw', + 'error' => 0, + 'size' => 4 + ) + ); + + $router = TestRouter::router(); + $router->reset(); + $router->getRequest()->setMethod('post'); + + $handler = TestRouter::request()->getInputHandler(); + $file = $handler->file('test'); + $this->assertInstanceOf(\Pecee\Http\Input\InputFile::class, $file); + $this->assertEquals('test.txt', $file->getFilename()); + $this->assertEquals('text/plain', $file->getType()); + $this->assertEquals('/tmp/phpYfWUiw', $file->getTmpName()); + $this->assertEquals(0, $file->getError()); + $this->assertEquals(4, $file->getSize()); + $this->assertEquals('txt', $file->getExtension()); + + + if(file_exists('/tmp')){ + file_put_contents('/tmp/phpYfWUiw', 'test'); + $this->assertEquals('test', $file->getContents()); + } + // TODO: implement test-file $this->assertEquals(true, true); } From fef65313e5d4744a0d5910bc5da379347b1df92c Mon Sep 17 00:00:00 2001 From: DeveloperMarius Date: Wed, 24 Mar 2021 13:20:41 +0100 Subject: [PATCH 103/117] Added file content test for all platforms --- tests/Pecee/SimpleRouter/InputHandlerTest.php | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/tests/Pecee/SimpleRouter/InputHandlerTest.php b/tests/Pecee/SimpleRouter/InputHandlerTest.php index 99bd83e..163ab67 100644 --- a/tests/Pecee/SimpleRouter/InputHandlerTest.php +++ b/tests/Pecee/SimpleRouter/InputHandlerTest.php @@ -114,12 +114,13 @@ class InputHandlerTest extends \PHPUnit\Framework\TestCase public function testFile() { global $_FILES; + $temp_dir = sys_get_temp_dir(); $_FILES = array( 'test' => array( 'name' => 'test.txt', 'type' => 'text/plain', - 'tmp_name' => '/tmp/phpYfWUiw', + 'tmp_name' => $temp_dir . '/phpYfWUiw', 'error' => 0, 'size' => 4 ) @@ -134,19 +135,16 @@ class InputHandlerTest extends \PHPUnit\Framework\TestCase $this->assertInstanceOf(\Pecee\Http\Input\InputFile::class, $file); $this->assertEquals('test.txt', $file->getFilename()); $this->assertEquals('text/plain', $file->getType()); - $this->assertEquals('/tmp/phpYfWUiw', $file->getTmpName()); + $this->assertEquals($temp_dir . '/phpYfWUiw', $file->getTmpName()); $this->assertEquals(0, $file->getError()); $this->assertEquals(4, $file->getSize()); $this->assertEquals('txt', $file->getExtension()); + file_put_contents($temp_dir . '/phpYfWUiw', 'test'); + $this->assertEquals('test', $file->getContents()); - if(file_exists('/tmp')){ - file_put_contents('/tmp/phpYfWUiw', 'test'); - $this->assertEquals('test', $file->getContents()); - } - - // TODO: implement test-file - $this->assertEquals(true, true); + //cleanup + unlink($temp_dir . '/phpYfWUiw'); } public function testFiles() From 3e1333ccd4447fab1df81c813b0e55ec8c0a85c8 Mon Sep 17 00:00:00 2001 From: DeveloperMarius Date: Wed, 24 Mar 2021 13:32:15 +0100 Subject: [PATCH 104/117] Defined variables for the file data --- tests/Pecee/SimpleRouter/InputHandlerTest.php | 42 +++++++++++-------- 1 file changed, 24 insertions(+), 18 deletions(-) diff --git a/tests/Pecee/SimpleRouter/InputHandlerTest.php b/tests/Pecee/SimpleRouter/InputHandlerTest.php index 163ab67..fc3baf1 100644 --- a/tests/Pecee/SimpleRouter/InputHandlerTest.php +++ b/tests/Pecee/SimpleRouter/InputHandlerTest.php @@ -1,5 +1,7 @@ 'test.txt', + 'type' => 'text/plain', + 'tmp_name' => $temp_dir . '/phpYfWUiw', + 'error' => 0, + 'size' => 4 + ); + $test_file_content = 'test_content'; + $_FILES = array( - 'test' => array( - 'name' => 'test.txt', - 'type' => 'text/plain', - 'tmp_name' => $temp_dir . '/phpYfWUiw', - 'error' => 0, - 'size' => 4 - ) + $test_file_input_name => $test_file ); $router = TestRouter::router(); @@ -131,20 +137,20 @@ class InputHandlerTest extends \PHPUnit\Framework\TestCase $router->getRequest()->setMethod('post'); $handler = TestRouter::request()->getInputHandler(); - $file = $handler->file('test'); - $this->assertInstanceOf(\Pecee\Http\Input\InputFile::class, $file); - $this->assertEquals('test.txt', $file->getFilename()); - $this->assertEquals('text/plain', $file->getType()); - $this->assertEquals($temp_dir . '/phpYfWUiw', $file->getTmpName()); - $this->assertEquals(0, $file->getError()); - $this->assertEquals(4, $file->getSize()); - $this->assertEquals('txt', $file->getExtension()); + $file = $handler->file($test_file_input_name); + $this->assertInstanceOf(InputFile::class, $file); + $this->assertEquals($test_file['name'], $file->getFilename()); + $this->assertEquals($test_file['type'], $file->getType()); + $this->assertEquals($test_file['tmp_name'], $file->getTmpName()); + $this->assertEquals($test_file['error'], $file->getError()); + $this->assertEquals($test_file['size'], $file->getSize()); + $this->assertEquals(pathinfo($test_file['name'], PATHINFO_EXTENSION), $file->getExtension()); - file_put_contents($temp_dir . '/phpYfWUiw', 'test'); - $this->assertEquals('test', $file->getContents()); + file_put_contents($test_file['tmp_name'], $test_file_content); + $this->assertEquals($test_file_content, $file->getContents()); //cleanup - unlink($temp_dir . '/phpYfWUiw'); + unlink($test_file['tmp_name']); } public function testFiles() From 0ec7c0d96025ab15b8ddcc9367f5f14434a9bdfd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20Sessing=C3=B8?= Date: Wed, 24 Mar 2021 23:18:17 +0100 Subject: [PATCH 105/117] Optimisations - Added phpunit cache to .gitignore - Updated README with latest helper.php example. - Minor phpDocs changes. --- .gitignore | 3 ++- README.md | 4 +--- helpers.php | 2 +- src/Pecee/Http/Input/InputHandler.php | 2 +- 4 files changed, 5 insertions(+), 6 deletions(-) diff --git a/.gitignore b/.gitignore index 6e51a97..d85ecfa 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ composer.lock vendor/ -.idea/ \ No newline at end of file +.idea/ +.phpunit.result.cache \ No newline at end of file diff --git a/README.md b/README.md index 701c012..a0e0918 100644 --- a/README.md +++ b/README.md @@ -300,8 +300,6 @@ We recommend that you add these helper functions to your project. These will all To implement the functions below, simply copy the code to a new file and require the file before initializing the router or copy the `helpers.php` we've included in this library. ```php - Date: Thu, 25 Mar 2021 03:41:11 +0100 Subject: [PATCH 106/117] Features & bugfixes - Feature: added new getFirstHeader to Request object that will return the first header found from array list- used to simplify the code. - Feature: added new InputHandler::getValueFromArray method that loops through input-items to ensure that value is always returned. - Fixed calling getUrl with array as parameters option throws error. - Fixed `SimpleRouter::getUrl` having wrong nullable return type. --- src/Pecee/Http/Input/InputHandler.php | 31 ++++++++++++--- src/Pecee/Http/Request.php | 38 +++++++++++++------ src/Pecee/Http/Url.php | 2 +- .../SimpleRouter/ClassLoader/ClassLoader.php | 2 +- src/Pecee/SimpleRouter/Router.php | 16 ++++---- tests/Pecee/SimpleRouter/InputHandlerTest.php | 9 +++++ 6 files changed, 72 insertions(+), 26 deletions(-) diff --git a/src/Pecee/Http/Input/InputHandler.php b/src/Pecee/Http/Input/InputHandler.php index 1f2b696..a09618e 100644 --- a/src/Pecee/Http/Input/InputHandler.php +++ b/src/Pecee/Http/Input/InputHandler.php @@ -237,6 +237,22 @@ class InputHandler return $element; } + protected function getValueFromArray(array $array): array + { + $output = []; + /* @var $item InputItem */ + foreach ($array as $key => $item) { + + if ($item instanceof IInputItem) { + $item = $item->getValue(); + } + + $output[$key] = \is_array($item) ? $this->getValueFromArray($item) : $item; + } + + return $output; + } + /** * Get input element value matching index * @@ -249,18 +265,18 @@ class InputHandler { $input = $this->find($index, ...$methods); + if ($input instanceof IInputItem) { + $input = $input->getValue(); + } + /* Handle collection */ if (\is_array($input) === true) { - $output = []; - /* @var $item InputItem */ - foreach ($input as $item) { - $output[] = \is_array($item) ? $item : $item->getValue(); - } + $output = $this->getValueFromArray($input); return (\count($output) === 0) ? $defaultValue : $output; } - return ($input === null || (\is_string($input->getValue()) && trim($input->getValue()) === '')) ? $defaultValue : $input->getValue(); + return ($input === null || (\is_string($input) && trim($input) === '')) ? $defaultValue : $input; } /** @@ -380,6 +396,7 @@ class InputHandler public function setOriginalPost(array $post): self { $this->originalPost = $post; + return $this; } @@ -400,6 +417,7 @@ class InputHandler public function setOriginalParams(array $params): self { $this->originalParams = $params; + return $this; } @@ -420,6 +438,7 @@ class InputHandler public function setOriginalFile(array $file): self { $this->originalFile = $file; + return $this; } diff --git a/src/Pecee/Http/Request.php b/src/Pecee/Http/Request.php index 8d6dab9..15f9cb4 100644 --- a/src/Pecee/Http/Request.php +++ b/src/Pecee/Http/Request.php @@ -117,7 +117,9 @@ class Request $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->setUrl(new Url($this->getFirstHeader(['unencoded-url', 'request-uri',]))); $this->method = strtolower($this->getHeader('request-method')); $this->inputHandler = new InputHandler($this); @@ -205,13 +207,11 @@ class Request */ public function getIp(): ?string { - return $this->getHeader( + return $this->getFirstHeader([ 'http-cf-connecting-ip', - $this->getHeader( - 'http-x-forwarded-for', - $this->getHeader('remote-addr') - ) - ); + 'http-x-forwarded-for', + 'remote-addr', + ]); } /** @@ -270,6 +270,25 @@ class Request return $header ?? $defaultValue; } + /** + * Will try to find first header from list of headers. + * + * @param array $headers + * @param null $defaultValue + * @return mixed|null + */ + public function getFirstHeader(array $headers, $defaultValue = null) + { + foreach($headers as $header) { + $header = $this->getHeader($header); + if($header !== null) { + return $header; + } + } + + return $defaultValue; + } + /** * Get input class * @return InputHandler @@ -286,7 +305,7 @@ class Request * * @return bool */ - public function isFormatAccepted($format): bool + public function isFormatAccepted(string $format): bool { return ($this->getHeader('http-accept') !== null && stripos($this->getHeader('http-accept'), $format) !== false); } @@ -426,7 +445,6 @@ class Request public function setLoadedRoutes(array $routes): self { $this->loadedRoutes = $routes; - return $this; } @@ -439,7 +457,6 @@ class Request public function addLoadedRoute(ILoadableRoute $route): self { $this->loadedRoutes[] = $route; - return $this; } @@ -462,7 +479,6 @@ class Request public function setHasPendingRewrite(bool $boolean): self { $this->hasPendingRewrite = $boolean; - return $this; } diff --git a/src/Pecee/Http/Url.php b/src/Pecee/Http/Url.php index 161dc37..256e4a5 100644 --- a/src/Pecee/Http/Url.php +++ b/src/Pecee/Http/Url.php @@ -371,7 +371,7 @@ class Url implements \JsonSerializable */ public function getParam(string $name, ?string $defaultValue = null): ?string { - return isset($this->getParams()[$name]) ?? $defaultValue; + return (isset($this->getParams()[$name]) === true) ? $this->getParams()[$name] : $defaultValue; } /** diff --git a/src/Pecee/SimpleRouter/ClassLoader/ClassLoader.php b/src/Pecee/SimpleRouter/ClassLoader/ClassLoader.php index f1e5729..b6359cf 100644 --- a/src/Pecee/SimpleRouter/ClassLoader/ClassLoader.php +++ b/src/Pecee/SimpleRouter/ClassLoader/ClassLoader.php @@ -11,7 +11,7 @@ class ClassLoader implements IClassLoader * * @param string $class * @return object - * @throws NotFoundHttpException + * @throws ClassNotFoundHttpException */ public function loadClass(string $class) { diff --git a/src/Pecee/SimpleRouter/Router.php b/src/Pecee/SimpleRouter/Router.php index 99ecb07..72fbc05 100644 --- a/src/Pecee/SimpleRouter/Router.php +++ b/src/Pecee/SimpleRouter/Router.php @@ -683,14 +683,16 @@ class Router ->setParams($getParams); } - /* We try to find a match on the given name */ - $route = $this->findRoute($name); + if($name !== null) { + /* We try to find a match on the given name */ + $route = $this->findRoute($name); - if ($route !== null) { - return $this->request - ->getUrlCopy() - ->setPath($route->findUrl($route->getMethod(), $parameters, $name)) - ->setParams($getParams); + if ($route !== null) { + return $this->request + ->getUrlCopy() + ->setPath($route->findUrl($route->getMethod(), $parameters, $name)) + ->setParams($getParams); + } } /* Using @ is most definitely a controller@method or alias@method */ diff --git a/tests/Pecee/SimpleRouter/InputHandlerTest.php b/tests/Pecee/SimpleRouter/InputHandlerTest.php index 7fcb87b..0657a73 100644 --- a/tests/Pecee/SimpleRouter/InputHandlerTest.php +++ b/tests/Pecee/SimpleRouter/InputHandlerTest.php @@ -20,6 +20,13 @@ class InputHandlerTest extends \PHPUnit\Framework\TestCase 'Canon', ]; + protected $sodas = [ + 0 => 'Pepsi', + 1 => 'Coca Cola', + 2 => 'Harboe', + 3 => 'Mountain Dew', + ]; + protected $day = 'monday'; public function testPost() @@ -29,6 +36,7 @@ class InputHandlerTest extends \PHPUnit\Framework\TestCase $_POST = [ 'names' => $this->names, 'day' => $this->day, + 'sodas' => $this->sodas, ]; $router = TestRouter::router(); @@ -51,6 +59,7 @@ class InputHandlerTest extends \PHPUnit\Framework\TestCase $this->assertNull($handler->find('non-existing')); $this->assertNull($handler->value('names', null, 'get')); $this->assertNull($handler->find('names', 'get')); + $this->assertEquals($this->sodas, $handler->value('sodas')); $objects = $handler->find('names'); From 86bb88a41fff148eb0f53aec1d83908a9618efe2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20Sessing=C3=B8?= Date: Thu, 25 Mar 2021 05:58:49 +0100 Subject: [PATCH 107/117] [FEATURE] Added better support for nested file/arrays in InputHandler. - Added unit tests for file arrays - Removed legacy .yml configs --- .codeclimate.yml | 22 ---- .scrutinizer.yml | 13 --- .travis.yml | 25 ---- src/Pecee/Http/Input/InputHandler.php | 15 ++- tests/Pecee/SimpleRouter/InputHandlerTest.php | 109 +++++++++++++----- 5 files changed, 92 insertions(+), 92 deletions(-) delete mode 100644 .codeclimate.yml delete mode 100644 .scrutinizer.yml delete mode 100644 .travis.yml diff --git a/.codeclimate.yml b/.codeclimate.yml deleted file mode 100644 index 467daf9..0000000 --- a/.codeclimate.yml +++ /dev/null @@ -1,22 +0,0 @@ -engines: - phpmd: - enabled: true - checks: - Design/TooManyPublicMethods: - enabled: true - Naming/ShortVariable: - enabled: true - CleanCode/StaticAccess: - enabled: true - Controversial/CamelCaseMethodName: - enabled: true - fixme: - enabled: true - duplication: - enabled: true - config: - languages: - - php: -ratings: - paths: - - src/** diff --git a/.scrutinizer.yml b/.scrutinizer.yml deleted file mode 100644 index 0608e7a..0000000 --- a/.scrutinizer.yml +++ /dev/null @@ -1,13 +0,0 @@ -build: - tests: - override: - - - command: './vendor/bin/phpunit --coverage-clover=coverage.clover' - coverage: - file: 'coverage.clover' - format: 'clover' -checks: - php: - code_rating: true - duplication: true - diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index a3d4148..0000000 --- a/.travis.yml +++ /dev/null @@ -1,25 +0,0 @@ -language: php - -php: - - 7.4.2 - -before_script: - - mkdir -p _clover - - ls -al - -script: - - ./vendor/phpunit/phpunit/phpunit --configuration ./phpunit.xml ./tests - -install: - # Install composer packages - - travis_retry composer install --no-interaction --no-suggest - # Install coveralls.phar - - wget -c -nc --retry-connrefused --tries=0 https://github.com/php-coveralls/php-coveralls/releases/download/v2.0.0/php-coveralls.phar -O coveralls.phar - - chmod +x coveralls.phar - - php coveralls.phar --version - -after_success: - # Submit coverage report to Coveralls servers, see .coveralls.yml - - travis_retry php coveralls.phar -v - # Submit coverage report to codecov.io - - bash <(curl -s https://codecov.io/bash) \ No newline at end of file diff --git a/src/Pecee/Http/Input/InputHandler.php b/src/Pecee/Http/Input/InputHandler.php index a09618e..2eefba3 100644 --- a/src/Pecee/Http/Input/InputHandler.php +++ b/src/Pecee/Http/Input/InputHandler.php @@ -92,22 +92,29 @@ class InputHandler /* Parse get requests */ if (\count($_FILES) !== 0) { $this->originalFile = $_FILES; - $this->file = $this->parseFiles(); + $this->file = $this->parseFiles($this->originalFile); } } /** * @return array */ - public function parseFiles(): array + public function parseFiles(array $files, $parentKey = null): array { $list = []; - foreach ($_FILES as $key => $value) { + foreach ($files as $key => $value) { + + // Parse multi dept file array + if(isset($value['name']) === false && \is_array($value) === true) { + $list[$key] = $this->parseFiles($value, $key); + continue; + } // Handle array input if (\is_array($value['name']) === false) { - $values['index'] = $key; + $values['index'] = $parentKey ?? $key; + try { $list[$key] = InputFile::createFromArray($values + $value); } catch (InvalidArgumentException $e) { diff --git a/tests/Pecee/SimpleRouter/InputHandlerTest.php b/tests/Pecee/SimpleRouter/InputHandlerTest.php index 49cb62e..11dcf28 100644 --- a/tests/Pecee/SimpleRouter/InputHandlerTest.php +++ b/tests/Pecee/SimpleRouter/InputHandlerTest.php @@ -122,50 +122,87 @@ class InputHandlerTest extends \PHPUnit\Framework\TestCase $_GET = []; } + + public function testFile() { global $_FILES; - $temp_dir = sys_get_temp_dir(); - $test_file_input_name = 'test_input'; - $test_file = array( - 'name' => 'test.txt', - 'type' => 'text/plain', - 'tmp_name' => $temp_dir . '/phpYfWUiw', - 'error' => 0, - 'size' => 4 - ); - $test_file_content = 'test_content'; + $testFile = $this->generateFile(); - $_FILES = array( - $test_file_input_name => $test_file - ); + $_FILES = [ + 'test_input' => $testFile, + ]; $router = TestRouter::router(); $router->reset(); $router->getRequest()->setMethod('post'); + $inputHandler = TestRouter::request()->getInputHandler(); + + $testFileContent = md5(uniqid('test', false)); + + $file = $inputHandler->file('test_input'); - $handler = TestRouter::request()->getInputHandler(); - $file = $handler->file($test_file_input_name); $this->assertInstanceOf(InputFile::class, $file); - $this->assertEquals($test_file['name'], $file->getFilename()); - $this->assertEquals($test_file['type'], $file->getType()); - $this->assertEquals($test_file['tmp_name'], $file->getTmpName()); - $this->assertEquals($test_file['error'], $file->getError()); - $this->assertEquals($test_file['size'], $file->getSize()); - $this->assertEquals(pathinfo($test_file['name'], PATHINFO_EXTENSION), $file->getExtension()); + $this->assertEquals($testFile['name'], $file->getFilename()); + $this->assertEquals($testFile['type'], $file->getType()); + $this->assertEquals($testFile['tmp_name'], $file->getTmpName()); + $this->assertEquals($testFile['error'], $file->getError()); + $this->assertEquals($testFile['size'], $file->getSize()); + $this->assertEquals(pathinfo($testFile['name'], PATHINFO_EXTENSION), $file->getExtension()); - file_put_contents($test_file['tmp_name'], $test_file_content); - $this->assertEquals($test_file_content, $file->getContents()); + file_put_contents($testFile['tmp_name'], $testFileContent); + $this->assertEquals($testFileContent, $file->getContents()); - //cleanup - unlink($test_file['tmp_name']); + // Cleanup + unlink($testFile['tmp_name']); } - public function testFiles() + public function testFilesArray() { - // TODO: implement test-files - $this->assertEquals(true, true); + global $_FILES; + + $testFiles = [ + $file = $this->generateFile(), + $file = $this->generateFile(), + $file = $this->generateFile(), + $file = $this->generateFile(), + $file = $this->generateFile(), + ]; + + $_FILES = [ + 'my_files' => $testFiles, + ]; + + $router = TestRouter::router(); + $router->reset(); + $router->getRequest()->setMethod('post'); + $inputHandler = TestRouter::request()->getInputHandler(); + + $files = $inputHandler->file('my_files'); + $this->assertCount(5, $files); + + /* @var $file InputFile */ + foreach ($files as $key => $file) { + + $testFileContent = md5(uniqid('test', false)); + + $this->assertInstanceOf(InputFile::class, $file); + $this->assertEquals($testFiles[$key]['name'], $file->getFilename()); + $this->assertEquals($testFiles[$key]['type'], $file->getType()); + $this->assertEquals($testFiles[$key]['tmp_name'], $file->getTmpName()); + $this->assertEquals($testFiles[$key]['error'], $file->getError()); + $this->assertEquals($testFiles[$key]['size'], $file->getSize()); + $this->assertEquals(pathinfo($testFiles[$key]['name'], PATHINFO_EXTENSION), $file->getExtension()); + + file_put_contents($testFiles[$key]['tmp_name'], $testFileContent); + + $this->assertEquals($testFileContent, $file->getContents()); + + // Cleanup + unlink($testFiles[$key]['tmp_name']); + } + } public function testAll() @@ -218,4 +255,20 @@ class InputHandlerTest extends \PHPUnit\Framework\TestCase $_POST = []; } + protected function generateFile() + { + return [ + 'name' => uniqid('', false) . '.txt', + 'type' => 'text/plain', + 'tmp_name' => sys_get_temp_dir() . '/phpYfWUiw', + 'error' => 0, + 'size' => rand(3, 40), + ]; + } + + protected function generateFileContent() + { + return md5(uniqid('', false)); + } + } \ No newline at end of file From 8835aca02e02f2b626e7838b83f08d271322e4a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20Sessing=C3=B8?= Date: Thu, 25 Mar 2021 13:09:23 +0100 Subject: [PATCH 108/117] [FEATURE] Added Request::getContentType for content-type header-parsing - Added unit-tests for Request::getContentType parsing. --- src/Pecee/Http/Request.php | 41 ++++++++++++++++++++++-- tests/Pecee/SimpleRouter/RequestTest.php | 38 ++++++++++++++++++++++ 2 files changed, 76 insertions(+), 3 deletions(-) create mode 100644 tests/Pecee/SimpleRouter/RequestTest.php diff --git a/src/Pecee/Http/Request.php b/src/Pecee/Http/Request.php index 15f9cb4..f645189 100644 --- a/src/Pecee/Http/Request.php +++ b/src/Pecee/Http/Request.php @@ -19,6 +19,10 @@ class Request public const REQUEST_TYPE_DELETE = 'delete'; public const REQUEST_TYPE_HEAD = 'head'; + public const CONTENT_TYPE_JSON = 'application/json'; + public const CONTENT_TYPE_FORM_DATA = 'multipart/form-data'; + public const CONTENT_TYPE_X_FORM_ENCODED = 'application/x-www-form-urlencoded'; + /** * All request-types * @var string[] @@ -57,6 +61,12 @@ class Request */ protected $headers = []; + /** + * Request ContentType + * @var string + */ + protected $contentType; + /** * Request host * @var string @@ -117,10 +127,10 @@ class Request $this->setHost($this->getHeader('http-host')); // Check if special IIS header exist, otherwise use default. - - $this->setUrl(new Url($this->getFirstHeader(['unencoded-url', 'request-uri',]))); + $this->setContentType(strtolower($this->getHeader('content-type'))); + $this->method = strtolower($this->getHeader('request-method')); $this->inputHandler = new InputHandler($this); $this->method = strtolower($this->inputHandler->value('_method', $this->getHeader('request-method'))); @@ -289,6 +299,31 @@ class Request return $defaultValue; } + /** + * Get request content-type + * @return string|null + */ + public function getContentType(): ?string + { + return $this->contentType; + } + + /** + * Set request content-type + * @param string $contentType + * @return $this + */ + protected function setContentType(string $contentType): self + { + if(strpos($contentType, ';') > 0) { + $this->contentType = substr($contentType, 0, strpos($contentType, ';')); + } else { + $this->contentType = $contentType; + } + + return $this; + } + /** * Get input class * @return InputHandler @@ -497,4 +532,4 @@ class Request return $this->data[$name] ?? null; } -} +} \ No newline at end of file diff --git a/tests/Pecee/SimpleRouter/RequestTest.php b/tests/Pecee/SimpleRouter/RequestTest.php new file mode 100644 index 0000000..736164a --- /dev/null +++ b/tests/Pecee/SimpleRouter/RequestTest.php @@ -0,0 +1,38 @@ +reset(); + + $request = $router->getRequest(); + + $this->assertEquals($contentType, $request->getContentType()); + + // Test special content-types + $router->reset(); + + $_SERVER['content_type'] = 'application/x-www-form-urlencoded; charset=UTF-8'; + + $this->assertEquals($contentType, $request->getContentType()); + + $router->reset(); + } + + // TODO: implement more test-cases + +} \ No newline at end of file From cf6750aaf31e07956af140c263e240a30b43191f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20Sessing=C3=B8?= Date: Thu, 25 Mar 2021 14:18:56 +0100 Subject: [PATCH 109/117] [FEATURE] Optimised Request::getIp method - Added unit-tests for Request::getIp - Optimised existing RequestTest unit-tests. --- src/Pecee/Http/Request.php | 22 +++------ tests/Pecee/SimpleRouter/RequestTest.php | 62 +++++++++++++++++++++--- 2 files changed, 62 insertions(+), 22 deletions(-) diff --git a/src/Pecee/Http/Request.php b/src/Pecee/Http/Request.php index 08b922d..bb3f8d6 100644 --- a/src/Pecee/Http/Request.php +++ b/src/Pecee/Http/Request.php @@ -220,22 +220,16 @@ class Request */ public function getIp(bool $safe = false): ?string { - $client_header = null; - if(!$safe){ - $client_header = $this->getHeader( + $headers = ['remote-addr']; + if($safe === false) { + $headers = array_merge($headers, [ 'http-cf-connecting-ip', - $this->getHeader( - 'http-client-ip', - $this->getHeader( - 'http-x-forwarded-for', - $this->getHeader('remote-addr') - ) - ) - ); + 'http-client-ip', + 'http-x-forwarded-for', + ]); } - if($client_header === null) - $client_header = $this->getHeader('remote-addr'); - return filter_var($client_header, FILTER_VALIDATE_IP) ? $client_header : null; + + return $this->getFirstHeader($headers); } /** diff --git a/tests/Pecee/SimpleRouter/RequestTest.php b/tests/Pecee/SimpleRouter/RequestTest.php index 736164a..9f9469f 100644 --- a/tests/Pecee/SimpleRouter/RequestTest.php +++ b/tests/Pecee/SimpleRouter/RequestTest.php @@ -9,28 +9,74 @@ require_once 'Dummy/Handler/ExceptionHandler.php'; class RequestTest extends \PHPUnit\Framework\TestCase { - public function testContentTypeParse() + protected function testHeader($name, $value, callable $callback) { global $_SERVER; - $contentType = 'application/x-www-form-urlencoded'; - $_SERVER['content_type'] = $contentType; + $_SERVER[$name] = $value; $router = TestRouter::router(); $router->reset(); $request = $router->getRequest(); - $this->assertEquals($contentType, $request->getContentType()); + $callback($request); - // Test special content-types + // Reset everything + $_SERVER[$name] = null; $router->reset(); + } - $_SERVER['content_type'] = 'application/x-www-form-urlencoded; charset=UTF-8'; + public function testContentTypeParse() + { + global $_SERVER; - $this->assertEquals($contentType, $request->getContentType()); + // Test normal content-type + + $contentType = 'application/x-www-form-urlencoded'; + + $this->testHeader('content_type', $contentType, function(\Pecee\Http\Request $request) use($contentType) { + $this->assertEquals($contentType, $request->getContentType()); + }); + + // Test special content-type with encoding + + $contentTypeWithEncoding = 'application/x-www-form-urlencoded; charset=UTF-8'; + + $this->testHeader('content_type', $contentTypeWithEncoding, function(\Pecee\Http\Request $request) use($contentType) { + $this->assertEquals($contentType, $request->getContentType()); + }); + } + + public function testGetIp() + { + $ip = '1.1.1.1'; + $this->testHeader('remote_addr', $ip, function(\Pecee\Http\Request $request) use($ip) { + $this->assertEquals($ip, $request->getIp()); + }); + + $ip = '2.2.2.2'; + $this->testHeader('http-cf-connecting-ip', $ip, function(\Pecee\Http\Request $request) use($ip) { + $this->assertEquals($ip, $request->getIp()); + }); + + $ip = '3.3.3.3'; + $this->testHeader('http-client-ip', $ip, function(\Pecee\Http\Request $request) use($ip) { + $this->assertEquals($ip, $request->getIp()); + }); + + $ip = '4.4.4.4'; + $this->testHeader('http-x-forwarded-for', $ip, function(\Pecee\Http\Request $request) use($ip) { + $this->assertEquals($ip, $request->getIp()); + }); + + // Test safe + + $ip = '5.5.5.5'; + $this->testHeader('http-x-forwarded-for', $ip, function(\Pecee\Http\Request $request) { + $this->assertEquals(null, $request->getIp(true)); + }); - $router->reset(); } // TODO: implement more test-cases From d9cfa715342249138387740bc6662384a818dac6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20Sessing=C3=B8?= Date: Thu, 25 Mar 2021 14:21:30 +0100 Subject: [PATCH 110/117] Fixed naming in unit-tests. --- tests/Pecee/SimpleRouter/RequestTest.php | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/tests/Pecee/SimpleRouter/RequestTest.php b/tests/Pecee/SimpleRouter/RequestTest.php index 9f9469f..b17256a 100644 --- a/tests/Pecee/SimpleRouter/RequestTest.php +++ b/tests/Pecee/SimpleRouter/RequestTest.php @@ -9,7 +9,7 @@ require_once 'Dummy/Handler/ExceptionHandler.php'; class RequestTest extends \PHPUnit\Framework\TestCase { - protected function testHeader($name, $value, callable $callback) + protected function processHeader($name, $value, callable $callback) { global $_SERVER; @@ -35,7 +35,7 @@ class RequestTest extends \PHPUnit\Framework\TestCase $contentType = 'application/x-www-form-urlencoded'; - $this->testHeader('content_type', $contentType, function(\Pecee\Http\Request $request) use($contentType) { + $this->processHeader('content_type', $contentType, function(\Pecee\Http\Request $request) use($contentType) { $this->assertEquals($contentType, $request->getContentType()); }); @@ -43,7 +43,7 @@ class RequestTest extends \PHPUnit\Framework\TestCase $contentTypeWithEncoding = 'application/x-www-form-urlencoded; charset=UTF-8'; - $this->testHeader('content_type', $contentTypeWithEncoding, function(\Pecee\Http\Request $request) use($contentType) { + $this->processHeader('content_type', $contentTypeWithEncoding, function(\Pecee\Http\Request $request) use($contentType) { $this->assertEquals($contentType, $request->getContentType()); }); } @@ -51,29 +51,29 @@ class RequestTest extends \PHPUnit\Framework\TestCase public function testGetIp() { $ip = '1.1.1.1'; - $this->testHeader('remote_addr', $ip, function(\Pecee\Http\Request $request) use($ip) { + $this->processHeader('remote_addr', $ip, function(\Pecee\Http\Request $request) use($ip) { $this->assertEquals($ip, $request->getIp()); }); $ip = '2.2.2.2'; - $this->testHeader('http-cf-connecting-ip', $ip, function(\Pecee\Http\Request $request) use($ip) { + $this->processHeader('http-cf-connecting-ip', $ip, function(\Pecee\Http\Request $request) use($ip) { $this->assertEquals($ip, $request->getIp()); }); $ip = '3.3.3.3'; - $this->testHeader('http-client-ip', $ip, function(\Pecee\Http\Request $request) use($ip) { + $this->processHeader('http-client-ip', $ip, function(\Pecee\Http\Request $request) use($ip) { $this->assertEquals($ip, $request->getIp()); }); $ip = '4.4.4.4'; - $this->testHeader('http-x-forwarded-for', $ip, function(\Pecee\Http\Request $request) use($ip) { + $this->processHeader('http-x-forwarded-for', $ip, function(\Pecee\Http\Request $request) use($ip) { $this->assertEquals($ip, $request->getIp()); }); // Test safe $ip = '5.5.5.5'; - $this->testHeader('http-x-forwarded-for', $ip, function(\Pecee\Http\Request $request) { + $this->processHeader('http-x-forwarded-for', $ip, function(\Pecee\Http\Request $request) { $this->assertEquals(null, $request->getIp(true)); }); From cf1c59aee0098406709ebe369ae8905a809bec99 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20Sessing=C3=B8?= Date: Thu, 25 Mar 2021 14:24:50 +0100 Subject: [PATCH 111/117] Changed parameter name and added parameter phpDocs description. --- src/Pecee/Http/Request.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Pecee/Http/Request.php b/src/Pecee/Http/Request.php index bb3f8d6..e1d363a 100644 --- a/src/Pecee/Http/Request.php +++ b/src/Pecee/Http/Request.php @@ -215,13 +215,13 @@ class Request * Get id address * If $safe is false, this function will detect Proxys. But the user can edit this header to whatever he wants! * https://stackoverflow.com/questions/3003145/how-to-get-the-client-ip-address-in-php#comment-25086804 - * @param bool $safe + * @param bool $safeMode When enabled, only safe non-spoofable headers will be returned. Note this can cause issues when using proxy. * @return string|null */ - public function getIp(bool $safe = false): ?string + public function getIp(bool $safeMode = false): ?string { $headers = ['remote-addr']; - if($safe === false) { + if($safeMode === false) { $headers = array_merge($headers, [ 'http-cf-connecting-ip', 'http-client-ip', From 39ee1bb7cd822933d9223b4d2925c00ef3a9927f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20Sessing=C3=B8?= Date: Thu, 25 Mar 2021 14:31:04 +0100 Subject: [PATCH 112/117] Added missing phpDocs for parameters. --- src/Pecee/Http/Input/InputHandler.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/Pecee/Http/Input/InputHandler.php b/src/Pecee/Http/Input/InputHandler.php index 2eefba3..bf99881 100644 --- a/src/Pecee/Http/Input/InputHandler.php +++ b/src/Pecee/Http/Input/InputHandler.php @@ -97,9 +97,11 @@ class InputHandler } /** + * @param array $files Array with files to parse + * @param string|null $parentKey Key from parent (used when parsing nested array). * @return array */ - public function parseFiles(array $files, $parentKey = null): array + public function parseFiles(array $files, ?string $parentKey = null): array { $list = []; From 073479f9ddc5f8becaf105cd91db5816b6a54249 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20Sessing=C3=B8?= Date: Fri, 26 Mar 2021 01:32:01 +0100 Subject: [PATCH 113/117] [BUGFIX] Fixed group not matching domain with no parameters (issue: #468). - Added unit-tests --- src/Pecee/SimpleRouter/Route/RouteGroup.php | 9 +++-- tests/Pecee/SimpleRouter/RouterRouteTest.php | 36 ++++++++++++++++++++ 2 files changed, 42 insertions(+), 3 deletions(-) diff --git a/src/Pecee/SimpleRouter/Route/RouteGroup.php b/src/Pecee/SimpleRouter/Route/RouteGroup.php index e3fc8ac..8e724ee 100644 --- a/src/Pecee/SimpleRouter/Route/RouteGroup.php +++ b/src/Pecee/SimpleRouter/Route/RouteGroup.php @@ -26,12 +26,15 @@ class RouteGroup extends Route implements IGroupRoute foreach ($this->domains as $domain) { + // If domain has no parameters but matches + if ($domain === $request->getHost()) { + return true; + } + $parameters = $this->parseParameters($domain, $request->getHost(), '.*'); if ($parameters !== null && \count($parameters) !== 0) { - $this->parameters = $parameters; - return true; } } @@ -56,7 +59,7 @@ class RouteGroup extends Route implements IGroupRoute $prefix = $this->prefix; - foreach($this->getParameters() as $parameter => $value) { + foreach ($this->getParameters() as $parameter => $value) { $prefix = str_ireplace('{' . $parameter . '}', $value, $prefix); } diff --git a/tests/Pecee/SimpleRouter/RouterRouteTest.php b/tests/Pecee/SimpleRouter/RouterRouteTest.php index 28a7b4e..3a3d2c1 100644 --- a/tests/Pecee/SimpleRouter/RouterRouteTest.php +++ b/tests/Pecee/SimpleRouter/RouterRouteTest.php @@ -107,6 +107,42 @@ class RouterRouteTest extends \PHPUnit\Framework\TestCase $this->assertEquals('it, system', $response); } + public function testFixedDomain() + { + $result = false; + TestRouter::request()->setHost('admin.world.com'); + + TestRouter::group(['domain' => 'admin.world.com'], function () use (&$result) { + TestRouter::get('/test', function ($subdomain = null) use (&$result) { + $result = true; + }); + }); + + TestRouter::debug('/test', 'get'); + + $this->assertTrue($result); + } + + public function testFixedNotAllowedDomain() + { + $result = false; + TestRouter::request()->setHost('other.world.com'); + + TestRouter::group(['domain' => 'admin.world.com'], function () use (&$result) { + TestRouter::get('/', function ($subdomain = null) use (&$result) { + $result = true; + }); + }); + + try { + TestRouter::debug('/', 'get'); + } catch(\Exception $e) { + + } + + $this->assertFalse($result); + } + public function testDomainAllowedRoute() { $result = false; From e5eb9667800729bcfadf86cef47cff398e8e9899 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20Sessing=C3=B8?= Date: Sun, 28 Mar 2021 04:05:09 +0200 Subject: [PATCH 114/117] Added Request::isPostBack helper method --- README.md | 9 +++++---- src/Pecee/Http/Request.php | 10 ++++++++++ 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index a0e0918..5e2e293 100644 --- a/README.md +++ b/README.md @@ -658,6 +658,7 @@ SimpleRouter::group(['prefix' => '/admin'], function () { ## Partial groups Partial router groups has the same benefits as a normal group, but supports parameters and are only rendered once the url has matched. +Partial groups will render once a part of the url has matched. This can be extremely useful in situations, where you only want special routes to be added, when a certain criteria or logic has been met. @@ -666,11 +667,11 @@ This can be extremely useful in situations, where you only want special routes t **Example:** ```php -SimpleRouter::partialGroup('/admin/{applicationId}', function ($applicationId) { +SimpleRouter::partialGroup('/lang/{language}', function ($language) { - SimpleRouter::get('/', function($applicationId) { + SimpleRouter::get('/', function($language) { - // Matches The "/admin/applicationId" URL + // Matches The "/lang/da" URL }); @@ -1905,4 +1906,4 @@ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. +SOFTWARE. \ No newline at end of file diff --git a/src/Pecee/Http/Request.php b/src/Pecee/Http/Request.php index e1d363a..53912b0 100644 --- a/src/Pecee/Http/Request.php +++ b/src/Pecee/Http/Request.php @@ -363,6 +363,16 @@ class Request return (strtolower($this->getHeader('http-x-requested-with')) === 'xmlhttprequest'); } + /** + * Returns true when request-type is post. + * + * @return bool + */ + public function isPostBack(): bool + { + return ($this->getMethod() === static::REQUEST_TYPE_POST); + } + /** * Get accept formats * @return array From 6ccd06911e81499a014b643ab7fad62d76c1d4f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20Sessing=C3=B8?= Date: Sun, 28 Mar 2021 04:24:33 +0200 Subject: [PATCH 115/117] Fixed possible bug causing InputHandler not to get the correct request-method + simplified Request class. --- src/Pecee/Http/Request.php | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/src/Pecee/Http/Request.php b/src/Pecee/Http/Request.php index e1d363a..1937b4e 100644 --- a/src/Pecee/Http/Request.php +++ b/src/Pecee/Http/Request.php @@ -23,6 +23,8 @@ class Request public const CONTENT_TYPE_FORM_DATA = 'multipart/form-data'; public const CONTENT_TYPE_X_FORM_ENCODED = 'application/x-www-form-urlencoded'; + public const FORCE_METHOD_KEY = '_method'; + /** * All request-types * @var string[] @@ -127,13 +129,10 @@ class Request $this->setHost($this->getHeader('http-host')); // Check if special IIS header exist, otherwise use default. - $this->setUrl(new Url($this->getFirstHeader(['unencoded-url', 'request-uri',]))); - - $this->setContentType(strtolower($this->getHeader('content-type'))); - - $this->method = strtolower($this->getHeader('request-method')); + $this->setUrl(new Url($this->getFirstHeader(['unencoded-url', 'request-uri']))); + $this->setContentType((string)$this->getHeader('content-type')); + $this->setMethod((string)($_POST[static::FORCE_METHOD_KEY] ?? $this->getHeader('request-method'))); $this->inputHandler = new InputHandler($this); - $this->method = strtolower($this->inputHandler->value('_method', $this->getHeader('request-method'))); } public function isSecure(): bool @@ -324,9 +323,9 @@ class Request protected function setContentType(string $contentType): self { if(strpos($contentType, ';') > 0) { - $this->contentType = substr($contentType, 0, strpos($contentType, ';')); + $this->contentType = strtolower(substr($contentType, 0, strpos($contentType, ';'))); } else { - $this->contentType = $contentType; + $this->contentType = strtolower($contentType); } return $this; From 9ed2d2b8d1a56842fed4f2207927096b23cc88aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20Sessing=C3=B8?= Date: Sun, 28 Mar 2021 23:32:33 +0200 Subject: [PATCH 116/117] Updated Request::isPostBack to return true if request-method could contain data in body. --- src/Pecee/Http/Input/InputHandler.php | 2 +- src/Pecee/Http/Middleware/BaseCsrfVerifier.php | 2 +- src/Pecee/Http/Request.php | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Pecee/Http/Input/InputHandler.php b/src/Pecee/Http/Input/InputHandler.php index bf99881..13bfe5c 100644 --- a/src/Pecee/Http/Input/InputHandler.php +++ b/src/Pecee/Http/Input/InputHandler.php @@ -71,7 +71,7 @@ class InputHandler /* Parse post requests */ $this->originalPost = $_POST; - if (\in_array($this->request->getMethod(), Request::$requestTypesPost, false) === true) { + if ($this->request->isPostBack() === true) { $contents = file_get_contents('php://input'); diff --git a/src/Pecee/Http/Middleware/BaseCsrfVerifier.php b/src/Pecee/Http/Middleware/BaseCsrfVerifier.php index f137504..392bcf9 100644 --- a/src/Pecee/Http/Middleware/BaseCsrfVerifier.php +++ b/src/Pecee/Http/Middleware/BaseCsrfVerifier.php @@ -63,7 +63,7 @@ class BaseCsrfVerifier implements IMiddleware */ public function handle(Request $request): void { - if ($this->skip($request) === false && \in_array($request->getMethod(), Request::$requestTypesPost, true) === true) { + if ($this->skip($request) === false && $request->isPostBack() === true) { $token = $request->getInputHandler()->value( static::POST_KEY, diff --git a/src/Pecee/Http/Request.php b/src/Pecee/Http/Request.php index 04e69b5..aab2ddb 100644 --- a/src/Pecee/Http/Request.php +++ b/src/Pecee/Http/Request.php @@ -363,13 +363,13 @@ class Request } /** - * Returns true when request-type is post. + * Returns true when request-method is type that could contain data in the page body. * * @return bool */ public function isPostBack(): bool { - return ($this->getMethod() === static::REQUEST_TYPE_POST); + return \in_array($this->getMethod(), static::$requestTypesPost, true); } /** From c916a1dd2e38797bf0aeeeafe3d005b0c411c5e7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20Sessing=C3=B8?= Date: Mon, 29 Mar 2021 00:00:01 +0200 Subject: [PATCH 117/117] [CLEANUP] Cleaned up code - Change variable $values to $settings in Route::setSettings method. - Added return types to methods. - Added type to method variables. - Change ClassNotFoundException so required parameters are first. --- src/Pecee/Http/Request.php | 4 +- .../SimpleRouter/ClassLoader/ClassLoader.php | 4 +- .../SimpleRouter/Event/EventArgument.php | 2 +- .../Exceptions/ClassNotFoundHttpException.php | 2 +- src/Pecee/SimpleRouter/Route/IGroupRoute.php | 2 +- .../SimpleRouter/Route/ILoadableRoute.php | 2 +- src/Pecee/SimpleRouter/Route/IRoute.php | 8 ++-- .../SimpleRouter/Route/LoadableRoute.php | 16 +++---- src/Pecee/SimpleRouter/Route/Route.php | 42 +++++++++---------- .../SimpleRouter/Route/RouteController.php | 12 +++--- src/Pecee/SimpleRouter/Route/RouteGroup.php | 24 +++++------ .../SimpleRouter/Route/RoutePartialGroup.php | 2 +- .../SimpleRouter/Route/RouteResource.php | 16 +++---- src/Pecee/SimpleRouter/Route/RouteUrl.php | 2 +- src/Pecee/SimpleRouter/Router.php | 4 +- src/Pecee/SimpleRouter/SimpleRouter.php | 2 +- 16 files changed, 72 insertions(+), 72 deletions(-) diff --git a/src/Pecee/Http/Request.php b/src/Pecee/Http/Request.php index aab2ddb..fddb573 100644 --- a/src/Pecee/Http/Request.php +++ b/src/Pecee/Http/Request.php @@ -291,7 +291,7 @@ class Request * Will try to find first header from list of headers. * * @param array $headers - * @param null $defaultValue + * @param mixed|null $defaultValue * @return mixed|null */ public function getFirstHeader(array $headers, $defaultValue = null) @@ -534,7 +534,7 @@ class Request return $this; } - public function __isset($name) + public function __isset($name): bool { return array_key_exists($name, $this->data) === true; } diff --git a/src/Pecee/SimpleRouter/ClassLoader/ClassLoader.php b/src/Pecee/SimpleRouter/ClassLoader/ClassLoader.php index b6359cf..027028e 100644 --- a/src/Pecee/SimpleRouter/ClassLoader/ClassLoader.php +++ b/src/Pecee/SimpleRouter/ClassLoader/ClassLoader.php @@ -16,7 +16,7 @@ class ClassLoader implements IClassLoader public function loadClass(string $class) { if (class_exists($class) === false) { - throw new ClassNotFoundHttpException(sprintf('Class "%s" does not exist', $class), 404, null, $class); + throw new ClassNotFoundHttpException($class, null, sprintf('Class "%s" does not exist', $class), 404, null); } return new $class(); @@ -34,4 +34,4 @@ class ClassLoader implements IClassLoader return \call_user_func_array($closure, $parameters); } -} +} \ No newline at end of file diff --git a/src/Pecee/SimpleRouter/Event/EventArgument.php b/src/Pecee/SimpleRouter/Event/EventArgument.php index e1aad3e..092f9a0 100644 --- a/src/Pecee/SimpleRouter/Event/EventArgument.php +++ b/src/Pecee/SimpleRouter/Event/EventArgument.php @@ -83,7 +83,7 @@ class EventArgument implements IEventArgument * @param string $name * @return bool */ - public function __isset(string $name) + public function __isset(string $name): bool { return array_key_exists($name, $this->arguments); } diff --git a/src/Pecee/SimpleRouter/Exceptions/ClassNotFoundHttpException.php b/src/Pecee/SimpleRouter/Exceptions/ClassNotFoundHttpException.php index d283874..09fed6a 100644 --- a/src/Pecee/SimpleRouter/Exceptions/ClassNotFoundHttpException.php +++ b/src/Pecee/SimpleRouter/Exceptions/ClassNotFoundHttpException.php @@ -9,7 +9,7 @@ class ClassNotFoundHttpException extends NotFoundHttpException protected $class; protected $method; - public function __construct($message = "", $code = 0, Throwable $previous = null, string $class, ?string $method = null) + public function __construct(string $class, ?string $method = null, $message = "", $code = 0, Throwable $previous = null) { parent::__construct($message, $code, $previous); diff --git a/src/Pecee/SimpleRouter/Route/IGroupRoute.php b/src/Pecee/SimpleRouter/Route/IGroupRoute.php index fbfddf3..ff26273 100644 --- a/src/Pecee/SimpleRouter/Route/IGroupRoute.php +++ b/src/Pecee/SimpleRouter/Route/IGroupRoute.php @@ -29,7 +29,7 @@ interface IGroupRoute extends IRoute * @param array $handlers * @return static */ - public function setExceptionHandlers(array $handlers); + public function setExceptionHandlers(array $handlers): self; /** * Get exception-handlers for group diff --git a/src/Pecee/SimpleRouter/Route/ILoadableRoute.php b/src/Pecee/SimpleRouter/Route/ILoadableRoute.php index d0d7090..0e874e8 100644 --- a/src/Pecee/SimpleRouter/Route/ILoadableRoute.php +++ b/src/Pecee/SimpleRouter/Route/ILoadableRoute.php @@ -82,6 +82,6 @@ interface ILoadableRoute extends IRoute * @param string $regex * @return static */ - public function setMatch($regex): self; + public function setMatch(string $regex): self; } \ No newline at end of file diff --git a/src/Pecee/SimpleRouter/Route/IRoute.php b/src/Pecee/SimpleRouter/Route/IRoute.php index 1af8fe8..4ac88db 100644 --- a/src/Pecee/SimpleRouter/Route/IRoute.php +++ b/src/Pecee/SimpleRouter/Route/IRoute.php @@ -10,11 +10,11 @@ interface IRoute /** * Method called to check if a domain matches * - * @param string $route + * @param string $url * @param Request $request * @return bool */ - public function matchRoute($route, Request $request): bool; + public function matchRoute(string $url, Request $request): bool; /** * Called when route is matched. @@ -129,7 +129,7 @@ interface IRoute * @param string $namespace * @return static */ - public function setDefaultNamespace($namespace): IRoute; + public function setDefaultNamespace(string $namespace): IRoute; /** * Get default namespace @@ -196,7 +196,7 @@ interface IRoute * @param string $middleware * @return static */ - public function addMiddleware($middleware): self; + public function addMiddleware(string $middleware): self; /** * Set middlewares array diff --git a/src/Pecee/SimpleRouter/Route/LoadableRoute.php b/src/Pecee/SimpleRouter/Route/LoadableRoute.php index ba03159..edf414e 100644 --- a/src/Pecee/SimpleRouter/Route/LoadableRoute.php +++ b/src/Pecee/SimpleRouter/Route/LoadableRoute.php @@ -183,7 +183,7 @@ abstract class LoadableRoute extends Route implements ILoadableRoute * @param string $regex * @return static */ - public function setMatch($regex): ILoadableRoute + public function setMatch(string $regex): ILoadableRoute { $this->regex = $regex; @@ -229,15 +229,15 @@ abstract class LoadableRoute extends Route implements ILoadableRoute /** * Merge with information from another route. * - * @param array $values + * @param array $settings * @param bool $merge * @return static */ - public function setSettings(array $values, bool $merge = false): IRoute + public function setSettings(array $settings, bool $merge = false): IRoute { - if (isset($values['as']) === true) { + if (isset($settings['as']) === true) { - $name = $values['as']; + $name = $settings['as']; if ($this->name !== null && $merge !== false) { $name .= '.' . $this->name; @@ -246,11 +246,11 @@ abstract class LoadableRoute extends Route implements ILoadableRoute $this->setName($name); } - if (isset($values['prefix']) === true) { - $this->prependUrl($values['prefix']); + if (isset($settings['prefix']) === true) { + $this->prependUrl($settings['prefix']); } - return parent::setSettings($values, $merge); + return parent::setSettings($settings, $merge); } } \ No newline at end of file diff --git a/src/Pecee/SimpleRouter/Route/Route.php b/src/Pecee/SimpleRouter/Route/Route.php index 1696c98..72c96c6 100644 --- a/src/Pecee/SimpleRouter/Route/Route.php +++ b/src/Pecee/SimpleRouter/Route/Route.php @@ -95,7 +95,7 @@ abstract class Route implements IRoute } if (method_exists($class, $method) === false) { - throw new ClassNotFoundHttpException(sprintf('Method "%s" does not exist in class "%s"', $method, $className), 404, null, $className, $method); + throw new ClassNotFoundHttpException($className, $method, sprintf('Method "%s" does not exist in class "%s"', $method, $className), 404, null); } $router->debug('Executing callback'); @@ -327,7 +327,7 @@ abstract class Route implements IRoute * @param string $namespace * @return static */ - public function setDefaultNamespace($namespace): IRoute + public function setDefaultNamespace(string $namespace): IRoute { $this->defaultNamespace = $namespace; @@ -382,35 +382,35 @@ abstract class Route implements IRoute /** * Merge with information from another route. * - * @param array $values + * @param array $settings * @param bool $merge * @return static */ - public function setSettings(array $values, bool $merge = false): IRoute + public function setSettings(array $settings, bool $merge = false): IRoute { - if ($this->namespace === null && isset($values['namespace']) === true) { - $this->setNamespace($values['namespace']); + if ($this->namespace === null && isset($settings['namespace']) === true) { + $this->setNamespace($settings['namespace']); } - if (isset($values['method']) === true) { - $this->setRequestMethods(array_merge($this->requestMethods, (array)$values['method'])); + if (isset($settings['method']) === true) { + $this->setRequestMethods(array_merge($this->requestMethods, (array)$settings['method'])); } - if (isset($values['where']) === true) { - $this->setWhere(array_merge($this->where, (array)$values['where'])); + if (isset($settings['where']) === true) { + $this->setWhere(array_merge($this->where, (array)$settings['where'])); } - if (isset($values['parameters']) === true) { - $this->setParameters(array_merge($this->parameters, (array)$values['parameters'])); + if (isset($settings['parameters']) === true) { + $this->setParameters(array_merge($this->parameters, (array)$settings['parameters'])); } // Push middleware if multiple - if (isset($values['middleware']) === true) { - $this->setMiddlewares(array_merge((array)$values['middleware'], $this->middlewares)); + if (isset($settings['middleware']) === true) { + $this->setMiddlewares(array_merge((array)$settings['middleware'], $this->middlewares)); } - if (isset($values['defaultParameterRegex']) === true) { - $this->setDefaultParameterRegex($values['defaultParameterRegex']); + if (isset($settings['defaultParameterRegex']) === true) { + $this->setDefaultParameterRegex($settings['defaultParameterRegex']); } return $this; @@ -493,11 +493,11 @@ abstract class Route implements IRoute /** * Add middleware class-name * - * @param IMiddleware|string $middleware + * @param string $middleware * @return static * @deprecated This method is deprecated and will be removed in the near future. */ - public function setMiddleware($middleware) + public function setMiddleware(string $middleware): self { $this->middlewares[] = $middleware; @@ -507,10 +507,10 @@ abstract class Route implements IRoute /** * Add middleware class-name * - * @param IMiddleware|string $middleware + * @param string $middleware * @return static */ - public function addMiddleware($middleware): IRoute + public function addMiddleware(string $middleware): IRoute { $this->middlewares[] = $middleware; @@ -545,7 +545,7 @@ abstract class Route implements IRoute * @param string $regex * @return static */ - public function setDefaultParameterRegex($regex) + public function setDefaultParameterRegex(string $regex): self { $this->defaultParameterRegex = $regex; diff --git a/src/Pecee/SimpleRouter/Route/RouteController.php b/src/Pecee/SimpleRouter/Route/RouteController.php index 551ddbb..2b00ec5 100644 --- a/src/Pecee/SimpleRouter/Route/RouteController.php +++ b/src/Pecee/SimpleRouter/Route/RouteController.php @@ -86,7 +86,7 @@ class RouteController extends LoadableRoute implements IControllerRoute return '/' . trim($url, '/') . '/'; } - public function matchRoute($url, Request $request): bool + public function matchRoute(string $url, Request $request): bool { if ($this->getGroup() !== null && $this->getGroup()->matchRoute($url, $request) === false) { return false; @@ -167,17 +167,17 @@ class RouteController extends LoadableRoute implements IControllerRoute /** * Merge with information from another route. * - * @param array $values + * @param array $settings * @param bool $merge * @return static */ - public function setSettings(array $values, bool $merge = false): IRoute + public function setSettings(array $settings, bool $merge = false): IRoute { - if (isset($values['names']) === true) { - $this->names = $values['names']; + if (isset($settings['names']) === true) { + $this->names = $settings['names']; } - return parent::setSettings($values, $merge); + return parent::setSettings($settings, $merge); } } \ No newline at end of file diff --git a/src/Pecee/SimpleRouter/Route/RouteGroup.php b/src/Pecee/SimpleRouter/Route/RouteGroup.php index 8e724ee..68e9e75 100644 --- a/src/Pecee/SimpleRouter/Route/RouteGroup.php +++ b/src/Pecee/SimpleRouter/Route/RouteGroup.php @@ -49,7 +49,7 @@ class RouteGroup extends Route implements IGroupRoute * @param Request $request * @return bool */ - public function matchRoute($url, Request $request): bool + public function matchRoute(string $url, Request $request): bool { if ($this->getGroup() !== null && $this->getGroup()->matchRoute($url, $request) === false) { return false; @@ -154,28 +154,28 @@ class RouteGroup extends Route implements IGroupRoute /** * Merge with information from another route. * - * @param array $values + * @param array $settings * @param bool $merge * @return static */ - public function setSettings(array $values, bool $merge = false): IRoute + public function setSettings(array $settings, bool $merge = false): IRoute { - if (isset($values['prefix']) === true) { - $this->setPrefix($values['prefix'] . $this->prefix); + if (isset($settings['prefix']) === true) { + $this->setPrefix($settings['prefix'] . $this->prefix); } - if ($merge === false && isset($values['exceptionHandler']) === true) { - $this->setExceptionHandlers((array)$values['exceptionHandler']); + if ($merge === false && isset($settings['exceptionHandler']) === true) { + $this->setExceptionHandlers((array)$settings['exceptionHandler']); } - if ($merge === false && isset($values['domain']) === true) { - $this->setDomains((array)$values['domain']); + if ($merge === false && isset($settings['domain']) === true) { + $this->setDomains((array)$settings['domain']); } - if (isset($values['as']) === true) { + if (isset($settings['as']) === true) { - $name = $values['as']; + $name = $settings['as']; if ($this->name !== null && $merge !== false) { $name .= '.' . $this->name; @@ -184,7 +184,7 @@ class RouteGroup extends Route implements IGroupRoute $this->name = $name; } - return parent::setSettings($values, $merge); + return parent::setSettings($settings, $merge); } /** diff --git a/src/Pecee/SimpleRouter/Route/RoutePartialGroup.php b/src/Pecee/SimpleRouter/Route/RoutePartialGroup.php index fc3628b..1e1a51b 100644 --- a/src/Pecee/SimpleRouter/Route/RoutePartialGroup.php +++ b/src/Pecee/SimpleRouter/Route/RoutePartialGroup.php @@ -22,7 +22,7 @@ class RoutePartialGroup extends RouteGroup implements IPartialGroupRoute * @param Request $request * @return bool */ - public function matchRoute($url, Request $request): bool + public function matchRoute(string $url, Request $request): bool { if ($this->getGroup() !== null && $this->getGroup()->matchRoute($url, $request) === false) { return false; diff --git a/src/Pecee/SimpleRouter/Route/RouteResource.php b/src/Pecee/SimpleRouter/Route/RouteResource.php index 7ae692c..73ea662 100644 --- a/src/Pecee/SimpleRouter/Route/RouteResource.php +++ b/src/Pecee/SimpleRouter/Route/RouteResource.php @@ -83,7 +83,7 @@ class RouteResource extends LoadableRoute implements IControllerRoute return true; } - public function matchRoute($url, Request $request): bool + public function matchRoute(string $url, Request $request): bool { if ($this->getGroup() !== null && $this->getGroup()->matchRoute($url, $request) === false) { return false; @@ -210,21 +210,21 @@ class RouteResource extends LoadableRoute implements IControllerRoute /** * Merge with information from another route. * - * @param array $values + * @param array $settings * @param bool $merge * @return static */ - public function setSettings(array $values, bool $merge = false): IRoute + public function setSettings(array $settings, bool $merge = false): IRoute { - if (isset($values['names']) === true) { - $this->names = $values['names']; + if (isset($settings['names']) === true) { + $this->names = $settings['names']; } - if (isset($values['methods']) === true) { - $this->methodNames = $values['methods']; + if (isset($settings['methods']) === true) { + $this->methodNames = $settings['methods']; } - return parent::setSettings($values, $merge); + return parent::setSettings($settings, $merge); } } \ No newline at end of file diff --git a/src/Pecee/SimpleRouter/Route/RouteUrl.php b/src/Pecee/SimpleRouter/Route/RouteUrl.php index cdfcb60..a4f62c1 100644 --- a/src/Pecee/SimpleRouter/Route/RouteUrl.php +++ b/src/Pecee/SimpleRouter/Route/RouteUrl.php @@ -12,7 +12,7 @@ class RouteUrl extends LoadableRoute $this->setCallback($callback); } - public function matchRoute($url, Request $request): bool + public function matchRoute(string $url, Request $request): bool { if ($this->getGroup() !== null && $this->getGroup()->matchRoute($url, $request) === false) { return false; diff --git a/src/Pecee/SimpleRouter/Router.php b/src/Pecee/SimpleRouter/Router.php index 72fbc05..91b7b67 100644 --- a/src/Pecee/SimpleRouter/Router.php +++ b/src/Pecee/SimpleRouter/Router.php @@ -461,7 +461,7 @@ class Router * @throws HttpException * @throws \Exception */ - protected function handleRouteRewrite($key, string $url): ?string + protected function handleRouteRewrite(string $key, string $url): ?string { /* If the request has changed */ if ($this->request->hasPendingRewrite() === false) { @@ -874,7 +874,7 @@ class Router * @param string $name * @param array $arguments */ - protected function fireEvents($name, array $arguments = []): void + protected function fireEvents(string $name, array $arguments = []): void { if (\count($this->eventHandlers) === 0) { return; diff --git a/src/Pecee/SimpleRouter/SimpleRouter.php b/src/Pecee/SimpleRouter/SimpleRouter.php index d11d255..408a8d2 100644 --- a/src/Pecee/SimpleRouter/SimpleRouter.php +++ b/src/Pecee/SimpleRouter/SimpleRouter.php @@ -169,7 +169,7 @@ class SimpleRouter * @param int $httpCode * @return IRoute */ - public static function redirect($where, $to, $httpCode = 301): IRoute + public static function redirect(string $where, string $to, int $httpCode = 301): IRoute { return static::get($where, function () use ($to, $httpCode) { static::response()->redirect($to, $httpCode);