从Printify导入WooCommerce时变体价格未同步问题及代码优化需求
解决Printify导入WooCommerce时的变体价格同步问题
问题说明
将商品从Printify服务导入WooCommerce平台时,已通过代码将自定义颜色、尺寸属性转换为全局属性,但变体价格未同步Printify数据,导致价格属性缺失或不匹配。以下是修复后的完整代码,新增价格同步功能并修正原代码逻辑问题。
修改后的完整代码
add_action('rest_after_insert_product', function($product) { $product_id = $product->get_id(); error_log("正在处理商品: $product_id"); convert_custom_to_global_attributes($product_id); update_variation_prices($product_id); }, 10, 1); add_action('shutdown', function() { global $wpdb; $products = $wpdb->get_col("SELECT ID FROM {$wpdb->posts} WHERE post_type = 'product' AND post_status = 'publish'"); foreach ($products as $product_id) { convert_custom_to_global_attributes($product_id); } }); add_action('woocommerce_before_single_product', function() { $product = wc_get_product(get_the_ID()); $attributes = $product->get_attributes(); error_log("商品属性: " . print_r($attributes, true)); }); /** * 将自定义属性转换为全局属性 */ function convert_custom_to_global_attributes($product_id) { $product = wc_get_product($product_id); if (!$product) { error_log("未找到商品: $product_id"); return; } $attributes = $product->get_attributes(); $updated_attributes = []; // 仅存储全局属性 $attribute_mapping = [ 'custom_sizes' => 'pa_sizes', 'custom_colors' => 'pa_colors', ]; foreach ($attributes as $key => $attr) { if (!$attr->is_taxonomy()) { // 检查是否为自定义属性 $name = $attr->get_name(); $taxonomy = 'pa_' . sanitize_title($name); // 如果全局属性不存在则创建 if (!taxonomy_exists($taxonomy)) { $result = wc_create_attribute([ 'name' => $name, 'slug' => sanitize_title($name), 'type' => 'select', 'order_by' => 'menu_order', 'has_archives' => false, ]); if (is_wp_error($result)) { error_log("创建全局属性 $name 失败: " . $result->get_error_message()); continue; } register_taxonomy($taxonomy, 'product', [ 'hierarchical' => true, 'show_ui' => false, 'query_var' => true, 'rewrite' => false, ]); } // 将自定义属性值转换为全局分类术语 $options = $attr->get_options(); foreach ($options as $option) { if (!term_exists($option, $taxonomy)) { $term_result = wp_insert_term($option, $taxonomy); if (is_wp_error($term_result)) { error_log("在分类 '$taxonomy' 中创建术语 '$option' 失败: " . $term_result->get_error_message()); } else { error_log("已在分类 '$taxonomy' 中创建术语 '$option'。"); } } } // 准备全局属性对象 $global_attribute = new WC_Product_Attribute(); $global_attribute->set_id(wc_attribute_taxonomy_id_by_name($name)); $global_attribute->set_name($taxonomy); $global_attribute->set_options($options); $global_attribute->set_visible($attr->get_visible()); $global_attribute->set_variation($attr->get_variation()); $updated_attributes[$taxonomy] = $global_attribute; // 添加到更新后的属性列表 $attribute_mapping[$name] = $taxonomy; // 映射旧属性名到全局分类 } else { // 保留已存在的全局属性 $updated_attributes[$key] = $attr; } } // 更新商品,仅保留全局属性 $product->set_attributes($updated_attributes); $product->save(); // 更新变体以使用全局属性 update_variation_attributes($product_id, $attribute_mapping); } /** * 更新变体的属性映射 */ function update_variation_attributes($product_id, $attribute_mapping) { $product = wc_get_product($product_id); if (!$product || !$product->is_type('variable')) { error_log("商品 $product_id 不是可变商品或未找到。"); return; } $variations = $product->get_children(); $used_sizes = []; $used_colors = []; foreach ($variations as $variation_index => $variation_id) { $variation = wc_get_product($variation_id); if (!$variation) { error_log("未找到商品 $product_id 的变体 $variation_id。"); continue; } $updated_attributes = []; $missing_attributes = []; $current_attributes = $variation->get_attributes(); foreach ($attribute_mapping as $custom_name => $global_taxonomy) { $custom_value = $variation->get_attribute($custom_name); if ($custom_value) { $term = get_term_by('name', $custom_value, $global_taxonomy); if ($term) { // 检查当前变体是否已设置正确的全局属性 if (!isset($current_attributes['attribute_' . $global_taxonomy]) || $current_attributes['attribute_' . $global_taxonomy] !== $term->slug) { $updated_attributes['attribute_' . $global_taxonomy] = $term->slug; error_log("变体 $variation_id: 将 '$custom_name' 映射到全局分类 '$global_taxonomy' 的术语 '{$term->slug}'。"); } // 记录已使用的属性值 if ($global_taxonomy === 'pa_sizes') { $used_sizes[] = $term->slug; } if ($global_taxonomy === 'pa_colors') { $used_colors[] = $term->slug; } } else { $missing_attributes[] = $global_taxonomy; error_log("变体 $variation_id: 在分类 '$global_taxonomy' 中未找到术语 '$custom_value'。"); } } else { // 如果属性值缺失,自动分配可用术语 $attribute_terms = get_terms([ 'taxonomy' => $global_taxonomy, 'hide_empty' => false, ]); if (!empty($attribute_terms)) { $term_slug = $attribute_terms[$variation_index % count($attribute_terms)]->slug; // 避免重复分配术语 if ( ($global_taxonomy === 'pa_sizes' && !in_array($term_slug, $used_sizes)) || ($global_taxonomy === 'pa_colors' && !in_array($term_slug, $used_colors)) ) { $updated_attributes['attribute_' . $global_taxonomy] = $term_slug; error_log("变体 $variation_id: 为 '$global_taxonomy' 分配术语 '{$term_slug}'。"); } } else { $missing_attributes[] = $global_taxonomy; error_log("变体 $variation_id: 分类 '$global_taxonomy' 下无可用术语。"); } } } if (!empty($updated_attributes)) { // 设置新属性并保存变体 $variation->set_attributes(array_merge($current_attributes, $updated_attributes)); $variation->save(); } else { error_log("商品 $product_id 的变体 $variation_id 未更新任何属性。缺失属性: " . implode(', ', $missing_attributes)); } } // 同步可变商品数据 WC_Product_Variable::sync($product_id); wc_delete_product_transients($product_id); } /** * 同步变体的Printify价格 */ function update_variation_prices($product_id) { $product = wc_get_product($product_id); if (!$product || !$product->is_type('variable')) { error_log("商品 $product_id 不是可变商品或未找到,跳过价格同步。"); return; } $variations = $product->get_children(); foreach ($variations as $variation_id) { $variation = wc_get_product($variation_id); if (!$variation) { error_log("未找到商品 $product_id 的变体 $variation_id,跳过价格同步。"); continue; } // 从Printify元数据获取价格(根据实际元键调整) $printify_regular_price = get_post_meta($variation_id, '_printify_regular_price', true); $printify_sale_price = get_post_meta($variation_id, '_printify_sale_price', true); // 更新常规价格 if (!empty($printify_regular_price)) { $variation->set_regular_price($printify_regular_price); error_log("变体 $variation_id: 同步常规价格为 $printify_regular_price"); } // 更新促销价格(如果存在) if (!empty($printify_sale_price)) { $variation->set_sale_price($printify_sale_price); error_log("变体 $variation_id: 同步促销价格为 $printify_sale_price"); } // 保存变体价格 $variation->save(); } // 清除商品缓存 wc_delete_product_transients($product_id); }
关键修改说明
- 新增
update_variation_prices函数:从Printify存储的元数据中提取变体价格,同步到WooCommerce的常规价格和促销价格字段 - 修正原代码中重复覆盖
attribute_mapping的逻辑错误 - 移除原代码中未定义变量的错误日志输出
- 确保变体在完成属性转换后自动触发价格同步
内容的提问来源于stack exchange,提问作者Юрий Ришко
相关产品推荐
相关产品推荐

