taxonomy.module 38.4 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

Dries Buytaert's avatar
   
Dries Buytaert 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
14
15
    $channel['link'] = url("taxonomy/view/$taxonomy->operator/$taxonomy->str_tids", NULL, NULL, TRUE);
    $channel['title'] = variable_get('site_name', 'drupal') .' - '. $term->name;
    $channel['description'] = $term->description;
Kjartan Mannes's avatar
Kjartan Mannes committed
16
    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

Dries Buytaert's avatar
   
Dries Buytaert committed
20
21
22
/**
 * Implementation of hook_perm().
 */
Kjartan Mannes's avatar
Kjartan Mannes committed
23
function taxonomy_perm() {
Dries Buytaert's avatar
   
Dries Buytaert committed
24
  return array('administer taxonomy');
Kjartan Mannes's avatar
Kjartan Mannes committed
25
}
Dries Buytaert's avatar
 
Dries Buytaert committed
26

Dries Buytaert's avatar
   
Dries Buytaert committed
27
28
29
30
31
32
33
34
35
36
37
/**
 * 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
38
function taxonomy_link($type, $node = NULL) {
Dries Buytaert's avatar
   
Dries Buytaert committed
39
  if ($type == 'taxonomy terms' && $node != NULL) {
Kjartan Mannes's avatar
   
Kjartan Mannes committed
40
    $links = array();
Dries Buytaert's avatar
   
Dries Buytaert committed
41
    if (array_key_exists('taxonomy', $node)) {
Dries Buytaert's avatar
   
Dries Buytaert committed
42
43
      foreach ($node->taxonomy as $tid) {
        $term = taxonomy_get_term($tid);
44
        $links[] = l($term->name, "taxonomy/page/or/$term->tid", $term->description ? array ('title' => $term->description) : array());
Dries Buytaert's avatar
   
Dries Buytaert committed
45
46
47
48
49
      }
    }
    else {
      $links = array();
      foreach (taxonomy_node_get_terms($node->nid) as $term) {
50
        $links[] = l($term->name, "taxonomy/page/or/$term->tid", $term->description ? array ('title' => $term->description) : array());
Dries Buytaert's avatar
   
Dries Buytaert committed
51
      }
Dries Buytaert's avatar
   
Dries Buytaert committed
52
53
54
55

    }
    return $links;
  }
Kjartan Mannes's avatar
Kjartan Mannes committed
56
57
}

Dries Buytaert's avatar
   
Dries Buytaert committed
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
/**
 * Implementation of hook_menu().
 */
function taxonomy_menu() {
  $items = array();
  $items[] = array('path' => 'admin/taxonomy', 'title' => t('categories'),
    'callback' => 'taxonomy_admin',
    'access' => user_access('administer taxonomy'));
  $items[] = array('path' => 'admin/taxonomy/add/vocabulary', 'title' => t('add vocabulary'),
    'callback' => 'taxonomy_admin',
    'access' => user_access('administer taxonomy'),
    'type' => MENU_LOCAL_TASK);
  $items[] = array('path' => 'taxonomy', 'title' => t('taxonomy'),
    'callback' => 'taxonomy_page',
    'access' => user_access('access content'),
    'type' => MENU_CALLBACK);
  return $items;
}
Dries Buytaert's avatar
 
Dries Buytaert committed
76

Kjartan Mannes's avatar
Kjartan Mannes committed
77
function taxonomy_form_vocabulary($edit = array()) {
Dries Buytaert's avatar
   
Dries Buytaert committed
78
  foreach (node_list() as $type) {
Dries Buytaert's avatar
   
Dries Buytaert committed
79
    $nodetypes[$type] = node_invoke($type, 'node_name');
Kjartan Mannes's avatar
Kjartan Mannes committed
80
  }
Dries Buytaert's avatar
   
Dries Buytaert committed
81

Dries Buytaert's avatar
   
Dries Buytaert committed
82
83
84
85
86
87
88
89
90
91
  $form .= form_textfield(t('Vocabulary name'), 'name', $edit['name'], 50, 64, t('Required') .'. '. t('The name for this vocabulary.  Example: "Topic"') .'.');
  $form .= form_textarea(t('Description'), 'description', $edit['description'], 60, 5, t('Optional') .'. '. t('Description of the vocabulary; can be used by modules.'));
  $form .= form_textfield(t('Help text'), 'help', $edit['help'], 50, 255, t('Optional') .'. '. t('Instructions to present to the user when choosing a term.') .'.');
  $form .= form_checkboxes(t('Types'), 'nodes', explode(',', $edit['nodes']), $nodetypes, t('Required') .'. '. t('A list of node types you want to associate with this vocabulary.'));
  $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'))), '');
  $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 <strong>must</strong> have at least one term in this vocabulary.'));
  $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.'));
  $form .= form_submit(t('Submit'));
Dries Buytaert's avatar
 
Dries Buytaert committed
92

Dries Buytaert's avatar
   
Dries Buytaert committed
93
94
95
  if ($edit['vid']) {
    $form .= form_submit(t('Delete'));
    $form .= form_hidden('vid', $edit['vid']);
Dries Buytaert's avatar
 
Dries Buytaert committed
96
97
  }

Kjartan Mannes's avatar
Kjartan Mannes committed
98
99
  return form($form);
}
Kjartan Mannes's avatar
Kjartan Mannes committed
100

Kjartan Mannes's avatar
Kjartan Mannes committed
101
function taxonomy_save_vocabulary($edit) {
Dries Buytaert's avatar
   
Dries Buytaert committed
102
103
  if (!$edit['nodes']) {
    $edit['nodes'] = array();
Dries Buytaert's avatar
   
Dries Buytaert committed
104
105
  }

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

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

Dries Buytaert's avatar
   
Dries Buytaert committed
124
125
  drupal_set_message($message);
  return $edit;
Kjartan Mannes's avatar
Kjartan Mannes committed
126
}
Dries Buytaert's avatar
 
Dries Buytaert committed
127

Kjartan Mannes's avatar
Kjartan Mannes committed
128
function taxonomy_del_vocabulary($vid) {
Dries Buytaert's avatar
   
Dries Buytaert committed
129
130
  $vocabulary = taxonomy_get_vocabulary($vid);

Dries Buytaert's avatar
   
Dries Buytaert committed
131
132
  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
133
134
  while ($term = db_fetch_object($result)) {
    taxonomy_del_term($term->tid);
Dries Buytaert's avatar
 
Dries Buytaert committed
135
  }
Dries Buytaert's avatar
   
Dries Buytaert committed
136

Dries Buytaert's avatar
   
Dries Buytaert committed
137
  module_invoke_all('taxonomy', 'delete', 'vocabulary', $vocabulary);
Dries Buytaert's avatar
   
Dries Buytaert committed
138

Dries Buytaert's avatar
   
Dries Buytaert committed
139
140
  cache_clear_all();

Dries Buytaert's avatar
   
Dries Buytaert committed
141
  return t('deleted vocabulary "%name".', array('%name' => $vocabulary->name));
Dries Buytaert's avatar
   
Dries Buytaert committed
142
143
144
145
146
}

