webdam-1.0.x-dev/src/WebdamService.php

src/WebdamService.php
<?php

namespace Drupal\webdam;

use Drupal\webdam\Plugin\Field\FieldType\WebdamMetadataItem;
use Drupal\webdam\Plugin\media\Source\Webdam;
use Drupal\Component\Datetime\TimeInterface;
use Drupal\Component\Serialization\Json;
use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Extension\ModuleHandlerInterface;
use Drupal\Core\Logger\LoggerChannelFactoryInterface;
use Drupal\Core\State\StateInterface;
use GuzzleHttp\Exception\ClientException;

/**
 * WebDAM service.
 */
class WebdamService implements WebdamServiceInterface {

  /**
   * The state metadata update ID key.
   */
  const METADATA_UPDATE_ID_KEY = 'webdam.metadata_update_id';

  /**
   * The state metadata timestamp key.
   */
  const METADATA_UPDATE_TIMESTAMP_KEY = 'webdam.metadata_update_timestamp';

  /**
   * The default maximum number of items to process in one run.
   */
  const MAX_ITEMS = 100;

  /**
   * The WebDAM Connector.
   *
   * @var \Drupal\webdam\WebdamConnector
   */
  protected $webdamConnector;

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

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

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

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

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

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

  /**
   * The module handler.
   *
   * @var \Drupal\Core\Extension\ModuleHandlerInterface
   */
  protected $moduleHandler;

  /**
   * WebdamMetadataService constructor.
   *
   * @param \Drupal\webdam\WebdamConnector $webdam_connector
   *   The WebDAM connector.
   * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
   *   The entity type manager service.
   * @param \Drupal\Core\Logger\LoggerChannelFactoryInterface $logger_factory
   *   Logger factory.
   * @param \Drupal\Core\State\StateInterface $state
   *   The state service.
   * @param \Drupal\Component\Datetime\TimeInterface $time
   *   The time service.
   * @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory
   *   Config factory.
   * @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
   *   The module handler.
   */
  public function __construct(WebdamConnector $webdam_connector, EntityTypeManagerInterface $entity_type_manager, LoggerChannelFactoryInterface $logger_factory, StateInterface $state, TimeInterface $time, ConfigFactoryInterface $config_factory, ModuleHandlerInterface $module_handler = NULL) {
    $this->webdamConnector = $webdam_connector;
    $this->entityTypeManager = $entity_type_manager;
    $this->logger = $logger_factory->get('webdam');
    $this->state = $state;
    $this->time = $time;
    $this->configFactory = $config_factory;
    $this->mediaStorage = $entity_type_manager->getStorage('media');
    $this->moduleHandler = $module_handler ?: \Drupal::service('module_handler');
  }

  /**
   * {@inheritdoc}
   */
  public function getWebdamMediaTypes() {
    $webdam_media_types = [];
    /** @var \Drupal\media\MediaTypeInterface $media_type */
    foreach ($this->entityTypeManager->getStorage('media_type')->loadMultiple() as $media_type_id => $media_type) {
      if ($media_type->getSource() instanceof Webdam) {
        $webdam_media_types[$media_type_id] = $media_type;
      }
    }

    return $webdam_media_types;
  }

  /**
   * {@inheritdoc}
   */
  public function getTotalCountOfMediaEntities() {
    $webdam_media_types = $this->getWebdamMediaTypes();
    if (empty($webdam_media_types)) {
      return 0;
    }

    $count = $this->mediaStorage
      ->getQuery()
      ->condition($this->mediaStorage->getEntityType()->getKey('bundle'), array_keys($webdam_media_types), 'IN')
      ->accessCheck(FALSE)
      ->count()
      ->execute();

    return (int) $count;
  }

