3

I am creating posts (variable products) using (wp_insert_post) function. An Example, I have 9 colors, 9 sizes. Which makes 9×9 = 81 total variations for 1 product, which is 81 times below function to be executed.

function create_product_variation( $product_id, $variation_data){

    $product = wc_get_product($product_id);

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

    // Creating the product variation
    $variation_id = wp_insert_post( $variation_post );

    // Get an instance of the WC_Product_Variation object
    $variation = new WC_Product_Variation( $variation_id );

    // Iterating through the variations attributes
    foreach ($variation_data['attributes'] as $attribute => $term_name )
    {
        //Only have 2 attributes, size and color.
        $taxonomy = 'pa_'.$attribute;
        update_post_meta( $variation_id, 'attribute_'.$taxonomy, $term_name );
    }

    // Prices
    $variation->set_price( $variation_data['regular_price'] );
    $variation->set_regular_price( $variation_data['regular_price'] );
    $variation->set_image_id($variation_data['variation_thumbnail_id']);

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

Before running the above code, I encapsulate the loop as below:

$productColors = array("siyah","kirmizi","bordo","haki","beyaz","antrasit","gri-kircilli","sari","lacivert","acik-mavi");
$Sizes = array("5xl","4xl","3xl","xxl","xl","l","m","s","xs");

  wp_defer_term_counting( true );     //Speeding Up Bulk Update Tricks    
  wp_defer_comment_counting( true );  //Speeding Up Bulk Update Tricks    


  foreach ($Sizes as $size){                                        //Create each variation    
      foreach($productColors as $color){    
          $existingVarId = $wpdb->get_col($wpdb->prepare( "SELECT child.post_id
                                                        FROM wp_postmeta AS child
                                                        INNER JOIN wp_postmeta AS parent
                                                          ON child.post_id = parent.post_id
                                                        WHERE child.meta_value = %s and parent.meta_value = %s
                                                        and child.post_id in (select id from wp_posts where post_type = 'product_variation' and post_parent = %d)", array( $size,$color,$post_id )));
          if(!isset($existingVarId[0]))
          {
            $varCount++;
            if (in_array($size, $oversize))
            {
                /* SKIP Beyaz - Kırmızı - Oversize*/
                switch ($model) {

                case "Kadın Tişört": $price = 49;break;
                case "Fermuarlı Kapşonlu Sweatshirt":$price = 134;break;
                case "Kapşonlu Sweatshirt":$price = 119;break;
                case "Sweatshirt":$price = 109;break;
                case "Atlet":$price = 49;break;
                case "Tişört":$price = 65;break;
                }
            }
            else
            {
                switch ($model) {
                case "Kadın Tişört":$price = 49;break;
                case "Fermuarlı Kapşonlu Sweatshirt":$price = 108;break;
                case "Kapşonlu Sweatshirt":$price = 94;break;
                case "Sweatshirt":$price = 84;break;
                case "Atlet":$price = 49;break;
                case "Tişört":$price = 49;break;
                }
            }

            $variation_data =  array(
                'attributes' => array(
                    'beden'  => $size,
                    'renk' => $color,
                ),
                'regular_price' => $price,
                'variation_thumbnail_id' => $productColorsAndIDs[$color],
            );

            create_product_variation( $post_id, $variation_data);
          }
      }

  }

  wp_defer_term_counting( false);         //Speeding Up Bulk Update Tricks
  wp_defer_comment_counting( false );     //Speeding Up Bulk Update Tricks

The creation process is getting slow everytime, even I am on a fast hosting (SiteGround GoGeek hosting plan.) Above code creates 1 product in 1-2 minutes, which is pretty slow, and most of the time, I get gateway 504 errors while running it.

How can I optimize it to work faster ? Deferring seems not affective at all.

  • Why your function has a third parameter called $productColorsAndIDs. Also, can you provide the code that calls this function and where that code is written? – IbrahimShendy Jan 18 at 6:20
  • 1
    @IbrahimShendy , I removed $productColorsAndIDs. I think it was something I forgot to remove. The second one is , I updated where I call the function. You can see the parameters there. I didn't add the whole function, because lots of unnecessary code parts. I wanted to keep it as simple as possible. But let me know if you need more details. – HOY Jan 18 at 20:59
  • 1
    @IbrahimShendy , this function is called by me. This is a plugin and it has an interface in the admin panel of wordpress, where I give the title, and tags of the product, and it creates 1 parent product with the title and then call this function which creates all the variations. It is a simple bulk product creation plugin. – HOY Jan 19 at 9:26
  • 1
    @admcfajn hi, sorry I couldn't follow up with some of the things you said. My app is for creating t-shirt like products. So the arrays are with less than 10 elements. Php is 7.1.26. you wrote create_product_variation look like? but this function is already in the question. I didn't get it. I didn't remove the revisions as I don't have much pages. (I checked with wp-sweep plugin and there are 220 revisions). This won't possibly cause performance issues. For your last sentence, I didn't get it, as all my code is in the question, I use core wordpress functions and not much mysql. – HOY Jan 19 at 9:52
  • 1
    @IbrahimShendy, it is triggered by an html form submit. After I submit the product title from admin panel plugin interface, the create_parent_product function is called and it creates 1 post as parent product (This is not in the question, and not needed as it is a simple wp_insert_post). After that this create_product_variations function is called with the loop. The plugin is quite simple. It doesn't use hooks etc. – HOY Jan 19 at 9:59
0

Siteground has WP-CLI installed and when you have WooCommerce installed it adds its own set of WP-CLI commands. See this: https://github.com/woocommerce/woocommerce/wiki/WC-CLI-Overview

With this your solution would be cleaner as it would go though WC's API.

Maybe you can also check for ideas how WC does it. I remember in the add/edit product UI there was a link to (re)generate variations but there was limit I think.

  • is WP-CLI can bu used with plugins? Is it suitable if I want some end users to use it ? – HOY Jan 19 at 23:51
  • Not directly. It's meant to be used via command line. You can use it to automate things. Well, you could have a simple UI which calls it e.g. if users want to replace something in their WordPress database but you have to plan for things that can go wrong e.g. if they decide to replace their website URL to something else and suddenly and right away their site will stop working – Svetoslav Marinov Jan 23 at 9:29

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.