* ),
* bundle_label = @Translation("Media type"),
* handlers = {
- * "storage" = "Drupal\Core\Entity\Sql\SqlContentEntityStorage",
+ * "storage" = "Drupal\media\MediaStorage",
* "view_builder" = "Drupal\Core\Entity\EntityViewBuilder",
* "list_builder" = "Drupal\media\MediaListBuilder",
* "access" = "Drupal\media\MediaAccessControlHandler",
* "add" = "Drupal\media\MediaForm",
* "edit" = "Drupal\media\MediaForm",
* "delete" = "Drupal\Core\Entity\ContentEntityDeleteForm",
+ * "delete-multiple-confirm" = "Drupal\Core\Entity\Form\DeleteMultipleForm",
* },
* "translation" = "Drupal\content_translation\ContentTranslationHandler",
* "views_data" = "Drupal\media\MediaViewsData",
* "canonical" = "/media/{media}",
* "collection" = "/admin/content/media",
* "delete-form" = "/media/{media}/delete",
+ * "delete-multiple-form" = "/media/delete",
* "edit-form" = "/media/{media}/edit",
* "revision" = "/media/{media}/revisions/{media_revision}/view",
* }
* {@inheritdoc}
*/
public function getName() {
- $name = $this->get('name');
+ $name = $this->getEntityKey('label');
- if ($name->isEmpty()) {
+ if (empty($name)) {
$media_source = $this->getSource();
return $media_source->getMetadata($this, $media_source->getPluginDefinition()['default_name_metadata_attribute']);
}
- else {
- return $name->value;
- }
+
+ return $name;
}
/**
* https://www.drupal.org/node/2878119
*/
protected function updateThumbnail($from_queue = FALSE) {
- $file_storage = \Drupal::service('entity_type.manager')->getStorage('file');
- $thumbnail_uri = $this->getThumbnailUri($from_queue);
- $existing = $file_storage->getQuery()
- ->condition('uri', $thumbnail_uri)
- ->execute();
-
- if ($existing) {
- $this->thumbnail->target_id = reset($existing);
- }
- else {
- /** @var \Drupal\file\FileInterface $file */
- $file = $file_storage->create(['uri' => $thumbnail_uri]);
- if ($owner = $this->getOwner()) {
- $file->setOwner($owner);
- }
- $file->setPermanent();
- $file->save();
- $this->thumbnail->target_id = $file->id();
- }
+ $this->thumbnail->target_id = $this->loadThumbnail($this->getThumbnailUri($from_queue))->id();
// Set the thumbnail alt.
$media_source = $this->getSource();
return $this;
}
+ /**
+ * Loads the file entity for the thumbnail.
+ *
+ * If the file entity does not exist, it will be created.
+ *
+ * @param string $thumbnail_uri
+ * (optional) The URI of the thumbnail, used to load or create the file
+ * entity. If omitted, the default thumbnail URI will be used.
+ *
+ * @return \Drupal\file\FileInterface
+ * The thumbnail file entity.
+ */
+ protected function loadThumbnail($thumbnail_uri = NULL) {
+ $values = [
+ 'uri' => $thumbnail_uri ?: $this->getDefaultThumbnailUri(),
+ ];
+
+ $file_storage = $this->entityTypeManager()->getStorage('file');
+
+ $existing = $file_storage->loadByProperties($values);
+ if ($existing) {
+ $file = reset($existing);
+ }
+ else {
+ /** @var \Drupal\file\FileInterface $file */
+ $file = $file_storage->create($values);
+ if ($owner = $this->getOwner()) {
+ $file->setOwner($owner);
+ }
+ $file->setPermanent();
+ $file->save();
+ }
+ return $file;
+ }
+
+ /**
+ * Returns the URI of the default thumbnail.
+ *
+ * @return string
+ * The default thumbnail URI.
+ */
+ protected function getDefaultThumbnailUri() {
+ $default_thumbnail_filename = $this->getSource()->getPluginDefinition()['default_thumbnail_filename'];
+ return \Drupal::config('media.settings')->get('icon_base_uri') . '/' . $default_thumbnail_filename;
+ }
+
/**
* Updates the queued thumbnail for the media item.
*
protected function getThumbnailUri($from_queue) {
$thumbnails_queued = $this->bundle->entity->thumbnailDownloadsAreQueued();
if ($thumbnails_queued && $this->isNew()) {
- $default_thumbnail_filename = $this->getSource()->getPluginDefinition()['default_thumbnail_filename'];
- $thumbnail_uri = \Drupal::service('config.factory')->get('media.settings')->get('icon_base_uri') . '/' . $default_thumbnail_filename;
+ return $this->getDefaultThumbnailUri();
}
elseif ($thumbnails_queued && !$from_queue) {
- $thumbnail_uri = $this->get('thumbnail')->entity->getFileUri();
- }
- else {
- $thumbnail_uri = $this->getSource()->getMetadata($this, $this->getSource()->getPluginDefinition()['thumbnail_uri_metadata_attribute']);
+ return $this->get('thumbnail')->entity->getFileUri();
}
- return $thumbnail_uri;
+ $source = $this->getSource();
+ return $source->getMetadata($this, $source->getPluginDefinition()['thumbnail_uri_metadata_attribute']);
}
/**
public function preSave(EntityStorageInterface $storage) {
parent::preSave($storage);
- $media_source = $this->getSource();
- foreach ($this->translations as $langcode => $data) {
- if ($this->hasTranslation($langcode)) {
- $translation = $this->getTranslation($langcode);
- // Try to set fields provided by the media source and mapped in
- // media type config.
- foreach ($translation->bundle->entity->getFieldMap() as $metadata_attribute_name => $entity_field_name) {
- // Only save value in entity field if empty. Do not overwrite existing
- // data.
- if ($translation->hasField($entity_field_name) && ($translation->get($entity_field_name)->isEmpty() || $translation->hasSourceFieldChanged())) {
- $translation->set($entity_field_name, $media_source->getMetadata($translation, $metadata_attribute_name));
- }
- }
-
- // Try to set a default name for this media item if no name is provided.
- if ($translation->get('name')->isEmpty()) {
- $translation->setName($translation->getName());
- }
-
- // Set thumbnail.
- if ($translation->shouldUpdateThumbnail()) {
- $translation->updateThumbnail();
- }
- }
+ // If no thumbnail has been explicitly set, use the default thumbnail.
+ if ($this->get('thumbnail')->isEmpty()) {
+ $this->thumbnail->target_id = $this->loadThumbnail()->id();
}
}
}
}
+ /**
+ * Sets the media entity's field values from the source's metadata.
+ *
+ * Fetching the metadata could be slow (e.g., if requesting it from a remote
+ * API), so this is called by \Drupal\media\MediaStorage::save() prior to it
+ * beginning the database transaction, whereas static::preSave() executes
+ * after the transaction has already started.
+ *
+ * @internal
+ * Expose this as an API in
+ * https://www.drupal.org/project/drupal/issues/2992426.
+ */
+ public function prepareSave() {
+ // @todo If the source plugin talks to a remote API (e.g. oEmbed), this code
+ // might be performing a fair number of HTTP requests. This is dangerously
+ // brittle and should probably be handled by a queue, to avoid doing HTTP
+ // operations during entity save. See
+ // https://www.drupal.org/project/drupal/issues/2976875 for more.
+
+ // In order for metadata to be mapped correctly, $this->original must be
+ // set. However, that is only set once parent::save() is called, so work
+ // around that by setting it here.
+ if (!isset($this->original) && $id = $this->id()) {
+ $this->original = $this->entityTypeManager()
+ ->getStorage('media')
+ ->loadUnchanged($id);
+ }
+
+ $media_source = $this->getSource();
+ foreach ($this->translations as $langcode => $data) {
+ if ($this->hasTranslation($langcode)) {
+ $translation = $this->getTranslation($langcode);
+ // Try to set fields provided by the media source and mapped in
+ // media type config.
+ foreach ($translation->bundle->entity->getFieldMap() as $metadata_attribute_name => $entity_field_name) {
+ // Only save value in entity field if empty. Do not overwrite existing
+ // data.
+ if ($translation->hasField($entity_field_name) && ($translation->get($entity_field_name)->isEmpty() || $translation->hasSourceFieldChanged())) {
+ $translation->set($entity_field_name, $media_source->getMetadata($translation, $metadata_attribute_name));
+ }
+ }
+
+ // Try to set a default name for this media item if no name is provided.
+ if ($translation->get('name')->isEmpty()) {
+ $translation->setName($translation->getName());
+ }
+
+ // Set thumbnail.
+ if ($translation->shouldUpdateThumbnail($this->isNew())) {
+ $translation->updateThumbnail();
+ }
+ }
+ }
+ }
+
/**
* {@inheritdoc}
*/