PluginProbe
AcyMailing – An Ultimate Newsletter Plugin and Marketing Automation Solution for WordPress / 11.1.1
AcyMailing – An Ultimate Newsletter Plugin and Marketing Automation Solution for WordPress v11.1.1
11.1.1 11.1.0 11.0.5 11.0.4 11.0.3 11.0.2 11.0.1 11.0.0 10.11.1 10.11.0 10.10.2 10.10.1 10.10.0 10.9.1 trunk 10.0.0 10.0.1 10.1.0 10.1.1 10.1.2 10.1.3 10.1.4 10.2.0 10.2.1 10.2.2 All 62 releases
← All changes | back/Helpers/MailerHelper.php +0 -1793 10.10.2 → 11.1.1 View file →
@@ -1,1793 +1,0 @@
1 -<?php
2 -
3 -namespace AcyMailing\Helpers;
4 -
5 -use AcyMailing\Classes\CampaignClass;
6 -use AcyMailing\Classes\ConfigurationClass;
7 -use AcyMailing\Classes\FollowupClass;
8 -use AcyMailing\Classes\MailArchiveClass;
9 -use AcyMailing\Classes\MailClass;
10 -use AcyMailing\Classes\OverrideClass;
11 -use AcyMailing\Classes\UrlClass;
12 -use AcyMailing\Classes\UserClass;
13 -use AcyMailerPhp\Exception;
14 -use AcyMailerPhp\OAuth;
15 -use AcyMailerPhp\Mailer;
16 -use AcyMailing\Libraries\Pelago\Emogrifier\CssInliner;
17 -use AcyMailing\Libraries\Pelago\Emogrifier\HtmlProcessor\HtmlPruner;
18 -
19 -class MailerHelper extends Mailer
20 -{
21 - const NEW_TRY_ERRORS = [1, 6];
22 - const REGEX_URL = '#<[^>]* href[ ]*=[ ]*"(?!mailto:|\#|ymsgr:|callto:|file:|ftp:|webcal:|skype:|tel:)([^"]+)"#Ui';
23 -
24 - public $to = [];
25 - public $cc = [];
26 - public $bcc = [];
27 - public $ReplyTo = [];
28 - public $attachment = [];
29 - public $CustomHeader = [];
30 -
31 - public string $preheader;
32 - public string $replyname;
33 - public string $replyemail;
34 - public string $body;
35 - public string $altbody;
36 - public string $subject;
37 - public string $from;
38 - public string $fromName;
39 - public array $replyto;
40 - public bool $custom_view;
41 -
42 - private EncodingHelper $encodingHelper;
43 - private EditorHelper $editorHelper;
44 - private UserClass $userClass;
45 - private MailClass $mailClass;
46 - private MailArchiveClass $mailArchiveClass;
47 - public ConfigurationClass $config;
48 -
49 - public bool $report = true;
50 - public bool $alreadyCheckedAddresses = false;
51 - public int $errorNumber = 0;
52 - public bool $failedCounting = true;
53 -
54 - public bool $autoAddUser = false;
55 - public bool $userCreationTriggers = true;
56 -
57 - public string $reportMessage = '';
58 - public bool $dtextsFailed = false;
59 - private array $originalDynamicUrls = [];
60 -
61 - public bool $trackEmail = false;
62 -
63 - public string $externalMailer;
64 -
65 - public string $stylesheet = '';
66 - public array $settings;
67 -
68 - public array $parameters = [];
69 -
70 - private string $userLanguage = '';
71 - private string $receiverEmail;
72 -
73 - private object $overrideEmailToSend;
74 - public bool $isTest = false;
75 - public bool $isSpamTest = false;
76 - public bool $isForward = false;
77 -
78 - public int $mailId = 0;
79 - public int $creator_id;
80 - public string $type;
81 - public string $links_language;
82 - public int $id = 0;
83 - public ?object $mail = null;
84 - private array $defaultMail = [];
85 -
86 - public array $listsIds = [];
87 - private string $currentSendingMethod = '';
88 - private array $currentMethodSetting = [];
89 -
90 - public bool $isAbTest = false;
91 - public bool $isTransactional = false;
92 - public bool $isOneTimeMail = false;
93 - public bool $isSendingMethodByListActive = false;
94 - public string $portError;
95 -
96 - public function __construct()
97 - {
98 - parent::__construct();
99 -
100 - $this->XMailer = ' ';
101 - $this->SMTPAutoTLS = false;
102 -
103 - $this->encodingHelper = new EncodingHelper();
104 - $this->editorHelper = new EditorHelper();
105 - $this->userClass = new UserClass();
106 - $this->mailClass = new MailClass();
107 - $this->mailArchiveClass = new MailArchiveClass();
108 - $this->config = acym_config();
109 -
110 - $this->setFrom($this->getSendSettings('from_email'), $this->getSendSettings('from_name'));
111 - $this->Sender = $this->cleanText($this->getSendSettings('bounce_email'));
112 - if (empty($this->Sender)) {
113 - $this->Sender = '';
114 - }
115 - $maxLineLength = $this->config->get('mailer_wordwrap', 0);
116 - if (!empty($maxLineLength) && self::MAX_LINE_LENGTH > $maxLineLength) {
117 - $this->WordWrap = $maxLineLength;
118 - }
119 -
120 - $this->setSendingMethodSetting();
121 -
122 - if ($this->config->get('dkim', 0) && $this->Mailer != 'elasticemail') {
123 - $this->DKIM_domain = $this->config->get('dkim_domain');
124 - $this->DKIM_selector = $this->config->get('dkim_selector', 'acy');
125 - if (empty($this->DKIM_selector)) $this->DKIM_selector = 'acy';
126 - $this->DKIM_passphrase = $this->config->get('dkim_passphrase');
127 - $this->DKIM_identity = $this->config->get('dkim_identity');
128 - $this->DKIM_private = trim($this->config->get('dkim_private'));
129 - $this->DKIM_private_string = trim($this->config->get('dkim_private'));
130 - }
131 -
132 - $this->CharSet = strtolower($this->config->get('charset'));
133 - if (empty($this->CharSet)) {
134 - $this->CharSet = 'utf-8';
135 - }
136 -
137 - $this->clearAll();
138 -
139 - $this->Encoding = $this->config->get('encoding_format');
140 - if (empty($this->Encoding)) {
141 - $this->Encoding = '8bit';
142 - }
143 -
144 - @ini_set('pcre.backtrack_limit', 1000000);
145 -
146 - $this->SMTPOptions = ['ssl' => ['verify_peer' => false, 'verify_peer_name' => false, 'allow_self_signed' => true]];
147 -
148 - $this->addParamInfo();
149 - }
150 -
151 - public function setSendingMethodSetting(): void
152 - {
153 - $externalSendingMethod = [];
154 - acym_trigger('onAcymGetSendingMethods', [&$externalSendingMethod, true]);
155 - $externalSendingMethod = array_keys($externalSendingMethod['sendingMethods']);
156 -
157 - $mailerMethodConfig = $this->getSendingMethod();
158 - $this->currentSendingMethod = $mailerMethodConfig;
159 -
160 - if ($mailerMethodConfig === 'google') {
161 - $this->isSMTP();
162 - $this->Host = 'smtp.gmail.com:465';
163 - $this->SMTPAuth = true;
164 - $this->Username = trim($this->getSendingMethodSettings('google_username'));
165 - $this->AuthType = 'XOAUTH2';
166 - $this->SMTPSecure = 'ssl';
167 -
168 - $this->setOAuth(
169 - new OAuth(
170 - [
171 - 'sendingMethod' => 'google',
172 - 'tokenGenerationUrl' => 'https://oauth2.googleapis.com/token',
173 - 'userName' => $this->Username,
174 - 'clientId' => trim($this->getSendingMethodSettings('google_client_id')),
175 - 'clientSecret' => trim($this->getSendingMethodSettings('google_client_secret')),
176 - 'oauthToken' => trim($this->getSendingMethodSettings('google_access_token')),
177 - 'oauthTokenExpiration' => trim($this->getSendingMethodSettings('google_access_token_expiration')),
178 - 'refreshToken' => trim($this->getSendingMethodSettings('google_refresh_token')),
179 - ]
180 - )
181 - );
182 -
183 - if (empty($this->Sender)) {
184 - $this->Sender = strpos($this->Username, '@') ? $this->Username : $this->getSendingMethodSettings('from_email');
185 - }
186 - } elseif ($mailerMethodConfig === 'outlook') {
187 - $this->isSMTP();
188 - $tenant = trim($this->getSendingMethodSettings('outlook_tenant', 'consumers'));
189 - $host = $tenant === 'consumers' ? 'smtp-mail.outlook.com' : 'smtp.office365.com';
190 - $this->Host = $host.':587';
191 - $this->SMTPAuth = true;
192 - $this->Username = trim($this->getSendingMethodSettings('outlook_username'));
193 - $this->AuthType = 'XOAUTH2';
194 - $this->SMTPSecure = 'tls';
195 -
196 - $this->setOAuth(
197 - new OAuth(
198 - [
199 - 'sendingMethod' => 'outlook',
200 - 'tokenGenerationUrl' => 'https://login.microsoftonline.com/'.$tenant.'/oauth2/v2.0/token',
201 - 'userName' => $this->Username,
202 - 'clientId' => trim($this->getSendingMethodSettings('outlook_client_id')),
203 - 'clientSecret' => trim($this->getSendingMethodSettings('outlook_client_secret')),
204 - 'oauthToken' => trim($this->getSendingMethodSettings('outlook_access_token')),
205 - 'oauthTokenExpiration' => trim($this->getSendingMethodSettings('outlook_access_token_expiration')),
206 - 'refreshToken' => trim($this->getSendingMethodSettings('outlook_refresh_token')),
207 - ]
208 - )
209 - );
210 -
211 - if (empty($this->Sender)) {
212 - $this->Sender = strpos($this->Username, '@') ? $this->Username : $this->getSendingMethodSettings('from_email');
213 - }
214 - } elseif ($mailerMethodConfig === 'smtp') {
215 - $this->isSMTP();
216 - $this->Host = trim($this->getSendingMethodSettings('smtp_host'));
217 - $port = $this->getSendingMethodSettings('smtp_port');
218 - if (empty($port) && $this->getSendingMethodSettings('smtp_secured') === 'ssl') {
219 - $port = 465;
220 - }
221 - if (!empty($port)) {
222 - $this->Host .= ':'.$port;
223 - }
224 - $this->SMTPAuth = (bool)$this->getSendingMethodSettings('smtp_auth', '1');
225 - $this->Username = trim($this->getSendingMethodSettings('smtp_username'));
226 -
227 - $authMethod = $this->getSendingMethodSettings('smtp_method');
228 - if (in_array($authMethod, ['CRAM-MD5', 'LOGIN', 'PLAIN'])) {
229 - $this->AuthType = $authMethod;
230 - }
231 - if ($this->SMTPAuth) {
232 - $this->Password = trim($this->getSendingMethodSettings('smtp_password'));
233 - }
234 -
235 - $this->SMTPSecure = trim($this->getSendingMethodSettings('smtp_secured'));
236 -
237 - if (empty($this->Sender)) {
238 - $this->Sender = strpos($this->Username, '@') ? $this->Username : $this->getSendingMethodSettings('from_email');
239 - }
240 - } elseif ($mailerMethodConfig === 'sendmail') {
241 - $this->isSendmail();
242 - $this->Sendmail = trim($this->getSendingMethodSettings('sendmail_path'));
243 - if (empty($this->Sendmail)) {
244 - $this->Sendmail = '/usr/sbin/sendmail';
245 - }
246 - } elseif ($mailerMethodConfig === 'qmail') {
247 - $this->isQmail();
248 - } elseif ($mailerMethodConfig === 'amazon') {
249 - $this->isSMTP();
250 - $amazonCredentials = [];
251 - acym_trigger('onAcymGetCredentialsSendingMethod', [&$amazonCredentials, 'amazon', $this->currentMethodSetting], 'plgAcymAmazon');
252 - $this->Host = trim($amazonCredentials['amazon_host']).':587';
253 - $this->Username = trim($amazonCredentials['amazon_username']);
254 - $this->Password = trim($amazonCredentials['amazon_password']);
255 - $this->SMTPAuth = true;
256 - $this->SMTPSecure = 'tls';
257 - } elseif ($mailerMethodConfig === 'brevo-smtp') {
258 - $this->isSMTP();
259 - $brevoSmtpCredentials = [];
260 - acym_trigger('onAcymGetCredentialsSendingMethod', [&$brevoSmtpCredentials, 'brevo-smtp', $this->currentMethodSetting], 'plgAcymBrevo');
261 - $this->Host = trim($brevoSmtpCredentials['brevo-smtp_host']).':587';
262 - $this->Username = trim($brevoSmtpCredentials['brevo-smtp_username']);
263 - $this->Password = trim($brevoSmtpCredentials['brevo-smtp_password']);
264 - $this->SMTPAuth = true;
265 - $this->SMTPSecure = 'tls';
266 - } elseif (in_array($mailerMethodConfig, $externalSendingMethod)) {
267 - $this->isExternal($mailerMethodConfig);
268 - } else {
269 - $this->isMail();
270 - }
271 - }
272 -
273 - protected function externalSend(string $MIMEHeader, string $MIMEBody): bool
274 - {
275 - $fromName = empty($this->FromName) ? $this->config->get('from_name') : $this->FromName;
276 - $reply_to = array_shift($this->ReplyTo);
277 -
278 - $attachments = [];
279 - if (!empty($this->attachment) && $this->config->get('embed_files')) {
280 - foreach ($this->attachment as $i => $oneAttach) {
281 - $encodedContent = $this->encodeFile($oneAttach[0], $oneAttach[3]);
282 - $this->attachment[$i]['contentEncoded'] = $encodedContent;
283 - }
284 - $attachments = $this->attachment;
285 - }
286 -
287 - $response = [];
288 - $data = [
289 - &$response,
290 - $this,
291 - ['email' => $this->to[0][0], 'name' => $this->to[0][1]],
292 - ['email' => $this->From, 'name' => $fromName],
293 - ['email' => $reply_to[0], 'name' => $reply_to[1]],
294 - !empty($this->bcc) ? $this->bcc : [],
295 - $attachments,
296 - $this->currentMethodSetting,
297 - ];
298 - acym_trigger('onAcymSendEmail', $data);
299 -
300 - if (!empty($response['error'])) {
301 - $this->setError($response['message']);
302 -
303 - return false;
304 - }
305 -
306 - return true;
307 - }
308 -
309 - public function send(): bool
310 - {
311 - if (!file_exists(ACYM_LIBRARIES.'Mailer'.DS.'Mailer.php')) {
312 - $this->reportMessage = acym_translationSprintf('ACYM_X_FILE_MISSING', 'Mailer', ACYM_LIBRARIES.'Mailer'.DS);
313 - if ($this->report) {
314 - acym_enqueueMessage($this->reportMessage, 'error');
315 - }
316 -
317 - return false;
318 - }
319 -
320 - if (empty($this->Subject) || empty($this->Body)) {
321 - if ($this->isTest && empty($this->Subject)) {
322 - $this->Subject = acym_translation('ACYM_EMAIL_SUBJECT');
323 - } else {
324 - $this->reportMessage = acym_translation('ACYM_SEND_EMPTY');
325 - $this->errorNumber = 8;
326 - if ($this->report) {
327 - acym_enqueueMessage($this->reportMessage, 'error');
328 - }
329 -
330 - return false;
331 - }
332 - }
333 -
334 - if (empty($this->ReplyTo) && empty($this->ReplyToQueue)) {
335 - if (!empty($this->replyemail)) {
336 - $replyToEmail = $this->replyemail;
337 - } elseif ($this->config->get('from_as_replyto', 1) == 1) {
338 - $replyToEmail = $this->getSendSettings('from_email');
339 - } else {
340 - $replyToEmail = $this->getSendSettings('replyto_email');
341 - }
342 -
343 - if (!empty($this->replyname)) {
344 - $replyToName = $this->replyname;
345 - } elseif ($this->config->get('from_as_replyto', 1) == 1) {
346 - $replyToName = $this->getSendSettings('from_name');
347 - } else {
348 - $replyToName = $this->getSendSettings('replyto_name');
349 - }
350 -
351 - $this->acymAddReplyTo($replyToEmail, $replyToName);
352 - }
353 -
354 - $shouldEmbed = $this->config->get('embed_images', 0);
355 - if (intval($shouldEmbed) === 1 && $this->Mailer !== 'elasticemail') {
356 - $this->embedImages();
357 - }
358 -
359 - if (!$this->alreadyCheckedAddresses) {
360 - $this->alreadyCheckedAddresses = true;
361 -
362 - $replyToTmp = '';
363 - if (!empty($this->ReplyTo)) {
364 - $replyToTmp = reset($this->ReplyTo);
365 - $replyToTmp = $replyToTmp[0];
366 - } elseif (!empty($this->ReplyToQueue)) {
367 - $replyToTmp = reset($this->ReplyToQueue);
368 - $replyToTmp = $replyToTmp[1];
369 - }
370 -
371 - if (empty($replyToTmp) || !acym_isValidEmail($replyToTmp)) {
372 - $this->reportMessage = acym_translation('ACYM_VALID_EMAIL').' ( '.acym_translation('ACYM_REPLYTO_EMAIL').' : '.(empty($this->ReplyTo) ? '' : $replyToTmp).' ) ';
373 - $this->errorNumber = 9;
374 - if ($this->report) {
375 - acym_enqueueMessage($this->reportMessage, 'error');
376 - }
377 -
378 - return false;
379 - }
380 -
381 - if (empty($this->From) || !acym_isValidEmail($this->From)) {
382 - $this->reportMessage = acym_translation('ACYM_VALID_EMAIL').' ( '.acym_translation('ACYM_FROM_EMAIL').' : '.$this->From.' ) ';
383 - $this->errorNumber = 9;
384 - if ($this->report) {
385 - acym_enqueueMessage($this->reportMessage, 'error');
386 - }
387 -
388 - return false;
389 - }
390 -
391 - if (!empty($this->Sender) && !acym_isValidEmail($this->Sender)) {
392 - $this->reportMessage = acym_translation('ACYM_VALID_EMAIL').' ( '.acym_translation('ACYM_BOUNCE_EMAIL').' : '.$this->Sender.' ) ';
393 - $this->errorNumber = 9;
394 - if ($this->report) {
395 - acym_enqueueMessage($this->reportMessage, 'error');
396 - }
397 -
398 - return false;
399 - }
400 - }
401 -
402 - if ($this->config->get('save_body') === '1') {
403 - @file_put_contents(ACYM_ROOT.'acydebug_mail.html', $this->Body);
404 - }
405 -
406 - $this->Body = htmlentities($this->Body);
407 - $this->Body = htmlspecialchars_decode($this->Body);
408 - $this->Body = str_replace(['&amp;', '&sigmaf;'], ['&', 'ς'], $this->Body);
409 -
410 - if ($this->CharSet !== 'utf-8') {
411 - $this->Body = $this->encodingHelper->change($this->Body, 'UTF-8', $this->CharSet);
412 - $this->Subject = $this->encodingHelper->change($this->Subject, 'UTF-8', $this->CharSet);
413 - }
414 -
415 - $this->Subject = str_replace(
416 - ['’', '“', '”', '–'],
417 - ["'", '"', '"', '-'],
418 - $this->Subject
419 - );
420 -
421 - $this->Body = str_replace(" ", ' ', $this->Body);
422 -
423 - $externalSending = false;
424 -
425 - $this->isOneTimeMail = $this->isTransactional = $this->isForward || $this->isTest || $this->isSpamTest;
426 - if (!empty($this->mailId) && !empty($this->defaultMail[$this->mailId])) {
427 - if ($this->mailClass->isTransactionalMail($this->defaultMail[$this->mailId])) {
428 - $this->isTransactional = true;
429 - }
430 -
431 - if ($this->mailClass->isOneTimeMail($this->defaultMail[$this->mailId])) {
432 - $this->isOneTimeMail = true;
433 - }
434 - }
435 -
436 - acym_trigger('onAcymProcessQueueExternalSendingCampaign', [&$externalSending, $this->isTransactional]);
437 -
438 - $warnings = '';
439 -
440 - if (ACYM_PRODUCTION) {
441 - if ($externalSending) {
442 - $result = false;
443 - acym_trigger('onAcymRegisterReceiverContentAndList', [&$result, $this->Subject, $this->Body, $this->receiverEmail, $this->mailId, &$warnings]);
444 - } else {
445 - acym_trigger('onAcymBeforeEmailSend', [&$this]);
446 - ob_start();
447 - $result = parent::send();
448 - $warnings = ob_get_clean();
449 - }
450 - }
451 -
452 -
453 - if (!empty($warnings) && strpos($warnings, 'bloque')) {
454 - $result = false;
455 - }
456 -
457 - $this->mailHeader = '';
458 -
459 - $receivers = [];
460 - foreach ($this->to as $oneReceiver) {
461 - $receivers[] = $oneReceiver[0];
462 - }
463 -
464 - if (!$result) {
465 - $this->reportMessage = acym_translationSprintf('ACYM_SEND_ERROR', '<b>'.$this->Subject.'</b>', '<b>'.implode(' , ', $receivers).'</b>');
466 - if (!empty($this->ErrorInfo)) {
467 - $this->reportMessage .= " \n\n ".$this->ErrorInfo;
468 - }
469 - if (!empty($warnings)) {
470 - $this->reportMessage .= " \n\n ".$warnings;
471 - }
472 - $this->errorNumber = 1;
473 - if ($this->report) {
474 - $this->reportMessage = str_replace(
475 - 'Could not instantiate mail function',
476 - '<a target="_blank" href="'.ACYM_DOCUMENTATION.'faq/could-not-instantiate-mail-function">'.acym_translation('ACYM_COUND_NOT_INSTANCIATE_MAIL_FUCNTION').'</a>',
477 - $this->reportMessage
478 - );
479 - acym_enqueueMessage(nl2br($this->reportMessage), 'error');
480 - }
481 - } else {
482 - if ($this->isSendingMethodByListActive) {
483 - $this->reportMessage = acym_translationSprintf(
484 - 'ACYM_SEND_SUCCESS_WITH_SENDING_METHOD',
485 - '<b>'.$this->Subject.'</b>',
486 - '<b>'.implode(' , ', $receivers).'</b>',
487 - '<b>'.$this->currentSendingMethod.'</b>'
488 - );
489 - } else {
490 - $this->reportMessage = acym_translationSprintf('ACYM_SEND_SUCCESS', '<b>'.$this->Subject.'</b>', '<b>'.implode(' , ', $receivers).'</b>');
491 - }
492 -
493 - if (!empty($warnings)) {
494 - $this->reportMessage .= " \n\n ".$warnings;
495 - }
496 -
497 - if ($this->report && acym_isAdmin()) {
498 - acym_enqueueMessage(preg_replace('#(<br( ?/)?>){2}#', '<br />', nl2br($this->reportMessage)), 'info');
499 - }
500 - }
501 -
502 - return $result;
503 - }
504 -
505 - public function clearAll(): void
506 - {
507 - $this->Subject = '';
508 - $this->Body = '';
509 - $this->AltBody = '';
510 - $this->ClearAllRecipients();
511 - $this->ClearAttachments();
512 - $this->ClearCustomHeaders();
513 - $this->ClearReplyTos();
514 - $this->errorNumber = 0;
515 - $this->MessageID = '';
516 - $this->ErrorInfo = '';
517 - $this->setFrom($this->getSendSettings('from_email'), $this->getSendSettings('from_name'));
518 - }
519 -
520 - public function load(int $mailId, ?object $user = null): ?object
521 - {
522 - if (isset($this->defaultMail[$mailId])) {
523 - return $this->defaultMail[$mailId];
524 - }
525 -
526 - if (!empty($this->overrideEmailToSend)) {
527 - $this->defaultMail[$mailId] = $this->overrideEmailToSend;
528 - } else {
529 - $this->defaultMail[$mailId] = $this->mailClass->getOneById($mailId, true);
530 - }
531 -
532 - global $acymLanguages;
533 - if (!$this->isAbTest && empty($this->overrideEmailToSend) && acym_isMultilingual()) {
534 - $defaultLanguage = $this->config->get('multilingual_default', ACYM_DEFAULT_LANGUAGE);
535 - $mails = $this->mailClass->getMultilingualMails($mailId);
536 -
537 - $this->userLanguage = !empty($user->language) ? $user->language : $defaultLanguage;
538 -
539 - if (!empty($mails)) {
540 - $languages = array_keys($mails);
541 - if (count($languages) == 1) {
542 - $key = $languages[0];
543 - } elseif (empty($mails[$this->userLanguage])) {
544 - $key = $defaultLanguage;
545 - } else {
546 - $key = $this->userLanguage;
547 - }
548 -
549 - if (isset($mails[$key])) {
550 - $this->defaultMail[$mailId] = $mails[$key];
551 - }
552 - } else {
553 - unset($this->defaultMail[$mailId]);
554 -
555 - return null;
556 - }
557 -
558 - $acymLanguages['userLanguage'] = $this->userLanguage;
559 - $this->setFrom($this->getSendSettings('from_email'), $this->getSendSettings('from_name'));
560 - }
561 -
562 - if (empty($this->defaultMail[$mailId]->id)) {
563 - unset($this->defaultMail[$mailId]);
564 -
565 - return null;
566 - }
567 -
568 - if (!empty($this->defaultMail[$mailId]->attachments)) {
569 - $this->defaultMail[$mailId]->attach = [];
570 -
571 - $attachments = json_decode($this->defaultMail[$mailId]->attachments, true);
572 - foreach ($attachments as $oneAttach) {
573 - $attach = new \stdClass();
574 - $attach->name = basename($oneAttach['filename']);
575 - $attach->filename = str_replace(['/', '\\'], DS, ACYM_ROOT).$oneAttach['filename'];
576 - $attach->url = ACYM_LIVE.$oneAttach['filename'];
577 - $this->defaultMail[$mailId]->attach[] = $attach;
578 - }
579 - }
580 -
581 -
582 - $this->mailId = $mailId;
583 - $this->id = $this->mailId;
584 - $this->mail = clone $this->defaultMail[$mailId];
585 - acym_trigger('replaceContent', [&$this->defaultMail[$mailId], true]);
586 -
587 - $this->prepareEmailContent($mailId);
588 - if (!$this->isTest) {
589 - $this->storeArchiveVersion($mailId);
590 - }
591 -
592 - return $this->defaultMail[$mailId];
593 - }
594 -
595 - public function sendOne($mailId, $user, array $options = []): bool
596 - {
597 - $this->clearAll();
598 -
599 - $receiver = $this->loadUser($user);
600 - $this->isTest = !empty($options['isTest']);
601 - $this->dtextsFailed = false;
602 -
603 - if (empty($receiver->email)) {
604 - $this->errorNumber = 4;
605 - $this->reportMessage = acym_translationSprintf('ACYM_SEND_ERROR_USER', '<b><i>'.acym_escape($user).'</i></b>');
606 - if ($this->report) {
607 - acym_enqueueMessage($this->reportMessage, 'error');
608 - }
609 -
610 - return false;
611 - }
612 -
613 - $mailId = intval($mailId);
614 - $receiver->id = intval($receiver->id);
615 -
616 - if (!$this->load($mailId, $receiver)) {
617 - $this->reportMessage = 'Can not load the email with ID n°'.$mailId;
618 - $this->errorNumber = 2;
619 -
620 - if ($this->report) {
621 - acym_enqueueMessage($this->reportMessage, 'error');
622 - }
623 -
624 - return false;
625 - }
626 -
627 - $this->prepareContent($mailId, $options);
628 - $this->prepareHeaders($mailId, $receiver->id, $options);
629 - $this->prepareAddresses($mailId, $receiver);
630 - $this->prepareBcc($mailId, $options);
631 - $this->prepareAttachments($mailId, $options);
632 - $this->replaceDynamicContent($mailId);
633 - $this->extractOriginalDynamicUrls();
634 - if (!$this->handleDtexts($receiver)) {
635 - $this->dtextsFailed = true;
636 -
637 - return false;
638 - }
639 - $this->prepareTracking($mailId, $receiver);
640 -
641 - $status = $this->send();
642 -
643 - $this->initStatistics($status, $receiver->id);
644 -
645 - return $status;
646 - }
647 -
648 - public function triggerFollowUpAgain(string $mailId, string $userId): void
649 - {
650 - if ($this->defaultMail[$mailId]->type !== MailClass::TYPE_FOLLOWUP) {
651 - return;
652 - }
653 -
654 - $followUpClass = new FollowupClass();
655 - $followUp = $followUpClass->getOneByMailId(intval($mailId));
656 -
657 - if (empty($followUp)) {
658 - return;
659 - }
660 -
661 - if (empty($followUp->loop)) {
662 - return;
663 - }
664 -
665 - $lastEmail = $followUpClass->getLastEmail(intval($followUp->id));
666 - if (empty($lastEmail) || $lastEmail->id != $mailId) {
667 - return;
668 - }
669 -
670 - $delay = 0;
671 - if (!empty($followUp->loop_delay)) {
672 - $delay = $followUp->loop_delay;
673 - }
674 -
675 - $mailToSkip = [];
676 - if (!empty($followUp->loop_mail_skip)) {
677 - $mailToSkip = json_decode($followUp->loop_mail_skip);
678 - }
679 -
680 - $followUpClass->triggerFollowUp(intval($followUp->id), intval($userId), $delay, $mailToSkip);
681 - }
682 -
683 - public function statClick(int $mailId, int $userid, bool $fromStat = false, string $userkey = ''): void
684 - {
685 - if (!$fromStat && !in_array($this->type, MailClass::TYPES_WITH_STATS)) {
686 - return;
687 - }
688 -
689 - $urlClass = new UrlClass();
690 - $urls = [];
691 -
692 - $trackingSystemExternalWebsite = $this->config->get('trackingsystemexternalwebsite', 1);
693 - $trackingSystem = $this->config->get('trackingsystem', 'acymailing');
694 - if (false === strpos($trackingSystem, 'acymailing') && false === strpos($trackingSystem, 'google')) {
695 - return;
696 - }
697 -
698 - if (strpos($trackingSystem, 'google') !== false) {
699 - $mail = $this->mailClass->getOneById($mailId);
700 - $campaignClass = new CampaignClass();
701 - $campaign = $campaignClass->getOneCampaignByMailId($mailId);
702 -
703 - $utmCampaign = acym_getAlias($mail->subject);
704 - }
705 -
706 - preg_match_all(self::REGEX_URL, $this->body, $results);
707 - if (empty($results)) {
708 - return;
709 - }
710 -
711 - $countLinks = array_count_values($results[1]);
712 - if (array_product($countLinks) != 1) {
713 - $previousLinkHandled = '';
714 - foreach ($results[1] as $key => $url) {
715 - if ($countLinks[$url] === 1) {
716 - continue;
717 - }
718 -
719 - $previousIsOutlook = false;
720 - if (strpos($results[0][$key], '<v:roundrect') === 0) {
721 - $previousLinkHandled = $results[0][$key];
722 - if ($countLinks[$url] === 2) {
723 - $countLinks[$url] = 1;
724 - continue;
725 - }
726 - } elseif (strpos($previousLinkHandled, '<v:roundrect') === 0) {
727 - $previousIsOutlook = true;
728 - }
729 - $previousLinkHandled = $results[0][$key];
730 -
731 - if (!$previousIsOutlook) {
732 - $countLinks[$url]--;
733 - }
734 -
735 - $toAddUrl = (strpos($url, '?') === false ? '?' : '&').'idU='.$countLinks[$url];
736 -
737 - if ($previousIsOutlook) {
738 - $countLinks[$url]--;
739 - }
740 -
741 - $posHash = strpos($url, '#');
742 - if ($posHash !== false) {
743 - $newURL = substr($url, 0, $posHash).$toAddUrl.substr($url, $posHash);
744 - } else {
745 - $newURL = $url.$toAddUrl;
746 - }
747 -
748 - $this->body = preg_replace('#href="('.preg_quote($url, '#').')"#Uis', 'href="'.$newURL.'"', $this->body, 1);
749 -
750 - $results[0][$key] = 'href="'.$newURL.'"';
751 - $results[1][$key] = $newURL;
752 - }
753 - }
754 -
755 - foreach ($results[1] as $i => $url) {
756 - $urlsNotToTrack = [
757 - 'task=unsub',
758 - 'fonts.googleapis.com',
759 - ];
760 -
761 - $track = true;
762 -
763 - foreach ($urlsNotToTrack as $urlNotToTrack) {
764 - if (strpos($url, $urlNotToTrack)) {
765 - $track = false;
766 - break;
767 - }
768 - }
769 -
770 - if (isset($urls[$results[0][$i]]) || !$track) {
771 - continue;
772 - }
773 -
774 - $simplifiedUrl = str_replace(['https://', 'http://', 'www.'], '', $url);
775 - $simplifiedWebsite = str_replace(['https://', 'http://', 'www.'], '', ACYM_LIVE);
776 - $internalUrl = strpos($simplifiedUrl, rtrim($simplifiedWebsite, '/')) === 0;
777 -
778 - $subfolder = false;
779 - if ($internalUrl) {
780 - $urlWithoutBase = str_replace($simplifiedWebsite, '', $simplifiedUrl);
781 - if (strpos($urlWithoutBase, '/') || strpos($urlWithoutBase, '?')) {
782 - $slashPosition = strpos($urlWithoutBase, '/');
783 - $folderName = substr($urlWithoutBase, 0, !$slashPosition ? strpos($urlWithoutBase, '?') : $slashPosition);
784 - if (strpos($folderName, '.') === false) {
785 - $subfolder = @is_dir(ACYM_ROOT.$folderName);
786 - }
787 - }
788 - }
789 -
790 - if ((!$internalUrl || $subfolder) && $trackingSystemExternalWebsite != 1) {
791 - continue;
792 - }
793 -
794 - if (strpos($url, 'utm_source') === false && strpos($trackingSystem, 'google') !== false) {
795 - $idToUse = empty($campaign) ? $mailId : $campaign->id;
796 - $args = [];
797 - $args[] = empty($campaign->sending_params['utm_source']) ? 'utm_source=newsletter_'.$idToUse : 'utm_source='.urlencode($campaign->sending_params['utm_source']);
798 - $args[] = empty($campaign->sending_params['utm_medium']) ? 'utm_medium=email' : 'utm_medium='.urlencode($campaign->sending_params['utm_medium']);
799 - $args[] = empty($campaign->sending_params['utm_campaign']) ? 'utm_campaign='.$utmCampaign : 'utm_campaign='.urlencode($campaign->sending_params['utm_campaign']);
800 - $anchor = '';
801 - if (strpos($url, '#') !== false) {
802 - $anchor = substr($url, strpos($url, '#'));
803 - $url = substr($url, 0, strpos($url, '#'));
804 - }
805 -
806 - if (strpos($url, '?')) {
807 - $mytracker = $url.'&'.implode('&', $args);
808 - } else {
809 - $mytracker = $url.'?'.implode('&', $args);
810 - }
811 - $mytracker .= $anchor;
812 - $urls[$results[0][$i]] = str_replace($results[1][$i], $mytracker, $results[0][$i]);
813 -
814 - $url = $mytracker;
815 - }
816 -
817 - if (strpos($trackingSystem, 'acymailing') !== false) {
818 - $isAutologin = false;
819 - $autologinParams = 'autoSubId=%7Bsubscriber:id%7D&amp;subKey=%7Bsubscriber:autologin_token%7Curlencode%7D';
820 - if (strpos($url, $autologinParams) !== false) {
821 - $isAutologin = true;
822 - $url = str_replace(
823 - [
824 - '?'.$autologinParams.'&amp;',
825 - '?'.$autologinParams,
826 - '&amp;'.$autologinParams,
827 - ],
828 - [
829 - '?',
830 - '',
831 - '',
832 - ],
833 - $url
834 - );
835 - }
836 -
837 - if (preg_match('#passw|modify|\{|%7B#i', $url)) {
838 - continue;
839 - }
840 -
841 - $urlForRegistration = $url;
842 - if (!empty($this->originalDynamicUrls[$i])) {
843 - $urlForRegistration = $this->originalDynamicUrls[$i];
844 -
845 - if (strpos($urlForRegistration, $autologinParams) !== false) {
846 - $isAutologin = true;
847 - }
848 -
849 - $urlForRegistration = str_replace(
850 - [
851 - '?'.$autologinParams.'&amp;',
852 - '?'.$autologinParams,
853 - '&amp;'.$autologinParams,
854 - ],
855 - ['?', '', ''],
856 - $urlForRegistration
857 - );
858 -
859 - if (preg_match('#[?&](idU=\d+)#', $url, $idUMatch)) {
860 - $separator = strpos($urlForRegistration, '?') === false ? '?' : '&amp;';
861 - $urlForRegistration .= $separator.$idUMatch[1];
862 - }
863 - }
864 -
865 - if (!$fromStat) {
866 - $mytracker = $urlClass->getUrl($urlForRegistration, $mailId, $userid, $userkey);
867 - }
868 -
869 - if (empty($mytracker)) {
870 - continue;
871 - }
872 -
873 - if ($isAutologin) {
874 - $mytracker .= strpos($mytracker, '?') === false ? '?' : '&amp;';
875 - if (!empty($this->originalDynamicUrls[$i]) && preg_match('#autoSubId=[^&"]+&amp;subKey=[^&"]+#', $url, $resolvedAutologinMatch)) {
876 - $mytracker .= $resolvedAutologinMatch[0];
877 - } else {
878 - $mytracker .= $autologinParams;
879 - }
880 - }
881 -
882 - $urls[$results[0][$i]] = str_replace($results[1][$i], $mytracker, $results[0][$i]);
883 - }
884 - }
885 -
886 - $this->body = str_replace(array_keys($urls), $urls, $this->body);
887 - }
888 -
889 - public function textVersion(string $html, bool $fullConvert = true): string
890 - {
891 - $html = acym_absoluteURL($html);
892 -
893 - if ($fullConvert) {
894 - $html = preg_replace('# +#', ' ', $html);
895 - $html = str_replace(["\n", "\r", "\t"], '', $html);
896 - }
897 -
898 - $removepictureslinks = "#< *a[^>]*> *< *img[^>]*> *< *\/ *a *>#isU";
899 - $removeScript = "#< *script(?:(?!< */ *script *>).)*< */ *script *>#isU";
900 - $removeStyle = "#< *style(?:(?!< */ *style *>).)*< */ *style *>#isU";
901 - $removeStrikeTags = '#< *strike(?:(?!< */ *strike *>).)*< */ *strike *>#iU';
902 - $replaceByTwoReturnChar = '#< *(h1|h2)[^>]*>#Ui';
903 - $replaceByStars = '#< *li[^>]*>#Ui';
904 - $replaceByReturnChar1 = '#< */ *(li|td|dt|tr|div|p)[^>]*> *< *(li|td|dt|tr|div|p)[^>]*>#Ui';
905 - $replaceByReturnChar = '#< */? *(br|p|h1|h2|legend|h3|li|ul|dd|dt|h4|h5|h6|tr|td|div)[^>]*>#Ui';
906 - $replaceLinks = '/< *a[^>]*href *= *"([^#][^"]*)"[^>]*>(.+)< *\/ *a *>/Uis';
907 -
908 - $text = preg_replace(
909 - [
910 - $removepictureslinks,
911 - $removeScript,
912 - $removeStyle,
913 - $removeStrikeTags,
914 - $replaceByTwoReturnChar,
915 - $replaceByStars,
916 - $replaceByReturnChar1,
917 - $replaceByReturnChar,
918 - $replaceLinks,
919 - ],
920 - ['', '', '', '', "\n\n", "\n* ", "\n", "\n", '${2} ( ${1} )'],
921 - $html
922 - );
923 -
924 - $text = preg_replace('#(&lt;|&\#60;)([^ \n\r\t])#i', '&lt; ${2}', $text);
925 -
926 - $text = str_replace([" ", "&nbsp;"], ' ', strip_tags($text));
927 -
928 - $text = trim(@html_entity_decode($text, ENT_QUOTES, 'UTF-8'));
929 -
930 - if ($fullConvert) {
931 - $text = preg_replace('# +#', ' ', $text);
932 - $text = preg_replace('#\n *\n\s+#', "\n\n", $text);
933 - }
934 -
935 - return $text;
936 - }
937 -
938 - protected function embedImages(): bool
939 - {
940 - preg_match_all('/(src|background)=[\'|"]([^"\']*)[\'|"]/Ui', $this->Body, $images);
941 -
942 - if (empty($images[2])) {
943 - return true;
944 - }
945 -
946 - $embedSuccess = true;
947 -
948 - $mimetypes = [
949 - 'bmp' => 'image/bmp',
950 - 'gif' => 'image/gif',
951 - 'jpeg' => 'image/jpeg',
952 - 'jpg' => 'image/jpeg',
953 - 'jpe' => 'image/jpeg',
954 - 'png' => 'image/png',
955 - 'tiff' => 'image/tiff',
956 - 'tif' => 'image/tiff',
957 - ];
958 -
959 - $allImages = [];
960 -
961 - foreach ($images[2] as $i => $url) {
962 - if (isset($allImages[$url])) {
963 - continue;
964 - }
965 -
966 - if (strpos($url, 'ctrl=') !== false) {
967 - continue;
968 - }
969 -
970 - $allImages[$url] = 1;
971 -
972 - $path = acym_internalUrlToPath($url);
973 - $path = $this->removeAdditionalParams($path);
974 -
975 - $filename = str_replace(['%', ' '], '_', basename($url));
976 - $filename = $this->removeAdditionalParams($filename);
977 -
978 - $md5 = md5($filename);
979 - $cid = 'cid:'.$md5;
980 - $fileParts = explode(".", $filename);
981 - if (empty($fileParts[1])) {
982 - continue;
983 - }
984 - $ext = strtolower($fileParts[1]);
985 - if (!isset($mimetypes[$ext])) {
986 - continue;
987 - }
988 -
989 - if ($this->addEmbeddedImage($path, $md5, $filename, 'base64', $mimetypes[$ext])) {
990 - $this->Body = preg_replace('/'.preg_quote($images[0][$i], '/').'/Ui', $images[1][$i].'="'.$cid.'"', $this->Body);
991 - } else {
992 - $embedSuccess = false;
993 - }
994 - }
995 -
996 - return $embedSuccess;
997 - }
998 -
999 - public function cleanText(?string $text): string
1000 - {
1001 - return trim(preg_replace('/(%0A|%0D|\n+|\r+)/i', '', (string)$text));
1002 - }
1003 -
1004 - public function addParamInfo(): void
1005 - {
1006 - if (!empty($_SERVER)) {
1007 - $serverinfo = [];
1008 - foreach ($_SERVER as $oneKey => $oneInfo) {
1009 - $serverinfo[] = $oneKey.' => '.strip_tags(print_r($oneInfo, true));
1010 - }
1011 - $this->addParam('serverinfo', implode('<br />', $serverinfo));
1012 - }
1013 -
1014 - if (!empty($_REQUEST)) {
1015 - $postinfo = [];
1016 - foreach ($_REQUEST as $oneKey => $oneInfo) {
1017 - $postinfo[] = $oneKey.' => '.strip_tags(print_r($oneInfo, true));
1018 - }
1019 - $this->addParam('postinfo', implode('<br />', $postinfo));
1020 - }
1021 - }
1022 -
1023 - public function addParam(string $name, $value): void
1024 - {
1025 - $tagName = '{'.$name.'}';
1026 - $this->parameters[$tagName] = $value;
1027 - }
1028 -
1029 - public function overrideEmail(array $options): bool
1030 - {
1031 - $overrideAllEmails = $this->config->get('send_website_emails', 0) == 1;
1032 -
1033 - $overrideClass = new OverrideClass();
1034 - $override = $overrideClass->getMailByBaseContent($options['subject'], $options['message']);
1035 -
1036 - if (empty($override) && !$overrideAllEmails) {
1037 - return false;
1038 - }
1039 -
1040 - $this->autoAddUser = true;
1041 -
1042 - if (empty($override)) {
1043 - $this->trackEmail = false;
1044 -
1045 - return $this->overrideAllEmails($options);
1046 - } else {
1047 - $this->trackEmail = true;
1048 -
1049 - return $this->sendOverride($override, $options);
1050 - }
1051 - }
1052 -
1053 - public function isPortOpen(int $port, string $targetServer): bool
1054 - {
1055 - if (!function_exists('fsockopen')) {
1056 - $this->portError = acym_translation('ACYM_FSOCKOPEN');
1057 -
1058 - return false;
1059 - }
1060 -
1061 - $errorCode = 0;
1062 - $errorMessage = 0;
1063 - $fp = @fsockopen($targetServer, $port, $errorCode, $errorMessage, 5);
1064 -
1065 - if (is_resource($fp)) {
1066 - fclose($fp);
1067 -
1068 - return true;
1069 - } else {
1070 - $this->portError = $errorCode.' - '.acym_utf8Encode($errorMessage);
1071 -
1072 - return false;
1073 - }
1074 - }
1075 -
1076 - private function getSendingMethodSettings(string $settingName, string $default = ''): string
1077 - {
1078 - if (empty($this->currentMethodSetting)) {
1079 - return $this->config->get($settingName, $default);
1080 - }
1081 -
1082 - return $this->currentMethodSetting[$settingName] ?? $default;
1083 - }
1084 -
1085 - private function getSendingMethod(): string
1086 - {
1087 - $this->currentMethodSetting = [];
1088 -
1089 - $sendingMethods = $this->config->get('sending_method_list', '{}');
1090 - $sendingMethods = json_decode($sendingMethods, true);
1091 - $sendingMethodsByList = $this->config->get('sending_method_list_by_list', '{}');
1092 - $sendingMethodsByList = json_decode($sendingMethodsByList, true);
1093 -
1094 - if (empty($this->listsIds) || empty($sendingMethods) || empty($sendingMethodsByList) || empty($sendingMethodsByList[$this->listsIds[0]])) {
1095 - return $this->config->get('mailer_method', 'phpmail');
1096 - }
1097 -
1098 - $sendingMethodIds = [];
1099 -
1100 - foreach ($this->listsIds as $listId) {
1101 - if (!empty($sendingMethodsByList[$listId])) {
1102 - $sendingMethodIds[] = $sendingMethodsByList[$listId];
1103 - }
1104 - }
1105 -
1106 - if (count($sendingMethodIds) !== count($this->listsIds) || count(array_unique($sendingMethodIds)) !== 1) {
1107 - return $this->config->get('mailer_method', 'phpmail');
1108 - }
1109 -
1110 - $sendingMethodId = $sendingMethodIds[0];
1111 -
1112 - if (empty($sendingMethods[$sendingMethodId])) {
1113 - return $this->config->get('mailer_method', 'phpmail');
1114 - }
1115 -
1116 - $this->currentMethodSetting = $sendingMethods[$sendingMethodId];
1117 -
1118 - return $sendingMethods[$sendingMethodId]['mailer_method'];
1119 - }
1120 -
1121 - private function isExternal(string $method): void
1122 - {
1123 - $this->Mailer = 'external';
1124 - $this->externalMailer = $method;
1125 - }
1126 -
1127 - private function storeArchiveVersion(int $mailId): void
1128 - {
1129 - if ($this->defaultMail[$mailId]->type !== MailClass::TYPE_STANDARD) {
1130 - return;
1131 - }
1132 -
1133 - $mailArchive = new \stdClass();
1134 -
1135 - $alreadyExisting = $this->mailArchiveClass->getOneByMailId($mailId);
1136 - if (!empty($alreadyExisting)) {
1137 - $mailArchive->id = $alreadyExisting->id;
1138 - }
1139 -
1140 - $mailArchive->mail_id = $mailId;
1141 - $mailArchive->date = time();
1142 - $mailArchive->body = $this->defaultMail[$mailId]->body;
1143 - $mailArchive->subject = $this->defaultMail[$mailId]->subject;
1144 - $mailArchive->settings = $this->defaultMail[$mailId]->settings;
1145 - $mailArchive->stylesheet = $this->defaultMail[$mailId]->stylesheet;
1146 - $mailArchive->attachments = $this->defaultMail[$mailId]->attachments;
1147 - $this->mailArchiveClass->save($mailArchive);
1148 - }
1149 -
1150 - private function canTrack(int $mailId, object $user): bool
1151 - {
1152 - if ($this->isTest || empty($mailId) || empty($user) || !isset($user->tracking) || $user->tracking != 1) {
1153 - return false;
1154 - }
1155 -
1156 - $mail = $this->mailClass->getOneById($mailId);
1157 - if (!empty($mail) && $mail->tracking != 1) {
1158 - return false;
1159 - }
1160 -
1161 - $lists = $this->mailClass->getAllListsByMailIdAndUserId($mailId, $user->id);
1162 -
1163 - foreach ($lists as $list) {
1164 - if ($list->tracking != 1) {
1165 - return false;
1166 - }
1167 - }
1168 -
1169 - return true;
1170 - }
1171 -
1172 - private function loadUser($user, bool $force = false): object
1173 - {
1174 - if (is_numeric($user)) {
1175 - $receiver = $this->userClass->getOneById($user);
1176 - } elseif (is_object($user)) {
1177 - $receiver = $user;
1178 - } elseif (is_string($user) && strpos($user, '@')) {
1179 - acym_setVar('acy_source', 'When sending a test');
1180 - $this->userClass->triggers = $this->userCreationTriggers;
1181 - $receiver = $this->userClass->getOneByEmail($user, $force || $this->autoAddUser);
1182 - }
1183 -
1184 - if (empty($receiver)) {
1185 - throw new Exception(acym_translation('ACYM_USER_NOT_FOUND'));
1186 - }
1187 -
1188 - $this->userLanguage = empty($receiver->language) ? acym_getLanguageTag() : $receiver->language;
1189 - $this->receiverEmail = (string)($receiver->email ?? '');
1190 -
1191 - return $receiver;
1192 - }
1193 -
1194 - private function prepareContent(int $mailId, array $options): void
1195 - {
1196 - $this->isHTML();
1197 -
1198 - if (!empty($this->defaultMail[$mailId]->stylesheet)) {
1199 - $this->stylesheet = $this->defaultMail[$mailId]->stylesheet;
1200 - }
1201 - $this->settings = empty($this->defaultMail[$mailId]->settings) ? [] : json_decode($this->defaultMail[$mailId]->settings, true);
1202 -
1203 - $this->Subject = $this->defaultMail[$mailId]->subject;
1204 - $this->Body = $this->defaultMail[$mailId]->body;
1205 - if ($this->isTest && !empty($options['testNote'])) {
1206 - $this->Body = '<div style="text-align: center; padding: 25px; font-family: Poppins; font-size: 20px">'.$options['testNote'].'</div>'.$this->Body;
1207 - }
1208 -
1209 - if (!empty($this->introtext)) {
1210 - $this->Body = $this->introtext.$this->Body;
1211 - }
1212 -
1213 - if (!empty($this->defaultMail[$mailId]->preheader)) {
1214 - $preHeader = '<!--[if !mso 9]><!--><div style="visibility:hidden;mso-hide:all;font-size:0;color:transparent;height:0;line-height:0;max-height:0;max-width:0;opacity:0;overflow:hidden;">';
1215 - $preHeader .= $this->defaultMail[$mailId]->preheader;
1216 - $preHeader .= '</div><!--<![endif]-->';
1217 -
1218 - preg_match('#(<(.*)<body(.*)>)#Uis', $this->Body, $matches);
1219 - if (empty($matches) || empty($matches[1])) {
1220 - $this->Body = $preHeader.$this->Body;
1221 - } else {
1222 - $this->Body = $matches[1].$preHeader.str_replace($matches[1], '', $this->Body);
1223 - }
1224 - }
1225 -
1226 - if (ACYM_CMS === 'wordpress') {
1227 - ob_start();
1228 - $this->Body = do_shortcode($this->Body);
1229 - ob_end_clean();
1230 - }
1231 - }
1232 -
1233 - private function prepareHeaders(int $mailId, int $receiverId, array $options): void
1234 - {
1235 - $subject = base64_encode(rand(0, 9999999)).'AC'.$receiverId.'Y'.$this->defaultMail[$mailId]->id.'BA'.base64_encode(time().rand(0, 99999));
1236 - $this->MessageID = '<'.preg_replace('|[^a-z0-9+_]|i', '', $subject).'@'.$this->serverHostname().'>';
1237 - $this->addCustomHeader('Feedback-ID', $this->defaultMail[$mailId]->id.':'.$receiverId.':'.$this->defaultMail[$mailId]->type.':'.base64_encode(ACYM_ROOT));
1238 -
1239 - if (!empty($this->defaultMail[$mailId]->headers)) {
1240 - $this->mailHeader = $this->defaultMail[$mailId]->headers;
1241 - }
1242 -
1243 - if (!empty($options['headers'])) {
1244 - foreach ($options['headers'] as $headerName => $headerValue) {
1245 - $this->addCustomHeader(trim($headerName), trim($headerValue));
1246 - }
1247 - }
1248 - }
1249 -
1250 - private function prepareAddresses(int $mailId, object $receiver): void
1251 - {
1252 - $receiverName = '';
1253 - if ($this->config->get('add_names', true)) {
1254 - $receiverName = $this->cleanText($receiver->name);
1255 - if ($receiverName == $this->cleanText($receiver->email)) {
1256 - $receiverName = '';
1257 - }
1258 - }
1259 - $this->addAddress($this->cleanText($receiver->email), $receiverName);
1260 -
1261 - $this->setFrom($this->getSendSettings('from_email', $mailId), $this->getSendSettings('from_name', $mailId));
1262 - $this->acymAddReplyTo($this->defaultMail[$mailId]->reply_to_email ?? '', $this->defaultMail[$mailId]->reply_to_name ?? '');
1263 -
1264 - if (!empty($this->defaultMail[$mailId]->bounce_email)) {
1265 - $this->Sender = $this->cleanText($this->defaultMail[$mailId]->bounce_email);
1266 - } else {
1267 - $this->Sender = $this->cleanText($this->config->get('bounce_email'));
1268 - }
1269 - }
1270 -
1271 - private function prepareBcc(int $mailId, array $options): void
1272 - {
1273 - $bccAddresses = [];
1274 -
1275 - if (!empty($options['bcc'])) {
1276 - $bccAddresses = $options['bcc'];
1277 - }
1278 -
1279 - if (!empty($this->defaultMail[$mailId]->bcc)) {
1280 - $emailBccAddresses = explode(';', trim(str_replace([',', ' '], ';', $this->defaultMail[$mailId]->bcc)));
1281 - $bccAddresses = array_unique(array_merge($bccAddresses, $emailBccAddresses));
1282 - }
1283 -
1284 - if (!empty($bccAddresses)) {
1285 - $bccAddresses = array_filter($bccAddresses);
1286 - foreach ($bccAddresses as $oneBccAddress) {
1287 - $this->loadUser($oneBccAddress, true);
1288 - $this->addBCC($oneBccAddress);
1289 - }
1290 - }
1291 - }
1292 -
1293 - private function prepareAttachments(int $mailId, array $options): void
1294 - {
1295 - $attachments = [];
1296 -
1297 - if (!empty($this->defaultMail[$mailId]->attach)) {
1298 - $attachments = $this->defaultMail[$mailId]->attach;
1299 - }
1300 -
1301 - if (!empty($options['attachments'])) {
1302 - $attachments = array_merge($attachments, $options['attachments']);
1303 - }
1304 -
1305 - if (empty($attachments)) {
1306 - return;
1307 - }
1308 -
1309 - if ($this->config->get('embed_files')) {
1310 - foreach ($attachments as $attachment) {
1311 - $this->addAttachment($attachment->filename, $attachment->name);
1312 - }
1313 - } else {
1314 - $attachStringHTML = '<fieldset><legend>'.acym_translation('ACYM_ATTACHMENTS').'</legend><table>';
1315 - foreach ($attachments as $attachment) {
1316 - $attachStringHTML .= '<tr><td><a href="'.$attachment->url.'" target="_blank">'.$attachment->name.'</a></td></tr>';
1317 - }
1318 - $attachStringHTML .= '</table></fieldset>';
1319 -
1320 - if ($this->config->get('attachments_position', 'bottom') === 'top') {
1321 - $this->Body = $attachStringHTML.'<br />'.$this->Body;
1322 - } else {
1323 - $this->Body .= '<br />'.$attachStringHTML;
1324 - }
1325 - }
1326 - }
1327 -
1328 - private function replaceDynamicContent(int $mailId): void
1329 - {
1330 - $this->replaceParams();
1331 -
1332 - $this->body = &$this->Body;
1333 - $this->altbody = &$this->AltBody;
1334 - $this->subject = &$this->Subject;
1335 - $this->from = &$this->From;
1336 - $this->fromName = &$this->FromName;
1337 - $this->replyto = &$this->ReplyTo;
1338 - $this->replyname = $this->defaultMail[$mailId]->reply_to_name ?? '';
1339 - $this->replyemail = $this->defaultMail[$mailId]->reply_to_email ?? '';
1340 - $this->mailId = intval($this->defaultMail[$mailId]->id);
1341 - $this->id = $this->mailId;
1342 - $this->creator_id = intval($this->defaultMail[$mailId]->creator_id);
1343 - $this->type = $this->defaultMail[$mailId]->type;
1344 - $this->stylesheet = &$this->stylesheet;
1345 - $this->links_language = $this->defaultMail[$mailId]->links_language;
1346 - }
1347 -
1348 - private function extractOriginalDynamicUrls(): void
1349 - {
1350 - $this->originalDynamicUrls = [];
1351 - $absoluteBody = acym_absoluteURL($this->body);
1352 - preg_match_all(
1353 - self::REGEX_URL,
1354 - $absoluteBody,
1355 - $results
1356 - );
1357 -
1358 - if (empty($results[1])) {
1359 - return;
1360 - }
1361 -
1362 - foreach ($results[1] as $i => $url) {
1363 - if (preg_match('#\{|%7B#i', $url)) {
1364 - $this->originalDynamicUrls[$i] = $url;
1365 - }
1366 - }
1367 - }
1368 -
1369 - private function prepareTracking(int $mailId, object $receiver): void
1370 - {
1371 - if ($this->canTrack($mailId, $receiver)) {
1372 - $receiver->id = intval($receiver->id);
1373 - $this->statPicture($this->mailId, $receiver->id);
1374 - $this->body = acym_absoluteURL($this->body);
1375 - $this->statClick($this->mailId, $receiver->id, false, $receiver->key ?? '');
1376 - if (acym_isTrackingSalesActive()) {
1377 - $this->trackingSales($this->mailId, $receiver->id);
1378 - }
1379 - }
1380 - }
1381 -
1382 - private function handleDtexts(object $receiver): bool
1383 - {
1384 - $this->replaceParams();
1385 -
1386 - if (strpos($receiver->email, '@mt.acyba.com') !== false) {
1387 - $currentUser = $this->userClass->getOneByEmail(acym_currentUserEmail());
1388 - if (empty($currentUser)) {
1389 - $currentUser = $receiver;
1390 - }
1391 - $result = acym_trigger('replaceUserInformation', [&$this, &$currentUser, true]);
1392 - } else {
1393 - $result = acym_trigger('replaceUserInformation', [&$this, &$receiver, true]);
1394 - if (!empty($result)) {
1395 - foreach ($result as $oneResult) {
1396 - if (!empty($oneResult) && !$oneResult['send']) {
1397 - $this->reportMessage = $oneResult['message'];
1398 -
1399 - return false;
1400 - }
1401 - }
1402 - }
1403 - }
1404 -
1405 - global $acymLanguages;
1406 - if (!empty($acymLanguages['userLanguage'])) {
1407 - unset($acymLanguages['userLanguage']);
1408 - }
1409 -
1410 - foreach ($result as $oneResult) {
1411 - if (!empty($oneResult['emogrifier'])) {
1412 - $this->prepareEmailContent();
1413 - break;
1414 - }
1415 - }
1416 -
1417 - if ($this->config->get('multiple_part', false)) {
1418 - $bodyForText = preg_replace('#<head\b[^>]*>.*?</head\s*>#is', '', $this->Body);
1419 - $this->altbody = $this->textVersion($bodyForText);
1420 - }
1421 -
1422 - $this->replaceParams();
1423 -
1424 - return true;
1425 - }
1426 -
1427 - private function initStatistics(bool $status, int $receiverId): void
1428 - {
1429 - if ($this->trackEmail) {
1430 - $statsAdd = [];
1431 - $statsAdd[$this->mailId][intval($status)][] = $receiverId;
1432 -
1433 - $queueHelper = new QueueHelper();
1434 - $queueHelper->statsAdd($statsAdd);
1435 - $this->trackEmail = false;
1436 - }
1437 - }
1438 -
1439 - private function trackingSales(int $mailId, int $userId): void
1440 - {
1441 - preg_match_all('#href[ ]*=[ ]*"(?!mailto:|\#|ymsgr:|callto:|file:|ftp:|webcal:|skype:|tel:)([^"]+)"#Ui', $this->body, $results);
1442 - if (empty($results)) {
1443 - return;
1444 - }
1445 -
1446 - foreach ($results[1] as $url) {
1447 - $simplifiedUrl = str_replace(['https://', 'http://', 'www.'], '', $url);
1448 - $simplifiedWebsite = str_replace(['https://', 'http://', 'www.'], '', ACYM_LIVE);
1449 - if (strpos($simplifiedUrl, rtrim($simplifiedWebsite, '/')) === false || strpos($url, 'task=unsub')) continue;
1450 -
1451 - $toAddUrl = (strpos($url, '?') === false ? '?' : '&').'linkReferal='.$mailId.'-'.$userId;
1452 -
1453 - $posHash = strpos($url, '#');
1454 - if ($posHash !== false) {
1455 - $newURL = substr($url, 0, $posHash).$toAddUrl.substr($url, $posHash);
1456 - } else {
1457 - $newURL = $url.$toAddUrl;
1458 - }
1459 -
1460 - $this->body = preg_replace('#href="('.preg_quote($url, '#').')"#Uis', 'href="'.$newURL.'"', $this->body);
1461 - }
1462 - }
1463 -
1464 - private function statPicture(int $mailId, int $userId): void
1465 - {
1466 - $pictureLink = acym_frontendLink('frontstats&task=openStats&id='.$mailId.'&userid='.$userId, true, false);
1467 -
1468 - $statPicture = '<img class="spict" alt="" src="'.$pictureLink.'" border="0" width="50" height="1" />';
1469 -
1470 - if (strpos($this->body, '</body>')) {
1471 - $this->body = str_replace('</body>', $statPicture.'</body>', $this->body);
1472 - } else {
1473 - $this->body .= $statPicture;
1474 - }
1475 - }
1476 -
1477 - private function removeAdditionalParams(string $url): string
1478 - {
1479 - $additionalParamsPos = strpos($url, '?');
1480 - if (!empty($additionalParamsPos)) {
1481 - $url = substr($url, 0, $additionalParamsPos);
1482 - }
1483 -
1484 - return $url;
1485 - }
1486 -
1487 - private function replaceParams(): void
1488 - {
1489 - if (empty($this->parameters)) {
1490 - return;
1491 - }
1492 -
1493 - $pluginHelper = new PluginHelper();
1494 -
1495 - $this->generateAllParams();
1496 -
1497 - $vars = [
1498 - 'Subject',
1499 - 'Body',
1500 - 'From',
1501 - 'FromName',
1502 - 'replyname',
1503 - 'replyemail',
1504 - ];
1505 -
1506 - foreach ($vars as $oneVar) {
1507 - if (!empty($this->$oneVar)) {
1508 - $this->$oneVar = $pluginHelper->replaceDText($this->$oneVar, $this->parameters);
1509 - }
1510 - }
1511 -
1512 - if (!empty($this->ReplyTo)) {
1513 - foreach ($this->ReplyTo as $i => $replyto) {
1514 - foreach ($replyto as $a => $oneval) {
1515 - $this->ReplyTo[$i][$a] = $pluginHelper->replaceDText($this->ReplyTo[$i][$a], $this->parameters);
1516 - }
1517 - }
1518 - }
1519 - }
1520 -
1521 - private function generateAllParams(): void
1522 - {
1523 - $result = '<table style="border:1px solid;border-collapse:collapse;" border="1" cellpadding="10"><tr><td>Tag</td><td>Value</td></tr>';
1524 - foreach ($this->parameters as $name => $value) {
1525 - if (!is_string($value)) continue;
1526 -
1527 - $result .= '<tr><td>'.trim($name, '{}').'</td><td>'.$value.'</td></tr>';
1528 - }
1529 - $result .= '</table>';
1530 - $this->addParam('allshortcodes', $result);
1531 - }
1532 -
1533 - private function sendOverride(object $override, array $options): bool
1534 - {
1535 - for ($i = 1; $i < count($override->parameters); $i++) {
1536 - $oneParam = $override->parameters[$i];
1537 -
1538 - $unmodified = $oneParam;
1539 - $oneParam = preg_replace(
1540 - '/(http|https):\/\/(.*)/',
1541 - '<a href="$1://$2" target="_blank">$1://$2</a>',
1542 - $oneParam,
1543 - -1,
1544 - $count
1545 - );
1546 - if ($count > 0) {
1547 - $this->addParam('link'.$i, $unmodified);
1548 - }
1549 - $this->addParam('param'.$i, $oneParam);
1550 - }
1551 -
1552 - $this->addParam('subject', $options['subject']);
1553 -
1554 - $this->overrideEmailToSend = $override;
1555 - $statusSend = $this->sendOne($override->id, $options['to'], $options);
1556 - if (!$statusSend && !empty($this->reportMessage)) {
1557 - $cronHelper = new CronHelper();
1558 - $cronHelper->saveReport([$this->reportMessage]);
1559 - }
1560 -
1561 - return $statusSend;
1562 - }
1563 -
1564 - public function getSendSettings(string $type, int $mailId = 0): string
1565 - {
1566 - if (!in_array($type, ['from_name', 'from_email', 'replyto_name', 'replyto_email', 'bounce_email'])) {
1567 - return '';
1568 - }
1569 -
1570 - $mailType = strpos($type, 'replyto') !== false ? str_replace('replyto', 'reply_to', $type) : $type;
1571 - if (!empty($mailId) && !empty($this->defaultMail[$mailId]->$mailType)) {
1572 - return $this->defaultMail[$mailId]->$mailType;
1573 - }
1574 -
1575 - $lang = empty($this->userLanguage) ? acym_getLanguageTag() : $this->userLanguage;
1576 - $setting = $this->config->get($type);
1577 - $translation = $this->config->get('sender_info_translation');
1578 -
1579 - if (!empty($translation)) {
1580 - $translation = json_decode($translation, true);
1581 -
1582 - if (!empty($translation[$lang][$type])) {
1583 - $setting = $translation[$lang][$type];
1584 - }
1585 - }
1586 -
1587 - return $setting;
1588 - }
1589 -
1590 - private function prepareEmailContent(int $mailId = 0): void
1591 - {
1592 - $this->handleRelativeURLs($mailId);
1593 - $this->inlineCSS($mailId);
1594 - $this->finalizeHtmlStructure($mailId);
1595 - }
1596 -
1597 - private function handleRelativeURLs(int $mailId): void
1598 - {
1599 - $mail = empty($mailId) ? $this : $this->defaultMail[$mailId];
1600 - $mail->body = acym_absoluteURL($mail->body);
1601 - }
1602 -
1603 - private function inlineCSS(int $mailId): void
1604 - {
1605 - $mail = empty($mailId) ? $this : $this->defaultMail[$mailId];
1606 - if (empty($mail->body)) {
1607 - return;
1608 - }
1609 -
1610 - global $emogrifiedMediaCSS;
1611 - $emogrifiedMediaCSS = '';
1612 -
1613 - $style = $this->getEmailStylesheet($mail);
1614 - $cssInliner = CssInliner::fromHtml($mail->body)->inlineCss(implode('', $style));
1615 - $domDocument = $cssInliner->getDomDocument();
1616 -
1617 - $mail->body = preg_replace(
1618 - [
1619 - '# id="mce_\d+"#Ui',
1620 - '#(style="[^"]+);"#Ui',
1621 - ],
1622 - [
1623 - '',
1624 - '$1"',
1625 - ],
1626 - HtmlPruner::fromDomDocument($domDocument)
1627 - ->removeRedundantClassesAfterCssInlined($cssInliner)
1628 - ->renderBodyContent()
1629 - );
1630 -
1631 - $mail->body = str_replace('&zwj;', '', $mail->body);
1632 -
1633 - $mail->body = preg_replace_callback(
1634 - '#style="([^"]+)"#Ui',
1635 - function ($matches) {
1636 - return 'style="'.str_replace(['; ', ': '], [';', ':'], $matches[1]).'"';
1637 - },
1638 - $mail->body
1639 - );
1640 - }
1641 -
1642 - private function finalizeHtmlStructure(int $mailId): void
1643 - {
1644 - $mail = empty($mailId) ? $this : $this->defaultMail[$mailId];
1645 -
1646 - $finalContent = '<html xmlns="http://www.w3.org/1999/xhtml" xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office">';
1647 - $finalContent .= '<head>';
1648 - $finalContent .= '<!--[if gte mso 9]><xml><o:OfficeDocumentSettings><o:AllowPNG/><o:PixelsPerInch>96</o:PixelsPerInch></o:OfficeDocumentSettings></xml><![endif]-->';
1649 - $finalContent .= '<meta http-equiv="Content-Type" content="text/html; charset='.strtolower($this->config->get('charset')).'" />'."\n";
1650 - $finalContent .= '<meta name="viewport" content="width=device-width, initial-scale=1.0" />'."\n";
1651 - $finalContent .= '<title>'.$mail->subject.'</title>'."\n";
1652 -
1653 - global $emogrifiedMediaCSS;
1654 - $finalContent .= '<style>'.$emogrifiedMediaCSS.'</style>';
1655 - $finalContent .= '<!--[if mso]><style type="text/css">#acym__wysid__template center > table { width: 580px; }</style><![endif]-->';
1656 - $finalContent .= '<!--[if !mso]><!--><style>#acym__wysid__template center > table { width: 100%; }</style><!--<![endif]-->';
1657 -
1658 - if (!empty($mail->headers)) {
1659 - $finalContent .= $mail->headers;
1660 - }
1661 - $finalContent .= '</head>';
1662 -
1663 - preg_match('@<[^>"t]*body[^>]*>@', $mail->body, $matches);
1664 - if (empty($matches[0])) {
1665 - $mail->body = '<body>'.$mail->body.'</body>';
1666 - } else {
1667 - preg_match('@<[^>"t]*/body[^>]*>@', $mail->body, $matches);
1668 - if (empty($matches[0])) {
1669 - $mail->body .= '</body>';
1670 - }
1671 - }
1672 -
1673 - $finalContent .= $mail->body;
1674 - $finalContent .= '</html>';
1675 -
1676 - $mail->body = $finalContent;
1677 - }
1678 -
1679 - private function getEmailStylesheet(object $mail): array
1680 - {
1681 - $style = [];
1682 -
1683 - if (strpos($mail->body, 'acym__wysid__template') !== false) {
1684 - static $foundationCSS = null;
1685 - if (empty($foundationCSS)) {
1686 - $foundationCSS = acym_fileGetContent(ACYM_MEDIA.'css'.DS.'libraries'.DS.'foundation_email.min.css');
1687 - $foundationCSS = str_replace('#acym__wysid__template ', '', $foundationCSS);
1688 - }
1689 - $style['foundation'] = $foundationCSS;
1690 - }
1691 -
1692 - static $emailFixes = null;
1693 - if (empty($emailFixes)) {
1694 - $emailFixes = acym_getEmailCssFixes();
1695 - }
1696 - $style['fixes'] = $emailFixes;
1697 -
1698 - if (!empty($mail->stylesheet)) {
1699 - $style['custom_stylesheet'] = $mail->stylesheet;
1700 - }
1701 -
1702 - $settingsStyles = $this->editorHelper->getSettingsStyle($mail->settings);
1703 - if (!empty($settingsStyles)) {
1704 - $style['settings_stylesheet'] = $settingsStyles;
1705 - }
1706 -
1707 - return $style;
1708 - }
1709 -
1710 - private function overrideAllEmails(array $options): bool
1711 - {
1712 - $this->trackEmail = false;
1713 -
1714 - $this->addParam('subject', $options['subject']);
1715 -
1716 - if (isset($options['isHtml']) && !$options['isHtml']) {
1717 - $options['message'] = nl2br($options['message']);
1718 - }
1719 - $this->addParam('body', $options['message']);
1720 -
1721 - $mailClass = new MailClass();
1722 - $this->overrideEmailToSend = $mailClass->getOneByName('acy_notification_cms');
1723 -
1724 - if (empty($this->overrideEmailToSend)) {
1725 - return false;
1726 - }
1727 -
1728 - $statusSend = $this->sendOne($this->overrideEmailToSend->id, $options['to'], $options);
1729 - if (!$statusSend && !empty($this->reportMessage)) {
1730 - $cronHelper = new CronHelper();
1731 - $cronHelper->addMessage($this->reportMessage);
1732 - $cronHelper->saveReport();
1733 - }
1734 -
1735 - return $statusSend;
1736 - }
1737 -
1738 -
1739 - private function acymAddReplyTo(string $email, string $name): void
1740 - {
1741 - if (empty($email)) {
1742 - return;
1743 - }
1744 -
1745 - $replyToName = $this->config->get('add_names', true) ? $this->cleanText(trim($name)) : '';
1746 - $replyToEmail = trim($email);
1747 -
1748 - if (substr_count($replyToEmail, '@') > 1) {
1749 - $replyToEmailArray = explode(';', str_replace([';', ','], ';', $replyToEmail));
1750 - $replyToNameArray = explode(';', str_replace([';', ','], ';', $replyToName));
1751 - foreach ($replyToEmailArray as $i => $oneReplyTo) {
1752 - $this->addReplyTo($this->cleanText($oneReplyTo), @$replyToNameArray[$i]);
1753 - }
1754 - } else {
1755 - $this->addReplyTo($this->cleanText($replyToEmail), $replyToName);
1756 - }
1757 - }
1758 -
1759 - public function setFrom($email, $name = '', $auto = false)
1760 - {
1761 - if (!empty($email)) {
1762 - $this->From = $this->cleanText($email);
1763 - }
1764 - if (!empty($name) && $this->config->get('add_names', true)) {
1765 - $this->FromName = $this->cleanText($name);
1766 - }
1767 - }
1768 -
1769 - protected function edebug($str)
1770 - {
1771 - if (strpos($this->ErrorInfo, $str) === false) {
1772 - $this->ErrorInfo .= ' '.$str;
1773 - }
1774 - }
1775 -
1776 - public function getMailMIME()
1777 - {
1778 - $result = parent::getMailMIME();
1779 -
1780 - $result = rtrim($result, static::$LE);
1781 -
1782 - if ($this->Mailer != 'mail') {
1783 - $result .= static::$LE.static::$LE;
1784 - }
1785 -
1786 - return $result;
1787 - }
1788 -
1789 - public static function validateAddress($address, $patternselect = null)
1790 - {
1791 - return true;
1792 - }
1793 -}