Completed
Pull Request — master (#19)
by Flo
05:47
created

AbstractController::render()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 9
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 9
rs 9.6666
c 0
b 0
f 0
cc 1
eloc 6
nc 1
nop 2
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\RequestService;
15
use Faulancer\Service\SessionManagerService;
16
use Faulancer\ServiceLocator\ServiceInterface;
17
use Faulancer\View\ViewController;
18
use Faulancer\ServiceLocator\ServiceLocator;
19
20
/**
21
 * Class AbstractController
22
 *
23
 * @category Controller
24
 * @package  Faulancer\AbstractController
25
 * @author   Florian Knapp <[email protected]>
26
 * @license  MIT License
27
 * @link     none
28
 */
29
abstract class AbstractController
30
{
31
32
    /**
33
     * Holds the views per controller request
34
     *
35
     * @var array
36
     */
37
    private $_viewArray = [];
38
39
    /**
40
     * Holds the request
41
     *
42
     * @var Request
43
     */
44
    protected $request;
45
46
    /**
47
     * AbstractController constructor.
48
     *
49
     * @param Request $request The request object
50
     */
51
    public function __construct(Request $request)
52
    {
53
        $this->request = $request;
54
    }
55
56
    /**
57
     * Returns the service locator
58
     *
59
     * @return ServiceLocator
60
     */
61
    public function getServiceLocator() :ServiceLocator
62
    {
63
        return ServiceLocator::instance();
64
    }
65
66
    /**
67
     * Returns the session manager
68
     *
69
     * @return SessionManagerService|ServiceInterface
70
     */
71
    public function getSessionManager() :SessionManagerService
72
    {
73
        return $this->getServiceLocator()->get(SessionManagerService::class);
74
    }
75
76
    /**
77
     * Returns the view controller
78
     *
79
     * @return ViewController
80
     */
81
    public function getView() :ViewController
82
    {
83
        $calledClass = get_called_class();
84
85
        if (in_array($calledClass, array_keys($this->_viewArray), true)) {
86
            return $this->_viewArray[$calledClass];
87
        }
88
89
        $viewController = new ViewController();
90
91
        $this->_viewArray[$calledClass] = $viewController;
92
93
        return $viewController;
94
95
    }
96
97
    /**
98
     * Returns the orm/entity manager
99
     *
100
     * @return DbService|ServiceInterface
101
     */
102
    public function getDb() :DbService
103
    {
104
        return $this->getServiceLocator()->get(DbService::class);
105
    }
106
107
    /**
108
     * Render view with given template
109
     *
110
     * @param string $template  The template to be rendered
111
     * @param array  $variables The variables for the template
112
     *
113
     * @return Response
114
     */
115
    public function render(string $template = '', $variables = []) :Response
116
    {
117
        return new Response(
118
            $this->getView()
119
                ->setTemplate($template)
120
                ->setVariables($variables)
121
                ->render()
122
        );
123
    }
124
125
    /**
126
     * Check if user is permitted based on his role(s)
127
     *
128
     * @param array $roles The corresponding user roles
129
     *
130
     * @return bool|null
131
     */
132
    public function isPermitted($roles = [])
133
    {
134
        /** @var AuthenticatorService $authService */
135
        $authService = $this->getServiceLocator()->get(AuthenticatorService::class);
136
137
        return $authService->isPermitted($roles);
138
    }
139
140
    /**
141
     * Redirect to specific uri
142
     *
143
     * @param string $uri The target uri
144
     *
145
     * @return bool
146
     */
147
    public function redirect(string $uri) :bool
148
    {
149
        /** @var HttpService $httpService */
150
        $httpService = $this->getServiceLocator()->get(HttpService::class);
151
        return $httpService->redirect($uri);
152
    }
153
154
    /**
155
     * Set a universal text token which is valid for exactly one request/call
156
     *
157
     * @param string $key     Key for the flash message
158
     * @param string $message Content for the flash message
159
     *
160
     * @return void
161
     */
162
    public function setFlashMessage(string $key, string $message)
163
    {
164
        $sessionManager = $this->getSessionManager();
165
        $sessionManager->setFlashMessage($key, $message);
166
    }
167
168
    /**
169
     * Retrieve a flash message
170
     *
171
     * @param string $key The flash message key
172
     *
173
     * @return string|null
174
     */
175
    public function getFlashMessage(string $key)
176
    {
177
        $sessionManager = $this->getSessionManager();
178
        return $sessionManager->getFlashMessage($key);
179
    }
180
181
    /**
182
     * Get the url for a specific route name
183
     *
184
     * @param string $name       Name of the route
185
     * @param array  $parameters Apply parameters where necessary
186
     * @param bool   $absolute   Return an absolute url with host as prefix
187
     *
188
     * @return string
189
     * @throws RouteInvalidException
190
     */
191
    public function route(string $name, array $parameters = [], $absolute = false)
192
    {
193
        /** @var Config $config */
194
        $config    = ServiceLocator::instance()->get(Config::class);
195
        $routes    = $config->get('routes');
196
        $apiRoutes = $config->get('routes:rest');
197
        $routes    = array_merge($routes, $apiRoutes);
198
        $path      = '';
199
200 View Code Duplication
        foreach ($routes as $routeName => $data) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

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.

Loading history...
201
202
            if ($routeName === $name) {
203
                $path = preg_replace('|/\((.*)\)|', '', $data['path']);
204
                break;
205
            }
206
207
        }
208
209
        if (empty($path)) {
210
211
            throw new RouteInvalidException(
212
                'No route for name "' . $name . '" found'
213
            );
214
215
        }
216
217 View Code Duplication
        if (!empty($parameters)) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

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.

Loading history...
218
219
            if (in_array('query', array_keys($parameters), true)) {
220
                $query = $parameters['query'];
221
                $query = http_build_query($query);
222
                $path  = $path . '?' . $query;
223
            } else {
224
                $path = $path . '/' . implode('/', $parameters);
225
            }
226
227
        }
228
229
        if ($absolute) {
230
231
            $path = $this->request->getScheme()
232
                . $this->request->getHost()
233
                . $path;
234
235
        }
236
237
        return $path;
238
    }
