1
|
<?php
|
2
|
|
3
|
/**
|
4
|
* @file
|
5
|
* User page callbacks for the forum module.
|
6
|
*/
|
7
|
|
8
|
/**
|
9
|
* Menu callback; prints a forum listing.
|
10
|
*/
|
11
|
function advanced_forum_page($forum_term = NULL) {
|
12
|
if (!isset($forum_term)) {
|
13
|
// On the main page, display all the top-level forums.
|
14
|
$forum_term = advanced_forum_forum_load(0);
|
15
|
}
|
16
|
|
17
|
// Set tid for <root> container.
|
18
|
if (!isset($forum_term->tid)) {
|
19
|
$forum_term->tid = 0;
|
20
|
}
|
21
|
_advanced_forum_add_files();
|
22
|
|
23
|
$forum_per_page = variable_get('forum_per_page', 25);
|
24
|
$sortby = variable_get('forum_order', 1);
|
25
|
|
26
|
if (empty($forum_term->container)) {
|
27
|
$topics = advanced_forum_get_topics($forum_term->tid, $sortby, $forum_per_page);
|
28
|
}
|
29
|
else {
|
30
|
$topics = '';
|
31
|
}
|
32
|
|
33
|
$vid = variable_get('forum_nav_vocabulary', 0);
|
34
|
$vocabulary = taxonomy_vocabulary_load($vid);
|
35
|
|
36
|
// Breadcrumb navigation:
|
37
|
$breadcrumb[] = l(t('Home'), NULL);
|
38
|
if ($forum_term->tid) {
|
39
|
$breadcrumb[] = l($vocabulary->name, 'forum');
|
40
|
}
|
41
|
|
42
|
if ($forum_term->parents) {
|
43
|
foreach (array_reverse($forum_term->parents) as $p) {
|
44
|
if ($p->tid != $forum_term->tid) {
|
45
|
$breadcrumb[] = l($p->name, 'forum/' . $p->tid);
|
46
|
}
|
47
|
else {
|
48
|
$title = $p->name;
|
49
|
}
|
50
|
}
|
51
|
}
|
52
|
|
53
|
if (empty($title)) {
|
54
|
$title = $vocabulary->name;
|
55
|
}
|
56
|
|
57
|
if (!variable_get('advanced_forum_disable_breadcrumbs', FALSE)) {
|
58
|
drupal_set_breadcrumb($breadcrumb);
|
59
|
}
|
60
|
|
61
|
drupal_set_title($title);
|
62
|
|
63
|
return theme('forums', array(
|
64
|
'forums' => $forum_term->forums,
|
65
|
'topics' => $topics,
|
66
|
'parents' => $forum_term->parents,
|
67
|
'tid' => $forum_term->tid,
|
68
|
'sortby' => $sortby,
|
69
|
'forums_per_page' => $forum_per_page,
|
70
|
));
|
71
|
}
|
72
|
|
73
|
/**
|
74
|
* Returns a tree of all forums for a given taxonomy term ID.
|
75
|
*
|
76
|
* This is copied from the forum module and adapted.
|
77
|
*
|
78
|
* @param int|null $tid
|
79
|
* (optional) Taxonomy ID of the forum, if not givin all forums will be returned.
|
80
|
*
|
81
|
* @return object
|
82
|
* A tree of taxonomy objects, with the following additional properties:
|
83
|
* - 'num_topics': Number of topics in the forum
|
84
|
* - 'num_posts': Total number of posts in all topics
|
85
|
* - 'last_post': Most recent post for the forum
|
86
|
* - 'forums': An array of child forums
|
87
|
*/
|
88
|
function advanced_forum_forum_load($tid = NULL) {
|
89
|
$cache = &drupal_static(__FUNCTION__, array());
|
90
|
|
91
|
global $language;
|
92
|
|
93
|
// Return a cached forum tree if available.
|
94
|
if (empty($tid)) {
|
95
|
$tid = 0;
|
96
|
}
|
97
|
if (isset($cache[$tid])) {
|
98
|
return $cache[$tid];
|
99
|
}
|
100
|
|
101
|
// Find out from the style's .info how many posts per forum to collect.
|
102
|
$info = advanced_forum_style_info();
|
103
|
$post_count = isset($info['forum list post count']) ? intval($info['forum list post count']) : 1;
|
104
|
|
105
|
$vid = variable_get('forum_nav_vocabulary', 0);
|
106
|
|
107
|
// Load and validate the parent term.
|
108
|
if ($tid) {
|
109
|
$forum_term = taxonomy_term_load($tid);
|
110
|
|
111
|
if (module_exists('i18n_taxonomy')) {
|
112
|
$forum_term = i18n_taxonomy_localize_terms($forum_term);
|
113
|
}
|
114
|
if (!$forum_term || ($forum_term->vid != $vid)) {
|
115
|
return $cache[$tid] = FALSE;
|
116
|
}
|
117
|
}
|
118
|
// If $tid is 0, create an empty object to hold the child terms.
|
119
|
elseif ($tid === 0) {
|
120
|
$forum_term = (object) array(
|
121
|
'tid' => 0,
|
122
|
);
|
123
|
}
|
124
|
|
125
|
// Determine if the requested term is a container.
|
126
|
if (!$forum_term->tid || in_array($forum_term->tid, variable_get('forum_containers', array()))) {
|
127
|
$forum_term->container = 1;
|
128
|
}
|
129
|
|
130
|
// Load parent terms.
|
131
|
$forum_term->parents = taxonomy_get_parents_all($forum_term->tid);
|
132
|
|
133
|
// Load the tree below.
|
134
|
$forums = array();
|
135
|
$_forums = taxonomy_get_tree($vid, $tid);
|
136
|
|
137
|
if (module_exists('i18n_taxonomy')) {
|
138
|
$_forums = i18n_taxonomy_localize_terms($_forums);
|
139
|
}
|
140
|
|
141
|
if ($cached = cache_get('adv_forum_counts' . $tid . ':' . $language->language, 'cache')) {
|
142
|
if ($cached->expire > time()) {
|
143
|
$counts = $cached->data;
|
144
|
}
|
145
|
}
|
146
|
if (count($_forums) && empty($counts)) {
|
147
|
$query = db_select('node', 'n');
|
148
|
$query->join('node_comment_statistics', 'ncs', 'n.nid = ncs.nid');
|
149
|
$query->join('forum_index', 'f', 'n.nid = f.nid');
|
150
|
$query->addExpression('COUNT(DISTINCT(f.nid))', 'topic_count');
|
151
|
$query->addExpression('SUM(f.comment_count)', 'comment_count');
|
152
|
|
153
|
// Limit the query to only node types that can actually be associated with
|
154
|
// the forum vocabulary.
|
155
|
if ($vid) {
|
156
|
$vocabulary = taxonomy_vocabulary_load($vid);
|
157
|
$vocabulary_fields = field_read_fields(array('module' => 'taxonomy'));
|
158
|
$node_types = array();
|
159
|
foreach ($vocabulary_fields as $field_name => $vocabulary_field) {
|
160
|
foreach ($vocabulary_field['settings']['allowed_values'] as $key => $allowed_value) {
|
161
|
if ($allowed_value['vocabulary'] == $vocabulary->machine_name) {
|
162
|
$field_info = field_info_field($field_name);
|
163
|
if (isset($field_info['bundles']['node'])) {
|
164
|
$node_types += $field_info['bundles']['node'];
|
165
|
}
|
166
|
}
|
167
|
}
|
168
|
}
|
169
|
|
170
|
if (!empty($node_types)) {
|
171
|
$query->condition('type', $node_types, 'IN');
|
172
|
}
|
173
|
|
174
|
$query->condition('language', array(LANGUAGE_NONE, $language->language));
|
175
|
}
|
176
|
|
177
|
$counts = $query
|
178
|
->fields('f', array('tid'))
|
179
|
->condition('status', 1)
|
180
|
->groupBy('tid')
|
181
|
->addTag('node_access')
|
182
|
->execute()
|
183
|
->fetchAllAssoc('tid');
|
184
|
// 1 hour.
|
185
|
cache_set('adv_forum_counts' . $tid, $counts, 'cache', time() + 60 * 60);
|
186
|
}
|
187
|
|
188
|
// Get last nodes with comments for subquery SELECT optimization.
|
189
|
$subquery = db_select('node_comment_statistics', 'lnsc')
|
190
|
->fields('lnsc', array('nid'))
|
191
|
->distinct()
|
192
|
->orderBy('last_comment_timestamp', 'DESC')
|
193
|
->range(0, 1000);
|
194
|
// Should be moved to options or additionally calculated elsewhere.
|
195
|
foreach ($_forums as $forum) {
|
196
|
// Determine if the child term is a container.
|
197
|
if (in_array($forum->tid, variable_get('forum_containers', array()))) {
|
198
|
$forum->container = 1;
|
199
|
}
|
200
|
|
201
|
// Merge in the topic and post counters.
|
202
|
if (!empty($counts[$forum->tid])) {
|
203
|
$forum->num_topics = $counts[$forum->tid]->topic_count;
|
204
|
$forum->num_posts = $counts[$forum->tid]->topic_count + $counts[$forum->tid]->comment_count;
|
205
|
}
|
206
|
else {
|
207
|
$forum->num_topics = 0;
|
208
|
$forum->num_posts = 0;
|
209
|
}
|
210
|
|
211
|
// Query "Last Post" information for this forum.
|
212
|
$query = db_select('node', 'n');
|
213
|
$query->join($subquery, 'lastnodes', 'n.nid = lastnodes.nid');
|
214
|
$query->join('forum_index', 'f', 'n.nid = f.nid AND f.tid = :tid', array(':tid' => $forum->tid));
|
215
|
$query->join('node_comment_statistics', 'ncs', 'n.nid = ncs.nid');
|
216
|
$query->join('users', 'u', 'ncs.last_comment_uid = u.uid');
|
217
|
$query->addExpression('CASE ncs.last_comment_uid WHEN 0 THEN ncs.last_comment_name ELSE u.name END', 'last_comment_name');
|
218
|
|
219
|
$topics = $query
|
220
|
->fields('ncs', array('last_comment_timestamp', 'last_comment_uid'))
|
221
|
->fields('n', array('nid', 'title', 'type'))
|
222
|
->condition('n.status', 1)
|
223
|
->orderBy('last_comment_timestamp', 'DESC')
|
224
|
->range(0, $post_count)
|
225
|
->addTag('node_access')
|
226
|
->execute();
|
227
|
|
228
|
while ($topic = $topics->fetchObject()) {
|
229
|
// Merge in the "Last Post" information.
|
230
|
$last_post = new stdClass();
|
231
|
if (!empty($topic->last_comment_timestamp)) {
|
232
|
$last_post->nid = $topic->nid;
|
233
|
$last_post->node_title = $topic->title;
|
234
|
$last_post->type = $topic->type;
|
235
|
$last_post->created = $topic->last_comment_timestamp;
|
236
|
$last_post->name = $topic->last_comment_name;
|
237
|
$last_post->uid = $topic->last_comment_uid;
|
238
|
}
|
239
|
if ($post_count > 1) {
|
240
|
$forum->last_post[] = $last_post;
|
241
|
}
|
242
|
else {
|
243
|
$forum->last_post = $last_post;
|
244
|
}
|
245
|
}
|
246
|
|
247
|
$forums[$forum->tid] = $forum;
|
248
|
}
|
249
|
|
250
|
// Cache the result, and return the tree.
|
251
|
$forum_term->forums = $forums;
|
252
|
$cache[$tid] = $forum_term;
|
253
|
return $forum_term;
|
254
|
}
|
255
|
|
256
|
/**
|
257
|
* Update parent post count.
|
258
|
*/
|
259
|
function _advanced_forum_update_parent_post_count(&$forums, $forum) {
|
260
|
foreach ($forum->parents as $parent_tid) {
|
261
|
if (!empty($forums[$parent_tid])) {
|
262
|
$forums[$parent_tid]->num_topics += $forum->num_topics;
|
263
|
$forums[$parent_tid]->num_posts += $forum->num_posts;
|
264
|
|
265
|
// Recursive loop to update all parents/
|
266
|
if (!empty($forums[$parent_tid]->parents)) {
|
267
|
_advanced_forum_update_parent_post_count($forums, $forums[$parent_tid]);
|
268
|
}
|
269
|
}
|
270
|
}
|
271
|
}
|
272
|
|
273
|
/**
|
274
|
* This is copied from the forum module and adapted.
|
275
|
*/
|
276
|
function advanced_forum_get_topics($tid, $sortby, $forum_per_page, $sort_form = TRUE) {
|
277
|
$term = taxonomy_term_load($tid);
|
278
|
drupal_add_feed('taxonomy/term/' . $tid . '/feed', 'RSS - ' . check_plain($term->name));
|
279
|
|
280
|
// Views handles this page.
|
281
|
$view = views_get_view('advanced_forum_topic_list');
|
282
|
$view->set_items_per_page($forum_per_page);
|
283
|
$view->sort_form = $sort_form;
|
284
|
|
285
|
return $view->preview('default', array($tid));
|
286
|
}
|