实现WooCommerce产品导入/批量编辑时自动添加下载文件
解决方案
你的代码存在两个关键问题导致导入/批量编辑时失效:
- 变量
$md5_num未定义,导致下载文件无法正确添加到数组 - 部分钩子的参数与函数接收的
$product对象不匹配(比如woocommerce_new_product、save_post传递的是产品ID而非WC_Product对象)
以下是修复并适配产品导入和批量编辑场景的完整代码:
适配产品导入场景
使用woocommerce_product_import_inserted_product_object钩子,这是WooCommerce导入流程中专门用于修改插入后产品对象的钩子,确保导入时自动添加下载文件:
add_action( 'woocommerce_product_import_inserted_product_object', 'auto_add_downloadable_file_on_import', 50, 2 ); function auto_add_downloadable_file_on_import( $product, $data ) { // 仅处理可下载产品,若导入时未设置可下载属性,手动开启 if ( !$product->is_downloadable() ) { $product->set_downloadable( true ); } // 检查是否已有下载文件,避免重复添加 $downloads = (array) $product->get_downloads(); if ( sizeof($downloads) > 0 ) { return $product; } // 获取产品缩略图的完整尺寸URL $thumb_id = get_post_thumbnail_id( $product->get_id() ); if ( !$thumb_id ) { return $product; } $src_img = wp_get_attachment_image_src( $thumb_id, 'full' ); $img_meta = wp_get_attachment_metadata( $thumb_id, false ); if ( !$src_img || !$img_meta ) { return $product; } // 准备下载文件数据 $file_title = $img_meta['image_meta']['title'] ?: $product->get_name(); $file_url = reset($src_img); $file_md5 = md5($file_url); // 创建WC_Product_Download对象 $download = new WC_Product_Download(); $download->set_name( $file_title ); $download->set_id( $file_md5 ); $download->set_file( $file_url ); // 添加到下载数组并更新产品 $downloads[$file_md5] = $download; $product->set_downloads( $downloads ); return $product; }
适配批量编辑场景
如果导入后需要批量处理现有产品,可使用woocommerce_bulk_edit_save_product钩子,或者直接运行一次性脚本批量更新:
批量编辑钩子代码
add_action( 'woocommerce_bulk_edit_save_product', 'auto_add_downloadable_file_on_bulk_edit', 50, 1 ); function auto_add_downloadable_file_on_bulk_edit( $product ) { // 逻辑与导入场景一致,复用核心代码 if ( !$product->is_downloadable() ) { $product->set_downloadable( true ); } $downloads = (array) $product->get_downloads(); if ( sizeof($downloads) > 0 ) { return; } $thumb_id = get_post_thumbnail_id( $product->get_id() ); if ( !$thumb_id ) { return; } $src_img = wp_get_attachment_image_src( $thumb_id, 'full' ); $img_meta = wp_get_attachment_metadata( $thumb_id, false ); if ( !$src_img || !$img_meta ) { return; } $file_title = $img_meta['image_meta']['title'] ?: $product->get_name(); $file_url = reset($src_img); $file_md5 = md5($file_url); $download = new WC_Product_Download(); $download->set_name( $file_title ); $download->set_id( $file_md5 ); $download->set_file( $file_url ); $downloads[$file_md5] = $download; $product->set_downloads( $downloads ); }
一次性批量更新脚本(适合上万产品)
如果批量编辑钩子效率不足,可在主题functions.php中临时添加以下脚本,访问网站任意页面后删除(注意备份数据):
add_action( 'init', 'bulk_add_downloadable_files' ); function bulk_add_downloadable_files() { // 仅管理员可执行 if ( !current_user_can( 'manage_options' ) ) { return; } // 分批获取产品,避免内存溢出 $paged = 1; $per_page = 50; while ( true ) { $products = wc_get_products( array( 'status' => 'publish', 'type' => 'simple', // 根据你的产品类型调整,比如variable 'limit' => $per_page, 'paged' => $paged, 'downloadable' => false, // 仅处理未设置可下载的产品 ) ); if ( empty($products) ) { break; } foreach ( $products as $product ) { // 复用核心逻辑 $downloads = (array) $product->get_downloads(); if ( sizeof($downloads) > 0 ) { continue; } $thumb_id = get_post_thumbnail_id( $product->get_id() ); if ( !$thumb_id ) { continue; } $src_img = wp_get_attachment_image_src( $thumb_id, 'full' ); $img_meta = wp_get_attachment_metadata( $thumb_id, false ); if ( !$src_img || !$img_meta ) { continue; } $product->set_downloadable( true ); $file_title = $img_meta['image_meta']['title'] ?: $product->get_name(); $file_url = reset($src_img); $file_md5 = md5($file_url); $download = new WC_Product_Download(); $download->set_name( $file_title ); $download->set_id( $file_md5 ); $download->set_file( $file_url ); $downloads[$file_md5] = $download; $product->set_downloads( $downloads ); $product->save(); } $paged++; } echo '批量更新完成!'; exit; }
注意事项
- 确保产品的缩略图已正确导入,否则无法获取图片URL
- 对于可变产品,需调整代码以处理每个变体(可根据
$product->is_type('variable')判断并遍历变体) - 批量更新前请备份数据库,避免数据丢失
内容的提问来源于stack exchange,提问作者alberto
相关产品推荐
相关产品推荐

