forum.module 31.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
17
18
19
    case 'admin/forum':
      return t('Forums and containers are used to organize the threaded discussions.  Forums may be nested in each other.  A container is used to group like forums together with out allowing topics to be created in the container.  Containers can be nested just like forums.  To delete a forum or container choose the appropriate "edit" operation.');
    case 'admin/forum/add/container':
      return t('When creating a contianer you are creating a group to contain multiple forums.  Users are not able to create topic inside container.  You can nest containers inside forums or other containers.');
    case 'admin/forum/add/forum':
      return t('When creating a forum you are creating an area for user to create similar topics for discussion. Forums may be nested underneath other forums or in containers.');
Dries Buytaert's avatar
   
Dries Buytaert committed
20
    case 'admin/modules#description':
21
      return t('Enable threaded discussions about general topics.');
Dries Buytaert's avatar
   
Dries Buytaert committed
22
    case 'node/add#forum':
23
      return t('A forum is a threaded discussion, enabling users to communicate about a particular topic.');
Dries Buytaert's avatar
   
Dries Buytaert committed
24
25
26
  }
}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

  return form($form);
}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

  return $vid;
}

/**
 * Implementation of hook_settings
 */
function forum_settings() {
  $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.'));

  return $output;
}

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

  return $forum;
}

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

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

311
312
313
    case 'save':
      variable_set('forum_block_num', $edit['forum_block_num']);
      break;
Dries Buytaert's avatar
   
Dries Buytaert committed
314

315
316
    case 'view':
      if (user_access('access content')) {
Dries Buytaert's avatar
   
Dries Buytaert committed
317
        $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";
318
        $sql = db_rewrite_sql($sql);
Dries Buytaert's avatar
   
Dries Buytaert committed
319
        $content  = node_title_list(db_query_range($sql, 0, variable_get('forum_block_num', '5')), t('Active forum topics:'));
Dries Buytaert's avatar
   
Dries Buytaert committed
320

Dries Buytaert's avatar
   
Dries Buytaert committed
321
        $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";
322
        $sql = db_rewrite_sql($sql);
Dries Buytaert's avatar
   
Dries Buytaert committed
323
        $content .= node_title_list(db_query_range($sql, 0, variable_get('forum_block_num', '5')), t('New forum topics:'));
Dries Buytaert's avatar
   
Dries Buytaert committed
324

325
326
327
328
329
330
331
332
333
334
        if ($content) {
          $content .= '<div class="more-link">'. l(t('more'), 'forum', array('title' => t('Read the latest forum topics.'))) .'</div>';
        }

        $block['subject'] = t('Forum topics');
        $block['content'] = $content;

        return $block;
      }
  }
Dries Buytaert's avatar
   
Dries Buytaert committed
335
336
}

Dries Buytaert's avatar
   
Dries Buytaert committed
337
338
339
/**
 * Implementation of hook_link().
 */
340
function forum_link($type, $node = 0, $main = 0) {
Dries Buytaert's avatar
Dries Buytaert committed
341
  global $user;
Dries Buytaert's avatar
   
Dries Buytaert committed
342

Dries Buytaert's avatar
   
Dries Buytaert committed
343
344
  $links = array();

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

Steven Wittens's avatar
Steven Wittens committed
348
    $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));
349
    $sql = db_rewrite_sql($sql);
Dries Buytaert's avatar
   
Dries Buytaert committed
350
    $result = db_query($sql, $node->tid);
Dries Buytaert's avatar
   
Dries Buytaert committed
351
352
353

    while ($topic = db_fetch_object($result)) {
      if ($stop == 1) {
354
        $next = new StdClass();
Dries Buytaert's avatar
   
Dries Buytaert committed
355
356
357
358
359
360
361
362
        $next->nid = $topic->nid;
        $next->title = $topic->title;
        break;
      }
      if ($topic->nid == $node->nid) {
        $stop = 1;
      }
      else {
363
        $prev = new StdClass();
Dries Buytaert's avatar
   
Dries Buytaert committed
364
365
366
367
368
369
        $prev->nid = $topic->nid;
        $prev->title = $topic->title;
      }
    }

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

    if ($next) {
Dries Buytaert's avatar
   
Dries Buytaert committed
374
      $links[] = l(t('next forum topic'), "node/$next->nid", array('title' => $next->title));
Dries Buytaert's avatar
   
Dries Buytaert committed
375
    }
