Issue #2205185 by larowlan, hairqles, andypost, slashrsm: Split up ForumManager to create ForumIndexStorage.

8.0.x
Alex Pott 2014-06-08 21:24:40 -05:00
parent eb3e7866ad
commit 1b34836c90
6 changed files with 295 additions and 135 deletions

View File

@ -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());
}
}

View File

@ -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']

View File

@ -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();
}
}

View File

@ -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);
}

View File

@ -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}
*/

View File

@ -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);
}