taxonomy.module 33 KB
Newer Older
Dries's avatar
 
Dries committed
1
<?php
Kjartan's avatar
Kjartan committed
2
// $Id$
Dries's avatar
 
Dries committed
3

4
function taxonomy_system($field){
Kjartan's avatar
Kjartan committed
5
  $system["description"] = t("Enables the organization of content into categories.");
6 7 8
  return $system[$field];
}

Dries's avatar
 
Dries committed
9 10
function taxonomy_feed($taxonomy) {
  global $id, $type;
Dries's avatar
 
Dries committed
11

Kjartan's avatar
Kjartan committed
12
  if ($type == "voc") {
Dries's avatar
 
Dries committed
13
    //TODO - vocabulary feed.
Kjartan's avatar
Kjartan committed
14 15
  }
  else {
Dries's avatar
 
Dries committed
16 17
    $result = taxonomy_select_nodes($taxonomy, 0);
    $term = taxonomy_get_term($taxonomy->tids[0]);
Dries's avatar
 
Dries committed
18
    $channel["link"] = url("taxonomy/view/$taxonomy->operator/$taxonomy->str_tids");
Kjartan's avatar
Kjartan committed
19 20 21
    $channel["title"] = variable_get("site_name", "drupal") ." - ". $term->name;
    $channel["description"] = $term->description;
    node_feed($result, $channel);
Dries's avatar
 
Dries committed
22
  }
Kjartan's avatar
Kjartan committed
23
}
Dries's avatar
 
Dries committed
24

Kjartan's avatar
Kjartan committed
25 26 27
function taxonomy_perm() {
  return array("administer taxonomy");
}
Dries's avatar
 
Dries committed
28

Dries's avatar
 
Dries committed
29
function taxonomy_link($type, $node = NULL) {
Kjartan's avatar
Kjartan committed
30
  if ($type == "admin" && user_access("administer taxonomy")) {
Dries's avatar
 
Dries committed
31
    $help["taxonomy"] = "The taxonomy module allows you to classify posts 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).";
Dries's avatar
 
Dries committed
32
    $help["vocabulary"] = "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 Slashdot.org's or Kuro5hin.org's sections. For more complex implementations, you might create a hierarchical list of categories.";
Dries's avatar
 
Dries committed
33

Dries's avatar
 
Dries committed
34
    menu("admin/taxonomy", "taxonomy", "taxonomy_admin", $help["taxonomy"], 3);
35
    menu("admin/taxonomy/add/vocabulary", "create new vocabulary", "taxonomy_admin", $help["vocabulary"]);
Dries's avatar
 
Dries committed
36
    menu("admin/taxonomy/help", "help", "taxonomy_admin", NULL, 9);
Dries's avatar
 
Dries committed
37
  }
Dries's avatar
 
Dries committed
38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54
  else if ($type == "taxonomy terms" && $node != NULL) {
    /*
    ** Themes can print taxonomy links with:
    **
    ** if (module_exist("taxonomy")) {
    **   $this->links(taxonomy_link("taxonomy terms", $node));
    ** }
    */

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

    return $links;
  }
Kjartan's avatar
Kjartan committed
55 56
}

Dries's avatar
 
Dries committed
57 58 59 60
/*
** admin pages (form, save, overview)
*/

Kjartan's avatar
Kjartan committed
61 62 63 64
function taxonomy_form_vocabulary($edit = array()) {
  foreach (module_list() as $name) {
    if (module_hook($name, "node")) {
      $nodetypes[$name] = $name;
Dries's avatar
 
Dries committed
65
    }
Kjartan's avatar
Kjartan committed
66
  }
Dries's avatar
 
Dries committed
67

Dries's avatar
 
Dries committed
68 69 70
  $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."));
  $form .= form_select(t("Types"), "types", explode(",", $edit["types"]), $nodetypes, t("Required") . ". " . t("A list of node types you want to associate this vocabulary with."), "", 1);
Dries's avatar
 
Dries committed
71 72
  $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's avatar
 
Dries committed
73 74
  $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's avatar
 
Dries committed
75
  $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's avatar
 
Dries committed
76
  $form .= form_submit(t("Submit"));
Dries's avatar
 
Dries committed
77

Kjartan's avatar
Kjartan committed
78
  if ($edit["vid"]) {
Dries's avatar
 
Dries committed
79
    $form .= form_submit(t("Delete"));
Kjartan's avatar
Kjartan committed
80
    $form .= form_hidden("vid", $edit["vid"]);
Dries's avatar
 
Dries committed
81 82
  }

Kjartan's avatar
Kjartan committed
83 84
  return form($form);
}
Kjartan's avatar
Kjartan committed
85

