1

I'm currently trying to assign a custom taxonomy to a WooCommerce product via the REST API. I created this custom taxonomy named "editoriales" using JetEngine and have activated the "Is Hierachical" and "Show in REST API" options.

When I create a new product via POST, I'm trying to assign the taxonomy as follows:

{
    ...
    "editoriales": [1055],
    ...
}

Where 1055 is the term_id of the taxonomy I want to assign to the product. However, this is not working - the product is created, but without the "editoriales" taxonomy assigned to it.

Furthermore, when I try to update an existing product via PUT and assign the "editoriales" taxonomy, it still doesn't work:

{
    "product": {
        "editoriales": [1055]
    }
}

Also tried with this code in the functions.php file, but got Error 500.

// Registro de la API para la taxonomía personalizada "editoriales"
add_action( 'rest_api_init', 'register_rest_field_for_custom_taxonomy_editoriales' );

function register_rest_field_for_custom_taxonomy_editoriales() {
    register_rest_field('product', "editoriales", array(
        'get_callback'    => 'product_get_callback',
        'update_callback' => 'product_update_callback',
        'schema' => null,
    ));
}

// Obtener los registros de la taxonomía en la REST API de WooCommerce
function product_get_callback($post, $attr, $request, $object_type) {
    $terms = array();

    // Obtener los términos
    foreach (wp_get_post_terms($post['id'], 'editoriales') as $term) {
        $terms[] = array(
            'term_id' => $term->term_id,
            'name'    => $term->name,
            'slug'    => $term->slug
        );
    }

    return $terms;
}

// Actualizar los registros de la taxonomía en la REST API de WooCommerce
function product_update_callback($values, $post, $attr, $request, $object_type) {   
    // ID del producto
    $postId = $post->get_id();

    // Ejemplo: $values = [1055];                

    // Asignar los términos
    wp_set_object_terms($postId, $values, 'editoriales');
}

I made a GET request to a product that already has the "editoriales" taxonomy assigned, and I can see the taxonomy data in the response, with term_id as the identifier.

Has anyone else encountered this problem before? Any ideas why I can't assign my custom taxonomy to the product when I create or update it via the WooCommerce REST API? Any help or guidance would be appreciated.

Peter Palmer
  • 726
  • 11
  • 18

1 Answers1

0

Answer

It seems yI was on the right track. The problem might be related to the way I was trying to register my custom taxonomy ("editoriales") with the REST API. I also mentioned I want to extend my API to include another custom taxonomy, "autores". I will provide a solution that caters to both of these needs.

This code extends the WooCommerce REST API to handle two custom taxonomies, 'editoriales' and 'autores'. You can add this to your functions.php file:

// Add the 'editoriales' and 'autores' taxonomies to the WooCommerce API.
function custom_wc_rest_product_object_type($types) {
    $types[] = 'editoriales';
    $types[] = 'autores';
    return $types;
}
add_filter('woocommerce_rest_product_object_type', 'custom_wc_rest_product_object_type');

// GET Endpoint to get 'editoriales' and 'autores' of a specific product.
add_action('rest_api_init', function () {
    register_rest_route('wc/v3', 'products/(?P<id>\d+)/editoriales', array(
        'methods' => 'GET',
        'callback' => function ($data) {
            $editoriales = get_the_terms($data['id'], 'editoriales');
            return (is_wp_error($editoriales) || empty($editoriales)) ? null : $editoriales;
        },
    ));
    register_rest_route('wc/v3', 'products/(?P<id>\d+)/autores', array(
        'methods' => 'GET',
        'callback' => function ($data) {
            $autores = get_the_terms($data['id'], 'autores');
            return (is_wp_error($autores) || empty($autores)) ? null : $autores;
        },
    ));
});

// POST Endpoint to create a new product with 'editoriales' and 'autores'.
add_action('rest_api_init', function () {
    register_rest_route('wc/v3', 'products', array(
        'methods' => 'POST',
        'callback' => function ($data) {
            $product_id = wp_insert_post(array(
                'post_title' => $data['name'],
                'post_type' => 'product',
                'post_status' => 'publish',
            ));
            wp_set_object_terms($product_id, $data['editoriales'], 'editoriales');
            wp_set_object_terms($product_id, $data['autores'], 'autores');
            return new WP_REST_Response($product_id, 201);
        },
    ));
});

// PUT Endpoint to update an existing product with 'editoriales' and 'autores'.
add_action('rest_api_init', function () {
    register_rest_route('wc/v3', 'products/(?P<id>\d+)', array(
        'methods' => 'PUT',
        'callback' => function ($data) {
            wp_update_post(array(
                'ID' => $data['id'],
                'post_title' => $data['name'],
            ));
            $editoriales_ids = array_map(function ($editorial) {
                return $editorial['id'];
            }, $data['editoriales']);
            wp_set_object_terms($data['id'], $editoriales_ids, 'editoriales');
            $autores_ids = array_map(function ($autor) {
                return $autor['id'];
            }, $data['autores']);
            wp_set_object_terms($data['id'], $autores_ids, 'autores');
            return new WP_REST_Response(null, 204);
        },
    ));
});

// Modify the WooCommerce product API response to include 'editoriales' and 'autores' in the product data.
function custom_product_api_response($response, $product, $request){
    if (empty($response->data)) {
        return $response;
    }

    $editoriales = wp_get_post_terms($product->get_id(), 'editoriales', ['fields' => 'names']);
    $response->data['editoriales'] = $editoriales;

    $autores = wp_get_post_terms($product->get_id(), 'autores', ['fields' => 'names']);
    $response->data['autores'] = $autores;

    return $response;
}
add_filter('woocommerce_rest_prepare_product_object', 'custom_product_api_response', 20, 3);

Remember, the code assumes you've already registered the taxonomies 'editoriales' and 'autores' for WooCommerce products elsewhere in your code.

Peter Palmer
  • 726
  • 11
  • 18