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

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

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

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

Dries Buytaert's avatar
   
Dries Buytaert committed
24
25
26
27
28
29
30
31
32
33
34
/**
 * Implementation of hook_link().
 *
 * This hook is extended with $type = 'taxonomy terms' to allow themes to
 * print lists of terms associated with a node. Themes can print taxonomy
 * links with:
 *
 * if (module_exist('taxonomy')) {
 *   $this->links(taxonomy_link('taxonomy terms', $node));
 * }
 */
Dries Buytaert's avatar
   
Dries Buytaert committed
35
function taxonomy_link($type, $node = NULL) {
Dries Buytaert's avatar
   
Dries Buytaert committed
36
37
38
39
40
41
  if ($type == 'system') {
      menu('admin/taxonomy', t('categories'), user_access('administer taxonomy') ? 'taxonomy_admin' : MENU_DENIED, 3);
      menu('admin/taxonomy/add/vocabulary', t('create new vocabulary'), user_access('administer taxonomy') ? 'taxonomy_admin' : MENU_DENIED);
      menu('admin/taxonomy/help', t('help'), user_access('administer taxonomy') ? 'taxonomy_admin' : MENU_DENIED, 9);

      menu('taxonomy', t('taxonomy'), user_access('access content') ? 'taxonomy_page' : MENU_DENIED, 0, MENU_HIDE, MENU_LOCKED);
Dries Buytaert's avatar
   
Dries Buytaert committed
42
  }
Dries Buytaert's avatar
   
Dries Buytaert committed
43
  else if ($type == 'taxonomy terms' && $node != NULL) {
Kjartan Mannes's avatar
   
Kjartan Mannes committed
44
    $links = array();
Dries Buytaert's avatar
   
Dries Buytaert committed
45
46
47
    if ($node->taxonomy) {
      foreach ($node->taxonomy as $tid) {
        $term = taxonomy_get_term($tid);
48
        $links[] = l($term->name, "taxonomy/page/or/$term->tid", $term->description ? array ('title' => $term->description) : array());
Dries Buytaert's avatar
   
Dries Buytaert committed
49
50
51
52
53
      }
    }
    else {
      $links = array();
      foreach (taxonomy_node_get_terms($node->nid) as $term) {
54
        $links[] = l($term->name, "taxonomy/page/or/$term->tid", $term->description ? array ('title' => $term->description) : array());
Dries Buytaert's avatar
   
Dries Buytaert committed
55
      }
Dries Buytaert's avatar
   
Dries Buytaert committed
56
57
58
59

    }
    return $links;
  }
Kjartan Mannes's avatar
Kjartan Mannes committed
60
61
}

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

Kjartan Mannes's avatar
Kjartan Mannes committed
66
function taxonomy_form_vocabulary($edit = array()) {
Dries Buytaert's avatar
   
Dries Buytaert committed
67
68
  foreach (node_list() as $type) {
    $nodetypes[$type] = node_invoke($type, "node_name");
Kjartan Mannes's avatar
Kjartan Mannes committed
69
  }
Dries Buytaert's avatar
   
Dries Buytaert committed
70

Dries Buytaert's avatar
   
Dries Buytaert committed
71
72
  $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."));
73
  $form .= form_textfield(t("Help text"), "help", $edit["help"], 50, 255, t("Optional") .". ". t("Instructions to present to the user when choosing a term.") .".");
Dries Buytaert's avatar
   
Dries Buytaert committed
74
  $form .= form_checkboxes(t("Types"), "nodes", explode(",", $edit["nodes"]), $nodetypes, t("Required") .". ". t("A list of node types you want to associate this vocabulary with."));
Dries Buytaert's avatar
   
Dries Buytaert committed
75
76
  $form .= form_checkbox(t("Related terms"), "relations", 1, $edit["relations"], t("Optional") .". ". t("Allows <a href=\"%help-url\">related terms</a> in this vocabulary.", array("%help-url" => url("admin/taxonomy/help", NULL, NULL, "related-terms"))));
  $form .= form_radios(t("Hierarchy"), "hierarchy", $edit["hierarchy"], array(t("Disabled"), t("Single"), t("Multiple")), t("Optional") .". ". t("Allows <a href=\"%help-url\">a tree-like hierarchy</a> between terms of this vocabulary.", array("%help-url" => url("admin/taxonomy/help", NULL, NULL, "hierarchy"))), "", 0);
Dries Buytaert's avatar
   
Dries Buytaert committed
77
  $form .= form_checkbox(t("Multiple select"), "multiple", 1, $edit["multiple"], t("Optional") .". ". t("Allows nodes to have more than one term in this vocabulary."));
78
  $form .= form_checkbox(t("Required"), "required", 1, $edit["required"], t("If enabled every node <strong>must</strong> have at least one term in this vocabulary"));
Dries Buytaert's avatar
   
Dries Buytaert committed
79
  $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 Buytaert's avatar
   
Dries Buytaert committed
80
  $form .= form_submit(t("Submit"));
Dries Buytaert's avatar
 
Dries Buytaert committed
81

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

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

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

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

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

Dries Buytaert's avatar
   
Dries Buytaert committed
113
114
  drupal_set_message($message);
  return $edit;
Kjartan Mannes's avatar
Kjartan Mannes committed
115
}
Dries Buytaert's avatar
 
