'; $vocabularies = taxonomy_get_vocabularies(); $voc_list = array(); foreach ($vocabularies as $vocabulary) { $voc_list[] = l($vocabulary->name, 'admin/content/taxonomy_manager/voc/'. $vocabulary->vid); } if (!count($voc_list)) { $voc_list[] = t('No Vocabularies available'); } $output .= theme('item_list', $voc_list, t("Vocabularies:")); return $output; } /** * defines forms for taxonomy manager interface * * @param $vid vocabulary id * @param $tid a term id, if not 0, displays term editing from for given tid on right side * @param $search_string a string to filter root level terms */ function taxonomy_manager_form(&$form_state, $vid, $tid = 0, $filter = NULL) { // Check for confirmation forms. if (isset($form_state['confirm_delete'])) { return taxonomy_manager_term_confirm_delete($form_state, $vid); } $module_path = drupal_get_path('module', 'taxonomy_manager') .'/'; drupal_add_css($module_path .'css/taxonomy_manager.css'); drupal_add_js($module_path .'js/hideForm.js'); drupal_add_js($module_path .'js/updateWeight.js'); drupal_add_js($module_path .'js/termData.js'); drupal_add_js(array('termData' => array('url' => url("admin/content/taxonomy_manager/termdata/edit/". $vid), 'tid' => $tid, 'term_url' => url('admin/content/taxonomy_manager/termdata/'. $vid))), 'setting'); //TODO check if values necessary and correct drupal_add_js(array('updateWeight' => array('up' => 'edit-weight-up', 'down' => 'edit-weight-down', 'url' => url('admin/content/taxonomy_manager/weight/'), 'disable_mouseover' => variable_get('taxonomy_manager_disable_mouseover', 0))), 'setting'); drupal_add_js(array('TMAjaxThrobber' => array('add' => TRUE)), 'setting'); drupal_add_js(array('taxonomy_manager' => array('modulePath' => (url($module_path) == $module_path) ? $module_path : (base_path() . $module_path))), 'setting'); $form = array(); $voc = taxonomy_vocabulary_load($vid); drupal_set_title(t("Taxonomy Manager - %voc_name", array("%voc_name" => $voc->name))); if (!is_numeric($voc->vid)) { $text = t('No vocabulary with this ID available! Check this list for available vocabularies or create a new one', array('!list' => url('admin/content/taxonomy_manager'), '!create' => url('admin/content/taxonomy/add/vocabulary'))); $form['text'] = array( '#value' => $text, ); return $form; } $form['vid'] = array('#type' => 'value', "#value" => $vid); if (_taxonomy_manager_voc_is_empty($vid)) { $text = t('No terms available'); $form['text'] = array( '#value' => $text, ); $form += taxonomy_manager_add_form($voc, FALSE); return $form; } $form['#cache'] = TRUE; $form['taxonomy']['#tree'] = TRUE; $form['taxonomy']['manager'] = array( '#type' => 'fieldset', '#title' => check_plain($voc->name), '#weight' => 10, '#tree' => TRUE, ); $form['taxonomy']['manager']['top'] = array( '#value' => '', '#prefix' => '
', '#suffix' => '
', ); if (module_exists('i18ntaxonomy')) { if (i18ntaxonomy_vocabulary($vid) == I18N_TAXONOMY_TRANSLATE) { if ($tid) { $language = _taxonomy_manager_term_get_lang($tid); } else { $lang = language_default(); $language = $lang->language; } $form['taxonomy']['manager']['top']['language'] = array( '#type' => 'select', '#title' => t('Language'), '#default_value' => $language, '#options' => array('' => t('All'), 'no language' => t('no language')) + locale_language_list('name'), '#attributes' => array('class' => 'language-selector'), ); } } $form['taxonomy']['manager']['top']['size'] = array('#value' => '
'. theme("image", $module_path ."images/grippie.png", t("Resize tree"), t("Resize tree"), array('class' => "div-grippie")) .'
'); $form['taxonomy']['manager']['tree'] = array( '#type' => 'taxonomy_manager_tree', '#vid' => $vid, '#pager' => TRUE, '#search_string' => ($tid) ? NULL : $filter, '#language' => isset($language) ? $language : '', '#term_to_expand' => $tid, ); $search_description = t("You can search directly for exisiting terms. If your input doesn't match an existing term, it will be used for filtering root level terms (useful for non-hierarchical vocabularies)."); $form['search'] = array( '#type' => 'fieldset', '#attributes' => array('id' => 'taxonomy-manager-search'), '#title' => t('Search'), '#description' => $search_description, '#collapsible' => TRUE, '#collapsed' => TRUE, '#tree' => TRUE, ); $form['search']['field'] = array( '#type' => 'textfield', '#title' => t('Search String'), '#autocomplete_path' => 'taxonomy_manager/autocomplete/'. $voc->vid, '#prefix' => '
', '#suffix' => '
', ); $form['search']['button'] = array( '#type' => 'submit', '#attributes' => array('class' => 'taxonomy-manager-buttons search'), '#value' => t('Search'), '#suffix' => '
', ); $search_options = array( 'synonyms' => t('Include synonyms'), 'subtrees' => t('Search under selected terms'), ); if (module_exists('i18ntaxonomy')) { if (i18ntaxonomy_vocabulary($vid) == I18N_TAXONOMY_TRANSLATE) { $search_options['language'] = t('Search within selected language'); } } $form['search']['options'] = array( '#type' => 'checkboxes', '#title' => t('Search options'), '#options' => $search_options, ); $form['toolbar'] = array( '#type' => 'fieldset', '#title' => t('Toolbar'), '#attributes' => array('id' => 'taxonomy-manager-toolbar'), ); $form['toolbar']['weight_up'] = array( '#type' => 'button', '#attributes' => array('class' => 'taxonomy-manager-buttons'), '#value' => t('Up'), '#theme' => 'no_submit_button', '#prefix' => '
', ); $form['toolbar']['weight-down'] = array( '#type' => 'button', '#attributes' => array('class' => 'taxonomy-manager-buttons'), '#value' => t('Down'), '#theme' => 'no_submit_button', ); $form['toolbar']['delete_confirm'] = array( '#type' => 'button', '#attributes' => array('class' => 'taxonomy-manager-buttons delete'), '#value' => t('Delete'), '#theme' => 'no_submit_button', /*'#ahah' => array( 'path' => 'admin/content/taxonomy_manager/toolbar/form', 'method' => 'replace', 'event' => 'click', 'wrapper' => 'taxonomy-manager-toolbar-forms', 'progress' => array(), ),*/ ); $form['toolbar']['add_show'] = array( '#type' => 'button', '#attributes' => array('class' => 'taxonomy-manager-buttons add'), '#value' => t('Add'), '#theme' => 'no_submit_button', ); $form['toolbar']['move_show'] = array( '#type' => 'button', '#value' => t('Move'), '#attributes' => array('class' => 'taxonomy-manager-buttons move'), '#theme' => 'no_submit_button', ); $form['toolbar']['merge_show'] = array( '#type' => 'button', '#attributes' => array('class' => 'taxonomy-manager-buttons merge'), '#value' => t('Merge'), '#theme' => 'no_submit_button', ); $form['toolbar']['export_show'] = array( '#type' => 'button', '#attributes' => array('class' => 'taxonomy-manager-buttons export'), '#value' => t('CSV Export'), '#theme' => 'no_submit_button', ); $form['toolbar']['double_tree_show'] = array( '#type' => 'button', '#attributes' => array('class' => 'taxonomy-manager-buttons double-tree'), '#value' => t('Double Tree'), '#theme' => 'no_submit_button', ); $form['toolbar']['wrapper'] = array( '#type' => 'markup', '#value' => '
', '#weight' => 20, '#prefix' => '
', ); $form['toolbar_forms_wrapper'] = array( '#type' => 'markup', '#value' => '
', ); $form += taxonomy_manager_add_form($voc); $form += taxonomy_manager_merge_form($voc); $form += taxonomy_manager_move_form($voc); $form += taxonomy_manager_confirm_delete($voc); $form += taxonomy_manager_export_form($voc); $form += taxonomy_manager_double_tree_settings_form($voc); if ($tid) { $form += taxonomy_manager_form_term_data($tid); } else { $form['term_data'] = array('#tree' => TRUE); } // add save button for term_data already to the form array, // but do not render (see theme_taxonomy_manager_form) if not needed // otherwise an #ahah callback on dynamically added forms makes problems $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, ); return $form; } function taxonomy_manager_double_tree_form(&$form_state, $vid1, $vid2, $tid = 0, $filter = NULL) { // Check for confirmation forms. if (isset($form_state['confirm_delete'])) { return taxonomy_manager_term_confirm_delete($form_state, $vid1, $vid2); } $module_path = drupal_get_path('module', 'taxonomy_manager') .'/'; $form = taxonomy_manager_form($form_state, $vid1, $tid, $filter); drupal_add_js(array('DoubleTree' => array('enabled' => TRUE, 'url' => url('admin/content/taxonomy_manager/double-tree/edit'))), 'setting'); drupal_add_js($module_path .'js/doubleTree.js'); $form['disable'] = array( '#value' => l(t('Disable Double Tree'), 'admin/content/taxonomy_manager/voc/'. $vid1), '#weight' => -100, ); $voc2 = taxonomy_vocabulary_load($vid2); $form['vid2'] = array('#type' => 'value', "#value" => $vid2); $form['taxonomy2'] = array( '#tree' => TRUE, ); $form['taxonomy2']['manager'] = array( '#type' => 'fieldset', '#title' => check_plain($voc2->name), '#weight' => 10, '#tree' => TRUE, ); $form['taxonomy2']['manager']['top'] = array( '#value' => '', '#prefix' => '
', '#suffix' => '
', ); if (module_exists('i18ntaxonomy')) { if (i18ntaxonomy_vocabulary($vid2) == I18N_TAXONOMY_TRANSLATE) { if ($tid) { $language = _taxonomy_manager_term_get_lang($tid); } else { $lang = language_default(); $language = $lang->language; } $form['taxonomy2']['manager']['top']['language'] = array( '#type' => 'select', '#title' => t('Language'), '#default_value' => $language, '#options' => array('' => t('All'), 'no language' => t('no language')) + locale_language_list('name'), '#attributes' => array('class' => 'language-selector'), ); } } $form['taxonomy2']['manager']['top']['size'] = array('#value' => '
'. theme("image", $module_path ."images/grippie.png", t("Resize tree"), t("Resize tree"), array('class' => "div-grippie")) .'
'); $form['taxonomy2']['manager']['tree'] = array( '#type' => 'taxonomy_manager_tree', '#vid' => $vid2, '#pager' => TRUE, '#search_string' => ($tid) ? NULL : $filter, '#language' => isset($language) ? $language : '', '#term_to_expand' => $tid, ); $form['double-tree']['operations'] = array( '#tree' => TRUE, ); $form['double-tree']['operations']['move_right'] = array( '#type' => 'image_button', '#value' => 'Move right', '#attributes' => array('title' => t('Move right')), '#src' => $module_path ."images/go-next.png", //'#executes_submit_callback' => FALSE, '#prefix' => '
', '#suffix' => '
', ); $form['double-tree']['operations']['move_left'] = array( '#type' => 'image_button', '#value' => 'Move left', '#attributes' => array('title' => t('Move left')), '#src' => $module_path ."images/go-previous.png", //'#executes_submit_callback' => FALSE, '#prefix' => '
', '#suffix' => '
', ); //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' => '
    
