cloudflare_stream-8.x-1.0/src/Plugin/Field/FieldType/CloudflareVideoItem.php

src/Plugin/Field/FieldType/CloudflareVideoItem.php
<?php

namespace Drupal\cloudflare_stream\Plugin\Field\FieldType;

use Drupal\cloudflare_stream\Service\CloudflareStreamApiInterface;
use Drupal\cloudflare_stream\Service\CloudflareStreamInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Field\FieldStorageDefinitionInterface;
use Drupal\Core\File\FileSystemInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\TempStore\PrivateTempStore;
use Drupal\Core\TypedData\DataDefinition;
use Drupal\Core\TypedData\TraversableTypedDataInterface;
use Drupal\file\Entity\File;
use Drupal\file\FileUsage\FileUsageInterface;
use Drupal\file\Plugin\Field\FieldType\FileItem;

/**
 * Plugin implementation of the 'cloudflareVideo' field type.
 *
 * @FieldType(
 *   id = "cloudflarevideo",
 *   label = @Translation("Cloudflare Video"),
 *   description = @Translation("This field stores the ID of an cloudflare video."),
 *   category = @Translation("Cloudflare"),
 *   default_widget = "cloudflarevideo_default",
 *   default_formatter = "cloudflarevideo_default",
 *   list_class = "\Drupal\file\Plugin\Field\FieldType\FileFieldItemList",
 *   constraints = {"ReferenceAccess" = {}, "FileValidation" = {}}
 * )
 */
class CloudflareVideoItem extends FileItem {

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

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

  /**
   * The Cloudflare Stream service.
   *
   * @var \Drupal\cloudflare_stream\Service\CloudflareStreamInterface
   */
  protected CloudflareStreamInterface $cloudflareStream;

  /**
   * The Cloudflare Stream API service.
   *
   * @var \Drupal\cloudflare_stream\Service\CloudflareStreamApiInterface
   */
  protected CloudflareStreamApiInterface $cloudflareStreamApi;

  /**
   * The file usage service.
   *
   * @var \Drupal\file\FileUsage\FileUsageInterface
   */
  protected FileUsageInterface $fileUsage;

  /**
   * Key-value store to hold video ID for our field widget.
   */
  protected PrivateTempStore $tempStore;

  /**
   * {@inheritdoc}
   */
  public static function createInstance($definition, $name = NULL, TraversableTypedDataInterface $parent = NULL) {
    // @todo refactor when https://www.drupal.org/project/drupal/issues/3294266
    // is resolved.
    $instance = parent::createInstance($definition, $name, $parent);
    $instance->entityTypeManager = \Drupal::service('entity_type.manager');
    $instance->fileSystem = \Drupal::service('file_system');
    $instance->fileUsage = \Drupal::service('file.usage');
    $instance->cloudflareStream = \Drupal::service('cloudflare_stream');
    $instance->cloudflareStreamApi = \Drupal::service('cloudflare_stream.api');
    $factory = \Drupal::service('tempstore.private');
    $instance->tempStore = $factory->get('cloudflare_stream');
    return $instance;
  }

  /**
   * {@inheritdoc}
   */
  public static function defaultStorageSettings() {
    $default = parent::defaultStorageSettings();
    $default['uri_scheme'] = 'cfstream';
    return $default;
  }

  /**
   * {@inheritdoc}
   */
  public function storageSettingsForm(array &$form, FormStateInterface $form_state, $has_data) {
    $element = parent::storageSettingsForm($form, $form_state, $has_data);
    $settings = self::defaultStorageSettings();
    $element['uri_scheme'] = [
      '#type' => 'item',
      '#title' => $this->t('Upload destination'),
      '#default_value' => $settings['uri_scheme'],
      '#description' => $this->t('Cloudflare Video fields always use CloudflareStream storage.'),
    ];
    return $element;
  }

  /**
   * {@inheritdoc}
   */
  public static function defaultFieldSettings() {
    $fieldSettings = parent::defaultFieldSettings();
    $cloudflareStream = \Drupal::service('cloudflare_stream');
    $fieldSettings['file_extensions'] = $cloudflareStream->listAllowedFileExtensions();
    $fieldSettings['file_directory'] = '';
    return $fieldSettings;
  }

  /**
   * {@inheritdoc}
   */
  public static function schema(FieldStorageDefinitionInterface $field_definition) {
    $schema = parent::schema($field_definition);
    $schema['columns']['cloudflareStreamVideoID'] = [
      'type' => 'text',
      'length' => 512,
      'not null' => FALSE,
    ];
    $schema['columns']['thumbnail'] = [
      'type' => 'text',
      'length' => 512,
      'not null' => FALSE,
    ];

    return $schema;
  }

