taxonomy.module 32.9 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);
Dries's avatar
 
Dries committed
35
    menu("admin/taxonomy/addvocabulary", "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()) {
Dries's avatar
 
Dries committed
137
  $vocabulary_id = arg(3);
Dries's avatar
 
Dries committed
138

Kjartan's avatar
Kjartan committed
139 140 141 142
  if (!$vocabulary_id) {
    $vocabulary_id = $edit["vid"];
  }
  $vocabulary = taxonomy_get_vocabulary($vocabulary_id);
Dries's avatar
 
Dries committed
143

Dries's avatar
 
Dries committed
144 145
  $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
146

Kjartan's avatar
Kjartan committed
147
  if ($vocabulary->relations) {
Dries's avatar
 
Dries committed
148
    $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"]));
Kjartan's avatar
Kjartan committed
149
  }
Dries's avatar
 
Dries committed
150

Kjartan's avatar
Kjartan committed
151 152
  if ($vocabulary->hierarchy) {
    $parent = array_keys(taxonomy_get_parents($edit["tid"]));
Dries's avatar
 
Dries committed
153
    $children = taxonomy_get_tree($vocabulary_id, $edit["tid"]);
Dries's avatar
 
Dries committed
154 155 156 157 158

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

Kjartan's avatar
Kjartan committed
161
    if ($vocabulary->hierarchy == 1) {
Dries's avatar
 
Dries committed
162
      $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
163
    }
Kjartan's avatar
Kjartan committed
164
    elseif ($vocabulary->hierarchy == 2) {
Dries's avatar
 
Dries committed
165
      $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
166
    }
Kjartan's avatar
Kjartan committed
167
  }
Dries's avatar
 
Dries committed
168

Dries's avatar
 
Dries committed
169
  $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
170
  $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
171
  $form .= form_hidden("vid", $vocabulary->vid);
Dries's avatar
 
Dries committed
172
  $form .= form_submit(t("Submit"));
Kjartan's avatar
Kjartan committed
173 174

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

Kjartan's avatar
Kjartan committed
179 180
  return form($form);
}
Dries's avatar
 
Dries committed
181

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

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

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

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

Dries's avatar
 
Dries committed
225
  db_query("DELETE FROM term_synonym WHERE tid = '%d'", $edit["tid"]);
Kjartan's avatar
Kjartan committed
226
  if ($edit["synonyms"]) {
Dries's avatar
 
Dries committed
227 228 229 230
    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
231
    }
Dries's avatar
 
Dries committed
232
  }
Dries's avatar
 
Dries committed
233

Dries's avatar
 
Dries committed
234 235
  cache_clear_all();

Dries's avatar
 
Dries committed
236
  return $message;
Kjartan's avatar
Kjartan committed
237
}
Dries's avatar
 
Dries committed
238

Kjartan's avatar
Kjartan committed
239
function taxonomy_del_term($tid) {
Dries's avatar
 
Dries committed
240 241
  $term = taxonomy_get_term($tid);

Dries's avatar
 
Dries committed
242 243 244 245 246
  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
247

Dries's avatar
 
Dries committed
248
  module_invoke_all("taxonomy", "delete", "term", $term);
Dries's avatar
 
Dries committed
249 250
  cache_clear_all();

Dries's avatar
 
Dries committed
251 252 253 254 255 256 257 258 259 260 261 262 263
  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
264
}
Dries's avatar
 
Dries committed
265

Kjartan's avatar
Kjartan committed
266
function taxonomy_overview() {
Dries's avatar
 
Dries committed
267

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

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

Kjartan's avatar
Kjartan committed
272 273 274
  $vocabularies = taxonomy_get_vocabularies();
  foreach ($vocabularies as $vocabulary) {
    $links = array();
Dries's avatar
 
Dries committed
275

Dries's avatar
 
Dries committed
276
    $rows[] = array($vocabulary->name, array("data" => $vocabulary->types, "align" => "center"), l(t("edit vocabulary"), "admin/taxonomy/editvocabulary/$vocabulary->vid"), l(t("add term"), "admin/taxonomy/addterm/$vocabulary->vid"), l(t("preview form"), "admin/taxonomy/preview/vocabulary/$vocabulary->vid"));
Kjartan's avatar
Kjartan committed
277

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

Dries's avatar
 
Dries committed
288
  return table($header, $rows);
Kjartan's avatar
Kjartan committed
289 290 291 292 293 294 295 296 297 298
}

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
299
    $blank = "<" . t("none") . ">";
Kjartan's avatar
Kjartan committed
300
  }