Dries Buytaert committed
116

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

Dries Buytaert's avatar
   
Dries Buytaert committed
120
121
  db_query("DELETE FROM {vocabulary} WHERE vid = %d", $vid);
  $result = db_query("SELECT tid FROM {term_data} WHERE vid = %d", $vid);
Kjartan Mannes's avatar
Kjartan Mannes committed
122
123
  while ($term = db_fetch_object($result)) {
    taxonomy_del_term($term->tid);
Dries Buytaert's avatar
 
Dries Buytaert committed
124
  }
Dries Buytaert's avatar
   
Dries Buytaert committed
125

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

Dries Buytaert's avatar
   
Dries Buytaert committed
128
129
  cache_clear_all();

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

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

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

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

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

Kjartan Mannes's avatar
Kjartan Mannes committed
162
    if ($vocabulary->hierarchy == 1) {
Dries Buytaert's avatar
   
Dries Buytaert committed
163
      $form .= _taxonomy_term_select(t("Parent"), "parent", $parent, $vocabulary_id, t("Required") .". ". l(t("Parent term"), "admin/taxonomy/help", NULL, NULL, "parent") .".", 0, "<". t("root") .">", $exclude);
Dries Buytaert's avatar
 
Dries Buytaert committed
164
    }
Kjartan Mannes's avatar
Kjartan Mannes committed
165
    elseif ($vocabulary->hierarchy == 2) {
Dries Buytaert's avatar
   
Dries Buytaert committed
166
      $form .= _taxonomy_term_select(t("Parents"), "parent", $parent, $vocabulary_id, t("Required") .". ". l(t("Parent terms"), "admin/taxonomy/help", NULL, NULL, "parent") .".", 1, "<". t("root") .">", $exclude);
Dries Buytaert's avatar
 
Dries Buytaert committed
167
    }
Kjartan Mannes's avatar
Kjartan Mannes committed
168
  }
Dries Buytaert's avatar
 
Dries Buytaert committed
169

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

Dries Buytaert's avatar
   
Dries Buytaert committed
174
  $form .= form_textarea(t("Synonyms"), "synonyms", implode("\n", taxonomy_get_synonyms($edit["tid"])), 30, 5, t("Optional") . ". ". t("<a href=\"%help-url\">Synonyms</a> of this term, one synonym per line.", array("%help-url" => url("admin/taxonomy/help", NULL, NULL, "synonyms"))));
Dries Buytaert's avatar
   
Dries Buytaert committed
175
  $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 Mannes's avatar
Kjartan Mannes committed
176
  $form .= form_hidden("vid", $vocabulary->vid);
Dries Buytaert's avatar
   
Dries Buytaert committed
177
  $form .= form_submit(t("Submit"));
Kjartan Mannes's avatar
Kjartan Mannes committed
178
179

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

Kjartan Mannes's avatar
Kjartan Mannes committed
184
185
  return form($form);
}
Dries Buytaert's avatar
 
Dries Buytaert committed
186

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

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

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

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

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

Dries Buytaert's avatar
   
Dries Buytaert committed
239
240
  cache_clear_all();

Dries Buytaert's avatar
   
Dries Buytaert committed
241
  drupal_set_message($message);
Dries Buytaert's avatar
   
Dries Buytaert committed
242
  return $edit;
Kjartan Mannes's avatar
Kjartan Mannes committed
243
}
Dries Buytaert's avatar
 
Dries Buytaert committed
244

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

Dries Buytaert's avatar
   
