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

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

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

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

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

Dries's avatar
   
Dries committed
29
function taxonomy_link($type, $node = NULL) {
Kjartan's avatar
Kjartan committed
30
  if ($type == "admin" && user_access("administer taxonomy")) {
Dries's avatar
   
Dries committed
31
32
    $help["taxonomy"] = 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\".");
    $help["vocabulary"] = 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
33

Dries's avatar
   
Dries committed
34
    menu("admin/taxonomy", "taxonomy", "taxonomy_admin", $help["taxonomy"], 3);
35
    menu("admin/taxonomy/add/vocabulary", "create new vocabulary", "taxonomy_admin", $help["vocabulary"]);
Dries's avatar
   
Dries committed
36
    menu("admin/taxonomy/help", "help", "taxonomy_admin", NULL, 9);
Dries's avatar
   
Dries committed
37
  }
Dries's avatar
   
Dries committed
38
  else if ($type == "taxonomy terms" && $node != NULL) {
Dries's avatar
   
Dries committed
39
40
41
42
43
44
45
46
47

    if ($node->taxonomy) {
      foreach ($node->taxonomy as $tid) {
        $term = taxonomy_get_term($tid);
        $links[] = l($term->name, "taxonomy/page/or/$term->tid", $term->description ? array("title" => $term->description) : array());
      }
    }
    else {

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

Dries's avatar
   
Dries committed
56
57
58
59
      $links = array();
      foreach (taxonomy_node_get_terms($node->nid) as $term) {
        $links[] = l($term->name, "taxonomy/page/or/$term->tid", $term->description ? array("title" => $term->description) : array());
      }
Dries's avatar
   
Dries committed
60
61
62
63

    }
    return $links;
  }
Kjartan's avatar
Kjartan committed
64
65
}

Dries's avatar
 
Dries committed
66
67
68
69
/*
** admin pages (form, save, overview)
*/

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

Dries's avatar
   
Dries committed
77
78
  $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."));
Dries's avatar
   
Dries committed
79
  $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);
Dries's avatar
   
Dries committed
80
81
  $form .= form_checkbox(t("Related terms"), "relations", 1, $edit["relations"], t("Optional") . ". " . t("Allows ". l("related terms", "admin/taxonomy/help#relatedterms") ." in this vocabulary."));
  $form .= form_select(t("Hierarchy"), "hierarchy", $edit["hierarchy"], array(t("Disabled"), t("Single"), t("Multiple")), t("Optional") . ". ". t("Allows ". l("a tree-like hierarchy", "admin/taxonomy/help#hierarchy") ." between terms of this vocabulary."), "", 0);
Dries's avatar
   
Dries committed
82
83
  $form .= form_checkbox(t("Multiple select"), "multiple", 1, $edit["multiple"], t("Optional") . ". " . t("Allows nodes to have more than one term in this vocabulary."));
  $form .= form_checkbox(t("Required"), "required", 1, $edit["required"], t("If enabled every node <b>must</b> have at least one term in this vocabulary"));
Dries's avatar
   
Dries committed
84
  $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
85
  $form .= form_submit(t("Submit"));
Dries's avatar
 
Dries committed
86

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

Kjartan's avatar
Kjartan committed
92
93
  return form($form);
}
Kjartan's avatar
Kjartan committed
94

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

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

  cache_clear_all();
Dries's avatar
   
Dries committed
117
118

  return $message;
Kjartan's avatar
Kjartan committed
119
}
Dries's avatar
 
Dries committed
120

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

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

Dries's avatar
   
Dries committed
130
131
  module_invoke_all("taxonomy", "delete", "vocabulary", $vocabulary);

Dries's avatar
   
Dries committed
132
133
  cache_clear_all();

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

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

Dries's avatar
   
Dries committed
153
154
  $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
155

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

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

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

174
175
176
177
  if ($vocabulary->relations) {
    $form .= _taxonomy_term_select(t("Related terms"), "relations", array_keys(taxonomy_get_related($edit["tid"])), $vocabulary_id, t("Optional") . ". ", 1, "<" . t("none") . ">", array($edit["tid"]));
  }

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

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

Kjartan's avatar
Kjartan committed
188
189
  return form($form);
}
Dries's avatar
 
Dries committed
190

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

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

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

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

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

Dries's avatar
   
Dries committed
243
244
  cache_clear_all();

Dries's avatar
   
Dries committed
245
  return $message;
Kjartan's avatar
Kjartan committed
246
}
Dries's avatar
 
Dries committed
247

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

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

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

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

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

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

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

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

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

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

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

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

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

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

/*
** API functions
*/

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Dries's avatar
   
Dries committed
543
544
545
546
547
548
549
550
551
552
/**
 * 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
553
  $db_result = db_query("SELECT * FROM {vocabulary} WHERE LOWER('%s') LIKE LOWER(name)", trim($name));
Dries's avatar
   
Dries committed
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
  $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
572
  $db_result = db_query("SELECT * FROM {term_data} WHERE LOWER('%s') LIKE LOWER(name)", trim($name));
Dries's avatar
   
Dries committed
573
574
575
576
577
578
579
580
  $result = array();
  while ($term = db_fetch_object($db_result)) {
    $result[] = $term;
  }

  return $result;
}

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

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

/*
** service functions
*/

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

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

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

