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