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) { // Just delete terms taxonomy_node_delete($node); $node->taxonomy = array(); return; } // Operate on a terms array. 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; } // Reassemble a taxonomy array that can be saved. $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; // Match content taxonomy fields with their respective vocabulary. 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 tags, give the ability to add new terms 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('
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 Replace existing terms with selected ones will cause all existing terms on the node to be deleted first, then the new, selected terms will be added. Replace terms within same vocabulary will delete existing terms within the selected terms\' vocabularies only, and will leave other existing terms untouched.'), ); return $form; } /** * Take a multi-dimensional array of vocabularies -> selected terms and * return an array of only the terms selected */ 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.')); } } }