Kjartan's avatar
Kjartan committed
614
  if (count($options) > 0) {
Dries's avatar
   
Dries committed
615
616
    foreach ($options as $option) {
      $select .= "<option value=\"".$option["tid"]."\"". (is_array($value) ? (in_array($option["tid"], $value) ? " selected=\"selected\"" : "") : ($option["tid"] == $value ? " selected=\"selected\"" : "")) .">". check_form($option["name"]) ."</option>";
Kjartan's avatar
Kjartan committed
617
    }
Dries's avatar
 
Dries committed
618

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

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

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

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

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

Dries's avatar
   
Dries committed
653
654
655
656
657
658
659
660
/*
** 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;

661
662
  if ($taxonomy->str_tids) {
    if ($taxonomy->operator == "or") {
Dries's avatar
   
Dries committed
663
664
      $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 LEFT 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 LEFT JOIN {users} u ON n.uid = u.uid WHERE r.tid IN ($taxonomy->str_tids) AND n.status = '1'";
665
666
    }
    else {
Dries's avatar
   
Dries committed
667
      $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 LEFT 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
668

669
      // Special trick as we could not find anything better:
Dries's avatar
   
Dries committed
670
      $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)));
671
672
      $sql_count = "SELECT $count";
    }
Dries's avatar
   
Dries committed
673

674
675
676
677
678
679
    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
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
  }

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

Dries's avatar
   
Dries committed
714
715
716
717
718
719

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

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

Kjartan's avatar
Kjartan committed
733
/*
Dries's avatar
 
Dries committed
734
735
736
** admin
*/

Kjartan's avatar
Kjartan committed
737
function taxonomy_admin() {
Dries's avatar
   
Dries committed
738
739
  $op = $_POST["op"];
  $edit = $_POST["edit"];
Kjartan's avatar
Kjartan committed
740
741

  if (user_access("administer taxonomy")) {
Dries's avatar
   
Dries committed
742
743
744
745
    if (empty($op)) {
      $op = arg(2);
    }

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

801
  return $output;
Kjartan's avatar
Kjartan committed
802
803
804
}

function taxonomy_help() {
Dries's avatar
   
Dries committed
805

Dries's avatar
   
Dries committed
806
807
  $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 <a href=\"http://www.eleganthack.com/archives/002165.html#002165\">classification types</a> and insight into the development of the <i>taxonomy.module</i>, see this <a href=\"http://www.drupal.org/node/view/55\">drupal.org discussion</a>.</p>";
  $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>";
Dries's avatar
   
Dries committed
808
809
810
  $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>";
  $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 <a href=\"http://www.slashdot.com/\">Slashdot's</a> sections.  For more complex implementations, you might create a hierarchical list of categories such as <i>Food</i> taxonomy shown above.</p>";
  $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
811
  $output .= "<p>When setting up a controlled vocabulary you are asked for: <ul><li><b>Vocabulary name</b> (Required) -- The name for this vocabulary. Example: <i>Dairy</i>.</li><li><b>Description</b> (Optional) -- Description of the vocabulary, this can be used by modules and feeds.</li><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><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><li><a id=\"hierarchy\"></a><b>Hierarchy</b> -- Allows a tree-like taxonomy, as in our <i>Foods</i> example above</li><li><b>Multiple select</b> -- Allows nodes to be described using more than one term. Nodes may then appear on multiple taxonomy pages.</li><li><b>Required</b> -- Each node has to have a term in this vacabulary associated with it.</li><li><b>Weight</b> -- The over all weight for this vocaulary in listings with multiple vacabularies.</ul></p>";
Dries's avatar
   
Dries committed
812
  $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
813
814
  $output .= "<p><ul><li><b>Term name</b> (Required) -- The name for this term. Example: <i>Milk</i></li><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><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><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><li><b>Weight</b> (Optional) -- The weight is used to sort the terms of this vocabulary.</li></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, ". l("taxonomy/page/or/1,2","taxonomy/pages/or/1,2") .".  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 ". l("taxonomy overview", "admin/taxonomy") ." 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>";
Dries's avatar
   
Dries committed
815
  $output .= "<h3>RSS feeds</h3><p>Every term, or collection of terms, provides an <a href=\"http://backend.userland.com/stories/rss\">RSS</a> feed to which interested users may subscribe. The URL format for a sample RSS feed is ". l("node/feed/or/1,2","node/feed/or/1,2") .". Built like a Taxonomy URL, ". l("see above", "admin/taxonomy/help#taxonomyURL") ." it starts with \"node/feed\", then has the querystring parameter, and finally the Term IDs.</p>";
Dries's avatar
   
Dries committed
816
  return t($output);
Kjartan's avatar
Kjartan committed
817
}
Dries's avatar
   
Dries committed
818
?>