acquia_dam-1.0.0-rc1/src/EmbedCodeFactory.php

src/EmbedCodeFactory.php
<?php

namespace Drupal\acquia_dam;

use Drupal\acquia_dam\Entity\ImageAltTextField;
use Drupal\acquia_dam\Entity\MediaSourceField;
use Drupal\acquia_dam\Plugin\Field\FieldType\AssetItem;
use Drupal\Core\Link;
use Drupal\Core\Security\TrustedCallbackInterface;
use Drupal\Core\Url;
use Drupal\media\MediaInterface;

/**
 * Create system specific embed codes.
 */
final class EmbedCodeFactory implements TrustedCallbackInterface {

  /**
   * Returns array containing select options for select render.
   *
   * @param string|null $asset_type
   *   Asset type.
   *
   * @return string[]
   *   Select options for given type or full mapping if asset type not provided.
   */
  public static function getSelectOptions(string $asset_type = NULL): array {
    // Generated url won't have the download option.
    // https://www.drupal.org/project/drupal/issues/2984272 Core issue where
    // "." in the query parameter gets replaced with "_" so the url with
    // "t.download=true" will be replaced with "t_download=true".
    $image_styles = [];
    /** @var \Drupal\acquia_dam\ImageStyleHelper $image_style_helper */
    $image_style_helper = \Drupal::service('acquia_dam.image_style_support');
    foreach ($image_style_helper->getAllowedImageStyles() as $styles) {
      $image_styles[$styles->id()] = $styles->label();
    }
    $image_styles = ['original' => 'Original'] + $image_styles;
    $mapping = [
      'pdf' => [
        'inline_view_download' => 'Inline viewer with download',
        'inline_view' => 'Inline viewer without download',
        'link_text_download' => 'Text linked to viewer with download',
        'link_text' => 'Text linked to viewer without download',
        'link_thumbnail_download' => 'Thumbnail linked to viewer with download',
        'link_thumbnail' => 'Thumbnail linked to viewer without download',
      ],
      'video' => [
        'inline_view_download' => 'Inline player with download',
        'inline_view' => 'Inline player without download',
        'link_thumbnail_download' => 'Thumbnail linked to player with download',
        'link_thumbnail' => 'Thumbnail linked to player without download',
        'video_stream' => 'Video without player',
      ],
      'spinset' => [
        'inline_view' => 'Inline viewer without download',
        'link_text' => 'Text linked to viewer without download',
      ],
      'image' => $image_styles,
      'documents' => [
        'inline_view_download' => 'Inline viewer with download',
        'link_text_download' => 'Text linked to viewer with download',
        'link_thumbnail_download' => 'Thumbnail linked to viewer with download',
        'link_thumbnail' => 'Thumbnail linked to viewer without download',
      ],
    ];

    return $asset_type ? $mapping[$asset_type] : $mapping;
  }

  /**
   * Returns a render array based on the parameters.
   *
   * @param string $format
   *   Embed code id for formatting.
   * @param \Drupal\media\MediaInterface $media
   *   Media instance.
   *
   * @return array
   *   Render array.
   */
  public static function renderAsset(string $format, MediaInterface $media): array {
    /** @var \Drupal\acquia_dam\Plugin\media\Source\Asset $source */
    $source = $media->getSource();
    $asset_field = $media->get(MediaSourceField::SOURCE_FIELD_NAME)->first();
    $external_id = $asset_field->external_id;

    // If we don't have the external_id saved locally, fetch it from the API.
    if (!$external_id) {
      $external_id = $source->getMetadata($media, 'external_id');
    }

    switch ($source->getDerivativeId()) {
      case 'documents':
      case 'pdf':
        $embed = self::renderDocumentsPdfAsset(self::getCdnDomain(), $external_id, $format, $media->getName(), self::encodeFilename($media->getName()));
        break;

      case 'video':
        $embed = self::renderVideoAsset(self::getCdnDomain(), $external_id, $format, $media->getName(), self::encodeFilename($media->getName()));
        break;

      case 'spinset':
        $embed = self::renderSpinsetAsset(self::getCdnDomain(), $external_id, $format, $media->getName(), self::encodeFilename($media->getName()));
        break;

      case 'image':
        assert($asset_field instanceof AssetItem);
        $image_properties = $source->getMetadata($media, 'image_properties');
        $alt_text = $media->get(ImageAltTextField::IMAGE_ALT_TEXT_FIELD_NAME)->value ?? $media->label();
        if ($format == 'original') {
          $embed = [
            '#theme' => 'image',
            '#uri' => "acquia-dam://$asset_field->asset_id/$asset_field->version_id",
            // @todo fetch alt from metadata for a proper value.
            '#alt' => $alt_text,
            '#width' => $image_properties['width'],
            '#height' => $image_properties['height'],
          ];
        }
        else {
          $embed = [
            '#theme' => 'image_style',
            '#uri' => "acquia-dam://$asset_field->asset_id/$asset_field->version_id.png",
            // @todo fetch alt from metadata for a proper value.
            '#alt' => $alt_text,
            '#width' => $image_properties['width'],
            '#style_name' => $format,
            '#height' => $image_properties['height'],
          ];
        }

        break;

      default:
        $embed = [];
    }

    return $embed;
  }

