diff --git a/core/modules/block/custom_block/custom_block.local_actions.yml b/core/modules/block/custom_block/custom_block.local_actions.yml new file mode 100644 index 00000000000..b2726911e57 --- /dev/null +++ b/core/modules/block/custom_block/custom_block.local_actions.yml @@ -0,0 +1,5 @@ +custom_block_type_add: + route_name: custom_block_type_add + title: 'Add custom block type' + appears_on: + - custom_block_type_list diff --git a/core/modules/block/custom_block/custom_block.module b/core/modules/block/custom_block/custom_block.module index a9f6eade744..318796dcf0e 100644 --- a/core/modules/block/custom_block/custom_block.module +++ b/core/modules/block/custom_block/custom_block.module @@ -8,6 +8,25 @@ use Drupal\custom_block\Plugin\Core\Entity\CustomBlockType; use Drupal\custom_block\Plugin\Core\Entity\CustomBlock; +/** + * Implements hook_help(). + */ +function custom_block_help($path, $arg) { + switch ($path) { + case 'admin/help#custom_block': + return t('Allows the creation of custom blocks through the user interface.'); + + case 'admin/structure/custom-blocks': + $output = '

' . t('This page lists user-created blocks. These blocks are derived from block types. A block type can consist of different fields and display settings. From the block types tab you can manage these fields as well as create new block types.') . '

'; + return $output; + + case 'admin/structure/custom-blocks/types': + $output = '

' . t('This page lists block types. A block type can consist of different fields and display settings. From here you can manage these fields as well as create new block types.') . '

'; + return $output; + + } +} + /** * Implements hook_menu_local_tasks(). */ @@ -25,6 +44,19 @@ function custom_block_menu_local_tasks(&$data, $router_item, $root_path) { ); } } + if ($router_item['route_name'] == 'custom_block_list') { + // @todo Move to a LocalAction plugin when https://drupal.org/node/2045267 + // allows local actions to work with query strings. + $item = menu_get_item('block/add'); + if ($item['access']) { + // Add a destination parameter. + $item['localized_options']['query']['destination'] = 'admin/structure/custom-blocks'; + $data['actions']['block/add'] = array( + '#theme' => 'menu_local_action', + '#link' => $item, + ); + } + } } /** @@ -32,11 +64,20 @@ function custom_block_menu_local_tasks(&$data, $router_item, $root_path) { */ function custom_block_menu() { $items['admin/structure/custom-blocks'] = array( - 'title' => 'Custom block types', - 'description' => 'Manage custom block types.', - 'route_name' => 'custom_block_type_list', + 'title' => 'Custom blocks', + 'description' => 'Manage custom blocks.', + 'route_name' => 'custom_block_list', ); - $items['admin/structure/custom-blocks/add'] = array( + $items['admin/structure/custom-blocks/list'] = array( + 'title' => 'Blocks', + 'type' => MENU_DEFAULT_LOCAL_TASK, + ); + $items['admin/structure/custom-blocks/types'] = array( + 'title' => 'Types', + 'route_name' => 'custom_block_type_list', + 'type' => MENU_LOCAL_TASK, + ); + $items['admin/structure/custom-blocks/types/add'] = array( 'route_name' => 'custom_block_type_add', 'type' => MENU_SIBLING_LOCAL_TASK, 'weight' => 1, @@ -92,21 +133,6 @@ function custom_block_menu() { return $items; } -/** - * Implements hook_local_actions(). - */ -function custom_block_local_actions() { - return array( - array( - 'route_name' => 'custom_block_type_add', - 'title' => t('Add custom block type'), - 'appears_on' => array( - 'custom_block_type_list', - ), - ), - ); -} - /** * Implements hook_theme(). */ diff --git a/core/modules/block/custom_block/custom_block.pages.inc b/core/modules/block/custom_block/custom_block.pages.inc index ae7de301278..68f3b78f351 100644 --- a/core/modules/block/custom_block/custom_block.pages.inc +++ b/core/modules/block/custom_block/custom_block.pages.inc @@ -73,5 +73,5 @@ function custom_block_delete_form_submit($form, &$form_state) { drupal_set_message(t('Custom block %label has been deleted.', array('%label' => $block->label()))); watchdog('custom_block', 'Custom block %label has been deleted.', array('%label' => $block->label()), WATCHDOG_NOTICE); - $form_state['redirect'] = 'admin/structure/block'; + $form_state['redirect'] = 'admin/structure/custom-blocks'; } diff --git a/core/modules/block/custom_block/custom_block.routing.yml b/core/modules/block/custom_block/custom_block.routing.yml index 02bad136399..52e1575b87f 100644 --- a/core/modules/block/custom_block/custom_block.routing.yml +++ b/core/modules/block/custom_block/custom_block.routing.yml @@ -1,5 +1,5 @@ custom_block_type_list: - pattern: '/admin/structure/custom-blocks' + pattern: '/admin/structure/custom-blocks/types' defaults: _entity_list: 'custom_block_type' requirements: @@ -35,7 +35,7 @@ custom_block_edit: custom_block: \d+ custom_block_type_add: - pattern: '/admin/structure/custom-blocks/add' + pattern: '/admin/structure/custom-blocks/types/add' defaults: _entity_form: 'custom_block_type.add' requirements: @@ -47,3 +47,10 @@ custom_block_type_edit: _entity_form: 'custom_block_type.edit' requirements: _entity_access: 'custom_block_type.update' + +custom_block_list: + pattern: '/admin/structure/custom-blocks' + defaults: + _entity_list: 'custom_block' + requirements: + _permission: 'administer blocks' diff --git a/core/modules/block/custom_block/lib/Drupal/custom_block/CustomBlockFormController.php b/core/modules/block/custom_block/lib/Drupal/custom_block/CustomBlockFormController.php index cde78aeeedd..20d748dc7ad 100644 --- a/core/modules/block/custom_block/lib/Drupal/custom_block/CustomBlockFormController.php +++ b/core/modules/block/custom_block/lib/Drupal/custom_block/CustomBlockFormController.php @@ -191,7 +191,7 @@ class CustomBlockFormController extends EntityFormControllerNG { } } else { - $form_state['redirect'] = 'admin/structure/block'; + $form_state['redirect'] = 'admin/structure/custom-blocks'; } } else { diff --git a/core/modules/block/custom_block/lib/Drupal/custom_block/CustomBlockListController.php b/core/modules/block/custom_block/lib/Drupal/custom_block/CustomBlockListController.php new file mode 100644 index 00000000000..d2429b60f6c --- /dev/null +++ b/core/modules/block/custom_block/lib/Drupal/custom_block/CustomBlockListController.php @@ -0,0 +1,51 @@ +uri(); + $operations['edit']['href'] = $uri['path']; + $operations['edit']['query']['destination'] = 'admin/structure/custom-blocks'; + } + return $operations; + } + +} diff --git a/core/modules/block/custom_block/lib/Drupal/custom_block/CustomBlockTypeFormController.php b/core/modules/block/custom_block/lib/Drupal/custom_block/CustomBlockTypeFormController.php index a98730e140d..06e92a5e453 100644 --- a/core/modules/block/custom_block/lib/Drupal/custom_block/CustomBlockTypeFormController.php +++ b/core/modules/block/custom_block/lib/Drupal/custom_block/CustomBlockTypeFormController.php @@ -101,7 +101,7 @@ class CustomBlockTypeFormController extends EntityFormController { watchdog('custom_block', 'Custom block type %label has been added.', array('%label' => $block_type->label()), WATCHDOG_NOTICE, l(t('Edit'), $uri['path'] . '/edit')); } - $form_state['redirect'] = 'admin/structure/custom-blocks'; + $form_state['redirect'] = 'admin/structure/custom-blocks/types'; } /** diff --git a/core/modules/block/custom_block/lib/Drupal/custom_block/CustomBlockTypeListController.php b/core/modules/block/custom_block/lib/Drupal/custom_block/CustomBlockTypeListController.php index aaf26764fa1..ed44d75a1c1 100644 --- a/core/modules/block/custom_block/lib/Drupal/custom_block/CustomBlockTypeListController.php +++ b/core/modules/block/custom_block/lib/Drupal/custom_block/CustomBlockTypeListController.php @@ -66,4 +66,13 @@ class CustomBlockTypeListController extends ConfigEntityListController { return $row; } + /** + * {@inheritdoc} + */ + public function render() { + // @todo Remove this once https://drupal.org/node/2032535 is in. + drupal_set_title(t('Custom block types')); + return parent::render(); + } + } diff --git a/core/modules/block/custom_block/lib/Drupal/custom_block/Form/CustomBlockTypeDeleteForm.php b/core/modules/block/custom_block/lib/Drupal/custom_block/Form/CustomBlockTypeDeleteForm.php index 7e595d21130..4b7c220ceb4 100644 --- a/core/modules/block/custom_block/lib/Drupal/custom_block/Form/CustomBlockTypeDeleteForm.php +++ b/core/modules/block/custom_block/lib/Drupal/custom_block/Form/CustomBlockTypeDeleteForm.php @@ -60,7 +60,7 @@ class CustomBlockTypeDeleteForm extends EntityConfirmFormBase implements EntityC * {@inheritdoc} */ public function getCancelPath() { - return 'admin/structure/custom-blocks'; + return 'admin/structure/custom-blocks/types'; } /** @@ -90,7 +90,7 @@ class CustomBlockTypeDeleteForm extends EntityConfirmFormBase implements EntityC */ public function submit(array $form, array &$form_state) { $this->entity->delete(); - $form_state['redirect'] = 'admin/structure/custom-blocks'; + $form_state['redirect'] = 'admin/structure/custom-blocks/types'; drupal_set_message(t('Custom block type %label has been deleted.', array('%label' => $this->entity->label()))); watchdog('custom_block', 'Custom block type %label has been deleted.', array('%label' => $this->entity->label()), WATCHDOG_NOTICE); } diff --git a/core/modules/block/custom_block/lib/Drupal/custom_block/Plugin/Core/Entity/CustomBlock.php b/core/modules/block/custom_block/lib/Drupal/custom_block/Plugin/Core/Entity/CustomBlock.php index 6bc0f4d2c60..97722f60d19 100644 --- a/core/modules/block/custom_block/lib/Drupal/custom_block/Plugin/Core/Entity/CustomBlock.php +++ b/core/modules/block/custom_block/lib/Drupal/custom_block/Plugin/Core/Entity/CustomBlock.php @@ -24,6 +24,7 @@ use Drupal\custom_block\CustomBlockInterface; * controllers = { * "storage" = "Drupal\custom_block\CustomBlockStorageController", * "access" = "Drupal\custom_block\CustomBlockAccessController", + * "list" = "Drupal\custom_block\CustomBlockListController", * "render" = "Drupal\custom_block\CustomBlockRenderController", * "form" = { * "add" = "Drupal\custom_block\CustomBlockFormController", diff --git a/core/modules/block/custom_block/lib/Drupal/custom_block/Tests/CustomBlockCreationTest.php b/core/modules/block/custom_block/lib/Drupal/custom_block/Tests/CustomBlockCreationTest.php index 4fe83476495..3ce451303a3 100644 --- a/core/modules/block/custom_block/lib/Drupal/custom_block/Tests/CustomBlockCreationTest.php +++ b/core/modules/block/custom_block/lib/Drupal/custom_block/Tests/CustomBlockCreationTest.php @@ -157,7 +157,9 @@ class CustomBlockCreationTest extends CustomBlockTestBase { 'settings[label]' => $edit['info'], 'region' => 'sidebar_first', ); - $this->drupalPost(NULL, $instance, t('Save block')); + $block = entity_load('custom_block', 1); + $url = 'admin/structure/block/add/custom_block:' . $block->uuid() . '/' . \Drupal::config('system.theme')->get('default'); + $this->drupalPost($url, $instance, t('Save block')); $block = custom_block_load(1); diff --git a/core/modules/block/custom_block/lib/Drupal/custom_block/Tests/CustomBlockFieldTest.php b/core/modules/block/custom_block/lib/Drupal/custom_block/Tests/CustomBlockFieldTest.php index da5ac4f0620..7c1d7d5c02a 100644 --- a/core/modules/block/custom_block/lib/Drupal/custom_block/Tests/CustomBlockFieldTest.php +++ b/core/modules/block/custom_block/lib/Drupal/custom_block/Tests/CustomBlockFieldTest.php @@ -99,13 +99,15 @@ class CustomBlockFieldTest extends CustomBlockTestBase { $this->field['field_name'] . '[und][0][title]' => 'Example.com' ); $this->drupalPost(NULL, $edit, t('Save')); + $block = entity_load('custom_block', 1); + $url = 'admin/structure/block/add/custom_block:' . $block->uuid() . '/' . \Drupal::config('system.theme')->get('default'); // Place the block. $instance = array( 'machine_name' => drupal_strtolower($edit['info']), 'settings[label]' => $edit['info'], 'region' => 'sidebar_first', ); - $this->drupalPost(NULL, $instance, t('Save block')); + $this->drupalPost($url, $instance, t('Save block')); // Navigate to home page. $this->drupalGet(''); $this->assertLinkByHref('http://example.com'); diff --git a/core/modules/block/custom_block/lib/Drupal/custom_block/Tests/CustomBlockListTest.php b/core/modules/block/custom_block/lib/Drupal/custom_block/Tests/CustomBlockListTest.php new file mode 100644 index 00000000000..438b4f98f35 --- /dev/null +++ b/core/modules/block/custom_block/lib/Drupal/custom_block/Tests/CustomBlockListTest.php @@ -0,0 +1,122 @@ + 'Custom Block listing', + 'description' => 'Tests the listing of custom blocks.', + 'group' => 'Custom Block', + ); + } + + /** + * Tests the custom block listing page. + */ + public function testListing() { + $this->drupalLogin($this->drupalCreateUser(array('administer blocks'))); + $this->drupalGet('admin/structure/custom-blocks'); + + // Test for the page title. + $this->assertTitle(t('Custom blocks') . ' | Drupal'); + + // Test for the table. + $element = $this->xpath('//div[@class="l-content"]//table'); + $this->assertTrue($element, 'Configuration entity list table found.'); + + // Test the table header. + $elements = $this->xpath('//div[@class="l-content"]//table/thead/tr/th'); + $this->assertEqual(count($elements), 2, 'Correct number of table header cells found.'); + + // Test the contents of each th cell. + $expected_items = array(t('Block description'), t('Operations')); + foreach ($elements as $key => $element) { + $this->assertIdentical((string) $element[0], $expected_items[$key]); + } + + $label = 'Antelope'; + $new_label = 'Albatross'; + // Add a new entity using the operations link. + $link_text = t('Add custom block'); + $this->assertLink($link_text); + $this->clickLink($link_text); + $this->assertResponse(200); + $edit = array(); + $langcode = Language::LANGCODE_NOT_SPECIFIED; + $edit['info'] = $label; + $edit["block_body[$langcode][0][value]"] = $this->randomName(16); + $this->drupalPost(NULL, $edit, t('Save')); + + // Confirm that once the user returns to the listing, the text of the label + // (versus elsewhere on the page). + $this->assertFieldByXpath('//td', $label, 'Label found for added block.'); + + // Check the number of table row cells. + $elements = $this->xpath('//div[@class="l-content"]//table/tbody/tr[@class="odd"]/td'); + $this->assertEqual(count($elements), 2, 'Correct number of table row cells found.'); + // Check the contents of each row cell. The first cell contains the label, + // the second contains the machine name, and the third contains the + // operations list. + $this->assertIdentical((string) $elements[0], $label); + + // Edit the entity using the operations link. + $blocks = $this->container + ->get('plugin.manager.entity') + ->getStorageController('custom_block') + ->loadByProperties(array('info' => $label)); + $block = reset($blocks); + if (!empty($block)) { + $this->assertLinkByHref('block/' . $block->id()); + $this->clickLink(t('Edit')); + $this->assertResponse(200); + $this->assertTitle(strip_tags(t('Edit custom block %label', array('%label' => $label)) . ' | Drupal')); + $edit = array('info' => $new_label); + $this->drupalPost(NULL, $edit, t('Save')); + } + else { + $this->fail('Did not find Albatross block in the database.'); + } + + // Confirm that once the user returns to the listing, the text of the label + // (versus elsewhere on the page). + $this->assertFieldByXpath('//td', $new_label, 'Label found for updated custom block.'); + + // Delete the added entity using the operations link. + $this->assertLinkByHref('block/' . $block->id() . '/delete'); + $delete_text = t('Delete'); + $this->clickLink($delete_text); + $this->assertResponse(200); + $this->assertTitle(strip_tags(t('Are you sure you want to delete %label?', array('%label' => $new_label)) . ' | Drupal')); + $this->drupalPost(NULL, array(), $delete_text); + + // Verify that the text of the label and machine name does not appear in + // the list (though it may appear elsewhere on the page). + $this->assertNoFieldByXpath('//td', $new_label, 'No label found for deleted custom block.'); + + // Confirm that the empty text is displayed. + $this->assertText(t('There is no Custom Block yet.')); + } + +} diff --git a/core/modules/block/custom_block/lib/Drupal/custom_block/Tests/CustomBlockTypeTest.php b/core/modules/block/custom_block/lib/Drupal/custom_block/Tests/CustomBlockTypeTest.php index 37dbf7964a0..4e8c7d68ee4 100644 --- a/core/modules/block/custom_block/lib/Drupal/custom_block/Tests/CustomBlockTypeTest.php +++ b/core/modules/block/custom_block/lib/Drupal/custom_block/Tests/CustomBlockTypeTest.php @@ -61,7 +61,7 @@ class CustomBlockTypeTest extends CustomBlockTestBase { 'id' => 'foo', 'label' => 'title for foo', ); - $this->drupalPost('admin/structure/custom-blocks/add', $edit, t('Save')); + $this->drupalPost('admin/structure/custom-blocks/types/add', $edit, t('Save')); $block_type = entity_load('custom_block_type', 'foo'); $this->assertTrue($block_type, 'The new block type has been created.');