Cakephp几秒钟/分钟后发送电子邮件

时间:2013-04-16 21:58:05

标签: php email cakephp cakephp-2.0

在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触发后,即使它没有完成压缩,脚本也会继续发送电子邮件并刷新浏览器。

3 个答案:

答案 0 :(得分:1)

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

我建议您创建一个名为EmailQueue的新表和模型。然后我会创建一个shell,例如/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']);
    }

}

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

答案 1 :(得分:0)

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

Alternativaly,而不是直接发送电子邮件,你可以有效地排队(可能只是通过在数据库的'电子邮件'表中创建一个记录),并通过查找已准备好发送的电子邮件的cron作业检查查看上传的文件是否已完成压缩?

答案 2 :(得分:0)

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

https://github.com/MSeven/cakephp_queue#readme