Kjartan's avatar
Kjartan committed
86 87 88
function taxonomy_save_vocabulary($edit) {
  $data = array("name" => $edit["name"], "types" => @implode(",", $edit["types"]), "description" => $edit["description"], "multiple" => $edit["multiple"], "required" => $edit["required"], "hierarchy" => $edit["hierarchy"], "relations" => $edit["relations"], "weight" => $edit["weight"]);
  if ($edit["vid"] && $edit["name"]) {
Dries's avatar
 
Dries committed
89
    db_query("UPDATE vocabulary SET ". _prepare_update($data) ." WHERE vid = '%d'", $edit["vid"]);
Dries's avatar
 
Dries committed
90 91
    module_invoke_all("taxonomy", "update", "vocabulary", $edit);
    $message = t("updated vocabulary '%name'.", array("%name" => $edit["name"]));
Dries's avatar
 
Dries committed
92
  }
Kjartan's avatar
Kjartan committed
93
  else if ($edit["vid"]) {
Dries's avatar
 
Dries committed
94
    $message = taxonomy_del_vocabulary($edit["vid"]);
Kjartan's avatar
Kjartan committed
95 96
  }
  else {
Dries's avatar
 
Dries committed
97
    $data["vid"] = $edit["vid"] = db_next_id("vocabulary");
Kjartan's avatar
Kjartan committed
98
    db_query("INSERT INTO vocabulary ". _prepare_insert($data, 1) ." VALUES ". _prepare_insert($data, 2));
Dries's avatar
 
Dries committed
99 100
    module_invoke_all("taxonomy", "insert", "vocabulary", $edit);
    $message = t("created new vocabulary '%name'.", array("%name" => $edit["name"]));
Kjartan's avatar
Kjartan committed
101
  }
Dries's avatar
 
Dries committed
102 103

  cache_clear_all();
Dries's avatar
 
Dries committed
104 105

  return $message;
Kjartan's avatar
Kjartan committed
106
}
Dries's avatar
 
Dries committed
107

Kjartan's avatar
Kjartan committed
108
function taxonomy_del_vocabulary($vid) {
Dries's avatar
 
Dries committed
109 110
  $vocabulary = taxonomy_get_vocabulary($vid);

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

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

Dries's avatar
 
Dries committed
119 120
  cache_clear_all();

Dries's avatar
 
Dries committed
121 122 123 124 125 126 127 128 129 130 131 132 133
  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's avatar
Kjartan committed
134
}
Dries's avatar
 
Dries committed
135

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

Dries's avatar
 
Dries committed
140 141
  $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's avatar
 
Dries committed
142

Kjartan's avatar
Kjartan committed
143 144
  if ($vocabulary->hierarchy) {
    $parent = array_keys(taxonomy_get_parents($edit["tid"]));
Dries's avatar
 
Dries committed
145
    $children = taxonomy_get_tree($vocabulary_id, $edit["tid"]);
Dries's avatar
 
Dries committed
146 147 148 149 150

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

Kjartan's avatar
Kjartan committed
153
    if ($vocabulary->hierarchy == 1) {
Dries's avatar
 
Dries committed
154
      $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's avatar
 
Dries committed
155
    }
Kjartan's avatar
Kjartan committed
156
    elseif ($vocabulary->hierarchy == 2) {
Dries's avatar
 
Dries committed
157
      $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's avatar
 
Dries committed
158
    }
Kjartan's avatar
Kjartan committed
159
  }
Dries's avatar
 
Dries committed
160

161 162 163 164
  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's avatar
 
Dries committed
165
  $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's avatar
 
Dries committed
166
  $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's avatar
Kjartan committed
167
  $form .= form_hidden("vid", $vocabulary->vid);
Dries's avatar
 
Dries committed
168
  $form .= form_submit(t("Submit"));
