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

Dries's avatar
   
Dries 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's avatar
   
Dries committed
13
  switch ($section) {
14
    case 'admin/forum':
15
      return t('<p>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.</p>');
16
    case 'admin/forum/add/container':
17
      return t('<p>Containers help you organize your forum. The job of a container is to hold, or contain, other forums that have something in common. Containers are usually placed at the top level (root) of your forum but you can also place a container within another container or forum.</p>');
18
    case 'admin/forum/add/forum':
19
      return t('<p>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.</p>');
Dries's avatar
   
Dries committed
20
    case 'admin/modules#description':
21
      return t('Enable threaded discussions about general topics.');
Dries's avatar
   
Dries committed
22
    case 'node/add#forum':
23
      return t('A forum is a threaded discussion, enabling users to communicate about a particular topic.');
Dries's avatar
   
Dries committed
24
25
26
  }
}

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

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

Dries's avatar
   
Dries committed
40
41
  if ($op == 'create') {
    return user_access('create forum topics');
Dries's avatar
   
Dries committed
42
  }
Dries's avatar
   
Dries 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's avatar
   
Dries committed
49
50
}

51
52
53
/**
 * Implementation of hook_perm().
 */
Dries's avatar
   
Dries committed
54
function forum_perm() {
55
  return array('create forum topics', 'edit own forum topics', 'administer forums');
Dries's avatar
   
Dries committed
56
}
Dries's avatar
   
Dries 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's avatar
   
Dries committed
68

69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
  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']) {
88
        $output = _forum_confirm_delete($edit['tid']);
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
        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's avatar
   
Dries committed
119
    }
120
121
  }
}
Dries's avatar
   
Dries committed
122

123
124
125
126
127
/**
 * Returns a confirmation page for deleting a forum taxonomy term
 *
 * @param $tid ID of the term to be deleted
 */
128
function _forum_confirm_delete($tid) {
129
130
131
132
133
134
135
136
137
138
  $term = taxonomy_get_term($tid);

  $extra = form_hidden('tid', $tid);
  $output = theme('confirm',
                  t('Are you sure you want to delete the forum %name?', array('%name' => '<em>'. $term->name .'</em>')),
                  'admin/forums',
                  t('Deleting a forum or container will delete all sub-forums as well. This action cannot be undone.'),
                  t('Delete'),
                  t('Cancel'),
                  $extra);
139
  return $output;
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
179
180
181
}

/**
 * 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']);
  }
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
208
209
210
  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's avatar
   
Dries committed
211
212
    }
  }
Dries's avatar
   
Dries committed
213

214
215
216
217
218
  if (!$parents) {
    $parents = 0;
  }

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

221
/**
222
 * Returns an overview list of existing forums and contianers
223
 */
224
225
226
227
228
229
230
231
232
233
234
235
236
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's avatar
Dries committed
237
    }
238
239

    return theme('table', $header, $rows);
Dries's avatar
Dries committed
240
241
242
  }
}

243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
/**
 * 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) {
265
      $vocabulary = taxonomy_save_vocabulary(array('name' => 'Forums', 'multiple' => 0, 'required' => 1, 'hierarchy' => 1, 'relations' => 0, 'module' => 'forum', 'nodes' => array('forum')));
266
267
268
269
270
271
272
273
274
275
276
      $vid = $vocabulary['vid'];
    }
    variable_set('forum_nav_vocabulary', $vid);
  }

  return $vid;
}

/**
 * Implementation of hook_settings
 */
277
278
279
function forum_admin_configure() {
  system_settings_save();

280
281
282
283
284
285
286
287
  $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.'));

288
  print theme('page', system_settings_form($output));
289
290
}

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

  return $forum;
}

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

313
    case 'configure':
314
      $output = form_select(t('Number of topics'), 'forum_block_num_'. $delta, variable_get('forum_block_num_'. $delta, '5'), drupal_map_assoc(array(2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20)));
315
      return $output;
Dries's avatar
   
Dries committed
316

317
    case 'save':
318
      variable_set('forum_block_num_'. $delta, $edit['forum_block_num_'. $delta]);
319
      break;
Dries's avatar
   
Dries committed
320

