forum.module 24.7 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, 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
120
121
122
123
124
125
126
127
128
129
130
131
132

    while ($topic = db_fetch_object($result)) {
      if ($stop == 1) {
        $next->nid = $topic->nid;
        $next->title = $topic->title;
        $next->body = $topic->body;
        break;
      }
      if ($topic->nid == $node->nid) {
        $stop = 1;
      }
      else {
        $prev->nid = $topic->nid;
        $prev->title = $topic->title;
        $prev->body = $topic->body;
      }
    }

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

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

Dries Buytaert's avatar
   
Dries Buytaert committed
141
  return $links;
Dries Buytaert's avatar
   
Dries Buytaert committed
142
143
}

Dries Buytaert's avatar
   
Dries Buytaert committed
144
145
146
147
148
149
function forum_content($node) {
  $node->teaser = check_output($node->teaser);
  $node->body = check_output($node->body);
  return $node;
}

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

Dries Buytaert's avatar
   
Dries Buytaert committed
152
153
154
155
156
157
158
  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
159
160
161
162
163
164
    // Breadcrumb navigation
    $breadcrumb[] = l(t("Home"), NULL);
    $breadcrumb[] = l(t("Forums"), "forum");
    $breadcrumb[] = l($term_data->name, "forum/$term_data->tid");
    // print the breadcrumb
    theme("breadcrumb",$breadcrumb);
165
  }
Dries Buytaert's avatar
   
Dries Buytaert committed
166
167
168
169
  // prepair the node content
  $node = forum_content($node);
  // print the node
  theme("node", $node, $main);
Dries Buytaert's avatar
   
Dries Buytaert committed
170
171
}

172
173
174
175
function forum_validate(&$node) {
  // Make sure all fields are set properly:
  $node->icon = $node->icon ? $node->icon : "";
  $node->shadow = $node->shadow ? $node->shadow : 0;
176
  $node->tid = $node->tid ? $node->tid : 0;
177
178
179
180
181
182
  // 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
183
184
185
  }
}

Dries Buytaert's avatar
   
Dries Buytaert committed
186
function forum_form(&$node, &$help, &$error) {
Dries Buytaert's avatar
Dries Buytaert committed
187
188
189
  if ($node->tid) {
    // editing
    $tid = $node->tid;
190
191
  }
  else {
Dries Buytaert's avatar
Dries Buytaert committed
192
193
    // new topic
    $tid = arg(3);
194
195
  }

Dries Buytaert's avatar
   
Dries Buytaert committed
196
197
198
  // outputs the compose guidelines
  $help = variable_get("forum_help", "");

Dries Buytaert's avatar
   
Dries Buytaert committed
199
  $output .= _taxonomy_term_select(t("Forum"), "tid", $tid, variable_get("forum_nav_vocabulary", ""), "", 0, "");
Dries Buytaert's avatar
Dries Buytaert committed
200
201
202
203
204

  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
205

206
  $output .= form_textarea(t("Body"), "body", $node->body, 60, 10);
Dries Buytaert's avatar
   
Dries Buytaert committed
207
208
209
210

  return $output;
}

Dries Buytaert's avatar
   
Dries Buytaert committed
211
function forum_insert($node) {
Dries Buytaert's avatar
   
Dries Buytaert committed
212
  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
213
214
215
}

function forum_update($node) {
Dries Buytaert's avatar
   
Dries Buytaert committed
216
  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
217
218
219
}

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

Dries Buytaert's avatar
   
Dries Buytaert committed
223
function _forum_num_comments($nid) {
Dries Buytaert's avatar
   
Dries Buytaert committed
224
  $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
225
226
227
  return ($value) ? $value->count : 0;
}

Dries Buytaert's avatar
   
Dries Buytaert committed
228
function _forum_last_comment($nid) {
Dries Buytaert's avatar
   
Dries Buytaert committed
229
  $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
230
231
232
  return ($value) ? format_date($value->timestamp, "small") : "&nbsp;";
}

Dries Buytaert's avatar
   
Dries Buytaert committed
233
function _forum_last_reply($nid) {
Dries Buytaert's avatar
   
Dries Buytaert committed
234
  $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
235
236
237
238
239
  return $value;
}

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

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

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

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

Dries Buytaert's avatar
   
Dries Buytaert committed
256
  if (empty($cache)) {
257
    $forums = array();
Dries Buytaert's avatar
   
Dries Buytaert committed
258
    $_forums = taxonomy_get_tree(variable_get("forum_nav_vocabulary", ""), $tid);
Dries Buytaert's avatar
   
Dries Buytaert committed
259
260
    $n = 0;
    foreach ($_forums as $forum) {
Dries Buytaert's avatar
   
Dries Buytaert committed
261
262
263
      $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
264
265
266
267
      $forums[$forum->tid] = $forum;
      $n++;
    }

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

  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
293

Dries Buytaert's avatar
   
Dries Buytaert committed
294
295
296
297
  return $parents;
}

