This issue occurs when using either Content Moderation/Workflows or Workbench Moderation.

Steps to reproduce:

1) Set up workflows for a content type so that you have a draft and publish option (which is default)
2) Add a paragraph type that has another nested paragraph underneath it
3) Add content of that type and set the status to published
4) Make changes to the nested paragraph, but save the node as a DRAFT
5) The above actually causes the nested paragraph type to automatically be set to the content moderation status of published instead of respecting the parent paragraph, which in this example is draft.

Essentially, nested paragraphs always are being set to published with the workflows/content moderation module.

Issue fork paragraphs-2949412

Command icon Show commands

Start within a Git clone of the project using the version control instructions.

Or, if you do not have SSH keys set up on git.drupalcode.org:

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

dualfragment created an issue. See original summary.

miro_dietiker’s picture

I don‘t get the scenario.

You never set a paragraph to unpublished, thus it‘s published.

The host node entity moderation workflow should not influence the paragraphs published status at all.

Access to paragraphs is checked by delegating access checks to the host.

The published status of a paragraph is to hide such a paragraph for a given version. If i review a node with 5 pararaphs published and 2 unpublished for internal notes, i want the 5 published and the 2 need to remain unpublished on releasing that revision.

Berdir’s picture

Well, the thing is that the paragraph references just the parent ID, not the revision. So it references the default revision, that is accessible and published, so is the paragraphs.

That should only be a problem if paragraphs are displayed on their own, in most cases you should just render the parent node with its fields. However, some uses case like private file access are indeed broken then.

The only way to address that is to start tracking the parent revision ID as well..

brettboylen’s picture

Priority: Critical » Major
brettboylen’s picture

Berdir, exactly. Last week before I saw your response, we also tracked it down specifically to what you stated, that it isn't actually tracking the parent revision ID.

This is probably something that should be fixed sometime in the future. If we solve it in-house with a patch, I'll post the patch here. We may just take an alternate approach to our use-case scenario, however, for the time-being.

miro_dietiker’s picture

Moving this to the content moderation parent.

miro_dietiker’s picture

Priority: Major » Critical

Promoting according to roadmap.

charginghawk’s picture

I'd just like to note this is an issue when creating a view of paragraphs with a "published" filter. It then presents content from published and unpublished nodes regardless.

miro_dietiker’s picture

@charginghawk Not sure if this is related. The views integration needs work (mostly test coverage) and note that the Paragraph entity intentionally has a published base field as well independent of the node published one.

brettboylen’s picture

EDIT: My apologies, didn't mean to make this post, was trying to add a comment on another issue.

rudam’s picture

I'm also having this issue.

Cant edit paragraphs inside a node in draft revision. If I give the user permission to edit "published" content the paragraphs then gets editable.
Any luck on this?

andy_w’s picture

I had the same issue using content moderation with paragraphs. I ended up extending the AccessHandler with a custom module and then adding in the ModerationInformation service, and then using that to retrieve the latest revision to check access on (as this is the revision being edited).

  protected function checkAccess(EntityInterface $paragraph, $operation, AccountInterface $account) {
    ...
      if ($paragraph->getParentEntity()->getEntityTypeId() != 'paragraphs_library_item') {
        // Updating paragraphs while using content moderation requires access
        // checking the parent entity that is being updated
        // (not the latest published entity).
        $parent = $this->moderationInformation->getLatestRevision($paragraph->getParentEntity()->getEntityTypeId(), $paragraph->getParentEntity()->id());
        $parent_access = $parent->access($operation, $account, TRUE);
        $access_result = $access_result->andIf($parent_access);
      }
    }
    return $access_result;
  }

Although obviously the better solution would be to store the revision on the paragraph.

kencyong’s picture

Hi there, I'm having this problem using Workbench Moderation, it's a real bummer. Anybody have any kind of solution to this?

Poindexterous’s picture

