forum.module 32.2 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
    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':
17
      return t('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.');
18
19
    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
  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 Buytaert's avatar
   
Dries Buytaert committed
119
    }
120
121
  }
}
Dries Buytaert's avatar
   
Dries Buytaert 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 Buytaert's avatar
   
Dries Buytaert committed
211
212
    }
  }
Dries Buytaert's avatar
   
Dries Buytaert committed
213

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

  return form_select($title, $name, $parents, $options, NULL, 0, FALSE, TRUE);
Dries Buytaert's avatar
   
Dries Buytaert 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 Buytaert's avatar
Dries Buytaert committed
237
    }
238
239

    return theme('table', $header, $rows);
Dries Buytaert's avatar
Dries Buytaert 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 Buytaert's avatar
   
Dries Buytaert committed
294
function forum_load($node) {
Dries Buytaert's avatar
   
Dries Buytaert committed
295
  $forum = db_fetch_object(db_query('SELECT * FROM {forum} WHERE nid = %d', $node->nid));
Dries Buytaert's avatar
   
Dries Buytaert 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 Buytaert's avatar
   
Dries Buytaert committed
309
310
      $blocks[0]['info'] = t('Active forum topics');
      $blocks[1]['info'] = t('New forum topics');
311
      return $blocks;
Dries Buytaert's avatar
   
Dries Buytaert 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 Buytaert's avatar
   
Dries Buytaert committed
316

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

321
322
    case 'view':
      if (user_access('access content')) {
Dries Buytaert's avatar
   
Dries Buytaert 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 Buytaert's avatar
   
Dries Buytaert 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 Buytaert's avatar
   
Dries Buytaert committed
335
        }
Dries Buytaert's avatar
   
Dries Buytaert 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 Buytaert's avatar
   
Dries Buytaert committed
341
        $block['subject'] = $title;
342
343
344
345
346
        $block['content'] = $content;

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

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

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

Dries Buytaert's avatar
   
Dries Buytaert committed
357
  if (!$main && $type == 'node' && $node->type == 'forum') {
Dries Buytaert's avatar
   
Dries Buytaert 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 Buytaert's avatar
   
Dries Buytaert committed
362
    $result = db_query($sql, $node->tid);
Dries Buytaert's avatar
   
Dries Buytaert committed
363
364
365

    while ($topic = db_fetch_object($result)) {
      if ($stop == 1) {
366
        $next = new StdClass();
Dries Buytaert's avatar
   
Dries Buytaert 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 Buytaert's avatar
   
Dries Buytaert committed
376
377
378
379
380
381
        $prev->nid = $topic->nid;
        $prev->title = $topic->title;
      }
    }

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

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

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

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

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

  return $items;
}

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

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

458
  $node = node_prepare($node, $teaser);
Dries Buytaert's avatar
   
Dries Buytaert 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 Buytaert's avatar
   
Dries Buytaert committed
469
  $node->icon = $node->icon ? $node->icon : '';
Dries Buytaert's avatar
   
Dries Buytaert committed
470
471
472

  if ($node->taxonomy) {
    // Extract the node's proper topic ID.
Dries Buytaert's avatar
   
Dries Buytaert committed
473
    $vocabulary = variable_get('forum_nav_vocabulary', '');
474
    $containers = variable_get('forum_containers', array());
Dries Buytaert's avatar
   
Dries Buytaert committed
475
    foreach ($node->taxonomy as $term) {
Dries Buytaert's avatar
   
Dries Buytaert 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 Buytaert's avatar
   
Dries Buytaert 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 Buytaert's avatar
   
Dries Buytaert committed
484
      }
485
    }
Dries Buytaert's avatar
   
Dries Buytaert 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 Buytaert's avatar
Dries Buytaert committed
493
494
495
  }
}

Dries Buytaert's avatar
   
Dries Buytaert 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 Buytaert's avatar
   
Dries Buytaert committed
506
function forum_form(&$node) {
Dries Buytaert's avatar
   
Dries Buytaert committed
507
  if (!$node->nid) {
Dries Buytaert's avatar
Dries Buytaert committed
508
    // new topic
Dries Buytaert's avatar
   
Dries Buytaert committed
509
    $node->taxonomy[] = arg(3);
510
  }
Dries Buytaert's avatar
   
Dries Buytaert committed
511
512
513
  else {
    $node->taxonomy = array($node->tid);
  }
514

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

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

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

  return $output;
}

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

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

Dries Buytaert's avatar
   