function _forum_num_topics($term) {
Dries Buytaert's avatar
   
Dries Buytaert committed
298
  $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
299
300
301
302
  return ($value) ? $value->count : 0;
}

function _forum_num_replies($term) {
Dries Buytaert's avatar
   
Dries Buytaert committed
303
  $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
304
305
306
307
  return ($value) ? $value->count : 0;
}

function _forum_topics_read($uid) {
Dries Buytaert's avatar
   
Dries Buytaert committed
308
  $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
309
310
311
312
313
314
315
316
317

  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
318
  $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
319

Dries Buytaert's avatar
   
Dries Buytaert committed
320
  $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
321
322
323
324
325
326

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

  return $value;
}

Dries Buytaert's avatar
Dries Buytaert committed
327
function forum_get_topics($tid, $sortby, $forum_per_page) {
Dries Buytaert's avatar
   
Dries Buytaert committed
328
  global $user, $forum_topic_list_header;
Dries Buytaert's avatar
   
Dries Buytaert committed
329

Dries Buytaert's avatar
   
Dries Buytaert committed
330
  $forum_topic_list_header = array(
331
332
      array("data" => "&nbsp;"),
      array("data" => t("Topic"), "field" => "n.title"),
Dries Buytaert's avatar
   
Dries Buytaert committed
333
334
335
336
      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
337
338

  $sql_sortby = _forum_get_topic_order($sortby);
Dries Buytaert's avatar
   
Dries Buytaert committed
339
340
341
342
343
344
345
346
  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
347

Dries Buytaert's avatar
Dries Buytaert committed
348
  // show topics with the correct tid, or in the forum but with shadow = 1
Dries Buytaert's avatar
   
Dries Buytaert committed
349
  $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
350
  $sql .= tablesort_sql($forum_topic_list_header);
Dries Buytaert's avatar
Dries Buytaert committed
351

Dries Buytaert's avatar
   
Dries Buytaert committed
352
  $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
353

Dries Buytaert's avatar
Dries Buytaert committed
354
  $result = pager_query($sql, $forum_per_page, 0, $sql_count);
Dries Buytaert's avatar
   
Dries Buytaert committed
355
356
357
358
  $topic_num = db_num_rows($result);

  $n = 0;
  while ($topic = db_fetch_object($result)) {
Dries Buytaert's avatar
Dries Buytaert committed
359
360
361
362
363
    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
364
365
      }
      else {
Dries Buytaert's avatar
Dries Buytaert committed
366
367
        if (!$history && $user->uid) {
          $topic->new_replies = 0;
Dries Buytaert's avatar
   
Dries Buytaert committed
368
369
370
          $topic->new = 1;
        }
        else {
Dries Buytaert's avatar
   
Dries Buytaert committed
371
          $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
372
373
374
375
376
377
378
379

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

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

Dries Buytaert's avatar
Dries Buytaert committed
393
  return $topics;
Dries Buytaert's avatar
   
Dries Buytaert committed
394
395
}

Dries Buytaert's avatar
Dries Buytaert committed
396
function _forum_new($tid) {
Dries Buytaert's avatar
   
Dries Buytaert committed
397
  global $user;
Dries Buytaert's avatar
   
Dries Buytaert committed
398
  $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
399
400
401
402
  while ($r = db_fetch_object($result)) {
    $read[] = $r->nid;
  }

Dries Buytaert's avatar
   
Dries Buytaert committed
403
  $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
404
405
406
407

  return $nid ? $nid : 0;
}

Dries Buytaert's avatar
   
Dries Buytaert committed
408
409
410
411
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
412
function forum_page() {
Dries Buytaert's avatar
   
Dries Buytaert committed
413
  global $sortby, $forum_per_page, $from, $user;
Dries Buytaert's avatar
   
Dries Buytaert committed
414

Dries Buytaert's avatar
   
Dries Buytaert committed
415
  $op = $_POST["op"];
Dries Buytaert's avatar
   
Dries Buytaert committed
416

Dries Buytaert's avatar
   
Dries Buytaert committed
417
  if (user_access("access content")) {
Dries Buytaert's avatar
   
Dries Buytaert committed
418
    if (module_exist("taxonomy")) {
Dries Buytaert's avatar
   
Dries Buytaert committed
419
      $tid = arg(1);
420
      if ($op == t("Update settings") && $user->uid) {
Dries Buytaert's avatar
   
Dries Buytaert committed
421
422
        $user = user_save($user, array("sortby" => $sortby, "forum_per_page" => $forum_per_page));
      }
Dries Buytaert's avatar
   
Dries Buytaert committed
423

Dries Buytaert's avatar
Dries Buytaert committed
424
425
426
427
428
      if (arg(2) == "new") {
        if ($nid = _forum_new($tid)) {
          drupal_goto(url("node/view/$nid"));
        }
      }
Dries Buytaert's avatar
   
Dries Buytaert committed
429

Dries Buytaert's avatar
   
Dries Buytaert committed
430
431
432
      if (empty($sortby)) {
        $sortby = isset($user->sortby) ? $user->sortby : variable_get("forum_order",1);
      }
Dries Buytaert's avatar
   
Dries Buytaert committed
433

Dries Buytaert's avatar
   
Dries Buytaert committed
434
435
436
      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
437

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

Dries Buytaert's avatar
   
Dries Buytaert committed
440
441
      $forums = forum_get_forums($tid);
      $parents = forum_get_parents($tid);
Dries Buytaert's avatar
   
Dries Buytaert committed
442
      $topics = forum_get_topics($tid, $sortby, $forum_per_page);
Dries Buytaert's avatar
   
Dries Buytaert committed
443

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

Dries Buytaert's avatar
   
Dries Buytaert committed
459
/*
Dries Buytaert's avatar
   
Dries Buytaert committed
460
** Theme functions
Dries Buytaert's avatar
   
Dries Buytaert committed
461
*/
Dries Buytaert's avatar
   
Dries Buytaert committed
462

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

Dries Buytaert's avatar
   
Dries Buytaert committed
466

Dries Buytaert's avatar
   
Dries Buytaert committed
467
468
469
  /*
  ** Breadcrumb navigation:
  */
Dries Buytaert's avatar
   
Dries Buytaert committed
470

Dries Buytaert's avatar
   
Dries Buytaert committed
471
472
  $breadcrumb[] = l(t("Home"), "");
  $breadcrumb[] = l(t("Forums"), "forum");
Dries Buytaert's avatar
   
Dries Buytaert committed
473
474

  if ($parents) {
Dries Buytaert's avatar
   
Dries Buytaert committed
475
476
    $parents = array_reverse($parents);
    foreach ($parents as $p) {
477
478
      if ($p->tid == $tid) {
        $title = $p->name;
Dries Buytaert's avatar
   
Dries Buytaert committed
479
480
      }
      else {
Dries Buytaert's avatar
   
Dries Buytaert committed
481
        $breadcrumb[] = l($p->name, "forum/$p->tid");
Dries Buytaert's avatar
   
Dries Buytaert committed
482
483
484
485
      }
    }
  }

Dries Buytaert's avatar
   
Dries Buytaert committed
486
487
488
489
490
491
492
493
494
  $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>";

495
  theme("header");
Dries Buytaert's avatar
   
Dries Buytaert committed
496
  theme("breadcrumb", $breadcrumb);
Dries Buytaert's avatar
   
Dries Buytaert committed
497
  theme("box", $title, $output);
Dries Buytaert's avatar
   
Dries Buytaert committed
498
499
500
501
502
503
  theme("footer");
}

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

Dries Buytaert's avatar
   
Dries Buytaert committed
504
505
  if ($forums) {

Dries Buytaert's avatar
   
Dries Buytaert committed
506
    $header = array(t("Forum"), t("Topics"), t("Posts"), t("Last post"));
Dries Buytaert's avatar
   
Dries Buytaert committed
507
508

    foreach ($forums as $forum) {
Dries Buytaert's avatar
   
Dries Buytaert committed
509
510
      if ($user->uid) {
        $new_topics = $forum->num_topics - $forum->old_topics;
511
      }
Dries Buytaert's avatar
   
Dries Buytaert committed
512

Dries Buytaert's avatar
   
Dries Buytaert committed
513
514
515
516
517
      $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
518

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

      $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
538
        array("data" => _forum_format($forum->last_post), "class" => "last-reply")
Dries Buytaert's avatar
   
Dries Buytaert committed
539
540
       );

Dries Buytaert's avatar
   
Dries Buytaert committed
541
542
543
    }
  }

Dries Buytaert's avatar
   
Dries Buytaert committed
544
  return table($header, $rows);
Dries Buytaert's avatar
   
Dries Buytaert committed
545
546
547
}


Dries Buytaert's avatar
   
Dries Buytaert committed
548
function forum_theme_topic_list($tid, $topics, $sortby, $forum_per_page, $offset) {
Dries Buytaert's avatar
   
Dries Buytaert committed
549
  global $id, $status, $user, $pager_total, $forum_topic_list_header;
Dries Buytaert's avatar
   
Dries Buytaert committed
550
551

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

Dries Buytaert's avatar
   
Dries Buytaert committed
553
554
    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
555
      if ($topic->tid != $tid) {
Dries Buytaert's avatar
   
Dries Buytaert committed
556
        $rows[] = array(
Dries Buytaert's avatar
   
Dries Buytaert committed
557
          array("data" => _forum_icon($topic->new, $topic->num_comments, $topic->comment_mode), "class" => "icon"),
Dries Buytaert's avatar
   
Dries Buytaert committed
558
          array("data" => $topic->title, "class" => "title"),
Dries Buytaert's avatar
   
Dries Buytaert committed
559
          array("data" => l(t("This topic has been moved"), "forum/$topic->tid"), "colspan" => "3")
Dries Buytaert's avatar
   
Dries Buytaert committed
560
        );
Dries Buytaert's avatar
   
Dries Buytaert committed
561
562
      }
      else {
Dries Buytaert's avatar
   
Dries Buytaert committed
563
        $rows[] = array(
Dries Buytaert's avatar
   
Dries Buytaert committed
564
          array("data" => _forum_icon($topic->new, $topic->num_comments, $topic->comment_mode), "class" => "icon"),
Dries Buytaert's avatar
   
Dries Buytaert committed
565
566
          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
567
568
          array("data" => _forum_format($topic), "class" => "created"),
          array("data" => _forum_format($topic->last_reply), "class" => "last-reply")
Dries Buytaert's avatar
   
Dries Buytaert committed
569
        );
Dries Buytaert's avatar
   
Dries Buytaert committed
570
571
572
      }
    }

Dries Buytaert's avatar
   
Dries Buytaert committed
573
    if ($pager = pager_display(NULL, $forum_per_page, 0, "default", tablesort_pager())) {
Dries Buytaert's avatar
   
Dries Buytaert committed
574
      $rows[] = array(array("data" => $pager, "colspan" => "5", "class" => "pager"));
Dries Buytaert's avatar
   
Dries Buytaert committed
575
576
    }
  }
Dries Buytaert's avatar
   
Dries Buytaert committed
577
578


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

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

Dries Buytaert's avatar
   
Dries Buytaert committed
585
586
587
  return $output;
}

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

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

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

Dries Buytaert's avatar
   
Dries Buytaert committed
603
    // default
Dries Buytaert's avatar
   
Dries Buytaert committed
604
    $file = $base_path."/forum-$icon.gif";
Dries Buytaert's avatar
   
Dries Buytaert committed
605

Dries Buytaert's avatar
   
Dries Buytaert committed
606
    return "<img src=\"$file\" alt=\"\" title=\"\" />";
Dries Buytaert's avatar
   
Dries Buytaert committed
607
608
609
610
611
612
613
614
615
616
  }
  else {
    return "&nbsp;";
  }
}

