Drupal → Выполнить очередь с помощью Batch API

16.12.2019

Пример выполнения очереди products_import с помощью Batch API:

class ProductsImportForm extends FormBase {

  /**
   * {@inheritDoc}
   */
  public function getFormId(): string {
    return 'products_import_form';
  }

  /**
   * {@inheritDoc}
   */
  public function buildForm(array $form, FormStateInterface $form_state): array {
    $form['submit'] = [
      '#type' => 'submit',
      '#value' => $this->t('Start'),
    ];

    return $form;
  }

  /**
   * {@inheritDoc}
   */
  public function submitForm(array &$form, FormStateInterface $form_state): void {
    batch_set([
      'title' => $this->t('Products import'),
      'operations' => [
        // Operation 1
        [
          // Operation callback
          [static::class, 'processQueue'],
          // Operation data
          []
        ]
      ],
    ]);
  }

  /**
   * Batch operation.
   */
  public static function processQueue(array &$context): void {
    $queue = \Drupal::queue('products_import');
    $queue_worker_manager = \Drupal::service('plugin.manager.queue_worker'); /** @var QueueWorkerManagerInterface $queue_worker_manager */
    $queue_worker = $queue_worker_manager->createInstance('products_import');

    if (empty($context['sandbox'])) {
      $context['sandbox']['max'] = $queue->numberOfItems();
    }

    /** @see \Drupal\Core\Cron::processQueues() */
    if ($item = $queue->claimItem()) {
      $queue_worker->processItem($item->data);
      $queue->deleteItem($item);
    }

    if ($queue_items_count = $queue->numberOfItems()) {
      $context['finished'] = ($context['sandbox']['max'] - $queue_items_count) / $context['sandbox']['max'];
      $context['finished'] = min($context['finished'], 0.99);
    }
  }

}

При этом очередь products_import уже должна быть наполнена и у неё должен быть рабочий воркер.

Написанное актуально для
Drupal 8
Похожие записи

Добавить комментарий