Problem/Motivation

Steps to reproduce:

  1. Enable Content Moderation
  2. Enable moderation on node articles
  3. Create a new article with draft state
  4. Edit draft to make it published
  5. Edit to make it archived
  6. Revert back to the second (published) revision
  7. Entity is still unpublished, has the default moderation state (draft)

Proposed resolution

When saving an entity create a ContentModerationState entity with the original state.

Remaining tasks

User interface changes

API changes

Data model changes

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

timmillwood created an issue. See original summary.

timmillwood’s picture

Status: Active » Needs review
FileSize
1.11 KB

Here's a test which shows this bug.

Status: Needs review » Needs work

The last submitted patch, 2: test-only.patch, failed testing.

timmillwood’s picture

Status: Needs work » Needs review
FileSize
1.97 KB
881 bytes

Status: Needs review » Needs work

The last submitted patch, 4: 2809123-3.patch, failed testing.

timmillwood’s picture

timmillwood’s picture

Version: 8.2.x-dev » 8.3.x-dev
Assigned: timmillwood » Unassigned
Status: Postponed » Needs review
FileSize
1.63 KB
2.11 KB

Status: Needs review » Needs work

The last submitted patch, 7: 2809123-7.patch, failed testing.

timmillwood’s picture

Status: Needs work » Needs review
FileSize
2.17 KB
789 bytes

Needed a check to make sure that the loaded revision ID is not the same as the revision ID.

Status: Needs review » Needs work

The last submitted patch, 9: 2809123-9.patch, failed testing.

timmillwood’s picture

Status: Needs work » Needs review
Sam152’s picture

Uploading a test only patch, because it's a little puzzling why the condition right above it would ever be FALSE while the new one would be TRUE.

edit: figured out above comment after reviewing the patch in more detail.

  1. +++ b/core/modules/content_moderation/src/Plugin/Field/ModerationStateFieldItemList.php
    @@ -57,6 +57,14 @@ protected function getModerationState() {
    +    if (!empty($entity->getLoadedRevisionId()) && $entity->getLoadedRevisionId() != $entity->getRevisionId()) {
    

    Based on the condition right above this one I think the whole second part of this condition is superfluous. You only enter this line if getRevisionId is null.

    Maybe this method could do with some more commenting.

  2. +++ b/core/modules/content_moderation/tests/src/Kernel/ContentModerationStateTest.php
    @@ -101,6 +101,21 @@ public function testBasicModeration() {
    +    $node->set('moderation_state', 'archived');
    

    Rest of the test uses $node->moderation_state->value =, not ->set

  3. +++ b/core/modules/content_moderation/tests/src/Kernel/ContentModerationStateTest.php
    @@ -101,6 +101,21 @@ public function testBasicModeration() {
    +    $prev_rev = \Drupal::entityTypeManager()->getStorage('node')->loadRevision(4);
    

    nit, should be full form, $previous_revision.

  4. +++ b/core/modules/content_moderation/tests/src/Kernel/ContentModerationStateTest.php
    @@ -101,6 +101,21 @@ public function testBasicModeration() {
    +    // Get the default revision
    

    nit, full stop

  5. +++ b/core/modules/content_moderation/tests/src/Kernel/ContentModerationStateTest.php
    @@ -101,6 +101,21 @@ public function testBasicModeration() {
    +
    

    nit, extra whitespace

Sam152’s picture

Could this implementation also work?

The last submitted patch, 12: 2809123-9--test-only.patch, failed testing.

timmillwood’s picture

@Sam152 - I quite like your solution, much simpler. I do think the whole getModerationState() method could do with a number of comments to explain how and why it all works because it takes a for moments to understand all the logic in there.

Sam152’s picture

Status: Needs review » Needs work

Agreed. NW based on that.

Sam152’s picture

Status: Needs work » Needs review
FileSize
1.36 KB
7.64 KB
6.53 KB

Added some comments and addressed feedback in #12. The extra methods are a bit more self documenting, add some extra comments and reduce the complexity of the big getModerationStateId method.

timmillwood’s picture

Status: Needs review » Reviewed & tested by the community

Little code exists in #17 from my patch, so guess I am entitled to RTBC.

Looks good, fixes the bug, tidier, easier to understand, all round better.

alexpott’s picture

Status: Reviewed & tested by the community » Needs work
+++ b/core/modules/content_moderation/src/Plugin/Field/ModerationStateFieldItemList.php
@@ -27,43 +29,67 @@ protected function getModerationState() {
+  protected function loadCorrespondingContentModerationStateLanguage(ContentEntityInterface $entity, ContentModerationStateInterface $content_moderation_state) {
...
+  protected function loadContentModerationStateRevision(ContentEntityInterface $entity) {

Let's not have two additional methods here - I think this is unnecessary. You're always going to want the correct language. I think all we need to do is merge loadContentModerationRevision and loadCorrespondingContentModerationStateLanguage together and just call it loadContentModerationState.

timmillwood’s picture

Status: Needs work » Needs review
FileSize
6.86 KB
3.09 KB

Consolidation of methods as suggested in #19.

alexpott’s picture

Status: Needs review » Needs work
  1. +++ b/core/modules/content_moderation/src/Plugin/Field/ModerationStateFieldItemList.php
    @@ -27,43 +29,56 @@ protected function getModerationState() {
    +      return null;
    

    The early return here is fine but lets capitalise null as per standards.

  2. +++ b/core/modules/content_moderation/src/Plugin/Field/ModerationStateFieldItemList.php
    @@ -27,43 +29,56 @@ protected function getModerationState() {
    +    $content_moderation_state = $content_moderation_storage->loadRevision(key($revisions));
    +    if (!$entity->getEntityType()->hasKey('langcode')) {
    +      return $content_moderation_state;
    +    }
    +    ¶
    +    $langcode = $entity->language()->getId();
    +    if (!$content_moderation_state->hasTranslation($langcode)) {
    +      $content_moderation_state->addTranslation($langcode);
         }
    +    return $content_moderation_state->language()->getId() !== $langcode ? $content_moderation_state->getTranslation($langcode) : $content_moderation_state;
    

    Let's turn this logic around to avoid the early return. Basically as this logic was before. And then the final line can be return $content_moderation_state;

timmillwood’s picture

Status: Needs work » Needs review
FileSize
6.91 KB
2.44 KB

Done #21.

Sam152’s picture

Status: Needs review » Reviewed & tested by the community

interdiff LGTM

alexpott’s picture

Status: Reviewed & tested by the community » Fixed

Committed 6b34291 and pushed to 8.3.x. Thanks!

  • alexpott committed 6b34291 on 8.3.x
    Issue #2809123 by timmillwood, Sam152: Reverting a revision doesn't keep...

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.

timmillwood’s picture