ViewUI::renderPreview

public ViewUI::renderPreview($display_id, $args = array())

File

core/modules/views_ui/src/ViewUI.php, line 515

Class

ViewUI
Stores UI related temporary settings.

Namespace

Drupal\views_ui

Code

public function renderPreview($display_id, $args = array()) {
  // Save the current path so it can be restored before returning from this function.
  $request_stack = \Drupal::requestStack();
  $current_request = $request_stack->getCurrentRequest();
  $executable = $this->getExecutable();

  // Determine where the query and performance statistics should be output.
  $config = \Drupal::config('views.settings');
  $show_query = $config->get('ui.show.sql_query.enabled');
  $show_info = $config->get('ui.show.preview_information');
  $show_location = $config->get('ui.show.sql_query.where');

  $show_stats = $config->get('ui.show.performance_statistics');
  if ($show_stats) {
    $show_stats = $config->get('ui.show.sql_query.where');
  }

  $combined = $show_query && $show_stats;

  $rows = array('query' => array(), 'statistics' => array());

  $errors = $executable->validate();
  $executable->destroy();
  if (empty($errors)) {
    $this->ajax = TRUE;
    $executable->live_preview = TRUE;

    // AJAX happens via HTTP POST but everything expects exposed data to
    // be in GET. Copy stuff but remove ajax-framework specific keys.
    // If we're clicking on links in a preview, though, we could actually
    // have some input in the query parameters, so we merge request() and
    // query() to ensure we get it all.
    $exposed_input = array_merge(\Drupal::request()->request->all(), \Drupal::request()->query->all());
    foreach (array('view_name', 'view_display_id', 'view_args', 'view_path', 'view_dom_id', 'pager_element', 'view_base_path', AjaxResponseSubscriber::AJAX_REQUEST_PARAMETER, 'ajax_page_state', 'form_id', 'form_build_id', 'form_token') as $key) {
      if (isset($exposed_input[$key])) {
        unset($exposed_input[$key]);
      }
    }
    $executable->setExposedInput($exposed_input);

    if (!$executable->setDisplay($display_id)) {
      return [
        '#markup' => t('Invalid display id @display', array('@display' => $display_id)),
      ];
    }

    $executable->setArguments($args);

    // Store the current view URL for later use:
    if ($executable->hasUrl() && $executable->display_handler->getOption('path')) {
      $path = $executable->getUrl();
    }

    // Make view links come back to preview.

    // Also override the current path so we get the pager, and make sure the
    // Request object gets all of the proper values from $_SERVER.
    $request = Request::createFromGlobals();
    $request->attributes->set(RouteObjectInterface::ROUTE_NAME, 'entity.view.preview_form');
    $request->attributes->set(RouteObjectInterface::ROUTE_OBJECT, \Drupal::service('router.route_provider')->getRouteByName('entity.view.preview_form'));
    $request->attributes->set('view', $this->storage);
    $request->attributes->set('display_id', $display_id);
    $raw_parameters = new ParameterBag();
    $raw_parameters->set('view', $this->id());
    $raw_parameters->set('display_id', $display_id);
    $request->attributes->set('_raw_variables', $raw_parameters);

    foreach ($args as $key => $arg) {
      $request->attributes->set('arg_' . $key, $arg);
    }
    $request_stack->push($request);

    // Suppress contextual links of entities within the result set during a
    // Preview.
    // @todo We'll want to add contextual links specific to editing the View, so
    //   the suppression may need to be moved deeper into the Preview pipeline.
    views_ui_contextual_links_suppress_push();

    $show_additional_queries = $config->get('ui.show.additional_queries');

    Timer::start('entity.view.preview_form');

    if ($show_additional_queries) {
      $this->startQueryCapture();
    }

    // Execute/get the view preview.
    $preview = $executable->preview($display_id, $args);

    if ($show_additional_queries) {
      $this->endQueryCapture();
    }

    $this->render_time = Timer::stop('entity.view.preview_form') ['time'];

    views_ui_contextual_links_suppress_pop();

    // Prepare the query information and statistics to show either above or
    // below the view preview.
    // Initialise the empty rows arrays so we can safely merge them later.
    $rows['query'] = [];
    $rows['statistics'] = [];
    if ($show_info || $show_query || $show_stats) {
      // Get information from the preview for display.
      if (!empty($executable->build_info['query'])) {
        if ($show_query) {
          $query_string = $executable->build_info['query'];
          // Only the sql default class has a method getArguments.
          $quoted = array();

          if ($executable->query instanceof Sql) {
            $quoted = $query_string->getArguments();
            $connection = Database::getConnection();
            foreach ($quoted as $key => $val) {
              if (is_array($val)) {
                $quoted[$key] = implode(', ', array_map(array($connection, 'quote'), $val));
              }
              else {
                $quoted[$key] = $connection->quote($val);
              }
            }
          }
          $rows['query'][] = array(
            array(
              'data' => array(
                '#type' => 'inline_template',
                '#template' => "<strong>{% trans 'Query' %}</strong>",
              ),
            ),
            array(
              'data' => array(
                '#type' => 'inline_template',
                '#template' => '<pre>{{ query }}</pre>',
                '#context' => array('query' => strtr($query_string, $quoted)),
              ),
            ),
          );
          if (!empty($this->additionalQueries)) {
            $queries[] = array(
              '#prefix' => '<strong>',
              '#markup' => t('These queries were run during view rendering:'),
              '#suffix' => '</strong>',
            );
            foreach ($this->additionalQueries as $query) {
              $query_string = strtr($query['query'], $query['args']);
              $queries[] = array(
                '#prefix' => "\n",
                '#markup' => t('[@time ms] @query', array('@time' => round($query['time'] * 100000, 1) / 100000.0, '@query' => $query_string)),
              );
            }

            $rows['query'][] = array(
              array(
                'data' => array(
                  '#type' => 'inline_template',
                  '#template' => "<strong>{% trans 'Other queries' %}</strong>",
                ),
              ),
              array(
                'data' => array(
                  '#prefix' => '<pre>',
                  'queries' => $queries,
                  '#suffix' => '</pre>',
                ),
              ),
            );
          }
        }
        if ($show_info) {
          $rows['query'][] = array(
            array(
              'data' => array(
                '#type' => 'inline_template',
                '#template' => "<strong>{% trans 'Title' %}</strong>",
              ),
            ),
            Xss::filterAdmin($executable->getTitle()),
          );
          if (isset($path)) {
            // @todo Views should expect and store a leading /. See:
            //   https://www.drupal.org/node/2423913
            $path = \Drupal::l($path->toString(), $path);
          }
          else {
            $path = t('This display has no path.');
          }
          $rows['query'][] = array(
            array(
              'data' => array(
                '#prefix' => '<strong>',
                '#markup' => t('Path'),
                '#suffix' => '</strong>',
              ),
            ),
            array(
              'data' => array(
                '#markup' => $path,
              ),
            )
          );
        }
        if ($show_stats) {
          $rows['statistics'][] = array(
            array(
              'data' => array(
                '#type' => 'inline_template',
                '#template' => "<strong>{% trans 'Query build time' %}</strong>",
              ),
            ),
            t('@time ms', array('@time' => intval($executable->build_time * 100000) / 100)),
          );

          $rows['statistics'][] = array(
            array(
              'data' => array(
                '#type' => 'inline_template',
                '#template' => "<strong>{% trans 'Query execute time' %}</strong>",
              ),
            ),
            t('@time ms', array('@time' => intval($executable->execute_time * 100000) / 100)),
          );

          $rows['statistics'][] = array(
            array(
              'data' => array(
                '#type' => 'inline_template',
                '#template' => "<strong>{% trans 'View render time' %}</strong>",
              ),
            ),
            t('@time ms', array('@time' => intval($this->render_time * 100) / 100)),
          );
        }
        \Drupal::moduleHandler()->alter('views_preview_info', $rows, $executable);
      }
      else {
        // No query was run. Display that information in place of either the
        // query or the performance statistics, whichever comes first.
        if ($combined || ($show_location === 'above')) {
          $rows['query'][] = array(
            array(
              'data' => array(
                '#prefix' => '<strong>',
                '#markup' => t('Query'),
                '#suffix' => '</strong>',
              ),
            ),
            array(
              'data' => array(
                '#markup' => t('No query was run'),
              ),
            ),
          );
        }
        else {
          $rows['statistics'][] = array(
            array(
              'data' => array(
                '#prefix' => '<strong>',
                '#markup' => t('Query'),
                '#suffix' => '</strong>',
              ),
            ),
            array(
              'data' => array(
                '#markup' => t('No query was run'),
              ),
            ),
          );
        }
      }
    }
  }
  else {
    foreach ($errors as $display_errors) {
      foreach ($display_errors as $error) {
        drupal_set_message($error, 'error');
      }
    }
    $preview = ['#markup' => t('Unable to preview due to validation errors.')];
  }

  // Assemble the preview, the query info, and the query statistics in the
  // requested order.
  $table = array(
    '#type' => 'table',
    '#prefix' => '<div class="views-query-info">',
    '#suffix' => '</div>',
    '#rows' => array_merge($rows['query'], $rows['statistics']),
  );

  if ($show_location == 'above') {
    $output = [
      'table' => $table,
      'preview' => $preview,
    ];
  }
  else {
    $output = [
      'preview' => $preview,
      'table' => $table,
    ];
  }

  // Ensure that we just remove an additional request we pushed earlier.
  // This could happen if $errors was not empty.
  if ($request_stack->getCurrentRequest() != $current_request) {
    $request_stack->pop();
  }
  return $output;
}
doc_Drupal
2016-10-29 09:56:04
Comments
Leave a Comment

Please login to continue.