1
|
|
|
<?php |
2
|
|
|
/** |
3
|
|
|
* Class AbstractController |
4
|
|
|
* |
5
|
|
|
* @package Faulancer\AbstractController |
6
|
|
|
* @author Florian Knapp <[email protected]> |
7
|
|
|
*/ |
8
|
|
|
namespace Faulancer\Controller; |
9
|
|
|
|
10
|
|
|
use Faulancer\Exception\PluginException; |
11
|
|
|
use Faulancer\Exception\RouteInvalidException; |
12
|
|
|
use Faulancer\Fixture\Entity\UserEntity; |
13
|
|
|
use Faulancer\Http\Request; |
14
|
|
|
use Faulancer\Http\Response; |
15
|
|
|
use Faulancer\Plugin\AbstractPlugin; |
16
|
|
|
use Faulancer\Service\AuthenticatorService; |
17
|
|
|
use Faulancer\Service\Config; |
18
|
|
|
use Faulancer\Service\DbService; |
19
|
|
|
use Faulancer\Service\HttpService; |
20
|
|
|
use Faulancer\Service\SessionManagerService; |
21
|
|
|
use Faulancer\ServiceLocator\ServiceInterface; |
22
|
|
|
use Faulancer\View\ViewController; |
23
|
|
|
use Faulancer\ServiceLocator\ServiceLocator; |
24
|
|
|
|
25
|
|
|
/** |
26
|
|
|
* Class AbstractController |
27
|
|
|
*/ |
28
|
|
|
abstract class AbstractController |
29
|
|
|
{ |
30
|
|
|
|
31
|
|
|
/** |
32
|
|
|
* Holds the views per controller request |
33
|
|
|
* @var array |
34
|
|
|
*/ |
35
|
|
|
private $viewArray = []; |
36
|
|
|
|
37
|
|
|
/** |
38
|
|
|
* @var Request |
39
|
|
|
*/ |
40
|
|
|
protected $request; |
41
|
|
|
|
42
|
|
|
/** |
43
|
|
|
* AbstractController constructor. |
44
|
|
|
* @param Request $request |
45
|
|
|
*/ |
46
|
|
|
public function __construct(Request $request) |
47
|
|
|
{ |
48
|
|
|
$this->request = $request; |
49
|
|
|
} |
50
|
|
|
|
51
|
|
|
/** |
52
|
|
|
* Returns the service locator |
53
|
|
|
* |
54
|
|
|
* @return ServiceLocator |
55
|
|
|
*/ |
56
|
|
|
public function getServiceLocator() :ServiceLocator |
57
|
|
|
{ |
58
|
|
|
return ServiceLocator::instance(); |
59
|
|
|
} |
60
|
|
|
|
61
|
|
|
/** |
62
|
|
|
* Returns the session manager |
63
|
|
|
* |
64
|
|
|
* @return SessionManagerService|ServiceInterface |
65
|
|
|
*/ |
66
|
|
|
public function getSessionManager() :SessionManagerService |
67
|
|
|
{ |
68
|
|
|
return $this->getServiceLocator()->get(SessionManagerService::class); |
69
|
|
|
} |
70
|
|
|
|
71
|
|
|
/** |
72
|
|
|
* Returns the view controller |
73
|
|
|
* |
74
|
|
|
* @return ViewController |
75
|
|
|
*/ |
76
|
|
|
public function getView() :ViewController |
77
|
|
|
{ |
78
|
|
|
$calledClass = get_called_class(); |
79
|
|
|
|
80
|
|
|
if (in_array($calledClass, array_keys($this->viewArray))) { |
81
|
|
|
return $this->viewArray[$calledClass]; |
82
|
|
|
} |
83
|
|
|
|
84
|
|
|
$viewController = new ViewController(); |
85
|
|
|
$this->viewArray[$calledClass] = $viewController; |
86
|
|
|
|
87
|
|
|
return $viewController; |
88
|
|
|
} |
89
|
|
|
|
90
|
|
|
/** |
91
|
|
|
* Returns the orm/entity manager |
92
|
|
|
* |
93
|
|
|
* @return DbService|ServiceInterface |
94
|
|
|
*/ |
95
|
|
|
public function getDb() :DbService |
96
|
|
|
{ |
97
|
|
|
return $this->getServiceLocator()->get(DbService::class); |
98
|
|
|
} |
99
|
|
|
|
100
|
|
|
/** |
101
|
|
|
* Render view with given template |
102
|
|
|
* |
103
|
|
|
* @param string $template |
104
|
|
|
* @param array $variables |
105
|
|
|
* @return Response |
106
|
|
|
*/ |
107
|
|
|
public function render(string $template = '', $variables = []) :Response |
108
|
|
|
{ |
109
|
|
|
return new Response($this->getView()->setTemplate($template)->setVariables($variables)->render()); |
110
|
|
|
} |
111
|
|
|
|
112
|
|
|
/** |
113
|
|
|
* @param array $roles |
114
|
|
|
* |
115
|
|
|
* @return bool |
116
|
|
|
*/ |
117
|
|
|
public function requireAuth($roles = []) |
118
|
|
|
{ |
119
|
|
|
/** @var AuthenticatorService $authService */ |
120
|
|
|
$authService = $this->getServiceLocator()->get(AuthenticatorService::class); |
121
|
|
|
|
122
|
|
|
if (!$authService->isAuthenticated($roles)) { |
123
|
|
|
return $authService->redirectToAuthentication(); |
124
|
|
|
} |
125
|
|
|
|
126
|
|
|
return true; |
127
|
|
|
} |
128
|
|
|
|
129
|
|
|
/** |
130
|
|
|
* @param string $uri |
131
|
|
|
* @return bool |
132
|
|
|
*/ |
133
|
|
|
public function redirect(string $uri) :bool |
134
|
|
|
{ |
135
|
|
|
/** @var HttpService $httpService */ |
136
|
|
|
$httpService = $this->getServiceLocator()->get(HttpService::class); |
137
|
|
|
return $httpService->redirect($uri); |
138
|
|
|
} |
139
|
|
|
|
140
|
|
|
/** |
141
|
|
|
* @param string $key |
142
|
|
|
* @param string $message |
143
|
|
|
*/ |
144
|
|
|
public function setFlashMessage(string $key, string $message) |
145
|
|
|
{ |
146
|
|
|
$sessionManager = $this->getSessionManager(); |
147
|
|
|
$sessionManager->setFlashMessage($key, $message); |
148
|
|
|
} |
149
|
|
|
|
150
|
|
|
/** |
151
|
|
|
* @param $key |
152
|
|
|
* @return string|null |
153
|
|
|
*/ |
154
|
|
|
public function getFlashMessage(string $key) |
155
|
|
|
{ |
156
|
|
|
$sessionManager = $this->getSessionManager(); |
157
|
|
|
return $sessionManager->getFlashMessage($key); |
158
|
|
|
} |
159
|
|
|
|
160
|
|
|
/** |
161
|
|
|
* @param string $name |
162
|
|
|
* @param array $parameters |
163
|
|
|
* @param bool $absolute |
164
|
|
|
* |
165
|
|
|
* @return string |
166
|
|
|
* @throws RouteInvalidException |
167
|
|
|
*/ |
168
|
|
|
public function route(string $name, array $parameters = [], $absolute = false) |
169
|
|
|
{ |
170
|
|
|
/** @var Config $config */ |
171
|
|
|
$config = $this->getServiceLocator()->get(Config::class); |
172
|
|
|
$routes = $config->get('routes'); |
173
|
|
|
|
174
|
|
View Code Duplication |
foreach ($routes as $routeName => $routeConfig) { |
|
|
|
|
175
|
|
|
|
176
|
|
|
if ($routeName === $name) { |
177
|
|
|
$path = preg_replace('|/\((.*)\)|', '', $routeConfig['path']); |
178
|
|
|
break; |
179
|
|
|
} |
180
|
|
|
|
181
|
|
|
} |
182
|
|
|
|
183
|
|
|
if (empty($path)) { |
184
|
|
|
throw new RouteInvalidException('No route for name "' . $name . '" found'); |
185
|
|
|
} |
186
|
|
|
|
187
|
|
|
if (!empty($parameters)) { |
188
|
|
|
$path = $path . '/' . implode('/', $parameters); |
189
|
|
|
} |
190
|
|
|
|
191
|
|
|
if ($absolute) { |
192
|
|
|
$path = $this->getRequest()->getScheme() . $this->getRequest()->getHost() . $path; |
193
|
|
|
} |
194
|
|
|
|
195
|
|
|
return $path; |
196
|
|
|
} |
197
|
|
|
|
198
|
|
|
/** |
199
|
|
|
* @return Request |
200
|
|
|
*/ |
201
|
|
|
public function getRequest() :Request |
202
|
|
|
{ |
203
|
|
|
return $this->request; |
204
|
|
|
} |
205
|
|
|
|
206
|
|
|
/** |
207
|
|
|
* Magic method for providing a view helper |
208
|
|
|
* |
209
|
|
|
* @param string $name The class name |
210
|
|
|
* @param array $arguments Arguments if given |
211
|
|
|
* @return AbstractPlugin |
212
|
|
|
* @throws PluginException |
213
|
|
|
*/ |
214
|
|
View Code Duplication |
public function __call($name, $arguments) |
|
|
|
|
215
|
|
|
{ |
216
|
|
|
// Search in core view helpers first |
217
|
|
|
$corePlugin = 'Faulancer\Plugin\\' . ucfirst($name); |
218
|
|
|
|
219
|
|
|
if (class_exists($corePlugin)) { |
220
|
|
|
|
221
|
|
|
$class = new $corePlugin; |
222
|
|
|
array_unshift($arguments, $this); |
223
|
|
|
|
224
|
|
|
return call_user_func_array($class, $arguments); |
225
|
|
|
|
226
|
|
|
} |
227
|
|
|
|
228
|
|
|
// No core implementations found; search in custom view helpers |
229
|
|
|
|
230
|
|
|
/** @var Config $config */ |
231
|
|
|
$config = ServiceLocator::instance()->get(Config::class); |
232
|
|
|
$namespace = '\\' . $config->get('namespacePrefix'); |
233
|
|
|
|
234
|
|
|
$customPlugin = $namespace . '\Plugin\\' . ucfirst($name); |
235
|
|
|
|
236
|
|
|
if (class_exists($customPlugin)) { |
237
|
|
|
|
238
|
|
|
$class = new $customPlugin; |
239
|
|
|
array_unshift($arguments, $this); |
240
|
|
|
|
241
|
|
|
return call_user_func_array($class, $arguments); |
242
|
|
|
|
243
|
|
|
} |
244
|
|
|
|
245
|
|
|
throw new PluginException('No plugin for "' . $name . '" found.'); |
246
|
|
|
} |
247
|
|
|
|
248
|
|
|
} |
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.