Dries Buytaert committed
248
249
250
251
252
  db_query("DELETE FROM {term_data} WHERE tid = %d", $tid);
  db_query("DELETE FROM {term_hierarchy} WHERE tid = %d", $tid);
  db_query("DELETE FROM {term_relation} WHERE tid1 = %d OR tid2 = %d", $tid, $tid);
  db_query("DELETE FROM {term_synonym} WHERE tid = %d", $tid);
  db_query("DELETE FROM {term_node} WHERE tid = %d", $tid);
Dries Buytaert's avatar
   
Dries Buytaert committed
253

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

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

Dries Buytaert's avatar
   
Dries Buytaert committed
258
259
260
261
262
263
264
265
266
267
268
269
270
  return t("deleted term '%name'.", array("%name" => $term->name));
}

function _taxonomy_confirm_del_term($tid) {
  $term = taxonomy_get_term($tid);

  $form .= form_hidden("confirm", 1);
  $form .= form_hidden("type", "term");
  $form .= form_hidden("tid", $tid);
  $form .= form_submit(t("Delete"));
  $form .= form_submit(t("Cancel"));

  return form(form_item(t("Delete term '%name'", array("%name" => $term->name)), $form, t("Are you sure you want to delete the term?")));
Kjartan Mannes's avatar
Kjartan Mannes committed
271
}
Dries Buytaert's avatar
 
Dries Buytaert committed
272

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

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

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

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

