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

Dries's avatar
   
Dries committed
4
5
function taxonomy_feed($taxonomy) {
  global $id, $type;
Dries's avatar
   
Dries committed
6

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

Kjartan's avatar
Kjartan committed
20
21
22
function taxonomy_perm() {
  return array("administer taxonomy");
}
Dries's avatar
 
Dries committed
23

Dries's avatar
   
Dries committed
24
function taxonomy_link($type, $node = NULL) {
Dries's avatar
   
Dries committed
25
26
  if ($type == "system") {
    if (user_access("administer taxonomy")) {
Dries's avatar
   
Dries committed
27
28
29
      menu("admin/taxonomy", t("taxonomy"), "taxonomy_admin", 3);
      menu("admin/taxonomy/add/vocabulary", t("create new vocabulary"), "taxonomy_admin");
      menu("admin/taxonomy/help", t("help"), "taxonomy_admin", 9);
Dries's avatar
   
Dries committed
30
    }
Dries's avatar
   
Dries committed
31
32
33
    if (user_access("access content")) {
      menu("taxonomy", t("taxonomy"), "taxonomy_page", 0, 1);
    }
Dries's avatar
   
Dries committed
34
  }
Dries's avatar
   
Dries committed
35
  else if ($type == "taxonomy terms" && $node != NULL) {
Kjartan's avatar
   
Kjartan committed
36
    $links = array();
Dries's avatar
   
Dries committed
37
38
39
    if ($node->taxonomy) {
      foreach ($node->taxonomy as $tid) {
        $term = taxonomy_get_term($tid);
40
        $links[] = l($term->name, "taxonomy/page/or/$term->tid");
Dries's avatar
   
Dries committed
41
42
43
44
      }
    }
    else {

Dries's avatar
   
Dries committed
45
46
47
48
49
50
51
52
    /*
    ** Themes can print taxonomy links with:
    **
    ** if (module_exist("taxonomy")) {
    **   $this->links(taxonomy_link("taxonomy terms", $node));
    ** }
    */

Dries's avatar
   
Dries committed
53
54
      $links = array();
      foreach (taxonomy_node_get_terms($node->nid) as $term) {
55
        $links[] = l($term->name, "taxonomy/page/or/$term->tid");
Dries's avatar
   
Dries committed
56
      }
Dries's avatar
   
Dries committed
57
58
59
60

    }
    return $links;
  }
Kjartan's avatar
Kjartan committed
61
62
}

Dries's avatar
 
Dries committed
63
64
65
66
/*
** admin pages (form, save, overview)
*/

Kjartan's avatar
Kjartan committed
67
68
69
function taxonomy_form_vocabulary($edit = array()) {
  foreach (module_list() as $name) {
    if (module_hook($name, "node")) {
Dries's avatar
   
Dries committed
70
      $nodetypes[$name] = module_invoke($name, "node", "name");
Dries's avatar
 
Dries committed
71
    }
Kjartan's avatar
Kjartan committed
72
  }
Dries's avatar
   
Dries committed
73

Dries's avatar
   
Dries committed
74
75
76
77
  $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"), "nodes", explode(",", $edit["nodes"]), $nodetypes, t("Required") .". ". t("A list of node types you want to associate this vocabulary with."), "", 1);
  $form .= form_checkbox(t("Related terms"), "relations", 1, $edit["relations"], t("Optional") .". ". t("Allows ". l("related terms", "admin/taxonomy/help#relatedterms") ." in this vocabulary."));
Dries's avatar
   
Dries committed
78
  $form .= form_radios(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
79
  $form .= form_checkbox(t("Multiple select"), "multiple", 1, $edit["multiple"], t("Optional") .". ". t("Allows nodes to have more than one term in this vocabulary."));
Dries's avatar
   
Dries committed
80
  $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
81
  $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
82
  $form .= form_submit(t("Submit"));
Dries's avatar
 
Dries committed
83

Kjartan's avatar
Kjartan committed
84
  if ($edit["vid"]) {
Dries's avatar
   
Dries committed
85
    $form .= form_submit(t("Delete"));
Kjartan's avatar
Kjartan committed
86
    $form .= form_hidden("vid", $edit["vid"]);
Dries's avatar
 
Dries committed
87
88
  }

Kjartan's avatar
Kjartan committed
89
90
  return form($form);
}
Kjartan's avatar
Kjartan committed
91

Kjartan's avatar
Kjartan committed
92
function taxonomy_save_vocabulary($edit) {
Dries's avatar
   
Dries committed
93
94
  if (!$edit["nodes"]) {
    $edit["nodes"] = array();
Dries's avatar
   
Dries committed
95
96
  }

Dries's avatar
   
Dries committed
97
  $data = array("name" => $edit["name"], "nodes" => implode(",", $edit["nodes"]), "description" => $edit["description"], "multiple" => $edit["multiple"], "required" => $edit["required"], "hierarchy" => $edit["hierarchy"], "relations" => $edit["relations"], "weight" => $edit["weight"]);
Kjartan's avatar
Kjartan committed
98
  if ($edit["vid"] && $edit["name"]) {
Dries's avatar
   
Dries committed
99
    db_query("UPDATE {vocabulary} SET ". _prepare_update($data) ." WHERE vid = %d", $edit["vid"]);
Dries's avatar
   
Dries committed
100
101
    module_invoke_all("taxonomy", "update", "vocabulary", $edit);
    $message = t("updated vocabulary '%name'.", array("%name" => $edit["name"]));
Dries's avatar
 
Dries committed
102
  }
Kjartan's avatar
Kjartan committed
103
  else if ($edit["vid"]) {
Dries's avatar
   
Dries committed
104
    $message = taxonomy_del_vocabulary($edit["vid"]);
Kjartan's avatar
Kjartan committed
105
106
  }
  else {
Dries's avatar
   
Dries committed
107
    $data["vid"] = $edit["vid"] = db_next_id("{vocabulary}_vid");
Dries's avatar
   
Dries committed
108
    db_query("INSERT INTO {vocabulary} ". _prepare_insert($data, 1) ." VALUES ". _prepare_insert($data, 2));
Dries's avatar
   
Dries committed
109
110
    module_invoke_all("taxonomy", "insert", "vocabulary", $edit);
    $message = t("created new vocabulary '%name'.", array("%name" => $edit["name"]));
Kjartan's avatar
Kjartan committed
111
  }
Dries's avatar
   
Dries committed
112
113

  cache_clear_all();
Dries's avatar
   
Dries committed
114

Dries's avatar
   
Dries committed
115
116
  drupal_set_message($message);
  return $edit;
Kjartan's avatar
Kjartan committed
117
}
Dries's avatar
 
Dries committed
118

Kjartan's avatar
Kjartan committed
119
function taxonomy_del_vocabulary($vid) {
Dries's avatar
   
Dries committed
120
121
  $vocabulary = taxonomy_get_vocabulary($vid);

Dries's avatar
   
Dries committed
122
123
  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
124
125
  while ($term = db_fetch_object($result)) {
    taxonomy_del_term($term->tid);
Dries's avatar
 
Dries committed
126
  }
Dries's avatar
   
Dries committed
127

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

Dries's avatar
   
Dries committed
130
131
  cache_clear_all();

Dries's avatar
   
Dries committed
132
133
134
135
136
137
138
139
140
141
142
143
144
  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
145
}
Dries's avatar
 
Dries committed
146

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

Dries's avatar
   
Dries committed
151
152
  $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
153

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

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

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

172
  if ($vocabulary->relations) {
Dries's avatar
   
Dries committed
173
    $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"]));
174
175
  }

Dries's avatar
   
Dries committed
176
  $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
177
  $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
178
  $form .= form_hidden("vid", $vocabulary->vid);
Dries's avatar
   
Dries committed
179
  $form .= form_submit(t("Submit"));
Kjartan's avatar
Kjartan committed
180
181

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

Kjartan's avatar
Kjartan committed
186
187
  return form($form);
}
Dries's avatar
 
Dries committed
188

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

Dries's avatar
   
Dries committed
193
    db_query("UPDATE {term_data} SET ". _prepare_update($data) ." WHERE tid = %d", $edit["tid"]);
Dries's avatar
   
Dries committed
194
    module_invoke_all("taxonomy", "update", "term", $edit);
Dries's avatar
   
Dries committed
195
    $message = t("the term '%a' has been updated.", array("%a" => $edit["name"]));
Kjartan's avatar
Kjartan committed
196
197
  }
  else if ($edit["tid"]) {
Dries's avatar
   
Dries committed
198
    return taxonomy_del_term($edit["tid"]);
Kjartan's avatar
Kjartan committed
199
200
  }
  else {
Dries's avatar
   
Dries committed
201
    $edit["tid"] = db_next_id("{term_data}_tid");
Kjartan's avatar
Kjartan committed
202
    $data = array("tid" => $edit["tid"], "name" => $edit["name"], "description" => $edit["description"], "vid" => $edit["vid"], "weight" => $edit["weight"]);
Dries's avatar
   
Dries committed
203
    db_query("INSERT INTO {term_data} ". _prepare_insert($data, 1) ." VALUES ". _prepare_insert($data, 2));
Dries's avatar
   
Dries committed
204
    module_invoke_all("taxonomy", "insert", "term", $edit);
Dries's avatar
   
Dries committed
205
    $message = t("created new term '%name'.", array("%name" => $edit["name"]));
Kjartan's avatar
Kjartan committed
206
  }
