media_acquiadam-8.x-1.46/src/Plugin/QueueWorker/AssetRefresh.php

src/Plugin/QueueWorker/AssetRefresh.php
<?php

namespace Drupal\media_acquiadam\Plugin\QueueWorker;

use Drupal\Component\Datetime\TimeInterface;
use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Drupal\Core\Queue\DelayedRequeueException;
use Drupal\Core\Queue\QueueWorkerBase;
use Drupal\Core\Queue\RequeueException;
use Drupal\Core\Queue\SuspendQueueException;
use Drupal\media\MediaInterface;
use Drupal\media_acquiadam\Service\AssetMediaFactory;
use GuzzleHttp\Exception\ClientException;
use GuzzleHttp\Exception\ConnectException;
use GuzzleHttp\Exception\ServerException;
use Psr\Log\LoggerInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;

/**
 * Updates Acquia DAM assets.
 *
 * To reduce duplicate queue items, install `queue_unique` and register this
 * queue worker.
 *
 * @link https://www.drupal.org/project/queue_unique
 *
 * @QueueWorker (
 *   id = "media_acquiadam_asset_refresh",
 *   title = @Translation("Acquia DAM Asset Refresh"),
 *   cron = {"time" = 30}
 * )
 */
class AssetRefresh extends QueueWorkerBase implements ContainerFactoryPluginInterface {

  /**
   * Drupal logger channel service.
   *
   * @var \Psr\Log\LoggerInterface
   */
  protected $loggerChannel;

  /**
   * Drupal entity type manager service.
   *
   * @var \Drupal\Core\Entity\EntityTypeManagerInterface
   */
  protected $entityTypeManager;

  /**
   * Acquia DAM Asset Media Factory service.
   *
   * @var \Drupal\media_acquiadam\Service\AssetMediaFactory
   */
  protected $assetMediaFactory;

  /**
   * The config factory service.
   *
   * @var \Drupal\Core\Config\ConfigFactoryInterface
   */
  protected $configFactory;

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

  /**
   * {@inheritdoc}
   */
  public function __construct(array $configuration, $plugin_id, $plugin_definition, LoggerInterface $loggerChannel, EntityTypeManagerInterface $entityTypeManager, AssetMediaFactory $assetMediaFactory, ConfigFactoryInterface $config_factory, TimeInterface $time) {
    parent::__construct($configuration, $plugin_id, $plugin_definition);
    $this->loggerChannel = $loggerChannel;
    $this->entityTypeManager = $entityTypeManager;
    $this->assetMediaFactory = $assetMediaFactory;
    $this->configFactory = $config_factory;
    $this->time = $time;
  }

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

  /**
   * {@inheritdoc}
   *
   * @return bool
   *   TRUE if a media entity was updated successfully, FALSE - otherwise.
   *
   * @phpstan-param array{media_id: string} $data
   */
  public function processItem($data) {
    if (empty($data['media_id'])) {
      return FALSE;
    }

    $entity = $this->entityTypeManager->getStorage('media')->load(
      $data['media_id']
    );
    if (!$entity instanceof MediaInterface) {
      $this->loggerChannel->error(
        'Unable to load media entity @media_id in order to refresh the associated asset. Was the media entity deleted within Drupal?',
        ['@media_id' => $data['media_id']]
      );
      return FALSE;
    }

    $wrapped_media = $this->assetMediaFactory->get($entity);
    $assetID = $wrapped_media->getAssetId();
    if (empty($assetID)) {
      $this->loggerChannel->error(
        'Unable to load asset ID from media entity @media_id. This might mean that the DAM and Drupal relationship has been broken. Please check the media entity.',
        ['@media_id' => $data['media_id']]
      );
      return FALSE;
    }
    try {
      $asset = $wrapped_media->getAsset();
    }
    catch (ServerException $exception) {
      // If there is a server exception, suspend the queue.
      throw new SuspendQueueException(
        $exception->getMessage(),
        $exception->getCode(),
        $exception
      );
    }
    catch (ConnectException $exception) {
      throw new SuspendQueueException(
        'Could not create connection to DAM, possible local network issue',
        $exception->getCode(),
        $exception
      );
    }
    catch (ClientException $exception) {
      $response = $exception->getResponse();
      if ($response === NULL) {
        throw new RequeueException();
      }
      if ($response->getStatusCode() === 401) {
        throw new SuspendQueueException('Unable to process queue due to authorization errors', 401, $exception);
      }
      // If 404 response, the asset has been removed. Allow processing to
      // determine if it should be deleted.
      if ($response->getStatusCode() === 404) {
        $asset = NULL;
      }
      elseif ($response->getStatusCode() === 408) {
        throw new DelayedRequeueException(60, 'Timed out loading asset, trying again later.', 408, $exception);
      }
      else {
        // Try again for unknown 4xx responses.
        throw new RequeueException();
      }
    }
    catch (\Exception $x) {
      $this->loggerChannel->error(
        'Error trying to check asset from media entity @media_id',
        ['@media_id' => $data['media_id']]
      );
      return FALSE;
    }

    // If the asset is expired/deleted in Acquia DAM and is unpublished in
    // Drupal, we delete it.
    $perform_delete = $this->configFactory->get('media_acquiadam.settings')->get('sync_perform_delete');
    if (($asset === NULL || !$asset->released_and_not_expired) && $perform_delete && !$entity->isPublished()) {
      $entity->delete();
      $this->loggerChannel->warning(
        'Deleted media entity @media_id with asset id @assetID.',
        [
          '@media_id' => $data['media_id'],
          '@assetID' => $assetID,
        ]
      );
      return TRUE;
    }

    // If the asset is expired/deleted in Acquia DAM but is published in
    // Drupal, we log it because we can't delete it.
    if ($asset !== NULL && !$asset->released_and_not_expired && $entity->isPublished()) {
      $this->loggerChannel->warning(
        'Unable to delete media entity @media_id because it is published. This warning will continue to appear until the media entity has been deleted or unpublished.',
        [
          '@media_id' => $data['media_id'],
        ]
      );
    }

    // If the asset does not exist anymore in Acquia DAM, log the information
    // for visibility.
    if ($asset === NULL) {
      $this->loggerChannel->warning(
        'Unable to update media entity @media_id with information from asset @assetID because the asset was missing. This warning will continue to appear until the media entity has been deleted.',
        [
          '@media_id' => $data['media_id'],
          '@assetID' => $assetID,
        ]
      );
      return FALSE;
    }

    try {
      // Re-save the entity, prompting the clearing and redownloading of
      // metadata and asset file. We always modify the changed time to help
      // indicate the last time this media entity had a refresh performed.
      $entity->setChangedTime($this->time->getCurrentTime());
      $entity->save();
    }
    catch (\Exception $x) {
      // Something within `media_acquiadam_media_presave` caused a failure that
      // we cannot detect. Provide verbose logging and let its lock expire
      // before re-processing.
      $this->loggerChannel->error(
        'Error when saving media to sync data with DAM for media entity @media_id and asset ID @asset_id. Leaving in queue for retry.

%exception_type: %error',
        [
          '@media_id' => $data['media_id'],
          '@asset_id' => $assetID,
          '%exception_type' => get_class($x),
          '%error' => $x->getMessage(),
        ]
      );
      return FALSE;
    }

    return TRUE;
  }

}

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

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