Kjartan Mannes's avatar
Kjartan Mannes committed
281
282
  foreach ($vocabularies as $vocabulary) {
    $links = array();
Dries Buytaert's avatar
   
Dries Buytaert committed
283
284
    $types = array();
    foreach(explode(",", $vocabulary->nodes) as $type) {
Dries Buytaert's avatar
   
Dries Buytaert committed
285
      $types[] = node_invoke($type, "node_name");
Dries Buytaert's avatar
   
Dries Buytaert committed
286
287
    }
    $rows[] = array($vocabulary->name, array("data" => implode(", ", $types), "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 Mannes's avatar
Kjartan Mannes committed
288

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

Dries Buytaert's avatar
   
Dries Buytaert committed
299
  return theme("table", $header, $rows);
Kjartan Mannes's avatar
Kjartan Mannes committed
300
301
}

302
function taxonomy_form($vocabulary_id, $value = 0, $error = array(), $help = NULL) {
Kjartan Mannes's avatar
Kjartan Mannes committed
303
  $vocabulary = taxonomy_get_vocabulary($vocabulary_id);
304
  $help = ($help) ? $help : $vocabulary->help;
Kjartan Mannes's avatar
Kjartan Mannes committed
305
306
307
308
  if ($vocabulary->required) {
    $blank = 0;
  }
  else {
Dries Buytaert's avatar
   
Dries Buytaert committed
309
    $blank = "<". t("none") .">";
Kjartan Mannes's avatar
Kjartan Mannes committed
310
  }
Dries Buytaert's avatar
   
Dries Buytaert committed
311

312
  $help .= $error['taxonomy'];
Dries Buytaert's avatar
   
Dries Buytaert committed
313

314
  return _taxonomy_term_select($vocabulary->name, 'taxonomy', $value, $vocabulary_id, $help, intval($vocabulary->multiple), $blank);
Kjartan Mannes's avatar
Kjartan Mannes committed
315
}
Dries Buytaert's avatar
 
Dries Buytaert committed
316
317
318
319
320

/*
** API functions
*/

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

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

Kjartan Mannes's avatar
Kjartan Mannes committed
337
// return form with current term
338
function taxonomy_node_form($type, $node = '', $error = array()) {
Kjartan Mannes's avatar
Kjartan Mannes committed
339
340
341
  if (!$node->taxonomy) {
    if ($node->nid) {
      $terms = array_keys(taxonomy_node_get_terms($node->nid));
Kjartan Mannes's avatar
Kjartan Mannes committed
342
343
    }
    else {
Kjartan Mannes's avatar
Kjartan Mannes committed
344
      $terms = 0;
Dries Buytaert's avatar
 
Dries Buytaert committed
345
    }
Kjartan Mannes's avatar
Kjartan Mannes committed
346
347
348
349
  }
  else {
    $terms = $node->taxonomy;
  }
Dries Buytaert's avatar
 
Dries Buytaert committed
350

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

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

Dries Buytaert's avatar
   
Dries Buytaert 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 Mannes's avatar
Kjartan Mannes 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 Buytaert's avatar
   
Dries Buytaert 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 Mannes's avatar
Kjartan Mannes committed
368
369
370
  $terms = array();
  while ($term = db_fetch_object($result)) {
    $terms[$term->$key] = $term;
Dries Buytaert's avatar
 
Dries Buytaert committed
371
  }
Kjartan Mannes's avatar
Kjartan Mannes 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 Buytaert's avatar
 
Dries Buytaert committed
378

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

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

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

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

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

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

Dries Buytaert's avatar
   
Dries Buytaert committed
435
436
437
438
439
440
441
442
443
444
445
446
447
448
// Gets all parents, parents of parents, etc.
function taxonomy_get_parents_all($tid, $key = "tid") {
  $parents = array();
  if ($tid) {
    $parents[] = taxonomy_get_term($tid);
    $n = 0;
    while ($parent = taxonomy_get_parents($parents[$n]->tid)) {
      $parents = array_merge($parents, $parent);
      $n++;
    }
  }
  return $parents;
}

Kjartan Mannes's avatar
Kjartan Mannes committed
449
450
451
// hierarchy: get children
function taxonomy_get_children($tid, $vid = 0, $key = "tid") {
  if ($vid) {
Dries Buytaert's avatar
   
Dries Buytaert committed
452
    $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 Buytaert's avatar
 
Dries Buytaert committed
453
  }
Kjartan Mannes's avatar
Kjartan Mannes committed
454
  else {
Dries Buytaert's avatar
   
Dries Buytaert committed
455
    $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 Mannes's avatar
Kjartan Mannes committed
456
457
458
459
460
461
462
  }
  $children = array();
  while ($term = db_fetch_object($result)) {
    $children[$term->$key] = $term;
  }
  return $children;
}
Dries Buytaert's avatar
 
Dries Buytaert committed
463

Kjartan Mannes's avatar
Kjartan Mannes committed
464
// hierarchy: get whole family, with tid, parent and depth; useful to show
Dries Buytaert's avatar
   
Dries Buytaert committed
465
function taxonomy_get_tree($vocabulary_id, $parent = 0, $depth = -1, $key = "tid") {
Dries Buytaert's avatar
   
Dries Buytaert committed
466
  static $children, $parents, $terms;
Dries Buytaert's avatar
   
Dries Buytaert committed
467

Kjartan Mannes's avatar
Kjartan Mannes committed
468
  $depth++;
Dries Buytaert's avatar
   
Dries Buytaert committed
469

Dries Buytaert's avatar
   
Dries Buytaert committed
470
471
472
473
  // 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 Buytaert's avatar
   
Dries Buytaert committed
474
    $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 Buytaert's avatar
   
Dries Buytaert committed
475
    while ($term = db_fetch_object($result)) {
Dries Buytaert's avatar
   
Dries Buytaert committed
476
477
478
      $children[$vocabulary_id][$term->parent][] = $term->tid;
      $parents[$vocabulary_id][$term->tid][] = $term->parent;
      $terms[$vocabulary_id][$term->tid] = $term;
Dries Buytaert's avatar
 
Dries Buytaert committed
479
480
    }
  }
Dries Buytaert's avatar
   
Dries Buytaert committed
481

Dries Buytaert's avatar
   
Dries Buytaert committed
482
483
484
485
486
487
  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 Buytaert's avatar
   
Dries Buytaert committed
488

Dries Buytaert's avatar
   
Dries Buytaert committed
489
      $tree = array_merge($tree, taxonomy_get_tree($vocabulary_id, $child, $depth));
Dries Buytaert's avatar
   
Dries Buytaert committed
490
    }
Kjartan Mannes's avatar
Kjartan Mannes committed
491
  }
Dries Buytaert's avatar
   
Dries Buytaert committed
492

Dries Buytaert's avatar
   
Dries Buytaert committed
493
  return $tree ? $tree : array();
Kjartan Mannes's avatar
Kjartan Mannes committed
494
}
Dries Buytaert's avatar
 
Dries Buytaert committed
495

Kjartan Mannes's avatar
Kjartan Mannes committed
496
497
498
// synonyms: return array of synonyms
function taxonomy_get_synonyms($tid) {
  if ($tid) {
Dries Buytaert's avatar
   
Dries Buytaert committed
499
    $result = db_query("SELECT name FROM {term_synonym} WHERE tid = %d", $tid);
Kjartan Mannes's avatar
Kjartan Mannes committed
500
501
    while ($synonym = db_fetch_array($result)) {
      $synonyms[] = $synonym["name"];
Dries Buytaert's avatar
 
Dries Buytaert committed
502
    }
Kjartan Mannes's avatar
Kjartan Mannes committed
503
    return $synonyms ? $synonyms : array();
Dries Buytaert's avatar
 
Dries Buytaert committed
504
  }
Kjartan Mannes's avatar
Kjartan Mannes committed
505
506
  else {
    return array();
Dries Buytaert's avatar
   
Dries Buytaert committed
507
  }
Kjartan Mannes's avatar
Kjartan Mannes committed
508
}
Dries Buytaert's avatar
   