Dries's avatar
 
Dries committed
207

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

Kjartan's avatar
Kjartan committed
218
  // hierarchy
Dries's avatar
   
Dries committed
219
  db_query("DELETE FROM {term_hierarchy} WHERE tid = %d", $edit["tid"]);
Kjartan's avatar
Kjartan committed
220
221
222
223
224
  if (!isset($edit["parent"])) {
    $edit["parent"] = 0;
  }
  if (is_array($edit["parent"])) {
    foreach ($edit["parent"] as $parent) {
Dries's avatar
   
Dries committed
225
      db_query("INSERT INTO {term_hierarchy} (tid, parent) VALUES (%d, %d)", $edit["tid"], $parent);
Dries's avatar
 
Dries committed
226
    }
Kjartan's avatar
Kjartan committed
227
228
  }
  else {
Dries's avatar
   
Dries committed
229
    db_query("INSERT INTO {term_hierarchy} (tid, parent) VALUES (%d, %d)", $edit["tid"], $edit["parent"][0]);
Dries's avatar
 
Dries committed
230
231
  }

Dries's avatar
   
Dries committed
232
  db_query("DELETE FROM {term_synonym} WHERE tid = %d", $edit["tid"]);
Kjartan's avatar
Kjartan committed
233
  if ($edit["synonyms"]) {
Dries's avatar
   
Dries committed
234
235
    foreach (explode ("\n", str_replace("\r", "", $edit["synonyms"])) as $synonym) {
      if ($synonym) {
Dries's avatar
   
Dries committed
236
        db_query("INSERT INTO {term_synonym} (tid, name) VALUES (%d, '%s')", $edit["tid"], chop($synonym));
Dries's avatar
   
Dries committed
237
      }
Kjartan's avatar
Kjartan committed
238
    }
Dries's avatar
 
Dries committed
239
  }
