You are here

public function AcsfDuplicationScrubCommentStorage::deleteOrphanedItems in Acquia Cloud Site Factory Connector 8

Same name and namespace in other branches
  1. 8.2 src/Event/AcsfDuplicationScrubCommentStorage.php \Drupal\acsf\Event\AcsfDuplicationScrubCommentStorage::deleteOrphanedItems()

Deletes orphaned comments without having to load the full entities first.

The regular EntityStorageInterface::delete() expects fully loaded entities as arguments but -because of the above- we cannot load orphaned comments. So we'll query for IDs, and mimic delete-related methods so they need IDs as an argument instead of full entities.

Parameters

int $limit: (optional) Maximum number of comments to delete in one go.

int $already_processed_min_id: (optional) If specified and >0, only delete items with an ID lower than this. 0 is interpreted as "no deletion is necessary".

Return value

array The orphaned items that were found, and possibly deleted.

File

src/Event/AcsfDuplicationScrubCommentStorage.php, line 77

Class

AcsfDuplicationScrubCommentStorage
Comment storage class (using a SQL backend) which ignores load failures.

Namespace

Drupal\acsf\Event

Code

public function deleteOrphanedItems($limit = 0, $already_processed_min_id = -1) {
  $cids = $this
    ->getOrphanedItems($limit, $already_processed_min_id);
  if ($cids) {

    // First, check if these comments have children which are not orphaned
    // (i.e. the commented node and user do exist; the parent comment is only
    // orphaned because its parent does not exist). If so, add these to the
    // list. (These cannot be loaded without generating fatal errors either,
    // because rdf_comment_storage_load() calls $comment->getParentComment()
    // which tries to load the whole parent comment which recursively etc.
    // until rdf_comment_storage_load() processes the orphaned parent and
    // crashes.)
    $uid_and_entity_ok = array_filter($cids);
    $child_cids = [];
    if ($uid_and_entity_ok) {

      // Database statement copied/changed from $this->getChildCids():
      $child_cids = $this->database
        ->select('comment_field_data', 'c')
        ->fields('c', [
        'cid',
      ])
        ->condition('pid', array_keys($uid_and_entity_ok), 'IN')
        ->condition('default_langcode', 1)
        ->execute()
        ->fetchCol();
    }
    $cids = array_merge(array_keys($cids), $child_cids);

    // Mimic the parts of CommentStorage::delete() that are possible.
    // The call structure:
    // - Comment::preDelete: is empty.
    // - invokeHook('predelete'): needs entity.
    // - doDelete():
    //   - invokeFieldMethod('delete'): needs entity.
    //   - doDeleteFieldItems(): can be mimicked.
    $this
      ->doDeleteFieldItemsById($cids);

    // - resetCache()
    $this
      ->resetCache($cids);

    // - Comment::postDelete:
    //   - deletes child comments: done above.
    //   - deletes statistics: copying CommentStatistics::delete() code here:
    $this->database
      ->delete('comment_entity_statistics')
      ->condition('entity_id', $cids, 'IN')
      ->condition('entity_type', 'comment')
      ->execute();

    // - invokeHook('postdelete'): needs entity.
  }
  return $cids;
}