Dries Buytaert committed
509

Kjartan Mannes's avatar
Kjartan Mannes committed
510
511
// synonyms: return original term
function taxonomy_get_synonym_root($term) {
Dries Buytaert's avatar
   
Dries Buytaert committed
512
  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 Mannes's avatar
Kjartan Mannes committed
513
}
Dries Buytaert's avatar
   
Dries Buytaert committed
514

Dries Buytaert's avatar
   
Dries Buytaert committed
515
// given a term id, count number of published nodes in it
Dries Buytaert's avatar
   
Dries Buytaert committed
516
function taxonomy_term_count_nodes($tid, $type = 0) {
Kjartan Mannes's avatar
Kjartan Mannes committed
517
  static $count;
Dries Buytaert's avatar
   
Dries Buytaert committed
518

Dries Buytaert's avatar
   
Dries Buytaert committed
519
520
521
  if (!isset($count[$type])) {
    // $type == 0 always evaluates true is $type is a string
    if (is_numeric($type)) {
Dries Buytaert's avatar
   
Dries Buytaert committed
522
      $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 Buytaert's avatar
   
Dries Buytaert committed
523
524
    }
    else {
Dries Buytaert's avatar
   
Dries Buytaert committed
525
      $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 Buytaert's avatar
   
Dries Buytaert committed
526
    }
Kjartan Mannes's avatar
Kjartan Mannes committed
527
    while ($term = db_fetch_object($result)) {
Dries Buytaert's avatar
   
Dries Buytaert committed
528
      $count[$type][$term->tid] = $term->c;
Dries Buytaert's avatar
   
Dries Buytaert committed
529
530
531
    }
  }

Kjartan Mannes's avatar
Kjartan Mannes committed
532
  foreach (_taxonomy_term_children($tid) as $c) {
Dries Buytaert's avatar
   
Dries Buytaert committed
533
    $children_count += taxonomy_term_count_nodes($c, $type);
Kjartan Mannes's avatar
Kjartan Mannes committed
534
  }
Dries Buytaert's avatar
   
Dries Buytaert committed
535
  return $count[$type][$tid] + $children_count;
Kjartan Mannes's avatar
Kjartan Mannes committed
536
537
538
539
540
}

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

Dries Buytaert's avatar
   
Dries Buytaert committed
542
  if (!isset($children)) {
Dries Buytaert's avatar
   
Dries Buytaert committed
543
    $result = db_query("SELECT tid, parent FROM {term_hierarchy} ");
Kjartan Mannes's avatar
Kjartan Mannes committed
544
545
    while ($term = db_fetch_object($result)) {
      $children[$term->parent][] = $term->tid;
Dries Buytaert's avatar
   
Dries Buytaert committed
546
    }
Dries Buytaert's avatar
 
Dries Buytaert committed
547
  }
Kjartan Mannes's avatar
Kjartan Mannes committed
548
549
  return $children[$tid] ? $children[$tid] : array();
}
Dries Buytaert's avatar
 
Dries Buytaert committed
550

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

  return $result;
}

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

  return $result;
}

Kjartan Mannes's avatar
Kjartan Mannes committed
587
588
function taxonomy_get_vocabulary($vid) {
  // simple cache using a static var?
Dries Buytaert's avatar
   
Dries Buytaert committed
589
  return db_fetch_object(db_query("SELECT * FROM {vocabulary} WHERE vid = %d", $vid));
Kjartan Mannes's avatar
Kjartan Mannes committed
590
}
Dries Buytaert's avatar
 
Dries Buytaert committed
591

Kjartan Mannes's avatar
Kjartan Mannes committed
592
593
function taxonomy_get_term($tid) {
  // simple cache using a static var?
Dries Buytaert's avatar
   
Dries Buytaert committed
594
  return db_fetch_object(db_query("SELECT * FROM {term_data} WHERE tid = %d", $tid));
Kjartan Mannes's avatar
Kjartan Mannes committed
595
}
Dries Buytaert's avatar
 
