NodeNewComments.php
Same filename in other branches
Namespace
Drupal\comment\Plugin\views\fieldFile
-
core/
modules/ comment/ src/ Plugin/ views/ field/ NodeNewComments.php
View source
<?php
namespace Drupal\comment\Plugin\views\field;
use Drupal\Core\Database\Connection;
use Drupal\comment\CommentInterface;
use Drupal\Core\Entity\EntityFieldManagerInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\node\Entity\Node;
use Drupal\views\Plugin\views\field\NumericField;
use Drupal\views\Plugin\views\display\DisplayPluginBase;
use Drupal\views\ResultRow;
use Drupal\views\ViewExecutable;
use Symfony\Component\DependencyInjection\ContainerInterface;
/**
* Field handler to display the number of new comments.
*
* @ingroup views_field_handlers
*
* @ViewsField("node_new_comments")
*/
class NodeNewComments extends NumericField {
/**
* {@inheritdoc}
*/
public function usesGroupBy() {
return FALSE;
}
/**
* Database Service Object.
*
* @var \Drupal\Core\Database\Connection
*/
protected $database;
/**
* The entity type manager.
*
* @var \Drupal\Core\Entity\EntityTypeManagerInterface
*/
protected $entityTypeManager;
/**
* The entity field manager.
*
* @var \Drupal\Core\Entity\EntityFieldManagerInterface
*/
protected $entityFieldManager;
/**
* Constructs a \Drupal\comment\Plugin\views\field\NodeNewComments object.
*
* @param array $configuration
* A configuration array containing information about the plugin instance.
* @param string $plugin_id
* The plugin_id for the plugin instance.
* @param mixed $plugin_definition
* The plugin implementation definition.
* @param \Drupal\Core\Database\Connection $database
* Database Service Object.
* @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
* The entity type manager service.
* @param \Drupal\Core\Entity\EntityFieldManagerInterface $entity_field_manager
* The entity field manager service.
*/
public function __construct(array $configuration, $plugin_id, $plugin_definition, Connection $database, EntityTypeManagerInterface $entity_type_manager = NULL, EntityFieldManagerInterface $entity_field_manager = NULL) {
parent::__construct($configuration, $plugin_id, $plugin_definition);
$this->database = $database;
if (!$entity_type_manager) {
@trigger_error("Not passing the entity type manager to the NodeNewComments constructor is deprecated in drupal:8.8.0 and will be required in drupal:9.0.0. @see https://www.drupal.org/node/3047897", E_USER_DEPRECATED);
$entity_type_manager = \Drupal::entityTypeManager();
}
if (!$entity_field_manager) {
@trigger_error("Not passing the entity type manager to the NodeNewComments constructor is deprecated in drupal:8.8.0 and will be required in drupal:9.0.0. @see https://www.drupal.org/node/3047897", E_USER_DEPRECATED);
$entity_field_manager = \Drupal::service('entity_field.manager');
}
$this->entityTypeManager = $entity_type_manager;
$this->entityFieldManager = $entity_field_manager;
}
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
return new static($configuration, $plugin_id, $plugin_definition, $container->get('database'), $container->get('entity_type.manager'), $container->get('entity_field.manager'));
}
/**
* {@inheritdoc}
*/
public function init(ViewExecutable $view, DisplayPluginBase $display, array &$options = NULL) {
parent::init($view, $display, $options);
$this->additional_fields['entity_id'] = 'nid';
$this->additional_fields['type'] = 'type';
$this->additional_fields['comment_count'] = [
'table' => 'comment_entity_statistics',
'field' => 'comment_count',
];
}
/**
* {@inheritdoc}
*/
protected function defineOptions() {
$options = parent::defineOptions();
$options['link_to_comment'] = [
'default' => TRUE,
];
return $options;
}
/**
* {@inheritdoc}
*/
public function buildOptionsForm(&$form, FormStateInterface $form_state) {
$form['link_to_comment'] = [
'#title' => $this->t('Link this field to new comments'),
'#description' => $this->t("Enable to override this field's links."),
'#type' => 'checkbox',
'#default_value' => $this->options['link_to_comment'],
];
parent::buildOptionsForm($form, $form_state);
}
/**
* {@inheritdoc}
*/
public function query() {
$this->ensureMyTable();
$this->addAdditionalFields();
$this->field_alias = $this->table . '_' . $this->field;
}
/**
* {@inheritdoc}
*/
public function preRender(&$values) {
$user = \Drupal::currentUser();
if ($user->isAnonymous() || empty($values)) {
return;
}
$nids = [];
$ids = [];
foreach ($values as $id => $result) {
$nids[] = $result->{$this->aliases['nid']};
$values[$id]->{$this->field_alias} = 0;
// Create a reference so we can find this record in the values again.
if (empty($ids[$result->{$this->aliases['nid']}])) {
$ids[$result->{$this->aliases['nid']}] = [];
}
$ids[$result->{$this->aliases['nid']}][] = $id;
}
if ($nids) {
$result = $this->database
->query("SELECT n.nid, COUNT(c.cid) AS num_comments FROM {node} n INNER JOIN {comment_field_data} c ON n.nid = c.entity_id AND c.entity_type = 'node' AND c.default_langcode = 1\n LEFT JOIN {history} h ON h.nid = n.nid AND h.uid = :h_uid WHERE n.nid IN ( :nids[] )\n AND c.changed > GREATEST(COALESCE(h.timestamp, :timestamp1), :timestamp2) AND c.status = :status GROUP BY n.nid", [
':status' => CommentInterface::PUBLISHED,
':h_uid' => $user->id(),
':nids[]' => $nids,
':timestamp1' => HISTORY_READ_LIMIT,
':timestamp2' => HISTORY_READ_LIMIT,
]);
foreach ($result as $node) {
foreach ($ids[$node->nid] as $id) {
$values[$id]->{$this->field_alias} = $node->num_comments;
}
}
}
}
/**
* Prepares the link to the first new comment.
*
* @param string $data
* The XSS safe string for the link text.
* @param \Drupal\views\ResultRow $values
* The values retrieved from a single row of a view's query result.
*
* @return string
* Returns a string for the link text.
*/
protected function renderLink($data, ResultRow $values) {
if (!empty($this->options['link_to_comment']) && $data !== NULL && $data !== '') {
$node_type = $this->getValue($values, 'type');
$node = Node::create([
'nid' => $this->getValue($values, 'nid'),
'type' => $node_type,
]);
// Because there is no support for selecting a specific comment field to
// reference, we arbitrarily use the first such field name we find.
// @todo Provide a means for selecting the comment field.
// https://www.drupal.org/node/2594201
$field_map = $this->entityFieldManager
->getFieldMapByFieldType('comment');
$comment_field_name = 'comment';
foreach ($field_map['node'] as $field_name => $field_data) {
foreach ($field_data['bundles'] as $bundle_name) {
if ($node_type == $bundle_name) {
$comment_field_name = $field_name;
break 2;
}
}
}
$page_number = $this->entityTypeManager
->getStorage('comment')
->getNewCommentPageNumber($this->getValue($values, 'comment_count'), $this->getValue($values), $node, $comment_field_name);
$this->options['alter']['make_link'] = TRUE;
$this->options['alter']['url'] = $node->toUrl();
$this->options['alter']['query'] = $page_number ? [
'page' => $page_number,
] : NULL;
$this->options['alter']['fragment'] = 'new';
}
return $data;
}
/**
* {@inheritdoc}
*/
public function render(ResultRow $values) {
$value = $this->getValue($values);
if (!empty($value)) {
return $this->renderLink(parent::render($values), $values);
}
else {
$this->options['alter']['make_link'] = FALSE;
}
}
}
Classes
Title | Deprecated | Summary |
---|---|---|
NodeNewComments | Field handler to display the number of new comments. |
Buggy or inaccurate documentation? Please file an issue. Need support? Need help programming? Connect with the Drupal community.