Quantcast
Channel: Issues for Drupal core
Viewing all articles
Browse latest Browse all 295112

$entity->isDefaultTranslation() behaves incorrectly when changing default translation, causing file/image field usage to be set to zero, causing files to be deleted

$
0
0

Problem/Motivation

Images uploaded to an image field are lost when the node language is changed (because file usage incorrectly drops down to zero, causing the permanent file to be marked temporary, and then eventually being deleted — after 6 hours by default).

Same for files uploaded to a file field.

Steps to reproduce

  1. create a content type with an image field
  2. enable >=2 languages in site
  3. set the content translatable (tested setting the file translatable or not)
  4. create a node with an image and save it
  5. verify that the uploaded file has its status column in the file_managed table set to 1,
    and it has 1 usage in the file_usage table
  6. edit the node and change the language
    • expected result: the uploaded file still has its status column in the file_managed table set to 1, and it has 1 usage in the file_usage table
    • actual result: the uploaded file now has its status column in the file_managed table set to 0, and it has 0 usage in the file_usage table
  7. run cron 6 hours later (this is the default value of the temporary_maximum_age setting in system.file)
    • expected result: the uploaded file is still present (because usage > 0)
    • actual result: the uploaded file is absent (because usage = 0)

Note: see #40, where it is explained how this same problem is even reproducible on sites without content_translation are affected by this, merely having the language (Interface translation) module installed and having >1 interface language enabled is sufficient to reproduce this problem for image/file fields on User entities!

Proposed resolution

Root cause analysis:

  • \Drupal\file\Plugin\Field\FieldType\FileFieldItemList::delete() removing file usages:
      public function delete() {
        parent::delete();
        $entity = $this->getEntity();
    
        // If a translation is deleted only decrement the file usage by one. If the
        // default translation is deleted remove all file usages within this entity.
        $count = $entity->isDefaultTranslation() ? 0 : 1;
        foreach ($this->referencedEntities() as $file) {
          \Drupal::service('file.usage')->delete($file, 'file', $entity->getEntityTypeId(), $entity->id(), $count);
        }
      }
    
  • to delete file usages, it relies on $entity->isDefaultTranslation() (i.e. \Drupal\Core\TypedData\TranslatableInterface::isDefaultTranslation()) to determine whether a translation is being deleted or not
  • $entity->isDefaultTranslation() behaves incorrectly when the default translation is being changed

Therefore the solution is: fix \Drupal\Core\Entity\ContentEntityBase::isDefaultTranslation().

Remaining tasks

TBD

User interface changes

None.

API changes

None.

Data model changes

None.


Viewing all articles
Browse latest Browse all 295112

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>