diff -u b/core/modules/media/media.services.yml b/core/modules/media/media.services.yml --- b/core/modules/media/media.services.yml +++ b/core/modules/media/media.services.yml @@ -8 +8 @@ - arguments: ['@entity_type.manager', '@string_translation'] + arguments: ['@entity_type.manager', '@string_translation', '@config.factory'] diff -u b/core/modules/media/src/Annotation/MediaSource.php b/core/modules/media/src/Annotation/MediaSource.php --- b/core/modules/media/src/Annotation/MediaSource.php +++ b/core/modules/media/src/Annotation/MediaSource.php @@ -59,2 +59,40 @@ + /** + * A filename for the default thumbnail. + * + * The thumbnails are placed in the directory defined in + * media.settings.icon_base_uri. When using custom icons, make sure the + * module provides a hook_install() implementation to copy the custom icons + * to this directory. The media_install() function provides a clear example + * on how to do this. + * + * @var string + * + * @see media_install() + */ + public $default_thumbnail_filename = 'generic.png'; + + /** + * Whether to update the thumbnail when the source field value changes. + * + * This is typically used for media sources that use images as a thumbnail. + * + * @var bool + */ + public $update_thumbnail_on_source_field_change = FALSE; + + /** + * The metadata attribute name to provide the thumbnail URI. + * + * @var string + */ + public $thumbnail_uri_metadata_attribute = 'thumbnail_uri'; + + /** + * The metadata attribute name to provide the default name. + * + * @var string + */ + public $default_name_metadata_attribute = 'default_name'; + } diff -u b/core/modules/media/src/Entity/Media.php b/core/modules/media/src/Entity/Media.php --- b/core/modules/media/src/Entity/Media.php +++ b/core/modules/media/src/Entity/Media.php @@ -132,6 +132,32 @@ } /** + * Determines if the thumbnail should be updated for a media item. + * + * @param bool $is_new + * Specifies whether the media item is new. + * + * @return bool + * TRUE if the thumbnail should be updated, FALSE otherwise. + */ + protected function shouldUpdateThumbnail($is_new = FALSE) { + $source_field_name = $this->getSource()->getConfiguration()['source_field']; + + // Update thumbnail if we don't have a thumbnail yet. + if (!$this->get('thumbnail')->entity || $is_new) { + return TRUE; + } + + // For existing items, we check if the media source needs to update the + // thumbnail when the source field value changes. + if ($this->getSource()->getPluginDefinition()['update_thumbnail_on_source_field_change'] && (isset($this->original) && $this->get($source_field_name)->getValue() != $this->original->get($source_field_name)->getValue())) { + return TRUE; + } + + return FALSE; + } + + /** * {@inheritdoc} */ public function preSave(EntityStorageInterface $storage) { @@ -149,11 +175,11 @@ // Try to set a default name for this media item if no label is provided. if (!$this->label()) { - $this->set('name', $this->getSource()->getDefaultName($this)); + $this->set('name', $this->getSource()->getMetadata($this, $this->getSource()->getPluginDefinition()['default_name_metadata_attribute'])); } // Set thumbnail. - if ($this->getSource()->shouldUpdateThumbnail($this)) { + if ($this->shouldUpdateThumbnail()) { \Drupal::service('media.thumbnail_handler')->updateThumbnail($this); } } @@ -164,7 +190,7 @@ public function postSave(EntityStorageInterface $storage, $update = TRUE) { parent::postSave($storage, $update); $is_new = !$update; - if ($this->bundle->entity->thumbnailDownloadsAreQueued() && $this->getSource()->shouldUpdateThumbnail($this, $is_new)) { + if ($this->bundle->entity->thumbnailDownloadsAreQueued() && $this->shouldUpdateThumbnail($is_new)) { $queue = \Drupal::queue('media_entity_thumbnail'); $queue->createItem(['id' => $this->id()]); } diff -u b/core/modules/media/src/MediaSourceBase.php b/core/modules/media/src/MediaSourceBase.php --- b/core/modules/media/src/MediaSourceBase.php +++ b/core/modules/media/src/MediaSourceBase.php @@ -39,18 +39,18 @@ protected $entityFieldManager; /** - * The config factory service. + * The field type plugin manager service. * - * @var \Drupal\Core\Config\ConfigFactoryInterface + * @var \Drupal\Core\Field\FieldTypePluginManagerInterface */ - protected $configFactory; + protected $fieldTypeManager; /** - * The field type plugin manager service. + * The config factory service. * - * @var \Drupal\Core\Field\FieldTypePluginManagerInterface + * @var \Drupal\Core\Config\ConfigFactoryInterface */ - protected $fieldTypeManager; + protected $configFactory; /** * Constructs a new class instance. @@ -65,17 +65,17 @@ * Entity type manager service. * @param \Drupal\Core\Entity\EntityFieldManagerInterface $entity_field_manager * Entity field manager service. - * @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory - * The config factory service. * @param \Drupal\Core\Field\FieldTypePluginManagerInterface $field_type_manager * The field type plugin manager service. + * @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory + * The config factory 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) { + public function __construct(array $configuration, $plugin_id, $plugin_definition, EntityTypeManagerInterface $entity_type_manager, EntityFieldManagerInterface $entity_field_manager, FieldTypePluginManagerInterface $field_type_manager, ConfigFactoryInterface $config_factory) { parent::__construct($configuration, $plugin_id, $plugin_definition); $this->entityTypeManager = $entity_type_manager; $this->entityFieldManager = $entity_field_manager; - $this->configFactory = $config_factory; $this->fieldTypeManager = $field_type_manager; + $this->configFactory = $config_factory; $this->setConfiguration($configuration); } @@ -89,8 +89,8 @@ $plugin_definition, $container->get('entity_type.manager'), $container->get('entity_field.manager'), - $container->get('config.factory'), - $container->get('plugin.manager.field.field_type') + $container->get('plugin.manager.field.field_type'), + $container->get('config.factory') ); } @@ -123,22 +123,17 @@ /** * {@inheritdoc} */ - public function shouldUpdateThumbnail(MediaInterface $media, $is_new = FALSE) { - $source_field_name = $this->configuration['source_field']; + public function getMetadata(MediaInterface $media, $attribute_name) { + switch ($attribute_name) { - // Update thumbnail if we don't have a thumbnail yet, for new items, - // or if the value of the source field changed. - if (!$media->get('thumbnail')->entity || $is_new || (isset($media->original) && $media->get($source_field_name)->getValue() != $media->original->get($source_field_name)->getValue())) { - return TRUE; - } - return FALSE; - } + case 'default_name': + return 'media:' . $media->bundle() . ':' . $media->uuid(); - /** - * {@inheritdoc} - */ - public function getDefaultThumbnail() { - return $this->configFactory->get('media.settings')->get('icon_base_uri') . '/generic.png'; + case 'thumbnail_uri': + $default_thumbnail_filename = $this->pluginDefinition['default_thumbnail_filename']; + return $this->configFactory->get('media.settings')->get('icon_base_uri') . '/' . $default_thumbnail_filename; + + } } /** @@ -223,13 +218,6 @@ } /** - * {@inheritdoc} - */ - public function getDefaultName(MediaInterface $media) { - return 'media:' . $media->bundle() . ':' . $media->uuid(); - } - - /** * Creates the source field storage definition. * * By default, the first field type listed in the plugin definition's diff -u b/core/modules/media/src/MediaSourceInterface.php b/core/modules/media/src/MediaSourceInterface.php --- b/core/modules/media/src/MediaSourceInterface.php +++ b/core/modules/media/src/MediaSourceInterface.php @@ -102,13 +102,13 @@ * * @param \Drupal\media\MediaInterface $media * A media item. - * @param string $name + * @param string $attribute_name * Name of the attribute to fetch. * * @return mixed|false * Metadata attribute value or FALSE if unavailable. */ - public function getMetadata(MediaInterface $media, $name); + public function getMetadata(MediaInterface $media, $attribute_name); /** * Attaches media source-specific validation constraints to a media item. @@ -119,57 +119,6 @@ public function attachConstraints(MediaInterface $media); /** - * Determines if the thumbnail should be updated for a media item. - * - * @param \Drupal\media\MediaInterface $media - * A media item. - * @param bool $is_new - * Specifies whether the media item is new. - * - * @return bool - * TRUE if the thumbnail should be updated, FALSE otherwise. - */ - public function shouldUpdateThumbnail(MediaInterface $media, $is_new = FALSE); - - /** - * Gets thumbnail image. - * - * The media source is responsible for returning the file URI of the - * generic thumbnail if no other is available. This function should always - * return a valid file URI. - * - * @param \Drupal\media\MediaInterface $media - * A media item. - * - * @return string - * File URI of the thumbnail. - */ - public function getThumbnail(MediaInterface $media); - - /** - * Gets the default thumbnail image. - * - * @return string - * File URI of the default thumbnail image. - */ - public function getDefaultThumbnail(); - - /** - * Provide a default name for the media item. - * - * Plugins defining a media source are suggested to override this method and - * provide a default name, to be used when there is no user-defined label - * available. - * - * @param \Drupal\media\MediaInterface $media - * A media item. - * - * @return string - * A string that should be used as default media name. - */ - public function getDefaultName(MediaInterface $media); - - /** * Get the source field definition for a media type. * * @param \Drupal\media\MediaTypeInterface $type diff -u b/core/modules/media/src/MediaThumbnailHandler.php b/core/modules/media/src/MediaThumbnailHandler.php --- b/core/modules/media/src/MediaThumbnailHandler.php +++ b/core/modules/media/src/MediaThumbnailHandler.php @@ -2,6 +2,7 @@ namespace Drupal\media; +use Drupal\Core\Config\ConfigFactoryInterface; use Drupal\Core\Entity\EntityTypeManagerInterface; use Drupal\Core\StringTranslation\StringTranslationTrait; use Drupal\Core\StringTranslation\TranslationInterface; @@ -21,16 +22,26 @@ protected $fileStorage; /** + * The config factory service. + * + * @var \Drupal\Core\Config\ConfigFactoryInterface + */ + protected $configFactory; + + /** * Constructs a new MediaThumbnailHandler. * * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager * The entity type manager service. * @param \Drupal\Core\StringTranslation\TranslationInterface $translation * The string translation service. + * @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory + * The config factory service. */ - public function __construct(EntityTypeManagerInterface $entity_type_manager, TranslationInterface $translation) { + public function __construct(EntityTypeManagerInterface $entity_type_manager, TranslationInterface $translation, ConfigFactoryInterface $config_factory) { $this->fileStorage = $entity_type_manager->getStorage('file'); $this->stringTranslation = $translation; + $this->configFactory = $config_factory; } /** @@ -80,13 +91,14 @@ */ protected function getThumbnailUri(MediaInterface $media, $from_queue) { if ($media->bundle->entity->thumbnailDownloadsAreQueued() && $media->isNew()) { - $thumbnail_uri = $media->getSource()->getDefaultThumbnail(); + $default_thumbnail_filename = $media->getSource()->getPluginDefinition()['default_thumbnail_filename']; + $thumbnail_uri = $this->configFactory->get('media.settings')->get('icon_base_uri') . '/' . $default_thumbnail_filename; } elseif ($media->bundle->entity->thumbnailDownloadsAreQueued() && !$from_queue) { $thumbnail_uri = $media->get('thumbnail')->entity->getFileUri(); } else { - $thumbnail_uri = $media->getSource()->getThumbnail($media); + $thumbnail_uri = $media->getSource()->getMetadata($media, $media->getSource()->getPluginDefinition()['thumbnail_uri_metadata_attribute']); } return $thumbnail_uri; diff -u b/core/modules/media/tests/modules/media_test_source/src/Plugin/media/Source/Test.php b/core/modules/media/tests/modules/media_test_source/src/Plugin/media/Source/Test.php --- b/core/modules/media/tests/modules/media_test_source/src/Plugin/media/Source/Test.php +++ b/core/modules/media/tests/modules/media_test_source/src/Plugin/media/Source/Test.php @@ -21,13 +21,6 @@ /** * {@inheritdoc} */ - public function getThumbnail(MediaInterface $media) { - return DRUPAL_ROOT . '/core/misc/druplicon.png'; - } - - /** - * {@inheritdoc} - */ public function getMetadataAttributes() { return [ 'attribute_1' => $this->t('Attribute 1'), @@ -38,8 +31,16 @@ /** * {@inheritdoc} */ - public function getMetadata(MediaInterface $media, $name) { - return FALSE; + public function getMetadata(MediaInterface $media, $attribute_name) { + switch ($attribute_name) { + + case 'thumbnail_uri': + return DRUPAL_ROOT . '/core/misc/druplicon.png'; + + default: + return parent::getMetadata($media, $attribute_name); + + } } /** diff -u b/core/modules/media/tests/src/Functional/MediaUiFunctionalTest.php b/core/modules/media/tests/src/Functional/MediaUiFunctionalTest.php --- b/core/modules/media/tests/src/Functional/MediaUiFunctionalTest.php +++ b/core/modules/media/tests/src/Functional/MediaUiFunctionalTest.php @@ -175,8 +175,9 @@ $media_item = Media::create(['bundle' => $media_type->id()]); $media_item->save(); - $default_thumb_uri = $media_item->getSource()->getDefaultThumbnail(); - $source_thumb_uri = $media_item->getSource()->getThumbnail($media_item); + $filename = $media_item->getSource()->getPluginDefinition()['default_thumbnail_filename']; + $default_thumb_uri = \Drupal::service('config.factory')->get('media.settings')->get('icon_base_uri') . '/' . $filename; + $source_thumb_uri = $media_item->getSource()->getMetadata($media_item, $media_item->getSource()->getPluginDefinition()['thumbnail_uri_metadata_attribute']); // Media thumbnail should be the default image. $this->assertEquals($default_thumb_uri, $media_item->get('thumbnail')->entity->getFileUri());