Image Media thumbnail alt text cannot be changed without reuploading the image

Created on 10 September 2021, almost 3 years ago
Updated 30 April 2024, about 2 months ago

Problem/Motivation

Media entities have base field definitions for a thumbnail, which includes alt text.

For media types that use an image as their source field, they are essentially pointing at the same thing.

For media types that use an image field as their base (like the default Image media type), the source field and thumbnail point to the same file, but attributes like alt are stored in two different database tables.

When alt text is updated for the source field (without also changing the image), the alt text does NOT get updated on the thumbnail. This is confusing as the any view or display that renders the thumbnail will be using the original alt text that was provided, where as views or displays that render the source field will use the correct alt text.

Here's why it happens:

Media module has a built in mechanism for triggering an update to the thumbnail, but it's only triggered if it thinks the source field has changed:

  protected function shouldUpdateThumbnail($is_new = FALSE) {
    // Update thumbnail if we don't have a thumbnail yet or when the source
    // field value changes.
    return !$this->get('thumbnail')->entity || $is_new || $this->hasSourceFieldChanged();
  }

  protected function hasSourceFieldChanged() {
    $source = $this->getSource();
    return isset($this->original) && $source->getSourceFieldValue($this) !== $source->getSourceFieldValue($this->original);
  }

For Image source fields, it only checks if the main property has changed, which in this case is the reference to the file entity. So, it would trigger a thumbnail update if the user uploaded a different image, but not if the alt text on the image was changed.

Unfortunately, I don't even think there is a workaround available to manually refresh the thumbnail data until Expose triggering update of media metadata + thumbnail to end users Needs work gets in.

Steps to reproduce

  1. Install Media module
  2. Add an Image media entity with any image file and specify alt text
  3. Edit the image media entity and update the alt text and save
  4. Observe that in the media table view listing, the thumbnail image alt text uses the original alt text

Proposed resolution

What if the we leave it up to source field plugins to determine if their source field has changed? Right now the Media entity class determines this on their behalf but that doesn't seem right. Individual source plugins know best about their sources and what constitutes a change.

Media module could expand hasSourceFieldChanged to ask the source if it's changed as well.

Remaining tasks

User interface changes

API changes

Data model changes

Release notes snippet

🐛 Bug report
Status

Needs work

Version

11.0 🔥

Component
Media 

Last updated about 1 hour ago

Created by

🇺🇸United States bkosborne New Jersey, USA

Live updates comments and jobs are added and updated live.
  • Accessibility

    It affects the ability of people with disabilities or special needs (such as blindness or color-blindness) to use Drupal.

Sign in to follow issues

Comments & Activities

Not all content is available!

It's likely this issue predates Contrib.social: some issue and comment data are missing.

  • 🇵🇹Portugal introfini

    Thanks @Juanjol, this bug was driving me crazy!

  • 🇨🇦Canada mmaranao Calgary, AB

    The work around from @Juanjol worked for me as well! Is there a fix yet for tranlations?

  • Status changed to Needs review about 1 year ago
  • Here's a first patch for this, it implements the solution proposed in the IS, so far it comes without any tests.

  • 🇮🇳India TanujJain-TJ

    Fixed CCF on #16, keeping the status to needs work as it still needs tests.

  • Status changed to Needs work about 1 year ago
  • 🇮🇳India Akram Khan Cuttack, Odisha

    adding updated patch and to fix the error

  • 🇧🇪Belgium joevagyok

    The patch fails because there is a specific assertion in the test to ensure that changing non-primary properties like the "alt" will not trigger an update implemented in this issue here: #3192059: Use the source field main property to determine if the source field has changed

    By doing this, we are going against that requirement. However, looking into and focus on the related issue here: Expose triggering update of media metadata + thumbnail to end users Needs work would bring us closer to a more robust solution. I would say let's focus on that, since we have a workaround in #8 for the meantime.

  • 🇫🇮Finland iamfredrik

    I tried implementing the presave function in #8 but couldn't get it to work. I put the code from #8 in mymodule/src/MediaImage.php, and then the following code in mymodule.module.

     use Drupal\Core\Entity\EntityTypeInterface;
     use Drupal\Core\Entity\EntityTypeManagerInterface;
    
    function mymodule_entity_type_build(array &$entity_types) {
      if (isset($entity_types['media'])) {
        $entity_types['media']->setClass('Drupal\mymodule\Entity\MediaImage');
      }
    }

    Help with implementing the workaround correctly would be much appreciated.

  • 🇺🇸United States PapaGrande

    @iamfredrik, I implemented @Juanjol's "rather messy workaround" in #8 (the first one) and it's working just fine. I suggest going with that until we can get this issue resolved.

  • 🇫🇮Finland iamfredrik

    @PapaGrande, I tried both workarounds and none of them worked.

  • 🇺🇸United States rex.barkdoll

    Hi all,
    I've been trying to implement this and nothing is working.

    I've created my own module, but nothing in #8 is doing anything (assuming I put the code in the .module file).

    I've also tried the patches and they don't apply. I'm trying to apply them to drupal/media, so let me know if that's incorrect.
    Thanks for any insight or help you can provide.

  • 🇺🇸United States ian.ssu

    @rec.barkdoll #8 seems to work for me in Drupal 10.2.x I've added a check to prevent warning with other media types (i.e document).

    my_module.module

    /**
     * Implements hook_ENTITY_TYPE_presave().
     */
    function my_module_media_presave(EntityInterface $entity): void {
      /** @var \Drupal\media\Entity\Media $entity */
      if ($entity->bundle() === 'image'
        && $entity->hasField('thumbnail')
        && $entity->hasField('field_media_image')
      ) {
        $entity->thumbnail->alt = $entity->field_media_image->alt;
      }
    }
    
Production build 0.69.0 2024