media_mpx-8.x-1.x-dev/src/Form/QueueContentsForm.php

src/Form/QueueContentsForm.php
<?php

namespace Drupal\media_mpx\Form;

use Drupal\Core\Batch\BatchBuilder;
use Drupal\Core\Form\FormBase;
use Drupal\Core\Form\FormStateInterface;
use Drupal\media_mpx\Repository\MpxMediaType;
use Drupal\media_mpx\Service\QueueVideoImportsRequest;
use Drupal\media_mpx\Service\QueueVideoImportsResponse;
use Symfony\Component\DependencyInjection\ContainerInterface;

/**
 * Allows a site administrator to queue videos for import.
 */
class QueueContentsForm extends FormBase {

  /**
   * The mpx Media Types repository.
   *
   * @var \Drupal\media_mpx\Repository\MpxMediaType
   */
  private $mpxMediaTypeRepository;

  /**
   * QueueContentsForm constructor.
   */
  public function __construct(MpxMediaType $mpxMediaTypeRepository) {
    $this->mpxMediaTypeRepository = $mpxMediaTypeRepository;
  }

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container) {
    return new static(
      $container->get('media_mpx.repository.mpx_media_types')
    );
  }

  /**
   * {@inheritdoc}
   */
  public function buildForm(array $form, FormStateInterface $form_state) {
    $mpx_media_types = $this->mpxMediaTypeRepository->findAllTypes();
    $options = [];
    foreach ($mpx_media_types as $mpx_media_type) {
      $options[$mpx_media_type->id()] = $mpx_media_type->label();
    }

    $form['mpx_video_types'] = [
      '#type' => 'checkboxes',
      '#title' => $this->t('mpx Video types'),
      '#options' => $options,
      '#default_value' => count($options) === 1 ? array_keys($options) : [],
      '#required' => TRUE,
    ];
    $form['actions']['#type'] = 'actions';
    $form['actions']['queue'] = [
      '#type' => 'submit',
      '#value' => $this->t('Import videos'),
      '#button_type' => 'primary',
    ];

    return $form;
  }

  /**
   * {@inheritdoc}
   */
  public function submitForm(array &$form, FormStateInterface $form_state) {
    $types = array_filter(array_values($form_state->getValue('mpx_video_types')));

    $batch_builder = new BatchBuilder();
    $batch_builder->setTitle($this->t('Finding mpx videos to import'))
      ->setFinishCallback([$this, 'batchFinished'])
      ->setInitMessage($this->t('Queueing mpx videos for background imports.'));

    foreach ($types as $type) {
      $batch_builder->addOperation([$this, 'batchedQueueItemsForMediaType'], ['media_type_id' => $type]);
    }
    batch_set($batch_builder->toArray());
  }

  /**
   * Operation callback to queue each mpx media type for imports.
   *
   * @param string $media_type_id
   *   The media type id to process in this callback.
   * @param array $context
   *   Context data passed between batches.
   *
   * @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException
   * @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException
   * @throws \Drupal\media_mpx\Exception\MediaTypeDoesNotExistException
   * @throws \Drupal\media_mpx\Exception\MediaTypeNotAssociatedWithMpxException
   */
  public function batchedQueueItemsForMediaType(string $media_type_id, array &$context) {
    /** @var \Drupal\media_mpx\Service\QueueVideoImports $queue_service */
    $queue_service = \Drupal::getContainer()->get('media_mpx.service.queue_video_imports');

    // Mpx responses might be a bit heavy, so limit batches size to 200. Don't
    // want php running out of memory.
    // @see vendor/lullabot/mpx-php/src/DataService/ObjectListQuery.php
    $batch_size = 200;

    if (empty($context['sandbox'])) {
      $context['sandbox']['progress'] = 0;
      $context['sandbox']['last_index'] = 0;
      $context['results'] = [
        'success' => [],
        'errors' => [],
      ];
    }

    $request = new QueueVideoImportsRequest(
      $media_type_id,
      $batch_size,
      $context['sandbox']['last_index'] + 1
    );

    $response = $queue_service->execute($request);
    $this->updateContextArrayFromResponse($media_type_id, $context, $response, $batch_size);
  }

  /**
   * Updates the context array after getting a response from the queue service.
   *
   * @param string $media_type_id
   *   The media type id being processed.
   * @param array $context
   *   The context array.
   * @param \Drupal\media_mpx\Service\QueueVideoImportsResponse $response
   *   The response from the queue service.
   * @param int $batch_size
   *   The batch size being used for the batch operation.
   */
  private function updateContextArrayFromResponse(string $media_type_id, array &$context, QueueVideoImportsResponse $response, int $batch_size): void {
    $context['sandbox']['total_results'] = $context['sandbox']['total_results'] ?: $response->getIterator()->getTotalResults();
    $total_items = $context['sandbox']['total_results'];

    $context['results']['success'] = array_merge($context['results']['success'], $response->getQueuedVideos());
    $context['results']['errors'] = array_merge($context['results']['errors'], $response->getNotQueuedVideos());
    $context['sandbox']['progress'] += count($response->getQueuedVideos());
    $context['sandbox']['last_index'] = $context['sandbox']['last_index'] + $batch_size;
    $context['message'] = $this->t('Queued @progress %type items out of @total.', [
      '@progress' => $context['sandbox']['progress'],
      '@total'    => $total_items,
      '%type'     => $media_type_id,
    ]);

    $context['finished'] = $context['sandbox']['progress'] / $total_items;
  }

  /**
   * Finished callback for the batch queuing operations to update mpx videos.
   *
   * @param bool $success
   *   Result of the queuing operations.
   * @param array $results
   *   An array with the count of successful and errored queue operations.
   */
  public function batchFinished(bool $success, array $results) {
    $finished_message = $this->t('Finished with errors.');

    if ($success) {
      $finished_message = $this->formatPlural(count($results['success']),
        'One mpx item queued.',
        '@count mpx items queued for updates. Imports will continue in the background.');
    }

    $this->messenger()->addMessage($finished_message);

    if (count($results['errors']) > 0) {
      $errors_message = $this->formatPlural(
        count($results['errors']),
        'The following mpx item could not be queued. Check logs for details.',
        'The following @count mpx items could not be queued for updates. Check logs for details.');
      $this->messenger()->addError($errors_message);

      /** @var \Lullabot\Mpx\DataService\Media\Media $mpx_item */
      foreach ($results['errors'] as $mpx_item) {
        $this->messenger()->addError($mpx_item->getId());
      }
    }
  }

  /**
   * {@inheritdoc}
   */
  public function getFormId() {
    return 'media_mpx_asset_sync_queue';
  }

}

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

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