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 }
|