cloudinary-8.x-1.x-dev/modules/cloudinary_sdk/src/Service/CloudinaryAssetHelper.php

modules/cloudinary_sdk/src/Service/CloudinaryAssetHelper.php
<?php

namespace Drupal\cloudinary_sdk\Service;

use Cloudinary\Api\ApiResponse;
use Cloudinary\Asset\AssetType;
use Cloudinary\Asset\Image;
use Cloudinary\Asset\Video;
use Cloudinary\Cloudinary;
use Cloudinary\Configuration\Configuration;
use Cloudinary\Tag\BaseTag;
use Cloudinary\Transformation\Resize;
use Drupal\cloudinary_media_library_widget\Model\Asset;
use Symfony\Component\Serializer\Serializer;

/**
 * Define a service to work with custom value from cloudinary form element.
 */
class CloudinaryAssetHelper implements AssetHelperInterface {

  /**
   * The serializer service.
   *
   * @var \Symfony\Component\Serializer\Serializer
   */
  protected Serializer $serializer;

  /**
   * Constructs a service object.
   *
   * @param \Symfony\Component\Serializer\Serializer $serializer
   *   The serializer service.
   */
  public function __construct(Serializer $serializer) {
    $this->serializer = $serializer;
  }

  /**
   * Get instance of cloudinary API.
   *
   * @return \Cloudinary\Cloudinary
   *   The cloudinary API.
   */
  public static function cloudinary() {
    return new Cloudinary(Configuration::instance());
  }

  /**
   * {@inheritdoc}
   */
  public function generatePreviewImageUrl(string $value, int $width = 400): ?string {
    $asset = $this->getBaseMediaAsset($value);

    // No preview available if base media asset is not found.
    if (!$asset) {
      return NULL;
    }

    $info = $this->parseValue($value);

    // Force small size of the thumbnail to increase performance.
    $asset->resize(Resize::fill()->width($width));

    // Apply only custom transformation for the preview image.
    // Applying default transformation does not make sense.
    if ($info['transformation']) {
      $asset->addTransformation($info['transformation']);
    }

    // Force extension to support PDF thumbnails.
    $asset->extension('jpeg');

    return (string) $asset->toUrl();
  }

  /**
   * {@inheritdoc}
   */
  public function renderAsset(string $value): ?array {
    try {
      $info = $this->parseValue($value);
    }
    catch (\Exception $e) {
      // Nothing to render here.
      return NULL;
    }

    switch ($info['resource_type']) {
      case AssetType::IMAGE:
        return $this->renderImage($info);

      case AssetType::VIDEO:
        return $this->renderVideo($info);
    }

    // Nothing to render.
    return NULL;
  }

  /**
   * Render image asset in Drupal way.
   *
   * @param array $info
   *   The parsed value from the form element.
   *
   * @return array
   *   Renderable array with image element build.
   */
  protected function renderImage(array $info): array {
    return [
      '#type' => 'cloudinary_image',
      '#public_id' => $info['public_id'],
      '#delivery_type' => $info['delivery_type'],
      '#raw_transformation' => $info['transformation'] ?? '',
    ];
  }

  /**
   * Render video asset in Drupal way.
   *
   * @param array $info
   *   The parsed value from the form element.
   *
   * @return array
   *   Renderable array with video element build.
   */
  protected function renderVideo(array $info): array {
    return [
      '#type' => 'cloudinary_video',
      '#public_id' => $info['public_id'],
      '#delivery_type' => $info['delivery_type'],
      '#raw_transformation' => $info['transformation'] ?? '',
    ];
  }

  /**
   * {@inheritdoc}
   */
  public function isApplicable(string $value): bool {
    return preg_match('/^cloudinary:(image|video|raw):(upload|private|authenticated):([^:]*)(:(.+))?$/', $value) > 0;
  }

  /**
   * {@inheritdoc}
   */
  public function parseValue(string $value): array {
    if (!$this->isApplicable($value)) {
      throw new \Exception('Could not parse the value.');
    }

    preg_match('/^cloudinary:(image|video|raw):(upload|private|authenticated):([^:]*)(:(.+))?$/', $value, $matches);
    [, $resource_type, $delivery_type, $public_id,, $transformation] = array_pad($matches, 6, NULL);

    return [
      'type' => 'cloudinary',
      'resource_type' => $resource_type,
      'delivery_type' => $delivery_type,
      'public_id' => $public_id,
      'transformation' => $transformation ?? '',
    ];
  }

  /**
   * {@inheritdoc}
   */
  public function getBaseTag(string $value): ?BaseTag {
    try {
      $info = $this->parseValue($value);
    }
    catch (\Exception $e) {
      // Nothing to render here.
      return NULL;
    }

    switch ($info['resource_type']) {
      case AssetType::IMAGE:
        return static::cloudinary()->imageTag($info['public_id']);

      case AssetType::VIDEO:
        return static::cloudinary()->videoTag($info['public_id']);
    }

    // Nothing to render.
    return NULL;
  }

  /**
   * {@inheritdoc}
   */
  public function generateStringValue(array $value): string {
    if (!isset($value['resource_type']) || !isset($value['delivery_type']) || !isset($value['public_id'])) {
      throw new \Exception('Some fields are missing from the field value.');
    }

    return implode(':', array_filter([
      'cloudinary',
      $value['resource_type'],
      $value['delivery_type'],
      $value['public_id'],
      $value['transformation'] ?? NULL,
    ]));
  }

  /**
   * {@inheritdoc}
   */
  public function loadAssetByPublicId(string $public_id, string $resource_type = AssetType::IMAGE): Asset {
    $asset_data = static::cloudinary()->adminApi()->asset($public_id, [
      AssetType::KEY => $resource_type,
    ]);
    assert($asset_data instanceof ApiResponse);

    $asset = $this->serializer->denormalize($asset_data, Asset::class);

    assert($asset instanceof Asset);

    return $asset;
  }

  /**
   * {@inheritdoc}
   */
  public function getBaseMediaAsset(string $value): Video|Image|NULL {
    $info = $this->parseValue($value);
    $asset = NULL;

    switch ($info['resource_type']) {
      case AssetType::IMAGE:
        $asset = static::cloudinary()->image($info['public_id']);
        break;

      case AssetType::VIDEO:
        $asset = static::cloudinary()->video($info['public_id']);
        break;
    }

    if (!$asset) {
      return NULL;
    }

    $asset->deliveryType($info['delivery_type']);

    return $asset;
  }

}

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

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