Kjartan's avatar
Kjartan committed
169 170

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

Kjartan's avatar
Kjartan committed
175 176
  return form($form);
}
Dries's avatar
 
Dries committed
177

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

Dries's avatar
 
Dries committed
182
    db_query("UPDATE term_data SET ". _prepare_update($data) ." WHERE tid = '%d'", $edit["tid"]);
Dries's avatar
 
Dries committed
183
    module_invoke_all("taxonomy", "update", "term", $edit);
Dries's avatar
 
Dries committed
184
    $message = t("the term '%a' has been updated.", array("%a" => $edit["name"]));
Kjartan's avatar
Kjartan committed
185 186
  }
  else if ($edit["tid"]) {
Dries's avatar
 
Dries committed
187
    return taxonomy_del_term($edit["tid"]);
Kjartan's avatar
Kjartan committed
188 189
  }
  else {
Dries's avatar
 
Dries committed
190
    $edit["tid"] = db_next_id("term_data");
Kjartan's avatar
Kjartan committed
191 192
    $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's avatar
 
Dries committed
193
    module_invoke_all("taxonomy", "insert", "term", $edit);
Dries's avatar
 
Dries committed
194
    $message = t("created new term '%name'.", array("%name" => $edit["name"]));
Kjartan's avatar
Kjartan committed
195
  }
Dries's avatar
 
Dries committed
196

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

Kjartan's avatar
Kjartan committed
207
  // hierarchy
Dries's avatar
 
Dries committed
208
  db_query("DELETE FROM term_hierarchy WHERE tid = '%d'", $edit["tid"]);
Kjartan's avatar
Kjartan committed
209 210 211 212 213
  if (!isset($edit["parent"])) {
    $edit["parent"] = 0;
  }
  if (is_array($edit["parent"])) {
    foreach ($edit["parent"] as $parent) {
Dries's avatar
 
Dries committed
214
      db_query("INSERT INTO term_hierarchy (tid, parent) VALUES ('%d', '%d')", $edit["tid"], $parent);
Dries's avatar
 
Dries committed
215
    }
Kjartan's avatar
Kjartan committed
216 217
  }
  else {
Dries's avatar
 
Dries committed
218
    db_query("INSERT INTO term_hierarchy (tid, parent) VALUES ('%d', '%d')", $edit["tid"], $edit["parent"][0]);
Dries's avatar
 
Dries committed
219 220
  }

Dries's avatar
 
Dries committed
221
  db_query("DELETE FROM term_synonym WHERE tid = '%d'", $edit["tid"]);
Kjartan's avatar
Kjartan committed
222
  if ($edit["synonyms"]) {
Dries's avatar
 
Dries committed
223 224 225 226
    foreach (explode ("\n", str_replace("\r", "", $edit["synonyms"])) as $synonym) {
      if ($synonym) {
        db_query("INSERT INTO term_synonym (tid, name) VALUES ('%d', '%s')", $edit["tid"], chop($synonym));
      }
Kjartan's avatar
Kjartan committed
227
    }
Dries's avatar
 
Dries committed
228
  }
Dries's avatar
 
Dries committed
229

Dries's avatar
 
Dries committed
230 231
  cache_clear_all();

Dries's avatar
 
Dries committed
232
  return $message;
Kjartan's avatar
Kjartan committed
233
}
Dries's avatar
 
Dries committed
234

Kjartan's avatar
Kjartan committed
235
function taxonomy_del_term($tid) {
Dries's avatar
 
Dries committed
236 237
  $term = taxonomy_get_term($tid);

Dries's avatar
 
Dries committed
238 239 240 241 242
  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's avatar
 
Dries committed
243

Dries's avatar
 
Dries committed
244
  module_invoke_all("taxonomy", "delete", "term", $term);
Dries's avatar
 
Dries committed
245 246
  cache_clear_all();

Dries's avatar
 
Dries committed
247 248 249 250 251 252 253 254 255 256 257 258 259
  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's avatar
Kjartan committed
260
}
Dries's avatar
 
Dries committed
261

