drupaldrupal-8paragraph

Drupal 8 orphan paragraphs


I've noticed that Paragraph entities are not deleted from the database. They rather unlink from the parent node.

This is noticeable if you create a view, that lists Paragraphs and attach a contextual filter, that filters by Parent ID.

For now, I've found a workaround, to create a view that lists Content. Attach relationship to a Paragraph. This way it ensures that only linked paragraphs are displayed.

There is still an issue of having hundreds of orphan Paragraphs and field data in the database. Is there a way of cleaning them?

EDIT: This is apparently a major bug and could be found in Paragraph module's issue tracker: Removed paragraph entities are not deleted from database


Solution

  • Now that I've figured out that this is a bug and it is not fixed yet, my main goal is to just clean orphan Paragraphs.

    Someone created this module: Paragraph clean, but I'm not a fan of using modules for such purposes.

    So, below I will post my first successful attempt to solve it. I must warn this isn't safe, because it deletes Paragraphs!

    The solution is not tested for using revisions, content translation, etc. So this might ruin your day. Backup your site.

    Using Devel module, go to Development > Execute PHP Code. Paste and execute following code:

    // get all paragraphs
    $deleted = [];
    $paragraph_ids = \Drupal::entityQuery('paragraph')->execute();
    $paragraphs = \Drupal::entityTypeManager()->getStorage('paragraph')->loadMultiple($paragraph_ids);
    foreach ($paragraphs as $target_id => $paragraph) {
      // get parent entity (node, taxonomy, paragraph, etc.)
      $parent = $paragraph->getParentEntity();
      $field_name = $paragraph->parent_field_name->value;
    
      // Check if current paragraph exists in parent entity field values
      $exists = FALSE;
      $values = is_null($parent) ? [] : $parent->get($field_name)->getValue();
      foreach($values as $value) {
        if ($value['target_id'] == $target_id) {
          $exists = TRUE;
        }
      }
    
      // Delete paragraphs that aren't linked to an entity they claim as a parent
      if (!$exists) {
        $paragraph->delete();
        $deleted[] = $target_id;
      }
    }
    
    print "Deleted paragraph IDs: " . implode(', ', $deleted);