taxonomy.module 35 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
  }
Dries's avatar
   
Dries committed
32
  else if ($type == "taxonomy terms" && $node != NULL) {
Kjartan's avatar
   
Kjartan committed
33
    $links = array();
Dries's avatar
   
Dries committed
34
35
36
    if ($node->taxonomy) {
      foreach ($node->taxonomy as $tid) {
        $term = taxonomy_get_term($tid);
37
        $links[] = l($term->name, "taxonomy/page/or/$term->tid");
Dries's avatar
   
Dries committed
38
39
40
41
      }
    }
    else {

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

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

    }
    return $links;
  }
Kjartan's avatar
Kjartan committed
58
59
}

Dries's avatar
 
Dries committed
60
61
62
63
/*
** admin pages (form, save, overview)
*/

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

Dries's avatar
   
Dries committed
71
72
73
74
  $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
75
  $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
76
  $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
77
  $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
78
  $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
79
  $form .= form_submit(t("Submit"));
Dries's avatar
 
Dries committed
80

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

Kjartan's avatar
Kjartan committed
86
87
  return form($form);
}
Kjartan's avatar
Kjartan committed
88

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

Dries's avatar
   
Dries committed
94
  $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
95
  if ($edit["vid"] && $edit["name"]) {
Dries's avatar
   
Dries committed
96
    db_query("UPDATE {vocabulary} SET ". _prepare_update($data) ." WHERE vid = %d", $edit["vid"]);
Dries's avatar
   
Dries committed
97
98
    module_invoke_all("taxonomy", "update", "vocabulary", $edit);
    $message = t("updated vocabulary '%name'.", array("%name" => $edit["name"]));
Dries's avatar
 
Dries committed
99
  }
Kjartan's avatar
Kjartan committed
100
  else if ($edit["vid"]) {
Dries's avatar
   
Dries committed
101
    $message = taxonomy_del_vocabulary($edit["vid"]);
Kjartan's avatar
Kjartan committed
102
103
  }
  else {
Dries's avatar
   
Dries committed
104
    $data["vid"] = $edit["vid"] = db_next_id("{vocabulary}_vid");
Dries's avatar
   
Dries committed
105
    db_query("INSERT INTO {vocabulary} ". _prepare_insert($data, 1) ." VALUES ". _prepare_insert($data, 2));
Dries's avatar
   
Dries committed
106
107
    module_invoke_all("taxonomy", "insert", "vocabulary", $edit);
    $message = t("created new vocabulary '%name'.", array("%name" => $edit["name"]));
Kjartan's avatar
Kjartan committed
108
  }
Dries's avatar
   
Dries committed
109
110

  cache_clear_all();
Dries's avatar
   
Dries committed
111
112

  return $message;
Kjartan's avatar
Kjartan committed
113
}
Dries's avatar
 
Dries committed
114

Kjartan's avatar
Kjartan committed
115
function taxonomy_del_vocabulary($vid) {
Dries's avatar
   
Dries committed
116
117
  $vocabulary = taxonomy_get_vocabulary($vid);

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

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

Dries's avatar
   
Dries committed
126
127
  cache_clear_all();

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

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

Dries's avatar
   
Dries committed
147
148
  $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
149

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

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

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

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

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

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

Kjartan's avatar
Kjartan committed
182
183
  return form($form);
}
Dries's avatar
 
Dries committed
184

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

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

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

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

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

Dries's avatar
   
Dries committed
237
238
  cache_clear_all();

Dries's avatar
   
Dries committed
239
  return $message;
Kjartan's avatar
Kjartan committed
240
}
Dries's avatar
 
Dries committed
241

Kjartan's avatar
Kjartan committed
242
function taxonomy_del_term($tid) {
Dries's avatar
   
Dries committed
243
244
  $term = taxonomy_get_term($tid);

Dries's avatar
   
Dries committed
245
246
247
248
249
  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
250

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

Dries's avatar
   
Dries committed
253
254
  cache_clear_all();

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

Kjartan's avatar
Kjartan committed
270
function taxonomy_overview() {
Dries's avatar
 
Dries committed
271

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

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

Kjartan's avatar
Kjartan committed
276
  $vocabularies = taxonomy_get_vocabularies();
Dries's avatar
   
Dries committed
277

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

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

Dries's avatar
   
Dries committed
292
  return table($header, $rows);
Kjartan's avatar
Kjartan committed
293
294
295
296
297
298
299
300
301
302
}

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

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

/*
** API functions
*/

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

Kjartan's avatar
Kjartan committed
334
335
  return $vocabularies;
}
Dries's avatar
 
