From 8663c3b5f9f38229f390438363987a517f03b380 Mon Sep 17 00:00:00 2001 From: roykho Date: Tue, 13 Apr 2021 19:43:04 -0700 Subject: [PATCH] Assign default category to products closes #29540 --- includes/admin/class-wc-admin-taxonomies.php | 17 +++++++++ .../class-wc-rest-terms-controller.php | 7 ++++ includes/wc-term-functions.php | 35 +++++++++++++++++++ includes/wc-update-functions.php | 31 ++++------------ 4 files changed, 65 insertions(+), 25 deletions(-) diff --git a/includes/admin/class-wc-admin-taxonomies.php b/includes/admin/class-wc-admin-taxonomies.php index 82651dbc65d..68db2ac2ee7 100644 --- a/includes/admin/class-wc-admin-taxonomies.php +++ b/includes/admin/class-wc-admin-taxonomies.php @@ -49,6 +49,7 @@ class WC_Admin_Taxonomies { // Category/term ordering. add_action( 'create_term', array( $this, 'create_term' ), 5, 3 ); + add_action( 'delete_product_cat', array( $this, 'maybe_assign_default_product_cat' ) ); // Add form. add_action( 'product_cat_add_form_fields', array( $this, 'add_category_fields' ) ); @@ -110,6 +111,22 @@ class WC_Admin_Taxonomies { wc_deprecated_function( 'delete_term', '3.6' ); } + /** + * Assigns default product category. This is done when the product + * has no assgined product category. + * + * @since 5.3 + * @return void + */ + public function maybe_assign_default_product_cat() { + /* + * When a product category is deleted, we need to check + * if the product has no categories assigned. Then assign + * it a default category. + */ + _wc_maybe_assign_default_product_cat(); + } + /** * Category thumbnail fields. */ diff --git a/includes/rest-api/Controllers/Version3/class-wc-rest-terms-controller.php b/includes/rest-api/Controllers/Version3/class-wc-rest-terms-controller.php index f434ef60b00..a6fc7b9524e 100644 --- a/includes/rest-api/Controllers/Version3/class-wc-rest-terms-controller.php +++ b/includes/rest-api/Controllers/Version3/class-wc-rest-terms-controller.php @@ -563,6 +563,13 @@ abstract class WC_REST_Terms_Controller extends WC_REST_Controller { return new WP_Error( 'woocommerce_rest_cannot_delete', __( 'The resource cannot be deleted.', 'woocommerce' ), array( 'status' => 500 ) ); } + /* + * When a product category is deleted, we need to check + * if the product has no categories assigned. Then assign + * it a default category. + */ + _wc_maybe_assign_default_product_cat(); + /** * Fires after a single term is deleted via the REST API. * diff --git a/includes/wc-term-functions.php b/includes/wc-term-functions.php index c6fd42ab966..ba6ab629b11 100644 --- a/includes/wc-term-functions.php +++ b/includes/wc-term-functions.php @@ -689,3 +689,38 @@ function _wc_recount_terms_by_product( $product_id = '' ) { _wc_term_recount( $product_tags, get_taxonomy( 'product_tag' ), false, false ); } } + +/** + * Assigns default product category for products + * that have no categories. + * + * @since 5.3 + * @return void + */ +function _wc_maybe_assign_default_product_cat() { + global $wpdb; + + $default_category = get_option( 'default_product_cat', 0 ); + + if ( $default_category ) { + $wpdb->query( + $wpdb->prepare( + "INSERT INTO {$wpdb->term_relationships} (object_id, term_taxonomy_id) + SELECT DISTINCT posts.ID, %s FROM {$wpdb->posts} posts + LEFT JOIN + ( + SELECT object_id FROM {$wpdb->term_relationships} term_relationships + LEFT JOIN {$wpdb->term_taxonomy} term_taxonomy ON term_relationships.term_taxonomy_id = term_taxonomy.term_taxonomy_id + WHERE term_taxonomy.taxonomy = 'product_cat' + ) AS tax_query + ON posts.ID = tax_query.object_id + WHERE posts.post_type = 'product' + AND tax_query.object_id IS NULL", + $default_category + ) + ); + wp_cache_flush(); + delete_transient( 'wc_term_counts' ); + wp_update_term_count_now( array( $default_category ), 'product_cat' ); + } +} diff --git a/includes/wc-update-functions.php b/includes/wc-update-functions.php index 439095d5482..c6b8ed58102 100644 --- a/includes/wc-update-functions.php +++ b/includes/wc-update-functions.php @@ -1567,31 +1567,12 @@ function wc_update_330_webhooks() { * Assign default cat to all products with no cats. */ function wc_update_330_set_default_product_cat() { - global $wpdb; - - $default_category = get_option( 'default_product_cat', 0 ); - - if ( $default_category ) { - $wpdb->query( - $wpdb->prepare( - "INSERT INTO {$wpdb->term_relationships} (object_id, term_taxonomy_id) - SELECT DISTINCT posts.ID, %s FROM {$wpdb->posts} posts - LEFT JOIN - ( - SELECT object_id FROM {$wpdb->term_relationships} term_relationships - LEFT JOIN {$wpdb->term_taxonomy} term_taxonomy ON term_relationships.term_taxonomy_id = term_taxonomy.term_taxonomy_id - WHERE term_taxonomy.taxonomy = 'product_cat' - ) AS tax_query - ON posts.ID = tax_query.object_id - WHERE posts.post_type = 'product' - AND tax_query.object_id IS NULL", - $default_category - ) - ); - wp_cache_flush(); - delete_transient( 'wc_term_counts' ); - wp_update_term_count_now( array( $default_category ), 'product_cat' ); - } + /* + * When a product category is deleted, we need to check + * if the product has no categories assigned. Then assign + * it a default category. + */ + _wc_maybe_assign_default_product_cat(); } /**