taxonomy_manager.module in Taxonomy Manager 6.2
Same filename and directory in other branches
Taxonomy Manager
Administration interface for managing taxonomy vocabularies
File
taxonomy_manager.moduleView source
<?php
/**
*
* @file
* Taxonomy Manager
*
* Administration interface for managing taxonomy vocabularies
*
*/
/**
* Implementation of hook_menu
*/
function taxonomy_manager_menu() {
$items['admin/content/taxonomy_manager'] = array(
'title' => 'Taxonomy Manager',
'description' => 'Administer vocabularies with the Taxonomy Manager',
'page callback' => 'taxonomy_manager_voc_list',
'access arguments' => array(
'administer taxonomy',
),
'type' => MENU_NORMAL_ITEM,
'file' => 'taxonomy_manager.admin.inc',
);
$items['admin/content/taxonomy_manager/childform'] = array(
'page callback' => 'taxonomy_manager_tree_build_child_form',
'access arguments' => array(
'administer taxonomy',
),
'type' => MENU_CALLBACK,
);
$items['admin/content/taxonomy_manager/weight'] = array(
'page callback' => 'taxonomy_manager_update_weights',
'access arguments' => array(
'administer taxonomy',
),
'type' => MENU_CALLBACK,
'file' => 'taxonomy_manager.admin.inc',
);
$items['admin/content/taxonomy_manager/termdata'] = array(
'page callback' => 'taxonomy_manager_update_term_data_form',
'access arguments' => array(
'administer taxonomy',
),
'type' => MENU_CALLBACK,
'file' => 'taxonomy_manager.admin.inc',
);
$items['admin/content/taxonomy_manager/siblingsform'] = array(
'page callback' => 'taxonomy_manager_tree_build_siblings_form',
'access arguments' => array(
'administer taxonomy',
),
'type' => MENU_CALLBACK,
);
$items['admin/content/taxonomy_manager/termdata/edit'] = array(
'page callback' => 'taxonomy_manager_term_data_edit',
'access arguments' => array(
'administer taxonomy',
),
'type' => MENU_CALLBACK,
'file' => 'taxonomy_manager.admin.inc',
);
$items['admin/content/taxonomy_manager/export'] = array(
'page callback' => 'taxonomy_manager_export',
'access arguments' => array(
'administer taxonomy',
),
'type' => MENU_CALLBACK,
'file' => 'taxonomy_manager.admin.inc',
);
$items['admin/content/taxonomy_manager/double-tree/edit'] = array(
'page callback' => 'taxonomy_manager_double_tree_edit',
'access arguments' => array(
'administer taxonomy',
),
'type' => MENU_CALLBACK,
'file' => 'taxonomy_manager.admin.inc',
);
$items['admin/content/taxonomy_manager/voc'] = array(
'title' => 'Taxonomy Manager',
'page callback' => 'drupal_get_form',
'page arguments' => array(
'taxonomy_manager_form',
),
'access arguments' => array(
'administer taxonomy',
),
'type' => MENU_CALLBACK,
'file' => 'taxonomy_manager.admin.inc',
);
$items['admin/content/taxonomy_manager/double-tree'] = array(
'title' => 'Taxonomy Manager',
'page callback' => 'drupal_get_form',
'page arguments' => array(
'taxonomy_manager_double_tree_form',
),
'access arguments' => array(
'administer taxonomy',
),
'type' => MENU_CALLBACK,
'file' => 'taxonomy_manager.admin.inc',
);
$items['admin/settings/taxonomy_manager'] = array(
'title' => 'Taxonomy Manager',
'description' => 'Advanced settings for the Taxonomy Manager',
'page callback' => 'drupal_get_form',
'page arguments' => array(
'taxonomy_manager_settings',
),
'access arguments' => array(
'administer site configuration',
),
'file' => 'taxonomy_manager.admin.inc',
);
$items['admin/content/taxonomy_manager/toolbar/form'] = array(
'page callback' => 'taxonomy_manager_toolbar_forms',
'access arguments' => array(
'administer taxonomy',
),
'type' => MENU_CALLBACK,
'file' => 'taxonomy_manager.admin.inc',
);
$items['taxonomy_manager/autocomplete'] = array(
'title' => 'Taxonomy Manager Autocomplete',
'page callback' => 'taxonomy_manager_autocomplete_load',
'access arguments' => array(
'administer taxonomy',
),
'type' => MENU_CALLBACK,
'file' => 'taxonomy_manager.admin.inc',
);
return $items;
}
/**
* Implementation of hook_menu_alter
*/
function taxonomy_manager_menu_alter(&$callbacks) {
if (!variable_get('taxonomy_manager_disable_merge_redirect', TRUE)) {
$callbacks['taxonomy/term/%']['page callback'] = 'taxonomy_manager_term_page';
}
}
/**
* Implementation of hook_theme
*/
function taxonomy_manager_theme() {
return array(
'taxonomy_manager_form' => array(
'arguments' => array(
'form',
),
),
'taxonomy_manager_double_tree_form' => array(
'arguments' => array(
'form',
),
),
'no_submit_button' => array(
'arguments' => array(
'element',
),
),
'taxonomy_manager_image_button' => array(
'arguemnts' => array(
'element',
),
),
'taxonomy_manager_tree' => array(
'arguments' => array(
'element',
),
),
'taxonomy_manager_tree_elements' => array(
'arguments' => array(
'element',
),
),
'taxonomy_manager_tree_checkbox' => array(
'arguments' => array(
'element',
),
),
'taxonomy_manager_tree_radio' => array(
'arguments' => array(
'element',
),
),
'taxonomy_manager_term_data_extra' => array(
'arguments' => array(
'element',
),
),
);
}
/**
* Implementation of hook_help().
*/
function taxonomy_manager_help($path, $arg) {
switch ($path) {
case 'admin/help#taxonomy_manager':
$output = t('The Taxonomy Manager provides an additional interface for managing vocabularies of the taxonomy module. It\'s especially very useful for long sets of terms.
The vocabulary is represented in a dynamic tree view.
It supports operation like mass adding and deleting of terms, fast weight editing, moving of terms in hierarchies, merging of terms and fast term data editing.
For more information on how to use please read the readme file included in the taxonomy_manager directory.');
return $output;
}
}
/**
* function gets called by the taxonomy_manager_tree form type ('taxonomy_manager_'. form_id .'_operations')
* return an form array with values to show next to every term value
*/
function taxonomy_manager_taxonomy_manager_tree_operations($term) {
$form = array();
if (!variable_get('taxonomy_manager_disable_mouseover', 0)) {
$module_path = drupal_get_path('module', 'taxonomy_manager') . '/';
if (_taxonomy_manager_tree_term_children_count($term->tid) > 0) {
$form['select_all'] = array(
'#weight' => -1,
'#value' => '<span class="select-all-children" title="' . t("Select all children") . '"> </span>',
);
}
$form['up'] = array(
'#value' => theme("image", $module_path . "images/go-up-small.png", "go up", t("Move up"), array(
'class' => 'term-up',
)),
);
$form['down'] = array(
'#value' => theme("image", $module_path . "images/go-down-small.png", "go down", t("Move down"), array(
'class' => 'term-down',
)),
);
$link_img = theme("image", $module_path . "images/link-small.png", "link to term page");
$link = l(' ' . $link_img, taxonomy_term_path($term), array(
'attributes' => array(
'rel' => 'tag',
'title' => t("Go to term page"),
'target' => '_blank',
),
'html' => TRUE,
));
$form['link'] = array(
'#value' => $link,
'#weight' => 10,
);
}
return $form;
}
/**
* function gets called by taxonomy_manager_tree form type ('taxonomy_manager_'. form_id .'_link')
* and returns an link, where to go, when a term gets clicked
*
* @param $vid vocabulary id
*/
function taxonomy_manager_taxonomy_manager_tree_link($term) {
return "admin/content/taxonomy_manager/termdata/" . $term->vid . "/" . $term->tid;
}
function taxonomy_manager_taxonomy2_manager_tree_operations($term) {
return taxonomy_manager_taxonomy_manager_tree_operations($term);
}
function taxonomy_manager_taxonomy2_manager_tree_link($term) {
return taxonomy_manager_taxonomy_manager_tree_link($term);
}
/**
* sets / updates cache for merging history
*/
function taxonomy_manager_merge_history_update_cache() {
$merged_terms = array();
$result = db_query("SELECT * FROM {taxonomy_manager_merge}");
while ($data = db_fetch_object($result)) {
$merged_terms[$data->merged_tid] = $data->main_tid;
}
cache_set('taxonomy_manager_merge', $merged_terms, 'cache');
}
/**
* helper function for getting out the main term of former merged term (which no
* long exists)
*
* @param $tid of which the main term has to be evaluated
* @return term id of main term, if exists, else 0
*/
function taxonomy_manager_merge_get_main_term($tid) {
$merged_terms = array();
$cache = cache_get('taxonomy_manager_merge', 'cache');
if (!$cache) {
taxonomy_manager_merge_history_update_cache();
}
$merged_terms = $cache->data;
return $merged_terms[$tid];
}
/**
* menu callback
*
* replaces taxonomy_mangager_term_page, because we have to consider that the
* url may contain former merged terms, which no longer exists
* every given tid gets checked, if it has been merged. if yes, the tid gets replaced
* with tid of main term and afterwards passed to default taxonomy_manager_term_page
*
* @param $str_tids
* @param $depth
* @param $op
*/
function taxonomy_manager_term_page($str_tids = '', $depth = 0, $op = 'page') {
$tids = taxonomy_terms_parse_string($str_tids);
if ($tids['operator'] == 'and' || $tids['operator'] == 'or') {
$new_tids = array();
foreach ($tids['tids'] as $tid) {
//get cached main term, if not merged, returns 0
$main_term = taxonomy_manager_merge_get_main_term($tid);
$new_tids[] = $main_term ? $main_term : $tid;
}
if ($tids['operator'] == 'and') {
$operator = ',';
}
else {
if ($tids['operator'] == 'or') {
$operator = '+';
}
}
$new_tids_str = implode($operator, $new_tids);
if (!function_exists('taxonomy_term_page')) {
/**
* including the taxonomy.pages.inc file shouldn't be necessary, because
* TaxMan is correctly using hook_menu_alter to change the callback.
* but in some combinations with other modules, which overwrite the menu
* entry in hook_menu, calling taxonomy_term_page is causing an error.
* the following lines are going to prevent the fatal error
*/
$taxonomy_module_path = drupal_get_path('module', 'taxonomy');
include_once $taxonomy_module_path . '/taxonomy.pages.inc';
}
return taxonomy_term_page($new_tids_str, $depth, $op);
}
else {
drupal_not_found();
}
}
/******************************************
* TAXONOMY TREE FORM ELEMENT DEFINITION
*
* how to use:
* $form['name'] = array(
* '#type' => 'taxonomy_manager_tree',
* '#vid' => $vid,
* );
*
* additional parameter:
* #pager: TRUE / FALSE,
* whether to use pagers (drupal pager, load of nested children, load of siblings)
* or to load the whole tree on page generation
* #parent: only children on this parent will be loaded
* #term_to_expand: loads and opens the first path to a given term id
* #siblings_page: current page for loading pf next siblings, internal use
* #default_value: an array of term ids, which get selected by default
* #render_whole_tree: set this option to TRUE, if you have defined a parent for the tree and you want
* the the tree is fully rendered
* #add_term_info: if TRUE, hidden form values with the term id and weight are going to be added
* #expand_all: if TRUE, all elements are going to be expanded by default
* #multiple: if TRUE the tree will contain checkboxes, otherwise radio buttons
* #tree_is_required: use #tree_is_required instead of #required if you are using the tree within an other
* element and don't want that both are internally required, because it might cause that
* error messages are shown twice (see content_taxonomy_tree)
* #language lang code if i18n is enabled and multilingual vocabulary
*
* defining term operations:
* to add values (operations,..) to each term, add a function, which return a form array
* 'taxonomy_manager_'. $tree_form_id .'_operations'
*
* how to retrieve selected values:
* selected terms ids are available in validate / submit function in
* $form_values['name']['selected_terms'];
*
******************************************/
/**
* Implementation of hook_elements
*/
function taxonomy_manager_elements() {
$type['taxonomy_manager_tree'] = array(
'#input' => TRUE,
'#process' => array(
'taxonomy_manager_tree_process_elements',
),
'#tree' => TRUE,
);
return $type;
}
/**
* Processes the tree form element
*
* @param $element
* @return the tree element
*/
function taxonomy_manager_tree_process_elements($element) {
global $_taxonomy_manager_existing_ids;
//TEMP: seems like this functions gets called twice in preview and cause problem because of adding the settings to js twice
$_taxonomy_manager_existing_ids = is_array($_taxonomy_manager_existing_ids) ? $_taxonomy_manager_existing_ids : array();
$module_path = drupal_get_path('module', 'taxonomy_manager') . '/';
$id = form_clean_id(implode('-', $element['#parents']));
$vid = $element['#vid'];
if (!$element['#siblings_page'] && !in_array($id, $_taxonomy_manager_existing_ids)) {
$_taxonomy_manager_existing_ids[$id] = $id;
drupal_add_css($module_path . 'css/taxonomy_manager.css');
drupal_add_js($module_path . 'js/tree.js');
drupal_add_js(array(
'siblingsForm' => array(
'url' => url('admin/content/taxonomy_manager/siblingsform'),
'modulePath' => $module_path,
),
), 'setting');
drupal_add_js(array(
'childForm' => array(
'url' => url('admin/content/taxonomy_manager/childform'),
'modulePath' => $module_path,
),
), 'setting');
drupal_add_js(array(
'taxonomytree' => array(
'id' => $id,
'vid' => $vid,
),
), 'setting');
}
if (!is_array($element['#operations'])) {
$opertions_callback = 'taxonomy_manager_' . implode('_', $element['#parents']) . '_operations';
if (function_exists($opertions_callback)) {
$element['#operations_callback'] = $opertions_callback;
}
}
if (!isset($element['#link'])) {
$link_callback = 'taxonomy_manager_' . implode('_', $element['#parents']) . '_link';
if (function_exists($link_callback)) {
$element['#link_callback'] = $link_callback;
}
}
$tree = _taxonomy_manager_tree_get_item($element['#vid'], $element['#parent'], $element['#pager'], $element['#siblings_page'], $element['#search_string'], $element['#language']);
if ($element['#pager'] && !($element['#parent'] || $element['#siblings_page'])) {
$element['pager'] = array(
'#value' => theme('pager', NULL, variable_get('taxonomy_manager_pager_tree_page_size', 50)),
);
}
$element['#default_value'] = is_array($element['#default_value']) ? $element['#default_value'] : array();
$element['#multiple'] = isset($element['#multiple']) ? $element['#multiple'] : TRUE;
$element['#add_term_info'] = isset($element['#add_term_info']) ? $element['#add_term_info'] : TRUE;
$element['#tree'] = TRUE;
$element['#id'] = $id;
$element['#element_validate'] = array(
'taxonomy_manager_tree_validate',
);
$element['#required'] = isset($element['#tree_is_required']) ? $element['#tree_is_required'] : FALSE;
$terms_to_expand = array();
if ($element['#term_to_expand']) {
_taxonomy_manager_tree_get_first_path($element['#term_to_expand'], $tree, $terms_to_expand);
$terms_to_expand = taxonomy_manager_tree_get_terms_to_expand($tree, array(
$element['#term_to_expand'],
), TRUE);
}
if (count($element['#default_value']) && !$element['#expand_all']) {
$terms_to_expand = taxonomy_manager_tree_get_terms_to_expand($tree, $element['#default_value'], $element['#multiple']);
}
if (!empty($element['#language'])) {
$element['#elements']['language'] = array(
'#type' => 'hidden',
'#value' => $element['#language'],
'#attributes' => array(
'class' => 'tree-lang',
),
);
_taxonomy_manager_tree_element_set_params($element['#parents'], $element['#elements']);
}
taxonomy_manager_tree_build_form($index = 0, $tree, $element['#elements'], $element, $element['#parents'], $element['#siblings_page'], $element['#default_value'], $element['#multiple'], $terms_to_expand);
return $element;
}
/**
* loads tree with terms (depending on various settings)
*
* @param $vid
* @param $parent
* @param $pager
* @param $siblings_page
* @return array with term elements
*/
function _taxonomy_manager_tree_get_item($vid, $parent = 0, $pager = FALSE, $siblings_page = 0, $search_string = NULL, $language_code = NULL) {
$tree = array();
if (module_exists('i18ntaxonomy') && $language_code != "") {
return _taxonomy_manager_tree_get_translated_item($vid, $parent, $pager, $siblings_page, $search_string, $language_code);
}
if ($pager) {
if ($parent || $siblings_page) {
$start = ($siblings_page - 1) * variable_get('taxonomy_manager_pager_tree_page_size', 50);
$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 = %d ORDER BY weight, name", $vid, $parent, $start, variable_get('taxonomy_manager_pager_tree_page_size', 50));
}
else {
if ($search_string) {
$result = pager_query("SELECT t.* FROM {term_data} t INNER JOIN {term_hierarchy} h ON t.tid = h.tid WHERE vid = %d AND h.parent = 0 AND name LIKE ('%%%s%%') ORDER BY weight, name", variable_get('taxonomy_manager_pager_tree_page_size', 50), 0, NULL, array(
$vid,
$search_string,
));
}
else {
$result = pager_query("SELECT t.* FROM {term_data} t INNER JOIN {term_hierarchy} h ON t.tid = h.tid WHERE vid = %d AND h.parent = 0 ORDER BY weight, name", variable_get('taxonomy_manager_pager_tree_page_size', 50), 0, NULL, array(
$vid,
));
}
}
while ($term = db_fetch_object($result)) {
$term->depth = 0;
$tree[] = $term;
}
}
else {
$tree = taxonomy_get_tree($vid, $parent);
}
return $tree;
}
/**
* loads translated tree with terms (depending on various settings)
*
* @param $vid
* @param $parent
* @param $pager
* @param $siblings_page
* @return array with term elements
*/
function _taxonomy_manager_tree_get_translated_item($vid, $parent = 0, $pager = FALSE, $siblings_page = 0, $search_string = NULL, $language_code = NULL) {
$tree = array();
if ($language_code == "no language") {
$language_code = "";
//get terms where no language is specified
}
if ($pager) {
if ($parent || $siblings_page) {
$start = ($siblings_page - 1) * variable_get('taxonomy_manager_pager_tree_page_size', 50);
$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 = %d AND t.language = '%s' ORDER BY weight, name", $vid, $parent, $language_code, $start, variable_get('taxonomy_manager_pager_tree_page_size', 50));
}
else {
if ($search_string) {
$result = pager_query("SELECT t.* FROM {term_data} t INNER JOIN {term_hierarchy} h ON t.tid = h.tid WHERE vid = %d AND h.parent = 0 AND name LIKE ('%%%s%%') AND t.language = '%s' ORDER BY weight, name", variable_get('taxonomy_manager_pager_tree_page_size', 50), 0, NULL, array(
$vid,
$search_string,
$language_code,
));
}
else {
$result = pager_query("SELECT t.* FROM {term_data} t INNER JOIN {term_hierarchy} h ON t.tid = h.tid WHERE vid = %d AND h.parent = 0 AND t.language = '%s' ORDER BY weight, name", variable_get('taxonomy_manager_pager_tree_page_size', 50), 0, NULL, array(
$vid,
$language_code,
));
}
}
while ($term = db_fetch_object($result)) {
$term->depth = 0;
$tree[] = $term;
}
}
else {
$tree = i18ntaxonomy_get_tree($vid, $language_code, $parent);
}
return $tree;
}
/**
* marks parent terms to expand if a child terms is selected by default
*/
function taxonomy_manager_tree_get_terms_to_expand($tree, $default_values, $multiple) {
$terms = array();
foreach (array_reverse($tree) as $term) {
if (in_array($term->tid, array_values($default_values)) || in_array($term->tid, $terms)) {
if (is_array($term->parents)) {
foreach ($term->parents as $parent) {
if ($parent) {
$terms[$parent] = $parent;
}
if (!$multiple) {
break;
}
}
}
}
}
return $terms;
}
/**
* calculates a path to a certain term and merges it into the tree
*/
function _taxonomy_manager_tree_get_first_path($tid, &$tree, &$terms_to_expand) {
$path = array();
$next_tid = $tid;
$i = 0;
while ($i < 100) {
//prevent infinite loop if inconsistent hierarchy
$parents = taxonomy_get_parents($next_tid);
if (count($parents)) {
//takes first parent
$parent = array_pop($parents);
$path[] = $parent;
$next_tid = $parent->tid;
if (taxonomy_manager_term_is_root($next_tid)) {
break;
}
}
else {
break;
}
$i++;
}
$path = array_reverse($path);
$path[] = taxonomy_get_term($tid);
$root_term = $path[0];
$root_term_index;
if (count($path) > 1) {
foreach ($tree as $index => $term) {
if ($term->tid == $root_term->tid) {
$root_term_index = $index;
break;
}
}
}
if (isset($root_term_index)) {
$path_tree = taxonomy_manager_get_partial_tree($path);
$first_part = array_slice($tree, 0, $root_term_index + 1);
$last_part = array_slice($tree, $root_term_index + 1, count($tree));
$tree = array_merge($first_part, $path_tree, $last_part);
}
}
/**
* helper function to check whether a given term is a root term
*/
function taxonomy_manager_term_is_root($tid) {
if (db_affected_rows(db_query("SELECT tid FROM {term_hierarchy} WHERE tid = %d AND parent = 0", $tid)) == 1) {
return TRUE;
}
return FALSE;
}
/**
* returns partial tree for a given path
*/
function taxonomy_manager_get_partial_tree($path, $depth = 0) {
$tree = array();
$root_term = $path[$depth];
$children = taxonomy_get_children($root_term->tid);
if (isset($path[++$depth])) {
$next_term = $path[$depth];
}
foreach ($children as $key => $child) {
$child->depth = $depth;
$child->parents = array(
0 => $root_term->tid,
);
$tree[] = $child;
if ($child->tid == $next_term->tid) {
$tree = array_merge($tree, taxonomy_manager_get_partial_tree($path, $depth));
}
}
return $tree;
}
/**
* recursive function for building nested form array
* with checkboxes and weight forms for each term
*
* nested form array are allways appended to parent-form['children']
*
* @param $index current index in tree, start with 0
* @param $tree of terms (generated by taxonomy_get_tree)
* @return a form array
*/
function taxonomy_manager_tree_build_form(&$index, $tree, &$form, $root_form, $parents = array(), $page = 0, $default_value = array(), $multiple = TRUE, $terms_to_expand = array()) {
$current_depth = $tree[$index]->depth;
while ($index < count($tree) && $tree[$index]->depth >= $current_depth) {
$term = $tree[$index];
$attributes = array();
$this_parents = $parents;
$this_parents[] = $term->tid;
$value = in_array($term->tid, $default_value) ? 1 : 0;
if ($value && !$multiple) {
// Find our direct parent
$newindex = $index;
while ($newindex >= 0 && $tree[$newindex]->depth >= $current_depth) {
$newindex--;
}
if ($newindex >= 0) {
$value = in_array($tree[$newindex]->tid, $terms_to_expand) ? 1 : 0;
}
}
$form[$term->tid]['checkbox'] = array(
'#type' => $multiple ? 'checkbox' : 'radio',
'#title' => $term->name,
'#value' => $value,
'#return_value' => $term->tid,
'#theme' => $multiple ? 'taxonomy_manager_tree_checkbox' : 'taxonomy_manager_tree_radio',
);
if (!empty($root_form['#link_callback'])) {
$link_callback = $root_form['#link_callback'];
if (function_exists($link_callback)) {
$form[$term->tid]['checkbox']['#link'] = $link_callback($term);
}
}
if ($root_form['#add_term_info']) {
$form[$term->tid]['weight'] = array(
'#type' => 'hidden',
'#value' => $term->weight,
'#attributes' => array(
'class' => 'weight-form',
),
);
$form[$term->tid]['tid'] = array(
'#type' => 'hidden',
'#value' => $term->tid,
'#attributes' => array(
'class' => 'term-id',
),
);
$form[$term->tid]['checkbox']['#extra_info'] = taxonomy_manager_tree_term_extra_info($term);
}
if (!empty($root_form['#operations_callback'])) {
$opertions_callback = $root_form['#operations_callback'];
if (function_exists($opertions_callback)) {
$form[$term->tid]['operations'] = $opertions_callback($term);
}
}
if ($page) {
if ($index == variable_get('taxonomy_manager_pager_tree_page_size', 50) - 1 && !isset($tree[$index + 1])) {
$module_path = drupal_get_path('module', 'taxonomy_manager') . '/';
$form[$term->tid]['has-more-siblings'] = array(
'#type' => 'markup',
'#value' => theme("image", $module_path . "images/2downarrow.png", "more", NULL, array(
'class' => 'load-siblings',
)),
);
$form[$term->tid]['page'] = array(
'#type' => 'hidden',
'#value' => $page,
'#attributes' => array(
'class' => 'page',
),
);
$next_count = _taxonomy_manager_tree_get_next_siblings_count($term->vid, $page, $root_form['#parent']);
$form[$term->tid]['next_count'] = array(
'#value' => $next_count,
);
$form[$term->tid]['#attributes']['class'] .= 'has-more-siblings ';
}
}
_taxonomy_manager_tree_element_set_params($this_parents, $form[$term->tid]);
$class = _taxonomy_manager_tree_term_get_class($index, $tree, $root_form['#expand_all'] || in_array($term->tid, $terms_to_expand));
if (!empty($class)) {
$form[$term->tid]['#attributes']['class'] .= $class;
}
$index++;
if ($tree[$index]->depth > $current_depth) {
taxonomy_manager_tree_build_form($index, $tree, $form[$term->tid]['children'], $root_form, array_merge($this_parents, array(
'children',
)), $page, $default_value, $multiple, $terms_to_expand);
}
}
}
/**
* adds #id and #name to all form elements
*
* @param $parents
* @param $form
*/
function _taxonomy_manager_tree_element_set_params($parents, &$form) {
foreach (element_children($form) as $field_name) {
$field_parents = array_merge($parents, array(
$field_name,
));
$form[$field_name]['#tree'] = TRUE;
$form[$field_name]['#post'] = array();
$form[$field_name]['#parents'] = $field_parents;
$form[$field_name]['#id'] = form_clean_id('edit-' . implode('-', $field_parents));
$form[$field_name]['#name'] = array_shift($field_parents) . '[' . implode('][', $field_parents) . ']';
}
}
/**
* calculates class type (expandable, lastExpandable) for current element
*
* @param $current_index in tree array
* @param $tree array with terms
* @return expandable or lastExpandable
*/
function _taxonomy_manager_tree_term_get_class($current_index, $tree, $expand) {
$term = $tree[$current_index];
$next = $tree[++$current_index];
$children = FALSE;
while ($next->depth > $term->depth) {
$children = TRUE;
$next = $tree[++$current_index];
}
if ($children) {
if (isset($next->depth) && $next->depth == $term->depth) {
$class .= $expand ? 'collapsable' : 'expandable';
}
else {
$class .= $expand ? 'lastCollapsable' : 'lastExpandable';
}
}
else {
if (_taxonomy_manager_tree_term_children_count($term->tid) > 0) {
$class .= 'has-children ';
if ($current_index == count($tree)) {
$class .= 'lastExpandable';
}
else {
$class .= 'expandable';
}
}
else {
if (count($tree) == $current_index || $term->depth > $next->depth) {
$class = 'last';
}
}
}
return $class;
}
/**
* @param $tid
* @return children count
*/
function _taxonomy_manager_tree_term_children_count($tid) {
static $tids = array();
if (!isset($tids[$tid])) {
$tids[$tid] = db_result(db_query("SELECT COUNT(tid) FROM {term_hierarchy} WHERE parent = %d", $tid));
}
return $tids[$tid];
}
/**
* returns some additional information about the term which gets added to the link title
*/
function taxonomy_manager_tree_term_extra_info($term) {
$extra_info = "";
$term_children_count = _taxonomy_manager_tree_term_children_count($term->tid);
$term_parents = taxonomy_get_parents($term->tid);
if ($term_children_count > 0) {
$extra_info = t('Children Count: ') . $term_children_count;
}
if (count($term_parents) >= 1) {
$extra_info .= !empty($extra_info) ? ' | ' : '';
$extra_info .= t('Direct Parents: ');
$p_names = array();
foreach ($term_parents as $p) {
if ($p->tid != $term->tid) {
$p_names[] = $p->name;
}
}
$extra_info .= implode(', ', $p_names);
}
return $extra_info;
}
/**
* calculates number of next siblings if using paging
*
* @param $vid
* @param $page
* @param $parent
* @return next page size
*/
function _taxonomy_manager_tree_get_next_siblings_count($vid, $page, $parent = 0) {
$count = db_result(db_query("SELECT COUNT(t.tid) FROM {term_data} t INNER JOIN {term_hierarchy} h ON t.tid = h.tid WHERE vid = %d AND h.parent = %d", $vid, $parent));
$current_count = variable_get('taxonomy_manager_pager_tree_page_size', 50) * $page;
$diff = $count - $current_count;
if ($diff > variable_get('taxonomy_manager_pager_tree_page_size', 50)) {
$diff = variable_get('taxonomy_manager_pager_tree_page_size', 50);
}
return $diff;
}
/**
* callback for generating and rendering nested child forms (AHAH)
*
* @param $tree_id
* @param $parent term id of parent, that is expanded and of which children have to be loaded
*/
function taxonomy_manager_tree_build_child_form($tree_id, $vid, $parent, $tid = 0) {
$params = $_GET;
$GLOBALS['devel_shutdown'] = FALSE;
$form_state = array(
'submitted' => FALSE,
);
if (isset($tid) && $tid != 0) {
$language = _taxonomy_manager_term_get_lang($tid);
}
else {
$language = $params['language'];
}
$child_form = array(
'#type' => 'taxonomy_manager_tree',
'#vid' => $vid,
'#parent' => $parent,
'#pager' => TRUE,
'#language' => $language,
'#term_to_expand' => $tid,
);
if (!$root_level) {
//TODO ?
$child_form['#siblings_page'] = 1;
}
$opertions_callback = 'taxonomy_manager_' . str_replace('-', '_', $tree_id) . '_operations';
if (function_exists($opertions_callback)) {
$child_form['#operations_callback'] = $opertions_callback;
}
$link_callback = 'taxonomy_manager_' . str_replace('-', '_', $tree_id) . '_link';
if (function_exists($link_callback)) {
$child_form['#link_callback'] = $link_callback;
}
_taxonomy_manager_tree_sub_forms_set_parents($tree_id, $parent, $child_form);
//TODO use caching functions
//$form = form_get_cache($param['form_build_id'], $form_state);
//form_set_cache($param['form_build_id'], $form, $form_state);
$child_form = form_builder($param['form_id'], $child_form, $form_state);
print drupal_render($child_form);
exit;
}
/**
* callback for generating and rendering next siblings terms form (AHAH)
*
* @param $tree_id
* @param $page current page
* @param $prev_tid last sibling, that appears
* @param $parent if in hierarchies, parent id
*/
function taxonomy_manager_tree_build_siblings_form($tree_id, $page, $prev_tid, $parent = 0) {
$params = $_GET;
$GLOBALS['devel_shutdown'] = FALSE;
//prevent devel queries footprint
$form_state = array(
'submitted' => FALSE,
);
$vid = db_result(db_query("SELECT vid FROM {term_data} WHERE tid = %d", $prev_tid));
$siblings_form = array(
'#type' => 'taxonomy_manager_tree',
'#vid' => $vid,
'#parent' => $parent,
'#pager' => TRUE,
'#siblings_page' => $page + 1,
'#language' => $params['language'],
);
$opertions_callback = 'taxonomy_manager_' . str_replace('-', '_', $tree_id) . '_operations';
if (function_exists($opertions_callback)) {
$siblings_form['#operations_callback'] = $opertions_callback;
}
$link_callback = 'taxonomy_manager_' . str_replace('-', '_', $tree_id) . '_link';
if (function_exists($link_callback)) {
$siblings_form['#link_callback'] = $link_callback;
}
_taxonomy_manager_tree_sub_forms_set_parents($tree_id, $parent, $siblings_form);
$siblings_form = form_builder('taxonomy_manager_form', $siblings_form, $form_state);
$output = drupal_render($siblings_form);
//cutting of <ul> and ending </ul> ... can this be done cleaner?
$output = drupal_substr($output, 21, -5);
print $output;
exit;
}
/**
* sets parents depending on form_id and hierarchical parents
*
* @param $tree_id
* @param $parent term id
* @param $form
*/
function _taxonomy_manager_tree_sub_forms_set_parents($tree_id, $parent, &$form) {
$tree_ids = explode('-', $tree_id);
foreach ($tree_ids as $key => $id) {
$form['#parents'][] = $id;
}
if ($parent) {
$form['#parents'][] = $parent;
$form['#parents'][] = 'children';
/*$all_parents = taxonomy_get_parents_all($parent);
for ($i=count($all_parents)-1; $i >= 0; $i--) {
$form['#parents'][] = $all_parents[$i]->tid;
$form['#parents'][] = 'children';
}*/
}
}
/**
* validates submitted form values
* checks if selected terms really belong to initial voc, if not --> form_set_error
*
* if all is valid, selected values get added to 'selected_terms' for easy use in submit
*
* @param $form
*/
function taxonomy_manager_tree_validate($form, &$form_state) {
$selected = array();
if ($form['#multiple']) {
$selected = _taxonomy_manager_tree_get_selected_terms($form['#value']);
}
else {
if (is_numeric($form['#value'])) {
$selected[$form['#value']] = $form['#value'];
}
}
$vid = $form['#vid'];
foreach ($selected as $tid) {
if (!_taxonomy_manager_tree_term_valid($tid, $vid)) {
form_set_error('', t('An illegal choice has been detected. Please contact the site administrator.'));
}
}
form_set_value($form, array(
'selected_terms' => $selected,
), $form_state);
}
/**
* checks if term id belongs to vocabulary
*
* @param $tid term id
* @param $vid voc id
* @return true, if term belongs to voc, else false
*/
function _taxonomy_manager_tree_term_valid($tid, $vid) {
$term = taxonomy_get_term($tid);
if ($term->vid != $vid) {
return FALSE;
}
return TRUE;
}
/**
* returns term ids of selected checkboxes
*
* goes through nested form array recursivly
*
* @param $form_values
* @return an array with ids of selected terms
*/
function _taxonomy_manager_tree_get_selected_terms($form_values) {
$tids = array();
if (is_array($form_values)) {
foreach ($form_values as $tid => $form_value) {
if ($form_value['checkbox'] && $tid && $tid == $form_value['checkbox']) {
$tids[$tid] = $tid;
}
if (is_array($form_value['children'])) {
$tids += _taxonomy_manager_tree_get_selected_terms($form_value['children']);
}
}
}
return $tids;
}
/**
* returns language of a term (multilingual voc), if i18ntaxonomy enabled
*/
function _taxonomy_manager_term_get_lang($tid) {
if (module_exists('i18ntaxonomy')) {
return db_result(db_query("SELECT language FROM {term_data} WHERE tid = %d", $tid));
}
return "";
}
/**
* theme function for root element
*
* @param $element
* @return html output
*/
function theme_taxonomy_manager_tree($element) {
$tree = theme('taxonomy_manager_tree_elements', $element['#elements']);
if (!$element['#parent'] && !$element['#siblings_page'] || $element['#render_whole_tree']) {
$output = '<div id="' . $element['#id'] . '">';
$output .= $tree;
$output .= '</div>';
return theme('form_element', $element, $output);
}
return $tree;
}
/**
* recursive theme function for term elements
*
* @param $element
* @return html lists
*/
function theme_taxonomy_manager_tree_elements($element) {
$output .= '<ul class="treeview">';
if (is_array($element)) {
foreach (element_children($element) as $tid) {
if (is_numeric($tid)) {
$output .= '<li' . drupal_attributes($element[$tid]['#attributes']) . '>';
if (strpos($element[$tid]['#attributes']['class'], 'has-children') !== FALSE || is_array($element[$tid]['children'])) {
$output .= '<div class="hitArea"></div>';
}
$output .= '<div class="term-line">';
$output .= drupal_render($element[$tid]['checkbox']);
$output .= '<div class="term-operations" style="display: none;">';
$output .= drupal_render($element[$tid]['operations']);
$output .= '</div>';
if (is_array($element[$tid]['weight']) && is_array($element[$tid]['tid'])) {
$output .= drupal_render($element[$tid]['weight']);
$output .= drupal_render($element[$tid]['tid']);
}
if (is_array($element[$tid]['has-more-siblings'])) {
$output .= '<div class="term-has-more-siblings">';
$output .= '<div class="term-next-count">next ' . drupal_render($element[$tid]['next_count']) . '</div>';
$output .= '<div class="term-downarrow-img">';
$output .= drupal_render($element[$tid]['has-more-siblings']);
$output .= drupal_render($element[$tid]['page']);
$output .= '</div><div class="clear"></div></div>';
}
$output .= '</div>';
if (is_array($element[$tid]['children'])) {
$output .= theme('taxonomy_manager_tree_elements', $element[$tid]['children']);
}
$output .= '</li>';
}
}
}
$output .= "</ul>";
if (isset($element['language'])) {
$output .= drupal_render($element['language']);
}
return $output;
}
/**
* themes a checkbox, where a label can optional contain a link
*/
function theme_taxonomy_manager_tree_checkbox($element) {
_form_set_class($element, array(
'form-checkbox',
));
$checkbox = '<input ';
$checkbox .= 'type="checkbox" ';
$checkbox .= 'name="' . $element['#name'] . '" ';
$checkbox .= 'id="' . $element['#id'] . '" ';
$checkbox .= 'value="' . $element['#return_value'] . '" ';
$checkbox .= $element['#value'] ? ' checked="checked" ' : ' ';
$checkbox .= drupal_attributes($element['#attributes']) . ' />';
$title = $element['#title'];
if ($element['#link']) {
$attr = array();
$attr["class"] = "term-data-link";
if (isset($element['#extra_info'])) {
$attr["title"] = $element['#extra_info'];
}
$title = $title = l($title, $element['#link'], array(
'attributes' => $attr,
));
}
else {
$title = check_plain($title);
}
if (!is_null($title)) {
$checkbox = '<label class="option">' . $checkbox . ' ' . $title . '</label>';
}
unset($element['#title']);
return theme('form_element', $element, $checkbox);
}
/**
* themes a radio, where a label can optional contain a link
*/
function theme_taxonomy_manager_tree_radio($element) {
_form_set_class($element, array(
'form-radio',
));
$output = '<input ';
$output .= 'type="radio" ';
$output .= 'name="' . $element['#parents'][0] . "[" . $element['#parents'][1] . "]" . '" ';
//TODO check this
$output .= 'id="' . $element['#id'] . '" ';
$output .= 'value="' . $element['#return_value'] . '" ';
$checkbox .= $element['#value'] ? ' checked="checked" ' : ' ';
$output .= $element['#value'] ? ' checked="checked" ' : ' ';
$output .= drupal_attributes($element['#attributes']) . ' />';
$title = $element['#title'];
if ($element['#link']) {
$title = l($title, $element['#link'], array(
'attributes' => array(
"class" => "term-data-link",
),
));
}
else {
$title = check_plain($title);
}
if (!is_null($title)) {
$output = '<label class="option">' . $output . ' ' . $title . '</label>';
}
unset($element['#title']);
return theme('form_element', $element, $output);
}
Functions
Name | Description |
---|---|
taxonomy_manager_elements | Implementation of hook_elements |
taxonomy_manager_get_partial_tree | returns partial tree for a given path |
taxonomy_manager_help | Implementation of hook_help(). |
taxonomy_manager_menu | Implementation of hook_menu |
taxonomy_manager_menu_alter | Implementation of hook_menu_alter |
taxonomy_manager_merge_get_main_term | helper function for getting out the main term of former merged term (which no long exists) |
taxonomy_manager_merge_history_update_cache | sets / updates cache for merging history |
taxonomy_manager_taxonomy2_manager_tree_link | |
taxonomy_manager_taxonomy2_manager_tree_operations | |
taxonomy_manager_taxonomy_manager_tree_link | function gets called by taxonomy_manager_tree form type ('taxonomy_manager_'. form_id .'_link') and returns an link, where to go, when a term gets clicked |
taxonomy_manager_taxonomy_manager_tree_operations | function gets called by the taxonomy_manager_tree form type ('taxonomy_manager_'. form_id .'_operations') return an form array with values to show next to every term value |
taxonomy_manager_term_is_root | helper function to check whether a given term is a root term |
taxonomy_manager_term_page | menu callback |
taxonomy_manager_theme | Implementation of hook_theme |
taxonomy_manager_tree_build_child_form | callback for generating and rendering nested child forms (AHAH) |
taxonomy_manager_tree_build_form | recursive function for building nested form array with checkboxes and weight forms for each term |
taxonomy_manager_tree_build_siblings_form | callback for generating and rendering next siblings terms form (AHAH) |
taxonomy_manager_tree_get_terms_to_expand | marks parent terms to expand if a child terms is selected by default |
taxonomy_manager_tree_process_elements | Processes the tree form element |
taxonomy_manager_tree_term_extra_info | returns some additional information about the term which gets added to the link title |
taxonomy_manager_tree_validate | validates submitted form values checks if selected terms really belong to initial voc, if not --> form_set_error |
theme_taxonomy_manager_tree | theme function for root element |
theme_taxonomy_manager_tree_checkbox | themes a checkbox, where a label can optional contain a link |
theme_taxonomy_manager_tree_elements | recursive theme function for term elements |
theme_taxonomy_manager_tree_radio | themes a radio, where a label can optional contain a link |
_taxonomy_manager_term_get_lang | returns language of a term (multilingual voc), if i18ntaxonomy enabled |
_taxonomy_manager_tree_element_set_params | adds #id and #name to all form elements |
_taxonomy_manager_tree_get_first_path | calculates a path to a certain term and merges it into the tree |
_taxonomy_manager_tree_get_item | loads tree with terms (depending on various settings) |
_taxonomy_manager_tree_get_next_siblings_count | calculates number of next siblings if using paging |
_taxonomy_manager_tree_get_selected_terms | returns term ids of selected checkboxes |
_taxonomy_manager_tree_get_translated_item | loads translated tree with terms (depending on various settings) |
_taxonomy_manager_tree_sub_forms_set_parents | sets parents depending on form_id and hierarchical parents |
_taxonomy_manager_tree_term_children_count | |
_taxonomy_manager_tree_term_get_class | calculates class type (expandable, lastExpandable) for current element |
_taxonomy_manager_tree_term_valid | checks if term id belongs to vocabulary |