forum.module 24.6 KB
Newer Older
Dries Buytaert's avatar
   
Dries Buytaert committed
1
2
3
<?php
// $Id$

4
function forum_system($field){
Dries Buytaert's avatar
   
Dries Buytaert committed
5
6
7
8
9
10
  $output = "";

  if ($field == "description") { $output = forum_help("admin/system/modules"); }
  else if ($field == "admin_help") { $output = forum_help("admin/system/modules/forum"); };

  return $output;
11
12
}

Dries Buytaert's avatar
   
Dries Buytaert committed
13
function forum_node($field) {
Dries Buytaert's avatar
   
Dries Buytaert committed
14
  $info["name"] = t("forum topic");
Dries Buytaert's avatar
   
Dries Buytaert committed
15
16
17
18
19
20
21
22
23
  $info["description"] = t("A forum is a threaded discussion, enabling users to communicate about a particular topic.");

  return $info[$field];
}

function forum_access($op, $node) {
  if ($op == "view") {
    return $node->status;
  }
Dries Buytaert's avatar
   
Dries Buytaert committed
24
  if ($op == "create") {
Dries Buytaert's avatar
   
Dries Buytaert committed
25
    return user_access("create forum topics");
Dries Buytaert's avatar
   
Dries Buytaert committed
26
  }
Dries Buytaert's avatar
   
Dries Buytaert committed
27
28
}

Dries Buytaert's avatar
   
Dries Buytaert committed
29
function forum_perm() {
Dries Buytaert's avatar
   
Dries Buytaert committed
30
  return array("create forum topics");
Dries Buytaert's avatar
   
Dries Buytaert committed
31
}
Dries Buytaert's avatar
   
Dries Buytaert committed
32

33
function forum_settings() {
Dries Buytaert's avatar
   
Dries Buytaert committed
34

Dries Buytaert's avatar
   
Dries Buytaert committed
35
  if (module_exist("taxonomy")) {
Dries Buytaert's avatar
   
Dries Buytaert committed
36
    $vocs[0] = "<". t("none") .">";
Dries Buytaert's avatar
   
Dries Buytaert committed
37
38
39
40
    foreach (taxonomy_get_vocabularies("forum") as $vid => $voc) {
      $vocs[$vid] = $voc->name;
    }

Dries Buytaert's avatar
   
Dries Buytaert committed
41
    if ($voc) {
42
43
      $output .= form_textarea(t("Explanation or submission guidelines"), "forum_help", variable_get("forum_help", ""), 70, 5, t("This text will be displayed at the top of the forum submission form.  Useful for helping or instructing your users."));
      $output .= form_select(t("Forum vocabulary"), "forum_nav_vocabulary", variable_get("forum_nav_vocabulary", ""), $vocs, t("The taxonomy vocabulary that will be used as the navigation tree."));
Dries Buytaert's avatar
   
Dries Buytaert committed
44
      $output .= form_textfield(t("Forum icon path"), "forum_icon_path", variable_get("forum_icon_path", ""), 30, 255, t("The path to the forum icons.  Leave blank to disable icons.  Don't add a trailing slash.  Default icons are available in the 'misc' directory."));
Dries Buytaert's avatar
   
Dries Buytaert committed
45
      $number = array(5 => 5, 10 => 10, 15 => 15, 20 => 20, 25 => 25, 30 => 30, 35 => 35, 40 => 40, 50 => 50, 60 => 60, 80 => 80, 100 => 100, 10000=>10000);
46
      $output .= form_select(t("Hot topic threshold"), "forum_hot_topic", variable_get("forum_hot_topic", 15), $number, t("The number of posts a topic must have to be considered <b>hot</b>."));
Dries Buytaert's avatar
   
Dries Buytaert committed
47
      $number = array(10 => 10, 25 => 25, 50 => 50, 75 => 75, 100 => 100);
48
49
50
51
      $output .= form_select(t("Topics per page"), "forum_per_page", variable_get("forum_per_page", 25), $number, t("The default number of topics displayed per page; links to browse older messages are automatically being displayed."));
      $forder = array(1 => t("Date - newest first"), 2 => t("Date - oldest first"), 3 => t("Posts - most active first"), 4=> t("Posts - least active first"));
      $output .= form_select(t("Default order"), "forum_order", variable_get("forum_order", 1), $forder, t("The default display order for topics."));
      $output .= form_textfield(t("Number of topics in block"), "forum_block_num", variable_get("forum_block_num", "5"), 5, 5, t("The number of topics in the <b>Forum topics</b>-block.  To enable the block, click ". l("here", "admin/block") ."."));
Dries Buytaert's avatar
   
Dries Buytaert committed
52
53
54
55
56
57
58
59
    }
    else {
      $output .= _forum_message_taxonomy();
    }
  }
  else {
    $output .= _forum_message_taxonomy();
  }
Dries Buytaert's avatar
   
Dries Buytaert committed
60

Dries Buytaert's avatar
   
Dries Buytaert committed
61
62
63
  return $output;
}

Dries Buytaert's avatar
Dries Buytaert committed
64
65
function forum_taxonomy($op, $type, $object) {
  if ($type == "vocabulary" && ($op == "insert" || $op == "update")) {
Dries Buytaert's avatar
   
Dries Buytaert committed
66
    if (variable_get("forum_nav_vocabulary", "") == "" && in_array("forum", $object["nodes"])) {
Dries Buytaert's avatar
Dries Buytaert committed
67
68
69
70
71
72
      // since none is already set, silently set this vocabulary as the navigation vocabulary
      variable_set("forum_nav_vocabulary", $object["vid"]);
    }
  }
}

Dries Buytaert's avatar
   
Dries Buytaert committed
73
function forum_load($node) {
Dries Buytaert's avatar
   
Dries Buytaert committed
74
  $forum = db_fetch_object(db_query("SELECT * FROM {forum} WHERE nid = %d", $node->nid));
Dries Buytaert's avatar
   
Dries Buytaert committed
75
76
77
78

  return $forum;
}

