WordPress.org

Make WordPress Core

Changeset 43049


Ignore:
Timestamp:
04/30/2018 09:07:16 PM (3 years ago)
Author:
boonebgorges
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.
See #42691.

Location:
trunk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-includes/class-wp-term-query.php

    r42876 r43049  
    679679        if ( false !== $cache ) {
    680680            if ( 'all' === $_fields ) {
    681                 $cache = array_map( 'get_term', $cache );
     681                $cache = $this->populate_terms( $cache );
    682682            }
    683683
     
    811811
    812812        if ( 'all' === $_fields || 'all_with_object_id' === $_fields ) {
    813             $terms = array_map( 'get_term', $terms );
     813            $terms = $this->populate_terms( $terms );
    814814        }
    815815
     
    973973        return $wpdb->prepare( '((t.name LIKE %s) OR (t.slug LIKE %s))', $like, $like );
    974974    }
     975
     976    /**
     977     * Creates an array of term objects from an array of term IDs.
     978     *
     979     * Also discards invalid term objects.
     980     *
     981     * @since 5.0.0
     982     *
     983     * @param array $term_ids Term IDs.
     984     * @return array
     985     */
     986    protected function populate_terms( $term_ids ) {
     987        $terms = array();
     988
     989        if ( ! is_array( $term_ids ) ) {
     990            return $terms;
     991        }
     992
     993        foreach ( $term_ids as $key => $term_id ) {
     994            $term = get_term( $term_id );
     995            if ( $term instanceof WP_Term ) {
     996                $terms[ $key ] = $term;
     997            }
     998        }
     999
     1000        return $terms;
     1001    }
    9751002}
  • trunk/tests/phpunit/tests/term/query.php

    r42343 r43049  
    615615        $this->assertSame( array(), $q->terms );
    616616    }
     617
     618    /**
     619     * @ticket 42691
     620     */
     621    public function test_null_term_object_should_be_discarded() {
     622        register_taxonomy( 'wptests_tax', 'post' );
     623
     624        $terms = self::factory()->term->create_many( 3, array(
     625            'taxonomy' => 'wptests_tax',
     626        ) );
     627
     628        $this->term_id = $terms[1];
     629
     630        add_filter( 'get_term', array( $this, 'filter_term_to_null' ) );
     631        $found = get_terms( array(
     632            'taxonomy'   => 'wptests_tax',
     633            'hide_empty' => false,
     634        ) );
     635        remove_filter( 'get_term', array( $this, 'filter_term_to_null' ) );
     636
     637        $expected = array( $terms[0], $terms[2] );
     638
     639        $this->assertEqualSets( $expected, wp_list_pluck( $found, 'term_id' ) );
     640    }
     641
     642    public function filter_term_to_null( $term ) {
     643        if ( $this->term_id === $term->term_id ) {
     644            return null;
     645        }
     646
     647        return $term;
     648    }
     649
     650    /**
     651     * @ticket 42691
     652     */
     653    public function test_error_term_object_should_be_discarded() {
     654        register_taxonomy( 'wptests_tax', 'post' );
     655
     656        $terms = self::factory()->term->create_many( 3, array(
     657            'taxonomy' => 'wptests_tax',
     658        ) );
     659
     660        $this->term_id = $terms[1];
     661
     662        add_filter( 'get_term', array( $this, 'filter_term_to_wp_error' ) );
     663        $found = get_terms( array(
     664            'taxonomy'   => 'wptests_tax',
     665            'hide_empty' => false,
     666        ) );
     667        remove_filter( 'get_term', array( $this, 'filter_term_to_wp_error' ) );
     668
     669        $expected = array( $terms[0], $terms[2] );
     670
     671        $this->assertEqualSets( $expected, wp_list_pluck( $found, 'term_id' ) );
     672    }
     673
     674    public function filter_term_to_wp_error( $term ) {
     675        if ( $this->term_id === $term->term_id ) {
     676            return new WP_Error( 'foo' );
     677        }
     678
     679        return $term;
     680    }
    617681}
Note: See TracChangeset for help on using the changeset viewer.