Dries's avatar
   
Dries committed
240

Dries's avatar
   
Dries committed
241
242
  cache_clear_all();

Dries's avatar
   
Dries committed
243
  drupal_set_message($message);
Dries's avatar
   
Dries committed
244
  return $edit;
Kjartan's avatar
Kjartan committed
245
}
Dries's avatar
 
Dries committed
246

Kjartan's avatar
Kjartan committed
247
function taxonomy_del_term($tid) {
Dries's avatar
   
Dries committed
248
249
  $term = taxonomy_get_term($tid);

Dries's avatar
   
Dries committed
250
251
252
253
254
  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
255

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

Dries's avatar
   
Dries committed
258
259
  cache_clear_all();

Dries's avatar
   
Dries committed
260
261
262
263
264
265
266
267
268
269
270
271
272
  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
273
}
Dries's avatar
 
Dries committed
274

Kjartan's avatar
Kjartan committed
275
function taxonomy_overview() {
Dries's avatar
 
Dries committed
276

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

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

Kjartan's avatar
Kjartan committed
281
  $vocabularies = taxonomy_get_vocabularies();
Dries's avatar
   
Dries committed
282

Kjartan's avatar
Kjartan committed
283
284
  foreach ($vocabularies as $vocabulary) {
    $links = array();
Dries's avatar
   
Dries committed
285
    $rows[] = array($vocabulary->name, array("data" => module_invoke($vocabulary->nodes, "node", "name"), "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
286

Dries's avatar
   
Dries committed
287
    $tree = taxonomy_get_tree($vocabulary->vid);
Kjartan's avatar
Kjartan committed
288
    if ($tree) {
Dries's avatar
   
Dries committed
289
      unset($data);
Kjartan's avatar
Kjartan committed
290
      foreach ($tree as $term) {
291
        $data .= _taxonomy_depth($term->depth) ." ". $term->name ." (". l(t("edit term"), "admin/taxonomy/edit/term/$term->tid") .")<br />";
Dries's avatar
 
Dries committed
292
      }
Dries's avatar
   
Dries committed
293
      $rows[] = array(array("data" => $data, "colspan" => 5));
Dries's avatar
 
Dries committed
294
295
296
    }
  }

Dries's avatar
   
Dries committed
297
  return theme("table", $header, $rows);
Kjartan's avatar
Kjartan committed
298
299
300
301
302
303
304
305
306
307
}

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

Kjartan's avatar
Kjartan committed
311
  if ($vocabulary->multiple) {
Dries's avatar
   
Dries committed
312
    $description = t("You $verb choose one or more terms for this node.");
Kjartan's avatar
Kjartan committed
313
    $multiple = 1;
Dries's avatar
 
Dries committed
314
  }
Kjartan's avatar
Kjartan committed
315
  else {
Dries's avatar
   
Dries committed
316
    $description = t("You $verb choose one term for this node.");
Kjartan's avatar
Kjartan committed
317
318
319
320
    $multiple = 0;
  }
  return _taxonomy_term_select($vocabulary->name, "taxonomy", $value, $vocabulary_id, $description, $multiple, $blank);
}
Dries's avatar
 
Dries committed
321
322
323
324
325

/*
** API functions
*/

Kjartan's avatar
Kjartan committed
326
327
328
// return array of vocabularies, as objects
function taxonomy_get_vocabularies($type = '', $key = "vid") {
  if ($type) {
Dries's avatar
   
Dries committed
329
    $result = db_query("SELECT * FROM {vocabulary} WHERE nodes LIKE '%%%s%%' ORDER BY weight, name", $type);
Kjartan's avatar
Kjartan committed
330
331
  }
  else {
Dries's avatar
   
Dries committed
332
    $result = db_query("SELECT * FROM {vocabulary} ORDER BY weight, name");
Kjartan's avatar
Kjartan committed
333
334
335
336
  }
  $vocabularies = array();
  while ($voc = db_fetch_object($result)) {
    $vocabularies[$voc->$key] = $voc;
Dries's avatar
 
Dries committed
337
  }
Dries's avatar
   
Dries committed
338

Kjartan's avatar
Kjartan committed
339
340
  return $vocabularies;
}
Dries's avatar
 
Dries committed
341

Kjartan's avatar
Kjartan committed
342
343
344
345
346
// 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
347
348
    }
    else {
Kjartan's avatar
Kjartan committed
349
      $terms = 0;
Dries's avatar
 
Dries committed
350
    }
