1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
namespace Faulancer\Controller; |
4
|
|
|
|
5
|
|
|
use Faulancer\Exception\PluginException; |
6
|
|
|
use Faulancer\Exception\RouteInvalidException; |
7
|
|
|
use Faulancer\Http\Request; |
8
|
|
|
use Faulancer\Http\Response; |
9
|
|
|
use Faulancer\Plugin\AbstractPlugin; |
10
|
|
|
use Faulancer\Service\AuthenticatorService; |
11
|
|
|
use Faulancer\Service\Config; |
12
|
|
|
use Faulancer\Service\DbService; |
13
|
|
|
use Faulancer\Service\HttpService; |
14
|
|
|
use Faulancer\Service\SessionManagerService; |
15
|
|
|
use Faulancer\ServiceLocator\ServiceInterface; |
16
|
|
|
use Faulancer\View\ViewController; |
17
|
|
|
use Faulancer\ServiceLocator\ServiceLocator; |
18
|
|
|
|
19
|
|
|
/** |
20
|
|
|
* Class AbstractController |
21
|
|
|
* |
22
|
|
|
* @category Controller |
23
|
|
|
* @package Faulancer\AbstractController |
24
|
|
|
* @author Florian Knapp <[email protected]> |
25
|
|
|
* @license MIT License |
26
|
|
|
* @link none |
27
|
|
|
*/ |
28
|
|
|
abstract class AbstractController |
29
|
|
|
{ |
30
|
|
|
|
31
|
|
|
/** |
32
|
|
|
* Holds the views per controller request |
33
|
|
|
* |
34
|
|
|
* @var array |
35
|
|
|
*/ |
36
|
|
|
private $_viewArray = []; |
37
|
|
|
|
38
|
|
|
/** |
39
|
|
|
* Holds the request |
40
|
|
|
* |
41
|
|
|
* @var Request |
42
|
|
|
*/ |
43
|
|
|
protected $request; |
44
|
|
|
|
45
|
|
|
/** |
46
|
|
|
* AbstractController constructor. |
47
|
|
|
* |
48
|
|
|
* @param Request $request The request object |
49
|
|
|
*/ |
50
|
|
|
public function __construct(Request $request) |
51
|
|
|
{ |
52
|
|
|
$this->request = $request; |
53
|
|
|
} |
54
|
|
|
|
55
|
|
|
/** |
56
|
|
|
* Returns the service locator |
57
|
|
|
* |
58
|
|
|
* @return ServiceLocator |
59
|
|
|
*/ |
60
|
|
|
public function getServiceLocator() :ServiceLocator |
61
|
|
|
{ |
62
|
|
|
return ServiceLocator::instance(); |
63
|
|
|
} |
64
|
|
|
|
65
|
|
|
/** |
66
|
|
|
* Returns the session manager |
67
|
|
|
* |
68
|
|
|
* @return SessionManagerService|ServiceInterface |
69
|
|
|
*/ |
70
|
|
|
public function getSessionManager() :SessionManagerService |
71
|
|
|
{ |
72
|
|
|
return $this->getServiceLocator()->get(SessionManagerService::class); |
73
|
|
|
} |
74
|
|
|
|
75
|
|
|
/** |
76
|
|
|
* Returns the view controller |
77
|
|
|
* |
78
|
|
|
* @return ViewController |
79
|
|
|
*/ |
80
|
|
|
public function getView() :ViewController |
81
|
|
|
{ |
82
|
|
|
$calledClass = get_called_class(); |
83
|
|
|
|
84
|
|
|
if (in_array($calledClass, array_keys($this->_viewArray), true)) { |
85
|
|
|
return $this->_viewArray[$calledClass]; |
86
|
|
|
} |
87
|
|
|
|
88
|
|
|
$viewController = new ViewController(); |
89
|
|
|
|
90
|
|
|
$this->_viewArray[$calledClass] = $viewController; |
91
|
|
|
|
92
|
|
|
return $viewController; |
93
|
|
|
|
94
|
|
|
} |
95
|
|
|
|
96
|
|
|
/** |
97
|
|
|
* Returns the orm/entity manager |
98
|
|
|
* |
99
|
|
|
* @return DbService|ServiceInterface |
100
|
|
|
*/ |
101
|
|
|
public function getDb() :DbService |
102
|
|
|
{ |
103
|
|
|
return $this->getServiceLocator()->get(DbService::class); |
104
|
|
|
} |
105
|
|
|
|
106
|
|
|
/** |
107
|
|
|
* Render view with given template |
108
|
|
|
* |
109
|
|
|
* @param string $template The template to be rendered |
110
|
|
|
* @param array $variables The variables for the template |
111
|
|
|
* |
112
|
|
|
* @return Response |
113
|
|
|
*/ |
114
|
|
|
public function render(string $template = '', $variables = []) :Response |
115
|
|
|
{ |
116
|
|
|
return new Response( |
117
|
|
|
$this->getView() |
118
|
|
|
->setTemplate($template) |
119
|
|
|
->setVariables($variables) |
120
|
|
|
->render() |
121
|
|
|
); |
122
|
|
|
} |
123
|
|
|
|
124
|
|
|
/** |
125
|
|
|
* Check if user is permitted based on his role(s) |
126
|
|
|
* |
127
|
|
|
* @param array $roles The corresponding user roles |
128
|
|
|
* |
129
|
|
|
* @return bool|null |
130
|
|
|
*/ |
131
|
|
|
public function isPermitted($roles = []) |
132
|
|
|
{ |
133
|
|
|
/** @var AuthenticatorService $authService */ |
134
|
|
|
$authService = $this->getServiceLocator()->get(AuthenticatorService::class); |
135
|
|
|
|
136
|
|
|
return $authService->isPermitted($roles); |
137
|
|
|
} |
138
|
|
|
|
139
|
|
|
/** |
140
|
|
|
* Redirect to specific uri |
141
|
|
|
* |
142
|
|
|
* @param string $uri The target uri |
143
|
|
|
* |
144
|
|
|
* @return bool |
145
|
|
|
*/ |
146
|
|
|
public function redirect(string $uri) :bool |
147
|
|
|
{ |
148
|
|
|
/** @var HttpService $httpService */ |
149
|
|
|
$httpService = $this->getServiceLocator()->get(HttpService::class); |
150
|
|
|
return $httpService->redirect($uri); |
151
|
|
|
} |
152
|
|
|
|
153
|
|
|
/** |
154
|
|
|
* Set a universal text token which is valid for exactly one request/call |
155
|
|
|
* |
156
|
|
|
* @param string $key Key for the flash message |
157
|
|
|
* @param string $message Content for the flash message |
158
|
|
|
* |
159
|
|
|
* @return void |
160
|
|
|
*/ |
161
|
|
|
public function setFlashMessage(string $key, string $message) |
162
|
|
|
{ |
163
|
|
|
$sessionManager = $this->getSessionManager(); |
164
|
|
|
$sessionManager->setFlashMessage($key, $message); |
165
|
|
|
} |
166
|
|
|
|
167
|
|
|
/** |
168
|
|
|
* Retrieve a flash message |
169
|
|
|
* |
170
|
|
|
* @param string $key The flash message key |
171
|
|
|
* |
172
|
|
|
* @return string|null |
173
|
|
|
*/ |
174
|
|
|
public function getFlashMessage(string $key) |
175
|
|
|
{ |
176
|
|
|
$sessionManager = $this->getSessionManager(); |
177
|
|
|
return $sessionManager->getFlashMessage($key); |
178
|
|
|
} |
179
|
|
|
|
180
|
|
|
/** |
181
|
|
|
* Get the url for a specific route name |
182
|
|
|
* |
183
|
|
|
* @param string $name Name of the route |
184
|
|
|
* @param array $parameters Apply parameters where necessary |
185
|
|
|
* @param bool $absolute Return an absolute url with host as prefix |
186
|
|
|
* |
187
|
|
|
* @return string |
188
|
|
|
* @throws RouteInvalidException |
189
|
|
|
*/ |
190
|
|
|
public function route(string $name, array $parameters = [], $absolute = false) |
191
|
|
|
{ |
192
|
|
|
/** @var Config $config */ |
193
|
|
|
$config = $this->getServiceLocator()->get(Config::class); |
194
|
|
|
$routes = $config->get('routes'); |
195
|
|
|
|
196
|
|
View Code Duplication |
foreach ($routes as $routeName => $routeConfig) { |
|
|
|
|
197
|
|
|
|
198
|
|
|
if ($routeName === $name) { |
199
|
|
|
$path = preg_replace('|/\((.*)\)|', '', $routeConfig['path']); |
200
|
|
|
break; |
201
|
|
|
} |
202
|
|
|
|
203
|
|
|
} |
204
|
|
|
|
205
|
|
|
if (empty($path)) { |
206
|
|
|
throw new RouteInvalidException( |
207
|
|
|
'No route for name "' . $name . '" found' |
208
|
|
|
); |
209
|
|
|
} |
210
|
|
|
|
211
|
|
|
if (!empty($parameters)) { |
212
|
|
|
$path = $path . '/' . implode('/', $parameters); |
213
|
|
|
} |
214
|
|
|
|
215
|
|
|
if ($absolute) { |
216
|
|
|
|
217
|
|
|
$path = $this->getRequest()->getScheme() |
218
|
|
|
. $this->getRequest()->getHost() |
219
|
|
|
. $path; |
220
|
|
|
|
221
|
|
|
} |
222
|
|
|
|
223
|
|
|
return $path; |
224
|
|
|
} |
225
|
|
|
|
226
|
|
|
/** |
227
|
|
|
* Return the current request object |
228
|
|
|
* |
229
|
|
|
* @return Request |
230
|
|
|
*/ |
231
|
|
|
public function getRequest() :Request |
232
|
|
|
{ |
233
|
|
|
return $this->request; |
234
|
|
|
} |
235
|
|
|
|
236
|
|
|
/** |
237
|
|
|
* Magic method for providing a view helper |
238
|
|
|
* |
239
|
|
|
* @param string $name The class name |
240
|
|
|
* @param array $arguments Arguments if given |
241
|
|
|
* |
242
|
|
|
* @return AbstractPlugin |
243
|
|
|
* @throws PluginException |
244
|
|
|
* |
245
|
|
|
* @codeCoverageIgnore Not implemented yet |
246
|
|
|
*/ |
247
|
|
View Code Duplication |
public function __call($name, $arguments) |
|
|
|
|
248
|
|
|
{ |
249
|
|
|
// Search in core view helpers first |
250
|
|
|
$corePlugin = 'Faulancer\Plugin\\' . ucfirst($name); |
251
|
|
|
|
252
|
|
|
if (class_exists($corePlugin)) { |
253
|
|
|
|
254
|
|
|
$class = new $corePlugin; |
255
|
|
|
array_unshift($arguments, $this); |
256
|
|
|
|
257
|
|
|
return call_user_func_array($class, $arguments); |
258
|
|
|
|
259
|
|
|
} |
260
|
|
|
|
261
|
|
|
// No core implementations found; search in custom view helpers |
262
|
|
|
|
263
|
|
|
/** @var Config $config */ |
264
|
|
|
$config = ServiceLocator::instance()->get(Config::class); |
265
|
|
|
$namespace = '\\' . $config->get('namespacePrefix'); |
266
|
|
|
|
267
|
|
|
$customPlugin = $namespace . '\Plugin\\' . ucfirst($name); |
268
|
|
|
|
269
|
|
|
if (class_exists($customPlugin)) { |
270
|
|
|
|
271
|
|
|
$class = new $customPlugin; |
272
|
|
|
array_unshift($arguments, $this); |
273
|
|
|
|
274
|
|
|
return call_user_func_array($class, $arguments); |
275
|
|
|
|
276
|
|
|
} |
277
|
|
|
|
278
|
|
|
throw new PluginException('No plugin for "' . $name . '" found.'); |
279
|
|
|
} |
280
|
|
|
|
281
|
|
|
} |
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.