cached_moderation_state-1.0.0-alpha2/src/Commands/CachedModerationStateCommands.php

src/Commands/CachedModerationStateCommands.php
<?php

namespace Drupal\cached_moderation_state\Commands;

use Drupal\cached_moderation_state\BatchUpdateHandlerInterface;
use Drupal\cached_moderation_state\FieldConfigHandlerInterface;
use Drush\Commands\DrushCommands;

/**
 * Drush command implementations for this module.
 *
 * Copyright (C) 2022  Library Solutions, LLC (et al.).
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 */
class CachedModerationStateCommands extends DrushCommands {

  /**
   * The batch update handler service.
   *
   * @var \Drupal\cached_moderation_state\BatchUpdateHandlerInterface
   */
  protected $batchUpdateHandler;

  /**
   * The field config handler service.
   *
   * @var \Drupal\cached_moderation_state\FieldConfigHandlerInterface
   */
  protected $fieldConfigHandler;

  /**
   * Constructs a CachedModerationStateCommands object.
   *
   * @param \Drupal\cached_moderation_state\BatchUpdateHandlerInterface $batch_update_handler
   *   The batch update handler service.
   * @param \Drupal\cached_moderation_state\FieldConfigHandlerInterface $field_config_handler
   *   The field config handler service.
   */
  public function __construct(BatchUpdateHandlerInterface $batch_update_handler, FieldConfigHandlerInterface $field_config_handler) {
    $this->batchUpdateHandler = $batch_update_handler;
    $this->fieldConfigHandler = $field_config_handler;
  }

  /**
   * List all moderated bundles.
   *
   * @command cached-moderation-state:list-moderated-bundles
   *
   * @option format
   *   The output format to use.
   */
  public function listModeratedBundles(array $options = ['format' => 'csv']) {
    $results = [];

    foreach ($this->fieldConfigHandler->getModeratedEntityTypes() as $entity_type) {
      foreach ($this->fieldConfigHandler->getModeratedBundlesForEntityType($entity_type) as $bundle) {
        $results[] = "{$entity_type->id()}:{$bundle}";
      }
    }

    return $results;
  }

  /**
   * Initialize the batch operation with a set of entity identifiers.
   *
   * @param string $entity_type_id
   *   The entity type from which the batch operation should be initialized.
   * @param string[] $bundles
   *   The bundles from which the batch operation should be initialized.
   * @param bool $only_uninitialized
   *   TRUE to only query entities with uninitialized fields.
   * @param array $context
   *   Context information for the batch operation.
   */
  public function runBatchInitializeStep(string $entity_type_id, array $bundles, bool $only_uninitialized, &$context): void {
    $entity_ids = $this->batchUpdateHandler->getEntitiesForEntityType($entity_type_id, $bundles, $only_uninitialized);

    foreach ($entity_ids as $entity_id) {
      $context['results'][] = $entity_id;
    }

    $context['message'] = \dt('Collected @count entities.', [
      '@count' => \count($context['results']),
    ]);
  }

  /**
   * Process the list of entities using the specified batch size.
   *
   * @param int $batch_size
   *   The number of entities to process in a single run.
   * @param array $context
   *   Context information for the batch operation.
   */
  public function runBatchProcessStep(int $batch_size, &$context): void {
    // Initialize the sandbox before the first batch.
    if (empty($context['sandbox'])) {
      $context['sandbox']['max'] = \count($context['results']);
      $context['sandbox']['progress'] = 0;
    }

    // Exit immediately if there is no work to be done.
    if ($context['sandbox']['max'] === 0) {
      $context['message'] = \dt('No entities required updates.');
      $context['finished'] = 1.0;

      return;
    }

    // Process a batch of entities, incrementing the progress.
    $context['sandbox']['progress'] += $this->batchUpdateHandler->updateEntities($context['results'], $batch_size);

    // Update the progress indicator and status message.
    $context['finished'] = $context['sandbox']['progress'] / $context['sandbox']['max'];
    $context['message'] = \dt('Updated @progress of @max entities.', [
      '@max' => $context['sandbox']['max'],
      '@progress' => $context['sandbox']['progress'],
    ]);
  }

  /**
   * Manually synchronize 'cached_moderation_state' field instances.
   *
   * This method will create or delete 'cached_moderation_state' field instances
   * as needed to establish a one-to-one relationship of field instances to
   * moderated entity bundles.
   *
   * This process is done automatically on module installation and every time a
   * workflow is updated. Only use this command if something goes awry.
   *
   * @command cached-moderation-state:sync-fields
   */
  public function syncFields() {
    $this->fieldConfigHandler->sync();
    $this->logger()->success(\dt("Synchronized 'cached_moderation_state' field instances."));
  }

  /**
   * Updates 'cached_moderation_state' for the supplied bundles.
   *
   * @param string $bundles
   *   A comma-separated list of ENTITY_TYPE_ID:BUNDLE strings to update.
   * @param array $options
   *   An array of additional options for this command.
   *
   * @command cached-moderation-state:update
   *
   * @option batch-size
   *   The number of entities to process at one time.
   * @option only-uninitialized
   *   Only update entities with uninitialized fields.
   */
  public function update(string $bundles = '', array $options = ['batch-size' => 20, 'only-uninitialized' => FALSE]): void {
    if (empty($bundles)) {
      throw new \RuntimeException(\dt('A list of bundles to update is required'));
    }

    $batch_size = $options['batch-size'];
    $only_uninitialized = $options['only-uninitialized'];

    $bundles_by_entity_type_id = [];
    foreach (\preg_split('/,\\s*/', $bundles) as $bundle) {
      if (\strpos($bundle, ':') === FALSE) {
        throw new \InvalidArgumentException(\dt("Invalid bundle '{$bundle}'; bundles must follow the format ENTITY_TYPE_ID:BUNDLE"));
      }

      [$entity_type_id, $bundle] = \explode(':', $bundle, 2);
      $bundles_by_entity_type_id[$entity_type_id][$bundle] = $bundle;
    }

    foreach ($bundles_by_entity_type_id as $entity_type_id => $bundles) {
      // Add an operation to populate entities from this bundle.
      $operations[] = [
        [$this, 'runBatchInitializeStep'],
        [
          $entity_type_id,
          $bundles,
          $only_uninitialized,
        ],
      ];
    }

    // Add the final operation step to process the resulting entities.
    $operations[] = [
      [$this, 'runBatchProcessStep'],
      [
        $batch_size,
      ],
    ];

    \batch_set(['operations' => $operations]);
    \drush_backend_batch_process();
  }

  /**
   * Updates all entities with a 'cached_moderation_state' field.
   *
   * @param array $options
   *   An array of additional options for this command.
   *
   * @command cached-moderation-state:update-all
   *
   * @option batch-size
   *   The number of entities to process at one time.
   * @option only-uninitialized
   *   Only update entities with uninitialized fields.
   */
  public function updateAll(array $options = ['batch-size' => 20, 'only-uninitialized' => FALSE]) {
    $bundles = \implode(',', $this->listModeratedBundles());
    $this->update($bundles, $options);
  }

}

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

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