acquia_dam-1.0.0-rc1/src/Plugin/QueueWorker/AssetUpdateChecker.php
src/Plugin/QueueWorker/AssetUpdateChecker.php
<?php namespace Drupal\acquia_dam\Plugin\QueueWorker; use Drupal\acquia_dam\Client\AcquiaDamClientFactory; use Drupal\acquia_dam\Entity\MediaExpiryDateField; use Drupal\acquia_dam\Event\NewAssetVersionEvent; use Drupal\Component\Datetime\TimeInterface; use Drupal\Core\Cache\CacheTagsInvalidatorInterface; use Drupal\Core\Entity\EntityTypeManagerInterface; use Drupal\Core\Logger\LoggerChannelInterface; use Drupal\Core\Plugin\ContainerFactoryPluginInterface; use Symfony\Component\DependencyInjection\ContainerInterface; use Symfony\Component\EventDispatcher\EventDispatcherInterface; /** * Updates Acquia DAM assets. * * @QueueWorker ( * id = "acquia_dam_asset_update", * title = @Translation("Acquia DAM Asset Update Checker"), * cron = {"time" = 30} * ) */ class AssetUpdateChecker extends AssetQueueWorkerBase implements ContainerFactoryPluginInterface { /** * Drupal entity type manager service. * * @var \Drupal\Core\Entity\EntityTypeManagerInterface */ protected $entityTypeManager; /** * Drupal logger channel service. * * @var \Drupal\Core\Logger\LoggerChannelInterface */ protected $loggerChannel; /** * The Acquia Dam client factory. * * @var \Drupal\acquia_dam\Client\AcquiaDamClientFactory */ protected $clientFactory; /** * Time interface. * * @var \Drupal\Component\Datetime\TimeInterface */ protected $time; /** * Cache tag invalidator service. * * @var \Drupal\Core\Cache\CacheTagsInvalidatorInterface */ protected $cacheTagInvalidator; /** * The event dispatcher. * * @var \Symfony\Component\EventDispatcher\EventDispatcherInterface */ private $eventDispatcher; /** * {@inheritdoc} */ public function __construct(array $configuration, $plugin_id, $plugin_definition, LoggerChannelInterface $loggerChannel, EntityTypeManagerInterface $entityTypeManager, AcquiaDamClientFactory $clientFactory, TimeInterface $time, CacheTagsInvalidatorInterface $cacheTagInvalidator, EventDispatcherInterface $event_dispatcher) { parent::__construct($configuration, $plugin_id, $plugin_definition); $this->loggerChannel = $loggerChannel; $this->entityTypeManager = $entityTypeManager; $this->clientFactory = $clientFactory; $this->time = $time; $this->cacheTagInvalidator = $cacheTagInvalidator; $this->eventDispatcher = $event_dispatcher; } /** * {@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('acquia_dam.update_assets'), $container->get('entity_type.manager'), $container->get('acquia_dam.client.factory'), $container->get('datetime.time'), $container->get('cache_tags.invalidator'), $container->get('event_dispatcher') ); } /** * {@inheritdoc} */ public function processItem($data) { if (empty($data['asset_id'] || empty($data['media_id']))) { return FALSE; } // Deleting the asset cache. $this->cacheTagInvalidator->invalidateTags(["acquia-dam-asset:{$data['asset_id']}"]); try { $client = $this->clientFactory->getSiteClient(); $version_list = $client->getAssetVersionList($data['asset_id']); $asset_data = $client->getAsset($data['asset_id']); } catch (\Exception $exception) { $this->loggerChannel->warning('Cannot get asset version list from API. Asset id: %asset_id, error: %message', [ '%asset_id' => $data['asset_id'], '%message' => $exception->getMessage(), ] ); $this->processException($exception); } $media_storage = $this->entityTypeManager->getStorage('media'); /** @var \Drupal\media\MediaInterface $media */ $media = $media_storage->load($data['media_id']); if (!$media) { $this->loggerChannel->warning('Media item (id: %media_id) associated with Dam asset (asset id: %asset_id) has been deleted.', [ '%asset_id' => $data['asset_id'], '%media_id' => $data['media_id'], ]); return TRUE; } $revision_id = $media->getRevisionId(); $current_version = $media->get('acquia_dam_asset_id')->first()->getValue(); // We can assume, that the latest version is the last item of the array. $up_to_date_version = $this->getLatestVersion($version_list['versions']); if (!$up_to_date_version) { $this->loggerChannel->warning('Cannot find finalised version for asset (%asset_id)', [ '%asset_id' => $current_version['asset_id'], ]); return TRUE; } // If the current version in Drupal does not match the version we get from // the API, then update the version id for the given entity. if ($current_version['version_id'] !== $up_to_date_version) { $current_version['version_id'] = $up_to_date_version; $media->setNewRevision(); // Ensure the thumbnail is also updated. $media ->set('acquia_dam_asset_id', $current_version); } // Not all asset have an expiration date. if ($asset_data['security']['expiration_date']) { $date = \DateTime::createFromFormat(\DateTimeInterface::ISO8601, $asset_data['security']['expiration_date']); $media->set(MediaExpiryDateField::EXPIRY_DATE_FIELD_NAME, $date->getTimestamp()); } // Still update the thumbnail. $media->updateQueuedThumbnail(); $media->setChangedTime($this->time->getCurrentTime()); $media->save(); // We have to dispatch this event after saving the media item, so that the // media system has been able to re-sync field mappings. if ($revision_id !== $media->getRevisionId()) { try { $this->eventDispatcher->dispatch(new NewAssetVersionEvent( $media, // We do not use the original media object or clone it to prevent side // effects after saving a new revision from that object. $media_storage->loadRevision($revision_id) )); } catch (\Throwable $exception) { // Do nothing if an event subscriber causes an exception or error.The // media has already been saved. } } return TRUE; } /** * Gets the uuid of the last edited version. * * @param array $version_list * Versions array of asset versions endpoint response. * * @return string * Latest version's uuid. */ protected function getLatestVersion(array $version_list): string { usort($version_list, function ($a, $b) { return $a['dateLastEdited'] <=> $b['dateLastEdited']; }); return end($version_list)['uuid']; } }