function _taxonomy_confirm_del_vocabulary($vid) {
  $vocabulary = taxonomy_get_vocabulary($vid);

Dries Buytaert's avatar
   
Dries Buytaert committed
147
148
149
150
151
  $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'));
Dries Buytaert's avatar
   
Dries Buytaert committed
152

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

Kjartan Mannes's avatar
Kjartan Mannes committed
156
function taxonomy_form_term($edit = array()) {
Dries Buytaert's avatar
   
Dries Buytaert committed
157
  $vocabulary_id = isset($edit['vid']) ? $edit['vid'] : arg(4);
Kjartan Mannes's avatar
Kjartan Mannes committed
158
  $vocabulary = taxonomy_get_vocabulary($vocabulary_id);
Dries Buytaert's avatar
   
Dries Buytaert committed
159

Dries Buytaert's avatar
   
Dries Buytaert committed
160
161
  $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
162

Kjartan Mannes's avatar
Kjartan Mannes committed
163
  if ($vocabulary->hierarchy) {
Dries Buytaert's avatar
   
Dries Buytaert committed
164
165
    $parent = array_keys(taxonomy_get_parents($edit['tid']));
    $children = taxonomy_get_tree($vocabulary_id, $edit['tid']);
Dries Buytaert's avatar
   
Dries Buytaert committed
166

Dries Buytaert's avatar
   
Dries Buytaert committed
167
    // A term can't be the child of itself, nor of its children.
Dries Buytaert's avatar
   
Dries Buytaert committed
168
169
170
    foreach ($children as $child) {
      $exclude[] = $child->tid;
    }
Dries Buytaert's avatar
   
Dries Buytaert committed
171
    $exclude[] = $edit['tid'];
Dries Buytaert's avatar
   
Dries Buytaert committed
172

Kjartan Mannes's avatar
Kjartan Mannes committed
173
    if ($vocabulary->hierarchy == 1) {
Dries Buytaert's avatar
   
Dries Buytaert committed
174
      $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
175
    }
Kjartan Mannes's avatar
Kjartan Mannes committed
176
    elseif ($vocabulary->hierarchy == 2) {
Dries Buytaert's avatar
   
Dries Buytaert committed
177
      $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
178
    }
Kjartan Mannes's avatar
Kjartan Mannes committed
179
  }
Dries Buytaert's avatar
 
Dries Buytaert committed
180

181
  if ($vocabulary->relations) {
Dries Buytaert's avatar
   
Dries Buytaert committed
182
    $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']));
183
184
  }

Dries Buytaert's avatar
   
Dries Buytaert committed
185
186
187
188
  $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'))));
  $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.'));
  $form .= form_hidden('vid', $vocabulary->vid);
  $form .= form_submit(t('Submit'));
Kjartan Mannes's avatar
Kjartan Mannes committed
189

Dries Buytaert's avatar
   
Dries Buytaert committed
190
191
192
  if ($edit['tid']) {
    $form .= form_submit(t('Delete'));
    $form .= form_hidden('tid', $edit['tid']);
Dries Buytaert's avatar
 
Dries Buytaert committed
193
194
  }

Kjartan Mannes's avatar
Kjartan Mannes committed
195
196
  return form($form);
}
Dries Buytaert's avatar
 
Dries Buytaert committed
197

Kjartan Mannes's avatar
Kjartan Mannes committed
198
function taxonomy_save_term($edit) {
Dries Buytaert's avatar
   
Dries Buytaert committed
199
200
  if ($edit['tid'] && $edit['name']) {
    $data = array('name' => $edit['name'], 'description' => $edit['description'], 'weight' => $edit['weight']);
Dries Buytaert's avatar
 
Dries Buytaert committed
201

Dries Buytaert's avatar
   
Dries Buytaert committed
202
203
204
    db_query('UPDATE {term_data} SET '. _prepare_update($data) .' WHERE tid = %d', $edit['tid']);
    module_invoke_all('taxonomy', 'update', 'term', $edit);
    $message = t('the term "%a" has been updated.', array('%a' => $edit['name']));
Kjartan Mannes's avatar
Kjartan Mannes committed
205
  }
Dries Buytaert's avatar
   
Dries Buytaert committed
206
207
  else if ($edit['tid']) {
    return taxonomy_del_term($edit['tid']);
Kjartan Mannes's avatar
Kjartan Mannes committed
208
209
  }
  else {
Dries Buytaert's avatar
   
Dries Buytaert committed
210
211
212
213
214
    $edit['tid'] = db_next_id('{term_data}_tid');
    $data = array('tid' => $edit['tid'], 'name' => $edit['name'], 'description' => $edit['description'], 'vid' => $edit['vid'], 'weight' => $edit['weight']);
    db_query('INSERT INTO {term_data} '. _prepare_insert($data, 1) .' VALUES '. _prepare_insert($data, 2));
    module_invoke_all('taxonomy', 'insert', 'term', $edit);
    $message = t('created new term "%name".', array('%name' => $edit['name']));
Kjartan Mannes's avatar
Kjartan Mannes committed
215
  }
Dries Buytaert's avatar
 
Dries Buytaert committed
216

Dries Buytaert's avatar
   
Dries Buytaert committed
217
218
219
  db_query('DELETE FROM {term_relation} WHERE tid1 = %d OR tid2 = %d', $edit['tid'], $edit['tid']);
  if ($edit['relations']) {
    foreach ($edit['relations'] as $related_id) {
Kjartan Mannes's avatar
Kjartan Mannes committed
220
      if ($related_id != 0) {
Dries Buytaert's avatar
   
Dries Buytaert committed
221
        db_query('INSERT INTO {term_relation} (tid1, tid2) VALUES (%d, %d)', $edit['tid'], $related_id);
Dries Buytaert's avatar
 
Dries Buytaert committed
222
      }
Kjartan Mannes's avatar
Kjartan Mannes committed
223
    }
Kjartan Mannes's avatar
Kjartan Mannes committed
224
  }
Dries Buytaert's avatar
 
Dries Buytaert committed
225

Dries Buytaert's avatar
   
Dries Buytaert committed
226
227
228
  db_query('DELETE FROM {term_hierarchy} WHERE tid = %d', $edit['tid']);
  if (!isset($edit['parent'])) {
    $edit['parent'] = 0;
Kjartan Mannes's avatar
Kjartan Mannes committed
229
  }
Dries Buytaert's avatar
   
Dries Buytaert committed
230
231
232
  if (is_array($edit['parent'])) {
    foreach ($edit['parent'] as $parent) {
      db_query('INSERT INTO {term_hierarchy} (tid, parent) VALUES (%d, %d)', $edit['tid'], $parent);
Dries Buytaert's avatar
 
Dries Buytaert committed
233
    }
Kjartan Mannes's avatar
Kjartan Mannes committed
234
235
  }
  else {
Dries Buytaert's avatar
   
Dries Buytaert committed
236
    db_query('INSERT INTO {term_hierarchy} (tid, parent) VALUES (%d, %d)', $edit['tid'], $edit['parent'][0]);
Dries Buytaert's avatar
 
Dries Buytaert committed
237
238
  }

Dries Buytaert's avatar
   
Dries Buytaert committed
239
240
241
  db_query('DELETE FROM {term_synonym} WHERE tid = %d', $edit['tid']);
  if ($edit['synonyms']) {
    foreach (explode ("\n", str_replace("\r", '', $edit['synonyms'])) as $synonym) {
Dries Buytaert's avatar
   
Dries Buytaert committed
242
      if ($synonym) {
Dries Buytaert's avatar
   
Dries Buytaert committed
243
        db_query("INSERT INTO {term_synonym} (tid, name) VALUES (%d, '%s')", $edit['tid'], chop($synonym));
Dries Buytaert's avatar
   
Dries Buytaert committed
244
      }
Kjartan Mannes's avatar
Kjartan Mannes committed
245
    }
Dries Buytaert's avatar
 
Dries Buytaert committed
246
  }
Dries Buytaert's avatar
   
Dries Buytaert committed
247

Dries Buytaert's avatar
   
Dries Buytaert committed
248
249
  cache_clear_all();

Dries Buytaert's avatar
   
Dries Buytaert committed
250
  drupal_set_message($message);
Dries Buytaert's avatar
   
Dries Buytaert committed
251
  return $edit;
Kjartan Mannes's avatar
Kjartan Mannes committed
252
}
Dries Buytaert's avatar
 
Dries Buytaert committed
253

Kjartan Mannes's avatar
Kjartan Mannes committed
254
function taxonomy_del_term($tid) {
Dries Buytaert's avatar
   
Dries Buytaert committed
255
256
  $term = taxonomy_get_term($tid);

Dries Buytaert's avatar
   
Dries Buytaert committed
257
258
259
260
261
  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
262

Dries Buytaert's avatar
   
Dries Buytaert committed
263
  module_invoke_all('taxonomy', 'delete', 'term', $term);
Dries Buytaert's avatar
   
Dries Buytaert committed
264

Dries Buytaert's avatar
   
Dries Buytaert committed
265
266
  cache_clear_all();

Dries Buytaert's avatar
   
Dries Buytaert committed
267
  return t('deleted term "%name".', array('%name' => $term->name));
Dries Buytaert's avatar
   
Dries Buytaert committed
268
269
270
271
272
}

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

Dries Buytaert's avatar
   
Dries Buytaert committed
273
274
275
276
277
  $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'));
Dries Buytaert's avatar
   
Dries Buytaert committed
278

Dries Buytaert's avatar
   
Dries Buytaert committed
279
  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
280
}
Dries Buytaert's avatar
 
