type); $perms[] = "alter taxonomy on $name content"; } return $perms; } /** * Implementation of hook_menu(). */ function comment_alter_taxonomy_menu() { $items = array(); $items[] = array( 'path' => 'admin/settings/comment_alter_taxonomy', 'title' => t('Comment alter taxonomy'), 'description' => t('Enable/disable vocabularies that users may alter from their comments.'), 'callback' => 'drupal_get_form', 'callback arguments' => array('comment_alter_taxonomy_admin_settings'), ); return $items; } /** * Administration settings form. */ function comment_alter_taxonomy_admin_settings() { $options = array(); // Get a list of all vocabularies in the system. $vocabularies = taxonomy_get_vocabularies(); foreach ($vocabularies as $vid => $vocabulary) { $options[$vid] = check_plain($vocabulary->name); } $form['comment_alter_taxonomy_vocabularies'] = array( '#type' => 'checkboxes', '#title' => t('Vocabularies that may be altered'), '#options' => $options, '#default_value' => variable_get('comment_alter_taxonomy_vocabularies', array()), ); return system_settings_form($form); } /** * Implementation of hook_form_alter(). */ function comment_alter_taxonomy_form_alter($form_id, &$form) { // Only fire on comment forms. if ($form_id == 'comment_form') { // Prepare some variables for later checking. $node = node_load($form['nid']['#value']); $type = check_plain($node->type); $access = "alter taxonomy on $type content"; $vocabularies = taxonomy_get_vocabularies($type); $enabled = array_keys($vocabularies); $allowed = variable_get('comment_alter_taxonomy_vocabularies', array()); $intersect = array_intersect($enabled, $allowed); // Only proceed if user has access to alter tags on this node type, and if // node type has vocabularies enabled on it which can be altered. if (user_access($access) && !empty($intersect)) { // Display the edit form for each qualifying vocabulary. foreach ($intersect as $vid) { _comment_alter_taxonomy_vocabulary_form($vocabularies[$vid], $node, $form); } // Add custom submit handler. $form['#submit']['comment_taxonomy_alter_submit'] = array(); } } } /** * Submit handler for taxonomy alter form. */ function comment_taxonomy_alter_submit($form_id, $form_values) { taxonomy_node_save($form_values['nid'], $form_values['taxonomy']); } /** * Generate taxonomy forms for a given set of vocabulary IDs. * * This is kind of nasty (it is indeed!!); mostly a copy/paste of taxonomy_form_alter, which is * a big glop of stuff. */ function _comment_alter_taxonomy_vocabulary_form($vocabulary, $node, &$form) { // Determine existing term assignments, if any. if (!isset($node->taxonomy)) { if ($node->nid) { $terms = taxonomy_node_get_terms($node->nid); } else { $terms = array(); } } else { $terms = $node->taxonomy; } if ($vocabulary->tags) { // Handle free-tagging vocabularies. $typed_terms = array(); foreach ($terms as $term) { // Extract terms belonging to the vocabulary in question. if ($term->vid == $vocabulary->vid) { // Commas and quotes in terms are special cases, so encode 'em. if (strpos($term->name, ',') !== FALSE || strpos($term->name, '"') !== FALSE) { $term->name = '"'.str_replace('"', '""', $term->name).'"'; } $typed_terms[] = $term->name; } } $typed_string = implode(', ', $typed_terms) . (array_key_exists('tags', $terms) ? $terms['tags'][$vocabulary->vid] : NULL); if ($vocabulary->help) { $help = $vocabulary->help; } else { $help = t('A comma-separated list of terms describing this content. Example: funny, bungee jumping, "Company, Inc.".'); } $form['taxonomy']['tags'][$vocabulary->vid] = array('#type' => 'textfield', '#title' => $vocabulary->name, '#description' => $help, '#required' => $vocabulary->required, '#default_value' => $typed_string, '#autocomplete_path' => 'taxonomy/autocomplete/'. $vocabulary->vid, '#weight' => $vocabulary->weight, '#maxlength' => 255, '#tree' => TRUE, ); } else { // Extract terms belonging to the vocabulary in question. $default_terms = array(); foreach ($terms as $term) { if ($term->vid == $vocabulary->vid) { $default_terms[$term->tid] = $term; } } $form['taxonomy'][$vocabulary->vid] = taxonomy_form($vocabulary->vid, array_keys($default_terms), $vocabulary->help); $form['taxonomy'][$vocabulary->vid]['#weight'] = $vocabulary->weight; $form['taxonomy'][$vocabulary->vid]['#required'] = $vocabulary->required; $form['taxonomy'][$vocabulary->vid]['#tree'] = TRUE; } if (is_array($form['taxonomy']) && !empty($form['taxonomy'])) { if (count($form['taxonomy']) > 1) { // Add fieldset only if form has more than 1 element. $form['taxonomy'] += array( '#type' => 'fieldset', '#title' => t('Categories'), '#collapsible' => TRUE, '#collapsed' => FALSE, ); } $form['taxonomy']['#weight'] = -3; $form['taxonomy']['#tree'] = TRUE; } } /** * Implementation of hook_followup_metadata_changes * * Handles the diffing of taxonomy terms in project_issue comments. */ function comment_alter_taxonomy_followup_metadata_changes($old_data, $new_data) { global $project_issue_comment_changes_array; if (!in_array('taxonomy', $project_issue_comment_changes_array['changes_keys'])) { return; } $old_taxonomy = unserialize($project_issue_comment_changes_array['old']['taxonomy']); $new_taxonomy = unserialize($project_issue_comment_changes_array['new']['taxonomy']); // Process changeserences in free tagging vocabularies. $vids = array(); if (!empty($old_taxonomy['tags'])) { $vids = array_keys($old_taxonomy['tags']); } if (!empty($new_taxonomy['tags'])) { $vids += array_keys($new_taxonomy['tags']); } $vids = array_unique($vids); foreach ($vids as $vid) { if (isset($old_taxonomy['tags'][$vid]) && isset($new_taxonomy['tags'][$vid])) { if ($old_taxonomy['tags'][$vid] != $new_taxonomy['tags'][$vid]) { $project_issue_comment_changes_array['old']["taxonomy_vid_$vid"] = $old_taxonomy['tags'][$vid]; $project_issue_comment_changes_array['new']["taxonomy_vid_$vid"] = $new_taxonomy['tags'][$vid]; $project_issue_comment_changes_array['changes_keys'][] = 'taxonomy_vid_'. $vid; $vocabulary = taxonomy_get_vocabulary($vid); $project_issue_comment_changes_array['label_array']["taxonomy_vid_$vid"] = check_plain($vocabulary->name); } } elseif ($old_taxonomy['tags'][$vid]) { $project_issue_comment_changes_array['old']["taxonomy_vid_$vid"] = $old_taxonomy['tags'][$vid]; $project_issue_comment_changes_array['new']["taxonomy_vid_$vid"] = ''; $project_issue_comment_changes_array['changes_keys'][] = 'taxonomy_vid_'. $vid; $vocabulary = taxonomy_get_vocabulary($vid); $project_issue_comment_changes_array['label_array']["taxonomy_vid_$vid"] = check_plain($vocabulary->name); } else { $project_issue_comment_changes_array['old']["taxonomy_vid_$vid"] = ''; $project_issue_comment_changes_array['new']["taxonomy_vid_$vid"] = $new_taxonomy['tags'][$vid]; $project_issue_comment_changes_array['changes_keys'][] = 'taxonomy_vid_'. $vid; $vocabulary = taxonomy_get_vocabulary($vid); $project_issue_comment_changes_array['label_array']["taxonomy_vid_$vid"] = check_plain($vocabulary->name); } } } /** * @return * An array with each value representing one vid present in $taxonomy. */ function _comment_alter_taxonomy_get_vid_array($taxonomy) { $vid_array = array_keys($taxonomy); if (!empty($taxonomy) && array_key_exists('tags', $taxonomy)) { $tag_vids = array_keys($taxonomy['tags']); $vid_array = array_merge($vid_array, $tag_vids); } return $vid_array; }