Dries Buytaert's avatar
   
Dries Buytaert committed
376
377
  }

Dries Buytaert's avatar
   
Dries Buytaert committed
378
  return $links;
Dries Buytaert's avatar
   
Dries Buytaert committed
379
380
}

Dries Buytaert's avatar
   
Dries Buytaert committed
381
382
383
/**
 * Implementation of hook_menu().
 */
Dries Buytaert's avatar
   
Dries Buytaert committed
384
function forum_menu($may_cache) {
Dries Buytaert's avatar
   
Dries Buytaert committed
385
386
  $items = array();

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

Dries Buytaert's avatar
   
Dries Buytaert committed
391
392
393
    $items[] = array('path' => 'forum', 'title' => t('forums'),
      'callback' => 'forum_page',
      'access' => user_access('access content'),
394
      'type' => MENU_SUGGESTED_ITEM);
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410

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

Dries Buytaert's avatar
   
Dries Buytaert committed
411
  }
Dries Buytaert's avatar
   
Dries Buytaert committed
412
413
414
415

  return $items;
}

416
417
418
/**
 * Implementation of hook_view().
 */
Dries Buytaert's avatar
   
Dries Buytaert committed
419
function forum_view(&$node, $teaser = FALSE, $page = FALSE) {
Dries Buytaert's avatar
   
Dries Buytaert committed
420

Dries Buytaert's avatar
   
Dries Buytaert committed
421
  if ($page) {
Dries Buytaert's avatar
   
Dries Buytaert committed
422
    $vocabulary = taxonomy_get_vocabulary(variable_get('forum_nav_vocabulary', ''));
Dries Buytaert's avatar
   
Dries Buytaert committed
423
    // Breadcrumb navigation
Dries Buytaert's avatar
   
Dries Buytaert committed
424
425
    $breadcrumb = array();
    $breadcrumb[] = array('path' => 'forum', 'title' => $vocabulary->name);
Dries Buytaert's avatar
   
Dries Buytaert committed
426
    if ($parents = taxonomy_get_parents_all($node->tid)) {
Dries Buytaert's avatar
   
Dries Buytaert committed
427
428
      $parents = array_reverse($parents);
      foreach ($parents as $p) {
Dries Buytaert's avatar
   
Dries Buytaert committed
429
        $breadcrumb[] = array('path' => 'forum/'. $p->tid, 'title' => $p->name);
Dries Buytaert's avatar
   
Dries Buytaert committed
430
431
      }
    }
Dries Buytaert's avatar
   
Dries Buytaert committed
432
433
    $breadcrumb[] = array('path' => 'node/'. $node->nid);
    menu_set_location($breadcrumb);
434
  }
Dries Buytaert's avatar
   
Dries Buytaert committed
435

436
  $node = node_prepare($node, $teaser);
Dries Buytaert's avatar
   
Dries Buytaert committed
437
438
}

439
440
441
442
443
444
/**
 * Implementation of hook_validate().
 *
 * Check in particular that only a "leaf" term in the associated taxonomy
 * vocabulary is selected, not a "container" term.
 */
445
446
function forum_validate(&$node) {
  // Make sure all fields are set properly:
Dries Buytaert's avatar
   
Dries Buytaert committed
447
  $node->icon = $node->icon ? $node->icon : '';
Dries Buytaert's avatar
   
Dries Buytaert committed
448
449
450

  if ($node->taxonomy) {
    // Extract the node's proper topic ID.
Dries Buytaert's avatar
   
Dries Buytaert committed
451
    $vocabulary = variable_get('forum_nav_vocabulary', '');
452
    $containers = variable_get('forum_containers', array());
Dries Buytaert's avatar
   
Dries Buytaert committed
453
    foreach ($node->taxonomy as $term) {
Dries Buytaert's avatar
   
Dries Buytaert committed
454
      if (db_result(db_query('SELECT COUNT(*) FROM {term_data} WHERE tid = %d AND vid = %d', $term, $vocabulary))) {
455
456
        if (in_array($term, $containers)) {
          $term = taxonomy_get_term($term);
Dries Buytaert's avatar
   
Dries Buytaert committed
457
          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>")));
458
459
460
461
        }
        else {
          $node->tid = $term;
        }
Dries Buytaert's avatar
   
Dries Buytaert committed
462
      }
463
    }
Dries Buytaert's avatar
   
Dries Buytaert committed
464
465
466
467
468
469
470
    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
471
472
473
  }
}

