Ticket #38280: 38280.6.diff
File 38280.6.diff, 12.1 KB (added by , 6 years ago) |
---|
-
src/wp-includes/taxonomy.php
diff --git src/wp-includes/taxonomy.php src/wp-includes/taxonomy.php index 1a0d170848..f89fb7d8d7 100644
function wp_update_term_count_now( $terms, $taxonomy ) { 2916 2916 return true; 2917 2917 } 2918 2918 2919 /** 2920 * Retrieves the term count for a specific object type. 2921 * 2922 * @since 4.9.0 2923 * 2924 * @param int $term_id Term ID. 2925 * @param string $taxonomy Taxonomy name. 2926 * @param string $object_type Object type. 2927 * 2928 * @return WP_Error|bool|int WP_Error if invalid taxonomy is passed. 2929 * False if object is not in taxonomy. 2930 * Object term count otherwise. 2931 */ 2932 function wp_get_term_count_for_object_type( $term_id, $taxonomy, $object_type ) { 2933 if ( ! taxonomy_exists( $taxonomy ) ) { 2934 return new WP_Error( 'invalid_taxonomy', __( 'Invalid taxonomy.' ) ); 2935 } 2936 2937 if ( ! is_object_in_taxonomy( $object_type, $taxonomy ) ) { 2938 return false; 2939 } 2940 2941 $term = get_term( $term_id, $taxonomy ); 2942 2943 if ( 0 === $term->count ) { 2944 return 0; 2945 } 2946 2947 $taxonomy_object = get_taxonomy( $taxonomy ); 2948 2949 if ( 1 >= count( $taxonomy_object->object_type ) ) { 2950 return $term->count; 2951 } 2952 2953 $term_object_count = get_term_meta( $term_id, '_wp_object_count_' . $object_type, true ); 2954 if ( $term_object_count ) { 2955 return (int) $term_object_count; 2956 } 2957 2958 $counted_object_types = (array) get_term_meta( $term_id, '_wp_counted_object_types', true ); 2959 2960 /* 2961 * If the object type has been counted, and other counts exist in meta, we can 2962 * assume this term has 0 relationships for this object type. 2963 */ 2964 if ( in_array( $object_type, $counted_object_types, true ) ) { 2965 foreach ( $taxonomy_object->object_type as $type ) { 2966 if ( $test_meta = get_term_meta( $term_id, '_wp_object_count_' . $type, true ) ) { 2967 return 0; 2968 } 2969 } 2970 } 2971 2972 // No other meta caches existed. Count and try again. 2973 if ( wp_update_term_count_now( array( $term_id ), $taxonomy ) ) { 2974 return wp_get_term_count_for_object_type( $term_id, $taxonomy, $object_type ); 2975 } 2976 } 2977 2919 2978 // 2920 2979 // Cache 2921 2980 // … … function _update_post_term_count( $terms, $taxonomy ) { 3412 3471 3413 3472 $object_types = (array) $taxonomy->object_type; 3414 3473 3415 foreach ( $object_types as &$object_type ) 3474 foreach ( $object_types as &$object_type ) { 3416 3475 list( $object_type ) = explode( ':', $object_type ); 3476 } 3417 3477 3418 3478 $object_types = array_unique( $object_types ); 3419 3479 … … function _update_post_term_count( $terms, $taxonomy ) { 3422 3482 $check_attachments = true; 3423 3483 } 3424 3484 3425 if ( $object_types ) 3485 if ( $object_types ) { 3426 3486 $object_types = esc_sql( array_filter( $object_types, 'post_type_exists' ) ); 3487 } 3427 3488 3428 3489 foreach ( (array) $terms as $term ) { 3429 3490 $count = 0; 3430 3491 3492 // Remove previous counts to prevent stale data if an object type is removed from a taxonomy. 3493 $counted_object_types = (array) get_term_meta( $term, '_wp_counted_object_types', true ); 3494 3495 foreach ( $counted_object_types as $o_type ) { 3496 delete_term_meta( $term, '_wp_object_count_' . $o_type ); 3497 } 3498 3499 delete_term_meta( $term, '_wp_counted_object_types' ); 3500 3501 $term_count_meta = array(); 3502 3503 if ( $object_types ) { 3504 foreach ( $object_types as $type ) { 3505 $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 ) ); 3506 3507 $count += $current_count; 3508 $term_count_meta[ $type ] = $current_count; 3509 } 3510 } 3511 3431 3512 // Attachments can be 'inherit' status, we need to base count off the parent's status if so. 3432 if ( $check_attachments ) 3433 $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 ) ); 3513 if ( $check_attachments ) { 3514 $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 ) ); 3515 3516 $count += $attachment_count; 3517 $term_count_meta['attachment'] = $attachment_count; 3434 3518 3435 if ( $object_types ) 3436 $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 ) ); 3519 // Re-add attachment so the meta gets saved below. 3520 $object_types[] = 'attachment'; 3521 } 3522 3523 // Save individual counts for each object type in term meta. 3524 if ( 1 < count( $term_count_meta ) ) { 3525 foreach ( $object_types as $type ) { 3526 if ( ! empty( $term_count_meta[ $type ] ) ) { 3527 update_term_meta( $term, '_wp_object_count_' . $type, (int) $term_count_meta[ $type ] ); 3528 } 3529 } 3530 3531 update_term_meta( $term, '_wp_counted_object_types', $object_types ); 3532 } else { 3533 foreach ( $object_types as $type ) { 3534 delete_term_meta( $term, '_wp_object_count_' . $type ); 3535 } 3536 3537 delete_term_meta( $term, '_wp_counted_object_types' ); 3538 } 3437 3539 3438 3540 /** This action is documented in wp-includes/taxonomy.php */ 3439 3541 do_action( 'edit_term_taxonomy', $term, $taxonomy->name ); … … function wp_get_split_term( $old_term_id, $taxonomy ) { 3861 3963 * 3862 3964 * @param int $term_id Term ID. 3863 3965 * @return bool Returns false if a term is not shared between multiple taxonomies or 3864 * if splittng shared taxonomy terms is finished. 3966 * if splittng shared taxonomy terms is finished. 3865 3967 */ 3866 3968 function wp_term_is_shared( $term_id ) { 3867 3969 global $wpdb; -
tests/phpunit/tests/term/getTerms.php
diff --git tests/phpunit/tests/term/getTerms.php tests/phpunit/tests/term/getTerms.php index 575e5ca1c0..881c67a467 100644
class Tests_Term_getTerms extends WP_UnitTestCase { 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 … … class Tests_Term_getTerms extends WP_UnitTestCase { 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 }