media_acquiadam-8.x-1.46/src/Service/AssetRefreshManager.php

src/Service/AssetRefreshManager.php
<?php

namespace Drupal\media_acquiadam\Service;

use Drupal\Component\Datetime\TimeInterface;
use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Core\Datetime\DrupalDateTime;
use Drupal\Core\DependencyInjection\ContainerInjectionInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Logger\LoggerChannelFactoryInterface;
use Drupal\Core\Queue\QueueFactory;
use Drupal\Core\State\StateInterface;
use Drupal\media_acquiadam\AcquiadamInterface;
use Drupal\media_acquiadam\Exception\InvalidCredentialsException;
use GuzzleHttp\Exception\GuzzleException;
use Symfony\Component\DependencyInjection\ContainerInterface;

/**
 * Class AssetRefreshManager.
 *
 * Adds media items to the asset sync queue for later processing.
 * Uses the Search API to get affected asset ids - determines which
 * assets where changed within the given period of time, and adds them to the
 * queue.
 *
 * @package Drupal\media_acquiadam
 */
class AssetRefreshManager implements AssetRefreshManagerInterface, ContainerInjectionInterface {

  /**
   * The Acquiadam Service.
   *
   * @var \Drupal\media_acquiadam\AcquiadamInterface
   */
  protected $acquiadam;

  /**
   * The Drupal State Service.
   *
   * @var \Drupal\Core\State\StateInterface
   */
  protected $state;

  /**
   * The Logger Factory Service.
   *
   * @var \Drupal\Core\Logger\LoggerChannelInterface
   */
  protected $logger;

  /**
   * The Queue Worker.
   *
   * @var \Drupal\Core\Queue\QueueInterface
   */
  protected $queue;

  /**
   * The media storage.
   *
   * @var \Drupal\Core\Entity\EntityStorageInterface
   */
  protected $mediaStorage;

  /**
   * The config.
   *
   * @var \Drupal\Core\Config\ImmutableConfig
   */
  protected $config;

  /**
   * The time service.
   *
   * @var \Drupal\Component\Datetime\TimeInterface
   */
  protected $time;

  /**
   * The maximum number of items to return in search API response.
   *
   * @var int
   */
  protected $requestLimit = 100;