Dries Buytaert's avatar
   
Dries Buytaert committed
474
475
476
477
478
479
480
/**
 * Implementation of hook_update().
 */
function forum_update($node) {
  db_query('UPDATE {forum} SET tid = %d WHERE nid = %d', $node->tid, $node->nid);
}

481
482
483
/**
 * Implementation of hook_form().
 */
Dries Buytaert's avatar
   
Dries Buytaert committed
484
function forum_form(&$node) {
Dries Buytaert's avatar
   
Dries Buytaert committed
485
  if (!$node->nid) {
Dries Buytaert's avatar
Dries Buytaert committed
486
    // new topic
Dries Buytaert's avatar
   
Dries Buytaert committed
487
    $node->taxonomy[] = arg(3);
488
  }
Dries Buytaert's avatar
   
Dries Buytaert committed
489
490
491
  else {
    $node->taxonomy = array($node->tid);
  }
492

Dries Buytaert's avatar
   
Dries Buytaert committed
493
  $output = implode('', taxonomy_node_form('forum', $node));
Dries Buytaert's avatar
Dries Buytaert committed
494
495
496

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

501
  $output .= form_textarea(t('Body'), 'body', $node->body, 60, 20, '');
502
  $output .= filter_form('format', $node->format);
Dries Buytaert's avatar
   
Dries Buytaert committed
503
504
505
506

  return $output;
}

507
508
509
/**
 * Implementation of hook_insert().
 */
Dries Buytaert's avatar
   
Dries Buytaert committed
510
function forum_insert($node) {
Dries Buytaert's avatar
   
Dries Buytaert committed
511
  db_query('INSERT INTO {forum} (nid, tid) VALUES (%d, %d)', $node->nid, $node->tid);
Dries Buytaert's avatar
   
Dries Buytaert committed
512
513
}

514
515
516
/**
 * Implementation of hook_delete().
 */
Dries Buytaert's avatar
   
Dries Buytaert committed
517
function forum_delete(&$node) {
Dries Buytaert's avatar
   
Dries Buytaert committed
518
  db_query('DELETE FROM {forum} WHERE nid = %d', $node->nid);
Dries Buytaert's avatar
   
Dries Buytaert committed
519
}
Dries Buytaert's avatar
   
Dries Buytaert committed
520

Dries Buytaert's avatar
   
Dries Buytaert committed
521
522
523
/**
 * Formats a topic for display
 *
524
 * @TODO Give a better description. Not sure where this function is used yet.
Dries Buytaert's avatar
   
Dries Buytaert committed
525
 */
Dries Buytaert's avatar
   
Dries Buytaert committed
526
function _forum_format($topic) {
527
  if ($topic && $topic->timestamp) {
Dries Buytaert's avatar
   
Dries Buytaert committed
528
    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
529
530
531
532
533
534
  }
  else {
    return message_na();
  }
}

Dries Buytaert's avatar
   