Kjartan's avatar
Kjartan committed
351
352
353
354
  }
  else {
    $terms = $node->taxonomy;
  }
Dries's avatar
 
Dries committed
355

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

Kjartan's avatar
Kjartan committed
363
364
// 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
365
  $term_name = db_result(db_query("SELECT name FROM {term_data} WHERE tid = %d", $tid));
Dries's avatar
 
Dries committed
366

Dries's avatar
   
Dries committed
367
  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
368
369
370
371
}

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

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

Dries's avatar
   
Dries committed
384
  if (!isset($terms[$nid])) {
Dries's avatar
   
Dries committed
385
    $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
386
    $terms[$nid] = array();
Dries's avatar
 
Dries committed
387
    while ($term = db_fetch_object($result)) {
Kjartan's avatar
Kjartan committed
388
      $terms[$nid][$term->$key] = $term;
Dries's avatar
 
Dries committed
389
390
    }
  }
Kjartan's avatar
Kjartan committed
391
392
  return $terms[$nid];
}
Dries's avatar
 
Dries committed
393

Kjartan's avatar
Kjartan committed
394
395
396
// save terms of a node
function taxonomy_node_save($nid, $terms) {
  taxonomy_node_delete($nid);
Dries's avatar
 
Dries committed
397

Kjartan's avatar
Kjartan committed
398
  if ($terms) {
Dries's avatar
   
Dries committed
399
    foreach ($terms as $term) {
Dries's avatar
   
Dries committed
400
      db_query("INSERT INTO {term_node} (nid, tid) VALUES (%d, %d)", $nid, $term);
Dries's avatar
 
Dries committed
401
402
    }
  }
Kjartan's avatar
Kjartan committed
403
}
Dries's avatar
 
Dries committed
404

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

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

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

Kjartan's avatar
Kjartan committed
440
441
442
// hierarchy: get children
function taxonomy_get_children($tid, $vid = 0, $key = "tid") {
  if ($vid) {
Dries's avatar
   
Dries committed
443
    $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
444
  }
Kjartan's avatar
Kjartan committed
445
  else {
Dries's avatar
   
Dries committed
446
    $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
447
448
449
450
451
452
453
  }
  $children = array();
  while ($term = db_fetch_object($result)) {
    $children[$term->$key] = $term;
  }
  return $children;
}
Dries's avatar
 
Dries committed
454

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

Kjartan's avatar
Kjartan committed
459
  $depth++;
Dries's avatar
   
Dries committed
460

Dries's avatar
   
Dries committed
461
462
463
464
  // 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
465
    $result = db_query("SELECT t.*, parent FROM {term_data} t, {term_hierarchy} h WHERE t.tid = h.tid AND t.vid = %d ORDER BY weight, name", $vocabulary_id);
Dries's avatar
   
Dries committed
466
    while ($term = db_fetch_object($result)) {
Dries's avatar
   
Dries committed
467
468
469
      $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
470
471
    }
  }
Dries's avatar
   
Dries committed
472

Dries's avatar
   
Dries committed
473
474
475
476
477
478
  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
479

Dries's avatar
   
Dries committed
480
      $tree = array_merge($tree, taxonomy_get_tree($vocabulary_id, $child, $depth));
Dries's avatar
   
Dries committed
481
    }
Kjartan's avatar
Kjartan committed
482
  }
Dries's avatar
   
Dries committed
483

Dries's avatar
   
