Search code examples
phpattributeswoocommerceproducttaxonomy

Woocommerce newProduct() Taxonomy is Not Working


Can you show me what I'm doing wrong?

My code to add a new product to Woocommerce looks like this right now:

function newProduct( $idERP, $titulo, $conteudo, $preco, $precoDesconto, $sku, $peso, $comprimento, $largura, $altura, $estoque, $variacoes, $categorias ){

        global $woocommerce;

        $titulo = utf8_encode($titulo);
        $conteudo = utf8_encode($conteudo);

        $my_post = array(
          'post_title'    => $titulo,
          'post_content'  => $conteudo,
          'post_status'   => 'pending',
          'post_author'   => 6,
          'post_type'     =>'product'
        );
        $product_ID = wp_insert_post( $my_post );

        if ( $product_ID ){

          if( $preco == $precoDesconto){
              add_post_meta($product_ID, '_price',         $precoDesconto );
          }else{
              add_post_meta($product_ID, '_regular_price', $preco );
              add_post_meta($product_ID, '_price',         $precoDesconto );
              add_post_meta($product_ID, '_sale_price',    $precoDesconto );
          }


          add_post_meta($product_ID, '_sku',           $sku );
          add_post_meta($product_ID, '_weight',        $peso );
          add_post_meta($product_ID, '_length',        $comprimento );
          add_post_meta($product_ID, '_width',         $largura );
          add_post_meta($product_ID, '_height',        $altura );
          add_post_meta($product_ID, '_stock',         $this->estoque($estoque) );
          add_post_meta($product_ID, '_idERP',         $idERP ); //ID from erp
          wp_set_object_terms( $product_ID,  'variable', 'product_type' );
          //wp_set_object_terms( $product_ID, $categorias, 'product_cat');

          $guardaVariacoes = array();$i = 1;
          foreach($variacoes as $v){
            $vid = wp_insert_post(
                array(
                  'post_title'    => 'Variacao #' . $i,
                  'post_name'     => 'product-' . $product_ID . '-variation-' . $i,
                  'post_status'   => 'publish',
                  'post_parent'   => $product_ID,
                  'post_type'     => 'product_variation',
                  'guid'          =>  home_url() . '/?product_variation=product-' . $product_ID . '-variation-' . $i
                )
            );

            if( $v[1] == $v[2] ){
                update_post_meta( $vid, '_regular_price', $v[1]);
            }else{
                update_post_meta( $vid, '_price', $v[2] );
                update_post_meta( $vid, '_regular_price', $v[1]);
                update_post_meta( $vid, '_sale_price',  $v[2] );
            }

            update_post_meta( $vid, '_stock', $this->estoque($v[0]) );
            update_post_meta( $vid, '_weight', $v[3]);
            update_post_meta( $vid, '_width', $v[4]);
            update_post_meta( $vid, '_height', $v[5]);
            update_post_meta( $vid, '_length', $v[6]);
            update_post_meta( $vid, '_sku', $v[8]);
            update_post_meta( $vid, '_idERP', $v[9]);

            foreach($v[7] as $nAtr=>$vAtr){
                $nomeAtributo = strtolower(trim($nAtr));


                 $tt = $nomeAtributo;
                 if(strtolower($tt) == 'tamanho')$tt = 'pa_tamanho';
                 if(strtolower($tt) == 'cor')$tt = 'pa_cor';


                update_post_meta( $vid, 'attribute_'.$tt, trim($vAtr));
                $temp = $tt.'|'.$nAtr;
                if( !array_key_exists($temp,$guardaVariacoes) ) $guardaVariacoes[$temp] = array();
                $guardaVariacoes[$temp][] = $vAtr;  
            }
            $i++;
          }

          $product_attributes = array();
          foreach($guardaVariacoes as $r=>$s){

              $r = explode('|',$r);

              $temp = array();
              foreach($s as $w){

                  $w = trim($w);

                  if( strtoupper($w) == 'UNICA'  ){
                      $w = 'Única';
                  }
                  if( strtoupper($w) == 'UNICO'  ){
                      $w = 'Único';
                  }


                  if( array_search( $w,$temp)===false){
                     if( strtoupper(trim($r[1])) == 'COR'){
                         $temp[] = ucfirst(strtolower($w)); 
                      }else{
                          $temp[] = $w; 
                    } 
                  }
              }
              $s = array_unique($temp);



             $tt = $r[1];
             if(strtolower($tt) == 'tamanho')$tt = 'pa_tamanho';
             if(strtolower($tt) == 'cor')$tt = 'pa_cor';


              $product_attributes[$r[0]] = array(
                'name' => $tt, 
                'value' => implode(' | ', $s ),
                'position' => 1,
                'is_visible' => 1,
                'is_variation' => 1,
                'is_taxonomy' => 1  //MY PROBLEM IS HERE
              );
          }
          update_post_meta($product_ID, '_product_attributes', $product_attributes);
        }
        return $product_ID;
    }