Dries Buytaert committed
535
536
537
/**
 * Returns a list of all forums for a given taxonomy id
 *
538
 * Forum objects contain the following fields
Dries Buytaert's avatar
   
Dries Buytaert committed
539
540
541
542
543
544
545
546
547
 * -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
548
function forum_get_forums($tid = 0) {
549

Dries Buytaert's avatar
   
Dries Buytaert committed
550
551
552
553
  if (!$tid) {
    $tid = 0;
  }

Dries Buytaert's avatar
   
Dries Buytaert committed
554
555
  $forums = array();
  $_forums = taxonomy_get_tree(variable_get('forum_nav_vocabulary', ''), $tid);
Dries Buytaert's avatar
   
Dries Buytaert committed
556

Dries Buytaert's avatar
   
Dries Buytaert committed
557
  if (count($_forums)) {
Dries Buytaert's avatar
   
Dries Buytaert committed
558

Dries Buytaert's avatar
   
Dries Buytaert committed
559
560
    $counts = array();

Dries Buytaert's avatar
   
Dries Buytaert committed
561
    $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";
562
    $sql = db_rewrite_sql($sql);
Dries Buytaert's avatar
   
Dries Buytaert committed
563
    $_counts = db_query($sql, $forum->tid);
Dries Buytaert's avatar
   
Dries Buytaert committed
564
565
566
    while ($count = db_fetch_object($_counts)) {
      $counts[$count->tid] = $count;
    }
Dries Buytaert's avatar
   
Dries Buytaert committed
567
  }
Dries Buytaert's avatar
   
Dries Buytaert committed
568

Dries Buytaert's avatar
   
Dries Buytaert committed
569
570
571
572
  foreach ($_forums as $forum) {
    if (in_array($forum->tid, variable_get('forum_containers', array()))) {
      $forum->container = 1;
    }
Dries Buytaert's avatar
   
Dries Buytaert committed
573

Dries Buytaert's avatar
   
Dries Buytaert committed
574
575
576
577
578
579
580
581
582
583
584
    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
585
    // used to join node_comment_statistics to users.
Dries Buytaert's avatar
   
Dries Buytaert committed
586
    $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";
587
    $sql = db_rewrite_sql($sql);
Dries Buytaert's avatar
   
Dries Buytaert committed
588
    $topic = db_fetch_object(db_query_range($sql, $forum->tid, 0, 1));
589
590

    $last_post = new StdClass();
Dries Buytaert's avatar
   
Dries Buytaert committed
591
592
593
594
    $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
595

Dries Buytaert's avatar
   
Dries Buytaert committed
596
597
598
599
    $forums[$forum->tid] = $forum;
  }

  return $forums;
Dries Buytaert's avatar
   
Dries Buytaert committed
600
601
}

602
603
604
605
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
606
  $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'";
607
  $sql = db_rewrite_sql($sql);
Dries Buytaert's avatar
   
Dries Buytaert committed
608
609
  $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";
610
  $sql = db_rewrite_sql($sql);
Dries Buytaert's avatar
   
Dries Buytaert committed
611
  $recent = db_result(db_query($sql, $uid, $term, NODE_NEW_LIMIT));
Dries Buytaert's avatar
   
Dries Buytaert committed
612

613
  return $ancient + $recent;
Dries Buytaert's avatar
   
Dries Buytaert committed
614
615
}

Dries Buytaert's avatar
Dries Buytaert committed
616
function forum_get_topics($tid, $sortby, $forum_per_page) {
Dries Buytaert's avatar
   
Dries Buytaert committed
617
  global $user, $forum_topic_list_header;
Dries Buytaert's avatar
   
Dries Buytaert committed
618

Dries Buytaert's avatar
   
Dries Buytaert committed
619
  $forum_topic_list_header = array(
Dries Buytaert's avatar
   
Dries Buytaert committed
620
621
    array('data' => '&nbsp;'),
    array('data' => t('Topic'), 'field' => 'n.title'),
Dries Buytaert's avatar
   
Dries Buytaert committed
622
    array('data' => t('Replies'), 'field' => 'l.comment_count'),
Dries Buytaert's avatar
   
Dries Buytaert committed
623
    array('data' => t('Created'), 'field' => 'n.created'),
Dries Buytaert's avatar
   
Dries Buytaert committed
624
    array('data' => t('Last reply'), 'field' => 'l.last_comment_timestamp'),
Dries Buytaert's avatar
   
Dries Buytaert committed
625
  );
Dries Buytaert's avatar
   
Dries Buytaert committed
626

Dries Buytaert's avatar
   
Dries Buytaert committed
627
  $order = _forum_get_topic_order($sortby);
Dries Buytaert's avatar
   
Dries Buytaert committed
628
  for ($i = 0; $i < count($forum_topic_list_header); $i++) {
Dries Buytaert's avatar
   
Dries Buytaert committed
629
630
    if ($forum_topic_list_header[$i]['field'] == $order['field']) {
      $forum_topic_list_header[$i]['sort'] = $order['sort'];
Dries Buytaert's avatar
   
Dries Buytaert committed
631
632
633
634
    }
  }

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

636
  $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
637
  $sql .= tablesort_sql($forum_topic_list_header, 'n.sticky DESC,');
Dries Buytaert's avatar
Dries Buytaert committed
638

639
  $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
640

Steven Wittens's avatar
Steven Wittens committed
641
  $result = pager_query($sql, $forum_per_page, 0, $sql_count, $tid);
Dries Buytaert's avatar
   
Dries Buytaert committed
642
643

  while ($topic = db_fetch_object($result)) {
Dries Buytaert's avatar
Dries Buytaert committed
644
645
    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
646
      if ($topic->tid != $tid) {
Dries Buytaert's avatar
Dries Buytaert committed
647
        $topic->new = 0;
Dries Buytaert's avatar
   
Dries Buytaert committed
648
649
      }
      else {
Dries Buytaert's avatar
   
Dries Buytaert committed
650
        $history = _forum_user_last_visit($topic->nid);
Dries Buytaert's avatar
   
Dries Buytaert committed
651
        $topic->new_replies = comment_num_new($topic->nid, $history);
652
        $topic->new = $topic->new_replies || ($topic->timestamp > $history);
Dries Buytaert's avatar
   
Dries Buytaert committed
653
      }
654
655
    }
    else {
656
      // Do not track "new replies" status for topics if the user is anonymous.
Dries Buytaert's avatar
Dries Buytaert committed
657
658
      $topic->new_replies = 0;
      $topic->new = 0;
659
    }
Dries Buytaert's avatar
   
Dries Buytaert committed
660

Dries Buytaert's avatar
   
Dries Buytaert committed
661
    if ($topic->num_comments > 0) {
662
      $last_reply = new StdClass();
Dries Buytaert's avatar
   
Dries Buytaert committed
663
664
665
666
667
      $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
668
669
670
    $topics[] = $topic;
  }

Dries Buytaert's avatar
Dries Buytaert committed
671
  return $topics;
Dries Buytaert's avatar
   
Dries Buytaert committed
672
673
}

Dries Buytaert's avatar
   
Dries Buytaert committed
674
675
676
/**
 * Finds the first unread node for a given forum.
 */
