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'];
      }
    }
  }

}

Главная | Обратная связь

drupal hosting | друпал хостинг | it patrol .inc