diff --git a/core/modules/entity_reference/lib/Drupal/entity_reference/Plugin/views/style/EntityReference.php b/core/modules/entity_reference/lib/Drupal/entity_reference/Plugin/views/style/EntityReference.php index f3763e3f00d..b8dba2d6715 100644 --- a/core/modules/entity_reference/lib/Drupal/entity_reference/Plugin/views/style/EntityReference.php +++ b/core/modules/entity_reference/lib/Drupal/entity_reference/Plugin/views/style/EntityReference.php @@ -91,7 +91,7 @@ class EntityReference extends StylePluginBase { foreach ($sets as $records) { foreach ($records as $values) { // Sanitize HTML, remove line breaks and extra whitespace. - $output = $this->row_plugin->render($values); + $output = $this->view->rowPlugin->render($values); $output = drupal_render($output); $results[$values->{$id_field_alias}] = filter_xss_admin(preg_replace('/\s\s+/', ' ', str_replace("\n", '', $output))); $this->view->row_index++; diff --git a/core/modules/node/node.views.inc b/core/modules/node/node.views.inc index 5d14a38de0f..03b6bcded31 100644 --- a/core/modules/node/node.views.inc +++ b/core/modules/node/node.views.inc @@ -616,7 +616,7 @@ function node_views_data() { */ function node_row_node_view_preprocess_node(&$vars) { $node = $vars['node']; - $options = $vars['view']->style_plugin->row_plugin->options; + $options = $vars['view']->rowPlugin->options; // Prevent the comment form from showing up if this is not a page display. if ($vars['view_mode'] == 'full' && !$vars['view']->display_handler->hasPath()) { diff --git a/core/modules/rest/lib/Drupal/rest/Plugin/views/style/Serializer.php b/core/modules/rest/lib/Drupal/rest/Plugin/views/style/Serializer.php index 1906cfa6072..d3a317f0699 100644 --- a/core/modules/rest/lib/Drupal/rest/Plugin/views/style/Serializer.php +++ b/core/modules/rest/lib/Drupal/rest/Plugin/views/style/Serializer.php @@ -66,7 +66,7 @@ class Serializer extends StylePluginBase { // is used, $rows will not contain objects and will pass directly to the // Encoder. foreach ($this->view->result as $row) { - $rows[] = $this->row_plugin->render($row); + $rows[] = $this->view->rowPlugin->render($row); } return $this->serializer->serialize($rows, $this->displayHandler->getContentType()); diff --git a/core/modules/views/lib/Drupal/views/Plugin/views/display/Feed.php b/core/modules/views/lib/Drupal/views/Plugin/views/display/Feed.php index f589423881c..cd8d2b62a2e 100644 --- a/core/modules/views/lib/Drupal/views/Plugin/views/display/Feed.php +++ b/core/modules/views/lib/Drupal/views/Plugin/views/display/Feed.php @@ -255,16 +255,15 @@ class Feed extends PathPluginBase { // Defer to the feed style; it may put in meta information, and/or // attach a feed icon. - $plugin = $this->getPlugin('style'); - if ($plugin) { - $clone->setDisplay($this->display['id']); - $clone->buildTitle(); + $clone->setDisplay($this->display['id']); + $clone->buildTitle(); + if ($plugin = $clone->display_handler->getPlugin('style')) { $plugin->attach_to($display_id, $this->getPath(), $clone->getTitle()); - - // Clean up. - $clone->destroy(); - unset($clone); } + + // Clean up. + $clone->destroy(); + unset($clone); } /** diff --git a/core/modules/views/lib/Drupal/views/Plugin/views/style/Rss.php b/core/modules/views/lib/Drupal/views/Plugin/views/style/Rss.php index bf56a31d023..987004282e3 100644 --- a/core/modules/views/lib/Drupal/views/Plugin/views/style/Rss.php +++ b/core/modules/views/lib/Drupal/views/Plugin/views/style/Rss.php @@ -108,7 +108,7 @@ class Rss extends StylePluginBase { } function render() { - if (empty($this->row_plugin)) { + if (empty($this->view->rowPlugin)) { debug('Drupal\views\Plugin\views\style\Rss: Missing row plugin'); return; } @@ -129,7 +129,7 @@ class Rss extends StylePluginBase { foreach ($this->view->result as $row_index => $row) { $this->view->row_index = $row_index; - $rows .= $this->row_plugin->render($row); + $rows .= $this->view->rowPlugin->render($row); } $output = theme($this->themeFunctions(), diff --git a/core/modules/views/lib/Drupal/views/Plugin/views/style/StylePluginBase.php b/core/modules/views/lib/Drupal/views/Plugin/views/style/StylePluginBase.php index 5585ca39f46..d28276cec5d 100644 --- a/core/modules/views/lib/Drupal/views/Plugin/views/style/StylePluginBase.php +++ b/core/modules/views/lib/Drupal/views/Plugin/views/style/StylePluginBase.php @@ -41,14 +41,6 @@ abstract class StylePluginBase extends PluginBase { */ var $row_tokens = array(); - /** - * Contains the row plugin, if it's initialized - * and the style itself supports it. - * - * @var views_plugin_row - */ - var $row_plugin; - /** * Does the style plugin allows to use style plugins. * @@ -100,7 +92,7 @@ abstract class StylePluginBase extends PluginBase { parent::init($view, $display, $options); if ($this->usesRowPlugin() && $display->getOption('row')) { - $this->row_plugin = $display->getPlugin('row'); + $this->view->rowPlugin = $display->getPlugin('row'); } $this->options += array( @@ -112,8 +104,8 @@ abstract class StylePluginBase extends PluginBase { public function destroy() { parent::destroy(); - if (isset($this->row_plugin)) { - $this->row_plugin->destroy(); + if (isset($this->view->rowPlugin)) { + $this->view->rowPlugin->destroy(); } } @@ -154,8 +146,8 @@ abstract class StylePluginBase extends PluginBase { // If we use a row plugin, ask the row plugin. Chances are, we don't // care, it does. $row_uses_fields = FALSE; - if ($this->usesRowPlugin() && !empty($this->row_plugin)) { - $row_uses_fields = $this->row_plugin->usesFields(); + if ($this->usesRowPlugin() && !empty($this->view->rowPlugin)) { + $row_uses_fields = $this->view->rowPlugin->usesFields(); } // Otherwise, check the definition or the option. return $row_uses_fields || $this->usesFields || !empty($this->options['uses_fields']); @@ -396,8 +388,8 @@ abstract class StylePluginBase extends PluginBase { * The full array of results from the query. */ function pre_render($result) { - if (!empty($this->row_plugin)) { - $this->row_plugin->pre_render($result); + if (!empty($this->view->rowPlugin)) { + $this->view->rowPlugin->pre_render($result); } } @@ -405,7 +397,7 @@ abstract class StylePluginBase extends PluginBase { * Render the display in this style. */ function render() { - if ($this->usesRowPlugin() && empty($this->row_plugin)) { + if ($this->usesRowPlugin() && empty($this->view->rowPlugin)) { debug('Drupal\views\Plugin\views\style\StylePluginBase: Missing row plugin'); return; } @@ -455,7 +447,7 @@ abstract class StylePluginBase extends PluginBase { if ($this->usesRowPlugin()) { foreach ($set['rows'] as $index => $row) { $this->view->row_index = $index; - $render = $this->row_plugin->render($row); + $render = $this->view->rowPlugin->render($row); // Row render arrays cannot be contained by style render arrays. $set['rows'][$index] = drupal_render($render); } @@ -684,8 +676,8 @@ abstract class StylePluginBase extends PluginBase { public function query() { parent::query(); - if (isset($this->row_plugin)) { - $this->row_plugin->query(); + if (isset($this->view->rowPlugin)) { + $this->view->rowPlugin->query(); } } diff --git a/core/modules/views/lib/Drupal/views/Tests/Plugin/StyleTest.php b/core/modules/views/lib/Drupal/views/Tests/Plugin/StyleTest.php index 8a14ca03dad..2e5f4d2a83d 100644 --- a/core/modules/views/lib/Drupal/views/Tests/Plugin/StyleTest.php +++ b/core/modules/views/lib/Drupal/views/Tests/Plugin/StyleTest.php @@ -80,10 +80,10 @@ class StyleTest extends ViewTestBase { $view->style_plugin->setUsesRowPlugin(TRUE); // Reinitialize the style as it supports row plugins now. $view->style_plugin->init($view, $view->display_handler); - $this->assertTrue($view->style_plugin->row_plugin instanceof RowTest, 'Make sure the right row plugin class is loaded.'); + $this->assertTrue($view->rowPlugin instanceof RowTest, 'Make sure the right row plugin class is loaded.'); $random_text = $this->randomName(); - $view->style_plugin->row_plugin->setOutput($random_text); + $view->rowPlugin->setOutput($random_text); $output = $view->preview(); $this->assertTrue(strpos($output, $random_text) !== FALSE, 'Take sure that the rendering of the row plugin appears in the output of the view.'); diff --git a/core/modules/views/lib/Drupal/views/Tests/ViewExecutableTest.php b/core/modules/views/lib/Drupal/views/Tests/ViewExecutableTest.php index c8769728018..40528461fa9 100644 --- a/core/modules/views/lib/Drupal/views/Tests/ViewExecutableTest.php +++ b/core/modules/views/lib/Drupal/views/Tests/ViewExecutableTest.php @@ -14,6 +14,8 @@ use Drupal\views\DisplayBag; use Drupal\views\Plugin\views\display\DefaultDisplay; use Drupal\views\Plugin\views\display\Page; use Drupal\views\Plugin\views\style\DefaultStyle; +use Drupal\views\Plugin\views\style\Grid; +use Drupal\views\Plugin\views\row\Fields; use Drupal\views\Plugin\views\query\Sql; /** @@ -204,6 +206,21 @@ class ViewExecutableTest extends ViewUnitTestBase { $this->assertEqual($view->current_display, 'default', 'If setDisplay is called with an invalid display id the default display should be used.'); $this->assertEqual(spl_object_hash($view->display_handler), spl_object_hash($view->displayHandlers->get('default'))); + + // Test the style and row plugins are replaced correctly when setting the + // display. + $view->setDisplay('page_1'); + $view->initStyle(); + $this->assertTrue($view->style_plugin instanceof DefaultStyle); + $this->assertTrue($view->rowPlugin instanceof Fields); + $this->assertEqual($view->plugin_name, 'default'); + + $view->setDisplay('page_2'); + $view->initStyle(); + $this->assertTrue($view->style_plugin instanceof Grid); + // @todo Change this rowPlugin type too. + $this->assertTrue($view->rowPlugin instanceof Fields); + $this->assertEqual($view->plugin_name, 'grid'); } /** diff --git a/core/modules/views/lib/Drupal/views/ViewExecutable.php b/core/modules/views/lib/Drupal/views/ViewExecutable.php index 02972ba1306..aa39dae1bc6 100644 --- a/core/modules/views/lib/Drupal/views/ViewExecutable.php +++ b/core/modules/views/lib/Drupal/views/ViewExecutable.php @@ -212,6 +212,13 @@ class ViewExecutable { */ public $style_plugin; + /** + * The current used row plugin, if the style plugin supports row plugins. + * + * @var \Drupal\views\Plugin\views\row\RowPluginBase + */ + public $rowPlugin; + /** * Stores the current active row while rendering. * @@ -669,8 +676,18 @@ class ViewExecutable { return FALSE; } - // Set the current display. - $this->current_display = $display_id; + // Reset if the display has changed. It could be called multiple times for + // the same display, especially in the UI. + if ($this->current_display != $display_id) { + // Set the current display. + $this->current_display = $display_id; + + // Reset the style and row plugins. + $this->style_plugin = NULL; + $this->plugin_name = NULL; + $this->rowPlugin = NULL; + } + // Set a shortcut. $this->display_handler = $this->displayHandlers->get($display_id); @@ -1729,7 +1746,7 @@ class ViewExecutable { $this->style_plugin->destroy(); } - $keys = array('current_display', 'display_handler', 'displayHandlers', 'field', 'argument', 'filter', 'sort', 'relationship', 'header', 'footer', 'empty', 'query', 'result', 'inited', 'style_plugin', 'plugin_name', 'exposed_data', 'exposed_input', 'many_to_one_tables'); + $keys = array('current_display', 'display_handler', 'displayHandlers', 'field', 'argument', 'filter', 'sort', 'relationship', 'header', 'footer', 'empty', 'query', 'result', 'inited', 'style_plugin', 'rowPlugin', 'plugin_name', 'exposed_data', 'exposed_input', 'many_to_one_tables'); foreach ($keys as $key) { unset($this->$key); } diff --git a/core/modules/views/tests/views_test_config/test_views/views.view.test_executable_displays.yml b/core/modules/views/tests/views_test_config/test_views/views.view.test_executable_displays.yml index 83a217258b0..dc100c2f3cf 100644 --- a/core/modules/views/tests/views_test_config/test_views/views.view.test_executable_displays.yml +++ b/core/modules/views/tests/views_test_config/test_views/views.view.test_executable_displays.yml @@ -18,6 +18,12 @@ display: display_title: 'Page 2' id: page_2 position: '2' + display_options: + defaults: + style: '0' + style: + type: grid human_name: '' +langcode: en id: test_executable_displays tag: '' diff --git a/core/modules/views/tests/views_test_data/lib/Drupal/views_test_data/Plugin/views/style/StyleTest.php b/core/modules/views/tests/views_test_data/lib/Drupal/views_test_data/Plugin/views/style/StyleTest.php index ec1d2ba0c3a..9dc8d80d1e1 100644 --- a/core/modules/views/tests/views_test_data/lib/Drupal/views_test_data/Plugin/views/style/StyleTest.php +++ b/core/modules/views/tests/views_test_data/lib/Drupal/views_test_data/Plugin/views/style/StyleTest.php @@ -100,7 +100,7 @@ class StyleTest extends StylePluginBase { else { foreach ($this->view->result as $index => $row) { $this->view->row_index = $index; - $output .= $this->row_plugin->render($row) . "\n"; + $output .= $this->view->rowPlugin->render($row) . "\n"; } } diff --git a/core/modules/views/views_ui/lib/Drupal/views_ui/ViewEditFormController.php b/core/modules/views/views_ui/lib/Drupal/views_ui/ViewEditFormController.php index 4b1df77e3c3..2bd2864fb5b 100644 --- a/core/modules/views/views_ui/lib/Drupal/views_ui/ViewEditFormController.php +++ b/core/modules/views/views_ui/lib/Drupal/views_ui/ViewEditFormController.php @@ -857,10 +857,15 @@ class ViewEditFormController extends ViewFormControllerBase { * Add information about a section to a display. */ public function getFormBucket(ViewUI $view, $type, $display) { + $executable = $view->get('executable'); + $executable->setDisplay($display['id']); + $executable->initStyle(); + + $types = $executable->viewsHandlerTypes(); + $build = array( '#theme_wrappers' => array('views_ui_display_tab_bucket'), ); - $types = ViewExecutable::viewsHandlerTypes(); $build['#overridden'] = FALSE; $build['#defaulted'] = FALSE; @@ -884,7 +889,7 @@ class ViewEditFormController extends ViewFormControllerBase { break; case 'field': // Fetch the style plugin info so we know whether to list fields or not. - $style_plugin = $view->get('executable')->displayHandlers->get($display['id'])->getPlugin('style'); + $style_plugin = $executable->style_plugin; $uses_fields = $style_plugin && $style_plugin->usesFields(); if (!$uses_fields) { $build['fields'][] = array( @@ -898,7 +903,7 @@ class ViewEditFormController extends ViewFormControllerBase { case 'header': case 'footer': case 'empty': - if (!$view->get('executable')->displayHandlers->get($display['id'])->usesAreas()) { + if (!$executable->display_handler->usesAreas()) { $build[$type][] = array( '#markup' => t('The selected display type does not utilize @type plugins', array('@type' => $type)), '#theme_wrappers' => array('views_ui_container'), @@ -911,7 +916,7 @@ class ViewEditFormController extends ViewFormControllerBase { // Create an array of actions to pass to theme_links $actions = array(); - $count_handlers = count($view->get('executable')->displayHandlers->get($display['id'])->getHandlers($type)); + $count_handlers = count($executable->display_handler->getHandlers($type)); $actions['add'] = array( 'title' => t('Add'), 'href' => "admin/structure/views/nojs/add-item/{$view->id()}/{$display['id']}/$type", @@ -936,8 +941,8 @@ class ViewEditFormController extends ViewFormControllerBase { ), ); - if (!$view->get('executable')->displayHandlers->get($display['id'])->isDefaultDisplay()) { - if (!$view->get('executable')->displayHandlers->get($display['id'])->isDefaulted($types[$type]['plural'])) { + if (!$executable->display_handler->isDefaultDisplay()) { + if (!$executable->display_handler->isDefaulted($types[$type]['plural'])) { $build['#overridden'] = TRUE; } else { @@ -949,7 +954,7 @@ class ViewEditFormController extends ViewFormControllerBase { if (!isset($relationships)) { // Get relationship labels $relationships = array(); - foreach ($view->get('executable')->displayHandlers->get($display['id'])->getHandlers('relationship') as $id => $handler) { + foreach ($executable->display_handler->getHandlers('relationship') as $id => $handler) { $relationships[$id] = $handler->label(); } } @@ -958,7 +963,7 @@ class ViewEditFormController extends ViewFormControllerBase { $groups = array(); $grouping = FALSE; if ($type == 'filter') { - $group_info = $view->get('executable')->displayHandlers->get('default')->getOption('filter_groups'); + $group_info = $executable->display_handler->getOption('filter_groups'); // If there is only one group but it is using the "OR" filter, we still // treat it as a group for display purposes, since we want to display the // "OR" label next to items within the group. @@ -970,12 +975,12 @@ class ViewEditFormController extends ViewFormControllerBase { $build['fields'] = array(); - foreach ($view->get('executable')->displayHandlers->get($display['id'])->getOption($types[$type]['plural']) as $id => $field) { + foreach ($executable->display_handler->getOption($types[$type]['plural']) as $id => $field) { // Build the option link for this handler ("Node: ID = article"). $build['fields'][$id] = array(); $build['fields'][$id]['#theme'] = 'views_ui_display_tab_setting'; - $handler = $view->get('executable')->displayHandlers->get($display['id'])->getHandler($type, $id); + $handler = $executable->display_handler->getHandler($type, $id); if (empty($handler)) { $build['fields'][$id]['#class'][] = 'broken'; $field_name = t('Broken/missing handler: @table > @field', array('@table' => $field['table'], '@field' => $field['field'])); @@ -997,7 +1002,7 @@ class ViewEditFormController extends ViewFormControllerBase { $build['fields'][$id]['#link'] = l($link_text, "admin/structure/views/nojs/config-item/{$view->id()}/{$display['id']}/$type/$id", array('attributes' => $link_attributes, 'html' => TRUE)); $build['fields'][$id]['#class'][] = drupal_clean_css_identifier($display['id']. '-' . $type . '-' . $id); - if ($view->get('executable')->displayHandlers->get($display['id'])->useGroupBy() && $handler->usesGroupBy()) { + if ($executable->display_handler->useGroupBy() && $handler->usesGroupBy()) { $build['fields'][$id]['#settings_links'][] = l('' . t('Aggregation settings') . '', "admin/structure/views/nojs/config-item-group/{$view->id()}/{$display['id']}/$type/$id", array('attributes' => array('class' => 'views-button-configure views-ajax-link', 'title' => t('Aggregation settings')), 'html' => TRUE)); }