Skip to content
taxonomy.module 34.1 KiB
Newer Older
Dries Buytaert's avatar
Dries Buytaert committed
<?php
Kjartan Mannes's avatar
Kjartan Mannes committed
// $Id$
Dries Buytaert's avatar
 
Dries Buytaert committed

function taxonomy_system($field){
  $system["description"] = t("Enables the organization of content into categories.");
Dries Buytaert's avatar
 
Dries Buytaert committed
function taxonomy_feed($taxonomy) {
  global $id, $type;
Dries Buytaert's avatar
 
Dries Buytaert committed

Kjartan Mannes's avatar
Kjartan Mannes committed
  if ($type == "voc") {
Dries Buytaert's avatar
 
Dries Buytaert committed
    //TODO - vocabulary feed.
Kjartan Mannes's avatar
Kjartan Mannes committed
  }
  else {
Dries Buytaert's avatar
 
Dries Buytaert committed
    $result = taxonomy_select_nodes($taxonomy, 0);
    $term = taxonomy_get_term($taxonomy->tids[0]);
Dries Buytaert's avatar
 
Dries Buytaert committed
    $channel["link"] = url("taxonomy/view/$taxonomy->operator/$taxonomy->str_tids");
Kjartan Mannes's avatar
Kjartan Mannes committed
    $channel["title"] = variable_get("site_name", "drupal") ." - ". $term->name;
    $channel["description"] = $term->description;
    node_feed($result, $channel);
Dries Buytaert's avatar
 
Dries Buytaert committed
  }
Kjartan Mannes's avatar
Kjartan Mannes committed
}
Dries Buytaert's avatar
 
Dries Buytaert committed

Kjartan Mannes's avatar
Kjartan Mannes committed
function taxonomy_perm() {
  return array("administer taxonomy");
}
Dries Buytaert's avatar
Dries Buytaert committed

Dries Buytaert's avatar
 
Dries Buytaert committed
function taxonomy_link($type, $node = NULL) {
Kjartan Mannes's avatar
Kjartan Mannes committed
  if ($type == "admin" && user_access("administer taxonomy")) {
Dries Buytaert's avatar
 
Dries Buytaert committed
    $help["taxonomy"] = t("The taxonomy module allows you to classify content into categories and subcategories; it allows multiple lists of categories for classification (controlled vocabularies) and offers the possibility of creating thesauri (controlled vocabularies that indicate the relationship of terms) and taxonomies (controlled vocabularies where relationships are indicated hierarchically). To delete a term choose \"edit term\". To delete a vocabulary, and all its terms, choose \"edit vocabulary\".");
    $help["vocabulary"] = t("When you create a controlled vocabulary you are creating a set of terms to use for describing content (known as descriptors in indexing lingo).  Drupal allows you to describe each node type (blog, story, etc.) using one or many of these terms. For simple implementations, you might create a set of categories without subcategories, similar to Slashdot.org's or Kuro5hin.org's sections. For more complex implementations, you might create a hierarchical list of categories.");
Dries Buytaert's avatar
Dries Buytaert committed

Dries Buytaert's avatar
 
Dries Buytaert committed
    menu("admin/taxonomy", "taxonomy", "taxonomy_admin", $help["taxonomy"], 3);
    menu("admin/taxonomy/add/vocabulary", "create new vocabulary", "taxonomy_admin", $help["vocabulary"]);
Dries Buytaert's avatar
 
Dries Buytaert committed
    menu("admin/taxonomy/help", "help", "taxonomy_admin", NULL, 9);
Dries Buytaert's avatar
 
Dries Buytaert committed
  }
Dries Buytaert's avatar
 
Dries Buytaert committed
  else if ($type == "taxonomy terms" && $node != NULL) {
Dries Buytaert's avatar
 
Dries Buytaert committed

    if ($node->taxonomy) {
      foreach ($node->taxonomy as $tid) {
        $term = taxonomy_get_term($tid);
        $links[] = l($term->name, "taxonomy/page/or/$term->tid", $term->description ? array("title" => $term->description) : array());
      }
    }
    else {

Dries Buytaert's avatar
 
Dries Buytaert committed
    /*
    ** Themes can print taxonomy links with:
    **
    ** if (module_exist("taxonomy")) {
    **   $this->links(taxonomy_link("taxonomy terms", $node));
    ** }
    */

Dries Buytaert's avatar
 
Dries Buytaert committed
      $links = array();
      foreach (taxonomy_node_get_terms($node->nid) as $term) {
        $links[] = l($term->name, "taxonomy/page/or/$term->tid", $term->description ? array("title" => $term->description) : array());
      }
Dries Buytaert's avatar
 
Dries Buytaert committed

    }
    return $links;
  }
Dries Buytaert's avatar
Dries Buytaert committed
/*
** admin pages (form, save, overview)
*/

Kjartan Mannes's avatar
Kjartan Mannes committed
function taxonomy_form_vocabulary($edit = array()) {
  foreach (module_list() as $name) {
    if (module_hook($name, "node")) {
      $nodetypes[$name] = $name;
Dries Buytaert's avatar
Dries Buytaert committed
    }
Kjartan Mannes's avatar
Kjartan Mannes committed
  }
Dries Buytaert's avatar
 
Dries Buytaert committed

Dries Buytaert's avatar
 
Dries Buytaert committed
  $form .= form_textfield(t("Vocabulary name"), "name", $edit["name"], 50, 64, t("Required") . ". " . t("The name for this vocabulary.  Example: 'Topic'") . ".");
  $form .= form_textarea(t("Description"), "description", $edit["description"], 60, 5, t("Optional") . ". " . t("Description of the vocabulary, can be used by modules."));
Dries Buytaert's avatar
 
Dries Buytaert committed
  $form .= form_select(t("Types"), "nodes", explode(",", $edit["nodes"]), $nodetypes, t("Required") . ". " . t("A list of node types you want to associate this vocabulary with."), "", 1);
Dries Buytaert's avatar
 
Dries Buytaert committed
  $form .= form_checkbox(t("Related terms"), "relations", 1, $edit["relations"], t("Optional") . ". " . t("Allows ". l("related terms", "admin/taxonomy/help#relatedterms") ." in this vocabulary."));
  $form .= form_select(t("Hierarchy"), "hierarchy", $edit["hierarchy"], array(t("Disabled"), t("Single"), t("Multiple")), t("Optional") . ". ". t("Allows ". l("a tree-like hierarchy", "admin/taxonomy/help#hierarchy") ." between terms of this vocabulary."), "", 0);
Dries Buytaert's avatar
 
Dries Buytaert committed
  $form .= form_checkbox(t("Multiple select"), "multiple", 1, $edit["multiple"], t("Optional") . ". " . t("Allows nodes to have more than one term in this vocabulary."));
  $form .= form_checkbox(t("Required"), "required", 1, $edit["required"], t("If enabled every node <b>must</b> have at least one term in this vocabulary"));
Dries Buytaert's avatar
 
Dries Buytaert committed
  $form .= form_weight(t("Weight"), "weight", $edit["weight"], 10, t("Optional. In listings, the heavier vocabularies will sink and the lighter vocabularies will be positioned nearer the top."));
Dries Buytaert's avatar
 
Dries Buytaert committed
  $form .= form_submit(t("Submit"));
Dries Buytaert's avatar
Dries Buytaert committed

Kjartan Mannes's avatar
Kjartan Mannes committed
  if ($edit["vid"]) {
Dries Buytaert's avatar
 
Dries Buytaert committed
    $form .= form_submit(t("Delete"));
Kjartan Mannes's avatar
Kjartan Mannes committed
    $form .= form_hidden("vid", $edit["vid"]);
Dries Buytaert's avatar
Dries Buytaert committed
  }

Kjartan Mannes's avatar
Kjartan Mannes committed
  return form($form);
}
Kjartan Mannes's avatar
Kjartan Mannes committed

Kjartan Mannes's avatar
Kjartan Mannes committed
function taxonomy_save_vocabulary($edit) {
Dries Buytaert's avatar
 
Dries Buytaert committed
  if (!$edit["nodes"]) {
    $edit["nodes"] = array();
Dries Buytaert's avatar
 
Dries Buytaert committed
  }

Dries Buytaert's avatar
 
Dries Buytaert committed
  $data = array("name" => $edit["name"], "nodes" => implode(",", $edit["nodes"]), "description" => $edit["description"], "multiple" => $edit["multiple"], "required" => $edit["required"], "hierarchy" => $edit["hierarchy"], "relations" => $edit["relations"], "weight" => $edit["weight"]);
Kjartan Mannes's avatar
Kjartan Mannes committed
  if ($edit["vid"] && $edit["name"]) {
Dries Buytaert's avatar
 
Dries Buytaert committed
    db_query("UPDATE vocabulary SET ". _prepare_update($data) ." WHERE vid = %d", $edit["vid"]);
Dries Buytaert's avatar
 
Dries Buytaert committed
    module_invoke_all("taxonomy", "update", "vocabulary", $edit);
    $message = t("updated vocabulary '%name'.", array("%name" => $edit["name"]));
Dries Buytaert's avatar
Dries Buytaert committed
  }
Kjartan Mannes's avatar
Kjartan Mannes committed
  else if ($edit["vid"]) {
Dries Buytaert's avatar
 
Dries Buytaert committed
    $message = taxonomy_del_vocabulary($edit["vid"]);
Kjartan Mannes's avatar
Kjartan Mannes committed
  }
  else {
Dries Buytaert's avatar
 
Dries Buytaert committed
    $data["vid"] = $edit["vid"] = db_next_id("vocabulary_vid");
Kjartan Mannes's avatar
Kjartan Mannes committed
    db_query("INSERT INTO vocabulary ". _prepare_insert($data, 1) ." VALUES ". _prepare_insert($data, 2));
Dries Buytaert's avatar
 
Dries Buytaert committed
    module_invoke_all("taxonomy", "insert", "vocabulary", $edit);
    $message = t("created new vocabulary '%name'.", array("%name" => $edit["name"]));
Kjartan Mannes's avatar
Kjartan Mannes committed
  }
Dries Buytaert's avatar
 
Dries Buytaert committed

  cache_clear_all();
Dries Buytaert's avatar
 
Dries Buytaert committed

  return $message;
Kjartan Mannes's avatar
Kjartan Mannes committed
}
Dries Buytaert's avatar
Dries Buytaert committed

Kjartan Mannes's avatar
Kjartan Mannes committed
function taxonomy_del_vocabulary($vid) {
Dries Buytaert's avatar
 
Dries Buytaert committed
  $vocabulary = taxonomy_get_vocabulary($vid);

Dries Buytaert's avatar
 
Dries Buytaert committed
  db_query("DELETE FROM vocabulary WHERE vid = %d", $vid);
  $result = db_query("SELECT tid FROM term_data WHERE vid = %d", $vid);
Kjartan Mannes's avatar
Kjartan Mannes committed
  while ($term = db_fetch_object($result)) {
    taxonomy_del_term($term->tid);
Dries Buytaert's avatar
Dries Buytaert committed
  }
Dries Buytaert's avatar
 
Dries Buytaert committed

Dries Buytaert's avatar
 
Dries Buytaert committed
  module_invoke_all("taxonomy", "delete", "vocabulary", $vocabulary);

Dries Buytaert's avatar
 
Dries Buytaert committed
  cache_clear_all();

Dries Buytaert's avatar
 
Dries Buytaert committed
  return t("deleted vocabulary '%name'.", array("%name" => $vocabulary->name));
}

function _taxonomy_confirm_del_vocabulary($vid) {
  $vocabulary = taxonomy_get_vocabulary($vid);

  $form .= form_hidden("confirm", 1);
  $form .= form_hidden("type", "vocabulary");
  $form .= form_hidden("vid", $vid);
  $form .= form_submit(t("Delete"));
  $form .= form_submit(t("Cancel"));

  return form(form_item(t("Delete vocabulary '%name'", array("%name" => $vocabulary->name)), $form, t("Are you sure you want to delete the vocabulary and all its terms?")));
Kjartan Mannes's avatar
Kjartan Mannes committed
}
Dries Buytaert's avatar
Dries Buytaert committed

Kjartan Mannes's avatar
Kjartan Mannes committed
function taxonomy_form_term($edit = array()) {
  $vocabulary_id = isset($edit["vid"]) ? $edit["vid"] : arg(4);
Kjartan Mannes's avatar
Kjartan Mannes committed
  $vocabulary = taxonomy_get_vocabulary($vocabulary_id);
Dries Buytaert's avatar
 
Dries Buytaert committed

Dries Buytaert's avatar
 
Dries Buytaert committed
  $form = form_textfield(t("Term name"), "name", $edit["name"], 50, 64, t("Required") . ". " . t("The name for this term.  Example: 'Linux'."));
  $form .= form_textarea(t("Description"), "description", $edit["description"], 60, 5, t("Optional") . ". " . t("A description of the term."));
Dries Buytaert's avatar
Dries Buytaert committed

Kjartan Mannes's avatar
Kjartan Mannes committed
  if ($vocabulary->hierarchy) {
    $parent = array_keys(taxonomy_get_parents($edit["tid"]));
Dries Buytaert's avatar
 
Dries Buytaert committed
    $children = taxonomy_get_tree($vocabulary_id, $edit["tid"]);
Dries Buytaert's avatar
 
Dries Buytaert committed

    // you can't be son of yourself nor of your children
    foreach ($children as $child) {
      $exclude[] = $child->tid;
    }
Kjartan Mannes's avatar
Kjartan Mannes committed
    $exclude[] = $edit["tid"];
Dries Buytaert's avatar
 
Dries Buytaert committed

Kjartan Mannes's avatar
Kjartan Mannes committed
    if ($vocabulary->hierarchy == 1) {
Dries Buytaert's avatar
 
Dries Buytaert committed
      $form .= _taxonomy_term_select(t("Parent"), "parent", $parent, $vocabulary_id, t("Required") . ". " . l(t("Parent term"), "admin/taxonomy/help#parent") .".", 0, "<" . t("root") . ">", $exclude);
Dries Buytaert's avatar
Dries Buytaert committed
    }
Kjartan Mannes's avatar
Kjartan Mannes committed
    elseif ($vocabulary->hierarchy == 2) {
Dries Buytaert's avatar
 
Dries Buytaert committed
      $form .= _taxonomy_term_select(t("Parents"), "parent", $parent, $vocabulary_id, t("Required") . ". ". l(t("Parent terms"), "admin/taxonomy/help#parent") .".", 1, "<" . t("root") . ">", $exclude);
Dries Buytaert's avatar
Dries Buytaert committed
    }
Kjartan Mannes's avatar
Kjartan Mannes committed
  }
Dries Buytaert's avatar
Dries Buytaert committed

  if ($vocabulary->relations) {
    $form .= _taxonomy_term_select(t("Related terms"), "relations", array_keys(taxonomy_get_related($edit["tid"])), $vocabulary_id, t("Optional") . ". ", 1, "<" . t("none") . ">", array($edit["tid"]));
  }

Dries Buytaert's avatar
 
Dries Buytaert committed
  $form .= form_textarea(t("Synonyms"), "synonyms", implode("\n", taxonomy_get_synonyms($edit["tid"])), 30, 5, t("Optional") . ". ". t(l("Synonyms", "admin/taxonomy/help#synonyms") ." of this term, one synonym per line."));
Dries Buytaert's avatar
 
Dries Buytaert committed
  $form .= form_weight(t("Weight"), "weight", $edit["weight"], 10, t("Optional. In listings, the heavier terms will sink and the lighter terms will be positioned nearer the top."));
Kjartan Mannes's avatar
Kjartan Mannes committed
  $form .= form_hidden("vid", $vocabulary->vid);
Dries Buytaert's avatar
 
Dries Buytaert committed
  $form .= form_submit(t("Submit"));
Kjartan Mannes's avatar
Kjartan Mannes committed

  if ($edit["tid"]) {
Dries Buytaert's avatar
 
Dries Buytaert committed
    $form .= form_submit(t("Delete"));
Kjartan Mannes's avatar
Kjartan Mannes committed
    $form .= form_hidden("tid", $edit["tid"]);
Dries Buytaert's avatar
Dries Buytaert committed
  }

Kjartan Mannes's avatar
Kjartan Mannes committed
  return form($form);
}
Dries Buytaert's avatar
Dries Buytaert committed

Kjartan Mannes's avatar
Kjartan Mannes committed
function taxonomy_save_term($edit) {
Dries Buytaert's avatar
 
Dries Buytaert committed
  if ($edit["tid"] && $edit["name"]) {
Kjartan Mannes's avatar
Kjartan Mannes committed
    $data = array("name" => $edit["name"], "description" => $edit["description"], "weight" => $edit["weight"]);
Dries Buytaert's avatar
Dries Buytaert committed

Dries Buytaert's avatar
 
Dries Buytaert committed
    db_query("UPDATE term_data SET ". _prepare_update($data) ." WHERE tid = %d", $edit["tid"]);
Dries Buytaert's avatar
 
Dries Buytaert committed
    module_invoke_all("taxonomy", "update", "term", $edit);
Dries Buytaert's avatar
 
Dries Buytaert committed
    $message = t("the term '%a' has been updated.", array("%a" => $edit["name"]));
Kjartan Mannes's avatar
Kjartan Mannes committed
  }
  else if ($edit["tid"]) {
Dries Buytaert's avatar
 
Dries Buytaert committed
    return taxonomy_del_term($edit["tid"]);
Kjartan Mannes's avatar
Kjartan Mannes committed
  }
  else {
Dries Buytaert's avatar
 
Dries Buytaert committed
    $edit["tid"] = db_next_id("term_data_tid");
Kjartan Mannes's avatar
Kjartan Mannes committed
    $data = array("tid" => $edit["tid"], "name" => $edit["name"], "description" => $edit["description"], "vid" => $edit["vid"], "weight" => $edit["weight"]);
    db_query("INSERT INTO term_data ". _prepare_insert($data, 1) ." VALUES ". _prepare_insert($data, 2));
Dries Buytaert's avatar
 
Dries Buytaert committed
    module_invoke_all("taxonomy", "insert", "term", $edit);
Dries Buytaert's avatar
 
Dries Buytaert committed
    $message = t("created new term '%name'.", array("%name" => $edit["name"]));
Kjartan Mannes's avatar
Kjartan Mannes committed
  }
Dries Buytaert's avatar
Dries Buytaert committed

Kjartan Mannes's avatar
Kjartan Mannes committed
  // relations (seem very powerful, but I have to understand it completely)
Dries Buytaert's avatar
 
Dries Buytaert committed
  db_query("DELETE FROM term_relation WHERE tid1 = %d OR tid2 = %d", $edit["tid"], $edit["tid"]);
Kjartan Mannes's avatar
Kjartan Mannes committed
  if ($edit["relations"]) {
    foreach ($edit["relations"] as $related_id) {
      if ($related_id != 0) {
Dries Buytaert's avatar
 
Dries Buytaert committed
        db_query("INSERT INTO term_relation (tid1, tid2) VALUES (%d, %d)", $edit["tid"], $related_id);
Dries Buytaert's avatar
Dries Buytaert committed
      }
Kjartan Mannes's avatar
Kjartan Mannes committed
    }
Kjartan Mannes's avatar
Kjartan Mannes committed
  }
Dries Buytaert's avatar
Dries Buytaert committed

Kjartan Mannes's avatar
Kjartan Mannes committed
  // hierarchy
Dries Buytaert's avatar
 
Dries Buytaert committed
  db_query("DELETE FROM term_hierarchy WHERE tid = %d", $edit["tid"]);
Kjartan Mannes's avatar
Kjartan Mannes committed
  if (!isset($edit["parent"])) {
    $edit["parent"] = 0;
  }
  if (is_array($edit["parent"])) {
    foreach ($edit["parent"] as $parent) {
Dries Buytaert's avatar
 
Dries Buytaert committed
      db_query("INSERT INTO term_hierarchy (tid, parent) VALUES (%d, %d)", $edit["tid"], $parent);
Dries Buytaert's avatar
Dries Buytaert committed
    }
Kjartan Mannes's avatar
Kjartan Mannes committed
  }
  else {
Dries Buytaert's avatar
 
Dries Buytaert committed
    db_query("INSERT INTO term_hierarchy (tid, parent) VALUES (%d, %d)", $edit["tid"], $edit["parent"][0]);
Dries Buytaert's avatar
Dries Buytaert committed
  }

Dries Buytaert's avatar
 
Dries Buytaert committed
  db_query("DELETE FROM term_synonym WHERE tid = %d", $edit["tid"]);
Kjartan Mannes's avatar
Kjartan Mannes committed
  if ($edit["synonyms"]) {
Dries Buytaert's avatar
 
Dries Buytaert committed
    foreach (explode ("\n", str_replace("\r", "", $edit["synonyms"])) as $synonym) {
      if ($synonym) {
Dries Buytaert's avatar
 
Dries Buytaert committed
        db_query("INSERT INTO term_synonym (tid, name) VALUES (%d, '%s')", $edit["tid"], chop($synonym));
Dries Buytaert's avatar
 
Dries Buytaert committed
      }
Kjartan Mannes's avatar
Kjartan Mannes committed
    }
Dries Buytaert's avatar
Dries Buytaert committed
  }
Dries Buytaert's avatar
 
Dries Buytaert committed

Dries Buytaert's avatar
 
Dries Buytaert committed
  cache_clear_all();

Dries Buytaert's avatar
 
Dries Buytaert committed
  return $message;
Kjartan Mannes's avatar
Kjartan Mannes committed
}
Dries Buytaert's avatar
Dries Buytaert committed

Kjartan Mannes's avatar
Kjartan Mannes committed
function taxonomy_del_term($tid) {
Dries Buytaert's avatar
 
Dries Buytaert committed
  $term = taxonomy_get_term($tid);

Dries Buytaert's avatar
 
Dries Buytaert committed
  db_query("DELETE FROM term_data WHERE tid = %d", $tid);
  db_query("DELETE FROM term_hierarchy WHERE tid = %d", $tid);
  db_query("DELETE FROM term_relation WHERE tid1 = %d OR tid2 = %d", $tid, $tid);
  db_query("DELETE FROM term_synonym WHERE tid = %d", $tid);
  db_query("DELETE FROM term_node WHERE tid = %d", $tid);
Dries Buytaert's avatar
 
Dries Buytaert committed

Dries Buytaert's avatar
 
Dries Buytaert committed
  module_invoke_all("taxonomy", "delete", "term", $term);
Dries Buytaert's avatar
 
Dries Buytaert committed

Dries Buytaert's avatar
 
Dries Buytaert committed
  cache_clear_all();

Dries Buytaert's avatar
 
Dries Buytaert committed
  return t("deleted term '%name'.", array("%name" => $term->name));
}

function _taxonomy_confirm_del_term($tid) {
  $term = taxonomy_get_term($tid);

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

  return form(form_item(t("Delete term '%name'", array("%name" => $term->name)), $form, t("Are you sure you want to delete the term?")));
Kjartan Mannes's avatar
Kjartan Mannes committed
}
Dries Buytaert's avatar
Dries Buytaert committed

Kjartan Mannes's avatar
Kjartan Mannes committed
function taxonomy_overview() {
Dries Buytaert's avatar
Dries Buytaert committed

Dries Buytaert's avatar
 
Dries Buytaert committed
  $output .= "<h3>" . t("Vocabularies overview") . "</h3>";
Dries Buytaert's avatar
 
Dries Buytaert committed

  $header = array(t("name"), t("node types"), array("data" => t("operations"), "colspan" => 3));
Dries Buytaert's avatar
 
Dries Buytaert committed

Kjartan Mannes's avatar
Kjartan Mannes committed
  $vocabularies = taxonomy_get_vocabularies();
  foreach ($vocabularies as $vocabulary) {
    $links = array();
Dries Buytaert's avatar
 
Dries Buytaert committed
    $rows[] = array($vocabulary->name, array("data" => $vocabulary->nodes, "align" => "center"), l(t("edit vocabulary"), "admin/taxonomy/edit/vocabulary/$vocabulary->vid"), l(t("add term"), "admin/taxonomy/add/term/$vocabulary->vid"), l(t("preview form"), "admin/taxonomy/preview/vocabulary/$vocabulary->vid"));
Dries Buytaert's avatar
 
Dries Buytaert committed
    $tree = taxonomy_get_tree($vocabulary->vid);
Kjartan Mannes's avatar
Kjartan Mannes committed
    if ($tree) {
Dries Buytaert's avatar
 
Dries Buytaert committed
      unset($data);
Kjartan Mannes's avatar
Kjartan Mannes committed
      foreach ($tree as $term) {
        $data .= _taxonomy_depth($term->depth) ." ". $term->name ." (". l(t("edit term"), "admin/taxonomy/edit/term/$term->tid") .")<br />";
Dries Buytaert's avatar
Dries Buytaert committed
      }
Dries Buytaert's avatar
 
Dries Buytaert committed
      $rows[] = array(array("data" => $data, "colspan" => 5));
Dries Buytaert's avatar
Dries Buytaert committed
    }
  }

Dries Buytaert's avatar
 
Dries Buytaert committed
  return table($header, $rows);
Kjartan Mannes's avatar
Kjartan Mannes committed
}

function taxonomy_form($vocabulary_id, $value = 0) {
  $vocabulary = taxonomy_get_vocabulary($vocabulary_id);
  if ($vocabulary->required) {
    $verb = "must";
    $blank = 0;
  }
  else {
    $verb = "can";
Dries Buytaert's avatar
 
Dries Buytaert committed
    $blank = "<" . t("none") . ">";
Kjartan Mannes's avatar
Kjartan Mannes committed
  }
Dries Buytaert's avatar
 
Dries Buytaert committed

Kjartan Mannes's avatar
Kjartan Mannes committed
  if ($vocabulary->multiple) {
Dries Buytaert's avatar
 
Dries Buytaert committed
    $description = t("You $verb choose one or more terms for this node.");
Kjartan Mannes's avatar
Kjartan Mannes committed
    $multiple = 1;
Dries Buytaert's avatar
Dries Buytaert committed
  }
Kjartan Mannes's avatar
Kjartan Mannes committed
  else {
Dries Buytaert's avatar
 
Dries Buytaert committed
    $description = t("You $verb choose one term for this node.");
Kjartan Mannes's avatar
Kjartan Mannes committed
    $multiple = 0;
  }
  return _taxonomy_term_select($vocabulary->name, "taxonomy", $value, $vocabulary_id, $description, $multiple, $blank);
}
Dries Buytaert's avatar
Dries Buytaert committed

/*
** API functions
*/

Kjartan Mannes's avatar
Kjartan Mannes committed
// return array of vocabularies, as objects
function taxonomy_get_vocabularies($type = '', $key = "vid") {
  if ($type) {
Dries Buytaert's avatar
 
Dries Buytaert committed
    $result = db_query("SELECT * FROM vocabulary WHERE nodes LIKE '%%%s%%' ORDER BY weight, name", $type);
Kjartan Mannes's avatar
Kjartan Mannes committed
  }
  else {
    $result = db_query("SELECT * FROM vocabulary ORDER BY weight, name");
  }
  $vocabularies = array();
  while ($voc = db_fetch_object($result)) {
    $vocabularies[$voc->$key] = $voc;
Dries Buytaert's avatar
Dries Buytaert committed
  }
Dries Buytaert's avatar
 
Dries Buytaert committed

Kjartan Mannes's avatar
Kjartan Mannes committed
  return $vocabularies;
}
Dries Buytaert's avatar
Dries Buytaert committed

Kjartan Mannes's avatar
Kjartan Mannes committed
// return form with current term
function taxonomy_node_form($type, $node = '') {
  if (!$node->taxonomy) {
    if ($node->nid) {
      $terms = array_keys(taxonomy_node_get_terms($node->nid));
Kjartan Mannes's avatar
Kjartan Mannes committed
    }
    else {
Kjartan Mannes's avatar
Kjartan Mannes committed
      $terms = 0;
Dries Buytaert's avatar
Dries Buytaert committed
    }
Kjartan Mannes's avatar
Kjartan Mannes committed
  }
  else {
    $terms = $node->taxonomy;
  }
Dries Buytaert's avatar
Dries Buytaert committed

Dries Buytaert's avatar
 
Dries Buytaert committed
  $c = db_query("SELECT * FROM vocabulary WHERE nodes LIKE '%%%s%%' ORDER BY weight, name", $type);
Kjartan Mannes's avatar
Kjartan Mannes committed
  while ($vocabulary = db_fetch_object($c)) {
    $result[] .= taxonomy_form($vocabulary->vid, $terms);
Dries Buytaert's avatar
Dries Buytaert committed
  }
Kjartan Mannes's avatar
Kjartan Mannes committed
  return $result ? $result : array();
}
Dries Buytaert's avatar
Dries Buytaert committed

Kjartan Mannes's avatar
Kjartan Mannes committed
// return 1 if node identified by $nid contains a taxonomy term identified by $tid in his body or title
function taxonomy_node_has_term($nid, $tid) {
Dries Buytaert's avatar
 
Dries Buytaert committed
  $term_name = db_result(db_query("SELECT name FROM term_data WHERE tid = %d", $tid));
Dries Buytaert's avatar
Dries Buytaert committed

Dries Buytaert's avatar
 
Dries Buytaert committed
  return db_result(db_query("SELECT COUNT(n.nid) FROM node n WHERE n.nid = %d AND ((n.body LIKE '%%%s%%') OR (n.body LIKE '%%%s%%'))", $nid, $term_name, $term_name));
Kjartan Mannes's avatar
Kjartan Mannes committed
}

// return array of terms of a node beloging to a particular vocabulary identified by $vid
function taxonomy_node_get_terms_by_vocabulary($nid, $vid, $key = "tid") {
Dries Buytaert's avatar
 
Dries Buytaert committed
  $result = db_query("SELECT t.* FROM term_data t, term_node r WHERE t.tid = r.tid AND t.vid = %d AND r.nid = %d ORDER BY weight", $vid, $nid);
Kjartan Mannes's avatar
Kjartan Mannes committed
  $terms = array();
  while ($term = db_fetch_object($result)) {
    $terms[$term->$key] = $term;
Dries Buytaert's avatar
Dries Buytaert committed
  }
Kjartan Mannes's avatar
Kjartan Mannes committed
  return $terms;
}

// return array of terms of a node
function taxonomy_node_get_terms($nid, $key = "tid") {
  static $terms;
Dries Buytaert's avatar
Dries Buytaert committed

Dries Buytaert's avatar
 
Dries Buytaert committed
  if (!isset($terms[$nid])) {
Dries Buytaert's avatar
 
Dries Buytaert committed
    $result = db_query("SELECT t.* FROM term_data t, term_node r WHERE r.tid = t.tid AND r.nid = %d ORDER BY weight, name", $nid);
Kjartan Mannes's avatar
Kjartan Mannes committed
    $terms[$nid] = array();
Dries Buytaert's avatar
Dries Buytaert committed
    while ($term = db_fetch_object($result)) {
Kjartan Mannes's avatar
Kjartan Mannes committed
      $terms[$nid][$term->$key] = $term;
Dries Buytaert's avatar
Dries Buytaert committed
    }
  }
Kjartan Mannes's avatar
Kjartan Mannes committed
  return $terms[$nid];
}
Dries Buytaert's avatar
Dries Buytaert committed

Kjartan Mannes's avatar
Kjartan Mannes committed
// save terms of a node
function taxonomy_node_save($nid, $terms) {
  taxonomy_node_delete($nid);
Dries Buytaert's avatar
Dries Buytaert committed

Kjartan Mannes's avatar
Kjartan Mannes committed
  if ($terms) {
Dries Buytaert's avatar
 
Dries Buytaert committed
    foreach ($terms as $term) {
Dries Buytaert's avatar
 
Dries Buytaert committed
      db_query("INSERT INTO term_node (nid, tid) VALUES (%d, %d)", $nid, $term);
Dries Buytaert's avatar
Dries Buytaert committed
    }
  }
Kjartan Mannes's avatar
Kjartan Mannes committed
}
Dries Buytaert's avatar
Dries Buytaert committed

Kjartan Mannes's avatar
Kjartan Mannes committed
// clean up terms
function taxonomy_node_delete($nid) {
Dries Buytaert's avatar
 
Dries Buytaert committed
  db_query("DELETE FROM term_node WHERE nid = %d", $nid);
Kjartan Mannes's avatar
Kjartan Mannes committed
}
Dries Buytaert's avatar
Dries Buytaert committed

Kjartan Mannes's avatar
Kjartan Mannes committed
// relations: return array of related terms
function taxonomy_get_related($tid, $key = "tid") {
  if ($tid) {
Dries Buytaert's avatar
 
Dries Buytaert committed
    $result = db_query("SELECT t.*, tid1, tid2 FROM term_relation, term_data t WHERE (t.tid = tid1 OR t.tid = tid2) AND (tid1 = %d OR tid2 = %d) AND t.tid != %d ORDER BY weight, name", $tid, $tid, $tid);
Kjartan Mannes's avatar
Kjartan Mannes committed
    $related = array();
    while ($term = db_fetch_object($result)) {
      $related[$term->$key] = $term;
Dries Buytaert's avatar
Dries Buytaert committed
    }
Kjartan Mannes's avatar
Kjartan Mannes committed
    return $related;
Dries Buytaert's avatar
Dries Buytaert committed
  }
Kjartan Mannes's avatar
Kjartan Mannes committed
  else {
    return array();
Dries Buytaert's avatar
Dries Buytaert committed
  }
Kjartan Mannes's avatar
Kjartan Mannes committed
}
Dries Buytaert's avatar
Dries Buytaert committed

Kjartan Mannes's avatar
Kjartan Mannes committed
// hierarchy: get parent terms
function taxonomy_get_parents($tid, $key = "tid") {
  if ($tid) {
Dries Buytaert's avatar
 
Dries Buytaert committed
    $result = db_query("SELECT t.* FROM term_hierarchy h, term_data t WHERE h.parent = t.tid AND h.tid = %d ORDER BY weight, name", $tid);
Kjartan Mannes's avatar
Kjartan Mannes committed
    $parents = array();
    while ($parent = db_fetch_object($result)) {
      $parents[$parent->$key] = $parent;
Dries Buytaert's avatar
 
Dries Buytaert committed
    }
Kjartan Mannes's avatar
Kjartan Mannes committed
    return $parents;
Dries Buytaert's avatar
Dries Buytaert committed
  }
Kjartan Mannes's avatar
Kjartan Mannes committed
  else {
    return array();
  }
}
Dries Buytaert's avatar
Dries Buytaert committed

Kjartan Mannes's avatar
Kjartan Mannes committed
// hierarchy: get children
function taxonomy_get_children($tid, $vid = 0, $key = "tid") {
  if ($vid) {
Dries Buytaert's avatar
 
Dries Buytaert committed
    $result = db_query("SELECT t.* FROM term_hierarchy h, term_data t WHERE t.vid = %d AND h.tid = t.tid AND h.parent = %d ORDER BY weight, name", $vid, $tid);
Dries Buytaert's avatar
Dries Buytaert committed
  }
Kjartan Mannes's avatar
Kjartan Mannes committed
  else {
Dries Buytaert's avatar
 
Dries Buytaert committed
    $result = db_query("SELECT t.* FROM term_hierarchy h, term_data t WHERE h.tid = t.tid AND parent = %d ORDER BY weight", $tid);
Kjartan Mannes's avatar
Kjartan Mannes committed
  }
  $children = array();
  while ($term = db_fetch_object($result)) {
    $children[$term->$key] = $term;
  }
  return $children;
}
Dries Buytaert's avatar
Dries Buytaert committed

Kjartan Mannes's avatar
Kjartan Mannes committed
// hierarchy: get whole family, with tid, parent and depth; useful to show
Dries Buytaert's avatar
 
Dries Buytaert committed
function taxonomy_get_tree($vocabulary_id, $parent = 0, $depth = -1, $key = "tid") {
Dries Buytaert's avatar
 
Dries Buytaert committed
  static $children, $parents, $terms;
Dries Buytaert's avatar
 
Dries Buytaert committed

Kjartan Mannes's avatar
Kjartan Mannes committed
  $depth++;
Dries Buytaert's avatar
 
Dries Buytaert committed

Dries Buytaert's avatar
 
Dries Buytaert committed
  // we cache trees, so it's not cpu-intensive to call get_tree on a term and its children too
  if (!isset($children[$vocabulary_id])) {
    $children[$vocabulary_id] = array();

Dries Buytaert's avatar
 
Dries Buytaert committed
    $result = db_query("SELECT t.*, parent FROM term_data t, term_hierarchy h WHERE t.tid = h.tid AND t.vid = %d ORDER BY weight, name", $vocabulary_id);
Dries Buytaert's avatar
 
Dries Buytaert committed
    while ($term = db_fetch_object($result)) {
Dries Buytaert's avatar
 
Dries Buytaert committed
      $children[$vocabulary_id][$term->parent][] = $term->tid;
      $parents[$vocabulary_id][$term->tid][] = $term->parent;
      $terms[$vocabulary_id][$term->tid] = $term;
Dries Buytaert's avatar
Dries Buytaert committed
    }
  }
Dries Buytaert's avatar
 
Dries Buytaert committed

Dries Buytaert's avatar
 
Dries Buytaert committed
  if ($children[$vocabulary_id][$parent]) {
    foreach ($children[$vocabulary_id][$parent] as $child) {
      $terms[$vocabulary_id][$child]->depth = $depth;
      unset($terms[$vocabulary_id][$child]->parent); // this is not useful as it would show one parent only
      $terms[$vocabulary_id][$child]->parents = $parents[$vocabulary_id][$child];
      $tree[] = $terms[$vocabulary_id][$child];
Dries Buytaert's avatar
 
Dries Buytaert committed

Dries Buytaert's avatar
 
Dries Buytaert committed
      $tree = array_merge($tree, taxonomy_get_tree($vocabulary_id, $child, $depth));
Dries Buytaert's avatar
 
Dries Buytaert committed
    }
Kjartan Mannes's avatar
Kjartan Mannes committed
  }
Dries Buytaert's avatar
 
Dries Buytaert committed

Dries Buytaert's avatar
 
Dries Buytaert committed
  return $tree ? $tree : array();
Kjartan Mannes's avatar
Kjartan Mannes committed
}
Dries Buytaert's avatar
Dries Buytaert committed

Kjartan Mannes's avatar
Kjartan Mannes committed
// synonyms: return array of synonyms
function taxonomy_get_synonyms($tid) {
  if ($tid) {
Dries Buytaert's avatar
 
Dries Buytaert committed
    $result = db_query("SELECT name FROM term_synonym WHERE tid = %d", $tid);
Kjartan Mannes's avatar
Kjartan Mannes committed
    while ($synonym = db_fetch_array($result)) {
      $synonyms[] = $synonym["name"];
Dries Buytaert's avatar
Dries Buytaert committed
    }
Kjartan Mannes's avatar
Kjartan Mannes committed
    return $synonyms ? $synonyms : array();
Dries Buytaert's avatar
Dries Buytaert committed
  }
Kjartan Mannes's avatar
Kjartan Mannes committed
  else {
    return array();
Dries Buytaert's avatar
 
Dries Buytaert committed
  }
Kjartan Mannes's avatar
Kjartan Mannes committed
}
Dries Buytaert's avatar
 
Dries Buytaert committed

Kjartan Mannes's avatar
Kjartan Mannes committed
// synonyms: return original term
function taxonomy_get_synonym_root($term) {
  return db_fetch_object(db_query("SELECT * FROM term_synonym s, term_data t WHERE t.tid = s.tid AND s.name = '%s'", $term));
}
Dries Buytaert's avatar
 
Dries Buytaert committed

Dries Buytaert's avatar
 
Dries Buytaert committed
// given a term id, count number of published nodes in it
Dries Buytaert's avatar
 
Dries Buytaert committed
function taxonomy_term_count_nodes($tid, $type = 0) {
Kjartan Mannes's avatar
Kjartan Mannes committed
  static $count;
Dries Buytaert's avatar
 
Dries Buytaert committed

Dries Buytaert's avatar
 
Dries Buytaert committed
  if (!isset($count[$type])) {
    // $type == 0 always evaluates true is $type is a string
    if (is_numeric($type)) {
Dries Buytaert's avatar
 
Dries Buytaert committed
      $result = db_query("SELECT t.tid, COUNT(*) AS c FROM term_node t LEFT JOIN node n ON t.nid = n.nid WHERE n.status = 1 GROUP BY t.tid");
Dries Buytaert's avatar
 
Dries Buytaert committed
    }
    else {
Dries Buytaert's avatar
 
Dries Buytaert committed
      $result = db_query("SELECT t.tid, COUNT(*) AS c FROM term_node t, node n WHERE t.nid = n.nid AND n.status = 1 AND n.type = '%s' GROUP BY t.tid", $type);
Dries Buytaert's avatar
 
Dries Buytaert committed
    }
Kjartan Mannes's avatar
Kjartan Mannes committed
    while ($term = db_fetch_object($result)) {
Dries Buytaert's avatar
 
Dries Buytaert committed
      $count[$type][$term->tid] = $term->c;
Dries Buytaert's avatar
 
Dries Buytaert committed
    }
  }

Kjartan Mannes's avatar
Kjartan Mannes committed
  foreach (_taxonomy_term_children($tid) as $c) {
Dries Buytaert's avatar
 
Dries Buytaert committed
    $children_count += taxonomy_term_count_nodes($c, $type);
Kjartan Mannes's avatar
Kjartan Mannes committed
  }
Dries Buytaert's avatar
 
Dries Buytaert committed
  return $count[$type][$tid] + $children_count;
Kjartan Mannes's avatar
Kjartan Mannes committed
}

// helper for above function
function _taxonomy_term_children($tid) {
  static $children;
Dries Buytaert's avatar
 
Dries Buytaert committed

Dries Buytaert's avatar
 
Dries Buytaert committed
  if (!isset($children)) {
Kjartan Mannes's avatar
Kjartan Mannes committed
    $result = db_query("SELECT tid, parent FROM term_hierarchy");
    while ($term = db_fetch_object($result)) {
      $children[$term->parent][] = $term->tid;
Dries Buytaert's avatar
 
Dries Buytaert committed
    }
Dries Buytaert's avatar
Dries Buytaert committed
  }
Kjartan Mannes's avatar
Kjartan Mannes committed
  return $children[$tid] ? $children[$tid] : array();
}
Dries Buytaert's avatar
Dries Buytaert committed

Dries Buytaert's avatar
 
Dries Buytaert committed
/**
 * Try to map a string to existing vocabularies
 * Provide case insensitive and trimmed map so as to
 * maximize likelihood of successful mapping.
 *
 * @param   string  $name  Name of the vocabulary to search
 * @return  array   array of matching vocabularies, as objects
 */
function taxonomy_get_vocabulary_by_name($name) {
  // LOWER is ANSI SQL-92
  $db_result = db_query("SELECT * FROM vocabulary WHERE LOWER('%s') LIKE LOWER(name)", trim($name));
  $result = array();
  while ($vocabulary = db_fetch_object($db_result)) {
    $result[] = $vocabulary;
  }

  return $result;
}

/**
 * Try to map a string to existing terms
 * Provide case insensitive and trimmed map so as to
 * maximize likelihood of successful mapping.
 *
 * @param   string  $name  Name of the term to search
 * @return  array   array of matching terms, as objects
 */
function taxonomy_get_term_by_name($name) {
  // LOWER is ANSI SQL-92
  $db_result = db_query("SELECT * FROM term_data WHERE LOWER('%s') LIKE LOWER(name)", trim($name));
  $result = array();
  while ($term = db_fetch_object($db_result)) {
    $result[] = $term;
  }

  return $result;
}

Kjartan Mannes's avatar
Kjartan Mannes committed
function taxonomy_get_vocabulary($vid) {
  // simple cache using a static var?
Dries Buytaert's avatar
 
Dries Buytaert committed
  return db_fetch_object(db_query("SELECT * FROM vocabulary WHERE vid = %d", $vid));
Kjartan Mannes's avatar
Kjartan Mannes committed
}
Dries Buytaert's avatar
Dries Buytaert committed

Kjartan Mannes's avatar
Kjartan Mannes committed
function taxonomy_get_term($tid) {
  // simple cache using a static var?
Dries Buytaert's avatar
 
Dries Buytaert committed
  return db_fetch_object(db_query("SELECT * FROM term_data WHERE tid = %d", $tid));
Kjartan Mannes's avatar
Kjartan Mannes committed
}
Dries Buytaert's avatar
Dries Buytaert committed

/*
** service functions
*/

Kjartan Mannes's avatar
Kjartan Mannes committed
function _taxonomy_term_select($title, $name, $value, $vocabulary_id, $description, $multiple, $blank, $exclude = array()) {
Dries Buytaert's avatar
 
Dries Buytaert committed
  $tree = taxonomy_get_tree($vocabulary_id);
Dries Buytaert's avatar
Dries Buytaert committed

Kjartan Mannes's avatar
Kjartan Mannes committed
  if ($blank) {
Dries Buytaert's avatar
 
Dries Buytaert committed
    $options[] = array("tid" => 0, "name" => $blank);
Kjartan Mannes's avatar
Kjartan Mannes committed
  }
Dries Buytaert's avatar
Dries Buytaert committed

Kjartan Mannes's avatar
Kjartan Mannes committed
  if ($tree) {
    foreach ($tree as $term) {
      if (!in_array($term->tid, $exclude)) {
Dries Buytaert's avatar
 
Dries Buytaert committed
        $options[] = array("tid" => $term->tid, "name" => _taxonomy_depth($term->depth, '-').$term->name);
Dries Buytaert's avatar
Dries Buytaert committed
      }
    }
Kjartan Mannes's avatar
Kjartan Mannes committed
    if (!$blank && !$value) {
      // required but without a predefined value, so set first as predefined
      $value = $tree[0]->tid;
    }
  }
Dries Buytaert's avatar
Dries Buytaert committed

Kjartan Mannes's avatar
Kjartan Mannes committed
  if (count($options) > 0) {
Dries Buytaert's avatar
 
Dries Buytaert committed
    foreach ($options as $option) {
      $select .= "<option value=\"".$option["tid"]."\"". (is_array($value) ? (in_array($option["tid"], $value) ? " selected=\"selected\"" : "") : ($option["tid"] == $value ? " selected=\"selected\"" : "")) .">". check_form($option["name"]) ."</option>";
Kjartan Mannes's avatar
Kjartan Mannes committed
    }
Dries Buytaert's avatar
Dries Buytaert committed

Dries Buytaert's avatar
 
Dries Buytaert committed
    $size = min(12, count($options));
Dries Buytaert's avatar
Dries Buytaert committed

Kjartan Mannes's avatar
Kjartan Mannes committed
    return form_item($title, "<select name=\"edit[$name][]\"". ($multiple ? " multiple size=\"$size\"" : "") . ($extra ? " $extra" : "") .">$select</select>", $description);
Dries Buytaert's avatar
Dries Buytaert committed
  }
Kjartan Mannes's avatar
Kjartan Mannes committed
}
Dries Buytaert's avatar
Dries Buytaert committed

Kjartan Mannes's avatar
Kjartan Mannes committed
function _taxonomy_depth($depth, $graphic = '--') {
  for ($n = 0; $n < $depth; $n++) {
    $result .= $graphic;
Dries Buytaert's avatar
Dries Buytaert committed
  }
Kjartan Mannes's avatar
Kjartan Mannes committed
  return $result;
}
Dries Buytaert's avatar
Dries Buytaert committed

Kjartan Mannes's avatar
Kjartan Mannes committed
function _prepare_update($data) {
  foreach ($data as $key => $value) {
    $q[] = "$key = '". check_query($value) ."'";
Dries Buytaert's avatar
Dries Buytaert committed
  }
Kjartan Mannes's avatar
Kjartan Mannes committed
  $result = implode(", ", $q);
  return $result;
}
Dries Buytaert's avatar
Dries Buytaert committed

Kjartan Mannes's avatar
Kjartan Mannes committed
function _prepare_insert($data, $stage) {
  if ($stage == 1) {
    $result = implode(", ", array_keys($data));
  }
  else {
    foreach (array_values($data) as $value) {
      $q[] = "'". check_query($value) ."'";
Dries Buytaert's avatar
Dries Buytaert committed
    }
Kjartan Mannes's avatar
Kjartan Mannes committed
    $result = implode(", ", $q);
Dries Buytaert's avatar
Dries Buytaert committed
  }
Kjartan Mannes's avatar
Kjartan Mannes committed
  return "($result)";
}
Dries Buytaert's avatar
 
Dries Buytaert committed

Dries Buytaert's avatar
 
Dries Buytaert committed
/*
** Accepts taxonomy conditions and returns a resource identifier.  If
** you intend to use the nodes without a pager (eg. in a XML feed),
** then set $pager to false.
*/
function taxonomy_select_nodes($taxonomy, $pager = 1) {
  global $user;

  if ($taxonomy->str_tids) {
    if ($taxonomy->operator == "or") {
      $sql = "SELECT DISTINCT(n.nid), n.title, n.type, n.created, n.changed, n.uid, n.static, n.created, u.name FROM node n LEFT JOIN term_node r ON n.nid = r.nid LEFT JOIN users u ON n.uid = u.uid WHERE r.tid IN ($taxonomy->str_tids) AND n.status = '1' ORDER BY static DESC, created DESC";
      $sql_count = "SELECT COUNT(DISTINCT(n.nid)) FROM node n LEFT JOIN term_node r ON n.nid = r.nid LEFT JOIN users u ON n.uid = u.uid WHERE r.tid IN ($taxonomy->str_tids) AND n.status = '1'";
    }
    else {
      $sql = "SELECT n.nid, n.title, n.type, n.created, n.changed, n.uid, u.name FROM node n LEFT JOIN term_node r ON n.nid = r.nid LEFT JOIN users u ON n.uid = u.uid WHERE r.tid IN ($taxonomy->str_tids) AND n.status = '1' GROUP BY n.nid, n.title, n.type, n.created, n.changed, n.uid, u.name HAVING COUNT(n.nid) = ".count($taxonomy->tids)." ORDER BY static DESC, created DESC";
Dries Buytaert's avatar
 
Dries Buytaert committed

      // Special trick as we could not find anything better:
      $count = db_num_rows(db_query("SELECT n.nid FROM node n LEFT JOIN term_node r ON n.nid = r.nid WHERE r.tid IN ($taxonomy->str_tids) AND n.status = '1' GROUP BY n.nid HAVING COUNT(n.nid) = ". count($taxonomy->tids)));
      $sql_count = "SELECT $count";
    }
Dries Buytaert's avatar
 
Dries Buytaert committed

    if ($pager) {
      $result = pager_query($sql, variable_get("default_nodes_main", 10) , 0, $sql_count);
    }
    else {
      $result = db_query_range($sql, 0, 15);
    }
Dries Buytaert's avatar
 
Dries Buytaert committed
  }

  return $result;
}

/*
** Accepts the result of a db_query() and formats each node along
** with a pager.
*/
function taxonomy_render_nodes($result) {

  while ($node = db_fetch_object($result)) {
    node_view(node_load(array("nid" => $node->nid, "type" => $node->type)), 1);
  }
  print pager_display_default(NULL, variable_get("default_nodes_main", 10), 0);
}

Dries Buytaert's avatar
 
Dries Buytaert committed
function taxonomy_nodeapi($node, $op, $arg = 0) {

  switch ($op) {
    case "insert":
      taxonomy_node_save($node->nid, $node->taxonomy);
      break;
    case "update":
      taxonomy_node_save($node->nid, $node->taxonomy);
      break;
    case "delete":
      taxonomy_node_delete($node->nid);
      break;
  }
}

Kjartan Mannes's avatar
Kjartan Mannes committed
function taxonomy_page() {
Dries Buytaert's avatar
 
Dries Buytaert committed

Dries Buytaert's avatar
 
Dries Buytaert committed

  // taxonomy querystring always parsed here
  // TODO: support term *names* in URL (e.g. taxonomy/view/or/milk,beer,red+wine)
  $taxonomy->operator = arg(2);
  $taxonomy->str_tids = check_query(arg(3));
  $taxonomy->tids = explode(",", $taxonomy->str_tids);
Dries Buytaert's avatar
 
Dries Buytaert committed

Dries Buytaert's avatar
 
Dries Buytaert committed
  switch (arg(1)) {
Kjartan Mannes's avatar
Kjartan Mannes committed
    case "feed":
Dries Buytaert's avatar
 
Dries Buytaert committed
      taxonomy_feed($taxonomy);
Kjartan Mannes's avatar
Kjartan Mannes committed
      break;
    default:
Dries Buytaert's avatar
 
Dries Buytaert committed
      theme("header");
Dries Buytaert's avatar
 
Dries Buytaert committed
      taxonomy_render_nodes(taxonomy_select_nodes($taxonomy));
Dries Buytaert's avatar
 
Dries Buytaert committed
      theme("footer");
Dries Buytaert's avatar
 
Dries Buytaert committed
      break;
Dries Buytaert's avatar
 
Dries Buytaert committed
  }
Kjartan Mannes's avatar
Kjartan Mannes committed
}
Dries Buytaert's avatar
 
Dries Buytaert committed

Kjartan Mannes's avatar
Kjartan Mannes committed
/*
Dries Buytaert's avatar
Dries Buytaert committed
** admin
*/

Kjartan Mannes's avatar
Kjartan Mannes committed
function taxonomy_admin() {
Dries Buytaert's avatar
 
Dries Buytaert committed
  $op = $_POST["op"];
  $edit = $_POST["edit"];
Kjartan Mannes's avatar
Kjartan Mannes committed

  if (user_access("administer taxonomy")) {
Dries Buytaert's avatar
 
Dries Buytaert committed
    if (empty($op)) {
      $op = arg(2);
    }

Kjartan Mannes's avatar
Kjartan Mannes committed
    switch ($op) {
      case "add":
        if (arg(3) == "vocabulary")
          $output .= taxonomy_form_vocabulary();
        else if (arg(3) == "term")
          $output .= taxonomy_form_term();
Dries Buytaert's avatar
 
Dries Buytaert committed
        break;
      case "edit":
        if (arg(3) == "vocabulary")
          $output .= taxonomy_form_vocabulary(object2array(taxonomy_get_vocabulary(arg(4))));
        else if (arg(3) == "term")
          $output .= taxonomy_form_term(object2array(taxonomy_get_term(arg(4))));
Kjartan Mannes's avatar
Kjartan Mannes committed
        break;
      case "preview":
        $output .= taxonomy_form(arg(4));
Kjartan Mannes's avatar
Kjartan Mannes committed
        break;
      case "help":
        $output .= taxonomy_help();
Kjartan Mannes's avatar
Kjartan Mannes committed
        break;
Dries Buytaert's avatar
 
Dries Buytaert committed
      case t("Delete"):
Dries Buytaert's avatar
 
Dries Buytaert committed
        if (!$edit["confirm"]) {
Dries Buytaert's avatar
 
Dries Buytaert committed
          if (arg(3) == "vocabulary") {
            $output .= _taxonomy_confirm_del_vocabulary($edit["vid"]);
Dries Buytaert's avatar
 
Dries Buytaert committed
          }
          else {
            $output .= _taxonomy_confirm_del_term($edit["tid"]);
Dries Buytaert's avatar
 
Dries Buytaert committed
          }
          break;
        }
        else {
          $edit["name"] = 0;
          // fall through:
        }
Dries Buytaert's avatar
 
Dries Buytaert committed
      case t("Submit"):
        if (arg(3) == "vocabulary") {
          $output .= status(taxonomy_save_vocabulary($edit));
Dries Buytaert's avatar
 
Dries Buytaert committed
          $output .= status(taxonomy_save_term($edit));
Dries Buytaert's avatar
 
Dries Buytaert committed
          if (!$edit["tid"]) {
            // if INSERT show form again
            $output .= taxonomy_form_term();
Dries Buytaert's avatar
 
Dries Buytaert committed
            break;
          }
          // else (UPDATE or DELETE) fall through
Kjartan Mannes's avatar
Kjartan Mannes committed
        // fall through:
      default:
        $output .= taxonomy_overview();
Kjartan Mannes's avatar
Kjartan Mannes committed
    }
  }
  else {
    $output .= message_access();
Kjartan Mannes's avatar
Kjartan Mannes committed
  }
Dries Buytaert's avatar
 
Dries Buytaert committed

  return $output;
Kjartan Mannes's avatar
Kjartan Mannes committed
}

function taxonomy_help() {
Dries Buytaert's avatar
 
Dries Buytaert committed

Dries Buytaert's avatar
 
Dries Buytaert committed
  $output .= "<h3>Background</h3><p>Taxonomy is the study of classification. Drupal's taxonomy module allows you to define categories which are used to classify content. The module supports hierarchical classification and association between terms, allowing for truly flexible information retrieval and classification. For more details about <a href=\"http://www.eleganthack.com/archives/002165.html#002165\">classification types</a> and insight into the development of the <i>taxonomy.module</i>, see this <a href=\"http://www.drupal.org/node/view/55\">drupal.org discussion</a>.</p>";
  $output .= "<h3>An example taxonomy: food</h3><ul><li>Dairy<ul><li>Milk</li></ul></li><li>Drink<ul><li>Alchohol<ul><li>Beer</li><li>Wine</li></ul></li><li>Pop</li><li>Milk</li></ul></li><li>Meat<ul><li>Beef</li><li>Chicken</li><li>Lamb</li></ul></li><li>Spices<ul><li>Sugar</li></ul></li></ul>";
Dries Buytaert's avatar
 
Dries Buytaert committed
  $output .= "<p><b>Notes</b></p><ul><li>The term <i>Milk</i> appears within both <i>Dairy</i> and <i>Drink</i>.  This is an example of <i>multiple parents</i> for a term.</li><li>In Drupal the order of siblings (e.g. <i>Beef</i>, <i>Chicken</i>, <i>Lamb</i>) in a taxonomy may be controlled with the <i>weight</i> parameter.</li></ul>";
  $output .= "<h3>Vocabularies</h3><p>When you create a controlled vocabulary you are creating a set of terms to use for describing content (known as descriptors in indexing lingo). Drupal allows you to describe each node of content (blog, story, etc.) using one or many of these terms. For simple implementations, you might create a set of categories without subcategories, similar to <a href=\"http://www.slashdot.com/\">Slashdot's</a> sections.  For more complex implementations, you might create a hierarchical list of categories such as <i>Food</i> taxonomy shown above.</p>";
  $output .= "<h4>Setting up a vocabulary</h4><p>When setting up a controlled vocabulary, if you select the <i>hierarchy</i> option, you will be defining a taxonomy or a thesaurus. If you select the <i>related terms</i> option, you are allowing the definition of related terms, think <i>see also</i>, as in a thesaurus. Selecting <i>multiple select</i> will allow you to describe a node using more than one term. That node will then appear in each term's page, thus increasing the chance that a user will find it.</p>";
Dries Buytaert's avatar
 
Dries Buytaert committed
  $output .= "<p>When setting up a controlled vocabulary you are asked for: <ul><li><b>Vocabulary name</b> (Required) -- The name for this vocabulary. Example: <i>Dairy</i>.</li><li><b>Description</b> (Optional) -- Description of the vocabulary, this can be used by modules and feeds.</li><li><b>Types</b> (Required) -- The list of node types you want to associate this vocabulary with. Some available types are: blog, book, forum, page, story.</li><li><a id=\"relatedterms\"></a><b>Related terms</b> -- Allows relationships between terms within this vocabulary. Think of these as <i>see also</i>-references.</li><li><a id=\"hierarchy\"></a><b>Hierarchy</b> -- Allows a tree-like taxonomy, as in our <i>Foods</i> example above</li><li><b>Multiple select</b> -- Allows nodes to be described using more than one term. Nodes may then appear on multiple taxonomy pages.</li><li><b>Required</b> -- Each node has to have a term in this vacabulary associated with it.</li><li><b>Weight</b> -- The over all weight for this vocaulary in listings with multiple vacabularies.</ul></p>";
Dries Buytaert's avatar
 
Dries Buytaert committed
  $output .= "<h4>Adding terms to a vocabulary</h4><p>Once done defining the vocabulary, you have to add terms to it to make it useful. The options you see when adding a term to a vocabulary will depend on what you selected for <i>related terms</i>, <i>hierarchy </i>and <i>multiple select</i>. These options are:</p>";
Dries Buytaert's avatar
 
Dries Buytaert committed
  $output .= "<p><ul><li><b>Term name</b> (Required) -- The name for this term. Example: <i>Milk</i></li><li><b>Description</b> (Optional) -- Description of the term that may be used by modules and feeds.  This is synonymous with a 'scope note'.</li><li><b><a id=\"parent\"></a>Parent</b> (Required) -- Select the term under which this term is a subset -- the branch of the hierarchy that this term belongs under. This is also known as the \"Broader term\" indicator used in thesauri.</li><li><b><a id=\"synonyms\"></a>Synonyms</b> (Optional) -- Enter synonyms for this term, one synonym per line. Synonyms can be used for variant spellings, acronyms, and other terms that have the same meaning as the added term, but which are not explicitly listed in this thesaurus (i.e. <i>unauthorized terms</i>)</li><li><b>Weight</b> (Optional) -- The weight is used to sort the terms of this vocabulary.</li></ul></p>";
  $output .= "<h3><a id=\"taxonomyURL\"></a>Displaying nodes organized by term(s)</h3><p>In order to view the nodes associated with a term or a collection of terms, you should browse to a properly formed Taxonomy URL. For example, ". l("taxonomy/page/or/1,2","taxonomy/pages/or/1,2") .".  Taxonomy URLs always contain one or more term IDs (tid) at the end of the URL (a.k.a the <i>querystring</i>). You may learn the term ID for a given term by hovering over that term in the ". l("taxonomy overview", "admin/taxonomy") ." page and noting the number at the end or the URL.  To build a Taxonomy URL start with \"taxonomy/page\". Now add the querystring parameter, either <i>or</i>, which chooses nodes tagged with <b>any</b> of the given term IDs, or <i>and</i>, which chooses nodes tagged with <b>all</b> of the given Term IDs. Thus <i>or</i> is less specific than <i>and</i>. Finally add a comma seperated list of term IDs.</p>";
Dries Buytaert's avatar
 
Dries Buytaert committed
  $output .= "<h3>RSS feeds</h3><p>Every term, or collection of terms, provides an <a href=\"http://backend.userland.com/stories/rss\">RSS</a> feed to which interested users may subscribe. The URL format for a sample RSS feed is ". l("node/feed/or/1,2","node/feed/or/1,2") .". Built like a Taxonomy URL, ". l("see above", "admin/taxonomy/help#taxonomyURL") ." it starts with \"node/feed\", then has the querystring parameter, and finally the Term IDs.</p>";
Dries Buytaert's avatar
 
Dries Buytaert committed
  return t($output);
Kjartan Mannes's avatar
Kjartan Mannes committed
}
Dries Buytaert's avatar
 
Dries Buytaert committed
?>