Issue #2205185 by larowlan, hairqles, andypost, slashrsm: Split up ForumManager to create ForumIndexStorage.
parent
eb3e7866ad
commit
1b34836c90
|
@ -5,6 +5,7 @@
|
|||
* Provides discussion forums.
|
||||
*/
|
||||
|
||||
use Drupal\comment\CommentInterface;
|
||||
use Drupal\comment\Plugin\Field\FieldType\CommentItemInterface;
|
||||
use Drupal\Component\Utility\Xss;
|
||||
use Drupal\Core\Entity\EntityInterface;
|
||||
|
@ -245,7 +246,7 @@ function forum_node_presave(EntityInterface $node) {
|
|||
$node->forum_tid = $node->taxonomy_forums->target_id;
|
||||
// Only do a shadow copy check if this is not a new node.
|
||||
if (!$node->isNew()) {
|
||||
$old_tid = db_query_range("SELECT f.tid FROM {forum} f INNER JOIN {node} n ON f.vid = n.vid WHERE n.nid = :nid ORDER BY f.vid DESC", 0, 1, array(':nid' => $node->id()))->fetchField();
|
||||
$old_tid = \Drupal::service('forum.index_storage')->getOriginalTermId($node);
|
||||
if ($old_tid && isset($node->forum_tid) && ($node->forum_tid != $old_tid) && !empty($node->shadow)) {
|
||||
// A shadow copy needs to be created. Retain new term and add old term.
|
||||
$node->taxonomy_forums[count($node->taxonomy_forums)] = array('target_id' => $old_tid);
|
||||
|
@ -262,73 +263,37 @@ function forum_node_update(EntityInterface $node) {
|
|||
if (\Drupal::service('forum_manager')->checkNodeType($node)) {
|
||||
// If this is not a new revision and does exist, update the forum record,
|
||||
// otherwise insert a new one.
|
||||
if ($node->getRevisionId() == $node->original->getRevisionId() && db_query('SELECT tid FROM {forum} WHERE nid=:nid', array(':nid' => $node->id()))->fetchField()) {
|
||||
/** @var \Drupal\forum\ForumIndexStorageInterface $forum_index_storage */
|
||||
$forum_index_storage = \Drupal::service('forum.index_storage');
|
||||
if ($node->getRevisionId() == $node->original->getRevisionId() && $forum_index_storage->getOriginalTermId($node)) {
|
||||
if (!empty($node->forum_tid)) {
|
||||
db_update('forum')
|
||||
->fields(array('tid' => $node->forum_tid))
|
||||
->condition('vid', $node->getRevisionId())
|
||||
->execute();
|
||||
$forum_index_storage->update($node);
|
||||
}
|
||||
// The node is removed from the forum.
|
||||
else {
|
||||
db_delete('forum')
|
||||
->condition('nid', $node->id())
|
||||
->execute();
|
||||
$forum_index_storage->delete($node);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (!empty($node->forum_tid)) {
|
||||
db_insert('forum')
|
||||
->fields(array(
|
||||
'tid' => $node->forum_tid,
|
||||
'vid' => $node->getRevisionId(),
|
||||
'nid' => $node->id(),
|
||||
))
|
||||
->execute();
|
||||
$forum_index_storage->create($node);
|
||||
}
|
||||
}
|
||||
// If the node has a shadow forum topic, update the record for this
|
||||
// revision.
|
||||
if (!empty($node->shadow)) {
|
||||
db_delete('forum')
|
||||
->condition('nid', $node->id())
|
||||
->condition('vid', $node->getRevisionId())
|
||||
->execute();
|
||||
db_insert('forum')
|
||||
->fields(array(
|
||||
'nid' => $node->id(),
|
||||
'vid' => $node->getRevisionId(),
|
||||
'tid' => $node->forum_tid,
|
||||
))
|
||||
->execute();
|
||||
$forum_index_storage->deleteRevision($node);
|
||||
$forum_index_storage->create($node);
|
||||
}
|
||||
|
||||
// If the node is published, update the forum index.
|
||||
if ($node->isPublished()) {
|
||||
db_delete('forum_index')->condition('nid', $node->id())->execute();
|
||||
$query = db_insert('forum_index')->fields(array('nid', 'title', 'tid', 'sticky', 'created', 'comment_count', 'last_comment_timestamp'));
|
||||
foreach ($node->getTranslationLanguages() as $langcode => $language) {
|
||||
$translation = $node->getTranslation($langcode);
|
||||
foreach ($translation->taxonomy_forums as $item) {
|
||||
$query->values(array(
|
||||
'nid' => $node->id(),
|
||||
'title' => $translation->label(),
|
||||
'tid' => $item->target_id,
|
||||
'sticky' => (int) $node->isSticky(),
|
||||
'created' => $node->getCreatedTime(),
|
||||
'comment_count' => 0,
|
||||
'last_comment_timestamp' => $node->getCreatedTime(),
|
||||
));
|
||||
}
|
||||
}
|
||||
$query->execute();
|
||||
// The logic for determining last_comment_count is fairly complex, so
|
||||
// update the index too.
|
||||
\Drupal::service('forum_manager')->updateIndex($node->id());
|
||||
$forum_index_storage->deleteIndex($node);
|
||||
$forum_index_storage->createIndex($node);
|
||||
}
|
||||
// When a forum node is unpublished, remove it from the forum_index table.
|
||||
else {
|
||||
db_delete('forum_index')->condition('nid', $node->id())->execute();
|
||||
$forum_index_storage->deleteIndex($node);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -338,32 +303,15 @@ function forum_node_update(EntityInterface $node) {
|
|||
*/
|
||||
function forum_node_insert(EntityInterface $node) {
|
||||
if (\Drupal::service('forum_manager')->checkNodeType($node)) {
|
||||
/** @var \Drupal\forum\ForumIndexStorageInterface $forum_index_storage */
|
||||
$forum_index_storage = \Drupal::service('forum.index_storage');
|
||||
if (!empty($node->forum_tid)) {
|
||||
db_insert('forum')
|
||||
->fields(array(
|
||||
'tid' => $node->forum_tid,
|
||||
'vid' => $node->getRevisionId(),
|
||||
'nid' => $node->id(),
|
||||
))
|
||||
->execute();
|
||||
$forum_index_storage->create($node);
|
||||
}
|
||||
|
||||
// If the node is published, update the forum index.
|
||||
if ($node->isPublished()) {
|
||||
$query = db_insert('forum_index')->fields(array('nid', 'title', 'tid', 'sticky', 'created', 'comment_count', 'last_comment_timestamp'));
|
||||
foreach ($node->getTranslationLanguages() as $langcode => $language) {
|
||||
$translation = $node->getTranslation($langcode);
|
||||
$query->values(array(
|
||||
'nid' => $node->id(),
|
||||
'title' => $translation->label(),
|
||||
'tid' => $translation->taxonomy_forums->target_id,
|
||||
'sticky' => (int) $node->isSticky(),
|
||||
'created' => $node->getCreatedTime(),
|
||||
'comment_count' => 0,
|
||||
'last_comment_timestamp' => $node->getCreatedTime(),
|
||||
));
|
||||
}
|
||||
$query->execute();
|
||||
$forum_index_storage->createIndex($node);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -373,12 +321,10 @@ function forum_node_insert(EntityInterface $node) {
|
|||
*/
|
||||
function forum_node_predelete(EntityInterface $node) {
|
||||
if (\Drupal::service('forum_manager')->checkNodeType($node)) {
|
||||
db_delete('forum')
|
||||
->condition('nid', $node->id())
|
||||
->execute();
|
||||
db_delete('forum_index')
|
||||
->condition('nid', $node->id())
|
||||
->execute();
|
||||
/** @var \Drupal\forum\ForumIndexStorageInterface $forum_index_storage */
|
||||
$forum_index_storage = \Drupal::service('forum.index_storage');
|
||||
$forum_index_storage->delete($node);
|
||||
$forum_index_storage->deleteIndex($node);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -393,11 +339,7 @@ function forum_node_load($nodes) {
|
|||
}
|
||||
}
|
||||
if (!empty($node_vids)) {
|
||||
$query = db_select('forum', 'f');
|
||||
$query
|
||||
->fields('f', array('nid', 'tid'))
|
||||
->condition('f.vid', $node_vids);
|
||||
$result = $query->execute();
|
||||
$result = \Drupal::service('forum.index_storage')->read($node_vids);
|
||||
foreach ($result as $record) {
|
||||
$nodes[$record->nid]->forum_tid = $record->tid;
|
||||
}
|
||||
|
@ -422,9 +364,9 @@ function forum_permission() {
|
|||
* This actually handles the insertion and update of published nodes since
|
||||
* $comment->save() calls hook_comment_publish() for all published comments.
|
||||
*/
|
||||
function forum_comment_publish($comment) {
|
||||
function forum_comment_publish(CommentInterface $comment) {
|
||||
if ($comment->getCommentedEntityTypeId() == 'node') {
|
||||
\Drupal::service('forum_manager')->updateIndex($comment->getCommentedEntityId());
|
||||
\Drupal::service('forum.index_storage')->updateIndex($comment->getCommentedEntity());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -434,29 +376,29 @@ function forum_comment_publish($comment) {
|
|||
* The Comment module doesn't call hook_comment_unpublish() when saving
|
||||
* individual comments, so we need to check for those here.
|
||||
*/
|
||||
function forum_comment_update($comment) {
|
||||
function forum_comment_update(CommentInterface $comment) {
|
||||
// $comment->save() calls hook_comment_publish() for all published comments,
|
||||
// so we need to handle all other values here.
|
||||
if (!$comment->isPublished() && $comment->getCommentedEntityTypeId() == 'node') {
|
||||
\Drupal::service('forum_manager')->updateIndex($comment->getCommentedEntityId());
|
||||
\Drupal::service('forum.index_storage')->updateIndex($comment->getCommentedEntity());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_comment_unpublish().
|
||||
*/
|
||||
function forum_comment_unpublish($comment) {
|
||||
function forum_comment_unpublish(CommentInterface $comment) {
|
||||
if ($comment->getCommentedEntityTypeId() == 'node') {
|
||||
\Drupal::service('forum_manager')->updateIndex($comment->getCommentedEntityId());
|
||||
\Drupal::service('forum.index_storage')->updateIndex($comment->getCommentedEntity());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_comment_delete().
|
||||
*/
|
||||
function forum_comment_delete($comment) {
|
||||
function forum_comment_delete(CommentInterface $comment) {
|
||||
if ($comment->getCommentedEntityTypeId() == 'node') {
|
||||
\Drupal::service('forum_manager')->updateIndex($comment->getCommentedEntityId());
|
||||
\Drupal::service('forum.index_storage')->updateIndex($comment->getCommentedEntity());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -12,3 +12,6 @@ services:
|
|||
arguments: ['@entity.manager', '@config.factory', '@forum_manager']
|
||||
tags:
|
||||
- { name: breadcrumb_builder, priority: 1001 }
|
||||
forum.index_storage:
|
||||
class: Drupal\forum\ForumIndexStorage
|
||||
arguments: ['@database', '@forum_manager']
|
||||
|
|
|
@ -0,0 +1,168 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\forum\ForumIndexStorage.
|
||||
*/
|
||||
|
||||
namespace Drupal\forum;
|
||||
use Drupal\comment\CommentInterface;
|
||||
use Drupal\Core\Database\Connection;
|
||||
use Drupal\node\NodeInterface;
|
||||
|
||||
/**
|
||||
* Handles CRUD operations to {forum_index} table.
|
||||
*/
|
||||
class ForumIndexStorage implements ForumIndexStorageInterface {
|
||||
|
||||
/**
|
||||
* The active database connection.
|
||||
*
|
||||
* @var \Drupal\Core\Database\Connection
|
||||
*/
|
||||
protected $database;
|
||||
|
||||
/**
|
||||
* Constructs a ForumIndexStorage object.
|
||||
*
|
||||
* @param \Drupal\Core\Database\Connection $database
|
||||
* The current database connection.
|
||||
*/
|
||||
function __construct(Connection $database) {
|
||||
$this->database = $database;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getOriginalTermId(NodeInterface $node) {
|
||||
return $this->database->queryRange("SELECT f.tid FROM {forum} f INNER JOIN {node} n ON f.vid = n.vid WHERE n.nid = :nid ORDER BY f.vid DESC", 0, 1, array(':nid' => $node->id()))->fetchField();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function create(NodeInterface $node) {
|
||||
$this->database->insert('forum')
|
||||
->fields(array(
|
||||
'tid' => $node->forum_tid,
|
||||
'vid' => $node->getRevisionId(),
|
||||
'nid' => $node->id(),
|
||||
))
|
||||
->execute();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function read(array $vids) {
|
||||
return $this->database->select('forum', 'f')
|
||||
->fields('f', array('nid', 'tid'))
|
||||
->condition('f.vid', $vids)
|
||||
->execute();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function delete(NodeInterface $node) {
|
||||
$this->database->delete('forum')
|
||||
->condition('nid', $node->id())
|
||||
->execute();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function deleteRevision(NodeInterface $node) {
|
||||
$this->database->delete('forum')
|
||||
->condition('nid', $node->id())
|
||||
->condition('vid', $node->getRevisionId())
|
||||
->execute();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function update(NodeInterface $node) {
|
||||
$this->database->update('forum')
|
||||
->fields(array('tid' => $node->forum_tid))
|
||||
->condition('vid', $node->getRevisionId())
|
||||
->execute();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function updateIndex(NodeInterface $node) {
|
||||
$nid = $node->id();
|
||||
$count = $this->database->query("SELECT COUNT(cid) FROM {comment} c INNER JOIN {forum_index} i ON c.entity_id = i.nid WHERE c.entity_id = :nid AND c.field_id = 'node__comment_forum' AND c.entity_type = 'node' AND c.status = :status", array(
|
||||
':nid' => $nid,
|
||||
':status' => CommentInterface::PUBLISHED,
|
||||
))->fetchField();
|
||||
|
||||
if ($count > 0) {
|
||||
// Comments exist.
|
||||
$last_reply = $this->database->queryRange("SELECT cid, name, created, uid FROM {comment} WHERE entity_id = :nid AND field_id = 'node__comment_forum' AND entity_type = 'node' AND status = :status ORDER BY cid DESC", 0, 1, array(
|
||||
':nid' => $nid,
|
||||
':status' => CommentInterface::PUBLISHED,
|
||||
))->fetchObject();
|
||||
$this->database->update('forum_index')
|
||||
->fields( array(
|
||||
'comment_count' => $count,
|
||||
'last_comment_timestamp' => $last_reply->created,
|
||||
))
|
||||
->condition('nid', $nid)
|
||||
->execute();
|
||||
}
|
||||
else {
|
||||
// Comments do not exist.
|
||||
// @todo This should be actually filtering on the desired node language
|
||||
$this->database->update('forum_index')
|
||||
->fields( array(
|
||||
'comment_count' => 0,
|
||||
'last_comment_timestamp' => $node->getCreatedTime(),
|
||||
))
|
||||
->condition('nid', $nid)
|
||||
->execute();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function createIndex(NodeInterface $node) {
|
||||
$query = $this->database->insert('forum_index')
|
||||
->fields(array('nid', 'title', 'tid', 'sticky', 'created', 'comment_count', 'last_comment_timestamp'));
|
||||
foreach ($node->getTranslationLanguages() as $langcode => $language) {
|
||||
$translation = $node->getTranslation($langcode);
|
||||
foreach ($translation->taxonomy_forums as $item) {
|
||||
$query->values(array(
|
||||
'nid' => $node->id(),
|
||||
'title' => $translation->label(),
|
||||
'tid' => $item->target_id,
|
||||
'sticky' => (int) $node->isSticky(),
|
||||
'created' => $node->getCreatedTime(),
|
||||
'comment_count' => 0,
|
||||
'last_comment_timestamp' => $node->getCreatedTime(),
|
||||
));
|
||||
}
|
||||
}
|
||||
$query->execute();
|
||||
// The logic for determining last_comment_count is fairly complex, so
|
||||
// update the index too.
|
||||
if ($node->isNew()) {
|
||||
$this->updateIndex($node);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function deleteIndex(NodeInterface $node) {
|
||||
$this->database->delete('forum_index')
|
||||
->condition('nid', $node->id())
|
||||
->execute();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,94 @@
|
|||
<?php
|
||||
/**
|
||||
* @file
|
||||
* Contains
|
||||
*/
|
||||
namespace Drupal\forum;
|
||||
|
||||
use Drupal\node\NodeInterface;
|
||||
|
||||
|
||||
/**
|
||||
* Handles CRUD operations to {forum_index} table.
|
||||
*/
|
||||
interface ForumIndexStorageInterface {
|
||||
|
||||
/**
|
||||
* Returns the forum term id associated with an existing forum node.
|
||||
*
|
||||
* @param \Drupal\node\NodeInterface $node
|
||||
* The existing forum node.
|
||||
*
|
||||
* @return int
|
||||
* The forum term id currently associated with the node.
|
||||
*/
|
||||
public function getOriginalTermId(NodeInterface $node);
|
||||
|
||||
/**
|
||||
* Creates a record in {forum} table for the given node.
|
||||
*
|
||||
* @param \Drupal\node\NodeInterface $node
|
||||
* The node for which the record is to be created.
|
||||
*/
|
||||
public function create(NodeInterface $node);
|
||||
|
||||
/**
|
||||
* Reads an array of {forum} records for the given revision ids.
|
||||
*
|
||||
* @param array $vids
|
||||
* An array of node revision ids.
|
||||
*
|
||||
* @return \Drupal\Core\Database\StatementInterface
|
||||
* The records from {forum} for the given vids.
|
||||
*/
|
||||
public function read(array $vids);
|
||||
|
||||
/**
|
||||
* Updates the {forum} table for the given node.
|
||||
*
|
||||
* @param \Drupal\node\NodeInterface $node
|
||||
* The node for which the record is to be updated.
|
||||
*/
|
||||
public function update(NodeInterface $node);
|
||||
|
||||
/**
|
||||
* Deletes the records in {forum} table for the given node.
|
||||
*
|
||||
* @param \Drupal\node\NodeInterface $node
|
||||
* The node for which the records are to be deleted.
|
||||
*/
|
||||
public function delete(NodeInterface $node);
|
||||
|
||||
/**
|
||||
* Deletes the records in {forum} table for a given node revision.
|
||||
*
|
||||
* @param \Drupal\node\NodeInterface $node
|
||||
* The node revision for which the records are to be deleted.
|
||||
*/
|
||||
public function deleteRevision(NodeInterface $node);
|
||||
|
||||
/**
|
||||
* Creates a {forum_index} entry for the given node.
|
||||
*
|
||||
* @param \Drupal\node\NodeInterface $node
|
||||
* The node for which the index records are to be created.
|
||||
*/
|
||||
public function createIndex(NodeInterface $node);
|
||||
|
||||
/**
|
||||
* Updates the {forum_index} records for a given node.
|
||||
*
|
||||
* @param \Drupal\node\NodeInterface $node
|
||||
* The node for which the index records are to be updated.
|
||||
*/
|
||||
public function updateIndex(NodeInterface $node);
|
||||
|
||||
/**
|
||||
* Deletes the {forum_index} records for a given node.
|
||||
*
|
||||
* @param \Drupal\node\NodeInterface $node
|
||||
* The node for which the index records are to be deleted.
|
||||
*/
|
||||
public function deleteIndex(NodeInterface $node);
|
||||
|
||||
}
|
|
@ -14,7 +14,6 @@ use Drupal\Core\Entity\EntityManagerInterface;
|
|||
use Drupal\Core\Session\AccountInterface;
|
||||
use Drupal\Core\StringTranslation\TranslationInterface;
|
||||
use Drupal\Core\StringTranslation\StringTranslationTrait;
|
||||
use Drupal\comment\CommentInterface;
|
||||
use Drupal\node\NodeInterface;
|
||||
|
||||
/**
|
||||
|
@ -496,44 +495,6 @@ class ForumManager extends DependencySerialization implements ForumManagerInterf
|
|||
->fetchField();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function updateIndex($nid) {
|
||||
$count = $this->connection->query("SELECT COUNT(cid) FROM {comment} c INNER JOIN {forum_index} i ON c.entity_id = i.nid WHERE c.entity_id = :nid AND c.field_id = 'node__comment_forum' AND c.entity_type = 'node' AND c.status = :status", array(
|
||||
':nid' => $nid,
|
||||
':status' => CommentInterface::PUBLISHED,
|
||||
))->fetchField();
|
||||
|
||||
if ($count > 0) {
|
||||
// Comments exist.
|
||||
$last_reply = $this->connection->queryRange("SELECT cid, name, created, uid FROM {comment} WHERE entity_id = :nid AND field_id = 'node__comment_forum' AND entity_type = 'node' AND status = :status ORDER BY cid DESC", 0, 1, array(
|
||||
':nid' => $nid,
|
||||
':status' => CommentInterface::PUBLISHED,
|
||||
))->fetchObject();
|
||||
$this->connection->update('forum_index')
|
||||
->fields( array(
|
||||
'comment_count' => $count,
|
||||
'last_comment_timestamp' => $last_reply->created,
|
||||
))
|
||||
->condition('nid', $nid)
|
||||
->execute();
|
||||
}
|
||||
else {
|
||||
// Comments do not exist.
|
||||
// @todo This should be actually filtering on the desired node language and
|
||||
// just fall back to the default language.
|
||||
$node = $this->connection->query('SELECT uid, created FROM {node_field_data} WHERE nid = :nid AND default_langcode = 1', array(':nid' => $nid))->fetchObject();
|
||||
$this->connection->update('forum_index')
|
||||
->fields( array(
|
||||
'comment_count' => 0,
|
||||
'last_comment_timestamp' => $node->created,
|
||||
))
|
||||
->condition('nid', $nid)
|
||||
->execute();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
|
|
|
@ -96,12 +96,4 @@ interface ForumManagerInterface {
|
|||
*/
|
||||
public function unreadTopics($term, $uid);
|
||||
|
||||
/**
|
||||
* Updates the taxonomy index for a given node.
|
||||
*
|
||||
* @param int $nid
|
||||
* The ID of the node to update.
|
||||
*/
|
||||
public function updateIndex($nid);
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue