us The new post status. * @param string $old_status The previous post status. * @param WP_Post $post The post object. * * @return void */ public function update_on_product_status_changed( string $new_status, string $old_status, WP_Post $post ): void { if ( 'product' !== $post->post_type ) { return; } $product_id = $post->ID; // WordPress uses 'new' as old_status exclusively on the first transition_post_status of a newly inserted post. if ( 'new' === $old_status ) { $this->products_in_creation[ $product_id ] = true; } $is_new_cached = $this->product_count_cache->is_cached( 'product', $new_status ); $is_old_cached = $this->product_count_cache->is_cached( 'product', $old_status ); if ( ! $is_new_cached && ! $is_old_cached ) { return; } // If the status count has already been incremented for this product, skip. if ( ( $this->product_statuses[ $product_id ] ?? null ) === $new_status ) { return; } $previously_tracked = isset( $this->product_statuses[ $product_id ] ); $this->product_statuses[ $product_id ] = $new_status; $was_decremented = $is_old_cached && false !== $this->product_count_cache->decrement( 'product', $old_status ); if ( $is_new_cached ) { $this->product_count_cache->increment( 'product', $new_status ); } // Record old status for creation-time correction only; existing-product decrements are correct and must not be reversed. // If $previously_tracked, an earlier transition already counted the old status — decrement is legitimate. if ( ! $previously_tracked && $was_decremented && ! isset( $this->initial_product_statuses[ $product_id ] ) && isset( $this->products_in_creation[ $product_id ] ) ) { $this->initial_product_statuses[ $product_id ] = $old_status; } elseif ( ( $this->initial_product_statuses[ $product_id ] ?? null ) === $new_status ) { unset( $this->initial_product_statuses[ $product_id ] ); } } /** * Update the cache when a product is permanently deleted. * * @param int $post_id Post ID. * @param WP_Post $post The post object. * * @return void */ public function update_on_product_deleted( int $post_id, WP_Post $post ): void { if ( 'product' === $post->post_type ) { // Reverse any errant decrement from a mid-creation status transition that update_on_new_product will never get to correct. $this->maybe_restore_initial_status_count( $post_id ); $product_status = $post->post_status; if ( $this->product_count_cache->is_cached( 'product', $product_status ) ) { $this->product_count_cache->decrement( 'product', $product_status ); } unset( $this->product_statuses[ $post_id ], $this->products_in_creation[ $post_id ] ); } } /** * Reverses an errant decrement recorded in initial_product_statuses for a given product, if any. * * @param int $product_id Product ID. * * @return void */ private function maybe_restore_initial_status_count( int $product_id ): void { if ( isset( $this->initial_product_statuses[ $product_id ] ) ) { $initial_status = $this->initial_product_statuses[ $product_id ]; unset( $this->initial_product_statuses[ $product_id ] ); if ( $this->product_count_cache->is_cached( 'product', $initial_status ) ) { $this->product_count_cache->increment( 'product', $initial_status ); } } } }