Verified Commit 1857ebff 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
parent 4da76f6b
Loading
Loading
Loading
Loading
Loading
+29 −0
Original line number Diff line number Diff line
@@ -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;
    });
}
+1 −0
Original line number Diff line number Diff line
@@ -61,6 +61,7 @@
 *   },
 *   constraints = {
 *     "ImmutableProperties" = {"id", "source"},
 *     "MediaMappingsConstraint" = { },
 *   }
 * )
 */
+6 −0
Original line number Diff line number Diff line
@@ -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();
        }
+27 −0
Original line number Diff line number Diff line
<?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.';

}
+47 −0
Original line number Diff line number Diff line
<?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.
      }
    }
  }

}
Loading