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; }
Please login to continue.