Creates the response to return while executing the before and after
methods if they are available.

@param $route
@throws \Exception
@return Response | null
163273
private function createResponse($route): ?Response
    {
        $controller = $this->getRouteControllerInstance($route);
        if (!is_null($controller)) {
            $responseBefore = $controller->before();
            if ($responseBefore instanceof Response) {
                return $responseBefore;
            }
        }

        $values = $route['route']->getArguments($this->requestedUri);
        $this->loadRequestParameters($values);
        $callback = new Callback($route['callback']);
        $arguments = $this->getFunctionArguments($callback->getReflection(), array_values($values));
        $response = $callback->executeArray($arguments);

        if (!is_null($controller)) {
            $responseAfter = $controller->after($response);
            if ($responseAfter instanceof Response) {
                return $responseAfter;
            }
        }
        return $response;
    }
867776
private function execute()
	{
		if ($this->currentRoute == null) {
			$this->router->getRoute('error_page')->setAction('_notFound');
			$this->toRoute('error_page');
			return;
		}
		$controllerName = $this->currentRoute->getController();
		if ($controllerName == '') {
			if ($this->currentRoute->getParams() != null && array_key_exists('controller', $this->currentRoute->getParams()))
				$controllerName = $this->currentRoute->getParams()['controller'];
			elseif ($this->currentRoute->getDefault() != null)
				$controllerName = $this->currentRoute->getDefault()->getController();
			else {
				throw new \Exception($this->translator->translate("The requested url has a bad route configuration!"));
			}
		}

		if (array_key_exists($controllerName, $this->invokable))
			$controllerName = $this->invokable[$controllerName];
		elseif (strpos($controllerName, 'decoy\base') === false)
			throw new \Exception('The requested Controller: \'' . $controllerName . '\' is not registered!');
		$c = new $controllerName($this);
		if ($c->getResult() && !in_array($c->identifier, $this->disableRender) && $this->enableRender) {
			echo $this->response->output($c);
		}
	}
875306
public function createResponse($exception)
    {
        if (!$exception instanceof FlattenException) {
            $exception = FlattenException::create($exception);
        }

        return new Response($this->decorate($this->getContent($exception, $this->showAllExceptions), $this->getStylesheet($exception)), $exception->getStatusCode(), $exception->getHeaders());
    }
748333
private function prepare($route)
    {
        $this->route = $route;
        $this->setBeforeFilter($route->before());
        $this->setAfterRelease($route->after());
    }
576769
public function dispatchToRoute(Request $request)
	{
		// First we will find a route that matches this request. We will also set the
		// route resolver on the request so middlewares assigned to the route will
		// receive access to this route instance for checking of the parameters.
		$route = $this->findRoute($request);

		$request->setRouteResolver(function() use ($route)
		{
			return $route;
		});

		$this->events->fire('router.matched', [$route, $request]);

		// Once we have successfully matched the incoming request to a given route we
		// can call the before filters on that route. This works similar to global
		// filters in that if a response is returned we will not call the route.
		$response = $this->callRouteBefore($route, $request);

		if (is_null($response))
		{
			$response = $this->runRouteWithinStack(
				$route, $request
			);
		}

		$response = $this->prepareResponse($request, $response);

		// After we have a prepared response from the route or filter we will call to
		// the "after" filters to do any last minute processing on this request or
		// response object before the response is returned back to the consumer.
		$this->callRouteAfter($route, $request, $response);

		return $response;
	}
266752
public function route(Request $request) : Response
    {
        $method = $request->getMethod();

        /** @var ParsedRoute $route */
        foreach ($this->routeCollection->get($method) as $route) {
            $compiledRoute = $this->compiler->compile($route, $request);

            if ($compiledRoute->isMatch()) {
                $this->matchedRoute = $compiledRoute;

                return $this->dispatcher->dispatch($this->matchedRoute, $request, $this->matchedController);
            }
        }

        // If we've gotten here, we've got a missing route
        throw new HttpException(404);
    }