239
240
    /**
241
     * Return the current request object
242
     *
243
     * @return Request
244
     */
245
    public function getRequest() :Request
246
    {
247
        return $this->request;
248
    }
249
250
    /**
251
     * Magic method for providing a view helper
252
     *
253
     * @param string $name      The class name
254
     * @param array  $arguments Arguments if given
255
     *
256
     * @return AbstractPlugin
257
     * @throws PluginException
258
     *
259
     * @codeCoverageIgnore Not implemented yet
260
     */
261
    public function __call($name, $arguments)
262
    {
263
        // Search in core view helpers first
264
        $corePlugin = 'Faulancer\Plugin\\' . ucfirst($name);
265
266 View Code Duplication
        if (class_exists($corePlugin)) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

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.

Loading history...
267
268
            $class = new $corePlugin;
269
            array_unshift($arguments, $this);
270
271
            return call_user_func_array($class, $arguments);
272
273
        }
274
275
        // No core implementations found; search in custom view helpers
276
277
        /** @var Config $config */
278
        $config = ServiceLocator::instance()->get(Config::class);
279
        $namespace = '\\' . $config->get('namespacePrefix');
280
281
        $customPlugin = $namespace . '\Plugin\\' . ucfirst($name);
282
283 View Code Duplication
        if (class_exists($customPlugin)) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

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.

Loading history...
284
285
            $class = new $customPlugin;
286
            array_unshift($arguments, $this);
287
288
            return call_user_func_array($class, $arguments);
289
290
        }
291
292
        throw new PluginException('No plugin for "' . $name . '" found.');
293
    }
294
295
}