Dries Buytaert committed
281

Dries Buytaert's avatar
   
Dries Buytaert committed
282
283
284
/**
 * Generate a tabular listing of administrative functions for vocabularies.
 */
Kjartan Mannes's avatar
Kjartan Mannes committed
285
function taxonomy_overview() {
Dries Buytaert's avatar
   
Dries Buytaert committed
286
  $header = array(t('name'), t('node types'), array('data' => t('operations'), 'colspan' => 3));
Dries Buytaert's avatar
   
Dries Buytaert committed
287

Kjartan Mannes's avatar
Kjartan Mannes committed
288
  $vocabularies = taxonomy_get_vocabularies();
Dries Buytaert's avatar
   
Dries Buytaert committed
289

Kjartan Mannes's avatar
Kjartan Mannes committed
290
291
  foreach ($vocabularies as $vocabulary) {
    $links = array();
Dries Buytaert's avatar
   
Dries Buytaert committed
292
    $types = array();
Dries Buytaert's avatar
   
Dries Buytaert committed
293
294
    foreach(explode(',', $vocabulary->nodes) as $type) {
      $types[] = node_invoke($type, 'node_name');
Dries Buytaert's avatar
   
Dries Buytaert committed
295
    }
Dries Buytaert's avatar
   
Dries Buytaert committed
296
    $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
297

Dries Buytaert's avatar
   
Dries Buytaert committed
298
    $tree = taxonomy_get_tree($vocabulary->vid);
Kjartan Mannes's avatar
Kjartan Mannes committed
299
    if ($tree) {
Dries Buytaert's avatar
   
Dries Buytaert committed
300
      unset($data);
Kjartan Mannes's avatar
Kjartan Mannes committed
301
      foreach ($tree as $term) {
Dries Buytaert's avatar
   
Dries Buytaert committed
302
        $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
303
      }
Dries Buytaert's avatar
   
Dries Buytaert committed
304
      $rows[] = array(array('data' => $data, 'colspan' => 5));
Dries Buytaert's avatar
 
Dries Buytaert committed
305
306
307
    }
  }

Dries Buytaert's avatar
   
Dries Buytaert committed
308
  return theme('table', $header, $rows);
Kjartan Mannes's avatar
Kjartan Mannes committed
309
310
}

Dries Buytaert's avatar
   
Dries Buytaert committed
311
312
313
/**
 * Generate a form element for selecting terms from a vocabulary.
 */
Dries Buytaert's avatar
   
Dries Buytaert committed
314
function taxonomy_form($vid, $value = 0, $error = array(), $help = NULL, $name = 'taxonomy') {
Dries Buytaert's avatar
   
Dries Buytaert committed
315
  $vocabulary = taxonomy_get_vocabulary($vid);
316
  $help = ($help) ? $help : $vocabulary->help;
Kjartan Mannes's avatar
Kjartan Mannes committed
317
318
319
320
  if ($vocabulary->required) {
    $blank = 0;
  }
  else {
Dries Buytaert's avatar
   
Dries Buytaert committed
321
    $blank = '<'. t('none') .'>';
Kjartan Mannes's avatar
Kjartan Mannes committed
322
  }
Dries Buytaert's avatar
   
Dries Buytaert committed
323

324
  $help .= $error['taxonomy'];
Dries Buytaert's avatar
   
Dries Buytaert committed
325

Dries Buytaert's avatar
   
Dries Buytaert committed
326
  return _taxonomy_term_select($vocabulary->name, $name, $value, $vid, $help, intval($vocabulary->multiple), $blank);
Kjartan Mannes's avatar
Kjartan Mannes committed
327
}
Dries Buytaert's avatar
 
Dries Buytaert committed
328

Dries Buytaert's avatar
   
Dries Buytaert committed
329
330
331
332
333
334
335
/**
 * Return an array of all vocabulary objects.
 *
 * @param $type
 *   If set, return only those vocabularies associated with this node type.
 */