Dries's avatar
 
Dries committed
301

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

/*
** API functions
*/

Kjartan's avatar
Kjartan committed
317 318 319 320 321 322 323 324 325 326 327
// 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
328
  }
Kjartan's avatar
Kjartan committed
329 330
  return $vocabularies;
}
Dries's avatar
 
Dries committed
331

Kjartan's avatar
Kjartan committed
332 333 334 335 336
// 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
337 338
    }
    else {
Kjartan's avatar
Kjartan committed
339
      $terms = 0;
Dries's avatar
 
Dries committed
340
    }
Kjartan's avatar
Kjartan committed
341 342 343 344
  }
  else {
    $terms = $node->taxonomy;
  }
Dries's avatar
 
Dries committed
345

Kjartan's avatar
Kjartan committed
346 347 348
  $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
349
  }
Kjartan's avatar
Kjartan committed
350 351
  return $result ? $result : array();
}
Dries's avatar
 
Dries committed
352

Kjartan's avatar
Kjartan committed
353 354 355
// 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) {
  $term_name = db_result(db_query("SELECT name FROM term_data WHERE tid = '%s'", $tid));
Dries's avatar
 
Dries committed
356

Dries's avatar
 
Dries committed
357
  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
358 359 360 361
}

// 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
362
  $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
363 364 365
  $terms = array();
  while ($term = db_fetch_object($result)) {
    $terms[$term->$key] = $term;
Dries's avatar
 
Dries committed
366
  }
Kjartan's avatar
Kjartan committed
367 368 369 370 371 372
  return $terms;
}

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

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

Kjartan's avatar
Kjartan committed
384 385 386
// save terms of a node
function taxonomy_node_save($nid, $terms) {
  taxonomy_node_delete($nid);
Dries's avatar
 
Dries committed
387

Kjartan's avatar
Kjartan committed
388
  if ($terms) {
Dries's avatar
 
Dries committed
389 390
    foreach ($terms as $term) {
      db_query("INSERT INTO term_node (nid, tid) VALUES ('%d', '%d')", $nid, $term);
Dries's avatar
 
Dries committed
391 392
    }
  }
Kjartan's avatar
Kjartan committed
393
}
Dries's avatar
 
Dries committed
394

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

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

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

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

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

Kjartan's avatar
Kjartan committed
449
  $depth++;
Dries's avatar
 
Dries committed
450

Dries's avatar
 
Dries committed
451 452 453 454
  // 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
455 456
    $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
457 458 459
      $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
460 461
    }
  }
Dries's avatar
 
Dries committed
462

Dries's avatar
 
Dries committed
463 464 465 466 467 468
  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
469

Dries's avatar
 
Dries committed
470
      $tree = array_merge($tree, taxonomy_get_tree($vocabulary_id, $child, $depth));
Dries's avatar
 
Dries committed
471
    }
Kjartan's avatar
Kjartan committed
472
  }
Dries's avatar
 
Dries committed
473

Dries's avatar
 
Dries committed
474
  return $tree ? $tree : array();
Kjartan's avatar
Kjartan committed
475
}
Dries's avatar
 
Dries committed
476

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

Kjartan's avatar
Kjartan committed
491 492 493 494
// 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
495

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

Dries's avatar
 
Dries committed
500 501 502
  if (!isset($count[$type])) {
    // $type == 0 always evaluates true is $type is a string
    if (is_numeric($type)) {
Dries's avatar
 
Dries committed
503
      $result = db_query("SELECT t.tid, COUNT(*) AS c FROM term_node t GROUP BY t.tid");
Dries's avatar
 
Dries committed
504 505
    }
    else {
Dries's avatar
 
Dries committed
506
      $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
507
    }
Kjartan's avatar
Kjartan committed
508
    while ($term = db_fetch_object($result)) {
Dries's avatar
 
Dries committed
509
      $count[$type][$term->tid] = $term->c;
Dries's avatar
 
Dries committed
510 511 512
    }
  }

Kjartan's avatar
Kjartan committed
513
  foreach (_taxonomy_term_children($tid) as $c) {
Dries's avatar
 
Dries committed
514
    $children_count += taxonomy_term_count_nodes($c, $type);
Kjartan's avatar
Kjartan committed
515
  }
