taxonomy.module 35.1 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
115

  return $message;
Kjartan's avatar
Kjartan committed
116
}
Dries's avatar
 
Dries committed
117

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Dries's avatar
   
Dries committed
242
  return $message;
Kjartan's avatar
Kjartan committed
243
}
Dries's avatar
 
Dries committed
244

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

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

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

Dries's avatar
   
Dries committed
256
257
  cache_clear_all();

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

Kjartan's avatar
Kjartan committed
273
function taxonomy_overview() {
Dries's avatar
 
Dries committed
274

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

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

Kjartan's avatar
Kjartan committed
279
  $vocabularies = taxonomy_get_vocabularies();
Dries's avatar
   
Dries committed
280

Kjartan's avatar
Kjartan committed
281
282
  foreach ($vocabularies as $vocabulary) {
    $links = array();
Dries's avatar
   
Dries committed
283
    $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
284

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

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

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

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

/*
** API functions
*/

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

Kjartan's avatar
Kjartan committed
337
338
  return $vocabularies;
}
Dries's avatar
 
Dries committed
339

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Kjartan's avatar
Kjartan committed
457
  $depth++;
Dries's avatar
   
Dries committed
458

Dries's avatar
   
Dries committed
459
460
461
462
  // 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
463
    $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
464
    while ($term = db_fetch_object($result)) {
Dries's avatar
   
Dries committed
465
466
467
      $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
468
469
    }
  }
Dries's avatar
   
Dries committed
470

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

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

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

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

Kjartan's avatar
Kjartan committed
499
500
// synonyms: return original term
function taxonomy_get_synonym_root($term) {
Dries's avatar
   
Dries committed
501
  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
502
}
Dries's avatar
   
Dries committed
503

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

Dries's avatar
   
Dries committed
508
509
510
  if (!isset($count[$type])) {
    // $type == 0 always evaluates true is $type is a string
    if (is_numeric($type)) {
Dries's avatar
   
Dries committed
511
      $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
512
513
    }
    else {
Dries's avatar
   
Dries committed
514
      $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
515
    }
Kjartan's avatar
Kjartan committed
516
    while ($term = db_fetch_object($result)) {
Dries's avatar
   
Dries committed
517
      $count[$type][$term->tid] = $term->c;
Dries's avatar
   
Dries committed
518
519
520
    }
  }

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

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

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

Dries's avatar
   
Dries committed
540
/**
541
 * Try to map a string to existing vocabularies.
Dries's avatar
   
Dries committed
542
543
544
 * Provide case insensitive and trimmed map so as to
 * maximize likelihood of successful mapping.
 *
545
546
 * @param   $name  Name of the vocabulary to search
 * @return  array of matching vocabularies, as objects
Dries's avatar
   
Dries committed
547
548
549
 */
function taxonomy_get_vocabulary_by_name($name) {
  // LOWER is ANSI SQL-92
Dries's avatar
   
Dries committed
550
  $db_result = db_query("SELECT * FROM {vocabulary} WHERE LOWER('%s') LIKE LOWER(name)", trim($name));
Dries's avatar
   
Dries committed
551
552
553
554
555
556
557
558
559
560
561
562
563
  $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.
 *
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
    print node_view(node_load(array("nid" => $node->nid, "type" => $node->type)), 1);
Dries's avatar
   
Dries committed
690
  }
Dries's avatar
   
Dries committed
691
  print pager_display(NULL, variable_get("default_nodes_main", 10), 0);
Dries's avatar
   
Dries committed
692
693
}

Dries's avatar
   
