diff --git a/core/modules/comment/tests/modules/comment_test/src/CommentTestSqlEntityStorage.php b/core/modules/comment/tests/modules/comment_test/src/CommentTestSqlEntityStorage.php new file mode 100644 index 0000000000..94d3e46444 --- /dev/null +++ b/core/modules/comment/tests/modules/comment_test/src/CommentTestSqlEntityStorage.php @@ -0,0 +1,61 @@ +database->select('comment_field_data', 'c'); + $query->addExpression('MAX(cid)', 'cid_max'); + $query->addExpression('MAX(pid)', 'pid_max'); + $query->addExpression('MAX(uid)', 'uid_max'); + $query->addExpression('MAX(entity_id)', 'entity_id_max'); + $row = $query->execute()->fetchObject(); + if (!isset($row->pid_max) && isset($row->cid_max)) { + $row->pid_max = $row->cid_max; + } + + if (empty($comment_ids) && isset($row->cid_max)) { + $comment_ids = [$row->cid_max]; + } + + if (!empty($comment_ids)) { + $update_values = [ + 'entity_id' => $row->entity_id_max + 1, + 'pid' => $row->pid_max + 1, + 'uid' => $row->uid_max + 1, + ]; + if ($fields) { + $update_values = array_intersect_key($update_values, array_flip($fields)); + } + $this->database->update('comment_field_data') + ->fields($update_values) + ->condition('cid', $comment_ids) + ->execute(); + + $this->resetCache(); + } + } + +} diff --git a/core/modules/comment/tests/src/Functional/CommentOrphanedTest.php b/core/modules/comment/tests/src/Functional/CommentOrphanedTest.php new file mode 100644 index 0000000000..d7afe3e205 --- /dev/null +++ b/core/modules/comment/tests/src/Functional/CommentOrphanedTest.php @@ -0,0 +1,98 @@ +getStorage('comment'); + $this->assertInstanceOf(SqlEntityStorageInterface::class, $storage); + + $session = $this->assertSession(); + + // Make sure we have a comment. + $this->drupalLogin($this->webUser); + $comment_text = $this->randomMachineName(); + $subject = $this->randomMachineName(); + $this->postComment($this->node, $comment_text, $subject); + + $this->drupalGet('node/' . $this->node->id()); + $session->pageTextContains($comment_text); + $session->pageTextContains($subject); + + // Make the comment an orphan. + $original_class = get_class($storage); + $manager->clearCachedDefinitions(); + $manager->getDefinition('comment') + ->setStorageClass('Drupal\comment_test\CommentTestSqlEntityStorage'); + + $storage = $manager->getStorage('comment'); + // Invalidate the author/parent comment, not the commented entity. + $storage->orphanComments([], ['pid', 'uid']); + + // Render the entity, with orphaned comment, implicitly testing that + // nothing breaks. + $this->drupalGet('node/' . $this->node->id()); + $session->pageTextContains($comment_text); + $session->pageTextContains($subject); + + $ids = $storage->orphanComments(); + + // Load, render (standalone without commented entity) and delete comments, + // implicitly testing that nothing breaks when the commented entity is not + // available. This does not have a current practical application (there + // are no standalone 'comment pages') but it ensures some decoupling of + // the comment view/render code, which is a good thing in itself. + $entities = $storage->loadMultiple($ids); + $storage->delete($entities); + $manager->clearCachedDefinitions(); + $manager->getDefinition('comment')->setStorageClass($original_class); + + $this->drupalGet('node/' . $this->node->id()); + $session->pageTextNotContains($comment_text); + $session->pageTextNotContains($subject); + } + +} diff --git a/core/modules/rdf/rdf.module b/core/modules/rdf/rdf.module index 92cc337fc1..c280a213f6 100644 --- a/core/modules/rdf/rdf.module +++ b/core/modules/rdf/rdf.module @@ -237,12 +237,13 @@ function rdf_comment_storage_load($comments) { ->getPreparedFieldMapping('created'); /** @var \Drupal\comment\CommentInterface $comment*/ $comment->rdf_data['date'] = rdf_rdfa_attributes($created_mapping, $comment->get('created')->first()->toArray()); - $entity = $comment->getCommentedEntity(); // The current function is a storage level hook, so avoid to bubble // bubbleable metadata, because it can be outside of a render context. - $comment->rdf_data['entity_uri'] = $entity->toUrl()->toString(TRUE)->getGeneratedUrl(); - if ($comment->hasParentComment()) { - $comment->rdf_data['pid_uri'] = $comment->getParentComment()->toUrl()->toString(TRUE)->getGeneratedUrl(); + if ($entity = $comment->getCommentedEntity()) { + $comment->rdf_data['entity_uri'] = $entity->toUrl()->toString(TRUE)->getGeneratedUrl(); + } + if ($parent = $comment->getParentComment()) { + $comment->rdf_data['pid_uri'] = $parent->toUrl()->toString(TRUE)->getGeneratedUrl(); } } }