When I clone a node with a paragraph field (which is an entity reference with revisions) and then I delete the cloned node, the original node looses its content in the paragraph field.

How to reproduce:

  1. Install Drupal 8.2.6 standard profile.
  2. Install Node clone 8.x-1.x-dev (currently my composer.lock references 41a4050c1dca8851bba5136ee6e4a3b105fb4777) .
  3. Install Paragraphs 8.x-1.0 .
  4. Create a paragraph type with a plain text field.
  5. Add a paragraph field to the article content type.
  6. Create an Article with one or more paragraphs.
  7. Clone the created article
  8. Delete the cloned article
  9. View the original article, search for the paragraphs

I checked all database tables related to paragraphs and found all empty, so this looks like a use case resulting in unexpected data loss.

Comments

pedrop created an issue. See original summary.

O'Briat’s picture

It looks like the paragraphs are not cloned so, both the original content and the cloned one use the same paragraphs.

When deleting the cloned content, the paragraph is also deleted (it's not a typical entity reference).

To test it, try to modify a cloned content with paragraphs, the original content should also be modify.

Have a look at the replicate module, Paragraphs cloning seems to be available out of the box https://www.drupal.org/node/2778393

pedrop’s picture

Yes, I think node_clone should not allow to clone nodes with paragraphs as long as it doesn't support them properly.

szato’s picture

I think it's issue of the Entity Reference Revisions module. (Paragraphs uses the Entity Reference Revisions field)

hawkeye.twolf’s picture

Note that the current behaviour, which leverages Node::createDuplicate(), creates new revisions of the existing paragraphs item, rather than creating entirely new paragraph entities on the cloned node. I'm not sure Node Clone even wants to get in the business of supporting contrib-specific entities, but at the very least there should be a giant warning on the project page and README saying,

OMG PLEASE FOR THE LOVE OF GOD, DO NOT USE THIS WITH PARAGRAPHS. I KNOW, IT LOOKS LIKE IT WORKS RIGHT NOW, BUT YOU ARE IN FOR A WORLD OF CONFUSION AND PAIN IF YOU CHOOSE TO PROCEED.

And if we do want to support Paragraphs, we could make it a sub-module.

Consider combining this issue with either of:

  1. #2882111: File pragragraph clone is not working showing "You are not authorised to access this page" error for download file
  2. #2875564: Paragraph ID(reference entities ID) not updated in new page after clone any page
bburg’s picture

So for someone whose already fallen into the trap of installing this module on a site where paragraphs are heavily used... What are my next steps? I have content creators freaking out that their paragraph items are disappearing. My site users really like this module, they have complex paragraph content on some pages, and find it convenient to not have to re-create the paragraph structure each time.

What's the feasibility of creating a module/sub-module that also clones paragraph content?

hawkeye.twolf’s picture

@bburg, the Paragaraph module's Drupal 8 release includes an "Experimental" form widget that supports duplicating Paragraph items within a given field. I imagine whatever logic powers that behavior could be leveraged in a similar way to support cloning.

Not sure if this will help you at this point in your project, but my response to the issue of editors needing to create complex paragraph types was to just limit the complexity. Rather than architecting a super-flexible suite of nested Paragraph types, I moved in the direction of more content types with discrete Paragraphs fields that accomplish very specific layouts and content. This gives editors some direction when presented with a blank node edit form and helps them to feel less lost than in the former scenario, where they had to use their memory and judgment to figure out how to stitch together the complex paragraph items.

aposudevsky’s picture

@bburg, I faced the same problem. There is no way we can rebuild content structure as @derek.hawkeye.deraps suggests, because of huge number of existing content. So I've wrote a script which gets all cloned paragraphs and replicates them, sets the right field data and saves new paragraph item and then updates the entity reference field.
Unfortunately I was not able to come up with unified solution which will match any kind of content fields / paragraphs setup, but you can use my script as a reference to write your own.
Note : script depends on replicate module.

    $connection = \Drupal::database();
    // get cloned nodes data
    $query = $connection->query("SELECT entity_id node_entity_id, revision_id node_revision_id, field_vertical_tabs_target_id, field_vertical_tabs_target_revision_id FROM `node_revision__field_vertical_tabs` WHERE field_vertical_tabs_target_id IN (
        SELECT field_vertical_tabs_target_id FROM `node_revision__field_vertical_tabs` GROUP BY field_vertical_tabs_target_id HAVING COUNT(field_vertical_tabs_target_id) > 1)");
    $result = $query->fetchAll();

    /** @var \Drupal\replicate\Replicator $replicator */
    $replicator = \Drupal::service('replicate.replicator');

    $revisions_count = count($result);

    foreach ($result as $row) {
      // get actual fields values
      $sql = 'SELECT a.`field_tab_content_value`, b.`field_tab_title_value` FROM `paragraph_revision__field_tab_content` a INNER JOIN `paragraph_revision__field_tab_title` b ON a.revision_id = b.revision_id WHERE a.revision_id = ' . $row->field_vertical_tabs_target_revision_id;
      $data = $connection->query($sql)->fetchObject();
      $paragraph = \Drupal\paragraphs\Entity\Paragraph::load($row->field_vertical_tabs_target_id);

      if ($paragraph && $paragraph instanceof \Drupal\Core\Entity\EntityInterface) {
        $replicated_paragraph = $replicator->replicateEntity($paragraph);
        $replicated_paragraph->set('field_tab_content', ['value' => $data->field_tab_content_value, 'format' => 'full_html']);
        $replicated_paragraph->set('field_tab_title', $data->field_tab_title_value);

        $replicated_paragraph->save();

        // update revision table
        $sql = 'UPDATE `node_revision__field_vertical_tabs` SET field_vertical_tabs_target_id = ' . $replicated_paragraph->id() . ', 
            field_vertical_tabs_target_revision_id = ' . $replicated_paragraph->getRevisionId() . ' 
            WHERE revision_id = ' . $row->node_revision_id . ' AND entity_id=' . $row->node_entity_id . ' AND field_vertical_tabs_target_revision_id =' . $row->field_vertical_tabs_target_revision_id;
        $connection->query($sql)->execute();
        // update field table
        $sql = 'UPDATE `node__field_vertical_tabs` SET field_vertical_tabs_target_id = ' . $replicated_paragraph->id() . ', 
            field_vertical_tabs_target_revision_id = ' . $replicated_paragraph->getRevisionId() . ' 
            WHERE revision_id = ' . $row->node_revision_id . ' AND entity_id=' . $row->node_entity_id . ' AND field_vertical_tabs_target_revision_id =' . $row->field_vertical_tabs_target_revision_id;
        $connection->query($sql)->execute();
      }
    }

After running this script I'm able to delete content safely without deleting cloned nodes.

jorgemontoyab’s picture

I guess, I'm reading about this issue 5 minutes too late.

andypost’s picture

Balu Ertl’s picture

Title: Paragraph disappears from the original node upon deleting the clone. » Paragraph disappears from the original node upon deleting the clone