Skip to content
Snippets Groups Projects
Commit 694cb802 authored by catch's avatar catch
Browse files

Issue #3179199 by ekes, acrazyanimal, adriancid, smustgrave, sam152,...

Issue #3179199 by ekes, acrazyanimal, adriancid, smustgrave, sam152, amateescu, ravi.shankar, alexj12, s_leu, renatog: Content Moderation prevents workspace deployment
parent 7d4bba32
No related branches found
No related tags found
No related merge requests found
...@@ -39,9 +39,6 @@ public function onWorkspacePrePublish(WorkspacePublishEvent $event): void { ...@@ -39,9 +39,6 @@ public function onWorkspacePrePublish(WorkspacePublishEvent $event): void {
$workspace = $event->getWorkspace(); $workspace = $event->getWorkspace();
$tracked_revisions = $this->workspaceAssociation->getTrackedEntities($workspace->id()); $tracked_revisions = $this->workspaceAssociation->getTrackedEntities($workspace->id());
// Extract all the second-level keys (revision IDs) of the two-dimensional
// array.
$tracked_revision_ids = array_reduce(array_map('array_keys', $tracked_revisions), 'array_merge', []);
// Gather a list of moderation states that don't create a default revision. // Gather a list of moderation states that don't create a default revision.
$workflow_non_default_states = []; $workflow_non_default_states = [];
...@@ -57,12 +54,26 @@ public function onWorkspacePrePublish(WorkspacePublishEvent $event): void { ...@@ -57,12 +54,26 @@ public function onWorkspacePrePublish(WorkspacePublishEvent $event): void {
} }
} }
// If no tracked revisions are moderated then no status check is necessary.
if (empty($workflow_non_default_states)) {
return;
}
// Check if any revisions that are about to be published are in a // Check if any revisions that are about to be published are in a
// non-default revision moderation state. // non-default revision moderation state.
$query = $this->entityTypeManager->getStorage('content_moderation_state')->getQuery() $query = $this->entityTypeManager->getStorage('content_moderation_state')->getQuery()
->allRevisions() ->allRevisions()
->accessCheck(FALSE); ->accessCheck(FALSE);
$query->condition('content_entity_revision_id', $tracked_revision_ids, 'IN');
$tracked_revisions_condition_group = $query->orConditionGroup();
foreach ($tracked_revisions as $tracked_type => $tracked_revision_ids) {
$entity_type_group = $query->andConditionGroup()
->condition('content_entity_type_id', $tracked_type)
->condition('content_entity_revision_id', array_keys($tracked_revision_ids), 'IN');
$tracked_revisions_condition_group->condition($entity_type_group);
}
$query->condition($tracked_revisions_condition_group);
$workflow_condition_group = $query->orConditionGroup(); $workflow_condition_group = $query->orConditionGroup();
foreach ($workflow_non_default_states as $workflow_id => $non_default_states) { foreach ($workflow_non_default_states as $workflow_id => $non_default_states) {
......
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
namespace Drupal\Tests\content_moderation\Kernel; namespace Drupal\Tests\content_moderation\Kernel;
use Drupal\Core\Entity\EntityInterface; use Drupal\Core\Entity\EntityInterface;
use Drupal\entity_test\Entity\EntityTestMulRevPub;
use Drupal\node\Entity\Node; use Drupal\node\Entity\Node;
use Drupal\Tests\content_moderation\Traits\ContentModerationTestTrait; use Drupal\Tests\content_moderation\Traits\ContentModerationTestTrait;
use Drupal\Tests\node\Traits\ContentTypeCreationTrait; use Drupal\Tests\node\Traits\ContentTypeCreationTrait;
...@@ -84,8 +85,6 @@ public function testWorkspaceEntityTypeModeration(): void { ...@@ -84,8 +85,6 @@ public function testWorkspaceEntityTypeModeration(): void {
/** /**
* Tests the integration between Content Moderation and Workspaces. * Tests the integration between Content Moderation and Workspaces.
*
* @see content_moderation_workspace_access()
*/ */
public function testContentModerationIntegrationWithWorkspaces(): void { public function testContentModerationIntegrationWithWorkspaces(): void {
$editorial = $this->createEditorialWorkflow(); $editorial = $this->createEditorialWorkflow();
...@@ -174,6 +173,86 @@ public function testContentModerationIntegrationWithWorkspaces(): void { ...@@ -174,6 +173,86 @@ public function testContentModerationIntegrationWithWorkspaces(): void {
$this->workspaces['stage']->publish(); $this->workspaces['stage']->publish();
} }
/**
* Publish a workspace with workflows including no tracked default revisions.
*/
public function testContentModerationWithoutDefaultRevisionsInWorkspaces(): void {
$access_handler = $this->container->get('entity_type.manager')->getAccessControlHandler('workspace');
// Create a workflow which has the same states as the 'editorial' one,
// but it doesn't create any default revisions. This covers the case when a
// workspace is published containing no tracked types. This has to be the
// only workflow.
$editorial = $this->createEditorialWorkflow();
$type_settings = $editorial->get('type_settings');
$type_settings['states']['draft']['default_revision'] = FALSE;
$type_settings['states']['archived']['default_revision'] = FALSE;
$this->workspaceManager->executeOutsideWorkspace(function () use ($editorial) {
$editorial->save();
});
// Create an node bundle 'note' that uses non-default workflow.
$this->createContentType(['type' => 'note']);
// Create content in all states none with default revisions.
$note_archived = Node::create(['type' => 'note', 'title' => 'Test note - archived', 'moderation_state' => 'archived']);
$note_archived->save();
$note_draft = Node::create(['type' => 'note', 'title' => 'Test note - draft', 'moderation_state' => 'draft']);
$note_draft->save();
$note_published = Node::create(['type' => 'note', 'title' => 'Test note - published', 'moderation_state' => 'published']);
$note_published->save();
// Check workspace can be published.
$access_handler->resetCache();
$this->workspaces['stage']->publish();
}
/**
* Publish a workspace with multiple entities from different entity types.
*/
public function testContentModerationMultipleEntityTypesWithWorkspaces(): void {
$editorial = $this->createEditorialWorkflow();
$this->createContentType(['type' => 'page']);
$this->addEntityTypeAndBundleToWorkflow($editorial, 'node', 'page');
$this->addEntityTypeAndBundleToWorkflow($editorial, 'entity_test_mulrevpub', 'entity_test_mulrevpub');
// Create an entity with a previous revision that is tracked in unpublished
// state.
$entity_with_revision = EntityTestMulRevPub::create([
'title' => 'Test entity mulrevpub',
'type' => 'entity_test_mulrevpub',
'moderation_state' => 'draft',
]);
$entity_with_revision->save();
$entity_with_revision->save();
$entity_with_revision = $this->reloadEntity($entity_with_revision);
// Confirm unpublished earlier revision.
$this->assertEquals('draft', $entity_with_revision->moderation_state->value);
$earlier_revision_id = $entity_with_revision->getRevisionId();
// Publish.
$entity_with_revision->moderation_state->value = 'published';
$entity_with_revision->save();
$entity_with_revision = $this->reloadEntity($entity_with_revision);
// Confirm publish revision.
$this->assertEquals('published', $entity_with_revision->moderation_state->value);
$published_revision_id = $entity_with_revision->getRevisionId();
$this->assertNotEquals($earlier_revision_id, $published_revision_id);
// Create an entity that has a default revision id the same as the previous
// entity's old revision.
$entity_without_revision = Node::create([
'title' => 'Test node page',
'type' => 'page',
'moderation_state' => 'published',
]);
$entity_without_revision->save();
$entity_without_revision = $this->reloadEntity($entity_without_revision);
$this->assertEquals('published', $entity_without_revision->moderation_state->value);
// Current published revisions of second entity has the same revision as
// earlier unpublished revision of first entity.
$this->assertEquals($entity_without_revision->getRevisionId(), $earlier_revision_id);
$this->workspaces['stage']->publish();
}
/** /**
* Test cases for basic moderation test. * Test cases for basic moderation test.
*/ */
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment