1: | <?php |
2: | |
3: | use Aurora\System\EventEmitter; |
4: | |
5: | require_once __DIR__ . "/../../../system/autoload.php"; |
6: | |
7: | \Aurora\System\Api::Init(true); |
8: | set_time_limit(0); |
9: | date_default_timezone_set("UTC"); |
10: | |
11: | |
12: | |
13: | |
14: | |
15: | |
16: | $oMailScheduledMessagesModule = \Aurora\Modules\MailScheduledMessages\Module::getInstance(); |
17: | $oMailModule = \Aurora\Modules\Mail\Module::getInstance(); |
18: | |
19: | $iTime = time(); |
20: | |
21: | $aMessagesForSend = $oMailScheduledMessagesModule->Decorator()->GetMessagesForSend($iTime); |
22: | foreach ($aMessagesForSend as $aMessageForSend) { |
23: | $mSendResult = false; |
24: | $directMessageToStreamResult = false; |
25: | $oAccount = $oMailModule->GetAccount($aMessageForSend['AccountId']); |
26: | |
27: | try { |
28: | $directMessageToStreamResult = $oMailModule->getMailManager()->directMessageToStream( |
29: | $oAccount, |
30: | function ($rMessageResourse, $sContentType, $sFileName, $sMimeIndex = '') use ($oAccount, &$mSendResult) { |
31: | if (\is_resource($rMessageResourse)) { |
32: | $mSendResult = sendMessage($oAccount, $rMessageResourse); |
33: | \fclose($rMessageResourse); |
34: | } |
35: | }, |
36: | $aMessageForSend['FolderFullName'], |
37: | $aMessageForSend['MessageUid'] |
38: | ); |
39: | } catch (\Exception $oEx) { |
40: | \Aurora\System\Api::LogException($oEx); |
41: | } |
42: | |
43: | if ($directMessageToStreamResult && $mSendResult) { |
44: | $oNamespace = \Aurora\Modules\Mail\Module::getInstance()->getMailManager()->getFoldersNamespace($oAccount); |
45: | $sNamespace = $oNamespace ? $oNamespace->GetPersonalNamespace() : ''; |
46: | $sSentFolderFullName = $sNamespace . 'Sent'; |
47: | |
48: | $oMailModule->Decorator()->MoveMessages($aMessageForSend['AccountId'], $aMessageForSend['FolderFullName'], $sSentFolderFullName, $aMessageForSend['MessageUid']); |
49: | $oMailScheduledMessagesModule->Decorator()->RemoveMessage($aMessageForSend['AccountId'], $aMessageForSend['FolderFullName'], $aMessageForSend['MessageUid']); |
50: | } else { |
51: | |
52: | } |
53: | } |
54: | |
55: | function getRcpt($aHeaders) |
56: | { |
57: | $oResult = \MailSo\Mime\EmailCollection::NewInstance(); |
58: | if (isset($aHeaders['To'])) { |
59: | $oResult->MergeWithOtherCollection( |
60: | \MailSo\Mime\EmailCollection::NewInstance(\ltrim($aHeaders['To'])) |
61: | ); |
62: | } |
63: | if (isset($aHeaders['Cc'])) { |
64: | $oResult->MergeWithOtherCollection( |
65: | \MailSo\Mime\EmailCollection::NewInstance(\ltrim($aHeaders['Cc'])) |
66: | ); |
67: | } |
68: | if (isset($aHeaders['Bcc'])) { |
69: | $oResult->MergeWithOtherCollection( |
70: | \MailSo\Mime\EmailCollection::NewInstance(\ltrim($aHeaders['Bcc'])) |
71: | ); |
72: | } |
73: | |
74: | return $oResult->Unique(); |
75: | } |
76: | |
77: | function getHeaders($rResource) |
78: | { |
79: | $sRawHeaders = ''; |
80: | while (trim($line = fgets($rResource)) !== '') { |
81: | $sRawHeaders .= $line; |
82: | } |
83: | |
84: | $aHeaders = \explode("\n", \str_replace("\r", '', $sRawHeaders)); |
85: | |
86: | $sName = null; |
87: | $sValue = null; |
88: | $aResult = []; |
89: | foreach ($aHeaders as $sHeadersValue) { |
90: | if (0 === strlen($sHeadersValue)) { |
91: | continue; |
92: | } |
93: | |
94: | $sFirstChar = \substr($sHeadersValue, 0, 1); |
95: | if ($sFirstChar !== ' ' && $sFirstChar !== "\t" && false === \strpos($sHeadersValue, ':')) { |
96: | continue; |
97: | } elseif (null !== $sName && ($sFirstChar === ' ' || $sFirstChar === "\t")) { |
98: | $sValue = \is_null($sValue) ? '' : $sValue; |
99: | |
100: | if ('?=' === \substr(\rtrim($sHeadersValue), -2)) { |
101: | $sHeadersValue = \rtrim($sHeadersValue); |
102: | } |
103: | |
104: | if ('=?' === \substr(\ltrim($sHeadersValue), 0, 2)) { |
105: | $sHeadersValue = \ltrim($sHeadersValue); |
106: | } |
107: | |
108: | if ('=?' === \substr($sHeadersValue, 0, 2)) { |
109: | $sValue .= $sHeadersValue; |
110: | } else { |
111: | $sValue .= "\n".$sHeadersValue; |
112: | } |
113: | } else { |
114: | if (null !== $sName) { |
115: | $aResult[$sName] = $sValue; |
116: | |
117: | $sName = null; |
118: | $sValue = null; |
119: | } |
120: | |
121: | $aHeaderParts = \explode(':', $sHeadersValue, 2); |
122: | $sName = $aHeaderParts[0]; |
123: | $sValue = isset($aHeaderParts[1]) ? $aHeaderParts[1] : ''; |
124: | |
125: | if ('?=' === \substr(\rtrim($sValue), -2)) { |
126: | $sValue = \rtrim($sValue); |
127: | } |
128: | } |
129: | } |
130: | if (null !== $sName) { |
131: | $aResult[$sName] = $sValue; |
132: | } |
133: | |
134: | return $aResult; |
135: | } |
136: | |
137: | function sendMessage($oAccount, $rStream) |
138: | { |
139: | if (!$oAccount || !$rStream) { |
140: | throw new \Aurora\System\Exceptions\InvalidArgumentException(); |
141: | } |
142: | |
143: | $rMessageStream = \MailSo\Base\ResourceRegistry::CreateMemoryResource(); |
144: | |
145: | $iMessageStreamSize = \MailSo\Base\Utils::MultipleStreamWriter( |
146: | $rStream, |
147: | array($rMessageStream), |
148: | 8192, |
149: | true, |
150: | true, |
151: | true |
152: | ); |
153: | |
154: | $oMailModule = \Aurora\Modules\Mail\Module::getInstance(); |
155: | $oImapClient =& $oMailModule->getMailManager()->_getImapClient($oAccount); |
156: | |
157: | $mResult = false; |
158: | if (is_resource($rMessageStream)) { |
159: | $aHeaders = getHeaders($rMessageStream); |
160: | $oRcpt = getRcpt($aHeaders); |
161: | |
162: | if ($oRcpt && 0 < $oRcpt->Count()) { |
163: | $oServer = null; |
164: | try { |
165: | $oSettings =& \Aurora\System\Api::GetSettings(); |
166: | $iConnectTimeOut = $oSettings->GetValue('SocketConnectTimeoutSeconds', 5); |
167: | $iSocketTimeOut = $oSettings->GetValue('SocketGetTimeoutSeconds', 5); |
168: | $bVerifySsl = !!$oSettings->GetValue('SocketVerifySsl', false); |
169: | |
170: | $oSmtpClient = \MailSo\Smtp\SmtpClient::NewInstance(); |
171: | $oSmtpClient->SetTimeOuts($iConnectTimeOut, $iSocketTimeOut); |
172: | |
173: | $oLogger = $oImapClient->Logger(); |
174: | if ($oLogger) { |
175: | $oSmtpClient->SetLogger($oLogger); |
176: | } |
177: | |
178: | $oServer = $oAccount->getServer(); |
179: | $iSecure = \MailSo\Net\Enumerations\ConnectionSecurityType::AUTO_DETECT; |
180: | if ($oServer->OutgoingUseSsl) { |
181: | $iSecure = \MailSo\Net\Enumerations\ConnectionSecurityType::SSL; |
182: | } |
183: | |
184: | $sEhlo = \MailSo\Smtp\SmtpClient::EhloHelper(); |
185: | |
186: | $oSmtpClient->Connect($oServer->OutgoingServer, $oServer->OutgoingPort, $sEhlo, $iSecure, $bVerifySsl); |
187: | |
188: | if ($oServer->SmtpAuthType === \Aurora\Modules\Mail\Enums\SmtpAuthType::UseUserCredentials) { |
189: | $oSmtpClient->Login($oAccount->IncomingLogin, $oAccount->getPassword()); |
190: | } elseif ($oServer->SmtpAuthType === \Aurora\Modules\Mail\Enums\SmtpAuthType::UseSpecifiedCredentials) { |
191: | $oSmtpClient->Login($oServer->SmtpLogin, $oServer->SmtpPassword); |
192: | } |
193: | |
194: | $oSmtpClient->MailFrom($oAccount->Email); |
195: | |
196: | $aRcpt =& $oRcpt->GetAsArray(); |
197: | |
198: | foreach ($aRcpt as $oEmail) { |
199: | $sRcptEmail = $oEmail->GetEmail(); |
200: | $oSmtpClient->Rcpt($sRcptEmail); |
201: | } |
202: | |
203: | $aEmails = array(); |
204: | $oRcpt->ForeachList(function ($oEmail) use (&$aEmails) { |
205: | $aEmails[strtolower($oEmail->GetEmail())] = trim($oEmail->GetDisplayName()); |
206: | }); |
207: | |
208: | if (\is_array($aEmails)) { |
209: | $aArgs = ['IdUser' => $oAccount->IdUser, 'Emails' => $aEmails]; |
210: | EventEmitter::getInstance()->emit('Mail', 'AfterUseEmails', $aArgs); |
211: | } |
212: | |
213: | \rewind($rMessageStream); |
214: | $oSmtpClient->DataWithStream($rMessageStream); |
215: | |
216: | $oSmtpClient->LogoutAndDisconnect(); |
217: | \fclose($rMessageStream); |
218: | } catch (\MailSo\Net\Exceptions\ConnectionException $oException) { |
219: | throw new \Aurora\Modules\Mail\Exceptions\Exception( |
220: | \Aurora\Modules\Mail\Enums\ErrorCodes::CannotConnectToMailServer, |
221: | $oException, |
222: | $oException->getMessage() |
223: | ); |
224: | } catch (\MailSo\Smtp\Exceptions\LoginException $oException) { |
225: | throw new \Aurora\Modules\Mail\Exceptions\Exception( |
226: | \Aurora\Modules\Mail\Enums\ErrorCodes::CannotLoginCredentialsIncorrect, |
227: | $oException, |
228: | $oException->getMessage() |
229: | ); |
230: | } catch (\MailSo\Smtp\Exceptions\NegativeResponseException $oException) { |
231: | throw new \Aurora\Modules\Mail\Exceptions\Exception( |
232: | \Aurora\Modules\Mail\Enums\ErrorCodes::CannotSendMessage, |
233: | $oException, |
234: | $oException->getMessage() |
235: | ); |
236: | } catch (\MailSo\Smtp\Exceptions\MailboxUnavailableException $oException) { |
237: | $iErrorCode = ($oServer && $oServer->SmtpAuthType === \Aurora\Modules\Mail\Enums\SmtpAuthType::UseUserCredentials) |
238: | ? \Aurora\Modules\Mail\Enums\ErrorCodes::CannotSendMessageToRecipients |
239: | : \Aurora\Modules\Mail\Enums\ErrorCodes::CannotSendMessageToExternalRecipients; |
240: | throw new \Aurora\Modules\Mail\Exceptions\Exception( |
241: | $iErrorCode, |
242: | $oException, |
243: | $oException->getMessage() |
244: | ); |
245: | } |
246: | |
247: | $mResult = true; |
248: | } else { |
249: | throw new \Aurora\Modules\Mail\Exceptions\Exception(\Aurora\Modules\Mail\Enums\ErrorCodes::CannotSendMessageInvalidRecipients); |
250: | } |
251: | } |
252: | |
253: | return $mResult; |
254: | } |
255: | |