Commit 2bcd8444 authored by baldwinlouie's avatar baldwinlouie Committed by Yas Naoi
Browse files

Issue #3316407 by baldwinlouie, yas: Refactor to reassign Cloud Credit entity...

Issue #3316407 by baldwinlouie, yas: Refactor to reassign Cloud Credit entity UIDs when a user is deleted
parent 7a7369d4
Loading
Loading
Loading
Loading
+3 −3
Original line number Diff line number Diff line
@@ -496,7 +496,7 @@ function cloud_user_predelete($account): void {
  \Drupal::service('cloud')->reassignUids($cloud_config_ids, [
    'uid' => 0,
    'revision_uid' => 0,
  ], 'cloud_config', TRUE);
  ], 'cloud_config', TRUE, $account);

  $cloud_project_ids = \Drupal::entityTypeManager()
    ->getStorage('cloud_project')
@@ -506,7 +506,7 @@ function cloud_user_predelete($account): void {
  \Drupal::service('cloud')->reassignUids($cloud_project_ids, [
    'uid' => 0,
    'revision_uid' => 0,
  ], 'cloud_project', TRUE);
  ], 'cloud_project', TRUE, $account);

  // Reassign cloud store entities.
  $cloud_store_ids = \Drupal::entityTypeManager()
@@ -517,7 +517,7 @@ function cloud_user_predelete($account): void {

  \Drupal::service('cloud')->reassignUids($cloud_store_ids, [
    'uid' => 0,
  ], 'cloud_store', FALSE);
  ], 'cloud_store', FALSE, $account);

}

+81 −0
Original line number Diff line number Diff line
@@ -7,6 +7,7 @@

use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Routing\RouteMatchInterface;
use Drupal\Core\Session\AccountInterface;

/**
 * Implements hook_help().
@@ -44,6 +45,86 @@ function cloud_budget_cron() {
  cloud_budget_update_credits();
}

/**
 * Implements hook_ENTITY_TYPE_predelete().
 */
function cloud_budget_user_predelete($account): void {
  // Reassign cloud store entities.
  $cloud_store_ids = \Drupal::entityTypeManager()
    ->getStorage('cloud_credit')
    ->getQuery()
    ->condition('uid', $account->id())
    ->execute();

  \Drupal::service('cloud')->reassignUids($cloud_store_ids, [
    'uid' => 0,
  ], 'cloud_credit', FALSE, $account, [
    // Do additional processing specific to cloud_credit entities.
    'cloud_budget_delete_cloud_credit_user_callback',
  ]);
}

/**
 * Additional callback during user delete operation.
 *
 * Callback queries the cloud_credit table and deletes any entities
 * where the user field = user being deleted.
 *
 * @param array $entities
 *   Array of entity ids.
 * @param array $updates
 *   Array of key/values to update.
 * @param string $entity_type
 *   The entity type.
 * @param bool $revision
 *   TRUE if the entities support revisions.
 * @param array|\ArrayAccess $context
 *   An array of contextual key/values.
 */
function cloud_budget_delete_cloud_credit_user_callback(array $entities, array $updates, string $entity_type, bool $revision, AccountInterface $account, &$context): void {
  if (!isset($context['sandbox']['progress'])) {
    // Load cloud_credit entities.
    $cloud_store_entities = [];
    try {
      $cloud_store_entities = \Drupal::entityTypeManager()
        ->getStorage('cloud_credit')
        ->loadByProperties([
          'user' => $account->id(),
        ]);
    }
    catch (\Exception $e) {
      \Drupal::service('cloud')->handleException($e);
    }
    $context['sandbox']['progress'] = 0;
    $context['sandbox']['max'] = count($cloud_store_entities);
    $context['sandbox']['entities'] = $cloud_store_entities;
  }

  try {
    $count = min(5, count($context['sandbox']['entities']));
    for ($i = 1; $i <= $count; $i++) {
      /** @var \Drupal\cloud_budget\Entity\CloudCredit $entity */
      $entity = array_shift($context['sandbox']['entities']);
      $entity->delete();

      // Update our progress information.
      $context['sandbox']['progress']++;
    }
  }
  catch (\Exception $e) {
    \Drupal::service('cloud')->handleException($e);
    // Set progress value to max so batch processing completes.
    $context['sandbox']['progress'] = $context['sandbox']['max'];
  }

  // Inform the batch engine that we are not finished,
  // and provide an estimation of the completion level we reached.
  if ($context['sandbox']['progress'] != $context['sandbox']['max']) {
    $context['finished'] = $context['sandbox']['progress'] / $context['sandbox']['max'];
  }

}

