WooCommerce set attributes programmatically based on variations

Viewed 3071

Need some help with WooCommerce adding variations to product attributes.

I created an attribute called Data ( pa_data ), this attribute stores terms from a custom field added with ACF, this field is a date picker.

I want to create an event that is recurring, and for every recurrence, I want to add a variation with price and stock.

So the process is like this:

  1. Add all ACF fields in an array.

  2. Create Variations with this array.

  3. Add variations to attributes.

The problems is that i don't know how to add variations to the attribute ( pa_data );

Here is how is displaying my attributes https://i.imgur.com/YmbDFlO.png

Here is how i want to be displayed https://i.imgur.com/oDNvuOD.png

$days = array
    array(
        'date' => 'April 02, 2020',
        'price' => '10',
    ),
    array(
        'date' => 'April 03, 2020',
        'price' => '20',
    ),
    array(
        'date' => 'April 04, 2020',
        'price' => '10',
    ),
);


// This method inserts new data into the post after the post is saved
add_action('post_updated', 'ProductUpdate', 10, 3);


 // Callback function after the post is saved
function ProductUpdate($post_id, $post_after, $post_before) {
    if ( $post_after && get_post_type($post_id) == 'product' ) {
        ProductSetVariations( $post_id,  $postDataVariations );
    }
};


function ProductSetVariations($productID, $days ) {

     // Get product object
    $product = wc_get_product($productID);

    foreach ($days as $day ) {

        $date = $day['date'];
        $price = $day['price'];

        $variationPost = array(
            'post_title' => $product->get_title(),
            'post_name' => 'product-' . $productID . '-variation',
            'post_status' => 'publish',
            'post_parent' => $productID,
            'post_type' => 'product_variation',
            'guid' =>  $product->get_permalink()
        );

        // Insert the new variation post;
        $variationID = wp_insert_post($variationPost);

        // Create the new post based on the id
        $variation = new WC_Product_Variation($variationID); 

        $taxonomy = 'pa_data';

        // If term dosent exsist in taxonomy than add it
        if ( !term_exists( $date, $taxonomy )) {
            wp_insert_term( $date, $taxonomy );
        };

        $term_slug = get_term_by('name', $date, $taxonomy)->slug; // Get the term slug  


        $post_term_names =  wp_get_post_terms( $productID, $taxonomy, array('fields' => 'names') );

        if( ! in_array( $date, $post_term_names ) ) {
             wp_set_post_terms( $productID, $date, $taxonomy, true );    
        };

        $term_slug = get_term_by('name', $date, $taxonomy)->slug; // Get the term slug  
        update_post_meta( $variationID, 'attribute_'.$taxonomy, $term_slug );    

        $variation->set_price($price);
        $variation->save(); // Save the data

    } 
};

Resolved!

Solution:

The problem was with WordPress hook 'post_updated', it does save in the database the changes but it doesn't change it in admin.

Here is the solution, for someone who has to update posts from rest api or just post update.

This is only a simple demonstration.

    add_action('woocommerce_update_product', 'ProductUpdate', 10, 3);

    function ProductUpdate($post_id) {
        // Insert Product Attributes
        function insert_product_attributes ($post_id, $variations) {

           $product = wc_get_product($post_id);

            // Set up an array to store the current attributes values.
           $values = array();

           foreach ($variations as $variation)  {
               array_push($values, $variation['date']);          
           }

           wp_set_object_terms($post_id, $values, 'pa_data', true );

           $product_attributes_data = array('pa_data' => 
                array(
                    'name'         => 'pa_data',
                    'position'     => '1',
                    'is_visible'   => '1',
                    'is_variation' => '1',
                    'is_taxonomy'  => '1',
                );
           );

           update_post_meta($post_id, '_product_attributes', $product_attributes_data);  
        };

        function insert_product_variations ($post_id, $variations) {   

            foreach ($variations as $index => $variation) {

            $attribute_term = get_term_by('name', $variation['date'], 'pa_data');

            if ( $variation['date'] == $attribute_term ) {
                return;
            }

            $variation_post = array( // Setup the post data for the variation
                'post_title'  => 'Variation #'.$index.' of data for product#'. $post_id,
                'post_name'   => 'product-'.$post_id.'-variation-'.$index,
                'post_status' => 'publish',
                'post_parent' => $post_id,
                'post_type'   => 'product_variation',
                'guid'        => home_url() . '/?product_variation=product-' . $post_id . '-variation-' . $index
            );

            $variation_post_id = wp_insert_post($variation_post); // Insert the variation

            // We need to insert the slug not the name into the variation post meta
            update_post_meta($variation_post_id, 'attribute_pa_data', $attribute_term->slug);
            update_post_meta($variation_post_id, '_price', $variation['price']);
            update_post_meta($variation_post_id, '_regular_price', $variation['price']);
        }

        function ProductSetVariations($post_id ) {

           // Get product object
           $product = wc_get_product($post_id);

           // Verify if the product is variable or simple product
           if ( !$product->is_type( 'variable' ) ) {
               return;
           };

           $product_data = array(
               'days' => array(
                   array(
                      'sku' => '123SKU',
                      'date' => '1 April 2020',
                      'price' => '10',
                      'stock' => '20'
                   ),
                   array(
                      'sku' => '456SKU',
                      'date' => '2 April 2020',
                      'price' => '10',
                      'stock' => '20'
                   ),
                   array(
                      'sku' => '789SKU',
                      'date' => '3 April 2020',
                      'price' => '10',
                      'stock' => '20'
                )
            )
        );

        insert_product_attributes($post_id, $product_data['days']); // Insert variations passing the new post id & variations
        insert_product_variations($post_id, $product_data['days']); 

   }     
};
0 Answers
Related