79
80
81
82
83
84
function forum_block($op = "list", $delta = 0) {
  if ($op == "list") {
    $blocks[0]["info"] = t("Forum topics");
  }
  else {
    if (user_access("access content")) {
Dries Buytaert's avatar
   
Dries Buytaert committed
85
      $content = node_title_list(db_query_range("SELECT n.nid, n.title, GREATEST(n.created, MAX(c.timestamp)) AS sort FROM {node} n LEFT JOIN {comments} c ON n.nid = c.nid WHERE n.type = 'forum' AND n.status = 1 GROUP BY n.nid, n.title, n.created ORDER BY sort DESC", 0, variable_get("forum_block_num", "5")), t("Active forum topics:"));
Dries Buytaert's avatar
   
Dries Buytaert committed
86

Dries Buytaert's avatar
   
Dries Buytaert committed
87
      $content .= node_title_list(db_query_range("SELECT nid, title FROM {node} WHERE type = 'forum' ORDER BY nid DESC", 0, variable_get("forum_block_num", "5")), t("New forum topics:"));
Dries Buytaert's avatar
   
Dries Buytaert committed
88

Dries Buytaert's avatar
   
Dries Buytaert committed
89
      if ($content) {
Dries Buytaert's avatar
   
Dries Buytaert committed
90
        $content .= "<div class=\"more-link\">". l(t("more"), "forum", array("title" => t("Read the latest forum topics."))) ."</div>";
Dries Buytaert's avatar
   
Dries Buytaert committed
91
      }
Dries Buytaert's avatar
   
Dries Buytaert committed
92

93
      $blocks["subject"] = t("Forum topics");
Dries Buytaert's avatar
   
Dries Buytaert committed
94
      $blocks["content"] = $content;
Dries Buytaert's avatar
   
Dries Buytaert committed
95
96
    }
  }
Dries Buytaert's avatar
   
Dries Buytaert committed
97

Dries Buytaert's avatar
   
Dries Buytaert committed
98
99
100
  return $blocks;
}

101
function forum_link($type, $node = 0, $main = 0) {
Dries Buytaert's avatar
Dries Buytaert committed
102
  global $user;
Dries Buytaert's avatar
   
Dries Buytaert committed
103

Dries Buytaert's avatar
   
Dries Buytaert committed
104
105
  $links = array();

Dries Buytaert's avatar
   
Dries Buytaert committed
106
  if ($type == "page" && user_access("access content")) {
Dries Buytaert's avatar
   
Dries Buytaert committed
107
    $links[] = l(t("forums"), "forum");
Dries Buytaert's avatar
   
Dries Buytaert committed
108
109
  }

110
  if (!$main && $type == "node" && $node->type == "forum") {
Dries Buytaert's avatar
   
Dries Buytaert committed
111
112
    // get previous and next topic

Dries Buytaert's avatar
   
Dries Buytaert committed
113
    $result = db_query("SELECT n.nid, n.title, n.body, n.path, GREATEST(n.created, MAX(c.timestamp)) AS date_sort, COUNT(c.nid) AS num_comments FROM {node} n INNER JOIN {forum} f ON n.nid = f.nid INNER JOIN {comments} c ON n.nid = c.nid WHERE n.nid = f.nid AND f.tid = %d AND n.status = 1 GROUP BY n.nid, n.title, n.body, n.created ORDER BY ". _forum_get_topic_order(isset($user->sortby) ? $user->sortby : variable_get("forum_order",1)), $node->tid);
Dries Buytaert's avatar
   
Dries Buytaert committed
114
115
116
117
118
119

    while ($topic = db_fetch_object($result)) {
      if ($stop == 1) {
        $next->nid = $topic->nid;
        $next->title = $topic->title;
        $next->body = $topic->body;
Dries Buytaert's avatar
   
Dries Buytaert committed
120
        $next->path = $topic->path;
Dries Buytaert's avatar
   
Dries Buytaert committed
121
122
123
124
125
126
127
128
129
        break;
      }
      if ($topic->nid == $node->nid) {
        $stop = 1;
      }
      else {
        $prev->nid = $topic->nid;
        $prev->title = $topic->title;
        $prev->body = $topic->body;
Dries Buytaert's avatar
   
Dries Buytaert committed
130
        $prev->path = $topic->path;
Dries Buytaert's avatar
   
Dries Buytaert committed
131
132
133
134
      }
    }

    if ($prev) {
Dries Buytaert's avatar
   
Dries Buytaert committed
135
      $links[] = l(t("previous forum topic"), node_url($prev), array("title" => $prev->title .": ". substr(strip_tags($prev->body), 0, 100)."..."));
Dries Buytaert's avatar
   
Dries Buytaert committed
136
137
138
    }

    if ($next) {
Dries Buytaert's avatar
   
Dries Buytaert committed
139
      $links[] = l(t("next forum topic"), node_url($next), array("title" => $next->title .": ". substr(strip_tags($next->body), 0, 100)."..."));
Dries Buytaert's avatar
   
Dries Buytaert committed
140
    }
Dries Buytaert's avatar
   
Dries Buytaert committed
141
142
  }

Dries Buytaert's avatar
   
Dries Buytaert committed
143
  return $links;
Dries Buytaert's avatar
   
Dries Buytaert committed
144
145
}

Dries Buytaert's avatar
   
Dries Buytaert committed
146
function forum_view($node, $main = 0) {
Dries Buytaert's avatar
   
Dries Buytaert committed
147

Dries Buytaert's avatar
   
Dries Buytaert committed
148
149
150
151
152
153
154
155
  if ($main == 0) {
    $term_data = array_shift(taxonomy_node_get_terms($node->nid));
    if (!$term_data) {
      // we are previewing
      $term_data = taxonomy_get_term($node->taxonomy[0]);
    }
    $voc = taxonomy_get_vocabulary($term_data->vid);

Dries Buytaert's avatar
   
Dries Buytaert committed
156
157
158
    $node->trail[] = l(t("Home"), NULL);
    $node->trail[] = l(t("Forums"), "forum");
    $node->trail[] = l($term_data->name, "forum/$term_data->tid");
159
  }
Dries Buytaert's avatar
   
Dries Buytaert committed
160

Dries Buytaert's avatar
   
Dries Buytaert committed
161
162
163
  $node->teaser = check_output($node->teaser);
  $node->body = check_output($node->body);

Dries Buytaert's avatar
   
Dries Buytaert committed
164
  return $node;
Dries Buytaert's avatar
   
Dries Buytaert committed
165
166
}