/**
 * Update credits.
 */
+19 −12
Original line number Diff line number Diff line
@@ -1606,22 +1606,29 @@ class CloudService extends CloudServiceBase implements CloudServiceInterface, Cl
  /**
   * {@inheritdoc}
   */
  public function reassignUids(array $ids, array $update, string $entity_type, bool $revision, array $operations = []): void {
    if (empty($ids)) {
  public function reassignUids(array $ids, array $update, string $entity_type, bool $revision, AccountInterface $account, array $operations = []): void {
    // Exit the method if both $ids and $operations are empty.  There
    // can be cases where $ids is empty, but a module wants to do
    // additional processing and has passed additional $operations.
    if (empty($ids) && empty($operations)) {
      return;
    }

    $batch_builder = (new BatchBuilder())
    $batch_builder = new BatchBuilder();

    if (!empty($ids)) {
      $batch_builder
        ->addOperation([
          self::class,
          'batchProcessEntities',
      ], [$ids, $update, $revision, $entity_type]);
        ], [$ids, $update, $entity_type, $revision]);
    }

    // Add additional operations if passed into this method.  This lets
    // Add additional operations if passed into this method.  Let
    // implementing modules perform additional processing on the entity ids.
    foreach ($operations ?: [] as $operation) {
      $batch_builder->addOperation(
        $operation, [$ids, $update, $revision, $entity_type]);
        $operation, [$ids, $update, $entity_type, $revision, $account]);
    }

    $batch_builder
@@ -1644,14 +1651,14 @@ class CloudService extends CloudServiceBase implements CloudServiceInterface, Cl
   *   Array of entity ids.
   * @param array $updates
   *   Array of key/values to update.
   * @param bool $revision
   *   TRUE if the entities support revisions.
   * @param string $entity_type
   *   The entity type.
   * @param bool $revision
   *   TRUE if the entities support revisions.
   * @param array|\ArrayAccess $context
   *   An array of contextual key/values.
   */
  public static function batchProcessEntities(array $entities, array $updates, bool $revision, string $entity_type, &$context): void {
  public static function batchProcessEntities(array $entities, array $updates, string $entity_type, bool $revision, &$context): void {
    if (!isset($context['sandbox']['progress'])) {
      $context['sandbox']['progress'] = 0;
      $context['sandbox']['max'] = count($entities);
+5 −1
Original line number Diff line number Diff line
@@ -6,6 +6,7 @@ use Drupal\cloud\Entity\CloudContentEntityBase;
use Drupal\Core\Database\Query\AlterableInterface;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Queue\QueueInterface;
use Drupal\Core\Session\AccountInterface;

/**
 * Class CloudService.
@@ -337,6 +338,7 @@ interface CloudServiceInterface {
   *     array $updates,
   *     bool $revision,
   *     string $entity_type,
   *     AccountInterface $account,
   *     &$context
   *   );
   *
@@ -348,11 +350,13 @@ interface CloudServiceInterface {
   *   The entity type to query.
   * @param bool $revision
   *   Whether entity type uses revisions or not.
   * @param \Drupal\Core\Session\AccountInterface $account
   *   Account being deleted.
   * @param array $operations
   *   Optional operations to pass in for batch processing.
   *
   * @see batchProcessEntities()
   */
  public function reassignUids(array $ids, array $update, string $entity_type, bool $revision, array $operations = []): void;
  public function reassignUids(array $ids, array $update, string $entity_type, bool $revision, AccountInterface $account, array $operations = []): void;

}