/**
  * @param MvcEvent $evt
  * @return mixed
  * @throws \Exception
  */
 protected function getDispatchedController(MvcEvent $evt)
 {
     $controllerName = $evt->getRouteMatch()->getParam('controller');
     if (!$controllerName) {
         throw new \Exception('Unable to parse ZendRestModule annotation:' . " The route match for \"{$evt->getName()}\" is missing a \"controller\" param.");
     }
     return $controllerName;
 }
 /**
  * Render the view
  *
  * @param  MvcEvent $e
  * @return Response
  */
 public function render(MvcEvent $e)
 {
     $result = $e->getResult();
     if ($result instanceof Response) {
         return $result;
     }
     // Martial arguments
     $request = $e->getRequest();
     $response = $e->getResponse();
     $viewModel = $e->getViewModel();
     if (!$viewModel instanceof ViewModel) {
         return;
     }
     $view = $this->view;
     $view->setRequest($request);
     $view->setResponse($response);
     try {
         $view->render($viewModel);
     } catch (\Exception $ex) {
         if ($e->getName() === MvcEvent::EVENT_RENDER_ERROR) {
             throw $ex;
         }
         $application = $e->getApplication();
         $events = $application->getEventManager();
         $e->setError(Application::ERROR_EXCEPTION)->setParam('exception', $ex);
         $events->trigger(MvcEvent::EVENT_RENDER_ERROR, $e);
     }
     return $response;
 }
 /**
  * Render the view
  *
  * @param  MvcEvent $e
  * @return Response|null
  * @throws \Exception
  */
 public function render(MvcEvent $e)
 {
     $result = $e->getResult();
     if ($result instanceof Response) {
         return $result;
     }
     // Martial arguments
     $request = $e->getRequest();
     $response = $e->getResponse();
     $viewModel = $e->getViewModel();
     if (!$viewModel instanceof ViewModel) {
         return;
     }
     $view = $this->view;
     $view->setRequest($request);
     $view->setResponse($response);
     $caughtException = null;
     try {
         $view->render($viewModel);
     } catch (\Throwable $ex) {
         $caughtException = $ex;
     } catch (\Exception $ex) {
         // @TODO clean up once PHP 7 requirement is enforced
         $caughtException = $ex;
     }
     if ($caughtException !== null) {
         if ($e->getName() === MvcEvent::EVENT_RENDER_ERROR) {
             throw $caughtException;
         }
         $application = $e->getApplication();
         $events = $application->getEventManager();
         $e->setError(Application::ERROR_EXCEPTION);
         $e->setParam('exception', $caughtException);
         $e->setName(MvcEvent::EVENT_RENDER_ERROR);
         $events->triggerEvent($e);
     }
     return $response;
 }