Dries committed
484
  return $tree ? $tree : array();
Kjartan's avatar
Kjartan committed
485
}
Dries's avatar
 
Dries committed
486

Kjartan's avatar
Kjartan committed
487
488
489
// synonyms: return array of synonyms
function taxonomy_get_synonyms($tid) {
  if ($tid) {
Dries's avatar
   
Dries committed
490
    $result = db_query("SELECT name FROM {term_synonym} WHERE tid = %d", $tid);
Kjartan's avatar
Kjartan committed
491
492
    while ($synonym = db_fetch_array($result)) {
      $synonyms[] = $synonym["name"];
Dries's avatar
 
Dries committed
493
    }
Kjartan's avatar
Kjartan committed
494
    return $synonyms ? $synonyms : array();
Dries's avatar
 
Dries committed
495
  }
Kjartan's avatar
Kjartan committed
496
497
  else {
    return array();
Dries's avatar
   
Dries committed
498
  }
Kjartan's avatar
Kjartan committed
499
}
Dries's avatar
   
Dries committed
500

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

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

Dries's avatar
   
Dries committed
510
511
512
  if (!isset($count[$type])) {
    // $type == 0 always evaluates true is $type is a string
    if (is_numeric($type)) {
Dries's avatar
   
Dries committed
513
      $result = db_query("SELECT t.tid, COUNT(*) AS c FROM {term_node} t INNER JOIN {node} n ON t.nid = n.nid WHERE n.status = 1 GROUP BY t.tid");
Dries's avatar
   
Dries committed
514
515
    }
    else {
Dries's avatar
   
Dries committed
516
      $result = db_query("SELECT t.tid, COUNT(*) AS c FROM {term_node} t, {node} n WHERE t.nid = n.nid AND n.status = 1 AND n.type = '%s' GROUP BY t.tid", $type);
Dries's avatar
   
Dries committed
517
    }
Kjartan's avatar
Kjartan committed
518
    while ($term = db_fetch_object($result)) {
Dries's avatar
   
Dries committed
519
      $count[$type][$term->tid] = $term->c;
Dries's avatar
   
Dries committed
520
521
522
    }
  }

Kjartan's avatar
Kjartan committed
523
  foreach (_taxonomy_term_children($tid) as $c) {
Dries's avatar
   
Dries committed
524
    $children_count += taxonomy_term_count_nodes($c, $type);
Kjartan's avatar
Kjartan committed
525
  }
Dries's avatar
   
Dries committed
526
  return $count[$type][$tid] + $children_count;
Kjartan's avatar
Kjartan committed
527
528
529
530
531
}

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

Dries's avatar
   
Dries committed
533
  if (!isset($children)) {
Dries's avatar
   
Dries committed
534
    $result = db_query("SELECT tid, parent FROM {term_hierarchy} ");
Kjartan's avatar
Kjartan committed
535
536
    while ($term = db_fetch_object($result)) {
      $children[$term->parent][] = $term->tid;
Dries's avatar
   
Dries committed
537
    }
Dries's avatar
 
Dries committed
538
  }
Kjartan's avatar
Kjartan committed
539
540
  return $children[$tid] ? $children[$tid] : array();
}
Dries's avatar
 
Dries committed
541

Dries's avatar
   
Dries committed
542
/**
Dries's avatar
   
Dries committed
543
544
 * Try to map a string to existing vocabularies. Provide case insensitive and
 * trimmed map so as to maximize likelihood of successful mapping.
Dries's avatar
   
Dries committed
545
 *
Dries's avatar
   
Dries committed
546
547
 * @param $name Name of the vocabulary to search
 * @return array of matching vocabularies, as objects
Dries's avatar
   
Dries committed
548
549
550
 */
function taxonomy_get_vocabulary_by_name($name) {
  // LOWER is ANSI SQL-92
Dries's avatar
   
Dries committed
551
  $db_result = db_query("SELECT * FROM {vocabulary} WHERE LOWER('%s') LIKE LOWER(name)", trim($name));
Dries's avatar
   
Dries committed
552
553
554
555
556
557
558
559
560
  $result = array();
  while ($vocabulary = db_fetch_object($db_result)) {
    $result[] = $vocabulary;
  }

  return $result;
}

/**
Dries's avatar
   
Dries committed
561
562
 * Try to map a string to existing terms Provide case insensitive and trimmed
 * map so as to maximize likelihood of successful mapping.
Dries's avatar
   
Dries committed
563
 *
Dries's avatar
   
Dries committed
564
565
 * @param name Name of the term to search
 * @return rray of matching terms, as objects
Dries's avatar
   
Dries committed
566
567
568
 */
