function ViewAjaxController::ajaxView

Same name in other branches
  1. 9 core/modules/views/src/Controller/ViewAjaxController.php \Drupal\views\Controller\ViewAjaxController::ajaxView()
  2. 8.9.x core/modules/views/src/Controller/ViewAjaxController.php \Drupal\views\Controller\ViewAjaxController::ajaxView()
  3. 10 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 128

Class

ViewAjaxController
Defines a controller to load a view via AJAX.

Namespace

Drupal\views\Controller

Code

public function ajaxView(Request $request) {
    $name = $request->get('view_name');
    $display_id = $request->get('view_display_id');
    if (isset($name) && isset($display_id)) {
        $args = $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->get('view_path');
        $dom_id = $request->get('view_dom_id');
        $dom_id = isset($dom_id) ? preg_replace('/[^a-zA-Z0-9_-]+/', '-', $dom_id) : NULL;
        $pager_element = $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. Additionally we need to preserve
        // ajax_page_state and add it back after the request has been processed so
        // the related listener can behave correctly.
        // @todo Remove this parsing once these are removed from the request in
        //   https://www.drupal.org/node/2504709.
        $existing_page_state = $request->get('ajax_page_state');
        foreach (self::FILTERED_QUERY_PARAMETERS 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);
            }
            // Create a clone of the request object to avoid mutating the request
            // object stored in the request stack.
            $request_clone = clone $request;
            // Add all POST data, because AJAX is sometimes a POST and many things,
            // such as tablesorts, exposed filters and paging assume GET.
            $param_union = $request_clone->request
                ->all() + $request_clone->query
                ->all();
            $request_clone->query
                ->replace($param_union);
            // Overwrite the destination.
            // @see the redirect.destination service.
            $origin_destination = $request_clone->getBasePath() . '/' . ltrim($path ?? '/', '/');
            $used_query_parameters = $request_clone->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;
            // Populate request attributes temporarily with ajax_page_state theme
            // and theme_token for theme negotiation.
            $theme_keys = [
                'theme' => TRUE,
                'theme_token' => TRUE,
            ];
            if (is_array($existing_page_state) && ($temp_attributes = array_intersect_key($existing_page_state, $theme_keys))) {
                $request->attributes
                    ->set('ajax_page_state', $temp_attributes);
            }
            $preview = $view->preview($display_id, $args);
            $request->attributes
                ->remove('ajax_page_state');
            $response->addCommand(new ReplaceCommand(".js-view-dom-id-{$dom_id}", $preview));
            $response->addCommand(new PrependCommand(".js-view-dom-id-{$dom_id}", [
                '#type' => 'status_messages',
            ]));
            $request->query
                ->set('ajax_page_state', $existing_page_state);
            if (!empty($preview['#attached'])) {
                $response->setAttachments($preview['#attached']);
            }
            return $response;
        }
        else {
            throw new AccessDeniedHttpException();
        }
    }
    else {
        throw new NotFoundHttpException();
    }
}

Buggy or inaccurate documentation? Please file an issue. Need support? Need help programming? Connect with the Drupal community.