media_mpx-8.x-1.x-dev/src/Plugin/media/Source/MediaSourceBase.php

src/Plugin/media/Source/MediaSourceBase.php
<?php

namespace Drupal\media_mpx\Plugin\media\Source;

use Drupal\Core\File\FileSystemInterface;
use Drupal\media\MediaSourceBase as DrupalMediaSourceBase;
use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Core\Entity\EntityFieldManagerInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Field\FieldTypePluginManagerInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Messenger\MessengerTrait;
use Drupal\media\MediaInterface;
use Drupal\media_mpx\DataObjectFactoryCreator;
use Drupal\media_mpx\Entity\Account;
use Drupal\media_mpx\MpxLogger;
use GuzzleHttp\ClientInterface;
use GuzzleHttp\Psr7\Uri;
use Lullabot\Mpx\DataService\CachingPhpDocExtractor;
use Lullabot\Mpx\DataService\CustomFieldManager;
use Lullabot\Mpx\DataService\DateTime\DateTimeFormatInterface;
use Lullabot\Mpx\DataService\Media\Media;
use Lullabot\Mpx\DataService\ObjectInterface;
use Psr\Log\LoggerInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\PropertyInfo\Extractor\ReflectionExtractor;
use Symfony\Component\PropertyInfo\PropertyInfoExtractor;
use Symfony\Component\PropertyInfo\PropertyInfoExtractorInterface;

/**
 * Base class for mpx media sources.
 */
abstract class MediaSourceBase extends DrupalMediaSourceBase implements MpxMediaSourceInterface {
  use MessengerTrait;

  /**
   * The service to load mpx data.
   *
   * @var \Drupal\media_mpx\DataObjectFactoryCreator
   */
  protected $dataObjectFactoryCreator;

  /**
   * The http client used to download thumbnails.
   *
   * @var \GuzzleHttp\ClientInterface
   */
  protected $httpClient;

  /**
   * The logger used to log HTTP errors downloading thumbnails.
   *
   * @var \Psr\Log\LoggerInterface
   */
  protected $logger;

  /**
   * The manager used to load custom field implementations.
   *
   * @var \Lullabot\Mpx\DataService\CustomFieldManager
   */
  protected $customFieldManager;

  /**
   * The logger used for mpx-specific errors.
   *
   * @var \Drupal\media_mpx\MpxLogger
   */
  protected $mpxLogger;

  /**
   * The path to the thumbnails directory.
   *
   * Normally this would be a class constant, but file_prepare_directory()
   * requires the string to be passed by reference.
   *
   * @var string
   */
  protected $thumbnailsDirectory = 'public://media_mpx/thumbnails/';

  /**
   * The file system.
   *
   * @var \Drupal\Core\File\FileSystemInterface
   */
  private $fileSystem;

