Skip to content
Snippets Groups Projects
Select Git revision
  • 0d134850d90943ee1a4e568a46654d77499349d3
  • 11.x default protected
  • 10.5.x protected
  • 11.2.x protected
  • 10.6.x protected
  • 11.1.x protected
  • 10.4.x protected
  • 11.0.x protected
  • 10.3.x protected
  • 7.x protected
  • 10.2.x protected
  • 10.1.x protected
  • 9.5.x protected
  • 10.0.x protected
  • 9.4.x protected
  • 9.3.x protected
  • 9.2.x protected
  • 9.1.x protected
  • 8.9.x protected
  • 9.0.x protected
  • 8.8.x protected
  • 10.5.1 protected
  • 11.2.2 protected
  • 11.2.1 protected
  • 11.2.0 protected
  • 10.5.0 protected
  • 11.2.0-rc2 protected
  • 10.5.0-rc1 protected
  • 11.2.0-rc1 protected
  • 10.4.8 protected
  • 11.1.8 protected
  • 10.5.0-beta1 protected
  • 11.2.0-beta1 protected
  • 11.2.0-alpha1 protected
  • 10.4.7 protected
  • 11.1.7 protected
  • 10.4.6 protected
  • 11.1.6 protected
  • 10.3.14 protected
  • 10.4.5 protected
  • 11.0.13 protected
41 results

forum.module

Blame
  • Code owners
    Assign users and groups as approvers for specific file changes. Learn more.
    OEmbedResourceConstraintValidator.php 4.67 KiB
    <?php
    
    namespace Drupal\media\Plugin\Validation\Constraint;
    
    use Drupal\Core\DependencyInjection\ContainerInjectionInterface;
    use Drupal\Core\Logger\LoggerChannelFactoryInterface;
    use Drupal\media\OEmbed\ProviderException;
    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;
    use Symfony\Component\Validator\Constraint;
    use Symfony\Component\Validator\ConstraintValidator;
    
    /**
     * Validates oEmbed resource URLs.
     *
     * @internal
     *   This is an internal part of the oEmbed system and should only be used by
     *   oEmbed-related code in Drupal core.
     */
    class OEmbedResourceConstraintValidator extends ConstraintValidator implements ContainerInjectionInterface {
    
      /**
       * The oEmbed URL resolver service.
       *
       * @var \Drupal\media\OEmbed\UrlResolverInterface
       */
      protected $urlResolver;
    
      /**
       * The resource fetcher service.
       *
       * @var \Drupal\media\OEmbed\ResourceFetcherInterface
       */
      protected $resourceFetcher;
    
      /**
       * The logger service.
       *
       * @var \Drupal\Core\Logger\LoggerChannelInterface
       */
      protected $logger;
    
      /**
       * Constructs a new OEmbedResourceConstraintValidator.
       *
       * @param \Drupal\media\OEmbed\UrlResolverInterface $url_resolver
       *   The oEmbed URL resolver service.
       * @param \Drupal\media\OEmbed\ResourceFetcherInterface $resource_fetcher
       *   The resource fetcher service.
       * @param \Drupal\Core\Logger\LoggerChannelFactoryInterface $logger_factory
       *   The logger service.
       */
      public function __construct(UrlResolverInterface $url_resolver, ResourceFetcherInterface $resource_fetcher, LoggerChannelFactoryInterface $logger_factory) {
        $this->urlResolver = $url_resolver;
        $this->resourceFetcher = $resource_fetcher;
        $this->logger = $logger_factory->get('media');
      }
    
      /**
       * {@inheritdoc}
       */
      public static function create(ContainerInterface $container) {
        return new static(
          $container->get('media.oembed.url_resolver'),
          $container->get('media.oembed.resource_fetcher'),
          $container->get('logger.factory')
        );
      }
    
      /**
       * {@inheritdoc}
       */
      public function validate($value, Constraint $constraint) {
        /** @var \Drupal\media\MediaInterface $media */
        $media = $value->getEntity();
        /** @var \Drupal\media\Plugin\media\Source\OEmbedInterface $source */
        $source = $media->getSource();
    
        if (!($source instanceof OEmbedInterface)) {
          throw new \LogicException('Media source must implement ' . OEmbedInterface::class);
        }
        $url = $source->getSourceFieldValue($media);
        // The URL may be NULL if the source field is empty, which is invalid input.
        if (empty($url)) {
          $this->context->addViolation($constraint->invalidResourceMessage);
          return;
        }
    
        // Ensure that the URL matches a provider.
        try {
          $provider = $this->urlResolver->getProviderByUrl($url);
        }
        catch (ResourceException $e) {
          $this->handleException($e, $constraint->unknownProviderMessage);
          return;
        }
        catch (ProviderException $e) {
          $this->handleException($e, $constraint->providerErrorMessage);
          return;
        }
    
        // Ensure that the provider is allowed.
        if (!in_array($provider->getName(), $source->getProviders(), TRUE)) {
          $this->context->addViolation($constraint->disallowedProviderMessage, [
            '@name' => $provider->getName(),
          ]);
          return;
        }
    
        // Verify that resource fetching works, because some URLs might match
        // the schemes but don't support oEmbed.
        try {
          $resource_url = $this->urlResolver->getResourceUrl($url);
          $this->resourceFetcher->fetchResource($resource_url);
        }
        catch (ResourceException $e) {
          $this->handleException($e, $constraint->invalidResourceMessage);
        }
      }
    
      /**
       * Handles exceptions that occur during validation.
       *
       * @param \Exception $e
       *   The caught exception.
       * @param string $error_message
       *   (optional) The error message to set as a constraint violation.
       */
      protected function handleException(\Exception $e, $error_message = NULL) {
        if ($error_message) {
          $this->context->addViolation($error_message);
        }
    
        // The oEmbed system makes heavy use of exception wrapping, so log the
        // entire exception chain to help with troubleshooting.
        do {
          // @todo If $e is a ProviderException or ResourceException, log additional
          // debugging information contained in those exceptions in
          // https://www.drupal.org/project/drupal/issues/2972846.
          $this->logger->error($e->getMessage());
          $e = $e->getPrevious();
        } while ($e);
      }
    
    }