diff --git a/core/modules/views/lib/Drupal/views/Plugin/views/display/DisplayPluginBase.php b/core/modules/views/lib/Drupal/views/Plugin/views/display/DisplayPluginBase.php index 76713c2..040ff47 100644 --- a/core/modules/views/lib/Drupal/views/Plugin/views/display/DisplayPluginBase.php +++ b/core/modules/views/lib/Drupal/views/Plugin/views/display/DisplayPluginBase.php @@ -554,42 +554,49 @@ protected function defineOptions() { 'type' => array('default' => 'none'), 'options' => array('default' => array()), ), + 'merge_defaults' => 'mergePlugin', ), 'cache' => array( 'contains' => array( 'type' => array('default' => 'none'), 'options' => array('default' => array()), ), + 'merge_defaults' => 'mergePlugin', ), 'query' => array( 'contains' => array( 'type' => array('default' => 'views_query'), 'options' => array('default' => array()), ), + 'merge_defaults' => 'mergePlugin', ), 'exposed_form' => array( 'contains' => array( 'type' => array('default' => 'basic'), 'options' => array('default' => array()), ), + 'merge_defaults' => 'mergePlugin', ), 'pager' => array( 'contains' => array( 'type' => array('default' => 'mini'), 'options' => array('default' => array()), ), + 'merge_defaults' => 'mergePlugin', ), 'style' => array( 'contains' => array( 'type' => array('default' => 'default'), 'options' => array('default' => array()), ), + 'merge_defaults' => 'mergePlugin', ), 'row' => array( 'contains' => array( 'type' => array('default' => 'fields'), 'options' => array('default' => array()), ), + 'merge_defaults' => 'mergePlugin', ), 'exposed_block' => array( @@ -598,27 +605,34 @@ protected function defineOptions() { 'header' => array( 'default' => array(), + 'merge_defaults' => 'mergeHandler', ), 'footer' => array( 'default' => array(), + 'merge_defaults' => 'mergeHandler', ), 'empty' => array( 'default' => array(), + 'merge_defaults' => 'mergeHandler', ), // We want these to export last. // These are the 5 handler types. 'relationships' => array( 'default' => array(), + 'merge_defaults' => 'mergeHandler', ), 'fields' => array( 'default' => array(), + 'merge_defaults' => 'mergeHandler', ), 'sorts' => array( 'default' => array(), + 'merge_defaults' => 'mergeHandler', ), 'arguments' => array( 'default' => array(), + 'merge_defaults' => 'mergeHandler', ), 'filter_groups' => array( 'contains' => array( @@ -2725,6 +2739,65 @@ public function getPagerText() { ); } + /** + * Merges default values for all plugin types. + */ + public function mergeDefaults() { + $defined_options = $this->defineOptions(); + + // Build a map of plural => singular for handler types. + $type_map = array(); + foreach (ViewExecutable::viewsHandlerTypes() as $type => $info) { + $type_map[$info['plural']] = $type; + } + + // Find all defined options, that have specified a merge_defaults callback. + foreach ($defined_options as $type => $definition) { + if (!isset($definition['merge_defaults']) || !method_exists($this, $definition['merge_defaults'])) { + continue; + } + // Switch the type to singular, if it's a plural handler. + if (isset($type_map[$type])) { + $type = $type_map[$type]; + } + + $this->{$definition['merge_defaults']}($type); + } + } + + /** + * Merges plugins default values. + * + * @param string $type + * The name of the plugin type option. + */ + protected function mergePlugin($type) { + if (($options = $this->getOption($type)) && isset($options['options'])) { + $plugin = $this->getPlugin($type); + $options['options'] = $options['options'] + $plugin->options; + $this->setOption($type, $options); + } + } + + /** + * Merges handlers default values. + * + * @param string $type + * The name of the handler type option. + */ + protected function mergeHandler($type) { + $types = ViewExecutable::viewsHandlerTypes(); + + $options = $this->getOption($types[$type]['plural']); + foreach ($this->getHandlers($type) as $id => $handler) { + if (isset($options[$id])) { + $options[$id] = $options[$id] + $handler->options; + } + } + + $this->setOption($types[$type]['plural'], $options); + } + } /** diff --git a/core/modules/views/lib/Drupal/views/Plugin/views/wizard/WizardPluginBase.php b/core/modules/views/lib/Drupal/views/Plugin/views/wizard/WizardPluginBase.php index 9b88bb8..3945ae0 100644 --- a/core/modules/views/lib/Drupal/views/Plugin/views/wizard/WizardPluginBase.php +++ b/core/modules/views/lib/Drupal/views/Plugin/views/wizard/WizardPluginBase.php @@ -692,8 +692,9 @@ protected function alter_display_options(&$display_options, $form, $form_state) * Adds the array of display options to the view, with appropriate overrides. */ protected function addDisplays(View $view, $display_options, $form, $form_state) { - // Initialize the view executable to get the display plugin instances. - $view->get('executable'); + // Initialize and store the view executable to get the display plugin + // instances. + $executable = $view->get('executable'); // Display: Master $default_display = $view->newDisplay('default', 'Master', 'default'); @@ -728,6 +729,9 @@ protected function addDisplays(View $view, $display_options, $form, $form_state) $this->set_override_options($display_options['block'], $display, $default_display); } } + + // Initialize displays and merge all plugin default values. + $executable->mergeDefaults(); } /** @@ -749,6 +753,11 @@ protected function default_display_options() { $display_options['style']['type'] = 'default'; $display_options['row']['type'] = 'fields'; + // Add default options array to each plugin type. + foreach ($display_options as &$options) { + $options['options'] = array(); + } + // Add a least one field so the view validates and the user has a preview. // The base field can provide a default in its base settings; otherwise, // choose the first field with a field handler. diff --git a/core/modules/views/lib/Drupal/views/Tests/Plugin/DisplayUnitTest.php b/core/modules/views/lib/Drupal/views/Tests/Plugin/DisplayUnitTest.php new file mode 100644 index 0000000..189ae5a --- /dev/null +++ b/core/modules/views/lib/Drupal/views/Tests/Plugin/DisplayUnitTest.php @@ -0,0 +1,93 @@ + 'Display unit tests', + 'description' => 'Unit tests for the DisplayPluginBase class.', + 'group' => 'Views Plugins' + ); + } + + /** + * Test the default display options. + */ + public function testDefaultOptions() { + // Save the view. + $view = views_get_view('test_display_defaults'); + $view->mergeDefaults(); + $view->save(); + + // Reload to get saved storage values. + $view = views_get_view('test_display_defaults'); + $view->initDisplay(); + $display_data = $view->storage->get('display'); + + foreach ($view->displayHandlers as $id => $display) { + // Test the view plugin options against the storage. + foreach ($this->pluginTypes as $type) { + $options = $display->getOption($type); + $this->assertIdentical($display_data[$id]['display_options'][$type]['options'], $options['options']); + } + // Test the view handler options against the storage. + foreach ($this->handlerTypes as $type) { + $options = $display->getOption($type); + $this->assertIdentical($display_data[$id]['display_options'][$type], $options); + } + } + + } + +} diff --git a/core/modules/views/lib/Drupal/views/Tests/Wizard/BasicTest.php b/core/modules/views/lib/Drupal/views/Tests/Wizard/BasicTest.php index 8a82166..079b4a0 100644 --- a/core/modules/views/lib/Drupal/views/Tests/Wizard/BasicTest.php +++ b/core/modules/views/lib/Drupal/views/Tests/Wizard/BasicTest.php @@ -150,4 +150,27 @@ protected function testWizardForm() { $result = $this->xpath('//small[@id = "edit-label-machine-name-suffix"]'); $this->assertTrue(count($result), 'Ensure that the machine name is applied to the name field.'); } + + public function testWizardDefaultValues() { + $random_id = strtolower($this->randomName(16)); + // Create a basic view. + $view = array(); + $view['label'] = $this->randomName(16); + $view['id'] = $random_id; + $view['description'] = $this->randomName(16); + $view['page[create]'] = FALSE; + $this->drupalPost('admin/structure/views/add', $view, t('Save and edit')); + + // Make sure the plugin types that should not have empty options don't have. + // Test against all values is unit tested. + // @see Drupal\views\Tests\Plugin\DisplayUnitTest + $view = views_get_view($random_id); + $displays = $view->storage->get('display'); + foreach (array('query', 'exposed_form', 'pager', 'style', 'row') as $type) { + foreach ($displays as $display) { + $this->assertFalse(empty($display['display_options'][$type]['options']), format_string('Default options found for @plugin.', array('@plugin' => $type))); + } + } + + } } diff --git a/core/modules/views/lib/Drupal/views/ViewExecutable.php b/core/modules/views/lib/Drupal/views/ViewExecutable.php index 0c27d0d..a8a8dd2 100644 --- a/core/modules/views/lib/Drupal/views/ViewExecutable.php +++ b/core/modules/views/lib/Drupal/views/ViewExecutable.php @@ -2122,4 +2122,15 @@ public function getShowAdminLinks() { return $this->showAdminLinks; } + /** + * Merges all plugin default values for each display. + */ + public function mergeDefaults() { + $this->initDisplay(); + // Initialize displays and merge all plugin defaults. + foreach ($this->displayHandlers as $display) { + $display->mergeDefaults(); + } + } + } diff --git a/core/modules/views/tests/views_test_config/test_views/views.view.test_display_defaults.yml b/core/modules/views/tests/views_test_config/test_views/views.view.test_display_defaults.yml new file mode 100644 index 0000000..e2f5288 --- /dev/null +++ b/core/modules/views/tests/views_test_config/test_views/views.view.test_display_defaults.yml @@ -0,0 +1,49 @@ +base_field: id +base_table: views_test_data +core: 8.x +description: '' +status: '1' +display: + default: + display_plugin: default + id: default + display_title: Master + position: '' + display_options: + access: + type: none + options: { } + cache: + type: none + options: { } + query: + type: views_query + options: { } + exposed_form: + type: basic + options: { } + pager: + type: full + options: { } + style: + type: default + options: { } + row: + type: fields + options: { } + fields: + name: + id: name + table: views_test_data + field: name + sorts: + created: + id: created + table: views_test_data + field: created + order: DESC +label: '' +module: views +id: test_display_defaults +tag: '' +langcode: en