  /**
   * {@inheritdoc}
   */
  public function updateLocalMetadataCron() {
    // Get the update frequency value in seconds. In case it is empty or set to
    // zero, do not do any updates.
    $update_frequency = (int) $this->configFactory->get('webdam.settings')->get('update_frequency');
    if ($update_frequency === 0) {
      return;
    }

    // Only run updates if the last completed update was more than the
    // configured amount of time ago.
    $last_update = $this->state->get(static::METADATA_UPDATE_TIMESTAMP_KEY);
    $request_time = $this->time->getRequestTime();
    if ($last_update && $request_time - $last_update < $update_frequency) {
      return;
    }

    $results = $this->updateMetadataLastMediaEntities($this->state->get(static::METADATA_UPDATE_ID_KEY));

    // There are no WebDAM media types, Webdam media entities to update or we
    // are processing the latest chunk.
    if (empty($results) || $results['total'] < static::MAX_ITEMS) {
      $this->state->set(static::METADATA_UPDATE_TIMESTAMP_KEY, $request_time);
      $this->state->delete(static::METADATA_UPDATE_ID_KEY);
      return;
    }

    // Update the maximum update ID with a new maximum ID.
    $this->state->set(static::METADATA_UPDATE_ID_KEY, $results['max_id']);
  }

  /**
   * {@inheritdoc}
   */
  public function updateMetadataLastMediaEntities($minimum_id = NULL, $limit = WebdamService::MAX_ITEMS) {
    $webdam_media_types = $this->getWebdamMediaTypes();
    if (empty($webdam_media_types)) {
      return [];
    }

    $entity_id_key = $this->mediaStorage->getEntityType()->getKey('id');

    // Get the Webdam media entity IDs.
    $query = $this->mediaStorage->getQuery()
      ->accessCheck(FALSE)
      ->condition($this->mediaStorage->getEntityType()->getKey('bundle'), array_keys($webdam_media_types), 'IN')
      ->sort($entity_id_key)
      ->range(0, $limit);

    if ($minimum_id) {
      $query->condition($entity_id_key, $minimum_id, '>');
    }

    $media_ids = $query->execute();

    /** @var \Drupal\media\MediaInterface[] $media_entities */
    $media_entities = $this->mediaStorage->loadMultiple($media_ids);

    $webdam_media_entities = [];

    // Get the remote media UUIDs.
    foreach ($media_entities as $media_entity) {
      if ($remote_uuid = $media_entity->getSource()->getSourceFieldValue($media_entity)) {
        $webdam_media_entities[$remote_uuid] = $media_entity;
      }
    }

    // No media entities to process.
    if (empty($webdam_media_entities)) {
      return [];
    }

    $updated_entities = $this->updateMediaEntities($webdam_media_entities);

    $missing_remote_entities = [];
    // Log warning in case a media entity has been removed in the remote system.
    foreach ($webdam_media_entities as $missing_remote_entity) {
      $missing_remote_entities[$missing_remote_entity->id()] = $missing_remote_entity;

      $this->logger->warning('The media entity (ID: @id, Remote UUID: @remote_uuid) has been removed from the remote system.', [
        '@id' => $missing_remote_entity->id(),
        '@remote_uuid' => $missing_remote_entity->getSource()->getSourceFieldValue($missing_remote_entity),
      ]);
    }

    return [
      'updated' => $updated_entities,
      'skipped' => $missing_remote_entities,
      'total' => count($media_ids),
      'max_id' => max($media_ids),
    ];
  }

  /**
   * {@inheritdoc}
   */
  public function updateMediaEntities(array &$webdam_media_entities) {
    $updated_entities = [];
    foreach ($webdam_media_entities as $id => $media_entity) {
      try {
        $item = $this->webdamConnector
          ->getMetadataGraphQL($id);
      }
      catch (ClientException $e) {
        $this->logger->error($e->getMessage());
        continue;
      }

      /** @var \Drupal\webdam\Plugin\media\Source\Webdam $source */
      $source = $media_entity->getSource();
      $remote_metadata = $source->filterRemoteMetadata($item);

      $has_changed = FALSE;
      if ($source->hasMetadataChanged($media_entity, $remote_metadata)) {
        $media_entity->set(WebdamMetadataItem::METADATA_FIELD_NAME, Json::encode($remote_metadata));
        $has_changed = TRUE;
      }

      // Allow other modules to alter the media entity.
      $this->moduleHandler->alter('webdam_media_update', $media_entity, $item, $has_changed);

      if ($has_changed) {
        $media_entity->save();
      }

      $updated_entities[$media_entity->id()] = $media_entity;

      // Remove the processed item.
      unset($webdam_media_entities[$item['id']]);
    }
    return $updated_entities;
  }

}

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

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