Dries's avatar
 
Dries committed
516
  return $count[$type][$tid] + $children_count;
Kjartan's avatar
Kjartan committed
517 518 519 520 521
}

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

Dries's avatar
 
Dries committed
523
  if (!isset($children)) {
Kjartan's avatar
Kjartan committed
524 525 526
    $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
527
    }
Dries's avatar
 
Dries committed
528
  }
Kjartan's avatar
Kjartan committed
529 530
  return $children[$tid] ? $children[$tid] : array();
}
Dries's avatar
 
Dries committed
531

Dries's avatar
 
Dries committed
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 565 566 567 568 569
/**
 * 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
570 571
function taxonomy_get_vocabulary($vid) {
  // simple cache using a static var?
Dries's avatar
 
Dries committed
572
  return db_fetch_object(db_query("SELECT * FROM vocabulary WHERE vid = '%d'", $vid));
Kjartan's avatar
Kjartan committed
573
}
Dries's avatar
 
Dries committed
574

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

/*
** service functions
*/

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

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

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

Kjartan's avatar
Kjartan committed
603
  if (count($options) > 0) {
Dries's avatar
 
Dries committed
604 605
    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
606
    }
Dries's avatar
 
Dries committed
607

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

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

Kjartan's avatar
Kjartan committed
614 615 616
function _taxonomy_depth($depth, $graphic = '--') {
  for ($n = 0; $n < $depth; $n++) {
    $result .= $graphic;
Dries's avatar
 
Dries committed
617
  }
Kjartan's avatar
Kjartan committed
618 619
  return $result;
}
Dries's avatar
 
Dries committed
620

Kjartan's avatar
Kjartan committed
621 622 623
function _prepare_update($data) {
  foreach ($data as $key => $value) {
    $q[] = "$key = '". check_query($value) ."'";
Dries's avatar
 
Dries committed
624
  }
Kjartan's avatar
Kjartan committed
625 626 627
  $result = implode(", ", $q);
  return $result;
}
Dries's avatar
 
Dries committed
628

Kjartan's avatar
Kjartan committed
629 630 631 632 633 634 635
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
636
    }
Kjartan's avatar
Kjartan committed
637
    $result = implode(", ", $q);
Dries's avatar
 
Dries committed
638
  }
Kjartan's avatar
Kjartan committed
639 640
  return "($result)";
}
Dries's avatar
 
Dries committed
641

Dries's avatar
 
Dries committed
642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683
/*
** 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") {
    $sql = "SELECT DISTINCT(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' 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 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 {
    $result = db_query($sql ." LIMIT 15");
  }

  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
684
function taxonomy_page() {
Dries's avatar
 
Dries committed
685

Dries's avatar
 
Dries committed
686 687 688 689 690 691

  // 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
692

Dries's avatar
 
Dries committed
693
  switch (arg(1)) {
Kjartan's avatar
Kjartan committed
694
    case "feed":
Dries's avatar
 
Dries committed
695
      taxonomy_feed($taxonomy);
Kjartan's avatar
Kjartan committed
696 697
      break;
    default:
Dries's avatar
 
Dries committed
698
      theme("header");
Dries's avatar
 
Dries committed
699
      taxonomy_render_nodes(taxonomy_select_nodes($taxonomy));
Dries's avatar
 
Dries committed
700
      theme("footer");
Dries's avatar
 
Dries committed
701
      break;
Dries's avatar
 
Dries committed
702
  }
Kjartan's avatar
Kjartan committed
703
}
Dries's avatar
 
Dries committed
704

Kjartan's avatar
Kjartan committed
705
/*
Dries's avatar
 
Dries committed
706 707 708
** admin
*/

