/core/modules/media/src/Plugin/Field/FieldFormatter/OEmbedFormatter.php
PHP | 316 lines | 190 code | 27 blank | 99 comment | 11 complexity | 3f29d0ce7fa71480e371ef8fb9b0e439 MD5 | raw file
Possible License(s): GPL-2.0, LGPL-2.1
- <?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(),
- 'class' => ['media-oembed-content'],
- ],
- '#attached' => [
- 'library' => [
- 'media/oembed.formatter',
- ],
- ],
- ];
- // An empty title attribute will disable title inheritance, so only
- // add it if the resource has a title.
- $title = $resource->getTitle();
- if ($title) {
- $element[$delta]['#attributes']['title'] = $title;
- }
- 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;
- }
- }