698712
public function handle(Exception $exception): Response
    {
        foreach ($this->handlers as $hint => $handler) {
            if (!$exception instanceof $hint) {
                continue;
            }

            if ($response = $handler($exception)) {
                if (!$response instanceof BaseResponse) {
                    $response = new Response($response, $this->getExceptionStatusCode($exception));
                }

                return $response;
            }
        }

        return $this->genericResponse($exception);
    }
633574
public function handle($request) : ResponseInterface
    {
        $this->setRouter($request);

        try {
            $response = $this->sendRequestThroughRouter($request);
            /*
             * Check whether return value is a instance of Response,
             * otherwise we will try to fetch the response form container,
             * create a response and return to the browser.
             *
             */
            if (!$response instanceof ResponseInterface && !is_array($response)) {
                $r = $this->container->has('response') ? $this->container->get('response') : '';
                $response = Response::make($r);
            }
        } catch (\Exception $e) {
            $this->handleException($e);
        } catch (Throwable $e) {
            $this->handleException($e);
        }

        return $response;
    }
309334
public function createController($route)
    {
        preg_match('/(default)/', $route, $match);
        if (isset($match[0]))
            return parent::createController($route);

        return parent::createController("{$this->defaultRoute}/{$route}");
    }
789389
private function getReflectionMethodForRoute(Route $route)
    {
        $class = $this->extractClassFromRoute($route);
        $method = $this->extractFunctionFromRoute($route);

        if ($class !== null && $method !== null) {
            return new \ReflectionMethod($class, $method);
        }
        return null;
    }
853727
public function handleViolation(Route $route)
    {

        if(in_array($route, $this->violatingRoutes)) {
            throw new ApplicationException('Circular redirects detected; aborting.');
        }

        // to avoid circular references all redirects are logged

        $this->violatingRoutes[] = $route;

        Session::getSessionDataBag()->set('authViolatingRequest', Request::createFromGlobals());

        if($redirect = $route->getRedirect()) {
            return Application::getInstance()->getRouter()->getRoute($redirect);
        }

        else {
            throw new \RuntimeException(sprintf("No redirect configured for route '%s', which cannot be authenticated.", $route->getRouteId()));
        }

    }