function taxonomy_get_vocabularies($type = '', $key = 'vid') {
Kjartan Mannes's avatar
Kjartan Mannes committed
336
  if ($type) {
Dries Buytaert's avatar
   
Dries Buytaert committed
337
    $result = db_query("SELECT * FROM {vocabulary} WHERE nodes LIKE '%%%s%%' ORDER BY weight, name", $type);
Kjartan Mannes's avatar
Kjartan Mannes committed
338
339
  }
  else {
Dries Buytaert's avatar
   
Dries Buytaert committed
340
    $result = db_query('SELECT * FROM {vocabulary} ORDER BY weight, name');
Kjartan Mannes's avatar
Kjartan Mannes committed
341
342
343
344
  }
  $vocabularies = array();
  while ($voc = db_fetch_object($result)) {
    $vocabularies[$voc->$key] = $voc;
Dries Buytaert's avatar
 
Dries Buytaert committed
345
  }
Dries Buytaert's avatar
   
Dries Buytaert committed
346

Kjartan Mannes's avatar
Kjartan Mannes committed
347
348
  return $vocabularies;
}
Dries Buytaert's avatar
 
Dries Buytaert committed
349

Dries Buytaert's avatar
   
Dries Buytaert committed
350
351
352
/**
 * Generate a form for selecting terms to associate with a node.
 */
Dries Buytaert's avatar
   
Dries Buytaert committed
353
function taxonomy_node_form($type, $node = '', $error = array(), $help = NULL, $name = 'taxonomy') {
Kjartan Mannes's avatar
Kjartan Mannes committed
354
355
356
  if (!$node->taxonomy) {
    if ($node->nid) {
      $terms = array_keys(taxonomy_node_get_terms($node->nid));
Kjartan Mannes's avatar
Kjartan Mannes committed
357
358
    }
    else {
Kjartan Mannes's avatar
Kjartan Mannes committed
359
      $terms = 0;
Dries Buytaert's avatar
 
Dries Buytaert committed
360
    }
Kjartan Mannes's avatar
Kjartan Mannes committed
361
362
363
364
  }
  else {
    $terms = $node->taxonomy;
  }
Dries Buytaert's avatar
 
Dries Buytaert committed
365

Dries Buytaert's avatar
   
Dries Buytaert committed
366
  $c = db_query("SELECT * FROM {vocabulary} WHERE nodes LIKE '%%%s%%' ORDER BY weight, name", $type);
Kjartan Mannes's avatar
Kjartan Mannes committed
367
  while ($vocabulary = db_fetch_object($c)) {
Dries Buytaert's avatar
   
Dries Buytaert committed
368
    $result[] = taxonomy_form($vocabulary->vid, $terms, $error, $help, $name);
Dries Buytaert's avatar
 
Dries Buytaert committed
369
  }
Kjartan Mannes's avatar
Kjartan Mannes committed
370
371
  return $result ? $result : array();
}
Dries Buytaert's avatar
 
Dries Buytaert committed
372

Dries Buytaert's avatar
   
Dries Buytaert committed
373
374
375
/**
 * Determine whether a node mentions the name of a term.
 */
Kjartan Mannes's avatar
Kjartan Mannes committed
376
function taxonomy_node_has_term($nid, $tid) {
Dries Buytaert's avatar
   
Dries Buytaert committed
377
  $term_name = db_result(db_query('SELECT name FROM {term_data} WHERE tid = %d', $tid));
Dries Buytaert's avatar
 
Dries Buytaert committed
378

Dries Buytaert's avatar
   
Dries Buytaert committed
379
  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
380
381
}

Dries Buytaert's avatar
   
Dries Buytaert committed
382
383
384
385
386
/**
 * Find all terms associated to the given node, within one vocabulary.
 */
function taxonomy_node_get_terms_by_vocabulary($nid, $vid, $key = 'tid') {
  $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
387
388
389
  $terms = array();
  while ($term = db_fetch_object($result)) {
    $terms[$term->$key] = $term;
Dries Buytaert's avatar
 
Dries Buytaert committed
390
  }
Kjartan Mannes's avatar
Kjartan Mannes committed
391
392
393
  return $terms;
}

Dries Buytaert's avatar
   
Dries Buytaert committed
394
395
396
397
/**
 * Find all terms associated to the given node.
 */
function taxonomy_node_get_terms($nid, $key = 'tid') {
Kjartan Mannes's avatar
Kjartan Mannes committed
398
  static $terms;
Dries Buytaert's avatar
 
Dries Buytaert committed
399

Dries Buytaert's avatar
   
Dries Buytaert committed
400
  if (!isset($terms[$nid])) {
Dries Buytaert's avatar
   
Dries Buytaert committed
401
    $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
402
    $terms[$nid] = array();
Dries Buytaert's avatar
 
Dries Buytaert committed
403
    while ($term = db_fetch_object($result)) {
Kjartan Mannes's avatar
Kjartan Mannes committed
404
      $terms[$nid][$term->$key] = $term;
Dries Buytaert's avatar
 
Dries Buytaert committed
405
406
    }
  }
Kjartan Mannes's avatar
Kjartan Mannes committed
407
408
  return $terms[$nid];
}
Dries Buytaert's avatar
 
Dries Buytaert committed
409

Dries Buytaert's avatar
   
Dries Buytaert committed
410
411
412
/**
 * Save term associations for a given node.
 */
Kjartan Mannes's avatar
Kjartan Mannes committed
413
414
function taxonomy_node_save($nid, $terms) {
  taxonomy_node_delete($nid);
Dries Buytaert's avatar
 
Dries Buytaert committed
415

Kjartan Mannes's avatar
Kjartan Mannes committed
416
  if ($terms) {
Dries Buytaert's avatar
   
Dries Buytaert committed
417
    foreach ($terms as $term) {
418
      if ($term) {
Dries Buytaert's avatar
   
Dries Buytaert committed
419
        db_query('INSERT INTO {term_node} (nid, tid) VALUES (%d, %d)', $nid, $term);
420
      }
Dries Buytaert's avatar
 
Dries Buytaert committed
421
422
    }
  }
Kjartan Mannes's avatar
Kjartan Mannes committed
423
}
Dries Buytaert's avatar
 
Dries Buytaert committed
424

Dries Buytaert's avatar
   
Dries Buytaert committed
425
426
427
/**
 * Remove associations of a node to its terms.
 */
Kjartan Mannes's avatar
Kjartan Mannes committed
428
function taxonomy_node_delete($nid) {
Dries Buytaert's avatar
   
Dries Buytaert committed
429
  db_query('DELETE FROM {term_node} WHERE nid = %d', $nid);
Kjartan Mannes's avatar
Kjartan Mannes committed
430
}
Dries Buytaert's avatar
 
Dries Buytaert committed
431

Dries Buytaert's avatar
   