function _forum_user_last_visit($nid) {
  global $user;
  static $history;
  if (!$history) {
Dries Buytaert's avatar
   
Dries Buytaert committed
617
    $result = db_query("SELECT nid, timestamp FROM {history} WHERE uid = %d", $user->uid);
Dries Buytaert's avatar
   
Dries Buytaert committed
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
    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
642
643
644
645
646
647
648
function forum_help($section = "admin/forum/help") {
  $output = "";

  switch ($section) {
    case 'admin/help':
    case 'admin/forum/help':
      $output .= "<h3>Creating a forum</h3>";
Dries Buytaert's avatar
   
Dries Buytaert committed
649
650
      $output .= "<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>";
      $output .= "<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>";
Dries Buytaert's avatar
   
Dries Buytaert committed
651
      $output .= "<h4>Icons</h4>";
Dries Buytaert's avatar
   
Dries Buytaert committed
652
      $output .= "<p>To disable icons, set the icon path as blank in %forums.</p>";
Dries Buytaert's avatar
   
Dries Buytaert committed
653
      $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
654
      $output = t($output, array("%taxonomy" => l(t("taxonomy vocabulary"), "admin/taxonomy/add/vocabulary"), "%taxo-terms" => l(t("add some terms"), "admin/taxonomy"), "%forums" => l(t("site configutation &raquo; modules &raquo; forum"), "admin/system/modules/forum"), "%permission" => l(t("permission"), "admin/user/permission") ));
Dries Buytaert's avatar
   
Dries Buytaert committed
655
656
      break;
    case 'admin/system/modules':
Dries Buytaert's avatar
   
Dries Buytaert committed
657
      $output = t("Enable threaded discussions about general topics.");
Dries Buytaert's avatar
   
Dries Buytaert committed
658
659
      break;
    case 'admin/system/modules/forum':
Dries Buytaert's avatar
   
Dries Buytaert committed
660
      $output = t("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") ));
Dries Buytaert's avatar
   
Dries Buytaert committed
661
662
      break;
  }
Dries Buytaert's avatar
   
Dries Buytaert committed
663

Dries Buytaert's avatar
   
Dries Buytaert committed
664
  return $output;
Dries Buytaert's avatar
   
Dries Buytaert committed
665
666
667
}

?>