Kjartan's avatar
Kjartan committed
262
function taxonomy_overview() {
Dries's avatar
 
Dries committed
263

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

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

Kjartan's avatar
Kjartan committed
268 269 270
  $vocabularies = taxonomy_get_vocabularies();
  foreach ($vocabularies as $vocabulary) {
    $links = array();
271
    $rows[] = array($vocabulary->name, array("data" => $vocabulary->types, "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"));
Kjartan's avatar
Kjartan committed
272

Dries's avatar
 
Dries committed
273
    $tree = taxonomy_get_tree($vocabulary->vid);
Kjartan's avatar
Kjartan committed
274
    if ($tree) {
Dries's avatar
 
Dries committed
275
      unset($data);
Kjartan's avatar
Kjartan committed
276
      foreach ($tree as $term) {
277
        $data .= _taxonomy_depth($term->depth) ." ". $term->name ." (". l(t("edit term"), "admin/taxonomy/edit/term/$term->tid") .")<br />";
Dries's avatar
 
Dries committed
278
      }
Dries's avatar
 
Dries committed
279
      $rows[] = array(array("data" => $data, "colspan" => 5));
Dries's avatar
 
Dries committed
280 281 282
    }
  }

Dries's avatar
 
Dries committed
283
  return table($header, $rows);
Kjartan's avatar
Kjartan committed
284 285 286 287 288 289 290 291 292 293
}

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

Kjartan's avatar
Kjartan committed
297
  if ($vocabulary->multiple) {
Dries's avatar
 
Dries committed
298
    $description = t("You $verb choose one or more terms for this node.");
Kjartan's avatar
Kjartan committed
299
    $multiple = 1;
Dries's avatar
 
Dries committed
300
  }
Kjartan's avatar
Kjartan committed
301
  else {
Dries's avatar
 
Dries committed
302
    $description = t("You $verb choose one term for this node.");
Kjartan's avatar
Kjartan committed
303 304 305 306
    $multiple = 0;
  }
  return _taxonomy_term_select($vocabulary->name, "taxonomy", $value, $vocabulary_id, $description, $multiple, $blank);
}
Dries's avatar
 
Dries committed
307 308 309 310 311

/*
** API functions
*/

Kjartan's avatar
Kjartan committed
312 313 314 315 316 317 318 319 320 321 322
// return array of vocabularies, as objects
function taxonomy_get_vocabularies($type = '', $key = "vid") {
  if ($type) {
    $result = db_query("SELECT * FROM vocabulary WHERE types LIKE '%%%s%%' ORDER BY weight, name", $type);
  }
  else {
    $result = db_query("SELECT * FROM vocabulary ORDER BY weight, name");
  }
  $vocabularies = array();
  while ($voc = db_fetch_object($result)) {
    $vocabularies[$voc->$key] = $voc;
Dries's avatar
 
Dries committed
323
  }
Kjartan's avatar
Kjartan committed
324 325
  return $vocabularies;
}
Dries's avatar
 
Dries committed
326

Kjartan's avatar
Kjartan committed
327 328 329 330 331
// 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's avatar
Kjartan committed
332 333
    }
    else {
Kjartan's avatar
Kjartan committed
334
      $terms = 0;
Dries's avatar
 
Dries committed
335
    }
Kjartan's avatar
Kjartan committed
336 337 338 339
  }
  else {
    $terms = $node->taxonomy;
  }
Dries's avatar
 
Dries committed
340

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

Kjartan's avatar
Kjartan committed
348 349
// 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's avatar
 
Dries committed
350
  $term_name = db_result(db_query("SELECT name FROM term_data WHERE tid = '%d'", $tid));
Dries's avatar
 
Dries committed
351

Dries's avatar
 
Dries committed
352
  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's avatar
Kjartan committed
353 354 355 356
}

// 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's avatar
 
Dries committed
357
  $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's avatar
Kjartan committed
358 359 360
  $terms = array();
  while ($term = db_fetch_object($result)) {
    $terms[$term->$key] = $term;
Dries's avatar
 
Dries committed
361
  }
Kjartan's avatar
Kjartan committed
362 363 364 365 366 367
  return $terms;
}

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

Dries's avatar
 