492445
protected function processRoute($route)
	{
		$routeAction = $route->getAction();

		$this->getParentCommand()->info('Processing route [' . implode('/', $route->methods()) . '] ' . $routeAction['uri']);

		$routeControllerDocBlock = $this->getRouteControllerDocBlock($route);
		$routeControllerOperationTags = $this->getDocBlockOperationTags($routeControllerDocBlock);

		foreach ($route->methods() as $httpMethod) {
			// Ignore HEAD

			if (strtolower($httpMethod) == 'head') {
				continue;
			}

			if (isset($this->openAPI->paths[$routeAction['uri']])) {
				$pathItem = $this->openAPI->paths[$routeAction['uri']];
			} else {
				$pathItem = $this->openAPI->paths[$routeAction['uri']] = new PathItem();

				if (!is_null($routeControllerDocBlock)) {
					$pathItem->summary = $routeControllerDocBlock->getSummary();
					if (empty($pathItem->summary)) {
						$pathItem->summary = null;
					}
					$routeControllerDescriptionDocBlock = $routeControllerDocBlock->getDescription();
					$pathItem->description = $routeControllerDescriptionDocBlock->render();
					if (empty($pathItem->description)) {
						$pathItem->description = null;
					}
				}
			}

			$operation = new Operation();

			$operationTags = $routeControllerOperationTags;

			$routeMethodDocBlock = $this->getRouteMethodDocBlock($route);
			$extraParameterRefTags = [];

			if (!is_null($routeMethodDocBlock)) {
				$operation->summary = $routeMethodDocBlock->getSummary();
				if (empty($operation->summary)) {
					$operation->summary = null;
				}
				$routeMethodDescriptionDocBlock = $routeMethodDocBlock->getDescription();
				$operation->description = $routeMethodDescriptionDocBlock->render();
				if (empty($operation->description)) {
					$operation->description = null;
				}
				$routeMethodOperationTags = $this->getDocBlockOperationTags($routeMethodDocBlock);

				$operationTags = array_merge($routeControllerOperationTags, $routeMethodOperationTags);
				$extraParameterRefTags = $this->getDocBlockExtraParameterRefTags($routeMethodDocBlock);

				$operation->operationId = $this->getDocBlockOperationId($routeMethodDocBlock);
			}

			if (is_null($operation->operationId)) {
				switch (strtolower($httpMethod)) {
					case 'patch':
					case 'put':
						$operation->operationId = strtolower($httpMethod) . ucfirst(array_last(explode('.', $routeAction['as'])));
						break;
					default :
						$operation->operationId = array_last(explode('.', $routeAction['as']));
				}
			}

			if (count($operationTags) > 0) {
				$operation->tags = $operationTags;
			}

			// Try
			$routePathParameters = $this->getRoutePathParameters($route);

			foreach ($routePathParameters as $parameterName => $parameterData) {
				$parameterDescription = isset($parameterData['docDescription']) ? $parameterData['docDescription'] : '';
				if (trim($parameterDescription) == '') {
					$parameterDescription = null;
				}
				$parameter = new Parameter([
					'name' => $parameterName,
					'in' => 'path',
					'description' => $parameterDescription,
					'required' => true,
				]);
				if (isset($parameterData['type'])) {
					$parameter->schema = new Schema([
						'type' => $parameterData['type']
					]);
				}
				if (isset($parameterData['docType'])) {
					$parameter->schema = new Schema([
						'type' => $parameterData['docType']
					]);
				}
				$operation->parameters[] = $parameter;
			}

			// Try to get route validation rules
			$routeValidationRules = $this->getRouteValidationRules($route);

			if (count($routeValidationRules) > 0) {
				switch (strtolower($httpMethod)) {
					case 'get':
					//case 'head':

						foreach ($routeValidationRules as $parameterName => $rulesString) {
							$rules = explode('|', $rulesString);

							$parameter = new Parameter([
								'name' => $parameterName,
								'in' => 'query',
								'description' => null, /* @todo Grab description from phpdoc custom tag ? */
								'required' => in_array('required', $rules),
							]);

							$parameter->schema = $this->getPropertyValidationRulesSchema(
								$rules,
								'Validation rules for parameter "' . $parameterName . '"',
								true
							);
							
							if (is_null($parameter->schema->format)) {
								// ignore this parameter if no type found
								$this->getParentCommand()->warn('  Ignore parameter "' . $parameterName . '"');
								continue;
							}

							// Add if not already added from the "path" parameters
							$find = false;
							if (is_null($operation->parameters)) {
								$operation->parameters = [];
							}
							/** @var Parameter $p */
							foreach ($operation->parameters as $p) {
								if ($p->name == $parameter->name) {
									$find = true;
								}
							}
							if (!$find) {
								$operation->parameters[] = $parameter;
							}
						}

						break;

					case 'put':
					case 'patch':
					case 'post':

						$requestBody = new RequestBody();
						$mediaType = new MediaType();
						$mediaType->schema = new Schema();
						$mediaType->schema->properties = [];

						// Change to multi-part if file in parameters ("string" type and "binary" format)
						$contentType = 'application/json';
						
						foreach ($routeValidationRules as $parameterName => $rulesString) {
							$rules = explode('|', $rulesString);
							$schema = $this->getPropertyValidationRulesSchema(
								$rules,
								'Validation rules for parameter "' . $parameterName . '"',
								true
							);
							
							// ignore this property if no type found
							if (is_null($schema->type)) {
								$this->getParentCommand()->warn('  Ignore parameter "' . $parameterName . '"');
								continue;
							}
							
							// Change to multi-part if file in parameters ("string" type and "binary" format)
							if ($schema->type == 'string' && $schema->format == 'binary') {
								$contentType = 'multipart/form-data';
								// Change mediaType schema type
								$mediaType->schema->type = 'object';
							}
							
							$mediaType->schema->properties[$parameterName] = $schema;
						}

						$mediaType->schema->required = $this->getValidationRulesSchemaRequired($routeValidationRules);

						$requestBody->content[$contentType] = $mediaType;
						$operation->requestBody = $requestBody;

						$operation->responses = [];

						break;
				}
			}

			// Append extra parameter refs

			foreach ($extraParameterRefTags as $extraParameterRefTag) {
				$parameterRef = new Reference([
					'ref' => $extraParameterRefTag
				]);

				if (is_null($operation->parameters)) {
					$operation->parameters = [];
				}

				$operation->parameters[] = $parameterRef;
			}

			// First response

			$response = new Response();
			$responseMediaType = null;

			$apiResponseSchemaRefTags = $routeMethodDocBlock->getTagsByName('OpenApiResponseSchemaRef');
			if (count($apiResponseSchemaRefTags) > 0) {
				if (is_null($responseMediaType)) {
					$responseMediaType = new MediaType();
				}
				$apiResponseSchemaRefTag = $apiResponseSchemaRefTags[0];
				$apiResponseSchemaRef = trim(str_replace('@OpenApiResponseSchemaRef', '', $apiResponseSchemaRefTag->render()));
				$responseMediaType->schema = new Reference([
					'ref' => $apiResponseSchemaRef
				]);
			}
			
			$response->description = '';
			$apiResponseDescriptionTags = $routeMethodDocBlock->getTagsByName('OpenApiResponseDescription');
			if (count($apiResponseDescriptionTags) > 0) {
				$apiResponseDescriptionTag = $apiResponseDescriptionTags[0];
				$apiResponseDescription = trim(str_replace('@OpenApiResponseDescription', '', $apiResponseDescriptionTag->render()));
				$response->description = $apiResponseDescription;
			}

			$apiDocsNoCallTags = $routeMethodDocBlock->getTagsByName('ApiDocsNoCall');
			if (count($apiDocsNoCallTags) == 0) {
				$exampleResponse = $this->getRouteCallExampleResponse($route, $httpMethod);
				if (!is_null($exampleResponse)) {
					if (is_null($responseMediaType)) {
						$responseMediaType = new MediaType();
					}

					$exampleSchemaId = $this->getRouteExampleResponseId($route);

					// Create Example schema in components

					if (is_null($this->openAPI->components)) {
						$this->openAPI->components = new Components();
					}

					$this->openAPI->components->examples[$exampleSchemaId] = new Example([
						'value' => json_decode($exampleResponse, true)
					]);

					$responseMediaType->example = new Reference([
						'ref' => '#/components/examples/' . $exampleSchemaId
					]);
				}
			}

			if (!is_null($responseMediaType)) {
				$response->content['application/json'] = $responseMediaType;
			}
			
			// Excepted HTTP code specified ? "OpenApiResponseExceptedHTTPCode" tag
			
			$apiResponseExceptedHTTPCode = null;
			$apiResponseExceptedHTTPCodeTags = $routeMethodDocBlock->getTagsByName('OpenApiResponseExceptedHTTPCode');
			if (count($apiResponseExceptedHTTPCodeTags) > 0) {
				$apiResponseExceptedHTTPCodeTag = $apiResponseExceptedHTTPCodeTags[0];
				$apiResponseExceptedHTTPCode = trim(str_replace('@OpenApiResponseExceptedHTTPCode', '', $apiResponseExceptedHTTPCodeTag->render()));
			}

			if (!is_null($apiResponseExceptedHTTPCode)) {
				$operation->responses[$apiResponseExceptedHTTPCode] = $response;
			} else {
				switch (strtolower($httpMethod)) {
					case 'get':
						//case 'head':
						$operation->responses['200'] = $response;
						break;
					
					case 'put':
					case 'patch':
						$operation->responses['200'] = $response;
						break;
						
					case 'post':
						$operation->responses['201'] = $response;
						break;
					
					case 'delete':
						$operation->responses['204'] = $response;
						break;
				}
			}

			// Default response (Errors)

			$defaultResponse = new Response();
			$defaultResponseMediaType = null;

			$apiDefaultResponseSchemaRefTags = $routeMethodDocBlock->getTagsByName('OpenApiDefaultResponseSchemaRef');
			if (count($apiDefaultResponseSchemaRefTags) > 0) {
				if (is_null($defaultResponseMediaType)) {
					$defaultResponseMediaType = new MediaType();
				}
				$apiDefaultResponseSchemaRefTag = $apiDefaultResponseSchemaRefTags[0];
				$apiDefaultResponseSchemaRef = trim(str_replace('@OpenApiDefaultResponseSchemaRef', '', $apiDefaultResponseSchemaRefTag->render()));
				$defaultResponseMediaType->schema = new Reference([
					'ref' => $apiDefaultResponseSchemaRef
				]);
			}

			$defaultResponse->description = '';
			$apiDefaultResponseDescriptionTags = $routeMethodDocBlock->getTagsByName('OpenApiDefaultResponseDescription');
			if (count($apiDefaultResponseDescriptionTags) > 0) {
				$apiDefaultResponseDescriptionTag = $apiResponseDescriptionTags[0];
				$apiDefaultResponseDescription = trim(str_replace('@OpenApiDefaultResponseDescription', '', $apiDefaultResponseDescriptionTag->render()));
				$defaultResponse->description = $apiDefaultResponseDescription;
			}

			if (!is_null($defaultResponseMediaType)) {
				$defaultResponse->content['application/json'] = $defaultResponseMediaType;
			}

			$operation->responses['default'] = $defaultResponse;

			$pathItem->{strtolower($httpMethod)} = $operation;
		}
	}