167
168
169
170
function forum_validate(&$node) {
  // Make sure all fields are set properly:
  $node->icon = $node->icon ? $node->icon : "";
  $node->shadow = $node->shadow ? $node->shadow : 0;
171
  $node->tid = $node->tid ? $node->tid : 0;
172
173
174
175
176
177
  // We use the validate hook to remember the old taxonomy terms:
  if ($node->tid) {
    $node->taxonomy = array_keys(taxonomy_node_get_terms($node->nid));
    if (!in_array($node->tid[0], $node->taxonomy)) {
      $node->taxonomy[] = $node->tid[0];
    }
Dries Buytaert's avatar
Dries Buytaert committed
178
179
180
  }
}

Dries Buytaert's avatar
   
Dries Buytaert committed
181
function forum_form(&$node, &$help, &$error) {
Dries Buytaert's avatar
Dries Buytaert committed
182
183
184
  if ($node->tid) {
    // editing
    $tid = $node->tid;
185
186
  }
  else {
Dries Buytaert's avatar
Dries Buytaert committed
187
188
    // new topic
    $tid = arg(3);
189
190
  }

Dries Buytaert's avatar
   
Dries Buytaert committed
191
192
193
  // outputs the compose guidelines
  $help = variable_get("forum_help", "");

Dries Buytaert's avatar
   
Dries Buytaert committed
194
  $output .= _taxonomy_term_select(t("Forum"), "tid", $tid, variable_get("forum_nav_vocabulary", ""), "", 0, "");
Dries Buytaert's avatar
Dries Buytaert committed
195
196
197
198
199

  if ($node->nid) {
    // if editing, give option to leave shadows
    $output .= form_checkbox(t("Leave shadow copy"), "shadow", 1, $node->shadow, t("If you move this topic, you can leave a link in the old forum to the new forum."));
  }
Dries Buytaert's avatar
   
Dries Buytaert committed
200

201
  $output .= form_textarea(t("Body"), "body", $node->body, 60, 10);
Dries Buytaert's avatar
   
Dries Buytaert committed
202
203
204
205

  return $output;
}

Dries Buytaert's avatar
   
Dries Buytaert committed
206
function forum_insert($node) {
Dries Buytaert's avatar
   
Dries Buytaert committed
207
  db_query("INSERT INTO {forum} (nid, shadow, tid) VALUES (%d, %d, %d)", $node->nid, $node->shadow, $node->tid[0]);
Dries Buytaert's avatar
   
Dries Buytaert committed
208
209
210
}

function forum_update($node) {
Dries Buytaert's avatar
   
Dries Buytaert committed
211
  db_query("UPDATE {forum} SET shadow = %d, tid = %d WHERE nid = %d", $node->shadow, $node->tid[0], $node->nid);
Dries Buytaert's avatar
   
Dries Buytaert committed
212
213
214
}

function forum_delete(&$node) {
Dries Buytaert's avatar
   
Dries Buytaert committed
215
  db_query("DELETE FROM {forum} WHERE nid = %d", $node->nid);
Dries Buytaert's avatar
   
Dries Buytaert committed
216
}
Dries Buytaert's avatar
   
Dries Buytaert committed
217

Dries Buytaert's avatar
   
Dries Buytaert committed
218
function _forum_num_comments($nid) {
Dries Buytaert's avatar
   
Dries Buytaert committed
219
  $value = db_fetch_object(db_query("SELECT COUNT(cid) AS count FROM {comments} WHERE nid = %d AND status = 0", $nid));
Dries Buytaert's avatar
   
Dries Buytaert committed
220
221
222
  return ($value) ? $value->count : 0;
}

Dries Buytaert's avatar
   
Dries Buytaert committed
223
function _forum_last_comment($nid) {
Dries Buytaert's avatar
   
Dries Buytaert committed
224
  $value = db_fetch_object(db_query_range("SELECT timestamp FROM {comments} WHERE nid = %d AND status = 0 ORDER BY timestamp DESC", $nid, 0, 1));
Dries Buytaert's avatar
   
Dries Buytaert committed
225
226
227
  return ($value) ? format_date($value->timestamp, "small") : "&nbsp;";
}

Dries Buytaert's avatar
   
Dries Buytaert committed
228
function _forum_last_reply($nid) {
Dries Buytaert's avatar
   
Dries Buytaert committed
229
  $value = db_fetch_object(db_query_range("SELECT c.timestamp, u.name, u.uid FROM {comments} c INNER JOIN {users} u ON c.uid = u.uid WHERE c.nid = %d AND c.status = 0 ORDER BY c.timestamp DESC", $nid, 0, 1));
Dries Buytaert's avatar
   
Dries Buytaert committed
230
231
232
233
234
  return $value;
}

function _forum_format($topic) {
  if ($topic) {
Dries Buytaert's avatar
   
Dries Buytaert committed
235
    return t("%date<br />by %author", array("%date" => format_date($topic->timestamp, "small"), "%author" => format_name($topic)));
Dries Buytaert's avatar
   
Dries Buytaert committed
236
237
238
239
240
241
242
243
244
245
246
247
248
  }
  else {
    return message_na();
  }
}

