Make WordPress Core

Changeset 43492 for branches/4.9


Ignore:
Timestamp:
07/17/2018 04:27:12 PM (8 years ago)
Author:
SergeyBiryukov
Message:

Taxonomy: Ensure that invalid term objects are discarded in WP_Term_Query.

The get_term() mapping may result in term objects that are null or
WP_Error when plugins use get_term or a related filter. Since null
and error objects are not valid results for a term query, we discard
them.

Props GM_Alex.
Merges [43049] and [43491] to the 4.9 branch.
Fixes #42691.

Location:
branches/4.9
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • branches/4.9

  • branches/4.9/src/wp-includes/class-wp-term-query.php

    r43314 r43492  
    673673                if ( false !== $cache ) {
    674674                        if ( 'all' === $_fields || 'all_with_object_id' === $_fields ) {
    675                                 $cache = array_map( 'get_term', $cache );
     675                                $cache = $this->populate_terms( $cache );
    676676                        }
    677677
     
    805805
    806806                if ( 'all' === $_fields || 'all_with_object_id' === $_fields ) {
    807                         $terms = array_map( 'get_term', $terms );
     807                        $terms = $this->populate_terms( $terms );
    808808                }
    809809
     
    967967                return $wpdb->prepare( '((t.name LIKE %s) OR (t.slug LIKE %s))', $like, $like );
    968968        }
     969
     970        /**
     971         * Creates an array of term objects from an array of term IDs.
     972         *
     973         * Also discards invalid term objects.
     974         *
     975         * @since 4.9.8
     976         *
     977         * @param array $term_ids Term IDs.
     978         * @return array
     979         */
     980        protected function populate_terms( $term_ids ) {
     981                $terms = array();
     982
     983                if ( ! is_array( $term_ids ) ) {
     984                        return $terms;
     985                }
     986
     987                foreach ( $term_ids as $key => $term_id ) {
     988                        $term = get_term( $term_id );
     989                        if ( $term instanceof WP_Term ) {
     990                                $terms[ $key ] = $term;
     991                        }
     992                }
     993
     994                return $terms;
     995        }
    969996}
  • branches/4.9/tests/phpunit/tests/term/query.php

    r43314 r43492  
    507507                $this->assertSame( $expected, $found3 );
    508508        }
     509
     510        /**
     511         * @ticket 42691
     512         */
     513        public function test_null_term_object_should_be_discarded() {
     514                register_taxonomy( 'wptests_tax', 'post' );
     515
     516                $terms = self::factory()->term->create_many( 3, array(
     517                        'taxonomy' => 'wptests_tax',
     518                ) );
     519
     520                $this->term_id = $terms[1];
     521
     522                add_filter( 'get_term', array( $this, 'filter_term_to_null' ) );
     523                $found = get_terms( array(
     524                        'taxonomy'   => 'wptests_tax',
     525                        'hide_empty' => false,
     526                ) );
     527                remove_filter( 'get_term', array( $this, 'filter_term_to_null' ) );
     528
     529                $expected = array( $terms[0], $terms[2] );
     530
     531                $this->assertEqualSets( $expected, wp_list_pluck( $found, 'term_id' ) );
     532        }
     533
     534        public function filter_term_to_null( $term ) {
     535                if ( $this->term_id === $term->term_id ) {
     536                        return null;
     537                }
     538
     539                return $term;
     540        }
     541
     542        /**
     543         * @ticket 42691
     544         */
     545        public function test_error_term_object_should_be_discarded() {
     546                register_taxonomy( 'wptests_tax', 'post' );
     547
     548                $terms = self::factory()->term->create_many( 3, array(
     549                        'taxonomy' => 'wptests_tax',
     550                ) );
     551
     552                $this->term_id = $terms[1];
     553
     554                add_filter( 'get_term', array( $this, 'filter_term_to_wp_error' ) );
     555                $found = get_terms( array(
     556                        'taxonomy'   => 'wptests_tax',
     557                        'hide_empty' => false,
     558                ) );
     559                remove_filter( 'get_term', array( $this, 'filter_term_to_wp_error' ) );
     560
     561                $expected = array( $terms[0], $terms[2] );
     562
     563                $this->assertEqualSets( $expected, wp_list_pluck( $found, 'term_id' ) );
     564        }
     565
     566        public function filter_term_to_wp_error( $term ) {
     567                if ( $this->term_id === $term->term_id ) {
     568                        return new WP_Error( 'foo' );
     569                }
     570
     571                return $term;
     572        }
    509573}
Note: See TracChangeset for help on using the changeset viewer.