migrate_spip-1.0.0/modules/examples/src/Plugin/SpipRichText/OEmbed.php

modules/examples/src/Plugin/SpipRichText/OEmbed.php
<?php

declare(strict_types=1);

namespace Drupal\migrate_spip_examples\Plugin\SpipRichText;

use Drupal\Core\Database\Connection;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Drupal\Core\StringTranslation\TranslatableMarkup;
use Drupal\media\MediaInterface;
use Drupal\migrate_spip\Attribute\SpipRichText;
use Drupal\migrate_spip\SpipRichTextBase;
use Symfony\Component\DependencyInjection\ContainerInterface;

/**
 * Manage SPIP OEmbed plugin (based on version v3.0.3).
 *
 * Need to be executed before links.
 */
#[SpipRichText(
  id: 'plugin_oembed',
  label: new TranslatableMarkup('OEmbed plugin'),
  weight: -25,
)]
final class OEmbed extends SpipRichTextBase implements ContainerFactoryPluginInterface {

  /**
   * Default providers list.
   *
   * @see inc/oembed.php::oembed_lister_providers()
   *
   * @var array
   */
  private const PROVIDERS = [
    'http://*.youtube.com/watch*' => 'https://www.youtube.com/oembed',
    'http://*.youtube.com/playlist*' => 'https://www.youtube.com/oembed',
    'http://youtu.be/*' => 'https://www.youtube.com/oembed',
    'http://*.vimeo.com/*' => 'https://vimeo.com/api/oembed.json',
    'http://vimeo.com/*' => 'https://vimeo.com/api/oembed.json',
    'http://*.dailymotion.com/*' => 'https://www.dailymotion.com/services/oembed',
    'http://dai.ly/*' => 'https://www.dailymotion.com/services/oembed',
    'http://*.flickr.com/*' => 'https://www.flickr.com/services/oembed/',
    'http://flickr.com/*' => 'https://www.flickr.com/services/oembed/',
    'http://flic.kr/*' => 'https://www.flickr.com/services/oembed/',
    'http://soundcloud.com/*' => 'https://soundcloud.com/oembed',
    'http://mixcloud.com/*' => 'https://mixcloud.com/oembed',
    'http://*.soundcloud.com/*' => 'https://soundcloud.com/oembed',
    'http://*.mixcloud.com/*' => 'https://mixcloud.com/oembed',
    'http://*.slideshare.net/*/*' => 'https://www.slideshare.net/api/oembed/2',
    'http://www.slideshare.net/*/*' => 'https://www.slideshare.net/api/oembed/2',
    'http://huffduffer.com/*/*' => 'http://huffduffer.com/oembed',
    'http://nfb.ca/film/*' => 'http://www.nfb.ca/remote/services/oembed/',
    'http://dotsub.com/view/*' => 'http://dotsub.com/services/oembed',
    'http://clikthrough.com/theater/video/*' => 'http://clikthrough.com/services/oembed',
    'http://kinomap.com/*' => 'http://www.kinomap.com/oembed',
    'http://photobucket.com/albums/*' => 'http://api.photobucket.com/oembed',
    'http://photobucket.com/groups/*' => 'http://api.photobucket.com/oembed',
    'http://*.smugmug.com/*' => 'https://api.smugmug.com/services/oembed/',
    'http://meetup.com/*' => 'https://api.meetup.com/oembed',
    'http://meetup.ps/*' => 'http://api.meetup.com/oembed',
    'http://*.wordpress.com/*' => 'https://public-api.wordpress.com/oembed/1.0/',
    'http://twitter.com/*/status/*' => 'https://publish.twitter.com/oembed',
    'http://twitter.com/*/likes' => 'https://publish.twitter.com/oembed',
    'http://twitter.com/*/lists/*' => 'https://publish.twitter.com/oembed',
    'http://twitter.com/*/timelines/*' => 'https://publish.twitter.com/oembed',
    'http://twitter.com/i/moments/*' => 'https://publish.twitter.com/oembed',
    'http://techcrunch.com/*' => 'http://public-api.wordpress.com/oembed/1.0/',
    'http://wp.me/*' => 'http://public-api.wordpress.com/oembed/1.0/',
    'http://my.opera.com/*' => 'http://my.opera.com/service/oembed',
    'http://www.collegehumor.com/video/*' => 'http://www.collegehumor.com/oembed.json',
    'http://imgur.com/*' => 'http://api.imgur.com/oembed',
    'http://*.imgur.com/*' => 'http://api.imgur.com/oembed',
    'http://*.onf.ca/*' => 'http://www.onf.ca/remote/services/oembed/',
    'http://vine.co/v/*' => 'https://vine.co/oembed.json',
    'http://*.tumblr.com/post/*' => 'https://www.tumblr.com/oembed/1.0',
    'http://*.kickstarter.com/projects/*' => 'https://www.kickstarter.com/services/oembed',
    'http://speakerdeck.com/*' => 'https://speakerdeck.com/oembed.json',
    'http://issuu.com/*/docs/*' => 'https://issuu.com/oembed',
    'http://*.calameo.com/books/*' => 'https://www.calameo.com/services/oembed',
    'http://*.calameo.com/read/*' => 'https://www.calameo.com/services/oembed',
    'http://*.arte.tv/*/videos/*' => 'https://api.arte.tv/api/player/v1/oembed/',
    'http://egliseinfo.catholique.fr/*' => 'http://egliseinfo.catholique.fr/api/oembed',
    // 'https://gist.github.com/*' => 'http://github.com/api/oembed?format=json',
  ];

