2
votes

Using WooCommerce 2.6.1

I cannot delete a product variation for a variable product: the record is still in the database after the ajax call. It seems the ajax call doesn't go through: putting error_log(print_r('remove_variation', true)); doesn't output anything (line 387 in class-wc-ajax.php). The action is added in the constructor of the class. The function public function remove_variation() is just not called.

Has anyone had the same issue, and found a way to make it work?

2
It seems WooCommerce subscriptions plugin is the cause.user3480616
I would suggesting submiting this to Woo Support, so they can fix it.helgatheviking
That was done. The support was unresponsive for a week, and after I posted here, they magically woke up. I ended up debugging myself, though, because they expressed doubts on my conclusions. So I pointed where the the issue is (see my answer below) and now that the hard work is done, they should be able to provide a patch. NOTE: this is a commercial plugin, I shouldn't have been forced to contribute.user3480616

2 Answers

2
votes
/**
* Trash a variation, don't delete it permanently.
*
* This is hooked to
* Hijack WooCommerce's WC_AJAX::remove_variation() "Delete Variation" Trash a variation if it is a subscription variation via ajax function
*/
public static function remove_variations() {

if ( isset( $_POST['variation_id'] ) ) { // removing single variation
error_log("here3");

check_ajax_referer( 'delete-variation', 'security' );
$variation_ids = array( $_POST['variation_id'] );
error_log($_POST['variation_id']);

} else { // removing multiple variations
error_log("here4");

check_ajax_referer( 'delete-variations', 'security' );
$variation_ids = (array) $_POST['variation_ids'];

}

foreach ( $variation_ids as $variation_id ) {

$variation_post = get_post( $variation_id );
error_log(print_r($variation_post, ));

if ( $variation_post && $variation_post->post_type == 'product_variation' ) {

$variation_product = get_product( $variation_id );

if ( $variation_product && $variation_product->is_type( 'subscription_variation' ) ) {
wp_trash_post( $variation_id );
}
}
}
die();
}

remove && $variation_product->is_type( 'subscription_variation' ) to solve the problem of un-deletable variations. http://support.woothemes.com/requests/162693 should provide a patch, issue has been reported.

1
votes

Deleting the variation completely

This is for WooCommerece version 3+ (this code to be put in functions or a custom plugin: not Rest api)

Trashing the variation does not remove the swatch,

it just makes the swatch disabled.(which may be a litle bit embarasing)

If you don't want the variation in your product portfolio anymore, you should delete it. If you have created your variation using recognizable string in the slug (SKU), you can use below code.

function delete_variation($product_cat="all",$Sku__search_string="",$force_delete=false,$document_it=false){
 
    // 'posts_per_page' => -1: goes through all posts
 
     if($product_cat=="all") {    
         $args = array( 
             'post_type'      => 'product',
             'posts_per_page' => -1,          
         );
     } else {
         $args = array( 
             'post_type'      => 'product',
             'posts_per_page' => -1,
             'product_cat'    => $product_cat
         );
     }
    $query = new WP_Query($args);
 
    while ( $query->have_posts() ) {    
         $query->the_post();
         $post_id = get_the_ID();
         $product = wc_get_product($post_id);  
         $product_id = $product->get_id(); //same as post_id
 
         //if you want to see what you are doing put $document_it to true;
                                 
         if($document_it) echo "<br>*********** $product_id ****************<br>";
 
         if($Sku__search_string!="")   { 
 
            $variations = $product->get_available_variations();
 
            foreach($variations as $variation){
 
                 //get the SKU slug of the variation
                 $sku=$variation["sku"]; 
 
                 //get the variation id
                 $variation_id=$variation['variation_id'];
                 if($document_it) echo "varid $variation_id <br>";
 
                 //and then get the actual variation product
                 $var_product=wc_get_product($variation_id);  
                
                 //Check if the search_string is in the slug
 
                 //You can modify this, or modify the $args above,
                 //if you have other criteria
                                  
                if(stripos($sku,$Sku__search_string)>0){  
                     $is_deleted=false; 
 
                     //here the variation is deleted
                     $is_deleted=$var_product->delete($force_delete);
 
                     if($is_deleted){
                         if($document_it) echo "<br>Deleted:  $sku";
                     } else {
                         if($document_it) echo "<br>Not deleted:  $sku";
                     }
                }   
            }        
        }           
    }                   
}    

If you want to delete all variations you may use this