Пример #4
0
 /**
  * @param MvcEvent $event
  */
 public function handleError(MvcEvent $event)
 {
     // Do nothing if no error in the event
     $error = $event->getError();
     if (empty($error)) {
         return;
     }
     switch ($error) {
         case Application::ERROR_CONTROLLER_NOT_FOUND:
         case Application::ERROR_CONTROLLER_INVALID:
             // Specifically not handling these
             return;
             break;
         case Application::ERROR_ROUTER_NO_MATCH:
             if ($event->getName() == MvcEvent::EVENT_DISPATCH_ERROR) {
                 // add dummy 'no-route' route to silent routeMatch errors
                 $noRoute = 'no-route';
                 $event->getRouter()->addRoute($noRoute, Router\Http\Literal::factory(['route' => '']));
                 $event->setRouteMatch((new Router\RouteMatch([]))->setMatchedRouteName($noRoute));
             }
             break;
         case Application::ERROR_EXCEPTION:
         default:
             $exception = $event->getParam('exception');
             $logMessages = array();
             do {
                 $priority = Logger::ERR;
                 $extra = array('file' => $exception->getFile(), 'line' => $exception->getLine(), 'trace' => $exception->getTrace());
                 if (isset($exception->xdebug_message)) {
                     $extra['xdebug'] = $exception->xdebug_message;
                 }
                 $logMessages[] = array('priority' => $priority, 'message' => $exception->getMessage(), 'extra' => $extra);
                 $exception = $exception->getPrevious();
             } while ($exception);
             foreach (array_reverse($logMessages) as $logMessage) {
                 $this->log->log($logMessage['priority'], $logMessage['message'], $logMessage['extra']);
             }
             break;
     }
 }
 /**
  * Attempt to validate the incoming request
  *
  * If an input filter is associated with the matched controller service,
  * attempt to validate the incoming request, and inject the event with the
  * input filter, as the "ZF\ContentValidation\InputFilter" parameter.
  *
  * Uses the ContentNegotiation ParameterDataContainer to retrieve parameters
  * to validate, and returns an ApiProblemResponse when validation fails.
  *
  * Also returns an ApiProblemResponse in cases of:
  *
  * - Invalid input filter service name
  * - Missing ParameterDataContainer (i.e., ContentNegotiation is not registered)
  *
  * @param MvcEvent $e
  * @return null|ApiProblemResponse
  */
 public function onRoute(MvcEvent $e)
 {
     $request = $e->getRequest();
     if (!$request instanceof HttpRequest) {
         return;
     }
     $routeMatches = $e->getRouteMatch();
     if (!($routeMatches instanceof RouteMatch || $routeMatches instanceof V2RouteMatch)) {
         return;
     }
     $controllerService = $routeMatches->getParam('controller', false);
     if (!$controllerService) {
         return;
     }
     $method = $request->getMethod();
     $inputFilterService = $this->getInputFilterService($controllerService, $method);
     if (!$inputFilterService) {
         return;
     }
     if (!$this->hasInputFilter($inputFilterService)) {
         return new ApiProblemResponse(new ApiProblem(500, sprintf('Listed input filter "%s" does not exist; cannot validate request', $inputFilterService)));
     }
     $dataContainer = $e->getParam('ZFContentNegotiationParameterData', false);
     if (!$dataContainer instanceof ParameterDataContainer) {
         return new ApiProblemResponse(new ApiProblem(500, 'ZF\\ContentNegotiation module is not initialized; cannot validate request'));
     }
     $data = in_array($method, $this->methodsWithoutBodies) ? $dataContainer->getQueryParams() : $dataContainer->getBodyParams();
     if (null === $data || '' === $data) {
         $data = [];
     }
     $isCollection = $this->isCollection($controllerService, $data, $routeMatches, $request);
     $files = $request->getFiles();
     if (!$isCollection && 0 < count($files)) {
         // File uploads are not validated for collections; impossible to
         // match file fields to discrete sets
         $data = ArrayUtils::merge($data, $files->toArray(), true);
     }
     $inputFilter = $this->getInputFilter($inputFilterService);
     if ($isCollection && !in_array($method, $this->methodsWithoutBodies)) {
         $collectionInputFilter = new CollectionInputFilter();
         $collectionInputFilter->setInputFilter($inputFilter);
         $inputFilter = $collectionInputFilter;
     }
     $e->setParam('ZF\\ContentValidation\\InputFilter', $inputFilter);
     $currentEventName = $e->getName();
     $e->setName(self::EVENT_BEFORE_VALIDATE);
     $events = $this->getEventManager();
     $results = $events->triggerEventUntil(function ($result) {
         return $result instanceof ApiProblem || $result instanceof ApiProblemResponse;
     }, $e);
     $e->setName($currentEventName);
     $last = $results->last();
     if ($last instanceof ApiProblem) {
         $last = new ApiProblemResponse($last);
     }
     if ($last instanceof ApiProblemResponse) {
         return $last;
     }
     $inputFilter->setData($data);
     $status = $request->isPatch() ? $this->validatePatch($inputFilter, $data, $isCollection) : $inputFilter->isValid();
     if ($status instanceof ApiProblemResponse) {
         return $status;
     }
     // Invalid? Return a 422 response.
     if (false === $status) {
         return new ApiProblemResponse(new ApiProblem(422, 'Failed Validation', null, null, ['validation_messages' => $inputFilter->getMessages()]));
     }
     // Should we use the raw data vs. the filtered data?
     // - If no `use_raw_data` flag is present, always use the raw data, as
     //   that was the default experience starting in 1.0.
     // - If the flag is present AND is boolean true, that is also
     //   an indicator that the raw data should be present.
     $useRawData = $this->useRawData($controllerService);
     if (!$useRawData) {
         $data = $inputFilter->getValues();
     }
     // If we don't have an instance of UnknownInputsCapableInterface, or no
     // unknown data is in the input filter, at this point we can just
     // set the current data into the data container.
     if (!$inputFilter instanceof UnknownInputsCapableInterface || !$inputFilter->hasUnknown()) {
         $dataContainer->setBodyParams($data);
         return;
     }
     $unknown = $inputFilter->getUnknown();
     if ($this->allowsOnlyFieldsInFilter($controllerService)) {
         if ($inputFilter instanceof CollectionInputFilter) {
             $unknownFields = [];
             foreach ($unknown as $key => $fields) {
                 $unknownFields[] = '[' . $key . ': ' . implode(', ', array_keys($fields)) . ']';
             }
             $fields = implode(', ', $unknownFields);
         } else {
             $fields = implode(', ', array_keys($unknown));
         }
         $detail = sprintf('Unrecognized fields: %s', $fields);
         $problem = new ApiProblem(Response::STATUS_CODE_422, $detail);
         return new ApiProblemResponse($problem);
     }
     // The raw data already contains unknown inputs, so no need to merge
     // them with the data.
     if ($useRawData) {
         $dataContainer->setBodyParams($data);
         return;
     }
     // When not using raw data, we merge the unknown data with the
     // validated data to get the full set of input.
     $dataContainer->setBodyParams(array_merge($data, $unknown));
 }