Dries Buytaert's avatar
Dries Buytaert committed
677
function _forum_new($tid) {
Dries Buytaert's avatar
   
Dries Buytaert committed
678
679
  global $user;

Dries Buytaert's avatar
   
Dries Buytaert committed
680
  $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";
681
  $sql = db_rewrite_sql($sql);
Dries Buytaert's avatar
   
Dries Buytaert committed
682
  $nid = db_result(db_query_range($sql, $user->uid, $tid, NODE_NEW_LIMIT, 0, 1));
Dries Buytaert's avatar
   
Dries Buytaert committed
683
684
685
686

  return $nid ? $nid : 0;
}

687
/**
688
 * Menu callback; prints a forum listing.
689
 */
Dries Buytaert's avatar
Dries Buytaert committed
690
function forum_page($tid = 0) {
Dries Buytaert's avatar
   
Dries Buytaert committed
691
  global $user;
Dries Buytaert's avatar
   
Dries Buytaert committed
692

Dries Buytaert's avatar
   
Dries Buytaert committed
693
  if (module_exist('taxonomy')) {
Dries Buytaert's avatar
Dries Buytaert committed
694
695
    $forum_per_page = variable_get('forum_per_page', 25);
    $sortby = variable_get('forum_order', 1);
Dries Buytaert's avatar
   
Dries Buytaert committed
696

Dries Buytaert's avatar
Dries Buytaert committed
697
698
699
700
    $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
701
    }
Dries Buytaert's avatar
Dries Buytaert committed
702

703
    print theme('page', theme('forum_display', $forums, $topics, $parents, $tid, $sortby, $forum_per_page));
Dries Buytaert's avatar
   
Dries Buytaert committed
704
705
  }
  else {
706
707
    drupal_set_title(t('Warning'));
    print theme('page', forum_help('admin/settings/forum'));
Dries Buytaert's avatar
   
Dries Buytaert committed
708
709
710
  }
}

Dries Buytaert's avatar
   
Dries Buytaert committed
711
/**
Dries Buytaert's avatar
   
Dries Buytaert committed
712
713
 * Format the forum body.
 *
Dries Buytaert's avatar
   
Dries Buytaert committed
714
 * @ingroup themeable
Dries Buytaert's avatar
   
Dries Buytaert committed
715
 */
Dries Buytaert's avatar
   