function forum_get_forums($tid = 0) {
  global $user;

  if (!$tid) {
    $tid = 0;
  }

Dries Buytaert's avatar
   
Dries Buytaert committed
249
  $cache = cache_get("forum:$tid");
Dries Buytaert's avatar
   
Dries Buytaert committed
250

Dries Buytaert's avatar
   
Dries Buytaert committed
251
  if (empty($cache)) {
252
    $forums = array();
Dries Buytaert's avatar
   
Dries Buytaert committed
253
    $_forums = taxonomy_get_tree(variable_get("forum_nav_vocabulary", ""), $tid);
Dries Buytaert's avatar
   
Dries Buytaert committed
254
255
    $n = 0;
    foreach ($_forums as $forum) {
Dries Buytaert's avatar
   
Dries Buytaert committed
256
257
258
      $forum->num_topics = _forum_num_topics($forum->tid);
      $forum->num_posts = _forum_num_replies($forum->tid) + $forum->num_topics;
      $forum->last_post = _forum_last_post($forum->tid);
Dries Buytaert's avatar
   
Dries Buytaert committed
259
260
261
262
      $forums[$forum->tid] = $forum;
      $n++;
    }

Dries Buytaert's avatar
   
Dries Buytaert committed
263
    cache_set("forum:$tid", serialize($forums), 1);
Dries Buytaert's avatar
   
Dries Buytaert committed
264
  }
Dries Buytaert's avatar
   
Dries Buytaert committed
265
266
267
  else {
    $forums = unserialize($cache->data);
  }
Dries Buytaert's avatar
   
Dries Buytaert committed
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287

  if ($user->uid && $forums) {
    foreach (_forum_topics_read($user->uid) as $tid => $old) {
      if ($forums[$tid]) {
        $forums[$tid]->old_topics = $old;
      }
    }
  }
  return $forums;
}

function forum_get_parents($tid) {
  if ($tid) {
    $parents[] = taxonomy_get_term($tid);
  }
  $n = 0;
  while ($parent = taxonomy_get_parents($parents[$n]->tid)) {
    $parents = array_merge($parents, $parent);
    $n++;
  }
Dries Buytaert's avatar
   
Dries Buytaert committed
288

Dries Buytaert's avatar
   
Dries Buytaert committed
289
290
291
292
  return $parents;
}

function _forum_num_topics($term) {
Dries Buytaert's avatar
   
Dries Buytaert committed
293
  $value = db_fetch_object(db_query("SELECT COUNT(n.nid) AS count FROM {node} n INNER JOIN {forum} f ON n.nid = f.nid WHERE f.tid = %d AND n.nid = f.nid AND n.status = 1 AND n.type = 'forum'", $term));
Dries Buytaert's avatar
   
Dries Buytaert committed
294
295
296
297
  return ($value) ? $value->count : 0;
}

function _forum_num_replies($term) {
Dries Buytaert's avatar
   
Dries Buytaert committed
298
  $value = db_fetch_object(db_query("SELECT COUNT(*) AS count FROM {comments} c INNER JOIN {node} n ON n.nid = c.nid INNER JOIN {forum} f ON n.nid = f.nid WHERE f.tid = %d AND n.nid = f.nid AND n.nid = c.nid AND n.status = 1 AND c.status = 0 AND n.type = 'forum'", $term));
Dries Buytaert's avatar
   
Dries Buytaert committed
299
300
301
302
  return ($value) ? $value->count : 0;
}

function _forum_topics_read($uid) {
Dries Buytaert's avatar
   
Dries Buytaert committed
303
  $result = db_query("SELECT tid, count(*) AS c FROM {history} h INNER JOIN {node} n ON n.nid = h.nid INNER JOIN {forum} f ON n.nid = f.nid WHERE f.nid = n.nid AND n.nid = h.nid AND n.type = 'forum' AND n.status = 1 AND h.uid = %d GROUP BY tid", $uid);
Dries Buytaert's avatar
   
Dries Buytaert committed
304
305
306
307
308
309
310
311
312

  while ($obj = db_fetch_object($result)) {
    $topics_read[$obj->tid] = $obj->c;
  }

  return $topics_read ? $topics_read : array();
}

function _forum_last_post($term) {
Dries Buytaert's avatar
   
Dries Buytaert committed
313
  $topic = db_fetch_object(db_query_range("SELECT n.nid, n.created AS timestamp, u.name AS name, u.uid AS uid FROM {forum} f INNER JOIN {node} n ON n.nid = f.nid INNER JOIN {users} u ON n.uid = u.uid WHERE f.tid = %d AND n.nid = f.nid AND n.type = 'forum' AND n.status = 1 ORDER BY timestamp DESC", $term, 0, 1));
Dries Buytaert's avatar
   
Dries Buytaert committed
314

Dries Buytaert's avatar
   
Dries Buytaert committed
315
  $reply = db_fetch_object(db_query_range("SELECT n.nid, c.timestamp, u.name AS name, u.uid AS uid FROM {forum} f INNER JOIN {node} n ON n.nid = f.nid INNER JOIN {comments} c ON n.nid = c.nid INNER JOIN {users} u ON c.uid = u.uid WHERE f.tid = %d AND n.nid = f.nid AND n.type = 'forum' AND n.status = 1 AND c.status = 0 ORDER BY c.timestamp DESC", $term, 0, 1));
Dries Buytaert's avatar
   
Dries Buytaert committed
316
317
318
319
320
321

  $value = ($topic->timestamp > $reply->timestamp) ? $topic : $reply;

  return $value;
}