When I change the code like so...

    'is_taxonomy' => 1

...it works, but it doesn't work for "search layered filters", which means I have to use taxonomy.

How do I do that without losing the "attributes" inside my product?


Solution

  • Sounds to me like you are trying to set Categories for products, and correct me if I'm wrong please. If this is the case, you don't want to use taxonomies. First, you are missing a ton of meta_keys for the product and all of it's variations. I suggest you install a fresh copy of WooCommerce plugin on a Fresh copy of Wordpress. Create a product manually in the back-end with 2 variations, and take a look at the wp_posts and wp_postmeta (post_id, meta_key, and meta_values). For variations, there are more values for the actual product id in the wp_postmeta table than that of the variations. _max_variation_sale_price_id, _max_variation_sale_price, _min_variation_sale_price_id, _min_variation_sale_price, etc. etc. etc. There is also another serialized array, _default_attributes, that you can just make an empty array and serialize it, for the product so that it has it's defaults set.

    So, if you are referring to Categories and want to assign products to categories so that you can click on a category and see that product in there... than do the following:

    Keep is_taxonomy set to 0 is_visible doesn't matter, if you want to see it under Additional Info, than set to 1, otherwise, it should still show all different variations, but I suppose it depends on your theme's way of handling this. position needs to start at 1 and be incremented each time, so use a variable for this, example:

    $position = 1;
    foreach($guardaVariacoes as $r=>$s) {
    
        // your top code... down to where the _product_attributes array begins...
    
        $product_attributes[$r[0]] = array(
            'name' => $tt, 
            'value' => implode(' | ', $s),
            'position' => $position,
            'is_visible' => count($s) > 1 ? 0 : 1,
            'is_variation' => count($s) > 1 ? 1 : 0,
            'is_taxonomy' => 0
        );
    
        $position++;
    }
    

    To create and assign categories on the fly for products you use: term_exists (will return 0 or NULL if term doesn't exist, you can check with empty()), wp_insert_term (if the term doesn't exist), insert it so that you can assign the category to the product. Example below if you want to insert a sub-brand category into a parent brand category, just an example of how I add categories to products (wp_term_relationships table assigns the categories to each product, via the products/posts ID value):

    // Check if Brand exists or not...
    $brand = term_exists('brand', 'product_cat', 0);
    $category = 'new category';
    $cat_name = addslashes(ucwords(strtolower($category)));
    $cats['brand'] = array(
        'name' => $cat_name,
        'slug' => sanitize_title_with_dashes($category)
    );
    
    if (!empty($brand))
    {
        $subbrand = term_exists($cats['brand']['slug'], 'product_cat', $brand['term_id']);
    
        if (empty($subbrand))
        {
            $subbrand = wp_insert_term(
                $cats['brand']['name'],
                'product_cat',
                array(
                    'slug' => $cats['brand']['slug'],
                    'parent'=> $brand['term_id']
                )
            );
        }
    } else {
    
        $brand = wp_insert_term(
            'Brand',
            'product_cat',
            array(
                'slug' => 'brand',
                'parent'=> 0 // This means it will be at the first level!
            )
        );
    
        $subbrand = term_exists($cats['brand']['slug'], 'product_cat', $brand['term_id']);
    
        if (empty($subbrand))
        {
            $subbrand = wp_insert_term(
                $cats['brand']['name'],
                'product_cat',
                array(
                    'slug' => $cats['brand']['slug'],
                    'parent'=> $brand['term_id']
                )
            );
        }
    }
    
    $categories = array(
        'product_id' => // put the product id value in here!
        'terms' => array()
    );
    
    if (!empty($subbrand))
    {
        $categories['terms']['subbrands'] = $subbrand;
    }
    
    // Now insert into term_relationships table for that product and that's all folks...
    foreach($categories['terms'] as $type => $nfo)
    {
        $wpdb->insert(
            $wpdb->prefix . "term_relationships", 
            array(
                'object_id' => $categories['product_id'], 
                'term_taxonomy_id' => intval($nfo['term_taxonomy_id']),
                'term_order' => 0
            ),
            array('%d', '%d', '%d')
        );
    }
    

    So, hopefully this helps you to build categories for your products, while still keeping your product attributes in tact in the search filter. Good Luck.