diff --git a/core/lib/Drupal/Component/Utility/DiffArray.php b/core/lib/Drupal/Component/Utility/DiffArray.php index 719049e..983c3f3 100644 --- a/core/lib/Drupal/Component/Utility/DiffArray.php +++ b/core/lib/Drupal/Component/Utility/DiffArray.php @@ -47,4 +47,35 @@ public static function diffAssocRecursive(array $array1, array $array2) { return $difference; } + /** + * Computes the difference of arrays. + * + * The main difference from the array_diff() is that this method does not + * remove duplicates. For example: + * @code + * array_diff([1, 1, 1], [1]); // [] + * \Drupal\Component\Utility\DiffArray::diffOnce([1, 1, 1], [1]) // [1, 1] + * @endcode + * + * Keys are maintained from the $array1. + * + * @param array $array1 + * The array to compare from. + * @param array $array2 + * The array to compare to. + * @param bool $strict + * The comparison mode. + * + * @return array + */ + public static function diffOnce(array $array1, array $array2, $strict = FALSE) { + foreach ($array2 as $array) { + $pos = array_search($array, $array1, $strict); + if ($pos !== FALSE) { + unset($array1[$pos]); + } + } + return $array1; + } + } diff --git a/core/modules/editor/editor.module b/core/modules/editor/editor.module index 21cf7a9..3bdf2cb 100644 --- a/core/modules/editor/editor.module +++ b/core/modules/editor/editor.module @@ -5,7 +5,9 @@ * Adds bindings for client-side "text editors" to text formats. */ +use Drupal\Component\Utility\DiffArray; use Drupal\Component\Utility\Html; +use Drupal\Core\Language\LanguageInterface; use Drupal\Core\TypedData\TranslatableInterface; use Drupal\editor\Entity\Editor; use Drupal\Core\Entity\FieldableEntityInterface; @@ -365,39 +367,19 @@ function editor_entity_update(EntityInterface $entity) { // File references that existed both in the previous version of the revision // and in the new one don't need their usage to be updated. else { + $original_uuids_by_field = _editor_get_file_uuids_by_field($entity->original); + $uuids_by_field = _editor_get_file_uuids_by_field($entity); - // When an entity is updated, any amount of its translations can be updated - // as well. Check them all. - $entities = [[$entity, $entity->original]]; - if ($entity instanceof TranslatableInterface) { - $entities = []; - foreach ($entity->getTranslationLanguages() as $langcode => $language) { - // If the original entity does not have a translation in the given - // language, it will be handled in editor_entity_translation_insert(). - if ($entity->original->hasTranslation($langcode)) { - $entities[] = [ - $entity->getTranslation($langcode), - $entity->original->getTranslation($langcode) - ]; - } - } + // Detect file usages that should be incremented. + foreach ($uuids_by_field as $field => $uuids) { + $added_files = DiffArray::diffOnce($uuids_by_field[$field], $original_uuids_by_field[$field]); + _editor_record_file_usage($added_files, $entity); } - foreach ($entities as list($entity, $entity_original)) { - $original_uuids_by_field = _editor_get_file_uuids_by_field($entity_original); - $uuids_by_field = _editor_get_file_uuids_by_field($entity); - - // Detect file usages that should be incremented. - foreach ($uuids_by_field as $field => $uuids) { - $added_files = array_diff($uuids_by_field[$field], $original_uuids_by_field[$field]); - _editor_record_file_usage($added_files, $entity); - } - - // Detect file usages that should be decremented. - foreach ($original_uuids_by_field as $field => $uuids) { - $removed_files = array_diff($original_uuids_by_field[$field], $uuids_by_field[$field]); - _editor_delete_file_usage($removed_files, $entity, 1); - } + // Detect file usages that should be decremented. + foreach ($original_uuids_by_field as $field => $uuids) { + $removed_files = DiffArray::diffOnce($original_uuids_by_field[$field], $uuids_by_field[$field]); + _editor_delete_file_usage($removed_files, $entity, 1); } } } @@ -431,28 +413,6 @@ function editor_entity_revision_delete(EntityInterface $entity) { } /** - * Implements hook_entity_translation_insert(). - */ -function editor_entity_translation_insert(EntityInterface $translation) { - // Process like entity insert. - editor_entity_insert($translation); -} - -/** - * Implements hook_entity_translation_delete(). - */ -function editor_entity_translation_delete(EntityInterface $translation) { - // Only act on content entities. - if (!($translation instanceof FieldableEntityInterface)) { - return; - } - $referenced_files_by_field = _editor_get_file_uuids_by_field($translation); - foreach ($referenced_files_by_field as $field => $uuids) { - _editor_delete_file_usage($uuids, $translation, 1); - } -} - -/** * Records file usage of files referenced by formatted text fields. * * Every referenced file that does not yet have the FILE_STATUS_PERMANENT state, @@ -499,21 +459,38 @@ function _editor_delete_file_usage(array $uuids, EntityInterface $entity, $count /** * Finds all files referenced (data-entity-uuid) by formatted text fields. * - * @param EntityInterface $entity + * @param FieldableEntityInterface $entity * An entity whose fields to analyze. * * @return array * An array of file entity UUIDs. */ -function _editor_get_file_uuids_by_field(EntityInterface $entity) { +function _editor_get_file_uuids_by_field(FieldableEntityInterface $entity) { $uuids = array(); + $field_definitions = $entity->getFieldDefinitions(); $formatted_text_fields = _editor_get_formatted_text_fields($entity); foreach ($formatted_text_fields as $formatted_text_field) { + + // In case of a translatable field, iterate over all its translations. + if ($field_definitions[$formatted_text_field]->isTranslatable() && $entity instanceof TranslatableInterface) { + $langcodes = array_keys($entity->getTranslationLanguages()); + } + else { + $langcodes = [LanguageInterface::LANGCODE_NOT_APPLICABLE]; + } + $text = ''; - $field_items = $entity->get($formatted_text_field); - foreach ($field_items as $field_item) { - $text .= $field_item->value; + foreach ($langcodes as $langcode) { + if ($langcode == LanguageInterface::LANGCODE_NOT_APPLICABLE) { + $field_items = $entity->get($formatted_text_field); + } + else { + $field_items = $entity->getTranslation($langcode)->get($formatted_text_field); + } + foreach ($field_items as $field_item) { + $text .= $field_item->value; + } } $uuids[$formatted_text_field] = _editor_parse_file_uuids($text); }