forum.module 25.8 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, u.uid, u.name, GREATEST(n.created, MAX(c.timestamp)) AS sort FROM {node} n INNER JOIN {forum} f ON n.nid = f.nid INNER JOIN {comments} c ON n.nid = c.nid LEFT JOIN {users} u ON n.uid = u.uid WHERE n.type = 'forum' AND n.nid = f.nid AND n.status = 1 GROUP BY n.nid, n.title, n.created, u.uid, u.name 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 n.nid, n.title, u.uid, u.name FROM {node} n INNER JOIN {forum} f ON n.nid = f.nid LEFT JOIN {users} u ON n.uid = u.uid WHERE n.type = 'forum' ORDER BY n.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

  $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);

156
  if (!$main) {
Dries Buytaert's avatar
   
Dries Buytaert committed
157
    $node->title = l($voc->name, "forum") ." &raquo; ". l($term_data->name, "forum/$term_data->tid") ." &raquo; $node->title";
158
  }
Dries Buytaert's avatar
   
Dries Buytaert committed
159

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

Dries Buytaert's avatar
   
Dries Buytaert committed
163
  theme("node", $node, $main);
Dries Buytaert's avatar
   
Dries Buytaert committed
164
165
}

166
167
168
169
function forum_validate(&$node) {
  // Make sure all fields are set properly:
  $node->icon = $node->icon ? $node->icon : "";
  $node->shadow = $node->shadow ? $node->shadow : 0;
170
  $node->tid = $node->tid ? $node->tid : 0;
171
172
173
174
175
176
  // 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
177
178
179
  }
}

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

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

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

  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
199

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

  return $output;
}

Dries Buytaert's avatar
   
Dries Buytaert committed
205
function forum_insert($node) {
Dries Buytaert's avatar
   
Dries Buytaert committed
206
  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
207
208
209
}

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

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

Dries Buytaert's avatar
   
Dries Buytaert committed
217
function _forum_num_comments($nid) {
Dries Buytaert's avatar
   
Dries Buytaert committed
218
  $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
219
220
221
  return ($value) ? $value->count : 0;
}

Dries Buytaert's avatar
   
Dries Buytaert committed
222
function _forum_last_comment($nid) {
Dries Buytaert's avatar
   
Dries Buytaert committed
223
  $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
224
225
226
  return ($value) ? format_date($value->timestamp, "small") : "&nbsp;";
}

Dries Buytaert's avatar
   
