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

Dries Buytaert's avatar
   
Dries Buytaert committed
4
5
6
7
8
/**
 * @file
 * Enable threaded discussions about general topics.
 */

9
10
11
12
/**
 * Implementation of hook_help().
 */
function forum_help($section) {
Dries Buytaert's avatar
   
Dries Buytaert committed
13
  switch ($section) {
14
15
16
17
18
19
    case 'admin/forum':
      return t('Forums and containers are used to organize the threaded discussions.  Forums may be nested in each other.  A container is used to group like forums together with out allowing topics to be created in the container.  Containers can be nested just like forums.  To delete a forum or container choose the appropriate "edit" operation.');
    case 'admin/forum/add/container':
      return t('When creating a contianer you are creating a group to contain multiple forums.  Users are not able to create topic inside container.  You can nest containers inside forums or other containers.');
    case 'admin/forum/add/forum':
      return t('When creating a forum you are creating an area for user to create similar topics for discussion. Forums may be nested underneath other forums or in containers.');
Dries Buytaert's avatar
   
Dries Buytaert committed
20
    case 'admin/modules#description':
21
      return t('Enable threaded discussions about general topics.');
Dries Buytaert's avatar
   
Dries Buytaert committed
22
    case 'node/add#forum':
23
      return t('A forum is a threaded discussion, enabling users to communicate about a particular topic.');
Dries Buytaert's avatar
   
Dries Buytaert committed
24
25
26
  }
}

27
28
29
/**
 * Implementation of hook_node_name().
 */
Dries Buytaert's avatar
   
Dries Buytaert committed
30
function forum_node_name($node) {
Dries Buytaert's avatar
   
Dries Buytaert committed
31
  return t('forum topic');
Dries Buytaert's avatar
   
Dries Buytaert committed
32
33
}

34
35
36
/**
 * Implementation of hook_access().
 */
Dries Buytaert's avatar
   
Dries Buytaert committed
37
function forum_access($op, $node) {
Dries Buytaert's avatar
   
Dries Buytaert committed
38
39
  global $user;

Dries Buytaert's avatar
   
Dries Buytaert committed
40
41
  if ($op == 'create') {
    return user_access('create forum topics');
Dries Buytaert's avatar
   
Dries Buytaert committed
42
  }
Dries Buytaert's avatar
   
Dries Buytaert committed
43
44
45
46
47
48

  if ($op == 'update' || $op == 'delete') {
    if (user_access('edit own forum topics') && ($user->uid == $node->uid)) {
      return TRUE;
    }
  }
Dries Buytaert's avatar
   
Dries Buytaert committed
49
50
}

51
52
53
/**
 * Implementation of hook_perm().
 */
Dries Buytaert's avatar
   
Dries Buytaert committed
54
function forum_perm() {
55
  return array('create forum topics', 'edit own forum topics', 'administer forums');
Dries Buytaert's avatar
   
Dries Buytaert committed
56
}
Dries Buytaert's avatar
   
Dries Buytaert committed
57

58
/**
59
 * Admiinstration page which allows maintaining forums
60
 */
61
62
63
64
65
66
67
function forum_admin() {
  $op = $_POST['op'];
  $edit = $_POST['edit'];

  if (empty($op)) {
    $op = arg(2);
  }
Dries Buytaert's avatar
   
Dries Buytaert committed
68

69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
  switch ($op) {
    case 'add':
      if (arg(3) == 'forum') {
        $output = forum_form_forum();
      }
      else if (arg(3) == 'container') {
        $output = forum_form_container();
      }
      break;
    case 'edit':
      if (arg(3) == 'forum') {
        $output = forum_form_forum(object2array(taxonomy_get_term(arg(4))));
      }
      else if (arg(3) == 'container') {
         $output = forum_form_container(object2array(taxonomy_get_term(arg(4))));
      }
      break;
    case t('Delete'):
      if (!$edit['confirm']) {
        $output = _forum_confirm_del($edit['tid']);
        break;
      }
      else {
        $edit['name'] = 0;
      }
    case t('Submit'):
      $edit = taxonomy_save_term($edit);
      if (arg(3) == 'container') {
        $containers = variable_get('forum_containers', array());
        $containers[] = $edit['tid'];
        variable_set('forum_containers', $containers);
       }
      drupal_goto('admin/forum');
    default:
      $output = forum_overview();
  }

  print theme('page', $output);
}

/**
 * Implementation of hook_taxonomy().
 */
function forum_taxonomy($op, $type, $object) {
  if ($op == 'delete' && $type == 'term' && $object->vid == _forum_get_vid())  {
    $results = db_query('SELECT f.nid FROM forum f WHERE f.tid = %d', $object->tid);
    while ($node = db_fetch_object($results)) {
      $edit['nid'] = $node->nid;
      $edit['confirm'] = TRUE;
      node_delete($edit);
Dries Buytaert's avatar
   
Dries Buytaert committed
119
    }
120
121
  }
}
Dries Buytaert's avatar
   
Dries Buytaert committed
122

123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
/**
 * Returns a confirmation page for deleting a forum taxonomy term
 *
 * @param $tid ID of the term to be deleted
 */
function _forum_confirm_del($tid) {
   $term = taxonomy_get_term($tid);

   $form .= form_hidden('confirm', 1);
   $form .= form_hidden('tid', $tid);
   $form .= form_submit(t('Delete'));
   $form .= form_submit(t('Cancel'));

   return form(form_item(t('Delete "%name"', array('%name' => $term->name)), $form, t('Deleteing a forum or container will delete all sub-forums as well.  Are you sure you want to delete?')));
}

/**
 * Returns a form for adding a container to the forum vocabulary
 *
 * @param $edit Associative array containing a container term to be added or edited.
 */
function forum_form_container($edit = array()) {
  $form = form_textfield(t('Container name'), 'name', $edit['name'], 50, 64, t('The container name is used on the forum listing page to identify a group of forums.'), NULL, TRUE);
  $form .= form_textarea(t('Description'), 'description', $edit['description'], 60, 5, t('The description can provide additional information about the forum grouping.'));

  $form .= _forum_parent_select($edit['tid'], t('Parent'), 'parent][');
  $form .= form_weight(t('Weight'), 'weight', $edit['weight'], 10, t('In listings, the heavier terms (with a larger weight) will sink and the lighter terms will be positioned nearer the top.'));

  $form .= form_hidden('vid', _forum_get_vid());
  $form .= form_submit(t('Submit'));
  if ($edit['tid']) {
    $form .= form_submit(t('Delete'));
    $form .= form_hidden('tid', $edit['tid']);
  }

  return form($form);
}

/**
 * Returns a form for adding a forum to the forum vocabulary
 *
 * @param $edit Associative array containing a forum term to be added or edited.
 */
function forum_form_forum($edit = array()) {
  $form = form_textfield(t('Forum name'), 'name', $edit['name'], 50, 64, t('The name is used to identify the forum.'), NULL, TRUE);
  $form .= form_textarea(t('Description'), 'description', $edit['description'], 60, 5, t('The description can be used to provide more information about the forum, or further details about the topic.'));

  $form .= _forum_parent_select($edit['tid'], t('Parent'), 'parent][');
  $form .= form_weight(t('Weight'), 'weight', $edit['weight'], 10, t('In listings, the heavier (with a higher weight value) terms will sink and the lighter terms will be positioned nearer the top.'));

  $form .= form_hidden('vid', _forum_get_vid());
  $form .= form_submit(t('Submit'));
  if ($edit['tid']) {
    $form .= form_submit(t('Delete'));
    $form .= form_hidden('tid', $edit['tid']);
  }
179

180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
  return form($form);
}

