phpwordpresswoocommerceproductmarketplace

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


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.


Solution

  • 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