我的 WooComerce 商店中有 400 多种产品,它们都是作为简单产品完成的。问题是,现在我必须向所有产品添加变体(以满足运输插件的要求),如果我必须为每个产品手动执行此操作,我将花费很长时间。
我已经设置了我的一款产品,其中的所有变体和值都需要复制到同一类别的其他产品。
我尝试根据 TSCAmerica.com answer.
拼凑一个简单的插件来执行此操作下面是完整的插件代码,任何人都可以尝试一下,看看它是否适合他们或需要修复的地方:
<?php
/*
Plugin Name: WC Copy Variations
Plugin URI: https://www.example.com
Description: Copy a Woocommerce Product's Variations From One Product to Another
Version: 1.0
Author: Wayne Schulz
Author URI: https://www.example.com
License: GPL2
License URI: https://www.gnu.org/licenses/gpl-2.0.html
Text Domain: wc-copy-variations
Domain Path: /languages
*/
// plugin settings menu
add_action('admin_menu', 'wcvc_create_menu');
function wcvc_create_menu() {
//create new top-level menu
add_menu_page('WC Copy Variations Settings', 'Copy Variations', 'administrator', __FILE__, 'wcvc_settings_page' , plugins_url('/images/icon.png', __FILE__) );
//call register settings function
add_action( 'admin_init', 'register_wcvc_settings' );
}
function register_wcvc_settings() {
//register our settings
register_setting( 'wcvc-settings-group', 'source_product_id' );
register_setting( 'wcvc-settings-group', 'target_product_id' );
register_setting( 'wcvc-settings-group', 'wcvc_status' );
}
function wcvc_settings_page() {
// Trigger wcv copy
$wcvc_status = get_option('wcvc_status');
if(str_contains($wcvc_status, 'yes')) {
perform_wcv_copy();
}
?>
<div class="wrap">
<h1>WC Copy Variations</h1>
<form method="post" action="options.php">
<?php settings_fields( 'wcvc-settings-group' ); ?>
<?php do_settings_sections( 'wcvc-settings-group' ); ?>
<table class="form-table">
<tr valign="top">
<th scope="row">Source Product ID</th>
<td><input type="text" name="source_product_id" value="<?php echo esc_attr( get_option('source_product_id') ); ?>" /></td>
</tr>
<tr valign="top">
<th scope="row">Target Product ID</th>
<td><input type="text" name="target_product_id" value="<?php echo esc_attr( get_option('target_product_id') ); ?>" /></td>
</tr>
<tr valign="top">
<th scope="row">Type 'yes' to copy</th>
<td><input type="text" name="wcvc_status" value="<?php echo esc_attr( get_option('wcvc_status') ); ?>" /></td>
</tr>
</table>
<?php submit_button(); ?>
</form>
</div>
<table><tr><td style="vertical-align: top;"><?php show_wcv_source(); ?></td><td style="vertical-align: top;"><?php show_wcv_target(); ?></td></tr></table>
<?php }
function perform_wcv_copy() {
global $options;
$source_product_id = get_option('source_product_id');
$target_product_id = get_option('target_product_id');
$source_product = wc_get_product($source_product_id);
// Check if the source product has variations
if ($source_product->is_type('variable')) {
// Get the variations of the source product
$variations = $source_product->get_children();
foreach ($variations as $variation_id) {
$variation = wc_get_product($variation_id);
// Create a new variation for the target product
$new_variation = new WC_Product_Variation();
$new_variation->set_parent_id($target_product_id);
// Set attributes and other settings from the source variation
$new_variation->set_attributes($variation->get_attributes());
$new_variation->set_regular_price($variation->get_regular_price());
$new_variation->set_sale_price($variation->get_sale_price());
$new_variation->set_weight($variation->get_weight());
$new_variation->set_length($variation->get_length());
$new_variation->set_height($variation->get_height());
$new_variation->set_width($variation->get_width());
// Save the new variation
$new_variation->save();
}
}
update_option( 'wcvc_status', 'done' );
}
function show_wcv_source() {
global $options;
$source_product_id = get_option('source_product_id');
$target_product_id = get_option('target_product_id');
echo '<p><strong>Source Product ID: '.$source_product_id.'</strong><br />';
echo 'Product Categories: '.wc_get_product_category_list($source_product_id).'</p>';
$source_product = wc_get_product($source_product_id);
// Check if the source product has variations
if ($source_product->is_type('variable')) {
// Get the variations of the source product
$s_variations = $source_product->get_children();
foreach ($s_variations as $s_variation_id) {
$s_variation = wc_get_product($s_variation_id);
echo '<div class="wrap"><p>';
//$raw_variation = var_export($variation, true);
//echo 'Variation ID: '.$raw_variation.'<br />';
echo 'Attributes: ';
var_dump($s_variation->get_attributes());
echo '<br />';
$s_regular_price = $s_variation->get_regular_price();
echo 'Regular Price: '.$s_regular_price.'<br />';
$s_sale_price = $s_variation->get_sale_price();
echo 'Sale Price: '.$s_sale_price.'<br />';
$s_weight = $s_variation->get_weight();
echo 'Weight: '.$s_weight.'<br />';
$s_length = $s_variation->get_length();
echo 'Length: '.$s_length.'<br />';
$s_height = $s_variation->get_height();
echo 'Height: '.$s_height.'<br />';
$s_width = $s_variation->get_width();
echo 'Width: '.$s_width.'<br />';
echo '</p></div>';
}
}
}
function show_wcv_target() {
global $options;
$source_product_id = get_option('source_product_id');
$target_product_id = get_option('target_product_id');
echo '<p><strong>Target Product ID: '.$target_product_id.'</strong><br />';
echo 'Product Categories: '.wc_get_product_category_list($target_product_id).'</p>';
$target_product = wc_get_product($target_product_id);
// Check if the target product has variations
if ($target_product->is_type('variable')) {
// Get the variations of the target product (if any)
$variations = $target_product->get_children();
foreach ($t_variations as $t_variation_id) {
$t_variation = wc_get_product($t_variation_id);
echo '<div class="wrap"><p>';
// $raw_variation = var_export($variation, true);
// echo 'Variation ID: '.$raw_variation.'<br />';
echo 'Attributes: ';
var_dump($t_variation->get_attributes());
echo '<br />';
$t_regular_price = $t_variation->get_regular_price();
echo 'Regular Price: '.$t_regular_price.'<br />';
$t_sale_price = $t_variation->get_sale_price();
echo 'Sale Price: '.$t_sale_price.'<br />';
$t_weight = $t_variation->get_weight();
echo 'Weight: '.$t_weight.'<br />';
$t_length = $t_variation->get_length();
echo 'Length: '.$t_length.'<br />';
$t_height = $t_variation->get_height();
echo 'Height: '.$t_height.'<br />';
$t_width = $t_variation->get_width();
echo 'Width: '.$t_width.'<br />';
echo '</p></div>';
}
}
}
?>
输入源ID和目标ID并点击保存,然后它将显示源产品和目标产品的任何变化。如果您想执行复制,请在最后一个字段中输入“是”,然后再次点击“保存”。
我遇到的问题是它没有将新变体保存到目标产品。我 VAR DUMPED 所有可能的变量,并且数据位于正确的位置。在保存命令之后,每个新变体的 ID 都会增加,但是,要么 save() 由于某种原因无法正常工作,要么 WooComerce 在保存后立即删除已保存的变体。
我错过了什么或做错了什么?
上面的代码缺少两件事
您没有将属性添加到父产品,并且该产品仍设置为简单(非变量)产品
您可以添加几行来解决这个问题
function perform_wcv_copy() {
global $options;
$source_product_id = get_option('source_product_id');
$target_product_id = get_option('target_product_id');
$source_product = wc_get_product($source_product_id);
// Check if the source product has variations
if ($source_product->is_type('variable')) {
/* Update target parent */
$target_product = wc_get_product($target_product_id);
$target_product->set_attributes($source_product->get_attributes());
$target_product->save();
wp_set_object_terms( $target_product_id, 'variable', 'product_type' );
// Get the variations of the source product
$variations = $source_product->get_children();
foreach ($variations as $variation_id) {
$variation = wc_get_product($variation_id);
// Create a new variation for the target product
$new_variation = new WC_Product_Variation();
$new_variation->set_parent_id($target_product_id);
// Set attributes and other settings from the source variation
$new_variation->set_attributes($variation->get_attributes());
$new_variation->set_regular_price($variation->get_regular_price());
$new_variation->set_sale_price($variation->get_sale_price());
$new_variation->set_weight($variation->get_weight());
$new_variation->set_length($variation->get_length());
$new_variation->set_height($variation->get_height());
$new_variation->set_width($variation->get_width());
// Save the new variation
$new_variation->save();
}
}
update_option( 'wcvc_status', 'done' );
}
P.s.如果您多次为相同的 id 运行此操作(即使未显示变体,您也可能已经完成了),您将拥有多个相同的变体