Added CreditsController

This commit is contained in:
Igor Scheller 2018-09-02 02:13:18 +02:00
parent 9e217d87c0
commit 9d34f371cb
11 changed files with 222 additions and 90 deletions

View File

@ -1,14 +1,7 @@
<?php <?php
use FastRoute\RouteCollector; use FastRoute\RouteCollector;
use Psr\Http\Message\ServerRequestInterface;
/** @var RouteCollector $route */ /** @var RouteCollector $route */
/** Demo route endpoint, TODO: Remove */ $route->get('/credits', 'CreditsController@index');
$route->addRoute('GET', '/hello/{name}', function ($request) {
/** @var ServerRequestInterface $request */
$name = $request->getAttribute('name');
return response(sprintf('Hello %s!', htmlspecialchars($name)));
});

View File

@ -1,17 +0,0 @@
<?php
/**
* @return string
*/
function credits_title()
{
return __('Credits');
}
/**
* @return string
*/
function guest_credits()
{
return view(__DIR__ . '/../../templates/pages/credits.html');
}

View File

@ -0,0 +1,8 @@
<?php
namespace Engelsystem\Controllers;
abstract class BaseController
{
}

View File

@ -0,0 +1,24 @@
<?php
namespace Engelsystem\Controllers;
use Engelsystem\Http\Response;
class CreditsController extends BaseController
{
/** @var Response */
protected $response;
public function __construct(Response $response)
{
$this->response = $response;
}
/**
* @return Response
*/
public function index()
{
return $this->response->withView('pages/credits.twig');
}
}

View File

@ -18,7 +18,6 @@ class LegacyMiddleware implements MiddlewareInterface
'angeltypes', 'angeltypes',
'api', 'api',
'atom', 'atom',
'credits',
'ical', 'ical',
'login', 'login',
'public_dashboard', 'public_dashboard',
@ -249,11 +248,6 @@ class LegacyMiddleware implements MiddlewareInterface
$title = admin_log_title(); $title = admin_log_title();
$content = admin_log(); $content = admin_log();
return [$title, $content]; return [$title, $content];
case 'credits':
require_once realpath(__DIR__ . '/../../includes/pages/guest_credits.php');
$title = credits_title();
$content = guest_credits();
return [$title, $content];
} }
require_once realpath(__DIR__ . '/../../includes/pages/guest_start.php'); require_once realpath(__DIR__ . '/../../includes/pages/guest_start.php');

View File

@ -35,7 +35,7 @@ class RequestHandler implements MiddlewareInterface
public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
{ {
$requestHandler = $request->getAttribute('route-request-handler'); $requestHandler = $request->getAttribute('route-request-handler');
$requestHandler = $this->resolveMiddleware($requestHandler); $requestHandler = $this->resolveRequestHandler($requestHandler);
if ($requestHandler instanceof MiddlewareInterface) { if ($requestHandler instanceof MiddlewareInterface) {
return $requestHandler->process($request, $handler); return $requestHandler->process($request, $handler);
@ -47,4 +47,33 @@ class RequestHandler implements MiddlewareInterface
throw new InvalidArgumentException('Unable to process request handler of type ' . gettype($requestHandler)); throw new InvalidArgumentException('Unable to process request handler of type ' . gettype($requestHandler));
} }
/**
* @param string|callable|MiddlewareInterface|RequestHandlerInterface $handler
* @return MiddlewareInterface|RequestHandlerInterface
*/
protected function resolveRequestHandler($handler)
{
if (is_string($handler) && strpos($handler, '@') !== false) {
list($class, $method) = explode('@', $handler, 2);
if (!class_exists($class) && !$this->container->has($class)) {
$class = sprintf('Engelsystem\\Controllers\\%s', $class);
}
$handler = [$class, $method];
}
if (
is_array($handler)
&& is_string($handler[0])
&& (
class_exists($handler[0])
|| $this->container->has($handler[0])
)
) {
$handler[0] = $this->container->make($handler[0]);
}
return $this->resolveMiddleware($handler);
}
} }

View File