Dries Buytaert committed
432
433
434
435
/**
 * Find all term objects related to a given term ID.
 */
function taxonomy_get_related($tid, $key = 'tid') {
Kjartan Mannes's avatar
Kjartan Mannes committed
436
  if ($tid) {
Dries Buytaert's avatar
   
Dries Buytaert committed
437
    $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
438
439
440
    $related = array();
    while ($term = db_fetch_object($result)) {
      $related[$term->$key] = $term;
Dries Buytaert's avatar
 
Dries Buytaert committed
441
    }
Kjartan Mannes's avatar
Kjartan Mannes committed
442
    return $related;
Dries Buytaert's avatar
 
Dries Buytaert committed
443
  }
Kjartan Mannes's avatar
Kjartan Mannes committed
444
445
  else {
    return array();
Dries Buytaert's avatar
 
Dries Buytaert committed
446
  }
Kjartan Mannes's avatar
Kjartan Mannes committed
447
}
Dries Buytaert's avatar
 
Dries Buytaert committed
448

Dries Buytaert's avatar
   
Dries Buytaert committed
449
450
451
452
/**
 * Find all parents of a given term ID.
 */
function taxonomy_get_parents($tid, $key = 'tid') {
Kjartan Mannes's avatar
Kjartan Mannes committed
453
  if ($tid) {
Dries Buytaert's avatar
   
Dries Buytaert committed
454
    $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
455
456
457
    $parents = array();
    while ($parent = db_fetch_object($result)) {
      $parents[$parent->$key] = $parent;
Dries Buytaert's avatar
   
Dries Buytaert committed
458
    }
Kjartan Mannes's avatar
Kjartan Mannes committed
459
    return $parents;
Dries Buytaert's avatar
 
Dries Buytaert committed
460
  }
Kjartan Mannes's avatar
Kjartan Mannes committed
461
462
463
464
  else {
    return array();
  }
}
Dries Buytaert's avatar
 
Dries Buytaert committed
465

Dries Buytaert's avatar
   
Dries Buytaert committed
466
467
468
469
/**
 * Find all ancestors of a given term ID.
 */
function taxonomy_get_parents_all($tid) {
Dries Buytaert's avatar
   
Dries Buytaert committed
470
471
472
473
474
475
476
477
478
479
480
481
  $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;
}

Dries Buytaert's avatar
   
Dries Buytaert committed
482
483
484
485
/**
 * Find all children of a term ID.
 */
function taxonomy_get_children($tid, $vid = 0, $key = 'tid') {
Kjartan Mannes's avatar
Kjartan Mannes committed
486
  if ($vid) {
Dries Buytaert's avatar
   
Dries Buytaert committed
487
    $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
488
  }
Kjartan Mannes's avatar
Kjartan Mannes committed
489
  else {
Dries Buytaert's avatar
   
Dries Buytaert committed
490
    $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
491
492
493
494
495
496
497
  }
  $children = array();
  while ($term = db_fetch_object($result)) {
    $children[$term->$key] = $term;
  }
  return $children;
}
Dries Buytaert's avatar
 
Dries Buytaert committed
498

Dries Buytaert's avatar
   
Dries Buytaert committed
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
/**
 * Create a hierarchical representation of a vocabulary.
 *
 * @param $vid
 *   Which vocabulary to generate the tree for.
 *
 * @param $parent
 *   The term ID under which to generate the tree. If 0, generate the tree
 *   for the entire vocabulary.
 *
 * @param $depth
 *   Internal use only.
 *
 * @return
 *   An array of all term objects in the tree. Each term object is extended
 *   to have "depth" and "parents" attributes in addition to its normal ones.
 */
function taxonomy_get_tree($vid, $parent = 0, $depth = -1, $max_depth = NULL) {
Dries Buytaert's avatar
   
Dries Buytaert committed
517
  static $children, $parents, $terms;
Dries Buytaert's avatar
   
Dries Buytaert committed
518

Kjartan Mannes's avatar
Kjartan Mannes committed
519
  $depth++;
Dries Buytaert's avatar
   
Dries Buytaert committed
520

Dries Buytaert's avatar
   
Dries Buytaert committed
521
522
523
524
  // We cache trees, so it's not CPU-intensive to call get_tree() on a term
  // and its children, too.
  if (!isset($children[$vid])) {
    $children[$vid] = array();
Dries Buytaert's avatar
   
Dries Buytaert committed
525

Dries Buytaert's avatar
   
Dries Buytaert committed
526
    $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', $vid);
Dries Buytaert's avatar
   
Dries Buytaert committed
527
    while ($term = db_fetch_object($result)) {
Dries Buytaert's avatar
   
Dries Buytaert committed
528
529
530
      $children[$vid][$term->parent][] = $term->tid;
      $parents[$vid][$term->tid][] = $term->parent;
      $terms[$vid][$term->tid] = $term;
Dries Buytaert's avatar
 
Dries Buytaert committed
531
532
    }
  }
Dries Buytaert's avatar
   
Dries Buytaert committed
533

Dries Buytaert's avatar
   
Dries Buytaert committed
534
535
536
  $max_depth = ($max_depth == '') ? count($children[$vid]) : $max_depth;
  if ($children[$vid][$parent]) {
    foreach ($children[$vid][$parent] as $child) {
Dries Buytaert's avatar
   
Dries Buytaert committed
537
      if ($max_depth > $depth) {
Dries Buytaert's avatar
   
Dries Buytaert committed
538
539
540
541
542
        $terms[$vid][$child]->depth = $depth;
        // The "parent" attribute is not useful, as it would show one parent only.
        unset($terms[$vid][$child]->parent);
        $terms[$vid][$child]->parents = $parents[$vid][$child];
        $tree[] = $terms[$vid][$child];
Dries Buytaert's avatar
   
Dries Buytaert committed
543

Dries Buytaert's avatar
   
Dries Buytaert committed
544
        $tree = array_merge($tree, taxonomy_get_tree($vid, $child, $depth, $max_depth));
Dries Buytaert's avatar
   
Dries Buytaert committed
545
      }
Dries Buytaert's avatar
   
Dries Buytaert committed
546
    }
Kjartan Mannes's avatar
Kjartan Mannes committed
547
  }
Dries Buytaert's avatar
   
Dries Buytaert committed
548

Dries Buytaert's avatar
   
Dries Buytaert committed
549
  return $tree ? $tree : array();
Kjartan Mannes's avatar
Kjartan Mannes committed
550
}
Dries Buytaert's avatar
 
Dries Buytaert committed
551

Dries Buytaert's avatar
   
Dries Buytaert committed
552
553
554
/**
 * Return an array of synonyms of the given term ID.
 */
