_get_term_children()
云策文档标注
概述
_get_term_children() 函数用于从给定的术语集合中筛选出指定术语 ID 的后代术语。它根据输入术语的类型(对象或 ID)返回相应类型的数组,并递归处理层次结构以避免无限循环。
关键要点
- 函数返回 $terms 中属于 $term_id 后代的子集,返回类型与输入术语类型一致(对象数组或 ID 数组)。
- 参数包括 $term_id(祖先术语 ID)、$terms(术语集合)、$taxonomy(分类法)和可选的 $ancestors(祖先数组,用于递归跟踪)。
- 函数内部使用 _get_term_hierarchy() 检查术语层次,并通过 $ancestors 参数防止递归循环。
- 如果 $terms 为空或 $term_id 无子项,则返回空数组;如果获取术语时出错,则返回 WP_Error。
代码示例
function _get_term_children( $term_id, $terms, $taxonomy, &$ancestors = array() ) {
$empty_array = array();
if ( empty( $terms ) ) {
return $empty_array;
}
$term_id = (int) $term_id;
$term_list = array();
$has_children = _get_term_hierarchy( $taxonomy );
if ( $term_id && ! isset( $has_children[ $term_id ] ) ) {
return $empty_array;
}
// Include the term itself in the ancestors array, so we can properly detect when a loop has occurred.
if ( empty( $ancestors ) ) {
$ancestors[ $term_id ] = 1;
}
foreach ( (array) $terms as $term ) {
$use_id = false;
if ( ! is_object( $term ) ) {
$term = get_term( $term, $taxonomy );
if ( is_wp_error( $term ) ) {
return $term;
}
$use_id = true;
}
// Don't recurse if we've already identified the term as a child - this indicates a loop.
if ( isset( $ancestors[ $term->term_id ] ) ) {
continue;
}
if ( (int) $term->parent === $term_id ) {
if ( $use_id ) {
$term_list[] = $term->term_id;
} else {
$term_list[] = $term;
}
if ( ! isset( $has_children[ $term->term_id ] ) ) {
continue;
}
$ancestors[ $term->term_id ] = 1;
$children = _get_term_children( $term->term_id, $terms, $taxonomy, $ancestors );
if ( $children ) {
$term_list = array_merge( $term_list, $children );
}
}
}
return $term_list;
}注意事项
- 此函数是内部函数,通常不直接调用,而是通过其他 API 如 WP_Term_Query 使用。
- 递归处理时,$ancestors 参数通过引用传递以优化性能并防止无限循环。
- 确保 $taxonomy 参数正确,否则可能影响层次结构查询。
原文内容
Gets the subset of $terms that are descendants of $term_id.
Description
If $terms is an array of objects, then _get_term_children() returns an array of objects.
If $terms is an array of IDs, then _get_term_children() returns an array of IDs.
Parameters
$term_idintrequired-
The ancestor term: all returned terms should be descendants of
$term_id. $termsarrayrequired-
The set of terms – either an array of term objects or term IDs – from which those that are descendants of $term_id will be chosen.
$taxonomystringrequired-
The taxonomy which determines the hierarchy of the terms.
$ancestorsarrayoptional-
Term ancestors that have already been identified. Passed by reference, to keep track of found terms when recursing the hierarchy. The array of located ancestors is used to prevent infinite recursion loops. For performance,
term_idsare used as array keys, with 1 as value.Default:
array()
Source
function _get_term_children( $term_id, $terms, $taxonomy, &$ancestors = array() ) {
$empty_array = array();
if ( empty( $terms ) ) {
return $empty_array;
}
$term_id = (int) $term_id;
$term_list = array();
$has_children = _get_term_hierarchy( $taxonomy );
if ( $term_id && ! isset( $has_children[ $term_id ] ) ) {
return $empty_array;
}
// Include the term itself in the ancestors array, so we can properly detect when a loop has occurred.
if ( empty( $ancestors ) ) {
$ancestors[ $term_id ] = 1;
}
foreach ( (array) $terms as $term ) {
$use_id = false;
if ( ! is_object( $term ) ) {
$term = get_term( $term, $taxonomy );
if ( is_wp_error( $term ) ) {
return $term;
}
$use_id = true;
}
// Don't recurse if we've already identified the term as a child - this indicates a loop.
if ( isset( $ancestors[ $term->term_id ] ) ) {
continue;
}
if ( (int) $term->parent === $term_id ) {
if ( $use_id ) {
$term_list[] = $term->term_id;
} else {
$term_list[] = $term;
}
if ( ! isset( $has_children[ $term->term_id ] ) ) {
continue;
}
$ancestors[ $term->term_id ] = 1;
$children = _get_term_children( $term->term_id, $terms, $taxonomy, $ancestors );
if ( $children ) {
$term_list = array_merge( $term_list, $children );
}
}
}
return $term_list;
}
Changelog
| Version | Description |
|---|---|
| 2.3.0 | Introduced. |