Completed
Push — master ( 3d068e...ac9ede )
by Park Jong-Hun
03:17
created

Application::getRoutePathMap()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 7
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 7
rs 9.4285
cc 1
eloc 4
nc 1
nop 0
1
<?php
2
3
namespace Core;
4
5
use Prob\Handler\ParameterMap;
6
use Prob\Router\Dispatcher;
7
use Prob\Rewrite\Request;
8
use Prob\Router\Map;
9
use Prob\Router\Matcher;
10
use Doctrine\ORM\Tools\Setup;
11
use Doctrine\ORM\EntityManager;
12
13
class Application
14
{
15
    /**
16
     * @var Map
17
     */
18
    private $routerMap;
19
20
    private $routeConfig = [];
21
    private $siteConfig = [];
22
    private $viewEngineConfig = [];
23
    private $dbConfig = [];
24
25
    /**
26
     * Singleton: private constructor
27
     */
28
    private function __construct()
29
    {
30
    }
31
32
    /**
33
     * @return Application
34
     */
35
    public static function getInstance()
36
    {
37
        static $instance = null;
38
39
        if ($instance === null) {
40
            $instance = new self();
41
        }
42
43
        return $instance;
44
    }
45
46
    public function boot()
47
    {
48
        $this->setDisplayError();
49
50
        $this->setSiteConfig(require '../config/site.php');
51
        $this->setDbConfig(require '../config/db.php');
52
        $this->setViewEngineConfig(require '../config/viewEngine.php');
53
        $this->setRouterConfig(require '../config/router.php');
54
55
        $this->dispatcher(new Request());
56
    }
57
58
    public function setDisplayError($isDisplay = true)
59
    {
60
        error_reporting(E_ALL);
61
        ini_set('display_errors', $isDisplay);
62
    }
63
64
    public function setRouterConfig(array $routeConfig)
65
    {
66
        $this->routeConfig = $routeConfig;
67
        $this->buildRouterMap();
68
    }
69
70
    public function setSiteConfig(array $siteConfig)
71
    {
72
        $this->siteConfig = $siteConfig;
73
    }
74
75
    public function setDbConfig(array $dbConfig)
76
    {
77
        $this->dbConfig = $dbConfig;
78
    }
79
80
    public function setViewEngineConfig(array $viewEngineConfig)
81
    {
82
        $this->viewEngineConfig = $viewEngineConfig;
83
    }
84
85
    private function buildRouterMap()
86
    {
87
        $routerMap = new Map();
88
        $routerMap->setNamespace($this->routeConfig['namespace']);
89
90
        foreach ($this->getRoutePathMap() as $k => $v) {
91
            $this->addRouterMap($routerMap, $k, $v);
92
        }
93
94
        $this->routerMap = $routerMap;
95
    }
96
97
    private function getRoutePathMap()
98
    {
99
        $paths = $this->routeConfig;
100
        unset($paths['namespace']);
101
102
        return $paths;
103
    }
104
105
    /**
106
     * @param Map    $routerMap
107
     * @param string $path  url path
108
     * @param string|array|closure $handler
109
     */
110
    private function addRouterMap(Map $routerMap, $path, $handler)
111
    {
112
        // string | closure
113
        if (gettype($handler) === 'string' || is_callable($handler)) {
114
            $routerMap->get($path, $handler);
115
            return;
116
        }
117
118
        /**
119
         * $handler array schema
120
         * (optional) $handler['GET' | 'POST']
121
         *                => method_name(ex. 'classname.methodname')
122
         *                    or function_name
123
         *                    or closure
124
         */
125
        if (isset($handler['GET'])) {
126
            $routerMap->get($path, $handler['GET']);
127
        }
128
        if (isset($handler['POST'])) {
129
            $routerMap->post($path, $handler['POST']);
130
        }
131
    }
132
133
134
    public function url($url = '')
135
    {
136
        return $this->siteConfig['url'] . $url;
137
    }
138
139
    /**
140
     * @return EntityManager
141
     */
142
    public function getEntityManager()
143
    {
144
        $config = Setup::createAnnotationMetadataConfiguration(
145
                    $this->dbConfig['entityPath'],
146
                    $this->dbConfig['devMode']
147
                    );
148
        return EntityManager::create($this->dbConfig[$this->siteConfig['database']], $config);
149
    }
150
151
    public function dispatcher(Request $request)
152
    {
153
        $url = $this->resolveUrl($request);
154
        $viewModel = new ViewModel();
155
156
        $parameterMap = new ParameterMap();
157
        $this->bindUrlParameter($parameterMap, $url);
158
        $this->bindViewModelParameter($parameterMap, $viewModel);
159
160
        $returnOfController = $this->executeController($request, $parameterMap);
161
162
        $view = $this->resolveView($returnOfController);
163
        $this->setViewVariables($view, $viewModel->getVariables());
164
        $view->render();
165
    }
166
167
    private function resolveUrl(Request $request)
168
    {
169
        $matcher = new Matcher($this->routerMap);
170
        return $matcher->match($request)['urlNameMatching'] ?: [];
171
    }
172
173
    private function executeController(Request $request, ParameterMap $parameterMap)
174
    {
175
        $dispatcher = new Dispatcher($this->routerMap);
176
        return $dispatcher->dispatch($request, $parameterMap);
177
    }
178
179
    /**
180
     * @param  mixed $returnOfController
181
     * @return View
182
     */
183
    private function resolveView($returnOfController)
184
    {
185
        $viewResolver = new ViewResolver($returnOfController);
186
        return $viewResolver->resolve($this->viewEngineConfig[$this->siteConfig['viewEngine']]);
187
    }
188
189
    private function bindUrlParameter(ParameterMap $map, array $url)
190
    {
191
        $map->bindByNameWithType('array', 'url', $url);
192
193
        foreach ($url as $name => $value) {
194
            $map->bindByName($name, $value);
195
        }
196
    }
197
198
    private function bindViewModelParameter(ParameterMap $map, ViewModel $viewModel)
199
    {
200
        $map->bindByType(ViewModel::class, $viewModel);
201
    }
202
203
    private function setViewVariables(View $view, array $var)
204
    {
205
        foreach ($var as $key => $value) {
206
            $view->set($key, $value);
207
        }
208
    }
209
}
210