canto-1.0.x-dev/src/Plugin/media/Source/CantodamAsset.php

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

namespace Drupal\canto\Plugin\media\Source;

use Drupal\Component\Serialization\Json;
use Drupal\Core\Form\FormStateInterface;
use Drupal\file\FileInterface;
use Drupal\media\MediaInterface;
use Drupal\media\MediaSourceBase;

/**
 * Provides media type plugin for DAM assets.
 *
 * @MediaSource(
 *   id = "cantodam_asset",
 *   label = @Translation("Canto DAM asset"),
 *   description = @Translation("Provides business logic and metadata for
 *   assets stored on Canto DAM."),
 *   allowed_field_types = {"string", "json_native"},
 *   default_thumbnail_filename = "no-thumbnail.png",
 * )
 */
class CantodamAsset extends MediaSourceBase {

  const METADATA_FIELD_NAME = 'field_cantodam_asset_metadata';

  /**
   * The media entity that is being wrapped.
   *
   * @var \Drupal\media\MediaInterface
   */
  protected $mediaEntity;

  /**
   * Statically cached metadata information for the given assets.
   *
   * @var array
   */
  protected $metadata;

  /**
   * {@inheritdoc}
   */
  public function buildConfigurationForm(array $form, FormStateInterface $form_state) {
    // Fieldset with configuration options not needed.
    hide($form);
    return $form;
  }

  /**
   * {@inheritdoc}
   */
  public function defaultConfiguration() {
    return [
      'source_field' => 'field_cantodam_asset_id',
      'metadata_field' => CantodamAsset::METADATA_FIELD_NAME,
    ];
  }

  /**
   * {@inheritdoc}
   */
  public function submitConfigurationForm(array &$form, FormStateInterface $form_state) {
    $submitted_config = array_intersect_key(
      $form_state->getValues(),
      $this->configuration
    );
    foreach ($submitted_config as $config_key => $config_value) {
      $this->configuration[$config_key] = $config_value;
    }

    // For consistency, always use the default source_field field name.
    $default_field_name = $this->defaultConfiguration()['source_field'];
    // Check if it already exists so it can be used as a shared field.
    $storage = $this->entityTypeManager->getStorage('field_storage_config');
    $existing_source_field = $storage->load('media.' . $default_field_name);

    // Set or create the source field.
    if ($existing_source_field) {
      // If the default field already exists, return the default field name.
      $this->configuration['source_field'] = $default_field_name;
    }
    else {
      // Default source field name does not exist, so create a new one.
      $field_storage = $this->createSourceFieldStorage();
      $field_storage->save();
      $this->configuration['source_field'] = $field_storage->getName();
    }

    $metadata_field_name = $this->defaultConfiguration()['metadata_field'];
    // Check if it already exists so it can be used as a shared field.
    $existing_metadata_field = $storage->load('media.' . $metadata_field_name);

    // Set or create the source field.
    if ($existing_metadata_field) {
      // If the default field already exists, return the default field name.
      $this->configuration['metadata_field'] = $metadata_field_name;
    }
    else {
      // Default source field name does not exist, so create a new one.
      $metadata_field_storage = $this->createMetadataFieldStorage();
      $metadata_field_storage->save();
      $this->configuration['metadata_field'] = $metadata_field_storage->getName();
    }
  }

  /**
   * {@inheritdoc}
   *
   * @todo fix with appropriate canto fields.
   */
  public function getMetadataAttributes() {
    $fields = [
      'file' => $this->t('file'),
      'metadata' => $this->t('Metadata'),
      'uuid' => $this->t('ID'),
      'name' => $this->t('Name'),
      'description' => $this->t('Description'),
      'approval_status' => $this->t('Approval Status'),
      'tags' => $this->t('Tags'),
      'scheme' => $this->t('Type'),
      'smart_tags' => $this->t('Smart Tags'),
      'thumbnail_urls' => $this->t('Thumbnail urls'),
      'width' => $this->t('Width'),
      'height' => $this->t('Height'),
      'created' => $this->t('Date created'),
      'modified' => $this->t('Data modified'),
    ];

    return $fields;
  }

