diff --git a/core/modules/block/lib/Drupal/block/Tests/Views/DisplayBlockTest.php b/core/modules/block/lib/Drupal/block/Tests/Views/DisplayBlockTest.php index 1a667fa..ea408af 100644 --- a/core/modules/block/lib/Drupal/block/Tests/Views/DisplayBlockTest.php +++ b/core/modules/block/lib/Drupal/block/Tests/Views/DisplayBlockTest.php @@ -156,6 +156,16 @@ public function testViewsBlockForm() { // This will only return a result if our new block has been created with the // expected machine name. $this->assertTrue(!empty($blocks), 'The expected block was loaded.'); + + for ($i = 1; $i <= 2; $i++) { + // Place the same block again and make sure we have a new ID. + $this->drupalPost('admin/structure/block/add/views_block:test_view_block-block_1/' . $default_theme, array(), t('Save block')); + $storage = \Drupal::entityManager()->getStorageController('block'); + $blocks = $storage->load(array('stark.views_block__test_view_block_block_1_' . $i)); + // This will only return a result if our new block has been created with the + // expected machine name. + $this->assertTrue(!empty($blocks), 'The expected block was loaded.'); + } } /** diff --git a/core/modules/views/lib/Drupal/views/Plugin/Block/ViewsBlock.php b/core/modules/views/lib/Drupal/views/Plugin/Block/ViewsBlock.php index 1e2bfd5..a1c5ae7 100644 --- a/core/modules/views/lib/Drupal/views/Plugin/Block/ViewsBlock.php +++ b/core/modules/views/lib/Drupal/views/Plugin/Block/ViewsBlock.php @@ -109,4 +109,13 @@ protected function addContextualLinks(&$output, $block_type = 'block') { } } + /** + * Returns the ViewExecutable instance for this block. + * + * @return \Drupal\views\ViewExecutable + */ + public function getView() { + return $this->view; + } + } diff --git a/core/modules/views/views.module b/core/modules/views/views.module index 7061a52..99bd076 100644 --- a/core/modules/views/views.module +++ b/core/modules/views/views.module @@ -1824,18 +1824,38 @@ function views_cache_get($cid, $use_language = FALSE) { */ function views_form_block_form_alter(&$form, &$form_state) { // Ensure the block-form being altered is a Views block configuration form. - if ($form['settings']['module']['#value'] == 'views') { + if (($form['settings']['module']['#value'] == 'views') && empty($form['machine_name']['#default_value'])) { // Unset the machine_name provided by BlockFormController unset($form['machine_name']['#machine_name']['source']); // Load the Views plugin object using form_state array and create a // block machine_name based on the View ID and View Display ID. - $block_plugin = $form_state['build_info']['callback_object']->getEntity()->getPlugin(); - list($plugin, $delta) = explode(':', $block_plugin->getPluginId()); - list($view_id, $display_id) = explode('-', $delta, 2); + $view = $form_state['build_info']['callback_object']->getEntity()->getPlugin()->getView(); // Override the Views block's machine_name by providing a default_value. - $form['machine_name']['#default_value'] = 'views_block__' . $view_id . '_' . $display_id; + $form['machine_name']['#default_value'] = views_generate_block_instance_id($view); // Prevent users from changing the auto-generate block machine_name. $form['machine_name']['#access'] = FALSE; } } +/** + * Generates a views block instance id. + */ +function views_generate_block_instance_id($view) { + $original_id = 'views_block__' . $view->storage->id() . '_' . $view->current_display; + $manager = Drupal::entityManager()->getStorageController('block'); + + // Get an array of block IDs without the theme prefix. + $block_ids = array_map(function ($block_id) { + $parts = explode('.', $block_id); + return end($parts); + }, array_keys($manager->load())); + + $count = 1; + $id = $original_id; + while (in_array($id, $block_ids)) { + $id = $original_id . '_' . $count++; + } + + return $id; +} +