pluginDescription; } public function textPopup(): void { $others = []; $others['unsubscribe'] = ['name' => acym_translation('ACYM_UNSUBSCRIBE_LINK'), 'default' => 'ACYM_UNSUBSCRIBE']; $others['unsubscribeall'] = ['name' => acym_translation('ACYM_UNSUBSCRIBE_ALL_LISTS_LINK'), 'default' => 'ACYM_UNSUBSCRIBE_ALL_LISTS']; $others['direct_unsubscribe'] = ['name' => acym_translation('ACYM_DIRECT_UNSUBSCRIBE_LINK'), 'default' => 'ACYM_UNSUBSCRIBE']; $others['disable_tracking'] = ['name' => acym_translation('ACYM_DISABLE_TRACKING_LINK'), 'default' => 'ACYM_DISABLE_TRACKING']; $others['confirm'] = ['name' => acym_translation('ACYM_CONFIRM_SUBSCRIPTION_LINK'), 'default' => 'ACYM_CONFIRM_SUBSCRIPTION']; $others['subscribe'] = ['name' => acym_translation('ACYM_SUBSCRIBE_LINK'), 'default' => 'ACYM_SUBSCRIBE']; ?>

'.esc_html(acym_translation('ACYM_SUBSCRIPTION')).'

'; foreach ($others as $tagname => $tag) { $onclick = "changeSubscriptionTag('".$tagname."');"; if ($tagname === 'subscribe') { $onclick .= 'displayLists();return false;'; } elseif ($tagname === 'direct_unsubscribe') { $onclick .= 'displayDirectUnsubscribeRedirect();return false;'; } elseif ($tagname === 'unsubscribeall') { $onclick .= 'displayUnsubscribeAllRedirect();return false;'; } echo '
'; echo '
'.wp_kses( $tag['name'], [ 'b' => [], ] ).'
'; echo '
'; } echo '
'; acym_modalPaginationLists( 'acym__popup__subscription__change', '' ); echo '
'; // List tags $others = []; $others['name'] = acym_translation('ACYM_LIST_NAME'); $others['description'] = acym_translation('ACYM_LIST_DESCRIPTION'); $others['names'] = acym_translation('ACYM_LIST_NAMES'); $others['descriptions'] = acym_translation('ACYM_LIST_DESCRIPTIONS'); $others['id'] = acym_translation('ACYM_LIST_ID', true); echo '

'.esc_html(acym_translation('ACYM_LIST')).'

'; foreach ($others as $tagname => $tag) { echo '
'.esc_html($tag).'
'; } echo '
'; // Newsletter tags echo '
'.esc_html(acym_translation('ACYM_CAMPAIGN')).'
'; $othersMail = ['campaignid', 'subject']; foreach ($othersMail as $tag) { echo '
'.esc_html($tag).'
'; } echo '
'; // Smart newsletter tags echo '
'.esc_html(acym_translation('ACYM_AUTO').' '.acym_translation('ACYM_CAMPAIGNS')).'
'; $autoMail = [ 'number_generated' => [ 'name' => acym_translation('ACYM_ISSUE_NB'), 'default' => '#1', ], ]; foreach ($autoMail as $tag => $oneTag) { $tagInserted = $tag; if (!empty($oneTag['default'])) { $tagInserted = $tag.'|default:'.$oneTag['default']; } echo '
'.esc_html($oneTag['name']).'
'; } echo '
'; } public function replaceUserInformation(object &$email, ?object &$user, bool $send = true): void { if (empty($email->id)) { return; } $this->replacelisttags($email, $user, $send); // Check if we should add the List-Unsubscribe header if (empty($user->id) || !empty($this->addedListUnsubscribe[$email->id][$user->id])) return; if (empty($this->unsubscribeLink[$email->id]) || !method_exists($email, 'addCustomHeader')) return; $this->addedListUnsubscribe[$email->id][$user->id] = true; // Prepare the mailto parameters for the header $mailto = ''; if ($this->config->get('auto_bounce', 0)) { $mailto = $this->config->get('bounce_email'); } if (empty($mailto)) { $mailto = empty($email->replyemail) ? $this->config->get('replyto_email') : $email->replyemail; } // No bounce address, no reply-to address on the email or the configuration if (empty($mailto)) { return; } $body = 'Please%20unsubscribe%20user%20ID%20'.$user->id; if (!isset($this->mailLists[$email->id])) { $mailClass = new MailClass(); $lists = $mailClass->getAllListsByMailId($email->id); $this->mailLists[$email->id] = empty($lists) ? null : array_keys($lists); } // Make sure we unsubscribe from the correct lists and not all the lists if (!empty($this->mailLists[$email->id])) { $userClass = $this->getUserClass(); $userLists = $userClass->getSubscriptionStatus($user->id, [], UserClass::STATUS_SUBSCRIBED); if (!empty($userLists)) { $commonLists = array_intersect($this->mailLists[$email->id], array_keys($userLists)); if (!empty($commonLists)) { $body .= '%20from%20list(s)%20'.implode(',', $commonLists).'.'; } } } $unsubscribeLink = str_replace( ['{subscriber:id}', '{subscriber:key|urlencode}'], [$user->id, urlencode($user->key)], $this->unsubscribeLink[$email->id] ); $email->addCustomHeader('List-Unsubscribe', '<'.$unsubscribeLink.'&ajax=1>, id.'&body='.$body.'>'); $email->addCustomHeader('List-Unsubscribe-Post', 'List-Unsubscribe=One-Click'); } public function replaceContent(object &$email): void { $this->replaceSubscriptionTags($email); $this->replacemailtags($email); $this->replaceAutomailTags($email); } private function replacemailtags(&$email) { $result = $this->pluginHelper->extractTags($email, 'mail'); $tags = []; foreach ($result as $key => $oneTag) { if (isset($tags[$key])) { continue; } $field = $oneTag->id; if (!empty($email) && !empty($email->$field)) { $text = $email->$field; $this->pluginHelper->formatString($text, $oneTag); $tags[$key] = $text; } elseif (substr($field, 0, 8) == 'campaign') { $this->getCampaignTags($email, $tags, $oneTag, $key); } else { $tags[$key] = $oneTag->default; } } $this->pluginHelper->replaceTags($email, $tags); } private function getCampaignTags(&$email, &$tags, $oneTag, $key) { $campaignClass = new CampaignClass(); $campaignFromMail = $campaignClass->getOneCampaignByMailId($email->id); $campaignField = substr($oneTag->id, 8); if (!empty($campaignFromMail) && !empty($campaignFromMail->$campaignField)) { $text = $campaignFromMail->$campaignField; $this->pluginHelper->formatString($text, $oneTag); $tags[$key] = $text; } else { $tags[$key] = $oneTag->default; } } // Available tags: {automail:number_generated} private function replaceAutomailTags(&$email) { $result = $this->pluginHelper->extractTags($email, 'automail'); $tags = []; foreach ($result as $key => $oneTag) { if (isset($tags[$key])) { continue; } $field = $oneTag->id; $campaignClass = new CampaignClass(); $autoCampaignFromMail = $campaignClass->getAutoCampaignFromGeneratedMailId($email->id); if (!empty($autoCampaignFromMail) && !empty($autoCampaignFromMail->sending_params[$field])) { $text = $autoCampaignFromMail->sending_params[$field]; $this->pluginHelper->formatString($text, $oneTag); $tags[$key] = $text; } else { $tags[$key] = $oneTag->default; } } $this->pluginHelper->replaceTags($email, $tags); } //Available tags: {list:name} , {list:count} , {list:count|listid:0} (to count all users), {list:members}, {list:owner} private function replacelisttags(&$email, &$user, $send) { $tags = $this->pluginHelper->extractTags($email, 'list'); if (empty($tags)) { return; } $replaceTags = []; foreach ($tags as $oneTag => $parameter) { $method = 'list'.trim(strtolower($parameter->id)); if (method_exists($this, $method)) { $replaceTags[$oneTag] = $this->$method($email, $user, $parameter); } else { $replaceTags[$oneTag] = 'Method not found: '.$method; } } $this->pluginHelper->replaceTags($email, $replaceTags, true); } private function getAttachedListid($email, $subid) { $mailid = $email->id; if (isset($this->lists[$mailid][$subid])) { return $this->lists[$mailid][$subid]; } $mailClass = new MailClass(); $mailLists = array_keys($mailClass->getAllListsByMailId($mailid)); $userLists = []; if (!empty($subid)) { $userClass = $this->getUserClass(); $userLists = $userClass->getUserSubscriptionById($subid, 'id', false, false, false, true); $listid = null; foreach ($userLists as $id => $oneList) { if ($oneList->status == 1 && in_array($id, $mailLists)) { $this->lists[$mailid][$subid] = $id; return $this->lists[$mailid][$subid]; } } if (!empty($listid)) { $this->lists[$mailid][$subid] = $listid; return $listid; } } //We could not find a list id there... maybe there is no subscription in which case we take the first one... if (!empty($mailLists)) { $this->lists[$mailid][$subid] = array_shift($mailLists); return $this->lists[$mailid][$subid]; } if (!empty($subid) && !empty($email->type) && $email->type === MailClass::TYPE_WELCOME) { //Last list the user subscribed to... $listid = acym_loadResult( 'SELECT list.id FROM #__acym_list AS list JOIN #__acym_user_has_list AS userlist ON list.id = userlist.list_id WHERE list.welcome_id = '.intval($mailid).' AND userlist.user_id = '.intval($subid).' ORDER BY userlist.subscription_date DESC' ); if (!empty($listid)) { $this->lists[$mailid][$subid] = $listid; return $listid; } } if (!empty($subid) && !empty($email->type) && $email->type === MailClass::TYPE_UNSUBSCRIBE) { //Last list the user unsubscribed from... $listid = acym_loadResult( 'SELECT list.id FROM #__acym_list AS list JOIN #__acym_user_has_list AS userlist ON list.id = userlist.list_id WHERE list.unsubscribe_id = '.intval($mailid).' AND userlist.user_id = '.intval($subid).' ORDER BY userlist.unsubscribe_date DESC' ); if (!empty($listid)) { $this->lists[$mailid][$subid] = $listid; return $listid; } } //Still no list? well, lets load the first list the user is subscribed to then if (!empty($userLists)) { $listIds = array_keys($userLists); $this->lists[$mailid][$subid] = array_shift($listIds); return $this->lists[$mailid][$subid]; } return 0; } private function listnames(&$email, &$user, &$parameter) { if (empty($user->id)) return ''; $userClass = $this->getUserClass(); $usersubscription = $userClass->getUserSubscriptionById($user->id, 'id', false, true); $lists = []; if (!empty($usersubscription)) { foreach ($usersubscription as $onesub) { if ($onesub->status < 1 || empty($onesub->active)) { continue; } $lists[] = (!empty($onesub->display_name) ? $onesub->display_name : $onesub->name); } } return implode(isset($parameter->separator) ? $parameter->separator : ', ', $lists); } /** * Replace data about the list owner * Use the tag: {list:owner|field:name} or {list:owner|field:username} or {list:owner|field:email} */ private function listowner(&$email, &$user, &$parameter) { if (empty($user->id)) { return ''; } if (!in_array($parameter->field, ['username', 'name', 'email'])) { return 'Field not found : '.$parameter->field; } $listid = $this->getAttachedListid($email, $user->id); if (empty($listid)) { return ''; } global $acymCmsUserVars; if (!isset($this->listsowner[$listid])) { $this->listsowner[$listid] = acym_loadObject( 'SELECT `user`.* FROM #__acym_list AS `list` JOIN '.$acymCmsUserVars->table.' AS `user` ON `user`.'.$acymCmsUserVars->id.' = `list`.cms_user_id WHERE `list`.id = '.intval($listid) ); } return @$this->listsowner[$listid]->{$acymCmsUserVars->{$parameter->field}}; } private function listname(&$email, &$user, &$parameter) { if (empty($user->id)) { return ''; } $listid = $this->getAttachedListid($email, $user->id); if (empty($listid)) { return ''; } $this->loadlist($listid); return !empty($this->listsinfo[$listid]->display_name) ? $this->listsinfo[$listid]->display_name : @$this->listsinfo[$listid]->name; } private function listdescription(&$email, &$user, &$parameter) { if (empty($user->id)) { return ''; } if (!empty($parameter->listid)) $listid = $parameter->listid; if (empty($listid)) $listid = $this->getAttachedListid($email, $user->id); if (empty($listid)) { return ''; } $this->loadlist($listid); return @$this->listsinfo[$listid]->description; } private function loadlist($listid) { if (isset($this->listsinfo[$listid])) { return; } $listClass = new ListClass(); $this->listsinfo[$listid] = $listClass->getOneById(intval($listid)); } private function listdescriptions(&$email, &$user, &$parameter) { if (empty($user->id)) return ''; $userClass = $this->getUserClass(); $usersubscription = $userClass->getUserSubscriptionById($user->id); $listids = []; if (!empty($parameter->listids)) $listids = explode(',', $parameter->listids); $lists = []; if (!empty($usersubscription)) { foreach ($usersubscription as $onesub) { if (empty($onesub->description) || $onesub->status < 1 || empty($onesub->active) || (!empty($listids) && !in_array($onesub->id, $listids))) { continue; } $lists[] = $onesub->description; } } return implode(isset($parameter->separator) ? $parameter->separator : ', ', $lists); } private function listid(&$email, &$user, &$parameter) { if (empty($user->id)) { return ''; } $listid = $this->getAttachedListid($email, $user->id); if (empty($listid)) { return ''; } return $listid; } private function replaceSubscriptionTags(&$email) { $match = '#(?:{|%7B)(confirm|unsubscribe(?:\|[^}]+)*|unsubscribeall(?:\|[^}]+)*|direct_unsubscribe(?:\|[^}]+)*|disable_tracking(?:\|[^}]+)*|subscribe(?:\|[^}]+)*)(?:}|%7D)(.*)(?:{|%7B)/(confirm|unsubscribe|direct_unsubscribe|unsubscribeall|disable_tracking|subscribe)(?:}|%7D)#Uis'; $variables = ['subject', 'body']; $found = false; $results = []; foreach ($variables as $var) { if (empty($email->$var)) continue; $found = preg_match_all($match, $email->$var, $results[$var]) || $found; //we unset the results so that we won't handle it later... it will save some memory and processing if (empty($results[$var][0])) unset($results[$var]); } //If we didn't find anything... if (!$found) return; $tags = []; $this->addedListUnsubscribe[$email->id] = []; foreach ($results as $var => $allresults) { foreach ($allresults[0] as $i => $oneTag) { //Don't need to process twice a tag we already have! if (isset($tags[$oneTag])) continue; $tags[$oneTag] = $this->replaceSubscriptionTag($allresults, $i, $email); } } $this->pluginHelper->replaceTags($email, $tags); } private function replaceSubscriptionTag(&$allresults, $i, &$email) { $parameters = $this->pluginHelper->extractTag($allresults[1][$i]); $lang = $this->getLanguage($email->links_language); if ($parameters->id === 'confirm') { // subscription confirmation link $myLink = acym_frontendLink('frontusers&task=confirm&userId={subscriber:id}&userKey={subscriber:key|urlencode}'.$lang); if (empty($allresults[2][$i])) { return $myLink; } return ''.$allresults[2][$i].''; } elseif ($parameters->id === 'subscribe') { // direct subscription link if (empty($parameters->lists)) { return acym_translation('ACYM_EXPORT_SELECT_LIST'); } $lists = explode(',', $parameters->lists); acym_arrayToInteger($lists); $captchaKey = $this->config->get('captcha', 'none') !== 'none' ? '&seckey='.$this->config->get('security_key', '') : ''; $myLink = acym_frontendLink( 'frontusers&task=subscribe&hiddenlists='.implode(',', $lists).'&userId={subscriber:id}&userKey={subscriber:key|urlencode}'.$lang.$captchaKey ); if (empty($allresults[2][$i])) { return $myLink; } return ''.$allresults[2][$i].''; } elseif ($parameters->id === 'direct_unsubscribe') { $mailId = $email->id; $myLink = acym_frontendLink( 'frontusers&task=unsubscribe' .'&userId={subscriber:id}' .'&userKey={subscriber:key|urlencode}' .'&direct=1' .'&mail_id='.$mailId .$lang ); if (!empty($parameters->redirect)) { $myLink .= '&redirectunsub='.urlencode($parameters->redirect); } if (empty($allresults[2][$i])) { return $myLink; } return ''.$allresults[2][$i].''; } elseif ($parameters->id === 'disable_tracking') { $myLink = acym_frontendLink( 'frontusers&task=disableTracking' .'&userId={subscriber:id}' .'&userKey={subscriber:key|urlencode}' .'&mail_id='.$email->id .$lang ); if (empty($allresults[2][$i])) { return $myLink; } return ''.$allresults[2][$i].''; } else { $baseLink = 'frontusers'.$lang.'&mail_id='.$email->id; if ($parameters->id === 'unsubscribe') { $unsubscribeLink = $baseLink.'&task=unsubscribe&userId={subscriber:id}&userKey={subscriber:key|urlencode}'; if (ACYM_CMS !== 'wordpress') { $unsubscribeLink .= '&'.acym_noTemplate(); } $unsubClass = 'acym_unsubscribe'; } else { $unsubscribeLink = $baseLink.'&task=unsubscribeAll&user_id={subscriber:id}&user_key={subscriber:key|urlencode}'; $unsubClass = 'acym_unsubscribe_all_lists'; } $needToCompleteLink = true; if (!empty($parameters->baseUrl)) { $unsubscribeLink = $parameters->baseUrl.$unsubscribeLink; $needToCompleteLink = false; } $unsubscribeLink = acym_frontendLink($unsubscribeLink, $needToCompleteLink); if ($parameters->id === 'unsubscribeall' && !empty($parameters->redirect)) { $unsubscribeLink .= (strpos($unsubscribeLink, '?') === false ? '?' : '&').'redirectunsub='.urlencode($parameters->redirect); } $this->unsubscribeLink[$email->id] = $unsubscribeLink; if (empty($allresults[2][$i])) { return $unsubscribeLink; } return ''.$allresults[2][$i].''; } } private function getUserClass() { if ($this->userClass === null) { $this->userClass = new UserClass(); } return $this->userClass; } }