321
322
    case 'view':
      if (user_access('access content')) {
Dries's avatar
   
Dries committed
323
324
        switch ($delta) {
          case 0:
325
326
327
328
            $title = t('Active forum topics');
            $sql = db_rewrite_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");
            $content = node_title_list(db_query_range($sql, 0, variable_get('forum_block_num_0', '5')));
            break;
Dries's avatar
   
Dries committed
329
330

          case 1:
331
332
333
334
            $title = t('New forum topics');
            $sql = db_rewrite_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");
            $content = node_title_list(db_query_range($sql, 0, variable_get('forum_block_num_1', '5')));
            break;
Dries's avatar
   
Dries committed
335
        }
Dries's avatar
   
Dries committed
336

337
338
339
340
        if ($content) {
          $content .= '<div class="more-link">'. l(t('more'), 'forum', array('title' => t('Read the latest forum topics.'))) .'</div>';
        }

Dries's avatar
   
Dries committed
341
        $block['subject'] = $title;
342
343
344
345
346
        $block['content'] = $content;

        return $block;
      }
  }
Dries's avatar
   
Dries committed
347
348
}

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

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

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

Steven Wittens's avatar
Steven Wittens committed
360
    $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));
361
    $sql = db_rewrite_sql($sql);
Dries's avatar
   
Dries committed
362
    $result = db_query($sql, $node->tid);
Dries's avatar
   
Dries committed
363
364
365

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

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

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

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

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

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

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

    $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);
422
423
424
425
    $items[] = array('path' => 'admin/forum/configure', 'title' => t('configure'),
      'callback' => 'forum_admin_configure',
      'access' => user_access('administer forums'),
      'type' => MENU_LOCAL_TASK);
426
427
428
429
430
431
432

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

  return $items;
}

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

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

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

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

  if ($node->taxonomy) {
    // Extract the node's proper topic ID.
Dries's avatar
   
Dries committed
473
    $vocabulary = variable_get('forum_nav_vocabulary', '');
474
    $containers = variable_get('forum_containers', array());
Dries's avatar
   
Dries committed
475
    foreach ($node->taxonomy as $term) {
Dries's avatar
   
Dries committed
476
      if (db_result(db_query('SELECT COUNT(*) FROM {term_data} WHERE tid = %d AND vid = %d', $term, $vocabulary))) {
477
478
        if (in_array($term, $containers)) {
          $term = taxonomy_get_term($term);
Dries's avatar
   
Dries committed
479
          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>")));
480
481
482
483
        }
        else {
          $node->tid = $term;
        }
Dries's avatar
   
Dries committed
484
      }
485
    }
Dries's avatar
   
Dries committed
486
487
488
489
490
491
492
    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's avatar
Dries committed
493
494
495
  }
}

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

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

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

  if ($node->nid) {
    // if editing, give option to leave shadows
Dries's avatar
   
Dries committed
519
520
    $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's avatar
Dries committed
521
  }
Dries's avatar
   
Dries committed
522

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

  return $output;
}

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

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

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

Dries's avatar
   