Dries committed
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
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
709
function taxonomy_page() {
Dries's avatar
   
Dries committed
710

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

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

Dries's avatar
   
Dries committed
718
  switch (arg(1)) {
Kjartan's avatar
Kjartan committed
719
    case "feed":
Dries's avatar
   
Dries committed
720
      taxonomy_feed($taxonomy);
Kjartan's avatar
Kjartan committed
721
722
      break;
    default:
Dries's avatar
   
Dries committed
723
      print theme("header");
Dries's avatar
   
Dries committed
724
      taxonomy_render_nodes(taxonomy_select_nodes($taxonomy));
Dries's avatar
   
Dries committed
725
      print theme("footer");
Dries's avatar
   
Dries committed
726
      break;
Dries's avatar
   
Dries committed
727
  }
Kjartan's avatar
Kjartan committed
728
}
Dries's avatar
   
Dries committed
729

Kjartan's avatar
Kjartan committed
730
/*
Dries's avatar
 
Dries committed
731
732
733
** admin
*/

Kjartan's avatar
Kjartan committed
734
function taxonomy_admin() {
Dries's avatar
   
Dries committed
735
736
  $op = $_POST["op"];
  $edit = $_POST["edit"];
Kjartan's avatar
Kjartan committed
737
738

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

Kjartan's avatar
Kjartan committed
743
    switch ($op) {
744
745
746
747
748
      case "add":
        if (arg(3) == "vocabulary")
          $output .= taxonomy_form_vocabulary();
        else if (arg(3) == "term")
          $output .= taxonomy_form_term();
Dries's avatar
   
Dries committed
749
        break;
750
751
752
753
754
      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
755
756
        break;
      case "preview":
757
        $output .= taxonomy_form(arg(4));
Kjartan's avatar
Kjartan committed
758
759
        break;
      case "help":
760
        $output .= taxonomy_help();
Kjartan's avatar
Kjartan committed
761
        break;
Dries's avatar
   
Dries committed
762
      case t("Delete"):
Dries's avatar
   
Dries committed
763
        if (!$edit["confirm"]) {
Dries's avatar
   
Dries committed
764
          if (arg(3) == "vocabulary") {
765
            $output .= _taxonomy_confirm_del_vocabulary($edit["vid"]);
Dries's avatar
   
Dries committed
766
767
          }
          else {
768
            $output .= _taxonomy_confirm_del_term($edit["tid"]);
Dries's avatar
   
Dries committed
769
770
771
772
773
774
775
          }
          break;
        }
        else {
          $edit["name"] = 0;
          // fall through:
        }
Dries's avatar
   
Dries committed
776
      case t("Submit"):
777
778
        if (arg(3) == "vocabulary") {
          $output .= status(taxonomy_save_vocabulary($edit));
Kjartan's avatar
Kjartan committed
779
780
        }
        else {
Dries's avatar
   
Dries committed
781
          $output .= status(taxonomy_save_term($edit));
Dries's avatar
   
Dries committed
782
783
          if (!$edit["tid"]) {
            // if INSERT show form again
784
            $output .= taxonomy_form_term();
Dries's avatar
   
Dries committed
785
786
787
            break;
          }
          // else (UPDATE or DELETE) fall through
Kjartan's avatar
Kjartan committed
788
        }
Kjartan's avatar
Kjartan committed
789
790
        // fall through:
      default:
791
        $output .= taxonomy_overview();
Kjartan's avatar
Kjartan committed
792
793
794
    }
  }
  else {
795
    $output .= message_access();
Kjartan's avatar
Kjartan committed
796
  }
Dries's avatar
   
Dries committed
797

Dries's avatar
   
Dries committed
798
  print theme("page", $output);
Kjartan's avatar
Kjartan committed
799
800
}

Dries's avatar
   
