Ticket #38280: 38280.5.diff
File 38280.5.diff, 11.7 KB (added by , 6 years ago) |
---|
-
src/wp-includes/taxonomy.php
2904 2904 return true; 2905 2905 } 2906 2906 2907 /** 2908 * Retrieves the term count for a specific object type. 2909 * 2910 * @param int $term_id Term ID. 2911 * @param string $taxonomy Taxonomy name. 2912 * @param string $object_type Object type. 2913 * 2914 * @return WP_Error|bool|int WP_Error if invalid taxonomy is passed. 2915 * False if object is not in taxonomy. 2916 * Object term count otherwise. 2917 */ 2918 function wp_get_term_count_for_object_type( $term_id, $taxonomy, $object_type ) { 2919 if ( ! taxonomy_exists( $taxonomy ) ) { 2920 return new WP_Error( 'invalid_taxonomy', __( 'Invalid taxonomy.' ) ); 2921 } 2922 2923 if ( ! is_object_in_taxonomy( $object_type, $taxonomy ) ) { 2924 return false; 2925 } 2926 2927 $term = get_term( $term_id, $taxonomy ); 2928 2929 if ( 0 === $term->count ) { 2930 return 0; 2931 } 2932 2933 $taxonomy_object = get_taxonomy( $taxonomy ); 2934 2935 if ( 1 < count( $taxonomy_object->object_type ) ) { 2936 if ( $term_object_count = get_term_meta( $term_id, '_wp_object_count_' . $object_type, true ) ) { 2937 return (int) $term_object_count; 2938 } else { 2939 $counted_object_types = (array) get_term_meta( $term_id, '_wp_counted_object_types', true ); 2940 2941 /** 2942 * If the object type has been counted, and other counts exist in meta, we can 2943 * assume this term has 0 relationships for this object type. 2944 */ 2945 if ( in_array( $object_type, $counted_object_types, true ) ) { 2946 foreach ( $taxonomy_object->object_type as $type ) { 2947 if ( $test_meta = get_term_meta( $term_id, '_wp_object_count_' . $type, true ) ) { 2948 return 0; 2949 } 2950 } 2951 } 2952 2953 // No other meta caches existed. Count and try again. 2954 if ( wp_update_term_count_now( array( $term_id ), $taxonomy ) ) { 2955 return wp_get_term_count_for_object_type( $term_id, $taxonomy, $object_type ); 2956 } 2957 } 2958 } else { 2959 return $term->count; 2960 } 2961 } 2962 2907 2963 // 2908 2964 // Cache 2909 2965 // … … 3379 3435 3380 3436 $object_types = (array) $taxonomy->object_type; 3381 3437 3382 foreach ( $object_types as &$object_type ) 3438 foreach ( $object_types as &$object_type ) { 3383 3439 list( $object_type ) = explode( ':', $object_type ); 3440 } 3384 3441 3385 3442 $object_types = array_unique( $object_types ); 3386 3443 … … 3389 3446 $check_attachments = true; 3390 3447 } 3391 3448 3392 if ( $object_types ) 3449 if ( $object_types ) { 3393 3450 $object_types = esc_sql( array_filter( $object_types, 'post_type_exists' ) ); 3451 } 3394 3452 3395 3453 foreach ( (array) $terms as $term ) { 3396 3454 $count = 0; 3397 3455 3456 // Remove previous counts to prevent stale data if an object type is removed from a taxonomy. 3457 $counted_object_types = (array) get_term_meta( $term, '_wp_counted_object_types', true ); 3458 3459 foreach ( $counted_object_types as $o_type ) { 3460 delete_term_meta( $term, '_wp_object_count_' . $o_type ); 3461 } 3462 3463 delete_term_meta( $term, '_wp_counted_object_types' ); 3464 3465 $term_count_meta = array(); 3466 3467 if ( $object_types ) { 3468 foreach ( $object_types as $type ) { 3469 $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 ) ); 3470 3471 $count += $current_count; 3472 $term_count_meta[ $type ] = $current_count; 3473 } 3474 } 3475 3398 3476 // Attachments can be 'inherit' status, we need to base count off the parent's status if so. 3399 if ( $check_attachments ) 3400 $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 ) ); 3477 if ( $check_attachments ) { 3478 $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 ) ); 3479 3480 $count += $attachment_count; 3481 $term_count_meta['attachment'] = $attachment_count; 3482 3483 // Re-add attachment so the meta gets saved below. 3484 $object_types[] = 'attachment'; 3485 } 3486 3487 // Save individual counts for each object type in term meta. 3488 if ( 1 < count( $term_count_meta ) ) { 3489 foreach ( $object_types as $type ) { 3490 if ( ! empty( $term_count_meta[ $type ] ) ) { 3491 update_term_meta( $term, '_wp_object_count_' . $type, (int) $term_count_meta[ $type ] ); 3492 } 3493 } 3494 3495 update_term_meta( $term, '_wp_counted_object_types', $object_types ); 3496 } else { 3497 foreach ( $object_types as $type ) { 3498 delete_term_meta( $term, '_wp_object_count_' . $type ); 3499 } 3401 3500 3402 if ( $object_types ) 3403 $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 ) ); 3501 delete_term_meta( $term, '_wp_counted_object_types' ); 3502 } 3404 3503 3405 3504 /** This action is documented in wp-includes/taxonomy.php */ 3406 3505 do_action( 'edit_term_taxonomy', $term, $taxonomy->name ); -
tests/phpunit/tests/term/getTerms.php
228 228 ), $terms_id_slug ); 229 229 } 230 230 231 231 /** 232 232 * @ticket 11823 233 233 */ 234 234 function test_get_terms_include_exclude() { 235 235 global $wpdb; 236 236 … … 2219 2219 $this->assertNotEquals( 'foo', $found ); 2220 2220 } 2221 2221 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 $this->assertFalse( (bool) get_term_meta( $term_id, '_wp_counted_object_types', true ) ); 2233 2234 $term_object = get_term( $term_id, 'category' ); 2235 $this->assertEquals( 1, $term_object->count ); 2236 2237 wp_remove_object_terms( $post_id, array( $term_id ), 'category' ); 2238 2239 $this->assertEquals( 0, wp_get_term_count_for_object_type( $term_id, 'category', 'post' ) ); 2240 } 2241 2242 /** 2243 * @ticket 38280 2244 */ 2245 public function test_wp_get_term_count_for_object_type_multiple_object_types() { 2246 register_post_type( 'wptests_cpt' ); 2247 register_taxonomy_for_object_type( 'category', 'wptests_cpt' ); 2248 2249 $term_id = self::factory()->term->create( array( 'taxonomy' => 'category' ) ); 2250 $post_id = self::factory()->post->create( array( 'post_type' => 'post' ) ); 2251 $custom_post_id = self::factory()->post->create( array( 'post_type' => 'wptests_cpt' ) ); 2252 2253 $this->assertEquals( 0, wp_get_term_count_for_object_type( $term_id, 'category', 'post' ) ); 2254 $this->assertEquals( 0, wp_get_term_count_for_object_type( $term_id, 'category', 'wptests_cpt' ) ); 2255 $this->assertEmpty( get_term_meta( $term_id, '_wp_counted_object_types', true ) ); 2256 2257 wp_set_object_terms( $post_id, array( $term_id ), 'category' ); 2258 2259 $this->assertEquals( 1, wp_get_term_count_for_object_type( $term_id, 'category', 'post' ) ); 2260 $this->assertEquals( 0, wp_get_term_count_for_object_type( $term_id, 'category', 'wptests_cpt' ) ); 2261 $this->assertEquals( array( 'post', 'wptests_cpt' ), get_term_meta( $term_id, '_wp_counted_object_types', true ) ); 2262 2263 wp_set_object_terms( $custom_post_id, array( $term_id ), 'category' ); 2264 2265 $this->assertEquals( 1, wp_get_term_count_for_object_type( $term_id, 'category', 'post' ) ); 2266 $this->assertEquals( 1, wp_get_term_count_for_object_type( $term_id, 'category', 'wptests_cpt' ) ); 2267 $this->assertEquals( array( 'post', 'wptests_cpt' ), get_term_meta( $term_id, '_wp_counted_object_types', true ) ); 2268 2269 $term_object = get_term( $term_id, 'category' ); 2270 $this->assertEquals( 2, $term_object->count ); 2271 2272 wp_remove_object_terms( $custom_post_id, array( $term_id ), 'category' ); 2273 2274 $this->assertEquals( 1, wp_get_term_count_for_object_type( $term_id, 'category', 'post' ) ); 2275 $this->assertEquals( 0, wp_get_term_count_for_object_type( $term_id, 'category', 'wptests_cpt' ) ); 2276 $this->assertEquals( array( 'post', 'wptests_cpt' ), get_term_meta( $term_id, '_wp_counted_object_types', true ) ); 2277 2278 wp_remove_object_terms( $post_id, array( $term_id ), 'category' ); 2279 2280 $this->assertEquals( 0, wp_get_term_count_for_object_type( $term_id, 'category', 'post' ) ); 2281 $this->assertEquals( 0, wp_get_term_count_for_object_type( $term_id, 'category', 'wptests_cpt' ) ); 2282 $this->assertEquals( array( 'post', 'wptests_cpt' ), get_term_meta( $term_id, '_wp_counted_object_types', true ) ); 2283 } 2284 2285 /** 2286 * @ticket 38280 2287 */ 2288 public function test_wp_get_term_count_for_object_type_multiple_object_types_attachment() { 2289 register_taxonomy_for_object_type( 'category', 'attachment' ); 2290 2291 $term_id = self::factory()->term->create( array( 'taxonomy' => 'category' ) ); 2292 $post_id = self::factory()->post->create( array( 'post_type' => 'post' ) ); 2293 $attachment_id = self::factory()->attachment->create_upload_object( DIR_TESTDATA . '/images/canola.jpg', $post_id ); 2294 2295 $this->assertEmpty( wp_get_term_count_for_object_type( $term_id, 'category', 'post' ) ); 2296 $this->assertEmpty( wp_get_term_count_for_object_type( $term_id, 'category', 'attachment' ) ); 2297 $this->assertEmpty( get_term_meta( $term_id, '_wp_counted_object_types', true ) ); 2298 2299 wp_set_object_terms( $post_id, array( $term_id ), 'category' ); 2300 2301 $this->assertEquals( 1, wp_get_term_count_for_object_type( $term_id, 'category', 'post' ) ); 2302 $this->assertEquals( 0, wp_get_term_count_for_object_type( $term_id, 'category', 'attachment' ) ); 2303 $this->assertEquals( array( 'post', 'attachment' ), get_term_meta( $term_id, '_wp_counted_object_types', true ) ); 2304 2305 wp_set_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( 1, wp_get_term_count_for_object_type( $term_id, 'category', 'attachment' ) ); 2309 $this->assertEquals( array( 'post', 'attachment' ), get_term_meta( $term_id, '_wp_counted_object_types', true ) ); 2310 2311 $term_object = get_term( $term_id, 'category' ); 2312 $this->assertEquals( 2, $term_object->count ); 2313 2314 wp_remove_object_terms( $attachment_id, array( $term_id ), 'category' ); 2315 2316 $this->assertEquals( 1, wp_get_term_count_for_object_type( $term_id, 'category', 'post' ) ); 2317 $this->assertEquals( 0, wp_get_term_count_for_object_type( $term_id, 'category', 'attachment' ) ); 2318 2319 wp_remove_object_terms( $post_id, array( $term_id ), 'category' ); 2320 2321 $this->assertEquals( 0, wp_get_term_count_for_object_type( $term_id, 'category', 'post' ) ); 2322 $this->assertEquals( 0, wp_get_term_count_for_object_type( $term_id, 'category', 'attachment' ) ); 2323 $this->assertEquals( array( 'post', 'attachment' ), get_term_meta( $term_id, '_wp_counted_object_types', true ) ); 2324 } 2325 2222 2326 public static function maybe_filter_count() { 2223 2327 return 'foo'; 2224 2328 }