Completed
Pull Request — master (#19)
by Flo
02:37
created

AbstractController   A

Complexity

Total Complexity 16

Size/Duplication

Total Lines 223
Duplicated Lines 7.17 %

Coupling/Cohesion

Components 2
Dependencies 8

Importance

Changes 0
Metric Value
wmc 16
lcom 2
cbo 8
dl 16
loc 223
rs 10
c 0
b 0
f 0

13 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 4 1
A getServiceLocator() 0 4 1
A getSessionManager() 0 4 1
A redirect() 0 6 1
A getRequest() 0 4 1
A getView() 0 15 2
A getDb() 0 4 1
A render() 0 9 1
A isPermitted() 0 7 1
A setFlashMessage() 0 5 1
A getFlashMessage() 0 5 1
A route() 0 4 1
B __call() 16 33 3

How to fix   Duplicated Code   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

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\Helper\Route;
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
        return (new Route())($this->getView(), $name, $parameters, $absolute);
194
    }
195
196
    /**
197
     * Return the current request object
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
     *
212
     * @return AbstractPlugin
213
     * @throws PluginException
214
     *
215
     * @codeCoverageIgnore Not implemented yet
216
     */
217
    public function __call($name, $arguments)
218
    {
219
        // Search in core view helpers first
220
        $corePlugin = 'Faulancer\Plugin\\' . ucfirst($name);
221
222 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...
223
224
            $class = new $corePlugin;
225
            array_unshift($arguments, $this);
226
227
            return call_user_func_array($class, $arguments);
228
229
        }
230
231
        // No core implementations found; search in custom view helpers
232
233
        /** @var Config $config */
234
        $config = ServiceLocator::instance()->get(Config::class);
235
        $namespace = '\\' . $config->get('namespacePrefix');
236
237
        $customPlugin = $namespace . '\Plugin\\' . ucfirst($name);
238
239 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...
240
241
            $class = new $customPlugin;
242
            array_unshift($arguments, $this);
243
244
            return call_user_func_array($class, $arguments);
245
246
        }
247
248
        throw new PluginException('No plugin for "' . $name . '" found.');
249
    }
250
251
}