/** * Initializes the proper view. * * @return \Drupal\views\ViewExecutable * The view executable. */ public function loadView() { if (empty($this->view)) { $metadata = $this->getMetaData(); $view_id = $metadata['view_id']; $display_id = $metadata['display_id']; $view_entity = $this->entityManager->getStorage('view')->load($view_id); $view = $this->viewExecutableFactory->get($view_entity); $view->setDisplay($display_id); $view->initDisplay(); $this->view = $view; } return $this->view; }
/** * Collects all REST end-points. * * @param \Drupal\Core\Routing\RouteBuildEvent $event * The route build event. */ public function onRouteAlter(RouteBuildEvent $event) { $collection = $event->getRouteCollection(); foreach ($collection->all() as $route_name => $route) { // Rest module endpoint. if (strpos($route_name, 'rest.') === 0) { $this->restRouteNames[$route_name] = $route_name; } // Views module route. if (strpos($route_name, 'view.') === 0 && ($parts = explode('.', $route_name)) && count($parts) == 3) { // We need to introspect the display type. list(, $view_id, $display_id) = $parts; $entity = $this->viewsStorage->load($view_id); if (empty($entity)) { // Non-existent view. continue; } // Build the view. if (empty($this->builtViews[$view_id])) { $this->builtViews[$view_id] = $this->executableFactory->get($entity); $view = $this->builtViews[$view_id]; } else { $view = $this->builtViews[$view_id]; } // Set the given display. $view->setDisplay($display_id); $display = $view->getDisplay(); if ($display instanceof RestExport) { $this->restRouteNames[$route_name] = $route_name; } } } }
/** * Tests the get method. * * @covers ::get */ public function testGet() { $request_1 = new Request(); $request_2 = new Request(); $this->requestStack->push($request_1); $executable = $this->viewExecutableFactory->get($this->view); $this->assertInstanceOf('Drupal\\views\\ViewExecutable', $executable); $this->assertSame($executable->getRequest(), $request_1); $this->assertSame($executable->getUser(), $this->user); // Call get() again to ensure a new executable is created with the other // request object. $this->requestStack->push($request_2); $executable = $this->viewExecutableFactory->get($this->view); $this->assertInstanceOf('Drupal\\views\\ViewExecutable', $executable); $this->assertSame($executable->getRequest(), $request_2); $this->assertSame($executable->getUser(), $this->user); }
/** * Constructs a \Drupal\views\Plugin\Block\ViewsBlockBase object. * * @param array $configuration * A configuration array containing information about the plugin instance. * @param string $plugin_id * The plugin_id for the plugin instance. * @param mixed $plugin_definition * The plugin implementation definition. * @param \Drupal\views\ViewExecutableFactory $executable_factory * The view executable factory. * @param \Drupal\Core\Entity\EntityStorageInterface $storage * The views storage. * @param \Drupal\Core\Session\AccountInterface $user * The current user. */ public function __construct(array $configuration, $plugin_id, $plugin_definition, ViewExecutableFactory $executable_factory, EntityStorageInterface $storage, AccountInterface $user) { $this->pluginId = $plugin_id; $delta = $this->getDerivativeId(); list($name, $this->displayID) = explode('-', $delta, 2); // Load the view. $view = $storage->load($name); $this->view = $executable_factory->get($view); $this->displaySet = $this->view->setDisplay($this->displayID); $this->user = $user; parent::__construct($configuration, $plugin_id, $plugin_definition); }
/** * Handles a response for a view. */ public function handle(Request $request) { $view_id = $request->attributes->get('view_id'); $display_id = $request->attributes->get('display_id'); $entity = $this->storage->load($view_id); if (empty($entity)) { throw new NotFoundHttpException(String::format('Page controller for view %id requested, but view was not found.', array('%id' => $view_id))); } $view = $this->executableFactory->get($entity); $view->setRequest($request); $view->setDisplay($display_id); $view->initHandlers(); $args = array(); $map = $request->attributes->get(RouteObjectInterface::ROUTE_OBJECT)->getOption('_view_argument_map', array()); $arguments_length = count($view->argument); for ($argument_index = 0; $argument_index < $arguments_length; $argument_index++) { // Allow parameters be pulled from the request. // The map stores the actual name of the parameter in the request. Views // which override existing controller, use for example 'node' instead of // arg_nid as name. $attribute = 'arg_' . $argument_index; if (isset($map[$attribute])) { $attribute = $map[$attribute]; // First try to get from the original values then on the not converted // ones. if ($request->attributes->has('_raw_variables')) { $arg = $request->attributes->get('_raw_variables')->get($attribute); } else { $arg = $request->attributes->get($attribute); } } else { $arg = $request->attributes->get($attribute); } if (isset($arg)) { $args[] = $arg; } } return $view->executeDisplay($display_id, $args); }
/** * Handler a response for a given view and display. * * @param string $view_id * The ID of the view * @param string $display_id * The ID of the display. * @param \Symfony\Component\HttpFoundation\Request $request * The request. * @param \Drupal\Core\Routing\RouteMatchInterface $route_match * The route match. * @return null|void */ public function handle($view_id, $display_id, Request $request, RouteMatchInterface $route_match) { $entity = $this->storage->load($view_id); if (empty($entity)) { throw new NotFoundHttpException(String::format('Page controller for view %id requested, but view was not found.', array('%id' => $view_id))); } $view = $this->executableFactory->get($entity); $view->setRequest($request); $view->setDisplay($display_id); $view->initHandlers(); $args = array(); $map = $route_match->getRouteObject()->getOption('_view_argument_map', array()); $arguments_length = count($view->argument); for ($argument_index = 0; $argument_index < $arguments_length; $argument_index++) { // Allow parameters be pulled from the request. // The map stores the actual name of the parameter in the request. Views // which override existing controller, use for example 'node' instead of // arg_nid as name. $attribute = 'arg_' . $argument_index; if (isset($map[$attribute])) { $attribute = $map[$attribute]; } if ($arg = $route_match->getRawParameter($attribute)) { } else { $arg = $route_match->getParameter($attribute); } if (isset($arg)) { $args[] = $arg; } } $plugin_definition = $view->display_handler->getPluginDefinition(); if (!empty($plugin_definition['returns_response'])) { return $view->executeDisplay($display_id, $args); } else { return $view->buildRenderable($display_id, $args); } }
/** * Loads and renders a view via AJAX. * * @param \Symfony\Component\HttpFoundation\Request $request * The current request object. * * @return \Drupal\views\Ajax\ViewAjaxResponse * The view response as ajax response. * * @throws \Symfony\Component\HttpKernel\Exception\NotFoundHttpException * Thrown when the view was not found. */ public function ajaxView(Request $request) { $name = $request->request->get('view_name'); $display_id = $request->request->get('view_display_id'); if (isset($name) && isset($display_id)) { $args = $request->request->get('view_args'); $args = isset($args) && $args !== '' ? explode('/', $args) : array(); // Arguments can be empty, make sure they are passed on as NULL so that // argument validation is not triggered. $args = array_map(function ($arg) { return $arg == '' ? NULL : $arg; }, $args); $path = $request->request->get('view_path'); $dom_id = $request->request->get('view_dom_id'); $dom_id = isset($dom_id) ? preg_replace('/[^a-zA-Z0-9_-]+/', '-', $dom_id) : NULL; $pager_element = $request->request->get('pager_element'); $pager_element = isset($pager_element) ? intval($pager_element) : NULL; $response = new ViewAjaxResponse(); // Remove all of this stuff from the query of the request so it doesn't // end up in pagers and tablesort URLs. foreach (array('view_name', 'view_display_id', 'view_args', 'view_path', 'view_dom_id', 'pager_element', 'view_base_path', AjaxResponseSubscriber::AJAX_REQUEST_PARAMETER) as $key) { $request->query->remove($key); $request->request->remove($key); } // Load the view. if (!($entity = $this->storage->load($name))) { throw new NotFoundHttpException(); } $view = $this->executableFactory->get($entity); if ($view && $view->access($display_id)) { $response->setView($view); // Fix the current path for paging. if (!empty($path)) { $this->currentPath->setPath('/' . $path, $request); } // Add all POST data, because AJAX is always a post and many things, // such as tablesorts, exposed filters and paging assume GET. $request_all = $request->request->all(); $query_all = $request->query->all(); $request->query->replace($request_all + $query_all); // Overwrite the destination. // @see the redirect.destination service. $origin_destination = $path; // Remove some special parameters you never want to have part of the // destination query. $used_query_parameters = $request->query->all(); // @todo Remove this parsing once these are removed from the request in // https://www.drupal.org/node/2504709. unset($used_query_parameters[FormBuilderInterface::AJAX_FORM_REQUEST], $used_query_parameters[MainContentViewSubscriber::WRAPPER_FORMAT], $used_query_parameters['ajax_page_state']); $query = UrlHelper::buildQuery($used_query_parameters); if ($query != '') { $origin_destination .= '?' . $query; } $this->redirectDestination->set($origin_destination); // Override the display's pager_element with the one actually used. if (isset($pager_element)) { $response->addCommand(new ScrollTopCommand(".js-view-dom-id-{$dom_id}")); $view->displayHandlers->get($display_id)->setOption('pager_element', $pager_element); } // Reuse the same DOM id so it matches that in drupalSettings. $view->dom_id = $dom_id; $context = new RenderContext(); $preview = $this->renderer->executeInRenderContext($context, function () use($view, $display_id, $args) { return $view->preview($display_id, $args); }); if (!$context->isEmpty()) { $bubbleable_metadata = $context->pop(); BubbleableMetadata::createFromRenderArray($preview)->merge($bubbleable_metadata)->applyTo($preview); } $response->addCommand(new ReplaceCommand(".js-view-dom-id-{$dom_id}", $preview)); return $response; } else { throw new AccessDeniedHttpException(); } } else { throw new NotFoundHttpException(); } }
/** * Loads and renders a view via AJAX. * * @param \Symfony\Component\HttpFoundation\Request $request * The current request object. * * @return \Drupal\views\Ajax\ViewAjaxResponse * The view response as ajax response. * * @throws \Symfony\Component\HttpKernel\Exception\NotFoundHttpException * Thrown when the view was not found. */ public function ajaxView(Request $request) { $name = $request->request->get('view_name'); $display_id = $request->request->get('view_display_id'); if (isset($name) && isset($display_id)) { $args = $request->request->get('view_args'); $args = isset($args) && $args !== '' ? explode('/', $args) : array(); // Arguments can be empty, make sure they are passed on as NULL so that // argument validation is not triggered. $args = array_map(function ($arg) { return $arg == '' ? NULL : $arg; }, $args); $path = $request->request->get('view_path'); $dom_id = $request->request->get('view_dom_id'); $dom_id = isset($dom_id) ? preg_replace('/[^a-zA-Z0-9_-]+/', '-', $dom_id) : NULL; $pager_element = $request->request->get('pager_element'); $pager_element = isset($pager_element) ? intval($pager_element) : NULL; $response = new ViewAjaxResponse(); // Remove all of this stuff from the query of the request so it doesn't // end up in pagers and tablesort URLs. foreach (array('view_name', 'view_display_id', 'view_args', 'view_path', 'view_dom_id', 'pager_element', 'view_base_path', 'ajax_html_ids') as $key) { $request->query->remove($key); $request->request->remove($key); } // Load the view. if (!($entity = $this->storage->load($name))) { throw new NotFoundHttpException(); } $view = $this->executableFactory->get($entity); if ($view && $view->access($display_id)) { $response->setView($view); // Fix the current path for paging. if (!empty($path)) { $this->currentPath->setPath('/' . $path, $request); } // Add all POST data, because AJAX is always a post and many things, // such as tablesorts, exposed filters and paging assume GET. $request_all = $request->request->all(); $query_all = $request->query->all(); $request->query->replace($request_all + $query_all); // Overwrite the destination. // @see the redirect.destination service. $origin_destination = $path; $query = UrlHelper::buildQuery($request->query->all()); if ($query != '') { $origin_destination .= '?' . $query; } $this->redirectDestination->set($origin_destination); // Override the display's pager_element with the one actually used. if (isset($pager_element)) { $response->addCommand(new ScrollTopCommand(".view-dom-id-{$dom_id}")); $view->displayHandlers->get($display_id)->setOption('pager_element', $pager_element); } // Reuse the same DOM id so it matches that in drupalSettings. $view->dom_id = $dom_id; if ($preview = $view->preview($display_id, $args)) { $response->addCommand(new ReplaceCommand(".view-dom-id-{$dom_id}", $this->renderer->render($preview))); $response->setAttachments($preview['#attached']); } return $response; } else { throw new AccessDeniedHttpException(); } } else { throw new NotFoundHttpException(); } }