@ -28,8 +28,10 @@
{% endblock %} {% endblock %}
<div class="container-fluid"> <div class="container-fluid">
<div class="row"> <div class="row" id="content">
{% block content %}{{ content|raw }}{% endblock %} {% block content %}
{{ content|raw }}
{% endblock %}
</div> </div>
<div class="row" id="footer"> <div class="row" id="footer">
{% block footer %} {% block footer %}
@ -38,19 +40,21 @@
</div> </div>
</div> </div>
<script type="text/javascript" src="vendor/bootstrap/js/bootstrap.min.js"></script> {% block scripts %}
<script type="text/javascript" src="vendor/bootstrap-datepicker-1.7.1/js/bootstrap-datepicker.min.js"></script> <script type="text/javascript" src="vendor/bootstrap/js/bootstrap.min.js"></script>
<script type="text/javascript" src="vendor/bootstrap-datepicker-1.7.1/locales/bootstrap-datepicker.de.min.js"></script> <script type="text/javascript" src="vendor/bootstrap-datepicker-1.7.1/js/bootstrap-datepicker.min.js"></script>
<script type="text/javascript" src="vendor/Chart.min.js"></script> <script type="text/javascript" src="vendor/bootstrap-datepicker-1.7.1/locales/bootstrap-datepicker.de.min.js"></script>
<script type="text/javascript" src="js/forms.js"></script> <script type="text/javascript" src="vendor/Chart.min.js"></script>
<script type="text/javascript" src="vendor/moment-with-locales.min.js"></script> <script type="text/javascript" src="js/forms.js"></script>
<script type="text/javascript"> <script type="text/javascript" src="vendor/moment-with-locales.min.js"></script>
$(function () { <script type="text/javascript">
moment.locale("{{ session_get('locale')|escape('js') }}"); $(function () {
}); moment.locale("{{ session_get('locale')|escape('js') }}");
</script> });
<script type="text/javascript" src="js/moment-countdown.js"></script> </script>
<script type="text/javascript" src="js/sticky-headers.js"></script> <script type="text/javascript" src="js/moment-countdown.js"></script>
<script type="text/javascript" src="js/sticky-headers.js"></script>
{% endblock %}
{% endblock %} {% endblock %}
</body> </body>

View File

@ -1,36 +0,0 @@
<div class="container">
<h1>Credits</h1>
<div class="row">
<div class="col-md-4">
<h2>Source code</h2>
<p>
The original system was written by <a href="https://github.com/cookieBerlin/engelsystem">cookie</a>.
It was then completely rewritten and enhanced by
<a href="https://notrademark.de">msquare</a> (maintainer),
<a href="https://myigel.name">MyIgel</a>,
<a href="https://mortzu.de">mortzu</a>,
<a href="https://jplitza.de">jplitza</a> and
<a href="https://github.com/gnomus">gnomus</a>.
</p>
<p>
Please look at the <a href="https://github.com/engelsystem/engelsystem/graphs/contributors">
contributor list on github</a> for a more complete version.
</p>
</div>
<div class="col-md-4">
<h2>Hosting</h2>
<p>
Webspace, development platform and domain on <a href="https://engelsystem.de">engelsystem.de</a>
is currently provided by <a href="https://www.wybt.net/">would you buy this?</a> (ichdasich)
and adminstrated by <a href="https://mortzu.de">mortzu</a>,
<a href="http://derf.homelinux.org">derf</a> and ichdasich.
</p>
</div>
<div class="col-md-4">
<h2>Translation</h2>
<p>
Many thanks for the german translation: <a href="http://e7p.de">e7p</a>
</p>
</div>
</div>
</div>

View File

@ -0,0 +1,42 @@
{% extends "layouts/app.twig" %}
{% block title %}{{ __('Credits') }}{% endblock %}
{% block content %}
<div class="container">
<h1>Credits</h1>
<div class="row">
<div class="col-md-4">
<h2>Source code</h2>
<p>
The original system was written by <a href="https://github.com/cookieBerlin/engelsystem">cookie</a>.
It was then completely rewritten and enhanced by
<a href="https://notrademark.de">msquare</a> (maintainer),
<a href="https://myigel.name">MyIgel</a>,
<a href="https://mortzu.de">mortzu</a>,
<a href="https://jplitza.de">jplitza</a> and
<a href="https://github.com/gnomus">gnomus</a>.
</p>
<p>
Please look at the <a href="https://github.com/engelsystem/engelsystem/graphs/contributors">
contributor list on github</a> for a more complete version.
</p>
</div>
<div class="col-md-4">
<h2>Hosting</h2>
<p>
Webspace, development platform and domain on <a href="https://engelsystem.de">engelsystem.de</a>
is currently provided by <a href="https://www.wybt.net/">would you buy this?</a> (ichdasich)
and adminstrated by <a href="https://mortzu.de">mortzu</a>,
<a href="http://derf.homelinux.org">derf</a> and ichdasich.
</p>
</div>
<div class="col-md-4">
<h2>Translation</h2>
<p>
Many thanks for the german translation: <a href="http://e7p.de">e7p</a>
</p>
</div>
</div>
</div>
{% endblock %}

View File

@ -0,0 +1,28 @@
<?php
namespace Unit\Controllers;
use Engelsystem\Controllers\CreditsController;
use Engelsystem\Http\Response;
use PHPUnit\Framework\MockObject\MockObject;
use PHPUnit\Framework\TestCase;
class CreditsControllerTest extends TestCase
{
/**
* @covers \Engelsystem\Controllers\CreditsController::__construct
* @covers \Engelsystem\Controllers\CreditsController::index
*/
public function testIndex()
{
/** @var Response|MockObject $response */
$response = $this->createMock(Response::class);
$response->expects($this->once())
->method('withView')
->with('pages/credits.twig');
$controller = new CreditsController($response);
$controller->index();
}
}