Dries Buytaert committed
227
function _forum_last_reply($nid) {
Dries Buytaert's avatar
   
Dries Buytaert committed
228
  $value = db_fetch_object(db_query_range("SELECT c.timestamp, u.name, u.uid FROM {comments} c LEFT 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
229
230
231
232
233
  return $value;
}

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

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

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

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

Dries Buytaert's avatar
   
Dries Buytaert committed
250
  if (empty($cache)) {
251
    $forums = array();
Dries Buytaert's avatar
   
Dries Buytaert committed
252
    $_forums = taxonomy_get_tree(variable_get("forum_nav_vocabulary", ""), $tid);
Dries Buytaert's avatar
   
Dries Buytaert committed
253
254
    $n = 0;
    foreach ($_forums as $forum) {
Dries Buytaert's avatar
   
Dries Buytaert committed
255
256
257
      $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
258
259
260
261
      $forums[$forum->tid] = $forum;
      $n++;
    }

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

  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
287

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

function _forum_num_topics($term) {
Dries Buytaert's avatar
   
Dries Buytaert committed
292
  $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
293
294
295
296
  return ($value) ? $value->count : 0;
}

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

function _forum_topics_read($uid) {
Dries Buytaert's avatar
   
Dries Buytaert committed
302
  $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
303
304
305
306
307
308
309
310
311

  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
312
  $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 LEFT 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
313

Dries Buytaert's avatar
   
Dries Buytaert committed
314
  $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 LEFT 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
315
316
317
318
319
320

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

  return $value;
}

Dries Buytaert's avatar
Dries Buytaert committed
321
function forum_get_topics($tid, $sortby, $forum_per_page) {
Dries Buytaert's avatar
   
Dries Buytaert committed
322
323
324
325
326
327
328
  global $user;

  $term = taxonomy_get_term($tid);
  $voc = taxonomy_get_vocabulary($term->vid);

  $sql_sortby = _forum_get_topic_order($sortby);

Dries Buytaert's avatar
Dries Buytaert committed
329
  // show topics with the correct tid, or in the forum but with shadow = 1
Dries Buytaert's avatar
   
Dries Buytaert committed
330
  $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 LEFT 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 ORDER BY $sql_sortby";
Dries Buytaert's avatar
Dries Buytaert committed
331

Dries Buytaert's avatar
   
Dries Buytaert committed
332
  $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
333

Dries Buytaert's avatar
Dries Buytaert committed
334
  $result = pager_query($sql, $forum_per_page, 0, $sql_count);
Dries Buytaert's avatar
   
Dries Buytaert committed
335
336
337
338
  $topic_num = db_num_rows($result);

  $n = 0;
  while ($topic = db_fetch_object($result)) {
Dries Buytaert's avatar
Dries Buytaert committed
339
340
341
342
343
    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
344
345
      }
      else {
Dries Buytaert's avatar
Dries Buytaert committed
346
347
        if (!$history && $user->uid) {
          $topic->new_replies = 0;
Dries Buytaert's avatar
   
Dries Buytaert committed
348
349
350
          $topic->new = 1;
        }
        else {
Dries Buytaert's avatar
   
Dries Buytaert committed
351
          $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
352
353
354
355
356
357
358
359

          $topic->new_replies = $comments ? $comments : 0;
          if ($topic->new_replies) {
            $topic->new = 1;
          }
          else {
            $topic->new = 0;
          }
Dries Buytaert's avatar
   
Dries Buytaert committed
360
361
        }
      }
Dries Buytaert's avatar
Dries Buytaert committed
362
363
364
365
366
367
     }
     else {
      // you're not logged in eh?
      $topic->new_replies = 0;
      $topic->new = 0;
     }
Dries Buytaert's avatar
   
Dries Buytaert committed
368
369
370
371
372

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

Dries Buytaert's avatar
Dries Buytaert committed
373
  return $topics;
Dries Buytaert's avatar
   
Dries Buytaert committed
374
375
}

Dries Buytaert's avatar
Dries Buytaert committed
376
function _forum_new($tid) {
Dries Buytaert's avatar
   
Dries Buytaert committed
377
  global $user;
Dries Buytaert's avatar
   
Dries Buytaert committed
378
  $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
379
380
381
382
  while ($r = db_fetch_object($result)) {
    $read[] = $r->nid;
  }

Dries Buytaert's avatar
   
Dries Buytaert committed
383
  $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
384
385
386
387

  return $nid ? $nid : 0;
}

Dries Buytaert's avatar
   
Dries Buytaert committed
388
389
390
391
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
392
function forum_page() {
Dries Buytaert's avatar
   
Dries Buytaert committed
393
  global $sortby, $forum_per_page, $from, $user;
Dries Buytaert's avatar
   
Dries Buytaert committed
394

Dries Buytaert's avatar
   
Dries Buytaert committed
395
  $op = $_POST["op"];
Dries Buytaert's avatar
   
Dries Buytaert committed
396

Dries Buytaert's avatar
   
Dries Buytaert committed
397
  if (user_access("access content")) {
Dries Buytaert's avatar
   
Dries Buytaert committed
398
    if (module_exist("taxonomy")) {
Dries Buytaert's avatar
   
Dries Buytaert committed
399
      $tid = arg(1);
400
      if ($op == t("Update settings") && $user->uid) {
Dries Buytaert's avatar
   
Dries Buytaert committed
401
402
        $user = user_save($user, array("sortby" => $sortby, "forum_per_page" => $forum_per_page));
      }
Dries Buytaert's avatar
   
Dries Buytaert committed
403

Dries Buytaert's avatar
Dries Buytaert committed
404
405
406
407
408
      if (arg(2) == "new") {
        if ($nid = _forum_new($tid)) {
          drupal_goto(url("node/view/$nid"));
        }
      }
Dries Buytaert's avatar
   
Dries Buytaert committed
409

Dries Buytaert's avatar
   
Dries Buytaert committed
410
411
412
      if (empty($sortby)) {
        $sortby = isset($user->sortby) ? $user->sortby : variable_get("forum_order",1);
      }
Dries Buytaert's avatar
   
Dries Buytaert committed
413

Dries Buytaert's avatar
   
Dries Buytaert committed
414
415
416
      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
417

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

Dries Buytaert's avatar
   
Dries Buytaert committed
420
421
      $forums = forum_get_forums($tid);
      $parents = forum_get_parents($tid);
Dries Buytaert's avatar
   
Dries Buytaert committed
422
      $topics = forum_get_topics($tid, $sortby, $forum_per_page);
Dries Buytaert's avatar
   
Dries Buytaert committed
423

Dries Buytaert's avatar
   
Dries Buytaert committed
424
      theme("forum_theme_display", $forums, $topics, $parents, $tid, $sortby, $forum_per_page, $offset);
Dries Buytaert's avatar
   
Dries Buytaert committed
425
426
    }
    else {
Dries Buytaert's avatar
   
Dries Buytaert committed
427
428
429
      theme("header");
      theme("box", t("Warning"), _forum_message_taxonomy());
      theme("footer");
Dries Buytaert's avatar
   
Dries Buytaert committed
430
    }
Dries Buytaert's avatar
   
Dries Buytaert committed
431
432
  }
  else {
Dries Buytaert's avatar
   
Dries Buytaert committed
433
434
435
    theme("header");
    theme("box", t("Access denied"), message_access());
    theme("footer");
Dries Buytaert's avatar
   
Dries Buytaert committed
436
437
438
  }
}

Dries Buytaert's avatar
   
Dries Buytaert committed
439
/*
Dries Buytaert's avatar
   
Dries Buytaert committed
440
** Theme functions
Dries Buytaert's avatar
   
Dries Buytaert committed
441
*/
Dries Buytaert's avatar
   
Dries Buytaert committed
442

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

Dries Buytaert's avatar
   
Dries Buytaert committed
446
  theme("header");
Dries Buytaert's avatar
   
Dries Buytaert committed
447

Dries Buytaert's avatar
   
Dries Buytaert committed
448
449
450
  /*
  ** Breadcrumb navigation:
  */
Dries Buytaert's avatar
   
Dries Buytaert committed
451

Dries Buytaert's avatar
   
Dries Buytaert committed
452
453
454
455
456
  if ($tid) {
    $trail[] = l(t("Forums"), "forum");
  }
  else {
    $trail[] = t("Forums");
Dries Buytaert's avatar
   
Dries Buytaert committed
457
458
459
  }

  if ($parents) {
Dries Buytaert's avatar
   
Dries Buytaert committed
460
461
    $parents = array_reverse($parents);
    foreach ($parents as $p) {
Dries Buytaert's avatar
   
Dries Buytaert committed
462
      if ($tid != $p->tid) {
Dries Buytaert's avatar
   
Dries Buytaert committed
463
        $trail[] = l($p->name, "forum/$p->tid");
Dries Buytaert's avatar
   
Dries Buytaert committed
464
465
      }
      else {
Dries Buytaert's avatar
   
Dries Buytaert committed
466
        $trail[] = $p->name;
Dries Buytaert's avatar
   
Dries Buytaert committed
467
468
469
470
      }
    }
  }

Dries Buytaert's avatar
   
Dries Buytaert committed
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
  $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>";

  theme("box", implode($trail, " &raquo; "), $output);
  theme("footer");
}

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

Dries Buytaert's avatar
   
Dries Buytaert committed
487
488
  if ($forums) {

Dries Buytaert's avatar
   
Dries Buytaert committed
489
    $header = array(t("Forum"), t("Topics"), t("Posts"), t("Last post"));
Dries Buytaert's avatar
   
Dries Buytaert committed
490
491

    foreach ($forums as $forum) {
Dries Buytaert's avatar
   
Dries Buytaert committed
492
493
      if ($user->uid) {
        $new_topics = $forum->num_topics - $forum->old_topics;
494
      }
Dries Buytaert's avatar
   
Dries Buytaert committed
495

Dries Buytaert's avatar
   
Dries Buytaert committed
496
497
498
499
500
      $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
501

Dries Buytaert's avatar
   
Dries Buytaert committed
502
503
      if ($new_topics) {
        $links[] = l(t("the first new topic"), "forum/$forum->tid/new");
Dries Buytaert's avatar
   
Dries Buytaert committed
504
      }
Dries Buytaert's avatar
   
Dries Buytaert committed
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520

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

Dries Buytaert's avatar
   
Dries Buytaert committed
524
525
526
    }
  }

Dries Buytaert's avatar
   
Dries Buytaert committed
527
  return table($header, $rows);
Dries Buytaert's avatar
   
Dries Buytaert committed
528
529
}

