diff --git a/core/modules/settings_tray/settings_tray.module b/core/modules/settings_tray/settings_tray.module index 48b08caaab..834c6f4515 100644 --- a/core/modules/settings_tray/settings_tray.module +++ b/core/modules/settings_tray/settings_tray.module @@ -9,8 +9,12 @@ use Drupal\Core\Routing\RouteMatchInterface; use Drupal\Core\Url; use Drupal\settings_tray\Block\BlockEntityOffCanvasForm; +use \Drupal\settings_tray\Form\BlockFormWithRelatedConfigInterface; use Drupal\settings_tray\Form\SystemBrandingOffCanvasForm; use Drupal\settings_tray\Form\SystemMenuOffCanvasForm; +use Drupal\block\BlockInterface; +use Drupal\block\Entity\Block; +use \Drupal\Core\Plugin\PluginWithFormsInterface; /** * Implements hook_help(). @@ -54,6 +58,32 @@ function settings_tray_contextual_links_view_alter(&$element, $items) { } } +/** + * Checks if a block has overrides. + * + * @param \Drupal\block\BlockInterface $block + * The block to check for overrides. + * + * @return bool + * TRUE if the block has overrides otherwise FALSE. + * + * @internal + */ +function _settings_tray_has_block_overrides(BlockInterface $block) { + $has_overrides = \Drupal::config($block->getEntityType()->getConfigPrefix() . '.' . $block->id())->hasOverrides(); + if (!$has_overrides) { + // Check if the related config has overriddes + $block_plugin = $block->getPlugin(); + if ($block_plugin instanceof PluginWithFormsInterface) { + $settings_tray_form = Drupal::service('plugin_form.factory')->createInstance($block_plugin, 'settings_tray', 'configure'); + if($settings_tray_form instanceof BlockFormWithRelatedConfigInterface) { + $has_overrides = $settings_tray_form->hasOverriddenConfig(); + } + } + } + return $has_overrides; +} + /** * Implements hook_block_view_alter(). */ @@ -93,10 +123,14 @@ function settings_tray_preprocess_block(&$variables) { $block_plugin_manager = \Drupal::service('plugin.manager.block'); /** @var \Drupal\Core\Block\BlockPluginInterface $block_plugin */ $block_plugin = $block_plugin_manager->createInstance($variables['plugin_id']); - if ($access_checker->accessBlockPlugin($block_plugin)->isAllowed()) { - // Add class and attributes to all blocks to allow Javascript to target. - $variables['attributes']['class'][] = 'settings-tray-editable'; - $variables['attributes']['data-drupal-settingstray'] = 'editable'; + if (!empty($variables['elements']['#contextual_links']['block']['route_parameters']['block'])) { + $block_id = $variables['elements']['#contextual_links']['block']['route_parameters']['block']; + $block = Block::load($block_id); + if ($access_checker->accessBlockPlugin($block_plugin)->isAllowed() && !_settings_tray_has_block_overrides($block)) { + // Add class and attributes to all blocks to allow Javascript to target. + $variables['attributes']['class'][] = 'settings-tray-editable'; + $variables['attributes']['data-drupal-settingstray'] = 'editable'; + } } } @@ -196,3 +230,15 @@ function settings_tray_css_alter(&$css, AttachedAssetsInterface $assets) { $css[$path]['group'] = 200; } } + +/** + * Implements hook_contextual_links_alter(). + */ +function settings_tray_contextual_links_alter(array &$links, $group, array $route_parameters) { + if (isset($links['settings_tray.block_configure']['route_parameters']['block'])) { + $block = Block::load($links['settings_tray.block_configure']['route_parameters']['block']); + if (_settings_tray_has_block_overrides($block)) { + unset($links['settings_tray.block_configure']); + } + } +} diff --git a/core/modules/settings_tray/src/Form/BlockFormWithRelatedConfigInterface.php b/core/modules/settings_tray/src/Form/BlockFormWithRelatedConfigInterface.php new file mode 100644 index 0000000000..9ae4dc6720 --- /dev/null +++ b/core/modules/settings_tray/src/Form/BlockFormWithRelatedConfigInterface.php @@ -0,0 +1,19 @@ +plugin->submitConfigurationForm($form, $form_state); } + /** + * {@inheritdoc} + */ + public function hasOverriddenConfig() { + $config = $this->configFactory->get('system.site'); + return $config->hasOverrides('name') || $config->hasOverrides('slogan'); + } } diff --git a/core/modules/settings_tray/src/Form/SystemMenuOffCanvasForm.php b/core/modules/settings_tray/src/Form/SystemMenuOffCanvasForm.php index 15d19a87f9..3d202b6651 100644 --- a/core/modules/settings_tray/src/Form/SystemMenuOffCanvasForm.php +++ b/core/modules/settings_tray/src/Form/SystemMenuOffCanvasForm.php @@ -22,7 +22,7 @@ * * @internal */ -class SystemMenuOffCanvasForm extends PluginFormBase implements ContainerInjectionInterface { +class SystemMenuOffCanvasForm extends PluginFormBase implements ContainerInjectionInterface, BlockFormWithRelatedConfigInterface { use StringTranslationTrait; use RedirectDestinationTrait; @@ -150,4 +150,11 @@ public function setPlugin(PluginInspectionInterface $plugin) { $this->menu = $this->menuStorage->load($this->plugin->getDerivativeId()); } + /** + * {@inheritdoc} + */ + public function hasOverriddenConfig() { + return \Drupal::config($this->menu->getEntityType()->getConfigPrefix() . '.' . $this->menu->id())->hasOverrides(); + } + } diff --git a/core/modules/settings_tray/tests/modules/settings_tray_override_test/settings_tray_override_test.info.yml b/core/modules/settings_tray/tests/modules/settings_tray_override_test/settings_tray_override_test.info.yml new file mode 100644 index 0000000000..89f9732feb --- /dev/null +++ b/core/modules/settings_tray/tests/modules/settings_tray_override_test/settings_tray_override_test.info.yml @@ -0,0 +1,7 @@ +name: 'Configuration override test for Settings Tray' +type: module +package: Testing +version: VERSION +core: 8.x +dependencies: + - settings_tray diff --git a/core/modules/settings_tray/tests/modules/settings_tray_override_test/settings_tray_override_test.services.yml b/core/modules/settings_tray/tests/modules/settings_tray_override_test/settings_tray_override_test.services.yml new file mode 100644 index 0000000000..b23035bde2 --- /dev/null +++ b/core/modules/settings_tray/tests/modules/settings_tray_override_test/settings_tray_override_test.services.yml @@ -0,0 +1,5 @@ +services: + settings_tray_override_test.overrider: + class: Drupal\settings_tray_override_test\ConfigOverrider + tags: + - { name: config.factory.override} diff --git a/core/modules/settings_tray/tests/modules/settings_tray_override_test/src/ConfigOverrider.php b/core/modules/settings_tray/tests/modules/settings_tray_override_test/src/ConfigOverrider.php new file mode 100644 index 0000000000..1171a1bb90 --- /dev/null +++ b/core/modules/settings_tray/tests/modules/settings_tray_override_test/src/ConfigOverrider.php @@ -0,0 +1,53 @@ + ['settings' => ['label' => 'Now this will be the label.']]]; + } + if (in_array('system.site', $names)) { + if ($site_name = \Drupal::state()->get('settings_tray_override_test.site_name')) { + $overrides = $overrides + ['system.site' => ['name' => $site_name]]; + } + } + return $overrides; + } + + /** + * {@inheritdoc} + */ + public function getCacheSuffix() { + return 'ConfigOverrider'; + } + + /** + * {@inheritdoc} + */ + public function createConfigObject($name, $collection = StorageInterface::DEFAULT_COLLECTION) { + return NULL; + } + + /** + * {@inheritdoc} + */ + public function getCacheableMetadata($name) { + return new CacheableMetadata(); + } + +} diff --git a/core/modules/settings_tray/tests/src/FunctionalJavascript/SettingsTrayBlockFormTest.php b/core/modules/settings_tray/tests/src/FunctionalJavascript/SettingsTrayBlockFormTest.php index fcfecde400..c308d0edc3 100644 --- a/core/modules/settings_tray/tests/src/FunctionalJavascript/SettingsTrayBlockFormTest.php +++ b/core/modules/settings_tray/tests/src/FunctionalJavascript/SettingsTrayBlockFormTest.php @@ -43,6 +43,7 @@ class SettingsTrayBlockFormTest extends OffCanvasTestBase { // cause test failures. 'settings_tray_test_css', 'settings_tray_test', + 'settings_tray_override_test', ]; /** @@ -75,7 +76,7 @@ public function testBlocks($theme, $block_plugin, $new_page_text, $element_selec $page = $this->getSession()->getPage(); $this->enableTheme($theme); $block = $this->placeBlock($block_plugin); - $block_selector = str_replace('_', '-', $this->getBlockSelector($block)); + $block_selector = $this->getBlockSelector($block); $block_id = $block->id(); $this->drupalGet('user'); @@ -267,8 +268,10 @@ protected function assertOffCanvasBlockFormIsValid() { * @param string $contextual_link_container * The element that contains the contextual links. If none provide the * $block_selector will be used. + * @param bool $has_confirm_form + * Determines if the block form should be confirmed. */ - protected function openBlockForm($block_selector, $contextual_link_container = '') { + protected function openBlockForm($block_selector, $contextual_link_container = '', $has_confirm_form = TRUE) { if (!$contextual_link_container) { $contextual_link_container = $block_selector; } @@ -283,7 +286,9 @@ protected function openBlockForm($block_selector, $contextual_link_container = ' $this->assertSession()->assertWaitOnAjaxRequest(); $this->click($block_selector); $this->waitForOffCanvasToOpen(); - $this->assertOffCanvasBlockFormIsValid(); + if ($has_confirm_form) { + $this->assertOffCanvasBlockFormIsValid(); + } } /** @@ -321,7 +326,7 @@ public function testQuickEditLinks() { $this->enableTheme($theme); $block = $this->placeBlock($block_plugin); - $block_selector = str_replace('_', '-', $this->getBlockSelector($block)); + $block_selector = $this->getBlockSelector($block); // Load the same page twice. foreach ([1, 2] as $page_load_times) { $this->drupalGet('node/' . $node->id()); @@ -531,7 +536,7 @@ public function testCustomBlockLinks() { * The CSS selector. */ public function getBlockSelector(Block $block) { - return '#block-' . $block->id(); + return '#block-' . str_replace('_', '-', $block->id()); } /** @@ -577,4 +582,67 @@ protected function getTestThemes() { }); } + /** + * Tests that blocks with configuration overrides are disabled. + */ + public function testOverriddenDisabled() { + $web_assert = $this->assertSession(); + $page = $this->getSession()->getPage(); + $overridden_block = $this->placeBlock('system_powered_by_block', [ + 'id' => 'overridden_block', + 'label_display' => 1, + 'label' => 'This will be overridden.', + ]); + $this->drupalGet('user'); + $this->assertOverriddenBlockDisabled($overridden_block, 'Now this will be the label.'); + + // Test a non-overridden block does show the form in the off-canvas dialog. + $block = $this->placeBlock('system_powered_by_block', [ + 'label_display' => 1, + 'label' => 'Labely label', + ]); + $this->drupalGet('user'); + $block_selector = $this->getBlockSelector($block); + // Confirm the block is marked as Settings Tray editable. + $this->assertEquals('editable', $page->find('css', $block_selector)->getAttribute('data-drupal-settingstray')); + // Confirm the label is not overridden. + $web_assert->elementContains('css', $block_selector, 'Labely label'); + $this->enableEditMode(); + $this->openBlockForm($this->getBlockSelector($block)); + + // Confirm the branding block is disabled when site name is overridden. + $overridden_name = 'The namey name'; + $this->container->get('state')->set('settings_tray_override_test.site_name', $overridden_name); + $overridden_branding_block = $this->placeBlock('system_branding_block'); + $this->drupalGet('user'); + $this->assertOverriddenBlockDisabled($overridden_branding_block, $overridden_name); + } + + /** + * Asserts that an overridden block has Settings Tray disabled. + * + * @param \Drupal\block\Entity\Block $overridden_block + * The overridden block. + * @param string $override_text + * The override text that should appear in the block. + */ + protected function assertOverriddenBlockDisabled(Block $overridden_block, $override_text) { + $web_assert = $this->assertSession(); + $page = $this->getSession()->getPage(); + $block_selector = $this->getBlockSelector($overridden_block); + $block_id = $overridden_block->id(); + // Confirm the block does not have a quick edit link. + $contextual_links = $page->findAll('css', "$block_selector .contextual-links li a"); + $this->assertNotEmpty($contextual_links); + foreach ($contextual_links as $link) { + $this->assertNotContains("/admin/structure/block/manage/$block_id/off-canvas", $link->getAttribute('href')); + } + // Confirm the block is not marked as Settings Tray editable. + $this->assertFalse($page->find('css', $block_selector) + ->hasAttribute('data-drupal-settingstray')); + + // Confirm the text is actually overridden. + $web_assert->elementContains('css', $this->getBlockSelector($overridden_block), $override_text); + } + } diff --git a/core/modules/system/tests/src/FunctionalJavascript/OffCanvasTestBase.php b/core/modules/system/tests/src/FunctionalJavascript/OffCanvasTestBase.php index d3f446cf6a..86cca2c680 100644 --- a/core/modules/system/tests/src/FunctionalJavascript/OffCanvasTestBase.php +++ b/core/modules/system/tests/src/FunctionalJavascript/OffCanvasTestBase.php @@ -9,6 +9,11 @@ */ abstract class OffCanvasTestBase extends JavascriptTestBase { + /** + * CSS selector for the off-canvas dialog. + */ + const OFF_CANVAS_CSS_SELECTOR = '.ui-dialog[aria-describedby="drupal-off-canvas"]'; + /** * {@inheritdoc} */ @@ -83,7 +88,7 @@ protected function waitForOffCanvasToClose() { * @return \Behat\Mink\Element\NodeElement|null */ protected function getOffCanvasDialog() { - $off_canvas_dialog = $this->getSession()->getPage()->find('css', '.ui-dialog[aria-describedby="drupal-off-canvas"]'); + $off_canvas_dialog = $this->getSession()->getPage()->find('css', self::OFF_CANVAS_CSS_SELECTOR); $this->assertEquals(FALSE, empty($off_canvas_dialog), 'The off-canvas dialog was found.'); return $off_canvas_dialog; }