Commit 469003db authored by alexpott's avatar alexpott

Issue #2817835 by timmillwood, Sam152, alexpott: When enabling moderation apply a relative state

parent e7c6471f
......@@ -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?
......
......@@ -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()));
}
......
......@@ -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;
}
/**
......
......@@ -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);
}
}
......@@ -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());
......
......@@ -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);
......
<?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);
}
}
......@@ -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);
}
}
......@@ -243,14 +243,6 @@ public function deleteState($state_id) {
return $this;
}
/**
* {@inheritdoc}
*/
public function getInitialState() {
$ordered_states = $this->getStates();
return reset($ordered_states);
}
/**
* {@inheritdoc}
*/
......
......@@ -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);
}
}
......@@ -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.
*
......
......@@ -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.
*
......
......@@ -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');
......
......@@ -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
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment