_routerList = $routerList; $this->response = $response; $this->requestValidator = $requestValidator ?? ObjectManager::getInstance()->get(RequestValidator::class); $this->messages = $messageManager ?? ObjectManager::getInstance()->get(MessageManager::class); $this->logger = $logger ?? ObjectManager::getInstance()->get(LoggerInterface::class); } /** * Perform action and generate response * * @param RequestInterface|HttpRequest $request * @return ResponseInterface|ResultInterface * @throws \LogicException */ public function dispatch(RequestInterface $request) { \Magento\Framework\Profiler::start('routers_match'); $this->validatedRequest = false; $routingCycleCounter = 0; $result = null; while (!$request->isDispatched() && $routingCycleCounter++ < 100) { /** @var \Magento\Framework\App\RouterInterface $router */ foreach ($this->_routerList as $router) { try { $actionInstance = $router->match($request); if ($actionInstance) { $result = $this->processRequest( $request, $actionInstance ); break; } } catch (\Magento\Framework\Exception\NotFoundException $e) { $request->initForward(); $request->setActionName('noroute'); $request->setDispatched(false); break; } } } \Magento\Framework\Profiler::stop('routers_match'); if ($routingCycleCounter > 100) { throw new \LogicException('Front controller reached 100 router match iterations'); } return $result; } /** * @param HttpRequest $request * @param ActionInterface $actionInstance * @throws NotFoundException * * @return ResponseInterface|ResultInterface */ private function processRequest( HttpRequest $request, ActionInterface $actionInstance ) { $request->setDispatched(true); $this->response->setNoCacheHeaders(); $result = null; //Validating a request only once. if (!$this->validatedRequest) { try { $this->requestValidator->validate( $request, $actionInstance ); } catch (InvalidRequestException $exception) { //Validation failed - processing validation results. $this->logger->debug( 'Request validation failed for action "' .get_class($actionInstance) .'"' ); $result = $exception->getReplaceResult(); if ($messages = $exception->getMessages()) { foreach ($messages as $message) { $this->messages->addErrorMessage($message); } } } $this->validatedRequest = true; } //Validation did not produce a result to replace the action's. if (!$result) { if ($actionInstance instanceof AbstractAction) { $result = $actionInstance->dispatch($request); } else { $result = $actionInstance->execute(); } } //handling redirect to 404 if ($result instanceof NotFoundException) { throw $result; } return $result; } }