View source
<?php
define('TAXONOMY_ACTION_ADD', 0);
define('TAXONOMY_ACTION_REPLACE', 1);
define('TAXONOMY_ACTION_DELETE', 2);
define('TAXONOMY_ACTION_REPLACE_VOCABULARY', 3);
function views_bulk_operations_taxonomy_action_info() {
if (!module_exists('taxonomy')) {
return array();
}
return array(
'views_bulk_operations_taxonomy_action' => array(
'type' => 'node',
'description' => t('Modify node taxonomy terms'),
'configurable' => TRUE,
'behavior' => array(
'changes_node_property',
),
),
);
}
function views_bulk_operations_taxonomy_action(&$node, $context) {
if (empty($context['terms']) && $context['do'] == TAXONOMY_ACTION_REPLACE) {
taxonomy_node_delete($node);
$node->taxonomy = array();
return;
}
if (isset($context['terms']['tags'])) {
$tags = $context['terms']['tags'];
unset($context['terms']['tags']);
}
$terms = array();
foreach ($context['terms'] as $tid) {
$terms[$tid] = taxonomy_get_term($tid);
}
switch ($context['do']) {
case TAXONOMY_ACTION_DELETE:
$existing_terms = taxonomy_node_get_terms($node);
while (list($delete_tid) = each($terms)) {
if (array_key_exists($delete_tid, $existing_terms)) {
unset($existing_terms[$delete_tid]);
}
}
$terms = $existing_terms;
if (empty($terms)) {
taxonomy_node_delete($node);
}
break;
case TAXONOMY_ACTION_ADD:
$existing_terms = taxonomy_node_get_terms($node);
foreach ($terms as $add_tid => $term) {
if (array_key_exists($add_tid, $existing_terms)) {
unset($terms[$add_tid]);
}
}
$terms = array_merge($terms, $existing_terms);
break;
case TAXONOMY_ACTION_REPLACE_VOCABULARY:
$existing_terms = taxonomy_node_get_terms($node);
foreach ($existing_terms as $existing_term) {
foreach ($terms as $term) {
if ($term->vid == $existing_term->vid) {
unset($existing_terms[$existing_term->tid]);
}
}
}
$terms = array_merge($terms, $existing_terms);
break;
case TAXONOMY_ACTION_REPLACE:
break;
}
$taxonomy = array();
if (!empty($terms)) {
foreach ($terms as $term) {
if (!isset($taxonomy[$term->vid])) {
$taxonomy[$term->vid] = $term->tid;
}
else {
if (is_array($taxonomy[$term->vid])) {
$taxonomy[$term->vid][$term->tid] = $term->tid;
}
else {
$previous_tid = $taxonomy[$term->vid];
$taxonomy[$term->vid] = array(
$previous_tid => $previous_tid,
$term->tid => $term->tid,
);
}
}
}
}
if (isset($tags) && $context['do'] != TAXONOMY_ACTION_DELETE) {
$taxonomy['tags'] = $tags;
}
$node->taxonomy = $taxonomy;
if (module_exists('content_taxonomy')) {
$type_name = is_string($node) ? $node : (is_array($node) ? $node['type'] : $node->type);
$type = content_types($type_name);
foreach ($type['fields'] as $field) {
if ($field['type'] == 'content_taxonomy') {
$vid = $field['vid'];
$term_values = $node->taxonomy[$field['vid']];
$new_values = array();
if (is_array($term_values)) {
foreach ($term_values as $value) {
$new_values[]['value'] = $value;
}
}
else {
$new_values[]['value'] = $term_values;
}
$node->{$field}['field_name'] = $new_values;
}
}
}
}
function views_bulk_operations_taxonomy_action_form($context) {
if (isset($context['selection']) && isset($context['view'])) {
$vocabularies = array();
$nids = array_map('_views_bulk_operations_get_oid', $context['selection'], array_fill(0, count($context['selection']), $context['view']->base_field));
$placeholders = db_placeholders($nids);
$result = db_query("SELECT DISTINCT v.vid FROM {vocabulary_node_types} v LEFT JOIN {node} n ON v.type = n.type WHERE n.nid IN ({$placeholders})", $nids);
while ($v = db_fetch_object($result)) {
$vocabularies[$v->vid] = taxonomy_vocabulary_load($v->vid);
}
}
else {
$vocabularies = taxonomy_get_vocabularies();
}
if (empty($vocabularies)) {
drupal_set_message(t('The selected nodes are not associated with any vocabulary. Please select other nodes and try again.'), 'error');
return array();
}
$form['taxonomy'] = array(
'#type' => 'fieldset',
'#title' => t('Vocabularies'),
'#tree' => TRUE,
);
while (list(, $vocabulary) = each($vocabularies)) {
$form['taxonomy'][$vocabulary->vid] = taxonomy_form($vocabulary->vid, isset($context['terms']) ? $context['terms'] : NULL);
$form['taxonomy'][$vocabulary->vid]['#weight'] = $vocabulary->weight;
if ($vocabulary->tags) {
if ($vocabulary->help) {
$help = filter_xss_admin($vocabulary->help);
}
else {
$help = t('A comma-separated list of terms describing this content. Example: funny, bungee jumping, "Company, Inc.".');
}
$help .= t('<br />Note that this field has no effect when deleting terms.');
$form['taxonomy']['tags'][$vocabulary->vid] = array(
'#type' => 'textfield',
'#title' => $vocabulary->name . ' ' . t('(new tags)'),
'#autocomplete_path' => 'taxonomy/autocomplete/' . $vocabulary->vid,
'#weight' => $vocabulary->weight,
'#maxlength' => 1024,
'#description' => $help,
'#default_value' => isset($context['terms']['tags'][$vocabulary->vid]) ? $context['terms']['tags'][$vocabulary->vid] : '',
);
}
}
$form['do'] = array(
'#type' => 'radios',
'#title' => t('Action to take'),
'#default_value' => isset($context['do']) ? $context['do'] : TAXONOMY_ACTION_ADD,
'#options' => array(
TAXONOMY_ACTION_ADD => t('Add the selected terms'),
TAXONOMY_ACTION_REPLACE => t('Replace existing terms with selected ones'),
TAXONOMY_ACTION_REPLACE_VOCABULARY => t('Replace terms within same vocabulary'),
TAXONOMY_ACTION_DELETE => t('Delete selected terms'),
),
'#required' => TRUE,
'#weight' => -2,
'#description' => t('Note that <strong>Replace existing terms with selected ones</strong> will cause all existing terms on the node to be deleted first,
then the new, selected terms will be added. <strong>Replace terms within same vocabulary</strong> will delete existing terms within
the selected terms\' vocabularies only, and will leave other existing terms untouched.'),
);
return $form;
}
function _taxonomy_action_parse_terms($taxonomy) {
$ret = array();
while (list($key, $vocab) = each($taxonomy)) {
if ($key == 'tags') {
$ret['tags'] = $vocab;
}
else {
if (!is_array($vocab)) {
if (!empty($vocab)) {
$ret[] = $vocab;
}
}
else {
while (list(, $tid) = each($vocab)) {
if (!empty($tid)) {
$ret[] = $tid;
}
}
}
}
}
return $ret;
}
function views_bulk_operations_taxonomy_action_submit($form, $form_state) {
return array(
'do' => $form_state['values']['do'],
'terms' => _taxonomy_action_parse_terms($form_state['values']['taxonomy']),
);
}
function views_bulk_operations_taxonomy_action_validate($form, $form_state) {
if ($form_state['values']['do'] != TAXONOMY_ACTION_REPLACE) {
$terms = _taxonomy_action_parse_terms($form_state['values']['taxonomy']);
if (empty($terms)) {
form_set_error('terms', t('You did not select any term nor did you choose to replace existing terms. Please select one or more terms or choose to replace the terms.'));
}
}
}