Dries Buytaert's avatar
   
Dries Buytaert committed
530
function forum_theme_topic_browser() {
Dries Buytaert's avatar
   
Dries Buytaert committed
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
  global $tid, $sortby, $forum_per_page, $offset;

  if (empty($sortby)) {
    $sortby = variable_get("forum_order",1);
  }
  if (empty($forum_per_page)) {
    $forum_per_page = variable_get("forum_per_page", 25);
  }

  $forum_per_page_options = array(10, 25, 50, 75, 100);
  foreach ($forum_per_page_options as $value) {
    $options .= " <option value=\"$value\"". ($forum_per_page == $value ? " selected=\"selected\"" : "") .">".t("%a topics per page", array("%a" => $value))."</option>\n";
  }

  $output .= "<select name=\"forum_per_page\">$options</select>\n";

  $options = "";
  $sortby_options = array(1 => t("Date - newest first"), 2 => t("Date - oldest first"), 3 => t("Posts - most active first"), 4=> t("Posts - least active first"));
  foreach ($sortby_options as $key => $value) {
    $options .= " <option value=\"$key\"". ($sortby == $key ? " selected=\"selected\"" : "") .">$value</option>\n";
  }

  $output .= "\n<select name=\"sortby\">$options</select>\n";
  $output .= form_hidden("tid", $tid);
  $output .= form_submit(t("Update settings"));
Dries Buytaert's avatar
   
Dries Buytaert committed
556
  return form($output);
Dries Buytaert's avatar
   
Dries Buytaert committed
557
558
}

