mirror of
https://github.com/skipperbent/simple-php-router.git
synced 2026-06-17 00:37:52 +00:00
Development
- Added dependency injection support. - Added php-di composer dependency. - Added `ClassLoader` class. - Added `IClassLoader` interface. - Added unit-tests for dependency injection. - Updated documentation to reflect new features.
This commit is contained in:
@@ -0,0 +1,118 @@
|
||||
<?php
|
||||
|
||||
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
|
||||
*
|
||||
* @param string $class
|
||||
* @return mixed
|
||||
* @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());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return new $class();
|
||||
}
|
||||
|
||||
/**
|
||||
* Load closure
|
||||
*
|
||||
* @param \Closure $closure
|
||||
* @param array $parameters
|
||||
* @return mixed
|
||||
* @throws NotFoundHttpException
|
||||
*/
|
||||
public function loadClosure(\Closure $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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
<?php
|
||||
|
||||
namespace Pecee\SimpleRouter\ClassLoader;
|
||||
|
||||
interface IClassLoader
|
||||
{
|
||||
|
||||
public function loadClass(string $class);
|
||||
|
||||
public function loadClosure(\Closure $closure, array $parameters);
|
||||
|
||||
}
|
||||
@@ -150,7 +150,7 @@ class EventHandler implements IEventHandler
|
||||
$events = [];
|
||||
|
||||
foreach ($names as $eventName) {
|
||||
if(isset($this->registeredEvents[$eventName]) === true) {
|
||||
if (isset($this->registeredEvents[$eventName]) === true) {
|
||||
$events += $this->registeredEvents[$eventName];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,7 +4,8 @@ namespace Pecee\SimpleRouter\Handlers;
|
||||
|
||||
use Pecee\SimpleRouter\Router;
|
||||
|
||||
interface IEventHandler {
|
||||
interface IEventHandler
|
||||
{
|
||||
|
||||
/**
|
||||
* Get events.
|
||||
@@ -12,7 +13,7 @@ interface IEventHandler {
|
||||
* @param string|null $name Filter events by name.
|
||||
* @return array
|
||||
*/
|
||||
public function getEvents(?string $name) : array;
|
||||
public function getEvents(?string $name): array;
|
||||
|
||||
/**
|
||||
* Fires any events registered with given event-name
|
||||
@@ -21,6 +22,6 @@ interface IEventHandler {
|
||||
* @param string $name Event name
|
||||
* @param array $eventArgs Event arguments
|
||||
*/
|
||||
public function fireEvents(Router $router, string $name, array $eventArgs = []) : void;
|
||||
public function fireEvents(Router $router, string $name, array $eventArgs = []): void;
|
||||
|
||||
}
|
||||
@@ -2,8 +2,8 @@
|
||||
|
||||
namespace Pecee\SimpleRouter\Route;
|
||||
|
||||
use Pecee\SimpleRouter\Handlers\IExceptionHandler;
|
||||
use Pecee\Http\Request;
|
||||
use Pecee\SimpleRouter\Handlers\IExceptionHandler;
|
||||
|
||||
interface IGroupRoute extends IRoute
|
||||
{
|
||||
|
||||
@@ -35,7 +35,7 @@ abstract class LoadableRoute extends Route implements ILoadableRoute
|
||||
foreach ($this->getMiddlewares() as $middleware) {
|
||||
|
||||
if (\is_object($middleware) === false) {
|
||||
$middleware = $this->loadClass($middleware);
|
||||
$middleware = $router->getClassLoader()->loadClass($middleware);
|
||||
}
|
||||
|
||||
if (($middleware instanceof IMiddleware) === false) {
|
||||
|
||||
@@ -57,21 +57,6 @@ abstract class Route implements IRoute
|
||||
protected $originalParameters = [];
|
||||
protected $middlewares = [];
|
||||
|
||||
/**
|
||||
* Load class by name
|
||||
* @param string $name
|
||||
* @return mixed
|
||||
* @throws NotFoundHttpException
|
||||
*/
|
||||
protected function loadClass($name)
|
||||
{
|
||||
if (class_exists($name) === false) {
|
||||
throw new NotFoundHttpException(sprintf('Class "%s" does not exist', $name), 404);
|
||||
}
|
||||
|
||||
return new $name();
|
||||
}
|
||||
|
||||
/**
|
||||
* Render route
|
||||
*
|
||||
@@ -107,7 +92,7 @@ abstract class Route implements IRoute
|
||||
|
||||
/* When the callback is a function */
|
||||
|
||||
return \call_user_func_array($callback, $parameters);
|
||||
return $router->getClassLoader()->loadClosure($callback, $parameters);
|
||||
}
|
||||
|
||||
/* When the callback is a class + method */
|
||||
@@ -118,7 +103,8 @@ abstract class Route implements IRoute
|
||||
$className = ($namespace !== null && $controller[0][0] !== '\\') ? $namespace . '\\' . $controller[0] : $controller[0];
|
||||
|
||||
$router->debug('Loading class %s', $className);
|
||||
$class = $this->loadClass($className);
|
||||
$class = $router->getClassLoader()->loadClass($className);
|
||||
|
||||
$method = $controller[1];
|
||||
|
||||
if (method_exists($class, $method) === false) {
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
|
||||
namespace Pecee\SimpleRouter\Route;
|
||||
|
||||
use Pecee\SimpleRouter\Handlers\IExceptionHandler;
|
||||
use Pecee\Http\Request;
|
||||
use Pecee\SimpleRouter\Handlers\IExceptionHandler;
|
||||
|
||||
class RouteGroup extends Route implements IGroupRoute
|
||||
{
|
||||
|
||||
@@ -4,14 +4,16 @@ namespace Pecee\SimpleRouter;
|
||||
|
||||
use Pecee\Exceptions\InvalidArgumentException;
|
||||
use Pecee\Http\Exceptions\MalformedUrlException;
|
||||
use Pecee\Http\Middleware\BaseCsrfVerifier;
|
||||
use Pecee\Http\Request;
|
||||
use Pecee\Http\Url;
|
||||
use Pecee\SimpleRouter\ClassLoader\ClassLoader;
|
||||
use Pecee\SimpleRouter\ClassLoader\IClassLoader;
|
||||
use Pecee\SimpleRouter\Exceptions\HttpException;
|
||||
use Pecee\SimpleRouter\Exceptions\NotFoundHttpException;
|
||||
use Pecee\SimpleRouter\Handlers\EventHandler;
|
||||
use Pecee\SimpleRouter\Handlers\IEventHandler;
|
||||
use Pecee\SimpleRouter\Handlers\IExceptionHandler;
|
||||
use Pecee\Http\Middleware\BaseCsrfVerifier;
|
||||
use Pecee\Http\Request;
|
||||
use Pecee\SimpleRouter\Exceptions\HttpException;
|
||||
use Pecee\SimpleRouter\Exceptions\NotFoundHttpException;
|
||||
use Pecee\SimpleRouter\Route\IControllerRoute;
|
||||
use Pecee\SimpleRouter\Route\IGroupRoute;
|
||||
use Pecee\SimpleRouter\Route\ILoadableRoute;
|
||||
@@ -102,6 +104,12 @@ class Router
|
||||
*/
|
||||
protected $eventHandlers = [];
|
||||
|
||||
/**
|
||||
* Class loader instance
|
||||
* @var ClassLoader
|
||||
*/
|
||||
protected $classLoader;
|
||||
|
||||
/**
|
||||
* Router constructor.
|
||||
*/
|
||||
@@ -115,6 +123,7 @@ class Router
|
||||
*/
|
||||
public function reset(): void
|
||||
{
|
||||
$this->debugStartTime = microtime(true);
|
||||
$this->isProcessingRoute = false;
|
||||
|
||||
try {
|
||||
@@ -132,7 +141,7 @@ class Router
|
||||
$this->eventHandlers = [];
|
||||
$this->debugList = [];
|
||||
$this->csrfVerifier = null;
|
||||
$this->debugStartTime = microtime(true);
|
||||
$this->classLoader = new ClassLoader();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -271,7 +280,7 @@ class Router
|
||||
$this->debug('Rendering bootmanager "%s"', $className);
|
||||
$this->fireEvents(EventHandler::EVENT_RENDER_BOOTMANAGER, [
|
||||
'bootmanagers' => $this->bootManagers,
|
||||
'bootmanager' => $manager,
|
||||
'bootmanager' => $manager,
|
||||
]);
|
||||
|
||||
/* Render bootmanager */
|
||||
@@ -364,7 +373,7 @@ class Router
|
||||
}
|
||||
|
||||
$this->fireEvents(EventHandler::EVENT_RENDER_MIDDLEWARES, [
|
||||
'route' => $route,
|
||||
'route' => $route,
|
||||
'middlewares' => $route->getMiddlewares(),
|
||||
]);
|
||||
|
||||
@@ -483,8 +492,8 @@ class Router
|
||||
}
|
||||
|
||||
$this->fireEvents(EventHandler::EVENT_RENDER_EXCEPTION, [
|
||||
'exception' => $e,
|
||||
'exceptionHandler' => $handler,
|
||||
'exception' => $e,
|
||||
'exceptionHandler' => $handler,
|
||||
'exceptionHandlers' => $this->exceptionHandlers,
|
||||
]);
|
||||
|
||||
@@ -711,20 +720,28 @@ class Router
|
||||
|
||||
/**
|
||||
* Set BootManagers
|
||||
*
|
||||
* @param array $bootManagers
|
||||
* @return static
|
||||
*/
|
||||
public function setBootManagers(array $bootManagers): void
|
||||
public function setBootManagers(array $bootManagers): self
|
||||
{
|
||||
$this->bootManagers = $bootManagers;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add BootManager
|
||||
*
|
||||
* @param IRouterBootManager $bootManager
|
||||
* @return static
|
||||
*/
|
||||
public function addBootManager(IRouterBootManager $bootManager): void
|
||||
public function addBootManager(IRouterBootManager $bootManager): self
|
||||
{
|
||||
$this->bootManagers[] = $bootManager;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -783,13 +800,36 @@ class Router
|
||||
* @param BaseCsrfVerifier $csrfVerifier
|
||||
* @return static
|
||||
*/
|
||||
public function setCsrfVerifier(BaseCsrfVerifier $csrfVerifier)
|
||||
public function setCsrfVerifier(BaseCsrfVerifier $csrfVerifier): self
|
||||
{
|
||||
$this->csrfVerifier = $csrfVerifier;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set class loader
|
||||
*
|
||||
* @param IClassLoader $loader
|
||||
* @return static
|
||||
*/
|
||||
public function setClassLoader(IClassLoader $loader)
|
||||
{
|
||||
$this->classLoader = $loader;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get class loader
|
||||
*
|
||||
* @return ClassLoader
|
||||
*/
|
||||
public function getClassLoader(): IClassLoader
|
||||
{
|
||||
return $this->classLoader;
|
||||
}
|
||||
|
||||
/**
|
||||
* Register event handler
|
||||
*
|
||||
@@ -853,11 +893,14 @@ class Router
|
||||
/**
|
||||
* Enable or disables debugging
|
||||
*
|
||||
* @param bool $boolean
|
||||
* @param bool $enabled
|
||||
* @return static
|
||||
*/
|
||||
public function setDebugEnabled(bool $boolean): void
|
||||
public function setDebugEnabled(bool $enabled): self
|
||||
{
|
||||
$this->debugEnabled = $boolean;
|
||||
$this->debugEnabled = $enabled;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -10,14 +10,16 @@
|
||||
|
||||
namespace Pecee\SimpleRouter;
|
||||
|
||||
use DI\Container;
|
||||
use Pecee\Exceptions\InvalidArgumentException;
|
||||
use Pecee\Http\Exceptions\MalformedUrlException;
|
||||
use Pecee\Http\Url;
|
||||
use Pecee\SimpleRouter\Handlers\CallbackExceptionHandler;
|
||||
use Pecee\Http\Middleware\BaseCsrfVerifier;
|
||||
use Pecee\Http\Request;
|
||||
use Pecee\Http\Response;
|
||||
use Pecee\Http\Url;
|
||||
use Pecee\SimpleRouter\ClassLoader\IClassLoader;
|
||||
use Pecee\SimpleRouter\Exceptions\HttpException;
|
||||
use Pecee\SimpleRouter\Handlers\CallbackExceptionHandler;
|
||||
use Pecee\SimpleRouter\Handlers\IEventHandler;
|
||||
use Pecee\SimpleRouter\Route\IGroupRoute;
|
||||
use Pecee\SimpleRouter\Route\IPartialGroupRoute;
|
||||
@@ -530,6 +532,20 @@ class SimpleRouter
|
||||
return $route;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable or disable dependency injection
|
||||
*
|
||||
* @param Container $container
|
||||
* @return IClassLoader
|
||||
*/
|
||||
public static function enableDependencyInjection(Container $container): IClassLoader
|
||||
{
|
||||
return static::router()
|
||||
->getClassLoader()
|
||||
->useDependencyInjection(true)
|
||||
->setContainer($container);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get default namespace
|
||||
* @return string|null
|
||||
|
||||
Reference in New Issue
Block a user