Updated Drupal to 8.6. This goes with the following updates because it's possible...
[yaffs-website] / web / core / modules / media / src / Plugin / Field / FieldFormatter / OEmbedFormatter.php
diff --git a/web/core/modules/media/src/Plugin/Field/FieldFormatter/OEmbedFormatter.php b/web/core/modules/media/src/Plugin/Field/FieldFormatter/OEmbedFormatter.php
new file mode 100644 (file)
index 0000000..443df18
--- /dev/null
@@ -0,0 +1,303 @@
+<?php
+
+namespace Drupal\media\Plugin\Field\FieldFormatter;
+
+use Drupal\Core\Cache\CacheableMetadata;
+use Drupal\Core\Config\ConfigFactoryInterface;
+use Drupal\Core\Field\FieldDefinitionInterface;
+use Drupal\Core\Field\FieldItemListInterface;
+use Drupal\Core\Field\FormatterBase;
+use Drupal\Core\Form\FormStateInterface;
+use Drupal\Core\Logger\LoggerChannelFactoryInterface;
+use Drupal\Core\Messenger\MessengerInterface;
+use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
+use Drupal\Core\Url;
+use Drupal\media\Entity\MediaType;
+use Drupal\media\IFrameUrlHelper;
+use Drupal\media\OEmbed\Resource;
+use Drupal\media\OEmbed\ResourceException;
+use Drupal\media\OEmbed\ResourceFetcherInterface;
+use Drupal\media\OEmbed\UrlResolverInterface;
+use Drupal\media\Plugin\media\Source\OEmbedInterface;
+use Symfony\Component\DependencyInjection\ContainerInterface;
+
+/**
+ * Plugin implementation of the 'oembed' formatter.
+ *
+ * @internal
+ *   This is an internal part of the oEmbed system and should only be used by
+ *   oEmbed-related code in Drupal core.
+ *
+ * @FieldFormatter(
+ *   id = "oembed",
+ *   label = @Translation("oEmbed content"),
+ *   field_types = {
+ *     "link",
+ *     "string",
+ *     "string_long",
+ *   },
+ * )
+ */
+class OEmbedFormatter extends FormatterBase implements ContainerFactoryPluginInterface {
+
+  /**
+   * The messenger service.
+   *
+   * @var \Drupal\Core\Messenger\MessengerInterface
+   */
+  protected $messenger;
+
+  /**
+   * The oEmbed resource fetcher.
+   *
+   * @var \Drupal\media\OEmbed\ResourceFetcherInterface
+   */
+  protected $resourceFetcher;
+
+  /**
+   * The oEmbed URL resolver service.
+   *
+   * @var \Drupal\media\OEmbed\UrlResolverInterface
+   */
+  protected $urlResolver;
+
+  /**
+   * The logger service.
+   *
+   * @var \Psr\Log\LoggerInterface
+   */
+  protected $logger;
+
+  /**
+   * The media settings config.
+   *
+   * @var \Drupal\Core\Config\ImmutableConfig
+   */
+  protected $config;
+
+  /**
+   * The iFrame URL helper service.
+   *
+   * @var \Drupal\media\IFrameUrlHelper
+   */
+  protected $iFrameUrlHelper;
+
+  /**
+   * Constructs an OEmbedFormatter instance.
+   *
+   * @param string $plugin_id
+   *   The plugin ID for the formatter.
+   * @param mixed $plugin_definition
+   *   The plugin implementation definition.
+   * @param \Drupal\Core\Field\FieldDefinitionInterface $field_definition
+   *   The definition of the field to which the formatter is associated.
+   * @param array $settings
+   *   The formatter settings.
+   * @param string $label
+   *   The formatter label display setting.
+   * @param string $view_mode
+   *   The view mode.
+   * @param array $third_party_settings
+   *   Any third party settings.
+   * @param \Drupal\Core\Messenger\MessengerInterface $messenger
+   *   The messenger service.
+   * @param \Drupal\media\OEmbed\ResourceFetcherInterface $resource_fetcher
+   *   The oEmbed resource fetcher service.
+   * @param \Drupal\media\OEmbed\UrlResolverInterface $url_resolver
+   *   The oEmbed URL resolver service.
+   * @param \Drupal\Core\Logger\LoggerChannelFactoryInterface $logger_factory
+   *   The logger factory service.
+   * @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory
+   *   The config factory service.
+   * @param \Drupal\media\IFrameUrlHelper $iframe_url_helper
+   *   The iFrame URL helper service.
+   */
+  public function __construct($plugin_id, $plugin_definition, FieldDefinitionInterface $field_definition, array $settings, $label, $view_mode, array $third_party_settings, MessengerInterface $messenger, ResourceFetcherInterface $resource_fetcher, UrlResolverInterface $url_resolver, LoggerChannelFactoryInterface $logger_factory, ConfigFactoryInterface $config_factory, IFrameUrlHelper $iframe_url_helper) {
+    parent::__construct($plugin_id, $plugin_definition, $field_definition, $settings, $label, $view_mode, $third_party_settings);
+    $this->messenger = $messenger;
+    $this->resourceFetcher = $resource_fetcher;
+    $this->urlResolver = $url_resolver;
+    $this->logger = $logger_factory->get('media');
+    $this->config = $config_factory->get('media.settings');
+    $this->iFrameUrlHelper = $iframe_url_helper;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
+    return new static(
+      $plugin_id,
+      $plugin_definition,
+      $configuration['field_definition'],
+      $configuration['settings'],
+      $configuration['label'],
+      $configuration['view_mode'],
+      $configuration['third_party_settings'],
+      $container->get('messenger'),
+      $container->get('media.oembed.resource_fetcher'),
+      $container->get('media.oembed.url_resolver'),
+      $container->get('logger.factory'),
+      $container->get('config.factory'),
+      $container->get('media.oembed.iframe_url_helper')
+    );
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function defaultSettings() {
+    return [
+      'max_width' => 0,
+      'max_height' => 0,
+    ] + parent::defaultSettings();
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function viewElements(FieldItemListInterface $items, $langcode) {
+    $element = [];
+    $max_width = $this->getSetting('max_width');
+    $max_height = $this->getSetting('max_height');
+
+    foreach ($items as $delta => $item) {
+      $main_property = $item->getFieldDefinition()->getFieldStorageDefinition()->getMainPropertyName();
+      $value = $item->{$main_property};
+
+      if (empty($value)) {
+        continue;
+      }
+
+      try {
+        $resource_url = $this->urlResolver->getResourceUrl($value, $max_width, $max_height);
+        $resource = $this->resourceFetcher->fetchResource($resource_url);
+      }
+      catch (ResourceException $exception) {
+        $this->logger->error("Could not retrieve the remote URL (@url).", ['@url' => $value]);
+        continue;
+      }
+
+      if ($resource->getType() === Resource::TYPE_LINK) {
+        $element[$delta] = [
+          '#title' => $resource->getTitle(),
+          '#type' => 'link',
+          '#url' => Url::fromUri($value),
+        ];
+      }
+      elseif ($resource->getType() === Resource::TYPE_PHOTO) {
+        $element[$delta] = [
+          '#theme' => 'image',
+          '#uri' => $resource->getUrl()->toString(),
+          '#width' => $max_width ?: $resource->getWidth(),
+          '#height' => $max_height ?: $resource->getHeight(),
+        ];
+      }
+      else {
+        $url = Url::fromRoute('media.oembed_iframe', [], [
+          'query' => [
+            'url' => $value,
+            'max_width' => $max_width,
+            'max_height' => $max_height,
+            'hash' => $this->iFrameUrlHelper->getHash($value, $max_width, $max_height),
+          ],
+        ]);
+
+        $domain = $this->config->get('iframe_domain');
+        if ($domain) {
+          $url->setOption('base_url', $domain);
+        }
+
+        // Render videos and rich content in an iframe for security reasons.
+        // @see: https://oembed.com/#section3
+        $element[$delta] = [
+          '#type' => 'html_tag',
+          '#tag' => 'iframe',
+          '#attributes' => [
+            'src' => $url->toString(),
+            'frameborder' => 0,
+            'scrolling' => FALSE,
+            'allowtransparency' => TRUE,
+            'width' => $max_width ?: $resource->getWidth(),
+            'height' => $max_height ?: $resource->getHeight(),
+          ],
+        ];
+
+        CacheableMetadata::createFromObject($resource)
+          ->addCacheTags($this->config->getCacheTags())
+          ->applyTo($element[$delta]);
+      }
+    }
+    return $element;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function settingsForm(array $form, FormStateInterface $form_state) {
+    return parent::settingsForm($form, $form_state) + [
+      'max_width' => [
+        '#type' => 'number',
+        '#title' => $this->t('Maximum width'),
+        '#default_value' => $this->getSetting('max_width'),
+        '#size' => 5,
+        '#maxlength' => 5,
+        '#field_suffix' => $this->t('pixels'),
+        '#min' => 0,
+      ],
+      'max_height' => [
+        '#type' => 'number',
+        '#title' => $this->t('Maximum height'),
+        '#default_value' => $this->getSetting('max_height'),
+        '#size' => 5,
+        '#maxlength' => 5,
+        '#field_suffix' => $this->t('pixels'),
+        '#min' => 0,
+      ],
+    ];
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function settingsSummary() {
+    $summary = parent::settingsSummary();
+    if ($this->getSetting('max_width') && $this->getSetting('max_height')) {
+      $summary[] = $this->t('Maximum size: %max_width x %max_height pixels', [
+        '%max_width' => $this->getSetting('max_width'),
+        '%max_height' => $this->getSetting('max_height'),
+      ]);
+    }
+    elseif ($this->getSetting('max_width')) {
+      $summary[] = $this->t('Maximum width: %max_width pixels', [
+        '%max_width' => $this->getSetting('max_width'),
+      ]);
+    }
+    elseif ($this->getSetting('max_height')) {
+      $summary[] = $this->t('Maximum height: %max_height pixels', [
+        '%max_height' => $this->getSetting('max_height'),
+      ]);
+    }
+    return $summary;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function isApplicable(FieldDefinitionInterface $field_definition) {
+    if ($field_definition->getTargetEntityTypeId() !== 'media') {
+      return FALSE;
+    }
+
+    if (parent::isApplicable($field_definition)) {
+      $media_type = $field_definition->getTargetBundle();
+
+      if ($media_type) {
+        $media_type = MediaType::load($media_type);
+        return $media_type && $media_type->getSource() instanceof OEmbedInterface;
+      }
+    }
+    return FALSE;
+  }
+
+}