You are here

public function ViewAjaxController::ajaxView in Drupal 10

Same name and namespace in other branches
  1. 8 core/modules/views/src/Controller/ViewAjaxController.php \Drupal\views\Controller\ViewAjaxController::ajaxView()
  2. 9 core/modules/views/src/Controller/ViewAjaxController.php \Drupal\views\Controller\ViewAjaxController::ajaxView()

Loads and renders a view via AJAX.

Parameters

\Symfony\Component\HttpFoundation\Request $request: The current request object.

Return value

\Drupal\views\Ajax\ViewAjaxResponse The view response as ajax response.

Throws

\Symfony\Component\HttpKernel\Exception\NotFoundHttpException Thrown when the view was not found.

1 string reference to 'ViewAjaxController::ajaxView'
views.routing.yml in core/modules/views/views.routing.yml
core/modules/views/views.routing.yml

File

core/modules/views/src/Controller/ViewAjaxController.php, line 113

Class

ViewAjaxController
Defines a controller to load a view via AJAX.

Namespace

Drupal\views\Controller

Code

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 = $args !== '' ? explode('/', Html::decodeEntities($args)) : [];

    // 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.
    // @todo Remove this parsing once these are removed from the request in
    //   https://www.drupal.org/node/2504709.
    foreach ([
      'view_name',
      'view_display_id',
      'view_args',
      'view_path',
      'view_dom_id',
      'pager_element',
      'view_base_path',
      AjaxResponseSubscriber::AJAX_REQUEST_PARAMETER,
      FormBuilderInterface::AJAX_FORM_REQUEST,
      MainContentViewSubscriber::WRAPPER_FORMAT,
    ] 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) && $view
      ->setDisplay($display_id) && $view->display_handler
      ->ajaxEnabled()) {
      $response
        ->setView($view);

      // Fix the current path for paging.
      if (!empty($path)) {
        $this->currentPath
          ->setPath('/' . ltrim($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();
      unset($request_all['ajax_page_state']);
      $query_all = $request->query
        ->all();
      $request->query
        ->replace($request_all + $query_all);

      // Overwrite the destination.
      // @see the redirect.destination service.
      $origin_destination = $path;
      $used_query_parameters = $request->query
        ->all();
      $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();
  }
}