Issue #2614720 by quietone, roderik, ofry, Dylan Donkersgoed, Deepak Goyal, samiullah, jonathanshaw, benjifisher, larowlan, Rewted, Ruedische, KlemenDEV, ao2, abramm, vadim.hirbu, HiMyNameIsSeb, dionsj, mgp_novicell, scalas89, rollins, dmytro-aragorn, hchonov, mayurjadhav, paranojik, nplowman: Fatal errors while loading/building orphaned comments
parent
9e546b3678
commit
9beb71e610
|
@ -607,9 +607,8 @@ function template_preprocess_comment(&$variables) {
|
|||
|
||||
$variables['submitted'] = t('Submitted by @username on @datetime', ['@username' => $variables['author'], '@datetime' => $variables['created']]);
|
||||
|
||||
if ($comment->hasParentComment()) {
|
||||
if ($comment_parent = $comment->getParentComment()) {
|
||||
// Fetch and store the parent comment information for use in templates.
|
||||
$comment_parent = $comment->getParentComment();
|
||||
$account_parent = $comment_parent->getOwner();
|
||||
$variables['parent_comment'] = $comment_parent;
|
||||
$username = [
|
||||
|
|
|
@ -137,9 +137,9 @@ class CommentLazyBuilders implements TrustedCallbackInterface {
|
|||
if (!$is_in_preview) {
|
||||
/** @var \Drupal\comment\CommentInterface $entity */
|
||||
$entity = $this->entityTypeManager->getStorage('comment')->load($comment_entity_id);
|
||||
$commented_entity = $entity->getCommentedEntity();
|
||||
|
||||
$links['comment'] = $this->buildLinks($entity, $commented_entity);
|
||||
if ($commented_entity = $entity->getCommentedEntity()) {
|
||||
$links['comment'] = $this->buildLinks($entity, $commented_entity);
|
||||
}
|
||||
|
||||
// Allow other modules to alter the comment links.
|
||||
$hook_context = [
|
||||
|
|
|
@ -80,9 +80,11 @@ class CommentViewBuilder extends EntityViewBuilder {
|
|||
|
||||
/** @var \Drupal\comment\CommentInterface $entity */
|
||||
// Store a threading field setting to use later in self::buildComponents().
|
||||
$build['#comment_threaded'] = $entity->getCommentedEntity()
|
||||
->getFieldDefinition($entity->getFieldName())
|
||||
->getSetting('default_mode') === CommentManagerInterface::COMMENT_MODE_THREADED;
|
||||
$commented_entity = $entity->getCommentedEntity();
|
||||
$build['#comment_threaded'] =
|
||||
is_null($commented_entity)
|
||||
|| $commented_entity->getFieldDefinition($entity->getFieldName())
|
||||
->getSetting('default_mode') === CommentManagerInterface::COMMENT_MODE_THREADED;
|
||||
// If threading is enabled, don't render cache individual comments, but do
|
||||
// keep the cacheability metadata, so it can bubble up.
|
||||
if ($build['#comment_threaded']) {
|
||||
|
@ -140,10 +142,12 @@ class CommentViewBuilder extends EntityViewBuilder {
|
|||
|
||||
// Commented entities already loaded after self::getBuildDefaults().
|
||||
$commented_entity = $entity->getCommentedEntity();
|
||||
// Set defaults if the commented_entity does not exist.
|
||||
$bundle = $commented_entity ? $commented_entity->bundle() : '';
|
||||
$is_node = $commented_entity ? $commented_entity->getEntityTypeId() === 'node' : NULL;
|
||||
|
||||
$build[$id]['#entity'] = $entity;
|
||||
$build[$id]['#theme'] = 'comment__' . $entity->getFieldName() . '__' . $commented_entity->bundle();
|
||||
|
||||
$build[$id]['#theme'] = 'comment__' . $entity->getFieldName() . '__' . $bundle;
|
||||
$display = $displays[$entity->bundle()];
|
||||
if ($display->getComponent('links')) {
|
||||
$build[$id]['links'] = [
|
||||
|
@ -164,7 +168,7 @@ class CommentViewBuilder extends EntityViewBuilder {
|
|||
$build[$id]['#attached'] = [];
|
||||
}
|
||||
$build[$id]['#attached']['library'][] = 'comment/drupal.comment-by-viewer';
|
||||
if ($attach_history && $commented_entity->getEntityTypeId() === 'node') {
|
||||
if ($attach_history && $is_node) {
|
||||
$build[$id]['#attached']['library'][] = 'comment/drupal.comment-new-indicator';
|
||||
|
||||
// Embed the metadata for the comment "new" indicators on this node.
|
||||
|
|
|
@ -404,7 +404,8 @@ class Comment extends ContentEntityBase implements CommentInterface {
|
|||
* {@inheritdoc}
|
||||
*/
|
||||
public function getAuthorName() {
|
||||
if ($this->get('uid')->target_id) {
|
||||
// If their is a valid user id and the user entity exists return the label.
|
||||
if ($this->get('uid')->target_id && $this->get('uid')->entity) {
|
||||
return $this->get('uid')->entity->label();
|
||||
}
|
||||
return $this->get('name')->value ?: \Drupal::config('user.settings')->get('anonymous');
|
||||
|
|
|
@ -0,0 +1,134 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\comment\Kernel;
|
||||
|
||||
use Drupal\Core\Datetime\Entity\DateFormat;
|
||||
use Drupal\KernelTests\Core\Entity\EntityKernelTestBase;
|
||||
use Drupal\Tests\EntityViewTrait;
|
||||
use Drupal\field\Entity\FieldStorageConfig;
|
||||
|
||||
/**
|
||||
* Tests loading and rendering orphan comments.
|
||||
*
|
||||
* @group comment
|
||||
*/
|
||||
class CommentOrphanTest extends EntityKernelTestBase {
|
||||
|
||||
use EntityViewTrait;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $modules = ['comment', 'node'];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp(): void {
|
||||
parent::setUp();
|
||||
$this->installEntitySchema('date_format');
|
||||
$this->installEntitySchema('comment');
|
||||
$this->installSchema('comment', ['comment_entity_statistics']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test loading/deleting/rendering orphaned comments.
|
||||
*
|
||||
* @dataProvider providerTestOrphan
|
||||
*/
|
||||
public function testOrphan($property) {
|
||||
|
||||
DateFormat::create([
|
||||
'id' => 'fallback',
|
||||
'label' => 'Fallback',
|
||||
'pattern' => 'Y-m-d',
|
||||
])->save();
|
||||
|
||||
$comment_storage = $this->entityTypeManager->getStorage('comment');
|
||||
$node_storage = $this->entityTypeManager->getStorage('node');
|
||||
|
||||
// Create a page node type.
|
||||
$this->entityTypeManager->getStorage('node_type')->create([
|
||||
'type' => 'page',
|
||||
'name' => 'page',
|
||||
])->save();
|
||||
|
||||
$node = $node_storage->create([
|
||||
'type' => 'page',
|
||||
'title' => 'test',
|
||||
]);
|
||||
$node->save();
|
||||
|
||||
// Create comment field.
|
||||
$this->entityTypeManager->getStorage('field_storage_config')->create([
|
||||
'type' => 'text_long',
|
||||
'entity_type' => 'node',
|
||||
'field_name' => 'comment',
|
||||
])->save();
|
||||
|
||||
// Add comment field to page content.
|
||||
$this->entityTypeManager->getStorage('field_config')->create([
|
||||
'field_storage' => FieldStorageConfig::loadByName('node', 'comment'),
|
||||
'entity_type' => 'node',
|
||||
'bundle' => 'page',
|
||||
'label' => 'Comment',
|
||||
])->save();
|
||||
|
||||
// Make two comments
|
||||
$comment1 = $comment_storage->create([
|
||||
'field_name' => 'comment',
|
||||
'comment_body' => 'test',
|
||||
'entity_id' => $node->id(),
|
||||
'entity_type' => 'node',
|
||||
'comment_type' => 'default',
|
||||
])->save();
|
||||
|
||||
$comment_storage->create([
|
||||
'field_name' => 'comment',
|
||||
'comment_body' => 'test',
|
||||
'entity_id' => $node->id(),
|
||||
'entity_type' => 'node',
|
||||
'comment_type' => 'default',
|
||||
'pid' => $comment1,
|
||||
])->save();
|
||||
|
||||
// Render the comments.
|
||||
$renderer = \Drupal::service('renderer');
|
||||
$comments = $comment_storage->loadMultiple();
|
||||
foreach ($comments as $comment) {
|
||||
$built = $this->buildEntityView($comment, 'full', NULL);
|
||||
$renderer->renderPlain($built);
|
||||
}
|
||||
|
||||
// Make comment 2 an orphan by setting the property to an invalid value.
|
||||
\Drupal::database()->update('comment_field_data')
|
||||
->fields([$property => 10])
|
||||
->condition('cid', 2)
|
||||
->execute();
|
||||
$comment_storage->resetCache();
|
||||
$node_storage->resetCache();
|
||||
|
||||
// Render the comments with an orphan comment.
|
||||
$comments = $comment_storage->loadMultiple();
|
||||
foreach ($comments as $comment) {
|
||||
$built = $this->buildEntityView($comment, 'full', NULL);
|
||||
$renderer->renderPlain($built);
|
||||
}
|
||||
|
||||
$node = $node_storage->load($node->id());
|
||||
$built = $this->buildEntityView($node, 'full', NULL);
|
||||
$renderer->renderPlain($built);
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides test data for testOrphan.
|
||||
*/
|
||||
public function providerTestOrphan() {
|
||||
return [
|
||||
['entity_id'],
|
||||
['uid'],
|
||||
['pid'],
|
||||
];
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue