Search code examples
woocommercewoocommerce-rest-apiwpml

Is there a hook that precedes Woocommerce API's duplicate SKU check?


I have a site with Woocommerce and WPML + Multilingual Woocommerce installed. My problem is that I try to insert a product as a translation of a previously entered product without being aware of the ID of the main product. If I enter the ID as translation_of it works; both products share the same SKU and the translation has the SKU field disabled, which is how I want it to work. But I don't want to enter translation_of into the data that gets sent to Woocommerce. I want to only use the SKU and then let Wordpress first check if a product with that SKU already exists and replace sku with translation_of if it does.

This is how I went about it:

add_filter('woocommerce_api_create_product_data', '__create_product_data', -100, 2);

function __create_product_data($data, $api) {
    if(isset($data['sku']) && $product_id = wc_get_product_id_by_sku($data['sku'])) {
        $product_id = apply_filters('wpml_object_id', $product_id, 'product');
        $data['translation_of'] = $product_id;
        unset($data['sku']);
    }
    return $data;
}

But it seems to me that execution arrives at this point long after the SKU has been checked, because I noticed that I can return nothing and I still get product_invalid_sku error back. What would be the correct hook or does such a hook even exist?


Solution

  • My own solution:

    add_filter('rest_pre_dispatch', '__rest_pre_dispatch', 10, 3);
    
    function __rest_pre_dispatch($result, $server, $request) {
        $sku = $request->get_param('sku');
    
        if ($sku) {
            $id = wc_get_product_id_by_sku($sku);
            if ($id) {
                $product_id = apply_filters('wpml_object_id', $id, 'product');
                $request->set_param('translation_of', $product_id);
                $request->offsetUnset('sku');
            }
        }
    
        return $result;
    }