Dries Buytaert's avatar
   
Dries Buytaert committed
559
function forum_theme_topic_list($tid, $topics, $sortby, $forum_per_page, $offset) {
Dries Buytaert's avatar
   
Dries Buytaert committed
560
  global $id, $status, $user, $pager_total;
Dries Buytaert's avatar
   
Dries Buytaert committed
561
562

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

Dries Buytaert's avatar
   
Dries Buytaert committed
564
    $header = array(array("data" => t("Topic"), "colspan" => "2"), t("Replies"), t("Created"), t("Last reply"));
Dries Buytaert's avatar
   
Dries Buytaert committed
565
566
567

    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
568
      if ($topic->tid != $tid) {
Dries Buytaert's avatar
   
Dries Buytaert committed
569
        $rows[] = array(
Dries Buytaert's avatar
   
Dries Buytaert committed
570
          array("data" => _forum_icon($topic->new, $topic->num_comments, $topic->comment_mode), "class" => "icon"),
Dries Buytaert's avatar
   
Dries Buytaert committed
571
          array("data" => $topic->title, "class" => "title"),
Dries Buytaert's avatar
   
Dries Buytaert committed
572
          array("data" => l(t("This topic has been moved"), "forum/$topic->tid"), "colspan" => "3")
Dries Buytaert's avatar
   
Dries Buytaert committed
573
        );
Dries Buytaert's avatar
   
Dries Buytaert committed
574
575
      }
      else {
Dries Buytaert's avatar
   
Dries Buytaert committed
576
        $rows[] = array(
Dries Buytaert's avatar
   
Dries Buytaert committed
577
          array("data" => _forum_icon($topic->new, $topic->num_comments, $topic->comment_mode), "class" => "icon"),
Dries Buytaert's avatar
   
Dries Buytaert committed
578
579
          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
580
581
          array("data" => _forum_format($topic), "class" => "created"),
          array("data" => _forum_format($topic->last_reply), "class" => "last-reply")
Dries Buytaert's avatar
   
Dries Buytaert committed
582
        );
Dries Buytaert's avatar
   
Dries Buytaert committed
583
584
585
      }
    }