Kjartan Mannes's avatar
Kjartan Mannes committed
555
556
function taxonomy_get_synonyms($tid) {
  if ($tid) {
Dries Buytaert's avatar
   
Dries Buytaert committed
557
    $result = db_query('SELECT name FROM {term_synonym} WHERE tid = %d', $tid);
Kjartan Mannes's avatar
Kjartan Mannes committed
558
    while ($synonym = db_fetch_array($result)) {
Dries Buytaert's avatar
   
Dries Buytaert committed
559
      $synonyms[] = $synonym['name'];
Dries Buytaert's avatar
 
Dries Buytaert committed
560
    }
Kjartan Mannes's avatar
Kjartan Mannes committed
561
    return $synonyms ? $synonyms : array();
Dries Buytaert's avatar
 
Dries Buytaert committed
562
  }
Kjartan Mannes's avatar
Kjartan Mannes committed
563
564
  else {
    return array();
Dries Buytaert's avatar
   
Dries Buytaert committed
565
  }
Kjartan Mannes's avatar
Kjartan Mannes committed
566
}
Dries Buytaert's avatar
   
Dries Buytaert committed
567

Dries Buytaert's avatar
   
Dries Buytaert committed
568
569
570
571
572
/**
 * Return the term object that has the given string as a synonym.
 */
function taxonomy_get_synonym_root($synonym) {
  return db_fetch_object(db_query("SELECT * FROM {term_synonym} s, {term_data} t WHERE t.tid = s.tid AND s.name = '%s'", $synonym));
Kjartan Mannes's avatar
Kjartan Mannes committed
573
}
Dries Buytaert's avatar
   
Dries Buytaert committed
574

Dries Buytaert's avatar
   
Dries Buytaert committed
575
576
577
/**
 * Given a term id, count the number of published nodes in it.
 */
Dries Buytaert's avatar
   
Dries Buytaert committed
578
function taxonomy_term_count_nodes($tid, $type = 0) {
Kjartan Mannes's avatar
Kjartan Mannes committed
579
  static $count;
Dries Buytaert's avatar
   
Dries Buytaert committed
580

Dries Buytaert's avatar
   
Dries Buytaert committed
581
582
583
  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
584
      $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
585
586
    }
    else {
Dries Buytaert's avatar
   
Dries Buytaert committed
587
      $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
588
    }
Kjartan Mannes's avatar
Kjartan Mannes committed
589
    while ($term = db_fetch_object($result)) {
Dries Buytaert's avatar
   
Dries Buytaert committed
590
      $count[$type][$term->tid] = $term->c;
Dries Buytaert's avatar
   
Dries Buytaert committed
591
592
593
    }
  }

Kjartan Mannes's avatar
Kjartan Mannes committed
594
  foreach (_taxonomy_term_children($tid) as $c) {
Dries Buytaert's avatar
   
Dries Buytaert committed
595
    $children_count += taxonomy_term_count_nodes($c, $type);
Kjartan Mannes's avatar
Kjartan Mannes committed
596
  }
Dries Buytaert's avatar
   
Dries Buytaert committed
597
  return $count[$type][$tid] + $children_count;
Kjartan Mannes's avatar
Kjartan Mannes committed
598
599
}

Dries Buytaert's avatar
   
Dries Buytaert committed
600
601
602
/**
 * Helper for taxonomy_term_count_nodes().
 */
Kjartan Mannes's avatar
Kjartan Mannes committed
603
604
function _taxonomy_term_children($tid) {
  static $children;
Dries Buytaert's avatar
   
Dries Buytaert committed
605

Dries Buytaert's avatar
   
Dries Buytaert committed
606
  if (!isset($children)) {
Dries Buytaert's avatar
   
Dries Buytaert committed
607
    $result = db_query('SELECT tid, parent FROM {term_hierarchy}');
Kjartan Mannes's avatar
Kjartan Mannes committed
608
609
    while ($term = db_fetch_object($result)) {
      $children[$term->parent][] = $term->tid;
Dries Buytaert's avatar
   
Dries Buytaert committed
610
    }
Dries Buytaert's avatar
 
Dries Buytaert committed
611
  }
Kjartan Mannes's avatar
Kjartan Mannes committed
612
613
  return $children[$tid] ? $children[$tid] : array();
}
Dries Buytaert's avatar
 
Dries Buytaert committed
614

Dries Buytaert's avatar
   
Dries Buytaert committed
615
/**
Dries Buytaert's avatar
   
Dries Buytaert committed
616
617
618
619
620
621
622
 * Try to map a string to an existing vocabulary.
 *
 * Provides a case-insensitive and trimmed mapping, to maximize the
 * likelihood of a successful match.
 *
 * @param name
 *   Name of the vocabulary to search for.
Dries Buytaert's avatar
   
Dries Buytaert committed
623
 *
Dries Buytaert's avatar
   
Dries Buytaert committed
624
625
 * @return
 *   An array of matching vocabulary objects.
Dries Buytaert's avatar
   
Dries Buytaert committed
626
627
 */
function taxonomy_get_vocabulary_by_name($name) {
Dries Buytaert's avatar
   
Dries Buytaert committed
628
  $db_result = db_query("SELECT * FROM {vocabulary} WHERE LOWER('%s') LIKE LOWER(name)", trim($name));
Dries Buytaert's avatar
   
Dries Buytaert committed
629
630
631
632
633
634
635
636
637
  $result = array();
  while ($vocabulary = db_fetch_object($db_result)) {
    $result[] = $vocabulary;
  }

  return $result;
}

/**
Dries Buytaert's avatar
   
Dries Buytaert committed
638
 * Try to map a string to an existing term, as for glossary use.
Dries Buytaert's avatar
   
Dries Buytaert committed
639
 *
Dries Buytaert's avatar
   
Dries Buytaert committed
640
641
642
643
644
645
646
647
 * Provides a case-insensitive and trimmed mapping, to maximize the
 * likelihood of a successful match.
 *
 * @param name
 *   Name of the term to search for.
 *
 * @return
 *   An array of matching term objects.
Dries Buytaert's avatar
   
Dries Buytaert committed
648
649
 */
function taxonomy_get_term_by_name($name) {
Dries Buytaert's avatar
   
Dries Buytaert committed
650
  $db_result = db_query("SELECT * FROM {term_data} WHERE LOWER('%s') LIKE LOWER(name)", trim($name));
Dries Buytaert's avatar
   
Dries Buytaert committed
651
652
653
654
655
656
657
658
  $result = array();
  while ($term = db_fetch_object($db_result)) {
    $result[] = $term;
  }

  return $result;
}

Dries Buytaert's avatar
   
Dries Buytaert committed
659
660
661
/**
 * Return the vocabulary object matching a vocabulary ID.
 */
Kjartan Mannes's avatar
Kjartan Mannes committed
662
function taxonomy_get_vocabulary($vid) {
Dries Buytaert's avatar
   
Dries Buytaert committed
663
  return db_fetch_object(db_query('SELECT * FROM {vocabulary} WHERE vid = %d', $vid));
Kjartan Mannes's avatar
Kjartan Mannes committed
664
}
Dries Buytaert's avatar
 