  /**
   * The database connection.
   *
   * @var \Drupal\Core\Database\Connection
   */
  protected Connection $connection;

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

  /**
   * {@inheritdoc}
   */
  public static function create(
    ContainerInterface $container,
    array $configuration,
    $plugin_id,
    $plugin_definition
  ): static {
    $instance = parent::create($container, $configuration, $plugin_id, $plugin_definition);

    $instance->connection = $container->get('database');
    $instance->entityTypeManager = $container->get('entity_type.manager');
    return $instance;
  }

  /**
   * {@inheritdoc}
   *
   * @SuppressWarnings(PHPMD.ElseExpression)
   */
  public function apply(string $text): string {
    // Search video URLs.
    if (!preg_match_all("#(?:^|\n)(https?://(?:[-\w\.]+[-\w])+(?::\d+)?(?:/(?:[\w/_\.\#-]*(?:\?\S+)?[^\.\s])?)?)(?:\n|$)#s", $text, $matches)) {
      return $text;
    }

    $mediaStorage = $this->entityTypeManager->getStorage('media');

    foreach ($matches[1] as $index => $match) {
      if (
        empty($match) ||
        !$this->isVideoProviderUrl($match)
      ) {
        continue;
      }

      $mediaIds = $mediaStorage->getQuery()
        ->condition('field_media_oembed_video', $match)
        ->accessCheck(FALSE)
        ->execute();

      if (!empty($mediaIds)) {
        /** @var \Drupal\media\MediaInterface|null $media */
        $media = $this->entityTypeManager->getStorage('media')
          ->load(reset($mediaIds));
      }
      else {
        /** @var \Drupal\media\MediaInterface|null $media */
        $media = $this->entityTypeManager->getStorage('media')
          ->create([
            'bundle' => 'video',
            'field_media_oembed_video' => [
              'value' => $match,
            ],
          ]);
        $media
          ->setName($this->getMediaName($media))
          ->setPublished()
          ->save();
      }

      if ($media) {
        $text = str_replace(
          $matches[0][$index],
          $this->getMediaTag($media),
          $text
        );
      }
    }

    return $text;
  }

  /**
   * Get media name.
   *
   * @param \Drupal\media\MediaInterface $media
   *   The media entity.
   *
   * @return string
   *   The media name.
   */
  private function getMediaName(MediaInterface $media): string {
    $defaultName = $media->getSource()->getMetadata($media, 'default_name');
    if ($defaultName) {
      return $defaultName;
    }

    return (string) $this->t('Video @url', [
      '@url' => $media->get('field_media_oembed_video')->value,
    ]);
  }

  /**
   * Get Drupal media HTML tag.
   *
   * @param \Drupal\media\MediaInterface $media
   *   The media entity.
   *
   * @return string
   *   The media HTML tag.
   */
  protected function getMediaTag(MediaInterface $media): string {
    return '<drupal-media data-entity-type="media" data-entity-uuid="' .
      $media->uuid() .
      '"></drupal-media>';
  }

  /**
   * Check if given URL is a video provider URL.
   *
   * @param string $url
   *   The given url.
   *
   * @return bool
   *   True if URL is a video provider URL, false otherwise.
   *
   * @see inc/oembeD.php::oembed_verifier_provider()
   */
  private function isVideoProviderUrl(string $url): bool {
    foreach (array_keys(self::PROVIDERS) as &$scheme) {
      $regex = '#' . str_replace('\*', '(.+)', preg_quote($scheme, '#')) . '#';
      $regex = preg_replace('|^#http\\\://|', '#https?\://', $regex);
      if (preg_match($regex, $url)) {
        return TRUE;
      }
    }
    return FALSE;
  }

}

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

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