XMailer = ' ';
$this->SMTPAutoTLS = false;
$this->encodingHelper = new EncodingHelper();
$this->editorHelper = new EditorHelper();
$this->userClass = new UserClass();
$this->mailClass = new MailClass();
$this->mailArchiveClass = new MailArchiveClass();
$this->config = acym_config();
$this->setFrom($this->getSendSettings('from_email'), $this->getSendSettings('from_name'));
$this->Sender = $this->cleanText($this->getSendSettings('bounce_email'));
if (empty($this->Sender)) {
$this->Sender = '';
}
$maxLineLength = $this->config->get('mailer_wordwrap', 0);
if (!empty($maxLineLength) && self::MAX_LINE_LENGTH > $maxLineLength) {
$this->WordWrap = $maxLineLength;
}
$this->setSendingMethodSetting();
if ($this->config->get('dkim', 0) && $this->Mailer != 'elasticemail') {
$this->DKIM_domain = $this->config->get('dkim_domain');
$this->DKIM_selector = $this->config->get('dkim_selector', 'acy');
if (empty($this->DKIM_selector)) $this->DKIM_selector = 'acy';
$this->DKIM_passphrase = $this->config->get('dkim_passphrase');
$this->DKIM_identity = $this->config->get('dkim_identity');
$this->DKIM_private = trim($this->config->get('dkim_private'));
$this->DKIM_private_string = trim($this->config->get('dkim_private'));
}
$this->CharSet = strtolower($this->config->get('charset'));
if (empty($this->CharSet)) {
$this->CharSet = 'utf-8';
}
$this->clearAll();
$this->Encoding = $this->config->get('encoding_format');
if (empty($this->Encoding)) {
$this->Encoding = '8bit';
}
@ini_set('pcre.backtrack_limit', 1000000);
$this->SMTPOptions = ['ssl' => ['verify_peer' => false, 'verify_peer_name' => false, 'allow_self_signed' => true]];
$this->addParamInfo();
}
public function setSendingMethodSetting(): void
{
$externalSendingMethod = [];
acym_trigger('onAcymGetSendingMethods', [&$externalSendingMethod, true]);
$externalSendingMethod = array_keys($externalSendingMethod['sendingMethods']);
$mailerMethodConfig = $this->getSendingMethod();
$this->currentSendingMethod = $mailerMethodConfig;
if ($mailerMethodConfig === 'google') {
$this->isSMTP();
$this->Host = 'smtp.gmail.com:465';
$this->SMTPAuth = true;
$this->Username = trim($this->getSendingMethodSettings('google_username'));
$this->AuthType = 'XOAUTH2';
$this->SMTPSecure = 'ssl';
$this->setOAuth(
new OAuth(
[
'sendingMethod' => 'google',
'tokenGenerationUrl' => 'https://oauth2.googleapis.com/token',
'userName' => $this->Username,
'clientId' => trim($this->getSendingMethodSettings('google_client_id')),
'clientSecret' => trim($this->getSendingMethodSettings('google_client_secret')),
'oauthToken' => trim($this->getSendingMethodSettings('google_access_token')),
'oauthTokenExpiration' => trim($this->getSendingMethodSettings('google_access_token_expiration')),
'refreshToken' => trim($this->getSendingMethodSettings('google_refresh_token')),
]
)
);
if (empty($this->Sender)) {
$this->Sender = strpos($this->Username, '@') ? $this->Username : $this->getSendingMethodSettings('from_email');
}
} elseif ($mailerMethodConfig === 'outlook') {
$this->isSMTP();
$tenant = trim($this->getSendingMethodSettings('outlook_tenant', 'consumers'));
$host = $tenant === 'consumers' ? 'smtp-mail.outlook.com' : 'smtp.office365.com';
$this->Host = $host.':587';
$this->SMTPAuth = true;
$this->Username = trim($this->getSendingMethodSettings('outlook_username'));
$this->AuthType = 'XOAUTH2';
$this->SMTPSecure = 'tls';
$this->setOAuth(
new OAuth(
[
'sendingMethod' => 'outlook',
'tokenGenerationUrl' => 'https://login.microsoftonline.com/'.$tenant.'/oauth2/v2.0/token',
'userName' => $this->Username,
'clientId' => trim($this->getSendingMethodSettings('outlook_client_id')),
'clientSecret' => trim($this->getSendingMethodSettings('outlook_client_secret')),
'oauthToken' => trim($this->getSendingMethodSettings('outlook_access_token')),
'oauthTokenExpiration' => trim($this->getSendingMethodSettings('outlook_access_token_expiration')),
'refreshToken' => trim($this->getSendingMethodSettings('outlook_refresh_token')),
]
)
);
if (empty($this->Sender)) {
$this->Sender = strpos($this->Username, '@') ? $this->Username : $this->getSendingMethodSettings('from_email');
}
} elseif ($mailerMethodConfig === 'smtp') {
$this->isSMTP();
$this->Host = trim($this->getSendingMethodSettings('smtp_host'));
$port = $this->getSendingMethodSettings('smtp_port');
if (empty($port) && $this->getSendingMethodSettings('smtp_secured') === 'ssl') {
$port = 465;
}
if (!empty($port)) {
$this->Host .= ':'.$port;
}
$this->SMTPAuth = (bool)$this->getSendingMethodSettings('smtp_auth', '1');
$this->Username = trim($this->getSendingMethodSettings('smtp_username'));
$authMethod = $this->getSendingMethodSettings('smtp_method');
if (in_array($authMethod, ['CRAM-MD5', 'LOGIN', 'PLAIN'])) {
$this->AuthType = $authMethod;
}
if ($this->SMTPAuth) {
$this->Password = trim($this->getSendingMethodSettings('smtp_password'));
}
$this->SMTPSecure = trim($this->getSendingMethodSettings('smtp_secured'));
if (empty($this->Sender)) {
$this->Sender = strpos($this->Username, '@') ? $this->Username : $this->getSendingMethodSettings('from_email');
}
} elseif ($mailerMethodConfig === 'sendmail') {
$this->isSendmail();
$this->Sendmail = trim($this->getSendingMethodSettings('sendmail_path'));
if (empty($this->Sendmail)) {
$this->Sendmail = '/usr/sbin/sendmail';
}
} elseif ($mailerMethodConfig === 'qmail') {
$this->isQmail();
} elseif ($mailerMethodConfig === 'amazon') {
$this->isSMTP();
$amazonCredentials = [];
acym_trigger('onAcymGetCredentialsSendingMethod', [&$amazonCredentials, 'amazon', $this->currentMethodSetting], 'plgAcymAmazon');
$this->Host = trim($amazonCredentials['amazon_host']).':587';
$this->Username = trim($amazonCredentials['amazon_username']);
$this->Password = trim($amazonCredentials['amazon_password']);
$this->SMTPAuth = true;
$this->SMTPSecure = 'tls';
} elseif ($mailerMethodConfig === 'brevo-smtp') {
$this->isSMTP();
$brevoSmtpCredentials = [];
acym_trigger('onAcymGetCredentialsSendingMethod', [&$brevoSmtpCredentials, 'brevo-smtp', $this->currentMethodSetting], 'plgAcymBrevo');
$this->Host = trim($brevoSmtpCredentials['brevo-smtp_host']).':587';
$this->Username = trim($brevoSmtpCredentials['brevo-smtp_username']);
$this->Password = trim($brevoSmtpCredentials['brevo-smtp_password']);
$this->SMTPAuth = true;
$this->SMTPSecure = 'tls';
} elseif (in_array($mailerMethodConfig, $externalSendingMethod)) {
$this->isExternal($mailerMethodConfig);
} else {
$this->isMail();
}
}
protected function externalSend(string $MIMEHeader, string $MIMEBody): bool
{
$fromName = empty($this->FromName) ? $this->config->get('from_name') : $this->FromName;
$reply_to = array_shift($this->ReplyTo);
$attachments = [];
if (!empty($this->attachment) && $this->config->get('embed_files')) {
foreach ($this->attachment as $i => $oneAttach) {
$encodedContent = $this->encodeFile($oneAttach[0], $oneAttach[3]);
$this->attachment[$i]['contentEncoded'] = $encodedContent;
}
$attachments = $this->attachment;
}
$response = [];
$data = [
&$response,
$this,
['email' => $this->to[0][0], 'name' => $this->to[0][1]],
['email' => $this->From, 'name' => $fromName],
['email' => $reply_to[0], 'name' => $reply_to[1]],
!empty($this->bcc) ? $this->bcc : [],
$attachments,
$this->currentMethodSetting,
];
acym_trigger('onAcymSendEmail', $data);
if (!empty($response['error'])) {
$this->setError($response['message']);
return false;
}
return true;
}
public function send(): bool
{
if (!file_exists(ACYM_LIBRARIES.'Mailer'.DS.'Mailer.php')) {
$this->reportMessage = acym_translationSprintf('ACYM_X_FILE_MISSING', 'Mailer', ACYM_LIBRARIES.'Mailer'.DS);
if ($this->report) {
acym_enqueueMessage($this->reportMessage, 'error');
}
return false;
}
if (empty($this->Subject) || empty($this->Body)) {
if ($this->isTest && empty($this->Subject)) {
$this->Subject = acym_translation('ACYM_EMAIL_SUBJECT');
} else {
$this->reportMessage = acym_translation('ACYM_SEND_EMPTY');
$this->errorNumber = 8;
if ($this->report) {
acym_enqueueMessage($this->reportMessage, 'error');
}
return false;
}
}
if (empty($this->ReplyTo) && empty($this->ReplyToQueue)) {
if (!empty($this->replyemail)) {
$replyToEmail = $this->replyemail;
} elseif ($this->config->get('from_as_replyto', 1) == 1) {
$replyToEmail = $this->getSendSettings('from_email');
} else {
$replyToEmail = $this->getSendSettings('replyto_email');
}
if (!empty($this->replyname)) {
$replyToName = $this->replyname;
} elseif ($this->config->get('from_as_replyto', 1) == 1) {
$replyToName = $this->getSendSettings('from_name');
} else {
$replyToName = $this->getSendSettings('replyto_name');
}
$this->acymAddReplyTo($replyToEmail, $replyToName);
}
$shouldEmbed = $this->config->get('embed_images', 0);
if (intval($shouldEmbed) === 1 && $this->Mailer !== 'elasticemail') {
$this->embedImages();
}
if (!$this->alreadyCheckedAddresses) {
$this->alreadyCheckedAddresses = true;
$replyToTmp = '';
if (!empty($this->ReplyTo)) {
$replyToTmp = reset($this->ReplyTo);
$replyToTmp = $replyToTmp[0];
} elseif (!empty($this->ReplyToQueue)) {
$replyToTmp = reset($this->ReplyToQueue);
$replyToTmp = $replyToTmp[1];
}
if (empty($replyToTmp) || !acym_isValidEmail($replyToTmp)) {
$this->reportMessage = acym_translation('ACYM_VALID_EMAIL').' ( '.acym_translation('ACYM_REPLYTO_EMAIL').' : '.(empty($this->ReplyTo) ? '' : $replyToTmp).' ) ';
$this->errorNumber = 9;
if ($this->report) {
acym_enqueueMessage($this->reportMessage, 'error');
}
return false;
}
if (empty($this->From) || !acym_isValidEmail($this->From)) {
$this->reportMessage = acym_translation('ACYM_VALID_EMAIL').' ( '.acym_translation('ACYM_FROM_EMAIL').' : '.$this->From.' ) ';
$this->errorNumber = 9;
if ($this->report) {
acym_enqueueMessage($this->reportMessage, 'error');
}
return false;
}
if (!empty($this->Sender) && !acym_isValidEmail($this->Sender)) {
$this->reportMessage = acym_translation('ACYM_VALID_EMAIL').' ( '.acym_translation('ACYM_BOUNCE_EMAIL').' : '.$this->Sender.' ) ';
$this->errorNumber = 9;
if ($this->report) {
acym_enqueueMessage($this->reportMessage, 'error');
}
return false;
}
}
if ($this->config->get('save_body') === '1') {
@file_put_contents(ACYM_ROOT.'acydebug_mail.html', $this->Body);
}
$this->Body = htmlentities($this->Body);
$this->Body = htmlspecialchars_decode($this->Body);
$this->Body = str_replace(['&', 'ς'], ['&', 'ς'], $this->Body);
if ($this->CharSet !== 'utf-8') {
$this->Body = $this->encodingHelper->change($this->Body, 'UTF-8', $this->CharSet);
$this->Subject = $this->encodingHelper->change($this->Subject, 'UTF-8', $this->CharSet);
}
$this->Subject = str_replace(
['’', '“', '”', '–'],
["'", '"', '"', '-'],
$this->Subject
);
$this->Body = str_replace(" ", ' ', $this->Body);
$externalSending = false;
$this->isOneTimeMail = $this->isTransactional = $this->isForward || $this->isTest || $this->isSpamTest;
if (!empty($this->mailId) && !empty($this->defaultMail[$this->mailId])) {
if ($this->mailClass->isTransactionalMail($this->defaultMail[$this->mailId])) {
$this->isTransactional = true;
}
if ($this->mailClass->isOneTimeMail($this->defaultMail[$this->mailId])) {
$this->isOneTimeMail = true;
}
}
acym_trigger('onAcymProcessQueueExternalSendingCampaign', [&$externalSending, $this->isTransactional]);
$warnings = '';
if (ACYM_PRODUCTION) {
if ($externalSending) {
$result = false;
acym_trigger('onAcymRegisterReceiverContentAndList', [&$result, $this->Subject, $this->Body, $this->receiverEmail, $this->mailId, &$warnings]);
} else {
acym_trigger('onAcymBeforeEmailSend', [&$this]);
ob_start();
$result = parent::send();
$warnings = ob_get_clean();
}
}
if (!empty($warnings) && strpos($warnings, 'bloque')) {
$result = false;
}
$this->mailHeader = '';
$receivers = [];
foreach ($this->to as $oneReceiver) {
$receivers[] = $oneReceiver[0];
}
if (!$result) {
$this->reportMessage = acym_translationSprintf('ACYM_SEND_ERROR', ''.$this->Subject.'', ''.implode(' , ', $receivers).'');
if (!empty($this->ErrorInfo)) {
$this->reportMessage .= " \n\n ".$this->ErrorInfo;
}
if (!empty($warnings)) {
$this->reportMessage .= " \n\n ".$warnings;
}
$this->errorNumber = 1;
if ($this->report) {
$this->reportMessage = str_replace(
'Could not instantiate mail function',
''.acym_translation('ACYM_COUND_NOT_INSTANCIATE_MAIL_FUCNTION').'',
$this->reportMessage
);
acym_enqueueMessage(nl2br($this->reportMessage), 'error');
}
} else {
if ($this->isSendingMethodByListActive) {
$this->reportMessage = acym_translationSprintf(
'ACYM_SEND_SUCCESS_WITH_SENDING_METHOD',
''.$this->Subject.'',
''.implode(' , ', $receivers).'',
''.$this->currentSendingMethod.''
);
} else {
$this->reportMessage = acym_translationSprintf('ACYM_SEND_SUCCESS', ''.$this->Subject.'', ''.implode(' , ', $receivers).'');
}
if (!empty($warnings)) {
$this->reportMessage .= " \n\n ".$warnings;
}
if ($this->report && acym_isAdmin()) {
acym_enqueueMessage(preg_replace('#(
){2}#', '
', nl2br($this->reportMessage)), 'info');
}
}
return $result;
}
public function clearAll(): void
{
$this->Subject = '';
$this->Body = '';
$this->AltBody = '';
$this->ClearAllRecipients();
$this->ClearAttachments();
$this->ClearCustomHeaders();
$this->ClearReplyTos();
$this->errorNumber = 0;
$this->MessageID = '';
$this->ErrorInfo = '';
$this->setFrom($this->getSendSettings('from_email'), $this->getSendSettings('from_name'));
}
public function load(int $mailId, ?object $user = null): ?object
{
if (isset($this->defaultMail[$mailId])) {
return $this->defaultMail[$mailId];
}
if (!empty($this->overrideEmailToSend)) {
$this->defaultMail[$mailId] = $this->overrideEmailToSend;
} else {
$this->defaultMail[$mailId] = $this->mailClass->getOneById($mailId, true);
}
global $acymLanguages;
if (!$this->isAbTest && empty($this->overrideEmailToSend) && acym_isMultilingual()) {
$defaultLanguage = $this->config->get('multilingual_default', ACYM_DEFAULT_LANGUAGE);
$mails = $this->mailClass->getMultilingualMails($mailId);
$this->userLanguage = !empty($user->language) ? $user->language : $defaultLanguage;
if (!empty($mails)) {
$languages = array_keys($mails);
if (count($languages) == 1) {
$key = $languages[0];
} elseif (empty($mails[$this->userLanguage])) {
$key = $defaultLanguage;
} else {
$key = $this->userLanguage;
}
if (isset($mails[$key])) {
$this->defaultMail[$mailId] = $mails[$key];
}
} else {
unset($this->defaultMail[$mailId]);
return null;
}
$acymLanguages['userLanguage'] = $this->userLanguage;
$this->setFrom($this->getSendSettings('from_email'), $this->getSendSettings('from_name'));
}
if (empty($this->defaultMail[$mailId]->id)) {
unset($this->defaultMail[$mailId]);
return null;
}
if (!empty($this->defaultMail[$mailId]->attachments)) {
$this->defaultMail[$mailId]->attach = [];
$attachments = json_decode($this->defaultMail[$mailId]->attachments);
foreach ($attachments as $oneAttach) {
$attach = new \stdClass();
$attach->name = basename($oneAttach->filename);
$attach->filename = str_replace(['/', '\\'], DS, ACYM_ROOT).$oneAttach->filename;
$attach->url = ACYM_LIVE.$oneAttach->filename;
$this->defaultMail[$mailId]->attach[] = $attach;
}
}
$this->mailId = $mailId;
$this->id = $this->mailId;
$this->mail = clone $this->defaultMail[$mailId];
acym_trigger('replaceContent', [&$this->defaultMail[$mailId], true]);
$this->prepareEmailContent($mailId);
if (!$this->isTest) {
$this->storeArchiveVersion($mailId);
}
return $this->defaultMail[$mailId];
}
public function sendOne($mailId, $user, array $options = []): bool
{
$this->clearAll();
$receiver = $this->loadUser($user);
$this->isTest = !empty($options['isTest']);
$this->dtextsFailed = false;
if (empty($receiver->email)) {
$this->errorNumber = 4;
$this->reportMessage = acym_translationSprintf('ACYM_SEND_ERROR_USER', ''.acym_escape($user).'');
if ($this->report) {
acym_enqueueMessage($this->reportMessage, 'error');
}
return false;
}
$mailId = intval($mailId);
$receiver->id = intval($receiver->id);
if (!$this->load($mailId, $receiver)) {
$this->reportMessage = 'Can not load the email with ID n°'.$mailId;
$this->errorNumber = 2;
if ($this->report) {
acym_enqueueMessage($this->reportMessage, 'error');
}
return false;
}
$this->prepareContent($mailId, $options);
$this->prepareHeaders($mailId, $receiver->id, $options);
$this->prepareAddresses($mailId, $receiver);
$this->prepareBcc($mailId, $options);
$this->prepareAttachments($mailId, $options);
$this->replaceDynamicContent($mailId);
$this->prepareTracking($mailId, $receiver);
if (!$this->handleDtexts($receiver)) {
$this->dtextsFailed = true;
return false;
}
$status = $this->send();
$this->initStatistics($status, $receiver->id);
return $status;
}
public function triggerFollowUpAgain(string $mailId, string $userId): void
{
if ($this->defaultMail[$mailId]->type !== MailClass::TYPE_FOLLOWUP) {
return;
}
$followUpClass = new FollowupClass();
$followUp = $followUpClass->getOneByMailId(intval($mailId));
if (empty($followUp)) {
return;
}
if (empty($followUp->loop)) {
return;
}
$lastEmail = $followUpClass->getLastEmail(intval($followUp->id));
if (empty($lastEmail) || $lastEmail->id != $mailId) {
return;
}
$delay = 0;
if (!empty($followUp->loop_delay)) {
$delay = $followUp->loop_delay;
}
$mailToSkip = [];
if (!empty($followUp->loop_mail_skip)) {
$mailToSkip = json_decode($followUp->loop_mail_skip);
}
$followUpClass->triggerFollowUp(intval($followUp->id), intval($userId), $delay, $mailToSkip);
}
public function statClick(int $mailId, int $userid, bool $fromStat = false): void
{
if (!$fromStat && !in_array($this->type, MailClass::TYPES_WITH_STATS)) {
return;
}
$urlClass = new UrlClass();
$urls = [];
$trackingSystemExternalWebsite = $this->config->get('trackingsystemexternalwebsite', 1);
$trackingSystem = $this->config->get('trackingsystem', 'acymailing');
if (false === strpos($trackingSystem, 'acymailing') && false === strpos($trackingSystem, 'google')) {
return;
}
if (strpos($trackingSystem, 'google') !== false) {
$mail = $this->mailClass->getOneById($mailId);
$campaignClass = new CampaignClass();
$campaign = $campaignClass->getOneCampaignByMailId($mailId);
$utmCampaign = acym_getAlias($mail->subject);
}
preg_match_all('#<[^>]* href[ ]*=[ ]*"(?!mailto:|\#|ymsgr:|callto:|file:|ftp:|webcal:|skype:|tel:)([^"]+)"#Ui', $this->body, $results);
if (empty($results)) {
return;
}
$countLinks = array_count_values($results[1]);
if (array_product($countLinks) != 1) {
$previousLinkHandled = '';
foreach ($results[1] as $key => $url) {
if ($countLinks[$url] === 1) {
continue;
}
$previousIsOutlook = false;
if (strpos($results[0][$key], '
', $serverinfo));
}
if (!empty($_REQUEST)) {
$postinfo = [];
foreach ($_REQUEST as $oneKey => $oneInfo) {
$postinfo[] = $oneKey.' => '.strip_tags(print_r($oneInfo, true));
}
$this->addParam('postinfo', implode('
', $postinfo));
}
}
public function addParam(string $name, $value): void
{
$tagName = '{'.$name.'}';
$this->parameters[$tagName] = $value;
}
public function overrideEmail(array $options): bool
{
$overrideAllEmails = $this->config->get('send_website_emails', 0) == 1;
$overrideClass = new OverrideClass();
$override = $overrideClass->getMailByBaseContent($options['subject'], $options['message']);
if (empty($override) && !$overrideAllEmails) {
return false;
}
$this->autoAddUser = true;
if (empty($override)) {
$this->trackEmail = false;
return $this->overrideAllEmails($options);
} else {
$this->trackEmail = true;
return $this->sendOverride($override, $options);
}
}
private function getSendingMethodSettings(string $settingName, string $default = ''): string
{
if (empty($this->currentMethodSetting)) {
return $this->config->get($settingName, $default);
}
return $this->currentMethodSetting[$settingName] ?? $default;
}
private function getSendingMethod(): string
{
$this->currentMethodSetting = [];
$sendingMethods = $this->config->get('sending_method_list', '{}');
$sendingMethods = json_decode($sendingMethods, true);
$sendingMethodsByList = $this->config->get('sending_method_list_by_list', '{}');
$sendingMethodsByList = json_decode($sendingMethodsByList, true);
if (empty($this->listsIds) || empty($sendingMethods) || empty($sendingMethodsByList) || empty($sendingMethodsByList[$this->listsIds[0]])) {
return $this->config->get('mailer_method', 'phpmail');
}
$sendingMethodIds = [];
foreach ($this->listsIds as $listId) {
if (!empty($sendingMethodsByList[$listId])) {
$sendingMethodIds[] = $sendingMethodsByList[$listId];
}
}
if (count($sendingMethodIds) !== count($this->listsIds) || count(array_unique($sendingMethodIds)) !== 1) {
return $this->config->get('mailer_method', 'phpmail');
}
$sendingMethodId = $sendingMethodIds[0];
if (empty($sendingMethods[$sendingMethodId])) {
return $this->config->get('mailer_method', 'phpmail');
}
$this->currentMethodSetting = $sendingMethods[$sendingMethodId];
return $sendingMethods[$sendingMethodId]['mailer_method'];
}
private function isExternal(string $method): void
{
$this->Mailer = 'external';
$this->externalMailer = $method;
}
private function storeArchiveVersion(int $mailId): void
{
if ($this->defaultMail[$mailId]->type !== MailClass::TYPE_STANDARD) {
return;
}
$mailArchive = new \stdClass();
$alreadyExisting = $this->mailArchiveClass->getOneByMailId($mailId);
if (!empty($alreadyExisting)) {
$mailArchive->id = $alreadyExisting->id;
}
$mailArchive->mail_id = $mailId;
$mailArchive->date = time();
$mailArchive->body = $this->defaultMail[$mailId]->body;
$mailArchive->subject = $this->defaultMail[$mailId]->subject;
$mailArchive->settings = $this->defaultMail[$mailId]->settings;
$mailArchive->stylesheet = $this->defaultMail[$mailId]->stylesheet;
$mailArchive->attachments = $this->defaultMail[$mailId]->attachments;
$this->mailArchiveClass->save($mailArchive);
}
private function canTrack(int $mailId, object $user): bool
{
if ($this->isTest || empty($mailId) || empty($user) || !isset($user->tracking) || $user->tracking != 1) {
return false;
}
$mail = $this->mailClass->getOneById($mailId);
if (!empty($mail) && $mail->tracking != 1) {
return false;
}
$lists = $this->mailClass->getAllListsByMailIdAndUserId($mailId, $user->id);
foreach ($lists as $list) {
if ($list->tracking != 1) {
return false;
}
}
return true;
}
private function loadUser($user, bool $force = false): object
{
if (is_string($user) && strpos($user, '@')) {
$receiver = $this->userClass->getOneByEmail($user);
if (empty($receiver)) {
if (($force || $this->autoAddUser) && acym_isValidEmail($user)) {
$newUser = new \stdClass();
$newUser->email = $user;
$this->userClass->checkVisitor = false;
$this->userClass->sendConf = false;
acym_setVar('acy_source', 'When sending a test');
$this->userClass->triggers = $this->userCreationTriggers;
$userId = $this->userClass->save($newUser);
$receiver = $this->userClass->getOneById($userId);
} else {
throw new Exception(acym_translation('ACYM_USER_NOT_FOUND'));
}
}
} elseif (is_object($user)) {
$receiver = $user;
} else {
$receiver = $this->userClass->getOneById($user);
}
$this->userLanguage = empty($receiver->language) ? acym_getLanguageTag() : $receiver->language;
$this->receiverEmail = $receiver->email;
return $receiver;
}
private function prepareContent(int $mailId, array $options): void
{
$this->isHTML();
if (!empty($this->defaultMail[$mailId]->stylesheet)) {
$this->stylesheet = $this->defaultMail[$mailId]->stylesheet;
}
$this->settings = empty($this->defaultMail[$mailId]->settings) ? [] : json_decode($this->defaultMail[$mailId]->settings, true);
$this->Subject = $this->defaultMail[$mailId]->subject;
$this->Body = $this->defaultMail[$mailId]->body;
if ($this->isTest && !empty($options['testNote'])) {
$this->Body = '
'.$this->Body;
} else {
$this->Body .= '
'.$attachStringHTML;
}
}
}
private function replaceDynamicContent(int $mailId): void
{
$this->replaceParams();
$this->body = &$this->Body;
$this->altbody = &$this->AltBody;
$this->subject = &$this->Subject;
$this->from = &$this->From;
$this->fromName = &$this->FromName;
$this->replyto = &$this->ReplyTo;
$this->replyname = $this->defaultMail[$mailId]->reply_to_name ?? '';
$this->replyemail = $this->defaultMail[$mailId]->reply_to_email ?? '';
$this->mailId = intval($this->defaultMail[$mailId]->id);
$this->id = $this->mailId;
$this->creator_id = intval($this->defaultMail[$mailId]->creator_id);
$this->type = $this->defaultMail[$mailId]->type;
$this->stylesheet = &$this->stylesheet;
$this->links_language = $this->defaultMail[$mailId]->links_language;
}
private function prepareTracking(int $mailId, object $receiver): void
{
if ($this->canTrack($mailId, $receiver)) {
$receiver->id = intval($receiver->id);
$this->statPicture($this->mailId, $receiver->id);
$this->body = acym_absoluteURL($this->body);
$this->statClick($this->mailId, $receiver->id);
if (acym_isTrackingSalesActive()) {
$this->trackingSales($this->mailId, $receiver->id);
}
}
}
private function handleDtexts(object $receiver): bool
{
$this->replaceParams();
if (strpos($receiver->email, '@mt.acyba.com') !== false) {
$currentUser = $this->userClass->getOneByEmail(acym_currentUserEmail());
if (empty($currentUser)) {
$currentUser = $receiver;
}
$result = acym_trigger('replaceUserInformation', [&$this, &$currentUser, true]);
} else {
$result = acym_trigger('replaceUserInformation', [&$this, &$receiver, true]);
if (!empty($result)) {
foreach ($result as $oneResult) {
if (!empty($oneResult) && !$oneResult['send']) {
$this->reportMessage = $oneResult['message'];
return false;
}
}
}
}
global $acymLanguages;
if (!empty($acymLanguages['userLanguage'])) {
unset($acymLanguages['userLanguage']);
}
foreach ($result as $oneResult) {
if (!empty($oneResult['emogrifier'])) {
$this->prepareEmailContent();
break;
}
}
if ($this->config->get('multiple_part', false)) {
$this->altbody = $this->textVersion($this->Body);
}
$this->replaceParams();
return true;
}
private function initStatistics(bool $status, int $receiverId): void
{
if ($this->trackEmail) {
$statsAdd = [];
$statsAdd[$this->mailId][intval($status)][] = $receiverId;
$queueHelper = new QueueHelper();
$queueHelper->statsAdd($statsAdd);
$this->trackEmail = false;
}
}
private function trackingSales(int $mailId, int $userId): void
{
preg_match_all('#href[ ]*=[ ]*"(?!mailto:|\#|ymsgr:|callto:|file:|ftp:|webcal:|skype:|tel:)([^"]+)"#Ui', $this->body, $results);
if (empty($results)) {
return;
}
foreach ($results[1] as $url) {
$simplifiedUrl = str_replace(['https://', 'http://', 'www.'], '', $url);
$simplifiedWebsite = str_replace(['https://', 'http://', 'www.'], '', ACYM_LIVE);
if (strpos($simplifiedUrl, rtrim($simplifiedWebsite, '/')) === false || strpos($url, 'task=unsub')) continue;
$toAddUrl = (strpos($url, '?') === false ? '?' : '&').'linkReferal='.$mailId.'-'.$userId;
$posHash = strpos($url, '#');
if ($posHash !== false) {
$newURL = substr($url, 0, $posHash).$toAddUrl.substr($url, $posHash);
} else {
$newURL = $url.$toAddUrl;
}
$this->body = preg_replace('#href="('.preg_quote($url, '#').')"#Uis', 'href="'.$newURL.'"', $this->body);
}
}
private function statPicture(int $mailId, int $userId): void
{
$pictureLink = acym_frontendLink('frontstats&task=openStats&id='.$mailId.'&userid='.$userId, true, false);
$statPicture = '';
if (strpos($this->body, '')) {
$this->body = str_replace('
', $statPicture.'', $this->body); } else { $this->body .= $statPicture; } } private function removeAdditionalParams(string $url): string { $additionalParamsPos = strpos($url, '?'); if (!empty($additionalParamsPos)) { $url = substr($url, 0, $additionalParamsPos); } return $url; } private function replaceParams(): void { if (empty($this->parameters)) { return; } $pluginHelper = new PluginHelper(); $this->generateAllParams(); $vars = [ 'Subject', 'Body', 'From', 'FromName', 'replyname', 'replyemail', ]; foreach ($vars as $oneVar) { if (!empty($this->$oneVar)) { $this->$oneVar = $pluginHelper->replaceDText($this->$oneVar, $this->parameters); } } if (!empty($this->ReplyTo)) { foreach ($this->ReplyTo as $i => $replyto) { foreach ($replyto as $a => $oneval) { $this->ReplyTo[$i][$a] = $pluginHelper->replaceDText($this->ReplyTo[$i][$a], $this->parameters); } } } } private function generateAllParams(): void { $result = '
| Tag | Value |
| '.trim($name, '{}').' | '.$value.' |
'; $this->addParam('allshortcodes', $result); } private function sendOverride(object $override, array $options): bool { for ($i = 1 ; $i < count($override->parameters) ; $i++) { $oneParam = $override->parameters[$i]; $unmodified = $oneParam; $oneParam = preg_replace( '/(http|https):\/\/(.*)/', '$1://$2', $oneParam, -1, $count ); if ($count > 0) { $this->addParam('link'.$i, $unmodified); } $this->addParam('param'.$i, $oneParam); } $this->addParam('subject', $options['subject']); $this->overrideEmailToSend = $override; $statusSend = $this->sendOne($override->id, $options['to'], $options); if (!$statusSend && !empty($this->reportMessage)) { $cronHelper = new CronHelper(); $cronHelper->saveReport([$this->reportMessage]); } return $statusSend; } public function getSendSettings(string $type, int $mailId = 0): string { if (!in_array($type, ['from_name', 'from_email', 'replyto_name', 'replyto_email', 'bounce_email'])) { return ''; } $mailType = strpos($type, 'replyto') !== false ? str_replace('replyto', 'reply_to', $type) : $type; if (!empty($mailId) && !empty($this->defaultMail[$mailId]->$mailType)) { return $this->defaultMail[$mailId]->$mailType; } $lang = empty($this->userLanguage) ? acym_getLanguageTag() : $this->userLanguage; $setting = $this->config->get($type); $translation = $this->config->get('sender_info_translation'); if (!empty($translation)) { $translation = json_decode($translation, true); if (!empty($translation[$lang][$type])) { $setting = $translation[$lang][$type]; } } return $setting; } private function prepareEmailContent(int $mailId = 0): void { $this->handleRelativeURLs($mailId); $this->inlineCSS($mailId); $this->finalizeHtmlStructure($mailId); } private function handleRelativeURLs(int $mailId): void { $mail = empty($mailId) ? $this : $this->defaultMail[$mailId]; $mail->body = acym_absoluteURL($mail->body); } private function inlineCSS(int $mailId): void { $mail = empty($mailId) ? $this : $this->defaultMail[$mailId]; global $emogrifiedMediaCSS; $emogrifiedMediaCSS = ''; $style = $this->getEmailStylesheet($mail); $cssInliner = CssInlinerHelper::fromHtml($mail->body)->inlineCss(implode('', $style)); $domDocument = $cssInliner->getDomDocument(); $mail->body = preg_replace( [ '# id="mce_\d+"#Ui', '#(style="[^"]+);"#Ui', ], [ '', '$1"', ], HtmlPruner::fromDomDocument($domDocument) ->removeRedundantClassesAfterCssInlined($cssInliner) ->renderBodyContent() ); $mail->body = str_replace('', '', $mail->body); $mail->body = preg_replace_callback( '#style="([^"]+)"#Ui', function ($matches) { return 'style="'.str_replace(['; ', ': '], [';', ':'], $matches[1]).'"'; }, $mail->body ); } private function finalizeHtmlStructure(int $mailId): void { $mail = empty($mailId) ? $this : $this->defaultMail[$mailId]; $finalContent = ''; $finalContent .= '
'; $finalContent .= ''; $finalContent .= ''."\n"; $finalContent .= ''."\n"; $finalContent .= '
'."\n"; global $emogrifiedMediaCSS; $finalContent .= ''; $finalContent .= ''; $finalContent .= ''; if (!empty($mail->headers)) { $finalContent .= $mail->headers; } $finalContent .= ''; preg_match('@<[^>"t]*body[^>]*>@', $mail->body, $matches); if (empty($matches[0])) { $mail->body = '
'; } else { preg_match('@<[^>"t]*/body[^>]*>@', $mail->body, $matches); if (empty($matches[0])) { $mail->body .= ''; } } $finalContent .= $mail->body; $finalContent .= '