-
Notifications
You must be signed in to change notification settings - Fork 13
/
PresenterMiddleware.php
85 lines (75 loc) · 2.7 KB
/
PresenterMiddleware.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
<?php
declare(strict_types=1);
namespace Shoot\Shoot\Middleware;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\ContainerInterface;
use Shoot\Shoot\Context;
use Shoot\Shoot\HasPresenterInterface;
use Shoot\Shoot\MiddlewareInterface;
use Shoot\Shoot\PresentationModel;
use Shoot\Shoot\PresenterInterface;
use Shoot\Shoot\View;
/**
* Resolves presenters as defined by presentation models using a PSR-11 compliant DI container. If the model does not
* contain data, the presenter is invoked to update the model.
*/
final class PresenterMiddleware implements MiddlewareInterface
{
/** @var ContainerInterface */
private $container;
/**
* @param ContainerInterface $container A PSR-11 compliant DI container holding the presenters.
*/
public function __construct(ContainerInterface $container)
{
$this->container = $container;
}
/**
* @param View $view The view to be processed by this middleware.
* @param Context $context The context in which to process the view.
* @param callable $next The next middleware to call
*
* @throws ContainerExceptionInterface
*
* @return View The processed view.
*/
public function process(View $view, Context $context, callable $next): View
{
$presentationModel = $view->getPresentationModel();
if ($presentationModel instanceof HasPresenterInterface && !$this->hasData($presentationModel)) {
$presenter = $this->loadPresenter($presentationModel);
$presentationModel = $presenter->present($context, $presentationModel);
$view = $view->withPresentationModel($presentationModel);
}
return $next($view);
}
/**
* Load the presenter from the container.
*
* @param HasPresenterInterface $hasPresenter A presentation model which has a presenter defined.
*
* @throws ContainerExceptionInterface
*
* @return PresenterInterface The presenter as returned by the container.
*/
private function loadPresenter(HasPresenterInterface $hasPresenter): PresenterInterface
{
return $this->container->get($hasPresenter->getPresenter());
}
/**
* Determine whether the presentation model already holds data.
*
* @param PresentationModel $presentationModel The presentation model for which to determine whether it holds data.
*
* @return bool Whether the presentation model already holds data.
*/
private function hasData(PresentationModel $presentationModel): bool
{
foreach ($presentationModel->getVariables() as $value) {
if (!empty($value)) {
return true;
}
}
return false;
}
}