Issue #3026184 by phenaproxima, nmeegama, kyuubi, vsujeetkumar, carolpettirossi, alexpott, larowlan, seanB, danflanagan8, chr.fritsch: To avoid performance issues, allow tokens in oEmbed thumbnail paths
parent
9d8e7da4fc
commit
adf864ee84
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
namespace Drupal\media\Plugin\media\Source;
|
namespace Drupal\media\Plugin\media\Source;
|
||||||
|
|
||||||
|
use Drupal\Component\Render\PlainTextOutput;
|
||||||
use Drupal\Component\Utility\Crypt;
|
use Drupal\Component\Utility\Crypt;
|
||||||
use Drupal\Core\Config\ConfigFactoryInterface;
|
use Drupal\Core\Config\ConfigFactoryInterface;
|
||||||
use Drupal\Core\Entity\Display\EntityFormDisplayInterface;
|
use Drupal\Core\Entity\Display\EntityFormDisplayInterface;
|
||||||
|
@ -14,6 +15,7 @@ use Drupal\Core\File\FileSystemInterface;
|
||||||
use Drupal\Core\Form\FormStateInterface;
|
use Drupal\Core\Form\FormStateInterface;
|
||||||
use Drupal\Core\Messenger\MessengerInterface;
|
use Drupal\Core\Messenger\MessengerInterface;
|
||||||
use Drupal\Core\Url;
|
use Drupal\Core\Url;
|
||||||
|
use Drupal\Core\Utility\Token;
|
||||||
use Drupal\media\IFrameUrlHelper;
|
use Drupal\media\IFrameUrlHelper;
|
||||||
use Drupal\media\OEmbed\Resource;
|
use Drupal\media\OEmbed\Resource;
|
||||||
use Drupal\media\OEmbed\ResourceException;
|
use Drupal\media\OEmbed\ResourceException;
|
||||||
|
@ -126,6 +128,13 @@ class OEmbed extends MediaSourceBase implements OEmbedInterface {
|
||||||
*/
|
*/
|
||||||
protected $fileSystem;
|
protected $fileSystem;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The token replacement service.
|
||||||
|
*
|
||||||
|
* @var \Drupal\Core\Utility\Token
|
||||||
|
*/
|
||||||
|
protected $token;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructs a new OEmbed instance.
|
* Constructs a new OEmbed instance.
|
||||||
*
|
*
|
||||||
|
@ -157,8 +166,10 @@ class OEmbed extends MediaSourceBase implements OEmbedInterface {
|
||||||
* The iFrame URL helper service.
|
* The iFrame URL helper service.
|
||||||
* @param \Drupal\Core\File\FileSystemInterface $file_system
|
* @param \Drupal\Core\File\FileSystemInterface $file_system
|
||||||
* The file system.
|
* The file system.
|
||||||
|
* @param \Drupal\Core\Utility\Token $token
|
||||||
|
* The token replacement service.
|
||||||
*/
|
*/
|
||||||
public function __construct(array $configuration, $plugin_id, $plugin_definition, EntityTypeManagerInterface $entity_type_manager, EntityFieldManagerInterface $entity_field_manager, ConfigFactoryInterface $config_factory, FieldTypePluginManagerInterface $field_type_manager, LoggerInterface $logger, MessengerInterface $messenger, ClientInterface $http_client, ResourceFetcherInterface $resource_fetcher, UrlResolverInterface $url_resolver, IFrameUrlHelper $iframe_url_helper, FileSystemInterface $file_system) {
|
public function __construct(array $configuration, $plugin_id, $plugin_definition, EntityTypeManagerInterface $entity_type_manager, EntityFieldManagerInterface $entity_field_manager, ConfigFactoryInterface $config_factory, FieldTypePluginManagerInterface $field_type_manager, LoggerInterface $logger, MessengerInterface $messenger, ClientInterface $http_client, ResourceFetcherInterface $resource_fetcher, UrlResolverInterface $url_resolver, IFrameUrlHelper $iframe_url_helper, FileSystemInterface $file_system, Token $token = NULL) {
|
||||||
parent::__construct($configuration, $plugin_id, $plugin_definition, $entity_type_manager, $entity_field_manager, $field_type_manager, $config_factory);
|
parent::__construct($configuration, $plugin_id, $plugin_definition, $entity_type_manager, $entity_field_manager, $field_type_manager, $config_factory);
|
||||||
$this->logger = $logger;
|
$this->logger = $logger;
|
||||||
$this->messenger = $messenger;
|
$this->messenger = $messenger;
|
||||||
|
@ -167,6 +178,11 @@ class OEmbed extends MediaSourceBase implements OEmbedInterface {
|
||||||
$this->urlResolver = $url_resolver;
|
$this->urlResolver = $url_resolver;
|
||||||
$this->iFrameUrlHelper = $iframe_url_helper;
|
$this->iFrameUrlHelper = $iframe_url_helper;
|
||||||
$this->fileSystem = $file_system;
|
$this->fileSystem = $file_system;
|
||||||
|
if (empty($token)) {
|
||||||
|
@trigger_error('The token service should be passed to ' . __METHOD__ . '() and is required in drupal:10.0.0. See https://www.drupal.org/node/3240036', E_USER_DEPRECATED);
|
||||||
|
$token = \Drupal::token();
|
||||||
|
}
|
||||||
|
$this->token = $token;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -187,7 +203,8 @@ class OEmbed extends MediaSourceBase implements OEmbedInterface {
|
||||||
$container->get('media.oembed.resource_fetcher'),
|
$container->get('media.oembed.resource_fetcher'),
|
||||||
$container->get('media.oembed.url_resolver'),
|
$container->get('media.oembed.url_resolver'),
|
||||||
$container->get('media.oembed.iframe_url_helper'),
|
$container->get('media.oembed.iframe_url_helper'),
|
||||||
$container->get('file_system')
|
$container->get('file_system'),
|
||||||
|
$container->get('token')
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -362,7 +379,7 @@ class OEmbed extends MediaSourceBase implements OEmbedInterface {
|
||||||
*/
|
*/
|
||||||
public function defaultConfiguration() {
|
public function defaultConfiguration() {
|
||||||
return [
|
return [
|
||||||
'thumbnails_directory' => 'public://oembed_thumbnails',
|
'thumbnails_directory' => 'public://oembed_thumbnails/[date:custom:Y-m]',
|
||||||
'providers' => [],
|
'providers' => [],
|
||||||
] + parent::defaultConfiguration();
|
] + parent::defaultConfiguration();
|
||||||
}
|
}
|
||||||
|
@ -392,10 +409,13 @@ class OEmbed extends MediaSourceBase implements OEmbedInterface {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ensure that we can write to the local directory where thumbnails are
|
// Use the configured directory to store thumbnails. The directory can
|
||||||
// stored.
|
// contain basic (i.e., global) tokens. If any of the replaced tokens
|
||||||
|
// contain HTML, the tags will be removed and XML entities will be decoded.
|
||||||
$configuration = $this->getConfiguration();
|
$configuration = $this->getConfiguration();
|
||||||
$directory = $configuration['thumbnails_directory'];
|
$directory = $configuration['thumbnails_directory'];
|
||||||
|
$directory = $this->token->replace($directory);
|
||||||
|
$directory = PlainTextOutput::renderFromHtml($directory);
|
||||||
|
|
||||||
// The local thumbnail doesn't exist yet, so try to download it. First,
|
// The local thumbnail doesn't exist yet, so try to download it. First,
|
||||||
// ensure that the destination directory is writable, and if it's not,
|
// ensure that the destination directory is writable, and if it's not,
|
||||||
|
|
|
@ -135,19 +135,36 @@ class OEmbedSourceTest extends MediaKernelTestBase {
|
||||||
$media_type = $this->createMediaType('oembed:video');
|
$media_type = $this->createMediaType('oembed:video');
|
||||||
$source = $media_type->getSource();
|
$source = $media_type->getSource();
|
||||||
|
|
||||||
|
// Add some HTML to the global site slogan, and use the site:slogan token in
|
||||||
|
// the thumbnail path, in order to prove that the final thumbnail path is
|
||||||
|
// stripped of HTML tags, and XML entities are decoded.
|
||||||
|
$this->config('system.site')
|
||||||
|
->set('slogan', '<h1>this&that</h1>')
|
||||||
|
->save();
|
||||||
|
$configuration = $source->getConfiguration();
|
||||||
|
$configuration['thumbnails_directory'] .= '/[site:slogan]';
|
||||||
|
$source->setConfiguration($configuration);
|
||||||
|
$media_type->save();
|
||||||
|
|
||||||
$media = Media::create([
|
$media = Media::create([
|
||||||
'bundle' => $media_type->id(),
|
'bundle' => $media_type->id(),
|
||||||
$source->getSourceFieldDefinition($media_type)->getName() => $this->randomString(),
|
$source->getSourceFieldDefinition($media_type)->getName() => $this->randomString(),
|
||||||
]);
|
]);
|
||||||
$media->save();
|
$media->save();
|
||||||
|
|
||||||
|
// The thumbnail directory should include the current date, as per the
|
||||||
|
// default configuration of the oEmbed source plugin.
|
||||||
|
$date = date('Y-m', $this->container->get('datetime.time')->getRequestTime());
|
||||||
|
|
||||||
// The thumbnail should have a file extension, even if it wasn't in the URL.
|
// The thumbnail should have a file extension, even if it wasn't in the URL.
|
||||||
$expected_uri = 'public://oembed_thumbnails/' . Crypt::hashBase64($thumbnail_url) . ".$expected_extension";
|
$expected_uri = "public://oembed_thumbnails/$date/this&that/" . Crypt::hashBase64($thumbnail_url) . ".$expected_extension";
|
||||||
$this->assertSame($expected_uri, $source->getMetadata($media, 'thumbnail_uri'));
|
$this->assertSame($expected_uri, $source->getMetadata($media, 'thumbnail_uri'));
|
||||||
|
|
||||||
// Even if we get the thumbnail_uri more than once, it should only be
|
// Even if we get the thumbnail_uri more than once, it should only be
|
||||||
// downloaded once. The HTTP client will throw an exception if we try to
|
// downloaded once. The HTTP client will throw an exception if we try to
|
||||||
// do another request without setting up another response.
|
// do another request without setting up another response.
|
||||||
$source->getMetadata($media, 'thumbnail_uri');
|
$source->getMetadata($media, 'thumbnail_uri');
|
||||||
|
|
||||||
// The downloaded thumbnail should be usable by the image toolkit.
|
// The downloaded thumbnail should be usable by the image toolkit.
|
||||||
$this->assertFileExists($expected_uri);
|
$this->assertFileExists($expected_uri);
|
||||||
/** @var \Drupal\Core\Image\Image $image */
|
/** @var \Drupal\Core\Image\Image $image */
|
||||||
|
|
|
@ -8,7 +8,7 @@ source: 'oembed:video'
|
||||||
queue_thumbnail_downloads: false
|
queue_thumbnail_downloads: false
|
||||||
new_revision: true
|
new_revision: true
|
||||||
source_configuration:
|
source_configuration:
|
||||||
thumbnails_directory: 'public://oembed_thumbnails'
|
thumbnails_directory: 'public://oembed_thumbnails/[date:custom:Y-m]'
|
||||||
providers:
|
providers:
|
||||||
- YouTube
|
- YouTube
|
||||||
- Vimeo
|
- Vimeo
|
||||||
|
|
|
@ -8,7 +8,7 @@ source: 'oembed:video'
|
||||||
queue_thumbnail_downloads: false
|
queue_thumbnail_downloads: false
|
||||||
new_revision: true
|
new_revision: true
|
||||||
source_configuration:
|
source_configuration:
|
||||||
thumbnails_directory: 'public://oembed_thumbnails'
|
thumbnails_directory: 'public://oembed_thumbnails/[date:custom:Y-m]'
|
||||||
providers:
|
providers:
|
||||||
- YouTube
|
- YouTube
|
||||||
- Vimeo
|
- Vimeo
|
||||||
|
|
Loading…
Reference in New Issue