如何在Woocommerce中将属性设置为变体

时间:2014-02-10 00:45:39

标签: php wordpress woocommerce

我正在创建一个前端表单,允许用户使用预定义的属性和变体从前端向我的商店发布变量产品。

我找到了这个非常有用的问题:here它向我展示了如何将产品类型设置为变量,并在产品数据的属性部分中分配我的预定义属性。

然而,当我在Wordpress / Woocommerce的后端并编辑产品时,我点击变体并且没有设置,我查看属性,我的“分辨率”属性设置为我的3项。

如何将其设置为实际将这些属性设置为表单变体的位置?我需要使用wp_insert_post吗?查看phpmyadmin,看起来产品变体分配给parent_id(产品ID),帖子类型是product_varition等等。

$new_post = array(
'post_title' => esc_attr(strip_tags($_POST['postTitle'])),
'post_content' => esc_attr(strip_tags($_POST['postContent'])),
'post_status' => 'publish',
'post_type' => 'product',
'tags_input' => array($tags)
);

$skuu = rand();
$post_id = wp_insert_post($new_post);
update_post_meta($post_id, '_sku', $skuu );

//my array for setting the attributes
$avail_attributes = array(
    'high-resolution',
    'medium-resolution',
    'low-resolution'
);

//Sets the attributes up to be used as variations but doesnt actually set them up as variations
wp_set_object_terms ($post_id, 'variable', 'product_type');
wp_set_object_terms( $post_id, $avail_attributes, 'pa_resolution' );


$thedata = array(
'pa_resolution'=> array(
                'name'=>'pa_resolution',
                'value'=>'',
                'is_visible' => '1',
                'is_variation' => '1',
                'is_taxonomy' => '1'
                )
);
update_post_meta( $post_id,'_product_attributes',$thedata);

update_post_meta( $post_id, '_visibility', 'search' );
update_post_meta( $post_id, '_stock_status', 'instock');

所以,为了清楚(我往往会感到困惑)上面确实从前端创建了我的变量产品,当我在后端看产品时它是一个可变产品,它具有分辨率属性设置和我的3个术语(高分辨率,中等分辨率,低分辨率)作为属性。我只需要更进一步,将它们实际设置为变体,以便人们可以下订单。

Adds attributes to product already need it to add variations as well

4 个答案:

答案 0 :(得分:5)

我使用update_post_meta和wp_insert_post让我的情况正常。因为我已经设置了我的属性和术语,所以我需要的是一种添加到上面代码的方法,这样在创建产品时,它不仅会将属性分配给产品,还会将它们作为数据库中的变体插入。

这是我的解决方案:

//insert variations post_type
$i=1;
while ($i<=3) {
$my_post = array(
      'post_title'    => 'Variation #' . $i . ' of ' . esc_attr(strip_tags($_POST['postTitle'])),
      'post_name'     => 'product-' . $post_id . '-variation-' . $i,
      'post_status'   => 'publish',
      'post_parent'   => $post_id,
      'post_type'     => 'product_variation',
      'guid'          =>  home_url() . '/?product_variation=product-' . $post_id . '-variation-' . $i
    );

    // Insert the post into the database
    wp_insert_post( $my_post );

    $variable_id = $post_id + 1;
    $variable_two = $variable_id + 1;
    $variable_three = $variable_two + 1;

    update_post_meta( $variable_id, 'attribute_pa_resolution', 'high-resolution');
    update_post_meta( $variable_id, '_price', 8.50 );
    update_post_meta( $variable_id, '_regular_price', '8.50');

    update_post_meta( $variable_two, 'attribute_pa_resolution', 'medium-resolution');
    update_post_meta( $variable_two, '_price', 5.50 );
    update_post_meta( $variable_two, '_regular_price', '5.50');

    update_post_meta( $variable_three, 'attribute_pa_resolution', 'low-resolution');
    update_post_meta( $variable_three, '_price', 3.50 );
    update_post_meta( $variable_three, '_regular_price', '3.50');

    $i++;
    }

