appserver-io /
routlt
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 | * AppserverIo\Routlt\ControllerServlet |
||
| 5 | * |
||
| 6 | * NOTICE OF LICENSE |
||
| 7 | * |
||
| 8 | * This source file is subject to the Open Software License (OSL 3.0) |
||
| 9 | * that is available through the world-wide-web at this URL: |
||
| 10 | * http://opensource.org/licenses/osl-3.0.php |
||
| 11 | * |
||
| 12 | * PHP version 5 |
||
| 13 | * |
||
| 14 | * @author Tim Wagner <[email protected]> |
||
| 15 | * @copyright 2015 TechDivision GmbH <[email protected]> |
||
| 16 | * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) |
||
| 17 | * @link http://github.com/appserver-io/routlt |
||
| 18 | * @link http://www.appserver.io |
||
| 19 | */ |
||
| 20 | |||
| 21 | namespace AppserverIo\Routlt; |
||
| 22 | |||
| 23 | use AppserverIo\Http\HttpProtocol; |
||
| 24 | use AppserverIo\Properties\Properties; |
||
| 25 | use AppserverIo\Psr\Di\ProviderInterface; |
||
| 26 | use AppserverIo\Psr\Di\ObjectManagerInterface; |
||
| 27 | use AppserverIo\Psr\Servlet\Http\HttpServlet; |
||
| 28 | use AppserverIo\Psr\Servlet\ServletException; |
||
| 29 | use AppserverIo\Psr\Servlet\ServletConfigInterface; |
||
| 30 | use AppserverIo\Psr\Servlet\ServletRequestInterface; |
||
| 31 | use AppserverIo\Psr\Servlet\ServletResponseInterface; |
||
| 32 | use AppserverIo\Routlt\Util\ContextKeys; |
||
| 33 | use AppserverIo\Routlt\Util\ActionAware; |
||
| 34 | use AppserverIo\Routlt\Util\ServletContextAware; |
||
| 35 | use AppserverIo\Routlt\Results\ResultInterface; |
||
| 36 | use AppserverIo\Routlt\Description\PathDescriptorInterface; |
||
| 37 | use AppserverIo\Routlt\Description\ResultDescriptorInterface; |
||
| 38 | use AppserverIo\Routlt\Util\DescriptorAware; |
||
| 39 | use AppserverIo\Routlt\Description\ResultConfigurationDescriptorInterface; |
||
| 40 | |||
| 41 | /** |
||
| 42 | * Abstract example implementation that provides some kind of basic MVC functionality |
||
| 43 | * to handle requests by subclasses action methods. |
||
| 44 | * |
||
| 45 | * @author Tim Wagner <[email protected]> |
||
| 46 | * @copyright 2015 TechDivision GmbH <[email protected]> |
||
| 47 | * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) |
||
| 48 | * @link http://github.com/appserver-io/routlt |
||
| 49 | * @link http://www.appserver.io |
||
| 50 | */ |
||
| 51 | class ControllerServlet extends HttpServlet implements ControllerInterface |
||
| 52 | { |
||
| 53 | |||
| 54 | /** |
||
| 55 | * The key for the init parameter with the action namespace. |
||
| 56 | * |
||
| 57 | * @var string |
||
| 58 | */ |
||
| 59 | const INIT_PARAMETER_ACTION_NAMESPACE = 'action.namespace'; |
||
| 60 | |||
| 61 | /** |
||
| 62 | * The key for the init parameter with the path to the configuration file. |
||
| 63 | * |
||
| 64 | * @var string |
||
| 65 | */ |
||
| 66 | const INIT_PARAMETER_ROUTLT_CONFIGURATION_FILE = 'routlt.configuration.file'; |
||
| 67 | |||
| 68 | /** |
||
| 69 | * The default action if no valid action name was found in the path info. |
||
| 70 | * |
||
| 71 | * @var string |
||
| 72 | */ |
||
| 73 | const DEFAULT_ROUTE = '/index'; |
||
| 74 | |||
| 75 | /** |
||
| 76 | * The array with the initialized routes. |
||
| 77 | * |
||
| 78 | * @var array |
||
| 79 | */ |
||
| 80 | protected $routes = array(); |
||
| 81 | |||
| 82 | /** |
||
| 83 | * The array with the path descriptors. |
||
| 84 | * |
||
| 85 | * @var array |
||
| 86 | */ |
||
| 87 | protected $paths = array(); |
||
| 88 | |||
| 89 | /** |
||
| 90 | * The array with request method action -> route mappings. |
||
| 91 | * |
||
| 92 | * @var array |
||
| 93 | */ |
||
| 94 | protected $actionMappings = array(); |
||
| 95 | |||
| 96 | /** |
||
| 97 | * Initializes the servlet with the passed configuration. |
||
| 98 | * |
||
| 99 | * @param \AppserverIo\Psr\Servlet\ServletConfigInterface $config The configuration to initialize the servlet with |
||
| 100 | * |
||
| 101 | * @return void |
||
| 102 | */ |
||
| 103 | 4 | public function init(ServletConfigInterface $config) |
|
| 104 | { |
||
| 105 | |||
| 106 | // call parent method |
||
| 107 | 4 | parent::init($config); |
|
| 108 | |||
| 109 | // load the values from the configuration file |
||
| 110 | 4 | $this->initConfiguration(); |
|
| 111 | |||
| 112 | // initialize the routing |
||
| 113 | 4 | $this->initRoutes(); |
|
| 114 | 4 | } |
|
| 115 | |||
| 116 | /** |
||
| 117 | * Returns the available routes. |
||
| 118 | * |
||
| 119 | * @return array The array with the available routes |
||
| 120 | */ |
||
| 121 | 2 | public function getRoutes() |
|
| 122 | { |
||
| 123 | 2 | return $this->routes; |
|
| 124 | } |
||
| 125 | |||
| 126 | /** |
||
| 127 | * Returns the array with request method action -> route mappings. |
||
| 128 | * |
||
| 129 | * @return array The request method action -> route mappings |
||
| 130 | */ |
||
| 131 | 1 | public function getActionMappings() |
|
| 132 | { |
||
| 133 | 1 | return $this->actionMappings; |
|
| 134 | } |
||
| 135 | |||
| 136 | /** |
||
| 137 | * Returns the naming directoy instance (the application). |
||
| 138 | * |
||
| 139 | * @return \AppserverIo\Psr\Naming\NamingDirectoryInterface The naming directory instance |
||
| 140 | */ |
||
| 141 | 1 | public function getNamingDirectory() |
|
| 142 | { |
||
| 143 | 1 | return $this->getServletContext()->getApplication(); |
|
|
0 ignored issues
–
show
|
|||
| 144 | } |
||
| 145 | |||
| 146 | /** |
||
| 147 | * Returns the object manager instance |
||
| 148 | * |
||
| 149 | * @return \AppserverIo\Psr\Di\ObjectManagerInterface The object manager instance |
||
| 150 | */ |
||
| 151 | 1 | public function getObjectManager() |
|
| 152 | { |
||
| 153 | 1 | return $this->getNamingDirectory()->search(ObjectManagerInterface::IDENTIFIER); |
|
| 154 | } |
||
| 155 | |||
| 156 | /** |
||
| 157 | * Returns the DI provider instance. |
||
| 158 | * |
||
| 159 | * @return \AppserverIo\Psr\Di\ProviderInterface The DI provider instance |
||
| 160 | */ |
||
| 161 | 1 | public function getProvider() |
|
| 162 | { |
||
| 163 | 1 | return $this->getNamingDirectory()->search(ProviderInterface::IDENTIFIER); |
|
| 164 | } |
||
| 165 | |||
| 166 | /** |
||
| 167 | * This method returns the default route we'll invoke if the path info doesn't contain one. |
||
| 168 | * |
||
| 169 | * @return string The default route |
||
| 170 | */ |
||
| 171 | 2 | public function getDefaultRoute() |
|
| 172 | { |
||
| 173 | 2 | return ControllerServlet::DEFAULT_ROUTE; |
|
| 174 | } |
||
| 175 | |||
| 176 | /** |
||
| 177 | * Returns the array with the path descriptors. |
||
| 178 | * |
||
| 179 | * @return array The array with the path descriptors |
||
| 180 | */ |
||
| 181 | 1 | public function getPathDescriptors() |
|
| 182 | { |
||
| 183 | 1 | return $this->paths; |
|
| 184 | } |
||
| 185 | |||
| 186 | /** |
||
| 187 | * Adds a path descriptor to the controller. |
||
| 188 | * |
||
| 189 | * @param \AppserverIo\Routlt\Description\PathDescriptorInterface $pathDescriptor The path descriptor to add |
||
| 190 | * |
||
| 191 | * @return void |
||
| 192 | */ |
||
| 193 | 1 | public function addPathDescriptor(PathDescriptorInterface $pathDescriptor) |
|
| 194 | { |
||
| 195 | 1 | $this->paths[$pathDescriptor->getName()] = $pathDescriptor; |
|
| 196 | 1 | } |
|
| 197 | |||
| 198 | /** |
||
| 199 | * Returns the path descriptor with the passed name. |
||
| 200 | * |
||
| 201 | * @param string $name The name of the path descriptor to return |
||
| 202 | * |
||
| 203 | * @return \AppserverIo\Routlt\Description\PathDescriptorInterface The path descriptor instance |
||
| 204 | * @throws \Exception |
||
| 205 | */ |
||
| 206 | public function getPathDescriptor($name) |
||
| 207 | { |
||
| 208 | |||
| 209 | // query whether or not the path descriptor exists |
||
| 210 | if (isset($this->paths[$name])) { |
||
| 211 | return $this->paths[$name]; |
||
| 212 | } |
||
| 213 | |||
| 214 | // throw an exception if the requested path descriptor ist NOT available |
||
| 215 | throw new \Exception(sprintf('Can\'t find path descriptor with name "%s"', $name)); |
||
| 216 | } |
||
| 217 | |||
| 218 | /** |
||
| 219 | * Loads the values found in the configuration file and merges |
||
| 220 | * them with the servlet context initialization parameters. |
||
| 221 | * |
||
| 222 | * @return void |
||
| 223 | */ |
||
| 224 | 3 | protected function initConfiguration() |
|
| 225 | { |
||
| 226 | |||
| 227 | // load the relative path to the Routlt configuration file |
||
| 228 | 3 | $configurationFileName = $this->getInitParameter(ControllerServlet::INIT_PARAMETER_ROUTLT_CONFIGURATION_FILE); |
|
| 229 | |||
| 230 | // load the path to the configuration file |
||
| 231 | 3 | $configurationFile = $this->getServletConfig()->getWebappPath() . DIRECTORY_SEPARATOR . ltrim($configurationFileName, '/'); |
|
| 232 | |||
| 233 | // if the file is readable |
||
| 234 | 3 | if (is_file($configurationFile) && is_readable($configurationFile)) { |
|
| 235 | // load the properties from the file |
||
| 236 | 1 | $properties = new Properties(); |
|
| 237 | 1 | $properties->load($configurationFile); |
|
| 238 | |||
| 239 | // append the properties to the servlet context |
||
| 240 | 1 | foreach ($properties as $paramName => $paramValue) { |
|
| 241 | 1 | $this->getServletContext()->addInitParameter($paramName, $paramValue); |
|
| 242 | 1 | } |
|
| 243 | 1 | } |
|
| 244 | 3 | } |
|
| 245 | |||
| 246 | /** |
||
| 247 | * Initializes the available routes. |
||
| 248 | * |
||
| 249 | * @return void |
||
| 250 | */ |
||
| 251 | 3 | protected function initRoutes() |
|
| 252 | { |
||
| 253 | |||
| 254 | // load the action namespace |
||
| 255 | 3 | $actionNamespace = strtolower($this->getInitParameter(ControllerServlet::INIT_PARAMETER_ACTION_NAMESPACE)); |
|
| 256 | |||
| 257 | // register the actions located by annotations and the XML configuration |
||
| 258 | 3 | foreach ($this->getObjectManager()->getObjectDescriptors() as $descriptor) { |
|
|
0 ignored issues
–
show
|
|||
| 259 | // check if we've found a servlet descriptor |
||
| 260 | 2 | if ($descriptor instanceof PathDescriptorInterface) { |
|
| 261 | // register the action's references |
||
| 262 | 2 | $this->getServletContext()->registerReferences($descriptor); |
|
|
0 ignored issues
–
show
The method
registerReferences() does not seem to exist on object<AppserverIo\Psr\S...ervletContextInterface>.
This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces. This is most likely a typographical error or the method has been renamed. Loading history...
|
|||
| 263 | // initialize a new action instance |
||
| 264 | 2 | $action = $this->initActionInstance($descriptor); |
|
| 265 | |||
| 266 | // prepare the action's the result configuration descriptors |
||
| 267 | /** @var \AppserverIo\Routlt\Description\ResultConfigurationDescriptorInterface $resultConfigurationDescriptor */ |
||
| 268 | 2 | foreach ($descriptor->getResults() as $resultConfigurationDescriptor) { |
|
| 269 | 1 | $action->addResult($this->initResultInstance($resultConfigurationDescriptor, $action)); |
|
| 270 | 2 | } |
|
| 271 | |||
| 272 | // prepare the route, e. g. /index/index |
||
| 273 | 2 | $controllerName = str_replace($actionNamespace, '', $descriptor->getName()); |
|
| 274 | |||
| 275 | // initialize the action mappings |
||
| 276 | 2 | foreach ($descriptor->getActions() as $actionDescriptors) { |
|
| 277 | // iterate over all request methods |
||
| 278 | /** @var \AppserverIo\Routlt\Description\ActionDescriptorInterface $actionDescriptor */ |
||
| 279 | 1 | foreach ($actionDescriptors as $requestMethod => $actionDescriptor) { |
|
| 280 | // prepare the real action method name |
||
| 281 | 1 | $methodName = $actionDescriptor->getMethodName(); |
|
| 282 | // prepare the action path -> concatenate route + action name |
||
| 283 | 1 | $actionPath = sprintf('%s%s', $controllerName, $actionDescriptor->getName()); |
|
| 284 | |||
| 285 | // initialize the action mapping for the actual route |
||
| 286 | 1 | $actionMapping = new ActionMapping(); |
|
| 287 | 1 | $actionMapping->setControllerName($controllerName); |
|
| 288 | 1 | $actionMapping->setMethodName($methodName); |
|
| 289 | 1 | $actionMapping->compile( |
|
| 290 | 1 | $actionPath, |
|
| 291 | 1 | $actionDescriptor->getRestrictions(), |
|
| 292 | 1 | $actionDescriptor->getDefaults() |
|
| 293 | 1 | ); |
|
| 294 | |||
| 295 | // add the action path -> route mapping for the request method |
||
| 296 | 1 | $this->actionMappings[$requestMethod][$actionPath] = $actionMapping; |
|
| 297 | |||
| 298 | // add an alias for the route for the action's default method |
||
| 299 | 1 | if ($actionDescriptor->getMethodName() === $action->getDefaultMethod()) { |
|
| 300 | // initialize the action mapping for the default route |
||
| 301 | 1 | $actionMapping = new ActionMapping(); |
|
| 302 | 1 | $actionMapping->setControllerName($controllerName); |
|
| 303 | 1 | $actionMapping->setMethodName($methodName); |
|
| 304 | 1 | $actionMapping->compile( |
|
| 305 | 1 | $controllerName, |
|
| 306 | 1 | $actionDescriptor->getRestrictions(), |
|
| 307 | 1 | $actionDescriptor->getDefaults() |
|
| 308 | 1 | ); |
|
| 309 | // add the action mapping for the default route |
||
| 310 | 1 | $this->actionMappings[$requestMethod][$controllerName] = $actionMapping; |
|
| 311 | 1 | } |
|
| 312 | 1 | } |
|
| 313 | 2 | } |
|
| 314 | |||
| 315 | // add the initialized action |
||
| 316 | 2 | $this->routes[$controllerName] = $action; |
|
| 317 | 2 | } |
|
| 318 | 3 | } |
|
| 319 | 3 | } |
|
| 320 | |||
| 321 | /** |
||
| 322 | * Creates a new instance of the action from the passed path descriptor instance. |
||
| 323 | * |
||
| 324 | * @param \AppserverIo\Routlt\Description\PathDescriptorInterface $pathDescriptor The path descriptor to create the action from |
||
| 325 | * |
||
| 326 | * @return \AppserverIo\Routlt\ActionInterface The action instance |
||
| 327 | */ |
||
| 328 | protected function initActionInstance(PathDescriptorInterface $pathDescriptor) |
||
| 329 | { |
||
| 330 | |||
| 331 | // create a new action instance |
||
| 332 | $actionInstance = $this->getProvider()->get($pathDescriptor->getName()); |
||
| 333 | |||
| 334 | // if the action is servlet context aware |
||
| 335 | if ($actionInstance instanceof ServletContextAware) { |
||
| 336 | $actionInstance->setServletContext($this->getServletContext()); |
||
| 337 | } |
||
| 338 | |||
| 339 | // if the action is descriptor aware |
||
| 340 | if ($actionInstance instanceof DescriptorAware) { |
||
| 341 | $actionInstance->setDescriptor($pathDescriptor); |
||
| 342 | } |
||
| 343 | |||
| 344 | // return the action instance |
||
| 345 | return $actionInstance; |
||
| 346 | } |
||
| 347 | |||
| 348 | /** |
||
| 349 | * Creates a new instance of the action result the passed descriptor. |
||
| 350 | * |
||
| 351 | * @param \AppserverIo\Routlt\Description\ResultConfigurationDescriptorInterface $resultConfigurationDescriptor The action result configuration descriptor |
||
| 352 | * @param \AppserverIo\Routlt\ActionInterface $action The action instance the result is bound to |
||
| 353 | * |
||
| 354 | * @return \AppserverIo\Routlt\Results\ResultInterface The result instance |
||
| 355 | */ |
||
| 356 | protected function initResultInstance(ResultConfigurationDescriptorInterface $resultConfigurationDescriptor, ActionInterface $action) |
||
| 357 | { |
||
| 358 | |||
| 359 | // load the object manager instance |
||
| 360 | $objectManager = $this->getObjectManager(); |
||
| 361 | |||
| 362 | // query whether or not we've a real deployment descriptor or not |
||
| 363 | if ($objectManager->hasObjectDescriptor($lookupName = $resultConfigurationDescriptor->getType())) { |
||
| 364 | // if not replqce it with the real one |
||
| 365 | $objectDescriptor = $objectManager->getObjectDescriptor($lookupName); |
||
| 366 | // register the result's references |
||
| 367 | $this->getServletContext()->registerReferences($objectDescriptor); |
||
|
0 ignored issues
–
show
The method
registerReferences() does not seem to exist on object<AppserverIo\Psr\S...ervletContextInterface>.
This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces. This is most likely a typographical error or the method has been renamed. Loading history...
|
|||
| 368 | // now use the result descriptors name for lookup |
||
| 369 | $lookupName = $objectDescriptor->getName(); |
||
| 370 | } |
||
| 371 | |||
| 372 | // initialize the result instance by the lookup name |
||
| 373 | $resultInstance = $this->getProvider()->get($lookupName); |
||
| 374 | |||
| 375 | // if the result is action aware |
||
| 376 | if ($resultInstance instanceof ActionAware) { |
||
| 377 | $resultInstance->setAction($action); |
||
| 378 | } |
||
| 379 | |||
| 380 | // if the result is descriptor aware |
||
| 381 | if ($resultInstance instanceof DescriptorAware && $objectDescriptor instanceof ResultDescriptorInterface) { |
||
| 382 | $resultInstance->setDescriptor($objectDescriptor); |
||
|
0 ignored issues
–
show
The variable
$objectDescriptor 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
Loading history...
|
|||
| 383 | } |
||
| 384 | |||
| 385 | // if the result is servlet context aware |
||
| 386 | if ($resultInstance instanceof ServletContextAware) { |
||
| 387 | $resultInstance->setServletContext($this->getServletContext()); |
||
| 388 | } |
||
| 389 | |||
| 390 | // initialize the instance from the result descriptor |
||
| 391 | $resultInstance->init($resultConfigurationDescriptor); |
||
| 392 | |||
| 393 | // return the result instance |
||
| 394 | return $resultInstance; |
||
| 395 | } |
||
| 396 | |||
| 397 | /** |
||
| 398 | * Checks whether or not an action is generally available for any request method. |
||
| 399 | * Will return TRUE if so, FALSE otherwise. |
||
| 400 | * This method replicates a lot of the checks generally necessary but omits the request method check. |
||
| 401 | * Still best called in exception- or edge-cases |
||
| 402 | * |
||
| 403 | * @param string $pathInfo The action path which has been requested |
||
| 404 | * |
||
| 405 | * @return boolean |
||
| 406 | */ |
||
| 407 | 3 | public function checkGeneralActionAvailability($pathInfo) |
|
| 408 | { |
||
| 409 | |||
| 410 | // iterate the request methods we have mappings for and check if we can find the requested action |
||
| 411 | 3 | foreach ($this->getActionMappings() as $actionMapping) { |
|
| 412 | 3 | $run = true; |
|
| 413 | 3 | $requestedAction = $pathInfo; |
|
| 414 | do { |
||
| 415 | 3 | if (isset($actionMapping[$requestedAction])) { |
|
| 416 | 2 | return true; |
|
| 417 | } |
||
| 418 | // strip the last directory |
||
| 419 | 3 | $requestedAction = dirname($requestedAction); |
|
| 420 | |||
| 421 | // query whether we've to stop dispatching |
||
| 422 | 3 | if ($requestedAction === '/' || $requestedAction === false) { |
|
| 423 | 2 | $run = false; |
|
| 424 | 2 | } |
|
| 425 | 3 | } while ($run === true); |
|
| 426 | 2 | } |
|
| 427 | |||
| 428 | // nothing found? Return false then |
||
| 429 | 2 | return false; |
|
| 430 | } |
||
| 431 | |||
| 432 | /** |
||
| 433 | * Returns the array with request method action -> route mappings |
||
| 434 | * for the passed servlet request. |
||
| 435 | * |
||
| 436 | * @param \AppserverIo\Psr\Servlet\ServletRequestInterface $servletRequest The request instance |
||
| 437 | * |
||
| 438 | * @return array The request method action -> route mappings for the passed request method |
||
| 439 | */ |
||
| 440 | 4 | public function getActionMappingsForServletRequest(ServletRequestInterface $servletRequest) |
|
| 441 | { |
||
| 442 | // load the servlet request method |
||
| 443 | 4 | $requestMethod = $servletRequest->getMethod(); |
|
|
0 ignored issues
–
show
It seems like you code against a concrete implementation and not the interface
AppserverIo\Psr\Servlet\ServletRequestInterface as the method getMethod() does only exist in the following implementations of said interface: AppserverIo\Psr\Servlet\...tpServletRequestWrapper.
Let’s take a look at an example: interface User
{
/** @return string */
public function getPassword();
}
class MyUser implements 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 implementation 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.
Loading history...
|
|||
| 444 | |||
| 445 | // load the action mappings |
||
| 446 | 4 | $actionMappings = $this->getActionMappings(); |
|
| 447 | |||
| 448 | // query whether we've action mappings for the request method or not |
||
| 449 | 4 | if (isset($actionMappings[$requestMethod])) { |
|
| 450 | 3 | return $actionMappings[$requestMethod]; |
|
| 451 | } |
||
| 452 | |||
| 453 | // nothing found? Method must not be allowed then |
||
| 454 | 1 | throw new DispatchException(sprintf('Method %s not allowed', $requestMethod), 405); |
|
| 455 | } |
||
| 456 | |||
| 457 | /** |
||
| 458 | * Delegates to HTTP method specific functions like doPost() for POST e.g. |
||
| 459 | * |
||
| 460 | * @param \AppserverIo\Psr\Servlet\ServletRequestInterface $servletRequest The request instance |
||
| 461 | * @param \AppserverIo\Psr\Servlet\ServletResponseInterface $servletResponse The response sent back to the client |
||
| 462 | * |
||
| 463 | * @return void |
||
| 464 | * |
||
| 465 | * @throws \AppserverIo\Psr\Servlet\ServletException If no action has been found for the requested path |
||
| 466 | */ |
||
| 467 | 7 | public function service(ServletRequestInterface $servletRequest, ServletResponseInterface $servletResponse) |
|
| 468 | { |
||
| 469 | |||
| 470 | try { |
||
| 471 | // pre-initialize response |
||
| 472 | 7 | $servletResponse->addHeader(HttpProtocol::HEADER_X_POWERED_BY, get_class($this)); |
|
|
0 ignored issues
–
show
It seems like you code against a concrete implementation and not the interface
AppserverIo\Psr\Servlet\ServletResponseInterface as the method addHeader() does only exist in the following implementations of said interface: AppserverIo\Psr\Servlet\...pServletResponseWrapper.
Let’s take a look at an example: interface User
{
/** @return string */
public function getPassword();
}
class MyUser implements 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 implementation 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.
Loading history...
|
|||
| 473 | |||
| 474 | // load the path info from the servlet request |
||
| 475 | 6 | $pathInfo = $servletRequest->getPathInfo(); |
|
| 476 | |||
| 477 | // if the requested action has been found in the path info |
||
| 478 | 6 | if ($pathInfo == null) { |
|
| 479 | 2 | $pathInfo = $this->getDefaultRoute(); |
|
| 480 | 2 | } |
|
| 481 | |||
| 482 | // prepare the path of the requested action |
||
| 483 | 6 | $requestedAction = $pathInfo; |
|
| 484 | |||
| 485 | // load the routes |
||
| 486 | 6 | $routes = $this->getRoutes(); |
|
| 487 | |||
| 488 | // load the DI provider |
||
| 489 | 6 | $provider = $this->getProvider(); |
|
| 490 | |||
| 491 | // load the action mappings for the actual servlet request |
||
| 492 | 6 | $actionMappings = $this->getActionMappingsForServletRequest($servletRequest); |
|
| 493 | |||
| 494 | // initialize the parameter map with the values from the request |
||
| 495 | 5 | if ($servletRequest->getParameterMap()) { |
|
| 496 | $parameterMap = $servletRequest->getParameterMap(); |
||
| 497 | } else { |
||
| 498 | 5 | $parameterMap = array(); |
|
| 499 | } |
||
| 500 | |||
| 501 | // iterate over the action mappings and try to find a mapping |
||
| 502 | 5 | foreach ($actionMappings as $actionMapping) { |
|
| 503 | // try to match actual request by the tokenizer |
||
| 504 | 5 | if ($actionMapping->match($requestedAction)) { |
|
| 505 | // initialize the request attributes with the values from the action mapping |
||
| 506 | 3 | $servletRequest->setParameterMap( |
|
|
0 ignored issues
–
show
It seems like you code against a concrete implementation and not the interface
AppserverIo\Psr\Servlet\ServletRequestInterface as the method setParameterMap() does only exist in the following implementations of said interface: AppserverIo\Psr\Servlet\...tpServletRequestWrapper.
Let’s take a look at an example: interface User
{
/** @return string */
public function getPassword();
}
class MyUser implements 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 implementation 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.
Loading history...
|
|||
| 507 | 3 | array_merge($parameterMap, $actionMapping->getRequestParameters()) |
|
| 508 | 3 | ); |
|
| 509 | |||
| 510 | // resolve the action with the found mapping |
||
| 511 | 3 | $action = $routes[$actionMapping->getControllerName()]; |
|
| 512 | |||
| 513 | // query whether or not the action has a descriptor |
||
| 514 | 3 | if ($action instanceof DescriptorAware) { |
|
| 515 | 3 | $provider->injectDependencies($action->getDescriptor(), $action); |
|
| 516 | 3 | } |
|
| 517 | |||
| 518 | // set the method that has to be invoked in the action context |
||
| 519 | 3 | $action->setAttribute(ContextKeys::METHOD_NAME, $actionMapping->getMethodName()); |
|
| 520 | |||
| 521 | // pre-dispatch the action |
||
| 522 | 3 | $action->preDispatch($servletRequest, $servletResponse); |
|
| 523 | |||
| 524 | // if the action has been dispatched, we're done |
||
| 525 | 3 | if ($servletRequest->isDispatched()) { |
|
| 526 | 1 | return; |
|
| 527 | } |
||
| 528 | |||
| 529 | // initialize the result with the default value |
||
| 530 | 2 | $result = ActionInterface::INPUT; |
|
| 531 | |||
| 532 | // if not dispatch the action |
||
| 533 | 2 | if ($newResult = $action->perform($servletRequest, $servletResponse)) { |
|
| 534 | 1 | $result = $newResult; |
|
| 535 | 1 | } |
|
| 536 | |||
| 537 | // post-dispatch the action instance |
||
| 538 | 2 | $action->postDispatch($servletRequest, $servletResponse); |
|
| 539 | |||
| 540 | 1 | // process the result if available |
|
| 541 | 1 | if (($instance = $action->findResult($result)) instanceof ResultInterface) { |
|
| 542 | 1 | // query whether or not the result has a descriptor |
|
| 543 | if ($instance instanceof DescriptorAware && $descriptor = $instance->getDescriptor()) { |
||
| 544 | $provider->injectDependencies($descriptor, $instance); |
||
| 545 | 1 | } |
|
| 546 | 1 | ||
| 547 | 1 | // query whether or not the result is action aware |
|
| 548 | if ($instance instanceof ActionAware) { |
||
| 549 | $instance->setAction($action); |
||
| 550 | 1 | } |
|
| 551 | 1 | ||
| 552 | // process the result |
||
| 553 | $instance->process($servletRequest, $servletResponse); |
||
| 554 | 2 | } |
|
| 555 | |||
| 556 | // stop processing |
||
| 557 | 2 | return; |
|
| 558 | } |
||
| 559 | 2 | } |
|
| 560 | |||
| 561 | // We did not find anything for this method/URI connection. We have to evaluate if there simply |
||
| 562 | // is a method restriction. This replicates a lot of the checks we did before but omits extra |
||
| 563 | // iterations in a positive dispatch event, 4xx's should be the exception and can handle that |
||
| 564 | // penalty therefore |
||
| 565 | 2 | if ($this->checkGeneralActionAvailability($pathInfo)) { |
|
| 566 | // nothing found? Method must not be allowed then |
||
| 567 | 1 | throw new DispatchException(sprintf('Method %s not allowed', $servletRequest->getMethod()), 405); |
|
|
0 ignored issues
–
show
It seems like you code against a concrete implementation and not the interface
AppserverIo\Psr\Servlet\ServletRequestInterface as the method getMethod() does only exist in the following implementations of said interface: AppserverIo\Psr\Servlet\...tpServletRequestWrapper.
Let’s take a look at an example: interface User
{
/** @return string */
public function getPassword();
}
class MyUser implements 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 implementation 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.
Loading history...
|
|||
| 568 | } |
||
| 569 | |||
| 570 | // throw an action, because we can't find an action mapping |
||
| 571 | 1 | throw new DispatchException(sprintf('Can\'t find action to dispatch path info %s', $pathInfo), 404); |
|
| 572 | |||
| 573 | 4 | } catch (DispatchException $de) { |
|
| 574 | // results in a 4xx error |
||
| 575 | 3 | throw new ServletException($de->__toString(), $de->getCode(), $de); |
|
| 576 | 1 | } catch (\Exception $e) { |
|
| 577 | // results in a 500 error page |
||
| 578 | 1 | throw new ServletException($e->__toString(), 500, $e); |
|
| 579 | } |
||
| 580 | } |
||
| 581 | } |
||
| 582 |
This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.
This is most likely a typographical error or the method has been renamed.