Loading core/modules/media/src/Entity/Media.php +24 −3 Original line number Diff line number Diff line Loading @@ -449,10 +449,31 @@ public function prepareSave() { $translation = $this->getTranslation($langcode); // Try to set fields provided by the media source and mapped in // media type config. $original = $this->getOriginal(); foreach ($translation->bundle->entity->getFieldMap() as $metadata_attribute_name => $entity_field_name) { // Only save value in the entity if the field is empty or if the // source field changed. if ($translation->hasField($entity_field_name) && ($translation->get($entity_field_name)->isEmpty() || $translation->hasSourceFieldChanged())) { if (!$translation->hasField($entity_field_name)) { continue; } $set_metadata = FALSE; // Only save value in the entity if the field is empty, or if the // source field changed from one non-empty value to another non-empty // value. // 1st scenario: field is empty, safely store metadata there. if ($translation->get($entity_field_name)->isEmpty()) { $set_metadata = TRUE; } else { // 2nd scenario: field is not empty, but the source field has // changed between two non-empty values. $original_source_field_empty = ($original instanceof MediaInterface) && $media_source->getSourceFieldValue($original) === NULL; $new_source_field_empty = $media_source->getSourceFieldValue($translation) === NULL; if (!$original_source_field_empty && !$new_source_field_empty && $translation->hasSourceFieldChanged()) { $set_metadata = TRUE; } } if ($set_metadata) { $translation->set($entity_field_name, $media_source->getMetadata($translation, $metadata_attribute_name)); } } Loading core/modules/media/tests/src/Kernel/MediaSourceTest.php +21 −0 Original line number Diff line number Diff line Loading @@ -216,6 +216,27 @@ public function testMetadataMapping(): void { $this->assertSame('Snowball', $media_source->getMetadata($media, $attribute_name), 'Value of the metadata attribute is not correct.'); $media->save(); $this->assertSame('Snowball', $media->get($field_name)->value, 'Metadata attribute was not mapped to the field.'); // Test that we only overwrite existing field values if the source changed // from a non-empty value to another non-empty value. $media = Media::create([ 'bundle' => $this->testMediaType->id(), // Force an empty source field. 'field_media_test' => NULL, $field_name => 'Some pre-existing value', ]); $media->save(); // After first save, the entity has the pre-existing value in the mapped // field. $this->assertSame('Some pre-existing value', $media->get($field_name)->value); \Drupal::state()->set('media_source_test_attributes', [ $attribute_name => ['title' => 'Attribute to map', 'value' => 'Snowball'], ]); // Change the source field value from NULL to something different. $media->set('field_media_test', 'some_new_value'); $media->save(); // Verify the pre-existing value was not overwritten. $this->assertSame('Some pre-existing value', $media->get($field_name)->value); } /** Loading Loading
core/modules/media/src/Entity/Media.php +24 −3 Original line number Diff line number Diff line Loading @@ -449,10 +449,31 @@ public function prepareSave() { $translation = $this->getTranslation($langcode); // Try to set fields provided by the media source and mapped in // media type config. $original = $this->getOriginal(); foreach ($translation->bundle->entity->getFieldMap() as $metadata_attribute_name => $entity_field_name) { // Only save value in the entity if the field is empty or if the // source field changed. if ($translation->hasField($entity_field_name) && ($translation->get($entity_field_name)->isEmpty() || $translation->hasSourceFieldChanged())) { if (!$translation->hasField($entity_field_name)) { continue; } $set_metadata = FALSE; // Only save value in the entity if the field is empty, or if the // source field changed from one non-empty value to another non-empty // value. // 1st scenario: field is empty, safely store metadata there. if ($translation->get($entity_field_name)->isEmpty()) { $set_metadata = TRUE; } else { // 2nd scenario: field is not empty, but the source field has // changed between two non-empty values. $original_source_field_empty = ($original instanceof MediaInterface) && $media_source->getSourceFieldValue($original) === NULL; $new_source_field_empty = $media_source->getSourceFieldValue($translation) === NULL; if (!$original_source_field_empty && !$new_source_field_empty && $translation->hasSourceFieldChanged()) { $set_metadata = TRUE; } } if ($set_metadata) { $translation->set($entity_field_name, $media_source->getMetadata($translation, $metadata_attribute_name)); } } Loading
core/modules/media/tests/src/Kernel/MediaSourceTest.php +21 −0 Original line number Diff line number Diff line Loading @@ -216,6 +216,27 @@ public function testMetadataMapping(): void { $this->assertSame('Snowball', $media_source->getMetadata($media, $attribute_name), 'Value of the metadata attribute is not correct.'); $media->save(); $this->assertSame('Snowball', $media->get($field_name)->value, 'Metadata attribute was not mapped to the field.'); // Test that we only overwrite existing field values if the source changed // from a non-empty value to another non-empty value. $media = Media::create([ 'bundle' => $this->testMediaType->id(), // Force an empty source field. 'field_media_test' => NULL, $field_name => 'Some pre-existing value', ]); $media->save(); // After first save, the entity has the pre-existing value in the mapped // field. $this->assertSame('Some pre-existing value', $media->get($field_name)->value); \Drupal::state()->set('media_source_test_attributes', [ $attribute_name => ['title' => 'Attribute to map', 'value' => 'Snowball'], ]); // Change the source field value from NULL to something different. $media->set('field_media_test', 'some_new_value'); $media->save(); // Verify the pre-existing value was not overwritten. $this->assertSame('Some pre-existing value', $media->get($field_name)->value); } /** Loading