function taxonomy_get_term_by_name($name) {
  // LOWER is ANSI SQL-92
Dries's avatar
   
Dries committed
569
  $db_result = db_query("SELECT * FROM {term_data} WHERE LOWER('%s') LIKE LOWER(name)", trim($name));
Dries's avatar
   
Dries committed
570
571
572
573
574
575
576
577
  $result = array();
  while ($term = db_fetch_object($db_result)) {
    $result[] = $term;
  }

  return $result;
}

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

Kjartan's avatar
Kjartan committed
583
584
function taxonomy_get_term($tid) {
  // simple cache using a static var?
Dries's avatar
   
Dries committed
585
  return db_fetch_object(db_query("SELECT * FROM {term_data} WHERE tid = %d", $tid));
Kjartan's avatar
Kjartan committed
586
}
Dries's avatar
 
Dries committed
587
588
589
590
591

/*
** service functions
*/

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

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

Kjartan's avatar
Kjartan committed
599
600
601
  if ($tree) {
    foreach ($tree as $term) {
      if (!in_array($term->tid, $exclude)) {
Dries's avatar
   
Dries committed
602
        $options[] = array("tid" => $term->tid, "name" => _taxonomy_depth($term->depth, '-').$term->name);
Dries's avatar
 
Dries committed
603
604
      }
    }
Kjartan's avatar
Kjartan committed
605
606
607
608
609
    if (!$blank && !$value) {
      // required but without a predefined value, so set first as predefined
      $value = $tree[0]->tid;
    }
  }
Dries's avatar
 
Dries committed
610

Kjartan's avatar
Kjartan committed
611
  if (count($options) > 0) {
Dries's avatar
   
Dries committed
612
    foreach ($options as $option) {
Dries's avatar
   
Dries committed
613
      $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
614
    }
Dries's avatar
 
Dries committed
615

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

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

Kjartan's avatar
Kjartan committed
622
623
624
function _taxonomy_depth($depth, $graphic = '--') {
  for ($n = 0; $n < $depth; $n++) {
    $result .= $graphic;
Dries's avatar
 
Dries committed
625
  }
Kjartan's avatar
Kjartan committed
626
627
  return $result;
}
Dries's avatar
 
Dries committed
628

Kjartan's avatar
Kjartan committed
629
630
631
function _prepare_update($data) {
  foreach ($data as $key => $value) {
    $q[] = "$key = '". check_query($value) ."'";
Dries's avatar
 
Dries committed
632
  }
Kjartan's avatar
Kjartan committed
633
634
635
  $result = implode(", ", $q);
  return $result;
}
Dries's avatar
 
Dries committed
636

Kjartan's avatar
Kjartan committed
637
638
639
640
641
642
643
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
644
    }
Kjartan's avatar
Kjartan committed
645
    $result = implode(", ", $q);
Dries's avatar
 
Dries committed
646
  }
Kjartan's avatar
Kjartan committed
647
648
  return "($result)";
}
Dries's avatar
   
Dries committed
649

Dries's avatar
   
Dries committed
650
651
652
653
654
655
656
657
/*
** 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;

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

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

671
672
673
674
675
676
    if ($pager) {
      $result = pager_query($sql, variable_get("default_nodes_main", 10) , 0, $sql_count);
    }
    else {
      $result = db_query_range($sql, 0, 15);
    }
Dries's avatar
   
Dries committed
677
678
679
680
681
682
683
684
685
686
687
688
  }

  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)) {
Dries's avatar
   
Dries committed
689
    $output .= node_view(node_load(array("nid" => $node->nid, "type" => $node->type)), 1);
Dries's avatar
   
Dries committed
690
  }
Dries's avatar
Dries committed
691
  $output .= theme("pager", NULL, variable_get("default_nodes_main", 10), 0);
Dries's avatar
   
Dries committed
692
  return $output;
Dries's avatar
   
Dries committed
693
694
}

Dries's avatar
   
Dries committed
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
function taxonomy_nodeapi($node, $op, $arg = 0) {

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

Kjartan's avatar
Kjartan committed
710
function taxonomy_page() {
Dries's avatar
   
Dries committed
711

Dries's avatar
   
Dries committed
712
713
714
715
716
717

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

Dries's avatar
   
Dries committed
719
  switch (arg(1)) {
Kjartan's avatar
Kjartan committed
720
    case "feed":
Dries's avatar
   
Dries committed
721
      taxonomy_feed($taxonomy);
Kjartan's avatar
Kjartan committed
722
723
      break;
    default:
Dries's avatar
   
Dries committed
724
      // Build title:
Dries's avatar
   
Dries committed
725
726
727
728
729
      $sql = 'SELECT name FROM term_data WHERE tid IN (%s)';
      $result = db_query($sql, $taxonomy->str_tids);
      while ($term = db_fetch_object($result)) {
        $names[] = $term->name;
      }
Dries's avatar
   
Dries committed
730
731
732
733
734
735
736
737
738
739

      // Build breadcrumb based on first hierarchy of first term:
      $current->tid = $taxonomy->tids[0];
      while ($parents = taxonomy_get_parents($current->tid)) {
        $current = array_shift($parents);
        $breadcrumbs[] = l($current->name, "taxonomy/view/or/$current->tid");
      }
      $breadcrumbs[] = l(t('Home'), '');
      $breadcrumbs = array_reverse($breadcrumbs);

Dries's avatar
   
Dries committed
740
      $output = taxonomy_render_nodes(taxonomy_select_nodes($taxonomy));
Dries's avatar
   
Dries committed
741
      print theme("page", $output, implode(', ', $names), $breadcrumbs);
Dries's avatar
   
Dries committed
742
      break;
Dries's avatar
   
Dries committed
743
  }
Kjartan's avatar
Kjartan committed
744
}
Dries's avatar
   
Dries committed
745

Kjartan's avatar
Kjartan committed
746
/*
Dries's avatar
 
Dries committed
747
748
749
** admin
*/