Dries Buytaert's avatar
Dries Buytaert committed
322
function forum_get_topics($tid, $sortby, $forum_per_page) {
Dries Buytaert's avatar
   
Dries Buytaert committed
323
  global $user, $forum_topic_list_header;
Dries Buytaert's avatar
   
Dries Buytaert committed
324

Dries Buytaert's avatar
   
Dries Buytaert committed
325
  $forum_topic_list_header = array(
326
327
      array("data" => "&nbsp;"),
      array("data" => t("Topic"), "field" => "n.title"),
Dries Buytaert's avatar
   
Dries Buytaert committed
328
329
330
331
      array("data" => t("Replies"),"field" => "num_comments"),
      array("data" => t("Created"), "field" => "n.created"),
      array("data" => t("Last reply"), "field" => "date_sort", "sort" => "desc"),
  );
Dries Buytaert's avatar
   
Dries Buytaert committed
332
333

  $sql_sortby = _forum_get_topic_order($sortby);
Dries Buytaert's avatar
   
Dries Buytaert committed
334
335
336
337
338
339
340
341
  for ($i=0; $i < count($forum_topic_list_header); $i++) {
    if ($forum_topic_list_header[$i]["field"] == $sql_sortby) {
      $forum_topic_list_header[$i]["order"] = $sql_sortby;
    }
  }

  $term = taxonomy_get_term($tid);
  $voc = taxonomy_get_vocabulary($term->vid);
Dries Buytaert's avatar
   
Dries Buytaert committed
342

Dries Buytaert's avatar
Dries Buytaert committed
343
  // show topics with the correct tid, or in the forum but with shadow = 1
Dries Buytaert's avatar
   
Dries Buytaert committed
344
  $sql = "SELECT n.nid, n.title, u.name AS name, u.uid AS uid, n.created AS timestamp, GREATEST(n.created, MAX(c.timestamp)) AS date_sort, COUNT(c.nid) AS num_comments, n.comment AS comment_mode, f.tid FROM {node} n INNER JOIN {term_node} r ON n.nid = r.nid INNER JOIN {users} u ON n.uid = u.uid LEFT JOIN {comments} c ON n.nid = c.nid INNER JOIN {forum} f ON n.nid = f.nid WHERE n.nid = r.nid AND ((r.tid = '".check_query($tid)."' AND f.shadow = 1) OR f.tid = '".check_query($tid)."') AND n.status = 1 AND n.type = 'forum' GROUP BY n.nid, n.title, u.name, u.uid, n.created, n.comment, f.tid";
Dries Buytaert's avatar
   
Dries Buytaert committed
345
  $sql .= tablesort_sql($forum_topic_list_header);
Dries Buytaert's avatar
Dries Buytaert committed
346

Dries Buytaert's avatar
   
Dries Buytaert committed
347
  $sql_count = "SELECT COUNT(DISTINCT(n.nid)) FROM {node} n INNER JOIN {forum} f ON n.nid = f.nid INNER JOIN {term_node} r ON n.nid = r.nid WHERE n.nid = r.nid AND ( (r.tid = '".check_query($tid)."' AND f.shadow = 1) OR f.tid = '".check_query($tid)."') AND n.status = 1 AND n.type = 'forum'";
Dries Buytaert's avatar
   
Dries Buytaert committed
348

Dries Buytaert's avatar
Dries Buytaert committed
349
  $result = pager_query($sql, $forum_per_page, 0, $sql_count);
Dries Buytaert's avatar
   
Dries Buytaert committed
350
351
352
353
  $topic_num = db_num_rows($result);

  $n = 0;
  while ($topic = db_fetch_object($result)) {
Dries Buytaert's avatar
Dries Buytaert committed
354
355
356
357
358
    if ($user->uid) {
      $history = _forum_user_last_visit($topic->nid);
      // folder is new if topic is new or there are new comments since last visit
      if ($topic->shadow > 0) {
        $topic->new = 0;
Dries Buytaert's avatar
   
Dries Buytaert committed
359
360
      }
      else {
Dries Buytaert's avatar
Dries Buytaert committed
361
362
        if (!$history && $user->uid) {
          $topic->new_replies = 0;
Dries Buytaert's avatar
   
Dries Buytaert committed
363
364
365
          $topic->new = 1;
        }
        else {
Dries Buytaert's avatar
   
Dries Buytaert committed
366
          $comments = db_result(db_query("SELECT COUNT(c.nid) FROM {node} n INNER JOIN {comments} c ON n.nid = c.nid WHERE n.nid = '$topic->nid' AND n.status = 1 AND c.status = 0 AND timestamp > '$history' GROUP BY n.nid"));
Dries Buytaert's avatar
Dries Buytaert committed
367
368
369
370
371
372
373
374

          $topic->new_replies = $comments ? $comments : 0;
          if ($topic->new_replies) {
            $topic->new = 1;
          }
          else {
            $topic->new = 0;
          }
Dries Buytaert's avatar
   
Dries Buytaert committed
375
376
        }
      }
Dries Buytaert's avatar
Dries Buytaert committed
377
378
379
380
381
382
     }
     else {
      // you're not logged in eh?
      $topic->new_replies = 0;
      $topic->new = 0;
     }
Dries Buytaert's avatar
   
Dries Buytaert committed
383
384
385
386
387

    $topic->last_reply = _forum_last_reply($topic->nid);
    $topics[] = $topic;
  }

Dries Buytaert's avatar
Dries Buytaert committed
388
  return $topics;
Dries Buytaert's avatar
   
Dries Buytaert committed
389
390
}

Dries Buytaert's avatar
Dries Buytaert committed
391
function _forum_new($tid) {
Dries Buytaert's avatar
   
Dries Buytaert committed
392
  global $user;
Dries Buytaert's avatar
   
Dries Buytaert committed
393
  $result = db_query("SELECT n.nid FROM {node} n, {history} h, {forum} f WHERE n.type = 'forum' AND n.status = 1 AND h.nid = n.nid AND f.nid = h.nid AND f.tid = %d AND h.uid = %d", $tid, $user->uid);
Dries Buytaert's avatar
   
Dries Buytaert committed
394
395
396
397
  while ($r = db_fetch_object($result)) {
    $read[] = $r->nid;
  }

Dries Buytaert's avatar
   
Dries Buytaert committed
398
  $nid = db_result(db_query_range("SELECT n.nid FROM {node} n INNER JOIN {forum} f ON n.nid = f.nid WHERE n.type = 'forum' AND f.nid = n.nid AND n.status = 1 AND f.tid = %d ".($read ? "AND NOT (n.nid IN (".implode(",", $read).")) " : "") ."ORDER BY created", $tid, 0, 1));
Dries Buytaert's avatar
   
Dries Buytaert committed
399
400
401
402

  return $nid ? $nid : 0;
}

