taxonomy.admin.inc 15.2 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
<?php
// $Id$

/**
 * @file
 * Administrative page callbacks for the taxonomy module.
 */

/**
 * List and manage vocabularies.
 */
function taxonomy_overview_vocabularies() {
  $vocabularies = taxonomy_get_vocabularies();
  $rows = array();
  foreach ($vocabularies as $vocabulary) {
    $types = array();
    foreach ($vocabulary->nodes as $type) {
      $node_type = node_get_types('name', $type);
      $types[] = $node_type ? $node_type : $type;
    }
    $rows[] = array('name' => check_plain($vocabulary->name),
      'type' => implode(', ', $types),
      'edit' => l(t('edit vocabulary'), "admin/content/taxonomy/edit/vocabulary/$vocabulary->vid"),
      'list' => l(t('list terms'), "admin/content/taxonomy/$vocabulary->vid"),
      'add' => l(t('add terms'), "admin/content/taxonomy/$vocabulary->vid/add/term")
    );
  }
  if (empty($rows)) {
29
    $rows[] = array(array('data' => t('No terms available.'), 'colspan' => '5'));
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
  }
  $header = array(t('Name'), t('Type'), array('data' => t('Operations'), 'colspan' => '3'));

  return theme('table', $header, $rows, array('id' => 'taxonomy'));
}

/**
 * Display form for adding and editing vocabularies.
 *
 * @ingroup forms
 * @see taxonomy_form_vocabulary_submit().
 */
function taxonomy_form_vocabulary(&$form_state, $edit = array()) {
  $edit += array(
    'name' => '',
    'description' => '',
    'help' => '',
    'nodes' => array(),
    'hierarchy' => 0,
    'relations' => 0,
    'tags' => 0,
    'multiple' => 0,
    'required' => 0,
    'weight' => 0,
  );
55
56
57
58
59
60
  $form['identification'] = array(
    '#type' => 'fieldset',
    '#title' => t('Identification'),
    '#collapsible' => TRUE,
  );
  $form['identification']['name'] = array('#type' => 'textfield',
61
62
63
    '#title' => t('Vocabulary name'),
    '#default_value' => $edit['name'],
    '#maxlength' => 255,
64
    '#description' => t('The name for this vocabulary. i.e. <em>"Tags"</em>.'),
65
66
    '#required' => TRUE,
  );
67
  $form['identification']['description'] = array('#type' => 'textarea',
68
69
70
71
    '#title' => t('Description'),
    '#default_value' => $edit['description'],
    '#description' => t('Description of the vocabulary; can be used by modules.'),
  );
72
  $form['identification']['help'] = array('#type' => 'textfield',
73
74
75
    '#title' => t('Help text'),
    '#maxlength' => 255,
    '#default_value' => $edit['help'],
76
    '#description' => t('Instructions to present to the user when selecting terms. i.e. <em>"Enter a comma separated list of words".</em>'),
77
  );
78
79
80
81
82
83
  $form['content_types'] = array(
    '#type' => 'fieldset',
    '#title' => t('Content types'),
    '#collapsible' => TRUE,
  );
  $form['content_types']['nodes'] = array('#type' => 'checkboxes',
84
85
86
    '#title' => t('Content types'),
    '#default_value' => $edit['nodes'],
    '#options' => node_get_types('names'),
87
    '#description' => t('Select content types to categorize using this vocabulary.'),
88
  );
89
90
91
92
93
94
  $form['settings'] = array(
    '#type' => 'fieldset',
    '#title' => t('Settings'),
    '#collapsible' => TRUE,
   );
  $form['settings']['tags'] = array('#type' => 'checkbox',
95
    '#title' => t('Tags'),
96
    '#default_value' => $edit['tags'],
97
    '#description' => t('Terms are created by users when submitting posts by typing a comma separated list.'),
98
  );
99
  $form['settings']['multiple'] = array('#type' => 'checkbox',
100
101
    '#title' => t('Multiple select'),
    '#default_value' => $edit['multiple'],
102
    '#description' => t('Allows posts to have more than one term from this vocabulary (always true for tags).'),
103
  );
104
  $form['settings']['required'] = array('#type' => 'checkbox',
105
106
    '#title' => t('Required'),
    '#default_value' => $edit['required'],
107
    '#description' => t('At least one term in this vocabulary must be selected when submitting a post.'),
108
  );
109
  $form['settings']['weight'] = array('#type' => 'weight',
110
111
    '#title' => t('Weight'),
    '#default_value' => $edit['weight'],
112
113
114
115
116
117
118
119
120
121
    '#description' => t('Vocabularies are displayed in ascending order by weight.'),
  );
  // Set the hierarchy to "multiple parents" by default. This simplifies the
  // vocabulary form and standardizes the term form.
  $form['hierarchy'] = array('#type' => 'value',
    '#value' => '2',
  );
  // Enable "related terms" by default.
  $form['relations'] = array('#type' => 'value',
    '#value' => '1',
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
  );

  $form['submit'] = array('#type' => 'submit', '#value' => t('Save'));
  if (isset($edit['vid'])) {
    $form['delete'] = array('#type' => 'submit', '#value' => t('Delete'));
    $form['vid'] = array('#type' => 'value', '#value' => $edit['vid']);
    $form['module'] = array('#type' => 'value', '#value' => $edit['module']);
  }
  return $form;
}

