In particular, it tries to maintain the following features:
/** * Checks if there are some emails waiting in queue and sends them if possible. */ function send() { $alreadySent = Db::sentOrLockedCount(60); if ($alreadySent !== false) { $available = floor(ipGetOption('Email.hourlyLimit') * 0.8 - $alreadySent); //20% for immediate emails $lockKey = md5(uniqid(rand(), true)); if ($available > 0) { if ($available > 5 && !defined('CRON')) { //only cron job can send many emails at once. $available = 5; } $locked = Db::lock($available, $lockKey); } else { $available = 0; $locked = 0; } if ($locked == $available) { //if in queue left some messages if (ipGetOption('Email.hourlyLimit') - ($alreadySent + $available) > 0) { $locked = $locked + Db::lockOnlyImmediate(ipGetOption('Email.hourlyLimit') - ($alreadySent + $available), $lockKey); } } if ($locked) { $emails = Db::getLocked($lockKey); foreach ($emails as $key => $email) { if (function_exists('set_time_limit')) { set_time_limit((sizeof($emails) - $key) * 10 + 100); } $mail = new \PHPMailer(); /* $mail->Sender = $email['from']; $mail->addCustomHeader("Return-Path: " . $email['from']);*/ $mail->From = $email['from']; $mail->FromName = $email['fromName']; $mail->AddReplyTo($email['from'], $email['fromName']); $mail->WordWrap = 50; // set word wrap $mail->CharSet = ipConfig()->get('charset'); $mail->Subject = $email['subject']; /* foreach($this->posted_files as $file){ if(isset($_FILES[$file]['tmp_name']) && $_FILES[$file]['error'] == 0){ $mail->AddAttachment($_FILES[$file]['tmp_name'], $_FILES[$file]['name']); } }*/ $files = explode("\n", $email['files']); $fileNames = explode("\n", $email['fileNames']); $fileMimeTypes = explode("\n", $email['fileMimeTypes']); $fileCount = min(count($files), count($fileNames), count($fileMimeTypes)); for ($i = 0; $i < $fileCount; $i++) { if ($files[$i] != '') { if ($fileMimeTypes[$i] == '') { $answer = $mail->AddAttachment($files[$i], $fileNames[$i]); } else { $answer = $mail->AddAttachment($files[$i], $fileNames[$i], "base64", $fileMimeTypes[$i]); } if (!$answer) { ipLog()->error('Email.addAttachmentFailed: {subject} to {to}', array('to' => $email['to'], 'subject' => $email['subject'], 'filename' => $fileNames[$i])); return false; } } } if ($email['html']) { $mail->IsHTML(true); // send as HTML $mail->MsgHTML($email['email']); try { $altBody = \Ip\Internal\Text\Html2Text::convert($email['email']); } catch (\Ip\Internal\Text\Html2TextException $e) { $altBody = $email['email']; } $mail->AltBody = $altBody; } else { /*$h2t = new \Ip\Internal\Text\Html2Text($content, false); $mail->Body = $h2t->get_text();*/ $mail->Body = $email['email']; } $mail->AddAddress($email['to'], $email['toName']); $mail = ipFilter('ipSendEmailPHPMailerObject', $mail, $email); if (!$mail->Send()) { ipLog()->error('Email.sendFailed: {subject} to {to}', array('to' => $email['to'], 'subject' => $email['subject'], 'body' => $email['email'])); return false; } if (sizeof($emails) > 5) { sleep(1); } Db::unlockOne($email['id']); } } } return null; }