Get all products with the same names to change their price in WooCommerce

63 Views Asked by At

I am building a website, and I am using the WFCM plugin to use it as a marketplace. I want to when a price is changed in a product, I want to also change to all the products with the same name. So far I achieved to change the price of all products regardless of the name.

The latest code I used :

add_action('save_post', 'update_prices_by_product_name', 10, 2);

function update_prices_by_product_name($post_id, $post) {
    if ($post->post_type === 'product') {

        $product_name = $post->post_title;
        $new_price = get_post_meta($post_id, '_regular_price', true);
        $related_products = get_posts(array(
            'post_type' => 'product',
            'post_status' => 'publish',
            'posts_per_page' => -1,
            'exclude' => $post_id,
            'post_title' => $product_name,
        ));

        foreach ($related_products as $related_product) {
            $related_product_id = $related_product->ID;

            $update_data = array(
                'ID' => $related_product_id,
                'post_title' => $product_name,
            );
            wp_update_post($update_data);
        }
    }
}

It doesn't work, it changes all products prices. I know I am close, but I need help.

2

There are 2 best solutions below

0
LoicTheAztec On BEST ANSWER

In WordPress WP_Query, the 'post_title' parameter doesn't exist.

But, since WordPress 6.2+, you can use the undocumented search parameter search_columns for 'post_title' column like:

$related_products_ids = get_posts( array(
    'post_type'      => 'product',
    'post_status'    => 'publish',
    'posts_per_page' => -1,
    'exclude'        => $post_id,
    'search_columns' => array('post_title'), // Set search to "post_title" column
    's'              => $post->post_title, // Search string
    'fields'         => 'ids' // Return only products Ids
));

Or you can also use a WC_Product_Query like:

$related_products_ids = wc_get_products( array(
    'status'   => 'publish',
    'limit'    => -1,
    'exclude'  => array( $post_id ),
    'name'     => $post->post_title, 
    'return'   => 'ids', // Return only products Ids
));

Now, your provided code is not really updating the related products price, but their names.

To update the related product price, use the following code replacement instead:

add_action('save_post', 'update_prices_by_product_name', 10, 2);
function update_prices_by_product_name($post_id, $post) {
    if ( $post->post_type === 'product' && isset($_POST['_regular_price']) ) {

        $related_products_ids = get_posts( array(
            'post_type'      => 'product',
            'post_status'    => 'publish',
            'posts_per_page' => -1,
            'exclude'        => $post_id,
            'search_columns' => array('post_title'), // Set search to "post_title" column
            's'              => $post->post_title, // Search string
            'fields'         => 'ids' // Return only products Ids
        ));

        // Loop through related product Ids
        foreach ( $related_products_ids as $_product_id ) {
            // Update regular price
            update_post_meta( $_product_id, '_regular_price', wc_clean( wp_unslash( $_POST['_regular_price'] ) ) );
        }
    }
}

It should work

0
George On

Eventually i made a plugin with this code i used wpdb as @CBroe suggested if anyone has the same question in the future. It doesn't only check the names it checks for a specific name.

add_action('save_post', 'update_prices_by_product_name', 20, 5);
function update_prices_by_product_name($post_id, $post) {
if ($post->post_type === 'product') {
    $product_name = $post->post_title;
    $new_price = get_post_meta($post_id, '_regular_price', true);
global $wpdb;

    $related_product_ids = $wpdb->get_col($wpdb->prepare("
        SELECT ID
        FROM $wpdb->posts
        WHERE post_type = 'product'
        AND post_status = 'publish'
        AND post_title = %s
        AND ID != %d
", $product_name, $post_id));
    foreach ($related_product_ids as $related_product_id) {
        update_post_meta($related_product_id, '_regular_price', $new_price);
update_post_meta($related_product_id, '_price', $new_price);
  }
  }
  }