diff --git a/core/modules/region/config/region.body.yml b/core/modules/region/config/region.body.yml new file mode 100644 index 0000000..1b06f89 --- /dev/null +++ b/core/modules/region/config/region.body.yml @@ -0,0 +1,2 @@ +id: body +label: Body diff --git a/core/modules/region/config/region.footer_a.yml b/core/modules/region/config/region.footer_a.yml new file mode 100644 index 0000000..e3f611e --- /dev/null +++ b/core/modules/region/config/region.footer_a.yml @@ -0,0 +1,2 @@ +id: footer_a +label: Footer A diff --git a/core/modules/region/config/region.footer_b.yml b/core/modules/region/config/region.footer_b.yml new file mode 100644 index 0000000..0f04323 --- /dev/null +++ b/core/modules/region/config/region.footer_b.yml @@ -0,0 +1,2 @@ +id: footer_b +label: Footer B diff --git a/core/modules/region/config/region.footer_c.yml b/core/modules/region/config/region.footer_c.yml new file mode 100644 index 0000000..2f9dbe5 --- /dev/null +++ b/core/modules/region/config/region.footer_c.yml @@ -0,0 +1,2 @@ +id: footer_c +label: Footer C diff --git a/core/modules/region/config/region.header_a.yml b/core/modules/region/config/region.header_a.yml new file mode 100644 index 0000000..c3867f3 --- /dev/null +++ b/core/modules/region/config/region.header_a.yml @@ -0,0 +1,2 @@ +id: header_a +label: Header A diff --git a/core/modules/region/config/region.header_b.yml b/core/modules/region/config/region.header_b.yml new file mode 100644 index 0000000..d91fe82 --- /dev/null +++ b/core/modules/region/config/region.header_b.yml @@ -0,0 +1,2 @@ +id: header_b +label: Header B diff --git a/core/modules/region/config/region.header_c.yml b/core/modules/region/config/region.header_c.yml new file mode 100644 index 0000000..204ab21 --- /dev/null +++ b/core/modules/region/config/region.header_c.yml @@ -0,0 +1,2 @@ +id: header_c +label: Header C diff --git a/core/modules/region/config/region.navigation.yml b/core/modules/region/config/region.navigation.yml new file mode 100644 index 0000000..2f7afff --- /dev/null +++ b/core/modules/region/config/region.navigation.yml @@ -0,0 +1,2 @@ +id: navigation +label: Navigation diff --git a/core/modules/region/config/region.sidebar_a.yml b/core/modules/region/config/region.sidebar_a.yml new file mode 100644 index 0000000..7c27f3f --- /dev/null +++ b/core/modules/region/config/region.sidebar_a.yml @@ -0,0 +1,2 @@ +id: sidebar_a +label: Sidebar A diff --git a/core/modules/region/config/region.sidebar_b.yml b/core/modules/region/config/region.sidebar_b.yml new file mode 100644 index 0000000..e5a8e03 --- /dev/null +++ b/core/modules/region/config/region.sidebar_b.yml @@ -0,0 +1,2 @@ +id: sidebar_b +label: Sidebar B diff --git a/core/modules/region/config/region.sidebar_c.yml b/core/modules/region/config/region.sidebar_c.yml new file mode 100644 index 0000000..00c9bc9 --- /dev/null +++ b/core/modules/region/config/region.sidebar_c.yml @@ -0,0 +1,2 @@ +id: sidebar_c +label: Sidebar C diff --git a/core/modules/region/config/region.subheader_a.yml b/core/modules/region/config/region.subheader_a.yml new file mode 100644 index 0000000..db7685c --- /dev/null +++ b/core/modules/region/config/region.subheader_a.yml @@ -0,0 +1,2 @@ +id: subheader_a +label: Subheader A diff --git a/core/modules/region/config/region.subheader_b.yml b/core/modules/region/config/region.subheader_b.yml new file mode 100644 index 0000000..269a100 --- /dev/null +++ b/core/modules/region/config/region.subheader_b.yml @@ -0,0 +1,2 @@ +id: subheader_b +label: Subheader B diff --git a/core/modules/region/config/region.subheader_c.yml b/core/modules/region/config/region.subheader_c.yml new file mode 100644 index 0000000..0149b78 --- /dev/null +++ b/core/modules/region/config/region.subheader_c.yml @@ -0,0 +1,2 @@ +id: subheader_c +label: Subheader C diff --git a/core/modules/region/config/region.title.yml b/core/modules/region/config/region.title.yml new file mode 100644 index 0000000..aa36188 --- /dev/null +++ b/core/modules/region/config/region.title.yml @@ -0,0 +1,2 @@ +id: title +label: Title diff --git a/core/modules/region/lib/Drupal/region/Plugin/Core/Entity/Region.php b/core/modules/region/lib/Drupal/region/Plugin/Core/Entity/Region.php new file mode 100644 index 0000000..1e26642 --- /dev/null +++ b/core/modules/region/lib/Drupal/region/Plugin/Core/Entity/Region.php @@ -0,0 +1,59 @@ + 'textfield', + '#title' => t('Label'), + '#maxlength' => 255, + '#default_value' => $region->label(), + '#description' => t("Example: 'Banner' or 'Highlight'."), + '#required' => TRUE, + ); + $form['id'] = array( + '#type' => 'machine_name', + '#default_value' => $region->id(), + '#machine_name' => array( + 'exists' => 'region_load', + 'source' => array('label'), + ), + '#disabled' => !$region->isNew(), + ); + return parent::form($form, $form_state, $region); + } + + /** + * Overrides Drupal\Core\Entity\EntityFormController::actions(). + */ + protected function actions(array $form, array &$form_state) { + // Only includes a Save action for the entity, no direct Delete button. + return array( + 'submit' => array( + '#value' => t('Save'), + '#validate' => array( + array($this, 'validate'), + ), + '#submit' => array( + array($this, 'submit'), + array($this, 'save'), + ), + ), + ); + } + + /** + * Overrides Drupal\Core\Entity\EntityFormController::save(). + */ + public function save(array $form, array &$form_state) { + $region = $this->getEntity($form_state); + $region->save(); + + watchdog('region', 'Region @label saved.', array('@label' => $region->label()), WATCHDOG_NOTICE); + drupal_set_message(t('Region %label saved.', array('%label' => $region->label()))); + + $form_state['redirect'] = 'admin/structure/regions'; + } + +} + diff --git a/core/modules/region/lib/Drupal/region/Tests/RegionTest.php b/core/modules/region/lib/Drupal/region/Tests/RegionTest.php new file mode 100644 index 0000000..e7b32c9 --- /dev/null +++ b/core/modules/region/lib/Drupal/region/Tests/RegionTest.php @@ -0,0 +1,141 @@ + 'Region management', + 'description' => 'Tests region management.', + 'group' => 'Region', + ); + } + + /** + * Tests the default regions. + */ + function testDefaultRegions() { + // Create a new user, allow him to manage the blocks and the languages. + $admin_user = $this->drupalCreateUser(array( + 'administer regions', + )); + $this->drupalLogin($admin_user); + + // Check that these regions show up on the user interface. + $base_regions = array( + 'header_a' => 'Header A', + 'header_b' => 'Header B', + 'header_c' => 'Header C', + 'subheader_a' => 'Subheader A', + 'subheader_b' => 'Subheader B', + 'subheader_c' => 'Subheader C', + 'navigation' => 'Navigation', + 'title' => 'Title', + 'body' => 'Body', + 'sidebar_a' => 'Sidebar A', + 'sidebar_b' => 'Sidebar B', + 'sidebar_c' => 'Sidebar C', + 'footer_a' => 'Footer A', + 'footer_b' => 'Footer B', + 'footer_c' => 'Footer C', + ); + + // Check if the visibility setting is available. + $this->drupalGet('admin/structure/regions'); + foreach($base_regions as $machine_name => $label) { + $this->assertText($machine_name); + $this->assertText($label); + } + } + + /** + * Tests editing a default region. + */ + function testEditDefaultRegion() { + // Create a new user, allow him to manage the blocks and the languages. + $admin_user = $this->drupalCreateUser(array( + 'administer regions', + )); + $this->drupalLogin($admin_user); + + $this->drupalGet('admin/structure/regions/manage/body/edit'); + $this->assertResponse(200); + $this->assertPattern('!disabled="disabled"(.+)id="edit-id"(.+)value="body"!', 'Existing region name machine name field is disabled.'); + + $edit = array('label' => 'Page content'); + $this->drupalPost('admin/structure/regions/manage/body/edit', $edit, t('Save')); + $this->assertText('Page content'); + $this->assertNoText('Body'); + $this->assertRaw(t('Region %label saved.', array('%label' => 'Page content'))); + } + + /** + * Tests deleting a default region. + */ + function testDeleteDefaultRegion() { + // Create a new user, allow him to manage the blocks and the languages. + $admin_user = $this->drupalCreateUser(array( + 'administer regions', + )); + $this->drupalLogin($admin_user); + + $this->drupalGet('admin/structure/regions/manage/body/delete'); + $this->assertResponse(200); + + $this->drupalPost('admin/structure/regions/manage/body/delete', array(), t('Delete')); + $this->assertRaw(t('Region %label has been deleted.', array('%label' => 'Body'))); + $this->assertNoText('body'); + } + + /** + * Tests adding a new region and all actions on that. + */ + function testNewRegion() { + // Create a new user, allow him to manage the blocks and the languages. + $admin_user = $this->drupalCreateUser(array( + 'administer regions', + )); + $this->drupalLogin($admin_user); + + $edit = array('label' => 'Banner', 'id' => 'banner'); + $this->drupalPost('admin/structure/regions/add', $edit, t('Save')); + $this->assertText('banner'); + $this->assertRaw(t('Region %label saved.', array('%label' => 'Banner'))); + + $edit = array('label' => 'Highlight'); + $this->drupalPost('admin/structure/regions/manage/banner/edit', $edit, t('Save')); + $this->assertNoText('Banner'); + $this->assertText('banner'); + $this->assertRaw(t('Region %label saved.', array('%label' => 'Highlight'))); + + $edit = array('label' => 'Conflicting banner', 'id' => 'banner'); + $this->drupalPost('admin/structure/regions/add', $edit, t('Save')); + $this->assertText(t('The machine-readable name is already in use. It must be unique.')); + + $this->drupalGet('admin/structure/regions/manage/banner/edit'); + $this->assertPattern('!disabled="disabled"(.+)id="edit-id"(.+)value="banner"!', 'Existing region name machine name field is disabled.'); + + $this->drupalPost('admin/structure/regions/manage/banner/delete', array(), t('Delete')); + $this->assertRaw(t('Region %label has been deleted.', array('%label' => 'Highlight'))); + $this->assertNoText('banner'); + } + +} diff --git a/core/modules/region/region.admin.inc b/core/modules/region/region.admin.inc new file mode 100644 index 0000000..8c36b63 --- /dev/null +++ b/core/modules/region/region.admin.inc @@ -0,0 +1,67 @@ +render(); +} + +/** + * Page callback: Presents the region editing form. + * + * @see region_menu() + */ +function region_page_edit(Region $region) { + drupal_set_title(t('Edit region @label', array('@label' => $region->label())), PASS_THROUGH); + return entity_get_form($region); +} + +/** + * Page callback: Provides the new region addition form. + * + * @see region_menu() + */ +function region_page_add() { + $region = entity_create('region', array()); + return entity_get_form($region); +} + +/** + * Page callback: Form constructor for region deletion confirmation form. + * + * @see region_menu() + */ +function region_confirm_delete($form, &$form_state, Region $region) { + // Always provide entity id in the same form key as in the entity edit form. + $form['id'] = array('#type' => 'value', '#value' => $region->id()); + $form_state['region'] = $region; + return confirm_form($form, + t('Are you sure you want to remove the region %title?', array('%title' => $region->label())), + 'admin/structure/regions', + t('This action cannot be undone.'), + t('Delete'), + t('Cancel') + ); +} + +/** + * Form submission handler for region_delete_confirm(). + */ +function region_confirm_delete_submit($form, &$form_state) { + $region = $form_state['region']; + $region->delete(); + drupal_set_message(t('Region %label has been deleted.', array('%label' => $region->label()))); + watchdog('region', 'Region %label has been deleted.', array('%label' => $region->label()), WATCHDOG_NOTICE); + $form_state['redirect'] = 'admin/structure/regions'; +} diff --git a/core/modules/region/region.info b/core/modules/region/region.info new file mode 100644 index 0000000..552b8f3 --- /dev/null +++ b/core/modules/region/region.info @@ -0,0 +1,7 @@ +name = Region +description = Maintains a common set of regions available to dynamic layouts. +package = Core +version = VERSION +core = 8.x +dependencies[] = config +configure = admin/structure/regions diff --git a/core/modules/region/region.module b/core/modules/region/region.module new file mode 100644 index 0000000..32561e6 --- /dev/null +++ b/core/modules/region/region.module @@ -0,0 +1,111 @@ +' . t('Regions allow you to place blocks on pages. The region module provides management facilities for a dynamic region list useful for layout builders which allow you to dynamically edit your page layouts. It is not useful for static layouts shipped with modules and themes.') . '

'; + } +} + +/** + * Implements hook_menu(). + */ +function region_menu() { + $items['admin/structure/regions'] = array( + 'title' => 'Regions', + 'description' => 'Manage list of regions that allow content to be placed.', + 'page callback' => 'region_page_list', + 'access callback' => 'user_access', + 'access arguments' => array('administer regions'), + 'file' => 'region.admin.inc', + ); + $items['admin/structure/regions/add'] = array( + 'title' => 'Add region', + 'page callback' => 'region_page_add', + 'access callback' => 'user_access', + 'access arguments' => array('administer regions'), + 'type' => MENU_LOCAL_ACTION, + 'file' => 'region.admin.inc', + ); + $items['admin/structure/regions/manage/%region'] = array( + 'title' => 'Edit region', + 'page callback' => 'region_page_edit', + 'page arguments' => array(4), + 'access callback' => 'user_access', + 'access arguments' => array('administer regions'), + 'type' => MENU_CALLBACK, + 'file' => 'region.admin.inc', + ); + $items['admin/structure/regions/manage/%region/edit'] = array( + 'title' => 'Edit', + 'type' => MENU_DEFAULT_LOCAL_TASK, + 'weight' => -100, + ); + $items['admin/structure/regions/manage/%region/delete'] = array( + 'title' => 'Delete', + 'page callback' => 'drupal_get_form', + 'page arguments' => array('region_confirm_delete', 4), + 'access callback' => 'user_access', + 'access arguments' => array('administer regions'), + 'type' => MENU_LOCAL_TASK, + 'file' => 'region.admin.inc', + ); + return $items; +} + +/** + * Implements hook_permission(). + */ +function region_permission() { + return array( + 'administer regions' => array( + 'title' => t('Administer regions'), + 'description' => t('Manage list of regions available on the site.'), + ), + ); +} + +/** + * Entity URI callback. + * + * @param Drupal\region\Region $region + * Region configuration entity instance. + * + * @return array + * Entity URI information. + */ +function region_uri(Region $region) { + return array( + 'path' => 'admin/structure/regions/manage/' . $region->id(), + ); +} + +/** + * Load one region object by its identifier. + * + * @return Drupal\region\Region + * Region configuration entity instance. + */ +function region_load($id) { + return entity_load('region', $id); +} + +/** + * Load all region objects. + * + * @return array + * List of Drupal\region\Region instances keyed by id. + */ +function region_load_all() { + return entity_load_multiple('region'); +}