1204131
public function dispatch(Route $route)
    {
        do {
            $this->getEventManager()->publish("pre.dispatch", array($route, $this));

            $protoView = $this->_view->cloneThis();
            $controllerClassName = $route->getControllerName() . "Controller";
            $action = $route->getActionName() . "Action";
            $classPath = $this->getControllerPath() . DIRECTORY_SEPARATOR . $controllerClassName . ".php";
            $viewPath = $route->getControllerPath()
                . DIRECTORY_SEPARATOR
                . $route->getActionPath()
                . $protoView->getViewExt();

            if (!file_exists($classPath)) {
                // Use base controller
                $controllerClassName = 'Controller';
            } else {
                require_once $classPath;
            }

            $controller = new $controllerClassName($this);
            $controller->setRouter($this->getRouter());
            $controller->setRequest($this->getRequest());
            $controller->setParams(
                array_merge(
                    array(
                        "dispatcher" => $this,
                        "bootstrap" => $this->getBootstrap()
                    ),
                    $route->getParams()));
            $controller->setRawBody(@file_get_contents('php://input'));

            $controller->setView($protoView->cloneThis());
            $controller->view->controllerPath = $this->getControllerPath();

            if (method_exists($controller, $action)) {
                ob_start();
                $controller->init();
                $controller->$action();
                array_push($this->_viewsQueue, ob_get_contents());
                ob_end_clean();
            } else {
                if (!file_exists($controller->view->getViewPath() . DIRECTORY_SEPARATOR . $viewPath)) {
                    throw new RuntimeException("Page not found {$route->getControllerName()} -> {$route->getActionName()}", 404);
                }
            }

            if ($controller->view->getViewPath()) {
                array_push(
                    $this->_viewsQueue,
                    $controller->getView()->render(
                        (($controller->getViewPath() !== false) ? $controller->getViewPath() : $viewPath))
                );
            }

            $this->getEventManager()->publish("post.dispatch", array($this));
        } while(($route = array_shift($this->_actions)));

        return implode("", $this->_viewsQueue);
    }
