association-1.0.0-alpha2/src/Utility/DeleteAssociationBatchOp.php
src/Utility/DeleteAssociationBatchOp.php
<?php namespace Drupal\association\Utility; /** * Batch operations for deleting associations and linked entities. */ class DeleteAssociationBatchOp { const BATCH_SIZE = 50; /** * Deleted all entities linked to an entity association of a single type. * * @param \Drupal\association\Entity\AssociationInterface[] $associations * Array of association entity IDs to delete the linked entities for. * @param string $entity_type * The type of entity to delete. * @param array $context * Reference to batch context. This maintains the current progress and * state of this batch operation. */ public static function deleteLinkedEntitiesByType(array $associations, $entity_type, array &$context) { if (!$associations) { return; } $entityTypeManager = \Drupal::entityTypeManager(); $assocLinkDef = $entityTypeManager->getDefinition('association_link'); $query = \Drupal::database() ->select($assocLinkDef->getBaseTable(), 'base') ->fields('base', ['target']) ->condition('base.entity_type', $entity_type); if (count($associations) === 1) { $query->condition('base.association', reset($associations)); } else { $query->condition('base.association', $associations, 'IN'); } if (!isset($context['sandbox']['progress'])) { $countQuery = clone $query; $context['sandbox'] = [ 'current' => 0, 'progress' => 0, 'total' => $countQuery ->countQuery() ->execute() ->fetchField(), ]; // Make sure that there are associations to delete, otherwise just exit. if (empty($context['sandbox']['total'])) { return; } } $ids = $query ->condition('base.target', $context['sandbox']['current'], '>') ->range(0, self::BATCH_SIZE) ->orderBy('base.target', 'ASC') ->execute() ->fetchCol(); if ($ids) { $entityStorage = $entityTypeManager->getStorage($entity_type); $entities = $entityStorage->loadMultiple($ids); $entityStorage->delete($entities); $context['sandbox']['current'] = end($ids); $context['sandbox']['progress'] += count($ids); if ($context['sandbox']['progress'] < $context['sandbox']['total']) { $context['finished'] = $context['sandbox']['progress'] / $context['sandbox']['total']; } } if ($entityDef = $entityTypeManager->getDefinition($entity_type, FALSE)) { $context['message'] = t('Removing @type linked content: %progress of %total', [ '@type' => $entityDef->getLabel(), '%progress' => $context['sandbox']['progress'], '%total' => $context['sandbox']['total'], ]); } } /** * Deleted all entities linked to association entities of any type. * * This is less efficient that deleting entities by type, but is meant as a * final clean-up to remove any dangling referenced content. Ideally this * operation will not clear any entities as this will be run after all the * remove by entity type operations are run. * * @param \Drupal\association\Entity\AssociationInterface[] $associations * Array of association entity IDs to delete the linked entities for. * @param array $context * Reference to batch context. This maintains the current progress and * state of this batch operation. */ public static function deleteLinkedEntities(array $associations, array &$context) { if (!$associations) { return; } $entityTypeManager = \Drupal::entityTypeManager(); $assocLinkStorage = $entityTypeManager->getStorage('association_link'); $query = $assocLinkStorage ->getQuery() ->accessCheck(FALSE); if (count($associations) === 1) { $query->condition('association', reset($associations)); } else { $query->condition('association', $associations, 'IN'); } if (!isset($context['sandbox']['progress'])) { $countQuery = clone $query; $context['sandbox'] = [ 'current' => 0, 'progress' => 0, 'total' => $countQuery ->count() ->execute(), ]; // Make sure that there are links to delete, otherwise just exit. if (empty($context['sandbox']['total'])) { return; } } $ids = $query ->condition('id', $context['sandbox']['current'], '>') ->range(0, self::BATCH_SIZE) ->sort('id', 'ASC') ->execute(); if ($ids) { foreach ($assocLinkStorage->loadMultiple($ids) as $link) { $link->delete(); $context['sandbox']['current'] = $link->id(); $context['sandbox']['progress']++; } if ($context['sandbox']['progress'] < $context['sandbox']['total']) { $context['finished'] = $context['sandbox']['progress'] / $context['sandbox']['total']; } } } }