WordPress.org

Make WordPress Core

Changeset 30107


Ignore:
Timestamp:
10/30/2014 02:11:56 AM (7 years ago)
Author:
boonebgorges
Message:

In get_terms(), do not override 'hierarchical' and 'pad_counts' when 'parent' is present.

The previous behavior resulted in descendant terms being improperly excluded
from the results when passing a 'parent', even when 'hierarchical' had been
set to true.

The patch also adds unit tests that demonstrate the various interactions
between the 'child_of', 'parent', and 'hierarchical' parameters of get_terms().

Props landakram.
Fixes #29815.

Location:
trunk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-includes/taxonomy.php

    r30105 r30107  
    16291629    $args['number'] = absint( $args['number'] );
    16301630    $args['offset'] = absint( $args['offset'] );
    1631     if ( !$single_taxonomy || ! is_taxonomy_hierarchical( reset( $taxonomies ) ) ||
    1632         ( '' !== $args['parent'] && 0 !== $args['parent'] ) ) {
    1633         $args['child_of'] = 0;
     1631
     1632    // Save queries by not crawling the tree in the case of multiple taxes or a flat tax.
     1633    if ( ! $single_taxonomy || ! is_taxonomy_hierarchical( reset( $taxonomies ) ) ) {
     1634        $args['child_of'] = false;
    16341635        $args['hierarchical'] = false;
    16351636        $args['pad_counts'] = false;
     1637    }
     1638
     1639    // 'parent' overrides 'child_of'.
     1640    if ( 0 < intval( $args['parent'] ) ) {
     1641        $args['child_of'] = false;
    16361642    }
    16371643
  • trunk/tests/phpunit/tests/term/getTerms.php

    r30052 r30107  
    821821    }
    822822
     823    public function test_hierarchical_false_with_parent() {
     824        $initial_terms = $this->create_hierarchical_terms();
     825
     826        // Case where hierarchical is false
     827        $terms = get_terms( 'category', array(
     828            'hierarchical' => false,
     829            'parent' => $initial_terms['one_term']['term_id']
     830        ) );
     831
     832        // Verify that there are no children
     833        $this->assertEquals( 0, count( $terms ) );
     834    }
     835
     836    /**
     837     * @ticket 29185
     838     */
     839    public function test_hierarchical_true_with_parent() {
     840        $initial_terms = $this->create_hierarchical_terms();
     841
     842        // Case where hierarchical is true
     843        $terms = get_terms( 'category', array(
     844            'hierarchical' => true,
     845            'parent' => $initial_terms['one_term']['term_id']
     846        ) );
     847
     848        // Verify that the children with non-empty descendants are returned
     849        $expected = array(
     850            $initial_terms['two_term']['term_id'],
     851            $initial_terms['five_term']['term_id'],
     852        );
     853        $actual = wp_list_pluck( $terms, 'term_id' );
     854        $this->assertEqualSets( $expected, $actual );
     855    }
     856
     857    public function test_hierarchical_false_with_child_of_and_direct_child() {
     858        $initial_terms = $this->create_hierarchical_terms();
     859        $post_id = $this->factory->post->create();
     860        wp_set_post_terms(
     861            $post_id,
     862            array( $initial_terms['seven_term']['term_id'] ),
     863            'category'
     864        );
     865
     866        // Case where hierarchical is false
     867        $terms = get_terms( 'category', array(
     868            'hierarchical' => false,
     869            'child_of' => $initial_terms['one_term']['term_id']
     870        ) );
     871
     872        $expected = array(
     873            $initial_terms['seven_term']['term_id'],
     874        );
     875
     876        $actual = wp_list_pluck( $terms, 'term_id' );
     877        $this->assertEqualSets( $expected, $actual );
     878    }
     879
     880    public function test_hierarchical_false_with_child_of_should_not_return_grandchildren() {
     881        $initial_terms = $this->create_hierarchical_terms();
     882
     883        // Case where hierarchical is false
     884        $terms = get_terms( 'category', array(
     885            'hierarchical' => false,
     886            'child_of' => $initial_terms['one_term']['term_id']
     887        ) );
     888
     889        // Verify that there are no children
     890        $this->assertEquals( 0, count( $terms ) );
     891    }
     892
     893    public function test_hierarchical_true_with_child_of_should_return_grandchildren() {
     894        $initial_terms = $this->create_hierarchical_terms();
     895
     896        // Case where hierarchical is true
     897        $terms = get_terms( 'category', array(
     898            'hierarchical' => true,
     899            'child_of' => $initial_terms['one_term']['term_id']
     900        ) );
     901
     902        $expected = array(
     903            $initial_terms['two_term']['term_id'],
     904            $initial_terms['three_term']['term_id'],
     905            $initial_terms['five_term']['term_id'],
     906            $initial_terms['six_term']['term_id'],
     907        );
     908        $actual = wp_list_pluck( $terms, 'term_id' );
     909        $this->assertEqualSets( $expected, $actual );
     910    }
     911
     912    public function test_parent_should_override_child_of() {
     913        $initial_terms = $this->create_hierarchical_terms();
     914
     915        $terms = get_terms( 'category', array(
     916            'hide_empty' => false,
     917            'child_of' => $initial_terms['one_term']['term_id'],
     918            'parent' => $initial_terms['one_term']['term_id']
     919        ) );
     920
     921        // Verify that parent takes precedence over child_of and returns only direct children.
     922        $expected = array(
     923            $initial_terms['two_term']['term_id'],
     924            $initial_terms['five_term']['term_id'],
     925            $initial_terms['seven_term']['term_id']
     926        );
     927        $actual = wp_list_pluck( $terms, 'term_id' );
     928        $this->assertEqualSets( $expected, $actual );
     929    }
     930
     931    public function test_hierarchical_false_parent_should_override_child_of() {
     932        $initial_terms = $this->create_hierarchical_terms();
     933
     934        // Case where hierarchical is false
     935        $terms = get_terms( 'category', array(
     936            'hierarchical' => false,
     937            'child_of' => $initial_terms['one_term']['term_id'],
     938            'parent' => $initial_terms['one_term']['term_id']
     939        ) );
     940
     941        // hierarchical=false means that descendants are not fetched.
     942        $this->assertEquals( 0, count( $terms ) );
     943    }
     944
     945    /**
     946     * @ticket 29185
     947     */
     948    public function test_hierarchical_true_parent_overrides_child_of() {
     949        $initial_terms = $this->create_hierarchical_terms();
     950
     951        // Case where hierarchical is true
     952        $terms = get_terms( 'category', array(
     953            'hierarchical' => true,
     954            'child_of' => $initial_terms['one_term']['term_id'],
     955            'parent' => $initial_terms['one_term']['term_id'],
     956        ) );
     957
     958        // Verify that parent takes precedence over child_of
     959        $expected = array(
     960            $initial_terms['two_term']['term_id'],
     961            $initial_terms['five_term']['term_id'],
     962        );
     963        $actual = wp_list_pluck( $terms, 'term_id' );
     964        $this->assertEqualSets( $expected, $actual );
     965    }
     966
    823967    protected function create_hierarchical_terms_and_posts() {
    824 
    825968        $terms = array();
    826969
     
    837980        return $terms;
    838981    }
     982
     983    protected function create_hierarchical_terms() {
     984        // Set up the following hierarchy:
     985        // - One
     986        //   - Two
     987        //     - Three (1)
     988        //     - Four
     989        //   - Five
     990        //     - Six (1)
     991        //   - Seven
     992        $one_term = wp_insert_term(
     993            'One',
     994            'category'
     995        );
     996        $two_term = wp_insert_term(
     997            'Two',
     998            'category',
     999            array(
     1000                'parent' => $one_term['term_id']
     1001            )
     1002        );
     1003        $three_term = wp_insert_term(
     1004            'Three',
     1005            'category',
     1006            array(
     1007                'parent' => $two_term['term_id']
     1008            )
     1009        );
     1010        $four_term = wp_insert_term(
     1011            'Four',
     1012            'category',
     1013            array(
     1014                'parent' => $two_term['term_id']
     1015            )
     1016        );
     1017        $five_term = wp_insert_term(
     1018            'Five',
     1019            'category',
     1020            array(
     1021                'parent' => $one_term['term_id']
     1022            )
     1023        );
     1024        $six_term = wp_insert_term(
     1025            'Six',
     1026            'category',
     1027            array(
     1028                'parent' => $five_term['term_id']
     1029            )
     1030        );
     1031        $seven_term = wp_insert_term(
     1032            'Seven',
     1033            'category',
     1034            array(
     1035                'parent' => $one_term['term_id']
     1036            )
     1037        );
     1038
     1039        // Ensure child terms are not empty
     1040        $first_post_id = $this->factory->post->create();
     1041        $second_post_id = $this->factory->post->create();
     1042        wp_set_post_terms( $first_post_id, array( $three_term['term_id'] ), 'category' );
     1043        wp_set_post_terms( $second_post_id, array( $six_term['term_id'] ), 'category' );
     1044
     1045        return array(
     1046            'one_term' => $one_term,
     1047            'two_term' => $two_term,
     1048            'three_term' => $three_term,
     1049            'four_term' => $four_term,
     1050            'five_term' => $five_term,
     1051            'six_term' => $six_term,
     1052            'seven_term' => $seven_term
     1053        );
     1054    }
    8391055}
Note: See TracChangeset for help on using the changeset viewer.