12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121 |
- <?php
- /**
- *
- * @file
- * Taxonomy Manager
- *
- * Administration interface for managing taxonomy vocabularies
- *
- */
- // Default value for the tree pager. Value can be overridden with the variable
- // taxonomy_manager_pager_tree_page_size.
- define('TAXONOMY_MANAGER_PAGER_TREE_PAGE_SIZE_DEFAULT', 100);
- /**
- * Implements hook_menu().
- */
- function taxonomy_manager_menu() {
- $items['admin/structure/taxonomy_manager/voc'] = array(
- 'title' => 'Taxonomy Manager',
- 'description' => 'Administer vocabularies with the Taxonomy Manager',
- 'page callback' => 'taxonomy_manager_voc_list',
- 'access arguments' => array('administer taxonomy'),
- 'file' => 'taxonomy_manager.admin.inc',
- );
- $items['admin/structure/taxonomy_manager/voc/%taxonomy_vocabulary_machine_name'] = array(
- 'title callback' => 'taxonomy_admin_vocabulary_title_callback',
- 'title arguments' => array(4),
- 'page callback' => 'drupal_get_form',
- 'page arguments' => array('taxonomy_manager_form', 4),
- 'access arguments' => array('administer taxonomy'),
- 'file' => 'taxonomy_manager.admin.inc',
- );
- $items['admin/structure/taxonomy_manager/childform'] = array(
- 'page callback' => 'taxonomy_manager_tree_build_child_form',
- 'access arguments' => array('administer taxonomy'),
- 'type' => MENU_CALLBACK,
- );
- $items['admin/structure/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/structure/taxonomy_manager/siblingsform'] = array(
- 'page callback' => 'taxonomy_manager_tree_build_siblings_form',
- 'access arguments' => array('administer taxonomy'),
- 'type' => MENU_CALLBACK,
- );
- $items['admin/structure/taxonomy_manager/export'] = array(
- 'page callback' => 'taxonomy_manager_export',
- 'access arguments' => array('administer taxonomy'),
- 'type' => MENU_CALLBACK,
- 'file' => 'taxonomy_manager.admin.inc',
- );
- $items['admin/structure/taxonomy_manager/double-tree/%taxonomy_vocabulary_machine_name/%taxonomy_vocabulary_machine_name'] = array(
- 'title' => 'Taxonomy Manager',
- 'page callback' => 'drupal_get_form',
- 'page arguments' => array('taxonomy_manager_double_tree_form', 4, 5),
- 'access arguments' => array('administer taxonomy'),
- 'file' => 'taxonomy_manager.admin.inc',
- );
- $items['admin/config/user-interface/taxonomy-manager-settings'] = 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'),
- 'type' => MENU_NORMAL_ITEM,
- '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;
- }
- /**
- * Implements hook_admin_menu_map().
- */
- function taxonomy_manager_admin_menu_map() {
- if (!user_access('administer taxonomy')) {
- return;
- }
- $map['admin/structure/taxonomy_manager/voc/%taxonomy_vocabulary_machine_name'] = array(
- 'parent' => 'admin/structure/taxonomy_manager/voc',
- 'arguments' => array(
- array('%taxonomy_vocabulary_machine_name' => array_keys(taxonomy_vocabulary_get_names())),
- ),
- );
- return $map;
- }
- /**
- * Implements hook_theme().
- */
- function taxonomy_manager_theme() {
- return array(
- 'taxonomy_manager_form' => array(
- 'render element' => 'form',
- ),
- 'taxonomy_manager_double_tree_form' => array(
- 'render element' => 'form',
- ),
- 'no_submit_button' => array(
- 'render element' => 'element',
- ),
- 'taxonomy_manager_image_button' => array(
- 'render element' => 'element',
- ),
- 'taxonomy_manager_tree' => array(
- 'render element' => 'element',
- ),
- 'taxonomy_manager_tree_elements' => array(
- 'render element' => 'element',
- ),
- 'taxonomy_manager_tree_checkbox' => array(
- 'render element' => 'element',
- ),
- 'taxonomy_manager_tree_radio' => array(
- 'render element' => 'element',
- ),
- 'taxonomy_manager_term_data_extra' => array(
- 'render element' => 'element',
- ),
- );
- }
- /**
- * Implements 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, '#markup' => '<span class="select-all-children" title="' . t("Select all children") . '"> </span>');
- }
- $form['up'] = array('#markup' => theme("image", array('path' => $module_path . "images/go-up-small.png", 'alt' => "go up", 'title' => t("Move up"), 'attributes' => array('class' => 'term-up'))));
- $form['down'] = array('#markup' => theme("image", array('path' => $module_path . "images/go-down-small.png", 'alt' => "go down", 'title' => t("Move down"), 'attributes' => array('class' => 'term-down'))));
- $link_img = theme("image", array('path' => $module_path . "images/link-small.png", 'alt' => "link to term page"));
- $link = l(' ' . $link_img, 'taxonomy/term/' . $term->tid, array('attributes' => array('rel' => 'tag', 'title' => t("Go to term page"), 'target' => '_blank'), 'html' => TRUE));
- $form['link'] = array('#markup' => $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/structure/taxonomy_manager/termdata/" . $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);
- }
- /******************************************
- * 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
- * #terms_to_expand: loads and opens the first path of given term ids
- * #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'];
- *
- ******************************************/
- /**
- * Implements hook_elements().
- */
- function taxonomy_manager_element_info() {
- $type['taxonomy_manager_tree'] = array(
- '#input' => TRUE,
- '#process' => array('taxonomy_manager_tree_process_elements'),
- '#tree' => TRUE,
- '#element_validate' => array('taxonomy_manager_tree_validate'),
- '#theme' => 'taxonomy_manager_tree',
- '#parent' => 0,
- '#siblings_page' => 0,
- '#operations' => "",
- '#default_value' => array(),
- '#multiple' => TRUE,
- '#add_term_info' => TRUE,
- '#required' => FALSE,
- '#expand_all' => FALSE,
- '#render_whole_tree' => FALSE,
- '#search_string' => '',
- '#terms_to_expand' => array(),
- '#terms_to_highlight' => array(),
- '#language' => NULL,
- '#pager' => FALSE,
- );
- 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 = drupal_clean_css_identifier(implode('-', $element['#parents']));
- $element['#id'] = $id;
- $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/structure/taxonomy_manager/siblingsform'), 'modulePath' => $module_path)), 'setting');
- drupal_add_js(array('childForm' => array('url' => url('admin/structure/taxonomy_manager/childform'), 'modulePath' => $module_path)), 'setting');
- drupal_add_js(array('taxonomytree' => array(array('id' => $id, 'vid' => $vid, 'parents' => $element['#parents']))), 'setting');
- }
- if (empty($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;
- }
- }
- $element['#elements'] = array();
- $tree = _taxonomy_manager_tree_get_item($element['#vid'], $element['#parent'], $element['#pager'], $element['#siblings_page'], $element['#search_string'], $element['#language']);
- if (count($tree)) {
- if ($element['#pager'] && !($element['#parent'] || $element['#siblings_page'])) {
- $element['pager'] = array('#value' => theme('pager'));
- }
- $terms_to_expand = array();
- if (isset($element['#terms_to_expand'])) {
- // allow multiple terms to be expanded
- $requested_terms_to_expand = is_array($element['#terms_to_expand']) ? $element['#terms_to_expand'] : array($element['#terms_to_expand']);
- foreach ($requested_terms_to_expand as $term_to_expand) {
- // Multiple term version
- _taxonomy_manager_tree_get_first_path($term_to_expand, $tree, $terms_to_expand);
- }
- $terms_to_expand = taxonomy_manager_tree_get_terms_to_expand($tree, $requested_terms_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']);
- }
- if (!is_array($element['#terms_to_highlight'])) {
- $element['#terms_to_highlight'] = array($element['#terms_to_highlight']);
- }
- $index = 0;
- taxonomy_manager_tree_build_form($index, $tree, $element['#elements'], $element, $element['#parents'], $element['#siblings_page'], $element['#default_value'], $element['#multiple'], $terms_to_expand, $element['#terms_to_highlight']);
- }
- 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('i18n_taxonomy') && $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', TAXONOMY_MANAGER_PAGER_TREE_PAGE_SIZE_DEFAULT);
- $result = db_query_range("SELECT t.* FROM {taxonomy_term_data} t INNER JOIN {taxonomy_term_hierarchy} h ON t.tid = h.tid WHERE vid = :vid AND h.parent = :parent ORDER BY t.weight, t.name", $start, variable_get('taxonomy_manager_pager_tree_page_size', 100), array(':vid' => $vid, ':parent' => $parent));
- }
- else {
- $query = db_select('taxonomy_term_data', 't')->extend('PagerDefault');
- $query->fields('t');
- $table_alias = $query->join('taxonomy_term_hierarchy', 'h', 't.tid = h.tid AND h.parent = 0');
- $query->condition('t.vid', $vid)
- ->orderBy('t.weight', 'ASC')
- ->orderBy('t.name', 'ASC')
- ->limit(variable_get('taxonomy_manager_pager_tree_page_size', TAXONOMY_MANAGER_PAGER_TREE_PAGE_SIZE_DEFAULT));
- if ($search_string) {
- $query->condition('name', '%' . db_like($search_string) . '%', 'LIKE');
- }
- $result = $query->execute();
- }
- foreach ($result as $term) {
- $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) {
- //TODO merge with function above
- $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', TAXONOMY_MANAGER_PAGER_TREE_PAGE_SIZE_DEFAULT);
- $result = db_query_range("SELECT t.* FROM {taxonomy_term_data} t INNER JOIN {taxonomy_term_hierarchy} h ON t.tid = h.tid WHERE vid = :vid AND h.parent = :parent AND t.language = :language ORDER BY t.weight, t.name", $start, variable_get('taxonomy_manager_pager_tree_page_size', 50), array(':vid' => $vid, ':parent' => $parent, ':language' => $language_code));
- }
- else {
- $query = db_select('taxonomy_term_data', 't')->extend('PagerDefault');
- $query->fields('t');
- $table_alias = $query->join('taxonomy_term_hierarchy', 'h', 't.tid = h.tid AND h.parent = 0');
- $query->condition('t.vid', $vid)
- ->condition('t.language', $language_code)
- ->orderBy('t.weight', 'ASC')
- ->orderBy('t.name', 'ASC')
- ->limit(variable_get('taxonomy_manager_pager_tree_page_size', TAXONOMY_MANAGER_PAGER_TREE_PAGE_SIZE_DEFAULT));
- if ($search_string) {
- $query->condition('name', '%' . db_like($search_string) . '%', 'LIKE');
- }
- $result = $query->execute();
- }
- foreach ($result as $term) {
- $term->depth = 0;
- $tree[] = $term;
- }
- }
- else {
- $tree = i18n_taxonomy_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 (isset($term->parents) && 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_shift($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_term_load($tid);
- $root_term = $path[0];
- $root_term_index;
- // build a map of the path keyed on tid - helps in avoiding duplicates when merging multiple paths to the tree
- $term_map = array();
- if (count($path) > 1) {
- foreach ($tree as $index => $term) {
- $term_map[$term->tid] = $index;
- if ($term->tid == $root_term->tid) {
- $root_term_index = $index;
- }
- }
- reset($tree);
- }
- if (isset($root_term_index)) {
- $path_tree = taxonomy_manager_get_partial_tree($path);
- // build map of path tree keyed on tids
- $path_term_map = array();
- foreach ($path_tree as $index => $term) {
- $path_term_map[$term->tid] = $index;
- }
- reset($path_tree);
- // first find the set of new terms that we need to add - new terms should be contiguous within $path_tree
- $new_path_terms_map = array_diff_key($path_term_map, $term_map);
- if (!empty($new_path_terms_map)) {
- // something to add
- $insert_term_index = reset($new_path_terms_map);
- if ($insert_term_index > 0) {
- // use previous term as insertion point
- $previous_tid = $path_tree[$insert_term_index-1]->tid;
- $insertion_index = $term_map[$previous_tid];
- }
- else {
- // use root index as insertion point
- $insertion_index = $root_term_index;
- }
- // get the new terms to add from the path tree
- $new_path_tree = array_slice($path_tree, $insert_term_index, count($new_path_terms_map));
- // stick the new terms into the tree at the insertion point
- array_splice($tree, $insertion_index+1, 0, $new_path_tree);
- }
- }
- }
- /**
- * helper function to check whether a given term is a root term
- */
- function taxonomy_manager_term_is_root($tid) {
- $is_root = (bool) db_query_range("SELECT 1 FROM {taxonomy_term_hierarchy} h WHERE h.tid = :tid AND h.parent = 0", 0, 1, array(':tid' => $tid))->fetchField();
- if ($is_root) {
- 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 (isset($next_term) && $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(), $terms_to_highlight = 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, // Escaping is done in theme wrappers.
- '#value' => $value,
- '#return_value' => $term->tid,
- '#required' => FALSE,
- '#theme_wrappers' => ($multiple) ? array('taxonomy_manager_tree_checkbox') : array('taxonomy_manager_tree_radio'),
- '#highlight' => in_array($term->tid, $terms_to_highlight) ? TRUE : FALSE,
- );
- $form[$term->tid]['#attributes'] = array();
- 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' => array('weight-form')));
- $form[$term->tid]['tid'] = array('#type' => 'hidden', '#value' => $term->tid, '#attributes' => array('class' => array('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', TAXONOMY_MANAGER_PAGER_TREE_PAGE_SIZE_DEFAULT) - 1) && !isset($tree[$index+1])) {
- $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('#markup' => $next_count);
- $form[$term->tid]['#attributes']['class'][] = 'has-more-siblings';
- }
- }
- _taxonomy_manager_tree_element_set_params($this_parents, $form[$term->tid]);
- _taxonomy_manager_tree_term_set_class($form[$term->tid]['#attributes']['class'], $index, $tree, ($root_form['#expand_all'] || in_array($term->tid, $terms_to_expand)));
- $index++;
- if (isset($tree[$index]) && $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, $terms_to_highlight);
- }
- }
- }
- /**
- * 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'] = drupal_clean_css_identifier('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
- */
- function _taxonomy_manager_tree_term_set_class(&$class, $current_index, $tree, $expand) {
- $term = $tree[$current_index];
- $next_index = ++$current_index;
- $next = isset($tree[$next_index]) ? $tree[$next_index] : NULL;
- $children = FALSE;
- if (!empty($next) && $next->depth > $term->depth) {
- $children = TRUE;
- }
- if ($children) {
- if (!empty($next->depth) && $next->depth == $term->depth) {
- $class[] = ($expand) ? 'collapsable' : 'expandable';
- }
- else {
- $class[] = ($expand) ? 'lastCollapsable' : 'lastExpandable';
- }
- }
- elseif (_taxonomy_manager_tree_term_children_count($term->tid) > 0) {
- $class[] = 'has-children';
- if ($current_index == count($tree)) {
- $class[] = 'lastExpandable';
- }
- else {
- $class[] = 'expandable';
- }
- }
- elseif ((count($tree) == $current_index) || (!empty($next) && $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])) {
- $query = db_select('taxonomy_term_hierarchy', 'h');
- $query->condition('h.parent', $tid);
- $tids[$tid] = $query->countQuery()->execute()->fetchField();
- }
- 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) {
- $query = db_select('taxonomy_term_data', 't');
- $query->join('taxonomy_term_hierarchy', 'h', 't.tid = h.tid');
- $query->condition('t.vid', $vid);
- $query->condition('h.parent', $parent);
- $count = $query->countQuery()->execute()->fetchField();
- $current_count = variable_get('taxonomy_manager_pager_tree_page_size', TAXONOMY_MANAGER_PAGER_TREE_PAGE_SIZE_DEFAULT) * $page;
- $diff = $count - $current_count;
- if ($diff > variable_get('taxonomy_manager_pager_tree_page_size', TAXONOMY_MANAGER_PAGER_TREE_PAGE_SIZE_DEFAULT)) {
- $diff = variable_get('taxonomy_manager_pager_tree_page_size', TAXONOMY_MANAGER_PAGER_TREE_PAGE_SIZE_DEFAULT);
- }
- 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) {
- $params = $_GET;
- $form_state = form_state_defaults();
- $form_state['method'] = 'get';
- $form_state['values'] = array();
- $form_state['process_input'] = TRUE;
- $form_state['input'] = array();
- $form_state['complete form'] = array();
- $tids = array();
- if (isset($params['#terms_to_expand']) && $params['#terms_to_expand'] != 0) {
- // convert to array
- $tids = explode(',', $params['#terms_to_expand']);
- }
- if (count($tids) == 1) {
- $language = _taxonomy_manager_term_get_lang($tids[0]);
- }
- else {
- $language = $params['language'];
- }
- $child_form = array(
- '#type' => 'taxonomy_manager_tree',
- '#vid' => $vid,
- '#parent' => $parent,
- '#pager' => TRUE,
- '#language' => $language,
- '#terms_to_expand' => $tids,
- '#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($params['form_parents'], $parent, $child_form);
- $child_form = form_builder('taxonomy_manager_form', $child_form, $form_state);
- print drupal_json_output(array('data' => drupal_render($child_form)));
- ajax_footer();
- }
- /**
- * 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;
- $form_state = form_state_defaults();
- $form_state['method'] = 'get';
- $form_state['values'] = array();
- $form_state['process_input'] = TRUE;
- $form_state['input'] = array();
- $form_state['complete form'] = array();
- $vid = db_query("SELECT vid FROM {taxonomy_term_data} WHERE tid = :tid", array(':tid' => $prev_tid))->fetchField();
- $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($params['form_parents'], $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 drupal_json_output(array('data' => $output));
- ajax_footer();
- }
- /**
- * 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($form_parents, $parent, &$form) {
- $tree_ids = $form_parents;
- 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();
- //this can be useful for more complex processing, where the parent of the selecte term in the tree view is need (releveant if multi parent)
- //used in double tree
- $direct_parents = array();
- $selected = _taxonomy_manager_tree_get_selected_terms($form['#value'], $direct_parents);
- if (!$form['#multiple'] && count($selected) > 1) {
- // There should only be one selected term here. Make sure this is the case.
- $selected = array(key($selected) => key($selected));
- }
- $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, 'selected_terms_direct_parents' => $direct_parents), $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_term_load($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, &$direct_parents = array(), $direct_parent = 0) {
- $tids = array();
- if (is_array($form_values)) {
- foreach ($form_values as $tid => $form_value) {
- if (isset($form_value['checkbox']) && $tid && ($tid == $form_value['checkbox'])) {
- $tids[$tid] = $tid;
- if ($direct_parent) {
- $direct_parents[$tid] = $direct_parent;
- }
- }
- if (isset($form_value['children']) && is_array($form_value['children'])) {
- $tids += _taxonomy_manager_tree_get_selected_terms($form_value['children'], $direct_parents, $tid);
- }
- }
- }
- return $tids;
- }
- /**
- * returns language of a term (multilingual voc), if i18ntaxonomy enabled
- */
- function _taxonomy_manager_term_get_lang($tid) {
- if (module_exists('i18n_taxonomy')) {
- $term = taxonomy_term_load($tid);
- if ($term && isset($term->language)) {
- return $term->language;
- }
- }
- return "";
- }
- /**
- * theme function for root element
- *
- * @param $element
- * @return html output
- */
- function theme_taxonomy_manager_tree($variables) {
- $element = $variables['element'];
- $tree = theme('taxonomy_manager_tree_elements', array('element' => $element['#elements']));
- if ((!$element['#parent'] && !$element['#siblings_page']) || $element['#render_whole_tree']) {
- $element['#children'] = '<div id="' . $element['#id'] . '">';
- $element['#children'] .= $tree;
- $element['#children'] .= '</div>';
- $element['#title_display'] = 'none';
- return theme('form_element', array('element' => $element));
- }
- return $tree;
- }
- /**
- * recursive theme function for term elements
- *
- * @param $element
- * @return html lists
- */
- function theme_taxonomy_manager_tree_elements($variables) {
- $element = $variables['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 ((is_array($element[$tid]['#attributes']['class']) && in_array('has-children', $element[$tid]['#attributes']['class'])) || (isset($element[$tid]['children']) && is_array($element[$tid]['children']))) {
- $output .= '<div class="hitArea"></div>';
- }
- $output .= '<div class="term-line' . (($element[$tid]['checkbox']['#highlight']) ? ' highlightActiveTerm' : '') . '">';
- $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']);
- }
- $output .= '</div>';
- // Siblings Pager.
- if (isset($element[$tid]['next_count'])) {
- $output .= '<div class="term-has-more-siblings">';
- $output .= '<div class="term-next-count">' . t('next') . " " . drupal_render($element[$tid]['next_count']) . '</div>';
- $output .= drupal_render($element[$tid]['page']);
- $output .= '</div>';
- }
- if (isset($element[$tid]['children']) && is_array($element[$tid]['children'])) {
- $output .= theme('taxonomy_manager_tree_elements', array('element' => $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($variables) {
- $element = $variables['element'];
- $element['#attributes']['type'] = 'checkbox';
- element_set_attributes($element, array('id', 'name', '#return_value' => 'value'));
- // Unchecked checkbox has #value of integer 0.
- if (!empty($element['#checked'])) {
- $element['#attributes']['checked'] = 'checked';
- }
- _form_set_class($element, array('form-checkbox'));
- $output = '<input' . drupal_attributes($element['#attributes']) . ' />';
- $title = $element['#title'];
- if (isset($element['#link'])) {
- $attr = array();
- $attr["class"][] = "term-data-link";
- $attr["class"][] = "term-data-link-id-" . $element['#return_value'];
- if (isset($element['#extra_info'])) {
- $attr["title"] = $element['#extra_info'];
- }
- $title = l($title, $element['#link'], array('attributes' => $attr));
- }
- else {
- $title = check_plain($title);
- }
- $element['#children'] = '<label class="option">' . $output . ' ' . $title . '</label>';
- $element['#title_display'] = 'none';
- return theme('form_element', array('element' => $element));
- }
- /**
- * themes a radio, where a label can optional contain a link
- */
- function theme_taxonomy_manager_tree_radio($variables) {
- $element = $variables['element'];
- $element['#attributes']['type'] = 'radio';
- element_set_attributes($element, array('id', 'name', '#return_value' => 'value'));
- if (isset($element['#return_value']) && $element['#value'] !== FALSE && $element['#value'] == $element['#return_value']) {
- $element['#attributes']['checked'] = 'checked';
- }
- _form_set_class($element, array('form-radio'));
- $output = '<input' . drupal_attributes($element['#attributes']) . ' />';
- $title = $element['#title'];
- if (isset($element['#link'])) {
- $title = l($title, $element['#link'], array('attributes' => array("class" => "term-data-link term-data-link-id-" . $element['#return_value'])));
- }
- else {
- $title = check_plain($title);
- }
- $element['#children'] = '<label class="option">' . $output . ' ' . $title . '</label>';
- $element['#title_display'] = 'none';
- return theme('form_element', array('element' => $element));
- }
|