Dries committed
369
  if (!isset($terms[$nid])) {
Dries's avatar
 
Dries committed
370
    $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's avatar
Kjartan committed
371
    $terms[$nid] = array();
Dries's avatar
 
Dries committed
372
    while ($term = db_fetch_object($result)) {
Kjartan's avatar
Kjartan committed
373
      $terms[$nid][$term->$key] = $term;
Dries's avatar
 
Dries committed
374 375
    }
  }
Kjartan's avatar
Kjartan committed
376 377
  return $terms[$nid];
}
Dries's avatar
 
Dries committed
378

Kjartan's avatar
Kjartan committed
379 380 381
// save terms of a node
function taxonomy_node_save($nid, $terms) {
  taxonomy_node_delete($nid);
Dries's avatar
 
Dries committed
382

Kjartan's avatar
Kjartan committed
383
  if ($terms) {
Dries's avatar
 
Dries committed
384 385
    foreach ($terms as $term) {
      db_query("INSERT INTO term_node (nid, tid) VALUES ('%d', '%d')", $nid, $term);
Dries's avatar
 
Dries committed
386 387
    }
  }
Kjartan's avatar
Kjartan committed
388
}
Dries's avatar
 
Dries committed
389

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

Kjartan's avatar
Kjartan committed
395 396 397
// relations: return array of related terms
function taxonomy_get_related($tid, $key = "tid") {
  if ($tid) {
Dries's avatar
 
Dries committed
398
    $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's avatar
Kjartan committed
399 400 401
    $related = array();
    while ($term = db_fetch_object($result)) {
      $related[$term->$key] = $term;
Dries's avatar
 
Dries committed
402
    }
Kjartan's avatar
Kjartan committed
403
    return $related;
Dries's avatar
 
Dries committed
404
  }
Kjartan's avatar
Kjartan committed
405 406
  else {
    return array();
Dries's avatar
 
Dries committed
407
  }
Kjartan's avatar
Kjartan committed
408
}
Dries's avatar
 
Dries committed
409

Kjartan's avatar
Kjartan committed
410 411 412
// hierarchy: get parent terms
function taxonomy_get_parents($tid, $key = "tid") {
  if ($tid) {
Dries's avatar
 
Dries committed
413
    $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's avatar
Kjartan committed
414 415 416
    $parents = array();
    while ($parent = db_fetch_object($result)) {
      $parents[$parent->$key] = $parent;
Dries's avatar
 
Dries committed
417
    }
Kjartan's avatar
Kjartan committed
418
    return $parents;
Dries's avatar
 
Dries committed
419
  }
Kjartan's avatar
Kjartan committed
420 421 422 423
  else {
    return array();
  }
}
Dries's avatar
 
Dries committed
424

Kjartan's avatar
Kjartan committed
425 426 427
// hierarchy: get children
function taxonomy_get_children($tid, $vid = 0, $key = "tid") {
  if ($vid) {
Dries's avatar
 
Dries committed
428
    $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's avatar
 
Dries committed
429
  }
Kjartan's avatar
Kjartan committed
430
  else {
Dries's avatar
 
Dries committed
431
    $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's avatar
Kjartan committed
432 433 434 435 436 437 438
  }
  $children = array();
  while ($term = db_fetch_object($result)) {
    $children[$term->$key] = $term;
  }
  return $children;
}
Dries's avatar
 
Dries committed
439

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

Kjartan's avatar
Kjartan committed
444
  $depth++;
Dries's avatar
 
Dries committed
445

Dries's avatar
 
Dries committed
446 447 448 449
  // 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's avatar
 
Dries committed
450 451
    $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);
    while ($term = db_fetch_object($result)) {
Dries's avatar
 
Dries committed
452 453 454
      $children[$vocabulary_id][$term->parent][] = $term->tid;
      $parents[$vocabulary_id][$term->tid][] = $term->parent;
      $terms[$vocabulary_id][$term->tid] = $term;
Dries's avatar
 
Dries committed
455 456
    }
  }
Dries's avatar
 
Dries committed
457

Dries's avatar
 
Dries committed
458 459 460 461 462 463
  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's avatar
 
Dries committed
464

Dries's avatar
 
Dries committed
465
      $tree = array_merge($tree, taxonomy_get_tree($vocabulary_id, $child, $depth));
Dries's avatar
 
Dries committed
466
    }
Kjartan's avatar
Kjartan committed
467
  }
