0

我们正在使用 Cake 的 E-Mail 类发送带有附件的电子邮件。它适用于所有情况,除了一种情况,我们无法找出问题所在。

过程:

  • 一个 pdf 文件被创建并写入文件系统(文件被正确写入并且存在)
  • 发送电子邮件时,附件大小为 0 字节(而要附加的文件是在文件系统中正确创建的)

工作代码:
// Write invoice as file
$CakePdf->write(APP . 'tmp' . DS . 'invoices' . DS . $invoiceNo . '.pdf');
[...]
// Send invoice to customer
$Email = new CakeEmail('invoice');
$Email->attachments(APP . 'tmp' . DS . 'invoices' . DS . $invoiceNo . '.pdf');
$Email->to($this->Invoice->Customer->getEmailAdress($customerId));
$Email->viewVars(array('invoice_no' => $invoiceNo));
$Email->send();

无效代码(附件大小为零字节):
$CakePdf->write(APP . 'tmp'. DS .'certificates' . DS . $certLoginId . $certCourseId . '.pdf');
[...]
// Send certificate to customer
$Email = new CakeEmail('certificate');
$Email->attachments(APP . 'tmp'. DS .'certificates' . DS . $certLoginId . $certCourseId . '.pdf');
$Email->to($emailOfUser);
$Email->viewVars(array('courseName' => $certCourseName, 'probandName' => $probandName));
$Email->send();

编辑 - 没有错字,一切都正确设置。问题似乎是,由 tcpdf 生成 PDF 在后台异步运行。因此,当 Cake 尝试附加文件时,它并没有完全写入文件系统。所以不能贴。

如果试图让脚本休眠一段时间但没有成功:

echo '<br>';
echo $path_to_certificate;
echo '<br>';
echo filesize($path_to_certificate);
sleep(10);
echo '<br>';
echo $path_to_certificate;
echo '<br>';
echo filesize($path_to_certificate);
echo '<br>';
sleep(10);
echo $path_to_certificate;
echo '<br>';
echo filesize($path_to_certificate);

输出:

C:\xampp\htdocs\www\eflux_frontend\app\tmp\certificates\13750.pdf
0
C:\xampp\htdocs\www\eflux_frontend\app\tmp\certificates\13750.pdf
0
C:\xampp\htdocs\www\eflux_frontend\app\tmp\certificates\13750.pdf
0

而文件是同时生成的,因为我可以在文件系统中查看和访问该文件。这不是锁定问题,因为其他代码在不同的地方工作,但生成的文件更小,因此不会占用太多时间来处理。

我现在如何确保生成过程完成?

4

1 回答 1

0

似乎我们无法确保在将 PDF 附加到电子邮件之前正确创建 PDF(也许有人可以在这里帮我一把)。

由于创建的 PDF 被写入数据库这一事实,一个丑陋的解决方法是可能的:在 PDF 写入数据库后,我们可以将其从数据库中取出,使用 CakeFileHandler 编写一个文件并将其附加到电子邮件中为我工作:

// Workaround
$this->Certificate->recursive = -1;
$data = $this->Certificate->findById($cert_id);
$pdf = base64_decode($data['Certificate']['certificate_pdf']);

$path_to_certificate = APP . 'tmp'. DS .'certificates' . DS . $certLoginId . $certCourseId . '.pdf'; 
$certificate_file = new File($path_to_certificate);
$certificate_file->write($pdf);

[do mail stuff]

$certificate_file->delete();
$certificate_file->close();
于 2013-07-19T11:15:44.447 回答