1

cakephp 中是否有在指定时间内发送电子邮件的方法?

我有一个使用 cakephp 构建的文件上传网站,上传完成后它会发送一封电子邮件以获取下载链接,然后它会调用一个 php CLI 来压缩文件。在压缩过程中,站点已经关闭,所以我不知道压缩过程什么时候结束。我想知道是否可以在 cakephp 电子邮件中指定,例如在刷新页面之前 1 分钟后发送电子邮件。

这是一些代码来显示发生了什么

var xhr_zip;
xhr_zip = new XMLHttpRequest();
fd_zip = new FormData();
fd_zip.append("total_files", total_files);
xhr_zip.open("POST", "datas/zip/", true);
xhr_zip.send(fd_zip);

xhr_update_usage = new XMLHttpRequest();
fd_update_usage = new FormData();
xhr_update_usage.open("POST", "datas/update_usage/", true);
xhr_update_usage.send(fd_update_usage);

xhr_email = new XMLHttpRequest();

fd_email = new FormData();

xhr_email.open("POST", "datas/send_link/" + recipient + '/' + subject, true);
xhr_email.send(fd_email);

    xhr_email.onload = function(e) {
        setTimeout(function() {
            $("body").removeClass("loading");
            window.onbeforeunload = null;
            alert("Total Files : " + total_files + " Sent \n Total Upload Size : " + (total_upload_size/1048576).toFixed(2) + " MB");                   
            document.location.reload(true);
        }, 2000);
    };

因此,在 zip 触发后,即使它没有完成压缩,脚本也会继续发送电子邮件并刷新浏览器。

4

3 回答 3

1

听起来您已经在处理 zip 进度并且可以确定该过程何时完成,因此我将执行以下操作:

我建议您创建一个名为 EmailQueue 之类的新表和模型。然后我会创建一个外壳,例如 /app/Console/Command/EmailShell.php

/**
 * Shell to run background emails
 *
 * @property $EmailQueue
 */
class EmailShell extends AppShell {
    public $uses = array(
        'EmailQueue',
        'Model' // Name of model you are creating the zip for
    );

    public function main() {
        $this->out('You have hit the Email Shell.');
    }

    public function run_email_queue() {
        $emailQueueItem = $this->EmailQueue->find('first', array(
            'conditions' => array(
                'EmailQueue.status' => 0
            ),
            'order' => array(
                'EmailQueue.created ASC'
            )
        ));

        if(empty($emailQueueItem)) {
            $this->out('Email queue is empty.');
            return;
        }

        // Assuming you have a field for file status which is updated on zip completed
        // Alternatively, you could use a separate shell or cli to check
        switch($emailQueueItem['EmailQueue']['file_status']) {
            case "complete":
            case 1:
                $status = $this->send_email($emailQueueItem);
                break;

            default:
                $status = false;
                break;
        }

        if($status !== false) {
            // Update the status so that the email isn't sent later on
            $this->EmailQueue->id = $emailQueueItem['EmailQueue']['id'];
            $this->EmailQueue->save(array(
                'status' => 1
            ));
            $this->out(' ### Sending Email Successful');
        }
    }

    public function send_email($emailQueueItem = array()) {
        // Your model which does the zipping should have the email logic
        // I would have it return true or false.
        return $this->Model->originalEmailFunction($emailQueueItem['EmailQueue']['model_id']);
    }

}

上面是一个非常简化的外壳示例,只需在您的模型中放置某种已完成标志或在外壳完成压缩后更新“EmailQueue”表,然后当您的 cron 命中此外壳时,它将发送电子邮件,提供所述标志是present - 如果您无法在控制器操作中处理它,您可能需要第二个 shell 来更新 zip 文件的标志。

于 2013-04-24T14:48:55.947 回答
0

出于灵活的响应时间的原因,我会使用现成的排队解决方案,例如:

https://github.com/MSeven/cakephp_queue#readme
于 2013-04-17T09:13:51.207 回答
0

您希望用户在文件上传时停留在原始页面上吗?如果是这样,您能否使用回调进行初始 Ajax 调用,并在该回调中执行您的电子邮件发送代码?

或者,不是直接发送电子邮件,您是否可以有效地将其排队(可能只是通过在数据库的“电子邮件”表中创建一条记录)并通过查看是否上传的文件是否已完成压缩?

于 2013-04-17T09:11:09.913 回答