Dries Buytaert committed
716
function theme_forum_display($forums, $topics, $parents, $tid, $sortby, $forum_per_page) {
Dries Buytaert's avatar
   
Dries Buytaert committed
717
  global $user;
Dries Buytaert's avatar
   
Dries Buytaert committed
718
  // forum list, topics list, topic browser and 'add new topic' link
Dries Buytaert's avatar
   
Dries Buytaert committed
719

Dries Buytaert's avatar
   
Dries Buytaert committed
720
  $vocabulary = taxonomy_get_vocabulary(variable_get('forum_nav_vocabulary', ''));
721
  drupal_set_title($title = $vocabulary->name);
Dries Buytaert's avatar
   
Dries Buytaert committed
722

Dries Buytaert's avatar
   
Dries Buytaert committed
723
724
  // Breadcrumb navigation:
  $breadcrumb = array();
Dries Buytaert's avatar
   
Dries Buytaert committed
725
  if ($tid) {
Dries Buytaert's avatar
   
Dries Buytaert committed
726
    $breadcrumb[] = array('path' => 'forum', 'title' => $title);
Dries Buytaert's avatar
   
Dries Buytaert committed
727
  }
Dries Buytaert's avatar
   
Dries Buytaert committed
728
729

  if ($parents) {
Dries Buytaert's avatar
   
Dries Buytaert committed
730
731
    $parents = array_reverse($parents);
    foreach ($parents as $p) {
732
733
      if ($p->tid == $tid) {
        $title = $p->name;
Dries Buytaert's avatar
   
Dries Buytaert committed
734
735
      }
      else {
Dries Buytaert's avatar
   
Dries Buytaert committed
736
        $breadcrumb[] = array('path' => 'forum/'. $p->tid, 'title' => $p->name);
Dries Buytaert's avatar
   
Dries Buytaert committed
737
738
739
      }
    }
  }
Dries Buytaert's avatar
   
Dries Buytaert committed
740
741
  $breadcrumb[] = array('path' => $_GET['q']);
  menu_set_location($breadcrumb);
Dries Buytaert's avatar
   
Dries Buytaert committed
742

Dries Buytaert's avatar
   
Dries Buytaert committed
743
  if (count($forums) || count($parents)) {
744
745
    $output  = '<div id="forum">';
    $output .= '<ul>';
Dries Buytaert's avatar
   
Dries Buytaert committed
746
747
748

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

Dries Buytaert's avatar
   
Dries Buytaert committed
752
      $output .= ' <li>'. l(t('Active forum discussions.'), 'tracker') .'</li>';
Dries Buytaert's avatar
   
Dries Buytaert committed
753
754
755
    }

    if (user_access('create forum topics')) {
756
      $output .= '<li>'. l(t('Post new forum topic.'), "node/add/forum/$tid") .'</li>';
Dries Buytaert's avatar
   
Dries Buytaert committed
757
758
    }
    else if ($user->uid) {
759
      $output .= '<li>'. t('You are not allowed to post a new forum topic.') .'</li>';
Dries Buytaert's avatar
   
Dries Buytaert committed
760
761
762
763
    }
    else {
      $output .= '<li>'. t('<a href="%login">Login</a> to post a new forum topic.', array('%login' => url('user/login'))) .'</li>';
    }
764
    $output .= '</ul>';
Dries Buytaert's avatar
   
Dries Buytaert committed
765

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

Dries Buytaert's avatar
   
Dries Buytaert committed
768
    if ($tid && !in_array($tid, variable_get('forum_containers', array()))) {
Dries Buytaert's avatar
   
Dries Buytaert committed
769
      $output .= theme('forum_topic_list', $tid, $topics, $sortby, $forum_per_page);
Dries Buytaert's avatar
   
Dries Buytaert committed
770
    }
771
    $output .= '</div>';
Dries Buytaert's avatar
   
Dries Buytaert committed
772
773
  }
  else {
774
    drupal_set_title(t('No forums defined'));
Dries Buytaert's avatar
   
Dries Buytaert committed
775
    $output = '';
Dries Buytaert's avatar
   
Dries Buytaert committed
776
777
  }

778
  return $output;
Dries Buytaert's avatar
   
Dries Buytaert committed
779
780
}

Dries Buytaert's avatar
   
Dries Buytaert committed
781
/**
Dries Buytaert's avatar
   
Dries Buytaert committed
782
783
 * Format the forum listing.
 *
Dries Buytaert's avatar
   
Dries Buytaert committed
784
 * @ingroup themeable
Dries Buytaert's avatar
   
Dries Buytaert committed
785
 */
Dries Buytaert's avatar
   
