Cannot save unpublished versions of published content with Layout Builder

Created on 15 April 2025, 9 days ago

Problem/Motivation

As content editor I would like to edit content on Layout Builder with a Content Moderation Workflow. But, when I have Book module enable I get the following error message: "You can only change the book outline for the published version of this content. Visit Book outlines page to make changes."

This content type haven't been added to the Book Outline, so the validation should not be triggered.

Steps to reproduce

  1. Start with a clean D10 installation with Layout builder and Content moderation workflow enabled on any content type (lets say an Article).
  2. Make sure you also have Book module installed and enable for a different content type (lets create a book content type).
  3. Create a page (Article) and published the page.
  4. Switch to the "Layout" tab and make some changes to the layout.
  5. Attempt to save the layout with "Draft" state selected in the moderation control.
  6. Note the error message: "You can only change the book outline for the published version of this content. Visit Book outlines page to make changes."
  7. Note that no new revision is created despite selecting the Draft state.

Proposed resolution

A. The Book module's validation constraints need to be modified to only apply to content types that are actually part of the book hierarchy or have book functionality enabled. Currently, the validation is triggered for all content with moderation regardless of whether it's actually using book functionality. That should have been solved on a Cannot save unpublished versions of published content for users without manage book privileges πŸ› Cannot save unpublished versions of published content for users without manage book privileges Needs work

B. Layout Builder should be able to create new draft revisions without triggering book outline validation for content that isn't part of any book structure.

Remaining tasks

  1. Investigate which specific validation constraint in the Book module is being triggered.
  2. Determine if this is an issue with content moderation in general or specific to Layout Builder.
  3. Create a patch that checks if the entity is actually part of a book hierarchy before applying validation constraints.
  4. Write tests to ensure the fix doesn't break actual book functionality.

User interface changes

No UI changes required. The goal is to remove the error message for content that isn't part of a book outline.

API changes

Likely modification to one of the following:
- Book module's validation constraints
- Entity validation flow when triggered from Layout Builder

Data model changes

No data model changes expected.

πŸ› Bug report
Status

Active

Version

2.0

Component

Code

Created by

πŸ‡ΊπŸ‡ΈUnited States anilu@ Houston, TX

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Merge Requests

Comments & Activities

  • Issue created by @anilu@
  • πŸ‡ΊπŸ‡ΈUnited States anilu@ Houston, TX
  • πŸ‡ΊπŸ‡ΈUnited States anilu@ Houston, TX

    The primary issue is with the BookOutlineConstraintValidator in the Book module. This validator is designed to prevent changes to book outlines in non-default (draft) revisions.
    The key problematic code is in the validate() method of the BookOutlineConstraintValidator class:

    public function validate($entity, Constraint $constraint): void {
      // Validate the book structure when the user has access to manage book
      // outlines. When the user can manage book outlines, the book variable will
      // be populated even if the node is not part of the book. If the user cannot
      // manage book outlines, the book variable will be empty, and we can safely
      // ignore the constraints as the outline cannot be changed by this user.
      if (isset($entity) && !$entity->isNew() && !$entity->isDefaultRevision()) {
        /** @var \Drupal\Core\Entity\ContentEntityInterface $original */
        $original = $this->bookManager->loadBookLink($entity->id(), FALSE) ?: [
          'bid' => 0,
          'weight' => 0,
        ];
        if (empty($original['pid'])) {
          $original['pid'] = -1;
        }
    
        if ($entity->book['bid'] != $original['bid']) {
          $this->context->buildViolation($constraint->message)
            ->atPath('book.bid')
            ->setInvalidValue($entity)
            ->addViolation();
        }
        // Additional validation code...
      }
    }
    

    This constraint validator triggers when:

    1. An entity exists (isset($entity))
    2. The entity is not new (!$entity->isNew())
    3. The entity is not the default revision (!$entity->isDefaultRevision())
  • πŸ‡ΊπŸ‡ΈUnited States anilu@ Houston, TX

    Last development version for this module has the required validation for $value->book on src/Plugin/Validation/Constraint/BookOutlineConstraintValidator.php

    if (isset($value) && !empty($value->book) && !$value->isNew() && !$value->isDefaultRevision()) {

    This should be working, but is not. This may be related to the update from core to contrib module.

  • πŸ‡ΊπŸ‡ΈUnited States anilu@ Houston, TX
  • πŸ‡ΊπŸ‡ΈUnited States anilu@ Houston, TX

    I write a script on composer that removes book core module. For now this should work for anyone that needs a quick fix.

    {
        "scripts": {
            "post-install-cmd": [
                "rm -rf web/core/modules/book",
                "@composer drupal:scaffold"
            ],
            "post-update-cmd": [
                "rm -rf web/core/modules/book",
                "@composer drupal:scaffold"
            ]
        }
    }
  • πŸ‡ΊπŸ‡ΈUnited States anilu@ Houston, TX
  • Pipeline finished with Failed
    9 days ago
    Total: 482s
    #475240
  • πŸ‡ΊπŸ‡ΈUnited States anilu@ Houston, TX
  • πŸ‡ΊπŸ‡ΈUnited States anilu@ Houston, TX
  • πŸ‡ΊπŸ‡ΈUnited States anilu@ Houston, TX
  • πŸ‡ΊπŸ‡ΈUnited States anilu@ Houston, TX
  • πŸ‡ΊπŸ‡ΈUnited States anilu@ Houston, TX

    Automatic testing failed because of update to 3.0 branch. Manually applying the patch is working on my project but we need to update the patch and continued testing.

    At this moment, I am not sure if this is a long term solution. Open to hear oppinions.

  • Pipeline finished with Success
    8 days ago
    Total: 3837s
    #475308
Production build 0.71.5 2024