/**
 * Returns a select box for available parent terms
 *
 * @param $tid ID of the term which is being added or edited
 * @param $title Title to display the select box with
 * @param $name Name to use in the forum
 */
function _forum_parent_select($tid, $title, $name) {

  $parents = taxonomy_get_parents($tid);
  $children = taxonomy_get_tree(_forum_get_vid, $tid);

  // A term can't be the child of itself, nor of its children.
  foreach ($children as $child) {
    $exclude[] = $child->tid;
  }
  $exclude[] = $tid;

  $tree = taxonomy_get_tree(_forum_get_vid());
  $options[0] = '<'. t('root') .'>';
  if ($tree) {
    foreach ($tree as $term) {
      if (!in_array($term->tid, $exclude)) {
        $options[$term->tid] = _forum_depth($term->depth).$term->name;
      }
Dries Buytaert's avatar
   
Dries Buytaert committed
208
209
    }
  }
Dries Buytaert's avatar
   
Dries Buytaert committed
210

211
212
213
214
215
  if (!$parents) {
    $parents = 0;
  }

  return form_select($title, $name, $parents, $options, NULL, 0, FALSE, TRUE);
Dries Buytaert's avatar
   
Dries Buytaert committed
216
217
}

218
/**
219
 * Returns an overview list of existing forums and contianers
220
 */
221
222
223
224
225
226
227
228
229
230
231
232
233
function forum_overview() {
  $header = array(t('Name'), t('Operations'));

  $tree = taxonomy_get_tree(_forum_get_vid());
  if ($tree) {
    foreach ($tree as $term) {
      if (in_array($term->tid, variable_get('forum_containers', array()))) {
        $rows[] = array(_forum_depth($term->depth) .' '. $term->name, l(t('edit container'), "admin/forum/edit/container/$term->tid"));
      }
      else {
        $rows[] = array(_forum_depth($term->depth) .' '. $term->name, l(t('edit forum'), "admin/forum/edit/forum/$term->tid"));
       }

Dries Buytaert's avatar
Dries Buytaert committed
234
    }
235
236

    return theme('table', $header, $rows);
Dries Buytaert's avatar
Dries Buytaert committed
237
238
239
  }
}

240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
/**
 * Helper function used to generate indentation for forum list
 *
 * @param $depth Depth of the indentation
 * @param $graphic HTML text to be repeated for each stage of depth
 */
function _forum_depth($depth, $graphic = '--') {
  for ($n = 0; $n < $depth; $n++) {
    $result .= $graphic;
  }
  return $result;
}

/**
 * Returns the vocabulary id for forum navigation.
 */
function _forum_get_vid() {
  $vid = variable_get('forum_nav_vocabulary', '');
  if (empty($vid)) {
    // Check to see if a forum vocabulary exists
    $vid = db_result(db_query("SELECT vid FROM {vocabulary} WHERE module='%s'", 'forum'));
    if (!$vid) {
262
      $vocabulary = taxonomy_save_vocabulary(array('name' => 'Forums', 'multiple' => 0, 'required' => 1, 'hierarchy' => 1, 'relations' => 0, 'module' => 'forum', 'nodes' => array('forum')));
263
264
265
266
267
268
269
270
271
272
273
      $vid = $vocabulary['vid'];
    }
    variable_set('forum_nav_vocabulary', $vid);
  }

  return $vid;
}

/**
 * Implementation of hook_settings
 */
274
275
276
function forum_admin_configure() {
  system_settings_save();

277
278
279
280
281
282
283
284
  $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. You may use images of whatever size you wish, but it is recommended to use 15x15 or 16x16. '));
  $number = drupal_map_assoc(array(5, 10, 15, 20, 25, 30, 35, 40, 50, 60, 80, 100, 10000));
  $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 hot.'));
  $number = drupal_map_assoc(array(10, 25, 50, 75, 100));
  $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_radios(t('Default order'), 'forum_order', variable_get('forum_order', '1'), $forder, t('The default display order for topics.'));

285
  print theme('page', system_settings_form($output));
286
287
}

288
289
290
/**
 * Implementation of hook_load().
 */
Dries Buytaert's avatar
   
Dries Buytaert committed
291
function forum_load($node) {
Dries Buytaert's avatar
   
Dries Buytaert committed
292
  $forum = db_fetch_object(db_query('SELECT * FROM {forum} WHERE nid = %d', $node->nid));
Dries Buytaert's avatar
   
Dries Buytaert committed
293
294
295
296

  return $forum;
}

297
298
299
300
301
302
/**
 * Implementation of hook_block().
 *
 * Generates a block containing the currently active forum topics and the
 * most recently added forum topics.
 */