I'm using paragraph blocks with layout builder (with content moderation, too). This setup is complicated by the fact that we need custom blocks to wrap the paragraphs in order to use them in layout builder. So the custom block is the parent. I ran into an issue where the parent revision ID is needed to properly process the permission checks before render. I was hit by this issue pretty hard in the scenario where we had a published revision and a draft revision being juggled simultaneously. I don't have a perfect solution yet (highly experimental and I'm not very familiar with Paragraphs's code), but as a workaround I'm using a query to look up which revisions on the parent block hold the paragraph in question, and then load that parent entity with the correct revision id to pass along to the permission check.

In the paragraphAccessControlHandler check access method I'm using the following query:

            $paragraph_rid = $paragraph->getLoadedRevisionId();
            $paragraph_id = $paragraph->id();
            $paragraph_target_revision_id = $paragraph->parent_field_name->value . '.target_revision_id';
            $paragraph_target_id = $paragraph->parent_field_name->value . '.target_id';

            // Look up the paragraph's parent block by the revision.
            $entity_type_manager = \Drupal::entityTypeManager();
            $target_entity_storage = $entity_type_manager->getStorage('block_content');

            // Query block_content revisions that contain the paragraph at it's
            // given version id.
            $revision_ids = $target_entity_storage
              ->getQuery()
              ->allRevisions()
              ->condition($paragraph_target_revision_id, $paragraph_rid)
              ->condition($paragraph_target_id, $paragraph_id)
              ->execute();

You should be able to get the correct parent's revision ID from that query, but I don't know if there are any scenarios where one would expect multiple results- then it begs the question on which revision is the right one. I'm still tinkering with this.

lucasantunes’s picture

I don't think we should be checking the Parent's revision id. Instead, it should be "as simple as", when saving a parent, propagating its Moderation Status to all of its children. More specifically, its ERR children. For that reason, I believe this issue should be worked on the ERR project, not here, if that makes any sense.

That'll be of huge utility for a use case of ours where we wanna display only the latest approved (not in Draft) ERR children. Ex: Node VID 1000 (published) points to Child 1 -> RID 50; Child 2 -> RID 50. Node VID 1001 (Draft) points to Child 1 -> RID 51; Child 2 -> RID 51. In this use case, children shown should be RID 50, not 51, but since they're always published, we get 51 instead.

SrinuPodamekala’s picture

Hi Team,

I have a content type called products. I have enabled content moderation and workflow module and I am using multilingual website.

In the products content type, I have used nested paragraphs. Now I have created new product and using workflow process I have published the product.

Now if I update/modify the content in that product it becomes draft state from publish state and if I see it only in the latest version tab we can see the updated/modified content. the previous version content will not visible to public until and unless it is published. It is working fine for normal fields(node fields) but when it comes to nested paragraph, it is directly visible to public even the previous version content is in draft version.

I have created the paragraph field using Entity reference revisions.

Also I have verified that if I set the paragraph type as paragraph classic, it is working fine in the manage form display but if I set the type as inline entity form - complex, it is not working as except.

Please help me on this.

SrinuPodamekala’s picture

@miro_dietiker, Can you please help me on this.

Abyss made their first commit to this issue’s fork.

Abyss’s picture

Assigned: Unassigned » Abyss

Abyss’s picture

Assigned: Abyss » Unassigned
FileSize
1.51 KB
1.83 KB

I fixed incorrect paragraph work with content moderation, but for end work on this issue will need tests update, 'cause they were written for the previous logic.

Abyss’s picture

Status: Active » Needs work
sleitner’s picture

I tried to build a test for this issue following the steps in the summary. I must be missing something, because the test doesn't fail as expected. See test file attached.

amateescu’s picture

Status: Needs work » Closed (duplicate)
Parent issue: #2807371: META Support Content Moderation module »
Related issues: +#2954512: Store information about a paragraph's parent revision

#2954512: Store information about a paragraph's parent revision would fix this problem, so closing it as a duplicate.