Improve the include / exclude SQL generation in get_terms() by using IN and NOT IN where applicable. Adds unit tests for include / exclude.

Props sirzooro, duck_.

Fixes #11823.


Built from https://develop.svn.wordpress.org/trunk@25162


git-svn-id: http://core.svn.wordpress.org/trunk@25141 1a063a9b-81f0-0310-95a4-ce76da25c4cd
This commit is contained in:
Scott Taylor 2013-08-29 16:24:09 +00:00
parent 2f2f50c659
commit 4b449d38b4

View File

@ -1301,50 +1301,41 @@ function get_terms($taxonomies, $args = '') {
$where = "tt.taxonomy IN ('" . implode("', '", $taxonomies) . "')"; $where = "tt.taxonomy IN ('" . implode("', '", $taxonomies) . "')";
$inclusions = ''; $inclusions = '';
if ( !empty($include) ) { if ( ! empty( $include ) ) {
$exclude = ''; $exclude = '';
$exclude_tree = ''; $exclude_tree = '';
$interms = wp_parse_id_list($include); $inclusions = implode( ',', array_map( 'intval', wp_parse_id_list( $include ) ) );
foreach ( $interms as $interm ) {
if ( empty($inclusions) )
$inclusions = ' AND ( t.term_id = ' . intval($interm) . ' ';
else
$inclusions .= ' OR t.term_id = ' . intval($interm) . ' ';
}
} }
if ( !empty($inclusions) ) if ( ! empty( $inclusions ) )
$inclusions .= ')'; $inclusions = ' AND t.term_id IN ( ' . $inclusions . ' )';
$where .= $inclusions; $where .= $inclusions;
$exclusions = ''; $exclusions = '';
if ( ! empty( $exclude_tree ) ) { if ( ! empty( $exclude_tree ) ) {
$excluded_trunks = wp_parse_id_list( $exclude_tree ); $exclude_tree = wp_parse_id_list( $exclude_tree );
foreach ( $excluded_trunks as $extrunk ) { $excluded_children = array();
$excluded_children = (array) get_terms( reset( $taxonomies ), array( 'child_of' => intval( $extrunk ), 'fields' => 'ids', 'hide_empty' => 0 ) ); foreach ( $exclude_tree as $extrunk ) {
$excluded_children[] = $extrunk; $excluded_children = array_merge(
foreach( $excluded_children as $exterm ) { $excluded_children,
if ( empty( $exclusions ) ) (array) get_terms( $taxonomies[0], array( 'child_of' => intval( $extrunk ), 'fields' => 'ids', 'hide_empty' => 0 ) )
$exclusions = ' AND ( t.term_id <> ' . intval($exterm) . ' '; );
else
$exclusions .= ' AND t.term_id <> ' . intval($exterm) . ' ';
}
} }
$exclusions = implode( ',', array_map( 'intval', $excluded_children ) );
} }
if ( !empty($exclude) ) { if ( ! empty( $exclude ) ) {
$exterms = wp_parse_id_list($exclude); $exterms = array_map( 'intval', wp_parse_id_list( $exclude ) );
foreach ( $exterms as $exterm ) { if ( empty( $exclusions ) )
if ( empty($exclusions) ) $exclusions = implode( ',', $exterms );
$exclusions = ' AND ( t.term_id <> ' . intval($exterm) . ' '; else
else $exclusions .= ', ' . implode( ',', $exterms );
$exclusions .= ' AND t.term_id <> ' . intval($exterm) . ' ';
}
} }
if ( !empty($exclusions) ) if ( ! empty( $exclusions ) )
$exclusions .= ')'; $exclusions = ' AND t.term_id NOT IN (' . $exclusions . ')';
$exclusions = apply_filters('list_terms_exclusions', $exclusions, $args );
$exclusions = apply_filters( 'list_terms_exclusions', $exclusions, $args );
$where .= $exclusions; $where .= $exclusions;
if ( !empty($slug) ) { if ( !empty($slug) ) {