Kjartan's avatar
Kjartan committed
750
function taxonomy_admin() {
Dries's avatar
   
Dries committed
751
752
  $op = $_POST["op"];
  $edit = $_POST["edit"];
Kjartan's avatar
Kjartan committed
753
754

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

Kjartan's avatar
Kjartan committed
759
    switch ($op) {
760
761
762
763
764
      case "add":
        if (arg(3) == "vocabulary")
          $output .= taxonomy_form_vocabulary();
        else if (arg(3) == "term")
          $output .= taxonomy_form_term();
Dries's avatar
   
Dries committed
765
        break;
766
767
768
769
770
      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
771
772
        break;
      case "preview":
773
        $output .= taxonomy_form(arg(4));
Kjartan's avatar
Kjartan committed
774
775
        break;
      case "help":
776
        $output .= taxonomy_help();
Kjartan's avatar
Kjartan committed
777
        break;
Dries's avatar
   
Dries committed
778
      case t("Delete"):
Dries's avatar
   
Dries committed
779
        if (!$edit["confirm"]) {
Dries's avatar
   
Dries committed
780
          if (arg(3) == "vocabulary") {
781
            $output .= _taxonomy_confirm_del_vocabulary($edit["vid"]);
Dries's avatar
   
Dries committed
782
783
          }
          else {
784
            $output .= _taxonomy_confirm_del_term($edit["tid"]);
Dries's avatar
   
Dries committed
785
786
787
788
789
790
791
          }
          break;
        }
        else {
          $edit["name"] = 0;
          // fall through:
        }
Dries's avatar
   
Dries committed
792
      case t("Submit"):
793
        if (arg(3) == "vocabulary") {
Dries's avatar
   
Dries committed
794
          taxonomy_save_vocabulary($edit);
Kjartan's avatar
Kjartan committed
795
796
        }
        else {
Dries's avatar
   
Dries committed
797
          taxonomy_save_term($edit);
Dries's avatar
   
Dries committed
798
799
          if (!$edit["tid"]) {
            // if INSERT show form again
800
            $output .= taxonomy_form_term();
Dries's avatar
   
Dries committed
801
802
803
            break;
          }
          // else (UPDATE or DELETE) fall through
Kjartan's avatar
Kjartan committed
804
        }
Kjartan's avatar
Kjartan committed
805
806
        // fall through:
      default:
807
        $output .= taxonomy_overview();
Kjartan's avatar
Kjartan committed
808
809
810
    }
  }
  else {
811
    $output .= message_access();
Kjartan's avatar
Kjartan committed
812
  }
Dries's avatar
   
Dries committed
813

Dries's avatar
   
Dries committed
814
  print theme("page", $output);
Kjartan's avatar
Kjartan committed
815
816
}

Dries's avatar
   
