Code Coverage |
||||||||||
Classes and Traits |
Functions and Methods |
Lines |
||||||||
| Total | |
0.00% |
0 / 1 |
|
75.00% |
3 / 4 |
CRAP | |
83.61% |
51 / 61 |
| ViewAjaxController | |
0.00% |
0 / 1 |
|
75.00% |
3 / 4 |
20.59 | |
83.61% |
51 / 61 |
| __construct | |
100.00% |
1 / 1 |
1 | |
100.00% |
6 / 6 |
|||
| create | |
0.00% |
0 / 1 |
2 | |
0.00% |
0 / 6 |
|||
| ajaxView | |
100.00% |
1 / 1 |
16 | |
100.00% |
38 / 38 |
|||
| anonymous function | |
100.00% |
1 / 1 |
1 | |
100.00% |
2 / 2 |
|||
| <?php | |
| /** | |
| * @file | |
| * Contains \Drupal\views\Controller\ViewAjaxController. | |
| */ | |
| namespace Drupal\views\Controller; | |
| use Drupal\Component\Utility\UrlHelper; | |
| use Drupal\Core\Ajax\ReplaceCommand; | |
| use Drupal\Core\DependencyInjection\ContainerInjectionInterface; | |
| use Drupal\Core\Entity\EntityStorageInterface; | |
| use Drupal\Core\EventSubscriber\AjaxResponseSubscriber; | |
| use Drupal\Core\EventSubscriber\MainContentViewSubscriber; | |
| use Drupal\Core\Form\FormBuilderInterface; | |
| use Drupal\Core\Path\CurrentPathStack; | |
| use Drupal\Core\Render\BubbleableMetadata; | |
| use Drupal\Core\Render\RenderContext; | |
| use Drupal\Core\Render\RendererInterface; | |
| use Drupal\Core\Routing\RedirectDestinationInterface; | |
| use Drupal\views\Ajax\ScrollTopCommand; | |
| use Drupal\views\Ajax\ViewAjaxResponse; | |
| use Drupal\views\ViewExecutableFactory; | |
| use Symfony\Component\DependencyInjection\ContainerInterface; | |
| use Symfony\Component\HttpFoundation\Request; | |
| use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; | |
| use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException; | |
| /** | |
| * Defines a controller to load a view via AJAX. | |
| */ | |
| class ViewAjaxController implements ContainerInjectionInterface { | |
| /** | |
| * The entity storage for views. | |
| * | |
| * @var \Drupal\Core\Entity\EntityStorageInterface | |
| */ | |
| protected $storage; | |
| /** | |
| * The factory to load a view executable with. | |
| * | |
| * @var \Drupal\views\ViewExecutableFactory | |
| */ | |
| protected $executableFactory; | |
| /** | |
| * The renderer. | |
| * | |
| * @var \Drupal\Core\Render\RendererInterface | |
| */ | |
| protected $renderer; | |
| /** | |
| * The current path. | |
| * | |
| * @var \Drupal\Core\Path\CurrentPathStack | |
| */ | |
| protected $currentPath; | |
| /** | |
| * The redirect destination. | |
| * | |
| * @var \Drupal\Core\Routing\RedirectDestinationInterface | |
| */ | |
| protected $redirectDestination; | |
| /** | |
| * Constructs a ViewAjaxController object. | |
| * | |
| * @param \Drupal\Core\Entity\EntityStorageInterface $storage | |
| * The entity storage for views. | |
| * @param \Drupal\views\ViewExecutableFactory $executable_factory | |
| * The factory to load a view executable with. | |
| * @param \Drupal\Core\Render\RendererInterface $renderer | |
| * The renderer. | |
| * @param \Drupal\Core\Path\CurrentPathStack $current_path | |
| * The current path. | |
| * @param \Drupal\Core\Routing\RedirectDestinationInterface $redirect_destination | |
| * The redirect destination. | |
| */ | |
| public function __construct(EntityStorageInterface $storage, ViewExecutableFactory $executable_factory, RendererInterface $renderer, CurrentPathStack $current_path, RedirectDestinationInterface $redirect_destination) { | |
| $this->storage = $storage; | |
| $this->executableFactory = $executable_factory; | |
| $this->renderer = $renderer; | |
| $this->currentPath = $current_path; | |
| $this->redirectDestination = $redirect_destination; | |
| } | |
| /** | |
| * {@inheritdoc} | |
| */ | |
| public static function create(ContainerInterface $container) { | |
| return new static( | |
| $container->get('entity.manager')->getStorage('view'), | |
| $container->get('views.executable'), | |
| $container->get('renderer'), | |
| $container->get('path.current'), | |
| $container->get('redirect.destination') | |
| ); | |
| } | |
| /** | |
| * 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(); | |
| } | |
| } | |
| } |