vaibhav goti
vaibhav goti

Reputation: 19

Set Global Attributes While Importing Products Programmatically in WooCommerce

I am importing products into WooCommerce programmatically and need to assign global attributes to the products. However, the attributes are always being added as custom product attributes instead of global attributes, even when the attribute name and value already exist in the global attributes configuration.

The global attributes are critical for my product filters to work correctly. If I manually edit a product and click "Save attributes" without making any changes, the custom attributes automatically convert to global attributes. However, I have over 14,000 products, so manual updates are not feasible.

I want the attributes to be assigned as global attributes by default during the import process.

Here is the code I’m using to import products and set attributes:

$product_data = [
    'regular_price' => $row[15] ?? '',
    'sku' => $row[1],
    'category' => $diamond_type,
    'attributes' => [
        'Lab' => $row[2] ?? '',
        'Certificate No' => $row[3] ?? '',
        'Shape' => $row[4] ?? '',
        'Carat' => $row[5] ?? '',
        'Tinge' => $row[21] ?? '',
    ],
    'video_url' => $row[22] ?? '',
    'certificate_url' => $row[23] ?? '',
    'image_url' => $row[24] ?? '',
];

function spi_create_attributes_array($attributes) 
{
    $attribute_objects = [];

    foreach ($attributes as $name => $value) {
        if (!$value) continue; // Skip empty attributes

        // Convert attribute name to global taxonomy (e.g., pa_color)
        $taxonomy = 'pa_' . sanitize_title($name);

        // Check if the taxonomy exists, create it if it doesn't
        if (!taxonomy_exists($taxonomy)) {
            $attribute_data = [
                'name' => $name,
                'slug' => sanitize_title($name),
                'type' => 'select',
                'order_by' => 'menu_order',
                'has_archives' => false,
            ];
            wc_create_attribute($attribute_data);

            register_taxonomy(
                $taxonomy,
                'product',
                ['hierarchical' => false, 'show_ui' => false]
            );
        }

        // Add the term to the global attribute taxonomy if it doesn't exist
        if (!term_exists($value, $taxonomy)) {
            wp_insert_term($value, $taxonomy);
        }

        // Get the term ID for the value
        $term = get_term_by('name', $value, $taxonomy);
        if ($term) {
            $attribute = new WC_Product_Attribute();
            $attribute->set_name($taxonomy);
            $attribute->set_options([$term->name]);
            $attribute->set_visible(true);
            $attribute->set_variation(false);
            $attribute_objects[] = $attribute;
        }
    }

    return $attribute_objects;
}

$product = new WC_Product_Simple();
$attributes = spi_create_attributes_array($product_data['attributes']);
$product->set_attributes($attributes);
$product->save();

When import Product. before Click on save attribute Manually

Global Added already in attribute

After Save

Full Video

What I’ve Tried:
Problem:
Desired Solution:

How can I modify my code to make attributes global by default?

Upvotes: 0

Views: 64

Answers (1)

vaibhav goti
vaibhav goti

Reputation: 19

Here the Image With solution

The issue i am facing occurs because WooCommerce attributes, when added programmatically, are treated as custom attributes unless explicitly associated with global attributes. Your approach to handle this with pre-existing global attributes is correct and works perfectly.

The key to ensuring that attributes are set as global is to correctly associate the term IDs of the existing global attributes during product import. Here's the working code you provided:

$product_data = [
'regular_price' => $row[15] ?? '',
'sku' => $row[1],
'category' => $diamond_type,
'attributes' => [
    'Lab' => $row[2] ?? '',
    'Certificate No' => $row[3] ?? '',
    'Shape' => $row[4] ?? '',
    'Carat' => $row[5] ?? '',
    'Tinge' => $row[21] ?? '',
],
'video_url' => $row[22] ?? '',
'certificate_url' => $row[23] ?? '',
'image_url' => $row[24] ?? '',

];

function set_pre_existing_attribute_to_product( $product, $attribute_name, $term_ids, $for_variations = false, $visible = true, $position = 0 ) {
$taxonomy  = wc_attribute_taxonomy_name($attribute_name); // new attribute, already registered in WordPress

$attribute = new WC_Product_Attribute(); // new attribute object
$attribute->set_id( wc_attribute_taxonomy_id_by_name( $attribute_name ) ); // setting attribute configs
$attribute->set_name($taxonomy); 
$attribute->set_options($term_ids);
$attribute->set_variation($for_variations); 
$attribute->set_visible($visible); 
$attribute->set_position($position);

$attributes = (array) $product->get_attributes(); // Get existing attributes set in the product

$product->set_attributes( array_merge( $attributes, array($taxonomy => $attribute) ) );
$product->save();

}

$product = new WC_Product_Simple();

// Loop through your attributes and assign pre-existing attribute values foreach ($product_data['attributes'] as $name => $value) { if (!$value) continue; // Skip empty attributes

$taxonomy = 'pa_' . sanitize_title($name); // Convert attribute name to global taxonomy (e.g., pa_color)

// Check if the taxonomy exists, get the term ID for the value
if (taxonomy_exists($taxonomy)) {
    $term = get_term_by('name', $value, $taxonomy);
    if ($term) {
        $term_id = $term->term_id;
        // Add the pre-existing attribute to the product
        set_pre_existing_attribute_to_product($product, $name, [$term_id]);
    }
}

}

$product->save();

This code ensures that attributes are correctly linked to their global counterparts by checking if the taxonomy exists and assigning the term IDs to the products during the import process.

For official WordPress documentation on how attributes and taxonomies are handled in WooCommerce, you can refer to the following link:

[WooCommerce Product Attributes][1] - Official Documentation

This will help clarify how attributes are mapped to taxonomies and provide further context on managing global attributes in WooCommerce.

Upvotes: 1

Related Questions