reverted: --- b/core/modules/layout_builder/src/Field/LayoutSectionItemList.php +++ a/core/modules/layout_builder/src/Field/LayoutSectionItemList.php @@ -55,16 +55,4 @@ return $entity; } - /** - * Magic method: Implements a deep clone. - */ - public function __clone() { - $sections = $this->getSections(); - - foreach ($sections as $delta => $item) { - $sections[$delta] = clone $item; - } - - $this->setSections($sections); - } } diff -u b/core/modules/layout_builder/src/InlineBlockEntityOperations.php b/core/modules/layout_builder/src/InlineBlockEntityOperations.php --- b/core/modules/layout_builder/src/InlineBlockEntityOperations.php +++ b/core/modules/layout_builder/src/InlineBlockEntityOperations.php @@ -150,13 +150,13 @@ return; } $duplicate_blocks = FALSE; - $is_translating = FALSE; + $is_new_translation = FALSE; $sections = $this->getEntitySections($entity); if ($entity instanceof TranslatableInterface && $entity->isTranslatable()) { if (!$entity->isNew() && $entity->isNewTranslation() && !$entity->isDefaultTranslation()) { - $is_translating = TRUE; + $is_new_translation = TRUE; if ($this->isEntityUsingFieldOverride($entity) && !empty($sections)) { $duplicate_blocks = TRUE; } @@ -164,7 +164,7 @@ } if ($sections) { - if (!$is_translating && $this->isEntityUsingFieldOverride($entity)) { + if (!$is_new_translation && $this->isEntityUsingFieldOverride($entity)) { if (!$entity->isNew() && isset($entity->original)) { if (empty($this->getEntitySections($entity->original))) { // If there were no sections in the original entity then this is a diff -u b/core/modules/layout_builder/tests/src/FunctionalJavascript/InlineBlockTranslationTest.php b/core/modules/layout_builder/tests/src/FunctionalJavascript/InlineBlockTranslationTest.php --- b/core/modules/layout_builder/tests/src/FunctionalJavascript/InlineBlockTranslationTest.php +++ b/core/modules/layout_builder/tests/src/FunctionalJavascript/InlineBlockTranslationTest.php @@ -6,7 +6,7 @@ use Drupal\Core\Url; /** - * Tests that inline blocks with content translation. + * Tests that inline blocks works with content translation. * * @group layout_builder */ @@ -43,7 +43,6 @@ */ public function testInlineBlockContentTranslation() { $assert_session = $this->assertSession(); - $page = $this->getSession()->getPage(); $this->drupalLogin($this->drupalCreateUser([ 'access contextual links', @@ -115,2 +114,144 @@ + /** + * Tests that an translated entity can override the layout from default. + */ + public function testInlineBlockContentTranslationOverrideFromDefault() { + $assert_session = $this->assertSession(); + + $this->drupalLogin($this->drupalCreateUser([ + 'access contextual links', + 'configure any layout', + 'administer node display', + 'administer node fields', + 'translate bundle_with_section_field node', + 'create content translations', + ])); + + // Allow layout overrides. + $this->drupalPostForm( + static::FIELD_UI_PREFIX . '/display/default', + ['layout[enabled]' => TRUE], + 'Save' + ); + $this->drupalPostForm( + static::FIELD_UI_PREFIX . '/display/default', + ['layout[allow_custom]' => TRUE], + 'Save' + ); + + // Create a translation. + $add_translation_url = Url::fromRoute("entity.node.content_translation_add", [ + 'node' => 1, + 'source' => 'en', + 'target' => 'it', + ]); + $this->drupalPostForm($add_translation_url, [ + 'title[0][value]' => 'The translated node title', + 'body[0][value]' => 'The translated node body', + ], 'Save'); + + + // Add an inline block to the default layout. + $this->drupalGet(static::FIELD_UI_PREFIX . '/display/default'); + $this->clickLink('Manage layout'); + $assert_session->addressEquals(static::FIELD_UI_PREFIX . '/display-layout/default'); + $this->addInlineBlockToLayout('Block title', 'The DEFAULT block body'); + $this->assertSaveLayout(); + + $this->drupalGet('node/1'); + $assert_session->pageTextContains('The DEFAULT block body'); + $this->drupalGet('it/node/1'); + $assert_session->pageTextContains('The DEFAULT block body'); + + + // Override the translated node's layout. + $this->drupalGet('it/node/1/layout'); + $this->configureInlineBlock('The DEFAULT block body', 'Overriden block body'); + $this->assertSaveLayout(); + + $this->drupalGet('node/1'); + $assert_session->pageTextContains('The DEFAULT block body'); + $assert_session->pageTextNotContains('Overriden block body'); + $this->drupalGet('it/node/1'); + $assert_session->pageTextContains('Overriden block body'); + $assert_session->pageTextNotContains('The DEFAULT block body'); + } + + /** + * Tests deleting an translated entity with inline block. + */ + public function testDeletingTranslatedEntityWithInlineBlock() { + /** @var \Drupal\Core\Cron $cron */ + $cron = \Drupal::service('cron'); + /** @var \Drupal\layout_builder\InlineBlockUsage $usage */ + $usage = \Drupal::service('inline_block.usage'); + + $assert_session = $this->assertSession(); + + $this->drupalLogin($this->drupalCreateUser([ + 'access contextual links', + 'configure any layout', + 'administer node display', + 'administer node fields', + 'translate bundle_with_section_field node', + 'create content translations', + 'delete content translations', + ])); + + // Allow layout overrides. + $this->drupalPostForm( + static::FIELD_UI_PREFIX . '/display/default', + ['layout[enabled]' => TRUE], + 'Save' + ); + $this->drupalPostForm( + static::FIELD_UI_PREFIX . '/display/default', + ['layout[allow_custom]' => TRUE], + 'Save' + ); + + // Create a translation. + $add_translation_url = Url::fromRoute("entity.node.content_translation_add", [ + 'node' => 1, + 'source' => 'en', + 'target' => 'it', + ]); + $this->drupalPostForm($add_translation_url, [ + 'title[0][value]' => 'The translated node title', + 'body[0][value]' => 'The translated node body', + ], 'Save'); + + + // Override the translated node's layout. + $this->drupalGet('it/node/1/layout'); + $this->addInlineBlockToLayout('Block it title', 'Block it body'); + $this->assertSaveLayout(); + $it_block = $this->getLatestBlockEntityId(); + $this->assertCount(1, $this->blockStorage->loadMultiple()); + + // Add an inline block to the original node. + $this->drupalGet('node/1/layout'); + $this->addInlineBlockToLayout('Block en title', 'Block en body'); + $this->assertSaveLayout(); + $this->assertCount(2, $this->blockStorage->loadMultiple()); + + // Remove the translation. + $delete_translation_url = Url::fromRoute('entity.node.content_translation_delete', [ + 'node' => 1, + 'language' => 'it', + ]); + $this->drupalGet($delete_translation_url); + $this->drupalPostForm(NULL, [], 'Delete Italian translation'); + + $cron->run(); + + $this->blockStorage->resetCache([$it_block]); + $this->assertEmpty($this->blockStorage->load($it_block)); + $this->assertCount(1, $this->blockStorage->loadMultiple()); + $this->assertEmpty($usage->getUsage($it_block)); + + $this->drupalGet('node/1'); + $assert_session->pageTextContains('Block en body'); + } + } only in patch2: unchanged: --- a/core/modules/layout_builder/src/SectionStorage/SectionStorageTrait.php +++ b/core/modules/layout_builder/src/SectionStorage/SectionStorageTrait.php @@ -111,4 +111,17 @@ protected function hasSection($delta) { return isset($this->getSections()[$delta]); } + /** + * Magic method: Implements a deep clone. + */ + public function __clone() { + $sections = $this->getSections(); + + foreach ($sections as $delta => $item) { + $sections[$delta] = clone $item; + } + + $this->setSections($sections); + } + } only in patch2: unchanged: --- a/core/modules/layout_builder/tests/src/Kernel/SectionStorageTestBase.php +++ b/core/modules/layout_builder/tests/src/Kernel/SectionStorageTestBase.php @@ -137,6 +137,17 @@ public function testRemoveSection() { $this->assertSections($expected); } + /** + * Tests __clone(). + */ + public function testClone() { + $this->assertSame([], $this->sectionStorage->getSection(0)->getLayoutSettings()); + + $new_section_storage = clone $this->sectionStorage; + $new_section_storage->getSection(0)->setLayoutSettings(['asdf' => 'qwer']); + $this->assertSame([], $this->sectionStorage->getSection(0)->getLayoutSettings()); + } + /** * Asserts that the field list has the expected sections. *