diff --git a/core/modules/views/config/schema/views.data_types.schema.yml b/core/modules/views/config/schema/views.data_types.schema.yml index f371e12..11be323 100644 --- a/core/modules/views/config/schema/views.data_types.schema.yml +++ b/core/modules/views/config/schema/views.data_types.schema.yml @@ -263,6 +263,11 @@ views_display: exposed_block: type: boolean label: 'Put the exposed form in a block' + display_extenders: + type: sequence + label: 'Display extenders' + sequence: + - type: views.display_extender.[%key] views_sort: type: views_handler @@ -850,3 +855,7 @@ views_cache: type: type: string label: 'Cache type' + +views_display_extender: + type: mapping + label: 'Display extender settings' diff --git a/core/modules/views/src/Plugin/views/display/DisplayPluginBase.php b/core/modules/views/src/Plugin/views/display/DisplayPluginBase.php index e471d8a..8f68d0d 100644 --- a/core/modules/views/src/Plugin/views/display/DisplayPluginBase.php +++ b/core/modules/views/src/Plugin/views/display/DisplayPluginBase.php @@ -73,8 +73,10 @@ /** * Stores all available display extenders. + * + * @var \Drupal\views\Plugin\views\display_extender\DisplayExtenderPluginBase[] */ - var $extender = array(); + protected $extenders = []; /** * Overrides Drupal\views\Plugin\Plugin::$usesOptions. @@ -156,21 +158,27 @@ public function __construct(array $configuration, $plugin_id, $plugin_definition public function initDisplay(ViewExecutable $view, array &$display, array &$options = NULL) { $this->view = $view; - $this->setOptionDefaults($this->options, $this->defineOptions()); - $this->display = &$display; // Load extenders as soon as possible. - $this->extender = array(); + $display['display_options'] += ['display_extenders' => []]; + $this->extenders = array(); if ($extenders = Views::getEnabledDisplayExtenders()) { $manager = Views::pluginManager('display_extender'); + $display_extender_options = $display['display_options']['display_extenders']; foreach ($extenders as $extender) { + /** @var \Drupal\views\Plugin\views\display_extender\DisplayExtenderPluginBase $plugin */ if ($plugin = $manager->createInstance($extender)) { - $plugin->init($this->view, $this); - $this->extender[$extender] = $plugin; + $extender_options = isset($display_extender_options[$plugin->getPluginId()]) ? $display_extender_options[$plugin->getPluginId()] : []; + $plugin->init($this->view, $this, $extender_options); + $this->extenders[$extender] = $plugin; } } } + + $this->setOptionDefaults($this->options, $this->defineOptions()); + $this->display = &$display; + // Track changes that the user should know about. $changed = FALSE; @@ -237,7 +245,7 @@ public function destroy() { unset($this->default_display); } - foreach ($this->extender as $extender) { + foreach ($this->extenders as $extender) { $extender->destroy(); } } @@ -491,7 +499,7 @@ public function defaultableSections($section = NULL) { unset($sections['items_per_page']); } - foreach ($this->extender as $extender) { + foreach ($this->extenders as $extender) { $extender->defaultableSections($sections, $section); } @@ -701,7 +709,14 @@ protected function defineOptions() { unset($options['defaults']); } - foreach ($this->extender as $extender) { + $options['display_extenders'] = ['default' => []]; + // First allow display extenders to provide new options. + foreach ($this->extenders as $extender_id => $extender) { + $options['display_extenders']['contains'][$extender_id]['contains'] = $extender->defineOptions(); + } + + // Then allow display extenders to alter existing default values. + foreach ($this->extenders as $extender) { $extender->defineOptionsAlter($options); } @@ -1369,7 +1384,7 @@ public function optionsSummary(&$categories, &$options) { 'desc' => $this->t('Change the CSS class name(s) that will be added to this display.'), ); - foreach ($this->extender as $extender) { + foreach ($this->extenders as $extender) { $extender->optionsSummary($categories, $options); } } @@ -1857,7 +1872,7 @@ public function buildOptionsForm(&$form, FormStateInterface $form_state) { break; } - foreach ($this->extender as $extender) { + foreach ($this->extenders as $extender) { $extender->buildOptionsForm($form, $form_state); } } @@ -1909,7 +1924,7 @@ public function validateOptionsForm(&$form, FormStateInterface $form_state) { } } - foreach ($this->extender as $extender) { + foreach ($this->extenders as $extender) { $extender->validateOptionsForm($form, $form_state); } } @@ -2012,9 +2027,14 @@ public function submitOptionsForm(&$form, FormStateInterface $form_state) { break; } - foreach ($this->extender as $extender) { + $extender_options = $this->getOption('display_extenders'); + foreach ($this->extenders as $extender) { $extender->submitOptionsForm($form, $form_state); + + $plugin_id = $extender->getPluginId(); + $extender_options[$plugin_id] = $extender->options; } + $this->setOption('display_extenders', $extender_options); } /** @@ -2065,7 +2085,7 @@ public function setOverride($section, $new_state = NULL) { * Inject anything into the query that the display handler needs. */ public function query() { - foreach ($this->extender as $extender) { + foreach ($this->extenders as $extender) { $extender->query(); } } @@ -2272,7 +2292,7 @@ public function preExecute() { $exposed_form->preExecute(); } - foreach ($this->extender as $extender) { + foreach ($this->extenders as $extender) { $extender->preExecute(); } } @@ -2642,6 +2662,15 @@ protected function mergeHandler($type) { $this->setOption($types[$type]['plural'], $options); } + /** + * Gets the display extenders. + * + * @return \Drupal\views\Plugin\views\display_extender\DisplayExtenderPluginBase[] + */ + public function getExtenders() { + return $this->extenders; + } + } /** diff --git a/core/modules/views/src/Tests/Plugin/DisplayExtenderTest.php b/core/modules/views/src/Tests/Plugin/DisplayExtenderTest.php index d84d355..51ce6f5 100644 --- a/core/modules/views/src/Tests/Plugin/DisplayExtenderTest.php +++ b/core/modules/views/src/Tests/Plugin/DisplayExtenderTest.php @@ -41,9 +41,9 @@ public function testDisplayExtenders() { $view = Views::getView('test_view'); $view->initDisplay(); - $this->assertEqual(count($view->display_handler->extender), 1, 'Make sure that only one extender is initialized.'); + $this->assertEqual(count($view->display_handler->getExtenders()), 1, 'Make sure that only one extender is initialized.'); - $display_extender = $view->display_handler->extender['display_extender_test']; + $display_extender = $view->display_handler->getExtenders()['display_extender_test']; $this->assertTrue($display_extender instanceof \Drupal\views_test_data\Plugin\views\display_extender\DisplayExtenderTest, 'Make sure the right class got initialized.'); $view->preExecute(); diff --git a/core/modules/views/tests/modules/views_test_data/config/schema/views_test_data.views.schema.yml b/core/modules/views/tests/modules/views_test_data/config/schema/views_test_data.views.schema.yml index e200610..74892c4 100644 --- a/core/modules/views/tests/modules/views_test_data/config/schema/views_test_data.views.schema.yml +++ b/core/modules/views/tests/modules/views_test_data/config/schema/views_test_data.views.schema.yml @@ -85,3 +85,13 @@ views.style.test_style: test_option: type: string label: 'Test option' + +views.display_extender.display_extender_test: + type: views_display_extender + mapping: + test_extender_test_option: + type: string + label: 'Test option' + +views.display_extender.display_extender_test2: + type: views.display_extender.display_extender_test diff --git a/core/modules/views/tests/modules/views_test_data/src/Plugin/views/display_extender/DisplayExtenderTest.php b/core/modules/views/tests/modules/views_test_data/src/Plugin/views/display_extender/DisplayExtenderTest.php index 853dc6b..ce5afb0 100644 --- a/core/modules/views/tests/modules/views_test_data/src/Plugin/views/display_extender/DisplayExtenderTest.php +++ b/core/modules/views/tests/modules/views_test_data/src/Plugin/views/display_extender/DisplayExtenderTest.php @@ -28,10 +28,12 @@ class DisplayExtenderTest extends DisplayExtenderPluginBase { public $testState; /** - * Overrides Drupal\views\Plugin\views\display_extender\DisplayExtenderPluginBase::defineOptionsAlter(). + * {@inheritdoc} */ - public function defineOptionsAlter(&$options) { - $options['test_extender_test_option'] = array('default' => ''); + protected function defineOptions() { + $options = parent::defineOptions(); + + $options['test_extender_test_option'] = ['default' => 'Empty']; return $options; } @@ -50,12 +52,10 @@ public function optionsSummary(&$categories, &$options) { ), ); - $test_option = $this->displayHandler->getOption('test_extender_test_option') ?: $this->t('Empty'); - $options['test_extender_test_option'] = array( 'category' => 'display_extender_test', 'title' => $this->t('Test option'), - 'value' => views_ui_truncate($test_option, 24), + 'value' => views_ui_truncate($this->options['test_extender_test_option'], 24), ); } @@ -70,7 +70,7 @@ public function buildOptionsForm(&$form, FormStateInterface $form_state) { '#title' => $this->t('Test option'), '#type' => 'textfield', '#description' => $this->t('This is a textfield for test_option.'), - '#default_value' => $this->displayHandler->getOption('test_extender_test_option'), + '#default_value' => $this->options['test_extender_test_option'], ); } } @@ -82,7 +82,7 @@ public function submitOptionsForm(&$form, FormStateInterface $form_state) { parent::submitOptionsForm($form, $form_state); switch ($form_state->get('section')) { case 'test_extender_test_option': - $this->displayHandler->setOption('test_extender_test_option', $form_state->getValue('test_extender_test_option')); + $this->options['test_extender_test_option'] = $form_state->getValue('test_extender_test_option'); break; } } diff --git a/core/modules/views_ui/src/Tests/DisplayExtenderUITest.php b/core/modules/views_ui/src/Tests/DisplayExtenderUITest.php index d3412b3..30a5c7e 100644 --- a/core/modules/views_ui/src/Tests/DisplayExtenderUITest.php +++ b/core/modules/views_ui/src/Tests/DisplayExtenderUITest.php @@ -17,17 +17,6 @@ class DisplayExtenderUITest extends UITestBase { /** - * Set to TRUE to strict check all configuration saved. - * - * @see \Drupal\Core\Config\Testing\ConfigSchemaChecker - * - * @todo https://www.drupal.org/node/2387149 - * - * @var bool - */ - protected $strictConfigSchema = FALSE; - - /** * Views used by this test. * * @var array @@ -53,7 +42,8 @@ public function testDisplayExtenderUI() { $this->drupalPostForm(NULL, array(), t('Save')); $view = Views::getView($view->storage->id()); $view->initDisplay(); - $this->assertEqual($view->display_handler->getOption('test_extender_test_option'), $random_text, 'Make sure that the display extender option got saved.'); + $display_extender_options = $view->display_handler->getOption('display_extenders'); + $this->assertEqual($display_extender_options['display_extender_test']['test_extender_test_option'], $random_text, 'Make sure that the display extender option got saved.'); } }