diff --git a/core/modules/views/lib/Drupal/views/Tests/UI/DisplayTest.php b/core/modules/views/lib/Drupal/views/Tests/UI/DisplayTest.php index b9342cd..786be98 100644 --- a/core/modules/views/lib/Drupal/views/Tests/UI/DisplayTest.php +++ b/core/modules/views/lib/Drupal/views/Tests/UI/DisplayTest.php @@ -146,7 +146,31 @@ public function testCloneDisplay() { $this->drupalGet($path_prefix); $this->drupalPost(NULL, array(), 'clone Page'); - $this->assertLinkByHref($path_prefix . '/page_1', 0, 'Make sure after cloning the new display appears in the UI'); + $this->assertLinkByHref($path_prefix . '/page_2', 0, 'Make sure after cloning the new display appears in the UI'); + $this->assertUrl($path_prefix . '/page_2', array(), 'The user got redirected to the new display.'); + + // Set the title and override the css classes. + $random_title = $this->randomName(); + $random_css = $this->randomName(); + $this->drupalPost("admin/structure/views/nojs/display/{$view['name']}/page_2/title", array('title' => $random_title), t('Apply')); + $this->drupalPost("admin/structure/views/nojs/display/{$view['name']}/page_2/css_class", array('override[dropdown]' => 'page_2', 'css_class' => $random_css), t('Apply')); + + // Clone as a different display type. + $this->drupalPost(NULL, array(), 'clone as Block'); + $this->assertLinkByHref($path_prefix . '/block_1', 0, 'Make sure after cloning the new display appears in the UI'); + $this->assertUrl($path_prefix . '/block_1', array(), 'The user got redirected to the new display.'); + + $this->drupalPost(NULL, array(), t('Save')); + $view = views_get_view($view['name']); + $view->initDisplay(); + + $displays = $view->displayHandlers; + $this->assertTrue($displays['page_2'], 'The new page display got saved.'); + $this->assertTrue($displays['block_1'], 'The new block display got saved.'); + $this->assertEqual($displays['page_2']->display['display_title'], 'Page'); + $this->assertEqual($displays['block_1']->display['display_title'], 'Block', 'The new display title got generated as expected.'); + $this->assertEqual($displays['block_1']->getOption('title'), $random_title, 'The overridden title option from the display got copied into the clone'); + $this->assertEqual($displays['block_1']->getOption('css_class'), $random_css, 'The overridden css_class option from the display got copied into the clone'); } /** 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 c8a2c96..c27575d 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 @@ -8,6 +8,7 @@ namespace Drupal\views_ui; use Drupal\Core\Entity\EntityInterface; +use Drupal\Component\Utility\NestedArray; use Drupal\views\ViewExecutable; /** @@ -421,6 +422,21 @@ public function getDisplayDetails($view, $display) { "#suffix" => '', ); } + + foreach (views_fetch_plugin_names('display', NULL, array($view->get('storage')->get('base_table'))) as $type => $label) { + if ($type == $display['display_plugin']) { + continue; + } + + $build['top']['actions']['clone_as'][$type] = array( + '#type' => 'submit', + '#value' => t('clone as @type', array('@type' => $label)), + '#limit_validation_errors' => array(), + '#submit' => array(array($this, 'submitCloneDisplayAsType'), array($this, 'submitDelayDestination')), + '#prefix' => '
  • ', + '#suffix' => '
  • ', + ); + } } else { $build['top']['actions']['undo_delete'] = array( @@ -766,6 +782,37 @@ public function submitDisplayAdd($form, &$form_state) { } /** + * Submit handler to clone a display as another display type. + */ + public function submitCloneDisplayAsType($form, &$form_state) { + $view = $this->getEntity($form_state); + $display_id = $view->displayID; + + // Create the new display. + $parents = $form_state['triggering_element']['#parents']; + $display_type = array_pop($parents); + $new_display_id = $view->addDisplay($display_type); + $displays = $view->get('display'); + + // Let the display title be generated by the addDisplay method but copy + // the rest from the original display. + $display_clone = $displays[$display_id]; + unset($display_clone['display_title']); + + $displays[$new_display_id] = NestedArray::mergeDeep($displays[$new_display_id], $display_clone); + $displays[$new_display_id]['id'] = $new_display_id; + $view->set('display', $displays); + + // By setting the current display the changed marker will appear on the new + // display. + $view->get('executable')->current_display = $new_display_id; + views_ui_cache_set($view); + + // Redirect to the new display's edit page. + $form_state['redirect'] = 'admin/structure/views/view/' . $view->get('name') . '/edit/' . $new_display_id; + } + + /** * Build a renderable array representing one option on the edit form. * * This function might be more logical as a method on an object, if a suitable