Flexible Checkout Fields PRO:多文件无法附加至管理员新订单邮件
问题:WooCommerce Flexible Checkout Fields PRO 多文件附件无法添加到管理员新订单邮件
问题详情
使用Flexible Checkout Fields PRO for WooCommerce插件时,客户下单后能收到包含多文件上传附件的订单邮件,但管理员的「新订单」邮件仅能获取单个文件附件,多文件场景下代码失效。已开启插件「显示位置>页面/邮件>邮件」相关设置,自行编写的代码仅支持单文件,尝试多个版本仍未解决,官方文档无相关解决方案。
当前使用的代码如下:
add_filter('woocommerce_email_attachments', 'add_flexible_checkout_fields_attachments_to_vendor_email', 10, 3); function add_flexible_checkout_fields_attachments_to_vendor_email($attachments, $email_id, $order) { if ($email_id === 'new_order') { $order_id = $order->get_id(); $uploaded_files = get_post_meta($order_id, '_billing_datei_upload', true); if (!empty($uploaded_files)) { if (is_string($uploaded_files)) { $uploaded_files = explode(',', $uploaded_files); } if (is_array($uploaded_files)) { foreach ($uploaded_files as $file) { $file_path = get_attached_file($file); if ($file_path && file_exists($file_path)) { $attachments[] = $file_path; } } } else { $file_path = get_attached_file($uploaded_files); if ($file_path && file_exists($file_path)) { $attachments[] = $file_path; } } } } return $attachments; }
问题分析
原代码的核心问题在于:
get_post_meta使用true作为第三个参数,仅返回单个元值,若插件将多文件ID存储为多组post meta(而非逗号分隔字符串),会直接丢失其余文件数据。- 未考虑插件可能将多文件ID序列化为字符串存储的情况,仅通过逗号分隔解析无法处理序列化数组。
- 钩子优先级设为10,可能早于插件存储元数据的时机,导致获取不到最新的文件信息。
修正后的代码
add_filter('woocommerce_email_attachments', 'add_flexible_checkout_multiple_files_to_admin_email', 20, 3); function add_flexible_checkout_multiple_files_to_admin_email($attachments, $email_id, $order) { // 仅处理管理员新订单邮件 if ($email_id !== 'new_order') { return $attachments; } $order_id = $order->get_id(); // 获取该字段所有元数据,避免丢失多文件记录 $uploaded_files = get_post_meta($order_id, '_billing_datei_upload', false); // 处理单值数组情况 if (is_array($uploaded_files) && count($uploaded_files) === 1) { $uploaded_files = $uploaded_files[0]; } // 解析序列化的数组字符串 if (is_string($uploaded_files) && strpos($uploaded_files, 'a:') === 0) { $uploaded_files = maybe_unserialize($uploaded_files); } // 遍历添加有效文件附件 if (is_array($uploaded_files)) { foreach ($uploaded_files as $file_id) { $file_id = absint($file_id); if ($file_id <= 0) continue; $file_path = get_attached_file($file_id); if ($file_path && file_exists($file_path)) { $attachments[] = $file_path; } } } elseif (is_numeric($uploaded_files)) { // 处理单文件场景 $file_id = absint($uploaded_files); $file_path = get_attached_file($file_id); if ($file_path && file_exists($file_path)) { $attachments[] = $file_path; } } return $attachments; }
关键修正说明
- 将
get_post_meta的第三个参数改为false,获取该字段的所有元值,确保不遗漏多文件记录。 - 增加序列化数组解析逻辑,兼容插件可能的存储格式。
- 提高钩子优先级至20,确保在插件完成元数据存储后执行,获取准确的文件ID。
- 增加文件ID合法性校验,过滤无效ID,避免报错。
额外注意事项
- 确认字段元键
_billing_datei_upload是否正确:可通过查看订单的自定义字段(如使用WP后台的「自定义字段」功能或数据库工具)确认实际存储的元键。 - 测试时开启WooCommerce邮件日志:在「WooCommerce > 设置 > 高级 > 日志」中启用邮件日志,可查看附件添加是否成功及是否有报错信息。
- 若插件存储的是文件URL而非ID,需修改代码中获取文件路径的逻辑:使用
url_to_postid($file_url)将URL转换为附件ID,再调用get_attached_file获取路径。
内容的提问来源于stack exchange,提问作者Anne
相关产品推荐
相关产品推荐

