View source
<?php
namespace Drupal\media_acquiadam\Service;
use cweagans\webdam\Exception\InvalidCredentialsException;
use Drupal\Component\Datetime\TimeInterface;
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 GuzzleHttp\Exception\GuzzleException;
use Symfony\Component\DependencyInjection\ContainerInterface;
class AssetRefreshManager implements AssetRefreshManagerInterface, ContainerInjectionInterface {
protected $acquiadam;
protected $state;
protected $logger;
protected $queue;
protected $mediaStorage;
protected $time;
protected $requestLimit = 250;
protected $lastReadInterval = 43200;
protected function getActionsToTrack() : array {
return [
'asset_version',
'asset_property',
'asset_delete',
];
}
protected function getItemsTypesToTrack() : array {
return [
'asset',
'video',
'image',
'document',
'audio',
];
}
public function __construct(AcquiadamInterface $acquiadam, StateInterface $state, LoggerChannelFactoryInterface $logger_factory, QueueFactory $queue_factory, EntityTypeManagerInterface $entity_type_manager, 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->time = $time;
}
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('datetime.time'));
}
public function getQueueName() : string {
return 'media_acquiadam_asset_refresh';
}
public function updateQueue(array $asset_id_fields) {
if (empty($asset_id_fields)) {
$this
->saveStartTime($this
->getEndTime());
return 0;
}
$asset_ids = $this
->getAssetIds();
if (!$asset_ids) {
return 0;
}
$total = 0;
$media_query = $this->mediaStorage
->getQuery();
foreach ($asset_id_fields as $bundle => $field) {
$media_query
->condition($media_query
->orConditionGroup()
->condition('bundle', $bundle)
->condition($field, $asset_ids, 'IN'));
}
$media_ids = $media_query
->execute();
foreach ($media_ids as $media_id) {
$this->queue
->createItem([
'media_id' => $media_id,
]);
$total++;
}
return $total;
}
protected function getAssetIds() : array {
try {
$page = $this
->getNextPage() ? $this
->getNextPage() : 1;
$offset = $this
->getRequestLimit() * ($page - 1);
$response = $this->acquiadam
->getNotifications([
'limit' => $this
->getRequestLimit(),
'offset' => $offset,
'starttime' => $this
->getStartTime(),
'endtime' => $this
->getEndTime(),
]);
} catch (GuzzleException|InvalidCredentialsException $e) {
$this->logger
->error('Failed to fetch asset ids: @message.', [
'@message' => $e
->getMessage(),
]);
return [];
}
if (empty($response['notifications'])) {
$continue_fetch = FALSE;
$asset_ids = [];
}
else {
$continue_fetch = $response['total'] > $this
->getRequestLimit() * $page;
$asset_ids = $this
->extractAssetIds($response['notifications']);
}
if ($continue_fetch) {
$this
->saveNextPage(++$page);
$this
->saveEndTime($this
->getEndTime());
return $asset_ids;
}
$this
->saveStartTime($this
->getEndTime());
$this
->resetEndTime();
$this
->resetNextPage();
return $asset_ids;
}
public function getRequestLimit() : int {
return $this->requestLimit;
}
public function setRequestLimit(int $newLimit = 250) : int {
$old_limit = $this
->getRequestLimit();
$this->requestLimit = max(1, $newLimit);
return $old_limit;
}
public function getLastReadInterval() : int {
return $this->lastReadInterval;
}
public function setLastReadInterval(int $lastReadInterval = 43200) : int {
$old_interval = $this
->getLastReadInterval();
$this->lastReadInterval = max(1, $lastReadInterval);
return $old_interval;
}
protected function extractAssetIds(array $notifications) : array {
$asset_ids = [];
foreach ($notifications as $item) {
if (!in_array($item['action'], $this
->getActionsToTrack(), TRUE)) {
continue;
}
if (isset($item['source']['type']) && in_array($item['source']['type'], $this
->getItemsTypesToTrack(), TRUE)) {
$asset_ids[] = $item['source']['id'];
}
if (!isset($item['subitems']) || !is_array($item['subitems'])) {
continue;
}
foreach ($item['subitems'] as $subitem) {
if (!isset($subitem['type'], $subitem['id'])) {
continue;
}
if (!in_array($subitem['type'], $this
->getItemsTypesToTrack(), TRUE)) {
continue;
}
if (in_array($subitem['id'], $asset_ids)) {
continue;
}
$asset_ids[] = $subitem['id'];
}
}
return array_unique($asset_ids);
}
protected function getStartTime() : int {
$start_time_timestamp = $this->state
->get('media_acquiadam.notifications_starttime');
if ($start_time_timestamp) {
return $start_time_timestamp;
}
$default_start_time_timestamp = $this->time
->getRequestTime() - $this
->getLastReadInterval();
$this
->saveStartTime($default_start_time_timestamp);
return $default_start_time_timestamp;
}
protected function saveStartTime(int $timestamp) {
$this->state
->set('media_acquiadam.notifications_starttime', $timestamp);
}
protected function getEndTime() : ?int {
return $this->state
->get('media_acquiadam.notifications_endtime', $this->time
->getRequestTime());
}
protected function saveEndTime(int $timestamp) {
if ($this->state
->get('media_acquiadam.notifications_endtime')) {
return;
}
$this->state
->set('media_acquiadam.notifications_endtime', $timestamp);
}
protected function resetEndTime() {
$this->state
->set('media_acquiadam.notifications_endtime', NULL);
}
protected function getNextPage() : ?int {
return $this->state
->get('media_acquiadam.notifications_next_page');
}
protected function saveNextPage(int $page) {
$this->state
->set('media_acquiadam.notifications_next_page', $page);
}
protected function resetNextPage() {
$this->state
->set('media_acquiadam.notifications_next_page', NULL);
}
}