  /**
   * {@inheritdoc}
   */
  protected function createMetaDataFieldStorage() {
    $default_field_name = $this->defaultConfiguration()['metadata_field'];
    // Create the field.
    return $this->entityTypeManager->getStorage('field_storage_config')->create(
      [
        'entity_type' => 'media',
        'field_name' => $default_field_name,
        'type' => next($this->pluginDefinition['allowed_field_types']),
      ]
    );
  }

  /**
   * {@inheritdoc}
   */
  protected function createSourceFieldStorage() {
    $default_field_name = $this->defaultConfiguration()['source_field'];
    // Create the field.
    return $this->entityTypeManager->getStorage('field_storage_config')->create(
      [
        'entity_type' => 'media',
        'field_name' => $default_field_name,
        'type' => reset($this->pluginDefinition['allowed_field_types']),
      ]
    );
  }

  /**
   * Ensures the given media entity has Canto metadata information in place.
   *
   * @param \Drupal\media\MediaInterface $media
   *   The media entity.
   *
   * @return bool
   *   TRUE if the metadata is ensured. Otherwise, FALSE.
   *
   * @todo add the method.
   */
  public function ensureMetadata(MediaInterface $media) {
    if (!$media->hasField(CantodamAsset::METADATA_FIELD_NAME)) {
      \Drupal::logger('canto')
        ->error('The media type @type must have a canto metadata field named "canto_metadata".', [
          '@type' => $media->bundle(),
        ]);
      return FALSE;
    }
    $mediaId = $this->getSourceFieldValue($media);
    $metadata = Json::decode($media->get(CantodamAsset::METADATA_FIELD_NAME)->value);
    if (is_array($metadata)) {
      $this->metadata[$mediaId] = $metadata;
    }
    return TRUE;
  }

  /**
   * {@inheritDoc}
   */
  public function getMetadata(MediaInterface $media, $name) {
    if (!$this->ensureMetadata($media)) {
      throw new \RuntimeException('Metadata field not found.');
    }
    $field = $this->getAssetFileField($media);
    $file = $media->get($field)->entity;
    $id = $this->getSourceFieldValue($media);
    // If the source field is not required, it may be empty.
    if (!$file) {
      return parent::getMetadata($media, $name);
    }
    switch ($name) {
      case 'default_name':
        return parent::getMetadata($media, 'default_name');

      case 'file':
        $is_file = !empty($file) && $file instanceof FileInterface;
        return $is_file ? $file->id() : NULL;

      case 'thumbnail_uri':
        return $file->getFileUri();

      default:
        $default = $this->metadata[$id]['detailData'][$name] ?? FALSE;
        return $default ?: parent::getMetadata($media, $name);

    }
  }

  /**
   * Gets the file field being used to store the asset.
   *
   * @param \Drupal\media\MediaInterface $media
   *   The media entity.
   *
   * @return false|string
   *   The name of the file field on the media bundle or FALSE on failure.
   */
  protected function getAssetFileField(MediaInterface $media) {
    try {
      /** @var \Drupal\media\Entity\MediaType $bundle */
      $bundle = $this->entityTypeManager->getStorage('media_type')
        ->load($media->bundle());
      $field_map = !empty($bundle) ? $bundle->getFieldMap() : FALSE;
    }
    catch (\Exception $exception) {
      watchdog_exception('error', $exception->getMessage());
      return FALSE;
    }
    return empty($field_map['file']) ? FALSE : $field_map['file'];
  }

  /**
   * Gets the value of a field without knowing the key to use.
   *
   * @param \Drupal\media\MediaInterface $media
   *   The media entity.
   * @param string $fieldName
   *   The field name.
   *
   * @return null|mixed
   *   The field value or NULL.
   */
  protected function getFieldPropertyValue(MediaInterface $media, $fieldName) {
    if ($media->hasField($fieldName)) {
      /** @var \Drupal\Core\Field\FieldItemInterface $item */
      $item = $media->{$fieldName}->first();
      if (!empty($item)) {
        $property_name = $item->mainPropertyName();
        if (isset($media->{$fieldName}->{$property_name})) {
          return $media->{$fieldName}->{$property_name};
        }
      }
    }
    return NULL;
  }

}

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

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