Commit 56247da6 authored by catch's avatar catch

Issue #2915398 by Sam152, amateescu, timmillwood, plach, mstef: The...

Issue #2915398 by Sam152, amateescu, timmillwood, plach, mstef: The moderation_state field is not computed during the creation of a new entity translation
parent 74d9b41e
......@@ -5,6 +5,7 @@
use Drupal\Core\Entity\ContentEntityInterface;
use Drupal\Core\Entity\EntityPublishedInterface;
use Drupal\Core\Field\FieldItemList;
use Drupal\Core\TypedData\ComputedItemListTrait;
/**
* A computed field that provides a content entity's moderation state.
......@@ -14,6 +15,38 @@
*/
class ModerationStateFieldItemList extends FieldItemList {
use ComputedItemListTrait {
ensureComputedValue as traitEnsureComputedValue;
get as traitGet;
}
/**
* {@inheritdoc}
*/
protected function computeValue() {
$moderation_state = $this->getModerationStateId();
// Do not store NULL values, in the case where an entity does not have a
// moderation workflow associated with it, we do not create list items for
// the computed field.
if ($moderation_state) {
// An entity can only have a single moderation state.
$this->list[0] = $this->createItem(0, $moderation_state);
}
}
/**
* {@inheritdoc}
*/
protected function ensureComputedValue() {
// If the moderation state field is set to an empty value, always recompute
// the state. Empty is not a valid moderation state value, when none is
// present the default state is used.
if (!isset($this->list[0]) || $this->list[0]->isEmpty()) {
$this->valueComputed = FALSE;
}
$this->traitEnsureComputedValue();
}
/**
* Gets the moderation state ID linked to a content entity revision.
*
......@@ -90,32 +123,7 @@ public function get($index) {
if ($index !== 0) {
throw new \InvalidArgumentException('An entity can not have multiple moderation states at the same time.');
}
$this->computeModerationFieldItemList();
return isset($this->list[$index]) ? $this->list[$index] : NULL;
}
/**
* {@inheritdoc}
*/
public function getIterator() {
$this->computeModerationFieldItemList();
return parent::getIterator();
}
/**
* Recalculate the moderation field item list.
*/
protected function computeModerationFieldItemList() {
// Compute the value of the moderation state.
$index = 0;
if (!isset($this->list[$index]) || $this->list[$index]->isEmpty()) {
$moderation_state = $this->getModerationStateId();
// Do not store NULL values in the static cache.
if ($moderation_state) {
$this->list[$index] = $this->createItem($index, $moderation_state);
}
}
return $this->traitGet($index);
}
/**
......@@ -134,6 +142,7 @@ public function setValue($values, $notify = TRUE) {
parent::setValue($values, $notify);
if (isset($this->list[0])) {
$this->valueComputed = TRUE;
$this->updateModeratedEntity($this->list[0]->value);
}
}
......
......@@ -181,7 +181,7 @@ public function testInvalidStateMultilingual() {
]);
$node->save();
$node_fr = $node->addTranslation('fr');
$node_fr = $node->addTranslation('fr', $node->toArray());
$node_fr->setTitle('French Published Node');
$node_fr->save();
$this->assertEquals('published', $node_fr->moderation_state->value);
......@@ -207,7 +207,7 @@ public function testInvalidStateMultilingual() {
$this->assertCount(0, $violations);
// From the latest french revision, there should also be no violation.
$node_fr = $node->getTranslation('fr');
$node_fr = Node::load($node->id())->getTranslation('fr');
$this->assertEquals('published', $node_fr->moderation_state->value);
$node_fr->moderation_state = 'archived';
$violations = $node_fr->validate();
......
......@@ -43,6 +43,10 @@ protected function setUp() {
$this->installEntitySchema('content_moderation_state');
$this->installConfig('content_moderation');
NodeType::create([
'type' => 'unmoderated',
])->save();
$node_type = NodeType::create([
'type' => 'example',
]);
......@@ -79,6 +83,51 @@ public function testArrayIteration() {
$this->assertEquals(['draft'], $states);
}
/**
* @covers ::getValue
*/
public function testGetValue() {
$this->assertEquals([['value' => 'draft']], $this->testNode->moderation_state->getValue());
}
/**
* @covers ::get
*/
public function testGet() {
$this->assertEquals('draft', $this->testNode->moderation_state->get(0)->value);
$this->setExpectedException(\InvalidArgumentException::class);
$this->testNode->moderation_state->get(2);
}
/**
* Tests the computed field when it is unset or set to an empty value.
*/
public function testSetEmptyState() {
$this->testNode->moderation_state->value = '';
$this->assertEquals('draft', $this->testNode->moderation_state->value);
$this->testNode->moderation_state = '';
$this->assertEquals('draft', $this->testNode->moderation_state->value);
unset($this->testNode->moderation_state);
$this->assertEquals('draft', $this->testNode->moderation_state->value);
}
/**
* Test the list class with a non moderated entity.
*/
public function testNonModeratedEntity() {
$unmoderated_node = Node::create([
'type' => 'unmoderated',
'title' => 'Test title',
]);
$unmoderated_node->save();
$this->assertEquals(0, $unmoderated_node->moderation_state->count());
$unmoderated_node->moderation_state = NULL;
$this->assertEquals(0, $unmoderated_node->moderation_state->count());
}
/**
* Tests that moderation state changes also change the related entity state.
*/
......
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