/**
 * Accept the form submission for a vocabulary and save the results.
 */
function taxonomy_form_vocabulary_submit($form, &$form_state) {
  // Fix up the nodes array to remove unchecked nodes.
  $form_state['values']['nodes'] = array_filter($form_state['values']['nodes']);
  switch (taxonomy_save_vocabulary($form_state['values'])) {
    case SAVED_NEW:
      drupal_set_message(t('Created new vocabulary %name.', array('%name' => $form_state['values']['name'])));
      watchdog('taxonomy', 'Created new vocabulary %name.', array('%name' => $form_state['values']['name']), WATCHDOG_NOTICE, l(t('edit'), 'admin/content/taxonomy/edit/vocabulary/'. $form_state['values']['vid']));
      break;
    case SAVED_UPDATED:
      drupal_set_message(t('Updated vocabulary %name.', array('%name' => $form_state['values']['name'])));
      watchdog('taxonomy', 'Updated vocabulary %name.', array('%name' => $form_state['values']['name']), WATCHDOG_NOTICE, l(t('edit'), 'admin/content/taxonomy/edit/vocabulary/'. $form_state['values']['vid']));
      break;
  }

  $form_state['vid'] = $form_state['values']['vid'];
  $form_state['redirect'] = 'admin/content/taxonomy';
  return;
}

/**
 * Page to edit a vocabulary.
 */
function taxonomy_admin_vocabulary_edit($vocabulary) {
  if ((isset($_POST['op']) && $_POST['op'] == t('Delete')) || isset($_POST['confirm'])) {
    return drupal_get_form('taxonomy_vocabulary_confirm_delete', $vocabulary->vid);
  }
  return drupal_get_form('taxonomy_form_vocabulary', (array)$vocabulary);
}

/**
 * Page to edit a vocabulary term.
 */
function taxonomy_admin_term_edit($tid) {
169
  if ((isset($_POST['op']) && $_POST['op'] == t('Delete')) || isset($_POST['confirm'])) {
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
    return drupal_get_form('taxonomy_term_confirm_delete', $tid);
  }
  if ($term = (array)taxonomy_get_term($tid)) {
    return drupal_get_form('taxonomy_form_term', taxonomy_vocabulary_load($term['vid']), $term);
  }
  return drupal_not_found();
}

/**
 * Display a tree of all the terms in a vocabulary, with options to edit
 * each one.
 */
