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

WordPress表单转PDF多语言翻译插件邮件发送故障求助

WP Forms插件:邮件发送失败与提交确认消息被阻止问题排查

我正在开发一款WordPress插件,功能是将WP Forms表单提交内容转成PDF,再通过Google Translate API翻译成德、法、西三种语言并发送。但在本地和服务器环境测试时遇到两个问题:

  • 无法通过wp_mail发送邮件,已安装WP Mail SMTP插件(WP Forms自带通知可正常发送),调用send_test_email也收不到测试邮件
  • 插件激活后,WP Forms的提交确认消息无法显示

以下是当前代码:

<?php
/*
PLUGIN DESCRIPTION HERE
*/

// Hook into the WPForms submission process
add_action('wpforms_process_complete', 'translate_send_pdf_wpforms_process_complete', 10, 4);

function echo_log( $what )
{
    echo '<pre>'.print_r( $what, true ).'</pre>';
}

function translate_send_pdf_wpforms_process_complete($fields, $entry, $form_data, $entry_id) {
    
    $form_data = wpforms()->form->get($form_data['id']);
    echo_log($form_data);
    $user_submitted_data = wpforms()->entry->get($entry_id);

    // send_test_email($entry_id);

    $name_field = 'Single Line Text'; 
    $person_name = isset($user_submitted_data[$name_field]) ? $user_submitted_data[$name_field] : 'Unknown';

    error_log('person_name: ' . print_r($person_name, true));
    echo $person_name;
    echo 'hello';

    // Generate PDF for each language
    $languages = array('de', 'fr', 'es');
    $pdf_files = array();
    foreach ($languages as $language) {
        $translated_content = translate_content($user_submitted_data, $language);
        $pdf_content = generate_pdf($translated_content);
        $pdf_files[$language] = $pdf_content;
    }
    send_pdf_email(
        $pdf_files,
        $languages,
        $person_name
    );

}

