function send_outbox_mails() { session_commit(); set_time_limit(0); $utils = new MailUtilities(); if (!array_var($_GET, 'acc_id')) { $userAccounts = MailAccounts::getMailAccountsByUser(logged_user()); } else { $account = MailAccounts::findById(array_var($_GET, 'acc_id')); $userAccounts = array($account); } $old_memory_limit = ini_get('memory_limit'); if (php_config_value_to_bytes($old_memory_limit) < 256 * 1024 * 1024) { ini_set('memory_limit', '256M'); } foreach ($userAccounts as $account) { $accountUser = null; if (logged_user() instanceof User) { $accountUser = MailAccountUsers::getByAccountAndUser($account, logged_user()); } if (!$account || !$accountUser) { flash_error(lang('no access permissions')); ajx_current("empty"); return; } $errorMailId = 0; try { $mails = MailContents::findAll(array("conditions" => array("`is_deleted`=0 AND `state` >= 200 AND `account_id` = ? AND `created_by_id` = ?", $account->getId(), $accountUser->getUserId()), "order" => "`state` ASC")); $count = 0; foreach ($mails as $mail) { // Only send mails with pair status if ($mail->getState() % 2 == 1) { continue; } // Set impair status, to avoid sending it again when sending it in parallel if (!$mail->addToStatus(1)) { continue; } try { $errorMailId = $mail->getId(); $to = $mail->getTo(); $from = array($account->getEmailAddress() => $account->getFromName()); $subject = $mail->getSubject(); $body = $mail->getBodyHtml() != '' ? $mail->getBodyHtml() : $mail->getBodyPlain(); $cc = $mail->getCc(); $bcc = $mail->getBcc(); $type = $mail->getBodyHtml() != '' ? 'text/html' : 'text/plain'; $msg_id = $mail->getMessageId(); $in_reply_to_id = $mail->getInReplyToId(); $attachments = self::readAttachmentsFromFileSystem($mail, $att_version); if ($mail->getBodyHtml() != '') { $images = get_image_paths($body); } else { $images = null; } $mail->setSentDate(DateTimeValueLib::now()); $mail->setReceivedDate(DateTimeValueLib::now()); if (defined('DEBUG') && DEBUG) { file_put_contents(ROOT . "/cache/log_mails.txt", gmdate("d-m-Y H:i:s") . " antes de enviar: " . $mail->getId() . "\n", FILE_APPEND); } $sentOK = $utils->sendMail($account->getSmtpServer(), $to, $from, $subject, $body, $cc, $bcc, $attachments, $account->getSmtpPort(), $account->smtpUsername(), $account->smtpPassword(), $type, $account->getOutgoingTrasnportType(), $msg_id, $in_reply_to_id, $images, $complete_mail, $att_version); } catch (Exception $e) { // actions are taken below depending on the sentOK variable Logger::log("Could not send email: " . $e->getMessage() . "\nmail_id=" . $mail->getId()); $sentOK = false; } try { if ($sentOK) { DB::beginWork(); $mail->setState(3); $mail->save(); DB::commit(); } else { Logger::log("Swift returned sentOK = false after sending email\nmail_id=" . $mail->getId()); // set status to a higher and pair value, to retry later. if (!$mail->addToStatus(1)) { Logger::log("Swift could not send the email and the state could not be set to retry later.\nmail_id=" . $mail->getId()); } } } catch (Exception $e) { Logger::log("Exception marking email as sent: " . $e->getMessage() . "\nmail_id=" . $mail->getId()); if ($sentOK) { DB::rollback(); } } if (defined('DEBUG') && DEBUG) { file_put_contents(ROOT . "/cache/log_mails.txt", gmdate("d-m-Y H:i:s") . " despues de enviar: " . $mail->getId() . "\n", FILE_APPEND); } try { //if user selected the option to keep a copy of sent mails on the server if ($sentOK && config_option("sent_mails_sync") && $account->getSyncServer() != null && $account->getSyncSsl() != null && $account->getSyncSslPort() != null && $account->getSyncFolder() != null && $account->getSyncAddr() != null && $account->getSyncPass() != null) { $check_sync_box = MailUtilities::checkSyncMailbox($account->getSyncServer(), $account->getSyncSsl(), $account->getOutgoingTrasnportType(), $account->getSyncSslPort(), $account->getSyncFolder(), $account->getSyncAddr(), $account->getSyncPass()); if ($check_sync_box) { MailUtilities::sendToServerThroughIMAP($account->getSyncServer(), $account->getSyncSsl(), $account->getOutgoingTrasnportType(), $account->getSyncSslPort(), $account->getSyncFolder(), $account->getSyncAddr(), $account->getSyncPass(), $complete_mail); } } } catch (Exception $e) { Logger::log("Could not save sent mail in server through imap: " . $e->getMessage() . "\nmail_id=" . $mail->getId()); } if (defined('DEBUG') && DEBUG) { file_put_contents(ROOT . "/cache/log_mails.txt", gmdate("d-m-Y H:i:s") . " antes de try: " . $mail->getId() . "\n", FILE_APPEND); } try { if ($sentOK) { if (defined('DEBUG') && DEBUG) { file_put_contents(ROOT . "/cache/log_mails.txt", gmdate("d-m-Y H:i:s") . " sentOK=true: " . $mail->getId() . "\n", FILE_APPEND); } if (FileRepository::isInRepository($mail->getContentFileId())) { if ($att_version >= 2) { // delete attachments from repository foreach ($attachments as $att) { if (FileRepository::isInRepository($att['repo_id'])) { FileRepository::deleteFile($att['repo_id']); } } if (is_file($att['path'])) { @unlink($att['path']); } // if file was copied to tmp -> delete it if (defined('DEBUG') && DEBUG) { file_put_contents(ROOT . "/cache/log_mails.txt", gmdate("d-m-Y H:i:s") . " deleted attachments: " . $mail->getId() . "\n", FILE_APPEND); } } FileRepository::deleteFile($mail->getContentFileId()); if (defined('DEBUG') && DEBUG) { file_put_contents(ROOT . "/cache/log_mails.txt", gmdate("d-m-Y H:i:s") . " deleted att list: " . $mail->getId() . "\n", FILE_APPEND); } } } } catch (Exception $e) { Logger::log("Exception deleting tmp repository files (attachment list): " . $e->getMessage() . "\nmail_id=" . $mail->getId()); } try { DB::beginWork(); if ($sentOK) { $content = $complete_mail; $repository_id = $utils->saveContent($content); if (defined('DEBUG') && DEBUG) { file_put_contents(ROOT . "/cache/log_mails.txt", gmdate("d-m-Y H:i:s") . " content saved: " . $mail->getId() . "\n", FILE_APPEND); } $mail->setContentFileId($repository_id); $mail->setSize(strlen($content)); if (config_option("sent_mails_sync") && isset($check_sync_box) && $check_sync_box) { $mail->setSync(true); } $mail->save(); if (defined('DEBUG') && DEBUG) { file_put_contents(ROOT . "/cache/log_mails.txt", gmdate("d-m-Y H:i:s") . " email saved: " . $mail->getId() . "\n", FILE_APPEND); } $properties = array("id" => $mail->getId()); evt_add("mail sent", $properties); $count++; } DB::commit(); } catch (Exception $e) { DB::rollback(); Logger::log("Exception deleting tmp repository files (attachment list): " . $e->getMessage() . "\nmail_id=" . $mail->getId()); } } if ($count > 0) { evt_add("mails sent", $count); } } catch (Exception $e) { $errorEmailUrl = ''; if ($errorMailId > 0) { $email = MailContents::findById($errorMailId); if ($email instanceof MailContent) { Logger::log("failed to send mail: " . $e->getMessage() . "\n" . $email->getEditUrl()); Logger::log($e->getTraceAsString()); $errorEmailUrl = $email->getEditUrl(); } } flash_error($errorEmailUrl != '' ? $e->getMessage() : $e->getMessage()); ajx_current("empty"); } } ini_set('memory_limit', $old_memory_limit); ajx_current("empty"); }
function send_outbox_mails($user = null, $user_account = null, $from_time = null) { if (is_null($user)) { $user = logged_user(); } $from_time_cond = ""; if (!is_null($from_time) && $from_time instanceof DateTimeValue) { $from_time_cond = " AND `created_on` > '" . $from_time->toMySQL() . "'"; } session_commit(); set_time_limit(0); $utils = new MailUtilities(); if (!is_null($user_account)) { $userAccounts = array($user_account); } elseif (array_var($_GET, 'acc_id')) { $account = MailAccounts::findById(array_var($_GET, 'acc_id')); $userAccounts = array($account); } else { $userAccounts = MailAccounts::getMailAccountsByUser($user); } $old_memory_limit = ini_get('memory_limit'); if (php_config_value_to_bytes($old_memory_limit) < 256 * 1024 * 1024) { ini_set('memory_limit', '256M'); } foreach ($userAccounts as $account) { $accountUser = null; if ($user instanceof Contact) { $accountUser = MailAccountContacts::getByAccountAndContact($account, $user); } if (!$account || !$accountUser) { flash_error(lang('no access permissions')); ajx_current("empty"); return; } $errorMailId = 0; try { $mails = MailContents::findAll(array("conditions" => array("`is_deleted`=0 AND `state` >= 200 AND `account_id` = ? AND `created_by_id` = ? {$from_time_cond}", $account->getId(), $accountUser->getContactId()), "order" => "`state` ASC")); $count = 0; foreach ($mails as $mail) { /* @var $mail MailContent */ if ($mail->getTrashedById() > 0) { continue; } // Only send mails with pair status if ($mail->getState() % 2 == 1) { continue; } //if is archived do not send it if ($mail->isArchived()) { continue; } // Set impair status, to avoid sending it again when sending it in parallel if (!$mail->addToStatus(1)) { continue; } try { $errorMailId = $mail->getId(); $to = $mail->getTo(); if (!$accountUser instanceof MailAccountContact) { $from = array($account->getEmailAddress() => $account->getFromName()); } else { if ($user instanceof Contact && $accountUser->getIsDefault() && $accountUser->getSenderName() == "") { $from = array($account->getEmailAddress() => $user->getObjectName()); } else { $from = array($account->getEmailAddress() => $accountUser->getSenderName()); } } $subject = $mail->getSubject(); $body = $mail->getBodyHtml() != '' ? $mail->getBodyHtml() : $mail->getBodyPlain(); $cc = $mail->getCc(); $bcc = $mail->getBcc(); $type = $mail->getBodyHtml() != '' ? 'text/html' : 'text/plain'; $msg_id = $mail->getMessageId(); $in_reply_to_id = $mail->getInReplyToId(); $attachments = self::readAttachmentsFromFileSystem($mail, $att_version); if ($mail->getBodyHtml() != '') { $images = get_image_paths($body); } else { $images = null; } // Inline images preg_match_all("/<img[^>]*src=[\"'][^\"']*[\"']/", $body, $matches); foreach ($matches as $match) { $pos = strpos($match[0], 'src="'); $url = substr($match[0], $pos + 5); $url = substr($url, 0, -1); if (str_starts_with($url, ROOT_URL . "/tmp/")) { $path = str_replace(ROOT_URL, ROOT, $url); if (!is_array($images)) { $images = array(); } $images[$url] = $path; } if (str_starts_with($url, "data:")) { $mime_type = substr($url, 5, strpos($url, ';') - 5); $extension = substr($mime_type, strpos($mime_type, "/") + 1); if (!is_array($images)) { $images = array(); } $file_url = ROOT_URL . "/tmp/" . gen_id() . ".{$extension}"; $path = str_replace(ROOT_URL, ROOT, $file_url); $data = substr($url, strpos($url, "base64") + 6); file_put_contents($path, base64_decode($data)); $images[$file_url] = $path; $body = str_replace($url, $file_url, $body); } } $mail->setSentDate(DateTimeValueLib::now()); $mail->setReceivedDate(DateTimeValueLib::now()); if (defined('DEBUG') && DEBUG) { file_put_contents(ROOT . "/cache/log_mails.txt", gmdate("d-m-Y H:i:s") . " antes de enviar: " . $mail->getId() . "\n", FILE_APPEND); } $sentOK = $utils->sendMail($account->getSmtpServer(), $to, $from, $subject, $body, $cc, $bcc, $attachments, $account->getSmtpPort(), $account->smtpUsername(), $account->smtpPassword(), $type, $account->getOutgoingTrasnportType(), $msg_id, $in_reply_to_id, $images, $complete_mail, $att_version); $mail->orderConversation(); } catch (Exception $e) { // actions are taken below depending on the sentOK variable Logger::log("Could not send email: " . $e->getMessage() . "\nmail_id=" . $mail->getId()); $sentOK = false; } try { if ($sentOK) { DB::beginWork(); $mail->setState(3); $mail->save(); DB::commit(); } else { Logger::log("Swift returned sentOK = false after sending email\nmail_id=" . $mail->getId()); // set status to a higher and pair value, to retry later. if (!$mail->addToStatus(1)) { Logger::log("Swift could not send the email and the state could not be set to retry later.\nmail_id=" . $mail->getId()); } } } catch (Exception $e) { $extra_exception_info = $sentOK == true ? '(but it has been sent)' : '(and it has NOT been sent)'; Logger::log("Exception marking email as sent " . $extra_exception_info . ": " . $e->getMessage() . "\nmail_id=" . $mail->getId()); if ($sentOK) { DB::rollback(); } } if (defined('DEBUG') && DEBUG) { file_put_contents(ROOT . "/cache/log_mails.txt", gmdate("d-m-Y H:i:s") . " despues de enviar: " . $mail->getId() . "\n", FILE_APPEND); } try { //if user selected the option to keep a copy of sent mails on the server if ($sentOK && config_option("sent_mails_sync") && $account->getSyncServer() != null && $account->getSyncSsl() != null && $account->getSyncSslPort() != null && $account->getSyncFolder() != null && $account->getSyncAddr() != null && $account->getSyncPass() != null) { $check_sync_box = MailUtilities::checkSyncMailbox($account->getSyncServer(), $account->getSyncSsl(), $account->getOutgoingTrasnportType(), $account->getSyncSslPort(), $account->getSyncFolder(), $account->getSyncAddr(), $account->getSyncPass()); if ($check_sync_box) { MailUtilities::sendToServerThroughIMAP($account->getSyncServer(), $account->getSyncSsl(), $account->getOutgoingTrasnportType(), $account->getSyncSslPort(), $account->getSyncFolder(), $account->getSyncAddr(), $account->getSyncPass(), $complete_mail); } } } catch (Exception $e) { Logger::log("Could not save sent mail in server through imap: " . $e->getMessage() . "\nmail_id=" . $mail->getId()); } if (defined('DEBUG') && DEBUG) { file_put_contents(ROOT . "/cache/log_mails.txt", gmdate("d-m-Y H:i:s") . " antes de try: " . $mail->getId() . "\n", FILE_APPEND); } try { if ($sentOK) { if (defined('DEBUG') && DEBUG) { file_put_contents(ROOT . "/cache/log_mails.txt", gmdate("d-m-Y H:i:s") . " sentOK=true: " . $mail->getId() . "\n", FILE_APPEND); } if (FileRepository::isInRepository($mail->getContentFileId())) { if ($att_version >= 2) { // delete attachments from repository foreach ($attachments as $att) { if (FileRepository::isInRepository($att['repo_id'])) { FileRepository::deleteFile($att['repo_id']); } } if (isset($att['path']) && is_file($att['path'])) { @unlink($att['path']); } // if file was copied to tmp -> delete it if (defined('DEBUG') && DEBUG) { file_put_contents(ROOT . "/cache/log_mails.txt", gmdate("d-m-Y H:i:s") . " deleted attachments: " . $mail->getId() . "\n", FILE_APPEND); } } FileRepository::deleteFile($mail->getContentFileId()); if (defined('DEBUG') && DEBUG) { file_put_contents(ROOT . "/cache/log_mails.txt", gmdate("d-m-Y H:i:s") . " deleted att list: " . $mail->getId() . "\n", FILE_APPEND); } } } else { if (defined('DEBUG') && DEBUG) { file_put_contents(ROOT . "/cache/log_mails.txt", gmdate("d-m-Y H:i:s") . " sentOK=false: " . $mail->getId() . " - Error when sending mail: SentOK = false \n", FILE_APPEND); } } } catch (Exception $e) { Logger::log("Exception deleting tmp repository files (attachment list): " . $e->getMessage() . "\nmail_id=" . $mail->getId()); } try { DB::beginWork(); if ($sentOK) { $content = $complete_mail; $repository_id = $utils->saveContent($content); if (defined('DEBUG') && DEBUG) { file_put_contents(ROOT . "/cache/log_mails.txt", gmdate("d-m-Y H:i:s") . " content saved: " . $mail->getId() . "\n", FILE_APPEND); } $mail->setContentFileId($repository_id); $mail->setSize(strlen($content)); if (config_option("sent_mails_sync") && isset($check_sync_box) && $check_sync_box) { $mail->setSync(true); } $mail->save(); if (defined('DEBUG') && DEBUG) { file_put_contents(ROOT . "/cache/log_mails.txt", gmdate("d-m-Y H:i:s") . " email saved: " . $mail->getId() . "\n", FILE_APPEND); } $properties = array("id" => $mail->getId()); evt_add("mail sent", $properties); $count++; } DB::commit(); } catch (Exception $e) { DB::rollback(); Logger::log("Exception deleting tmp repository files (attachment list): " . $e->getMessage() . "\nmail_id=" . $mail->getId()); } } if ($count > 0) { evt_add("mails sent", $count); } } catch (Exception $e) { $errorEmailUrl = ''; if ($errorMailId > 0) { $email = MailContents::findById($errorMailId); if ($email instanceof MailContent) { Logger::log("failed to send mail: " . $e->getMessage() . "\n" . $email->getEditUrl()); Logger::log($e->getTraceAsString()); $errorEmailUrl = $email->getEditUrl(); } } flash_error($errorEmailUrl != '' ? $e->getMessage() : $e->getMessage()); ajx_current("empty"); } } ini_set('memory_limit', $old_memory_limit); ajx_current("empty"); }