Esempio n. 1
0
 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');
         views_ui_contextual_links_suppress_pop();
         // Prepare the query information and statistics to show either above or
         // below the view preview.
         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($executable->render_time * 100000) / 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 = 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>');
     if ($show_location === 'above' || $show_location === 'below') {
         if ($combined) {
             $table['#rows'] = array_merge($rows['query'], $rows['statistics']);
         } else {
             $table['#rows'] = $rows['query'];
         }
     } elseif ($show_stats === 'above' || $show_stats === 'below') {
         $table['#rows'] = $rows['statistics'];
     }
     if ($show_location === 'above' || $show_stats === 'above') {
         $output = ['table' => $table, 'preview' => $preview];
     } elseif ($show_location === 'below' || $show_stats === 'below') {
         $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;
 }
Esempio n. 2
0
 public function renderPreview($display_id, $args = array())
 {
     // Save the current path so it can be restored before returning from this function.
     $old_q = current_path();
     // 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());
     $output = '';
     $errors = $this->executable->validate();
     $this->executable->destroy();
     if (empty($errors)) {
         $this->ajax = TRUE;
         $this->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', 'ajax_html_ids', 'ajax_page_state', 'form_id', 'form_build_id', 'form_token') as $key) {
             if (isset($exposed_input[$key])) {
                 unset($exposed_input[$key]);
             }
         }
         $this->executable->setExposedInput($exposed_input);
         if (!$this->executable->setDisplay($display_id)) {
             return t('Invalid display id @display', array('@display' => $display_id));
         }
         $this->executable->setArguments($args);
         // Store the current view URL for later use:
         if ($this->executable->display_handler->getOption('path')) {
             $path = $this->executable->getUrl();
         }
         // Make view links come back to preview.
         $this->override_path = 'admin/structure/views/view/' . $this->id() . '/preview/' . $display_id;
         // Also override the current path so we get the pager.
         $original_path = current_path();
         $q = _current_path($this->override_path);
         if ($args) {
             $q .= '/' . implode('/', $args);
             _current_path($q);
         }
         // 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 = $this->executable->preview($display_id, $args);
         $preview = drupal_render($preview);
         if ($show_additional_queries) {
             $this->endQueryCapture();
         }
         $this->render_time = Timer::stop('entity.view.preview_form');
         views_ui_contextual_links_suppress_pop();
         // Reset variables.
         unset($this->override_path);
         _current_path($original_path);
         // Prepare the query information and statistics to show either above or
         // below the view preview.
         if ($show_info || $show_query || $show_stats) {
             // Get information from the preview for display.
             if (!empty($this->executable->build_info['query'])) {
                 if ($show_query) {
                     $query_string = $this->executable->build_info['query'];
                     // Only the sql default class has a method getArguments.
                     $quoted = array();
                     if ($this->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 = '<strong>' . t('These queries were run during view rendering:') . '</strong>';
                         foreach ($this->additionalQueries as $query) {
                             if ($queries) {
                                 $queries .= "\n";
                             }
                             $query_string = strtr($query['query'], $query['args']);
                             $queries .= 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>")), SafeMarkup::set('<pre>' . $queries . '</pre>'));
                     }
                 }
                 if ($show_info) {
                     $rows['query'][] = array(array('data' => array('#type' => 'inline_template', '#template' => "<strong>{% trans 'Title' %}</strong>")), Xss::filterAdmin($this->executable->getTitle()));
                     if (isset($path)) {
                         $path = _l($path, $path);
                     } else {
                         $path = t('This display has no path.');
                     }
                     $rows['query'][] = array(SafeMarkup::set('<strong>' . t('Path') . '</strong>'), $path);
                 }
                 if ($show_stats) {
                     $rows['statistics'][] = array('<strong>' . t('Query build time') . '</strong>', t('@time ms', array('@time' => intval($this->executable->build_time * 100000) / 100)));
                     $rows['statistics'][] = array('<strong>' . t('Query execute time') . '</strong>', t('@time ms', array('@time' => intval($this->executable->execute_time * 100000) / 100)));
                     $rows['statistics'][] = array('<strong>' . t('View render time') . '</strong>', t('@time ms', array('@time' => intval($this->executable->render_time * 100000) / 100)));
                 }
                 \Drupal::moduleHandler()->alter('views_preview_info', $rows, $this->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(SafeMarkup::set('<strong>' . t('Query') . '</strong>'), t('No query was run')));
                 } else {
                     $rows['statistics'] = array(array(SafeMarkup::set('<strong>' . t('Query') . '</strong>'), t('No query was run')));
                 }
             }
         }
     } else {
         foreach ($errors as $display_errors) {
             foreach ($display_errors as $error) {
                 drupal_set_message($error, 'error');
             }
         }
         $preview = 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>');
     if ($show_location === 'above' || $show_location === 'below') {
         if ($combined) {
             $table['#rows'] = array_merge($rows['query'], $rows['statistics']);
         } else {
             $table['#rows'] = $rows['query'];
         }
     } elseif ($show_stats === 'above' || $show_stats === 'below') {
         $table['#rows'] = $rows['statistics'];
     }
     if ($show_location === 'above' || $show_stats === 'above') {
         $output .= drupal_render($table) . $preview;
     } elseif ($show_location === 'below' || $show_stats === 'below') {
         $output .= $preview . drupal_render($table);
     }
     _current_path($old_q);
     return $output;
 }