You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何修复WooCommerce商品变体复制插件的保存失效问题?

问题原因分析
  • 目标商品类型不兼容:你的目标商品是「简单商品」类型,WooCommerce不允许简单商品关联变体,即使创建了变体也会被系统自动清理,所以会出现变体ID递增但实际不显示的情况。
  • 缺少父商品属性配置:变体依赖父商品的全局属性定义,你只复制了变体的属性值,但目标商品没有同步源商品的属性(包括属性名称、可选值、是否用于变体等核心设置),导致变体属性无法被系统识别。
  • 变体创建流程不完整:直接实例化WC_Product_Variation缺少必要的初始化逻辑,部分关键元数据或状态字段未设置,触发了WooCommerce的自动校验清理机制。
解决办法
  1. 先将目标商品从「简单商品」转为「可变商品」类型;
  2. 同步源商品的所有属性配置到目标商品;
  3. 使用WooCommerce官方推荐的wc_create_product_variation()函数创建变体,确保流程合规;
  4. 补充变体的必填字段(如库存状态、SKU),避免因字段缺失导致保存失败。
修复后的完整插件代码
<?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.1
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() {
    add_menu_page('WC Copy Variations Settings', 'Copy Variations', 'administrator', __FILE__, 'wcvc_settings_page' , plugins_url('/images/icon.png', __FILE__) );
    add_action( 'admin_init', 'register_wcvc_settings' );
}

function register_wcvc_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() {
    $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() {
    $source_product_id = get_option('source_product_id');
    $target_product_id = get_option('target_product_id');

    $source_product = wc_get_product($source_product_id);
    $target_product = wc_get_product($target_product_id);

    if (!$source_product || !$source_product->is_type('variable')) {
        update_option( 'wcvc_status', 'error: source is not variable product' );
        return;
    }

    // 1. 将目标商品转为可变类型
    if ($target_product->is_type('simple')) {
        $target_product->set_type('variable');
        $target_product->save();
        // 重新获取更新后的商品对象
        $target_product = wc_get_product($target_product_id);
    }

    // 2. 同步源商品的属性配置到目标商品
    $source_attributes = $source_product->get_attributes();
    foreach ($source_attributes as $attr_key => $attribute) {
        // 复制属性设置(包括名称、选项、是否用于变体等)
        $target_product->update_attribute($attr_key, $attribute->get_options());
        $attribute->set_id(0); // 重置ID,避免关联到源商品的属性
        $target_product->set_attribute($attr_key, $attribute);
    }
    $target_product->save();

    // 3. 复制变体
    $variations = $source_product->get_children();
    foreach ($variations as $variation_id) {
        $variation = wc_get_product($variation_id);
        
        // 整理变体属性格式(匹配父商品的属性键)
        $variation_attributes = [];
        foreach ($variation->get_attributes() as $attr_name => $attr_value) {
            $attr_taxonomy = wc_attribute_taxonomy_name($attr_name);
            $variation_attributes[$attr_taxonomy] = $attr_value;
        }

        // 使用官方函数创建变体
        $new_variation_id = wc_create_product_variation($target_product_id, [
            'attributes' => $variation_attributes,
            'regular_price' => $variation->get_regular_price(),
            'sale_price' => $variation->get_sale_price(),
            'weight' => $variation->get_weight(),
            'length' => $variation->get_length(),
            'height' => $variation->get_height(),
            'width' => $variation->get_width(),
            'stock_status' => $variation->get_stock_status() ?: 'instock',
            'sku' => $variation->get_sku() ?: $target_product->get_sku() . '-' . uniqid(),
        ]);
    }

    update_option( 'wcvc_status', 'done: variations copied successfully' );
}

function show_wcv_source() {
    $source_product_id = get_option('source_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);

    if ($source_product->is_type('variable')) {
        $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>';
            echo 'Attributes: ';
            var_dump($s_variation->get_attributes());
            echo '<br />';
            echo 'Regular Price: '.$s_variation->get_regular_price().'<br />';
            echo 'Sale Price: '.$s_variation->get_sale_price().'<br />';
            echo 'Weight: '.$s_variation->get_weight().'<br />';
            echo 'Length: '.$s_variation->get_length().'<br />';
            echo 'Height: '.$s_variation->get_height().'<br />';
            echo 'Width: '.$s_variation->get_width().'<br />';
            echo '</p></div>';
        }
    }
}

function show_wcv_target() {
    $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);

    if ($target_product->is_type('variable')) {
        $t_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>';
            echo 'Attributes: ';
            var_dump($t_variation->get_attributes());
            echo '<br />';
            echo 'Regular Price: '.$t_variation->get_regular_price().'<br />';
            echo 'Sale Price: '.$t_variation->get_sale_price().'<br />';
            echo 'Weight: '.$t_variation->get_weight().'<br />';
            echo 'Length: '.$t_variation->get_length().'<br />';
            echo 'Height: '.$t_variation->get_height().'<br />';
            echo 'Width: '.$t_variation->get_width().'<br />';
            echo '</p></div>';
        }
    }
}

?>

内容的提问来源于stack exchange,提问作者Wayne Schulz

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.16 09:44:51