Chris@0: storage = $storage; Chris@0: $this->executableFactory = $executable_factory; Chris@0: $this->renderer = $renderer; Chris@0: $this->currentPath = $current_path; Chris@0: $this->redirectDestination = $redirect_destination; Chris@0: } Chris@0: Chris@0: /** Chris@0: * {@inheritdoc} Chris@0: */ Chris@0: public static function create(ContainerInterface $container) { Chris@0: return new static( Chris@0: $container->get('entity.manager')->getStorage('view'), Chris@0: $container->get('views.executable'), Chris@0: $container->get('renderer'), Chris@0: $container->get('path.current'), Chris@0: $container->get('redirect.destination') Chris@0: ); Chris@0: } Chris@0: Chris@0: /** Chris@0: * Loads and renders a view via AJAX. Chris@0: * Chris@0: * @param \Symfony\Component\HttpFoundation\Request $request Chris@0: * The current request object. Chris@0: * Chris@0: * @return \Drupal\views\Ajax\ViewAjaxResponse Chris@0: * The view response as ajax response. Chris@0: * Chris@0: * @throws \Symfony\Component\HttpKernel\Exception\NotFoundHttpException Chris@0: * Thrown when the view was not found. Chris@0: */ Chris@0: public function ajaxView(Request $request) { Chris@0: $name = $request->request->get('view_name'); Chris@0: $display_id = $request->request->get('view_display_id'); Chris@0: if (isset($name) && isset($display_id)) { Chris@0: $args = $request->request->get('view_args'); Chris@0: $args = isset($args) && $args !== '' ? explode('/', $args) : []; Chris@0: Chris@0: // Arguments can be empty, make sure they are passed on as NULL so that Chris@0: // argument validation is not triggered. Chris@0: $args = array_map(function ($arg) { Chris@0: return ($arg == '' ? NULL : $arg); Chris@0: }, $args); Chris@0: Chris@0: $path = $request->request->get('view_path'); Chris@0: $dom_id = $request->request->get('view_dom_id'); Chris@0: $dom_id = isset($dom_id) ? preg_replace('/[^a-zA-Z0-9_-]+/', '-', $dom_id) : NULL; Chris@0: $pager_element = $request->request->get('pager_element'); Chris@0: $pager_element = isset($pager_element) ? intval($pager_element) : NULL; Chris@0: Chris@0: $response = new ViewAjaxResponse(); Chris@0: Chris@0: // Remove all of this stuff from the query of the request so it doesn't Chris@0: // end up in pagers and tablesort URLs. Chris@16: // @todo Remove this parsing once these are removed from the request in Chris@16: // https://www.drupal.org/node/2504709. Chris@16: foreach ([ Chris@16: 'view_name', Chris@16: 'view_display_id', Chris@16: 'view_args', Chris@16: 'view_path', Chris@16: 'view_dom_id', Chris@16: 'pager_element', Chris@16: 'view_base_path', Chris@16: AjaxResponseSubscriber::AJAX_REQUEST_PARAMETER, Chris@16: FormBuilderInterface::AJAX_FORM_REQUEST, Chris@16: MainContentViewSubscriber::WRAPPER_FORMAT, Chris@16: ] as $key) { Chris@0: $request->query->remove($key); Chris@0: $request->request->remove($key); Chris@0: } Chris@0: Chris@0: // Load the view. Chris@0: if (!$entity = $this->storage->load($name)) { Chris@0: throw new NotFoundHttpException(); Chris@0: } Chris@0: $view = $this->executableFactory->get($entity); Chris@0: if ($view && $view->access($display_id) && $view->setDisplay($display_id) && $view->display_handler->ajaxEnabled()) { Chris@0: $response->setView($view); Chris@0: // Fix the current path for paging. Chris@0: if (!empty($path)) { Chris@0: $this->currentPath->setPath('/' . $path, $request); Chris@0: } Chris@0: Chris@0: // Add all POST data, because AJAX is always a post and many things, Chris@0: // such as tablesorts, exposed filters and paging assume GET. Chris@0: $request_all = $request->request->all(); Chris@16: unset($request_all['ajax_page_state']); Chris@0: $query_all = $request->query->all(); Chris@0: $request->query->replace($request_all + $query_all); Chris@0: Chris@0: // Overwrite the destination. Chris@0: // @see the redirect.destination service. Chris@0: $origin_destination = $path; Chris@0: Chris@0: $used_query_parameters = $request->query->all(); Chris@0: $query = UrlHelper::buildQuery($used_query_parameters); Chris@0: if ($query != '') { Chris@0: $origin_destination .= '?' . $query; Chris@0: } Chris@0: $this->redirectDestination->set($origin_destination); Chris@0: Chris@0: // Override the display's pager_element with the one actually used. Chris@0: if (isset($pager_element)) { Chris@0: $response->addCommand(new ScrollTopCommand(".js-view-dom-id-$dom_id")); Chris@0: $view->displayHandlers->get($display_id)->setOption('pager_element', $pager_element); Chris@0: } Chris@0: // Reuse the same DOM id so it matches that in drupalSettings. Chris@0: $view->dom_id = $dom_id; Chris@0: Chris@0: $context = new RenderContext(); Chris@0: $preview = $this->renderer->executeInRenderContext($context, function () use ($view, $display_id, $args) { Chris@0: return $view->preview($display_id, $args); Chris@0: }); Chris@0: if (!$context->isEmpty()) { Chris@0: $bubbleable_metadata = $context->pop(); Chris@0: BubbleableMetadata::createFromRenderArray($preview) Chris@0: ->merge($bubbleable_metadata) Chris@0: ->applyTo($preview); Chris@0: } Chris@0: $response->addCommand(new ReplaceCommand(".js-view-dom-id-$dom_id", $preview)); Chris@0: Chris@0: return $response; Chris@0: } Chris@0: else { Chris@0: throw new AccessDeniedHttpException(); Chris@0: } Chris@0: } Chris@0: else { Chris@0: throw new NotFoundHttpException(); Chris@0: } Chris@0: } Chris@0: Chris@0: }