Improve 'offset' calculation when querying for hierarchical terms.

When querying for terms in hierarchical taxonomies, `get_terms()` initially
queries for all matching terms, and then trims the located results based on the
`$number` and `$offset` arguments passed to the function. See #8832. However,
a flaw in the original logic meant that results were failing to be trimmed
properly in cases where `$offset` exceeds the total number of matching terms;
in these cases, we should force an empty array.

Props danielbachhuber.
Fixes #35935.

git-svn-id: https://develop.svn.wordpress.org/trunk@36691 602fd350-edb4-49c9-b593-d223f7449a82
This commit is contained in:
Boone Gorges 2016-02-24 19:12:45 +00:00
parent 12645e6f75
commit 036bac45bc
2 changed files with 81 additions and 2 deletions

View File

@ -1719,8 +1719,13 @@ function get_terms( $args = array(), $deprecated = '' ) {
$terms = $_terms;
}
if ( $number && is_array( $terms ) && count( $terms ) > $number ) {
$terms = array_slice( $terms, $offset, $number, true );
// Hierarchical queries are not limited, so 'offset' and 'number' must be handled now.
if ( $hierarchical && $number && is_array( $terms ) ) {
if ( $offset >= count( $terms ) ) {
$terms = array();
} else {
$terms = array_slice( $terms, $offset, $number, true );
}
}
wp_cache_add( $cache_key, $terms, 'terms', DAY_IN_SECONDS );

View File

@ -2078,6 +2078,80 @@ class Tests_Term_getTerms extends WP_UnitTestCase {
$this->assertSame( array( $terms[0], $terms[1] ), array_keys( $found ) );
}
/**
* @ticket 35935
*/
public function test_hierarchical_offset_0_with_number_greater_than_total_available_count() {
register_taxonomy( 'wptests_tax', 'post', array( 'hierarchical' => true ) );
$terms = self::factory()->term->create_many( 2, array( 'taxonomy' => 'wptests_tax' ) );
$found = get_terms( 'wptests_tax', array(
'number' => 3,
'offset' => 0,
'hide_empty' => false,
'fields' => 'ids',
) );
$this->assertEqualSets( $terms, $found );
}
/**
* @ticket 35935
*/
public function test_hierarchical_offset_plus_number() {
register_taxonomy( 'wptests_tax', 'post', array( 'hierarchical' => true ) );
$terms = self::factory()->term->create_many( 3, array( 'taxonomy' => 'wptests_tax' ) );
$found = get_terms( 'wptests_tax', array(
'number' => 1,
'offset' => 1,
'hide_empty' => false,
'fields' => 'ids',
'orderby' => 'term_id',
'order' => 'ASC',
) );
$this->assertEqualSets( array( $terms[1] ), $found );
}
/**
* @ticket 35935
*/
public function test_hierarchical_offset_plus_number_exceeds_available_count() {
register_taxonomy( 'wptests_tax', 'post', array( 'hierarchical' => true ) );
$terms = self::factory()->term->create_many( 2, array( 'taxonomy' => 'wptests_tax' ) );
$found = get_terms( 'wptests_tax', array(
'number' => 2,
'offset' => 1,
'hide_empty' => false,
'fields' => 'ids',
'orderby' => 'term_id',
'order' => 'ASC',
) );
$this->assertEqualSets( array( $terms[1] ), $found );
}
/**
* @ticket 35935
*/
public function test_hierarchical_offset_exceeds_available_count() {
register_taxonomy( 'wptests_tax', 'post', array( 'hierarchical' => true ) );
$terms = self::factory()->term->create_many( 2, array( 'taxonomy' => 'wptests_tax' ) );
$found = get_terms( 'wptests_tax', array(
'number' => 100,
'offset' => 3,
'hide_empty' => false,
'fields' => 'ids',
'orderby' => 'term_id',
'order' => 'ASC',
) );
$this->assertEqualSets( array(), $found );
}
protected function create_hierarchical_terms_and_posts() {
$terms = array();