Dries Buytaert's avatar
   
Dries Buytaert committed
403
404
405
406
function _forum_message_taxonomy() {
  return t("For the forums to work, the taxonomy module has to be installed and enabled.  When activated, a taxonomy vocubulary needs to be created, bound to the forum module.  The vocabulary's terms define the forums.");
}

Dries Buytaert's avatar
   
Dries Buytaert committed
407
function forum_page() {
Dries Buytaert's avatar
   
Dries Buytaert committed
408
  global $sortby, $forum_per_page, $from, $user;
Dries Buytaert's avatar
   
Dries Buytaert committed
409

Dries Buytaert's avatar
   
Dries Buytaert committed
410
  $op = $_POST["op"];
Dries Buytaert's avatar
   
Dries Buytaert committed
411

Dries Buytaert's avatar
   
Dries Buytaert committed
412
  if (user_access("access content")) {
Dries Buytaert's avatar
   
Dries Buytaert committed
413
    if (module_exist("taxonomy")) {
Dries Buytaert's avatar
   
Dries Buytaert committed
414
      $tid = arg(1);
415
      if ($op == t("Update settings") && $user->uid) {
Dries Buytaert's avatar
   
Dries Buytaert committed
416
417
        $user = user_save($user, array("sortby" => $sortby, "forum_per_page" => $forum_per_page));
      }
Dries Buytaert's avatar
   
Dries Buytaert committed
418

Dries Buytaert's avatar
Dries Buytaert committed
419
420
421
422
423
      if (arg(2) == "new") {
        if ($nid = _forum_new($tid)) {
          drupal_goto(url("node/view/$nid"));
        }
      }
Dries Buytaert's avatar
   
Dries Buytaert committed
424

Dries Buytaert's avatar
   
Dries Buytaert committed
425
426
427
      if (empty($sortby)) {
        $sortby = isset($user->sortby) ? $user->sortby : variable_get("forum_order",1);
      }
Dries Buytaert's avatar
   
Dries Buytaert committed
428

Dries Buytaert's avatar
   
Dries Buytaert committed
429
430
431
      if (empty($forum_per_page)) {
        $forum_per_page = isset($user->forum_per_page) ? $user->forum_per_page : variable_get("forum_per_page", 25);
      }
Dries Buytaert's avatar
   
Dries Buytaert committed
432

Dries Buytaert's avatar
Dries Buytaert committed
433
      $offset = ($from / $forum_per_page) + 1;
Dries Buytaert's avatar
   
Dries Buytaert committed
434

Dries Buytaert's avatar
   
Dries Buytaert committed
435
436
      $forums = forum_get_forums($tid);
      $parents = forum_get_parents($tid);
Dries Buytaert's avatar
   
Dries Buytaert committed
437
      $topics = forum_get_topics($tid, $sortby, $forum_per_page);
Dries Buytaert's avatar
   
Dries Buytaert committed
438

Dries Buytaert's avatar
   
Dries Buytaert committed
439
      theme("forum_theme_display", $forums, $topics, $parents, $tid, $sortby, $forum_per_page, $offset);
Dries Buytaert's avatar
   
Dries Buytaert committed
440
441
    }
    else {
Dries Buytaert's avatar
   
Dries Buytaert committed
442
443
444
      theme("header");
      theme("box", t("Warning"), _forum_message_taxonomy());
      theme("footer");
Dries Buytaert's avatar
   
Dries Buytaert committed
445
    }
Dries Buytaert's avatar
   
Dries Buytaert committed
446
447
  }
  else {
Dries Buytaert's avatar
   
Dries Buytaert committed
448
449
450
    theme("header");
    theme("box", t("Access denied"), message_access());
    theme("footer");
Dries Buytaert's avatar
   
Dries Buytaert committed
451
452
453
  }
}

Dries Buytaert's avatar
   
Dries Buytaert committed
454
/*
Dries Buytaert's avatar
   
Dries Buytaert committed
455
** Theme functions
Dries Buytaert's avatar
   
Dries Buytaert committed
456
*/
Dries Buytaert's avatar
   
Dries Buytaert committed
457

Dries Buytaert's avatar
   
Dries Buytaert committed
458
function forum_theme_display($forums, $topics, $parents, $tid, $sortby, $forum_per_page, $offset) {
Dries Buytaert's avatar
   
Dries Buytaert committed
459
  // forum list, topics list, topic browser and "add new topic" link
Dries Buytaert's avatar
   
Dries Buytaert committed
460

Dries Buytaert's avatar
   
Dries Buytaert committed
461

Dries Buytaert's avatar
   
Dries Buytaert committed
462
463
464
  /*
  ** Breadcrumb navigation:
  */
Dries Buytaert's avatar
   
Dries Buytaert committed
465

466
  $trail[] = l(t("Home"), "");
Dries Buytaert's avatar
   
Dries Buytaert committed
467
  $trail[] = l(t("Forums"), "forum");
Dries Buytaert's avatar
   
Dries Buytaert committed
468
469

  if ($parents) {
Dries Buytaert's avatar
   
Dries Buytaert committed
470
471
    $parents = array_reverse($parents);
    foreach ($parents as $p) {
472
473
      if ($p->tid == $tid) {
        $title = $p->name;
Dries Buytaert's avatar
   
Dries Buytaert committed
474
475
      }
      else {
Dries Buytaert's avatar
   
Dries Buytaert committed
476
        $trail[] = l($p->name, "forum/$p->tid");
Dries Buytaert's avatar
   
Dries Buytaert committed
477
478
479
480
      }
    }
  }

Dries Buytaert's avatar
   
Dries Buytaert committed
481
482
483
484
485
486
487
488
489
  $output  = "<div id=\"forum\">";
  $output .= theme("forum_theme_list", $forums, $parents, $tid);

  if ($tid) {
    $output .= theme("forum_theme_topic_list", $tid, $topics, $sortby, $forum_per_page, $offset);
  }

  $output .= "</div>";

490
  theme("header");
Dries Buytaert's avatar
   
Dries Buytaert committed
491
  theme("breadcrumb", $trail);
Dries Buytaert's avatar
   
Dries Buytaert committed
492
  theme("box", $title, $output);
Dries Buytaert's avatar
   
Dries Buytaert committed
493
494
495
496
497
498
  theme("footer");
}

