示例#1
0
 /**
  * SendMail.
  *
  * @return bool True if it was sent or pushed
  */
 public function sendMail()
 {
     try {
         $emailTo = $this->emailTo;
         $nameTo = $this->nameTo;
         if ($this->userTo) {
             $user = $this->UserModel;
             if (!$user->id) {
                 $this->status = 'invalid';
                 $this->save();
                 $message = "Sending an email to an invalid user <{$this->userTo}> with action <{$this->mailAction}>.";
                 Log::notifySlack(":bangbang: {$message}");
                 return false;
             }
             if (empty($emailTo)) {
                 $emailTo = $user->email;
             }
             if (empty($nameTo)) {
                 if (!empty($user->name)) {
                     $nameTo = $user->name . ' ' . $user->surname;
                 } elseif (!empty($user->first_name)) {
                     $nameTo = $user->first_name . ' ' . $user->last_name;
                 }
             }
         } else {
             $user = false;
         }
         if (empty($emailTo)) {
             $this->status = 'invalid';
             $this->save();
             $with = $this->id ? "with id <{$this->id}> and" : 'with';
             $message = "Sending an email without email address {$with} action <{$this->mailAction}>.";
             Log::notifySlack(":bangbang: {$message}");
             return false;
         }
         $mail = new \Quaver\App\Model\Mail();
         $objMail = $mail->getFromAction($this->mailAction, $user ? $user->language : Config::get('core.LANG'));
         if (empty($objMail)) {
             $this->status = 'invalid';
             $this->save();
             $message = "An invalid mail action <{$this->mailAction}>.";
             Log::notifySlack(":bangbang: {$message}");
             return false;
         }
         if ($this->getBlock()) {
             return $this->push();
         }
         $title = $objMail->title;
         $template = htmlspecialchars_decode($objMail->template, ENT_QUOTES);
         $actionSender = $this->getActionSender($user);
         $this->status = 'sending';
         if ($this->exists()) {
             // Avoid concurrency with two cron at the same time
             $statusChange = $this->getFieldChange('status');
             if ($statusChange) {
                 $this->once('preSave', function ($carry, $event, $stopPropagation) {
                     $stopPropagation();
                     $model = $event['target'];
                     $db = new DB();
                     $sql = "UPDATE {$this->table} SET status = 'sending' WHERE id = ? AND status != 'sending'";
                     $result = $db->query($sql, $this->id);
                     return (bool) $result->rowCount();
                 });
             }
             if (!$statusChange || !$this->save(['status'])) {
                 throw new \LengthException("Concurrency detected sending the mail {$this->id}");
             }
         }
         // Update all possible changes and send the mail
         if ($this->save()) {
             try {
                 $ret = parent::send($subject = $actionSender->renderSubject($title), $body = \Quaver\App\Model\Mail::getMailTemplate($actionSender->renderBody($template)), $emailTo, $nameTo, $this->emailFrom, $this->nameFrom, $this->bcc, $actionSender->getAttachments(), $actionSender->getReplyTo());
             } catch (\Mandrill_Error $e) {
                 $ret = false;
             } catch (QException $e) {
                 $with = $this->id ? "with id <{$this->id}>," : 'with';
                 $objects = json_encode($this->mailObjects);
                 $message = "An unexpected mail error occurred {$with} email <{$emailTo}>, action <{$this->mailAction}> and objects <{$objects}>.\n";
                 $message .= get_class($e) . ' - ' . $e->getMessage();
                 Log::notifySlack(":bangbang: {$message}");
                 $ret = false;
             }
             if (!empty($ret)) {
                 $this->mandrill = $ret[0]['_id'];
                 $this->status = in_array($ret[0]['status'], ['rejected', 'invalid']) ? $ret[0]['status'] : 'sent';
                 $this->titleSent = $subject;
                 $this->bodySent = $body;
                 $this->sent = date('Y-m-d H:i:s');
                 if ($this->save()) {
                     $actionSender->onSent($this);
                 }
             } else {
                 // Fallback
                 if (++$this->retries >= self::MAX_RETRIES) {
                     $this->status = 'timeout';
                     $this->save();
                     $objects = json_encode($this->mailObjects);
                     $message = "A mailcenter timeout error occurred {$with} email <{$emailTo}>, action <{$this->mailAction}> and objects <{$objects}>.";
                     Log::notifySlack(":bangbang: {$message}");
                 } else {
                     return $this->push();
                 }
             }
         } else {
             $message = "An unexpected error occurred updating the mail {$this->id} before sending.\n";
             Log::notifySlack(":bangbang: {$message}");
         }
     } catch (QException $e) {
         $with = $this->id ? "with id <{$this->id}>," : 'with';
         $objects = json_encode($this->mailObjects);
         $message = "An unexpected mail error occurred {$with} action <{$this->mailAction}> and objects <{$objects}>.\n";
         $message .= get_class($e) . ' - ' . $e->getMessage();
         Log::notifySlack(":bangbang: {$message}");
     }
     return $this->status === 'sent';
 }