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 | /** |
||
4 | * |
||
5 | * This file is part of the Apix Project. |
||
6 | * |
||
7 | * (c) Franck Cassedanne <franck at ouarz.net> |
||
8 | * |
||
9 | * @license http://opensource.org/licenses/BSD-3-Clause New BSD License |
||
10 | * |
||
11 | */ |
||
12 | |||
13 | namespace Apix; |
||
14 | |||
15 | use Apix\Listener, |
||
16 | Apix\Config, |
||
17 | Apix\Resources, |
||
18 | Apix\Request, |
||
19 | Apix\HttpRequest, |
||
20 | Apix\Response, |
||
21 | Apix\Service; |
||
22 | |||
23 | // Apix\Router |
||
24 | |||
25 | class Main extends Listener |
||
26 | { |
||
27 | const VERSION = '@package_version@'; |
||
28 | |||
29 | /** |
||
30 | * @todo review this. |
||
31 | * @var array |
||
32 | */ |
||
33 | public $config = array(); |
||
34 | |||
35 | /** |
||
36 | * @var Request |
||
37 | */ |
||
38 | public $request = null; |
||
39 | |||
40 | /** |
||
41 | * @var Route |
||
42 | */ |
||
43 | public $route = null; |
||
44 | |||
45 | /** |
||
46 | * @var Resources |
||
47 | */ |
||
48 | public $resources = null; |
||
49 | |||
50 | /** |
||
51 | * @var Entity |
||
52 | */ |
||
53 | public $entity = null; |
||
54 | |||
55 | /** |
||
56 | * @var Response |
||
57 | */ |
||
58 | public $response = null; |
||
59 | |||
60 | /** |
||
61 | * Constructor. |
||
62 | * |
||
63 | * @return void |
||
0 ignored issues
–
show
|
|||
64 | */ |
||
65 | public function __construct( |
||
66 | $config=null, Request $request=null, Response $response=null |
||
67 | ) { |
||
68 | |||
69 | // Set and intialise the config |
||
70 | $c = $config instanceof Config ? $config : Config::getInstance($config); |
||
71 | $this->config = $c->get(); |
||
0 ignored issues
–
show
It seems like
$c->get() of type * is incompatible with the declared type array of property $config .
Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property. Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property.. ![]() |
|||
72 | |||
73 | $this->initSet($this->config); |
||
74 | |||
75 | // Load all the plugins |
||
76 | // $this->loadPlugins($c->get('plugins')); |
||
0 ignored issues
–
show
Unused Code
Comprehensibility
introduced
by
77% of this comment could be valid code. Did you maybe forget this after debugging?
Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it. The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production. This check looks for comments that seem to be mostly valid code and reports them. ![]() |
|||
77 | $this->loadPlugins($this->config['plugins']); |
||
78 | |||
79 | // Set the current request |
||
80 | $this->request = null === $request |
||
81 | ? new HttpRequest() |
||
82 | : $request; |
||
83 | |||
84 | if ($this->request instanceof HttpRequest) { |
||
85 | $this->request->setFormats($this->config['input_formats']); |
||
86 | } |
||
87 | |||
88 | // Initialise the response |
||
89 | $this->response = null === $response |
||
90 | ? new Response($this->request) |
||
91 | : $response; |
||
92 | |||
93 | $this->response->setFormats($this->config['routing']['formats']); |
||
94 | |||
95 | // Add all the resources from config. |
||
96 | $this->resources = new Resources(); |
||
97 | foreach ($c->getResources() as $key => $values) { |
||
98 | $this->resources->add( |
||
99 | $key, $values |
||
100 | ); |
||
101 | } |
||
102 | |||
103 | // Set some generic services |
||
104 | Service::set('config', $this->config); |
||
105 | Service::set('response', $this->response); |
||
106 | Service::set('request', $this->request); |
||
107 | Service::set('server', $this); |
||
108 | } |
||
109 | |||
110 | /** |
||
111 | * Deals with PHP inits and error handlers. |
||
112 | * |
||
113 | * @param array $configs The config entries to initialise. |
||
114 | * @return void |
||
115 | * @codeCoverageIgnore |
||
116 | */ |
||
117 | private function initSet(array $configs) |
||
118 | { |
||
119 | if ( !defined('UNIT_TEST') && isset($configs['init']) ) { |
||
120 | // set config inits |
||
121 | foreach ($configs['init'] as $key => $value) { |
||
122 | ini_set($key, $value); |
||
123 | } |
||
124 | } |
||
125 | |||
126 | // set the generic errors & exception handlers |
||
127 | set_error_handler(array('Apix\Exception', 'errorHandler'), E_ALL); |
||
128 | register_shutdown_function(array('Apix\Exception', 'shutdownHandler')); |
||
129 | } |
||
130 | |||
131 | /** |
||
132 | * Run the show... |
||
133 | * |
||
134 | * @throws \InvalidArgumentException 404 |
||
135 | * @codeCoverageIgnore |
||
136 | */ |
||
137 | public function run() |
||
138 | { |
||
139 | try { |
||
140 | // set the routing |
||
141 | $this->setRouting( |
||
142 | $this->request, |
||
143 | $this->resources->toArray(), |
||
144 | $this->config['routing'] |
||
145 | ); |
||
146 | |||
147 | // early listeners @ pre-server |
||
148 | $this->hook('server', 'early'); |
||
149 | |||
150 | // get the entity object from a route |
||
151 | $this->entity = $this->resources->get($this->route); |
||
152 | |||
153 | // set the results -- TODO: create a Response results obj |
||
154 | $this->results = $this->entity->call(); |
||
0 ignored issues
–
show
The property
results does not exist. Did you maybe forget to declare it?
In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code: class MyClass { }
$x = new MyClass();
$x->foo = true;
Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion: class MyClass {
public $foo;
}
$x = new MyClass();
$x->foo = true;
![]() |
|||
155 | |||
156 | } catch (\Exception $e) { |
||
157 | $http_code = $e->getCode()>199 ? $e->getCode() : 500; |
||
158 | $this->response->setHttpCode($http_code); |
||
159 | |||
160 | $error = array( |
||
161 | 'message' => $e->getMessage(), |
||
162 | 'code' => $http_code, |
||
163 | ); |
||
164 | |||
165 | if (DEBUG) { |
||
166 | $error['exception'] = Exception::toArray($e); |
||
167 | } |
||
168 | |||
169 | // set the error controller! |
||
170 | if ( |
||
171 | !in_array( |
||
172 | $this->route->getController(), |
||
173 | array_keys($this->resources->toArray()) |
||
174 | ) |
||
175 | ) { |
||
176 | $this->route->setController('error'); |
||
177 | |||
178 | $this->results = $error; |
||
179 | } |
||
180 | |||
181 | // listeners @ server exception stage |
||
182 | $this->hook('server', 'exception'); |
||
183 | } |
||
184 | |||
185 | switch ($this->response->getHttpCode()) { |
||
186 | case 401; |
||
0 ignored issues
–
show
case statements should be defined using a colon.
As per the PSR-2 coding standard, case statements should not be wrapped in curly braces.
There is no need for braces, since each case is terminated by the next There is also the option to use a semicolon instead of a colon, this is discouraged because many programmers do not even know it works and the colon is universal between programming languages. switch ($expr) {
case "A": { //wrong
doSomething();
break;
}
case "B"; //wrong
doSomething();
break;
case "C": //right
doSomething();
break;
}
To learn more about the PSR-2 coding standard, please refer to the PHP-Fig. ![]() |
|||
187 | // $this->response->setHeader('WWW-Authenticate', |
||
0 ignored issues
–
show
Unused Code
Comprehensibility
introduced
by
67% of this comment could be valid code. Did you maybe forget this after debugging?
Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it. The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production. This check looks for comments that seem to be mostly valid code and reports them. ![]() |
|||
188 | // sprintf( '%s realm="%s"', |
||
0 ignored issues
–
show
Unused Code
Comprehensibility
introduced
by
50% of this comment could be valid code. Did you maybe forget this after debugging?
Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it. The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production. This check looks for comments that seem to be mostly valid code and reports them. ![]() |
|||
189 | // $this->config['auth']['type'], |
||
0 ignored issues
–
show
Unused Code
Comprehensibility
introduced
by
82% of this comment could be valid code. Did you maybe forget this after debugging?
Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it. The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production. This check looks for comments that seem to be mostly valid code and reports them. ![]() |
|||
190 | // $this->config['org'] |
||
0 ignored issues
–
show
Unused Code
Comprehensibility
introduced
by
72% of this comment could be valid code. Did you maybe forget this after debugging?
Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it. The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production. This check looks for comments that seem to be mostly valid code and reports them. ![]() |
|||
191 | // ) |
||
192 | // ); |
||
193 | break; |
||
194 | |||
195 | case 405: |
||
196 | $this->response->setHeader('Allow', |
||
197 | implode(', ', array_keys( |
||
198 | $this->entity->getAllActions() |
||
199 | )), |
||
200 | false // preserve existing |
||
201 | ); |
||
202 | |||
203 | } |
||
204 | |||
205 | $this->response->generate( |
||
206 | $this->results, |
||
207 | $this->getServerVersion($this->config), |
||
208 | $this->config['output_rootNode'] |
||
209 | ); |
||
210 | |||
211 | // late listeners @ post-server |
||
212 | $this->hook('server', 'late'); |
||
213 | |||
214 | return $this->request->getMethod() == 'HEAD' |
||
215 | ? null |
||
216 | : $this->response->getOutput(); |
||
217 | } |
||
218 | |||
219 | /** |
||
220 | * Gets the server version string. |
||
221 | * |
||
222 | * @return string |
||
223 | */ |
||
224 | public function getServerVersion(array $config) |
||
225 | { |
||
226 | return sprintf('%s/%s (%s)', |
||
227 | $config['api_realm'], |
||
228 | $config['api_version'], |
||
229 | Server::VERSION |
||
230 | ); |
||
231 | } |
||
232 | |||
233 | /** |
||
234 | * Sets and initialise the routing processes. |
||
235 | * |
||
236 | * @param Request $request |
||
237 | * |
||
238 | * @return void |
||
239 | */ |
||
240 | public function setRouting( |
||
241 | Request $request, array $resources, array $opts=null |
||
242 | ) { |
||
243 | $path = isset($opts['path_prefix']) |
||
244 | ? preg_replace($opts['path_prefix'], '', $request->getUri()) |
||
245 | : $request->getUri(); |
||
246 | |||
247 | if ($path == '') { |
||
248 | $path = '/'; |
||
249 | } |
||
250 | |||
251 | // check allow_extension |
||
252 | if ($opts['allow_extension']) { |
||
253 | $info = pathinfo($path); |
||
254 | |||
255 | // use the first path entry to extratc the extension |
||
256 | // if ($opts['allow_extension']) { |
||
0 ignored issues
–
show
Unused Code
Comprehensibility
introduced
by
73% of this comment could be valid code. Did you maybe forget this after debugging?
Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it. The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production. This check looks for comments that seem to be mostly valid code and reports them. ![]() |
|||
257 | // $parts = explode('/', $path); |
||
0 ignored issues
–
show
Unused Code
Comprehensibility
introduced
by
54% of this comment could be valid code. Did you maybe forget this after debugging?
Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it. The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production. This check looks for comments that seem to be mostly valid code and reports them. ![]() |
|||
258 | // $info = pathinfo(isset($parts[1]) ? $parts[1] : $parts[0] ); |
||
0 ignored issues
–
show
Unused Code
Comprehensibility
introduced
by
68% of this comment could be valid code. Did you maybe forget this after debugging?
Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it. The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production. This check looks for comments that seem to be mostly valid code and reports them. ![]() |
|||
259 | // } |
||
260 | |||
261 | $ext = isset($info['extension']) ? $info['extension'] : null; |
||
262 | if ($ext) { |
||
263 | $path = preg_replace('/\.' . $ext . '/', '', $path, 1); |
||
264 | } |
||
265 | $rawController = $info['filename']; |
||
266 | } |
||
267 | |||
268 | $this->route = new Router( |
||
0 ignored issues
–
show
It seems like
new \Apix\Router($resour...h, 'server' => &$this)) of type object<Apix\Router> is incompatible with the declared type object<Apix\Route> of property $route .
Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property. Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property.. ![]() |
|||
269 | $resources, |
||
270 | array( |
||
271 | 'method' => $request->getMethod(), |
||
272 | 'path' => $path, |
||
273 | 'server' => & $this // so the resources can cross ref server. |
||
274 | ) |
||
275 | ); |
||
276 | $this->response->setRoute($this->route); |
||
277 | |||
278 | // Set the response format... |
||
279 | if (null !== $opts) { |
||
280 | $this->negotiateFormat($opts, isset($ext) ? $ext : false); |
||
281 | } |
||
282 | |||
283 | $this->route->map($path, $request->getParams()); |
||
284 | |||
285 | if (isset($rawController)) { |
||
286 | $this->route->setController($rawController); |
||
287 | } |
||
288 | } |
||
289 | |||
290 | /** |
||
291 | * Returns the route object. |
||
292 | * |
||
293 | * @return Router |
||
294 | */ |
||
295 | public function getRoute() |
||
296 | { |
||
297 | return $this->route; |
||
298 | } |
||
299 | |||
300 | /** |
||
301 | * Returns the response object. |
||
302 | * |
||
303 | * @return Response |
||
304 | */ |
||
305 | public function getResponse() |
||
306 | { |
||
307 | return $this->response; |
||
308 | } |
||
309 | |||
310 | /** |
||
311 | * Returns the output format from the request chain. |
||
312 | * |
||
313 | * @param array $opts Options are: |
||
314 | * - [default] => string e.g. 'json', |
||
315 | * - [allow_extension] => boolean, |
||
316 | * - [override] => false or $_REQUEST['format'], |
||
317 | * - [http_accept] => boolean. |
||
318 | * @param string|false $ext The contoller defined extension. |
||
319 | * |
||
320 | * @return string |
||
321 | */ |
||
322 | public function negotiateFormat(array $opts, $ext=false) |
||
323 | { |
||
324 | switch (true) { |
||
325 | case $opts['allow_extension'] |
||
326 | && $format = $ext: |
||
327 | break; |
||
328 | |||
329 | case false !== $opts['format_override'] |
||
330 | && $format = $opts['format_override']: |
||
331 | break; |
||
332 | |||
333 | case $opts['http_accept'] |
||
334 | && $format = $this->request->getAcceptFormat(): |
||
0 ignored issues
–
show
It seems like you code against a specific sub-type and not the parent class
Apix\Request as the method getAcceptFormat() does only exist in the following sub-classes of Apix\Request : Apix\HttpRequest . Maybe you want to instanceof check for one of these explicitly?
Let’s take a look at an example: abstract class User
{
/** @return string */
abstract public function getPassword();
}
class MyUser extends User
{
public function getPassword()
{
// return something
}
public function getDisplayName()
{
// return some name.
}
}
class AuthSystem
{
public function authenticate(User $user)
{
$this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
// do something.
}
}
In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different sub-classes of User which does not have a getDisplayName() method, the code will break. Available Fixes
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types
inside the if block in such a case.
![]() |
|||
335 | break; |
||
336 | |||
337 | default: |
||
338 | $format = $opts['default_format']; |
||
339 | } |
||
340 | |||
341 | $this->response->setFormat($format, $opts['default_format']); |
||
0 ignored issues
–
show
The variable
$format 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
![]() |
|||
342 | |||
343 | if ($opts['http_accept']) { |
||
344 | $this->response->setHeader('Vary', 'Accept'); |
||
345 | } |
||
346 | } |
||
347 | |||
348 | } |
||
349 |
Adding a
@return
annotation to a constructor is not recommended, since a constructor does not have a meaningful return value.Please refer to the PHP core documentation on constructors.