summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorIgor Scheller <igor.scheller@igorshp.de>2018-09-04 18:35:13 +0200
committerIgor Scheller <igor.scheller@igorshp.de>2018-09-04 21:13:28 +0200
commitb52444af8a289e089d1239657cdf6ff06b21b29d (patch)
treec2754b3049a50ad6743841a609ab0574f241720d /src
parentb320fc779063ee80b8f0ba505cb323287ccccbf5 (diff)
parenta1bc763a16ee8be109de5c9053fbc5eded53824e (diff)
Merge remote-tracking branch 'MyIgel/routing'
Diffstat (limited to 'src')
-rw-r--r--src/Http/LegacyUrlGenerator.php (renamed from src/Routing/LegacyUrlGenerator.php)6
-rw-r--r--src/Http/UrlGenerator.php (renamed from src/Routing/UrlGenerator.php)4
-rw-r--r--src/Http/UrlGeneratorInterface.php (renamed from src/Routing/UrlGeneratorInterface.php)4
-rw-r--r--src/Http/UrlGeneratorServiceProvider.php14
-rw-r--r--src/Middleware/CallableHandler.php77
-rw-r--r--src/Middleware/Dispatcher.php26
-rw-r--r--src/Middleware/LegacyMiddleware.php13
-rw-r--r--src/Middleware/NotFoundResponse.php56
-rw-r--r--src/Middleware/RequestHandler.php50
-rw-r--r--src/Middleware/RequestHandlerServiceProvider.php17
-rw-r--r--src/Middleware/ResolvesMiddlewareTrait.php56
-rw-r--r--src/Middleware/RouteDispatcher.php75
-rw-r--r--src/Middleware/RouteDispatcherServiceProvider.php41
-rw-r--r--src/Routing/RoutingServiceProvider.php24
-rw-r--r--src/helpers.php6
15 files changed, 354 insertions, 115 deletions
diff --git a/src/Routing/LegacyUrlGenerator.php b/src/Http/LegacyUrlGenerator.php
index fdac4f96..b9f8b7f1 100644
--- a/src/Routing/LegacyUrlGenerator.php
+++ b/src/Http/LegacyUrlGenerator.php
@@ -1,6 +1,6 @@
<?php
-namespace Engelsystem\Routing;
+namespace Engelsystem\Http;
/**
* Provides urls when webserver rewriting is disabled.
@@ -14,7 +14,7 @@ class LegacyUrlGenerator extends UrlGenerator
* @param array $parameters
* @return string urls in the form <app url>/index.php?p=<path>&<parameters>
*/
- public function linkTo($path, $parameters = [])
+ public function to($path, $parameters = [])
{
$page = ltrim($path, '/');
if (!empty($page)) {
@@ -22,7 +22,7 @@ class LegacyUrlGenerator extends UrlGenerator
$parameters = array_merge(['p' => $page], $parameters);
}
- $uri = parent::linkTo('index.php', $parameters);
+ $uri = parent::to('index.php', $parameters);
$uri = preg_replace('~(/index\.php)+~', '/index.php', $uri);
$uri = preg_replace('~(/index\.php)$~', '/', $uri);
diff --git a/src/Routing/UrlGenerator.php b/src/Http/UrlGenerator.php
index 188bac3b..7ced769e 100644
--- a/src/Routing/UrlGenerator.php
+++ b/src/Http/UrlGenerator.php
@@ -1,6 +1,6 @@
<?php
-namespace Engelsystem\Routing;
+namespace Engelsystem\Http;
/**
* Provides urls when rewriting on the webserver is enabled. (default)
@@ -14,7 +14,7 @@ class UrlGenerator implements UrlGeneratorInterface
* @param array $parameters
* @return string url in the form [app url]/[path]?[parameters]
*/
- public function linkTo($path, $parameters = [])
+ public function to($path, $parameters = [])
{
$path = '/' . ltrim($path, '/');
$request = app('request');
diff --git a/src/Routing/UrlGeneratorInterface.php b/src/Http/UrlGeneratorInterface.php
index f1a8ffed..b3b6b12d 100644
--- a/src/Routing/UrlGeneratorInterface.php
+++ b/src/Http/UrlGeneratorInterface.php
@@ -1,6 +1,6 @@
<?php
-namespace Engelsystem\Routing;
+namespace Engelsystem\Http;
/**
* To switch between different URL schemes.
@@ -12,5 +12,5 @@ interface UrlGeneratorInterface
* @param array $parameters
* @return string
*/
- public function linkTo($path, $parameters = []);
+ public function to($path, $parameters = []);
}
diff --git a/src/Http/UrlGeneratorServiceProvider.php b/src/Http/UrlGeneratorServiceProvider.php
new file mode 100644
index 00000000..37304076
--- /dev/null
+++ b/src/Http/UrlGeneratorServiceProvider.php
@@ -0,0 +1,14 @@
+<?php
+
+namespace Engelsystem\Http;
+
+use Engelsystem\Container\ServiceProvider;
+
+class UrlGeneratorServiceProvider extends ServiceProvider
+{
+ public function register()
+ {
+ $urlGenerator = $this->app->make(UrlGenerator::class);
+ $this->app->instance('http.urlGenerator', $urlGenerator);
+ }
+}
diff --git a/src/Middleware/CallableHandler.php b/src/Middleware/CallableHandler.php
new file mode 100644
index 00000000..eb493bf1
--- /dev/null
+++ b/src/Middleware/CallableHandler.php
@@ -0,0 +1,77 @@
+<?php
+
+namespace Engelsystem\Middleware;
+
+use Engelsystem\Container\Container;
+use Engelsystem\Http\Response;
+use InvalidArgumentException;
+use Psr\Http\Message\ResponseInterface;
+use Psr\Http\Message\ServerRequestInterface;
+use Psr\Http\Server\MiddlewareInterface;
+use Psr\Http\Server\RequestHandlerInterface;
+
+class CallableHandler implements MiddlewareInterface, RequestHandlerInterface
+{
+ /** @var callable */
+ protected $callable;
+
+ /** @var Container */
+ protected $container;
+
+ /**
+ * @param callable $callable The callable that should be wrapped
+ * @param Container $container
+ */
+ public function __construct(callable $callable, Container $container = null)
+ {
+ $this->callable = $callable;
+ $this->container = $container;
+ }
+
+ /**
+ * Process an incoming server request and return a response, optionally delegating
+ * response creation to a handler.
+ *
+ * @param ServerRequestInterface $request
+ * @param RequestHandlerInterface $handler
+ * @return ResponseInterface
+ */
+ public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
+ {
+ return $this->execute([$request, $handler]);
+ }
+
+ /**
+ * Handle the request and return a response.
+ *
+ * @param ServerRequestInterface $request
+ * @return ResponseInterface
+ */
+ public function handle(ServerRequestInterface $request): ResponseInterface
+ {
+ return $this->execute([$request]);
+ }
+
+ /**
+ * Execute the callable and return a response
+ *
+ * @param array $arguments
+ * @return ResponseInterface
+ */
+ protected function execute(array $arguments = []): ResponseInterface
+ {
+ $return = call_user_func_array($this->callable, $arguments);
+
+ if ($return instanceof ResponseInterface) {
+ return $return;
+ }
+
+ if (!$this->container instanceof Container) {
+ throw new InvalidArgumentException('Unable to resolve response');
+ }
+
+ /** @var Response $response */
+ $response = $this->container->get('response');
+ return $response->withContent($return);
+ }
+}
diff --git a/src/Middleware/Dispatcher.php b/src/Middleware/Dispatcher.php
index f2a5b5d5..48eb0948 100644
--- a/src/Middleware/Dispatcher.php
+++ b/src/Middleware/Dispatcher.php
@@ -12,6 +12,8 @@ use Psr\Http\Server\RequestHandlerInterface;
class Dispatcher implements MiddlewareInterface, RequestHandlerInterface
{
+ use ResolvesMiddlewareTrait;
+
/** @var MiddlewareInterface[]|string[] */
protected $stack;
@@ -70,10 +72,7 @@ class Dispatcher implements MiddlewareInterface, RequestHandlerInterface
throw new LogicException('Middleware queue is empty');
}
- if (is_string($middleware)) {
- $middleware = $this->resolveMiddleware($middleware);
- }
-
+ $middleware = $this->resolveMiddleware($middleware);
if (!$middleware instanceof MiddlewareInterface) {
throw new InvalidArgumentException('Middleware is no instance of ' . MiddlewareInterface::class);
}
@@ -82,25 +81,6 @@ class Dispatcher implements MiddlewareInterface, RequestHandlerInterface
}
/**
- * Resolve the middleware with the container
- *
- * @param string $middleware
- * @return MiddlewareInterface
- */
- protected function resolveMiddleware($middleware)
- {
- if (!$this->container instanceof Application) {
- throw new InvalidArgumentException('Unable to resolve middleware ' . $middleware);
- }
-
- if ($this->container->has($middleware)) {
- return $this->container->get($middleware);
- }
-
- return $this->container->make($middleware);
- }
-
- /**
* @param Application $container
*/
public function setContainer(Application $container)
diff --git a/src/Middleware/LegacyMiddleware.php b/src/Middleware/LegacyMiddleware.php
index 714141de..276fb3ee 100644
--- a/src/Middleware/LegacyMiddleware.php
+++ b/src/Middleware/LegacyMiddleware.php
@@ -83,7 +83,9 @@ class LegacyMiddleware implements MiddlewareInterface
}
if (empty($title) and empty($content)) {
- return $handler->handle($request);
+ $page = '404';
+ $title = _('Page not found');
+ $content = _('This page could not be found or you don\'t have permission to view it. You probably have to sign in or register in order to gain access!');
}
return $this->renderPage($page, $title, $content);
@@ -270,10 +272,17 @@ class LegacyMiddleware implements MiddlewareInterface
$parameters = [
'key' => (isset($user) ? $user['api_key'] : ''),
];
+
if ($page == 'user_meetings') {
$parameters['meetings'] = 1;
}
+ $status = 200;
+ if ($page == '404') {
+ $status = 404;
+ $content = info($content, true);
+ }
+
return response(view(__DIR__ . '/../../templates/layout.html', [
'theme' => isset($user) ? $user['color'] : config('theme'),
'title' => $title,
@@ -291,6 +300,6 @@ class LegacyMiddleware implements MiddlewareInterface
'contact_email' => config('contact_email'),
'locale' => locale(),
'event_info' => EventConfig_info($event_config) . ' <br />'
- ]));
+ ]), $status);
}
}
diff --git a/src/Middleware/NotFoundResponse.php b/src/Middleware/NotFoundResponse.php
deleted file mode 100644
index f9431c1d..00000000
--- a/src/Middleware/NotFoundResponse.php
+++ /dev/null
@@ -1,56 +0,0 @@
-<?php
-
-namespace Engelsystem\Middleware;
-
-use Engelsystem\Http\Response;
-use Psr\Http\Message\ResponseInterface;
-use Psr\Http\Message\ServerRequestInterface;
-use Psr\Http\Server\MiddlewareInterface;
-use Psr\Http\Server\RequestHandlerInterface;
-
-class NotFoundResponse implements MiddlewareInterface
-{
- /**
- * Returns a 404: Page not found response
- *
- * Should be the last middleware
- *
- * @param ServerRequestInterface $request
- * @param RequestHandlerInterface $handler
- * @return ResponseInterface
- */
- public function process(
- ServerRequestInterface $request,
- RequestHandlerInterface $handler
- ): ResponseInterface {
- $info = _('This page could not be found or you don\'t have permission to view it. You probably have to sign in or register in order to gain access!');
-
- return $this->renderPage($info);
- }
-
- /**
- * @param string $content
- * @return Response
- * @codeCoverageIgnore
- */
- protected function renderPage($content)
- {
- global $user;
- $event_config = EventConfig();
-
- return response(view(__DIR__ . '/../../templates/layout.html', [
- 'theme' => isset($user) ? $user['color'] : config('theme'),
- 'title' => _('Page not found'),
- 'atom_link' => '',
- 'start_page_url' => page_link_to('/'),
- 'credits_url' => page_link_to('credits'),
- 'menu' => make_menu(),
- 'content' => msg() . info($content),
- 'header_toolbar' => header_toolbar(),
- 'faq_url' => config('faq_url'),
- 'contact_email' => config('contact_email'),
- 'locale' => locale(),
- 'event_info' => EventConfig_info($event_config) . ' <br />'
- ]), 404);
- }
-}
diff --git a/src/Middleware/RequestHandler.php b/src/Middleware/RequestHandler.php
new file mode 100644
index 00000000..e1381abf
--- /dev/null
+++ b/src/Middleware/RequestHandler.php
@@ -0,0 +1,50 @@
+<?php
+
+namespace Engelsystem\Middleware;
+
+use Engelsystem\Application;
+use InvalidArgumentException;
+use Psr\Http\Message\ResponseInterface;
+use Psr\Http\Message\ServerRequestInterface;
+use Psr\Http\Server\MiddlewareInterface;
+use Psr\Http\Server\RequestHandlerInterface;
+
+class RequestHandler implements MiddlewareInterface
+{
+ use ResolvesMiddlewareTrait;
+
+ /** @var Application */
+ protected $container;
+
+ /**
+ * @param Application $container
+ */
+ public function __construct(Application $container)
+ {
+ $this->container = $container;
+ }
+
+ /**
+ * Process an incoming server request and return a response, optionally delegating
+ * response creation to a handler.
+ *
+ * @param ServerRequestInterface $request
+ * @param RequestHandlerInterface $handler
+ * @return ResponseInterface
+ */
+ public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
+ {
+ $requestHandler = $request->getAttribute('route-request-handler');
+ $requestHandler = $this->resolveMiddleware($requestHandler);
+
+ if ($requestHandler instanceof MiddlewareInterface) {
+ return $requestHandler->process($request, $handler);
+ }
+
+ if ($requestHandler instanceof RequestHandlerInterface) {
+ return $requestHandler->handle($request);
+ }
+
+ throw new InvalidArgumentException('Unable to process request handler of type ' . gettype($requestHandler));
+ }
+}
diff --git a/src/Middleware/RequestHandlerServiceProvider.php b/src/Middleware/RequestHandlerServiceProvider.php
new file mode 100644
index 00000000..c6488118
--- /dev/null
+++ b/src/Middleware/RequestHandlerServiceProvider.php
@@ -0,0 +1,17 @@
+<?php
+
+namespace Engelsystem\Middleware;
+
+use Engelsystem\Container\ServiceProvider;
+
+class RequestHandlerServiceProvider extends ServiceProvider
+{
+ public function register()
+ {
+ /** @var RequestHandler $requestHandler */
+ $requestHandler = $this->app->make(RequestHandler::class);
+
+ $this->app->instance('request.handler', $requestHandler);
+ $this->app->bind(RequestHandler::class, 'request.handler');
+ }
+}
diff --git a/src/Middleware/ResolvesMiddlewareTrait.php b/src/Middleware/ResolvesMiddlewareTrait.php
new file mode 100644
index 00000000..76557ce6
--- /dev/null
+++ b/src/Middleware/ResolvesMiddlewareTrait.php
@@ -0,0 +1,56 @@
+<?php
+
+namespace Engelsystem\Middleware;
+
+use Engelsystem\Application;
+use InvalidArgumentException;
+use Psr\Http\Server\MiddlewareInterface;
+use Psr\Http\Server\RequestHandlerInterface;
+
+trait ResolvesMiddlewareTrait
+{
+ /**
+ * Resolve the middleware with the container
+ *
+ * @param string|callable|MiddlewareInterface|RequestHandlerInterface $middleware
+ * @return MiddlewareInterface|RequestHandlerInterface
+ */
+ protected function resolveMiddleware($middleware)
+ {
+ if ($this->isMiddleware($middleware)) {
+ return $middleware;
+ }
+
+ if (!property_exists($this, 'container') || !$this->container instanceof Application) {
+ throw new InvalidArgumentException('Unable to resolve middleware');
+ }
+
+ /** @var Application $container */
+ $container = $this->container;
+
+ if (is_string($middleware)) {
+ $middleware = $container->make($middleware);
+ }
+
+ if (is_callable($middleware)) {
+ $middleware = $container->make(CallableHandler::class, ['callable' => $middleware]);
+ }
+
+ if ($this->isMiddleware($middleware)) {
+ return $middleware;
+ }
+
+ throw new InvalidArgumentException('Unable to resolve middleware');
+ }
+
+ /**
+ * Checks if the given object is a middleware or middleware or request handler
+ *
+ * @param mixed $middleware
+ * @return bool
+ */
+ protected function isMiddleware($middleware)
+ {
+ return ($middleware instanceof MiddlewareInterface || $middleware instanceof RequestHandlerInterface);
+ }
+}
diff --git a/src/Middleware/RouteDispatcher.php b/src/Middleware/RouteDispatcher.php
new file mode 100644
index 00000000..f14faea8
--- /dev/null
+++ b/src/Middleware/RouteDispatcher.php
@@ -0,0 +1,75 @@
+<?php
+
+namespace Engelsystem\Middleware;
+
+use FastRoute\Dispatcher as FastRouteDispatcher;
+use Psr\Http\Message\ResponseInterface;
+use Psr\Http\Message\ServerRequestInterface;
+use Psr\Http\Server\MiddlewareInterface;
+use Psr\Http\Server\RequestHandlerInterface;
+
+class RouteDispatcher implements MiddlewareInterface
+{
+ /** @var FastRouteDispatcher */
+ protected $dispatcher;
+
+ /** @var ResponseInterface */
+ protected $response;
+
+ /** @var MiddlewareInterface|null */
+ protected $notFound;
+
+ /**
+ * @param FastRouteDispatcher $dispatcher
+ * @param ResponseInterface $response Default response
+ * @param MiddlewareInterface|null $notFound Handles any requests if the route can't be found
+ */
+ public function __construct(
+ FastRouteDispatcher $dispatcher,
+ ResponseInterface $response,
+ MiddlewareInterface $notFound = null
+ ) {
+ $this->dispatcher = $dispatcher;
+ $this->response = $response;
+ $this->notFound = $notFound;
+ }
+
+ /**
+ * Process an incoming server request and return a response, optionally delegating
+ * response creation to a handler.
+ *
+ * @param ServerRequestInterface $request
+ * @param RequestHandlerInterface $handler
+ * @return ResponseInterface
+ */
+ public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
+ {
+ $route = $this->dispatcher->dispatch($request->getMethod(), urldecode($request->getUri()->getPath()));
+
+ $status = $route[0];
+ if ($status == FastRouteDispatcher::NOT_FOUND) {
+ if ($this->notFound instanceof MiddlewareInterface) {
+ return $this->notFound->process($request, $handler);
+ }
+
+ return $this->response->withStatus(404);
+ }
+
+ if ($status == FastRouteDispatcher::METHOD_NOT_ALLOWED) {
+ $methods = $route[1];
+ return $this->response
+ ->withStatus(405)
+ ->withHeader('Allow', implode(', ', $methods));
+ }
+
+ $routeHandler = $route[1];
+ $request = $request->withAttribute('route-request-handler', $routeHandler);
+
+ $vars = $route[2];
+ foreach ($vars as $name => $value) {
+ $request = $request->withAttribute($name, $value);
+ }
+
+ return $handler->handle($request);
+ }
+}
diff --git a/src/Middleware/RouteDispatcherServiceProvider.php b/src/Middleware/RouteDispatcherServiceProvider.php
new file mode 100644
index 00000000..3b4fa183
--- /dev/null
+++ b/src/Middleware/RouteDispatcherServiceProvider.php
@@ -0,0 +1,41 @@
+<?php
+
+namespace Engelsystem\Middleware;
+
+use Engelsystem\Container\ServiceProvider;
+use FastRoute\Dispatcher as FastRouteDispatcher;
+use FastRoute\RouteCollector;
+use Psr\Http\Server\MiddlewareInterface;
+
+class RouteDispatcherServiceProvider extends ServiceProvider
+{
+ public function register()
+ {
+ $this->app->alias(RouteDispatcher::class, 'route.dispatcher');
+
+ $this->app
+ ->when(RouteDispatcher::class)
+ ->needs(FastRouteDispatcher::class)
+ ->give(function () {
+ return $this->generateRouting();
+ });
+
+ $this->app
+ ->when(RouteDispatcher::class)
+ ->needs(MiddlewareInterface::class)
+ ->give(LegacyMiddleware::class);
+ }
+
+ /**
+ * Includes the routes.php file
+ *
+ * @return FastRouteDispatcher
+ * @codeCoverageIgnore
+ */
+ function generateRouting()
+ {
+ return \FastRoute\simpleDispatcher(function (RouteCollector $route) {
+ require config_path('routes.php');
+ });
+ }
+}
diff --git a/src/Routing/RoutingServiceProvider.php b/src/Routing/RoutingServiceProvider.php
deleted file mode 100644
index beaa6a94..00000000
--- a/src/Routing/RoutingServiceProvider.php
+++ /dev/null
@@ -1,24 +0,0 @@
-<?php
-namespace Engelsystem\Routing;
-
-use Engelsystem\Container\ServiceProvider;
-
-/**
- * Registers the url generator depending on config.
- */
-class RoutingServiceProvider extends ServiceProvider
-{
-
- public function register()
- {
- $config = $this->app->get('config');
- $class = UrlGenerator::class;
- if (! $config->get('rewrite_urls', true)) {
- $class = LegacyUrlGenerator::class;
- }
-
- $urlGenerator = $this->app->make($class);
- $this->app->instance('routing.urlGenerator', $urlGenerator);
- $this->app->bind(UrlGeneratorInterface::class, 'routing.urlGenerator');
- }
-}
diff --git a/src/helpers.php b/src/helpers.php
index 50c5c837..95571a40 100644
--- a/src/helpers.php
+++ b/src/helpers.php
@@ -6,7 +6,7 @@ use Engelsystem\Config\Config;
use Engelsystem\Http\Request;
use Engelsystem\Http\Response;
use Engelsystem\Renderer\Renderer;
-use Engelsystem\Routing\UrlGeneratorInterface;
+use Engelsystem\Http\UrlGenerator;
use Symfony\Component\HttpFoundation\Session\SessionInterface;
/**
@@ -125,13 +125,13 @@ function session($key = null, $default = null)
*/
function url($path = null, $parameters = [])
{
- $urlGenerator = app('routing.urlGenerator');
+ $urlGenerator = app('http.urlGenerator');
if (is_null($path)) {
return $urlGenerator;
}
- return $urlGenerator->linkTo($path, $parameters);
+ return $urlGenerator->to($path, $parameters);
}
/**