// Function to translate content
function translate_content($content, $target_language) {
    $api_key = 'API KEY HERE';
    $url = 'https://translation.googleapis.com/language/translate/v2?key=' . $api_key;

    $data = array(
        'q' => $content,
        'source' => 'en',
        'target' => $target_language,
    );

    // Initialize cURL session
    $handle = curl_init($url);
    curl_setopt($handle, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($handle, CURLOPT_POST, true);
    curl_setopt($handle, CURLOPT_POSTFIELDS, $data);

    // Execute the translation request
    $response = curl_exec($handle);

    // Close the cURL session
    curl_close($handle);

    // Parse the translation response
    $translation_data = json_decode($response, true);

    // Check if translation was successful
    if (isset($translation_data['data']['translations'][0]['translatedText'])) {
        // Extract and return the translated content
        $translated_content = $translation_data['data']['translations'][0]['translatedText'];
        return $translated_content;
    } else {
        // Return the original content if translation failed
        return $content;
    }

    return $content;
}

// Function to generate PDF from content using TCPDF
function generate_pdf($content) {
    // Include the TCPDF library if not already included
    if (!class_exists('TCPDF')) {
        require_once('/tcpdf-wrapper/lib/tcpdf/tcpdf.php');
    }

    // Create a new TCPDF instance
    $pdf = new TCPDF(PDF_PAGE_ORIENTATION, PDF_UNIT, PDF_PAGE_FORMAT, true, 'UTF-8', false);

    // Set document information
    $pdf->SetCreator('Name');
    $pdf->SetAuthor('Name');
    $pdf->SetTitle('Translated PDF');
    $pdf->SetSubject('Translated PDF');
    $pdf->SetKeywords('PDF, translation');

    // Set default header and footer fonts
    $pdf->setHeaderFont(Array(PDF_FONT_NAME_MAIN, '', PDF_FONT_SIZE_MAIN));
    $pdf->setFooterFont(Array(PDF_FONT_NAME_DATA, '', PDF_FONT_SIZE_DATA));

    // Set margins
    $pdf->SetMargins(PDF_MARGIN_LEFT, PDF_MARGIN_TOP, PDF_MARGIN_RIGHT);
    $pdf->SetHeaderMargin(PDF_MARGIN_HEADER);
    $pdf->SetFooterMargin(PDF_MARGIN_FOOTER);

    // Set auto page breaks
    $pdf->SetAutoPageBreak(TRUE, PDF_MARGIN_BOTTOM);

    // Add a page
    $pdf->AddPage();

    // Set font
    $pdf->SetFont('times', '', 12);

    // Add content to the PDF
    $pdf->MultiCell(0, 10, $content, 0, 'L');

    // Output the PDF to a variable
    $pdf_content = $pdf->Output('', 'S');

    return $pdf_content;
}

function send_pdf_email($pdf_files, $languages, $person_name) {
    $to = '...@gmail.com';
    $subject = 'New Form Submission'; 
    $message = 'Please find the attached PDFs for the following languages: ' . implode(', ', $languages);

    $attachments = array();
    $current_date = date('Y-m-d');

    // Loop through PDF files and attach them
    foreach ($pdf_files as $language => $pdf_content) {
        $pdf_file_name = "New_Form_{$person_name}_{$current_date}_{$language}.pdf";
        $attachments[$pdf_file_name] = $pdf_content;
    }

    // Send the email
    wp_mail($to, $subject, $message, '', $attachments);
}

function send_test_email($person_name) {
    $to = '...@gmail.com';
    $subject = 'Test Email';
    $message = "This is a test email sent from your WordPress plugin. {$person_name}";
    $result = wp_mail($to, $subject, $message);

}
?>

问题1:wp_mail发送失败修复

核心原因

  1. wp_mail附件参数要求传入文件路径,而非直接传入文件内容字符串
  2. 钩子执行优先级过高,WP Mail SMTP插件尚未完成初始化
  3. 缺少正确的邮件头设置,易触发邮件服务商的垃圾邮件过滤

修复步骤

  1. 修改send_pdf_email函数,先将PDF内容写入临时文件,再用文件路径作为附件:
function send_pdf_email($pdf_files, $languages, $person_name) {
    $to = '...@gmail.com';
    $subject = 'New Form Submission'; 
    $message = 'Please find the attached PDFs for the following languages: ' . implode(', ', $languages);
    
    // 设置UTF-8编码的邮件头
    $headers = array('Content-Type: text/plain; charset=UTF-8');

    $attachments = array();
    $current_date = date('Y-m-d');
    $temp_dir = wp_upload_dir()['path'] . '/temp_pdfs/';
    
    // 创建临时目录(不存在则自动创建)
    if (!file_exists($temp_dir)) {
        wp_mkdir_p($temp_dir);
    }

    foreach ($pdf_files as $language => $pdf_content) {
        $pdf_file_name = "New_Form_{$person_name}_{$current_date}_{$language}.pdf";
        $temp_file_path = $temp_dir . $pdf_file_name;
        
        // 将PDF内容写入临时文件
        file_put_contents($temp_file_path, $pdf_content);
        
        // 添加文件路径到附件数组
        $attachments[] = $temp_file_path;
    }

    // 发送邮件并记录结果
    $result = wp_mail($to, $subject, $message, $headers, $attachments);
    error_log('PDF邮件发送结果:' . ($result ? '成功' : '失败'));
    
    // 清理临时文件
    foreach ($attachments as $file) {
        if (file_exists($file)) {
            unlink($file);
        }
    }
}
  1. 调整钩子优先级,确保SMTP插件先完成初始化:
// 将优先级从10改为20
add_action('wpforms_process_complete', 'translate_send_pdf_wpforms_process_complete', 20, 4);
  1. 优化测试邮件函数,添加错误日志排查:
function send_test_email($person_name) {
    $to = '...@gmail.com';
    $subject = 'Test Email';
    $message = "This is a test email sent from your WordPress plugin. {$person_name}";
    $headers = array('Content-Type: text/plain; charset=UTF-8');
    
    $result = wp_mail($to, $subject, $message, $headers);
    
    // 记录发送结果和错误信息
    error_log('测试邮件发送结果:' . ($result ? '成功' : '失败'));
    if (!$result) {
        global $phpmailer;
        error_log('WP Mail错误详情:' . $phpmailer->ErrorInfo);
    }
}

问题2:提交确认消息被阻止修复

核心原因

代码中直接使用echo输出调试内容(echo $person_name;、echo_log函数),破坏了WP Forms提交后的AJAX响应格式,导致前端无法解析并显示确认消息。

修复步骤

  1. 移除所有直接echo的代码,改用error_log记录调试信息:
// 删除echo_log函数
// function echo_log( $what ) { ... }

function translate_send_pdf_wpforms_process_complete($fields, $entry, $form_data, $entry_id) {
    // 替换echo_log为error_log
    error_log('表单数据:' . print_r($form_data, true));
    
    $user_submitted_data = wpforms()->entry->get($entry_id);

    $name_field = 'Single Line Text'; 
    $person_name = isset($user_submitted_data[$name_field]) ? $user_submitted_data[$name_field] : 'Unknown';

    error_log('提交人姓名:' . $person_name);
    // 删除echo $person_name;和echo 'hello';
    
    // 剩余业务逻辑代码保持不变
}
  1. 确保整个钩子函数没有任何输出,WP Forms的AJAX响应要求返回纯净的JSON格式,任何额外输出都会导致响应失败。

额外优化建议

  1. 翻译函数中,$content是数组格式,需先转为字符串再传给Google Translate API:
function translate_content($content, $target_language) {
    $api_key = 'API KEY HERE';
    $url = 'https://translation.googleapis.com/language/translate/v2?key=' . $api_key;
    
    // 将表单数组转为键值对字符串
    $content_str = '';
    foreach ($content as $key => $value) {
        $content_str .= "{$key}: {$value}\n";
    }

    $data = array(
        'q' => $content_str,
        'source' => 'en',
        'target' => $target_language,
    );
    
    // 剩余代码保持不变
}
  1. TCPDF路径使用插件相对路径,避免绝对路径问题:
require_once plugin_dir_path(__FILE__) . 'tcpdf-wrapper/lib/tcpdf/tcpdf.php';

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.09 17:29:53