Dries's avatar
 
Dries committed
468

Dries's avatar
 
Dries committed
469
  return $tree ? $tree : array();
Kjartan's avatar
Kjartan committed
470
}
Dries's avatar
 
Dries committed
471

Kjartan's avatar
Kjartan committed
472 473 474
// synonyms: return array of synonyms
function taxonomy_get_synonyms($tid) {
  if ($tid) {
Dries's avatar
 
Dries committed
475
    $result = db_query("SELECT name FROM term_synonym WHERE tid = '%d'", $tid);
Kjartan's avatar
Kjartan committed
476 477
    while ($synonym = db_fetch_array($result)) {
      $synonyms[] = $synonym["name"];
Dries's avatar
 
Dries committed
478
    }
Kjartan's avatar
Kjartan committed
479
    return $synonyms ? $synonyms : array();
Dries's avatar
 
Dries committed
480
  }
Kjartan's avatar
Kjartan committed
481 482
  else {
    return array();
Dries's avatar
 
Dries committed
483
  }
Kjartan's avatar
Kjartan committed
484
}
Dries's avatar
 
Dries committed
485

Kjartan's avatar
Kjartan committed
486 487 488 489
// 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's avatar
 
Dries committed
490

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

Dries's avatar
 
Dries committed
495 496 497
  if (!isset($count[$type])) {
    // $type == 0 always evaluates true is $type is a string
    if (is_numeric($type)) {
Dries's avatar
 
Dries committed
498
      $result = db_query("SELECT t.tid, COUNT(*) AS c FROM term_node t GROUP BY t.tid");
Dries's avatar
 
Dries committed
499 500
    }
    else {
Dries's avatar
 
Dries committed
501
      $result = db_query("SELECT t.tid, COUNT(*) AS c FROM term_node t, node n WHERE t.nid = n.nid AND n.type = '%s' GROUP BY t.tid", $type);
Dries's avatar
 
Dries committed
502
    }
Kjartan's avatar
Kjartan committed
503
    while ($term = db_fetch_object($result)) {
Dries's avatar
 
Dries committed
504
      $count[$type][$term->tid] = $term->c;
Dries's avatar
 
Dries committed
505 506 507
    }
  }

Kjartan's avatar
Kjartan committed
508
  foreach (_taxonomy_term_children($tid) as $c) {
Dries's avatar
 
Dries committed
509
    $children_count += taxonomy_term_count_nodes($c, $type);
Kjartan's avatar
Kjartan committed
510
  }
Dries's avatar
 
Dries committed
511
  return $count[$type][$tid] + $children_count;
Kjartan's avatar
Kjartan committed
512 513 514 515 516
}

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

Dries's avatar
 
Dries committed
518
  if (!isset($children)) {
Kjartan's avatar
Kjartan committed
519 520 521
    $result = db_query("SELECT tid, parent FROM term_hierarchy");
    while ($term = db_fetch_object($result)) {
      $children[$term->parent][] = $term->tid;
Dries's avatar
 
Dries committed
522
    }
Dries's avatar
 
Dries committed
523
  }
Kjartan's avatar
Kjartan committed
524 525
  return $children[$tid] ? $children[$tid] : array();
}
Dries's avatar
 
Dries committed
526

Dries's avatar
 
Dries committed
527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564
/**
 * 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's avatar
Kjartan committed
565 566
function taxonomy_get_vocabulary($vid) {
  // simple cache using a static var?
Dries's avatar
 
Dries committed
567
  return db_fetch_object(db_query("SELECT * FROM vocabulary WHERE vid = '%d'", $vid));
Kjartan's avatar
Kjartan committed
568
}
Dries's avatar
 
Dries committed
569

Kjartan's avatar
Kjartan committed
570 571
function taxonomy_get_term($tid) {
  // simple cache using a static var?
Dries's avatar
 
Dries committed
572
  return db_fetch_object(db_query("SELECT * FROM term_data WHERE tid = '%d'", $tid));
Kjartan's avatar
Kjartan committed
573
}
Dries's avatar
 
Dries committed
574 575 576 577 578

/*
** service functions
*/

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

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