303
304
305
function forum_block($op = 'list', $delta = 0, $edit = array()) {
  switch ($op) {
    case 'list':
Dries Buytaert's avatar
   
Dries Buytaert committed
306
307
      $blocks[0]['info'] = t('Active forum topics');
      $blocks[1]['info'] = t('New forum topics');
308
      return $blocks;
Dries Buytaert's avatar
   
Dries Buytaert committed
309

310
311
312
    case 'configure':
      $output = form_select(t('Number of topics in block'), 'forum_block_num', variable_get('forum_block_num', '5'), drupal_map_assoc(array(2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20)));
      return $output;
Dries Buytaert's avatar
   
Dries Buytaert committed
313

314
315
316
    case 'save':
      variable_set('forum_block_num', $edit['forum_block_num']);
      break;
Dries Buytaert's avatar
   
Dries Buytaert committed
317

318
319
    case 'view':
      if (user_access('access content')) {
Dries Buytaert's avatar
   
Dries Buytaert committed
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
        switch ($delta) {
          case 0:
           $title = t('Active forum topics');
           $sql = "SELECT n.nid, n.title, l.last_comment_timestamp, l.comment_count FROM {node} n INNER JOIN {node_comment_statistics} l ON n.nid = l.nid WHERE n.status = 1 AND n.type='forum' ORDER BY l.last_comment_timestamp DESC";
           $sql = db_rewrite_sql($sql);
           $content  = node_title_list(db_query_range($sql, 0, variable_get('forum_block_num', '5')));
           break;

          case 1:
           $title = t('New forum topics');
           $sql = "SELECT n.nid, n.title, l.comment_count FROM {node} n INNER JOIN {node_comment_statistics} l ON n.nid = l.nid WHERE n.type = 'forum' AND n.status = 1 ORDER BY n.nid DESC";
           $sql = db_rewrite_sql($sql);
           $content .= node_title_list(db_query_range($sql, 0, variable_get('forum_block_num', '5')));
           break;
        }
Dries Buytaert's avatar
   
Dries Buytaert committed
335

336
337
338
339
        if ($content) {
          $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
340
        $block['subject'] = $title;
341
342
343
344
345
        $block['content'] = $content;

        return $block;
      }
  }
Dries Buytaert's avatar
   
Dries Buytaert committed
346
347
}

Dries Buytaert's avatar
   
Dries Buytaert committed
348
349
350
/**
 * Implementation of hook_link().
 */
351
function forum_link($type, $node = 0, $main = 0) {
Dries Buytaert's avatar
Dries Buytaert committed
352
  global $user;
Dries Buytaert's avatar
   
Dries Buytaert committed
353

Dries Buytaert's avatar
   
Dries Buytaert committed
354
355
  $links = array();

Dries Buytaert's avatar
   
Dries Buytaert committed
356
  if (!$main && $type == 'node' && $node->type == 'forum') {
Dries Buytaert's avatar
   
Dries Buytaert committed
357
358
    // get previous and next topic

Steven Wittens's avatar
Steven Wittens committed
359
    $sql = "SELECT n.nid, n.title, n.sticky, l.comment_count, l.last_comment_timestamp FROM {node} n INNER JOIN {node_comment_statistics} l ON n.nid = l.nid INNER JOIN {term_node} r ON n.nid = r.nid AND r.tid = %d WHERE n.status = 1 AND n.type = 'forum' ORDER BY n.sticky DESC, ". _forum_get_topic_order_sql(variable_get('forum_order', 1));
360
    $sql = db_rewrite_sql($sql);
Dries Buytaert's avatar
   
Dries Buytaert committed
361
    $result = db_query($sql, $node->tid);
Dries Buytaert's avatar
   
Dries Buytaert committed
362
363
364

    while ($topic = db_fetch_object($result)) {
      if ($stop == 1) {
365
        $next = new StdClass();
Dries Buytaert's avatar
   
Dries Buytaert committed
366
367
368
369
370
371
372
373
        $next->nid = $topic->nid;
        $next->title = $topic->title;
        break;
      }
      if ($topic->nid == $node->nid) {
        $stop = 1;
      }
      else {
374
        $prev = new StdClass();
Dries Buytaert's avatar
   
Dries Buytaert committed
375
376
377
378
379
380
        $prev->nid = $topic->nid;
        $prev->title = $topic->title;
      }
    }

    if ($prev) {
Dries Buytaert's avatar
   
Dries Buytaert committed
381
      $links[] = l(t('previous forum topic'), "node/$prev->nid", array('title' => $prev->title));
Dries Buytaert's avatar
   
Dries Buytaert committed
382
383
384
    }

    if ($next) {
Dries Buytaert's avatar
   
Dries Buytaert committed
385
      $links[] = l(t('next forum topic'), "node/$next->nid", array('title' => $next->title));
Dries Buytaert's avatar
   
Dries Buytaert committed
386
    }
Dries Buytaert's avatar
   
Dries Buytaert committed
387
388
  }

Dries Buytaert's avatar
   
Dries Buytaert committed
389
  return $links;
Dries Buytaert's avatar
   
Dries Buytaert committed
390
391
}

Dries Buytaert's avatar
   
Dries Buytaert committed
392
393
394
/**
 * Implementation of hook_menu().
 */
Dries Buytaert's avatar
   
Dries Buytaert committed
395
function forum_menu($may_cache) {
Dries Buytaert's avatar
   
Dries Buytaert committed
396
397
  $items = array();

Dries Buytaert's avatar
   
Dries Buytaert committed
398
399
400
  if ($may_cache) {
    $items[] = array('path' => 'node/add/forum', 'title' => t('forum topic'),
      'access' => user_access('create forum topics'));
401

Dries Buytaert's avatar
   
Dries Buytaert committed
402
403
404
    $items[] = array('path' => 'forum', 'title' => t('forums'),
      'callback' => 'forum_page',
      'access' => user_access('access content'),
405
      'type' => MENU_SUGGESTED_ITEM);
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420

    $items[] = array('path' => 'admin/forum', 'title' => t('forums'),
      'callback' => 'forum_admin',
      'access' => user_access('administer forums'),
      'type' => MENU_NORMAL_ITEM);

    $items[] = array('path' => 'admin/forum/list', 'title' => t('list'),
      'access' => user_access('administer forums'),
      'type' => MENU_DEFAULT_LOCAL_TASK, 'weight' => -10);
    $items[] = array('path' => 'admin/forum/add/container', 'title' => t('add container'),
      'access' => user_access('administer forums'),
      'type' => MENU_LOCAL_TASK);
    $items[] = array('path' => 'admin/forum/add/forum', 'title' => t('add forum'),
      'access' => user_access('administer forums'),
      'type' => MENU_LOCAL_TASK);
421
422
423
424
    $items[] = array('path' => 'admin/forum/configure', 'title' => t('configure'),
      'callback' => 'forum_admin_configure',
      'access' => user_access('administer forums'),
      'type' => MENU_LOCAL_TASK);
425
426
427
428
429
430
431

    $items[] = array('path' => 'admin/forum/edit/container', 'title' => t('edit container'),
      'access' => user_access('administer forums'),
      'type' => MENU_CALLBACK);
    $items[] = array('path' => 'admin/forum/edit/forum', 'title' => t('edit forum'),
      'access' => user_access('administer forums'),
      'type' => MENU_CALLBACK);
Dries Buytaert's avatar
   
Dries Buytaert committed
432
  }
Dries Buytaert's avatar
   
Dries Buytaert committed
433
434
435
436

  return $items;
}

437
438
439
/**
 * Implementation of hook_view().
 */
Dries Buytaert's avatar
   
Dries Buytaert committed
440
function forum_view(&$node, $teaser = FALSE, $page = FALSE) {
Dries Buytaert's avatar
   
Dries Buytaert committed
441

Dries Buytaert's avatar
   
Dries Buytaert committed
442
  if ($page) {
Dries Buytaert's avatar
   
Dries Buytaert committed
443
    $vocabulary = taxonomy_get_vocabulary(variable_get('forum_nav_vocabulary', ''));
Dries Buytaert's avatar
   
Dries Buytaert committed
444
    // Breadcrumb navigation
Dries Buytaert's avatar
   
Dries Buytaert committed
445
446
    $breadcrumb = array();
    $breadcrumb[] = array('path' => 'forum', 'title' => $vocabulary->name);
Dries Buytaert's avatar
   
Dries Buytaert committed
447
    if ($parents = taxonomy_get_parents_all($node->tid)) {
Dries Buytaert's avatar
   
Dries Buytaert committed
448
449
      $parents = array_reverse($parents);
      foreach ($parents as $p) {
Dries Buytaert's avatar
   
Dries Buytaert committed
450
        $breadcrumb[] = array('path' => 'forum/'. $p->tid, 'title' => $p->name);
Dries Buytaert's avatar
   
Dries Buytaert committed
451
452
      }
    }
Dries Buytaert's avatar
   
Dries Buytaert committed
453
454
    $breadcrumb[] = array('path' => 'node/'. $node->nid);
    menu_set_location($breadcrumb);
455
  }
Dries Buytaert's avatar
   
Dries Buytaert committed
456

457
  $node = node_prepare($node, $teaser);
Dries Buytaert's avatar
   
Dries Buytaert committed
458
459
}

460
461
462
463
464
465
/**
 * Implementation of hook_validate().
 *
 * Check in particular that only a "leaf" term in the associated taxonomy
 * vocabulary is selected, not a "container" term.
 */
466
467
function forum_validate(&$node) {
  // Make sure all fields are set properly:
Dries Buytaert's avatar
   
Dries Buytaert committed
468
  $node->icon = $node->icon ? $node->icon : '';
Dries Buytaert's avatar
   
Dries Buytaert committed
469
470
471

  if ($node->taxonomy) {
    // Extract the node's proper topic ID.
Dries Buytaert's avatar
   
Dries Buytaert committed
472
    $vocabulary = variable_get('forum_nav_vocabulary', '');
473
    $containers = variable_get('forum_containers', array());
Dries Buytaert's avatar
   
Dries Buytaert committed
474
    foreach ($node->taxonomy as $term) {
Dries Buytaert's avatar
   
Dries Buytaert committed
475
      if (db_result(db_query('SELECT COUNT(*) FROM {term_data} WHERE tid = %d AND vid = %d', $term, $vocabulary))) {
476
477
        if (in_array($term, $containers)) {
          $term = taxonomy_get_term($term);
Dries Buytaert's avatar
   
Dries Buytaert committed
478
          form_set_error('taxonomy', t('The item %forum is only a container for forums. Please select one of the forums below it.', array('%forum' => "<em>$term->name</em>")));
479
480
481
482
        }
        else {
          $node->tid = $term;
        }
Dries Buytaert's avatar
   
Dries Buytaert committed
483
      }
484
    }
Dries Buytaert's avatar
   
Dries Buytaert committed
485
486
487
488
489
490
491
    if ($node->tid && $node->shadow) {
      $terms = array_keys(taxonomy_node_get_terms($node->nid));
      if (!in_array($node->tid, $terms)) {
        $terms[] = $node->tid;
      }
      $node->taxonomy = $terms;
    }
Dries Buytaert's avatar
Dries Buytaert committed
492
493
494
  }
}

Dries Buytaert's avatar
   
Dries Buytaert committed
495
496
497
498
499
500
501
/**
 * Implementation of hook_update().
 */
function forum_update($node) {
  db_query('UPDATE {forum} SET tid = %d WHERE nid = %d', $node->tid, $node->nid);
}

502
503
504
/**
 * Implementation of hook_form().
 */
Dries Buytaert's avatar
   
Dries Buytaert committed
505
function forum_form(&$node) {
Dries Buytaert's avatar
   
Dries Buytaert committed
506
  if (!$node->nid) {
Dries Buytaert's avatar
Dries Buytaert committed
507
    // new topic
Dries Buytaert's avatar
   
Dries Buytaert committed
508
    $node->taxonomy[] = arg(3);
509
  }
Dries Buytaert's avatar
   
Dries Buytaert committed
510
511
512
  else {
    $node->taxonomy = array($node->tid);
  }
513

Dries Buytaert's avatar
   
Dries Buytaert committed
514
  $output = implode('', taxonomy_node_form('forum', $node));
Dries Buytaert's avatar
Dries Buytaert committed
515
516
517

  if ($node->nid) {
    // if editing, give option to leave shadows
Dries Buytaert's avatar
   
Dries Buytaert committed
518
519
    $shadow = (count(taxonomy_node_get_terms($node->nid)) > 1);
    $output .= form_checkbox(t('Leave shadow copy'), 'shadow', 1, $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
520
  }
Dries Buytaert's avatar
   
Dries Buytaert committed
521

522
  $output .= form_textarea(t('Body'), 'body', $node->body, 60, 20, '');
523
  $output .= filter_form('format', $node->format);
Dries Buytaert's avatar
   
Dries Buytaert committed
524
525
526
527

  return $output;
}

528
529
530
/**
 * Implementation of hook_insert().
 */
Dries Buytaert's avatar
   
Dries Buytaert committed
531
function forum_insert($node) {
Dries Buytaert's avatar
   
Dries Buytaert committed
532
  db_query('INSERT INTO {forum} (nid, tid) VALUES (%d, %d)', $node->nid, $node->tid);
Dries Buytaert's avatar
   
Dries Buytaert committed
533
534
}

535
536
537
/**
 * Implementation of hook_delete().
 */
Dries Buytaert's avatar
   
Dries Buytaert committed
538
function forum_delete(&$node) {
Dries Buytaert's avatar
   
Dries Buytaert committed
539
  db_query('DELETE FROM {forum} WHERE nid = %d', $node->nid);
Dries Buytaert's avatar
   
Dries Buytaert committed
540
}
Dries Buytaert's avatar
   
Dries Buytaert committed
541

Dries Buytaert's avatar
   
Dries Buytaert committed
542
543
544
/**
 * Formats a topic for display
 *
545
 * @TODO Give a better description. Not sure where this function is used yet.
Dries Buytaert's avatar
   
Dries Buytaert committed
546
 */
Dries Buytaert's avatar
   
Dries Buytaert committed
547
function _forum_format($topic) {
548
  if ($topic && $topic->timestamp) {
Dries Buytaert's avatar
   
Dries Buytaert committed
549
    return t('%time ago<br />by %author', array('%time' => format_interval(time() - $topic->timestamp), '%author' => format_name($topic)));
Dries Buytaert's avatar
   
Dries Buytaert committed
550
551
552
553
554
555
  }
  else {
    return message_na();
  }
}

Dries Buytaert's avatar
   
Dries Buytaert committed
556
557
558
/**
 * Returns a list of all forums for a given taxonomy id
 *
559
 * Forum objects contain the following fields
Dries Buytaert's avatar
   
Dries Buytaert committed
560
561
562
563
564
565
566
567
568
 * -num_topics Number of topics in the forum
 * -num_posts Total number of posts in all topics
 * -last_post Most recent post for the forum
 *
 * @param $tid
 *   Taxonomy ID of the vocabulary that holds the forum list.
 * @return
 *   Array of object containing the forum information.
 */
Dries Buytaert's avatar
   
Dries Buytaert committed
569
function forum_get_forums($tid = 0) {
570

Dries Buytaert's avatar
   
Dries Buytaert committed
571
572
573
574
  if (!$tid) {
    $tid = 0;
  }

Dries Buytaert's avatar
   
Dries Buytaert committed
575
576
  $forums = array();
  $_forums = taxonomy_get_tree(variable_get('forum_nav_vocabulary', ''), $tid);
Dries Buytaert's avatar
   
Dries Buytaert committed
577

Dries Buytaert's avatar
   
Dries Buytaert committed
578
  if (count($_forums)) {
Dries Buytaert's avatar
   
Dries Buytaert committed
579

Dries Buytaert's avatar
   
Dries Buytaert committed
580
581
    $counts = array();

Dries Buytaert's avatar
   
Dries Buytaert committed
582
    $sql = "SELECT r.tid, COUNT(n.nid) AS topic_count, SUM(l.comment_count) AS comment_count FROM {node} n INNER JOIN {node_comment_statistics} l ON n.nid = l.nid INNER JOIN {term_node} r ON n.nid = r.nid WHERE n.status = 1 AND n.type = 'forum' GROUP BY r.tid";
583
    $sql = db_rewrite_sql($sql);
Dries Buytaert's avatar
   
Dries Buytaert committed
584
    $_counts = db_query($sql, $forum->tid);
Dries Buytaert's avatar
   
Dries Buytaert committed
585
586
587
    while ($count = db_fetch_object($_counts)) {
      $counts[$count->tid] = $count;
    }
Dries Buytaert's avatar
   
Dries Buytaert committed
588
  }
Dries Buytaert's avatar
   
Dries Buytaert committed
589

Dries Buytaert's avatar
   
Dries Buytaert committed
590
591
592
593
  foreach ($_forums as $forum) {
    if (in_array($forum->tid, variable_get('forum_containers', array()))) {
      $forum->container = 1;
    }
Dries Buytaert's avatar
   
Dries Buytaert committed
594

Dries Buytaert's avatar
   
Dries Buytaert committed
595
596
597
598
599
600
601
602
603
604
605
    if ($counts[$forum->tid]) {
      $forum->num_topics = $counts[$forum->tid]->topic_count;
      $forum->num_posts = $counts[$forum->tid]->topic_count + $counts[$forum->tid]->comment_count;
    }
    else {
      $forum->num_topics = 0;
      $forum->num_posts = 0;
    }

    // This query does not use full ANSI syntax since MySQL 3.x does not support
    // table1 INNER JOIN table2 INNER JOIN table3 ON table2_criteria ON table3_criteria
Dries Buytaert's avatar
   
Dries Buytaert committed
606
    // used to join node_comment_statistics to users.
Dries Buytaert's avatar
   
Dries Buytaert committed
607
    $sql = "SELECT n.nid, l.last_comment_timestamp, IF(l.last_comment_uid, cu.name, l.last_comment_name) as last_comment_name, l.last_comment_uid FROM {node} n, {node_comment_statistics} l /*! USE INDEX (node_comment_timestamp) */, {users} cu, {term_node} r WHERE  n.nid = r.nid AND r.tid = %d AND n.status = 1 AND n.type = 'forum' AND l.last_comment_uid = cu.uid AND n.nid = l.nid ORDER BY l.last_comment_timestamp DESC";
608
    $sql = db_rewrite_sql($sql);
Dries Buytaert's avatar
   
Dries Buytaert committed
609
    $topic = db_fetch_object(db_query_range($sql, $forum->tid, 0, 1));
610
611

    $last_post = new StdClass();
Dries Buytaert's avatar
   
Dries Buytaert committed
612
613
614
615
    $last_post->timestamp = $topic->last_comment_timestamp;
    $last_post->name = $topic->last_comment_name;
    $last_post->uid = $topic->last_comment_uid;
    $forum->last_post = $last_post;
Dries Buytaert's avatar
   
Dries Buytaert committed
616

Dries Buytaert's avatar
   
Dries Buytaert committed
617
618
619
620
    $forums[$forum->tid] = $forum;
  }

  return $forums;
Dries Buytaert's avatar
   
Dries Buytaert committed
621
622
}

623
624
625
626
function _forum_topics_read($term, $uid) {
  // Calculate the number of topics the user has read. Assume all entries older
  // than NODE_NEW_LIMIT are read, and include the recent posts that user has
  // read.
Dries Buytaert's avatar
   
Dries Buytaert committed
627
  $sql = "SELECT COUNT(n.nid) FROM {node} n INNER JOIN {term_node} r ON n.nid = r.nid AND r.tid = %d WHERE n.created <= %d AND n.status = 1 AND n.type = 'forum'";
628
  $sql = db_rewrite_sql($sql);
Dries Buytaert's avatar
   
Dries Buytaert committed
629
630
  $ancient = db_result(db_query($sql, $term, NODE_NEW_LIMIT));
  $sql = "SELECT COUNT(n.nid) FROM {node} n INNER JOIN {history} h ON n.nid = h.nid AND h.uid = %d INNER JOIN {term_node} r ON n.nid = r.nid AND r.tid = %d WHERE n.status = 1 AND n.type = 'forum' AND n.created > %d";
631
  $sql = db_rewrite_sql($sql);
Dries Buytaert's avatar
   
Dries Buytaert committed
632
  $recent = db_result(db_query($sql, $uid, $term, NODE_NEW_LIMIT));
Dries Buytaert's avatar
   
Dries Buytaert committed
633

634
  return $ancient + $recent;
Dries Buytaert's avatar
   
Dries Buytaert committed
635
636
}

Dries Buytaert's avatar
Dries Buytaert committed
637
function forum_get_topics($tid, $sortby, $forum_per_page) {
Dries Buytaert's avatar
   
Dries Buytaert committed
638
  global $user, $forum_topic_list_header;
Dries Buytaert's avatar
   
Dries Buytaert committed
639

Dries Buytaert's avatar
   
Dries Buytaert committed
640
  $forum_topic_list_header = array(
Dries Buytaert's avatar
   
Dries Buytaert committed
641
642
    array('data' => '&nbsp;'),
    array('data' => t('Topic'), 'field' => 'n.title'),
Dries Buytaert's avatar
   
Dries Buytaert committed
643
    array('data' => t('Replies'), 'field' => 'l.comment_count'),
Dries Buytaert's avatar
   
Dries Buytaert committed
644
    array('data' => t('Created'), 'field' => 'n.created'),
Dries Buytaert's avatar
   
Dries Buytaert committed
645
    array('data' => t('Last reply'), 'field' => 'l.last_comment_timestamp'),
Dries Buytaert's avatar
   
Dries Buytaert committed
646
  );
Dries Buytaert's avatar
   
Dries Buytaert committed
647

Dries Buytaert's avatar
   
Dries Buytaert committed
648
  $order = _forum_get_topic_order($sortby);
Dries Buytaert's avatar
   
Dries Buytaert committed
649
  for ($i = 0; $i < count($forum_topic_list_header); $i++) {
Dries Buytaert's avatar
   
Dries Buytaert committed
650
651
    if ($forum_topic_list_header[$i]['field'] == $order['field']) {
      $forum_topic_list_header[$i]['sort'] = $order['sort'];
Dries Buytaert's avatar
   
Dries Buytaert committed
652
653
654
655
    }
  }

  $term = taxonomy_get_term($tid);
Dries Buytaert's avatar
   
Dries Buytaert committed
656

657
  $sql = db_rewrite_sql("SELECT n.nid, f.tid, n.title, n.sticky, u.name, u.uid, n.created AS timestamp, n.comment AS comment_mode, l.last_comment_timestamp, IF(l.last_comment_uid, cu.name, l.last_comment_name) AS last_comment_name, l.last_comment_uid, l.comment_count AS num_comments FROM {node} n, {node_comment_statistics} l, {users} cu, {term_node} r, {users} u, {forum} f WHERE n.status = 1 AND l.last_comment_uid = cu.uid AND n.nid = l.nid AND n.nid = r.nid AND r.tid = %d AND n.uid = u.uid AND n.nid = f.nid");
Dries Buytaert's avatar
   
Dries Buytaert committed
658
  $sql .= tablesort_sql($forum_topic_list_header, 'n.sticky DESC,');
Dries Buytaert's avatar
Dries Buytaert committed
659

660
  $sql_count = db_rewrite_sql("SELECT COUNT(n.nid) FROM {node} n INNER JOIN {term_node} r ON n.nid = r.nid AND r.tid = %d WHERE n.status = 1 AND n.type = 'forum'");
Dries Buytaert's avatar
   
Dries Buytaert committed
661

Steven Wittens's avatar
Steven Wittens committed
662
  $result = pager_query($sql, $forum_per_page, 0, $sql_count, $tid);
Dries Buytaert's avatar
   
Dries Buytaert committed
663
664

  while ($topic = db_fetch_object($result)) {
Dries Buytaert's avatar
Dries Buytaert committed
665
666
    if ($user->uid) {
      // folder is new if topic is new or there are new comments since last visit
Dries Buytaert's avatar
   
Dries Buytaert committed
667
      if ($topic->tid != $tid) {
Dries Buytaert's avatar
Dries Buytaert committed
668
        $topic->new = 0;
Dries Buytaert's avatar
   
Dries Buytaert committed
669
670
      }
      else {
Dries Buytaert's avatar
   
Dries Buytaert committed
671
        $history = _forum_user_last_visit($topic->nid);
Dries Buytaert's avatar
   
Dries Buytaert committed
672
        $topic->new_replies = comment_num_new($topic->nid, $history);
673
        $topic->new = $topic->new_replies || ($topic->timestamp > $history);
Dries Buytaert's avatar
   
Dries Buytaert committed
674
      }
675
676
    }
    else {
677
      // Do not track "new replies" status for topics if the user is anonymous.
Dries Buytaert's avatar
Dries Buytaert committed
678
679
      $topic->new_replies = 0;
      $topic->new = 0;
680
    }
Dries Buytaert's avatar
   
Dries Buytaert committed
681

Dries Buytaert's avatar
   
Dries Buytaert committed
682
    if ($topic->num_comments > 0) {
683
      $last_reply = new StdClass();
Dries Buytaert's avatar
   
Dries Buytaert committed
684
685
686
687
688
      $last_reply->timestamp = $topic->last_comment_timestamp;
      $last_reply->name = $topic->last_comment_name;
      $last_reply->uid = $topic->last_comment_uid;
      $topic->last_reply = $last_reply;
    }
Dries Buytaert's avatar
   
Dries Buytaert committed
689
690
691
    $topics[] = $topic;
  }

Dries Buytaert's avatar
Dries Buytaert committed
692
  return $topics;
Dries Buytaert's avatar
   
Dries Buytaert committed
693
694
}

Dries Buytaert's avatar
   
Dries Buytaert committed
695
696
697
/**
 * Finds the first unread node for a given forum.
 */
Dries Buytaert's avatar
Dries Buytaert committed
698
function _forum_new($tid) {
Dries Buytaert's avatar
   
Dries Buytaert committed
699
700
  global $user;

Dries Buytaert's avatar
   
Dries Buytaert committed
701
  $sql = "SELECT n.nid FROM {node} n LEFT JOIN {history} h ON n.nid = h.nid AND h.uid = %d INNER JOIN {term_node} r ON n.nid = r.nid AND r.tid = %d WHERE n.status = 1 AND n.type = 'forum' AND h.nid IS NULL AND n.created > %d ORDER BY created";
702
  $sql = db_rewrite_sql($sql);
Dries Buytaert's avatar
   
Dries Buytaert committed
703
  $nid = db_result(db_query_range($sql, $user->uid, $tid, NODE_NEW_LIMIT, 0, 1));
Dries Buytaert's avatar
   
Dries Buytaert committed
704
705
706
707

  return $nid ? $nid : 0;
}

708
/**
709
 * Menu callback; prints a forum listing.
710
 */
Dries Buytaert's avatar
Dries Buytaert committed
711
function forum_page($tid = 0) {
Dries Buytaert's avatar
   
Dries Buytaert committed
712
  global $user;
Dries Buytaert's avatar
   
Dries Buytaert committed
713

Dries Buytaert's avatar
   
Dries Buytaert committed
714
  if (module_exist('taxonomy')) {
Dries Buytaert's avatar
Dries Buytaert committed
715
716
    $forum_per_page = variable_get('forum_per_page', 25);
    $sortby = variable_get('forum_order', 1);
Dries Buytaert's avatar
   
Dries Buytaert committed
717

Dries Buytaert's avatar
Dries Buytaert committed
718
719
720
721
    $forums = forum_get_forums($tid);
    $parents = taxonomy_get_parents_all($tid);
    if ($tid && !in_array($tid, variable_get('forum_containers', array()))) {
      $topics = forum_get_topics($tid, $sortby, $forum_per_page);
Dries Buytaert's avatar
   
Dries Buytaert committed
722
    }
Dries Buytaert's avatar
Dries Buytaert committed
723

724
    print theme('page', theme('forum_display', $forums, $topics, $parents, $tid, $sortby, $forum_per_page));
Dries Buytaert's avatar
   
Dries Buytaert committed
725
726
  }
  else {
727
728
    drupal_set_title(t('Warning'));
    print theme('page', forum_help('admin/settings/forum'));
Dries Buytaert's avatar
   
Dries Buytaert committed
729
730
731
  }
}

Dries Buytaert's avatar
   
Dries Buytaert committed
732
/**
Dries Buytaert's avatar
   
Dries Buytaert committed
733
734
 * Format the forum body.
 *
Dries Buytaert's avatar
   
Dries Buytaert committed
735
 * @ingroup themeable
Dries Buytaert's avatar
   
Dries Buytaert committed
736
 */
Dries Buytaert's avatar
   
Dries Buytaert committed
737
function theme_forum_display($forums, $topics, $parents, $tid, $sortby, $forum_per_page) {
Dries Buytaert's avatar
   
Dries Buytaert committed
738
  global $user;
Dries Buytaert's avatar
   
Dries Buytaert committed
739
  // forum list, topics list, topic browser and 'add new topic' link
Dries Buytaert's avatar
   
Dries Buytaert committed
740

Dries Buytaert's avatar
   
Dries Buytaert committed
741
  $vocabulary = taxonomy_get_vocabulary(variable_get('forum_nav_vocabulary', ''));
742
  drupal_set_title($title = $vocabulary->name);
Dries Buytaert's avatar
   
Dries Buytaert committed
743

Dries Buytaert's avatar
   
Dries Buytaert committed
744
745
  // Breadcrumb navigation:
  $breadcrumb = array();
Dries Buytaert's avatar
   
Dries Buytaert committed
746
  if ($tid) {
Dries Buytaert's avatar
   
Dries Buytaert committed
747
    $breadcrumb[] = array('path' => 'forum', 'title' => $title);
Dries Buytaert's avatar
   
Dries Buytaert committed
748
  }
Dries Buytaert's avatar
   
Dries Buytaert committed
749
750

  if ($parents) {
Dries Buytaert's avatar
   
Dries Buytaert committed
751
752
    $parents = array_reverse($parents);
    foreach ($parents as $p) {
753
754
      if ($p->tid == $tid) {
        $title = $p->name;
Dries Buytaert's avatar
   
Dries Buytaert committed
755
756
      }
      else {
Dries Buytaert's avatar
   
Dries Buytaert committed
757
        $breadcrumb[] = array('path' => 'forum/'. $p->tid, 'title' => $p->name);
Dries Buytaert's avatar
   
Dries Buytaert committed
758
759
760
      }
    }
  }
Dries Buytaert's avatar
   
Dries Buytaert committed
761
762
  $breadcrumb[] = array('path' => $_GET['q']);
  menu_set_location($breadcrumb);
Dries Buytaert's avatar
   
Dries Buytaert committed
763

Dries Buytaert's avatar
   
Dries Buytaert committed
764
  if (count($forums) || count($parents)) {
765
766
    $output  = '<div id="forum">';
    $output .= '<ul>';
Dries Buytaert's avatar
   
Dries Buytaert committed
767
768
769

    if (module_exist('tracker')) {
      if ($user->uid) {
Dries Buytaert's avatar
   
Dries Buytaert committed
770
        $output .= ' <li>'. l(t('My forum discussions.'), "tracker/$user->uid") .'</li>';
Dries Buytaert's avatar
   
Dries Buytaert committed
771
772
      }

Dries Buytaert's avatar
   
Dries Buytaert committed
773
      $output .= ' <li>'. l(t('Active forum discussions.'), 'tracker') .'</li>';
Dries Buytaert's avatar
   
Dries Buytaert committed
774
775
776
    }

    if (user_access('create forum topics')) {
777
      $output .= '<li>'. l(t('Post new forum topic.'), "node/add/forum/$tid") .'</li>';
Dries Buytaert's avatar
   
Dries Buytaert committed
778
779
    }
    else if ($user->uid) {
780
      $output .= '<li>'. t('You are not allowed to post a new forum topic.') .'</li>';
Dries Buytaert's avatar
   
Dries Buytaert committed
781
782
783
784
    }
    else {
      $output .= '<li>'. t('<a href="%login">Login</a> to post a new forum topic.', array('%login' => url('user/login'))) .'</li>';
    }
785
    $output .= '</ul>';
Dries Buytaert's avatar
   
Dries Buytaert committed
786

Dries Buytaert's avatar
   
Dries Buytaert committed
787
    $output .= theme('forum_list', $forums, $parents, $tid);
Dries Buytaert's avatar
   
Dries Buytaert committed
788

Dries Buytaert's avatar
   
Dries Buytaert committed
789
    if ($tid && !in_array($tid, variable_get('forum_containers', array()))) {
Dries Buytaert's avatar
   
Dries Buytaert committed
790
      $output .= theme('forum_topic_list', $tid, $topics, $sortby, $forum_per_page);
Dries Buytaert's avatar
   
Dries Buytaert committed
791
    }
792
    $output .= '</div>';
Dries Buytaert's avatar
   
Dries Buytaert committed
793
794
  }
  else {
795
    drupal_set_title(t('No forums defined'));
Dries Buytaert's avatar
   
Dries Buytaert committed
796
    $output = '';
Dries Buytaert's avatar
   
Dries Buytaert committed
797
798
  }

799
  return $output;
Dries Buytaert's avatar
   
Dries Buytaert committed
800
801
}

Dries Buytaert's avatar
   
Dries Buytaert committed
802
/**
Dries Buytaert's avatar
   
Dries Buytaert committed
803
804
 * Format the forum listing.
 *
Dries Buytaert's avatar
   
Dries Buytaert committed
805
 * @ingroup themeable
Dries Buytaert's avatar
   
Dries Buytaert committed
806
 */
Dries Buytaert's avatar
   
Dries Buytaert committed
807
function theme_forum_list($forums, $parents, $tid) {
Dries Buytaert's avatar
   
Dries Buytaert committed
808
809
  global $user;

Dries Buytaert's avatar
   
Dries Buytaert committed
810
811
  if ($forums) {

Dries Buytaert's avatar
   
Dries Buytaert committed
812
    $header = array(t('Forum'), t('Topics'), t('Posts'), t('Last post'));
Dries Buytaert's avatar
   
Dries Buytaert committed
813
814

    foreach ($forums as $forum) {
Dries Buytaert's avatar
   
Dries Buytaert committed
815
      if ($forum->container) {
816
817
        $description  = '<div style="margin-left: '. ($forum->depth * 30) ."px;\">\n";
        $description .= ' <div class="name">'. l($forum->name, "forum/$forum->tid") ."</div>\n";
Dries Buytaert's avatar
   
Dries Buytaert committed
818
819
820
821
822
823

        if ($forum->description) {
          $description .= " <div class=\"description\">$forum->description</div>\n";
        }
        $description .= "</div>\n";

Dries Buytaert's avatar
   
Dries Buytaert committed
824
        $rows[] = array(array('data' => $description, 'class' => 'container', 'colspan' => '4'));
825
      }
Dries Buytaert's avatar
   
Dries Buytaert committed
826
      else {
827
        $forum->old_topics = _forum_topics_read($forum->tid, $user->uid);
Dries Buytaert's avatar
   
Dries Buytaert committed
828
829
830
        if ($user->uid) {
          $new_topics = $forum->num_topics - $forum->old_topics;
        }
Dries Buytaert's avatar
   
Dries Buytaert committed
831
832
833
        else {
          $new_topics = 0;
        }
Dries Buytaert's avatar
   
Dries Buytaert committed
834

835
836
        $description  = '<div style="margin-left: '. ($forum->depth * 30) ."px;\">\n";
        $description .= ' <div class="name">'. l($forum->name, "forum/$forum->tid") ."</div>\n";
Dries Buytaert's avatar
   
Dries Buytaert committed
837

Dries Buytaert's avatar
   
Dries Buytaert committed
838
839
840
841
        if ($forum->description) {
          $description .= " <div class=\"description\">$forum->description</div>\n";
        }
        $description .= "</div>\n";
Dries Buytaert's avatar
   
Dries Buytaert committed
842

Dries Buytaert's avatar
   
Dries Buytaert committed
843
        $rows[] = array(
Dries Buytaert's avatar
   
Dries Buytaert committed
844
          array('data' => $description, 'class' => 'forum'),
845
          array('data' => $forum->num_topics . ($new_topics ? '<br />'. l(t('%a new', array('%a' => $new_topics)), "forum/$forum->tid", NULL, NULL, 'new') : ''), 'class' => 'topics'),
Dries Buytaert's avatar
   
Dries Buytaert committed
846
847
          array('data' => $forum->num_posts, 'class' => 'posts'),
          array('data' => _forum_format($forum->last_post), 'class' => 'last-reply'));
Dries Buytaert's avatar
   
Dries Buytaert committed
848
      }
Dries Buytaert's avatar
   
Dries Buytaert committed
849
    }
Dries Buytaert's avatar
   
Dries Buytaert committed
850
851
852

    return theme('table', $header, $rows);

Dries Buytaert's avatar
   
Dries Buytaert committed
853
854
855
856
  }

}

Dries Buytaert's avatar
   
Dries Buytaert committed
857
/**
Dries Buytaert's avatar
   
Dries Buytaert committed
858
859
 * Format the topic listing.
 *
Dries Buytaert's avatar
   
Dries Buytaert committed
860
 * @ingroup themeable
Dries Buytaert's avatar
   
Dries Buytaert committed
861
 */
Dries Buytaert's avatar
   
Dries Buytaert committed
862
863
function theme_forum_topic_list($tid, $topics, $sortby, $forum_per_page) {
  global $forum_topic_list_header;
Dries Buytaert's avatar
   
Dries Buytaert committed
864
865

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

Dries Buytaert's avatar
   
Dries Buytaert committed
867
868
    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
869
      if ($topic->tid != $tid) {
Dries Buytaert's avatar
   
Dries Buytaert committed
870
        $rows[] = array(
Dries Buytaert's avatar
   
Dries Buytaert committed
871
          array('data' => _forum_icon($topic->new, $topic->num_comments, $topic->comment_mode, $topic->sticky), 'class' => 'icon'),
Dries Buytaert's avatar
   
Dries Buytaert committed
872
873
          array('data' => $topic->title, 'class' => 'title'),
          array('data' => l(t('This topic has been moved'), "forum/$topic->tid"), 'colspan' => '3')
Dries Buytaert's avatar
   
Dries Buytaert committed
874
        );
Dries Buytaert's avatar
   
Dries Buytaert committed
875
876
      }
      else {
Dries Buytaert's avatar
   
Dries Buytaert committed
877
        $rows[] = array(
Dries Buytaert's avatar
   
Dries Buytaert committed
878
          array('data' => _forum_icon($topic->new, $topic->num_comments, $topic->comment_mode, $topic->sticky), 'class' => 'icon'),
Dries Buytaert's avatar
   
Dries Buytaert committed
879
880
          array('data' => l($topic->title, "node/$topic->nid"), 'class' => 'topic'),
          array('data' => $topic->num_comments . ($topic->new_replies ? '<br />'. l(t('%a new', array('%a' => $topic->new_replies)), "node/$topic->nid", NULL, NULL, 'new') : ''), 'class' => 'replies'),
Dries Buytaert's avatar
   
Dries Buytaert committed
881
882
          array('data' => _forum_format($topic), 'class' => 'created'),
          array('data' => _forum_format($topic->last_reply), 'class' => 'last-reply')
Dries Buytaert's avatar
   
Dries Buytaert committed
883
        );
Dries Buytaert's avatar
   
Dries Buytaert committed
884
885
886
      }
    }

Dries Buytaert's avatar
   
Dries Buytaert committed
887
888
    if ($pager = theme('pager', NULL, $forum_per_page, 0, tablesort_pager())) {
      $rows[] = array(array('data' => $pager, 'colspan' => '5', 'class' => 'pager'));
Dries Buytaert's avatar
   
Dries Buytaert committed
889
890
    }
  }
Dries Buytaert's avatar
   
Dries Buytaert committed
891

Dries Buytaert's avatar
   
Dries Buytaert committed
892
  $output .= theme('table', $forum_topic_list_header, $rows);
Dries Buytaert's avatar
   
Dries Buytaert committed
893

Dries Buytaert's avatar
   
Dries Buytaert committed
894
895
896
  return $output;
}