Dries committed
557
558
559
/**
 * Returns a list of all forums for a given taxonomy id
 *
560
 * Forum objects contain the following fields
Dries's avatar
   
Dries committed
561
562
563
564
565
566
567
568
569
 * -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's avatar
   
Dries committed
570
function forum_get_forums($tid = 0) {
571

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

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

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

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

Dries's avatar
   
Dries committed
583
    $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";
584
    $sql = db_rewrite_sql($sql);
Dries's avatar
   
Dries committed
585
    $_counts = db_query($sql, $forum->tid);
Dries's avatar
   
Dries committed
586
587
588
    while ($count = db_fetch_object($_counts)) {
      $counts[$count->tid] = $count;
    }
Dries's avatar
   
Dries committed
589
  }
Dries's avatar
   
Dries committed
590

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

Dries's avatar
   
Dries committed
596
597
598
599
600
601
602
603
604
605
606
    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's avatar
   
Dries committed
607
    // used to join node_comment_statistics to users.
Dries's avatar
   
Dries committed
608
    $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";
609
    $sql = db_rewrite_sql($sql);
Dries's avatar
   
Dries committed
610
    $topic = db_fetch_object(db_query_range($sql, $forum->tid, 0, 1));
611
612

    $last_post = new StdClass();
Dries's avatar
   
Dries committed
613
614
615
616
    $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's avatar
   
Dries committed
617

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

  return $forums;
Dries's avatar
   
Dries committed
622
623
}

624
625
626
627
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's avatar
   
Dries committed
628
  $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'";
629
  $sql = db_rewrite_sql($sql);
Dries's avatar
   
Dries committed
630
631
  $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";
632
  $sql = db_rewrite_sql($sql);
Dries's avatar
   
Dries committed
633
  $recent = db_result(db_query($sql, $uid, $term, NODE_NEW_LIMIT));
Dries's avatar
   
Dries committed
634

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

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

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

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

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

658
  $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's avatar
   
Dries committed
659
  $sql .= tablesort_sql($forum_topic_list_header, 'n.sticky DESC,');
Dries's avatar
Dries committed
660

661
  $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's avatar
   
Dries committed
662

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

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

Dries's avatar
   
Dries committed
683
    if ($topic->num_comments > 0) {
684
      $last_reply = new StdClass();
Dries's avatar
   
Dries committed
685
686
687
688
689
      $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's avatar
   
Dries committed
690
691
692
    $topics[] = $topic;
  }

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

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

Dries's avatar
   
Dries committed
702
  $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";
703
  $sql = db_rewrite_sql($sql);
Dries's avatar
   
Dries committed
704
  $nid = db_result(db_query_range($sql, $user->uid, $tid, NODE_NEW_LIMIT, 0, 1));
Dries's avatar
   
Dries committed
705
706
707
708

  return $nid ? $nid : 0;
}

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

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

Dries's avatar
Dries committed
719
720
721
722
    $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's avatar
   
Dries committed
723
    }
Dries's avatar
Dries committed
724

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

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

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

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

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

  drupal_set_title($title);

Dries's avatar
   
Dries committed
765
766
  $breadcrumb[] = array('path' => $_GET['q']);
  menu_set_location($breadcrumb);
Dries's avatar
   
Dries committed
767

Dries's avatar
   
Dries committed
768
  if (count($forums) || count($parents)) {
769
770
    $output  = '<div id="forum">';
    $output .= '<ul>';
Dries's avatar
   
Dries committed
771
772
773

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

Dries's avatar
   
Dries committed
777
      $output .= ' <li>'. l(t('Active forum discussions.'), 'tracker') .'</li>';
Dries's avatar
   
Dries committed
778
779
780
    }

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

Dries's avatar
   
Dries committed
791
    $output .= theme('forum_list', $forums, $parents, $tid);
Dries's avatar
   
Dries committed
792

Dries's avatar
   
Dries committed
793
    if ($tid && !in_array($tid, variable_get('forum_containers', array()))) {
Dries's avatar
   
Dries committed
794
795
      drupal_set_html_head('<link rel="alternate" type="application/rss+xml" title="RSS - '. $title .'" href="'. url('taxonomy/term/'. $tid .'/0/feed') .'" />');

Dries's avatar
   
Dries committed
796
      $output .= theme('forum_topic_list', $tid, $topics, $sortby, $forum_per_page);
Dries's avatar
   
Dries committed
797
      $output .= theme('xml_icon', url("taxonomy/term/$tid/0/feed"));
Dries's avatar
   
Dries committed
798
    }
799
    $output .= '</div>';
Dries's avatar
   
Dries committed
800
801
  }
  else {
802
    drupal_set_title(t('No forums defined'));
Dries's avatar
   
Dries committed
803
    $output = '';
Dries's avatar
   
Dries committed
804
805
  }

806
  return $output;
Dries's avatar
   
Dries committed
807
808
}

Dries's avatar
   
Dries committed
809
/**
Dries's avatar
   
Dries committed
810
811
 * Format the forum listing.
 *
Dries's avatar
   
Dries committed
812
 * @ingroup themeable
Dries's avatar
   
Dries committed
813
 */
Dries's avatar
   