Dries committed
817
function taxonomy_help($section = "admin/help#taxonomy") {
Dries's avatar
   
Dries committed
818
  $output = "";
Dries's avatar
   
Dries committed
819

Dries's avatar
   
Dries committed
820
  switch ($section) {
Dries's avatar
   
Dries committed
821
    case 'admin/system/modules#description':
Dries's avatar
   
Dries committed
822
      $output = t("Enables the organization of content into categories.");
Dries's avatar
   
Dries committed
823
      break;
Dries's avatar
   
Dries committed
824
    case 'admin/taxonomy':
Dries's avatar
   
Dries committed
825
      $output = t("The taxonomy module allows you to classify content into categories and subcategories; it allows multiple lists of categories for classification (controlled vocabularies) and offers the possibility of creating thesauri (controlled vocabularies that indicate the relationship of terms) and taxonomies (controlled vocabularies where relationships are indicated hierarchically). To delete a term choose \"edit term\". To delete a vocabulary, and all its terms, choose \"edit vocabulary\".");
Dries's avatar
   
Dries committed
826
      break;
Dries's avatar
   
Dries committed
827
    case 'admin/taxonomy/add/vocabulary':
Dries's avatar
   
Dries committed
828
      $output = t("When you create a controlled vocabulary you are creating a set of terms to use for describing content (known as descriptors in indexing lingo).  Drupal allows you to describe each node type (blog, story, etc.) using one or many of these terms. For simple implementations, you might create a set of categories without subcategories, similar to Slashdot.org's or Kuro5hin.org's sections. For more complex implementations, you might create a hierarchical list of categories.");
Dries's avatar
   
Dries committed
829
      break;
Dries's avatar
   
Dries committed
830
    case 'admin/help#taxonomy':
Dries's avatar
   
Dries committed
831
      $output .= "<h3>Background</h3><p>Taxonomy is the study of classification. Drupal's taxonomy module allows you to define categories which are used to classify content. The module supports hierarchical classification and association between terms, allowing for truly flexible information retrieval and classification. For more details about %classification-types and insight into the development of the <i>taxonomy.module</i>, see this %drupal-dis.</p>";
Dries's avatar
   
Dries committed
832
833
      $output .= "<h3>An example taxonomy: food</h3><ul><li>Dairy<ul><li>Milk</li></ul></li><li>Drink<ul><li>Alchohol<ul><li>Beer</li><li>Wine</li></ul></li><li>Pop</li><li>Milk</li></ul></li><li>Meat<ul><li>Beef</li><li>Chicken</li><li>Lamb</li></ul></li><li>Spices<ul><li>Sugar</li></ul></li></ul>";
      $output .= "<p><b>Notes</b></p><ul><li>The term <i>Milk</i> appears within both <i>Dairy</i> and <i>Drink</i>.  This is an example of <i>multiple parents</i> for a term.</li><li>In Drupal the order of siblings (e.g. <i>Beef</i>, <i>Chicken</i>, <i>Lamb</i>) in a taxonomy may be controlled with the <i>weight</i> parameter.</li></ul>";
Dries's avatar
   
Dries committed
834
      $output .= "<h3>Vocabularies</h3><p>When you create a controlled vocabulary you are creating a set of terms to use for describing content (known as descriptors in indexing lingo). Drupal allows you to describe each node of content (blog, story, etc.) using one or many of these terms. For simple implementations, you might create a set of categories without subcategories, similar to %slashdot's sections.  For more complex implementations, you might create a hierarchical list of categories such as <i>Food</i> taxonomy shown above.</p>";
Dries's avatar
   
Dries committed
835
      $output .= "<h4>Setting up a vocabulary</h4><p>When setting up a controlled vocabulary, if you select the <i>hierarchy</i> option, you will be defining a taxonomy or a thesaurus. If you select the <i>related terms</i> option, you are allowing the definition of related terms, think <i>see also</i>, as in a thesaurus. Selecting <i>multiple select</i> will allow you to describe a node using more than one term. That node will then appear in each term's page, thus increasing the chance that a user will find it.</p>";
Dries's avatar
   
Dries committed
836
837
838
839
840
841
842
843
844
845
      $output .= "<p>When setting up a controlled vocabulary you are asked for: <ul>";
      $output .= "<li><b>Vocabulary name</b> (Required) -- The name for this vocabulary. Example: <i>Dairy</i>.</li>";
      $output .= "<li><b>Description</b> (Optional) -- Description of the vocabulary, this can be used by modules and feeds.</li>";
      $output .= "<li><b>Types</b> (Required) -- The list of node types you want to associate this vocabulary with. Some available types are: blog, book, forum, page, story.</li>";
      $output .= "<li><a id=\"relatedterms\"></a><b>Related terms</b> -- Allows relationships between terms within this vocabulary. Think of these as <i>see also</i>-references.</li>";
      $output .= "<li><a id=\"hierarchy\"></a><b>Hierarchy</b> -- Allows a tree-like taxonomy, as in our <i>Foods</i> example above</li>";
      $output .= "<li><b>Multiple select</b> -- Allows nodes to be described using more than one term. Nodes may then appear on multiple taxonomy pages.</li>";
      $output .= "<li><b>Required</b> -- Each node has to have a term in this vacabulary associated with it.</li>";
      $output .= "<li><b>Weight</b> -- The over all weight for this vocaulary in listings with multiple vacabularies.</li>";
      $output .= "</ul></p>";
Dries's avatar
   
Dries committed
846
      $output .= "<h4>Adding terms to a vocabulary</h4><p>Once done defining the vocabulary, you have to add terms to it to make it useful. The options you see when adding a term to a vocabulary will depend on what you selected for <i>related terms</i>, <i>hierarchy </i>and <i>multiple select</i>. These options are:</p>";
Dries's avatar
   
Dries committed
847
848
849
850
851
852
853
854
855
      $output