diff --git a/core/modules/content_moderation/src/Entity/Handler/BlockContentModerationHandler.php b/core/modules/content_moderation/src/Entity/Handler/BlockContentModerationHandler.php index a618b2246e..2b9a8b2ba9 100644 --- a/core/modules/content_moderation/src/Entity/Handler/BlockContentModerationHandler.php +++ b/core/modules/content_moderation/src/Entity/Handler/BlockContentModerationHandler.php @@ -2,6 +2,7 @@ namespace Drupal\content_moderation\Entity\Handler; +use Drupal\Core\Entity\ContentEntityInterface; use Drupal\Core\Form\FormStateInterface; /** @@ -29,4 +30,14 @@ public function enforceRevisionsBundleFormAlter(array &$form, FormStateInterface $form['revision']['#description'] = $this->t('Revisions must be required when moderation is enabled.'); } + /** + * {@inheritdoc} + */ + public function isModeratedEntity(ContentEntityInterface $entity) { + // Only reusable blocks can be moderated individually. Non-reusable or + // inline blocks are moderated as part of the entity they are a composite + // of. + return $entity->isReusable(); + } + } diff --git a/core/modules/content_moderation/src/ModerationInformation.php b/core/modules/content_moderation/src/ModerationInformation.php index 62c2a6103c..ee811b75aa 100644 --- a/core/modules/content_moderation/src/ModerationInformation.php +++ b/core/modules/content_moderation/src/ModerationInformation.php @@ -55,7 +55,7 @@ public function isModeratedEntity(EntityInterface $entity) { if (!$this->shouldModerateEntitiesOfBundle($entity->getEntityType(), $entity->bundle())) { return FALSE; } - return $entity->getEntityType()->getHandlerClass('moderation')->isModeratedEntity($entity); + return $this->entityTypeManager->getHandler($entity->getEntityTypeId(), 'moderation')->isModeratedEntity($entity); } /** diff --git a/core/modules/content_moderation/tests/src/Functional/LayoutBuilderContentModerationIntegrationTest.php b/core/modules/content_moderation/tests/src/Functional/LayoutBuilderContentModerationIntegrationTest.php index 3f61ea9eeb..f90c2f83fb 100644 --- a/core/modules/content_moderation/tests/src/Functional/LayoutBuilderContentModerationIntegrationTest.php +++ b/core/modules/content_moderation/tests/src/Functional/LayoutBuilderContentModerationIntegrationTest.php @@ -2,6 +2,7 @@ namespace Drupal\Tests\content_moderation\Functional; +use Drupal\block_content\Entity\BlockContentType; use Drupal\layout_builder\Entity\LayoutBuilderEntityViewDisplay; use Drupal\Tests\BrowserTestBase; use Drupal\Tests\content_moderation\Traits\ContentModerationTestTrait; @@ -24,6 +25,7 @@ class LayoutBuilderContentModerationIntegrationTest extends BrowserTestBase { 'node', 'content_moderation', 'menu_ui', + 'block_content', ]; /** @@ -36,10 +38,21 @@ protected function setUp() { // https://www.drupal.org/project/drupal/issues/2917777. $this->drupalPlaceBlock('local_tasks_block'); + $workflow = $this->createEditorialWorkflow(); + // Add a new bundle and add an editorial workflow. $this->createContentType(['type' => 'bundle_with_section_field']); - $workflow = $this->createEditorialWorkflow(); $workflow->getTypePlugin()->addEntityTypeAndBundle('node', 'bundle_with_section_field'); + + // Add a new block content bundle to the editorial workflow. + BlockContentType::create([ + 'id' => 'basic', + 'label' => 'Basic', + 'revision' => 1, + ])->save(); + block_content_add_body_field('basic'); + + $workflow->getTypePlugin()->addEntityTypeAndBundle('block_content', 'basic'); $workflow->save(); // Enable layout overrides. @@ -57,6 +70,7 @@ protected function setUp() { 'view latest version', 'use editorial transition create_new_draft', 'use editorial transition publish', + 'create and edit custom blocks', ])); } @@ -133,4 +147,44 @@ public function testLayoutModeration() { $assert_session->pageTextNotContains('Powered by Drupal'); } + /** + * Test placing inline blocks that belong to a moderated custom block bundle. + */ + public function testModeratedInlineBlockBundles() { + $page = $this->getSession()->getPage(); + $assert_session = $this->assertSession(); + + $node = $this->createNode([ + 'type' => 'bundle_with_section_field', + 'title' => 'The first node title', + 'moderation_state' => 'published', + ]); + $this->drupalGet("node/{$node->id()}/layout"); + $page->clickLink('Add block'); + $this->clickLink('Create custom block'); + + $assert_session->fieldNotExists('settings[block_form][moderation_state][0][state]'); + $this->submitForm([ + 'settings[label]' => 'Test inline block', + 'settings[block_form][body][0][value]' => 'Example block body', + ], 'Add block'); + + // Save a draft of the page with the inline block and ensure the drafted + // content appears on the latest version page. + $this->assertSession()->pageTextContains('Example block body'); + $this->submitForm([ + 'moderation_state[0][state]' => 'draft', + ], 'Save layout'); + $assert_session->pageTextContains('The layout override has been saved.'); + $assert_session->pageTextContains('Example block body'); + + // Publish the draft of the page ensure the draft inline block content + // apears on the published page. + $this->submitForm([ + 'new_state' => 'published', + ], 'Apply'); + $assert_session->pageTextContains('The moderation state has been updated.'); + $assert_session->pageTextContains('Example block body'); + } + } diff --git a/core/modules/content_moderation/tests/src/Unit/ModerationInformationTest.php b/core/modules/content_moderation/tests/src/Unit/ModerationInformationTest.php index dead3c88ee..d7a93473eb 100644 --- a/core/modules/content_moderation/tests/src/Unit/ModerationInformationTest.php +++ b/core/modules/content_moderation/tests/src/Unit/ModerationInformationTest.php @@ -13,6 +13,7 @@ use Drupal\content_moderation\ModerationInformation; use Drupal\Tests\UnitTestCase; use Drupal\workflows\WorkflowInterface; +use Prophecy\Argument; /** * @coversDefaultClass \Drupal\content_moderation\ModerationInformation @@ -38,6 +39,7 @@ protected function getUser() { */ protected function getEntityTypeManager() { $entity_type_manager = $this->prophesize(EntityTypeManagerInterface::class); + $entity_type_manager->getHandler(Argument::any(), 'moderation')->willReturn(new ModerationHandler()); return $entity_type_manager->reveal(); } @@ -94,6 +96,7 @@ public function testIsModeratedEntity($workflow, $expected) { ]); $entity = $this->prophesize(ContentEntityInterface::class); $entity->getEntityType()->willReturn($entity_type); + $entity->getEntityTypeId()->willReturn($entity_type->id()); $entity->bundle()->willReturn('test_bundle'); $this->assertEquals($expected, $moderation_information->isModeratedEntity($entity->reveal()));