  /**
   * Media constructor.
   *
   * @param array $configuration
   *   A configuration array containing information about the plugin instance.
   * @param string $plugin_id
   *   The plugin_id for the plugin instance.
   * @param mixed $plugin_definition
   *   The plugin implementation definition.
   * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
   *   Entity type manager service.
   * @param \Drupal\Core\Entity\EntityFieldManagerInterface $entity_field_manager
   *   Entity field manager service.
   * @param \Drupal\Core\Field\FieldTypePluginManagerInterface $field_type_manager
   *   The field type plugin manager service.
   * @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory
   *   The config factory service.
   * @param \Drupal\media_mpx\DataObjectFactoryCreator $dataObjectFactory
   *   The service to load mpx data.
   * @param \GuzzleHttp\ClientInterface $httpClient
   *   The HTTP client used to download thumbnails.
   * @param \Psr\Log\LoggerInterface $logger
   *   The logger used to log errors while downloading thumbnails.
   * @param \Lullabot\Mpx\DataService\CustomFieldManager $customFieldManager
   *   The manager used to load custom field classes.
   * @param \Drupal\Core\File\FileSystemInterface $fileSystem
   *   The file system.
   *
   * @todo Refactor this constructor to reduce the number of parameters.
   */
  public function __construct(array $configuration, string $plugin_id, $plugin_definition, EntityTypeManagerInterface $entity_type_manager, EntityFieldManagerInterface $entity_field_manager, FieldTypePluginManagerInterface $field_type_manager, ConfigFactoryInterface $config_factory, DataObjectFactoryCreator $dataObjectFactory, ClientInterface $httpClient, LoggerInterface $logger, CustomFieldManager $customFieldManager, FileSystemInterface $fileSystem) {
    parent::__construct($configuration, $plugin_id, $plugin_definition, $entity_type_manager, $entity_field_manager, $field_type_manager, $config_factory);
    $this->dataObjectFactoryCreator = $dataObjectFactory;
    $this->httpClient = $httpClient;
    $this->logger = $logger;
    $this->customFieldManager = $customFieldManager;

    $this->mpxLogger = new MpxLogger($logger);
    $this->fileSystem = $fileSystem;
  }

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
    return new static(
      $configuration,
      $plugin_id,
      $plugin_definition,
      $container->get('entity_type.manager'),
      $container->get('entity_field.manager'),
      $container->get('plugin.manager.field.field_type'),
      $container->get('config.factory'),
      $container->get('media_mpx.data_object_factory_creator'),
      $container->get('http_client'),
      $container->get('logger.channel.media_mpx'),
      $container->get('media_mpx.custom_field_manager'),
      $container->get('file_system')
    );
  }

  /**
   * {@inheritdoc}
   */
  public function defaultConfiguration() {
    return parent::defaultConfiguration() + [
      'account' => NULL,
    ];
  }

  /**
   * {@inheritdoc}
   */
  public function calculateDependencies() {
    return parent::calculateDependencies() + [
      'config' => [
        'media_mpx.media_mpx_account.' . $this->getConfiguration()['account'],
      ],
    ];
  }

  /**
   * {@inheritdoc}
   */
  public function buildConfigurationForm(array $form, FormStateInterface $form_state) {
    $form = parent::buildConfigurationForm($form, $form_state);
    $accounts = $this->entityTypeManager->getStorage('media_mpx_account')
      ->loadMultiple();

    if (empty($accounts)) {
      // @todo the #ajax callback isn't showing this, core bug?
      $this->messenger()
        ->addError($this->t('Create an account before configuring an mpx media type.'));
      return $form;
    }

    $options = [];
    foreach ($accounts as $account) {
      $options[$account->id()] = $this->t('@title', [
        '@title' => $account->label(),
      ]);
    }

    $form['account'] = [
      '#type' => 'select',
      '#title' => $this->t('mpx account'),
      '#description' => $this->t('Select the mpx account to associate with this media type.'),
      '#default_value' => $this->getConfiguration()['account'],
      '#options' => $options,
      '#required' => TRUE,
    ];

    return $form;
  }

  /**
   * Return the mpx account used for this media type.
   *
   * @return \Drupal\media_mpx\Entity\Account
   *   The mpx account.
   */
  public function getAccount(): Account {
    $id = $this->getConfiguration()['account'];
    /** @var \Drupal\media_mpx\Entity\Account $account */
    $account = $this->entityTypeManager->getStorage('media_mpx_account')
      ->load($id);
    return $account;
  }

  /**
   * Get the complete mpx object associated with a media entity.
   *
   * @param \Drupal\media\MediaInterface $media
   *   The media entity.
   *
   * @return \Lullabot\Mpx\DataService\ObjectInterface
   *   The mpx object.
   */
  public function getMpxObject(MediaInterface $media): ObjectInterface {
    $id = $media->get($this->configuration['source_field'])->getString();
    $factory = $this->dataObjectFactoryCreator->fromMediaSource($this);

    return $factory->load(new Uri($id))->wait();
  }

  /**
   * Return a property extractor.
   *
   * @return \Symfony\Component\PropertyInfo\PropertyInfoExtractorInterface
   *   An array of property values and their descriptions.
   */
  protected function propertyExtractor(): PropertyInfoExtractorInterface {
    $phpDocExtractor = new CachingPhpDocExtractor();
    $reflectionExtractor = new ReflectionExtractor();

    $listExtractors = [$reflectionExtractor];

    $typeExtractors = [$phpDocExtractor, $reflectionExtractor];

    $descriptionExtractors = [$phpDocExtractor];

    $accessExtractors = [$reflectionExtractor];

    $propertyInfo = new PropertyInfoExtractor(
      $listExtractors,
      $typeExtractors,
      $descriptionExtractors,
      $accessExtractors
    );
    return $propertyInfo;
  }

  /**
   * Call a get method on the mpx media object and return it's value.
   *
   * @param \Drupal\media\MediaInterface $media
   *   The media entity being accessed.
   * @param string $attribute_name
   *   The metadata attribute being accessed.
   * @param object $mpx_object
   *   The mpx object to get the property on.
   *
   * @return mixed|null
   *   Metadata attribute value or NULL if unavailable.
   */
  protected function getReflectedProperty(MediaInterface $media, string $attribute_name, $mpx_object) {
    $method = 'get' . ucfirst($attribute_name);
    $value = $mpx_object->$method();

    if ($value instanceof \DateTime || $value instanceof DateTimeFormatInterface) {
      // @todo Remove this when https://bravotv.atlassian.net/browse/BR-6856
      // is fixed.
      $value = $value->format('U');
    }

    return $value;
  }

  /**
   * Download a thumbnail to the local file system.
   *
   * @param \Lullabot\Mpx\DataService\Media\Media $mpx_media
   *   The mpx media object to download the thumbnail for.
   *
   * @return string
   *   The existing thumbnail, or the newly downloaded thumbnail.
   */
  protected function downloadThumbnail(Media $mpx_media): string {
    $thumbnailUrl = $mpx_media->getNormalizedDefaultThumbnailUrl();
    $local_uri = $this->thumbnailsDirectory . $thumbnailUrl->getHost() . $thumbnailUrl->getPath();
    if (!file_exists($local_uri)) {
      $directory = dirname($local_uri);
      $this->fileSystem->prepareDirectory($directory, FileSystemInterface::CREATE_DIRECTORY);
      $thumbnail = $this->httpClient->request('GET', $thumbnailUrl);
      $this->fileSystem->saveData((string) $thumbnail->getBody(), $local_uri);
    }

    return $local_uri;
  }

  /**
   * Return the alt tag for a thumbnail.
   *
   * While mpx has support for thumbnail descriptions, in practice they do not
   * look to be filled with useful text. Instead, we default to using the media
   * label, and if that is not available we fall back to the media title.
   *
   * @param \Drupal\media\MediaInterface $media
   *   The media entity being processed.
   *
   * @return string
   *   The thumbnail alt text.
   */
  protected function thumbnailAlt(MediaInterface $media) {
    /** @var \Lullabot\Mpx\DataService\Media\Media $mpx_media */
    $mpx_media = $this->getMpxObject($media);
    if (!empty($media->label())) {
      return $media->label();
    }
    return $mpx_media->getTitle();
  }

}

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

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