3 namespace Drupal\media\OEmbed;
5 use Drupal\Component\Utility\UrlHelper;
8 * Value object for oEmbed provider endpoints.
11 * This class is an internal part of the oEmbed system and should only be
12 * instantiated by instances of Drupal\media\OEmbed\Provider.
24 * The provider this endpoint belongs to.
26 * @var \Drupal\media\OEmbed\Provider
31 * List of URL schemes supported by the provider.
38 * List of supported formats. Only 'json' and 'xml' are allowed.
42 * @see https://oembed.com/#section2
47 * Whether the provider supports oEmbed discovery.
51 protected $supportsDiscovery;
54 * Endpoint constructor.
57 * The endpoint URL. May contain a @code '{format}' @endcode placeholder.
58 * @param \Drupal\media\OEmbed\Provider $provider
59 * The provider this endpoint belongs to.
60 * @param string[] $schemes
61 * List of URL schemes supported by the provider.
62 * @param string[] $formats
63 * List of supported formats. Can be "json", "xml" or both.
64 * @param bool $supports_discovery
65 * Whether the provider supports oEmbed discovery.
67 * @throws \InvalidArgumentException
68 * If the endpoint URL is empty.
70 public function __construct($url, Provider $provider, array $schemes = [], array $formats = [], $supports_discovery = FALSE) {
71 $this->provider = $provider;
72 $this->schemes = array_map('mb_strtolower', $schemes);
74 $this->formats = $formats = array_map('mb_strtolower', $formats);
75 // Assert that only the supported formats are present.
76 assert(array_diff($formats, ['json', 'xml']) == []);
78 // Use the first provided format to build the endpoint URL. If no formats
79 // are provided, default to JSON.
80 $this->url = str_replace('{format}', reset($this->formats) ?: 'json', $url);
82 if (!UrlHelper::isValid($this->url, TRUE) || !UrlHelper::isExternal($this->url)) {
83 throw new \InvalidArgumentException('oEmbed endpoint must have a valid external URL');
86 $this->supportsDiscovery = (bool) $supports_discovery;
90 * Returns the endpoint URL.
92 * The URL will be built with the first available format. If the endpoint
93 * does not provide any formats, JSON will be used.
98 public function getUrl() {
103 * Returns the provider this endpoint belongs to.
105 * @return \Drupal\media\OEmbed\Provider
106 * The provider object.
108 public function getProvider() {
109 return $this->provider;
113 * Returns list of URL schemes supported by the provider.
118 public function getSchemes() {
119 return $this->schemes;
123 * Returns list of supported formats.
128 public function getFormats() {
129 return $this->formats;
133 * Returns whether the provider supports oEmbed discovery.
136 * Returns TRUE if the provides discovery, otherwise FALSE.
138 public function supportsDiscovery() {
139 return $this->supportsDiscovery;
143 * Tries to match a URL against the endpoint schemes.
149 * TRUE if the URL matches against the endpoint schemes, otherwise FALSE.
151 public function matchUrl($url) {
152 foreach ($this->getSchemes() as $scheme) {
153 // Convert scheme into a valid regular expression.
154 $regexp = str_replace(['.', '*'], ['\.', '.*'], $scheme);
155 if (preg_match("|^$regexp$|", $url)) {
163 * Builds and returns the endpoint URL.
166 * The canonical media URL.
169 * URL of the oEmbed endpoint.
171 public function buildResourceUrl($url) {
172 $query = ['url' => $url];
173 return $this->getUrl() . '?' . UrlHelper::buildQuery($query);