function _hs_taxonomy_hierarchical_select_get_tree in Hierarchical Select 7.3
Same name and namespace in other branches
- 5.3 modules/hs_taxonomy.module \_hs_taxonomy_hierarchical_select_get_tree()
- 6.3 modules/hs_taxonomy.module \_hs_taxonomy_hierarchical_select_get_tree()
Drupal core's taxonomy_get_tree() doesn't allow us to reset the cached trees, which obviously causes problems when you create new items between two calls to it.
6 calls to _hs_taxonomy_hierarchical_select_get_tree()
- hs_taxonomy_hierarchical_select_children in modules/
hs_taxonomy.module - Implementation of hook_hierarchical_select_children().
- hs_taxonomy_hierarchical_select_create_item in modules/
hs_taxonomy.module - Implements hook_hierarchical_select_create_item().
- hs_taxonomy_hierarchical_select_root_level in modules/
hs_taxonomy.module - Implementation of hook_hierarchical_select_root_level().
- hs_taxonomy_term_count_nodes in modules/
hs_taxonomy.module - Drupal core's taxonomy_term_count_nodes() is buggy. See http://drupal.org/node/144969#comment-843000.
- _hs_taxonomy_hierarchical_select_get_depth in modules/
hs_taxonomy.module - Get the depth of a vocabulary's tree.
File
- modules/
hs_taxonomy.module, line 1111 - Implementation of the Hierarchical Select API for the Taxonomy module.
Code
function _hs_taxonomy_hierarchical_select_get_tree($vid, $parent = 0, $depth = -1, $max_depth = NULL, $reset = FALSE) {
static $children, $parents, $terms;
if ($reset) {
$children = $parents = $terms = array();
}
$tree = array();
if (!is_array($parent)) {
$parent = array(
$parent,
);
}
$max_depth = is_null($max_depth) ? 99999999 : $max_depth;
$depth++;
// We cache trees, so it's not CPU-intensive to call get_tree() on a term
// and its children, too.
if ($max_depth <= $depth) {
return $tree;
}
// Prepare queue for the "IN ( .. )" part of query.
$queue = array();
foreach ($parent as $single_parent) {
// Queue branch for processing if it's not cached yet.
if (!isset($children[$vid][$single_parent])) {
$queue[] = $single_parent;
// Use an empty array to distinguish between a stub (without children)
// term and a branch that is not loaded yet.
$children[$vid][$single_parent] = array();
}
}
if (!empty($queue)) {
$query = db_select('taxonomy_term_data', 't');
$query
->join('taxonomy_term_hierarchy', 'h', 'h.tid = t.tid');
$result = $query
->addTag('translatable')
->addTag('term_access')
->addTag('hs_taxonomy_tree')
->fields('t')
->fields('h', array(
'parent',
))
->condition('t.vid', $vid)
->condition('parent', array_merge(array(
$vid,
), $queue), 'IN')
->orderBy('t.weight')
->orderBy('t.name')
->execute();
foreach ($result as $term) {
$children[$vid][$term->parent][] = $term->tid;
$parents[$vid][$term->tid][] = $term->parent;
$terms[$vid][$term->tid] = $term;
}
}
// Provide support for Title module. If Title module is enabled and this
// vocabulary uses translated term names we want output those terms with their
// translated version. Therefore a full taxonomy term entity load is required,
// similar to taxonomy_get_tree().
if (!empty($terms) && module_exists('title')) {
$vocabulary = taxonomy_vocabulary_load($vid);
if (title_field_replacement_enabled('taxonomy_term', $vocabulary->machine_name, 'name')) {
$term_entities = taxonomy_term_load_multiple(array_keys($terms[$vid]));
}
}
$next_parent = array();
foreach ($parent as $single_parent) {
foreach ($children[$vid][$single_parent] as $child) {
$term = isset($term_entities[$child]) ? $term_entities[$child] : $terms[$vid][$child];
$term = clone $term;
$term->depth = $depth;
// The "parent" attribute is not useful, as it would show one parent only.
unset($term->parent);
$term->parents = $parents[$vid][$child];
$tree[] = $term;
// Need more steps ?
if ($max_depth > $depth + 1) {
// Queue children for the next step down the tree. Do not process
// children which we already know as stub ones.
if (!isset($children[$vid][$child]) || !empty($children[$vid][$child])) {
$next_parent[] = $child;
}
}
}
}
if (!empty($next_parent)) {
// Process multiple children together i.e. next level.
$tree = array_merge($tree, _hs_taxonomy_hierarchical_select_get_tree($vid, $next_parent, $depth, $max_depth));
}
return isset($tree) ? $tree : array();
}