Completed
Push — master ( a34111...b893df )
by Park Jong-Hun
14:20
created

ControllerDispatcher::getMatchedHandler()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 5
rs 9.4285
cc 1
eloc 3
nc 1
nop 1
1
<?php
2
3
namespace Core;
4
5
use Prob\Handler\Proc;
6
use Prob\Handler\ParameterMap;
7
use Prob\Router\Dispatcher;
8
use Prob\Rewrite\Request;
9
use Prob\Router\Matcher;
10
use Prob\Router\Map;
11
12
class ControllerDispatcher
13
{
14
15
    /**
16
     * @var Map
17
     */
18
    private $routerMap;
19
    private $routerConfig = [];
20
    private $viewEngineConfig = [];
21
22
    public function setRouterConfig(array $routerConfig)
23
    {
24
        $this->routerConfig = $routerConfig;
25
    }
26
27
    public function setViewEngineConfig(array $config)
28
    {
29
        $this->viewEngineConfig = $config;
30
    }
31
32
    public function dispatch(Request $request)
33
    {
34
        $this->buildRouterMap();
35
36
        $viewModel = new ViewModel();
37
        $parameterMap = $this->getControllerParameterMap($request, $viewModel);
38
39
        $returnOfController = $this->executeController($request, $parameterMap);
40
41
        $this->renderView($returnOfController, $viewModel);
42
    }
43
44
    private function buildRouterMap()
45
    {
46
        $builder = new RouterMapBuilder();
47
        $builder->setRouterConfig($this->routerConfig);
48
49
        $this->routerMap = $builder->build();
50
    }
51
52
    private function getControllerParameterMap(Request $request, ViewModel $viewModel)
53
    {
54
        $url = $this->resolveUrl($request);
55
56
        $parameterMap = new ParameterMap();
57
        $this->bindUrlParameter($parameterMap, $url);
58
        $this->bindViewModelParameter($parameterMap, $viewModel);
59
60
        return $parameterMap;
61
    }
62
63
    private function resolveUrl(Request $request)
64
    {
65
        $matcher = new Matcher($this->routerMap);
66
        return $matcher->match($request)['urlNameMatching'] ?: [];
67
    }
68
69
    private function bindUrlParameter(ParameterMap $map, array $url)
70
    {
71
        $map->bindByNameWithType('array', 'url', $url);
72
73
        foreach ($url as $name => $value) {
74
            $map->bindByName($name, $value);
75
        }
76
    }
77
78
    private function bindViewModelParameter(ParameterMap $map, ViewModel $viewModel)
79
    {
80
        $map->bindByType(ViewModel::class, $viewModel);
81
    }
82
83
84
    private function executeController(Request $request, ParameterMap $parameterMap)
85
    {
86
        $dispatcher = new Dispatcher($this->routerMap);
87
        $handlerResolvedName = $this->getMatchedHandler($request)->getResolvedName();
88
89
        $this->triggerEvent('Controller.' . $handlerResolvedName['class'] . '.' . $handlerResolvedName['func'] . '.before');
90
        $result = $dispatcher->dispatch($request, $parameterMap);
91
        $this->triggerEvent('Controller.' . $handlerResolvedName['class'] . '.' . $handlerResolvedName['func'] . '.after');
92
93
        return $result;
94
    }
95
96
    /**
97
     * @return Proc
98
     */
99
    private function getMatchedHandler(Request $request)
100
    {
101
        $matcher = new Matcher($this->routerMap);
102
        return $matcher->match($request)['handler'];
103
    }
104
105
    private function triggerEvent($eventName)
106
    {
107
        Application::getInstance()
108
            ->getEventManager()
109
                ->trigger($eventName);
110
    }
111
112
    private function renderView($returnOfController, ViewModel $viewModel)
113
    {
114
        $view = $this->resolveView($returnOfController);
115
116
        foreach ($viewModel->getVariables() as $key => $value) {
117
            $view->set($key, $value);
118
        }
119
120
        $view->render();
121
    }
122
123
    /**
124
     * @param  mixed $returnOfController
125
     * @return View
126
     */
127
    private function resolveView($returnOfController)
128
    {
129
        $viewResolver = new ViewResolver($returnOfController);
130
        return $viewResolver->resolve($this->viewEngineConfig);
131
    }
132
}
133