Dries committed
801
function taxonomy_help($section = "admin/help#taxonomy") {
Dries's avatar
   
Dries committed
802
  $output = "";
Dries's avatar
   
Dries committed
803

Dries's avatar
   
Dries committed
804
  switch ($section) {
Dries's avatar
   
Dries committed
805
    case 'admin/system/modules#description':
Dries's avatar
   
Dries committed
806
      $output = t("Enables the organization of content into categories.");
Dries's avatar
   
Dries committed
807
      break;
Dries's avatar
   
Dries committed
808
    case 'admin/taxonomy':
Dries's avatar
   
Dries committed
809
      $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
810
      break;
Dries's avatar
   
Dries committed
811
    case 'admin/taxonomy/add/vocabulary':
Dries's avatar
   
Dries committed
812
      $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
813
      break;
Dries's avatar
   
Dries committed
814
    case 'admin/help#taxonomy':
Dries's avatar
   
Dries committed
815
      $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
816
817
      $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
818
      $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
819
      $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
820
821
822
823
824
825
826
827
828
829
      $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
830
      $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
831
832
833
834
835
836
837
838
839
      $output .= "<p><ul>";
      $output .= "<li><b>Term name</b> (Required) -- The name for this term. Example: <i>Milk</i></li>";
      $output .= "<li><b>Description</b> (Optional) -- Description of the term that may be used by modules and feeds.  This is synonymous with a 'scope note'.</li>";
      $output .= "<li><b><a id=\"parent\"></a>Parent</b> (Required) -- Select the term under which this term is a subset -- the branch of the hierarchy that this term belongs under. This is also known as the \"Broader term\" indicator used in thesauri.</li>";
      $output .= "<li><b><a id=\"synonyms\"></a>Synonyms</b> (Optional) -- Enter synonyms for this term, one synonym per line. Synonyms can be used for variant spellings, acronyms, and other terms that have the same meaning as the added term, but which are not explicitly listed in this thesaurus (i.e. <i>unauthorized terms</i>)</li>";
      $output .= "<li><b>Weight</b> (Optional) -- The weight is used to sort the terms of this vocabulary.</li>";
      $output .= "</ul></p>";
      $output .= "<h3><a id=\"taxonomyURL\"></a>Displaying nodes organized by term(s)</h3><p>In order to view the nodes associated with a term or a collection of terms, you should browse to a properly formed Taxonomy URL. For example, %taxo-example.  Taxonomy URLs always contain one or more term IDs (tid) at the end of the URL (a.k.a the <i>querystring</i>). You may learn the term ID for a given term by hovering over that term in the %taxo-overview page and noting the number at the end or the URL.  To build a Taxonomy URL start with \"taxonomy/page\". Now add the querystring parameter, either <i>or</i>, which chooses nodes tagged with <b>any</b> of the given term IDs, or <i>and</i>, which chooses nodes tagged with <b>all</b> of the given Term IDs. Thus <i>or</i> is less specific than <i>and</i>. Finally add a comma seperated list of term IDs.</p>";
      $output .= "<h3>RSS feeds</h3><p>Every term, or collection of terms, provides an %userland-rss feed to which interested users may subscribe. The URL format for a sample RSS feed is %sample-rss. Built like a Taxonomy URL, %taxo-help it starts with \"node/feed\", then has the querystring parameter, and finally the Term IDs.</p>";
Dries's avatar
   
Dries committed
840
      $output = t($output, array("%classification-types" => "<a href=\"http://www.eleganthack.com/archives/002165.html#002165\">classification types</a>", "%drupal-dis" => "<a href=\"http://www.drupal.org/node/view/55\">drupal.org discussion</a>", "%slashdot" => "<a href=\"http://www.slashdot.com/\">Slashdot</a>", "%taxo-example" => l("taxonomy/page/or/1,2", "taxonomy/page/or/1,2"), "%taxo-overview" => l(t("taxonomy overview"), "admin/taxonomy"), "%userland-rss" => "<a href=\"http://backend.userland.com/stories/rss\">RSS</a>", "%sample-rss" => l("node/feed/or/1,2", "node/feed/or/1,2"), "%taxo-help" => l(t("see above"), "admin/taxonomy/help#taxonomyURL") ));
Dries's avatar
   
Dries committed
841
842
      break;
  }
Dries's avatar
   
Dries committed
843
844

  return $output;
Kjartan's avatar
Kjartan committed
845
}
Dries's avatar
   
Dries committed
846
?>