diff --git a/core/modules/content_moderation/src/EntityOperations.php b/core/modules/content_moderation/src/EntityOperations.php index 3e34d141ec9357bf5ae4aa7a47a37c7ccaa3290a..3f66100581bdc5280ff8329a069656d62a88b005 100644 --- a/core/modules/content_moderation/src/EntityOperations.php +++ b/core/modules/content_moderation/src/EntityOperations.php @@ -158,7 +158,7 @@ protected function updateOrCreateFromEntity(EntityInterface $entity) { $workflow = $this->moderationInfo->getWorkflowForEntity($entity); /** @var \Drupal\Core\Entity\ContentEntityInterface $entity */ if (!$moderation_state) { - $moderation_state = $workflow->getInitialState()->id(); + $moderation_state = $workflow->getTypePlugin()->getInitialState($workflow, $entity)->id(); } // @todo what if $entity->moderation_state is null at this point? diff --git a/core/modules/content_moderation/src/Plugin/Field/FieldWidget/ModerationStateWidget.php b/core/modules/content_moderation/src/Plugin/Field/FieldWidget/ModerationStateWidget.php index 970ac33a5dcc710356250b29bab6a8a91cac3ecc..ab5a5613609a2729d28f472f9d9f4d68af971dc8 100644 --- a/core/modules/content_moderation/src/Plugin/Field/FieldWidget/ModerationStateWidget.php +++ b/core/modules/content_moderation/src/Plugin/Field/FieldWidget/ModerationStateWidget.php @@ -117,7 +117,7 @@ public function formElement(FieldItemListInterface $items, $delta, array $elemen } $workflow = $this->moderationInformation->getWorkflowForEntity($entity); - $default = $items->get($delta)->value ? $workflow->getState($items->get($delta)->value) : $workflow->getInitialState(); + $default = $items->get($delta)->value ? $workflow->getState($items->get($delta)->value) : $workflow->getTypePlugin()->getInitialState($workflow, $entity); if (!$default) { throw new \UnexpectedValueException(sprintf('The %s bundle has an invalid moderation state configuration, moderation states are enabled but no default is set.', $bundle_entity->label())); } diff --git a/core/modules/content_moderation/src/Plugin/Field/ModerationStateFieldItemList.php b/core/modules/content_moderation/src/Plugin/Field/ModerationStateFieldItemList.php index 0444644f93266c56524ff534fac1e144b42971b8..2d93f5a7c2a9889d992dc6410dc4db3120162c43 100644 --- a/core/modules/content_moderation/src/Plugin/Field/ModerationStateFieldItemList.php +++ b/core/modules/content_moderation/src/Plugin/Field/ModerationStateFieldItemList.php @@ -37,8 +37,8 @@ protected function getModerationStateId() { // It is possible that the bundle does not exist at this point. For example, // the node type form creates a fake Node entity to get default values. // @see \Drupal\node\NodeTypeForm::form() - $workflow = $moderation_info->getWorkflowForEntity($entity); - return $workflow ? $workflow->getInitialState()->id() : NULL; + $workflow = $moderation_info->getWorkFlowForEntity($entity); + return $workflow ? $workflow->getTypePlugin()->getInitialState($workflow, $entity)->id() : NULL; } /** diff --git a/core/modules/content_moderation/src/Plugin/WorkflowType/ContentModeration.php b/core/modules/content_moderation/src/Plugin/WorkflowType/ContentModeration.php index 31f1c18c682bbb414bf78aee70f90e7138defa9d..51605d5383d68aa9113afffcceabfe7ef49fe5f7 100644 --- a/core/modules/content_moderation/src/Plugin/WorkflowType/ContentModeration.php +++ b/core/modules/content_moderation/src/Plugin/WorkflowType/ContentModeration.php @@ -4,6 +4,7 @@ use Drupal\Core\Access\AccessResult; use Drupal\Core\Entity\EntityTypeManagerInterface; +use Drupal\Core\Entity\EntityPublishedInterface; use Drupal\Core\Form\FormStateInterface; use Drupal\Core\Plugin\ContainerFactoryPluginInterface; use Drupal\Core\Session\AccountInterface; @@ -289,4 +290,14 @@ public function getConfiguration() { return $configuration; } + /** + * {@inheritdoc} + */ + public function getInitialState(WorkflowInterface $workflow, $entity = NULL) { + if ($entity instanceof EntityPublishedInterface) { + return $workflow->getState($entity->isPublished() ? 'published' : 'draft'); + } + return parent::getInitialState($workflow); + } + } diff --git a/core/modules/content_moderation/src/StateTransitionValidation.php b/core/modules/content_moderation/src/StateTransitionValidation.php index c4e26c26ff9bd00126c1bc93203d367cf052af7d..4952f2e7154cc8d1a121558b34830c221b162304 100644 --- a/core/modules/content_moderation/src/StateTransitionValidation.php +++ b/core/modules/content_moderation/src/StateTransitionValidation.php @@ -40,7 +40,7 @@ public function __construct(ModerationInformationInterface $moderation_info) { */ public function getValidTransitions(ContentEntityInterface $entity, AccountInterface $user) { $workflow = $this->moderationInfo->getWorkflowForEntity($entity); - $current_state = $entity->moderation_state->value ? $workflow->getState($entity->moderation_state->value) : $workflow->getInitialState(); + $current_state = $entity->moderation_state->value ? $workflow->getState($entity->moderation_state->value) : $workflow->getTypePlugin()->getInitialState($workflow, $entity); return array_filter($current_state->getTransitions(), function(Transition $transition) use ($workflow, $user) { return $user->hasPermission('use ' . $workflow->id() . ' transition ' . $transition->id()); diff --git a/core/modules/content_moderation/tests/src/Kernel/ContentModerationStateTest.php b/core/modules/content_moderation/tests/src/Kernel/ContentModerationStateTest.php index 70a5df5bcd6bca444667fb03c1dab8ace568857c..0f8469921378fcbcb656b1ae28a9c92448971c57 100644 --- a/core/modules/content_moderation/tests/src/Kernel/ContentModerationStateTest.php +++ b/core/modules/content_moderation/tests/src/Kernel/ContentModerationStateTest.php @@ -95,6 +95,9 @@ public function testBasicModeration($entity_type_id) { 'title' => 'Test title', $this->entityTypeManager->getDefinition($entity_type_id)->getKey('bundle') => $bundle_id, ]); + if ($entity instanceof EntityPublishedInterface) { + $entity->setUnpublished(); + } $entity->save(); $entity = $this->reloadEntity($entity); $this->assertEquals('draft', $entity->moderation_state->value); diff --git a/core/modules/content_moderation/tests/src/Kernel/InitialStateTest.php b/core/modules/content_moderation/tests/src/Kernel/InitialStateTest.php new file mode 100644 index 0000000000000000000000000000000000000000..0150d3c6e5f524c329937700aed7832c0864ca22 --- /dev/null +++ b/core/modules/content_moderation/tests/src/Kernel/InitialStateTest.php @@ -0,0 +1,82 @@ +<?php + +namespace Drupal\Tests\content_moderation\Kernel; + +use Drupal\entity_test\Entity\EntityTestRev; +use Drupal\KernelTests\KernelTestBase; +use Drupal\node\Entity\Node; +use Drupal\node\Entity\NodeType; +use Drupal\workflows\Entity\Workflow; + +/** + * Tests the correct initial states are set on install. + * + * @group content_moderation + */ +class InitialStateTest extends KernelTestBase { + + /** + * {@inheritdoc} + */ + public static $modules = [ + 'entity_test', + 'node', + 'user', + 'system', + ]; + + /** + * {@inheritdoc} + */ + protected function setUp() { + parent::setUp(); + + $this->installSchema('node', 'node_access'); + $this->installEntitySchema('node'); + $this->installEntitySchema('user'); + $this->installEntitySchema('entity_test_rev'); + } + + /** + * Tests the correct initial state. + */ + public function testInitialState() { + $node_type = NodeType::create([ + 'type' => 'example', + ]); + $node_type->save(); + + // Test with an entity type that implements EntityPublishedInterface. + $unpublished_node = Node::create([ + 'type' => 'example', + 'title' => 'Unpublished node', + 'status' => 0, + ]); + $unpublished_node->save(); + + $published_node = Node::create([ + 'type' => 'example', + 'title' => 'Published node', + 'status' => 1, + ]); + $published_node->save(); + + // Test with an entity type that doesn't implement EntityPublishedInterface. + $entity_test = EntityTestRev::create(); + $entity_test->save(); + + \Drupal::service('module_installer')->install(['content_moderation'], TRUE); + $workflow = Workflow::load('editorial'); + $workflow->getTypePlugin()->addEntityTypeAndBundle('node', 'example'); + $workflow->getTypePlugin()->addEntityTypeAndBundle('entity_test_rev', 'entity_test_rev'); + $workflow->save(); + + $loaded_unpublished_node = Node::load($unpublished_node->id()); + $loaded_published_node = Node::load($published_node->id()); + $loaded_entity_test = EntityTestRev::load($entity_test->id()); + $this->assertEquals('draft', $loaded_unpublished_node->moderation_state->value); + $this->assertEquals('published', $loaded_published_node->moderation_state->value); + $this->assertEquals('draft', $loaded_entity_test->moderation_state->value); + } + +} diff --git a/core/modules/content_moderation/tests/src/Kernel/ModerationStateFieldItemListTest.php b/core/modules/content_moderation/tests/src/Kernel/ModerationStateFieldItemListTest.php index 3f984da4552448e5ed6b2609444bc642e64a8fff..7e9a75c3f412e0d78dcf3afa062472edcf9dae68 100644 --- a/core/modules/content_moderation/tests/src/Kernel/ModerationStateFieldItemListTest.php +++ b/core/modules/content_moderation/tests/src/Kernel/ModerationStateFieldItemListTest.php @@ -64,7 +64,7 @@ protected function setUp() { * Test the field item list when accessing an index. */ public function testArrayIndex() { - $this->assertEquals('draft', $this->testNode->moderation_state[0]->value); + $this->assertEquals('published', $this->testNode->moderation_state[0]->value); } /** @@ -75,7 +75,7 @@ public function testArrayIteration() { foreach ($this->testNode->moderation_state as $item) { $states[] = $item->value; } - $this->assertEquals(['draft'], $states); + $this->assertEquals(['published'], $states); } } diff --git a/core/modules/workflows/src/Entity/Workflow.php b/core/modules/workflows/src/Entity/Workflow.php index c6b1ce6a43581085397e0a541f34900f5bf90ca5..51b8d174f7eae8bc692d0c026bb24e1c4a05b391 100644 --- a/core/modules/workflows/src/Entity/Workflow.php +++ b/core/modules/workflows/src/Entity/Workflow.php @@ -243,14 +243,6 @@ public function deleteState($state_id) { return $this; } - /** - * {@inheritdoc} - */ - public function getInitialState() { - $ordered_states = $this->getStates(); - return reset($ordered_states); - } - /** * {@inheritdoc} */ diff --git a/core/modules/workflows/src/Plugin/WorkflowTypeBase.php b/core/modules/workflows/src/Plugin/WorkflowTypeBase.php index 59c6b961371b68549ebc7f343fe4c1d375e2c73e..e87e4d79452ac1f55e1215818fa9d3e98cd901f9 100644 --- a/core/modules/workflows/src/Plugin/WorkflowTypeBase.php +++ b/core/modules/workflows/src/Plugin/WorkflowTypeBase.php @@ -145,4 +145,12 @@ public function onDependencyRemoval(array $dependencies) { return FALSE; } + /** + * {@inheritdoc} + */ + public function getInitialState(WorkflowInterface $workflow) { + $ordered_states = $workflow->getStates(); + return reset($ordered_states); + } + } diff --git a/core/modules/workflows/src/WorkflowInterface.php b/core/modules/workflows/src/WorkflowInterface.php index d014ddb781de1eaa32f7a8d65881c2e6f2548b6b..d156918a6f18f7b83d9d3dd6d03ad33271535632 100644 --- a/core/modules/workflows/src/WorkflowInterface.php +++ b/core/modules/workflows/src/WorkflowInterface.php @@ -105,14 +105,6 @@ public function setStateWeight($state_id, $weight); */ public function deleteState($state_id); - /** - * Gets the initial state for the workflow. - * - * @return \Drupal\workflows\StateInterface - * The initial state. - */ - public function getInitialState(); - /** * Adds a transition to the workflow. * diff --git a/core/modules/workflows/src/WorkflowTypeInterface.php b/core/modules/workflows/src/WorkflowTypeInterface.php index 0fe668547ce89595ed5dac3b38339abc27f9e84e..2412bf99f4389eca40edcf4010c3c0795df9e09f 100644 --- a/core/modules/workflows/src/WorkflowTypeInterface.php +++ b/core/modules/workflows/src/WorkflowTypeInterface.php @@ -93,6 +93,17 @@ public function decorateTransition(TransitionInterface $transition); */ public function deleteTransition($transition_id); + /** + * Gets the initial state for the workflow. + * + * @param \Drupal\workflows\WorkflowInterface $workflow + * The workflow entity. + * + * @return \Drupal\workflows\StateInterface + * The initial state. + */ + public function getInitialState(WorkflowInterface $workflow); + /** * Builds a form to be added to the Workflow state edit form. * diff --git a/core/modules/workflows/tests/src/Functional/WorkflowUiTest.php b/core/modules/workflows/tests/src/Functional/WorkflowUiTest.php index 3014dd739750be5181ba6657e3bf86253798fe9f..209e9865b5f5474004ff993dab4fb4daa2e74fa0 100644 --- a/core/modules/workflows/tests/src/Functional/WorkflowUiTest.php +++ b/core/modules/workflows/tests/src/Functional/WorkflowUiTest.php @@ -170,11 +170,11 @@ public function testWorkflowCreation() { // Ensure that weight changes the state ordering. $workflow = $workflow_storage->loadUnchanged('test'); - $this->assertEquals('published', $workflow->getInitialState()->id()); + $this->assertEquals('published', $workflow->getTypePlugin()->getInitialState($workflow)->id()); $this->drupalGet('admin/config/workflow/workflows/manage/test'); $this->submitForm(['states[draft][weight]' => '-1'], 'Save'); $workflow = $workflow_storage->loadUnchanged('test'); - $this->assertEquals('draft', $workflow->getInitialState()->id()); + $this->assertEquals('draft', $workflow->getTypePlugin()->getInitialState($workflow)->id()); // Verify that we are still on the workflow edit page. $this->assertSession()->addressEquals('admin/config/workflow/workflows/manage/test'); diff --git a/core/modules/workflows/tests/src/Unit/WorkflowTest.php b/core/modules/workflows/tests/src/Unit/WorkflowTest.php index e2a7401cec1166ac271365b96cbbe0d6f6fe4de5..51cb912070076044d8cd35f846c5fabc43faf5d7 100644 --- a/core/modules/workflows/tests/src/Unit/WorkflowTest.php +++ b/core/modules/workflows/tests/src/Unit/WorkflowTest.php @@ -263,25 +263,6 @@ public function testDeleteOnlyStateException() { $workflow->deleteState('draft'); } - /** - * @covers ::getInitialState - */ - public function testGetInitialState() { - $workflow = new Workflow(['id' => 'test', 'type' => 'test_type'], 'workflow'); - - // By default states are ordered in the order added. - $workflow - ->addState('draft', 'Draft') - ->addState('published', 'Published') - ->addState('archived', 'Archived'); - - $this->assertEquals('draft', $workflow->getInitialState()->id()); - - // Make published the first state. - $workflow->setStateWeight('published', -1); - $this->assertEquals('published', $workflow->getInitialState()->id()); - } - /** * @covers ::addTransition * @covers ::hasTransition