  /**
   * Returns a pdf/document asset render array based on the parameters.
   *
   * @param string $domain
   *   Domain.
   * @param string $external_id
   *   Asset external id.
   * @param string $format
   *   Embed code id for formatting.
   * @param string $filename
   *   Media name.
   * @param string $encoded_filename
   *   URL encoded filename.
   *
   * @return array
   *   Render array.
   */
  protected static function renderDocumentsPdfAsset(string $domain, string $external_id, string $format, string $filename, string $encoded_filename) :array {
    switch ($format) {
      case 'original':
        $url = "{$domain}/content/{$external_id}/original/{$encoded_filename}?download=true";
        $embed = self::renderAsLink($url, $filename);
        break;

      case 'inline_view_download':
        $embed = [
          '#type' => 'html_tag',
          '#tag' => 'iframe',
          '#attributes' => [
            'src' => "{$domain}/view/pdf/{$external_id}/{$encoded_filename}?t.download=true",
            'title' => "Document for $filename",
            'webkitallowfullscreen' => '',
            'mozallowfullscreen' => '',
            'allowfullscreen' => '',
          ],
        ];
        break;

      case 'inline_view':
        $embed = [
          '#type' => 'html_tag',
          '#tag' => 'iframe',
          '#attributes' => [
            'src' => "{$domain}/content/{$external_id}/pdf/{$encoded_filename}",
            'title' => "Document for $filename",
            'webkitallowfullscreen' => '',
            'mozallowfullscreen' => '',
            'allowfullscreen' => '',
          ],
        ];
        break;

      case 'link_text_download':
        $url = "{$domain}/view/pdf/{$external_id}/{$encoded_filename}?t.download=true";
        $embed = self::renderAsLink($url, $filename);
        break;

      case 'link_text':
        $url = "{$domain}/content/{$external_id}/pdf/{$encoded_filename}";
        $embed = self::renderAsLink($url, $filename);
        break;

      case 'link_thumbnail_download':
        $filename_without_extension = self::getFilenameWithoutExtension($encoded_filename);

        $asset_url = "{$domain}/view/pdf/{$external_id}/{$encoded_filename}?t.download=true";
        $thumbnail_url = "{$domain}/content/{$external_id}/jpeg/{$filename_without_extension}.jpg";

        $embed = self::renderAsThumbnailLink($asset_url, $thumbnail_url, $filename);
        break;

      case 'link_thumbnail':
        $filename_without_extension = self::getFilenameWithoutExtension($encoded_filename);

        $asset_url = "{$domain}/view/pdf/{$external_id}/{$filename}?t.download=true";
        $thumbnail_url = "{$domain}/content/{$external_id}/jpeg/{$filename_without_extension}.jpg";

        $embed = self::renderAsThumbnailLink($asset_url, $thumbnail_url, $filename);
        break;

      default:
        $embed = [];
    }

    return $embed;
  }

  /**
   * Returns a video asset render array based on the parameters.
   *
   * @param string $domain
   *   Domain.
   * @param string $external_id
   *   Asset external id.
   * @param string $format
   *   Embed code id for formatting.
   * @param string $filename
   *   Filename.
   * @param string $encoded_filename
   *   URL encoded filename.
   *
   * @return array
   *   Render array.
   */
  protected static function renderVideoAsset(string $domain, string $external_id, string $format, string $filename, string $encoded_filename): array {
    switch ($format) {
      case 'original':
        $url = "{$domain}/content/{$external_id}/original/{$encoded_filename}?download=true";
        $embed = self::renderAsLink($url, $filename);
        break;

      case 'inline_view_download':
        $embed = [
          '#theme' => 'acquia_dam_iframe_responsive',
          '#src' => "{$domain}/view/video/{$external_id}/{$encoded_filename}?t.download=true",
        ];
        break;

      case 'inline_view':
        $embed = [
          '#theme' => 'acquia_dam_iframe_responsive',
          '#src' => "{$domain}/view/video/{$external_id}/{$encoded_filename}",
        ];
        break;

      case 'link_thumbnail_download':
        $filename_without_extension = self::getFilenameWithoutExtension($encoded_filename);

        $asset_url = "{$domain}/view/video/{$external_id}/{$encoded_filename}?t.download=true";
        $thumbnail_url = "{$domain}/content/{$external_id}/jpeg/{$filename_without_extension}.jpg";

        $embed = self::renderAsThumbnailLink($asset_url, $thumbnail_url, $filename);
        break;

      case 'link_thumbnail':
        $filename_without_extension = self::getFilenameWithoutExtension($encoded_filename);

        $asset_url = "{$domain}/view/video/{$external_id}/{$encoded_filename}";
        $thumbnail_url = "{$domain}/content/{$external_id}/jpeg/{$filename_without_extension}.jpg";

        $embed = self::renderAsThumbnailLink($asset_url, $thumbnail_url, $filename);
        break;

      case 'video_stream':
        $embed = [
          '#theme' => 'acquia_dam_video_stream',
          '#attributes' => [
            "controls" => "controls",
          ],
          '#source_attributes' => [
            'src' => "{$domain}/content/{$external_id}/mp4/{$encoded_filename}?quality=hd",
            'video' => "video/mp4",
          ],
        ];
        break;

      default:
        $embed = [];
    }

    return $embed;
  }

