Ticket #38280: 38280.8.diff
File 38280.8.diff, 11.4 KB (added by , 5 years ago) |
---|
-
src/wp-includes/taxonomy.php
3091 3091 return true; 3092 3092 } 3093 3093 3094 /** 3095 * Retrieves the term count for a specific object type. 3096 * 3097 * @since 4.9.0 3098 * 3099 * @param int $term_id Term ID. 3100 * @param string $taxonomy Taxonomy name. 3101 * @param string $object_type Object type. 3102 * 3103 * @return WP_Error|bool|int WP_Error if invalid taxonomy is passed. 3104 * False if object is not in taxonomy. 3105 * Object term count otherwise. 3106 */ 3107 function wp_get_term_count_for_object_type( $term_id, $taxonomy, $object_type ) { 3108 if ( ! taxonomy_exists( $taxonomy ) ) { 3109 return new WP_Error( 'invalid_taxonomy', __( 'Invalid taxonomy.' ) ); 3110 } 3111 3112 if ( ! is_object_in_taxonomy( $object_type, $taxonomy ) ) { 3113 return false; 3114 } 3115 3116 $term = get_term( $term_id, $taxonomy ); 3117 3118 if ( 0 === $term->count ) { 3119 return 0; 3120 } 3121 3122 $taxonomy_object = get_taxonomy( $taxonomy ); 3123 3124 if ( 1 >= count( $taxonomy_object->object_type ) ) { 3125 return $term->count; 3126 } 3127 3128 $term_object_count = get_term_meta( $term_id, '_wp_object_count_' . $object_type, true ); 3129 if ( $term_object_count ) { 3130 return (int) $term_object_count; 3131 } 3132 3133 $counted_object_types = (array) get_term_meta( $term_id, '_wp_counted_object_types', true ); 3134 3135 /* 3136 * If the object type has been counted, and other counts exist in meta, we can 3137 * assume this term has 0 relationships for this object type. 3138 */ 3139 if ( in_array( $object_type, $counted_object_types, true ) ) { 3140 foreach ( $taxonomy_object->object_type as $type ) { 3141 if ( $test_meta = get_term_meta( $term_id, '_wp_object_count_' . $type, true ) ) { 3142 return 0; 3143 } 3144 } 3145 } 3146 3147 // No other meta caches existed. Count and try again. 3148 if ( wp_update_term_count_now( array( $term_id ), $taxonomy ) ) { 3149 return wp_get_term_count_for_object_type( $term_id, $taxonomy, $object_type ); 3150 } 3151 } 3152 3094 3153 // 3095 3154 // Cache 3096 3155 // … … 3634 3693 foreach ( (array) $terms as $term ) { 3635 3694 $count = 0; 3636 3695 3696 // Remove previous counts to prevent stale data if an object type is removed from a taxonomy. 3697 $counted_object_types = (array) get_term_meta( $term, '_wp_counted_object_types', true ); 3698 3699 foreach ( $counted_object_types as $o_type ) { 3700 delete_term_meta( $term, '_wp_object_count_' . $o_type ); 3701 } 3702 3703 delete_term_meta( $term, '_wp_counted_object_types' ); 3704 3705 $term_count_meta = array(); 3706 3707 $term_taxonomy_id = (int) $wpdb->get_var( $wpdb->prepare( "SELECT term_taxonomy_id FROM $wpdb->term_taxonomy WHERE term_id = %d", $term ) ); 3708 3709 if ( $object_types ) { 3710 foreach ( $object_types as $type ) { 3711 $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_taxonomy_id ) ); 3712 3713 $count += $current_count; 3714 $term_count_meta[ $type ] = $current_count; 3715 } 3716 } 3717 3637 3718 // Attachments can be 'inherit' status, we need to base count off the parent's status if so. 3638 3719 if ( $check_attachments ) { 3639 $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 ) ); 3720 $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_taxonomy_id ) ); 3721 3722 $count += $attachment_count; 3723 $term_count_meta['attachment'] = $attachment_count; 3724 3725 // Re-add attachment so the meta gets saved below. 3726 $object_types[] = 'attachment'; 3640 3727 } 3641 3728 3642 if ( $object_types ) { 3643 $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 ) ); 3729 // Save individual counts for each object type in term meta. 3730 if ( 1 < count( $term_count_meta ) ) { 3731 foreach ( $object_types as $type ) { 3732 if ( ! empty( $term_count_meta[ $type ] ) ) { 3733 update_term_meta( $term, '_wp_object_count_' . $type, (int) $term_count_meta[ $type ] ); 3734 } 3735 } 3736 3737 update_term_meta( $term, '_wp_counted_object_types', $object_types ); 3738 } else { 3739 foreach ( $object_types as $type ) { 3740 delete_term_meta( $term, '_wp_object_count_' . $type ); 3741 } 3742 3743 delete_term_meta( $term, '_wp_counted_object_types' ); 3644 3744 } 3645 3745 3646 3746 /** This action is documented in wp-includes/taxonomy.php */ 3647 3747 do_action( 'edit_term_taxonomy', $term, $taxonomy->name ); 3648 $wpdb->update( $wpdb->term_taxonomy, compact( 'count' ), array( 'term_taxonomy_id' => $term ) );3748 $wpdb->update( $wpdb->term_taxonomy, compact( 'count' ), array( 'term_taxonomy_id' => $term_taxonomy_id ) ); 3649 3749 3650 3750 /** This action is documented in wp-includes/taxonomy.php */ 3651 3751 do_action( 'edited_term_taxonomy', $term, $taxonomy->name ); -
tests/phpunit/tests/term/getTerms.php
2776 2776 $this->assertNotEquals( 'foo', $found ); 2777 2777 } 2778 2778 2779 /** 2780 * @ticket 38280 2781 */ 2782 public function test_wp_get_term_count_for_object_type_single_object_type() { 2783 $term_id = self::factory()->term->create( array( 'taxonomy' => 'category' ) ); 2784 $post_id = self::factory()->post->create( array( 'post_type' => 'post' ) ); 2785 2786 wp_set_object_terms( $post_id, array( $term_id ), 'category' ); 2787 2788 $this->assertEquals( 1, wp_get_term_count_for_object_type( $term_id, 'category', 'post' ) ); 2789 $this->assertFalse( (bool) get_term_meta( $term_id, '_wp_counted_object_types', true ) ); 2790 2791 $term_object = get_term( $term_id, 'category' ); 2792 $this->assertEquals( 1, $term_object->count ); 2793 2794 wp_remove_object_terms( $post_id, array( $term_id ), 'category' ); 2795 2796 $this->assertEquals( 0, wp_get_term_count_for_object_type( $term_id, 'category', 'post' ) ); 2797 } 2798 2799 /** 2800 * @ticket 38280 2801 */ 2802 public function test_wp_get_term_count_for_object_type_multiple_object_types() { 2803 register_post_type( 'wptests_cpt' ); 2804 register_taxonomy_for_object_type( 'category', 'wptests_cpt' ); 2805 2806 $term_id = self::factory()->term->create( array( 'taxonomy' => 'category' ) ); 2807 $post_id = self::factory()->post->create( array( 'post_type' => 'post' ) ); 2808 $custom_post_id = self::factory()->post->create( array( 'post_type' => 'wptests_cpt' ) ); 2809 2810 $this->assertEquals( 0, wp_get_term_count_for_object_type( $term_id, 'category', 'post' ) ); 2811 $this->assertEquals( 0, wp_get_term_count_for_object_type( $term_id, 'category', 'wptests_cpt' ) ); 2812 $this->assertEmpty( get_term_meta( $term_id, '_wp_counted_object_types', true ) ); 2813 2814 wp_set_object_terms( $post_id, array( $term_id ), 'category' ); 2815 2816 $this->assertEquals( 1, wp_get_term_count_for_object_type( $term_id, 'category', 'post' ) ); 2817 $this->assertEquals( 0, wp_get_term_count_for_object_type( $term_id, 'category', 'wptests_cpt' ) ); 2818 $this->assertEquals( array( 'post', 'wptests_cpt' ), get_term_meta( $term_id, '_wp_counted_object_types', true ) ); 2819 2820 wp_set_object_terms( $custom_post_id, array( $term_id ), 'category' ); 2821 2822 $this->assertEquals( 1, wp_get_term_count_for_object_type( $term_id, 'category', 'post' ) ); 2823 $this->assertEquals( 1, wp_get_term_count_for_object_type( $term_id, 'category', 'wptests_cpt' ) ); 2824 $this->assertEquals( array( 'post', 'wptests_cpt' ), get_term_meta( $term_id, '_wp_counted_object_types', true ) ); 2825 2826 $term_object = get_term( $term_id, 'category' ); 2827 $this->assertEquals( 2, $term_object->count ); 2828 2829 wp_remove_object_terms( $custom_post_id, array( $term_id ), 'category' ); 2830 2831 $this->assertEquals( 1, wp_get_term_count_for_object_type( $term_id, 'category', 'post' ) ); 2832 $this->assertEquals( 0, wp_get_term_count_for_object_type( $term_id, 'category', 'wptests_cpt' ) ); 2833 $this->assertEquals( array( 'post', 'wptests_cpt' ), get_term_meta( $term_id, '_wp_counted_object_types', true ) ); 2834 2835 wp_remove_object_terms( $post_id, array( $term_id ), 'category' ); 2836 2837 $this->assertEquals( 0, wp_get_term_count_for_object_type( $term_id, 'category', 'post' ) ); 2838 $this->assertEquals( 0, wp_get_term_count_for_object_type( $term_id, 'category', 'wptests_cpt' ) ); 2839 $this->assertEquals( array( 'post', 'wptests_cpt' ), get_term_meta( $term_id, '_wp_counted_object_types', true ) ); 2840 } 2841 2842 /** 2843 * @ticket 38280 2844 */ 2845 public function test_wp_get_term_count_for_object_type_multiple_object_types_attachment() { 2846 register_taxonomy_for_object_type( 'category', 'attachment' ); 2847 2848 $term_id = self::factory()->term->create( array( 'taxonomy' => 'category' ) ); 2849 $post_id = self::factory()->post->create( array( 'post_type' => 'post' ) ); 2850 $attachment_id = self::factory()->attachment->create_upload_object( DIR_TESTDATA . '/images/canola.jpg', $post_id ); 2851 2852 $this->assertEmpty( wp_get_term_count_for_object_type( $term_id, 'category', 'post' ) ); 2853 $this->assertEmpty( wp_get_term_count_for_object_type( $term_id, 'category', 'attachment' ) ); 2854 $this->assertEmpty( get_term_meta( $term_id, '_wp_counted_object_types', true ) ); 2855 2856 wp_set_object_terms( $post_id, array( $term_id ), 'category' ); 2857 2858 $this->assertEquals( 1, wp_get_term_count_for_object_type( $term_id, 'category', 'post' ) ); 2859 $this->assertEquals( 0, wp_get_term_count_for_object_type( $term_id, 'category', 'attachment' ) ); 2860 $this->assertEquals( array( 'post', 'attachment' ), get_term_meta( $term_id, '_wp_counted_object_types', true ) ); 2861 2862 wp_set_object_terms( $attachment_id, array( $term_id ), 'category' ); 2863 2864 $this->assertEquals( 1, wp_get_term_count_for_object_type( $term_id, 'category', 'post' ) ); 2865 $this->assertEquals( 1, wp_get_term_count_for_object_type( $term_id, 'category', 'attachment' ) ); 2866 $this->assertEquals( array( 'post', 'attachment' ), get_term_meta( $term_id, '_wp_counted_object_types', true ) ); 2867 2868 $term_object = get_term( $term_id, 'category' ); 2869 $this->assertEquals( 2, $term_object->count ); 2870 2871 wp_remove_object_terms( $attachment_id, array( $term_id ), 'category' ); 2872 2873 $this->assertEquals( 1, wp_get_term_count_for_object_type( $term_id, 'category', 'post' ) ); 2874 $this->assertEquals( 0, wp_get_term_count_for_object_type( $term_id, 'category', 'attachment' ) ); 2875 2876 wp_remove_object_terms( $post_id, array( $term_id ), 'category' ); 2877 2878 $this->assertEquals( 0, wp_get_term_count_for_object_type( $term_id, 'category', 'post' ) ); 2879 $this->assertEquals( 0, wp_get_term_count_for_object_type( $term_id, 'category', 'attachment' ) ); 2880 $this->assertEquals( array( 'post', 'attachment' ), get_term_meta( $term_id, '_wp_counted_object_types', true ) ); 2881 } 2882 2779 2883 public static function maybe_filter_count() { 2780 2884 return 'foo'; 2781 2885 }