Dries Buytaert committed
596
597
598
599
600

/*
** service functions
*/

Kjartan Mannes's avatar
Kjartan Mannes committed
601
function _taxonomy_term_select($title, $name, $value, $vocabulary_id, $description, $multiple, $blank, $exclude = array()) {
Dries Buytaert's avatar
   
Dries Buytaert committed
602
  $tree = taxonomy_get_tree($vocabulary_id);
Dries Buytaert's avatar
 
Dries Buytaert committed
603

604
605
606
607
608
609
610
611
  // We store the last selected ID in a session variable:
  if (!$value) {
    $value = $_SESSION['vocabulary']["$vocabulary_id"];
  }
  else {
    $_SESSION['vocabulary']["$vocabulary_id"] = $value;
  }

Kjartan Mannes's avatar
Kjartan Mannes committed
612
  if ($blank) {
Dries Buytaert's avatar
   
Dries Buytaert committed
613
    $options[] = array("tid" => 0, "name" => $blank);
Kjartan Mannes's avatar
Kjartan Mannes committed
614
  }
Dries Buytaert's avatar
 
Dries Buytaert committed
615

Kjartan Mannes's avatar
Kjartan Mannes committed
616
617
618
  if ($tree) {
    foreach ($tree as $term) {
      if (!in_array($term->tid, $exclude)) {
Dries Buytaert's avatar
   
Dries Buytaert committed
619
        $options[] = array("tid" => $term->tid, "name" => _taxonomy_depth($term->depth, '-').$term->name);
Dries Buytaert's avatar
 
Dries Buytaert committed
620
621
      }
    }
Kjartan Mannes's avatar
Kjartan Mannes committed
622
623
624
625
626
    if (!$blank && !$value) {
      // required but without a predefined value, so set first as predefined
      $value = $tree[0]->tid;
    }
  }
Dries Buytaert's avatar
 
Dries Buytaert committed
627

Kjartan Mannes's avatar
Kjartan Mannes committed
628
  if (count($options) > 0) {
Dries Buytaert's avatar
   
Dries Buytaert committed
629
    foreach ($options as $option) {
Dries Buytaert's avatar
   
Dries Buytaert committed
630
      $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 Mannes's avatar
Kjartan Mannes committed
631
    }
Dries Buytaert's avatar
 
Dries Buytaert committed
632

Dries Buytaert's avatar
   
Dries Buytaert committed
633
    $size = min(12, count($options));
Dries Buytaert's avatar
 
Dries Buytaert committed
634

Dries Buytaert's avatar
   
Dries Buytaert committed
635
    return form_item($title, "<select name=\"edit[$name][]\"". ($multiple ? " multiple=\"multiple\" size=\"$size\"" : "") . ($extra ? " $extra" : "") .">$select</select>", $description);
Dries Buytaert's avatar
 
Dries Buytaert committed
636
  }
Kjartan Mannes's avatar
Kjartan Mannes committed
637
}
Dries Buytaert's avatar
 
Dries Buytaert committed
638

Kjartan Mannes's avatar
Kjartan Mannes committed
639
640
641
function _taxonomy_depth($depth, $graphic = '--') {
  for ($n = 0; $n < $depth; $n++) {
    $result .= $graphic;
Dries Buytaert's avatar
 
Dries Buytaert committed
642
  }
Kjartan Mannes's avatar
Kjartan Mannes committed
643
644
  return $result;
}
Dries Buytaert's avatar
 
Dries Buytaert committed
645

Kjartan Mannes's avatar
Kjartan Mannes committed
646
647
648
function _prepare_update($data) {
  foreach ($data as $key => $value) {
    $q[] = "$key = '". check_query($value) ."'";
Dries Buytaert's avatar
 
Dries Buytaert committed
649
  }
Kjartan Mannes's avatar
Kjartan Mannes committed
650
651
652
  $result = implode(", ", $q);
  return $result;
}
Dries Buytaert's avatar
 
Dries Buytaert committed
653

Kjartan Mannes's avatar
Kjartan Mannes committed
654
655
656
657
658
659
660
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 Buytaert's avatar
 
Dries Buytaert committed
661
    }
Kjartan Mannes's avatar
Kjartan Mannes committed
662
    $result = implode(", ", $q);
Dries Buytaert's avatar
 
Dries Buytaert committed
663
  }
Kjartan Mannes's avatar
Kjartan Mannes committed
664
665
  return "($result)";
}
Dries Buytaert's avatar
   
Dries Buytaert committed
666