Dries Buytaert committed
786
function theme_forum_list($forums, $parents, $tid) {
Dries Buytaert's avatar
   
Dries Buytaert committed
787
788
  global $user;

Dries Buytaert's avatar
   
Dries Buytaert committed
789
790
  if ($forums) {

Dries Buytaert's avatar
   
Dries Buytaert committed
791
    $header = array(t('Forum'), t('Topics'), t('Posts'), t('Last post'));
Dries Buytaert's avatar
   
Dries Buytaert committed
792
793

    foreach ($forums as $forum) {
Dries Buytaert's avatar
   
Dries Buytaert committed
794
      if ($forum->container) {
795
796
        $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
797
798
799
800
801
802

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

Dries Buytaert's avatar
   
Dries Buytaert committed
803
        $rows[] = array(array('data' => $description, 'class' => 'container', 'colspan' => '4'));
804
      }
Dries Buytaert's avatar
   
Dries Buytaert committed
805
      else {
806
        $forum->old_topics = _forum_topics_read($forum->tid, $user->uid);
Dries Buytaert's avatar
   
Dries Buytaert committed
807
808
809
        if ($user->uid) {
          $new_topics = $forum->num_topics - $forum->old_topics;
        }
Dries Buytaert's avatar
   
Dries Buytaert committed
810
811
812
        else {
          $new_topics = 0;
        }
Dries Buytaert's avatar
   
Dries Buytaert committed
813

814
815
        $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
816

Dries Buytaert's avatar
   
Dries Buytaert committed
817
818
819
820
        if ($forum->description) {
          $description .= " <div class=\"description\">$forum->description</div>\n";
        }
        $description .= "</div>\n";
Dries Buytaert's avatar
   
Dries Buytaert committed
821

Dries Buytaert's avatar
   
Dries Buytaert committed
822
        $rows[] = array(
Dries Buytaert's avatar
   
Dries Buytaert committed
823
          array('data' => $description, 'class' => 'forum'),
824
          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
825
826
          array('data' => $forum->num_posts, 'class' => 'posts'),
          array('data' => _forum_format($forum->last_post), 'class' => 'last-reply'));
Dries Buytaert's avatar
   
Dries Buytaert committed
827
      }
Dries Buytaert's avatar
   
Dries Buytaert committed
828
    }
Dries Buytaert's avatar
   
Dries Buytaert committed
829
830
831

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

Dries Buytaert's avatar
   
Dries Buytaert committed
832
833
834
835
  }

}

Dries Buytaert's avatar
   
Dries Buytaert committed
836
/**
Dries Buytaert's avatar
   
Dries Buytaert committed
837
838
 * Format the topic listing.
 *
Dries Buytaert's avatar
   
Dries Buytaert committed
839
 * @ingroup themeable
Dries Buytaert's avatar
   
Dries Buytaert committed
840
 */
Dries Buytaert's avatar
   
Dries Buytaert committed
841
842
function theme_forum_topic_list($tid, $topics, $sortby, $forum_per_page) {
  global $forum_topic_list_header;
Dries Buytaert's avatar
   
Dries Buytaert committed
843
844

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

Dries Buytaert's avatar
   
Dries Buytaert committed
846
847
    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
848
      if ($topic->tid != $tid) {
Dries Buytaert's avatar
   
Dries Buytaert committed
849
        $rows[] = array(
Dries Buytaert's avatar
   
Dries Buytaert committed
850
          array('data' => _forum_icon($topic->new, $topic->num_comments, $topic->comment_mode, $topic->sticky), 'class' => 'icon'),
Dries Buytaert's avatar
   
Dries Buytaert committed
851
852
          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
853
        );
Dries Buytaert's avatar
   
Dries Buytaert committed
854
855
      }
      else {
Dries Buytaert's avatar
   
Dries Buytaert committed
856
        $rows[] = array(
Dries Buytaert's avatar
   
Dries Buytaert committed
857
          array('data' => _forum_icon($topic->new, $topic->num_comments, $topic->comment_mode, $topic->sticky), 'class' => 'icon'),
Dries Buytaert's avatar
   
Dries Buytaert committed
858
859
          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
860
861
          array('data' => _forum_format($topic), 'class' => 'created'),
          array('data' => _forum_format($topic->last_reply), 'class' => 'last-reply')
Dries Buytaert's avatar
   
Dries Buytaert committed
862
        );
Dries Buytaert's avatar
   
Dries Buytaert committed
863
864
865
      }
    }