Dries Buytaert's avatar
   
Dries Buytaert committed
897
function _forum_icon($new_posts, $num_posts = 0, $comment_mode = 0, $sticky = 0) {
Dries Buytaert's avatar
   
Dries Buytaert committed
898

Dries Buytaert's avatar
   
Dries Buytaert committed
899
  $base_path = variable_get('forum_icon_path', '');
Dries Buytaert's avatar
   
Dries Buytaert committed
900
  if ($base_path) {
Dries Buytaert's avatar
   
Dries Buytaert committed
901
902
    if ($num_posts > variable_get('forum_hot_topic', 15)) {
      $icon = $new_posts ? 'hot-new' : 'hot';
Dries Buytaert's avatar
   
Dries Buytaert committed
903
904
    }
    else {
Dries Buytaert's avatar
   
Dries Buytaert committed
905
      $icon = $new_posts ? 'new' : 'default';
Dries Buytaert's avatar
   
Dries Buytaert committed
906
907
908
    }

    if ($comment_mode == 1) {
Dries Buytaert's avatar
   
Dries Buytaert committed
909
      $icon = 'closed';
Dries Buytaert's avatar
   
Dries Buytaert committed
910
911
    }

Dries Buytaert's avatar
   
Dries Buytaert committed
912
913
914
915
    if ($sticky == 1) {
      $icon = 'sticky';
    }

Dries Buytaert's avatar
   
Dries Buytaert committed
916
    // default
Dries Buytaert's avatar
   
Dries Buytaert committed
917
    $file = "misc/forum-$icon.png";
Dries Buytaert's avatar
   
Dries Buytaert committed
918

Dries Buytaert's avatar
   
Dries Buytaert committed
919
    $output = theme('image', $file);
Dries Buytaert's avatar
   
Dries Buytaert committed
920
921
  }
  else {
Dries Buytaert's avatar
   
Dries Buytaert committed
922
    $output = '&nbsp;';
Dries Buytaert's avatar
   
Dries Buytaert committed
923
  }
Dries Buytaert's avatar
   
Dries Buytaert committed
924
925
926
927
928
929

  if ($new_posts) {
    $output = "<a name=\"new\">$output</a>";
  }

  return $output;
Dries Buytaert's avatar
   
Dries Buytaert committed
930
931
932
933
}