', '#weight' => -100, ); $form['term_data']['tid'] = array('#type' => 'hidden', '#value' => $tid); $form['term_data']['name'] = array( '#type' => 'textfield', '#title' => t('Name'), '#default_value' => $term->name, '#size' => 35, '#maxlength' => 255, '#required' => TRUE, '#weight' => -20, ); $form['term_data']['description'] = array( '#type' => 'textarea', '#title' => t('Description'), '#default_value' => $term->description, '#cols' => 35, '#rows' => 3, ); $synonyms = taxonomy_get_synonyms($term->tid); asort($synonyms); $form['term_data']['synonyms'] = _taxonomy_manager_form_term_data_lists($term, $synonyms, t('Synonyms'), 'synonym', FALSE); $form['term_data']['synonyms']['#tree'] = TRUE; $form['term_data']['synonyms']['#weight'] = '50'; $form['term_data']['relations'] = _taxonomy_manager_form_term_data_lists($term, taxonomy_get_related($term->tid), t('Relations'), 'related'); $form['term_data']['relations']['#tree'] = TRUE; $form['term_data']['relations']['#weight'] = '51'; $parents = taxonomy_get_parents($term->tid); $form['term_data']['parents'] = _taxonomy_manager_form_term_data_lists($term, $parents, t('Parents'), 'parent', TRUE); $form['term_data']['parents']['#tree'] = TRUE; $form['term_data']['parents']['#weight'] = '52'; if (module_exists('i18ntaxonomy')) { if (i18ntaxonomy_vocabulary($term->vid) == I18N_TAXONOMY_TRANSLATE) { $translations = i18ntaxonomy_term_get_translations(array('tid' => $term->tid), FALSE); $form['term_data']['translations'] = _taxonomy_manager_form_term_data_translations($term, $translations, t('Translations'), 'translation', TRUE); $form['term_data']['translations']['#tree'] = TRUE; $form['term_data']['translations']['#weight'] = '53'; $form['term_data']['language'] = array( '#type' => 'select', '#title' => t('Language'), '#default_value' => isset($term) && !empty($term->language) ? $term->language : '', '#options' => array('' => '') + locale_language_list('name'), '#description' => t('This term belongs to a multilingual vocabulary. You can set a language for it.'), '#weight' => 54, ); } } $form['term_data']['weight'] = array( '#type' => 'weight', '#default_value' => $term->weight, '#delta' => 50, '#prefix' => '
', '#suffix' => '
', '#title' => t('Weight'), '#weight' => 55, ); $link_img = theme("image", $module_path ."images/link-small.png", "link to term page"); $form['term_data']['link'] = array('#value' => '
'. l($link_img .' '. t('Go to the term page'), taxonomy_term_path($term), array('attributes' => array('rel' => 'tag', 'title' => strip_tags($term->description), 'target' => '_blank'), 'html' => TRUE)), '#weight' => '56'); $form['term_data']['vid'] = array('#type' => 'hidden', '#value' => $term->vid); return $form; } /** * helper function for generating tables with values and delete op and field for adding * * @param $term term object which is going to be displayed * @param $values array of values to show, e.g related terms, synonyms, parents, children * @param $header_type string to display as header * @param $attr attribute type to show, can be 'related', 'synonym', 'parent', 'child' * @param $autocomplete if true, adds autocomplete, else a textfield * @param $add if true, shows add operation * @return an form array */ function _taxonomy_manager_form_term_data_lists($term, $values, $header_type, $attr, $autocomplete = TRUE, $add = TRUE) { $module_path = drupal_get_path('module', 'taxonomy_manager') .'/'; $rows = array(); $form['#theme'] = 'taxonomy_manager_term_data_extra'; $form['data'] = array(); foreach ($values as $tid => $value) { if (is_object($value)) { $name = $value->name; $id = $value->tid; $vid = $value->vid; $extra_info = taxonomy_manager_tree_term_extra_info($value); } else { $name = $value; $id = $value; } $form['data'][$id][] = array( '#value' => (isset($vid) && $vid > 0) ? l($name, 'admin/content/taxonomy_manager/termdata/'. $vid ."/". $id, array('attributes' => array('title' => $extra_info, 'class' => 'taxonomy-term-data-name-link'))) : check_plain($name), '#row-class' => 'taxonomy-term-data-name', '#row-id' => 'term-'. $id, ); $form['data'][$id][] = array( '#value' => ' ', '#row-class' => 'taxonomy-term-data-operations', ); } $form['headers'][] = array('#value' => $header_type); $form['headers'][] = array('#value' => ''); $form['op'] = array(); if ($add) { $form['op']['add'] = array( '#type' => 'textfield', '#prefix' => '
', '#suffix' => '
', '#size' => 35, ); if ($autocomplete) { $form['op']['add']['#autocomplete_path'] = 'taxonomy_manager/autocomplete/'. $term->vid; } $form['op']['add_button'] = array( '#value' => ' ', '#prefix' => '
', '#suffix' => '
', ); } return $form; } /** * helper function for generating a table listing the translations */ function _taxonomy_manager_form_term_data_translations($term, $translations, $header_type, $attr, $autocomplete = TRUE, $add = TRUE) { $module_path = drupal_get_path('module', 'taxonomy_manager') .'/'; $rows = array(); $form['#theme'] = 'taxonomy_manager_term_data_extra'; $form['data'] = array(); foreach ($translations as $tid => $value) { if (is_object($value)) { $name = $value->name; $id = $value->tid; $vid = $value->vid; $lang = $value->language; $trid = $value->trid; $extra_info = taxonomy_manager_tree_term_extra_info($value); } $form['data'][$id][] = array( '#value' => (isset($vid) && $vid > 0) ? l($name, 'admin/content/taxonomy_manager/termdata/'. $vid ."/". $id, array('attributes' => array('title' => $extra_info))) : check_plain($name), '#row-class' => 'taxonomy-term-data-name', '#row-id' => 'term-'. $id, ); $form['data'][$id][] = array( '#value' => check_plain(locale_language_name($lang)), '#row-class' => 'taxonomy-term-data-lang', '#row-id' => 'term-lang-'. $id, ); $form['data'][$id][] = array( '#value' => ' ', '#row-class' => 'taxonomy-term-data-operations', ); } $form['headers'][] = array('#value' => $header_type); $form['headers'][] = array('#value' => t('Language')); $form['headers'][] = array('#value' => ''); $form['op'] = array(); if ($add) { $form['op']['add'] = array( '#type' => 'textfield', '#prefix' => '
', '#suffix' => '
', '#size' => 35, ); $form['op']['lang'] = array( '#type' => 'select', '#options' => array('' => '') + locale_language_list('name'), '#default value' => '', ); if ($autocomplete) { $form['op']['add']['#autocomplete_path'] = 'taxonomy_manager/autocomplete/'. $term->vid; } $form['op']['add_button'] = array( '#value' => ' ', '#prefix' => '
', '#suffix' => '
', ); } return $form; } /** * validates the form (only search button) **/ function taxonomy_manager_form_validate($form, &$form_state) { if ($form_state['clicked_button']['#value'] == t('Search') && empty($form_state['values']['search']['field'])) { form_set_error('search', t('Search field is empty')); $form_state['rebuild'] = TRUE; } } /** * submits the taxonomy manager form (only search button) **/ function taxonomy_manager_form_submit($form, &$form_state) { if ($form_state['values']['delete'] === TRUE) { return taxonomy_manager_term_confirm_delete_submit($form, $form_state); } if (isset($form_state['values']['vid2'])) { $url_prefix = 'admin/content/taxonomy_manager/double-tree/'. $form_state['values']['vid'] .'/'. $form_state['values']['vid2']; } else { $url_prefix = 'admin/content/taxonomy_manager/voc/'. $form_state['values']['vid']; } $search_string = $form_state['values']['search']['field']; $terms = array(); $include_synonyms = FALSE; $selected_tids = array(); if ($form_state['values']['search']['options']['synonyms']) { $include_synonyms = TRUE; } if ($form_state['values']['search']['options']['subtrees']) { $selected_tids = $form_state['values']['taxonomy']['manager']['tree']['selected_terms']; } if ($form_state['values']['search']['options']['language']) { $language = $form_state['values']['taxonomy']['manager']['top']['language']; } $terms = taxonomy_manager_autocomplete_search_terms($search_string, $form_state['values']['vid'], $include_synonyms, $selected_tids, $language); if (count($terms) == 1) { $tid = $terms[0]; drupal_set_message(t("Your search string matches exactly one term")); drupal_goto($url_prefix .'/'. $tid); } else if (count($terms) > 1) { $matched_text_list = array(); foreach ($terms as $matched_tid) { $matched_term = taxonomy_get_term($matched_tid); $parents = array(); foreach (taxonomy_get_parents($matched_tid) as $parent) { $parents[] = check_plain($parent->name); } $parent_text = count($parents) ? implode(' | ', $parents) ." › " : ""; $term = taxonomy_get_term($t['tid']); $matched_text_list[] = $parent_text ."". l($matched_term->name, $url_prefix .'/'. $matched_term->tid, array('attributes' => array('title' => taxonomy_manager_tree_term_extra_info($matched_term)))) ." (". $matched_term->tid . (!empty($matched_term->language) ? '-'. check_plain($matched_term->language) : '') . ")"; } drupal_set_message(t("Your search string matches !count terms:", array('!count' => count($terms))) ."". theme('item_list', $matched_text_list)); $form_state['rebuild'] = TRUE; } else { drupal_set_message(t("No match found. Filtering root level terms starting with @search_string.", array('@search_string' => $search_string))); drupal_set_message(l(t("Show unfiltered tree"), $url_prefix)); drupal_goto($url_prefix .'/0/'. $search_string); } } /** * validates taxonomy manager double tree **/ function taxonomy_manager_double_tree_form_validate($form, &$form_state) { return taxonomy_manager_form_validate($form, $form_state); } /** * submits the taxonomy manager double tree **/ function taxonomy_manager_double_tree_form_submit($form, &$form_state) { return taxonomy_manager_form_submit($form, $form_state); } /** * Submit handler for adding terms */ function taxonomy_manager_form_add_submit($form, &$form_state) { $terms = array(); $selected_tids = array(); $selected_tids = $form_state['values']['taxonomy']['manager']['tree']['selected_terms']; foreach ($form_state['values']['add']['term'] as $value) { if (!empty($value)) { $terms[] = $value; } } if ($form_state['values']['add']['mass']['mass_add']) { foreach (explode ("\n", str_replace("\r", '', $form_state['values']['add']['mass']['mass_add'])) as $term) { if ($term) { $terms[] = $term; } } } foreach ($terms as $name) { $term = array(); $term['name'] = $name; $term['vid'] = $form_state['values']['vid']; $term['parent'] = $selected_tids; taxonomy_save_term($term); if (module_exists('i18ntaxonomy')) { if (i18ntaxonomy_vocabulary($form_state['values']['vid']) == I18N_TAXONOMY_TRANSLATE && $form_state['values']['taxonomy']['manager']['top']['language'] != "") { _i18ntaxonomy_term_set_lang($term['tid'], $form_state['values']['taxonomy']['manager']['top']['language']); $updated_lang = TRUE; } } } taxonomy_manager_update_voc($form_state['values']['vid'], $selected_tids); if (isset($updated_lang) && $updated_lang == TRUE) { drupal_set_message(t("Saving terms to language @lang", array('@lang' => locale_language_name($form_state['values']['taxonomy']['manager']['top']['language'])))); } drupal_set_message(t("Terms added: %terms", array('%terms' => implode(', ', $terms)))); } /** * Validation handler for deleting terms */ function taxonomy_manager_form_delete_validate($form, &$form_state) { $selected_tids = array(); $selected_tids = $form_state['values']['taxonomy']['manager']['tree']['selected_terms']; if (count($selected_tids) < 1) { form_set_error('delete', t("No terms for deleting selected")); $form_state['rebuild'] = TRUE; } } /** * Submit handler for deleting terms */ function taxonomy_manager_form_delete_submit($form, &$form_state) { $selected_tids = array(); $selected_tids = $form_state['values']['taxonomy']['manager']['tree']['selected_terms']; if ($form_state['values']['delete'] === TRUE) { return taxonomy_manager_term_confirm_delete_submit($form, $form_state); } // Rebuild the form to confirm term deletion. $form_state['rebuild'] = TRUE; $form_state['confirm_delete'] = TRUE; } /** * Form builder for the term delete form. * */ function taxonomy_manager_term_confirm_delete(&$form_state, $vid, $vid2 = NULL) { if (isset($vid2)) { $form['vid2'] = array('#type' => 'value', '#value' => $vid2); $url = 'admin/content/taxonomy_manager/double-tree/'. $vid .'/'. $vid2; } else { $url = 'admin/content/taxonomy_manager/voc/'. $vid; } $selected = $form_state['values']['taxonomy']['manager']['tree']['selected_terms']; $form['selected_terms'] = array('#prefix' => '', '#tree' => TRUE); foreach ($selected as $tid) { $term = taxonomy_get_term($tid); $form['selected_terms'][$tid] = array('#type' => 'hidden', '#value' => $tid, '#prefix' => '
  • ', '#suffix' => check_plain($term->name) ."
  • \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 .= '
    '; $output .= '
    '; $output .= $tree; $output .= '
    '; $output .= '
    '; $output .= is_array($form['term_data']['tid']) ? $term_data : ''; $output .= '
    '; $output .= '
    '; return $output; } /** * theme function for taxonomy manager form */ function theme_taxonomy_manager_double_tree_form($form) { $pager = theme('pager', NULL, TAXONOMY_MANAGER_TREE_PAGE_SIZE, 0); $tree1 = drupal_render($form['taxonomy']); $tree2 = drupal_render($form['taxonomy2']); $operations = drupal_render($form['double-tree']); $term_data = drupal_render($form['term_data']); $top = drupal_render($form); $output = $top . $pager; $output .= '
    '; $output .= '
    '; $output .= $tree1; $output .= '
    '; $output .= '
    '; $output .= $operations; $output .= '
    '; $output .= '
    '; $output .= $tree2; $output .= '
    '; $output .= '
    '; $output .= is_array($form['term_data']['tid']) ? $term_data : ''; $output .= '
    '; $output .= '
    '; return $output; } /** * themes a real button form type (no form submit) */ function theme_no_submit_button($element) { // Make sure not to overwrite classes. if (isset($element['#attributes']['class'])) { $element['#attributes']['class'] = 'form-'. $element['#button_type'] .' '. $element['#attributes']['class']; } else { $element['#attributes']['class'] = 'form-'. $element['#button_type']; } return '\n"; } /** * themes a image type button */ function theme_taxonomy_manager_image_button($element) { //Make sure not to overwrite classes if (isset($element['#attributes']['class'])) { $element['#attributes']['class'] = 'form-'. $element['#button_type'] .' '. $element['#attributes']['class']; } else { $element['#attributes']['class'] = 'form-'. $element['#button_type']; } // here the novelty begins: check if #button_type is normal submit button or image button $return_string = '\n"; return $return_string; } function theme_taxonomy_manager_term_data_extra($element) { $rows = array(); $headers = array(); foreach (element_children($element['headers']) as $key) { if (is_array($element['headers'][$key])) { $headers[] = drupal_render($element['headers'][$key]); } } foreach ($element['data'] as $tid => $entries) { $row = array(); foreach (element_children($element['data'][$tid]) as $key) { if (is_array($element['data'][$tid][$key])) { $row[] = array( 'data' => drupal_render($element['data'][$tid][$key]), 'class' => $element['data'][$tid][$key]['#row-class'], 'id' => $element['data'][$tid][$key]['#row-id'], ); } } $rows[] = $row; } $row = array(); foreach (element_children($element['op']) as $key) { if (is_array($element['op'][$key])) { $row[] = drupal_render($element['op'][$key]); } } $rows[] = $row; return theme('table', $headers, $rows); }