Dries Buytaert's avatar
   
Dries Buytaert committed
667
668
669
670
671
672
673
674
/*
** 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;

675
676
  if ($taxonomy->str_tids) {
    if ($taxonomy->operator == "or") {
Dries Buytaert's avatar
   
Dries Buytaert committed
677
678
      $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'";
679
680
    }
    else {
Dries Buytaert's avatar
   
Dries Buytaert committed
681
      $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 Buytaert's avatar
   
Dries Buytaert committed
682

683
      // Special trick as we could not find anything better:
Dries Buytaert's avatar
   
Dries Buytaert committed
684
      $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)));
685
686
      $sql_count = "SELECT $count";
    }
Dries Buytaert's avatar
   
Dries Buytaert committed
687

688
689
690
691
692
693
    if ($pager) {
      $result = pager_query($sql, variable_get("default_nodes_main", 10) , 0, $sql_count);
    }
    else {
      $result = db_query_range($sql, 0, 15);
    }
Dries Buytaert's avatar
   
Dries Buytaert committed
694
695
696
697
698
699
700
701
702
703
704
705
  }

  return $result;
}

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

  while ($node = db_fetch_object($result)) {
Dries Buytaert's avatar
   
Dries Buytaert committed
706
    $output .= node_view(node_load(array("nid" => $node->nid, "type" => $node->type)), 1);
Dries Buytaert's avatar
   
Dries Buytaert committed
707
  }
Dries Buytaert's avatar
Dries Buytaert committed
708
  $output .= theme("pager", NULL, variable_get("default_nodes_main", 10), 0);
Dries Buytaert's avatar
   
Dries Buytaert committed
709
  return $output;
Dries Buytaert's avatar
   
Dries Buytaert committed
710
711
}

Dries Buytaert's avatar
   
Dries Buytaert committed
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
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 Mannes's avatar
Kjartan Mannes committed
727
function taxonomy_page() {
Dries Buytaert's avatar
   
Dries Buytaert committed
728

Dries Buytaert's avatar
   
Dries Buytaert committed
729
730
731
  $taxonomy->operator = arg(2);
  $taxonomy->str_tids = check_query(arg(3));
  $taxonomy->tids = explode(",", $taxonomy->str_tids);
Dries Buytaert's avatar
   
Dries Buytaert committed
732

733
  if (ereg("^([0-9]+,){0,}[0-9]+$", $taxonomy->str_tids)) {
Dries Buytaert's avatar
   
Dries Buytaert committed
734
735
736
    switch (arg(1)) {
      case "feed":
        taxonomy_feed($taxonomy);
Kjartan Mannes's avatar
Kjartan Mannes committed
737
      break;
Dries Buytaert's avatar
   
Dries Buytaert committed
738
      default:
Dries Buytaert's avatar
   
Dries Buytaert committed
739
      // Build title:
740
      $sql = 'SELECT name FROM {term_data} WHERE tid IN (%s)';
Dries Buytaert's avatar
   
Dries Buytaert committed
741
      $result = db_query($sql, $taxonomy->str_tids);
Kjartan Mannes's avatar
Kjartan Mannes committed
742
      $names = array();
Dries Buytaert's avatar
   
Dries Buytaert committed
743
744
745
      while ($term = db_fetch_object($result)) {
        $names[] = $term->name;
      }
Dries Buytaert's avatar
   
Dries Buytaert committed
746
747
748
749
750
751
752
753
754
755

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

Dries Buytaert's avatar
   
Dries Buytaert committed
756
      drupal_set_html_head('<link rel="alternate" type="application/rss+xml" title="RSS - '. implode(' : ', $names) .'" href="'. url("taxonomy/feed/or/$taxonomy->str_tids") .'" />');
Dries Buytaert's avatar
Dries Buytaert committed
757

Dries Buytaert's avatar
   
Dries Buytaert committed
758
      $output = taxonomy_render_nodes(taxonomy_select_nodes($taxonomy));
Dries Buytaert's avatar
   
Dries Buytaert committed
759
      print theme("page", $output, implode(', ', $names), $breadcrumbs);
Dries Buytaert's avatar
   
Dries Buytaert committed
760
      break;
Dries Buytaert's avatar
   
Dries Buytaert committed
761
762
763
764
    }
  }
  else {
    drupal_not_found();
Dries Buytaert's avatar
   
Dries Buytaert committed
765
  }
Kjartan Mannes's avatar
Kjartan Mannes committed
766
}
Dries Buytaert's avatar
   
Dries Buytaert committed
767

Kjartan Mannes's avatar
Kjartan Mannes committed
768
/*
Dries Buytaert's avatar
 
Dries Buytaert committed
769
770
771
** admin
*/