Dries committed
814
function theme_forum_list($forums, $parents, $tid) {
Dries's avatar
   
Dries committed
815
816
  global $user;

Dries's avatar
   
Dries committed
817
818
  if ($forums) {

Dries's avatar
   
Dries committed
819
    $header = array(t('Forum'), t('Topics'), t('Posts'), t('Last post'));
Dries's avatar
   
Dries committed
820
821

    foreach ($forums as $forum) {
Dries's avatar
   
Dries committed
822
      if ($forum->container) {
823
824
        $description  = '<div style="margin-left: '. ($forum->depth * 30) ."px;\">\n";
        $description .= ' <div class="name">'. l($forum->name, "forum/$forum->tid") ."</div>\n";
Dries's avatar
   
Dries committed
825
826
827
828
829
830

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

Dries's avatar
   
Dries committed
831
        $rows[] = array(array('data' => $description, 'class' => 'container', 'colspan' => '4'));
832
      }
Dries's avatar
   
Dries committed
833
      else {
834
        $forum->old_topics = _forum_topics_read($forum->tid, $user->uid);
Dries's avatar
   
Dries committed
835
836
837
        if ($user->uid) {
          $new_topics = $forum->num_topics - $forum->old_topics;
        }
Dries's avatar
   
Dries committed
838
839
840
        else {
          $new_topics = 0;
        }
Dries's avatar
   
Dries committed
841

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

Dries's avatar
   
Dries committed
845
846
847
848
        if ($forum->description) {
          $description .= " <div class=\"description\">$forum->description</div>\n";
        }
        $description .= "</div>\n";
Dries's avatar
   
Dries committed
849

Dries's avatar
   
Dries committed
850
        $rows[] = array(
Dries's avatar
   
Dries committed
851
          array('data' => $description, 'class' => 'forum'),
852
          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's avatar
   
Dries committed
853
854
          array('data' => $forum->num_posts, 'class' => 'posts'),
          array('data' => _forum_format($forum->last_post), 'class' => 'last-reply'));
Dries's avatar
   
Dries committed
855
      }
Dries's avatar
   
Dries committed
856
    }
Dries's avatar
   
Dries committed
857
858
859

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

Dries's avatar
   
Dries committed
860
861
862
863
  }

}

Dries's avatar
   
Dries committed
864
/**
Dries's avatar
   
Dries committed
865
866
 * Format the topic listing.
 *
Dries's avatar
   
Dries committed
867
 * @ingroup themeable
Dries's avatar
   
Dries committed
868
 */
Dries's avatar
   
Dries committed
869
870
function theme_forum_topic_list($tid, $topics, $sortby, $forum_per_page) {
  global $forum_topic_list_header;
Dries's avatar
   
Dries committed
871
872

  if ($topics) {
Dries's avatar
   
Dries committed
873

Dries's avatar
   
Dries committed
874
875
    foreach ($topics as $topic) {
      // folder is new if topic is new or there are new comments since last visit
Dries's avatar
Dries committed
876
      if ($topic->tid != $tid) {
Dries's avatar
   
Dries committed
877
        $rows[] = array(
Dries's avatar
   
Dries committed
878
          array('data' => _forum_icon($topic->new, $topic->num_comments, $topic->comment_mode, $topic->sticky), 'class' => 'icon'),
Dries's avatar
   
Dries committed
879
880
          array('data' => $topic->title, 'class' => 'title'),
          array('data' => l(t('This topic has been moved'), "forum/$topic->tid"), 'colspan' => '3')
Dries's avatar
   
Dries committed
881
        );
Dries's avatar
   
Dries committed
882
883
      }
      else {
Dries's avatar
   
Dries committed
884
        $rows[] = array(
Dries's avatar
   
Dries committed
885
          array('data' => _forum_icon($topic->new, $topic->num_comments, $topic->comment_mode, $topic->sticky), 'class' => 'icon'),
Dries's avatar
   
Dries committed
886
887
          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's avatar
   
Dries committed
888
889
          array('data' => _forum_format($topic), 'class' => 'created'),
          array('data' => _forum_format($topic->last_reply), 'class' => 'last-reply')
Dries's avatar
   
Dries committed
890
        );
Dries's avatar
   
Dries committed
891
892
893
      }
    }

Dries's avatar
   
Dries committed
894
895
    if ($pager = theme('pager', NULL, $forum_per_page, 0, tablesort_pager())) {
      $rows[] = array(array('data' => $pager, 'colspan' => '5', 'class' => 'pager'));
Dries's avatar
   
Dries committed
896
897
    }
  }
Dries's avatar
   
Dries committed
898

Dries's avatar
   
Dries committed
899
  $output .= theme('table', $forum_topic_list_header, $rows);
Dries's avatar
   
Dries committed
900

Dries's avatar
   
Dries committed
901
902
903
  return $output;
}

