This project does not seem to handle request data directly as such no vulnerable execution paths were found.
include
, or for example
via PHP's auto-loading mechanism.
These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
1 | <?php |
||
2 | |||
3 | class Ajde_Controller extends Ajde_Object_Standard |
||
4 | { |
||
5 | /** |
||
6 | * @var Ajde_View |
||
7 | */ |
||
8 | protected $_view = null; |
||
9 | |||
10 | /** |
||
11 | * @var Ajde_Core_Route |
||
12 | */ |
||
13 | protected $_route = null; |
||
14 | |||
15 | public function __construct($action = null, $format = null) |
||
16 | { |
||
17 | $this->setModule(strtolower(str_replace('Controller', '', get_class($this)))); |
||
0 ignored issues
–
show
|
|||
18 | if (!isset($action) || !isset($format)) { |
||
19 | $defaultParts = config('routes.default'); |
||
20 | } |
||
21 | $this->setAction(isset($action) ? $action : $defaultParts['action']); |
||
0 ignored issues
–
show
The variable
$defaultParts does not seem to be defined for all execution paths leading up to this point.
If you define a variable conditionally, it can happen that it is not defined for all execution paths. Let’s take a look at an example: function myFunction($a) {
switch ($a) {
case 'foo':
$x = 1;
break;
case 'bar':
$x = 2;
break;
}
// $x is potentially undefined here.
echo $x;
}
In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined. Available Fixes
![]() The method
setAction does not exist on object<Ajde_Controller> ? Since you implemented __call , maybe consider adding a @method annotation.
If you implement This is often the case, when class ParentClass {
private $data = array();
public function __call($method, array $args) {
if (0 === strpos($method, 'get')) {
return $this->data[strtolower(substr($method, 3))];
}
throw new \LogicException(sprintf('Unsupported method: %s', $method));
}
}
/**
* If this class knows which fields exist, you can specify the methods here:
*
* @method string getName()
*/
class SomeClass extends ParentClass { }
![]() |
|||
22 | $this->setFormat(isset($format) ? $format : $defaultParts['format']); |
||
0 ignored issues
–
show
The method
setFormat does not exist on object<Ajde_Controller> ? Since you implemented __call , maybe consider adding a @method annotation.
If you implement This is often the case, when class ParentClass {
private $data = array();
public function __call($method, array $args) {
if (0 === strpos($method, 'get')) {
return $this->data[strtolower(substr($method, 3))];
}
throw new \LogicException(sprintf('Unsupported method: %s', $method));
}
}
/**
* If this class knows which fields exist, you can specify the methods here:
*
* @method string getName()
*/
class SomeClass extends ParentClass { }
![]() |
|||
23 | |||
24 | $route = new Ajde_Core_Route($this->getAction()); |
||
25 | $route->setFormat($this->getFormat()); |
||
0 ignored issues
–
show
The method
setFormat does not exist on object<Ajde_Core_Route> ? Since you implemented __call , maybe consider adding a @method annotation.
If you implement This is often the case, when class ParentClass {
private $data = array();
public function __call($method, array $args) {
if (0 === strpos($method, 'get')) {
return $this->data[strtolower(substr($method, 3))];
}
throw new \LogicException(sprintf('Unsupported method: %s', $method));
}
}
/**
* If this class knows which fields exist, you can specify the methods here:
*
* @method string getName()
*/
class SomeClass extends ParentClass { }
![]() |
|||
26 | $this->_route = $route; |
||
27 | } |
||
28 | |||
29 | public function __fallback($method, $arguments) |
||
30 | { |
||
31 | if (Ajde_Event::has('Ajde_Controller', 'call')) { |
||
32 | return Ajde_Event::trigger('Ajde_Controller', 'call', [$method, $arguments]); |
||
33 | } |
||
34 | throw new Ajde_Exception('Call to undefined method '.get_class($this)."::$method()", 90006); |
||
35 | } |
||
36 | |||
37 | public function getModule() |
||
38 | { |
||
39 | return $this->get('module'); |
||
40 | } |
||
41 | |||
42 | public function getAction() |
||
43 | { |
||
44 | return $this->get('action'); |
||
45 | } |
||
46 | |||
47 | public function getFormat() |
||
48 | { |
||
49 | return $this->get('format'); |
||
50 | } |
||
51 | |||
52 | public function getId() |
||
53 | { |
||
54 | return $this->get('id'); |
||
55 | } |
||
56 | |||
57 | public function getRoute() |
||
58 | { |
||
59 | return $this->_route; |
||
60 | } |
||
61 | |||
62 | public function getCanonicalUrl() |
||
63 | { |
||
64 | return $this->_route->buildRoute(); |
||
65 | } |
||
66 | |||
67 | /** |
||
68 | * @param Ajde_Core_Route $route |
||
69 | * |
||
70 | * @return Ajde_Controller |
||
71 | */ |
||
72 | public static function fromRoute(Ajde_Core_Route $route) |
||
73 | { |
||
74 | if ($controller = $route->getController()) { |
||
75 | $moduleController = ucfirst($route->getModule()).ucfirst($controller).'Controller'; |
||
76 | } else { |
||
77 | $moduleController = ucfirst($route->getModule()).'Controller'; |
||
78 | } |
||
79 | if (!class_exists($moduleController)) { |
||
80 | |||
81 | // Prevent resursive 404 routing |
||
82 | $errorRoutes = config('routes.errors'); |
||
83 | if (isset($errorRoutes[Ajde_Http_Response::RESPONSE_TYPE_NOTFOUND])) { |
||
84 | $notFoundRoute = new Ajde_Core_Route($errorRoutes[Ajde_Http_Response::RESPONSE_TYPE_NOTFOUND]); |
||
85 | if ($route->buildRoute() == $notFoundRoute->buildRoute()) { |
||
86 | Ajde_Http_Response::setResponseType(404); |
||
87 | die('<h2>Ouch, something broke.</h2><p>This is serious. We tried to give you a nice error page, but even that failed.</p><button onclick="location.href=\''.config('app.rootUrl').'\';">Go back to homepage</button>'); |
||
88 | } |
||
89 | } |
||
90 | |||
91 | if (class_exists('Ajde_Exception')) { |
||
92 | $exception = new Ajde_Core_Exception_Routing("Controller $moduleController for module {$route->getModule()} not found", |
||
93 | 90008); |
||
94 | } else { |
||
95 | // Normal exception here to prevent [Class 'Ajde_Exception' not found] errors... |
||
96 | $exception = new Exception("Controller $moduleController for module {$route->getModule()} not found"); |
||
97 | } |
||
98 | Ajde::routingError($exception); |
||
99 | } |
||
100 | $controller = new $moduleController($route->getAction(), $route->getFormat()); |
||
101 | $controller->_route = $route; |
||
102 | foreach ($route->values() as $part => $value) { |
||
103 | $controller->set($part, $value); |
||
104 | } |
||
105 | |||
106 | return $controller; |
||
107 | } |
||
108 | |||
109 | /** |
||
110 | * @param string|null $action |
||
111 | * @param string|null $format |
||
112 | * |
||
113 | * @throws Ajde_Exception |
||
114 | * @throws Exception |
||
115 | * |
||
116 | * @return mixed |
||
117 | */ |
||
118 | public function invoke($action = null, $format = null) |
||
119 | { |
||
120 | $timerKey = Ajde::app()->addTimer((string) $this->_route); |
||
121 | $action = issetor($action, $this->getAction()); |
||
0 ignored issues
–
show
Are you sure the assignment to
$action is correct as issetor($action, $this->getAction()) (which targets issetor() ) seems to always return null.
This check looks for function or method calls that always return null and whose return value is assigned to a variable. class A
{
function getObject()
{
return null;
}
}
$a = new A();
$object = $a->getObject();
The method The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes. ![]() |
|||
122 | $format = issetor($format, $this->getFormat()); |
||
0 ignored issues
–
show
Are you sure the assignment to
$format is correct as issetor($format, $this->getFormat()) (which targets issetor() ) seems to always return null.
This check looks for function or method calls that always return null and whose return value is assigned to a variable. class A
{
function getObject()
{
return null;
}
}
$a = new A();
$object = $a->getObject();
The method The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes. ![]() |
|||
123 | $method = strtolower($_SERVER['REQUEST_METHOD']); |
||
124 | |||
125 | $tryTheseFunctions = []; |
||
126 | |||
127 | $formatFunction = $action.ucfirst($format); |
||
128 | $defaultFunction = $action.'Default'; |
||
129 | $emptyFunction = $action; |
||
130 | |||
131 | $tryTheseFunctions[] = $formatFunction.ucfirst($method); |
||
132 | $tryTheseFunctions[] = $defaultFunction.ucfirst($method); |
||
133 | $tryTheseFunctions[] = $emptyFunction.ucfirst($method); |
||
134 | $tryTheseFunctions[] = $formatFunction; |
||
135 | $tryTheseFunctions[] = $defaultFunction; |
||
136 | $tryTheseFunctions[] = $emptyFunction; |
||
137 | |||
138 | $invokeFunction = ''; |
||
139 | |||
140 | foreach ($tryTheseFunctions as $tryFunction) { |
||
141 | if (method_exists($this, $tryFunction)) { |
||
142 | $invokeFunction = $tryFunction; |
||
143 | break; |
||
144 | } |
||
145 | } |
||
146 | // dump(get_class($this) . '::' . $invokeFunction); |
||
147 | |||
148 | if (!$invokeFunction) { |
||
0 ignored issues
–
show
The expression
$invokeFunction of type string|null is loosely compared to false ; this is ambiguous if the string can be empty. You might want to explicitly use === null instead.
In PHP, under loose comparison (like For '' == false // true
'' == null // true
'ab' == false // false
'ab' == null // false
// It is often better to use strict comparison
'' === false // false
'' === null // false
![]() |
|||
149 | $exception = new Ajde_Core_Exception_Routing(sprintf('Action %s for module %s not found', |
||
150 | $this->getAction(), |
||
151 | $this->getModule() |
||
152 | ), 90011); |
||
153 | Ajde::routingError($exception); |
||
154 | } |
||
155 | |||
156 | $return = true; |
||
157 | View Code Duplication | if (method_exists($this, 'beforeInvoke')) { |
|
0 ignored issues
–
show
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. ![]() |
|||
158 | $return = $this->beforeInvoke(); |
||
0 ignored issues
–
show
|
|||
159 | if ($return !== true && $return !== false) { |
||
160 | // TODO: |
||
161 | throw new Ajde_Exception(sprintf('beforeInvoke() must return either TRUE or FALSE')); |
||
162 | } |
||
163 | } |
||
164 | if ($return === true) { |
||
165 | $return = $this->$invokeFunction(); |
||
166 | if (method_exists($this, 'afterInvoke')) { |
||
167 | $this->afterInvoke(); |
||
0 ignored issues
–
show
|
|||
168 | } |
||
169 | } |
||
170 | Ajde::app()->endTimer($timerKey); |
||
171 | |||
172 | return $return; |
||
173 | } |
||
174 | |||
175 | /** |
||
176 | * @return Ajde_View |
||
177 | */ |
||
178 | public function getView() |
||
179 | { |
||
180 | if (!isset($this->_view)) { |
||
181 | $this->_view = Ajde_View::fromController($this); |
||
182 | } |
||
183 | |||
184 | return $this->_view; |
||
185 | } |
||
186 | |||
187 | /** |
||
188 | * @param Ajde_View $view |
||
189 | */ |
||
190 | public function setView(Ajde_View $view) |
||
191 | { |
||
192 | $this->_view = $view; |
||
193 | } |
||
194 | |||
195 | /** |
||
196 | * Shorthand for $controller->getView()->getContents();. |
||
197 | */ |
||
198 | public function render() |
||
199 | { |
||
200 | $return = true; |
||
201 | View Code Duplication | if (method_exists($this, 'beforeRender')) { |
|
0 ignored issues
–
show
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. ![]() |
|||
202 | $return = $this->beforeRender(); |
||
0 ignored issues
–
show
|
|||
203 | if ($return !== true && $return !== false) { |
||
204 | // TODO: |
||
205 | throw new Ajde_Exception(sprintf('beforeRender() must return either TRUE or FALSE')); |
||
206 | } |
||
207 | } |
||
208 | if ($return === true) { |
||
209 | return $this->getView()->getContents(); |
||
210 | } |
||
211 | } |
||
212 | |||
213 | public function loadTemplate() |
||
214 | { |
||
215 | throw new Ajde_Core_Exception_Deprecated(); |
||
216 | $view = Ajde_View::fromController($this); |
||
0 ignored issues
–
show
$view = \Ajde_View::fromController($this); does not seem to be reachable.
This check looks for unreachable code. It uses sophisticated control flow analysis techniques to find statements which will never be executed. Unreachable code is most often the result of function fx() {
try {
doSomething();
return true;
}
catch (\Exception $e) {
return false;
}
return false;
}
In the above example, the last ![]() |
|||
217 | |||
218 | return $view->getContents(); |
||
219 | } |
||
220 | |||
221 | public function redirect($route = Ajde_Http_Response::REDIRECT_SELF) |
||
222 | { |
||
223 | Ajde::app()->getResponse()->setRedirect($route); |
||
224 | } |
||
225 | |||
226 | public function rewrite($route) |
||
227 | { |
||
228 | Ajde::app()->getResponse()->dieOnRoute($route); |
||
229 | } |
||
230 | |||
231 | public function updateCache() |
||
232 | { |
||
233 | // TODO: |
||
234 | throw new Ajde_Core_Exception_Deprecated(); |
||
235 | } |
||
236 | |||
237 | /** |
||
238 | * @param Ajde_Model|Ajde_Collection $object |
||
239 | */ |
||
240 | public function touchCache($object = null) |
||
241 | { |
||
242 | Ajde_Cache::getInstance()->updateHash(isset($object) ? $object->hash() : time()); |
||
243 | } |
||
244 | } |
||
245 |
If you implement
__call
and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.This is often the case, when
__call
is implemented by a parent class and only the child class knows which methods exist: