From 6d5e083a7730d542986b5c07667e856512a2b35f Mon Sep 17 00:00:00 2001
From: Alex Pott <alex.a.pott@googlemail.com>
Date: Tue, 19 Jan 2021 09:51:56 +0000
Subject: [PATCH] Issue #3192059 by chr.fritsch, Abhijith S, phenaproxima,
 alexpott: Use the source field main property to determine if the source field
 has changed

---
 core/modules/media/src/Entity/Media.php       | 10 ++-
 .../src/Functional/MediaSourceImageTest.php   | 76 +++++++++++++++++++
 2 files changed, 83 insertions(+), 3 deletions(-)
 create mode 100644 core/modules/media/tests/src/Functional/MediaSourceImageTest.php

diff --git a/core/modules/media/src/Entity/Media.php b/core/modules/media/src/Entity/Media.php
index 55ffb8a6a6d3..6649cccfd069 100644
--- a/core/modules/media/src/Entity/Media.php
+++ b/core/modules/media/src/Entity/Media.php
@@ -261,15 +261,19 @@ protected function getThumbnailUri($from_queue) {
   /**
    * Determines if the source field value has changed.
    *
+   * The comparison uses MediaSourceInterface::getSourceFieldValue() to ensure
+   * that the correct property from the source field is used.
+   *
    * @return bool
    *   TRUE if the source field value changed, FALSE otherwise.
    *
+   * @see \Drupal\media\MediaSourceInterface::getSourceFieldValue()
+   *
    * @internal
    */
   protected function hasSourceFieldChanged() {
-    $source_field_name = $this->getSource()->getConfiguration()['source_field'];
-    $current_items = $this->get($source_field_name);
-    return isset($this->original) && !$current_items->equals($this->original->get($source_field_name));
+    $source = $this->getSource();
+    return isset($this->original) && $source->getSourceFieldValue($this) !== $source->getSourceFieldValue($this->original);
   }
 
   /**
diff --git a/core/modules/media/tests/src/Functional/MediaSourceImageTest.php b/core/modules/media/tests/src/Functional/MediaSourceImageTest.php
new file mode 100644
index 000000000000..fabde4bfb22f
--- /dev/null
+++ b/core/modules/media/tests/src/Functional/MediaSourceImageTest.php
@@ -0,0 +1,76 @@
+<?php
+
+namespace Drupal\Tests\media\Functional;
+
+use Drupal\field\Entity\FieldConfig;
+use Drupal\file\Entity\File;
+use Drupal\media\Entity\Media;
+use Drupal\Tests\TestFileCreationTrait;
+
+/**
+ * Tests the image media source.
+ *
+ * @group media
+ */
+class MediaSourceImageTest extends MediaFunctionalTestBase {
+
+  use TestFileCreationTrait;
+
+  /**
+   * {@inheritdoc}
+   */
+  protected $defaultTheme = 'stark';
+
+  /**
+   * Test that non-main properties do not trigger source field value change.
+   */
+  public function testOnlyMainPropertiesTriggerSourceFieldChanged() {
+    $assert_session = $this->assertSession();
+    $page = $this->getSession()->getPage();
+
+    $media_type = $this->createMediaType('image');
+    $media_type_id = $media_type->id();
+    $media_type->setFieldMap(['name' => 'name']);
+    $media_type->save();
+
+    /** @var \Drupal\field\FieldConfigInterface $field */
+    // Disable the alt text field, because this is not a JavaScript test and
+    // the alt text field will therefore not appear without a full page refresh.
+    $field = FieldConfig::load("media.$media_type_id.field_media_image");
+    $settings = $field->getSettings();
+    $settings['alt_field'] = TRUE;
+    $settings['alt_field_required'] = FALSE;
+    $field->set('settings', $settings);
+    $field->save();
+
+    $file = File::create([
+      'uri' => $this->getTestFiles('image')[0]->uri,
+    ]);
+    $file->save();
+
+    $media = Media::create([
+      'name' => 'Custom name',
+      'bundle' => $media_type_id,
+      'field_media_image' => $file->id(),
+    ]);
+    $media->save();
+
+    // Change only the alt of the image.
+    $this->drupalGet($media->toUrl('edit-form'));
+    $this->submitForm(['field_media_image[0][alt]' => 'Alt text'], 'Save');
+
+    // Custom name should stay.
+    $this->drupalGet($media->toUrl('edit-form'));
+    $assert_session->fieldValueEquals('name[0][value]', 'Custom name');
+
+    // Remove image and attach a new one.
+    $this->submitForm([], 'Remove');
+    $image_media_name = 'example_1.jpeg';
+    $page->attachFileToField('files[field_media_image_0]', $this->root . '/core/modules/media/tests/fixtures/' . $image_media_name);
+    $page->pressButton('Save');
+
+    $this->drupalGet($media->toUrl('edit-form'));
+    $assert_session->fieldValueEquals('name[0][value]', 'example_1.jpeg');
+  }
+
+}
-- 
GitLab