  /**
   * {@inheritdoc}
   */
  public function fieldSettingsForm(array $form, FormStateInterface $form_state) {
    $form = parent::fieldSettingsForm($form, $form_state);

    $form['file_extensions']['#description'] = $this->t('Separate extensions with a space or comma and do not include the leading dot.<br>Cloudflare Stream supports following extensions: MP4, MKV, MOV, AVI, FLV, MPEG-2 TS, MPEG-2 PS, MXF, LXF, GXF, 3GP, WebM, MPG, QuickTime');
    // Directory is not supported.
    unset($form['file_directory']);
    return $form;
  }

  /**
   * {@inheritdoc}
   */
  public static function propertyDefinitions(FieldStorageDefinitionInterface $field_definition) {
    $properties = parent::propertyDefinitions($field_definition);

    $properties['cloudflareStreamVideoID'] = DataDefinition::create('string')
      ->setLabel(t('Cloudflare Video ID'));
    $properties['thumbnail'] = DataDefinition::create('string')
      ->setLabel(t('Cloudflare Video thumbnail'));
    return $properties;
  }

  /**
   * {@inheritdoc}
   */
  public function preSave(): void {
    $entity = $this->getEntity();
    if (is_null($this->getValue()['cloudflareStreamVideoID'])) {
      $fileID = $this->get('target_id')->getValue();
      $file = $this->entityTypeManager->getStorage('file')->load($fileID);
      if ($file instanceof File) {
        $videoId = $this->tempStore->get($file->getFileUri());
        $details = $this->cloudflareStreamApi->getDetails($videoId);

        if (isset($videoId)) {
          $oldVideoId = $this->getOldVideoId($entity, $this->name);
          if (isset($oldVideoId)) {
            $this->cloudflareStreamApi->deleteVideo($oldVideoId);
          }
          $this->setValue(
            [
              'target_id' => $this->getValue()['target_id'],
              'display' => $this->getValue()['display'],
              'description' => $this->getValue()['description'],
              'cloudflareStreamVideoID' => $videoId,
              'thumbnail' => $details['thumbnail'],
            ]
          );
          $scheme = parse_url($file->getFileUri(), PHP_URL_SCHEME);
          $file->setFileUri("$scheme://$videoId");
          $this->fileUsage->add($file, 'cloudflare_stream', 'cloudflarevideo', \Drupal::currentUser()->id());
          $file->setPermanent();
          $file->save();
        }
      }
    }
    else {
      $fieldName = $this->getParent()->getName();
      $newFieldData = $this->getEntity()->get($fieldName)->getValue();
      $originalFieldData = $entity->get($fieldName)->getValue();
      $videoIds = array_filter($this->getRemovedIds($originalFieldData, $newFieldData), function ($element) {
        if ($element !== NULL) {
          return $element;
        }
      });

      foreach ($videoIds as $videoId) {
        $this->cloudflareStreamApi->deleteVideo($videoId);
      }
    }
  }

  /**
   * Return the old video ID.
   */
  protected function getOldVideoId($entity, $delta) {
    $oldVideoID = NULL;
    if ($entity) {
      $fieldName = $this->getParent()->getName();
      $oldVideoID = $entity->get($fieldName)->getValue()[$delta]['cloudflareStreamVideoID'] ? $entity->get($fieldName)->getValue()[$delta]['cloudflareStreamVideoID'] : NULL;
    }
    return $oldVideoID;
  }

  /**
   * Get the removed video IDs from cloudflare stream.
   *
   * @param array $originalFieldData
   *   Contains the original video data.
   * @param array $newFieldData
   *   Contains the new video data.
   *
   * @return array
   *   The removed video IDs.
   */
  protected function getRemovedIds(array $originalFieldData, array $newFieldData) {
    $removedIds = [];
    foreach ($originalFieldData as $key => $originalFieldDatum) {
      foreach ($newFieldData as $newFieldDatum) {
        if ($originalFieldDatum['cloudflareStreamVideoID'] === $newFieldDatum['cloudflareStreamVideoID']) {
          $removedIds[$key] = NULL;
          break;
        }
        $removedIds[$key] = $originalFieldDatum['cloudflareStreamVideoID'];
      }
    }

    return $removedIds;
  }

  /**
   * {@inheritdoc}
   */
  public function delete() {
    $this->cloudflareStreamApi->deleteVideo($this->getValue()['cloudflareStreamVideoID']);
  }

}

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

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