Kjartan Mannes's avatar
Kjartan Mannes committed
772
function taxonomy_admin() {
Dries Buytaert's avatar
   
Dries Buytaert committed
773
774
  $op = $_POST["op"];
  $edit = $_POST["edit"];
Kjartan Mannes's avatar
Kjartan Mannes committed
775

Dries Buytaert's avatar
   
Dries Buytaert committed
776
777
778
  if (empty($op)) {
    $op = arg(2);
  }
Dries Buytaert's avatar
   
Dries Buytaert committed
779

Dries Buytaert's avatar
   
Dries Buytaert committed
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
  switch ($op) {
    case "add":
      if (arg(3) == "vocabulary") {
        $output .= taxonomy_form_vocabulary();
      }
      else if (arg(3) == "term") {
        $output .= taxonomy_form_term();
      }
      break;
    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))));
      }
      break;
    case "preview":
      $output .= taxonomy_form(arg(4));
      break;
    case "help":
      $output .= taxonomy_help();
      break;
    case t("Delete"):
      if (!$edit["confirm"]) {
805
        if (arg(3) == "vocabulary") {
Dries Buytaert's avatar
   
Dries Buytaert committed
806
          $output .= _taxonomy_confirm_del_vocabulary($edit["vid"]);
807
        }
Dries Buytaert's avatar
   
Dries Buytaert committed
808
809
        else {
          $output .= _taxonomy_confirm_del_term($edit["tid"]);
810
        }
Kjartan Mannes's avatar
Kjartan Mannes committed
811
        break;
Dries Buytaert's avatar
   
Dries Buytaert committed
812
813
814
815
816
817
818
819
820
821
822
823
824
825
      }
      else {
        $edit["name"] = 0;
        // fall through:
      }
    case t("Submit"):
      if (arg(3) == "vocabulary") {
        taxonomy_save_vocabulary($edit);
      }
      else {
        taxonomy_save_term($edit);
        if (!$edit["tid"]) {
          // if INSERT show form again
          $output .= taxonomy_form_term();
Dries Buytaert's avatar
   
Dries Buytaert committed
826
827
          break;
        }
Dries Buytaert's avatar
   
Dries Buytaert committed
828
829
830
831
832
        // else (UPDATE or DELETE) fall through
      }
      // fall through:
    default:
      $output .= taxonomy_overview();
Kjartan Mannes's avatar
Kjartan Mannes committed
833
  }
Dries Buytaert's avatar
   
Dries Buytaert committed
834

Dries Buytaert's avatar
   
Dries Buytaert committed
835
  print theme("page", $output);
Kjartan Mannes's avatar
Kjartan Mannes committed
836
837
}

Dries Buytaert's avatar
   
Dries Buytaert committed
838
function taxonomy_help($section = "admin/help#taxonomy") {
Dries Buytaert's avatar
   
Dries Buytaert committed
839
  $output = "";
Dries Buytaert's avatar
   
Dries Buytaert committed
840

Dries Buytaert's avatar
   
Dries Buytaert committed
841
  switch ($section) {
Dries Buytaert's avatar
   
Dries Buytaert committed
842
    case 'admin/system/modules#description':
Dries Buytaert's avatar
   
Dries Buytaert committed
843
      $output = t("Enables the organization of content into categories.");
Dries Buytaert's avatar
   
Dries Buytaert committed
844
      break;
Dries Buytaert's avatar
   
Dries Buytaert committed
845
    case 'admin/taxonomy':
Dries Buytaert's avatar
   
Dries Buytaert committed
846
      $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 Buytaert's avatar
   
Dries Buytaert committed
847
      break;
Dries Buytaert's avatar
   
Dries Buytaert committed
848
    case 'admin/taxonomy/add/vocabulary':
Dries Buytaert's avatar
   
Dries Buytaert committed
849
      $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 Buytaert's avatar
   
Dries Buytaert committed
850
      break;
Dries Buytaert's avatar
   
Dries Buytaert committed
851
    case 'admin/help#taxonomy':
Dries Buytaert's avatar
   
Dries Buytaert committed
852
853
      $output .= t("
      <h3>Background</h3>
854
      <p>Taxonomy is the study of classification. Drupal's taxonomy module allows you to define categories which are used to classify co