1131359
public static function performRoute($route) {
		$api_mode = isset($route["api-mode"]);
		Request::setRequestVariables($route["variables"], $api_mode);

		$controller = new $route["class"];
		$response = $controller->$route["method"]();

		if(!Request::isAjax() && !Request::isAPI() && isset($route["render-path"])) {
			Request::setRenderPath($route["render-path"]);
			try {
				$route = self::findRoute(explode('/', $route["render-path"]));
			} catch(ValidRouteNotFoundException $e) {
				throw new ValidRenderRouteNotFoundException($e);
			}
			$response = self::performRoute($route);
		}

		return $response;
	}
1056695
public function dispatch($route, $request)
    {
        $request->setParam('Closure', $route[4]);

        if(isset($route[3]) && is_string($route[3])) {
            $view = $route[3];
            $data = $route[4];
            return ['view' => [$view, $data]];
        }
        elseif(isset($route[2]) && is_string($route[2])) {
            list($controller, $method) = explode('@', $route[2]);
            return ['controller' => [$controller, $method]];
        }
        elseif(isset($route[2]) && ($route[2] instanceof Closure || get_class($route[2]) === "Closure")) {
            $function = $route[2];
            $reflectionFunction = new ReflectionFunction($function);
            $numReqParam = $reflectionFunction->getNumberOfRequiredParameters();
            if($numReqParam > count($request->getParam('Closure'))) {
                throw new Exception('Invaliding number of required parameter passed in route\'s callable function: '.$route[1]);
            }
            ob_start();
            if($request->getParam('Closure') !== false && is_array($request->getParam('Closure')) ) {
                $return = call_user_func_array($route[2], $request->getParam('Closure'));
            }
            else {
                //$function();
                throw new Exception('Invaliding parameter passed in route\'s callable function: '.$route[1]);
            }
            $output = ob_get_clean();
            return ['output' => [$output, $return]];
        }
        else {
            throw new Exception('Invaliding route is registered for: '.$route[1]);
        }
    }
