Skip to content
Snippets Groups Projects
Verified Commit 7c2638e2 authored by Alex Pott's avatar Alex Pott
Browse files

Issue #3271688 by smustgrave, larowlan, phenaproxima, borisson_, ravi.shankar,...

Issue #3271688 by smustgrave, larowlan, phenaproxima, borisson_, ravi.shankar, dianacastillo, TimoZura: Remove source from media mappings

(cherry picked from commit 1857ebff)
parent a1e704d7
No related branches found
No related tags found
32 merge requests!13092Issue #3498963 by benjifisher, heddn: Add lookup_migrations configuration to...,!12802Issue #3537193 by opauwlo: Add enable absolute path option for CKEditor5 image uploads,!12745Fixed: Path alias language doesn't changes on changing of node language,!12684Issue #3220784,!12537Add ViewsConfigUpdater deprecation support for default_argument_skip_url,!12523Issue #3493858 by vidorado, xavier.masson, smustgrave: Extend ViewsBlockBase...,!122353526426-warning-for-missing,!12212Issue #3445525 by alexpott, japerry, catch, mglaman, longwave: Add BC layer...,!11958Issue #3490507 by alexpott, smustgrave: Fix bogus mocking in...,!11769Issue #3517987: Add option to contextual filters to encode slashes in query parameter.,!11185Issue #3477324 by andypost, alexpott: Fix usage of str_getcsv() and fgetcsv() for PHP 8.4,!10602Issue #3438769 by vinmayiswamy, antonnavi, michelle, amateescu: Sub workspace does not clear,!10301Issue #3469309 by mstrelan, smustgrave, moshe weitzman: Use one-time login...,!10187Issue #3487488 by dakwamine: ExtensionMimeTypeGuesser::guessMimeType must support file names with "0" (zero) like foo.0.zip,!9944Issue #3483353: Consider making the createCopy config action optionally fail...,!9929Issue #3445469 by pooja_sharma, smustgrave: Add additional test coverage for...,!9787Resolve issue 3479427 - bootstrap barrio issue under Windows,!9742Issue #3463908 by catch, quietone: Split OptionsFieldUiTest into two,!9526Issue #3458177 by mondrake, catch, quietone, godotislate, longwave, larowlan,...,!8738Issue #3424162 by camilledavis, dineshkumarbollu, smustgrave: Claro...,!8704Make greek characters available in ckeditor5,!8597Draft: Issue #3442259 by catch, quietone, dww: Reduce time of Migrate Upgrade tests...,!8533Issue #3446962 by kim.pepper: Remove incorrectly added...,!8517Issue #3443748 by NexusNovaz, smustgrave: Testcase creates false positive,!8325Update file Sort.php,!8095Expose document root on install,!7930Resolve #3427374 "Taxonomytid viewsargumentdefault plugin",!7627Issue #3439440 by nicxvan, Binoli Lalani, longwave: Remove country support from DateFormatter,!7445Issue #3440169: When using drupalGet(), provide an associative array for $headers,!6502Draft: Resolve #2938524 "Plach testing issue",!38582585169-10.1.x,!3226Issue #2987537: Custom menu link entity type should not declare "bundle" entity key
Pipeline #146223 passed with warnings
Pipeline: drupal