Dries committed
336

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

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

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

Dries's avatar
   
Dries committed
362
  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
363
364
365
366
}

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

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

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

Kjartan's avatar
Kjartan committed
389
390
391
// save terms of a node
function taxonomy_node_save($nid, $terms) {
  taxonomy_node_delete($nid);
Dries's avatar
 
Dries committed
392

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

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

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

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

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

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

Kjartan's avatar
Kjartan committed
454
  $depth++;
Dries's avatar
   
Dries committed
455

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

Dries's avatar
   
Dries committed
468
469
470
471
472
473
  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
474

Dries's avatar
   
Dries committed
475
      $tree = array_merge($tree, taxonomy_get_tree($vocabulary_id, $child, $depth));
Dries's avatar
   
Dries committed
476
    }
Kjartan's avatar
Kjartan committed
477
  }
Dries's avatar
   
Dries committed
478

Dries's avatar
   
Dries committed
479
  return $tree ? $tree : array();
Kjartan's avatar
Kjartan committed
480
}
Dries's avatar
 
Dries committed
481

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

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

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

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

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

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

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

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

  return $result;
}

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

  return $result;
}

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

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

/*
** service functions
*/

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

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

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

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

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

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

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

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

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

Dries's avatar
   
Dries committed
647
648
649
650
651
652
653
654
/*
** 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;

655
656
  if ($taxonomy->str_tids) {
    if ($taxonomy->operator == "or") {
Dries's avatar
   
Dries committed
657
658
      $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'";
659
660
    }
    else {
Dries's avatar
   
Dries committed
661
      $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
662

663
      // Special trick as we could not find anything better:
Dries's avatar
   
Dries committed
664
      $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)));
665
666
      $sql_count = "SELECT $count";
    }
Dries's avatar
   
Dries committed
667

668
669
670
671
672
673
    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
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
  }

  return $result;
}

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

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

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

Dries's avatar
   
Dries committed
708
709
710
711
712
713

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

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

Kjartan's avatar
Kjartan committed
727
/*
Dries's avatar
 
Dries committed
728
729
730
** admin
*/

Kjartan's avatar
Kjartan committed
731
function taxonomy_admin() {
Dries's avatar
   
Dries committed
732
733
  $op = $_POST["op"];
  $edit = $_POST["edit"];
Kjartan's avatar
Kjartan committed
734
735

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

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

795
  return $output;
Kjartan's avatar
Kjartan committed
796
797
}

Dries's avatar
   
Dries committed
798
function taxonomy_help($section = "admin/help#taxonomy") {
Dries's avatar
   
Dries committed
799
  $output = "";
Dries's avatar
   
Dries committed
800

Dries's avatar
   
Dries committed
801
  switch ($section) {
Dries's avatar
   
Dries committed
802
    case 'admin/system/modules#description':
Dries's avatar
   
Dries committed
803
      $output = t("Enables the organization of content into categories.");
Dries's avatar
   
Dries committed
804
      break;
Dries's avatar
   
Dries committed
805
    case 'admin/taxonomy':
Dries's avatar
   
Dries committed
806
      $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
807
      break;
Dries's avatar
   
Dries committed
808
    case 'admin/taxonomy/add/vocabulary':
Dries's avatar
   
Dries committed
809
      $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
810
      break;
Dries's avatar
   
Dries committed
811
    case 'admin/help#taxonomy':
Dries's avatar
   
Dries committed
812
      $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
813
814
      $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
815
      $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
816
      $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
817
818
819
820
821
822
823
824
825
826
      $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
827
      $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
828
829
830
831
832
833
834
835
836
      $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
837
      $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
838
839
      break;
  }
Dries's avatar
   
Dries committed
840
841

  return $output;
Kjartan's avatar
Kjartan committed
842
}
Dries's avatar
   
Dries committed
843
?>