Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
ac81d2f
Introduce `update_count_by_callback` to WP_Taxonomy.
peterwilsoncc Sep 5, 2020
7e0ee7c
Revised approach.
peterwilsoncc Sep 6, 2020
f86213c
Test to ensure term count is not double incremented.
peterwilsoncc Sep 6, 2020
d0f8135
Pass third argument to taxonomy’s custom function.
peterwilsoncc Sep 6, 2020
1179ae9
I always forget about this rule.
peterwilsoncc Sep 6, 2020
44c0a49
Merge branch 'master' into 40351-term-count-scaling-2
peterwilsoncc Sep 11, 2020
16606de
Delete new test for relocation to new file.
peterwilsoncc Sep 12, 2020
7ab797b
Merge branch 'master' into 40351-term-count-scaling-2
peterwilsoncc Sep 19, 2020
8675d9c
A whole world of failing tests that pass on trunk.
peterwilsoncc Sep 19, 2020
78cd893
Ugh, this is rough but it works.
peterwilsoncc Sep 19, 2020
30afb2d
Account for inherited post statuses.
peterwilsoncc Sep 19, 2020
d913673
Fix a typo.
Oct 12, 2020
fc479ae
Ensure adding/removing a term from a user updates count correctly.
Oct 12, 2020
4367cc2
CS, words and such.
peterwilsoncc Oct 12, 2020
e175d01
Remove incorrect docblocks.
peterwilsoncc Oct 12, 2020
b284222
Ensure DB queries are as expected.
peterwilsoncc Oct 12, 2020
0218198
Update @covers.
peterwilsoncc Oct 12, 2020
ee4c113
Full recounts after partials.
peterwilsoncc Oct 12, 2020
4e7d5ed
Merge branch 'master' into 40351-term-count-scaling-2
peterwilsoncc Oct 14, 2020
c065835
Docblock would be dandy.
peterwilsoncc Oct 14, 2020
6f5dec7
Alignment!!!
peterwilsoncc Oct 14, 2020
c1ffe89
Add missed words.
peterwilsoncc Oct 14, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
64 changes: 42 additions & 22 deletions src/wp-includes/class-wp-taxonomy.php
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,14 @@ final class WP_Taxonomy {
*/
public $update_count_callback;

/**
* Function that will be called when the count is modified by an amount.
*
* @since 5.6.0
* @var callable
*/
public $update_count_by_callback;

/**
* Whether this taxonomy should appear in the REST API.
*
Expand Down Expand Up @@ -277,28 +285,29 @@ public function set_props( $object_type, $args ) {
$args = apply_filters( 'register_taxonomy_args', $args, $this->name, (array) $object_type );

$defaults = array(
'labels' => array(),
'description' => '',
'public' => true,
'publicly_queryable' => null,
'hierarchical' => false,
'show_ui' => null,
'show_in_menu' => null,
'show_in_nav_menus' => null,
'show_tagcloud' => null,
'show_in_quick_edit' => null,
'show_admin_column' => false,
'meta_box_cb' => null,
'meta_box_sanitize_cb' => null,
'capabilities' => array(),
'rewrite' => true,
'query_var' => $this->name,
'update_count_callback' => '',
'show_in_rest' => false,
'rest_base' => false,
'rest_controller_class' => false,
'default_term' => null,
'_builtin' => false,
'labels' => array(),
'description' => '',
'public' => true,
'publicly_queryable' => null,
'hierarchical' => false,
'show_ui' => null,
'show_in_menu' => null,
'show_in_nav_menus' => null,
'show_tagcloud' => null,
'show_in_quick_edit' => null,
'show_admin_column' => false,
'meta_box_cb' => null,
'meta_box_sanitize_cb' => null,
'capabilities' => array(),
'rewrite' => true,
'query_var' => $this->name,
'update_count_callback' => '',
'update_count_by_callback' => '',
'show_in_rest' => false,
'rest_base' => false,
'rest_controller_class' => false,
'default_term' => null,
'_builtin' => false,
);

$args = array_merge( $defaults, $args );
Expand Down Expand Up @@ -411,6 +420,17 @@ public function set_props( $object_type, $args ) {
);
}

// If generic update callback is defined but increment/decrement callback is not.
if (
! empty( $args['update_count_callback'] ) &&
is_callable( $args['update_count_callback'] ) &&
empty( $args['update_count_by_callback'] )
) {
$args['update_count_by_callback'] = function( $tt_ids, $taxonomy, $modify_by ) {
return call_user_func( $args['update_count_callback'], $tt_ids, $taxonomy );
};
}

foreach ( $args as $property_name => $property_value ) {
$this->$property_name = $property_value;
}
Expand Down
90 changes: 88 additions & 2 deletions src/wp-includes/post.php
Original file line number Diff line number Diff line change
Expand Up @@ -4071,6 +4071,8 @@ function wp_insert_post( $postarr, $wp_error = false ) {
clean_post_cache( $post_ID );
}

// Allow term counts to be handled by transitioning post type.
_wp_prevent_term_counting( true );
if ( is_object_in_taxonomy( $post_type, 'category' ) ) {
wp_set_post_categories( $post_ID, $post_category );
}
Expand Down Expand Up @@ -4127,6 +4129,8 @@ function wp_insert_post( $postarr, $wp_error = false ) {
}
}
}
// Restore term counting.
_wp_prevent_term_counting( false );

if ( ! empty( $postarr['meta_input'] ) ) {
foreach ( $postarr['meta_input'] as $field => $value ) {
Expand Down Expand Up @@ -4436,7 +4440,9 @@ function wp_publish_post( $post ) {
if ( ! $default_term_id ) {
continue;
}
_wp_prevent_term_counting( true );
wp_set_post_terms( $post->ID, array( $default_term_id ), $taxonomy );
_wp_prevent_term_counting( false );
}

$wpdb->update( $wpdb->posts, array( 'post_status' => 'publish' ), array( 'ID' => $post->ID ) );
Expand Down Expand Up @@ -7312,11 +7318,91 @@ function wp_queue_posts_for_term_meta_lazyload( $posts ) {
* @param WP_Post $post Post object.
*/
function _update_term_count_on_transition_post_status( $new_status, $old_status, $post ) {
// Update counts for the post's terms.
if ( 'inherit' === $new_status ) {
$new_status = get_post_status( $post->post_parent );
}

if ( 'inherit' === $old_status ) {
$old_status = get_post_status( $post->post_parent );
}

$count_new = 'publish' === $new_status;
$count_old = 'publish' === $old_status;

if ( $count_new === $count_old ) {
// Nothing to do.
return;
}

/*
* Update counts for the post's terms.
*
* Term counting is deferred while incrementing/decrementing the counts to
* reduce the number of database queries required. Once the counts are
* complete the updates are performed if term counting wasn't previously
* deferred.
*/
$previous_deferred_setting = wp_defer_term_counting();
wp_defer_term_counting( true );
foreach ( (array) get_object_taxonomies( $post->post_type ) as $taxonomy ) {
$tt_ids = wp_get_object_terms( $post->ID, $taxonomy, array( 'fields' => 'tt_ids' ) );
wp_update_term_count( $tt_ids, $taxonomy );

if ( empty( $tt_ids ) ) {
// No terms for this taxonomy on object.
continue;
}

$object_types = (array) get_taxonomy( $taxonomy )->object_type;

foreach ( $object_types as &$object_type ) {
list( $object_type ) = explode( ':', $object_type );
}

$object_types = array_unique( $object_types );

if ( ! in_array( $post->post_type, $object_types, true ) ) {
$modify_by = 0;
} elseif ( $count_new && ! $count_old ) {
$modify_by = 1;
} elseif ( $count_old && ! $count_new ) {
$modify_by = -1;
}

if ( 'attachment' === $post->post_type ) {
wp_modify_term_count_by( $tt_ids, $taxonomy, $modify_by );
continue;
}

$check_attachments = array_search( 'attachment', $object_types, true );
if ( false !== $check_attachments ) {
unset( $object_types[ $check_attachments ] );
$check_attachments = true;
}

wp_modify_term_count_by( $tt_ids, $taxonomy, $modify_by );
if ( ! $check_attachments ) {
continue;
}

/*
* For non-attachments, check if there are any attachment children
* with 'inherited' post status -- if so those will need to be counted.
*/
$attachments = get_children(
array(
'post_parent' => $post->ID,
'post_status' => 'inherit',
'post_type' => 'attachment',
'update_post_meta_cache' => false,
'update_post_term_cache' => true,
)
);

foreach ( $attachments as $attachment ) {
_update_term_count_on_transition_post_status( $new_status, $old_status, $attachment );
}
}
wp_defer_term_counting( $previous_deferred_setting );
}

/**
Expand Down
Loading