function forum_theme_list($forums, $parents, $tid) {
  global $user;

Dries Buytaert's avatar
   
Dries Buytaert committed
499
500
  if ($forums) {

Dries Buytaert's avatar
   
Dries Buytaert committed
501
    $header = array(t("Forum"), t("Topics"), t("Posts"), t("Last post"));
Dries Buytaert's avatar
   
Dries Buytaert committed
502
503

    foreach ($forums as $forum) {
Dries Buytaert's avatar
   
Dries Buytaert committed
504
505
      if ($user->uid) {
        $new_topics = $forum->num_topics - $forum->old_topics;
506
      }
Dries Buytaert's avatar
   
Dries Buytaert committed
507

Dries Buytaert's avatar
   
Dries Buytaert committed
508
509
510
511
512
      $links = array();

      if ($forum->last_post) {
        $links[] = l(t("the most recent topic"), "node/view/". $forum->last_post->nid);
      }
Dries Buytaert's avatar
   
Dries Buytaert committed
513

Dries Buytaert's avatar
   
Dries Buytaert committed
514
515
      if ($new_topics) {
        $links[] = l(t("the first new topic"), "forum/$forum->tid/new");
Dries Buytaert's avatar
   
Dries Buytaert committed
516
      }
Dries Buytaert's avatar
   
Dries Buytaert committed
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532

      $description  = "<div class=\"forum\" style=\"margin-left: ". ($forum->depth * 30) ."px;\">\n";
      $description .= " <div class=\"name\">". l($forum->name, "forum/$forum->tid") ."</div>\n";

      if ($forum->description) {
        $description .= " <div class=\"description\">$forum->description</div>\n";
      }
      if ($links) {
        $description .= " <div class=\"navigation\">". t("Jump to: %links", array("%links" => implode(", ", $links))) .".</div>\n";
      }
      $description .="</div>\n";

      $rows[] = array(
        array("data" => $description, "class" => "description"),
        array("data" => $forum->num_topics . ($new_topics ? "<br />(".t("%a new", array("%a" => $new_topics)).")" : ""), "class" => "topics"),
        array("data" => $forum->num_posts, "class" => "posts"),
Dries Buytaert's avatar
   
Dries Buytaert committed
533
        array("data" => _forum_format($forum->last_post), "class" => "last-reply")
Dries Buytaert's avatar
   
Dries Buytaert committed
534
535
       );

Dries Buytaert's avatar
   
Dries Buytaert committed
536
537
538
    }
  }

Dries Buytaert's avatar
   
Dries Buytaert committed
539
  return table($header, $rows);
Dries Buytaert's avatar
   
Dries Buytaert committed
540
541
542
}


Dries Buytaert's avatar
   
Dries Buytaert committed
543
function forum_theme_topic_list($tid, $topics, $sortby, $forum_per_page, $offset) {
Dries Buytaert's avatar
   
Dries Buytaert committed
544
  global $id, $status, $user, $pager_total, $forum_topic_list_header;
Dries Buytaert's avatar
   
Dries Buytaert committed
545
546

  if ($topics) {
Dries Buytaert's avatar
   
Dries Buytaert committed
547

Dries Buytaert's avatar
   
Dries Buytaert committed
548
549
    foreach ($topics as $topic) {
      // folder is new if topic is new or there are new comments since last visit
Dries Buytaert's avatar
Dries Buytaert committed
550
      if ($topic->tid != $tid) {
Dries Buytaert's avatar
   
Dries Buytaert committed
551
        $rows[] = array(
Dries Buytaert's avatar
   
Dries Buytaert committed
552
          array("data" => _forum_icon($topic->new, $topic->num_comments, $topic->comment_mode), "class" => "icon"),
Dries Buytaert's avatar
   
Dries Buytaert committed
553
          array("data" => $topic->title, "class" => "title"),
Dries Buytaert's avatar
   
Dries Buytaert committed
554
          array("data" => l(t("This topic has been moved"), "forum/$topic->tid"), "colspan" => "3")
Dries Buytaert's avatar
   
Dries Buytaert committed
555
        );
Dries Buytaert's avatar
   
Dries Buytaert committed
556
557
      }
      else {
Dries Buytaert's avatar
   
Dries Buytaert committed
558
        $rows[] = array(
Dries Buytaert's avatar
   
Dries Buytaert committed
559
          array("data" => _forum_icon($topic->new, $topic->num_comments, $topic->comment_mode), "class" => "icon"),
Dries Buytaert's avatar
   
Dries Buytaert committed
560
561
          array("data" => l($topic->title, "node/view/$topic->nid"), "class" => "topic"),
          array("data" => $topic->num_comments . ($topic->new_replies ? "<br />(".t("%a new", array("%a" => $topic->new_replies)).")" : ""), "class" => "replies"),
Dries Buytaert's avatar
   
Dries Buytaert committed
562
563
          array("data" => _forum_format($topic), "class" => "created"),
          array("data" => _forum_format($topic->last_reply), "class" => "last-reply")
Dries Buytaert's avatar
   
Dries Buytaert committed
564
        );
Dries Buytaert's avatar
   
Dries Buytaert committed
565
566
567
      }
    }

Dries Buytaert's avatar
   
Dries Buytaert committed
568
    if ($pager = pager_display(NULL, $forum_per_page, 0, "default", tablesort_pager())) {
Dries Buytaert's avatar
   
Dries Buytaert committed
569
      $rows[] = array(array("data" => $pager, "colspan" => "5", "class" => "pager"));
Dries Buytaert's avatar
   
Dries Buytaert committed
570
571
    }
  }
Dries Buytaert's avatar
   
Dries Buytaert committed
572
573


Dries Buytaert's avatar
Dries Buytaert committed
574
  if (user_access("create forum topics")) {
Dries Buytaert's avatar
   
Dries Buytaert committed
575
    $output = l(t("create new forum topic"), "node/add/forum/$tid") ."<br /><br />";
Dries Buytaert's avatar
   
Dries Buytaert committed
576
577
  }

Dries Buytaert's avatar
   
Dries Buytaert committed
578
  $output .= table($forum_topic_list_header, $rows);
Dries Buytaert's avatar
   
Dries Buytaert committed
579

Dries Buytaert's avatar
   
Dries Buytaert committed
580
581
582
  return $output;
}

