"Fossies" - the Fresh Open Source Software Archive

Member "drupal-8.9.10/core/modules/media/src/Plugin/Field/FieldFormatter/OEmbedFormatter.php" (26 Nov 2020, 10043 Bytes) of package /linux/www/drupal-8.9.10.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) PHP source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "OEmbedFormatter.php" see the Fossies "Dox" file reference documentation and the last Fossies "Diffs" side-by-side code changes report: 9.0.8_vs_9.1.0-rc1.

    1 <?php
    2 
    3 namespace Drupal\media\Plugin\Field\FieldFormatter;
    4 
    5 use Drupal\Core\Cache\CacheableMetadata;
    6 use Drupal\Core\Config\ConfigFactoryInterface;
    7 use Drupal\Core\Field\FieldDefinitionInterface;
    8 use Drupal\Core\Field\FieldItemListInterface;
    9 use Drupal\Core\Field\FormatterBase;
   10 use Drupal\Core\Form\FormStateInterface;
   11 use Drupal\Core\Logger\LoggerChannelFactoryInterface;
   12 use Drupal\Core\Messenger\MessengerInterface;
   13 use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
   14 use Drupal\Core\Url;
   15 use Drupal\media\Entity\MediaType;
   16 use Drupal\media\IFrameUrlHelper;
   17 use Drupal\media\OEmbed\Resource;
   18 use Drupal\media\OEmbed\ResourceException;
   19 use Drupal\media\OEmbed\ResourceFetcherInterface;
   20 use Drupal\media\OEmbed\UrlResolverInterface;
   21 use Drupal\media\Plugin\media\Source\OEmbedInterface;
   22 use Symfony\Component\DependencyInjection\ContainerInterface;
   23 
   24 /**
   25  * Plugin implementation of the 'oembed' formatter.
   26  *
   27  * @internal
   28  *   This is an internal part of the oEmbed system and should only be used by
   29  *   oEmbed-related code in Drupal core.
   30  *
   31  * @FieldFormatter(
   32  *   id = "oembed",
   33  *   label = @Translation("oEmbed content"),
   34  *   field_types = {
   35  *     "link",
   36  *     "string",
   37  *     "string_long",
   38  *   },
   39  * )
   40  */
   41 class OEmbedFormatter extends FormatterBase implements ContainerFactoryPluginInterface {
   42 
   43   /**
   44    * The messenger service.
   45    *
   46    * @var \Drupal\Core\Messenger\MessengerInterface
   47    */
   48   protected $messenger;
   49 
   50   /**
   51    * The oEmbed resource fetcher.
   52    *
   53    * @var \Drupal\media\OEmbed\ResourceFetcherInterface
   54    */
   55   protected $resourceFetcher;
   56 
   57   /**
   58    * The oEmbed URL resolver service.
   59    *
   60    * @var \Drupal\media\OEmbed\UrlResolverInterface
   61    */
   62   protected $urlResolver;
   63 
   64   /**
   65    * The logger service.
   66    *
   67    * @var \Psr\Log\LoggerInterface
   68    */
   69   protected $logger;
   70 
   71   /**
   72    * The media settings config.
   73    *
   74    * @var \Drupal\Core\Config\ImmutableConfig
   75    */
   76   protected $config;
   77 
   78   /**
   79    * The iFrame URL helper service.
   80    *
   81    * @var \Drupal\media\IFrameUrlHelper
   82    */
   83   protected $iFrameUrlHelper;
   84 
   85   /**
   86    * Constructs an OEmbedFormatter instance.
   87    *
   88    * @param string $plugin_id
   89    *   The plugin ID for the formatter.
   90    * @param mixed $plugin_definition
   91    *   The plugin implementation definition.
   92    * @param \Drupal\Core\Field\FieldDefinitionInterface $field_definition
   93    *   The definition of the field to which the formatter is associated.
   94    * @param array $settings
   95    *   The formatter settings.
   96    * @param string $label
   97    *   The formatter label display setting.
   98    * @param string $view_mode
   99    *   The view mode.
  100    * @param array $third_party_settings
  101    *   Any third party settings.
  102    * @param \Drupal\Core\Messenger\MessengerInterface $messenger
  103    *   The messenger service.
  104    * @param \Drupal\media\OEmbed\ResourceFetcherInterface $resource_fetcher
  105    *   The oEmbed resource fetcher service.
  106    * @param \Drupal\media\OEmbed\UrlResolverInterface $url_resolver
  107    *   The oEmbed URL resolver service.
  108    * @param \Drupal\Core\Logger\LoggerChannelFactoryInterface $logger_factory
  109    *   The logger factory service.
  110    * @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory
  111    *   The config factory service.
  112    * @param \Drupal\media\IFrameUrlHelper $iframe_url_helper
  113    *   The iFrame URL helper service.
  114    */
  115   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) {
  116     parent::__construct($plugin_id, $plugin_definition, $field_definition, $settings, $label, $view_mode, $third_party_settings);
  117     $this->messenger = $messenger;
  118     $this->resourceFetcher = $resource_fetcher;
  119     $this->urlResolver = $url_resolver;
  120     $this->logger = $logger_factory->get('media');
  121     $this->config = $config_factory->get('media.settings');
  122     $this->iFrameUrlHelper = $iframe_url_helper;
  123   }
  124 
  125   /**
  126    * {@inheritdoc}
  127    */
  128   public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
  129     return new static(
  130       $plugin_id,
  131       $plugin_definition,
  132       $configuration['field_definition'],
  133       $configuration['settings'],
  134       $configuration['label'],
  135       $configuration['view_mode'],
  136       $configuration['third_party_settings'],
  137       $container->get('messenger'),
  138       $container->get('media.oembed.resource_fetcher'),
  139       $container->get('media.oembed.url_resolver'),
  140       $container->get('logger.factory'),
  141       $container->get('config.factory'),
  142       $container->get('media.oembed.iframe_url_helper')
  143     );
  144   }
  145 
  146   /**
  147    * {@inheritdoc}
  148    */
  149   public static function defaultSettings() {
  150     return [
  151       'max_width' => 0,
  152       'max_height' => 0,
  153     ] + parent::defaultSettings();
  154   }
  155 
  156   /**
  157    * {@inheritdoc}
  158    */
  159   public function viewElements(FieldItemListInterface $items, $langcode) {
  160     $element = [];
  161     $max_width = $this->getSetting('max_width');
  162     $max_height = $this->getSetting('max_height');
  163 
  164     foreach ($items as $delta => $item) {
  165       $main_property = $item->getFieldDefinition()->getFieldStorageDefinition()->getMainPropertyName();
  166       $value = $item->{$main_property};
  167 
  168       if (empty($value)) {
  169         continue;
  170       }
  171 
  172       try {
  173         $resource_url = $this->urlResolver->getResourceUrl($value, $max_width, $max_height);
  174         $resource = $this->resourceFetcher->fetchResource($resource_url);
  175       }
  176       catch (ResourceException $exception) {
  177         $this->logger->error("Could not retrieve the remote URL (@url).", ['@url' => $value]);
  178         continue;
  179       }
  180 
  181       if ($resource->getType() === Resource::TYPE_LINK) {
  182         $element[$delta] = [
  183           '#title' => $resource->getTitle(),
  184           '#type' => 'link',
  185           '#url' => Url::fromUri($value),
  186         ];
  187       }
  188       elseif ($resource->getType() === Resource::TYPE_PHOTO) {
  189         $element[$delta] = [
  190           '#theme' => 'image',
  191           '#uri' => $resource->getUrl()->toString(),
  192           '#width' => $max_width ?: $resource->getWidth(),
  193           '#height' => $max_height ?: $resource->getHeight(),
  194         ];
  195       }
  196       else {
  197         $url = Url::fromRoute('media.oembed_iframe', [], [
  198           'query' => [
  199             'url' => $value,
  200             'max_width' => $max_width,
  201             'max_height' => $max_height,
  202             'hash' => $this->iFrameUrlHelper->getHash($value, $max_width, $max_height),
  203           ],
  204         ]);
  205 
  206         $domain = $this->config->get('iframe_domain');
  207         if ($domain) {
  208           $url->setOption('base_url', $domain);
  209         }
  210 
  211         // Render videos and rich content in an iframe for security reasons.
  212         // @see: https://oembed.com/#section3
  213         $element[$delta] = [
  214           '#type' => 'html_tag',
  215           '#tag' => 'iframe',
  216           '#attributes' => [
  217             'src' => $url->toString(),
  218             'frameborder' => 0,
  219             'scrolling' => FALSE,
  220             'allowtransparency' => TRUE,
  221             'width' => $max_width ?: $resource->getWidth(),
  222             'height' => $max_height ?: $resource->getHeight(),
  223             'class' => ['media-oembed-content'],
  224           ],
  225           '#attached' => [
  226             'library' => [
  227               'media/oembed.formatter',
  228             ],
  229           ],
  230         ];
  231 
  232         // An empty title attribute will disable title inheritance, so only
  233         // add it if the resource has a title.
  234         $title = $resource->getTitle();
  235         if ($title) {
  236           $element[$delta]['#attributes']['title'] = $title;
  237         }
  238 
  239         CacheableMetadata::createFromObject($resource)
  240           ->addCacheTags($this->config->getCacheTags())
  241           ->applyTo($element[$delta]);
  242       }
  243     }
  244     return $element;
  245   }
  246 
  247   /**
  248    * {@inheritdoc}
  249    */
  250   public function settingsForm(array $form, FormStateInterface $form_state) {
  251     return parent::settingsForm($form, $form_state) + [
  252       'max_width' => [
  253         '#type' => 'number',
  254         '#title' => $this->t('Maximum width'),
  255         '#default_value' => $this->getSetting('max_width'),
  256         '#size' => 5,
  257         '#maxlength' => 5,
  258         '#field_suffix' => $this->t('pixels'),
  259         '#min' => 0,
  260       ],
  261       'max_height' => [
  262         '#type' => 'number',
  263         '#title' => $this->t('Maximum height'),
  264         '#default_value' => $this->getSetting('max_height'),
  265         '#size' => 5,
  266         '#maxlength' => 5,
  267         '#field_suffix' => $this->t('pixels'),
  268         '#min' => 0,
  269       ],
  270     ];
  271   }
  272 
  273   /**
  274    * {@inheritdoc}
  275    */
  276   public function settingsSummary() {
  277     $summary = parent::settingsSummary();
  278     if ($this->getSetting('max_width') && $this->getSetting('max_height')) {
  279       $summary[] = $this->t('Maximum size: %max_width x %max_height pixels', [
  280         '%max_width' => $this->getSetting('max_width'),
  281         '%max_height' => $this->getSetting('max_height'),
  282       ]);
  283     }
  284     elseif ($this->getSetting('max_width')) {
  285       $summary[] = $this->t('Maximum width: %max_width pixels', [
  286         '%max_width' => $this->getSetting('max_width'),
  287       ]);
  288     }
  289     elseif ($this->getSetting('max_height')) {
  290       $summary[] = $this->t('Maximum height: %max_height pixels', [
  291         '%max_height' => $this->getSetting('max_height'),
  292       ]);
  293     }
  294     return $summary;
  295   }
  296 
  297   /**
  298    * {@inheritdoc}
  299    */
  300   public static function isApplicable(FieldDefinitionInterface $field_definition) {
  301     if ($field_definition->getTargetEntityTypeId() !== 'media') {
  302       return FALSE;
  303     }
  304 
  305     if (parent::isApplicable($field_definition)) {
  306       $media_type = $field_definition->getTargetBundle();
  307 
  308       if ($media_type) {
  309         $media_type = MediaType::load($media_type);
  310         return $media_type && $media_type->getSource() instanceof OEmbedInterface;
  311       }
  312     }
  313     return FALSE;
  314   }
  315 
  316 }