Kjartan's avatar
Kjartan committed
709
function taxonomy_admin() {
Dries's avatar
 
Dries committed
710
  global $op, $edit;
Kjartan's avatar
Kjartan committed
711 712

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

Kjartan's avatar
Kjartan committed
717
    switch ($op) {
Dries's avatar
 
Dries committed
718
      case "addvocabulary":
Dries's avatar
 
Dries committed
719 720
        print taxonomy_form_vocabulary();
        break;
Dries's avatar
 
Dries committed
721
      case "addterm":
Dries's avatar
 
Dries committed
722
        print taxonomy_form_term();
Kjartan's avatar
Kjartan committed
723
        break;
Dries's avatar
 
Dries committed
724 725 726 727 728
      case "editvocabulary":
        print taxonomy_form_vocabulary(object2array(taxonomy_get_vocabulary(arg(3))));
        break;
      case "editterm":
        print taxonomy_form_term(object2array(taxonomy_get_term(arg(3))));
Kjartan's avatar
Kjartan committed
729 730
        break;
      case "preview":
Dries's avatar
 
Dries committed
731
        print taxonomy_form(arg(4));
Kjartan's avatar
Kjartan committed
732 733 734 735
        break;
      case "help":
        print taxonomy_help();
        break;
Dries's avatar
 
Dries committed
736
      case t("Delete"):
Dries's avatar
 
Dries committed
737
        if (!$edit["confirm"]) {
Dries's avatar
 
Dries committed
738
          if (arg(3) == "vocabulary") {
Dries's avatar
 
Dries committed
739 740 741 742 743 744 745 746 747 748 749
            echo _taxonomy_confirm_del_vocabulary($edit["vid"]);
          }
          else {
            echo _taxonomy_confirm_del_term($edit["tid"]);
          }
          break;
        }
        else {
          $edit["name"] = 0;
          // fall through:
        }
Dries's avatar
 
Dries committed
750
      case t("Submit"):
Dries's avatar
 
Dries committed
751
        if (arg(2) == "addvocabulary" || arg(2) == "editvocabulary") {
Kjartan's avatar
Kjartan committed
752
          print status(taxonomy_save_vocabulary($edit));
Kjartan's avatar
Kjartan committed
753 754
        }
        else {
Kjartan's avatar
Kjartan committed
755
          print status(taxonomy_save_term($edit));
Dries's avatar
 
Dries committed
756 757 758 759 760 761
          if (!$edit["tid"]) {
            // if INSERT show form again
            print taxonomy_form_term();
            break;
          }
          // else (UPDATE or DELETE) fall through
Kjartan's avatar
Kjartan committed
762
        }
Kjartan's avatar
Kjartan committed
763 764 765 766 767 768 769 770 771 772 773 774
        // fall through:
      default:
        print taxonomy_overview();
    }
  }
  else {
    print message_access();
  }
}

function taxonomy_help() {
  ?>
Dries's avatar
 
Dries committed
775 776

  <h3>Background</h3>
Dries's avatar
 
Dries committed
777
  <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
778 779

  <h3>An example taxonomy: food</h3>
Dries's avatar
 
Dries committed
780 781 782 783 784
  <p>Dairy<br />
  --Milk<br />
  Drink<br />
  --Alchohol<br />
  --Pop<br />
Kjartan's avatar
Kjartan committed
785
  --Milk<br />
Dries's avatar
 
Dries committed
786 787 788 789 790
  Meat<br />
  --Beef<br />
  --Chicken<br />
  --Lamb<br />
  Spices<br />
Kjartan's avatar
Kjartan committed
791
  --Sugar</p>
Dries's avatar
 
Dries committed
792 793 794 795 796 797
  <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
798
  <h3>Vocabularies</h3>
Dries's avatar
 
Dries committed
799
  <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 the example <i>Food</i> taxonomy above.</p>
Kjartan's avatar
Kjartan committed
800 801

  <h4>Setting up a vocabulary</h4>
Dries's avatar
 
Dries committed
802 803
  <p>When you set up a controlled vocabulary, you will be asked to enter some descriptive data and define the attributes of this vocabulary. For example, if you select the <i>hierarchy</i> option, you will be defining a taxonomy or a thesaurus. If you select <i>related terms</i> option, you are allowing the definition of related terms 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's avatar
Dries committed
804
  <p><i>Vocabulary name</i><br />Required. The name for this vocabulary. Example: <i>Dairy</i>.<br />
Kjartan's avatar
Kjartan committed
805
  <br />
Dries's avatar
 
Dries committed
806
  <i>Description</i><br />Optional. Description of the vocabulary, can be used by modules and feeds.<br />
Kjartan's avatar
Kjartan committed
807
  <br />
Dries's avatar
 
Dries committed
808
  <i>Types</i><br />Required. The list of node types you want to associate this vocabulary with. Some available types are: blog, book, forum, page, story.<br />