annotate core/modules/forum/src/ForumManager.php @ 19:fa3358dc1485 tip

Add ndrum files
author Chris Cannam
date Wed, 28 Aug 2019 13:14:47 +0100
parents af1871eacc83
children
rev   line source
Chris@0 1 <?php
Chris@0 2
Chris@0 3 namespace Drupal\forum;
Chris@0 4
Chris@0 5 use Drupal\Core\Config\ConfigFactoryInterface;
Chris@0 6 use Drupal\Core\Database\Connection;
Chris@0 7 use Drupal\Core\DependencyInjection\DependencySerializationTrait;
Chris@18 8 use Drupal\Core\DependencyInjection\DeprecatedServicePropertyTrait;
Chris@18 9 use Drupal\Core\Entity\EntityFieldManagerInterface;
Chris@18 10 use Drupal\Core\Entity\EntityTypeManagerInterface;
Chris@0 11 use Drupal\Core\Session\AccountInterface;
Chris@0 12 use Drupal\Core\StringTranslation\TranslationInterface;
Chris@0 13 use Drupal\Core\StringTranslation\StringTranslationTrait;
Chris@0 14 use Drupal\comment\CommentManagerInterface;
Chris@0 15 use Drupal\node\NodeInterface;
Chris@0 16
Chris@0 17 /**
Chris@0 18 * Provides forum manager service.
Chris@0 19 */
Chris@0 20 class ForumManager implements ForumManagerInterface {
Chris@0 21 use StringTranslationTrait;
Chris@0 22 use DependencySerializationTrait {
Chris@0 23 __wakeup as defaultWakeup;
Chris@0 24 __sleep as defaultSleep;
Chris@0 25 }
Chris@18 26 use DeprecatedServicePropertyTrait;
Chris@18 27
Chris@18 28 /**
Chris@18 29 * {@inheritdoc}
Chris@18 30 */
Chris@18 31 protected $deprecatedProperties = ['entityManager' => 'entity.manager'];
Chris@0 32
Chris@0 33 /**
Chris@0 34 * Forum sort order, newest first.
Chris@0 35 */
Chris@0 36 const NEWEST_FIRST = 1;
Chris@0 37
Chris@0 38 /**
Chris@0 39 * Forum sort order, oldest first.
Chris@0 40 */
Chris@0 41 const OLDEST_FIRST = 2;
Chris@0 42
Chris@0 43 /**
Chris@0 44 * Forum sort order, posts with most comments first.
Chris@0 45 */
Chris@0 46 const MOST_POPULAR_FIRST = 3;
Chris@0 47
Chris@0 48 /**
Chris@0 49 * Forum sort order, posts with the least comments first.
Chris@0 50 */
Chris@0 51 const LEAST_POPULAR_FIRST = 4;
Chris@0 52
Chris@0 53 /**
Chris@0 54 * Forum settings config object.
Chris@0 55 *
Chris@0 56 * @var \Drupal\Core\Config\ConfigFactoryInterface
Chris@0 57 */
Chris@0 58 protected $configFactory;
Chris@0 59
Chris@0 60 /**
Chris@18 61 * Entity field manager.
Chris@0 62 *
Chris@18 63 * @var \Drupal\Core\Entity\EntityFieldManagerInterface
Chris@0 64 */
Chris@18 65 protected $entityFieldManager;
Chris@18 66
Chris@18 67 /**
Chris@18 68 * Entity type manager.
Chris@18 69 *
Chris@18 70 * @var \Drupal\Core\Entity\EntityTypeManagerInterface
Chris@18 71 */
Chris@18 72 protected $entityTypeManager;
Chris@0 73
Chris@0 74 /**
Chris@0 75 * Database connection
Chris@0 76 *
Chris@0 77 * @var \Drupal\Core\Database\Connection
Chris@0 78 */
Chris@0 79 protected $connection;
Chris@0 80
Chris@0 81 /**
Chris@0 82 * The comment manager service.
Chris@0 83 *
Chris@0 84 * @var \Drupal\comment\CommentManagerInterface
Chris@0 85 */
Chris@0 86 protected $commentManager;
Chris@0 87
Chris@0 88 /**
Chris@0 89 * Array of last post information keyed by forum (term) id.
Chris@0 90 *
Chris@0 91 * @var array
Chris@0 92 */
Chris@0 93 protected $lastPostData = [];
Chris@0 94
Chris@0 95 /**
Chris@0 96 * Array of forum statistics keyed by forum (term) id.
Chris@0 97 *
Chris@0 98 * @var array
Chris@0 99 */
Chris@0 100 protected $forumStatistics = [];
Chris@0 101
Chris@0 102 /**
Chris@0 103 * Array of forum children keyed by parent forum (term) id.
Chris@0 104 *
Chris@0 105 * @var array
Chris@0 106 */
Chris@0 107 protected $forumChildren = [];
Chris@0 108
Chris@0 109 /**
Chris@0 110 * Array of history keyed by nid.
Chris@0 111 *
Chris@0 112 * @var array
Chris@0 113 */
Chris@0 114 protected $history = [];
Chris@0 115
Chris@0 116 /**
Chris@0 117 * Cached forum index.
Chris@0 118 *
Chris@0 119 * @var \Drupal\taxonomy\TermInterface
Chris@0 120 */
Chris@0 121 protected $index;
Chris@0 122
Chris@0 123 /**
Chris@0 124 * Constructs the forum manager service.
Chris@0 125 *
Chris@0 126 * @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory
Chris@0 127 * The config factory service.
Chris@18 128 * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
Chris@18 129 * The entity type manager.
Chris@0 130 * @param \Drupal\Core\Database\Connection $connection
Chris@0 131 * The current database connection.
Chris@0 132 * @param \Drupal\Core\StringTranslation\TranslationInterface $string_translation
Chris@0 133 * The translation manager service.
Chris@0 134 * @param \Drupal\comment\CommentManagerInterface $comment_manager
Chris@0 135 * The comment manager service.
Chris@18 136 * @param \Drupal\Core\Entity\EntityFieldManagerInterface $entity_field_manager
Chris@18 137 * The entity field manager.
Chris@0 138 */
Chris@18 139 public function __construct(ConfigFactoryInterface $config_factory, EntityTypeManagerInterface $entity_type_manager, Connection $connection, TranslationInterface $string_translation, CommentManagerInterface $comment_manager, EntityFieldManagerInterface $entity_field_manager = NULL) {
Chris@0 140 $this->configFactory = $config_factory;
Chris@18 141 $this->entityTypeManager = $entity_type_manager;
Chris@0 142 $this->connection = $connection;
Chris@0 143 $this->stringTranslation = $string_translation;
Chris@0 144 $this->commentManager = $comment_manager;
Chris@18 145 if (!$entity_field_manager) {
Chris@18 146 @trigger_error('The entity_field.manager service must be passed to ForumManager::__construct(), it is required before Drupal 9.0.0. See https://www.drupal.org/node/2549139.', E_USER_DEPRECATED);
Chris@18 147 $entity_field_manager = \Drupal::service('entity_field.manager');
Chris@18 148 }
Chris@18 149 $this->entityFieldManager = $entity_field_manager;
Chris@0 150 }
Chris@0 151
Chris@0 152 /**
Chris@0 153 * {@inheritdoc}
Chris@0 154 */
Chris@0 155 public function getTopics($tid, AccountInterface $account) {
Chris@0 156 $config = $this->configFactory->get('forum.settings');
Chris@0 157 $forum_per_page = $config->get('topics.page_limit');
Chris@0 158 $sortby = $config->get('topics.order');
Chris@0 159
Chris@0 160 $header = [
Chris@0 161 ['data' => $this->t('Topic'), 'field' => 'f.title'],
Chris@0 162 ['data' => $this->t('Replies'), 'field' => 'f.comment_count'],
Chris@0 163 ['data' => $this->t('Last reply'), 'field' => 'f.last_comment_timestamp'],
Chris@0 164 ];
Chris@0 165
Chris@0 166 $order = $this->getTopicOrder($sortby);
Chris@0 167 for ($i = 0; $i < count($header); $i++) {
Chris@0 168 if ($header[$i]['field'] == $order['field']) {
Chris@0 169 $header[$i]['sort'] = $order['sort'];
Chris@0 170 }
Chris@0 171 }
Chris@0 172
Chris@0 173 $query = $this->connection->select('forum_index', 'f')
Chris@0 174 ->extend('Drupal\Core\Database\Query\PagerSelectExtender')
Chris@0 175 ->extend('Drupal\Core\Database\Query\TableSortExtender');
Chris@0 176 $query->fields('f');
Chris@0 177 $query
Chris@0 178 ->condition('f.tid', $tid)
Chris@0 179 ->addTag('node_access')
Chris@0 180 ->addMetaData('base_table', 'forum_index')
Chris@0 181 ->orderBy('f.sticky', 'DESC')
Chris@0 182 ->orderByHeader($header)
Chris@0 183 ->limit($forum_per_page);
Chris@0 184
Chris@0 185 $count_query = $this->connection->select('forum_index', 'f');
Chris@0 186 $count_query->condition('f.tid', $tid);
Chris@0 187 $count_query->addExpression('COUNT(*)');
Chris@0 188 $count_query->addTag('node_access');
Chris@0 189 $count_query->addMetaData('base_table', 'forum_index');
Chris@0 190
Chris@0 191 $query->setCountQuery($count_query);
Chris@0 192 $result = $query->execute();
Chris@0 193 $nids = [];
Chris@0 194 foreach ($result as $record) {
Chris@0 195 $nids[] = $record->nid;
Chris@0 196 }
Chris@0 197 if ($nids) {
Chris@18 198 $nodes = $this->entityTypeManager->getStorage('node')->loadMultiple($nids);
Chris@0 199
Chris@0 200 $query = $this->connection->select('node_field_data', 'n')
Chris@0 201 ->extend('Drupal\Core\Database\Query\TableSortExtender');
Chris@0 202 $query->fields('n', ['nid']);
Chris@0 203
Chris@0 204 $query->join('comment_entity_statistics', 'ces', "n.nid = ces.entity_id AND ces.field_name = 'comment_forum' AND ces.entity_type = 'node'");
Chris@0 205 $query->fields('ces', [
Chris@0 206 'cid',
Chris@0 207 'last_comment_uid',
Chris@0 208 'last_comment_timestamp',
Chris@17 209 'comment_count',
Chris@0 210 ]);
Chris@0 211
Chris@0 212 $query->join('forum_index', 'f', 'f.nid = n.nid');
Chris@0 213 $query->addField('f', 'tid', 'forum_tid');
Chris@0 214
Chris@0 215 $query->join('users_field_data', 'u', 'n.uid = u.uid AND u.default_langcode = 1');
Chris@0 216 $query->addField('u', 'name');
Chris@0 217
Chris@0 218 $query->join('users_field_data', 'u2', 'ces.last_comment_uid = u2.uid AND u.default_langcode = 1');
Chris@0 219
Chris@0 220 $query->addExpression('CASE ces.last_comment_uid WHEN 0 THEN ces.last_comment_name ELSE u2.name END', 'last_comment_name');
Chris@0 221
Chris@0 222 $query
Chris@0 223 ->orderBy('f.sticky', 'DESC')
Chris@0 224 ->orderByHeader($header)
Chris@0 225 ->condition('n.nid', $nids, 'IN')
Chris@0 226 // @todo This should be actually filtering on the desired node language
Chris@0 227 // and just fall back to the default language.
Chris@0 228 ->condition('n.default_langcode', 1);
Chris@0 229
Chris@0 230 $result = [];
Chris@0 231 foreach ($query->execute() as $row) {
Chris@0 232 $topic = $nodes[$row->nid];
Chris@0 233 $topic->comment_mode = $topic->comment_forum->status;
Chris@0 234
Chris@0 235 foreach ($row as $key => $value) {
Chris@0 236 $topic->{$key} = $value;
Chris@0 237 }
Chris@0 238 $result[] = $topic;
Chris@0 239 }
Chris@0 240 }
Chris@0 241 else {
Chris@0 242 $result = [];
Chris@0 243 }
Chris@0 244
Chris@0 245 $topics = [];
Chris@0 246 $first_new_found = FALSE;
Chris@0 247 foreach ($result as $topic) {
Chris@0 248 if ($account->isAuthenticated()) {
Chris@0 249 // A forum is new if the topic is new, or if there are new comments since
Chris@0 250 // the user's last visit.
Chris@0 251 if ($topic->forum_tid != $tid) {
Chris@0 252 $topic->new = 0;
Chris@0 253 }
Chris@0 254 else {
Chris@0 255 $history = $this->lastVisit($topic->id(), $account);
Chris@0 256 $topic->new_replies = $this->commentManager->getCountNewComments($topic, 'comment_forum', $history);
Chris@0 257 $topic->new = $topic->new_replies || ($topic->last_comment_timestamp > $history);
Chris@0 258 }
Chris@0 259 }
Chris@0 260 else {
Chris@0 261 // Do not track "new replies" status for topics if the user is anonymous.
Chris@0 262 $topic->new_replies = 0;
Chris@0 263 $topic->new = 0;
Chris@0 264 }
Chris@0 265
Chris@0 266 // Make sure only one topic is indicated as the first new topic.
Chris@0 267 $topic->first_new = FALSE;
Chris@0 268 if ($topic->new != 0 && !$first_new_found) {
Chris@0 269 $topic->first_new = TRUE;
Chris@0 270 $first_new_found = TRUE;
Chris@0 271 }
Chris@0 272
Chris@0 273 if ($topic->comment_count > 0) {
Chris@0 274 $last_reply = new \stdClass();
Chris@0 275 $last_reply->created = $topic->last_comment_timestamp;
Chris@0 276 $last_reply->name = $topic->last_comment_name;
Chris@0 277 $last_reply->uid = $topic->last_comment_uid;
Chris@0 278 $topic->last_reply = $last_reply;
Chris@0 279 }
Chris@0 280 $topics[$topic->id()] = $topic;
Chris@0 281 }
Chris@0 282
Chris@0 283 return ['topics' => $topics, 'header' => $header];
Chris@0 284
Chris@0 285 }
Chris@0 286
Chris@0 287 /**
Chris@0 288 * Gets topic sorting information based on an integer code.
Chris@0 289 *
Chris@0 290 * @param int $sortby
Chris@0 291 * One of the following integers indicating the sort criteria:
Chris@0 292 * - ForumManager::NEWEST_FIRST: Date - newest first.
Chris@0 293 * - ForumManager::OLDEST_FIRST: Date - oldest first.
Chris@0 294 * - ForumManager::MOST_POPULAR_FIRST: Posts with the most comments first.
Chris@0 295 * - ForumManager::LEAST_POPULAR_FIRST: Posts with the least comments first.
Chris@0 296 *
Chris@0 297 * @return array
Chris@0 298 * An array with the following values:
Chris@0 299 * - field: A field for an SQL query.
Chris@0 300 * - sort: 'asc' or 'desc'.
Chris@0 301 */
Chris@0 302 protected function getTopicOrder($sortby) {
Chris@0 303 switch ($sortby) {
Chris@0 304 case static::NEWEST_FIRST:
Chris@0 305 return ['field' => 'f.last_comment_timestamp', 'sort' => 'desc'];
Chris@0 306
Chris@0 307 case static::OLDEST_FIRST:
Chris@0 308 return ['field' => 'f.last_comment_timestamp', 'sort' => 'asc'];
Chris@0 309
Chris@0 310 case static::MOST_POPULAR_FIRST:
Chris@0 311 return ['field' => 'f.comment_count', 'sort' => 'desc'];
Chris@0 312
Chris@0 313 case static::LEAST_POPULAR_FIRST:
Chris@0 314 return ['field' => 'f.comment_count', 'sort' => 'asc'];
Chris@0 315
Chris@0 316 }
Chris@0 317 }
Chris@0 318
Chris@0 319 /**
Chris@0 320 * Gets the last time the user viewed a node.
Chris@0 321 *
Chris@0 322 * @param int $nid
Chris@0 323 * The node ID.
Chris@0 324 * @param \Drupal\Core\Session\AccountInterface $account
Chris@0 325 * Account to fetch last time for.
Chris@0 326 *
Chris@0 327 * @return int
Chris@0 328 * The timestamp when the user last viewed this node, if the user has
Chris@0 329 * previously viewed the node; otherwise HISTORY_READ_LIMIT.
Chris@0 330 */
Chris@0 331 protected function lastVisit($nid, AccountInterface $account) {
Chris@0 332 if (empty($this->history[$nid])) {
Chris@0 333 $result = $this->connection->select('history', 'h')
Chris@0 334 ->fields('h', ['nid', 'timestamp'])
Chris@0 335 ->condition('uid', $account->id())
Chris@0 336 ->execute();
Chris@0 337 foreach ($result as $t) {
Chris@0 338 $this->history[$t->nid] = $t->timestamp > HISTORY_READ_LIMIT ? $t->timestamp : HISTORY_READ_LIMIT;
Chris@0 339 }
Chris@0 340 }
Chris@0 341 return isset($this->history[$nid]) ? $this->history[$nid] : HISTORY_READ_LIMIT;
Chris@0 342 }
Chris@0 343
Chris@0 344 /**
Chris@0 345 * Provides the last post information for the given forum tid.
Chris@0 346 *
Chris@0 347 * @param int $tid
Chris@0 348 * The forum tid.
Chris@0 349 *
Chris@0 350 * @return \stdClass
Chris@0 351 * The last post for the given forum.
Chris@0 352 */
Chris@0 353 protected function getLastPost($tid) {
Chris@0 354 if (!empty($this->lastPostData[$tid])) {
Chris@0 355 return $this->lastPostData[$tid];
Chris@0 356 }
Chris@0 357 // Query "Last Post" information for this forum.
Chris@0 358 $query = $this->connection->select('node_field_data', 'n');
Chris@0 359 $query->join('forum', 'f', 'n.vid = f.vid AND f.tid = :tid', [':tid' => $tid]);
Chris@0 360 $query->join('comment_entity_statistics', 'ces', "n.nid = ces.entity_id AND ces.field_name = 'comment_forum' AND ces.entity_type = 'node'");
Chris@0 361 $query->join('users_field_data', 'u', 'ces.last_comment_uid = u.uid AND u.default_langcode = 1');
Chris@0 362 $query->addExpression('CASE ces.last_comment_uid WHEN 0 THEN ces.last_comment_name ELSE u.name END', 'last_comment_name');
Chris@0 363
Chris@0 364 $topic = $query
Chris@0 365 ->fields('ces', ['last_comment_timestamp', 'last_comment_uid'])
Chris@0 366 ->condition('n.status', 1)
Chris@0 367 ->orderBy('last_comment_timestamp', 'DESC')
Chris@0 368 ->range(0, 1)
Chris@0 369 ->addTag('node_access')
Chris@0 370 ->execute()
Chris@0 371 ->fetchObject();
Chris@0 372
Chris@0 373 // Build the last post information.
Chris@0 374 $last_post = new \stdClass();
Chris@0 375 if (!empty($topic->last_comment_timestamp)) {
Chris@0 376 $last_post->created = $topic->last_comment_timestamp;
Chris@0 377 $last_post->name = $topic->last_comment_name;
Chris@0 378 $last_post->uid = $topic->last_comment_uid;
Chris@0 379 }
Chris@0 380
Chris@0 381 $this->lastPostData[$tid] = $last_post;
Chris@0 382 return $last_post;
Chris@0 383 }
Chris@0 384
Chris@0 385 /**
Chris@0 386 * Provides statistics for a forum.
Chris@0 387 *
Chris@0 388 * @param int $tid
Chris@0 389 * The forum tid.
Chris@0 390 *
Chris@0 391 * @return \stdClass|null
Chris@0 392 * Statistics for the given forum if statistics exist, else NULL.
Chris@0 393 */
Chris@0 394 protected function getForumStatistics($tid) {
Chris@0 395 if (empty($this->forumStatistics)) {
Chris@0 396 // Prime the statistics.
Chris@0 397 $query = $this->connection->select('node_field_data', 'n');
Chris@0 398 $query->join('comment_entity_statistics', 'ces', "n.nid = ces.entity_id AND ces.field_name = 'comment_forum' AND ces.entity_type = 'node'");
Chris@0 399 $query->join('forum', 'f', 'n.vid = f.vid');
Chris@0 400 $query->addExpression('COUNT(n.nid)', 'topic_count');
Chris@0 401 $query->addExpression('SUM(ces.comment_count)', 'comment_count');
Chris@0 402 $this->forumStatistics = $query
Chris@0 403 ->fields('f', ['tid'])
Chris@0 404 ->condition('n.status', 1)
Chris@0 405 ->condition('n.default_langcode', 1)
Chris@0 406 ->groupBy('tid')
Chris@0 407 ->addTag('node_access')
Chris@0 408 ->execute()
Chris@0 409 ->fetchAllAssoc('tid');
Chris@0 410 }
Chris@0 411
Chris@0 412 if (!empty($this->forumStatistics[$tid])) {
Chris@0 413 return $this->forumStatistics[$tid];
Chris@0 414 }
Chris@0 415 }
Chris@0 416
Chris@0 417 /**
Chris@0 418 * {@inheritdoc}
Chris@0 419 */
Chris@0 420 public function getChildren($vid, $tid) {
Chris@0 421 if (!empty($this->forumChildren[$tid])) {
Chris@0 422 return $this->forumChildren[$tid];
Chris@0 423 }
Chris@0 424 $forums = [];
Chris@18 425 $_forums = $this->entityTypeManager->getStorage('taxonomy_term')->loadTree($vid, $tid, NULL, TRUE);
Chris@0 426 foreach ($_forums as $forum) {
Chris@0 427 // Merge in the topic and post counters.
Chris@0 428 if (($count = $this->getForumStatistics($forum->id()))) {
Chris@0 429 $forum->num_topics = $count->topic_count;
Chris@0 430 $forum->num_posts = $count->topic_count + $count->comment_count;
Chris@0 431 }
Chris@0 432 else {
Chris@0 433 $forum->num_topics = 0;
Chris@0 434 $forum->num_posts = 0;
Chris@0 435 }
Chris@0 436
Chris@0 437 // Merge in last post details.
Chris@0 438 $forum->last_post = $this->getLastPost($forum->id());
Chris@0 439 $forums[$forum->id()] = $forum;
Chris@0 440 }
Chris@0 441
Chris@0 442 $this->forumChildren[$tid] = $forums;
Chris@0 443 return $forums;
Chris@0 444 }
Chris@0 445
Chris@0 446 /**
Chris@0 447 * {@inheritdoc}
Chris@0 448 */
Chris@0 449 public function getIndex() {
Chris@0 450 if ($this->index) {
Chris@0 451 return $this->index;
Chris@0 452 }
Chris@0 453
Chris@0 454 $vid = $this->configFactory->get('forum.settings')->get('vocabulary');
Chris@18 455 $index = $this->entityTypeManager->getStorage('taxonomy_term')->create([
Chris@0 456 'tid' => 0,
Chris@0 457 'container' => 1,
Chris@0 458 'parents' => [],
Chris@0 459 'isIndex' => TRUE,
Chris@17 460 'vid' => $vid,
Chris@0 461 ]);
Chris@0 462
Chris@0 463 // Load the tree below.
Chris@0 464 $index->forums = $this->getChildren($vid, 0);
Chris@0 465 $this->index = $index;
Chris@0 466 return $index;
Chris@0 467 }
Chris@0 468
Chris@0 469 /**
Chris@0 470 * {@inheritdoc}
Chris@0 471 */
Chris@0 472 public function resetCache() {
Chris@0 473 // Reset the index.
Chris@0 474 $this->index = NULL;
Chris@0 475 // Reset history.
Chris@0 476 $this->history = [];
Chris@0 477 }
Chris@0 478
Chris@0 479 /**
Chris@0 480 * {@inheritdoc}
Chris@0 481 */
Chris@0 482 public function getParents($tid) {
Chris@18 483 return $this->entityTypeManager->getStorage('taxonomy_term')->loadAllParents($tid);
Chris@0 484 }
Chris@0 485
Chris@0 486 /**
Chris@0 487 * {@inheritdoc}
Chris@0 488 */
Chris@0 489 public function checkNodeType(NodeInterface $node) {
Chris@0 490 // Fetch information about the forum field.
Chris@18 491 $field_definitions = $this->entityFieldManager->getFieldDefinitions('node', $node->bundle());
Chris@0 492 return !empty($field_definitions['taxonomy_forums']);
Chris@0 493 }
Chris@0 494
Chris@0 495 /**
Chris@0 496 * {@inheritdoc}
Chris@0 497 */
Chris@0 498 public function unreadTopics($term, $uid) {
Chris@0 499 $query = $this->connection->select('node_field_data', 'n');
Chris@0 500 $query->join('forum', 'f', 'n.vid = f.vid AND f.tid = :tid', [':tid' => $term]);
Chris@0 501 $query->leftJoin('history', 'h', 'n.nid = h.nid AND h.uid = :uid', [':uid' => $uid]);
Chris@0 502 $query->addExpression('COUNT(n.nid)', 'count');
Chris@0 503 return $query
Chris@0 504 ->condition('status', 1)
Chris@0 505 // @todo This should be actually filtering on the desired node status
Chris@0 506 // field language and just fall back to the default language.
Chris@0 507 ->condition('n.default_langcode', 1)
Chris@0 508 ->condition('n.created', HISTORY_READ_LIMIT, '>')
Chris@0 509 ->isNull('h.nid')
Chris@0 510 ->addTag('node_access')
Chris@0 511 ->execute()
Chris@0 512 ->fetchField();
Chris@0 513 }
Chris@0 514
Chris@0 515 /**
Chris@0 516 * {@inheritdoc}
Chris@0 517 */
Chris@0 518 public function __sleep() {
Chris@0 519 $vars = $this->defaultSleep();
Chris@0 520 // Do not serialize static cache.
Chris@0 521 unset($vars['history'], $vars['index'], $vars['lastPostData'], $vars['forumChildren'], $vars['forumStatistics']);
Chris@0 522 return $vars;
Chris@0 523 }
Chris@0 524
Chris@0 525 /**
Chris@0 526 * {@inheritdoc}
Chris@0 527 */
Chris@0 528 public function __wakeup() {
Chris@0 529 $this->defaultWakeup();
Chris@0 530 // Initialize static cache.
Chris@0 531 $this->history = [];
Chris@0 532 $this->lastPostData = [];
Chris@0 533 $this->forumChildren = [];
Chris@0 534 $this->forumStatistics = [];
Chris@0 535 $this->index = NULL;
Chris@0 536 }
Chris@0 537
Chris@0 538 }