882595
private function exec(
        RouteInterface $route,
        RequestInterface $request,
        ResponseInterface $response,
        bool $error = false
    ) {
        $variables = $route->getVariables();
        $callback = $route->getCallback();

        // If extracted call back is string
        if (\is_string($callback)) {

            $className = $this->extractClass($callback);

            // Then class provided
            $class = new $className();
            $action = $this->detectAction($callback, $variables);

            // If method is not found in class and error is not triggered, then trigger error
            if (true !== $error && false === $this->methodCheck($class, $action)) {
                $router = $this->container('router');
                $routeError = $router->getError();
                return $this->exec($routeError, $request, $response, true);
            }

            // Call required action, with request/response
            $class->$action($request, $response, $variables);
        } else {
            // Else simple callback
            $callback($request, $response, $variables);
        }
        return $response->getBody();
    }
1222191
public static function handleRequest() {
        $response = get_response();
        try {
            $routes = self::$routes->getRoutes();
            if (!empty($routes)) {
                $beforeRoutes = self::$beforeRoutes->getRoutes();
                if (!empty($beforeRoutes)) {
                    foreach ($beforeRoutes as $beforeRoute) {
                        self::executeAction($beforeRoute->getAction(), array_merge($_REQUEST, $beforeRoute->getParameters()));
                    }
                }

                try {
                    foreach ($routes as $route) {
                        $routeResult = self::executeAction($route->getAction(), array_merge($_REQUEST, $route->getParameters()));
                        if (isset($routeResult)) {
                            $response->content($routeResult);
                        }
                    }
                    $afterRoutes = self::$afterRoutes->getRoutes();
                    if (!empty($afterRoutes)) {
                        foreach ($afterRoutes as $afterRoute) {
                            $routeResult = self::executeAction($afterRoute->getAction(), array_merge($_REQUEST, $afterRoute->getParameters()));
                            if (isset($routeResult)) {
                                $response->content($routeResult);
                            }
                        }
                    }
                    $response->send();
                }
                catch (ActionNotFoundException $notFoundException) {
                    self::handleRequestNotFound();
                }
            }
            else {
                self::handleRequestNotFound();
            }
        }
        catch (Throwable $ex) {
            self::handleRequestException($ex);
        }
    }