2013-04-16 41 views
1

反正有cakephp在指定時間內發送電子郵件嗎?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); 
    }; 

所以,拉鍊觸發後,即使它不能完成荏苒,該腳本將移動到發送電子郵件,並刷新瀏覽器。

+0

爲什麼不在壓縮後發送郵件 – 2013-04-16 22:00:49

+0

@Dagon,因爲壓縮是通過php完成的,而通過CakePHP發送電子郵件。它就像2個不同的應用程序。所以,如果我必須在壓縮後執行此操作,則需要將代碼移到標準的PHP代碼中,我試圖不去做 – Harts

+1

蛋糕是一個框架,而不是另一種語言。 – 2013-04-16 22:33:03

回答

0

您希望用戶在文件上傳時保留在原始頁面上嗎?如果是這樣,你可以做一個回調初始的Ajax調用,並執行你的電子郵件發送代碼在該回調?

替代性地,不是直接發送電子郵件,而是有效地排隊它(也許只需在數據庫中的「電子郵件」表中創建一條記錄),然後通過cron作業檢查是否可以發送電子郵件看看上傳的文件是否完成了壓縮?

0

爲華而不實的響應時間的原因我會用一個現成的架子排隊的解決方案,例如:

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

這聽起來像你已經在處理壓縮的進度,並確定何時過程完成,所以我會做以下幾點:

我建議你創建一個新的表和名爲類似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']); 
    } 

} 

上面是外殼的非常簡單的例子,只是把某種完成標誌的模型或更新「EmailQueue」表一旦你的shell已經完成了壓縮,那麼當你的cron命中這個shell時,它會發送提供該標誌的電子郵件 - 你可能需要第二個shell來更新壓縮文件的標誌,如果你無法處理它你的控制器行動。