From cd735be4dd57b4ded6b5e10477d9c5078472cd75 Mon Sep 17 00:00:00 2001 From: Alex Pott Date: Thu, 14 Oct 2021 13:33:22 +0100 Subject: [PATCH] Issue #2974156 by MegaChriz, k4v, John.nie, jian he, darrenwh, jurgenhaas, daffie, DuneBL, alexpott: TypeError: Argument 1 passed to _editor_get_file_uuids_by_field() must implement interface Drupal\Core\Entity\EntityInterface --- core/modules/editor/editor.module | 12 +++- .../editor/tests/modules/editor_test.module | 36 ++++++++++ .../tests/src/Kernel/EntityUpdateTest.php | 68 +++++++++++++++++++ 3 files changed, 113 insertions(+), 3 deletions(-) create mode 100644 core/modules/editor/tests/src/Kernel/EntityUpdateTest.php diff --git a/core/modules/editor/editor.module b/core/modules/editor/editor.module index 3031931afec..6e52d9e3655 100644 --- a/core/modules/editor/editor.module +++ b/core/modules/editor/editor.module @@ -396,13 +396,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); + $original_uuids_by_field = empty($entity->original) ? [] : + _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); + $original_uuids = isset($original_uuids_by_field[$field]) ? + $original_uuids_by_field[$field] : []; + + if ($added_files = array_diff($uuids_by_field[$field], $original_uuids)) { + _editor_record_file_usage($added_files, $entity); + } } // Detect file usages that should be decremented. diff --git a/core/modules/editor/tests/modules/editor_test.module b/core/modules/editor/tests/modules/editor_test.module index 70fe59fa415..bdb7292d62a 100644 --- a/core/modules/editor/tests/modules/editor_test.module +++ b/core/modules/editor/tests/modules/editor_test.module @@ -5,9 +5,45 @@ * Helper module for the Text Editor tests. */ +use Drupal\Core\Entity\EntityInterface; +use Drupal\node\NodeInterface; use Drupal\filter\FilterFormatInterface; use Drupal\file\FileInterface; +/** + * Implements hook_entity_update(). + * + * @see \Drupal\Tests\editor\Kernel\EntityUpdateTest + */ +function editor_test_entity_update(EntityInterface $entity) { + // Only act on nodes. + if (!$entity instanceof NodeInterface) { + return; + } + + // Avoid infinite loop by only going through our post save logic once. + if (!empty($entity->editor_test_updating)) { + return; + } + + // Set flag for whether or not the entity needs to be resaved. + $needs_update = FALSE; + + // Perform our post save logic. + if ($entity->title->value == 'test updated') { + // Change the node title. + $entity->title->value = 'test updated 2'; + $needs_update = TRUE; + } + + if ($needs_update) { + // Set flag on entity that our logic was already executed. + $entity->editor_test_updating = TRUE; + // And resave entity. + $entity->save(); + } +} + /** * Implements hook_editor_js_settings_alter(). */ diff --git a/core/modules/editor/tests/src/Kernel/EntityUpdateTest.php b/core/modules/editor/tests/src/Kernel/EntityUpdateTest.php new file mode 100644 index 00000000000..1a454ea349e --- /dev/null +++ b/core/modules/editor/tests/src/Kernel/EntityUpdateTest.php @@ -0,0 +1,68 @@ +installSchema('node', ['node_access']); + $this->installConfig(['node']); + + // Create a node type for testing. + $type = NodeType::create(['type' => 'page', 'name' => 'page']); + $type->save(); + + // Set editor_test module weight to be lower than editor module's weight so + // that editor_test_entity_update() is called before editor_entity_update(). + $extension_config = \Drupal::configFactory()->get('core.extension'); + $editor_module_weight = $extension_config->get('module.editor'); + module_set_weight('editor_test', $editor_module_weight - 1); + } + + /** + * Tests updating an existing entity. + * + * @see editor_test_entity_update() + */ + public function testEntityUpdate() { + // Create a node. + $node = Node::create([ + 'type' => 'page', + 'title' => 'test', + ]); + $node->save(); + + // Update the node. + // What happens is the following: + // 1. \Drupal\Core\Entity\EntityStorageBase::doPostSave() gets called. + // 2. editor_test_entity_update() gets called. + // 3. A resave of the updated entity gets triggered (second save call). + // 4. \Drupal\Core\Entity\EntityStorageBase::doPostSave() gets called. + // 5. editor_test_entity_update() gets called. + // 6. editor_entity_update() gets called (caused by the second save call). + // 7. editor_entity_update() gets called (caused by the first save call). + $node->title->value = 'test updated'; + $node->save(); + } + +}