View File

@ -38,15 +38,12 @@ class RequestHandlerTest extends TestCase
public function testProcess() public function testProcess()
{ {
/** @var Application|MockObject $container */ /** @var Application|MockObject $container */
$container = $this->createMock(Application::class);
/** @var ServerRequestInterface|MockObject $request */ /** @var ServerRequestInterface|MockObject $request */
$request = $this->getMockForAbstractClass(ServerRequestInterface::class);
/** @var RequestHandlerInterface|MockObject $handler */ /** @var RequestHandlerInterface|MockObject $handler */
$handler = $this->getMockForAbstractClass(RequestHandlerInterface::class);
/** @var ResponseInterface|MockObject $response */ /** @var ResponseInterface|MockObject $response */
$response = $this->getMockForAbstractClass(ResponseInterface::class); /** @var MiddlewareInterface|MockObject $middlewareInterface */
list($container, $request, $handler, $response, $middlewareInterface) = $this->getMocks();
$middlewareInterface = $this->getMockForAbstractClass(MiddlewareInterface::class);
$requestHandlerInterface = $this->getMockForAbstractClass(RequestHandlerInterface::class); $requestHandlerInterface = $this->getMockForAbstractClass(RequestHandlerInterface::class);
$request->expects($this->exactly(3)) $request->expects($this->exactly(3))
@ -57,10 +54,10 @@ class RequestHandlerTest extends TestCase
/** @var RequestHandler|MockObject $middleware */ /** @var RequestHandler|MockObject $middleware */
$middleware = $this->getMockBuilder(RequestHandler::class) $middleware = $this->getMockBuilder(RequestHandler::class)
->setConstructorArgs([$container]) ->setConstructorArgs([$container])
->setMethods(['resolveMiddleware']) ->setMethods(['resolveRequestHandler'])
->getMock(); ->getMock();
$middleware->expects($this->exactly(3)) $middleware->expects($this->exactly(3))
->method('resolveMiddleware') ->method('resolveRequestHandler')
->with('FooBarClass') ->with('FooBarClass')
->willReturnOnConsecutiveCalls( ->willReturnOnConsecutiveCalls(
$middlewareInterface, $middlewareInterface,
@ -86,4 +83,70 @@ class RequestHandlerTest extends TestCase
$this->expectException(InvalidArgumentException::class); $this->expectException(InvalidArgumentException::class);
$middleware->process($request, $handler); $middleware->process($request, $handler);
} }
/**
* @covers \Engelsystem\Middleware\RequestHandler::resolveRequestHandler
*/
public function testResolveRequestHandler()
{
/** @var Application|MockObject $container */
/** @var ServerRequestInterface|MockObject $request */
/** @var RequestHandlerInterface|MockObject $handler */
/** @var ResponseInterface|MockObject $response */
/** @var MiddlewareInterface|MockObject $middlewareInterface */
list($container, $request, $handler, $response, $middlewareInterface) = $this->getMocks();
$className = 'Engelsystem\\Controllers\\FooBarTestController';
$request->expects($this->exactly(1))
->method('getAttribute')
->with('route-request-handler')
->willReturn('FooBarTestController@showStuff');
/** @var RequestHandler|MockObject $middleware */
$middleware = $this->getMockBuilder(RequestHandler::class)
->setConstructorArgs([$container])
->setMethods(['resolveMiddleware'])
->getMock();
$middleware->expects($this->once())
->method('resolveMiddleware')
->with([$middlewareInterface, 'showStuff'])
->willReturn($middlewareInterface);
$middlewareInterface->expects($this->once())
->method('process')
->with($request, $handler)
->willReturn($response);
$container->expects($this->exactly(2))
->method('has')
->withConsecutive(['FooBarTestController'], [$className])
->willReturnOnConsecutiveCalls(false, true);
$container->expects($this->once())
->method('make')
->with($className)
->willReturn($middlewareInterface);
$return = $middleware->process($request, $handler);
$this->assertEquals($return, $response);
}
/**
* @return array
*/
protected function getMocks(): array
{
/** @var Application|MockObject $container */
$container = $this->createMock(Application::class);
/** @var ServerRequestInterface|MockObject $request */
$request = $this->getMockForAbstractClass(ServerRequestInterface::class);
/** @var RequestHandlerInterface|MockObject $handler */
$handler = $this->getMockForAbstractClass(RequestHandlerInterface::class);
/** @var ResponseInterface|MockObject $response */
$response = $this->getMockForAbstractClass(ResponseInterface::class);
/** @var MiddlewareInterface $middlewareInterface */
$middlewareInterface = $this->getMockForAbstractClass(MiddlewareInterface::class);
return array($container, $request, $handler, $response, $middlewareInterface);
}
} }