Dries's avatar
   
Dries committed
904
function _forum_icon($new_posts, $num_posts = 0, $comment_mode = 0, $sticky = 0) {
Dries's avatar
   
Dries committed
905

Dries's avatar
   
Dries committed
906
  $base_path = variable_get('forum_icon_path', '');
Dries's avatar
   
Dries committed
907
  if ($base_path) {
Dries's avatar
   
Dries committed
908
909
    if ($num_posts > variable_get('forum_hot_topic', 15)) {
      $icon = $new_posts ? 'hot-new' : 'hot';
Dries's avatar
   
Dries committed
910
911
    }
    else {
Dries's avatar
   
Dries committed
912
      $icon = $new_posts ? 'new' : 'default';
Dries's avatar
   
Dries committed
913
914
915
    }

    if ($comment_mode == 1) {
Dries's avatar
   
Dries committed
916
      $icon = 'closed';
Dries's avatar
   
Dries committed
917
918
    }

Dries's avatar
   
Dries committed
919
920
921
922
    if ($sticky == 1) {
      $icon = 'sticky';
    }

Dries's avatar
   
Dries committed
923
    // default
Dries's avatar
   
Dries committed
924
    $file = "misc/forum-$icon.png";
Dries's avatar
   
Dries committed
925

Dries's avatar
   
Dries committed
926
    $output = theme('image', $file);
Dries's avatar
   
Dries committed
927
928
  }
  else {
Dries's avatar
   
Dries committed
929
    $output = '&nbsp;';
Dries's avatar
   
Dries committed
930
  }
Dries's avatar
   
Dries committed
931
932
933
934
935
936

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

  return $output;
Dries's avatar
   
Dries committed
937
938
939
940
}

function _forum_user_last_visit($nid) {
  global $user;
941
942
943
  static $history = array();

  if (empty($history)) {
Dries's avatar
   
Dries committed
944
    $result = db_query('SELECT nid, timestamp FROM {history} WHERE uid = %d', $user->uid);
Dries's avatar
   
Dries committed
945
    while ($t = db_fetch_object($result)) {
946
      $history[$t->nid] = $t->timestamp > NODE_NEW_LIMIT ? $t->timestamp : NODE_NEW_LIMIT;
Dries's avatar
   
Dries committed
947
948
    }
  }
949
  return $history[$nid] ? $history[$nid] : NODE_NEW_LIMIT;
Dries's avatar
   
Dries committed
950
951
952
953
954
}

function _forum_get_topic_order($sortby) {
  switch ($sortby) {
    case 1:
Dries's avatar
   
Dries committed
955
      return array('field' => 'l.last_comment_timestamp', 'sort' => 'desc');
Dries's avatar
   
Dries committed
956
957
      break;
    case 2:
Dries's avatar
   
Dries committed
958
      return array('field' => 'l.last_comment_timestamp', 'sort' => 'asc');
Dries's avatar
   
Dries committed
959
960
      break;
    case 3:
Dries's avatar
   
Dries committed
961
      return array('field' => 'l.comment_count', 'sort' => 'desc');
Dries's avatar
   
Dries committed
962
963
      break;
    case 4:
Dries's avatar
   
Dries committed
964
      return array('field' => 'l.comment_count', 'sort' => 'asc');
Dries's avatar
   
Dries committed
965
966
967
968
      break;
  }
}

Dries's avatar
   
Dries committed
969
970
971
972
973
function _forum_get_topic_order_sql($sortby) {
  $order = _forum_get_topic_order($sortby);
  return $order['field'] .' '. $order['sort'];
}

Dries's avatar
   
Dries committed
974
?>