0

We need to update about 15.000 products with a meta_option after a plugin gets activated or after a plugin gets installed.

However, our code does not execute on all products, though the plugin activates fine.

function on_activate_function()
{
    // set all products to csa_stock true
    // getting all products
    $products_ids = get_posts(array(
        'post_type'        => 'product', // or ['product','product_variation'],        
        'post_status'      => 'publish',
        'fields'           => 'ids',
        'meta_query'       => array(array(
            'key'     => '_stock_from_csa',
            'compare' => 'NOT EXISTS',
        ))
    ));

    // Loop through product Ids
    foreach ($products_ids as $product_id) {

        // Get the WC_Product object
        $product = wc_get_product($product_id);

        // Mark product as updated
        $product->update_meta_data('_stock_from_csa', true);

        $product->save();
    }
}

register_activation_hook(__FILE__, 'on_activate_function');

We are using the hook register_activation_hook to execute code on the activation of the plugin.

The idea was to get all post ids based on a meta_query and then loop over the product ids, get each product associated with the id and then update the meta_data.

Considering the large amount of products this might not be the best approach, as in: doing this operation without batches and in a single run.

Is there a better way to update all products? Can it be done directly via SQL instead of doing this in PHP?

2

1 Answer 1

1

Based on Paul's original comment, we moved the code execution to a custom wp-cli command.

Which also allowed us add arguments and change code behaviour based on arguments.

Example code for anyone, including WPML language specification via

global $sitepress;
$sitepress->switch_lang("en");
...
'suppress_filters' => false,
<?php

/**
 * Registers CLI command csa
 * 
 * Allows to update all products with csa related meta options
 */
defined('ABSPATH') || exit;
defined('WP_CLI') || exit;

function update_all_products_with_csa_meta($limit = 100, $meta_option_select = 'stock')
{
    global $sitepress;
    $sitepress->switch_lang("en");

    $meta_option = '_stock_from_csa';
    switch ($meta_option_select) {
        case 'stock':
            $meta_option = '_stock_from_csa';
            break;

        case 'price':
            $meta_option = '_price_from_csa';
            break;

        default:
            $meta_option = '_stock_from_csa';
            break;
    }

    // set all products to csa_stock true
    // getting all products
    while ($products_ids = get_posts(array(
        'numberposts'      => $limit,
        'post_type'        => 'product', 
        'post_status'      => 'publish',
        'fields'           => 'ids',
        'suppress_filters' => false,
        'meta_query'       => array(array(
            'key'     => $meta_option,
            'compare' => 'NOT EXISTS',
        ))
    ))) {
        // Loop through product Ids
        foreach ($products_ids as $product_id) {

            // Get the WC_Product object
            $product = wc_get_product($product_id);

            // Mark product as updated
            $product->update_meta_data($meta_option, 'yes');

            $product->save();
        }
    }
}

function csa_command($args)
{
    $success = false;
    $message = "";
    $type = 'inventory';
    if (!empty($args)) {
        if (isset($args[0])) {
            $type = $args[0];
        }
    }

    switch ($type) {
        case "inventory":
            $success = true;
            $message = "Inventory Flag set";
            update_all_products_with_csa_meta(meta_option_select: 'stock');
            break;
        case "price":
            $success = true;
            $message = "Price Flag set";
            update_all_products_with_csa_meta(meta_option_select: 'price');
            break;
        default:
            $message = "Unknown parameter given.";
            break;
    }
    if ($success) {
        WP_CLI::success($message);
    } else {
        WP_CLI::error($message);
    }
}

WP_CLI::add_command('csa', 'csa_command');

Which can be called like this:

php wp-cli.phar csa foo

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.