entity_mesh-1.1.1/src/Batches/NodeBatch.php

src/Batches/NodeBatch.php
<?php

namespace Drupal\entity_mesh\Batches;

use Drupal\Core\Batch\BatchBuilder;
use Drupal\entity_mesh\TrackerInterface;
use Drupal\node\NodeInterface;

/**
 * Batch for processing nodes from tracker.
 */
class NodeBatch {

  /**
   * Get batch object preconfigured.
   *
   * @return \Drupal\Core\Batch\BatchBuilder
   *   Batch object.
   */
  public static function getBatchObjectPreconfigured(): BatchBuilder {
    $batch = new BatchBuilder();
    $batch->setTitle(t('Processing tracked nodes'))
      ->setFinishCallback([self::class, 'finished'])
      ->setInitMessage(t('Initializing node processing...'))
      ->setProgressMessage(t('Processing nodes...'))
      ->setErrorMessage(t('An error occurred during node processing.'));
    return $batch;
  }

  /**
   * Get items for operation from the tracker.
   *
   * Retrieves all pending node entities from the tracker queue that need
   * to be processed by the batch operation.
   *
   * @return array
   *   Array of tracker items, each containing:
   *   - id: The tracker record ID.
   *   - entity_type: The entity type (always 'node' in this case).
   *   - entity_id: The node ID.
   *   - operation: The operation type (OPERATION_PROCESS or OPERATION_DELETE).
   *   - status: The current processing status.
   *   - timestamp: When the item was added to the tracker.
   *   - retry_count: Number of failed processing attempts.
   */
  public static function getItemsForOperation() {
    $tracker = \Drupal::service('entity_mesh.tracker');
    $pending_entities = $tracker->getPendingEntities(NULL, 'node');

    return $pending_entities;
  }

  /**
   * Generate batch for processing tracked nodes.
   *
   * Creates a complete batch configuration that processes all pending nodes
   * from the tracker. Each tracked node will be processed individually by
   * the operation() method.
   *
   * @return \Drupal\Core\Batch\BatchBuilder
   *   A configured batch builder object ready to be executed. The batch will
   *   process all pending nodes from the tracker queue, updating their status
   *   as they are processed.
   */
  public static function generateBatch(): BatchBuilder {
    $batch = self::getBatchObjectPreconfigured();
    $items_for_operation = self::getItemsForOperation();

    foreach ($items_for_operation as $item) {
      $batch->addOperation([self::class, 'operation'], [$item]);
    }

    return $batch;
  }

  /**
   * Process a single tracked node.
   *
   * This is the main batch operation that processes a single node from the
   * tracker queue. It handles both OPERATION_PROCESS and OPERATION_DELETE
   * operations, updating the tracker status accordingly.
   *
   * The method will:
   * - Load the node from the database
   * - Execute the appropriate operation (process or delete)
   * - Mark the tracker item as processed on success
   * - Mark the tracker item as failed on error
   * - Log any errors that occur during processing
   *
   * @param array $tracker_item
   *   The tracker item array containing:
   *   - id: The tracker record ID (used for updating status).
   *   - entity_id: The node ID to process.
   *   - operation: The operation type (OPERATION_PROCESS or OPERATION_DELETE).
   *   - Other tracker fields (entity_type, status, timestamp, retry_count).
   * @param array $context
   *   The batch context array, used to track:
   *   - results['processed']: Array of successfully processed node IDs.
   *   - results['failed']: Array of failed node IDs.
   *   - message: Current operation message displayed to the user.
   *   - sandbox['progress']: Number of items processed so far.
   */
  public static function operation(array $tracker_item, array &$context) {
    $tracker = \Drupal::service('entity_mesh.tracker');
    $tracker_id = (int) $tracker_item['id'];
    $entity_id = $tracker_item['entity_id'];
    $operation = (int) $tracker_item['operation'];

    try {
      // Load the node.
      $node = \Drupal::entityTypeManager()
        ->getStorage('node')
        ->load($entity_id);

      if ($node instanceof NodeInterface) {
        // Check operation type.
        if ($operation === TrackerInterface::OPERATION_PROCESS) {
          // Clear mesh account cache before processing to ensure fresh config.
          \Drupal::service('entity_mesh.repository')->clearMeshAccountCache();

          // Process the entity.
          \Drupal::service('entity_mesh.entity_render')->processEntity($node);
        }

        // Mark as processed.
        $tracker->markAsProcessed($tracker_id);
        $context['results']['processed'][] = $entity_id;
      }
      else {
        // Node not found, mark as failed.
        $tracker->markAsFailed($tracker_id);
        $context['results']['failed'][] = $entity_id;
      }
    }
    catch (\Exception $e) {
      // Mark as failed on exception.
      $tracker->markAsFailed($tracker_id);
      $context['results']['failed'][] = $entity_id;
      \Drupal::logger('entity_mesh')->error('Error processing node @id: @message', [
        '@id' => $entity_id,
        '@message' => $e->getMessage(),
      ]);
    }

    if (!isset($context['sandbox']['progress'])) {
      $context['sandbox']['progress'] = 0;
    }
    $context['sandbox']['progress']++;

    $context['message'] = t('Processing node @id from tracker...', ['@id' => $entity_id]);
  }

  /**
   * Batch finished callback.
   *
   * Called when the batch processing is complete. Displays appropriate
   * messages to the user based on the processing results.
   *
   * @param bool $success
   *   TRUE if the batch completed successfully, FALSE if there was a fatal
   *   error that stopped batch processing.
   * @param array $results
   *   The results array accumulated during batch processing:
   *   - processed: Array of node IDs that were successfully processed.
   *   - failed: Array of node IDs that failed to process.
   * @param array $operations
   *   Array of operations that were executed (or remaining if batch failed).
   */
  public static function finished(bool $success, array $results, array $operations): void {
    $messenger = \Drupal::messenger();

    if ($success) {
      $processed = count($results['processed'] ?? []);
      $failed = count($results['failed'] ?? []);

      $messenger->addStatus(t('Successfully processed @count nodes.', [
        '@count' => $processed,
      ]));

      if ($failed > 0) {
        $messenger->addWarning(t('Failed to process @count nodes.', [
          '@count' => $failed,
        ]));
      }
    }
    else {
      $messenger->addError(t('An error occurred while processing nodes.'));
    }
  }

}

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

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