Change record status: 
Project: 
Introduced in branch: 
8.4.x
Introduced in version: 
8.4.0
Description: 

Moved the contributed Media Entity module to core as the new beta experimental Media module. On the way we reviewed each piece and made some key changes to the API compared to contrib which are detailed here. There are still crucial steps to make this useful for site builders and content creators as well, see the followup roadmap at https://www.drupal.org/node/2825215#followup-roadmap detailing the next steps.

This change record describes the API changes between the contributed Media Entity module and the Media core module to update custom modules. When upgrading an entire site, follow the FAQ - Transition from Media Entity to Media in core.

If you have a dependency on Media Entity...

  1. In your .info.yml file, replace any mention of media_entity with drupal:media (>= 8.4).
  2. In your .info.yml file, remove any dependencies to modules that will be removed after update. E.g media_entity_document and media_entity_image.
  3. If you have a composer.json file that requires drupal/media_entity, you can remove that dependency.
  4. Any automated tests that list media_entity in their $modules array should mention media instead.
  5. Automated tests that set up users (or user roles) with media-related permissions may need to be changed. See "Administrator-facing changes", below.

If you ship with icons for Media Entity...

  1. The media_entity_copy_icons() function was removed. For now modules providing icons should copy the hook_install() and hook_requirements() implementations from the media.install file and change it to copy their own icons to the directory specified by the media.settings:icon_base_uri config setting. A better way to handle this is being discussed at #2863438: Allow modules to declare the list of files it ships with that should be publicly accessible.

If you ship default configuration for Media Entity (install, optional, etc.)...

  1. If you have any media_entity.bundle.*.yml files in your default configuration, rename them to media.type.*.yml. For example: media_entity.bundle.tweet.ymlbecomes media.type.tweet.yml.
  2. In your media.type.*.yml files, change the top-level type and type_configuration keys to source and source_configuration, respectively.

If your site has base field overrides for media configurations (core.base_field_override.media.*.yml)

  1. If you have any core.base_field_override.media.*.yml files in your default configuration, replace any occurrences of default_value_callback: 'Drupal\media_entity\Entity\*' with default_value_callback: 'Drupal\media\Entity\*'. For example: default_value_callback: 'Drupal\media_entity\Entity\Media::getCurrentUserId' becomes default_value_callback: 'Drupal\media\Entity\Media::getCurrentUserId'.

If you have implemented any MediaType plugins...

  1. The plugin annotations must be @MediaSource, not @MediaType.
  2. The plugins must implement Drupal\media\MediaSourceInterface, or extend Drupal\media\MediaSourceBase.
  3. If you defined config schema for your plugins, change their identifiers from media_entity.bundle.type.PLUGIN_ID to media.source.PLUGIN_ID.
  4. The label() method has been removed. Set the 'label' key in the plugin annotation instead.
  5. The getField() method has been renamed to getMetadata(). Note that if you implement this method, make sure you return something for the attribute names: 'default_name' and 'thumbnail_uri'.
    If you are not implementing any specific logic for those, you probably want to do something like return parent::getMetadata($media, 'default_name'); and return parent::getMetadata($media, 'thumbnail_uri');, respectivelly.
  6. The attachConstraints() method has been removed and split across two new interfaces:
    Drupal\media\MediaSourceEntityConstraintsInterface
    This is for defining validation constraints that should be attached to media items which use this media source.
    Drupal\media\MediaSourceFieldConstraintsInterface
    This is for defining validation constraints that should be attached to the source field of media items which use this media source.

    Implement these interfaces as needed and separate the attachConstraints() logic accordingly.

  7. The thumbnail() method has been removed. Call $media_source->getMetadata($media_item, 'thumbnail_uri') instead.
  8. The getDefaultThumbnail() method has been removed. Set the 'default_thumbnail_filename' key in the plugin annotation instead.
  9. The getDefaultName() method has been removed. Set the 'default_name_metadata_attribute' key in the plugin annotation instead, which defines which metadata attribute contains the default name of the media item. If you don't set this key, 'default_name' will be used. This is equivalent to calling $media_source->getMetadata($media_item, 'default_name').
  10. The providedFields() method has been renamed to getMetadataAttributes().
  11. If you have implemented the buildConfigurationForm() method, please note that now the $form['source_field'] is handled in MediaSourceBase. If your method only provides this form element, you can entirely delete it. Otherwise, you should call parent::buildConfigurationForm() to get the 'source_field' element, and then add your additional elements to the form. If you had defined $allowed_field_types in the configuration form the field types defined here should be added to the annotation in allowed_field_types key.
  12. The trait \Drupal\media_entity\EmbedCodeValueTrait was removed. You should move it's single method to the class using the trait, or just move the part you need inline.
      /**
       * Extracts the raw embed code from input which may or may not be wrapped.
       *
       * @param mixed $value
       *   The input value. Can be a normal string or a value wrapped by the
       *   Typed Data API.
       *
       * @return string|null
       *   The raw embed code.
       */
      protected function getEmbedCode($value) {
        if (is_string($value)) {
          return $value;
        }
        elseif ($value instanceof FieldItemInterface) {
          $class = get_class($value);
          $property = $class::mainPropertyName();
          if ($property) {
            return $value->$property;
          }
        }
      }
    