Kjartan's avatar
Kjartan committed
586 587 588
  if ($tree) {
    foreach ($tree as $term) {
      if (!in_array($term->tid, $exclude)) {
Dries's avatar
 
Dries committed
589
        $options[] = array("tid" => $term->tid, "name" => _taxonomy_depth($term->depth, '-').$term->name);
Dries's avatar
 
Dries committed
590 591
      }
    }
Kjartan's avatar
Kjartan committed
592 593 594 595 596
    if (!$blank && !$value) {
      // required but without a predefined value, so set first as predefined
      $value = $tree[0]->tid;
    }
  }
Dries's avatar
 
Dries committed
597

Kjartan's avatar
Kjartan committed
598
  if (count($options) > 0) {
Dries's avatar
 
Dries committed
599 600
    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's avatar
Kjartan committed
601
    }
Dries's avatar
 
Dries committed
602

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

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

Kjartan's avatar
Kjartan committed
609 610 611
function _taxonomy_depth($depth, $graphic = '--') {
  for ($n = 0; $n < $depth; $n++) {
    $result .= $graphic;
Dries's avatar
 
Dries committed
612
  }
Kjartan's avatar
Kjartan committed
613 614
  return $result;
}
Dries's avatar
 
Dries committed
615

Kjartan's avatar
Kjartan committed
616 617 618
function _prepare_update($data) {
  foreach ($data as $key => $value) {
    $q[] = "$key = '". check_query($value) ."'";
Dries's avatar
 
Dries committed
619
  }
Kjartan's avatar
Kjartan committed
620 621 622
  $result = implode(", ", $q);
  return $result;
}
Dries's avatar
 
Dries committed
623

Kjartan's avatar
Kjartan committed
624 625 626 627 628 629 630
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's avatar
 
Dries committed
631
    }
Kjartan's avatar
Kjartan committed
632
    $result = implode(", ", $q);
Dries's avatar
 
Dries committed
633
  }
Kjartan's avatar
Kjartan committed
634 635
  return "($result)";
}
Dries's avatar
 
Dries committed
636

Dries's avatar
 
Dries committed
637 638 639 640 641 642 643 644 645
/*
** 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->operator == "or") {
Dries's avatar
 
Dries committed
646
    $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 tid IN ($taxonomy->str_tids) AND n.status = '1' ORDER BY static DESC, created DESC";
Dries's avatar
 
Dries committed
647 648 649 650 651 652 653 654 655 656 657 658 659 660
    $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 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 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";

    // 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 tid IN ($taxonomy->str_tids) AND n.status = '1' GROUP BY n.nid HAVING COUNT(n.nid) = ". count($taxonomy->tids)));
    $sql_count = "SELECT $count";
  }

  if ($pager) {
    $result = pager_query($sql, variable_get("default_nodes_main", 10) , 0, $sql_count);
  }
  else {
Dries's avatar
 
Dries committed
661
    $result = db_query_range($sql, 0, 15);
Dries's avatar
 
Dries committed
662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678
  }

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

Kjartan's avatar
Kjartan committed
679
function taxonomy_page() {
Dries's avatar
 
Dries committed
680

Dries's avatar
 
Dries committed
681 682 683 684 685 686

  // 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's avatar
 
Dries committed
687

Dries's avatar
 
Dries committed
688
  switch (arg(1)) {
Kjartan's avatar
Kjartan committed
689
    case "feed":
Dries's avatar
 
Dries committed
690
      taxonomy_feed($taxonomy);
Kjartan's avatar
Kjartan committed
691 692
      break;
    default:
Dries's avatar
 
Dries committed
693
      theme("header");
Dries's avatar
 
Dries committed
694
      taxonomy_render_nodes(taxonomy_select_nodes($taxonomy));
Dries's avatar
 
Dries committed
695
      theme("footer");
Dries's avatar
 
Dries committed
696
      break;
Dries's avatar
 
Dries committed
697
  }
Kjartan's avatar
Kjartan committed
698
}
Dries's avatar
 
Dries committed
699

Kjartan's avatar
Kjartan committed
700
/*
Dries's avatar
 
Dries committed
701 702 703
** admin
*/