Пример #6
0
 /**
  * Create and return a 400 view model
  *
  * @param  MvcEvent $e
  * @return void
  */
 public function prepareBadRequestViewModel(MvcEvent $e)
 {
     $firephp = \FirePHP::getInstance(true);
     $firephp->info(__METHOD__);
     $firephp->info($e->getName(), 'event name');
     $vars = $e->getResult();
     if ($vars instanceof Response) {
         // Already have a response as the result
         return;
     }
     $response = $e->getResponse();
     if ($response->getStatusCode() != 400) {
         // Only handle 404 responses
         return;
     }
     if (!$vars instanceof ViewModel) {
         $firephp->info('creating new ViewModel');
         $model = new ViewModel();
         if (is_string($vars)) {
             $model->setVariable('message', $vars);
         } else {
             $model->setVariable('message', 'Bad request.');
         }
     } else {
         $firephp->info('updating existing view model');
         $model = $vars;
         if ($model->getVariable('message') === null) {
             $model->setVariable('message', 'Bad request.');
         }
     }
     $firephp->info($model->getTemplate(), 'view model template');
     $model->setTemplate($this->getBadRequestTemplate());
     $firephp->info($model->getVariable('reason'), 'before injecting reason');
     // If displaying reasons, inject the reason
     $this->injectBadRequestReason($model, $e);
     $firephp->info($model->getVariable('reason'), 'reason');
     // If displaying exceptions, inject
     $this->injectException($model, $e);
     $firephp->info($model->getVariable('exception'), 'exception');
     // Inject controller if we're displaying either the reason or the exception
     $this->injectController($model, $e);
     $firephp->info($model->getVariable('controller'), 'controller');
     $e->setResult($model);
 }
Пример #7
-1
 public function renderAssets(MvcEvent $e)
 {
     $sm = $e->getApplication()->getServiceManager();
     /** @var Configuration $config */
     $config = $sm->get('AsseticConfiguration');
     if ($e->getName() === MvcEvent::EVENT_DISPATCH_ERROR) {
         $error = $e->getError();
         if ($error && !in_array($error, $config->getAcceptableErrors())) {
             // break if not an acceptable error
             return;
         }
     }
     $response = $e->getResponse();
     if (!$response) {
         $response = new Response();
         $e->setResponse($response);
     }
     /** @var $asseticService \AsseticBundle\Service */
     $asseticService = $sm->get('AsseticService');
     // setup service if a matched route exist
     $router = $e->getRouteMatch();
     if ($router) {
         $asseticService->setRouteName($router->getMatchedRouteName());
         $asseticService->setControllerName($router->getParam('controller'));
         $asseticService->setActionName($router->getParam('action'));
     }
     // Create all objects
     $asseticService->build();
     // Init assets for modules
     $asseticService->setupRenderer($sm->get('ViewRenderer'));
 }
 /**
  * @param \Zend\Mvc\MvcEvent $object
  * @param array $options
  *
  * @return array
  */
 public function format($object, array $options)
 {
     $data['route']['name'] = $object->getRouteMatch()->getMatchedRouteName();
     $data['route']['params'] = $object->getRouteMatch()->getParams();
     $parts = explode('/', $data['route']['name']);
     $route = $object->getRouter();
     $config = $object->getApplication()->getServiceManager()->get('config');
     $config = isset($config['router']['routes']) ? $config['router']['routes'] : [];
     while ($part = array_shift($parts)) {
         $route->hasRoute($part) and $route = $route->getRoute($part);
         isset($config[$part]) and $config = $config[$part];
     }
     $data['route']['class'] = get_class($route);
     $data['route']['assembled'] = $route->getAssembledParams();
     $data['event']['error'] = $object->getError();
     $data['event']['name'] = $object->getName();
     $controllers = [];
     $definitions = [];
     $title = '404 Error';
     $subtitle = 'Unknown Error';
     $context = null;
     $manager = $object->getApplication()->getServiceManager()->get('ControllerLoader');
     switch ($object->getError()) {
         case Application::ERROR_CONTROLLER_NOT_FOUND:
             $definitions = $config;
             $title = $object->getControllerClass();
             $subtitle = 'The requested controller cannot be found';
             $controllers = $manager->getCanonicalNames();
             array_pop($controllers);
             // because the Sm add the wrong into the list
             break;
         case Application::ERROR_CONTROLLER_INVALID:
             $title = $object->getControllerClass();
             $subtitle = $object->getParam('exception')->getMessage();
             break;
         case Application::ERROR_CONTROLLER_CANNOT_DISPATCH:
             $context = $this->getControllerContext($manager, $data['route']['params']);
             $subtitle = 'The controller cannot dispatch the request';
             $title = $data['route']['params']['controller'];
             break;
     }
     $data['title'] = $title;
     $data['subtitle'] = $subtitle;
     $data['route']['definition'] = $definitions;
     $data['controller']['names'] = $controllers;
     $data['controller']['context'] = $context;
     return $data;
 }