  /**
   * Returns a spinset asset render array based on the parameters.
   *
   * @param string $domain
   *   Domain.
   * @param string $external_id
   *   Asset external id.
   * @param string $format
   *   Embed code id for formatting.
   * @param string $filename
   *   Filename.
   * @param string $encoded_filename
   *   URL encoded filename.
   *
   * @return array
   *   Render array.
   */
  protected static function renderSpinsetAsset(string $domain, string $external_id, string $format, string $filename, string $encoded_filename): array {
    switch ($format) {
      case 'original':
        $embed = [
          '#type' => 'markup',
          '#markup' => "{$domain}/content/{$external_id}/original/{$encoded_filename}?download=true",
        ];
        break;

      case 'inline_view':
        $embed = [
          '#theme' => 'acquia_dam_iframe_responsive',
          '#src' => "{$domain}/view/spinset/{$external_id}/{$encoded_filename}",
        ];
        break;

      case 'link_text':
        $url = "{$domain}/view/spinset/{$external_id}/{$encoded_filename}";
        $embed = self::renderAsLink($url, $filename);
        break;

      default:
        $embed = [];
    }

    return $embed;
  }

  /**
   * Returns link pointing to the given asset embed.
   *
   * @param string $url
   *   Link url.
   * @param string $asset_name
   *   Asset name as link name.
   *
   * @return array
   *   Render array.
   */
  protected static function renderAsLink(string $url, string $asset_name): array {
    $link = Link::fromTextAndUrl($asset_name, Url::fromUri($url, ['attributes' => ['target' => '_blank']]));
    $render_array = $link->toRenderable();
    $render_array['#post_render'] = [[static::class, 'postRenderDamLink']];
    return $render_array;
  }

  /**
   * Returns thumbnail as a link.
   *
   * @param string $url
   *   Asset url.
   * @param string $thumbnail_url
   *   Thumbnail url.
   * @param string $name
   *   File name.
   *
   * @return array
   *   Render array.
   */
  protected static function renderAsThumbnailLink(string $url, string $thumbnail_url, string $name): array {
    $link_title = [
      '#theme' => 'image',
      '#width' => 300,
      '#height' => 300,
      '#uri' => $thumbnail_url,
      '#alt' => sprintf('%s preview', $name),
    ];

    return [
      '#type' => 'container',
      '#theme_wrappers' => ['container__acquia_dam_asset'],
      'embed' => [
        '#type' => 'link',
        '#title' => $link_title,
        '#url' => Url::fromUri($url, ['attributes' => ['target' => '_blank']]),
        '#post_render' => [[static::class, 'postRenderDamLink']],
      ],
    ];
  }

  /**
   * Replace t_download within the markup with the correct key.
   *
   * @param string $markup
   *   Link markup generated for embed code.
   *
   * @return string
   *   Markup.
   */
  public static function postRenderDamLink(string $markup) {
    if (!str_contains($markup, 't_download')) {
      return $markup;
    }

    return str_replace('t_download', 't.download', $markup);
  }

  /**
   * {@inheritdoc}
   */
  public static function trustedCallbacks() {
    return ['postRenderDamLink'];
  }

  /**
   * Get Acquia CDN domain.
   */
  private static function getCdnDomain() {
    static $domain;
    if ($domain === NULL) {
      $acquia_dam_domain = \Drupal::configFactory()->get('acquia_dam.settings')->get('domain');
      $subdomain = explode('.', $acquia_dam_domain)[0];

      $domain = "https://{$subdomain}.widen.net";
    }
    return $domain;
  }

  /**
   * Replaces certain characters in the filename so it matches the DAM ones.
   *
   * @param string $filename
   *   Media name.
   *
   * @return string
   *   Returns filename.
   */
  private static function encodeFilename(string $filename) {
    return str_replace(
      [' ', "'", '"'],
      ['-', '', ''],
      $filename
    );
  }

  /**
   * Gets a filename without the extension.
   *
   * @param string $filename
   *   Media name.
   *
   * @return string
   *   Returns filename without the extension.
   */
  private static function getFilenameWithoutExtension(string $filename) {
    $filename_without_extension = pathinfo($filename, PATHINFO_FILENAME);
    $filename_without_extension = urlencode($filename_without_extension);

    return $filename_without_extension;
  }

}

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

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