Kjartan's avatar
Kjartan committed
704
function taxonomy_admin() {
Dries's avatar
 
Dries committed
705
  global $op, $edit;
Kjartan's avatar
Kjartan committed
706 707

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

Kjartan's avatar
Kjartan committed
712
    switch ($op) {
713 714 715 716 717
      case "add":
        if (arg(3) == "vocabulary")
          $output .= taxonomy_form_vocabulary();
        else if (arg(3) == "term")
          $output .= taxonomy_form_term();
Dries's avatar
 
Dries committed
718
        break;
719 720 721 722 723
      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's avatar
Kjartan committed
724 725
        break;
      case "preview":
726
        $output .= taxonomy_form(arg(4));
Kjartan's avatar
Kjartan committed
727 728
        break;
      case "help":
729
        $output .= taxonomy_help();
Kjartan's avatar
Kjartan committed
730
        break;
Dries's avatar
 
Dries committed
731
      case t("Delete"):
Dries's avatar
 
Dries committed
732
        if (!$edit["confirm"]) {
Dries's avatar
 
Dries committed
733
          if (arg(3) == "vocabulary") {
734
            $output .= _taxonomy_confirm_del_vocabulary($edit["vid"]);
Dries's avatar
 
Dries committed
735 736
          }
          else {
737
            $output .= _taxonomy_confirm_del_term($edit["tid"]);
Dries's avatar
 
Dries committed
738 739 740 741 742 743 744
          }
          break;
        }
        else {
          $edit["name"] = 0;
          // fall through:
        }
Dries's avatar
 
Dries committed
745
      case t("Submit"):
746 747
        if (arg(3) == "vocabulary") {
          $output .= status(taxonomy_save_vocabulary($edit));
Kjartan's avatar
Kjartan committed
748 749
        }
        else {
Dries's avatar
 
Dries committed
750
          $output .= status(taxonomy_save_term($edit));
Dries's avatar
 
Dries committed
751 752
          if (!$edit["tid"]) {
            // if INSERT show form again
753
            $output .= taxonomy_form_term();
Dries's avatar
 
Dries committed
754 755 756
            break;
          }
          // else (UPDATE or DELETE) fall through
Kjartan's avatar
Kjartan committed
757
        }
Kjartan's avatar
Kjartan committed
758 759
        // fall through:
      default:
760
        $output .= taxonomy_overview();
Kjartan's avatar
Kjartan committed
761 762 763
    }
  }
  else {
764
    $output .= message_access();
Kjartan's avatar
Kjartan committed
765
  }
Dries's avatar
 
Dries committed
766

767
  return $output;
Kjartan's avatar
Kjartan committed
768 769 770
}

function taxonomy_help() {
771
?>
Dries's avatar
 
Dries committed
772
  <h3>Background</h3>
Dries's avatar
 
Dries committed
773
  <p>Classifying nodes allows for the organization of content into categories and subcategories of description. These categories can be used to organize and retrieve similarly described content. Drupal's <i>taxonomy.module</i> is an extremely flexible classification system that allows for 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). For details about <a href="http://www.eleganthack.com/archives/002165.html#002165">classification types</a> and insight into the development of <i>taxonomy.module</i>, see this <a href="http://www.drupal.org/node/view/55">drupal.org discussion</a>.</p>
Dries's avatar
 
Dries committed
774 775

  <h3>An example taxonomy: food</h3>
Dries's avatar
 
Dries committed
776 777 778 779 780
  <p>Dairy<br />
  --Milk<br />
  Drink<br />
  --Alchohol<br />
  --Pop<br />
Kjartan's avatar
Kjartan committed
781
  --Milk<br />
Dries's avatar
 
Dries committed
782 783 784 785 786
  Meat<br />
  --Beef<br />
  --Chicken<br />
  --Lamb<br />
  Spices<br />
Kjartan's avatar
Kjartan committed
787
  --Sugar</p>
Dries's avatar
 
Dries committed
788 789 790 791 792 793
  <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>nmultiple parents</i> for a term.</li>
   <li>The order of siblings (e.g. <i>Beef</i>, <i>Chicken</i>, <i>Lamb</i>) in the taxonomy may be controlled with the <i>weight</i> parameter. </li>
  </ul>

Kjartan's avatar
Kjartan committed
794
  <h3>Vocabularies</h3>
Dries's avatar
 
Dries committed
795
  <p>When you create a controlled vocabulary you ar