function _forum_user_last_visit($nid) {
  global $user;
934
935
936
  static $history = array();

  if (empty($history)) {
Dries Buytaert's avatar
   
Dries Buytaert committed
937
    $result = db_query('SELECT nid, timestamp FROM {history} WHERE uid = %d', $user->uid);
Dries Buytaert's avatar
   
Dries Buytaert committed
938
    while ($t = db_fetch_object($result)) {
939
      $history[$t->nid] = $t->timestamp > NODE_NEW_LIMIT ? $t->timestamp : NODE_NEW_LIMIT;
Dries Buytaert's avatar
   
Dries Buytaert committed
940
941
    }
  }
942
  return $history[$nid] ? $history[$nid] : NODE_NEW_LIMIT;
Dries Buytaert's avatar
   
Dries Buytaert committed
943
944
945
946
947
}

function _forum_get_topic_order($sortby) {
  switch ($sortby) {
    case 1:
Dries Buytaert's avatar
   
Dries Buytaert committed
948
      return array('field' => 'l.last_comment_timestamp', 'sort' => 'desc');
Dries Buytaert's avatar
   
Dries Buytaert committed
949
950
      break;
    case 2:
Dries Buytaert's avatar
   
Dries Buytaert committed
951
      return array('field' => 'l.last_comment_timestamp', 'sort' => 'asc');
Dries Buytaert's avatar
   
Dries Buytaert committed
952
953
      break;
    case 3:
Dries Buytaert's avatar
   
Dries Buytaert committed
954
      return array('field' => 'l.comment_count', 'sort' => 'desc');
Dries Buytaert's avatar
   
Dries Buytaert committed
955
956
      break;
    case 4:
Dries Buytaert's avatar
   
Dries Buytaert committed
957
      return array('field' => 'l.comment_count', 'sort' => 'asc');
Dries Buytaert's avatar
   
Dries Buytaert committed
958
959
960
961
      break;
  }
}

Dries Buytaert's avatar
   
Dries Buytaert committed
962
963
964
965
966
function _forum_get_topic_order_sql($sortby) {
  $order = _forum_get_topic_order($sortby);
  return $order['field'] .' '. $order['sort'];
}

Dries Buytaert's avatar
   
Dries Buytaert committed
967
?>