Dries Buytaert committed
665

Dries Buytaert's avatar
   
Dries Buytaert committed
666
667
668
/**
 * Return the term object matching a term ID.
 */
Kjartan Mannes's avatar
Kjartan Mannes committed
669
670
function taxonomy_get_term($tid) {
  // simple cache using a static var?
Dries Buytaert's avatar
   
Dries Buytaert committed
671
  return db_fetch_object(db_query('SELECT * FROM {term_data} WHERE tid = %d', $tid));
Kjartan Mannes's avatar
Kjartan Mannes committed
672
}
Dries Buytaert's avatar
 
Dries Buytaert committed
673

Kjartan Mannes's avatar
Kjartan Mannes committed
674
function _taxonomy_term_select($title, $name, $value, $vocabulary_id, $description, $multiple, $blank, $exclude = array()) {
Dries Buytaert's avatar
   
Dries Buytaert committed
675
  $tree = taxonomy_get_tree($vocabulary_id);
Dries Buytaert's avatar
Dries Buytaert committed
676
677
678
  if ($blank) {
    $options[] = array('tid' => 0, 'name' => $blank);
  }
Kjartan Mannes's avatar
Kjartan Mannes committed
679
680
681
  if ($tree) {
    foreach ($tree as $term) {
      if (!in_array($term->tid, $exclude)) {
Dries Buytaert's avatar
   
Dries Buytaert committed
682
        $options[] = array('tid' => $term->tid, 'name' => _taxonomy_depth($term->depth, '-').$term->name);
Dries Buytaert's avatar
 
Dries Buytaert committed
683
684
      }
    }
Kjartan Mannes's avatar
Kjartan Mannes committed
685
686
687
688
689
    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
690

Kjartan Mannes's avatar
Kjartan Mannes committed
691
  if (count($options) > 0) {
Dries Buytaert's avatar
   
Dries Buytaert committed
692
    foreach ($options as $option) {
Dries Buytaert's avatar
   
Dries Buytaert committed
693
      $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
694
    }
Dries Buytaert's avatar
 
Dries Buytaert committed
695

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

Dries Buytaert's avatar
   
Dries Buytaert committed
698
    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
699
  }
Kjartan Mannes's avatar
Kjartan Mannes committed
700
}
Dries Buytaert's avatar
 
Dries Buytaert committed
701

Kjartan Mannes's avatar
Kjartan Mannes committed
702
703
704
function _taxonomy_depth($depth, $graphic = '--') {
  for ($n = 0; $n < $depth; $n++) {
    $result .= $graphic;
Dries Buytaert's avatar
 
Dries Buytaert committed
705
  }
Kjartan Mannes's avatar
Kjartan Mannes committed
706
707
  return $result;
}
Dries Buytaert's avatar
 
Dries Buytaert committed
708

Kjartan Mannes's avatar
Kjartan Mannes committed
709
710
711
function _prepare_update($data) {
  foreach ($data as $key => $value) {
    $q[] = "$key = '". check_query($value) ."'";
Dries Buytaert's avatar
 
Dries Buytaert committed
712
  }
Dries Buytaert's avatar
   
Dries Buytaert committed
713
  $result = implode(', ', $q);
Kjartan Mannes's avatar
Kjartan Mannes committed
714
715
  return $result;
}
Dries Buytaert's avatar
 
Dries Buytaert committed
716

Kjartan Mannes's avatar
Kjartan Mannes committed
717
718
function _prepare_insert($data, $stage) {
  if ($stage == 1) {
Dries Buytaert's avatar
   
Dries Buytaert committed
719
    $result = implode(', ', array_keys($data));
Kjartan Mannes's avatar
Kjartan Mannes committed
720
721
722
723
  }
  else {
    foreach (array_values($data) as $value) {
      $q[] = "'". check_query($value) ."'";
Dries Buytaert's avatar
 
Dries Buytaert committed
724
    }
Dries Buytaert's avatar
   
Dries Buytaert committed
725
    $result = implode(', ', $q);
Dries Buytaert's avatar
 
Dries Buytaert committed
726
  }
Kjartan Mannes's avatar
Kjartan Mannes committed
727
728
  return "($result)";
}
Dries Buytaert's avatar
   
Dries Buytaert committed
729

Dries Buytaert's avatar
   
Dries Buytaert committed
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
/**
 * Finds all nodes that match selected taxonomy conditions.
 *
 * @param $taxonomy
 *   An object containing the conditions to match. The attributes of this
 *   object are:
 *   - "tids": An array of term IDs to match.
 *   - "str_tids": A comma-separated list of the same IDs.
 *   - "operator": How to interpret multiple IDs in the array. Can be
 *     "or" or "and".
 *
 * @param $pager
 *   Whether the nodes are to be used with a pager (the case on most Drupal
 *   pages) or not (in an XML feed, for example).
 *
 * @return
 *   A resource identifier pointing to the query results.
 */
function taxonomy_select_nodes($taxonomy, $pager = TRUE) {
749
  if ($taxonomy->str_tids) {
Dries Buytaert's avatar
   
Dries Buytaert committed
750
    if ($taxonomy->operator == 'or') {
Dries Buytaert's avatar
   
Dries Buytaert committed
751
      $sql = "SELECT DISTINCT(n.nid), n.title, n.type, n.created, n.changed, n.uid, n.sticky, 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 sticky DESC, created DESC";
Dries Buytaert's avatar
   
Dries Buytaert committed
752
      $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";
753
754
    }
    else {
Dries Buytaert's avatar
   
Dries Buytaert committed
755
      $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 sticky DESC, created DESC";
Dries Buytaert's avatar
   
Dries Buytaert committed
756

757
      // Special trick as we could not find anything better:
Dries Buytaert's avatar
   
Dries Buytaert committed
758
      $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)));
759
760
      $sql_count = "SELECT $count";
    }
Dries Buytaert's avatar
   
Dries Buytaert committed
761

762
    if ($pager) {
Dries Buytaert's avatar
   
Dries Buytaert committed
763
      $result = pager_query($sql, variable_get('default_nodes_main', 10) , 0, $sql_count);
764
765
766
767
    }
    else {
      $result = db_query_range($sql, 0, 15);
    }
Dries Buytaert's avatar
   
Dries Buytaert committed
768
769
770
771
772
  }

  return $result;
}

Dries Buytaert's avatar
   
