1
|
|
|
<?php |
2
|
|
|
declare(strict_types=1); |
3
|
|
|
|
4
|
|
|
/** |
5
|
|
|
* Selami Application |
6
|
|
|
* |
7
|
|
|
* @link https://github.com/selamiphp/core |
8
|
|
|
* @license https://github.com/selamiphp/core/blob/master/LICENSE (MIT License) |
9
|
|
|
*/ |
10
|
|
|
|
11
|
|
|
|
12
|
|
|
namespace Selami\Core; |
13
|
|
|
|
14
|
|
|
use Selami\Router; |
15
|
|
|
use Psr\Container\ContainerInterface; |
16
|
|
|
use Psr\Http\Message\ServerRequestInterface; |
17
|
|
|
use Psr\Http\Message\ResponseInterface; |
18
|
|
|
use Symfony\Component\HttpFoundation\Session\Session as SymfonySession; |
19
|
|
|
use Selami\Http\Psr7Response; |
20
|
|
|
use Zend\Config\Config as ZendConfig; |
21
|
|
|
|
22
|
|
|
|
23
|
|
|
class App |
24
|
|
|
{ |
25
|
|
|
|
26
|
|
|
/* |
|
|
|
|
27
|
|
|
private $config = [ |
28
|
|
|
'base_dir' => null, |
29
|
|
|
'app_dir' => '/var/lib/www/app', |
30
|
|
|
'app_data_dir' => '/tmp', |
31
|
|
|
'base_url' => null, |
32
|
|
|
'app_namespace' => 'SelamiApp', |
33
|
|
|
'app_name' => 'www', |
34
|
|
|
'default_return_type' => 'html', |
35
|
|
|
'template_engine' => 'Twig', |
36
|
|
|
'bypass_error_handlers' => true, |
37
|
|
|
'aliases' => [] |
38
|
|
|
]; |
39
|
|
|
*/ |
40
|
|
|
|
41
|
|
|
private $container; |
42
|
|
|
private $config; |
43
|
|
|
/** |
44
|
|
|
* ServerRequest |
45
|
|
|
* |
46
|
|
|
* @var ServerRequestInterface |
47
|
|
|
*/ |
48
|
|
|
private $request; |
49
|
|
|
private $route; |
50
|
|
|
private $session; |
51
|
|
|
private $response; |
52
|
|
|
|
53
|
|
|
public function __construct( |
54
|
|
|
ZendConfig $config, |
55
|
|
|
ServerRequestInterface $request, |
56
|
|
|
Router $router, |
57
|
|
|
SymfonySession $session, |
58
|
|
|
ContainerInterface $container |
59
|
|
|
) { |
60
|
|
|
|
61
|
|
|
$this->request = $request; |
62
|
|
|
$this->config = $config; |
63
|
|
|
$this->route = $router->getRoute(); |
64
|
|
|
$this->session = $session; |
65
|
|
|
$this->container = $container; |
66
|
|
|
} |
67
|
|
|
|
68
|
|
|
public static function selamiApplicationFactory(ContainerInterface $container) : App |
69
|
|
|
{ |
70
|
|
|
return new App( |
71
|
|
|
$container->get(ZendConfig::class), |
72
|
|
|
$container->get(ServerRequestInterface::class), |
73
|
|
|
$container->get(Router::class), |
74
|
|
|
$container->get(SymfonySession::class), |
75
|
|
|
$container |
76
|
|
|
); |
77
|
|
|
} |
78
|
|
|
|
79
|
|
|
public function __invoke( |
80
|
|
|
ServerRequestInterface $request, |
81
|
|
|
ResponseInterface $response, |
82
|
|
|
callable $next = null |
83
|
|
|
) : ResponseInterface { |
84
|
|
|
$this->request = $request; |
85
|
|
|
$this->run(); |
86
|
|
|
$psr7Response = new Psr7Response; |
87
|
|
|
$response = $psr7Response($response, $this->response); |
88
|
|
|
if ($next !== null) { |
89
|
|
|
$response = $next($request, $response); |
90
|
|
|
} |
91
|
|
|
return $response; |
92
|
|
|
} |
93
|
|
|
|
94
|
|
|
private function run() : void |
95
|
|
|
{ |
96
|
|
|
$this->startSession(); |
97
|
|
|
$this->runDispatcher($this->route['route']); |
98
|
|
|
} |
99
|
|
|
|
100
|
|
|
private function startSession() :void |
101
|
|
|
{ |
102
|
|
|
ini_set('session.use_cookies', '1'); |
103
|
|
|
ini_set('session.use_only_cookies', '1'); |
104
|
|
|
ini_set('session.cookie_httponly', '1'); |
105
|
|
|
ini_set('session.name', 'SELAMISESSID'); |
106
|
|
|
if (!$this->session->isStarted()) { |
107
|
|
|
$this->session->start(); |
108
|
|
|
} |
109
|
|
|
} |
110
|
|
|
|
111
|
|
|
private function runDispatcher(array $route) : void |
112
|
|
|
{ |
113
|
|
|
$this->response = new Result($this->container, $this->session); |
114
|
|
|
$defaultReturnType = $this->config->app->get('default_return_type', 'html'); |
115
|
|
|
switch ($route['status']) { |
116
|
|
|
case 405: |
117
|
|
|
$this->response->notFound(405, $defaultReturnType, 'Method Not Allowed'); |
118
|
|
|
break; |
119
|
|
|
case 200: |
120
|
|
|
$this->runRoute($route['controller'], $route['returnType'], $route['args']); |
121
|
|
|
break; |
122
|
|
|
case 404: |
123
|
|
|
default: |
124
|
|
|
$this->response->notFound(404, $defaultReturnType, 'Not Found'); |
125
|
|
|
break; |
126
|
|
|
} |
127
|
|
|
} |
128
|
|
|
|
129
|
|
|
private function runRoute(string $controller, string $returnType = 'html', ?array $args) : void |
130
|
|
|
{ |
131
|
|
|
if (!class_exists($controller)) { |
132
|
|
|
$message = "Controller has not class name as {$controller}"; |
133
|
|
|
throw new \BadMethodCallException($message); |
134
|
|
|
} |
135
|
|
|
$controllerInstance = new $controller($this->container, $args); |
136
|
|
|
if (method_exists($controllerInstance, 'applicationLoad')) { |
137
|
|
|
$controllerInstance->applicationLoad(); |
138
|
|
|
} |
139
|
|
|
if (method_exists($controllerInstance, 'controllerLoad')) { |
140
|
|
|
$controllerInstance->controllerLoad(); |
141
|
|
|
} |
142
|
|
|
$functionOutput = $controllerInstance(); |
143
|
|
|
|
144
|
|
|
$returnFunction = 'return' . ucfirst($returnType); |
145
|
|
|
$this->response->$returnFunction($functionOutput, $controller); |
146
|
|
|
} |
147
|
|
|
|
148
|
|
|
public function getResponse() : array |
149
|
|
|
{ |
150
|
|
|
$this->run(); |
151
|
|
|
return $this->response->getResponse(); |
152
|
|
|
} |
153
|
|
|
|
154
|
|
|
public function sendResponse() : void |
155
|
|
|
{ |
156
|
|
|
$this->run(); |
157
|
|
|
$this->response->sendResponse(); |
158
|
|
|
} |
159
|
|
|
} |
160
|
|
|
|
Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.
The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.
This check looks for comments that seem to be mostly valid code and reports them.