Same name and namespace in other branches
  1. 4.7.x modules/forum.module \forum_nodeapi()
  2. 5.x modules/forum/forum.module \forum_nodeapi()

Implementation of hook_nodeapi().

File

modules/forum/forum.module, line 168
Enable threaded discussions about general topics.

Code

function forum_nodeapi(&$node, $op, $teaser = NULL, $page = NULL) {

  // We are going to return if $node->type is not one of the node
  // types assigned to the forum vocabulary.  If forum_nav_vocabulary
  // is undefined or the vocabulary does not exist, it clearly cannot
  // be assigned to $node->type, so return to avoid E_ALL warnings.
  $vid = variable_get('forum_nav_vocabulary', '');
  $vocabulary = taxonomy_vocabulary_load($vid);
  if (empty($vocabulary)) {
    return;
  }

  // Operate only on node types assigned for the forum vocabulary.
  if (!in_array($node->type, $vocabulary->nodes)) {
    return;
  }
  switch ($op) {
    case 'view':
      if ($page && taxonomy_node_get_terms_by_vocabulary($node, $vid) && ($tree = taxonomy_get_tree($vid))) {

        // Get the forum terms from the (cached) tree
        foreach ($tree as $term) {
          $forum_terms[] = $term->tid;
        }
        foreach ($node->taxonomy as $term_id => $term) {
          if (in_array($term_id, $forum_terms)) {
            $node->tid = $term_id;
          }
        }

        // Breadcrumb navigation
        $breadcrumb[] = l(t('Home'), NULL);
        $breadcrumb[] = l($vocabulary->name, 'forum');
        if ($parents = taxonomy_get_parents_all($node->tid)) {
          $parents = array_reverse($parents);
          foreach ($parents as $p) {
            $breadcrumb[] = l($p->name, 'forum/' . $p->tid);
          }
        }
        drupal_set_breadcrumb($breadcrumb);
        if (!$teaser) {
          $node->content['forum_navigation'] = array(
            '#value' => theme('forum_topic_navigation', $node),
            '#weight' => 100,
          );
        }
      }
      break;
    case 'prepare':
      if (empty($node->nid)) {

        // New topic
        $node->taxonomy[arg(3)]->vid = $vid;
        $node->taxonomy[arg(3)]->tid = arg(3);
      }
      break;

    // Check in particular that only a "leaf" term in the associated taxonomy
    // vocabulary is selected, not a "container" term.
    case 'validate':
      if ($node->taxonomy) {

        // Extract the node's proper topic ID.
        $vocabulary = $vid;
        $containers = variable_get('forum_containers', array());
        foreach ($node->taxonomy as $term) {
          if (db_result(db_query('SELECT COUNT(*) FROM {term_data} WHERE tid = %d AND vid = %d', $term, $vocabulary))) {
            if (in_array($term, $containers)) {
              $term = taxonomy_get_term($term);
              form_set_error('taxonomy', t('The item %forum is only a container for forums. Please select one of the forums below it.', array(
                '%forum' => $term->name,
              )));
            }
          }
        }
      }
      break;

    // Assign forum taxonomy when adding a topic from within a forum.
    case 'presave':

      // Make sure all fields are set properly:
      $node->icon = !empty($node->icon) ? $node->icon : '';
      if ($node->taxonomy && ($tree = taxonomy_get_tree($vid))) {

        // Get the forum terms from the (cached) tree if we have a taxonomy.
        foreach ($tree as $term) {
          $forum_terms[] = $term->tid;
        }
        foreach ($node->taxonomy as $term_id) {
          if (in_array($term_id, $forum_terms)) {
            $node->tid = $term_id;
          }
        }
        $old_tid = db_result(db_query_range("SELECT f.tid FROM {forum} f INNER JOIN {node} n ON f.vid = n.vid WHERE n.nid = %d ORDER BY f.vid DESC", $node->nid, 0, 1));
        if ($old_tid && isset($node->tid) && $node->tid != $old_tid && !empty($node->shadow)) {

          // A shadow copy needs to be created. Retain new term and add old term.
          $node->taxonomy[] = $old_tid;
        }
      }
      break;
    case 'update':
      if (empty($node->revision) && db_result(db_query('SELECT tid FROM {forum} WHERE nid=%d', $node->nid))) {
        if (!empty($node->tid)) {
          db_query('UPDATE {forum} SET tid = %d WHERE vid = %d', $node->tid, $node->vid);
        }
        else {
          db_query('DELETE FROM {forum} WHERE nid = %d', $node->nid);
        }
        break;
      }

    // Deliberate no break -- for new revisions and for previously unassigned terms we need an insert.
    case 'insert':
      if (!empty($node->tid)) {
        db_query('INSERT INTO {forum} (tid, vid, nid) VALUES (%d, %d, %d)', $node->tid, $node->vid, $node->nid);
      }
      break;
    case 'delete':
      db_query('DELETE FROM {forum} WHERE nid = %d', $node->nid);
      break;
    case 'load':
      return db_fetch_array(db_query('SELECT tid AS forum_tid FROM {forum} WHERE vid = %d', $node->vid));
  }
  return;
}