Dries Buytaert committed
773
774
775
/**
 * Accepts the result of a pager_query() call, such as that performed by
 * taxonomy_select_nodes(), and formats each node along with a pager.
Dries Buytaert's avatar
   
Dries Buytaert committed
776
777
778
779
*/
function taxonomy_render_nodes($result) {

  while ($node = db_fetch_object($result)) {
Dries Buytaert's avatar
   
Dries Buytaert committed
780
    $output .= node_view(node_load(array('nid' => $node->nid, 'type' => $node->type)), 1);
Dries Buytaert's avatar
   
Dries Buytaert committed
781
  }
Dries Buytaert's avatar
   
Dries Buytaert committed
782
  $output .= theme('pager', NULL, variable_get('default_nodes_main', 10), 0);
Dries Buytaert's avatar
   
Dries Buytaert committed
783
  return $output;
Dries Buytaert's avatar
   
Dries Buytaert committed
784
785
}

Dries Buytaert's avatar
   
Dries Buytaert committed
786
787
788
/**
 * Implementation of hook_nodeapi().
 */
Dries Buytaert's avatar
   
Dries Buytaert committed
789
790
function taxonomy_nodeapi($node, $op, $arg = 0) {
  switch ($op) {
Dries Buytaert's avatar
   
Dries Buytaert committed
791
    case 'insert':
Dries Buytaert's avatar
   
Dries Buytaert committed
792
793
      taxonomy_node_save($node->nid, $node->taxonomy);
      break;
Dries Buytaert's avatar
   
Dries Buytaert committed
794
    case 'update':
Dries Buytaert's avatar
   
Dries Buytaert committed
795
796
      taxonomy_node_save($node->nid, $node->taxonomy);
      break;
Dries Buytaert's avatar
   
Dries Buytaert committed
797
    case 'delete':
Dries Buytaert's avatar
   
Dries Buytaert committed
798
799
800
801
802
      taxonomy_node_delete($node->nid);
      break;
  }
}

Kjartan Mannes's avatar
Kjartan Mannes committed
803
function taxonomy_page() {
Dries Buytaert's avatar
   
Dries Buytaert committed
804

Dries Buytaert's avatar
   
Dries Buytaert committed
805
806
  $taxonomy->operator = arg(2);
  $taxonomy->str_tids = check_query(arg(3));
Dries Buytaert's avatar
   
Dries Buytaert committed
807
  $taxonomy->tids = explode(',', $taxonomy->str_tids);
Dries Buytaert's avatar
   
Dries Buytaert committed
808

Dries Buytaert's avatar
   
Dries Buytaert committed
809
  if (ereg('^([0-9]+,){0,}[0-9]+$', $taxonomy->str_tids)) {
Dries Buytaert's avatar
   
Dries Buytaert committed
810
    switch (arg(1)) {
Dries Buytaert's avatar
   
Dries Buytaert committed
811
      case 'feed':
Dries Buytaert's avatar
   
Dries Buytaert committed
812
        taxonomy_feed($taxonomy);
Kjartan Mannes's avatar
Kjartan Mannes committed
813
      break;
Dries Buytaert's avatar
   
Dries Buytaert committed
814
      default:
Dries Buytaert's avatar
   
Dries Buytaert committed
815
      // Build title:
816
      $sql = 'SELECT name FROM {term_data} WHERE tid IN (%s)';
Dries Buytaert's avatar
   
Dries Buytaert committed
817
      $result = db_query($sql, $taxonomy->str_tids);
Kjartan Mannes's avatar
Kjartan Mannes committed
818
      $names = array();
Dries Buytaert's avatar
   
Dries Buytaert committed
819
820
821
      while ($term = db_fetch_object($result)) {
        $names[] = $term->name;
      }
Dries Buytaert's avatar
   
Dries Buytaert committed
822
823
824

      // Build breadcrumb based on first hierarchy of first term:
      $current->tid = $taxonomy->tids[0];
Dries Buytaert's avatar
   
Dries Buytaert committed
825
      $breadcrumbs = array(array('path' => $_GET['q']));
Dries Buytaert's avatar
   
Dries Buytaert committed
826
827
      while ($parents = taxonomy_get_parents($current->tid)) {
        $current = array_shift($parents);
Dries Buytaert's avatar
   
Dries Buytaert committed
828
        $breadcrumbs[] = array('path' => 'taxonomy/view/or/'. $current->tid, 'title' => $current->name);
Dries Buytaert's avatar
   
Dries Buytaert committed
829
830
      }
      $breadcrumbs = array_reverse($breadcrumbs);
Dries Buytaert's avatar
   
Dries Buytaert committed
831
      menu_set_location($breadcrumbs);
Dries Buytaert's avatar
   
Dries Buytaert committed
832

Dries Buytaert's avatar
   
Dries Buytaert committed
833
      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
834

Dries Buytaert's avatar
   
Dries Buytaert committed
835
      $output = taxonomy_render_nodes(taxonomy_select_nodes($taxonomy));
Dries Buytaert's avatar
   
Dries Buytaert committed
836
      print theme('page', $output, implode(', ', $names));
Dries Buytaert's avatar
   
Dries Buytaert committed
837
      break;
Dries Buytaert's avatar
   
Dries Buytaert committed
838
839
840
841
    }
  }
  else {
    drupal_not_found();
Dries Buytaert's avatar
   
Dries Buytaert committed
842
  }
Kjartan Mannes's avatar
Kjartan Mannes committed
843
}
Dries Buytaert's avatar
   
Dries Buytaert committed
844

Dries Buytaert's avatar
   
Dries Buytaert committed
845
846
847
/**
 * Menu callback; dispatches to the proper taxonomy administration function.
 */
Kjartan Mannes's avatar
Kjartan Mannes committed
848
function taxonomy_admin() {
Dries Buytaert's avatar
   
Dries Buytaert committed
849
850
  $op = $_POST['op'];
  $edit = $_POST['edit'];
Kjartan Mannes's avatar
Kjartan Mannes committed
851

Dries Buytaert's avatar
   
Dries Buytaert committed
852
853
854
  if (empty($op)) {
    $op = arg(2);
  }
Dries Buytaert's avatar
   
Dries Buytaert committed
855

Dries Buytaert's avatar
   
Dries Buytaert committed
856
  switch ($op) {
Dries Buytaert's avatar
   
Dries Buytaert committed
857
858
    case 'add':
      if (arg(3) == 'vocabulary') {
Dries Buytaert's avatar
   
Dries Buytaert committed
859
860
        $output .= taxonomy_form_vocabulary();
      }
Dries Buytaert's avatar
   
Dries Buytaert committed
861
      else if (arg(3) == 'term') {
Dries Buytaert's avatar
   
Dries Buytaert committed
862
863
864
        $output .= taxonomy_form_term();
      }
      break;
Dries Buytaert's avatar
   
Dries Buytaert committed
865
866
    case 'edit':
      if (arg(3) == 'vocabulary') {
Dries Buytaert's avatar
   
Dries Buytaert committed
867
868
        $output .= taxonomy_form_vocabulary(object2array(taxonomy_get_vocabulary(arg(4))));
      }
Dries Buytaert's avatar
   
Dries Buytaert committed
869
      else if (arg(3) == 'term') {
Dries Buytaert's avatar
   
Dries Buytaert committed
870 </