  /**
   * AssetRefreshManager constructor.
   *
   * @param \Drupal\media_acquiadam\AcquiadamInterface $acquiadam
   *   The Acquiadam Service.
   * @param \Drupal\Core\State\StateInterface $state
   *   The Drupal State Service.
   * @param \Drupal\Core\Logger\LoggerChannelFactoryInterface $logger_factory
   *   The Logger Factory Service.
   * @param \Drupal\Core\Queue\QueueFactory $queue_factory
   *   The Queue Factory Service.
   * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
   *   The EntityTypeManager service.
   * @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory
   *   The config factory.
   * @param \Drupal\Component\Datetime\TimeInterface $time
   *   The time service.
   *
   * @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException
   * @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException
   */
  public function __construct(AcquiadamInterface $acquiadam, StateInterface $state, LoggerChannelFactoryInterface $logger_factory, QueueFactory $queue_factory, EntityTypeManagerInterface $entity_type_manager, ConfigFactoryInterface $config_factory, TimeInterface $time) {
    $this->acquiadam = $acquiadam;
    $this->state = $state;
    $this->logger = $logger_factory->get('media_acquiadam');
    $this->queue = $queue_factory->get($this->getQueueName());
    $this->mediaStorage = $entity_type_manager->getStorage('media');
    $this->config = $config_factory->get('media_acquiadam.settings');
    $this->time = $time;
  }

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container) {
    return new static(
      $container->get('media_acquiadam.acquiadam'),
      $container->get('state'),
      $container->get('logger.factory'),
      $container->get('queue'),
      $container->get('entity_type.manager'),
      $container->get('config.factory'),
      $container->get('datetime.time')
    );
  }

  /**
   * {@inheritdoc}
   */
  public function getQueueName(): string {
    return 'media_acquiadam_asset_refresh';
  }

  /**
   * {@inheritdoc}
   */
  public function updateQueue(array $asset_id_fields) {
    if (empty($asset_id_fields)) {
      // Nothing to process. Associated media bundles are not found.
      return 0;
    }

    // Get ids of the changed (updated/deleted) assets.
    $asset_ids = $this->getAssetIds();
    if (!$asset_ids) {
      // Nothing to process.
      return 0;
    }

    // From the list of assets which have been updated in Acquia DAM, find the
    // ones which are used into Drupal as media entities.
    $total = 0;
    $media_ids = [];
    foreach ($asset_id_fields as $bundle => $field) {
      $media_query = $this->mediaStorage->getQuery();
      $media_ids_partial = $media_query
        ->accessCheck(FALSE)
        ->condition('bundle', $bundle)
        ->condition($field, $asset_ids, 'IN')
        ->execute();

      foreach ($media_ids_partial as $media_id) {
        $media_ids[] = $media_id;
      }
    }

    // Queue the media ids for later processing.
    foreach (array_unique($media_ids) as $media_id) {
      if ($this->queue->createItem(['media_id' => $media_id]) !== FALSE) {
        $total++;
      }
    }

    return $total;
  }

  /**
   * Returns the most recent media asset ids.
   *
   * Requests Assets Search API and gets the most recent asset ids available.
   *
   * @return array
   *   List of unique asset ids.
   */
  protected function getAssetIds(): array {
    $asset_ids = [];
    $page = 0;

    do {
      try {
        $page++;
        // Calculate the offset value as a number of previously processed items.
        $offset = $this->getRequestLimit() * ($page - 1);
        $last_sync = DrupalDateTime::createFromTimestamp($this->state->get('media_acquiadam.last_sync', 0), 'UTC');
        if ($this->config->get('transcode') === 'transcode') {
          // Updates to an asset can take one hour to become consistent across
          // the CDN. This ensures the CDN is correct by only processing assets
          // updated since our last sync, but not within the last hour.
          $cutoff = DrupalDateTime::createFromTimestamp($this->time->getCurrentTime(), 'UTC');
          $cutoff->modify('-1 hour');
          $last_sync->modify('-1 hour');
          // If the cut-off is before the last sync check, there is nothing to
          // query for.
          if ($cutoff < $last_sync) {
            return [];
          }
          $query = "(lastEditDate:[after {$last_sync->format('Y-m-d\TH:i:s\Z')}]) AND (lastEditDate:[before {$cutoff->format('Y-m-d\TH:i:s\Z')}])";
        }
        else {
          $query = "lastEditDate:[after {$last_sync->format('Y-m-d\TH:i:s\Z')}]";
        }

        $response = $this->acquiadam->searchAssets([
          'limit' => $this->getRequestLimit(),
          'offset' => $offset,
          'query' => $query,
          'include_deleted' => 'true',
          'include_archived' => 'true',
        ], FALSE);
      }
      catch (GuzzleException | InvalidCredentialsException $e) {
        $this->logger->error('Failed to fetch asset ids: @message.',
          ['@message' => $e->getMessage()]);
        return [];
      }

      foreach ($response['assets'] ?? [] as $asset) {
        $asset_ids[] = $asset->id;
      }

    } while (($response['total_count'] ?? 0) > $this->getRequestLimit() * $page);

    return $asset_ids;
  }

  /**
   * {@inheritdoc}
   */
  public function getRequestLimit(): int {
    return $this->requestLimit;
  }

  /**
   * {@inheritdoc}
   */
  public function setRequestLimit(int $newLimit = 100): int {
    $old_limit = $this->getRequestLimit();
    $this->requestLimit = max(1, $newLimit);
    return $old_limit;
  }

}

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

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