/** * Looks through the database and sends all the emails that need to be sent * * Emails are built by combining all the configuration settings from the plugin config file and the settings in the email table itself * See the hash::merge line for the order in which the configuration settings are implemented * * Once sent, emails will either be removed or marked 'sent' based on the master configuration setting `deleteAfterSend` * * @return array of results from each email send */ public function process(array $options = []) { $result = []; # find all the emails we need to send $emails = $this->EmailQueues->find(); # apply filters if set if (isset($options['limit'])) { $emails->limit($options['limit']); } if (isset($options['type'])) { $emails->where(['EmailQueues.type' => $options['type']]); } if (isset($options['status'])) { $emails->where(['EmailQueues.status' => $options['status']]); } if (isset($options['id'])) { $emails->where(['EmailQueues.id' => $options['id']]); } # build and send each email foreach ($emails as $email) { $config = $this->_getConfig($email); $profile = $this->_buildProfile($config, $email); $e = new Email($profile); # attempt to send the email try { # try and catch errors during transmission set_error_handler(function ($errno, $errstr, $errfile, $errline) { throw new \ErrorException($errstr, $errno, 0, $errfile, $errline); }); # now that the email is built, send it $e->send(); $email->status = self::STATUS_SENT; $email->sent_on = date('Y-m-d H:i:s'); restore_error_handler(); } catch (\Exception $e) { Log::error($e->getMessage()); $email->status = self::STATUS_ERROR; $email->error = $e->getMessage(); } # log it - include as much relevant data as possible $e = $e->jsonSerialize(); $log = $this->EmailLogs->newEntity(['email_id' => $email->id, 'email_type' => $email->type, 'email_data' => ['email' => $e, 'config' => $config, 'profile' => $email->toArray()], 'sent_to' => $e['_to'], 'sent_from' => $e['_from'], 'sent_on' => $email->sent_on ?: null, 'processed_on' => new \DateTime(), 'status' => $email->status, 'status_message' => $email->error]); $this->EmailLogs->save($log); # either delete or update the email depending on Configure::read(EmailQueue.master.deleteAfterSend) if ($config['deleteAfterSend'] && $email->status === self::STATUS_SENT) { $this->EmailQueues->delete($email); } else { $this->EmailQueues->save($email); } $result[] = $email; } # return the results from each email return $result; }