Dries Buytaert's avatar
   
Dries Buytaert committed
866
867
    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
868
869
    }
  }
Dries Buytaert's avatar
   
Dries Buytaert committed
870

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

Dries Buytaert's avatar
   
Dries Buytaert committed
873
874
875
  return $output;
}

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

Dries Buytaert's avatar
   
Dries Buytaert committed
878
  $base_path = variable_get('forum_icon_path', '');
Dries Buytaert's avatar
   
Dries Buytaert committed
879
  if ($base_path) {
Dries Buytaert's avatar
   
Dries Buytaert committed
880
881
    if ($num_posts > variable_get('forum_hot_topic', 15)) {
      $icon = $new_posts ? 'hot-new' : 'hot';
Dries Buytaert's avatar
   
Dries Buytaert committed
882
883
    }
    else {
Dries Buytaert's avatar
   
Dries Buytaert committed
884
      $icon = $new_posts ? 'new' : 'default';
Dries Buytaert's avatar
   
Dries Buytaert committed
885
886
887
    }

    if ($comment_mode == 1) {
Dries Buytaert's avatar
   
Dries Buytaert committed
888
      $icon = 'closed';
Dries Buytaert's avatar
   
Dries Buytaert committed
889
890
    }

Dries Buytaert's avatar
   
Dries Buytaert committed
891
892
893
894
    if ($sticky == 1) {
      $icon = 'sticky';
    }

Dries Buytaert's avatar
   
Dries Buytaert committed
895
    // default
Dries Buytaert's avatar
   
Dries Buytaert committed
896
    $file = "misc/forum-$icon.png";
Dries Buytaert's avatar
   
Dries Buytaert committed
897

Dries Buytaert's avatar
   
Dries Buytaert committed
898
    $output = theme('image', $file);
Dries Buytaert's avatar
   
Dries Buytaert committed
899
900
  }
  else {
Dries Buytaert's avatar
   
Dries Buytaert committed
901
    $output = '&nbsp;';
Dries Buytaert's avatar
   
Dries Buytaert committed
902
  }
Dries Buytaert's avatar
   
Dries Buytaert committed
903
904
905
906
907
908

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

  return $output;
Dries Buytaert's avatar
   
Dries Buytaert committed
909
910
911
912
}

function _forum_user_last_visit($nid) {
  global $user;
913
914
915
  static $history = array();

  if (empty($history)) {
Dries Buytaert's avatar
   
Dries Buytaert committed
916
    $result = db_query('SELECT nid, timestamp FROM {history} WHERE uid = %d', $user->uid);
Dries Buytaert's avatar
   
Dries Buytaert committed
917
    while ($t = db_fetch_object($result)) {
918
      $history[$t->nid] = $t->timestamp > NODE_NEW_LIMIT ? $t->timestamp : NODE_NEW_LIMIT;
Dries Buytaert's avatar
   
Dries Buytaert committed
919
920
    }
  }
921
  return $history[$nid] ? $history[$nid] : NODE_NEW_LIMIT;
Dries Buytaert's avatar
   
Dries Buytaert committed
922
923
924
925
926
}

function _forum_get_topic_order($sortby) {
  switch ($sortby) {
    case 1:
Dries Buytaert's avatar
   
Dries Buytaert committed
927
      return array('field' => 'l.last_comment_timestamp', 'sort' => 'desc');
Dries Buytaert's avatar
   
Dries Buytaert committed
928
929
      break;
    case 2:
Dries Buytaert's avatar
   
Dries Buytaert committed
930
      return array('field' => 'l.last_comment_timestamp', 'sort' => 'asc');
Dries Buytaert's avatar
   
Dries Buytaert committed
931
932
      break;
    case 3:
Dries Buytaert's avatar
   
Dries Buytaert committed
933
      return array('field' => 'l.comment_count', 'sort' => 'desc');
Dries Buytaert's avatar
   
Dries Buytaert committed
934
935
      break;
    case 4:
Dries Buytaert's avatar
   
Dries Buytaert committed
936
      return array('field' => 'l.comment_count', 'sort' => 'asc');
Dries Buytaert's avatar
   
Dries Buytaert committed
937
938
939
940
      break;
  }
}

Dries Buytaert's avatar
   
Dries Buytaert committed
941
942
943
944
945
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
946
?>