Contact Form 7摄像头图片作为邮件附件发送实现方法
兼容Contact Form 7的摄像头图片邮件附件实现
现有功能代码
我正在开发兼容Contact Form 7的摄像头插件,当前代码已经实现摄像头拍摄图片自动存入WordPress媒体库的功能,代码如下:
add_action('init','web_cam_form_submittion'); function web_cam_form_submittion(){ if(isset($_POST['web_cam_submit'])) { $img = sanitize_text_field($_POST['image']); if($_POST['slug']){ $slug = sanitize_text_field($_POST['slug']); } else{ $slug = ""; } $base = dirname(__FILE__); $folderPath = $base."/upload/"; $image_parts = explode(";base64,", $img); $image_type_aux = explode("image/", $image_parts[0]); $image_type = $image_type_aux[1]; $image_base64 = base64_decode($image_parts[1]); $fileName = uniqid() . '.png'; $file_before_upload = $folderPath . $fileName; file_put_contents($file_before_upload, $image_base64); $image_url = $file_before_upload; $upload_dir = wp_upload_dir(); $image_data = file_get_contents( $image_url ); $filename = basename( $image_url ); if ( wp_mkdir_p( $upload_dir['path'] ) ) { $file = $upload_dir['path'] . '/' . $filename; } else { $file = $upload_dir['basedir'] . '/' . $filename; } file_put_contents( $file, $image_data ); $wp_filetype = wp_check_filetype( $filename, null ); $attachment = array( 'post_mime_type' => $wp_filetype['type'], 'post_title' => sanitize_file_name( $filename ), 'post_content' => '', 'post_status' => 'inherit' ); $attach_id = wp_insert_attachment( $attachment, $file ); require_once( ABSPATH . 'wp-admin/includes/image.php' ); $attach_data = wp_generate_attachment_metadata( $attach_id, $file ); wp_update_attachment_metadata( $attach_id, $attach_data ); unlink($file_before_upload); if(has_action("web_cam_media_id")){ do_action("web_cam_media_id",array("media_id"=>$attach_id,"slug" =>$slug)); } } else{ return ''; } }
需求
调整功能逻辑,实现提交Contact Form 7表单时,将摄像头捕获的图片作为邮件附件发送到指定邮箱。
实现方案
原有逻辑的问题是在init钩子单独处理图片上传,和Contact Form 7的提交流程完全脱节,既没法保证图片和表单数据对应,表单提交失败时还会产生大量无用的媒体库文件。直接用Contact Form 7官方提供的钩子挂载附件即可,步骤如下:
- 调整前端提交逻辑:把摄像头生成的base64图片数据存入表单内name为
webcam_capture的隐藏input,和其他表单字段一起随Contact Form 7提交,不要单独发ajax请求上传图片。 - 绑定
wpcf7_before_send_mail钩子:在表单验证通过、正式发邮件前解析base64图片,生成临时文件后加入CF7的附件列表。 - 增加临时文件清理逻辑:邮件发送完成后自动删除临时文件,不需要保留的话就不用存入媒体库,节省存储空间。
功能代码
把下面代码加到主题的functions.php或者自定义插件文件里,替换掉原来的web_cam_form_submittion相关逻辑即可:
add_action('wpcf7_before_send_mail', 'cf7_attach_webcam_capture', 10, 3); function cf7_attach_webcam_capture($contact_form, &$abort, $submission) { // 获取表单提交的摄像头图片数据 $posted_data = $submission->get_posted_data(); if (empty($posted_data['webcam_capture'])) return; $raw_img = sanitize_text_field($posted_data['webcam_capture']); // 解析base64图片格式 $img_segments = explode(';base64,', $raw_img); if (count($img_segments) < 2) return; $type_seg = explode('image/', $img_segments[0]); $img_ext = !empty($type_seg[1]) ? strtolower(sanitize_file_name($type_seg[1])) : 'png'; $img_binary = base64_decode($img_segments[1]); if (!$img_binary) return; // 创建临时目录存图片 $upload_dir = wp_upload_dir(); $temp_path = $upload_dir['basedir'] . '/cf7-webcam-temp/'; if (!wp_mkdir_p($temp_path)) return; // 生成临时图片文件 $file_name = uniqid('webcam_') . '.' . $img_ext; $full_file_path = $temp_path . $file_name; file_put_contents($full_file_path, $img_binary); // 如果需要同时把图片存入媒体库,取消下面这段注释即可 /* $file_info = wp_check_filetype($file_name, null); $attach_args = [ 'post_mime_type' => $file_info['type'], 'post_title' => sanitize_file_name(pathinfo($file_name, PATHINFO_FILENAME)), 'post_content' => '', 'post_status' => 'inherit' ]; $attach_id = wp_insert_attachment($attach_args, $full_file_path); require_once ABSPATH . 'wp-admin/includes/image.php'; $attach_meta = wp_generate_attachment_metadata($attach_id, $full_file_path); wp_update_attachment_metadata($attach_id, $attach_meta); */ // 把图片加入邮件附件列表 $mail_config = $contact_form->prop('mail'); $exist_attachments = !empty($mail_config['attachments']) ? explode("\n", $mail_config['attachments']) : []; $exist_attachments[] = $full_file_path; $mail_config['attachments'] = implode("\n", array_filter($exist_attachments)); $contact_form->set_properties(['mail' => $mail_config]); // 邮件发送完成后删除临时文件,不需要保留文件就保留这段代码 add_action('wpcf7_mail_sent', function() use ($full_file_path) { if (file_exists($full_file_path)) unlink($full_file_path); }, 10, 0); }
补充说明
- 如果需要只在指定Contact Form 7表单启用该功能,在函数开头加判断
if ($contact_form->id() != 你的表单ID) return;即可- 确保WordPress上传目录有可写权限,否则临时文件生成失败会导致附件无法正常发送
- 如果需要对图片大小、格式做校验,在生成临时文件前加判断逻辑即可,避免不符合要求的图片被发送
内容的提问来源于stack exchange,提问作者Kreawich C
相关产品推荐
相关产品推荐

