OEmbedResourceConstraintValidator.php
Same filename in other branches
Namespace
Drupal\media\Plugin\Validation\ConstraintFile
-
core/
modules/ media/ src/ Plugin/ Validation/ Constraint/ OEmbedResourceConstraintValidator.php
View source
<?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);
}
}
Classes
Title | Deprecated | Summary |
---|---|---|
OEmbedResourceConstraintValidator | Validates oEmbed resource URLs. |
Buggy or inaccurate documentation? Please file an issue. Need support? Need help programming? Connect with the Drupal community.