function taxonomy_overview_terms($vocabulary) {
  $destination = drupal_get_destination();

  $header = array(t('Name'), t('Operations'));

187
  drupal_set_title(t('Terms in %vocabulary', array('%vocabulary' => $vocabulary->name)));
188
189
190
191
192
  $start_from      = isset($_GET['page']) ? $_GET['page'] : 0;
  $total_entries   = 0;  // total count for pager
  $page_increment  = 25; // number of tids per page
  $displayed_count = 0;  // number of tids shown

193
194
195
  if ($vocabulary->tags) {
    // We are not calling taxonomy_get_tree because that might fail with a big
    // number of tags in the freetagging vocabulary.
196
    $results = pager_query(db_rewrite_sql('SELECT t.*, h.parent FROM {term_data} t INNER JOIN  {term_hierarchy} h ON t.tid = h.tid WHERE t.vid = %d ORDER BY weight, name', 't', 'tid'), $page_increment, 0, NULL, $vocabulary->vid);
197
198
199
200
201
    while ($term = db_fetch_object($results)) {
      $rows[] = array(
        l($term->name, "taxonomy/term/$term->tid"),
        l(t('edit'), "admin/content/taxonomy/edit/term/$term->tid", array('query' => $destination)),
      );
202
203
    }
  }
204
205
206
207
208
209
210
211
212
213
  else {
    $tree = taxonomy_get_tree($vocabulary->vid);
    foreach ($tree as $term) {
      $total_entries++; // we're counting all-totals, not displayed
      if (($start_from && ($start_from * $page_increment) >= $total_entries) || ($displayed_count == $page_increment)) {
        continue;
      }
      $rows[] = array(str_repeat('--', $term->depth) .' '. l($term->name, "taxonomy/term/$term->tid"), l(t('edit'), "admin/content/taxonomy/edit/term/$term->tid", array('query' => $destination)));
      $displayed_count++; // we're counting tids displayed
    }
214

215
216
217
    if (empty($rows)) {
      $rows[] = array(array('data' => t('No terms available.'), 'colspan' => '2'));
    }
218

219
220
221
    $GLOBALS['pager_page_array'][] = $start_from;  // FIXME
    $GLOBALS['pager_total'][] = intval($total_entries / $page_increment) + 1; // FIXME
  }
222

223
  $output = theme('table', $header, $rows, array('id' => 'taxonomy'));
224
225
  if ($vocabulary->tags || $total_entries >= $page_increment) {
    $output .= theme('pager', NULL, $page_increment);
226
227
  }

228
  return $output;
229
230
}

231
232
233
234
235
236
237
238
239

/**
 * Menu callback; return the edit form for a new term after setting the title.
 */
function taxonomy_add_term_page($vocabulary) {
  drupal_set_title(t('Add term to %vocabulary', array('%vocabulary' => $vocabulary->name)));
  return drupal_get_form('taxonomy_form_term' , $vocabulary);
}

240
241
242
243
244
245
246
247
248
249
250
251
252
/**
 * Form function for the term edit form.
 *
 * @ingroup forms
 * @see taxonomy_form_term_submit().
 */
function taxonomy_form_term(&$form_state, $vocabulary, $edit = array()) {
  $edit += array(
    'name' => '',
    'description' => '',
    'tid' => NULL,
    'weight' => 0,
  );
253
254
255
256
257
258
  $form['identification'] = array(
    '#type' => 'fieldset',
    '#title' => t('Identification'),
    '#collapsible' => TRUE,
  );
  $form['identification']['name'] = array(
259
260
261
262
263
264
    '#type' => 'textfield',
    '#title' => t('Term name'),
    '#default_value' => $edit['name'],
    '#maxlength' => 255,
    '#description' => t('The name of this term.'),
    '#required' => TRUE);
265
  $form['identification']['description'] = array(
266
267
268
    '#type' => 'textarea',
    '#title' => t('Description'),
    '#default_value' => $edit['description'],
269
    '#description' => t('A description of the term. To be displayed on taxonomy/term pages and RSS feeds.'));
270

271
272
273
274
275
276
  $form['advanced'] = array(
    '#type' => 'fieldset',
    '#title' => 'Advanced options',
    '#collapsible' => TRUE,
    '#collapsed' => TRUE,
  );
277

278
279
280
  // taxonomy_get_tree and taxonomy_get_parents may contain large numbers of
  // items so we check for taxonomy_override_selector before loading the
  // full vocabulary. Contrib modules can then intercept before
Dries's avatar
Dries committed
281
  // hook_form_alter to provide scalable alternatives.
282
283
284
  if (!variable_get('taxonomy_override_selector', FALSE)) {
    $parent = array_keys(taxonomy_get_parents($edit['tid']));
    $children = taxonomy_get_tree($vocabulary->vid, $edit['tid']);
285

286
287
288
289
290
    // A term can't be the child of itself, nor of its children.
    foreach ($children as $child) {
      $exclude[] = $child->tid;
    }
    $exclude[] = $edit['tid'];
291

292
293
294
    $form['advanced']['parent'] = _taxonomy_term_select(t('Parents'), 'parent', $parent, $vocabulary->vid, t('Parent terms') .'.', 1, '<'. t('root') .'>', $exclude);
    $form['advanced']['relations'] = _taxonomy_term_select(t('Related terms'), 'relations', array_keys(taxonomy_get_related($edit['tid'])), $vocabulary->vid, NULL, 1, '<'. t('none') .'>', array($edit['tid']));
  }
295
  $form['advanced']['synonyms'] = array(
296
297
298
    '#type' => 'textarea',
    '#title' => t('Synonyms'),
    '#default_value' => implode("\n", taxonomy_get_synonyms($edit['tid'])),
299
    '#description' => t('Synonyms of this term, one synonym per line.'));
300
  $form['advanced']['weight'] = array(
301
302
303
    '#type' => 'weight',
    '#title' => t('Weight'),
    '#default_value' => $edit['weight'],
304
    '#description' => t('Vocabularies are displayed in ascending order by weight.'));
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
  $form['vid'] = array(
    '#type' => 'value',
    '#value' => $vocabulary->vid);
  $form['submit'] = array(
    '#type' => 'submit',
    '#value' => t('Save'));

  if ($edit['tid']) {
    $form['delete'] = array(
      '#type' => 'submit',
      '#value' => t('Delete'));
    $form['tid'] = array(
      '#type' => 'value',
      '#value' => $edit['tid']);
  }
  else {
    $form['destination'] = array('#type' => 'hidden', '#value' => $_GET['q']);
  }

  return $form;
}

