WordPress Version: 4.2
/**
* Get the subset of $terms that are descendants of $term_id.
*
* 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.
*
* @access private
* @since 2.3.0
*
* @param int $term_id The ancestor term: all returned terms should be descendants of $term_id.
* @param array $terms 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.
* @param string $taxonomy The taxonomy which determines the hierarchy of the terms.
* @param array $ancestors 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.
* @return array The subset of $terms that are descendants of $term_id.
*/
function _get_term_children($term_id, $terms, $taxonomy, &$ancestors = array())
{
$empty_array = array();
if (empty($terms)) {
return $empty_array;
}
$term_list = array();
$has_children = _get_term_hierarchy($taxonomy);
if (0 != $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;
}
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 (in_array($term->term_id, $ancestors)) {
continue;
}
if ($term->parent == $term_id) {
if ($use_id) {
$term_list[] = $term->term_id;
} else {
$term_list[] = $term;
}
if (!isset($has_children[$term->term_id])) {
continue;
}
if ($use_id) {
$ancestors = array_merge($ancestors, $term_list);
} else {
$ancestors = array_merge($ancestors, wp_list_pluck($term_list, 'term_id'));
}
if ($children = _get_term_children($term->term_id, $terms, $taxonomy, $ancestors)) {
$term_list = array_merge($term_list, $children);
}
}
}
return $term_list;
}