La verificación de SKU del producto WooCommerce no funciona

5 minutos de lectura

avatar de usuario
Blu3

Estoy tratando de crear y actualizar productos de woocommerce automáticamente desde una API. Creé el punto de partida del complemento y este es mi método que obtiene los productos de la API externa y luego los recorre y crea un producto simple en woocoommerce.

Crea los productos perfectamente bien, sin embargo, si ejecuto el código dos veces, los productos no se actualizan, pero se crea un lote completamente nuevo (los SKU se duplican sin ningún error), parece que el SKU no se reconoce a pesar de que existe y puedo verlo en el tablero del producto y en la interfaz aquí está mi código hasta ahora:

// Activating the function when the plugin is activated
public function __construct()
{
    add_action( 'activated_plugin', array($this, 'add_products_from_api') );
}

public function add_products_from_api() {

    // API products url
    $url="https://example.com/products";

    // Retreiving the products body from api and decoding the json
    $external_products = wp_remote_retrieve_body(wp_remote_get($url));
    $products = json_decode($external_products, true);

    // Products found 
    if (!empty($products)) {

        foreach ($products as $product) {

            // check if SKU already exists
            $product_id = wc_get_product_id_by_sku($product['id']);

            if (!$product_id) {
                $post = [
                    'post_author' => '',
                    'post_content' => $product['description'],
                    'post_status' => "publish",
                    'post_title' => wp_strip_all_tags($product['title']),
                    'post_name' => $product['title'],
                    'post_parent' => '',
                    'post_type' => "product",
                ];

                // Create product
                $product_id = wp_insert_post($post);

                // Set product type
                wp_set_object_terms($product_id, 'simple', 'product_type');

                update_post_meta($product_id, '_sku', $product['id']);
                update_post_meta($product_id, '_price', $product['price']);
                update_post_meta($product_id, '_manage_stock', "yes");
                update_post_meta($product_id, '_stock', $product['rating']['count']);
            } 
            else {
                // Product already exists
                $post = [
                    'ID' => $product_id,
                    'post_title' => $product['title'],
                    'post_content' => $product['description'],
                ];

                $post_id = wp_update_post($post, true);
                if (is_wp_error($post_id)) {
                    $errors = $post_id->get_error_messages();
                    foreach ($errors as $error) {
                        echo $error;
                    }
                }
            }

            update_post_meta($product_id, '_stock', $product['rating']['count']);
            update_post_meta($product_id, '_price', $product['price']);
        }
    }
}

¿Alguien tiene alguna idea de por qué los SKU están presentes pero no se reconocen y los productos siguen duplicándose? Gracias.

  • wc_get_product_id_by_sku devuelve 0 o un sku, por lo que siempre es cierto.

    – Howard E.

    16 de marzo a las 10:25


  • ok, entonces que me recomiendas hacer en este caso?

    – Blu3

    16 de marzo a las 11:50

  • La respuesta negativa es 0. Cambia tu condición.

    – Howard E.

    16 de marzo a las 12:15

  • Lo siento, pero no entiendo qué cambiar, si pudieras, por favor, muéstrame lo que quieres decir.

    – Blu3

    16 de marzo a las 12:28

  • @HowardE, si por casualidad puede mostrarme qué condición cambiar y cómo sería muy útil, gracias.

    – Blu3

    17 de marzo a las 14:16

La respuesta corta será si simplemente reemplazas if( !$product_id ) por esto if (empty($product_id )) resolverá el problema.

Pero una respuesta adecuada y funcional será cuando esté creando un producto en WooCommer, entonces lo haré. recomiendo usar el método CRUD nativo de WooCommerce. Sé que has tomado referencia de mi muy antigua respuesta (Actualizaré esa respuesta en breve.) en ese momento, WooCommer tiene un método incorporado para crear productos, por lo que tenemos que usar métodos WP.

Aquí está el ejemplo de código de trabajo.

<?php

// Activating the function when the plugin is activated
public function __construct()
{
    add_action( 'activated_plugin', array($this, 'add_products_from_api') );
}

public function add_products_from_api() {
    // API products url
    $url="https://fakestoreapi.com/products";

    // Retreiving the products body from api and decoding the json
    $external_products = wp_remote_retrieve_body(wp_remote_get($url));
    $products = json_decode($external_products, true);

    // Products found
    if (!empty($products)) {

        foreach ($products as $product) {

            // check if SKU already exists
            $productID = wc_get_product_id_by_sku($product['id']);

            // Product Do not exists
            if (empty($productID)) {
               $productID = $this->wh_createOrUpdateProduct($product);
            }
            // Product exists with the given SKU
            else {
                $productID = $this->wh_createOrUpdateProduct($product, $productID);
            }
//            echo $productID;
        }
    }
}

protected function wh_createOrUpdateProduct($product, $productId = 0){
    $objProduct = new WC_Product($productId);
    $objProduct->set_sku($product['id']); //Set product SKU.
    $objProduct->set_name($product['title']); //Set product name.
    $objProduct->set_description($product['description']); //Set product description.
    $objProduct->set_description($product['price']); //Set product price.

    // getting product cat ID from name
    $productCatID = $this->wh_getProductCatID($product['category']);


    $objProduct->set_category_ids([$productCatID]); //Set product category ID.
    $objProduct->set_average_rating($product['rating']['rate']); //Set avg. rating of the product.
    $objProduct->set_review_count($product['rating']['count']); //Set total rating of the product.

    $objProduct->set_manage_stock(true); //Set true if you want WooCommerce to manage your stock
    $objProduct->set_stock_quantity($product['rating']['count']); //Set product stock qty.
    $objProduct->set_status('publish'); //Set product status

    $productID = $objProduct->save(); //Saving the data to create new product, it will return product ID.
    return $productID;
}

protected function wh_getProductCatID($catName) {
    $productCatDetails = wp_insert_term($catName, 'product_cat');
    if (is_wp_error($productCatDetails)) {
        if ($productCatDetails->get_error_code() == 'term_exists') {
            $productCatID = $productCatDetails->get_error_data();
        }
        // TO DO: for other error code need to handle it
    } else {
        $productCatID = $productCatDetails['term_id'];
    }
    return $productCatID;
}

ejemplo de código de trabajo

Tenga en cuenta: he probado métodos/funciones individuales, pero no he probado todo el flujo. En segundo lugar, no he manejado la parte de la imagen en el ejemplo de código anterior, que creo que podrá manejar fácilmente.

¡Espero que esto ayude!

Referencia:

  • esto funciona muy bien, el código anterior no funcionaba incluso cuando se cambiaba a if(empty($product_id)) pero a quién le importa😄. Estoy muy contento de haber actualizado a un mejor código, gracias a ti. Sin embargo, también creé una función para descargar y asignar imágenes a cada producto y funciona, pero cada vez que se ejecuta el script, sigue descargando nuevas imágenes, te dejo un comentario en la sala de chat cuando tienes tiempo, muchas gracias de nuevo.

    – Blu3

    26 de marzo a las 18:49


¿Ha sido útil esta solución?

Esta web utiliza cookies propias y de terceros para su correcto funcionamiento y para fines analíticos y para mostrarte publicidad relacionada con sus preferencias en base a un perfil elaborado a partir de tus hábitos de navegación. Al hacer clic en el botón Aceptar, acepta el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. Configurar y más información
Privacidad