skip to Main Content

I have 4000+ products in multi site where i need to sync them with other sites so i tried with wp query but the problem is whenever i try to do that i got 500 internal server error. May be i need to optimize this script ?

function get_query_data($posts){
    foreach ($posts as $post){
        yield $post;
    }
}
// handle the ajax request
function sync_stock_action_fn()
{
    global $wpdb;
    $wpmis = new WPIMS();
    $paged = isset($_GET['paged']) ? $_GET['paged'] : 1;
    $post_per_page = 200;
    $offset_start = 1;

    $offset = ($paged - 1) * $post_per_page + $offset_start;
    $args     = array('post_type' => 'product', 'posts_per_page' => $post_per_page, 'post_status' => array('publish', 'draft', 'private'), 'paged' => $paged, 'offset' => $offset);
    $total_synced_products = array();
    $products = new WP_Query($args);
    $t_products = count($products->posts);
    $no_of_paginations = ceil($t_products / $post_per_page);
    $count = 0;
    $location = array();
    foreach (get_query_data($products->posts) as $product) {
        $product_id = (int)$product->ID;
        $location = $wpmis->wpmis_get_location($product_id);
        $sku = get_post_meta($product_id, '_sku', true);
  
        $stock = get_post_meta($product_id, '_stock', true);
        $current_blog_id = get_current_blog_id();
        $sites = array(1, 26,27,28);
        $d_sites = array();
        foreach ($sites as $site) {
            if ($site != $current_blog_id) {
                switch_to_blog($site);
                // GET PRODUCT BY SKU
                $p_id = $wpmis->wpmis_get_product_by_sku($sku);

                if ($p_id !== 0 && !empty($p_id)) {
                    wp_set_object_terms($p_id, $location, 'atum_location');
                    update_post_meta($p_id, '_stock', $stock);
                    $total_synced_products[] = $p_id;
                    $d_sites[] = $site;
                }
                restore_current_blog();
            }
        }
        
        $count++;
    }
    $results = array('total_synced' => count($total_synced_products), 'total_products' => $t_products, 'count' => $count, 'sites' => $d_sites);
    echo json_encode($results);
    exit;
}

i tried Generator function get_query_data but it not help me out.

Kindly suggest

3

Answers


  1. Can you not decrease post per page, i think it will help to decrease server memory limit, like you are using $post_per_page = 200; you can decrease it to 50 or so.

    Login or Signup to reply.
  2. There are two ways to do this, you can use an action scheduler plugin https://wordpress.org/plugins/action-scheduler/ and then process 50-100 products in a single batch.

    Another way is using Ajax request where you process 50-100 products at once with a check of memory limit & time limit, if time or memory limit breaks, you break the process and send the current process index in response and ajax will start again after the no of products has been processed.

    Complete Example is here you can find a php and js code here.

    https://github.com/vijayhardaha/wp-bulk-process-template
    
    Login or Signup to reply.
  3. Without directly seeing the code and the data that’s being returned, this is a tough one to say, but my first instinct is to check whether you need that get_query_data function call.. Especially as a ‘yield’, I could see that generator function consuming a lot of memory.

    You’re main loop essentially has 3 foreach loops running recursively, which is probably going to choke out many shared hosting servers.

    Do you have any way of determining WHICH products need synced, rather than all of them? Can you check against a last-modified timestamp or something similar?

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search