Make WordPress Core

Ticket #38280: 38280.11.diff

File 38280.11.diff, 5.3 KB (added by ivankristianto, 5 years ago)
  • src/wp-includes/taxonomy.php

     
    30913091        return true;
    30923092}
    30933093
     3094/**
     3095 * Retrieves the term count for a specific object type.
     3096 *
     3097 * @since 5.0.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, false if
     3104 *                           object is not in taxonomy, object term count otherwise.
     3105 */
     3106function wp_get_term_count_for_object_type( $term_id, $taxonomy, $object_type ) {
     3107        if ( ! taxonomy_exists( $taxonomy ) ) {
     3108                return new WP_Error( 'invalid_taxonomy', __( 'Invalid taxonomy.' ) );
     3109        }
     3110
     3111        if ( ! is_object_in_taxonomy( $object_type, $taxonomy ) ) {
     3112                return new WP_Error(
     3113                        'invalid_object_type',
     3114                        __( 'Object type is not in taxonomy.' ),
     3115                        array(
     3116                                'object_type' => $object_type,
     3117                                'taxonomy'    => $taxonomy,
     3118                        )
     3119                );
     3120        }
     3121
     3122        $term = get_term( $term_id, $taxonomy );
     3123
     3124        if ( is_wp_error( $term ) ) {
     3125                return $term;
     3126        }
     3127
     3128        if ( 0 === $term->count ) {
     3129                return 0;
     3130        }
     3131
     3132        $taxonomy_object = get_taxonomy( $taxonomy );
     3133
     3134        if ( 1 >= count( $taxonomy_object->object_type ) ) {
     3135                return $term->count;
     3136        }
     3137
     3138        $term_object_count = get_term_meta( $term_id, '_wp_object_count_' . $object_type, true );
     3139        if ( $term_object_count ) {
     3140                return (int) $term_object_count;
     3141        }
     3142
     3143        $counted_object_types = (array) get_term_meta( $term_id, '_wp_counted_object_types', true );
     3144
     3145        // When the object type is marked counted and no meta key exists, the count is 0.
     3146        if ( in_array( $object_type, $counted_object_types, true ) ) {
     3147                return 0;
     3148        }
     3149
     3150        // Term has not been counted for the object type. Calculate and fetch count.
     3151        wp_update_term_count_now( array( $term->term_taxonomy_id ), $taxonomy );
     3152        return wp_get_term_count_for_object_type( $term_id, $taxonomy, $object_type );
     3153}
     3154
    30943155//
    30953156// Cache
    30963157//
     
    36053666 *
    36063667 * @access private
    36073668 * @since 2.3.0
     3669 * @since 5.0.0 Store term counts on a per object type basis in meta.
    36083670 *
    36093671 * @global wpdb $wpdb WordPress database abstraction object.
    36103672 *
     
    36283690        }
    36293691
    36303692        if ( $object_types ) {
    3631                 $object_types = esc_sql( array_filter( $object_types, 'post_type_exists' ) );
     3693                $object_types = array_filter( $object_types, 'post_type_exists' );
    36323694        }
    36333695
    36343696        foreach ( (array) $terms as $term ) {
    36353697                $count = 0;
    36363698
     3699                $term_id = (int) $wpdb->get_var( $wpdb->prepare( "SELECT term_id FROM $wpdb->term_taxonomy WHERE term_taxonomy_id = %d", $term ) );
     3700
     3701                // Remove previous counts to prevent stale data if an object type is removed from a taxonomy.
     3702                $counted_object_types = (array) get_term_meta( $term_id, '_wp_counted_object_types', true );
     3703
     3704                foreach ( $counted_object_types as $o_type ) {
     3705                        delete_term_meta( $term_id, '_wp_object_count_' . $o_type );
     3706                }
     3707
     3708                delete_term_meta( $term_id, '_wp_counted_object_types' );
     3709
     3710                $term_count_meta = array();
     3711
     3712                if ( $object_types ) {
     3713                        foreach ( $object_types as $type ) {
     3714                                $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 ) );
     3715
     3716                                $count += $current_count;
     3717
     3718                                $term_count_meta[ $type ] = $current_count;
     3719                        }
     3720                }
     3721
    36373722                // Attachments can be 'inherit' status, we need to base count off the parent's status if so.
    36383723                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 ) );
     3724                        $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 ) );
     3725
     3726                        $count += $attachment_count;
     3727
     3728                        $term_count_meta['attachment'] = $attachment_count;
     3729
     3730                        // Re-add attachment so the meta gets saved below.
     3731                        $object_types[] = 'attachment';
    36403732                }
    36413733
    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 ) );
     3734                // Save individual counts for each object type in term meta.
     3735                if ( 1 < count( $term_count_meta ) ) {
     3736                        foreach ( $object_types as $type ) {
     3737                                if ( ! empty( $term_count_meta[ $type ] ) ) {
     3738                                        update_term_meta( $term_id, '_wp_object_count_' . $type, (int) $term_count_meta[ $type ] );
     3739                                }
     3740                        }
     3741
     3742                        update_term_meta( $term_id, '_wp_counted_object_types', $object_types );
    36443743                }
    36453744
    36463745                /** This action is documented in wp-includes/taxonomy.php */