/**
 * Accept the form submission for a taxonomy term and save the result.
 */
function taxonomy_form_term_submit($form, &$form_state) {
  switch (taxonomy_save_term($form_state['values'])) {
    case SAVED_NEW:
      drupal_set_message(t('Created new term %term.', array('%term' => $form_state['values']['name'])));
      watchdog('taxonomy', 'Created new term %term.', array('%term' => $form_state['values']['name']), WATCHDOG_NOTICE, l(t('edit'), 'admin/content/taxonomy/edit/term/'. $form_state['values']['tid']));
      break;
    case SAVED_UPDATED:
      drupal_set_message(t('Updated term %term.', array('%term' => $form_state['values']['name'])));
      watchdog('taxonomy', 'Updated term %term.', array('%term' => $form_state['values']['name']), WATCHDOG_NOTICE, l(t('edit'), 'admin/content/taxonomy/edit/term/'. $form_state['values']['tid']));
      break;
  }

  $form_state['tid'] = $form_state['values']['tid'];
  $form_state['redirect'] = 'admin/content/taxonomy';
  return;
}

/**
 * Form builder for the term delete form.
 *
 * @ingroup forms
 * @see taxonomy_term_confirm_delete_submit().
 */
function taxonomy_term_confirm_delete(&$form_state, $tid) {
  $term = taxonomy_get_term($tid);

  $form['type'] = array('#type' => 'value', '#value' => 'term');
  $form['name'] = array('#type' => 'value', '#value' => $term->name);
  $form['tid'] = array('#type' => 'value', '#value' => $tid);
  return confirm_form($form,
                  t('Are you sure you want to delete the term %title?',
                  array('%title' => $term->name)),
                  'admin/content/taxonomy',
                  t('Deleting a term will delete all its children if there are any. This action cannot be undone.'),
                  t('Delete'),
                  t('Cancel'));
}

function taxonomy_term_confirm_delete_submit($form, &$form_state) {
  taxonomy_del_term($form_state['values']['tid']);
  drupal_set_message(t('Deleted term %name.', array('%name' => $form_state['values']['name'])));
  watchdog('taxonomy', 'Deleted term %name.', array('%name' => $form_state['values']['name']), WATCHDOG_NOTICE);
  $form_state['redirect'] = 'admin/content/taxonomy';
  return;
}

/**
 * Form builder for the vocabulary delete confirmation form.
 *
 * @ingroup forms
 * @see taxonomy_vocabulary_confirm_delete_submit().
 */
function taxonomy_vocabulary_confirm_delete(&$form_state, $vid) {
  $vocabulary = taxonomy_vocabulary_load($vid);

  $form['type'] = array('#type' => 'value', '#value' => 'vocabulary');
  $form['vid'] = array('#type' => 'value', '#value' => $vid);
  $form['name'] = array('#type' => 'value', '#value' => $vocabulary->name);
  return confirm_form($form,
                  t('Are you sure you want to delete the vocabulary %title?',
                  array('%title' => $vocabulary->name)),
                  'admin/content/taxonomy',
                  t('Deleting a vocabulary will delete all the terms in it. This action cannot be undone.'),
                  t('Delete'),
                  t('Cancel'));
}

function taxonomy_vocabulary_confirm_delete_submit($form, &$form_state) {
  $status = taxonomy_del_vocabulary($form_state['values']['vid']);
  drupal_set_message(t('Deleted vocabulary %name.', array('%name' => $form_state['values']['name'])));
  watchdog('taxonomy', 'Deleted vocabulary %name.', array('%name' => $form_state['values']['name']), WATCHDOG_NOTICE);
  $form_state['redirect'] = 'admin/content/taxonomy';
  return;
}