diff --git a/core/includes/menu.inc b/core/includes/menu.inc index 3b444e7..565cc39 100644 --- a/core/includes/menu.inc +++ b/core/includes/menu.inc @@ -2323,6 +2323,7 @@ function menu_get_local_actions() { '#access' => $action_router_item['access'], ); } + uasort($links['actions'], 'element_sort'); return $links['actions']; } diff --git a/core/modules/block/block.routing.yml b/core/modules/block/block.routing.yml index 9e9d4e4..26d4068 100644 --- a/core/modules/block/block.routing.yml +++ b/core/modules/block/block.routing.yml @@ -8,7 +8,7 @@ block_admin_block_delete: block_admin_edit: pattern: '/admin/structure/block/manage/{block}' defaults: - _entity_form: 'block.default' + _entity_form: 'block.edit' requirements: _entity_access: 'block.update' diff --git a/core/modules/block/lib/Drupal/block/BlockFormController.php b/core/modules/block/lib/Drupal/block/BlockFormController.php index bd5c4ba..c6a4d9f 100644 --- a/core/modules/block/lib/Drupal/block/BlockFormController.php +++ b/core/modules/block/lib/Drupal/block/BlockFormController.php @@ -338,7 +338,26 @@ public function submit(array $form, array &$form_state) { // Save the settings of the plugin. $entity->save(); - drupal_set_message($this->t('The block configuration has been saved.')); + if ($this->operation == 'add') { + $theme = $this->entity->get('theme'); + $regions = system_region_list($theme); + $region = $this->entity->get('region'); + $themes = list_themes(); + if (isset($regions[$region])) { + drupal_set_message($this->t("Block placed in @theme's %region region.", array( + '@theme' => $themes[$theme]->info['name'], + '%region' => $regions[$region], + ))); + } + else { + drupal_set_message($this->t('Block added to @theme but not placed in a region.', array( + '@theme' => $themes[$theme]->info['name'], + ))); + } + } + else { + drupal_set_message($this->t('The block configuration has been saved.')); + } Cache::invalidateTags(array('content' => TRUE)); $form_state['redirect'] = array('admin/structure/block/list/' . $form_state['values']['theme'], array( 'query' => array('block-placement' => drupal_html_class($this->entity->id())), diff --git a/core/modules/block/lib/Drupal/block/Controller/BlockAddController.php b/core/modules/block/lib/Drupal/block/Controller/BlockAddController.php index 9e0c7c2..0eff3da 100644 --- a/core/modules/block/lib/Drupal/block/Controller/BlockAddController.php +++ b/core/modules/block/lib/Drupal/block/Controller/BlockAddController.php @@ -30,7 +30,7 @@ public function blockAddConfigureForm($plugin_id, $theme) { // Create a block entity. $entity = $this->entityManager()->getStorageController('block')->create(array('plugin' => $plugin_id, 'theme' => $theme)); - return $this->entityManager()->getForm($entity); + return $this->entityManager()->getForm($entity, 'add'); } } diff --git a/core/modules/block/lib/Drupal/block/Entity/Block.php b/core/modules/block/lib/Drupal/block/Entity/Block.php index e465455..c5c41ab 100644 --- a/core/modules/block/lib/Drupal/block/Entity/Block.php +++ b/core/modules/block/lib/Drupal/block/Entity/Block.php @@ -27,7 +27,8 @@ * "render" = "Drupal\block\BlockRenderController", * "list" = "Drupal\block\BlockListController", * "form" = { - * "default" = "Drupal\block\BlockFormController", + * "add" = "Drupal\block\BlockFormController", + * "edit" = "Drupal\block\BlockFormController", * "delete" = "Drupal\block\Form\BlockDeleteForm" * } * }, diff --git a/core/modules/block/lib/Drupal/block/Tests/BlockTest.php b/core/modules/block/lib/Drupal/block/Tests/BlockTest.php index 536a71c..72c778f 100644 --- a/core/modules/block/lib/Drupal/block/Tests/BlockTest.php +++ b/core/modules/block/lib/Drupal/block/Tests/BlockTest.php @@ -41,7 +41,7 @@ function testBlockVisibility() { $edit['visibility[path][pages]'] = 'user*'; $edit['visibility[role][roles][' . DRUPAL_AUTHENTICATED_RID . ']'] = TRUE; $this->drupalPostForm('admin/structure/block/add/' . $block_name . '/' . $default_theme, $edit, t('Save block')); - $this->assertText('The block configuration has been saved.', 'Block was saved'); + $this->assertRaw(t("Block placed in @theme's %region region.", array('@theme' => 'Stark', '%region' => 'Left sidebar')), 'Block was saved'); $this->drupalGet(''); $this->assertText($title, 'Block was displayed on the front page.'); @@ -81,7 +81,7 @@ function testBlockVisibilityListedEmpty() { // Set the block to be hidden on any user path, and to be shown only to // authenticated users. $this->drupalPostForm('admin/structure/block/add/' . $block_name . '/' . $default_theme, $edit, t('Save block')); - $this->assertText('The block configuration has been saved.', 'Block was saved'); + $this->assertRaw(t("Block placed in @theme's %region region.", array('@theme' => 'Stark', '%region' => 'Left sidebar')), 'Block was saved'); $this->drupalGet('user'); $this->assertNoText($title, 'Block was not displayed according to block visibility rules.'); @@ -109,7 +109,7 @@ function testBlock() { // Set block title to confirm that interface works and override any custom titles. $this->drupalPostForm('admin/structure/block/add/' . $block['id'] . '/' . $block['theme'], array('settings[label]' => $block['settings[label]'], 'machine_name' => $block['machine_name'], 'region' => $block['region']), t('Save block')); - $this->assertText(t('The block configuration has been saved.'), 'Block title set.'); + $this->assertRaw(t("Block placed in @theme's %region region.", array('@theme' => 'Stark', '%region' => 'Header')), 'Block title set.'); // Check to see if the block was created by checking its configuration. $instance = entity_load('block', $block['theme'] . '.' . $block['machine_name']); @@ -151,6 +151,7 @@ public function testBlockThemeSelector() { // Enable all themes. theme_enable(array('bartik', 'seven')); $theme_settings = $this->container->get('config.factory')->get('system.theme'); + $themes = list_themes(); foreach (array('bartik', 'stark', 'seven') as $theme) { // Select the 'Powered by Drupal' block to be placed. $block = array(); @@ -158,7 +159,7 @@ public function testBlockThemeSelector() { $block['theme'] = $theme; $block['region'] = 'content'; $this->drupalPostForm('admin/structure/block/add/system_powered_by_block', $block, t('Save block')); - $this->assertText(t('The block configuration has been saved.')); + $this->assertRaw(t("Block placed in @theme's %region region.", array('@theme' => $themes[$theme]->info['name'], '%region' => 'Content'))); $this->assertUrl('admin/structure/block/list/' . $theme . '?block-placement=' . drupal_html_class($theme . ':' . $block['machine_name'])); // Set the default theme and ensure the block is placed. @@ -185,7 +186,7 @@ function testHideBlockTitle() { 'settings[label]' => $title, ); $this->drupalPostForm('admin/structure/block/add/' . $block_name . '/' . $default_theme, $edit, t('Save block')); - $this->assertText('The block configuration has been saved.', 'Block was saved'); + $this->assertRaw(t("Block placed in @theme's %region region.", array('@theme' => 'Stark', '%region' => 'Left sidebar')), 'Block was saved'); $this->drupalGet('user'); $this->assertText($title, 'Block title was displayed by default.'); @@ -326,7 +327,7 @@ function testBlockModuleDisable() { 'region' => 'sidebar_first', ); $this->drupalPostForm('admin/structure/block/add/system_powered_by_block/stark', $edit, t('Save block')); - $this->assertText(t('The block configuration has been saved.')); + $this->assertRaw(t("Block placed in @theme's %region region.", array('@theme' => 'Stark', '%region' => 'Left sidebar'))); $this->assertText($edit['settings[label]']); // Update the weight of a block. diff --git a/core/modules/menu/lib/Drupal/menu/Tests/MenuBlockTest.php b/core/modules/menu/lib/Drupal/menu/Tests/MenuBlockTest.php new file mode 100644 index 0000000..c2d5ca6 --- /dev/null +++ b/core/modules/menu/lib/Drupal/menu/Tests/MenuBlockTest.php @@ -0,0 +1,61 @@ + 'Menu block', + 'description' => 'Tests block integration of menus.', + 'group' => 'Menu' + ); + } + + /** + * Tests placing menu blocks. + */ + public function testMenuBlockPlacement() { + // Try editing without block permissions. + $this->drupalLogin($this->drupalCreateUser(array('administer menu'))); + $this->drupalGet('admin/structure/menu'); + $this->clickLink(t('Edit menu')); + $this->assertNoLink(t('Place block')); + + // Place a menu block with proper permissions. + $this->drupalLogin($this->drupalCreateUser(array('administer menu', 'administer blocks'))); + $this->drupalGet('admin/structure/menu'); + $this->clickLink(t('Edit menu')); + + // Store the URL used to edit the menu before placing the block. + $menu_edit_url = $this->getUrl(); + $this->clickLink(t('Place block')); + $this->drupalPostForm(NULL, array(), t('Save block')); + // Assert that the message acknowledged that no region was specified. + $this->assertRaw(t('Block added to @theme but not placed in a region.', array('@theme' => 'Stark'))); + $this->assertUrl($menu_edit_url, array(), 'After saving the block, the redirect is back to the menu edit page.'); + + $this->clickLink(t('Place block')); + $this->drupalPostForm(NULL, array('region' => 'content'), t('Save block')); + // Verify the message displayed when a valid region was chosen. + $this->assertRaw(t("Block placed in @theme's %region region.", array('@theme' => 'Stark', '%region' => 'Content'))); + } + +} diff --git a/core/modules/menu/menu.module b/core/modules/menu/menu.module index 57f39b6..2a0dace 100644 --- a/core/modules/menu/menu.module +++ b/core/modules/menu/menu.module @@ -11,6 +11,7 @@ * URLs to be added to the main site navigation menu. */ +use Drupal\Component\Utility\Json; use Drupal\Core\Entity\EntityInterface; use Drupal\block\BlockPluginInterface; use Drupal\system\Entity\Menu; @@ -42,8 +43,14 @@ function menu_help($path, $arg) { $output .= '
' . t('After you have created a menu, you must enable and position the associated block on the Blocks administration page.', array('@blocks' => url('admin/structure/block'))) . '
'; $output .= ''; return $output; + case 'admin/structure/menu/add': return '

' . t('You can enable the newly-created block for this menu on the Blocks administration page.', array('@blocks' => url('admin/structure/block'))) . '

'; + + case 'admin/structure/menu/manage/%': + $output = ''; + $output .= '

' . t('On this page you can rename the menu and reorder or edit existing menu links. In addition, links are provided to add a new menu link, or place a block for this menu in any theme.') . '

'; + return $output; } if ($path == 'admin/structure/menu' && module_exists('block')) { return '

' . t('Each menu has a corresponding block that is managed on the Blocks administration page.', array('@blocks' => url('admin/structure/block'))) . '

'; @@ -121,6 +128,33 @@ function menu_menu() { } /** + * Implements hook_menu_local_tasks(). + */ +function menu_menu_local_tasks(&$data, $router_item, $root_path) { + if (Drupal::moduleHandler()->moduleExists('block') && $router_item['route_name'] == 'menu_menu_edit') { + // @todo Move to a LocalAction plugin when https://drupal.org/node/2045267 + // allows local actions to work with query strings. + $path = 'admin/structure/block/add/system_menu_block:' . end($router_item['original_map']); + $item = menu_get_item($path); + if ($item['access']) { + $item['localized_options']['query']['destination'] = Drupal::request()->attributes->get('_system_path'); + $item['localized_options']['attributes'] = array( + 'class' => array('use-ajax'), + 'data-accepts' => 'application/vnd.drupal-modal', + 'data-dialog-options' => Json::encode(array( + 'width' => 700, + )), + ); + $data['actions'][$path] = array( + '#theme' => 'menu_local_action', + '#link' => $item, + '#weight' => 100, + ); + } + } +} + +/** * Implements hook_entity_info(). */ function menu_entity_info(&$entity_info) {