WordPress.org

Make WordPress Core

Ticket #38280: 38280.4.diff

File 38280.4.diff, 9.8 KB (added by desrosj, 3 years ago)
  • src/wp-includes/taxonomy.php

     
    28972897        return true;
    28982898}
    28992899
     2900/**
     2901 * Retrieves the term count for a specific object type.
     2902 *
     2903 * @param int    $term_id Term ID.
     2904 * @param string $taxonomy Taxonomy name.
     2905 * @param string $object_type Object type.
     2906 *
     2907 * @return WP_Error|bool|int WP_Error if invalid taxonomy is passed.
     2908 *                           False if object is not in taxonomy.
     2909 *                           Object term count otherwise.
     2910 */
     2911function wp_get_term_count_for_object_type( $term_id, $taxonomy, $object_type ) {
     2912        if ( ! taxonomy_exists( $taxonomy ) ) {
     2913                return new WP_Error( 'invalid_taxonomy', __( 'Invalid taxonomy.' ) );
     2914        }
     2915
     2916        if ( ! is_object_in_taxonomy( $object_type, $taxonomy ) ) {
     2917                return false;
     2918        }
     2919
     2920        $term = get_term( $term_id, $taxonomy );
     2921
     2922        if ( 0 === $term->count ) {
     2923                return 0;
     2924        }
     2925
     2926        $taxonomy_object = get_taxonomy( $taxonomy );
     2927
     2928        if ( 1 < count( $taxonomy_object->object_type ) ) {
     2929                if ( $term_object_count = get_term_meta( $term_id, '_wp_object_count_' . $object_type, true ) ) {
     2930                        return (int) $term_object_count;
     2931                } else {
     2932                        // When a count for an object type does not exist, if any other meta caches exist we can assume 0.
     2933                        foreach ( $taxonomy_object->object_type as $type ) {
     2934                                if ( $test_meta = get_term_meta( $term_id, '_wp_object_count_' . $type, true ) ) {
     2935                                        return 0;
     2936                                }
     2937                        }
     2938
     2939                        // No other meta caches existed. Count and try again.
     2940                        if ( wp_update_term_count_now( array( $term_id ), $taxonomy ) ) {
     2941                                return wp_get_term_count_for_object_type( $term_id, $taxonomy, $object_type );
     2942                        }
     2943                }
     2944        } else {
     2945                return $term->count;
     2946        }
     2947}
     2948
    29002949//
    29012950// Cache
    29022951//
     
    33723421
    33733422        $object_types = (array) $taxonomy->object_type;
    33743423
    3375         foreach ( $object_types as &$object_type )
     3424        foreach ( $object_types as &$object_type ) {
    33763425                list( $object_type ) = explode( ':', $object_type );
     3426        }
    33773427
    33783428        $object_types = array_unique( $object_types );
    33793429
     
    33823432                $check_attachments = true;
    33833433        }
    33843434
    3385         if ( $object_types )
     3435        if ( $object_types ) {
    33863436                $object_types = esc_sql( array_filter( $object_types, 'post_type_exists' ) );
     3437        }
    33873438
    33883439        foreach ( (array) $terms as $term ) {
    33893440                $count = 0;
    33903441
     3442                $term_count_meta = array();
     3443
     3444                if ( $object_types ) {
     3445                        foreach ( $object_types as $type ) {
     3446                                $current_count = (int) $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(*) FROM $wpdb->term_relationships, $wpdb->posts WHERE $wpdb->posts.ID = $wpdb->term_relationships.object_id AND post_status = 'publish' AND post_type = %s AND term_taxonomy_id = %d", $type, $term ) );
     3447
     3448                                $count += $current_count;
     3449                                $term_count_meta[ $type ] = $current_count;
     3450                        }
     3451                }
     3452
    33913453                // Attachments can be 'inherit' status, we need to base count off the parent's status if so.
    3392                 if ( $check_attachments )
    3393                         $count += (int) $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(*) FROM $wpdb->term_relationships, $wpdb->posts p1 WHERE p1.ID = $wpdb->term_relationships.object_id AND ( post_status = 'publish' OR ( post_status = 'inherit' AND post_parent > 0 AND ( SELECT post_status FROM $wpdb->posts WHERE ID = p1.post_parent ) = 'publish' ) ) AND post_type = 'attachment' AND term_taxonomy_id = %d", $term ) );
     3454                if ( $check_attachments ) {
     3455                        $attachment_count = (int) $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(*) FROM $wpdb->term_relationships, $wpdb->posts p1 WHERE p1.ID = $wpdb->term_relationships.object_id AND ( post_status = 'publish' OR ( post_status = 'inherit' AND post_parent > 0 AND ( SELECT post_status FROM $wpdb->posts WHERE ID = p1.post_parent ) = 'publish' ) ) AND post_type = 'attachment' AND term_taxonomy_id = %d", $term ) );
    33943456
    3395                 if ( $object_types )
    3396                         $count += (int) $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(*) FROM $wpdb->term_relationships, $wpdb->posts WHERE $wpdb->posts.ID = $wpdb->term_relationships.object_id AND post_status = 'publish' AND post_type IN ('" . implode("', '", $object_types ) . "') AND term_taxonomy_id = %d", $term ) );
     3457                        $count += $attachment_count;
     3458                        $term_count_meta['attachment'] = $attachment_count;
    33973459
     3460                        // Re-add attachment so the meta gets saved below.
     3461                        $object_types[] = 'attachment';
     3462                }
     3463
     3464                // Save individual counts for each object type in term meta.
     3465                if ( 1 < count( $term_count_meta ) ) {
     3466                        foreach ( $object_types as $type ) {
     3467                                if ( empty( $term_count_meta[ $type ] ) ) {
     3468                                        delete_term_meta( $term, '_wp_object_count_' . $type );
     3469                                } else {
     3470                                        update_term_meta( $term, '_wp_object_count_' . $type, (int) $term_count_meta[ $type ] );
     3471                                }
     3472                        }
     3473                } else {
     3474                        foreach ( $object_types as $type ) {
     3475                                delete_term_meta( $term, '_wp_object_count_' . $type );
     3476                        }
     3477                }
     3478
    33983479                /** This action is documented in wp-includes/taxonomy.php */
    33993480                do_action( 'edit_term_taxonomy', $term, $taxonomy->name );
    34003481                $wpdb->update( $wpdb->term_taxonomy, compact( 'count' ), array( 'term_taxonomy_id' => $term ) );
  • tests/phpunit/tests/term/getTerms.php

     
    228228                ), $terms_id_slug );
    229229        }
    230230
    231         /**
     231        /**
    232232         * @ticket 11823
    233          */
     233         */
    234234        function test_get_terms_include_exclude() {
    235235                global $wpdb;
    236236
     
    22192219                $this->assertNotEquals( 'foo', $found );
    22202220        }
    22212221
     2222        /**
     2223         * @ticket 38280
     2224         */
     2225        public function test_wp_get_term_count_for_object_type_single_object_type() {
     2226                $term_id = self::factory()->term->create( array( 'taxonomy' => 'category' ) );
     2227                $post_id = self::factory()->post->create( array( 'post_type' => 'post' ) );
     2228
     2229                wp_set_object_terms( $post_id, array( $term_id ), 'category' );
     2230
     2231                $this->assertEquals( 1, wp_get_term_count_for_object_type( $term_id, 'category', 'post' ) );
     2232
     2233                $term_object = get_term( $term_id, 'category' );
     2234                $this->assertEquals( 1, $term_object->count );
     2235
     2236                wp_remove_object_terms( $post_id, array( $term_id ), 'category' );
     2237
     2238                $this->assertEquals( 0, wp_get_term_count_for_object_type( $term_id, 'category', 'post' ) );
     2239        }
     2240
     2241        /**
     2242         * @ticket 38280
     2243         */
     2244        public function test_wp_get_term_count_for_object_type_multiple_object_types() {
     2245                register_post_type( 'wptests_cpt' );
     2246                register_taxonomy_for_object_type( 'category', 'wptests_cpt' );
     2247
     2248                $term_id = self::factory()->term->create( array( 'taxonomy' => 'category' ) );
     2249                $post_id = self::factory()->post->create( array( 'post_type' => 'post' ) );
     2250                $custom_post_id = self::factory()->post->create( array( 'post_type' => 'wptests_cpt' ) );
     2251
     2252                $this->assertEmpty( wp_get_term_count_for_object_type( $term_id, 'category', 'post' ) );
     2253                $this->assertEmpty( wp_get_term_count_for_object_type( $term_id, 'category', 'wptests_cpt' ) );
     2254
     2255                wp_set_object_terms( $post_id, array( $term_id ), 'category' );
     2256
     2257                $this->assertEquals( 1, wp_get_term_count_for_object_type( $term_id, 'category', 'post' ) );
     2258                $this->assertEquals( 0, wp_get_term_count_for_object_type( $term_id, 'category', 'wptests_cpt' ) );
     2259
     2260                wp_set_object_terms( $custom_post_id, array( $term_id ), 'category' );
     2261
     2262                $this->assertEquals( 1, wp_get_term_count_for_object_type( $term_id, 'category', 'post' ) );
     2263                $this->assertEquals( 1, wp_get_term_count_for_object_type( $term_id, 'category', 'wptests_cpt' ) );
     2264
     2265                $term_object = get_term( $term_id, 'category' );
     2266                $this->assertEquals( 2, $term_object->count );
     2267
     2268                wp_remove_object_terms( $custom_post_id, array( $term_id ), 'category' );
     2269
     2270                $this->assertEquals( 1, wp_get_term_count_for_object_type( $term_id, 'category', 'post' ) );
     2271                $this->assertEquals( 0, wp_get_term_count_for_object_type( $term_id, 'category', 'wptests_cpt' ) );
     2272
     2273                wp_remove_object_terms( $post_id, array( $term_id ), 'category' );
     2274
     2275                $this->assertEquals( 0, wp_get_term_count_for_object_type( $term_id, 'category', 'post' ) );
     2276                $this->assertEquals( 0, wp_get_term_count_for_object_type( $term_id, 'category', 'wptests_cpt' ) );
     2277        }
     2278
     2279        /**
     2280         * @ticket 38280
     2281         */
     2282        public function test_wp_get_term_count_for_object_type_multiple_object_types_attachment() {
     2283                register_taxonomy_for_object_type( 'category', 'attachment' );
     2284
     2285                $term_id = self::factory()->term->create( array( 'taxonomy' => 'category' ) );
     2286                $post_id = self::factory()->post->create( array( 'post_type' => 'post' ) );
     2287                $attachment_id = self::factory()->attachment->create_upload_object( DIR_TESTDATA . '/images/canola.jpg', $post_id );
     2288
     2289                $this->assertEmpty( wp_get_term_count_for_object_type( $term_id, 'category', 'post' ) );
     2290                $this->assertEmpty( wp_get_term_count_for_object_type( $term_id, 'category', 'attachment' ) );
     2291
     2292                wp_set_object_terms( $post_id, array( $term_id ), 'category' );
     2293
     2294                $this->assertEquals( 1, wp_get_term_count_for_object_type( $term_id, 'category', 'post' ) );
     2295                $this->assertEquals( 0, wp_get_term_count_for_object_type( $term_id, 'category', 'attachment' ) );
     2296
     2297                wp_set_object_terms( $attachment_id, array( $term_id ), 'category' );
     2298
     2299                $this->assertEquals( 1, wp_get_term_count_for_object_type( $term_id, 'category', 'post' ) );
     2300                $this->assertEquals( 1, wp_get_term_count_for_object_type( $term_id, 'category', 'attachment' ) );
     2301
     2302                $term_object = get_term( $term_id, 'category' );
     2303                $this->assertEquals( 2, $term_object->count );
     2304
     2305                wp_remove_object_terms( $attachment_id, array( $term_id ), 'category' );
     2306
     2307                $this->assertEquals( 1, wp_get_term_count_for_object_type( $term_id, 'category', 'post' ) );
     2308                $this->assertEquals( 0, wp_get_term_count_for_object_type( $term_id, 'category', 'attachment' ) );
     2309
     2310                wp_remove_object_terms( $post_id, array( $term_id ), 'category' );
     2311
     2312                $this->assertEquals( 0, wp_get_term_count_for_object_type( $term_id, 'category', 'post' ) );
     2313                $this->assertEquals( 0, wp_get_term_count_for_object_type( $term_id, 'category', 'attachment' ) );
     2314        }
     2315
    22222316        public static function maybe_filter_count() {
    22232317                return 'foo';
    22242318        }