Problem/Motivation

When cloning a node which is under content moderation the status is not cloned. It is set to the default status of the workflow. Clone publication status of original? does not change this.

Steps to reproduce

Proposed resolution

Remaining tasks

User interface changes

API changes

Data model changes

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:

Comments

anruether created an issue. See original summary.

jurgenr’s picture

Status: Active » Needs review
StatusFileSize
new3.94 KB

I'va added a patch that handles workflow management.
The behaviour is added on the original node in the form, and all translations in the QuickNodeCloneEntityFormBuilder().

jurgenr’s picture

StatusFileSize
new3.89 KB

Updated patch to use unpublished status instead of draft.

liam morland made their first commit to this issue’s fork.

liam morland’s picture

Version: 8.x-1.14 » 8.x-1.x-dev

I have created a merge request with the patch in #3.

csakiistvan’s picture

Assigned: Unassigned » csakiistvan
csakiistvan’s picture

Assigned: csakiistvan » Unassigned
Status: Needs review » Reviewed & tested by the community
StatusFileSize
new1023.14 KB
new249.36 KB
new274.09 KB

Environment

  • Drupal: 11.4.4
  • PHP: 8.5.5
  • Database: MariaDB 10.11.16
  • DDEV: v1.25.2
  • Quick Node Clone: 8.x-1.22
  • Browser: Chrome

Prerequisites

  • Enable quick_node_clone, content_moderation and workflows.
  • Add the Article content type to the editorial workflow (/admin/config/workflow/workflows/manage/editorial). The workflow provides the states Draft, Published and Archived — there is no Unpublished state.
  • Create an article and save it as Published.
  • Open /admin/config/quick-node-clone and set Clone publication status to Clone publication status of original.

Steps

  1. Apply the fix from MR !68: resolve the wanted moderation state in QuickNodeCloneEntityFormBuilder::getForm(), pass it to the form through the form state, and preselect it on the widget in quick_node_clone_form_alter().
  2. Rebuild caches: ddev drush cr
  3. Go to /clone/<nid>/quick_clone and look at Save as at the bottom of the form.
  4. Change Clone publication status to Published, reload the clone form and look at Save as.
  5. Change Clone publication status to Unpublished, reload the clone form and look at Save as.
  6. Change Clone publication status to Use the default status of the content type, reload the clone form and look at Save as.
  7. Repeat steps 3–6 without the fix in place to compare the behaviour.

Expected results

  • With Clone publication status of original, the clone form should preselect the moderation state of the original node (Published).
  • With Published, the clone form should preselect Published.
  • With Unpublished, the clone form should preselect a state that is not published (Draft in the editorial workflow).
  • With Use the default status of the content type, the clone form should preselect the state matching the bundle default.

Actual results

The bug is reproducible on 8.x-1.22: with Clone publication status of original and a published, moderated article, the clone form shows Save as: Draft instead of Published. The root cause is that ModerationStateWidget::formElement() resets the moderation state of unsaved entities to the initial state of the workflow, so any state set on the clone in QuickNodeCloneEntityFormBuilder::getForm() is discarded before the widget is built.

The first revision of MR !68 only fixed the Published setting: the original case stayed a no-op, and the Unpublished and Use the default status of the content type settings wrote values into the widget that are not moderation states (the string unpublished, which no core workflow defines, and the boolean bundle default). The MR was reworked accordingly — the wanted state is now passed through the form state so it survives the widget, the original case takes the state of the original node, and the target state is resolved from the workflow (initial state first, otherwise the first state with the wanted publication status) instead of being hard coded.

After the rework all four settings behave as expected on a published moderated article (Published for original, published and default, Draft for unpublished), a draft original is cloned as Draft with the original setting, and cloning an unmoderated content type is unchanged. phpcs with the Drupal and DrupalPractice standards is clean on the changed files.

Changes

  • src/Entity/QuickNodeCloneEntityFormBuilder.php — the clone_status switch now goes through setCloneStatus(), which sets a moderation state on moderated nodes and keeps setPublished() / setUnpublished() for everything else, because content moderation derives the publication status from the state and would overwrite the status field. getModerationStateId() resolves the state from the workflow (initial state first, otherwise the first state with the wanted publication status), so no state ID is hard coded and workflows without a published or unpublished state keep working. The resulting state is passed to the form in $form_state_additions['quick_node_clone_moderation_state'], since the widget discards the state set on the entity. The original case takes the state of the original node instead of doing nothing — this is the case reported in the issue summary.
  • quick_node_clone.modulequick_node_clone_form_alter() preselects that state on the moderation state widget, but only if it is among the transitions available to the current user, so the form never offers a state the user may not select.
  • quick_node_clone.services.ymlcontent_moderation.moderation_information is injected as an optional dependency (@?), so the module keeps working when content moderation is not installed.

Remaining work

  • No test coverage is added for the moderated case.
  • The .gitlab-ci.yml change (OPT_IN_TEST_NEXT_MAJOR: 10) is unrelated to the fix and should be dropped.

Testing produced with the assistance of an LLM.