skip to Main Content

I’m using the following code to add attributes with terms:

$taxonomy = 'pa_' . $attr['name']; // The attribute taxonomy

if (!taxonomy_exists($taxonomy)) {
    global $wpdb;

    $insert = $wpdb->insert(
        $wpdb->prefix . 'woocommerce_attribute_taxonomies',
        array(
            'attribute_name'    => $attr['name'],
            'attribute_label'   => $attr['name'],
            'attribute_public'  => 0
        ),
        array('%s', '%s', '%d')
    );

    if (is_wp_error($insert)) {
        throw new WC_API_Exception('woocommerce_api_cannot_create_product_attribute', $insert->get_error_message(), 400);
    }

    // Clear transients
    delete_transient('wc_attribute_taxonomies');
}

if (!term_exists($attr['value'], $attr['name'])) {
    wp_insert_term($attr['value'], $attr['name']);
}

$term_slug = get_term_by('name', $attr['value'], $attr['name'])->slug; // Get the term slug

wp_set_post_terms($product_id, $attr['value'], $attr['name'], true);

// Set/save the attribute data in the product variation
update_post_meta($variation_id, 'attribute_' . $taxonomy, $term_slug);

// Assign to the product
wp_set_object_terms($product_id, $attr['value'], $taxonomy, true);
$att = array($taxonomy => array(
    'name' => $taxonomy,
    'value' => $attr['value'],
    'is_visible' => '1',
    'is_variation' => '1',
    'is_taxonomy' => '1',
));
update_post_meta($product_id, '_product_attributes', $att);

However, the first time the code runs it adds the attributes without terms. If I run it a second time, only then does it add the terms to the previously added attributes.

Why is that?

Edit: The problem seems to start at the following line:

$term_slug = get_term_by('name', $attr['value'], $attr['name'])->slug

It simply doesn’t yet recognize the newly created taxonomy. Only at the next run.

But why? Is there a function that can be used to “refresh” the attributes, or the $wp_attributes variable, which seems to be closely related?

Thanks!

2

Answers


  1. It is hard to debug without looking at the live site. However, I think it could be something to do with this code:

    if (!term_exists($attr['value'], $attr['name'])) {
        wp_insert_term($attr['value'], $attr['name']);
    }
    

    On first request the term is inserted yet it will not be part of WordPress main query until further requests.

    Again, this is mostly guessing as I need to see the actual implementation.

    Login or Signup to reply.
  2. I use such a method to create a taxonomy.

    public function setAttribute($attributeArgs)
      {
        $attributeId = wc_attribute_taxonomy_id_by_name($attributeArgs['slug']);
    
        if ($attributeId === 0) {
          $attributeId = wc_create_attribute($attributeArgs);
          register_taxonomy('pa_' . $attributeArgs['slug'], ['product'], []);
        } else {
          $attributeId = wc_update_attribute($attributeId, $attributeArgs);
        }
    
        return [
          'id' => $attributeId,
          'args' => $attributeArgs,
        ];
      }
    

    An important line in this code is register_taxonomy('pa_' . $attributeArgs['slug'], ['product'], []);
    Without this line, I had the same problem.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search