If your code interacts with Media or MediaBundle entities...

  1. The media_bundle entity type is now called media_type.
  2. Replace all mentions of Drupal\media_entity\Entity\Media with Drupal\media\Entity\Media.
  3. Replace all mentions of Drupal\media_entity\Entity\MediaBundle with Drupal\media\Entity\MediaType.
  4. Replace all mentions of Drupal\media_entity\MediaAccessController with Drupal\media\MediaAccessControlHandler.
  5. The following methods of the Media entity class have been renamed:
    • getPublisher() is now getOwner()
    • getPublisherId() is now getOwnerId()
    • setPublisherId() is now setOwnerId()
    • getType() is now getSource()
    • automaticallySetThumbnail() is now updateQueuedThumbnail(). However, this is an internal method used by the queue worker which downloads thumbnails, so you should not call it directly. When a media item is saved, the thumbnail is automatically set if:
      • The media entity is new, OR
      • No thumbnail has been set yet (i.e., $media_item->set('thumbnail', $thumbnail)), OR
      • The source field value has changed

      This means that, if you set the thumbnail explicitly, then change the source field value, then save the media item, the thumbnail will be automatically updated and the thumbnail you have set will be overridden. Be aware.

  6. The following methods of the MediaBundle (now MediaType) class have been removed or renamed:
    • getLabel(): Use $media_item->bundle->entity->label() instead.
    • exists(): Use Drupal\media\Entity\MediaType::load() instead.
    • getStatus(): Use status() instead.
    • getType(): Use getSource() instead.
    • getTypeConfiguration(): Use get('source_configuration') instead.
    • getQueueThumbnailDownloads(): Use thumbnailDownloadsAreQueued() instead.
    • setQueueThumbnailDownloads(): Use setQueueThumbnailDownloadsStatus() instead.
    • setSourceConfiguration(): Use set('source_configuration', $configuration) instead.

Removed classes and interfaces

  • Drupal\media_entity\MediaStorageInterface
  • Drupal\media_entity\MediaStorage
  • Drupal\media_entity\MediaTypeException
  • Drupal\media_entity\Form\MediaDeleteForm

Administrator-facing changes

  1. The administer media bundles permission was renamed to administer media types.
  2. The access media overview permission is removed.

If your code interacts with MediaType plugins...

  1. The plugin.manager.media_entity.type service is replaced by plugin.manager.media.source.
  2. Replace all mentions of Drupal\media_entity\MediaTypeManager with Drupal\media\MediaSourceManager.

If your module implements hook_entity_type_insert() or alike for MediaBundle entities...

If your code interacts with MediaForm or MediaTypeForm...

Libraries provided by media module have been renamed, please see the change record for this: https://www.drupal.org/node/2889470

...and one more thing

Don't forget to account for these changes in your automated tests!

Impacts: 
Module developers

Comments

anavarre’s picture

For those willing to play with it before 8.5.x is released, there's indication about how to enable/patch Media at https://www.drupal.org/docs/8/core/modules/media/faq-transition-from-med...