Passed
Push — master ( 3b9db0...fc649a )
by Flo
03:08
created

Controller   A

Complexity

Total Complexity 16

Size/Duplication

Total Lines 200
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 8

Importance

Changes 0
Metric Value
wmc 16
lcom 1
cbo 8
dl 0
loc 200
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 getView() 0 15 2
A getDb() 0 4 1
A render() 0 23 3
A isPermitted() 0 7 1
A redirect() 0 6 1
A setFlashMessage() 0 5 1
A getFlashMessage() 0 5 1
A route() 0 4 1
A getRequest() 0 4 1
A addAssets() 0 3 1
1
<?php
2
3
namespace Faulancer\Controller;
4
5
use Faulancer\Exception\FileNotFoundException;
6
use Faulancer\Exception\InvalidArgumentException;
7
use Faulancer\Exception\ServiceNotFoundException;
8
use Faulancer\Http\Http;
9
use Faulancer\Http\Request;
10
use Faulancer\Http\Response;
11
use Faulancer\Service\AuthenticatorService;
12
use Faulancer\Service\DbService;
13
use Faulancer\Session\SessionManager;
14
use Faulancer\ServiceLocator\ServiceInterface;
15
use Faulancer\View\Helper\Route;
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
 */
26
class Controller
27
{
28
29
    /**
30
     * Holds the views per controller request
31
     *
32
     * @var array
33
     */
34
    private $_viewArray = [];
35
36
    /**
37
     * Holds the request
38
     *
39
     * @var Request
40
     */
41
    protected $request;
42
43
    /**
44
     * AbstractController constructor.
45
     *
46
     * @param Request $request The request object
47
     */
48
    public function __construct(Request $request)
49
    {
50
        $this->request = $request;
51
    }
52
53
    /**
54
     * Returns the service locator
55
     *
56
     * @return ServiceLocator
57
     */
58
    public function getServiceLocator() :ServiceLocator
59
    {
60
        return ServiceLocator::instance();
61
    }
62
63
    /**
64
     * Returns the session manager
65
     *
66
     * @return SessionManager|ServiceInterface
67
     */
68
    public function getSessionManager() :SessionManager
69
    {
70
        return $this->getServiceLocator()->get(SessionManager::class);
71
    }
72
73
    /**
74
     * Returns the view controller
75
     *
76
     * @return ViewController
77
     */
78
    public function getView() :ViewController
79
    {
80
        $calledClass = get_called_class();
81
82
        if (in_array($calledClass, array_keys($this->_viewArray), true)) {
83
            return $this->_viewArray[$calledClass];
84
        }
85
86
        $viewController = new ViewController();
87
88
        $this->_viewArray[$calledClass] = $viewController;
89
90
        return $viewController;
91
92
    }
93
94
    /**
95
     * Returns the orm/entity manager
96
     *
97
     * @return DbService|ServiceInterface
98
     */
99
    public function getDb() :DbService
100
    {
101
        return $this->getServiceLocator()->get(DbService::class);
102
    }
103
104
    /**
105
     * Render view with given template
106
     *
107
     * @param string $template  The template to be rendered
108
     * @param array  $variables The variables for the template
109
     *
110
     * @return Response
111
     */
112
    public function render(string $template = '', $variables = []) :Response
113
    {
114
        $this->addAssets();
115
116
        try {
117
118
            /** @var Response $response */
119
            $response = $this->getServiceLocator()->get(Response::class);
120
121
            $viewResult = $this->getView()
122
                ->setTemplate($template)
123
                ->setVariables($variables)
124
                ->render();
125
126
        } catch (FileNotFoundException $e) {
127
            $viewResult = $e->getMessage();
128
        } catch (ServiceNotFoundException $e) {
129
            $response   = new Response();
130
            $viewResult = $e->getMessage();
131
        }
132
133
        return $response->setContent($viewResult);
134
    }
135
136
    /**
137
     * Check if user is permitted based on his role(s)
138
     *
139
     * @param array $roles The corresponding user roles
140
     *
141
     * @return bool|null
142
     */
143
    public function isPermitted($roles = [])
144
    {
145
        /** @var AuthenticatorService $authService */
146
        $authService = $this->getServiceLocator()->get(AuthenticatorService::class);
147
148
        return $authService->isPermitted($roles);
149
    }
150
151
    /**
152
     * Redirect to specific uri
153
     *
154
     * @param string $uri The target uri
155
     *
156
     * @return bool
157
     *
158
     * @throws InvalidArgumentException
159
     */
160
    public function redirect(string $uri) :bool
161
    {
162
        /** @var Http $httpService */
163
        $httpService = $this->getServiceLocator()->get(Http::class);
164
        return $httpService->redirect($uri);
165
    }
166
167
    /**
168
     * Set a generic text token which is valid for exactly one call
169
     *
170
     * @param string $key     Key for the flash message
171
     * @param string $message Content for the flash message
172
     *
173
     * @return void
174
     */
175
    public function setFlashMessage(string $key, string $message)
176
    {
177
        $sessionManager = $this->getSessionManager();
178
        $sessionManager->setFlashMessage($key, $message);
0 ignored issues
show
Bug introduced by
The method setFlashMessage does only exist in Faulancer\Session\SessionManager, but not in Faulancer\ServiceLocator\ServiceInterface.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
179
    }
180
181
    /**
182
     * Retrieve a flash message
183
     *
184
     * @param string $key The flash message key
185
     *
186
     * @return string|null
187
     */
188
    public function getFlashMessage(string $key)
189
    {
190
        $sessionManager = $this->getSessionManager();
191
        return $sessionManager->getFlashMessage($key);
0 ignored issues
show
Bug introduced by
The method getFlashMessage does only exist in Faulancer\Session\SessionManager, but not in Faulancer\ServiceLocator\ServiceInterface.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
192
    }
193
194
    /**
195
     * Get the url for a specific route name
196
     *
197
     * @param string $name       Name of the route
198
     * @param array  $parameters Apply parameters where necessary
199
     * @param bool   $absolute   Return an absolute url with host as prefix
200
     *
201
     * @return string
202
     */
203
    public function route(string $name, array $parameters = [], $absolute = false)
204
    {
205
        return (new Route())($name, $parameters, $absolute);
206
    }
207
208
    /**
209
     * Return the current request object
210
     *
211
     * @return Request
212
     */
213
    public function getRequest() :Request
214
    {
215
        return $this->request;
216
    }
217
218
    /**
219
     * Add default assets for every action
220
     */
221
    protected function addAssets() {
222
        // Should be inherited by child classes
223
    }
224
225
}