public TermStorage::loadTree($vid, $parent = 0, $max_depth = NULL, $load_entities = FALSE)
Finds all terms in a given vocabulary ID.
Parameters
string $vid: Vocabulary ID to retrieve terms for.
int $parent: The term ID under which to generate the tree. If 0, generate the tree for the entire vocabulary.
int $max_depth: The number of levels of the tree to return. Leave NULL to return all levels.
bool $load_entities: If TRUE, a full entity load will occur on the term objects. Otherwise they are partial objects queried directly from the {taxonomy_term_data} table to save execution time and memory consumption when listing large numbers of terms. Defaults to FALSE.
Return value
object[]|\Drupal\taxonomy\TermInterface[] An array of term objects that are the children of the vocabulary $vid.
Overrides TermStorageInterface::loadTree
File
- core/modules/taxonomy/src/TermStorage.php, line 195
Class
- TermStorage
- Defines a Controller class for taxonomy terms.
Namespace
Drupal\taxonomy
Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 | public function loadTree( $vid , $parent = 0, $max_depth = NULL, $load_entities = FALSE) { $cache_key = implode( ':' , func_get_args()); if (!isset( $this ->trees[ $cache_key ])) { // We cache trees, so it's not CPU-intensive to call on a term and its // children, too. if (!isset( $this ->treeChildren[ $vid ])) { $this ->treeChildren[ $vid ] = array (); $this ->treeParents[ $vid ] = array (); $this ->treeTerms[ $vid ] = array (); $query = $this ->database->select( 'taxonomy_term_field_data' , 't' ); $query ->join( 'taxonomy_term_hierarchy' , 'h' , 'h.tid = t.tid' ); $result = $query ->addTag( 'term_access' ) ->fields( 't' ) ->fields( 'h' , array ( 'parent' )) ->condition( 't.vid' , $vid ) ->condition( 't.default_langcode' , 1) ->orderBy( 't.weight' ) ->orderBy( 't.name' ) ->execute(); foreach ( $result as $term ) { $this ->treeChildren[ $vid ][ $term ->parent][] = $term ->tid; $this ->treeParents[ $vid ][ $term ->tid][] = $term ->parent; $this ->treeTerms[ $vid ][ $term ->tid] = $term ; } } // Load full entities, if necessary. The entity controller statically // caches the results. $term_entities = array (); if ( $load_entities ) { $term_entities = $this ->loadMultiple( array_keys ( $this ->treeTerms[ $vid ])); } $max_depth = (!isset( $max_depth )) ? count ( $this ->treeChildren[ $vid ]) : $max_depth ; $tree = array (); // Keeps track of the parents we have to process, the last entry is used // for the next processing step. $process_parents = array (); $process_parents [] = $parent ; // Loops over the parent terms and adds its children to the tree array. // Uses a loop instead of a recursion, because it's more efficient. while ( count ( $process_parents )) { $parent = array_pop ( $process_parents ); // The number of parents determines the current depth. $depth = count ( $process_parents ); if ( $max_depth > $depth && ! empty ( $this ->treeChildren[ $vid ][ $parent ])) { $has_children = FALSE; $child = current( $this ->treeChildren[ $vid ][ $parent ]); do { if ( empty ( $child )) { break ; } $term = $load_entities ? $term_entities [ $child ] : $this ->treeTerms[ $vid ][ $child ]; if (isset( $this ->treeParents[ $vid ][ $load_entities ? $term ->id() : $term ->tid])) { // Clone the term so that the depth attribute remains correct // in the event of multiple parents. $term = clone $term ; } $term ->depth = $depth ; unset( $term ->parent); $tid = $load_entities ? $term ->id() : $term ->tid; $term ->parents = $this ->treeParents[ $vid ][ $tid ]; $tree [] = $term ; if (! empty ( $this ->treeChildren[ $vid ][ $tid ])) { $has_children = TRUE; // We have to continue with this parent later. $process_parents [] = $parent ; // Use the current term as parent for the next iteration. $process_parents [] = $tid ; // Reset pointers for child lists because we step in there more // often with multi parents. reset( $this ->treeChildren[ $vid ][ $tid ]); // Move pointer so that we get the correct term the next time. next( $this ->treeChildren[ $vid ][ $parent ]); break ; } } while ( $child = next( $this ->treeChildren[ $vid ][ $parent ])); if (! $has_children ) { // We processed all terms in this hierarchy-level, reset pointer // so that this function works the next time it gets called. reset( $this ->treeChildren[ $vid ][ $parent ]); } } } $this ->trees[ $cache_key ] = $tree ; } return $this ->trees[ $cache_key ]; } |
Please login to continue.