Dries Buytaert committed
543
544
545
/**
 * Formats a topic for display
 *
546
 * @TODO Give a better description. Not sure where this function is used yet.
Dries Buytaert's avatar
   
Dries Buytaert committed
547
 */
Dries Buytaert's avatar
   
Dries Buytaert committed
548
function _forum_format($topic) {
549
  if ($topic && $topic->timestamp) {
Dries Buytaert's avatar
   
Dries Buytaert committed
550
    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
551
552
553
554
555
556
  }
  else {
    return message_na();
  }
}

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

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

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

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

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

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

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

Dries Buytaert's avatar
   
Dries Buytaert 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 Buytaert's avatar
   
Dries Buytaert committed
607
    // used to join node_comment_statistics to users.
Dries Buytaert's avatar
   
Dries Buytaert 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 Buytaert's avatar
   
Dries Buytaert committed
610
    $topic = db_fetch_object(db_query_range($sql, $forum->tid, 0, 1));
611
612

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

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

  return $forums;
Dries Buytaert's avatar
   
Dries Buytaert 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 Buytaert's avatar
   
Dries Buytaert 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 Buytaert's avatar
   
Dries Buytaert 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 Buytaert's avatar
   
Dries Buytaert committed
633
  $recent = db_result(db_query($sql, $uid, $term, NODE_NEW_LIMIT));
Dries Buytaert's avatar
   
Dries Buytaert committed
634

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

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

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

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

  $term = taxonomy_get_term($tid);
Dries Buytaert's avatar
   
Dries Buytaert 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 Buytaert's avatar
   
Dries Buytaert committed
659
  $sql .= tablesort_sql($forum_topic_list_header, 'n.sticky DESC,');
Dries Buytaert's avatar
Dries Buytaert 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 Buytaert's avatar
   
Dries Buytaert committed
662

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

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

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

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

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

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

  return $nid ? $nid : 0;
}

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

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

Dries Buytaert's avatar
Dries Buytaert 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 Buytaert's avatar
   
Dries Buytaert committed
723
    }
Dries Buytaert's avatar
Dries Buytaert committed
724

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    foreach ($forums as $forum) {
Dries Buytaert's avatar
   
Dries Buytaert committed
816
      if ($forum->container) {
817
818
        $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
819
820
821
822
823
824

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

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

836
837
        $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
838

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

Dries Buytaert's avatar
   
Dries Buytaert committed
844
        $rows[] = array(
Dries Buytaert's avatar
   
Dries Buytaert committed
845
          array('data' => $description, 'class' => 'forum'),
846
          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
847
848
          array('data' => $forum->num_posts, 'class' => 'posts'),
          array('data' => _forum_format($forum->last_post), 'class' => 'last-reply'));
Dries Buytaert's avatar
   
Dries Buytaert committed
849
      }
Dries Buytaert's avatar
   
Dries Buytaert committed
850
    }
Dries Buytaert's avatar
   
Dries Buytaert committed
851
852
853

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

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

}

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

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

Dries Buytaert's avatar
   
Dries Buytaert committed
868
869
    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
870
      if ($topic->tid != $tid) {
Dries Buytaert's avatar
   
Dries Buytaert committed
871
        $rows[] = array(
Dries Buytaert's avatar
   
Dries Buytaert committed
872
          array('data' => _forum_icon($topic->new, $topic->num_comments, $topic->comment_mode, $topic->sticky), 'class' => 'icon'),
Dries Buytaert's avatar
   
Dries Buytaert committed
873
874
          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
875
        );
Dries Buytaert's avatar
   
Dries Buytaert committed
876
877
      }
      else {
Dries Buytaert's avatar
   
Dries Buytaert committed
878
        $rows[] = array(
Dries Buytaert's avatar
   
Dries Buytaert committed
879
          array('data' => _forum_icon($topic->new, $topic->num_comments, $topic->comment_mode, $topic->sticky), 'class' => 'icon'),
Dries Buytaert's avatar
   
Dries Buytaert committed
880
881
          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
882
883
          array('data' => _forum_format($topic), 'class' => 'created'),
          array('data' => _forum_format($topic->last_reply), 'class' => 'last-reply')
Dries Buytaert's avatar
   
Dries Buytaert committed
884
        );
Dries Buytaert's avatar
   
Dries Buytaert committed
885
886
887
      }
    }

Dries Buytaert's avatar
   
Dries Buytaert committed
888
889
    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
890
891
    }
  }
Dries Buytaert's avatar
   
Dries Buytaert committed
892

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

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

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

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

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

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

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

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

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

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

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

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

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

Dries Buytaert's avatar
   
Dries Buytaert committed
963
964
965
966
967
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
968
?>