Merge branch 'v4-development' into v4-disable-multi-routing

This commit is contained in:
Simon Sessingø
2021-03-23 15:00:01 +01:00
committed by GitHub
21 changed files with 409 additions and 287 deletions
+1 -1
View File
@@ -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) {
@@ -2,44 +2,21 @@
namespace Pecee\SimpleRouter\ClassLoader;
use DI\Container;
use Pecee\SimpleRouter\Exceptions\NotFoundHttpException;
use Pecee\SimpleRouter\Exceptions\ClassNotFoundHttpException;
class ClassLoader implements IClassLoader
{
/**
* Dependency injection enabled
* @var bool
*/
protected $useDependencyInjection = false;
/**
* @var Container|null
*/
protected $container;
/**
* Load class
*
* @param string $class
* @return mixed
* @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->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());
}
}
throw new ClassNotFoundHttpException(sprintf('Class "%s" does not exist', $class), 404, null, $class);
}
return new $class();
@@ -51,68 +28,10 @@ class ClassLoader implements IClassLoader
* @param Callable $closure
* @param array $parameters
* @return mixed
* @throws NotFoundHttpException
*/
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;
}
}
@@ -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);
}
@@ -0,0 +1,38 @@
<?php
namespace Pecee\SimpleRouter\Exceptions;
use Throwable;
class ClassNotFoundHttpException extends NotFoundHttpException
{
protected $class;
protected $method;
public function __construct($message = "", $code = 0, Throwable $previous = null, string $class, ?string $method = null)
{
parent::__construct($message, $code, $previous);
$this->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;
}
}
@@ -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
+3 -3
View File
@@ -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;
@@ -77,7 +78,6 @@ abstract class Route implements IRoute
$router->debug('Executing callback');
/* When the callback is a function */
return $router->getClassLoader()->loadClosure($callback, $parameters);
}
@@ -95,7 +95,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');
@@ -250,7 +250,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
+8 -8
View File
@@ -276,6 +276,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,
]);
@@ -298,13 +305,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');
}
@@ -313,7 +313,7 @@ class Router
*
* @return string|null
* @throws NotFoundHttpException
* @throws TokenMismatchException
* @throws \Pecee\Http\Middleware\Exceptions\TokenMismatchException
* @throws HttpException
* @throws \Exception
*/
+22 -30
View File
@@ -10,7 +10,6 @@
namespace Pecee\SimpleRouter;
use DI\Container;
use Pecee\Exceptions\InvalidArgumentException;
use Pecee\Http\Middleware\BaseCsrfVerifier;
use Pecee\Http\Request;
@@ -59,6 +58,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 +311,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 +326,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 +350,6 @@ class SimpleRouter
{
$route = new RouteUrl($url, $callback);
$route->setRequestMethods($requestMethods);
$route = static::addDefaultNamespace($route);
if ($settings !== null) {
$route->setSettings($settings);
@@ -366,7 +369,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 +388,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 +407,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 +511,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;
@@ -545,17 +542,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);
}
/**