我正在创建一个前端表单,允许用户使用预定义的属性和变体从前端向我的商店发布变量产品。
我找到了这个非常有用的问题: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个术语(高分辨率,中等分辨率,低分辨率)作为属性。我只需要更进一步,将它们实际设置为变体,以便人们可以下订单。
答案 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 );
默认情况下会插入三个变体,我无法删除或插入其他变体。
任何解决方案?