Dries Buytaert's avatar
   
Dries Buytaert committed
586
587
    $rows[] = array(array("data" => t("%a topics, %b topics per page, page %c of %d", array("%a" => $pager_total[0], "%b" => $forum_per_page, "%c" => $offset, "%d" => ceil($pager_total[0]/$forum_per_page))), "colspan" => "5", "class" => "statistics"));
    $rows[] = array(array("data" => theme("forum_theme_topic_browser", $sortby, $forum_per_page, $offset), "colspan" => "5", "class" => "settings"));
Dries Buytaert's avatar
   
Dries Buytaert committed
588

Dries Buytaert's avatar
   
Dries Buytaert committed
589
    if ($pager = pager_display(NULL, $forum_per_page, 0, "default")) {
Dries Buytaert's avatar
   
Dries Buytaert committed
590
      $rows[] = array(array("data" => $pager, "colspan" => "5", "class" => "pager"));
Dries Buytaert's avatar
   
Dries Buytaert committed
591
592
    }
  }
Dries Buytaert's avatar
   
Dries Buytaert committed
593
594


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

Dries Buytaert's avatar
   
Dries Buytaert committed
599
  $output .= table($header, $rows);
Dries Buytaert's avatar
   
Dries Buytaert committed
600

Dries Buytaert's avatar
   
Dries Buytaert committed
601
602
603
  return $output;
}

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

Dries Buytaert's avatar
   
Dries Buytaert committed
606
  $base_path = variable_get("forum_icon_path", "");
Dries Buytaert's avatar
   
Dries Buytaert committed
607
608
  if ($base_path) {
    if ($num_posts > variable_get("forum_hot_topic", 15)) {
Dries Buytaert's avatar
   
Dries Buytaert committed
609
      $icon = $new_posts ? "hot-new" : "hot";
Dries Buytaert's avatar
   
Dries Buytaert committed
610
611
612
613
614
615
616
617
618
    }
    else {
      $icon = $new_posts ? "new" : "default";
    }

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

Dries Buytaert's avatar
   
Dries Buytaert committed
619
    // default
Dries Buytaert's avatar
   
Dries Buytaert committed
620
    $file = $base_path."/forum-$icon.gif";
Dries Buytaert's avatar
   
Dries Buytaert committed
621

Dries Buytaert's avatar
   
Dries Buytaert committed
622
    return "<img src=\"$file\" alt=\"\" title=\"\" />";
Dries Buytaert's avatar
   
Dries Buytaert committed
623
624
625
626
627
628
629
630
631
632
  }
  else {
    return "&nbsp;";
  }
}

function _forum_user_last_visit($nid) {
  global $user;
  static $history;
  if (!$history) {
Dries Buytaert's avatar
   
Dries Buytaert committed
633
    $result = db_query("SELECT nid, timestamp FROM {history} WHERE uid = %d", $user->uid);
Dries Buytaert's avatar
   
Dries Buytaert committed
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
    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
658
659
660
661
662
663
664
665
666
667
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
668
669
      $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
670
671
672
673
674
675
676
677
      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
678

Dries Buytaert's avatar
   
Dries Buytaert committed
679
  return t($output);
Dries Buytaert's avatar
   
Dries Buytaert committed
680
681
682
}

?>