答案 1 :(得分:1)

update_post_meta( $post_id, '_visibility', PARAM' ) 

它将有3个或4个参数:hidden |搜索|目录|可见

尝试将_visibility设置为&#34;可见&#34; PARAM。

答案 2 :(得分:1)

过去两天,我一直在努力在我的插件中实现在Woocommerce中设置产品变体的能力。

我设法在数据库中获取所有正确的数据,但Woocommerce没有像我想象的那样检索。

问题是“短暂的”&#39;存储在wp_options表中。

这是让我在WC 2.6.0上运行的代码:

根据所选属性创建变化($ _POST [&#39; term_id_arr&#39;]是从前端选择的所有属性列表,用于创建产品。对不起,我还不能发布图片在堆栈上.. Front-end form with variations created

$opzioni_arr=$_POST['term_id_arr'];
$qta = count($opzioni_arr);
if ($qta>0){
    $ID = $post_id;
    //make product type be variable:
    wp_set_object_terms ($ID,'variable','product_type');


    foreach ($opzioni_arr as $opzioni_val){
        $new_arr = explode("/",$opzioni_val);
        $att_taxonomy = $new_arr[0];
        $att_slug = $new_arr[1];
        $att_id =$new_arr[2];
        $att_arr[$att_taxonomy][$att_id]=$att_slug;
        $att_due_arr[$att_taxonomy][$att_taxonomy.'*'.$att_id]=$att_slug;
    }
    //################### Add attributes to main product: ####################
    foreach ($att_arr as $att_arr_key=>$att_arr_val){

        //Array for setting attributes
        unset ($avail_attributes);
        foreach ($att_arr_val as $key_two=>$val_two){
            $avail_attributes[] = $val_two;
        }

        wp_set_object_terms($ID, $avail_attributes, $att_arr_key);

        $thedata [$att_arr_key]= Array(
                                                'name'=>$att_arr_key,
                                                'value'=>'',
                                                'is_visible' => 1, 
                                                'is_variation' => 1,
                                                'is_taxonomy' => 1,
                                                'position' => '1'
                                            );

    }

        update_post_meta( $ID,'_product_attributes',$thedata);
    //########################## Done adding attributes to product #################

    //function to create combinations from attributes
    $combinations=lasap_get_combinations($att_due_arr);     

    foreach ($combinations as $key=>$val){
    // Start creating variations
    // The variation is simply a post
    // with the main product set as its parent
    // you might want to put that in a loop or something
    // to create multiple variations with multiple values
    $parent_id = $ID;
    $variation = array(
                        'post_title'   => 'Prodotto #' . $parent_id . ' Variante',
                        'post_content' => '',
                        'post_status'  => 'publish',
                        'post_parent'  => $parent_id,
                        'post_type'    => 'product_variation'
                    );
    // The variation id
    $variation_id = wp_insert_post( $variation );


    // Regular Price ( you can set other data like sku and sale price here )

    update_post_meta($variation_id, '_sku', $sku);

    update_post_meta($variation_id, '_regular_price', $regular_price);

    update_post_meta($variation_id, '_sale_price', $sale_price);
    update_post_meta($variation_id, '_sale_price_dates_from', $datasaldodal_time);
    update_post_meta($variation_id, '_sale_price_dates_to', $datasaldoal_time);

    if (($sale_price!='' AND ($sale_price<=$regular_price))){$price=$sale_price;} else {$price=$regular_price;}
    update_post_meta($variation_id, '_price', $price);

    update_post_meta($variation_id, '_thumbnail_id', $thumbnail_id);

    update_post_meta($variation_id, '_manage_stock', $manage_stock);
    update_post_meta($variation_id, '_stock_status', $stock_status);
    update_post_meta($variation_id, '_stock', $stock);
    update_post_meta($variation_id, '_stock_soglia', $stock_soglia);
    update_post_meta($variation_id, '_backorders', $backorders);


    foreach ($val as $chiave=>$valore){
            $exp = explode ("*", $chiave);
            $attributo_nome = $exp[0];
            update_post_meta( $variation_id, 'attribute_' . $attributo_nome, $valore );
            $split_attributo = explode("_", $attributo_nome);
            $attributo_nome_due = $split_attributo[1];
            echo "<p>Variante #$variation_id: $attributo_nome_due ($valore)</p>";

        }
    }
    do_action( 'product_variation_linked', $variation_id );
    // Update parent if variable so price sorting works and stays in sync with the cheapest child
    lasap_woo_sync_varianti ($post_id, $stock_status_before);   

}
delete_transient( 'wc_product_children_' . $parent_id );

更新变化(如价格,销售价格等等......)。

    $sku_arr = $_POST['sku'];
$prezzolistino_arr = $_POST['prezzolistino']; //regular_price
$prezzosaldo_arr = $_POST['prezzosaldo']; //sale_price
$datasaldoal_arr = $_POST['datasaldoal']; //sale_date_to
$datasaldodal_arr = $_POST['datasaldodal']; //sale_date_from
$manage_stock_arr = $_POST['manage_stock'];
$stock_arr = $_POST['stock'];
$stock_soglia_arr = $_POST['stock_soglia'];
$backorders_arr = $_POST['backorders'];

foreach ($sku_arr as $varID=>$sku){
    $prezzolistino = $prezzolistino_arr[$varID];
    $prezzosaldo = $prezzosaldo_arr[$varID];
    if (($prezzosaldo!='' AND ($prezzosaldo<=$prezzolistino))){$prezzoesposto=$prezzosaldo;} else {$prezzoesposto=$prezzolistino;}
        $prezzoesposto = $prezzoesposto * 1;
    $datasaldoal = $datasaldoal_arr[$varID];
    $datasaldodal = $datasaldodal_arr[$varID];
    $manage_stock = $manage_stock_arr[$varID];
    $stock = $stock_arr[$varID];
    $stock_soglia = $stock_soglia_arr[$varID];
    $backorders = $backorders_arr[$varID];
    switch ($manage_stock){
        case "on": $manage_stock = "yes"; break;
        default : $manage_stock = "no";
    }
    switch ($backorders){
        case "on": $backorders = "yes"; break;
        default : $backorders = "no";
    }

    update_post_meta ($varID, '_sku', $sku);
    update_post_meta ($varID, '_regular_price', $prezzolistino);
    update_post_meta ($varID, '_sale_price', $prezzosaldo);
    update_post_meta ($varID, '_price', $prezzoesposto);
    update_post_meta ($varID, '_sale_price_dates_to', $datasaldoal);
    update_post_meta ($varID, '_sale_price_dates_from', $datasaldodal);
    update_post_meta ($varID, '_manage_stock', $manage_stock);
    update_post_meta ($varID, '_stock', $stock);
    update_post_meta ($varID, '_stock_soglia', $stock_soglia);
    update_post_meta ($varID, '_backorders', $backorders);
}
// Update parent if variable so price sorting works and stays in sync with the cheapest child
    $tipo = $_POST['tipo'];//this is a value to check if I am updating main product or its children
    if ($tipo != 'parent'){
        lasap_woo_sync_varianti ($post_id, $stock_status_before);
    }

删除变化(S)

$ID_arr = $_POST['ID'];
foreach ($ID_arr as $ID){
    $res = wp_delete_post($ID, true);
}
$variazioni = lasap_woo_check_variazioni($post_id);

if ($variazioni > 0){
    // Update parent if variable so price sorting works and stays in sync with the cheapest child
    lasap_woo_sync_varianti ($post_id, $stock_status_before);
} else {
    //clean up main product
    delete_post_meta($post_id, '_product_attributes');
    delete_post_meta($post_id, '_min_variation_price');
    delete_post_meta($post_id, '_max_variation_price');
    delete_post_meta($post_id, '_min_price_variation_id');
    delete_post_meta($post_id, '_max_price_variation_id');
    delete_post_meta($post_id, '_min_variation_regular_price');
    delete_post_meta($post_id, '_max_variation_regular_price');
    delete_post_meta($post_id, '_min_regular_price_variation_id');
    delete_post_meta($post_id, '_max_regular_price_variation_id');
    delete_post_meta($post_id, '_min_variation_sale_price');
    delete_post_meta($post_id, '_max_variation_sale_price');
    delete_post_meta($post_id, '_min_sale_price_variation_id');
    delete_post_meta($post_id, '_max_sale_price_variation_id');

    update_post_meta($post_id, '_stock_status', 'instock');
    wp_set_object_terms ($post_id,'simple','product_type');
    wc_delete_product_transients( $post_id );
}

要求同步的功能......

function lasap_woo_sync_varianti ($post_id, $stock_status_before){
//https://docs.woocommerce.com/wc-apidocs/class-WC_Product_Variable.html
//WC_Product_Variable::variable_product_sync( $post_id );//sync variable product prices with the children lowest/highest (calls :sync)
//WC_Product_Variable::sync_stock_status( $post_id );//sync the variable product stock status with children
//WC_Product_Variable::sync_attributes( $post_id );//sync the variable product's attributes with the variations (called by :sync)
WC_Product_Variable::sync( $post_id );//sync the variable product with it's children
wc_delete_product_transients( $post_id );
lasap_get_variation_prices ($post_id);

$stock_status_after = get_post_meta($post_id, '_stock_status', true);
update_post_meta($post_id, '_stock_status', $stock_status_before);

}

设置瞬态的功能(从woocommerce \ includes \ class-wc-product-variable.php中提取)

function lasap_get_variation_prices( $post_id, $display = false ) {
    global $wp_filter, $woocommerce, $wpdb;
    $_product   = wc_get_product( $post_id );
    /**
     * Transient name for storing prices for this product (note: Max transient length is 45)
     * @since 2.5.0 a single transient is used per product for all prices, rather than many transients per product.
     */
    $transient_name = 'wc_var_prices_' . $post_id;

    /**
     * Create unique cache key based on the tax location (affects displayed/cached prices), product version and active price filters.
     * DEVELOPERS should filter this hash if offering conditonal pricing to keep it unique.
     * @var string
     */
    if ( $display ) {
        $price_hash = array( get_option( 'woocommerce_tax_display_shop', 'excl' ), WC_Tax::get_rates() );
    } else {
        $price_hash = array( false );
    }

    $filter_names = array( 'woocommerce_variation_prices_price', 'woocommerce_variation_prices_regular_price', 'woocommerce_variation_prices_sale_price' );

    foreach ( $filter_names as $filter_name ) {
        if ( ! empty( $wp_filter[ $filter_name ] ) ) {
            $price_hash[ $filter_name ] = array();

            foreach ( $wp_filter[ $filter_name ] as $priority => $callbacks ) {
                $price_hash[ $filter_name ][] = array_values( wp_list_pluck( $callbacks, 'function' ) );
            }
        }
    }

    $price_hash = md5( json_encode( apply_filters( 'woocommerce_get_variation_prices_hash', $price_hash, $_product, $display ) ) );


            // If the value has already been generated, we don't need to grab the values again.
    if ( empty( $post_id->prices_array[ $price_hash ] ) ) {

        // Get value of transient
        $prices_array = array_filter( (array) json_decode( strval( get_transient( $transient_name ) ), true ) );

        // If the product version has changed, reset cache

        if ( empty( $prices_array['version'] ) || $prices_array['version'] !== WC_Cache_Helper::get_transient_version( 'product' ) ) {
            $post_id->prices_array = array( 'version' => WC_Cache_Helper::get_transient_version( 'product' ) );
        }

        // If the prices are not stored for this hash, generate them
        //if ( empty( $prices_array[ $price_hash ] ) ) {
            if ( 1>0 ) {
            $prices         = array();
            $regular_prices = array();
            $sale_prices    = array();
            $variation_ids  = $wpdb->get_col("SELECT ID FROM $wpdb->posts WHERE post_type='product_variation' AND post_status='publish' AND post_parent=$post_id", 0);

            foreach ( $variation_ids as $variation_id ) {
                $post_meta = get_post_meta($variation_id);
                    $price         = $post_meta['_price'][0];
                    $regular_price = $post_meta['_regular_price'][0];
                    $sale_price    = $post_meta['_sale_price'][0];

                    // Skip empty prices
                    if ( '' === $price ) {
                        continue;
                    }

                    // If sale price does not equal price, the product is not yet on sale
                    if ( $sale_price === $regular_price || $sale_price !== $price ) {
                        $sale_price = $regular_price;
                    }

                    // If we are getting prices for display, we need to account for taxes
                    if ( $display ) {
                        if ( 'incl' === get_option( 'woocommerce_tax_display_shop' ) ) {
                            $price         = '' === $price ? ''         : $variation->get_price_including_tax( 1, $price );
                            $regular_price = '' === $regular_price ? '' : $variation->get_price_including_tax( 1, $regular_price );
                            $sale_price    = '' === $sale_price ? ''    : $variation->get_price_including_tax( 1, $sale_price );
                        } else {
                            $price         = '' === $price ? ''         : $variation->get_price_excluding_tax( 1, $price );
                            $regular_price = '' === $regular_price ? '' : $variation->get_price_excluding_tax( 1, $regular_price );
                            $sale_price    = '' === $sale_price ? ''    : $variation->get_price_excluding_tax( 1, $sale_price );
                        }
                    }

                    $prices[ $variation_id ]         = wc_format_decimal( $price, wc_get_price_decimals() );
                    $regular_prices[ $variation_id ] = wc_format_decimal( $regular_price, wc_get_price_decimals() );
                    $sale_prices[ $variation_id ]    = wc_format_decimal( $sale_price . '.00', wc_get_price_decimals() );

            }

            asort( $prices );
            asort( $regular_prices );
            asort( $sale_prices );

            $prices_array[ $price_hash ] = array(
                'price'         => $prices,
                'regular_price' => $regular_prices,
                'sale_price'    => $sale_prices,
            );
            echo "<br> 659) ";mostra_array($prices_array);
            set_transient( $transient_name, json_encode( $prices_array ), DAY_IN_SECONDS * 30 );
        }

        /**
         * Give plugins one last chance to filter the variation prices array which has been generated.
         */
        $post_id->prices_array[ $price_hash ] = apply_filters( 'woocommerce_variation_prices', $prices_array[ $price_hash ], $post_id, $display );
    }


}

我使用的功能检查产品是否有变化(退货数量)

function lasap_woo_check_variazioni($post_id){
global $wpdb;
$qry_var="  SELECT COUNT(ID) FROM $wpdb->posts WHERE
                post_type='product_variation' AND
                post_parent=$post_id AND
                post_status='publish'";
$res_var=$wpdb->get_var($qry_var);
return $res_var;

}

在这之后,又出现了另一个问题(它永远不会发生,不是吗?):我还没有弄明白为什么但是在更新变体后,父产品post_meta&#39; _stock_status&#39;总是被设定为&#39; outofstock&#39;。

我已经使用get_post_meta在开头修补了这个检索的正确状态,并将其值传递给函数lasap_woo_sync_varianti。

非常感谢任何改进,并希望这有助于某人节省他/她的时间!

测试并使用WC 2.6.13。请参见链接here

答案 3 :(得分:0)

随着woocommerce的最后一次实现,此代码不起作用。

当我使用此代码时:

$my_post = array(
'post_title'    => 'Variation #' . $i . ' of ' . esc_attr(strip_tags($_POST['postTitle'])),
'post_name'     => 'product-' . $post_id . '-variation-' . $i,
'post_status'   => 'publish',
'post_parent'   => $post_id,
'post_type'     => 'product_variation',
'guid' =>  home_url() . '/?product_variation=product-' . $post_id . '-variation-' . $i
);
wp_insert_post( $my_post );

默认情况下会插入三个变体,我无法删除或插入其他变体。

任何解决方案?