',
);
//switch operations
if ($vid1 != $vid2) {
$form['double-tree']['operations']['move_right']['#value'] = 'Switch right';
$form['double-tree']['operations']['move_right']['#attributes']['title'] = t('Switch selected terms and its children to the right voc');
$form['double-tree']['operations']['move_left']['#value'] = 'Switch left';
$form['double-tree']['operations']['move_left']['#attributes']['title'] = t('Switch selected terms and its children to the left voc');
}
else if (isset($language)) {
$form['double-tree']['operations']['add_translation'] = array(
'#type' => 'image_button',
'#value' => 'translation',
'#attributes' => array('title' => t('Add Translation')),
'#src' => $module_path ."images/connect.png",
//'#executes_submit_callback' => FALSE,
'#prefix' => '
',
'#suffix' => '
',
);
}
return $form;
}
function taxonomy_manager_toolbar_forms() {
/*$params = $_GET;
$form = array();
$form_state = array('submitted' => FALSE);
$form = form_get_cache($params['form_build_id'], $form_state);
$form += taxonomy_manager_confirm_delete($form['vid']);
$form = form_builder($param['form_id'], $form, $form_state);
drupal_prepare_form($param['form_id'], $form, $form_state);
$form = form_builder($param['form_id'], $form, $form_state);
form_set_cache($params['form_build_id'], $form, $form_state);
$output = drupal_render($form['delete']);
print drupal_to_js(array('status' => TRUE, 'data' => $output));
exit;*/
}
/**
* confirmation form for deleting selected terms
*/
function taxonomy_manager_confirm_delete($voc) {
drupal_add_js(array('hideForm' => array(
'show_button' => 'edit-delete-confirm',
'hide_button' => 'edit-delete-cancel',
'div' => 'del-confirm-form')), 'setting');
$form = array();
$form['delete'] = array(
'#type' => 'fieldset',
'#attributes' => array('id' => 'del-confirm-form', 'style' => 'display:none;'),
'#tree' => TRUE,
'#title' => t('Confirmation'),
);
$question = t('Are you sure you want to delete all selected terms? ');
$info = t('Remember all term specific data will be lost. This action cannot be undone.');
$form['delete']['text'] = array('#value' => "". $question ." ". $info);
$options = array(
'delete_orphans' => t('Delete children of selected terms, if there are any'),
);
$form['delete']['options'] = array(
'#type' => 'checkboxes',
'#title' => t('Options'),
'#options' => $options,
);
$form['delete']['delete'] = array(
'#type' => 'submit',
'#value' => t('Delete'),
'#attributes' => array('class' => 'taxonomy-manager-buttons delete'),
'#submit' => array('taxonomy_manager_form_delete_submit'),
'#validate' => array('taxonomy_manager_form_delete_validate'),
);
$form['delete']['cancel'] = array(
'#type' => 'button',
'#attributes' => array('class' => 'taxonomy-manager-buttons cancel'),
'#value' => t('Cancel'),
'#theme' => 'no_submit_button',
);
return $form;
}
/**
* form for adding terms
*/
function taxonomy_manager_add_form($voc, $hide_form = TRUE) {
if ($hide_form) {
drupal_add_js(array('hideForm' => array(
'show_button' => 'edit-add-show',
'hide_button' => 'edit-add-cancel',
'div' => 'add-form')), 'setting');
$attributes = array('id' => 'add-form', 'style' => 'display:none;');
}
else {
$attributes = array('id' => 'add-form');
}
$form = array();
$description = "";
$description = t("If you have selected one or more terms in the tree view, the new terms are automatically children of those.");
$form['add'] = array(
'#type' => 'fieldset',
'#tree' => TRUE,
'#attributes' => $attributes,
'#title' => t('Add new terms'),
'#description' => $description,
);
for ($i=0; $i<6; $i++) {
$form['add']['term'][$i] = array(
'#type' => 'textfield',
);
}
$form['add']['mass'] = array(
'#type' => 'fieldset',
'#tree' => TRUE,
'#title' => t('Mass term import (with textarea)'),
'#collapsible' => TRUE,
'#collapsed' => TRUE,
);
$form['add']['mass']['mass_add'] = array(
'#type' => 'textarea',
'#title' => t('Terms'),
'#description' => t('One term per line'),
'#rows' => 10,
);
$form['add']['add'] = array(
'#type' => 'submit',
'#attributes' => array('class' => 'taxonomy-manager-buttons add'),
'#value' => t('Add'),
'#validate' => array('taxonomy_manager_form_add_validate'),
'#submit' => array('taxonomy_manager_form_add_submit'),
);
$form['add']['cancel'] = array(
'#type' => 'button',
'#value' => t('Cancel'),
'#theme' => 'no_submit_button',
'#attributes' => array('class' => 'taxonomy-manager-buttons cancel'),
);
return $form;
}
/**
* form for merging terms
*/
function taxonomy_manager_merge_form($voc) {
drupal_add_js(array('hideForm' => array(
'show_button' => 'edit-merge-show',
'hide_button' => 'edit-merge-cancel',
'div' => 'merge-form')), 'setting');
$form = array();
$description .= t("The selected terms get merged into one term.
This resulting merged term can either be an exisiting term or a completely new term.
The selected terms will automatically get synomyms of the merged term and will be deleted afterwards.");
$form['merge'] = array(
'#type' => 'fieldset',
'#tree' => TRUE,
'#attributes' => array('id' => 'merge-form', 'style' => 'display:none;'),
'#title' => t('Merging of terms'),
'#description' => $description,
);
$form['merge']['main_term'] = array(
'#type' => 'textfield',
'#title' => t('Resulting merged term'),
'#description' => t("Enter a unique term name or a term id with 'term-id:[tid]'"),
'#required' => FALSE,
'#autocomplete_path' => 'taxonomy_manager/autocomplete/'. $voc->vid,
);
$options = array();
$options['collect_parents'] = t('Collect all parents of selected terms an add it to the merged term');
$options['collect_children'] = t('Collect all children of selected terms an add it to the merged term');
$options['collect_relations'] = t('Collect all relations of selected terms an add it to the merged term');
if (count($options) > 0) {
$form['merge']['options'] = array(
'#type' => 'checkboxes',
'#title' => t('Options'),
'#options' => $options,
);
}
$form['merge']['submit'] = array(
'#type' => 'submit',
'#value' => t('Merge'),
'#attributes' => array('class' => 'taxonomy-manager-buttons merge'),
'#validate' => array('taxonomy_manager_form_merge_validate'),
'#submit' => array('taxonomy_manager_form_merge_submit'),
);
$form['merge']['cancel'] = array(
'#type' => 'button',
'#value' => t('Cancel'),
'#attributes' => array('class' => 'taxonomy-manager-buttons cancel'),
'#theme' => 'no_submit_button',
);
return $form;
}
/**
* form for moving terms in hierarchies
*/
function taxonomy_manager_move_form($voc) {
drupal_add_js(array('hideForm' => array(
'show_button' => 'edit-move-show',
'hide_button' => 'edit-move-cancel',
'div' => 'move-form')), 'setting');
$form = array();
$description = t("You can change the parent of one or more selected terms.
If you leave the autocomplete field empty, the term will be a root term.");
$form['move'] = array(
'#type' => 'fieldset',
'#tree' => TRUE,
'#attributes' => array('id' => 'move-form', 'style' => 'display:none;'),
'#title' => t('Moving of terms'),
'#description' => $description,
);
$form['move']['parents'] = array(
'#type' => 'textfield',
'#title' => t('Parent term(s)'),
'#description' => t("Enter a unique term name or a term id with 'term-id:[tid]'. Separate multiple parent terms with commas."),
'#required' => FALSE,
'#autocomplete_path' => 'taxonomy_manager/autocomplete/'. $voc->vid,
);
$options = array();
$options['keep_old_parents'] = t('Keep old parents and add new ones (multi-parent). Otherwise old parents get replaced.');
$form['move']['options'] = array(
'#type' => 'checkboxes',
'#title' => t('Options'),
'#options' => $options,
);
$form['move']['submit'] = array(
'#type' => 'submit',
'#attributes' => array('class' => 'taxonomy-manager-buttons move'),
'#value' => t('Move'),
'#validate' => array('taxonomy_manager_form_move_validate'),
'#submit' => array('taxonomy_manager_form_move_submit'),
);
$form['move']['cancel'] = array(
'#type' => 'button',
'#value' => t('Cancel'),
'#attributes' => array('class' => 'taxonomy-manager-buttons cancel'),
'#theme' => 'no_submit_button',
);
return $form;
}
/**
* form for exporting terms
*/
function taxonomy_manager_export_form($voc) {
drupal_add_js(array('hideForm' => array(
'show_button' => 'edit-export-show',
'hide_button' => 'edit-export-cancel',
'div' => 'export-form')), 'setting');
$module_path = drupal_get_path('module', 'taxonomy_manager') .'/';
drupal_add_js($module_path .'js/csv_export.js');
drupal_add_js(array('exportCSV' => array('url' => url("admin/content/taxonomy_manager/export"))), 'setting');
$form = array();
$form['export'] = array(
'#type' => 'fieldset',
'#tree' => TRUE,
'#attributes' => array('id' => 'export-form', 'style' => 'display:none;'),
'#title' => t('CSV Export'),
'#description' => $description,
);
$form['export']['delimiter'] = array(
'#type' => 'textfield',
'#title' => t('Delimiter for CSV File'),
'#required' => FALSE,
'#default_value' => ";",
);
$options['whole_voc'] = t('Whole Vocabulary');
$options['children'] = t('Child terms of a selected term');
$options['root_terms'] = t('Root level terms only');
$form['export']['options'] = array(
'#type' => 'radios',
'#title' => t('Terms to export'),
'#options' => $options,
'#default_value' => 'whole_voc',
'#prefix' => '
',
'#suffix' => '
',
);
$form['export']['depth'] = array(
'#type' => 'textfield',
'#title' => t('Depth of tree'),
'#description' => t('The number of levels of the tree to export. Leave empty to return all levels.'),
);
$form['export']['csv'] = array(
'#type' => 'textarea',
'#title' => t('Exported CSV'),
'#description' => t('The generated code will appear here (per AJAX). You can copy and paste the code into a .csv file. The csv has following columns: voc id | term id | term name | description | parent id 1 | ... | parent id n'),
'#rows' => 8,
);
$form['export']['submit'] = array(
'#type' => 'submit',
'#attributes' => array('class' => 'taxonomy-manager-buttons export'),
'#value' => t('Export now'),
'#theme' => 'no_submit_button',
);
$form['export']['cancel'] = array(
'#type' => 'button',
'#value' => t('Cancel'),
'#attributes' => array('class' => 'taxonomy-manager-buttons cancel'),
'#theme' => 'no_submit_button',
);
return $form;
}
function taxonomy_manager_double_tree_settings_form($voc) {
drupal_add_js(array('hideForm' => array(
'show_button' => 'edit-double-tree-show',
'hide_button' => 'edit-double-tree-cancel',
'div' => 'double-tree-settings-form')), 'setting');
$form = array();
$form['double_tree'] = array(
'#type' => 'fieldset',
'#tree' => TRUE,
'#attributes' => array('id' => 'double-tree-settings-form', 'style' => 'display:none;'),
'#title' => t('Double Tree Settings'),
'#description' => t('Specify settings for second tree. Choose the same vocabulary if you want to move terms in the hierarchy or if you want to add new translations within a multilingual vocabulary. Choose a different vocabulary if you want to switch terms among these vocabularies.'),
);
$options = array();
$vocs = taxonomy_get_vocabularies();
foreach ($vocs as $v) {
$options[$v->vid] = $v->name;
}
$form['double_tree']['voc2'] = array(
'#type' => 'select',
'#title' => t('Vocabulary for second tree'),
'#options' => $options,
'#default_value' => $voc->vid,
);
$form['double_tree']['submit'] = array(
'#type' => 'submit',
'#attributes' => array('class' => 'taxonomy-manager-buttons double-tree'),
'#value' => t('Enable Double Tree'),
'#submit' => array('taxonomy_manager_form_double_tree_submit'),
);
if (arg(3) == "double-tree") {
$form['double_tree']['disable'] = array(
'#type' => 'submit',
'#attributes' => array('class' => 'taxonomy-manager-buttons double-tree-disable'),
'#value' => t('Disable Double Tree'),
'#submit' => array('taxonomy_manager_form_double_tree_disable_submit'),
);
}
$form['double_tree']['cancel'] = array(
'#type' => 'button',
'#value' => t('Cancel'),
'#attributes' => array('class' => 'taxonomy-manager-buttons cancel'),
'#theme' => 'no_submit_button',
);
return $form;
}
/**
* menu callback for displaying term data form
*
* if this function gets called by ahah, then the term data form gets
* generated, rendered and return
* otherwise, if no ahah call, redirect to original form with $vid and $tid as parameters
*
* @param $vid
* @param $tid
* @param $ahah if true, return rendered form, else redirect
*/
function taxonomy_manager_update_term_data_form($vid, $tid, $ahah = FALSE, $print = TRUE, $msg = "", $is_error_msg = FALSE) {
if (!$ahah) {
drupal_goto('admin/content/taxonomy_manager/voc/'. $vid .'/'. $tid);
}
$GLOBALS['devel_shutdown'] = FALSE; //prevent devel queries footprint
$params = $_GET;
//actually we don not need do use the caching because the saving only happens through a AJAX callback
//and it's a bit faster, cache loading, form building and cache saving needs some time else.
/*$form_state = array('submitted' => FALSE);
$form = form_get_cache($params['form_build_id'], $form_state);
unset($form['term_data']);
$form = form_builder($param['form_id'], $form, $form_state);*/
$term_form = taxonomy_manager_form_term_data($tid);
$term_form['term_data']['save'] = array(
'#type' => 'submit',
'#value' => t('Save changes'),
'#submit' => array(''),
'#attributes' => array('class' => 'taxonomy-manager-buttons save'),
'#ahah' => array(
'path' => 'admin/content/taxonomy_manager/termdata/edit',
'method' => 'replace',
'event' => 'click',
'wrapper' => 'taxonomy-term-data',
'progress' => array('type' => ''),
),
'#weight' => 20,
);
if ($msg != "") {
$term_form['term_data']['msg'] = array(
'#type' => 'markup',
'#prefix' => '
',
'#suffix' => '
',
'#value' => $msg,
'#weight' => -20,
);
if ($is_error_msg) {
$term_form['term_data']['msg']['#value'] = t("Error! Your last operation couldn't be performed because of following problem:") ." ". $msg;
$term_form['term_data']['msg']['#prefix'] = '
';
}
}
$form = $term_form;
drupal_prepare_form('taxonomy_manager_form', $form, $form_state);
$form = form_builder('taxonomy_manager_form', $form, $form_state);
//form_set_cache($params['form_build_id'], $form, $form_state);
$output = drupal_render($form['term_data']);
if ($print) {
print $output;
exit();
}
return $output;
}
/**
* term data editing form
*
* @param $tid
*/
function taxonomy_manager_form_term_data($tid) {
$term = taxonomy_get_term($tid);
$module_path = drupal_get_path('module', 'taxonomy_manager') .'/';
$vocabulary = taxonomy_vocabulary_load($term->vid);
//prevent that title of the fieldset is too long
$title = $term->name;
if (drupal_strlen($title) >= 33) {
$title = drupal_substr($title, 0, 33) ."...";
}
$title .= " (". $term->tid .")";
$title = check_plain($title);
$form['term_data'] = array(
'#type' => 'fieldset',
'#title' => $title,
'#attributes' => array('id' => 'taxonomy-term-data-fieldset'),
'#tree' => TRUE,
);
$form['term_data']['close'] = array(
'#value' => '
\n");
}
$form['delete'] = array('#type' => 'value', '#value' => TRUE);
$form['vid'] = array('#type' => 'value', '#value' => $vid);
$form['options'] = array('#type' => 'value', '#value' => $form_state['values']['delete']['options']);
$msg = !empty($form_state['values']['delete']['options']['delete_orphans']) ? t('Deleting a term will delete all its children if there are any. ') : '';
$msg .= t('This action cannot be undone.');
return confirm_form($form,
t('Are you sure you want to delete the following terms: '),
$url,
$msg,
t('Delete'),
t('Cancel'));
}
/**
* Submit handler to delete a term after confirmation.
*
*/
function taxonomy_manager_term_confirm_delete_submit($form, &$form_state) {
taxonomy_manager_delete_terms($form_state['values']['selected_terms'], $form_state['values']['options']);
if (isset($form_state['values']['vid2'])) {
$form_state['redirect'] = 'admin/content/taxonomy_manager/double-tree/'. $form_state['values']['vid'] .'/'. $form_state['values']['vid2'];
}
else {
$form_state['redirect'] = 'admin/content/taxonomy_manager/voc/'. $form_state['values']['vid'];
}
drupal_set_message(t("Selected terms deleted"));
return;
}
/**
* Validation handler for moving terms
*/
function taxonomy_manager_form_move_validate($form, &$form_state) {
$selected_tids = array();
$selected_tids = $form_state['values']['taxonomy']['manager']['tree']['selected_terms'];
$error_msg = "";
if (count($selected_tids) < 1) {
form_set_error('move', t("Please selected terms you want to move in the hierarchy"));
$form_state['rebuild'] = TRUE;
}
else if (_taxonomy_manager_check_duplicates($form_state['values']['vid'], $form_state['values']['move']['parents'], $error_msg)) {
form_set_error('move', t("Warning: Your input matches with multiple terms, because of duplicated term names. Please enter a unique term name or the term id with 'term-id:[tid]'") ." (". $error_msg .").");
$form_state['rebuild'] = TRUE;
}
$typed_parents = taxonomy_manager_autocomplete_tags_get_tids($form_state['values']['move']['parents'], $form_state['values']['vid'], FALSE);
$parents = array();
foreach ($typed_parents as $parent_info) {
$parents[(int) $parent_info['tid']] = (int) $parent_info['tid'];
}
if (!taxonomy_manager_check_circular_hierarchy($selected_tids, $parents)) {
form_set_error('move', t('Invalid selection. The resulting hierarchy would contain circles, which is not allowed. A term cannot be a parent of itself.'));
$form_state['rebuild'] = TRUE;
}
else if (!taxonomy_manager_check_language($form_state['values']['vid'], $selected_tids, $typed_parents)) {
form_set_error('move', t('Terms must be of the same language'));
$form_state['rebuild'] = TRUE;
}
}
/**
* checks for circles in the hierarchy, e.g. 1 -> 2 -> 3 -> 1
* a term can't contain itself as a parent
*
* returns TRUE if resulting hierarchy is valid, else FALSE
*/
function taxonomy_manager_check_circular_hierarchy($tids, $new_parents_tids) {
if (is_array($tids) && is_array($new_parents_tids)) {
//directly same term
foreach ($tids as $tid) {
if (in_array($tid, $new_parents_tids)) {
return FALSE;
}
}
//same term over more hierarchy levels
$all_parents = array();
foreach ($new_parents_tids as $parent_tid) {
$parents = taxonomy_get_parents_all($parent_tid);
foreach ($parents as $parent) {
$all_parents[$parent->tid] = $parent->tid;
}
}
foreach ($tids as $tid) {
if (in_array($tid, $all_parents)) {
return FALSE;
}
}
}
return TRUE;
}
/**
* checks if terms in move or merge operation are of the same language
*
* returns TRUE if operation allowed, else FALSE (different languages)
*/
function taxonomy_manager_check_language($vid, $selected_tids, $parents) {
if (module_exists('i18ntaxonomy')) {
if (count($parents) && count($selected_tids)) {
$term = array_pop($parents);
$lang = _taxonomy_manager_term_get_lang($term['tid']);
if (i18ntaxonomy_vocabulary($vid) == I18N_TAXONOMY_TRANSLATE) {
foreach ($parents as $parent) {
if (_taxonomy_manager_term_get_lang($parent['tid']) != $lang) {
return FALSE;
}
}
foreach ($selected_tids as $tid) {
if (_taxonomy_manager_term_get_lang($tid) != $lang) {
return FALSE;
}
}
}
}
}
return TRUE;
}
/**
* Submit handler for moving terms
*/
function taxonomy_manager_form_move_submit($form, $form_state) {
$selected_tids = array();
$selected_tids = $form_state['values']['taxonomy']['manager']['tree']['selected_terms'];
$typed_parents = taxonomy_manager_autocomplete_tags_get_tids($form_state['values']['move']['parents'], $form_state['values']['vid'], TRUE, $form_state['values']['taxonomy']['manager']['top']['language']);
$parents = array();
foreach ($typed_parents as $parent_info) {
$parents[] = $parent_info['tid'];
}
if (count($parents) == 0) $parents[0] = 0; //if empty, delete all parents
taxonomy_manager_move($parents, $selected_tids, $form_state['values']['move']['options']);
if ($form_state['values']['move']['options']['keep_old_parents']) {
$parents[] = 1; //++ parent count for hierarchy update (-> multi hierarchy)
}
taxonomy_manager_update_voc($form_state['values']['vid'], $parents);
$term_names_array = array();
foreach ($selected_tids as $selected_tid) {
$term = taxonomy_get_term($selected_tid);
$term_names_array[] = $term->name;
}
$term_names = implode(', ', $term_names_array);
$parent_names = "";
if (count($typed_parents) == 0) {
$parent_names = t("root level");
}
else {
$parent_names = $form_state['values']['move']['parents'];
}
drupal_set_message(t("Terms %term_names moved to %parent_names", array('%term_names' => $term_names, '%parent_names' => $parent_names)));
}
/**
* Validation handler for validating terms
*/
function taxonomy_manager_form_merge_validate($form, &$form_state) {
$selected_tids = array();
$selected_tids = $form_state['values']['taxonomy']['manager']['tree']['selected_terms'];
$main_terms = array();
$regexp = '%(?:^|,\ *)("(?>[^"]*)(?>""[^"]* )*"|(?: [^",]*))%x';
preg_match_all($regexp, $form_state['values']['merge']['main_term'], $matches);
$main_terms = $matches[1];
$error_msg = "";
$typed_terms = taxonomy_manager_autocomplete_tags_get_tids($form_state['values']['merge']['main_term'], $form_state['values']['vid'], FALSE);
if (!is_array($main_terms) || count($main_terms) == 0 || empty ($main_terms[0])) {
form_set_error('merge][main_term', t('Please enter a name into "Resulting merged term"'));
$form_state['rebuild'] = TRUE;
}
else if (count($main_terms) > 1) {
form_set_error('merge][main_term', t('Please only enter single names into "Resulting merged term"'));
$form_state['rebuild'] = TRUE;
}
if (count($selected_tids) < 1) {
form_set_error('merge', t("Please selected terms you want to merge"));
$form_state['rebuild'] = TRUE;
}
else if (count($selected_tids) > 50) {
form_set_error('merge', t("Please select less than 50 terms to merge. Merging of too many terms in one step can cause timeouts and inconsistent database states"));
$form_state['rebuild'] = TRUE;
}
else if (_taxonomy_manager_check_duplicates($form_state['values']['vid'], $form_state['values']['merge']['main_term'], $error_msg)) {
form_set_error('merge', t("Warning: Your input matches with multiple terms, because of duplicated term names. Please enter a unique term name or the term id with 'term-id:[tid]'") ." (". $error_msg .").");
$form_state['rebuild'] = TRUE;
}
else if ($form_state['values']['merge']['options']['collect_parents']) {
$main_terms = array();
foreach ($typed_terms as $term_info) {
$main_terms[$term_info['tid']] = $term_info['tid'];
}
if (count($main_terms) == 1) {
if (!taxonomy_manager_check_circular_hierarchy($main_terms, $selected_tids)) {
form_set_error('merge', t('Invalid selection. The resulting hierarchy would contain circles, which is not allowed. A term cannot be a parent of itself. Unselect "Collect all parents of selected terms an add it to the merged term" or specify a different resulting term.'));
$form_state['rebuild'] = TRUE;
}
}
}
else if (!taxonomy_manager_check_language($form_state['values']['vid'], $selected_tids, $typed_terms)) {
form_set_error('merge', t('Terms must be of the same language'));
$form_state['rebuild'] = TRUE;
}
}
/**
* Submit handler for merging terms
*/
function taxonomy_manager_form_merge_submit($form, $form_state) {
$selected_tids = array();
$selected_tids = $form_state['values']['taxonomy']['manager']['tree']['selected_terms'];
$main_terms = taxonomy_manager_autocomplete_tags_get_tids($form_state['values']['merge']['main_term'], $form_state['values']['vid'], TRUE, $form_state['values']['taxonomy']['manager']['top']['language']);
$main_term = array_shift($main_terms);
$new_inserted = FALSE;
if ($main_term['new']) {
$new_inserted = TRUE;
}
$main_term_tid = $main_term['tid'];
taxonomy_manager_merge($main_term_tid, $selected_tids, $form_state['values']['merge']['options'], $new_inserted);
$term_names_array = array();
foreach ($selected_tids as $selected_tid) {
$term = taxonomy_get_term($selected_tid);
$term_names_array[] = $term->name;
}
$term_names = implode($term_names_array, ', ');
drupal_set_message(t("Terms %term_names merged into %main_term", array('%term_names' => $term_names, '%main_term' => $form_state['values']['merge']['main_term'])));
}
/**
* returns TRUE if term with same name exists more often
*/
function _taxonomy_manager_check_duplicates($vid, $autocomplete_value, &$msg) {
$regexp = '%(?:^|,\ *)("(?>[^"]*)(?>""[^"]* )*"|(?: [^",]*))%x';
preg_match_all($regexp, $autocomplete_value, $matches);
foreach ($matches[1] as $match) {
$terms = array();
$terms = taxonomy_manager_autocomplete_tags_get_tids($match, $vid, FALSE);
if (count($terms) > 1) {
$tids = array();
foreach ($terms as $t) {
$term = taxonomy_get_term($t['tid']);
$tids[] = $term->tid . (!empty($term->language) ? '-'. check_plain($term->language) : '');
}
$msg .= check_plain($match) .": ". implode(", ", $tids);
return TRUE;
}
}
return FALSE;
}
function taxonomy_manager_form_double_tree_submit($form, $form_state) {
$voc1 = $form_state['values']['vid'];
$voc2 = $form_state['values']['double_tree']['voc2'];
drupal_goto('admin/content/taxonomy_manager/double-tree/'. $voc1 .'/'. $voc2);
}
function taxonomy_manager_form_double_tree_disable_submit($form, $form_state) {
drupal_goto('admin/content/taxonomy_manager/voc/'. $form_state['values']['vid']);
}
/**
* Defines a settings form.
*/
function taxonomy_manager_settings() {
$form['taxonomy_manager_disable_mouseover'] = array(
'#type' => 'checkbox',
'#title' => t('Disable mouse-over effect for terms (weights and direct link)'),
'#default_value' => variable_get('taxonomy_manager_disable_mouseover', 0),
'#description' => t('Disabeling this feature speeds up the Taxonomy Manager'),
);
$form['taxonomy_manager_disable_merge_redirect'] = array(
'#type' => 'checkbox',
'#title' => t('Disable redirect of the taxonomy term page to merged terms '),
'#default_value' => variable_get('taxonomy_manager_disable_merge_redirect', TRUE),
'#description' => t('When using the merging feature, the selected terms get merged into one term. All selected terms will be deleted afterwards. Normally the Taxonomy Manager redirects calls to taxonomy/term/$tid of the deleted terms (through merging) to the resulting merged term. This feature might conflict with other modules (e.g. Taxonomy Breadcrumb, Panels), which implement hook_menu_alter to change the taxonomy_manager_term_page callback. Disable this feature if it conflicts with other modules or if you do not need it. Changing this setting requires a (menu) cache flush to become active.'),
);
$form['taxonomy_manager_pager_tree_page_size'] = array(
'#type' => 'select',
'#title' => t('Pager count'),
'#options' => array(25 => 25, 50 => 50, 75 => 75, 100 => 100, 150 => 150, 200 => 200, 250 => 250, 300 => 300, 400 => 400, 500 => 500),
'#default_value' => variable_get('taxonomy_manager_pager_tree_page_size', 50),
'#description' => t('Select how many terms should be listed on one page. Huge page counts can slow down the Taxonomy Manager'),
);
return system_settings_form($form);
}
/**
* callback handler for updating term data
*
* @param $vid
*/
function taxonomy_manager_term_data_edit() {
$param = $_POST;
$msg = t("Changes successfully saved");
$is_error_msg = FALSE;
$tid = $param['tid'];
if (!$tid) {
$tid = $param['term_data']['tid'];
}
$vid = $param['vid'];
if (!$vid) {
$vid = $param['term_data']['vid'];
}
$values = $param['value'];
$attr_type = $param['attr_type'];
$op = $param['op'];
if ($op == t("Save changes")) {
db_query("UPDATE {term_data} SET name = '%s' WHERE tid = %d", $param['term_data']['name'], $tid);
db_query("UPDATE {term_data} SET description = '%s' WHERE tid = %d", $param['term_data']['description'], $tid);
}
if ($op == 'add') {
$typed_terms = taxonomy_manager_autocomplete_tags_get_tids($values, $vid, FALSE);
}
if ($op == 'add' && ($attr_type == 'parent' || $attr_type == 'related')) {
//check for unique names
$error_msg = "";
if (_taxonomy_manager_check_duplicates($vid, $values, $error_msg)) {
$msg = t("Warning: Your input matches with multiple terms, because of duplicated term names. Please enter a unique term name or the term id with 'term-id:[tid]'") ." (". $error_msg .").";
$is_error_msg = TRUE;
}
if(!taxonomy_manager_check_language($vid, array($tid), $typed_terms)) {
$msg = t("Terms must be of the same language");
$is_error_msg = TRUE;
}
if ($attr_type == 'parent') {
//validation for consistent hierarchy
$parents = array();
foreach ($typed_terms as $parent_info) {
$parents[$parent_info['tid']] = $parent_info['tid'];
}
$tids = array();
$tids[$tid] = $tid;
if (!taxonomy_manager_check_circular_hierarchy($tids, $parents)) {
$msg = t('Invalid parent. The resulting hierarchy would contain circles, which is not allowed. A term cannot be a parent of itself.');
$is_error_msg = TRUE;
}
}
}
else if ($op == 'add' && $attr_type == 'translation') {
$regexp = '%(?:^|,\ *)("(?>[^"]*)(?>""[^"]* )*"|(?: [^",]*))%x';
preg_match_all($regexp, $values, $matches);
$translation_terms = array_unique($matches[1]);
if (count($translation_terms) > 1) {
$msg = t('Please provide only one term for translation');
$is_error_msg = TRUE;
}
else if ($param['edit-term-data-translations-op-lang'] == $param['edit-term-data-language']) {
$msg = t('Invalid language selection');
$is_error_msg = TRUE;
}
else if (empty($param['edit-term-data-translations-op-lang'])) {
$msg = t('Missing language for new term');
$is_error_msg = TRUE;
}
else {
$translations = i18ntaxonomy_term_get_translations(array('tid' => $tid), FALSE);
foreach ($translations as $translation) {
if ($translation->language == $param['edit-term-data-translations-op-lang']) {
$msg = t('Invalid language selection. Translation already exists');
$is_error_msg = TRUE;
break;
}
}
}
}
else if ($attr_type == "language") {
$translations = i18ntaxonomy_term_get_translations(array('tid' => $tid), FALSE);
foreach ($translations as $translation) {
if ($translation->language == $values) {
$msg = t('Invalid language selection.');
$is_error_msg = TRUE;
break;
}
}
}
if (!$is_error_msg) {
if ($op == 'add') {
if ($attr_type == 'synonym') {
$regexp = '%(?:^|,\ *)("(?>[^"]*)(?>""[^"]* )*"|(?: [^",]*))%x';
preg_match_all($regexp, $values, $matches);
$synonyms = array_unique($matches[1]);
$values = array();
foreach ($synonyms as $syn) {
$values[] = trim($syn);
}
}
else {
$typed_term_tids = array();
if ($attr_type == "translation") {
$typed_term_tids = taxonomy_manager_autocomplete_tags_get_tids($values, $vid, TRUE, $param['edit-term-data-translations-op-lang']);
}
else {
$typed_term_tids = taxonomy_manager_autocomplete_tags_get_tids($values, $vid, TRUE, $param['edit-term-data-language']);
}
$values = array();
foreach ($typed_term_tids as $term_info) {
$values[] = $term_info['tid'];
}
}
}
switch ($attr_type) {
case 'parent':
if (!is_array($values)) $values = array($values);
foreach ($values as $value) {
db_query("DELETE FROM {term_hierarchy} WHERE parent = %d AND tid = %d", $value, $tid);
if ($op == 'add') {
db_query("INSERT INTO {term_hierarchy} (parent, tid) VALUES (%d, %d)", $value, $tid);
}
}
if ($op == 'delete') {
$parents = taxonomy_get_parents($tid);
if (count($parents) == 0) {
//ensure that a term has a least parent 0
db_query("DELETE FROM {term_hierarchy} WHERE parent = 0 AND tid = %d", $tid);
db_query("INSERT INTO {term_hierarchy} (parent, tid) VALUES (0, %d)", $tid);
}
}
else if ($op == 'add') {
db_query("DELETE FROM {term_hierarchy} WHERE parent = 0 AND tid = %d", $tid);
}
taxonomy_manager_update_voc($vid, taxonomy_get_parents($tid));
$msg = t("Successfully updated parents");
break;
case 'related':
if (!is_array($values)) $values = array($values);
foreach ($values as $value) {
if ($value != 0) {
db_query("DELETE FROM {term_relation} WHERE tid1 = %d AND tid2 = %d", $tid, $value);
// db_query("DELETE FROM {term_relation} WHERE tid2 = %d AND tid1 = %d", $tid, $value);
if ($op == 'add') {
db_query('INSERT INTO {term_relation} (tid1, tid2) VALUES (%d, %d)', $tid, $value);
}
}
}
$msg = t("Successfully updated related terms");
break;
case 'synonym':
if (!is_array($values)) $values = array($values);
foreach ($values as $value) {
db_query("DELETE FROM {term_synonym} WHERE tid = %d AND name = '%s'", $tid, $value);
if ($op == 'add') {
db_query("INSERT INTO {term_synonym} (tid, name) VALUES (%d, '%s')", $tid, $value);
}
}
$msg = t("Successfully updated synonyms");
break;
case 'weight':
if (is_numeric($values)) {
db_query("UPDATE {term_data} SET weight = %d WHERE tid = %d", $values, $tid);
$msg = t("Successfully updated weight to !weight", array('!weight' => $values));
}
break;
case 'language':
if (module_exists('i18ntaxonomy')) {
_i18ntaxonomy_term_set_lang($tid, $values);
$msg = t("Successfully updated language");
}
else {
$is_error_msg = TRUE;
$msg = t("Module i18ntaxonomy not enabled");
}
break;
case 'translation':
if (module_exists('i18ntaxonomy')) {
if ($op == "add") {
taxonomy_manager_add_translation($tid, $values[0]);
$msg = t("Successfully added translation");
}
else if ($op == "delete") {
db_query('UPDATE {term_data} SET trid = 0 WHERE tid = %d', $values);
if (count(i18ntaxonomy_term_get_translations(array('tid' => $tid), FALSE)) == 0) {
db_query('UPDATE {term_data} SET trid = 0 WHERE tid = %d', $tid);
}
$msg = t("Successfully removed translation");
}
}
else {
$is_error_msg = TRUE;
$msg = t("Module i18ntaxonomy not enabled");
}
break;
}
$term = (array) taxonomy_get_term($tid);
$term['fields'] = $param['term_data']['fields'];
module_invoke_all('taxonomy', 'update', 'term', $term);
module_invoke_all('taxonomy_manager_term_data_submit', $param, $values);
}
drupal_json(array('data' => taxonomy_manager_update_term_data_form($vid, $tid, TRUE, FALSE, $msg, $is_error_msg)));
//taxonomy_manager_update_term_data_form($vid, $tid, TRUE);
exit;
}
/**
* AJAX Callback for Double Tree operations
*/
function taxonomy_manager_double_tree_edit() {
$params = $_POST;
$op = $params['op'];
$msg = "";
$is_error_msg = FALSE;
if ($op == "move") {
taxonomy_manager_double_tree_edit_move($params, $msg, $is_error_msg);
}
else if ($op == "translation") {
taxonomy_manager_doube_tree_edit_translate($params, $msg, $is_error_msg);
}
else if ($op == "switch") {
taxonomy_manager_double_tree_edit_switch($params, $msg, $is_error_msg);
}
if ($msg == "") {
$msg = t("Invalid operation.");
$is_error_msg = TRUE;
}
$msg_type = ($is_error_msg) ? "error" : "status";
drupal_json(array('data' => $msg, 'type' => $msg_type));
}
function taxonomy_manager_double_tree_edit_move($params, &$msg, &$is_error_msg) {
$selected_terms = $params['selected_terms'];
$selected_parents = $params['selected_parents'];
if (!is_array($selected_terms) || !count($selected_terms)) {
$msg = t("No terms selected.");
$is_error_msg = TRUE;
return;
}
$selected_terms_names = array();
foreach ($selected_terms as $tid) {
$term = taxonomy_get_term($tid);
$vid = $term->vid;
$selected_terms_names[] = $term->name;
}
if (is_array($selected_parents) && count($selected_parents)) {
$p_array = array();
foreach ($selected_parents as $parent) {
$p_array[$parent]['tid'] = $parent;
}
if(!taxonomy_manager_check_language($vid, $selected_terms, $p_array)) {
$msg = t("Terms must be of the same language.");
$is_error_msg = TRUE;
return;
}
else if (!taxonomy_manager_check_circular_hierarchy($selected_terms, $selected_parents)) {
$msg = t('Invalid parent. The resulting hierarchy would contain circles, which is not allowed. A term cannot be a parent of itself.');
$is_error_msg = TRUE;
return;
}
}
foreach ($selected_terms as $tid) {
//reset all parents, except the direct parent in the tree
$term_parents = taxonomy_get_parents($tid);
$term_parents_array = array();
$direct_parent = is_numeric($params['selected_terms_parent'][$tid]) ? $params['selected_terms_parent'][$tid] : 0;
foreach ($term_parents as $term_parent) {
if ($direct_parent != $term_parent->tid) {
$term_parents_array[$term_parent->tid] = $term_parent->tid;
}
}
$selected_parent_names = array();
if (count($selected_parents)) {
foreach ($selected_parents as $parent) {
$term = taxonomy_get_term($parent);
$selected_parent_names[] = $term->name;
$term_parents_array[$term->tid] = $term->tid;
}
}
if (count($term_parents_array) == 0) {
$term_parents_array[0] = 0;
}
taxonomy_manager_move($term_parents_array, array($tid), array('keep_old_parents' => FALSE));
taxonomy_manager_update_voc($vid, $term_parents_array);
}
$term_names = implode(', ', $selected_terms_names);
if (count($selected_parents) == 0) {
$msg = t("Removed current parent form terms %terms.", array('%terms' => $term_names));
}
else {
$msg = t("Terms %terms moved to parents %parents.", array('%terms' => $term_names, '%parents' => implode(', ', $selected_parent_names)));
}
$is_error_msg = FALSE;
}
function taxonomy_manager_doube_tree_edit_translate($params, &$msg, &$is_error_msg) {
$term1 = taxonomy_get_term(array_pop($params['selected_terms']));
$term2 = taxonomy_get_term(array_pop($params['selected_parents']));
$vid = $term1->vid;
if (module_exists('i18ntaxonomy')) {
if (i18ntaxonomy_vocabulary($vid) == I18N_TAXONOMY_TRANSLATE) {
if ($term1->language == $term2->language) {
$msg = t("Selected terms are of the same language.");
$is_error_msg = TRUE;
}
else {
$translations = i18ntaxonomy_term_get_translations(array('tid' => $term1->tid), FALSE);
foreach ($translations as $translation) {
if ($translation->language == $term2->language) {
$msg = t('Translation for this language already exists.');
$is_error_msg = TRUE;
break;
}
}
$translations = i18ntaxonomy_term_get_translations(array('tid' => $term2->tid), FALSE);
foreach ($translations as $translation) {
if ($translation->language == $term1->language) {
$msg = t('Translation for this language already exists.');
$is_error_msg = TRUE;
break;
}
}
}
}
else {
$msg = t("This is not a multilingual vocabulary.");
$is_error_msg = TRUE;
}
}
else {
$msg = t("Module i18ntaxonomy not enabled.");
$is_error_msg = TRUE;
}
if (!$is_error_msg) {
taxonomy_manager_add_translation($term1->tid, $term2->tid);
$msg = t("Translation for %term2 - %term1 added.", array('%term2' => $term2->name, '%term1' => $term1->name));
}
}
function taxonomy_manager_double_tree_edit_switch($params, &$msg, &$is_error_msg) {
$selected_terms = $params['selected_terms'];
$selected_parents = $params['selected_parents'];
$voc1 = taxonomy_vocabulary_load($params['voc1']);
$voc2 = taxonomy_vocabulary_load($params['voc2']);
taxonomy_manager_switch($selected_terms, $voc1->vid, $voc2->vid, $selected_parents);
$selected_terms_names = array();
foreach ($selected_terms as $tid) {
$term = taxonomy_get_term($tid);
$selected_terms_names[] = $term->name;
}
$selected_parent_names = array();
if (count($selected_parents)) {
foreach ($selected_parents as $parent) {
$term = taxonomy_get_term($parent);
$selected_parent_names[] = $term->name;
$term_parents_array[$term->tid] = $term->tid;
}
}
$term_names = implode(', ', $selected_terms_names);
if (count($selected_parents) == 0) {
$msg = t("Terms %terms moved to vocabulary %voc.", array('%terms' => $term_names, '%voc' => $voc2->name));
}
else {
$msg = t("Terms %terms moved to vocabulary %voc under parents %parents.", array('%terms' => $term_names, '%voc' => $voc2->name, '%parents' => implode(', ', $selected_parent_names)));
}
$is_error_msg = FALSE;
}
/**
* adds translation between two terms
*/
function taxonomy_manager_add_translation($tid1, $tid2) {
$trid1 = db_result(db_query("SELECT trid FROM {term_data} WHERE tid = %d", $tid1));
$trid2 = db_result(db_query("SELECT trid FROM {term_data} WHERE tid = %d", $tid2));
if ($trid1 == 0 && $trid2 == 0) {
$trid = ((int)db_result(db_query('SELECT max(trid) FROM {term_data}'))) + 1;
db_query('UPDATE {term_data} SET trid = %d WHERE tid = %d OR tid = %d', $trid, $tid1, $tid2);
}
else if ($trid1 != 0 && $trid2 == 0) {
db_query('UPDATE {term_data} SET trid = %d WHERE tid = %d', $trid1, $tid2);
}
else if ($trid2 != 0 && $trid1 == 0) {
db_query('UPDATE {term_data} SET trid = %d WHERE tid = %d', $trid2, $tid1);
}
else {
$trid = max($trid1, $trid2);
db_query('UPDATE {term_data} SET trid = %d WHERE trid = %d OR trid = %d', $trid, $trid1, $trid2);
}
}
/**
* Changes vocabulary of given terms and its children
* conflicts might be possible with multi-parent terms!
*/
function taxonomy_manager_switch($tids, $from_voc, $to_voc, $parents = array()) {
foreach ($tids as $tid) {
//hook to inform modules about the changes
module_invoke_all('taxonomy_manager_term', 'switch', $tid, $from_voc, $to_voc);
$children = taxonomy_get_tree($from_voc, $tid);
$place_holder = array();
$terms_to_switch = array();
foreach ($children as $child) {
$placeholder[] = '%d';
$terms_to_switch[] = $child->tid;
}
$placeholder[] = '%d';
$terms_to_switch[] = $tid;
db_query("UPDATE {term_data} SET vid = %d WHERE tid IN (". implode(', ', $placeholder) .")", array_merge(array($to_voc), $terms_to_switch));
//delete references to parents from the old voc
foreach ($children as $child) {
$term_parents = taxonomy_get_parents($child->tid);
foreach ($term_parents as $term_parent) {
if ($term_parent->vid != $to_voc) {
db_query("DELETE FROM {term_hierarchy} WHERE tid = %d AND parent = %d", $child->tid, $term_parent->tid);
}
}
}
//set parent of the selected term
if (!count($parents)) {
$parents[0] = 0;
}
taxonomy_manager_move($parents, array($tid));
taxonomy_manager_update_voc($to_voc, $parents);
}
}
/**
* checks if voc has terms
*
* @param $vid voc id
* @return true, if terms already exists, else false
*/
function _taxonomy_manager_voc_is_empty($vid) {
$count = db_result(db_query_range("SELECT t.* FROM {term_data} t INNER JOIN {term_hierarchy} h ON t.tid = h.tid WHERE vid = %d AND h.parent = 0", $vid, 0, 1));
if ($count == 0) {
return TRUE;
}
return FALSE;
}
/**
* deletes terms from the database
* optional orphans (terms where parent get deleted) can be deleted as well
*
* (difference to taxonomy_del_term: deletion of orphans optional)
*
* @param $tids array of term id to delete
* @param $options associative array with options
* if $options['delete_orphans'] is true, orphans get deleted
*/
function taxonomy_manager_delete_terms($tids, $options = array()) {
if (!is_array($tids)) array($tids);
while (count($tids) > 0) {
$orphans = array();
foreach ($tids as $tid) {
if ($children = taxonomy_get_children($tid)) {
foreach ($children as $child) {
$parents = taxonomy_get_parents($child->tid);
if ($options['delete_orphans']) {
if (count($parents) == 1) {
$orphans[] = $child->tid;
}
}
else {
db_query("DELETE FROM {term_hierarchy} WHERE tid = %d AND parent = %d", $child->tid, $tid);
if (count($parents) == 1) {
if (!db_result(db_query("SELECT COUNT(*) FROM {term_hierarchy} WHERE tid = %d AND parent = 0", $child->tid))) {
db_query("INSERT INTO {term_hierarchy} (parent, tid) VALUES(0, %d)", $child->tid);
}
}
}
}
}
$term = (array) taxonomy_get_term($tid);
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);
module_invoke_all('taxonomy', 'delete', 'term', $term);
$tids = $orphans;
}
}
}
/**
* moves terms in hierarchies to other parents
*
* @param $parents
* array of parent term ids to where children can be moved
* array should only contain more parents if multi hiearchy enabled
* if array contains 0, terms get placed to first (root) level
* @param $children
* array of term ids to move
* @param $options
* array of additional options for moving
* 'keep_old_parents': if true, exisiting parents doesn't get deleted (only possible with multi hierarchies)
*/
function taxonomy_manager_move($parents, $children, $options = array()) {
if (!is_array($parents)) array($parents);
foreach ($children as $child) {
if (!$options['keep_old_parents']) {
db_query("DELETE FROM {term_hierarchy} WHERE tid = %d", $child);
}
foreach ($parents as $parent) {
db_query("DELETE FROM {term_hierarchy} WHERE parent = %d AND tid = %d", $parent, $child); //prevent duplicated sql errors
db_query("INSERT INTO {term_hierarchy} (parent, tid) VALUES (%d, %d)", $parent, $child);
}
}
}
/**
* merges terms into another term (main term), all merged term get added
* to the main term as synonyms.
* term_node relations are updated automatically (node with one of merging terms gets main term assigned)
* after all opterions are done (adding of hierarchies, relations is optional) merging
* terms get deleted
*
* @param $main_term
* id of term where other terms get merged into
* @param $merging_terms
* array of term ids, which get merged into main term and afterwards deleted
* @param $options
* array with additional options, possible values:
* 'collect_parents': if true, all parents of merging terms get added to main term (only possible with multi hierarchies)
* 'collect_children': if true, all children of merging terms get added to main term
* 'collect_relations': if true, all relations of merging terms are transfered to main term
*/
function taxonomy_manager_merge($main_term, $merging_terms, $options = array(), $new_inserted = TRUE) {
$vid = db_result(db_query("SELECT vid FROM {term_data} WHERE tid = %d", $main_term));
$voc = taxonomy_vocabulary_load($vid);
$merging_terms_parents = array();
foreach ($merging_terms as $merge_term) {
if ($merge_term != $main_term) {
//hook, to inform other modules about the changes
module_invoke_all('taxonomy_manager_term', 'merge', $main_term, $merge_term);
//update node-relations
$sql = db_query("SELECT * FROM {term_node} WHERE tid = %d", $merge_term);
while ($obj = db_fetch_object($sql)) {
db_query("DELETE FROM {term_node} WHERE tid = %d AND vid = %d", $obj->tid, $obj->vid);
if (!db_result(db_query("SELECT COUNT(*) FROM {term_node} WHERE tid = %d AND vid = %d", $main_term, $obj->vid))) {
$obj->tid = $main_term;
drupal_write_record('term_node', $obj);
}
}
if ($options['collect_parents']) {
$parents = taxonomy_get_parents($merge_term);
foreach ($parents as $parent_tid => $parent_term) {
$merging_terms_parents[$parent_tid] = $parent_tid;
if (!db_result(db_query("SELECT COUNT(*) FROM {term_hierarchy} WHERE tid = %d AND parent = %d", $main_term, $parent_tid))) {
db_query("INSERT INTO {term_hierarchy} (tid, parent) VALUES (%d, %d)", $main_term, $parent_tid);
}
}
}
if ($options['collect_children']) {
$children = taxonomy_get_children($merge_term);
foreach ($children as $child_tid => $child_term) {
if (!db_result(db_query("SELECT COUNT(*) FROM {term_hierarchy} WHERE tid = %d AND parent = %d", $child_tid, $main_term))) {
db_query("INSERT INTO {term_hierarchy} (tid, parent) VALUES (%d, %d)", $child_tid, $main_term);
}
}
}
if ($options['collect_relations']) {
$relations = taxonomy_get_related($merge_term);
foreach ($relations as $related_tid => $relation) {
if ($relation->tid1 == $merge_term) {
if (!db_result(db_query("SELECT COUNT(*) FROM {term_relation} WHERE tid1 = %d AND tid2 = %d", $main_term, $related_tid))) {
db_query("INSERT INTO {term_relation} (tid1, tid2) VALUES (%d, %d)", $main_term, $related_tid);
}
}
else if ($relation->tid2 == $merge_term) {
if (!db_result(db_query("SELECT COUNT(*) FROM {term_relation} WHERE tid2 = %d AND tid1 = %d", $main_term, $related_tid))) {
db_query("INSERT INTO {term_relation} (tid2, tid1) VALUES (%d, %d)", $main_term, $related_tid);
}
}
}
}
//save merged term (and synonomys of merged term) as synonym
$term = taxonomy_get_term($merge_term);
$merge_term_synonyms = taxonomy_get_synonyms($merge_term);
$merge_term_synonyms[] = $term->name;
foreach ($merge_term_synonyms as $syn) {
if (!db_result(db_query("SELECT COUNT(*) FROM {term_synonym} WHERE tid = %d AND name = '%s'", $main_term, $syn))) {
db_query("INSERT INTO {term_synonym} (tid, name) VALUES (%d, '%s')", $main_term, $syn);
}
}
taxonomy_manager_delete_terms(array($merge_term));
}
}
taxonomy_manager_update_voc($vid, $merging_terms_parents);
if ($options['collect_parents'] && (db_result(db_query("SELECT COUNT(*) FROM {term_hierarchy} WHERE tid = %d", $main_term)) > 1)) {
db_query("DELETE FROM {term_hierarchy} WHERE parent = 0 AND tid = %d", $main_term);
}
taxonomy_manager_merge_history_update($main_term, $merging_terms);
}
/**
* inserts merging information (main_tid - merged_tid ) into taxonomy_manager_merge
* and updates cache, which is used to reconstructs taxonomy/term pages
*
* @param $main_tid term if of main term
* @param $merged_tids array of merged term ids
*/
function taxonomy_manager_merge_history_update($main_tid, $merged_tids) {
if (!is_array($merged_tids)) (array) $merged_tids;
foreach ($merged_tids as $merged_tid) {
if ($merged_tid != $main_tid) {
//check if merged term has been a main term once before
$check_merged = db_result(db_query("SELECT COUNT(*) FROM {taxonomy_manager_merge} WHERE main_tid = %d", $merged_tid));
if ($check_merged) {
db_query("UPDATE {taxonomy_manager_merge} SET main_tid = %d WHERE main_tid = %d", $main_tid, $merged_tid);
}
//insert into merging history
db_query("INSERT INTO {taxonomy_manager_merge} (main_tid, merged_tid) VALUES (%d, %d)", $main_tid, $merged_tid);
}
}
taxonomy_manager_merge_history_update_cache();
}
/**
* helper function for getting out of term ids from autocomplete fields
* non-exsiting terms get inserted autmatically
* the input gets parsed for term names, optional a term id can be directly passed with prefixing the input with 'term-id:'
*
* @param $typed_input input string of form field
* @param $vid vocabulary id
* @param $insert_new TRUE if non-existing terms should be inserted
* @param $lang define the language (optional)
* @return array of term ids
*/
function taxonomy_manager_autocomplete_tags_get_tids($typed_input, $vid, $insert_new = TRUE, $lang = NULL) {
$tids = array();
$regexp = '%(?:^|,\ *)("(?>[^"]*)(?>""[^"]* )*"|(?: [^",]*))%x';
preg_match_all($regexp, $typed_input, $matches);
$typed_terms = array_unique($matches[1]);
foreach ($typed_terms as $typed_term) {
$typed_term = str_replace('""', '"', preg_replace('/^"(.*)"$/', '\1', $typed_term));
$typed_term = trim($typed_term);
if ($typed_term != "") {
if (substr($typed_term, 0, 8) == "term-id:") {
$id = substr($typed_term, 8);
$term = taxonomy_get_term($id);
if ($term->vid == $vid) {
$tids[$term->tid]['tid'] = $term->tid;
}
}
else {
$possibilities = taxonomy_get_term_by_name($typed_term);
$typed_term_tid = NULL; // tid match if any.
foreach ($possibilities as $possibility) {
if ($possibility->vid == $vid && !($lang && $lang != $possibility->language)) {
$typed_term_tid = $possibility->tid;
$tids[$typed_term_tid]['tid'] = $typed_term_tid;
}
}
if (!$typed_term_tid && $insert_new) {
$edit = array('vid' => $vid, 'name' => $typed_term);
$status = taxonomy_save_term($edit);
if (module_exists('i18ntaxonomy') && $lang != "") {
_i18ntaxonomy_term_set_lang($edit['tid'], $lang);
}
$typed_term_tid = $edit['tid'];
$tids[$typed_term_tid]['tid'] = $typed_term_tid;
$tids[$typed_term_tid]['new'] = TRUE;
}
}
}
}
return $tids;
}
/**
* similar to taxonomy_manager_autocomplete_tags_get_tids, but used for searching terms
* takes synonyms and selected subtrees into account
*
* @param $typed_input input string of form field
* @param $vid vocabulary id
* @param $include_synonyms TRUE if search should include synonyms
* @param $parents array of parents
* @return array of term ids
*/
function taxonomy_manager_autocomplete_search_terms($typed_input, $vid, $include_synonyms = FALSE, $parents = array(), $language = NULL) {
$tids = array();
if ($language != NULL && $language == "no language") {
$language = "";
}
$regexp = '%(?:^|,\ *)("(?>[^"]*)(?>""[^"]* )*"|(?: [^",]*))%x';
preg_match_all($regexp, $typed_input, $matches);
$typed_terms = array_unique($matches[1]);
foreach ($typed_terms as $typed_term) {
$typed_term = str_replace('""', '"', preg_replace('/^"(.*)"$/', '\1', $typed_term));
$typed_term = trim($typed_term);
if ($typed_term == "") {
continue;
}
if ($include_synonyms) {
if ($language != NULL) {
$search_sql = db_query("SELECT td.tid FROM {term_data} td LEFT JOIN {term_synonym} ts ON td.tid = ts.tid WHERE td.vid = %d AND (td.name = '%s' OR ts.name = '%s') AND td.language = '%s'", $vid, $typed_term, $typed_term, $language);
}
else {
$search_sql = db_query("SELECT td.tid FROM {term_data} td LEFT JOIN {term_synonym} ts ON td.tid = ts.tid WHERE td.vid = %d AND (td.name = '%s' OR ts.name = '%s')", $vid, $typed_term, $typed_term);
}
}
else {
if ($language != NULL) {
$search_sql = db_query("SELECT td.tid FROM {term_data} td WHERE td.vid = %d AND td.name = '%s' AND td.language = '%s'", $vid, $typed_term, $language);
}
else {
$search_sql = db_query("SELECT td.tid FROM {term_data} td WHERE td.vid = %d AND td.name = '%s'", $vid, $typed_term);
}
}
while ($obj = db_fetch_object($search_sql)) {
$tids[] = $obj->tid;
}
if (count($parents)) {
$filtered_tids = array();
foreach ($tids as $tid) {
$parents_all = taxonomy_get_parents_all($tid);
foreach ($parents_all as $key => $parent) {
if (in_array($parent->tid, $parents)) {
$filtered_tids[] = $tid;
break;
}
}
}
$tids = $filtered_tids;
}
}
return $tids;
}
/**
* callback for updating weights
* data send through AJAX, $_POST
* $_POST[$tid] => $weight
*
*/
function taxonomy_manager_update_weights() {
$weights = $_POST;
if (is_array($weights)) {
foreach ($weights as $tid => $weight) {
if (is_numeric($tid) && is_numeric($weight)) {
db_query("UPDATE {term_data} SET weight = %d WHERE tid = %d", $weight, $tid);
}
}
}
exit();
}
/**
* AJAX Callback that returns the CSV Output
*/
function taxonomy_manager_export() {
$edit = $_POST;
$depth = empty($edit['depth']) ? NULL : $edit['depth'];
$output = taxonomy_manager_export_csv($edit['delimiter'], $edit['vid'], $edit['tid'], $depth, array($edit['option'] => TRUE));
print $output;
exit();
}
/**
* Generates the CVS Ouput
*/
function taxonomy_manager_export_csv($delimiter = ";", $vid, $selected_tid = 0, $depth = NULL, $options = array()) {
$tree = taxonomy_manager_export_get_tree($vid, $selected_tid, $depth, $options);
foreach ($tree as $term) {
$array = array();
$array[] = '"'. $term->vid .'"';
$array[] = '"'. $term->tid .'"';
$array[] = '"'. $term->name .'"';
$array[] = '"'. $term->description .'"';
foreach ($term->parents as $parent) {
$array[] = '"'. $parent .'"';
}
$output .= implode($delimiter, $array) ."\n";
}
return $output;
}
/**
* Helper for cvs export to get taxonomy tree
*/
function taxonomy_manager_export_get_tree($vid, $selected_tid, $depth, $options) {
$tree = array();
if ($options['whole_voc']) {
$tree = taxonomy_get_tree($vid, 0, -1, $depth);
}
else if ($options['children'] && $selected_tid) {
$tree = taxonomy_get_tree($vid, $selected_tid, -1, $depth);
}
else if ($options['root_terms']) {
$tree = taxonomy_get_tree($vid, 0, -1, 1);
}
return $tree;
}
/**
* Helper function that updates the hierarchy settings of a voc
*/
function taxonomy_manager_update_voc($vid, $parents = array()) {
$voc = (array) taxonomy_vocabulary_load($vid);
if ($voc->vid == $vid) {
$current_hierarchy = count($parents);
if ($current_hierarchy > 2) {
$current_hierarchy = 2;
}
if ($current_hierarchy > $voc['hierarchy']) {
$voc['hierarchy'] = $current_hierarchy;
taxonomy_save_vocabulary($voc);
}
}
}
/**
* Retrieve a pipe delimited string of autocomplete suggestions (+synonyms)
*/
function taxonomy_manager_autocomplete_load($vid, $string = '') {
// The user enters a comma-separated list of tags. We only autocomplete the last tag.
$array = drupal_explode_tags($string);
// Fetch last tag
$last_string = trim(array_pop($array));
$matches = array();
if ($last_string != '') {
$result = db_query_range("SELECT t.name FROM {term_data} t
LEFT JOIN {term_synonym} s ON t.tid = s.tid
WHERE t.vid = %d
AND (LOWER(t.name) LIKE LOWER('%%%s%%') OR LOWER(s.name) LIKE LOWER('%%%s%%'))",
$vid, $last_string, $last_string, 0, 30);
$prefix = count($array) ? '"'. implode('", "', $array) .'", ' : '';
while ($tag = db_fetch_object($result)) {
$n = $tag->name;
// Commas and quotes in terms are special cases, so encode 'em.
if (strpos($tag->name, ',') !== FALSE || strpos($tag->name, '"') !== FALSE) {
$n = '"'. str_replace('"', '""', $tag->name) .'"';
}
$matches[$prefix . $n] = check_plain($tag->name);
}
}
drupal_json($matches);
}
/**
* theme function for taxonomy manager form
*/
function theme_taxonomy_manager_form($form) {
$pager = theme('pager', NULL, TAXONOMY_MANAGER_TREE_PAGE_SIZE, 0);
$tree = drupal_render($form['taxonomy']);
$term_data = drupal_render($form['term_data']);
$top = drupal_render($form);
$output = $top . $pager;
$output .= '