#146243

    Pipeline: drupal

    #146229

      ......@@ -8,6 +8,7 @@
      use Drupal\Core\Config\Entity\ConfigEntityUpdater;
      use Drupal\Core\Entity\Display\EntityViewDisplayInterface;
      use Drupal\media\MediaConfigUpdater;
      use Drupal\media\MediaTypeInterface;
      /**
      * Implements hook_removed_post_updates().
      ......@@ -45,3 +46,31 @@ function media_post_update_set_blank_iframe_domain_to_null() {
      ->save(TRUE);
      }
      }
      /**
      * Make sure no Media types are using the source field in the meta mappings.
      */
      function media_post_update_remove_mappings_targeting_source_field(array &$sandbox = NULL): void {
      \Drupal::classResolver(ConfigEntityUpdater::class)
      ->update($sandbox, 'media_type', function (MediaTypeInterface $media_type): bool {
      $source_field = $media_type->getSource()
      ->getSourceFieldDefinition($media_type);
      if ($source_field) {
      $source_field_name = $source_field->getName();
      $original_field_map = $media_type->getFieldMap();
      $field_map = array_diff($original_field_map, [$source_field_name]);
      // Check if old field map matches new field map.
      if (empty(array_diff($original_field_map, $field_map))) {
      return FALSE;
      }
      $media_type->setFieldMap($field_map);
      return TRUE;
      }
      return FALSE;
      });
      }
      ......@@ -61,6 +61,7 @@
      * },
      * constraints = {
      * "ImmutableProperties" = {"id", "source"},
      * "MediaMappingsConstraint" = { },
      * }
      * )
      */
      ......
      ......@@ -176,7 +176,13 @@ public function form(array $form, FormStateInterface $form_state) {
      }
      else {
      $options = [MediaSourceInterface::METADATA_FIELD_EMPTY => $this->t('- Skip field -')];
      $source_field_name = $source->getSourceFieldDefinition($this->entity)?->getName();
      foreach ($this->entityFieldManager->getFieldDefinitions('media', $this->entity->id()) as $field_name => $field) {
      // The source field cannot be the target of a field mapping, because
      // this would cause it to be overwritten, probably with invalid data.
      if ($field_name === $source_field_name) {
      continue;
      }
      if (!($field instanceof BaseFieldDefinition) || $field_name === 'name') {
      $options[$field_name] = $field->getLabel();
      }
      ......
      <?php
      namespace Drupal\media\Plugin\Validation\Constraint;
      use Symfony\Component\Validator\Constraint;
      /**
      * Validates media mappings.
      *
      * @internal
      *
      * @Constraint(
      * id = "MediaMappingsConstraint",
      * label = @Translation("Media Mapping Constraint", context = "Validation"),
      * type = {"string"}
      * )
      */
      class MediaMappingsConstraint extends Constraint {
      /**
      * The error message if source is used in media mapping.
      *
      * @var string
      */
      public string $invalidMappingMessage = 'It is not possible to map the source field @source_field_name of a media type.';
      }
      <?php
      namespace Drupal\media\Plugin\Validation\Constraint;
      use Drupal\Component\Plugin\Exception\PluginException;
      use Drupal\media\MediaTypeInterface;
      use Symfony\Component\Validator\Constraint;
      use Symfony\Component\Validator\ConstraintValidator;
      use Symfony\Component\Validator\Exception\UnexpectedTypeException;
      /**
      * Validates media mappings.
      */
      class MediaMappingsConstraintValidator extends ConstraintValidator {
      /**
      * {@inheritdoc}
      */
      public function validate($value, Constraint $constraint) {
      if (!$constraint instanceof MediaMappingsConstraint) {
      throw new UnexpectedTypeException($constraint, __NAMESPACE__ . '\MediaMappingsConstraint');
      }
      if (!$value instanceof MediaTypeInterface) {
      throw new UnexpectedTypeException($value, MediaTypeInterface::class);
      }
      // The source field cannot be the target of a field mapping because that
      // would cause it to be overwritten, possibly with invalid data. This is
      // also enforced in the UI.
      if (is_array($value->getFieldMap())) {
      try {
      $source_field_name = $value->getSource()
      ->getSourceFieldDefinition($value)
      ?->getName();
      if (in_array($source_field_name, $value->getFieldMap(), TRUE)) {
      $this->context->addViolation($constraint->invalidMappingMessage, [
      '@source_field_name' => $source_field_name,
      ]);
      }
      }
      catch (PluginException) {
      // The source references an invalid plugin.
      }
      }
      }
      }
      <?php
      declare(strict_types=1);
      namespace Drupal\Tests\media\Functional\Update;
      use Drupal\FunctionalTests\Update\UpdatePathTestBase;
      use Drupal\media\Entity\MediaType;
      use Drupal\media\Plugin\media\Source\File;
      use Drupal\Tests\media\Traits\MediaTypeCreationTrait;
      /**
      * Tests update functions for the Media module.
      *
      * @group media
      */
      class MediaMappingUpdateTest extends UpdatePathTestBase {
      use MediaTypeCreationTrait;
      /**
      * {@inheritdoc}
      */
      protected function setDatabaseDumpFiles(): void {
      $this->databaseDumpFiles = [
      $this->getDrupalRoot() . '/core/modules/system/tests/fixtures/update/drupal-9.4.0.bare.standard.php.gz',
      __DIR__ . '/../../../fixtures/update/media.php',
      ];
      }
      /**
      * {@inheritdoc}
      */
      protected function setUp(): void {
      parent::setUp();
      /** @var \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager */
      $entity_type_manager = $this->container->get('entity_type.manager');
      /** @var \Drupal\Core\Entity\EntityDefinitionUpdateManagerInterface $update_manager */
      $update_manager = $this->container->get('entity.definition_update_manager');
      $entity_type = $entity_type_manager->getDefinition('media_type');
      $update_manager->installEntityType($entity_type);
      $entity_type = $entity_type_manager->getDefinition('media');
      $update_manager->installEntityType($entity_type);
      }
      /**
      * Tests updating Media types using source field in meta mappings.
      *
      * @see media_post_update_remove_mappings_targeting_source_field()
      */
      public function testMediaMappingUpdate(): void {
      $media_type = $this->createMediaType('image', ['id' => 'invalid_mapping']);
      $source_field_name = $media_type->getSource()
      ->getSourceFieldDefinition($media_type)
      ->getName();
      $field_map = $media_type->getFieldMap();
      $field_map[File::METADATA_ATTRIBUTE_MIME] = $source_field_name;
      $this->config($media_type->getConfigDependencyName())
      ->set('field_map', $field_map)
      ->save();
      $this->runUpdates();
      $this->container->get('entity_type.manager')
      ->getStorage('media_type')
      ->resetCache(['invalid_mapping']);
      $field_map = MediaType::load('invalid_mapping')?->getFieldMap();
      $this->assertIsArray($field_map);
      $this->assertNotContains($source_field_name, $field_map);
      }
      }
      ......@@ -107,11 +107,13 @@ public function testMediaTypeCreationFormWithDefaultField() {
      $assert_session->pageTextContains('The media source cannot be changed after the media type is created.');
      // Check that the field map options are sorted alphabetically.
      // Source field should not be included.
      $options = $this->xpath('//select[@name="field_map[attribute_1]"]/option');
      $this->assertGreaterThanOrEqual(3, count($options));
      $this->assertGreaterThanOrEqual(2, count($options));
      $this->assertSame('- Skip field -', $options[0]->getText());
      $this->assertSame('Name', $options[1]->getText());
      $this->assertSame('Test source', $options[2]->getText());
      // It should not be possible to map the source field.
      $assert_session->optionNotExists('field_map[attribute_1]', 'Test source');
      // Open up the media add form and verify that the source field is right
      // after the name, and before the vertical tabs.
      ......
      <?php
      declare(strict_types=1);
      namespace Drupal\Tests\media\Kernel;
      use Drupal\KernelTests\KernelTestBase;
      use Drupal\media\Plugin\media\Source\File;
      use Drupal\Tests\media\Traits\MediaTypeCreationTrait;
      use Symfony\Component\Validator\ConstraintViolationListInterface;
      /**
      * @coversDefaultClass \Drupal\media\Plugin\Validation\Constraint\MediaMappingsConstraintValidator
      *
      * @group media
      */
      class MediaMappingsConstraintValidatorTest extends KernelTestBase {
      use MediaTypeCreationTrait;
      /**
      * {@inheritdoc}
      */
      protected static $modules = ['field', 'file', 'image', 'media', 'user'];
      /**
      * {@inheritdoc}
      */
      protected function setUp(): void {
      parent::setUp();
      $this->installEntitySchema('file');
      $this->installEntitySchema('user');
      }
      /**
      * @covers ::validate
      */
      public function testMediaMappingSource() {
      $media_type = $this->createMediaType('image', [
      'id' => 'test',
      ]);
      $source_field_name = $media_type->getSource()
      ->getSourceFieldDefinition($media_type)
      ->getName();
      $field_map = $media_type->getFieldMap();
      $field_map[File::METADATA_ATTRIBUTE_MIME] = $source_field_name;
      $media_type->setFieldMap($field_map);
      $media_type->save();
      $typed_data = $this->container->get('typed_data_manager');
      $definition = $typed_data->createDataDefinition('entity:media_type');
      $violations = $typed_data->create($definition, $media_type)->validate();
      assert($violations instanceof ConstraintViolationListInterface);
      $this->assertCount(1, $violations);
      $this->assertEquals('It is not possible to map the source field ' . $source_field_name . ' of a media type.', $violations[0]->getMessage());
      }
      }
      0% Loading or .
      You are about to add 0 people to the discussion. Proceed with caution.
      Please to comment