DispatcherBootstrap::getDispatcher()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 10
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 10
rs 9.4285
cc 1
eloc 6
nc 1
nop 0
1
<?php
2
3
namespace App\Bootstrap;
4
5
use Core\Bootstrap\BootstrapInterface;
6
use Core\ControllerDispatcher\Dispatcher;
7
use Core\ControllerDispatcher\ViewRenderer;
8
use Core\ControllerDispatcher\RequestMatcher;
9
use Core\ControllerDispatcher\RouterMapBuilder;
10
use Core\ParameterWire;
11
use Core\Utils\ArrayUtils;
12
use Core\ViewModel;
13
use Zend\Diactoros\Uri;
14
use Zend\Diactoros\ServerRequestFactory;
15
use Prob\Handler\ParameterMap;
16
use Prob\Handler\Parameter\Typed;
17
18
class DispatcherBootstrap implements BootstrapInterface
19
{
20
    private $env = [];
21
22
    /**
23
     * @var ViewModel
24
     */
25
    private $viewModel;
26
27
    public function __construct()
28
    {
29
        $this->viewModel = new ViewModel();
30
    }
31
32
    public function boot(array $env)
33
    {
34
        $this->env = $env;
35
36
        RequestMatcher::setRequest($this->getServerRequest());
37
        RequestMatcher::setRouterMap($this->getRouterMap());
38
39
        $dispatcher = $this->getDispatcher();
40
        $viewRenderer = $this->getViewRenderer();
41
42
        $controllerResult = $this->getControllerResult($viewRenderer, $dispatcher->dispatch());
43
44
        echo $viewRenderer->renderView($controllerResult);
45
    }
46
47
    private function getControllerResult(ViewRenderer $viewRenderer, $controllerResult)
48
    {
49
        $viewClassName = get_class($viewRenderer->resolveView($controllerResult));
50
51
        if(array_search($viewClassName, $this->env['viewPrefix']['applyView']) === false) {
52
            return $controllerResult;
53
        }
54
55
        return $this->getViewPrefix() . $controllerResult;
56
    }
57
58
    private function getViewPrefix()
59
    {
60
        $prefix = $this->env['viewPrefix']['controller'];
61
        $defaultPrefix = $this->env['viewPrefix']['default'];
62
63
        $controllerName = RequestMatcher::getControllerProc()->getName();
64
65
        $matchedViewPrefixKey = ArrayUtils::find(array_keys($prefix), $controllerName);
66
67
        return $matchedViewPrefixKey ? $prefix[$matchedViewPrefixKey] : $defaultPrefix;
68
    }
69
70
    private function getDispatcher()
71
    {
72
        $dispatcher = new Dispatcher();
73
74
        $dispatcher->setRequest($this->getServerRequest());
75
        $dispatcher->setRouterMap($this->getRouterMap());
76
        $dispatcher->setParameterMap($this->getParameterMap());
77
78
        return $dispatcher;
79
    }
80
81
    private function getViewRenderer()
82
    {
83
        $viewRenderer = new ViewRenderer();
84
85
        $viewRenderer->setViewEngineConfig($this->env['viewEngine']);
86
        $viewRenderer->setViewResolver($this->env['viewResolver']);
87
        $viewRenderer->setViewModel($this->viewModel);
88
89
        return $viewRenderer;
90
    }
91
92
    private function getParameterMap()
93
    {
94
        $parameterMap = new ParameterMap();
95
        $parameterMap->bindBy(new Typed(ViewModel::class), $this->viewModel);
96
        return ParameterWire::injectParameter($parameterMap);
97
    }
98
99
    private function getServerRequest()
100
    {
101
        $request = $this->env['dispatcher']['request'];
102
103
        $stripedUri = new Uri(
104
            $this->stripAppUrlPrefix($request->getUri()->getPath())
105
        );
106
107
        return $request->withUri($stripedUri);
108
    }
109
110
    private function stripAppUrlPrefix($url)
111
    {
112
        $appUrl = $this->env['site']['url'];
113
114
        if (substr($url, 0, strlen($appUrl)) === $appUrl) {
115
            return '/' . substr($url, strlen($appUrl)) ?: '/';
116
        }
117
118
        return $url;
119
    }
120
121
    private function getRouterMap()
122
    {
123
        return (new RouterMapBuilder($this->env['router']))->build();
124
    }
125
}
126