Dries Buytaert's avatar
   
Dries Buytaert committed
583
function _forum_icon($new_posts, $num_posts = 0, $comment_mode = 0) {
Dries Buytaert's avatar
   
Dries Buytaert committed
584

Dries Buytaert's avatar
   
Dries Buytaert committed
585
  $base_path = variable_get("forum_icon_path", "");
Dries Buytaert's avatar
   
Dries Buytaert committed
586
587
  if ($base_path) {
    if ($num_posts > variable_get("forum_hot_topic", 15)) {
Dries Buytaert's avatar
   
Dries Buytaert committed
588
      $icon = $new_posts ? "hot-new" : "hot";
Dries Buytaert's avatar
   
Dries Buytaert committed
589
590
591
592
593
594
595
596
597
    }
    else {
      $icon = $new_posts ? "new" : "default";
    }

    if ($comment_mode == 1) {
      $icon = "closed";
    }

Dries Buytaert's avatar
   
Dries Buytaert committed
598
    // default
Dries Buytaert's avatar
   
Dries Buytaert committed
599
    $file = $base_path."/forum-$icon.gif";
Dries Buytaert's avatar
   
Dries Buytaert committed
600

Dries Buytaert's avatar
   
Dries Buytaert committed
601
    return "<img src=\"$file\" alt=\"\" title=\"\" />";
Dries Buytaert's avatar
   
Dries Buytaert committed
602
603
604
605
606
607
608
609
610
611
  }
  else {
    return "&nbsp;";
  }
}

function _forum_user_last_visit($nid) {
  global $user;
  static $history;
  if (!$history) {
Dries Buytaert's avatar
   
Dries Buytaert committed
612
    $result = db_query("SELECT nid, timestamp FROM {history} WHERE uid = %d", $user->uid);
Dries Buytaert's avatar
   
Dries Buytaert committed
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
    while ($t = db_fetch_object($result)) {
      $history[$t->nid] = $t->timestamp;
    }
  }
  return $history[$nid] ? $history[$nid] : 0;
}

function _forum_get_topic_order($sortby) {
  switch ($sortby) {
    case 1:
      return "date_sort DESC";
      break;
    case 2:
      return "date_sort ASC";
      break;
    case 3:
      return "num_comments DESC";
      break;
    case 4:
      return "num_comments ASC";
      break;
  }
}

Dries Buytaert's avatar
   
Dries Buytaert committed
637
638
639
640
641
642
643
644
645
646
function forum_help($section = "admin/forum/help") {
  $output = "";

  switch ($section) {
    case 'admin/help':
    case 'admin/forum/help':
      $output .= "<h3>Creating a forum</h3>";
      $output .= strtr("<p>The forum module uses taxonomy to organize itself. To create a forum you first have to create a %taxonomy. When doing this, choose a sensible name for it (such as \"fora\") and make sure under \"Types\" that \"forum\" is selected. Once you have done this, %taxo-terms to it. Each term will become a forum. If you fill in the description field, users will be given additonal information about the forum on the main forum page. For example: \"troubleshooting\" - \"Please ask your questions here.\"</p>", array("%taxonomy" => l(t("taxonomy vocabulary"), "admin/taxonomy/add/vocabulary"), "%taxo-terms" => l(t("add some terms"), "admin/taxonomy" ) ));
      $output .= strtr("<p>When you are happy with your vocabulary, go to ". l("site configuration &raquo; modules &raquo; forum","admin/system/modules/forum") ." and set <b>Forum vocabulary</b> to the one you have just created. There will now be fora active on the site. For users to access them they must have the \"access content\" %permission and to create a topic they must have the \"create forum topics\" %permission. These permissions can be set in the %permission pages.</p>", array("%forums" => l(t("site configutation &raquo; modules &raquo; forum"), "admin/system/modules/forum"), "%permission" => l(t("permission"), "admin/user/permission") ));
      $output .= "<h4>Icons</h4>";
Dries Buytaert's avatar
   
Dries Buytaert committed
647
648
      $output .= strtr("<p>To disable icons, set the icon path as blank in %forums-icon.</p>", array("%forums-icon" => l(t("site configuration &raquo; modules &raquo; forums"), "admin/system/module/forum") ));
      $output .= "<p>All files in the icon directory are assumed to be images. You may use images of whatever size you wish, but it is recommended to use 15x15 or 16x16.</p>";
Dries Buytaert's avatar
   
Dries Buytaert committed
649
650
651
652
653
654
655
656
      break;
    case 'admin/system/modules':
      $output = "Enable threaded discussions about general topics.";
      break;
    case 'admin/system/modules/forum':
      $output = strtr("Forums are threaded discussions based on the taxonomy system so you must first %taxonomy-create of type \"forum\" to place the forum tree in. Then %taxonomy-add to this taxonomy. Each term becomes the name of a forum. If you define a term as a \"Container\" (See below) the term is not a forum itself, but rather holds forms. This lets you group your forums.", array("%taxonomy-create" => l(t("create a taxonomy"), "admin/taxonomy/add/vocabulary"), "%taxonomy" => l(t("add terms"), "admin/taxonomy") ));
      break;
  }
Dries Buytaert's avatar
   
Dries Buytaert committed
657

Dries Buytaert's avatar
   
Dries Buytaert committed
658
  return t($output);
Dries Buytaert's avatar
   
Dries Buytaert committed
659
660
661
}

?>