Make WordPress Core

Changeset 30107


Ignore:
Timestamp:
10/30/2014 02:11:56 AM (12 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.