PluginProbe
AcyMailing – An Ultimate Newsletter Plugin and Marketing Automation Solution for WordPress / 11.1.0
AcyMailing – An Ultimate Newsletter Plugin and Marketing Automation Solution for WordPress v11.1.0
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/dynamics/subscription/SubscriptionInsertion.php +240 -91 10.1.4 → 11.1.0 View file →
@@ -6,33 +6,43 @@
6 6 use AcyMailing\Classes\ListClass;
7 7
8 8 trait SubscriptionInsertion
9 9 {
10 + //Set this variable to true once the list unsubscribe is added so we don't add it twice
10 11 private $addedListUnsubscribe = [];
12 + //Keep all lists and IDs for users so we don't do the query twice
11 13 private $lists = [];
14 + //Keep all listsowner information so we don't do the query again and again
12 15 private $listsowner = [];
16 + //Keep the list information there
13 17 private $listsinfo = [];
18 + //Used to know if we should add a List-Unsubscribe header
14 19 private $unsubscribeLink = [];
20 + // Used for list-unsubscribe to store the mail's list ids
15 21 private $mailLists = [];
16 22 private $userClass = null;
17 23
18 - public function dynamicText($mailId)
24 + public function dynamicText(?int $mailId): ?object
19 25 {
20 26 return $this->pluginDescription;
21 27 }
22 28
23 - public function textPopup()
29 + public function textPopup(): void
24 30 {
25 31 $others = [];
26 32 $others['unsubscribe'] = ['name' => acym_translation('ACYM_UNSUBSCRIBE_LINK'), 'default' => 'ACYM_UNSUBSCRIBE'];
27 33 $others['unsubscribeall'] = ['name' => acym_translation('ACYM_UNSUBSCRIBE_ALL_LISTS_LINK'), 'default' => 'ACYM_UNSUBSCRIBE_ALL_LISTS'];
34 + $others['direct_unsubscribe'] = ['name' => acym_translation('ACYM_DIRECT_UNSUBSCRIBE_LINK'), 'default' => 'ACYM_UNSUBSCRIBE'];
35 + $others['disable_tracking'] = ['name' => acym_translation('ACYM_DISABLE_TRACKING_LINK'), 'default' => 'ACYM_DISABLE_TRACKING'];
28 36 $others['confirm'] = ['name' => acym_translation('ACYM_CONFIRM_SUBSCRIPTION_LINK'), 'default' => 'ACYM_CONFIRM_SUBSCRIPTION'];
29 37 $others['subscribe'] = ['name' => acym_translation('ACYM_SUBSCRIBE_LINK'), 'default' => 'ACYM_SUBSCRIBE'];
30 38
31 39 ?>
32 40 <script type="text/javascript">
33 - var openedLists = false;
34 - var selectedSubscriptionDText = '';
41 + let openedLists = false;
42 + let openedDirectUnsubscribeRedirect = false;
43 + let openedUnsubscribeAllRedirect = false;
44 + let selectedSubscriptionDText = '';
35 45
36 46 function changeSubscriptionTag(tagName) {
37 47 selectedSubscriptionDText = tagName;
38 48 let defaultText = [];
@@ -37,9 +47,9 @@
37 47 selectedSubscriptionDText = tagName;
38 48 let defaultText = [];
39 49 <?php
40 50 foreach ($others as $tagname => $tag) {
41 - echo 'defaultText["'.$tagname.'"] = "'.acym_translation($tag['default'], true).'";';
51 + echo 'defaultText["'.esc_attr($tagname).'"] = '.json_encode(acym_translation($tag['default'])).';';
42 52 }
43 53 ?>
44 54 jQuery('.selected_row').removeClass('selected_row');
45 55 jQuery('#tr_' + tagName).addClass('selected_row');
@@ -47,19 +57,37 @@
47 57 setSubscriptionTag();
48 58 }
49 59
50 60 function setSubscriptionTag() {
51 - var tag = '{' + selectedSubscriptionDText;
52 - var lists = jQuery('#acym__popup__subscription__listids');
61 + if (openedLists && selectedSubscriptionDText !== 'subscribe') {
62 + jQuery('#acym__popup__plugin__subscription__lists__modal').slideUp();
63 + jQuery('#select_lists_zone').hide();
64 + openedLists = false;
65 + }
66 + if (openedDirectUnsubscribeRedirect && selectedSubscriptionDText !== 'direct_unsubscribe') {
67 + jQuery('#acym__popup__plugin__direct_unsubscribe__modal').slideUp();
68 + openedDirectUnsubscribeRedirect = false;
69 + }
70 + if (openedUnsubscribeAllRedirect && selectedSubscriptionDText !== 'unsubscribeall') {
71 + jQuery('#acym__popup__plugin__unsubscribeall__modal').slideUp();
72 + openedUnsubscribeAllRedirect = false;
73 + }
53 74
75 + let tag = '{' + selectedSubscriptionDText;
76 + let lists = jQuery('#acym__popup__subscription__listids');
77 +
54 78 if ('subscribe' === selectedSubscriptionDText) {
55 79 tag += '|lists:' + lists.html();
56 - } else if (openedLists) {
57 - jQuery('#acym__popup__plugin__subscription__lists__modal').slideUp();
58 - jQuery('#select_lists_zone').hide();
59 - openedLists = false;
60 80 }
61 81
82 + if (selectedSubscriptionDText === 'direct_unsubscribe') {
83 + let redirect = jQuery('#acym__popup__direct_unsubscribe__redirect').val();
84 + if (redirect) tag += '|redirect:' + encodeURIComponent(redirect);
85 + } else if (selectedSubscriptionDText === 'unsubscribeall') {
86 + let redirect = jQuery('#acym__popup__unsubscribeall__redirect').val();
87 + if (redirect) tag += '|redirect:' + encodeURIComponent(redirect);
88 + }
89 +
62 90 tag += '}' + jQuery('#acym__popup__subscription__tagtext').val() + '{/' + selectedSubscriptionDText + '}';
63 91 setTag(tag, jQuery('#tr_' + selectedSubscriptionDText));
64 92 }
65 93
@@ -69,55 +97,100 @@
69 97
70 98 jQuery.acymModal();
71 99 jQuery('#acym__popup__plugin__subscription__lists__modal').slideDown();
72 100 jQuery('#select_lists_zone').toggle();
73 - jQuery('#acym__popup__subscription__change').on('change', function () {
74 - var lists = JSON.parse(jQuery('#acym__modal__lists-selected').val());
101 +
102 + jQuery('#acym__popup__subscription__change').off('change').on('change', function () {
103 + const lists = JSON.parse(jQuery('#acym__modal__lists-selected').val());
75 104 jQuery('#acym__popup__subscription__listids').html(lists.join());
76 105 changeSubscriptionTag('subscribe');
77 106 });
78 107 }
108 +
109 + function displayDirectUnsubscribeRedirect() {
110 + if (openedDirectUnsubscribeRedirect) return;
111 + openedDirectUnsubscribeRedirect = true;
112 + jQuery('#acym__popup__plugin__direct_unsubscribe__modal').slideDown();
113 +
114 + jQuery('#acym__popup__direct_unsubscribe__redirect').off('input').on('input', function () {
115 + let redirectLink = jQuery(this).val();
116 + jQuery('#acym__popup__direct_unsubscribe__preview').html(redirectLink);
117 + changeSubscriptionTag('direct_unsubscribe');
118 + });
119 + }
120 +
121 + function displayUnsubscribeAllRedirect() {
122 + if (openedUnsubscribeAllRedirect) return;
123 + openedUnsubscribeAllRedirect = true;
124 + jQuery('#acym__popup__plugin__unsubscribeall__modal').slideDown();
125 +
126 + jQuery('#acym__popup__unsubscribeall__redirect').off('input').on('input', function () {
127 + let redirectLink = jQuery(this).val();
128 + jQuery('#acym__popup__unsubscribeall__preview').html(redirectLink);
129 + changeSubscriptionTag('unsubscribeall');
130 + });
131 + }
79 132 </script>
80 133 <?php
134 + //Add an area where the user will be able to select another text to add
135 + echo '<div class="acym__popup__listing text-center grid-x">
136 + <h1 class="acym__title acym__title__secondary text-center cell">'.esc_html(acym_translation('ACYM_SUBSCRIPTION')).'</h1>
137 + <div class="grid-x medium-12 cell acym__row__no-listing text-left acym_vcenter">
138 + <div class="grid-x cell medium-5 small-12 acym__listing__title acym__listing__title__dynamics acym__subscription__subscription acym_vcenter">
139 + <label class="small-3 margin-bottom-0" for="acym__popup__subscription__tagtext">'.esc_html(acym_translation('ACYM_TEXT')).': </label>
140 + <input class="small-9" type="text" name="tagtext" id="acym__popup__subscription__tagtext" onchange="setSubscriptionTag();">
141 + </div>
142 + <div class="medium-1"></div>
143 + <div style="display: none;" id="select_lists_zone" class="grid-x cell medium-6 small-12 acym__listing__title acym__listing__title__dynamics">
144 + <p class="shrink" id="acym__popup__subscription__text__list">'.esc_html(acym_translation('ACYM_LISTS_SELECTED')).'</p>
145 + <p class="shrink" id="acym__popup__subscription__listids"></p>
146 + </div>
147 + </div>
148 + <div class="cell grid-x">';
81 149
82 - $text = '<div class="acym__popup__listing text-center grid-x">
83 - <h1 class="acym__title acym__title__secondary text-center cell">'.acym_translation('ACYM_SUBSCRIPTION').'</h1>
84 - <div class="grid-x medium-12 cell acym__row__no-listing text-left acym_vcenter">
85 - <div class="grid-x cell medium-5 small-12 acym__listing__title acym__listing__title__dynamics acym__subscription__subscription acym_vcenter">
86 - <label class="small-3 margin-bottom-0" for="acym__popup__subscription__tagtext">'.acym_translation('ACYM_TEXT').': </label>
87 - <input class="small-9" type="text" name="tagtext" id="acym__popup__subscription__tagtext" onchange="setSubscriptionTag();">
88 - </div>
89 - <div class="medium-1"></div>
90 - <div style="display: none;" id="select_lists_zone" class="grid-x cell medium-6 small-12 acym__listing__title acym__listing__title__dynamics">
91 - <p class="shrink" id="acym__popup__subscription__text__list">'.acym_translation('ACYM_LISTS_SELECTED').'</p>
92 - <p class="shrink" id="acym__popup__subscription__listids"></p>
93 - </div>
94 - </div>';
95 - $text .= '
96 - <div class="cell grid-x">';
97 -
98 150 foreach ($others as $tagname => $tag) {
99 151 $onclick = "changeSubscriptionTag('".$tagname."');";
100 - if ($tagname == 'subscribe') {
152 + if ($tagname === 'subscribe') {
101 153 $onclick .= 'displayLists();return false;';
154 + } elseif ($tagname === 'direct_unsubscribe') {
155 + $onclick .= 'displayDirectUnsubscribeRedirect();return false;';
156 + } elseif ($tagname === 'unsubscribeall') {
157 + $onclick .= 'displayUnsubscribeAllRedirect();return false;';
102 158 }
103 - $text .= '<div class="grid-x small-12 cell acym__row__no-listing acym__listing__row__popup text-left" onclick="'.$onclick.'" id="tr_'.$tagname.'" >';
104 - $text .= '<div class="cell small-12 acym__listing__title acym__listing__title__dynamics">'.$tag['name'].'</div>';
105 - $text .= '</div>';
159 +
160 + echo '<div class="grid-x small-12 cell acym__row__no-listing acym__listing__row__popup text-left" onclick="'.esc_attr($onclick).'" id="tr_'.esc_attr(
161 + $tagname
162 + ).'" >';
163 + echo '<div class="cell small-12 acym__listing__title acym__listing__title__dynamics">'.wp_kses(
164 + $tag['name'],
165 + [
166 + 'b' => [],
167 + ]
168 + ).'</div>';
169 + echo '</div>';
106 170 }
107 - $text .= '</div>
108 - <div class="medium-1"></div>
109 - <div class="medium-10 text-left">';
110 - $text .= acym_modalPaginationLists(
171 + echo '</div>
172 + <div class="medium-1"></div>
173 + <div class="medium-10 text-left">';
174 + acym_modalPaginationLists(
111 175 'acym__popup__subscription__change',
112 - '',
113 - false,
114 - 'style="display: none;" id="acym__popup__plugin__subscription__lists__modal"'
176 + ''
115 177 );
116 - $text .= ' </div>
117 - <div class="medium-1"></div>
118 - </div>';
178 + echo '<div style="display: none;" id="acym__popup__plugin__direct_unsubscribe__modal" class="grid-x cell medium-6 small-12 acym__listing__title acym__listing__title__dynamics">
179 + <label>'.esc_html(acym_translation('ACYM_REDIRECTION_URL')).'</label>
180 + <input type="text" id="acym__popup__direct_unsubscribe__redirect" placeholder="https://example.com/unsubscribed" />
181 + <p id="acym__popup__direct_unsubscribe__preview" class="acym_smalltext text-gray"></p>
182 + </div>
183 + <div style="display: none;" id="acym__popup__plugin__unsubscribeall__modal" class="grid-x cell medium-6 small-12 acym__listing__title acym__listing__title__dynamics">
184 + <label>'.esc_html(acym_translation('ACYM_REDIRECTION_URL')).'</label>
185 + <input type="text" id="acym__popup__unsubscribeall__redirect" placeholder="https://example.com/all-unsubscribed" />
186 + <p id="acym__popup__unsubscribeall__preview" class="acym_smalltext text-gray"></p>
187 + </div>
188 + </div>
189 + <div class="medium-1"></div>
190 + </div>';
119 191
192 + // List tags
120 193 $others = [];
121 194 $others['name'] = acym_translation('ACYM_LIST_NAME');
122 195 $others['description'] = acym_translation('ACYM_LIST_DESCRIPTION');
123 196 $others['names'] = acym_translation('ACYM_LIST_NAMES');
@@ -123,53 +196,72 @@
123 196 $others['names'] = acym_translation('ACYM_LIST_NAMES');
124 197 $others['descriptions'] = acym_translation('ACYM_LIST_DESCRIPTIONS');
125 198 $others['id'] = acym_translation('ACYM_LIST_ID', true);
126 199
127 - $text .= '<div class="acym__popup__listing text-center grid-x">
128 - <h1 class="acym__title acym__title__secondary text-center cell">'.acym_translation('ACYM_LIST').'</h1>
129 - <div class="cell grid-x">';
200 + echo '<div class="acym__popup__listing text-center grid-x">
201 + <h1 class="acym__title acym__title__secondary text-center cell">'.esc_html(acym_translation('ACYM_LIST')).'</h1>
202 + <div class="cell grid-x">';
130 203
131 204 foreach ($others as $tagname => $tag) {
132 - $text .= '<div class="grid-x medium-12 cell acym__row__no-listing acym__listing__row__popup text-left" onclick="changeSubscriptionTag(\'list\');setTag(\'{list:'.$tagname.'}\', jQuery(this));" id="tr_'.$tagname.'">
133 - <div class="cell medium-12 small-12 acym__listing__title acym__listing__title__dynamics">'.$tag.'</div>
134 - </div>';
205 + echo '<div class="grid-x medium-12 cell acym__row__no-listing acym__listing__row__popup text-left" onclick="changeSubscriptionTag(\'list\');setTag(\'{list:'.esc_attr(
206 + $tagname
207 + ).'}\', jQuery(this));" id="tr_'.esc_attr($tagname).'">
208 + <div class="cell medium-12 small-12 acym__listing__title acym__listing__title__dynamics">'.esc_html($tag).'</div>
209 + </div>';
135 210 }
136 211
137 - $text .= '</div></div>';
212 + echo '</div></div>';
138 213
139 - $text .= '<div class="acym__popup__listing text-center grid-x">
140 - <span class="acym__title acym__title__secondary text-center cell">'.acym_translation('ACYM_CAMPAIGN').'</span>
141 - <div class="cell grid-x">';
214 + // Newsletter tags
215 + echo '<div class="acym__popup__listing text-center grid-x">
216 + <span class="acym__title acym__title__secondary text-center cell">'.esc_html(acym_translation('ACYM_CAMPAIGN')).'</span>
217 + <div class="cell grid-x">';
142 218 $othersMail = ['campaignid', 'subject'];
143 219
144 220 foreach ($othersMail as $tag) {
145 - $text .= '<div class="grid-x medium-12 cell acym__row__no-listing acym__listing__row__popup text-left" onclick="changeSubscriptionTag(\'mail\');setTag(\'{mail:'.$tag.'}\', jQuery(this));" id="tr_'.$tag.'">
146 - <div class="cell medium-12 small-12 acym__listing__title acym__listing__title__dynamics">'.$tag.'</div>
147 - </div>';
221 + echo '<div class="grid-x medium-12 cell acym__row__no-listing acym__listing__row__popup text-left" onclick="changeSubscriptionTag(\'mail\');setTag(\'{mail:'.esc_attr(
222 + $tag
223 + ).'}\', jQuery(this));" id="tr_'.esc_attr($tag).'">
224 + <div class="cell medium-12 small-12 acym__listing__title acym__listing__title__dynamics">'.esc_html($tag).'</div>
225 + </div>';
148 226 }
149 - $text .= '</div></div>';
227 + echo '</div></div>';
150 228
151 - $text .= '<div class="acym__popup__listing text-center grid-x">
152 - <span class="acym__title acym__title__secondary text-center cell">'.acym_translation('ACYM_AUTO').' '.acym_translation('ACYM_CAMPAIGNS').'</span>
153 - <div class="cell grid-x">';
154 - $autoMail = ['number_generated' => ['name' => acym_translation('ACYM_ISSUE_NB'), 'default' => '#1']];
229 + // Smart newsletter tags
230 + echo '<div class="acym__popup__listing text-center grid-x">
231 + <span class="acym__title acym__title__secondary text-center cell">'.esc_html(acym_translation('ACYM_AUTO').' '.acym_translation('ACYM_CAMPAIGNS')).'</span>
232 + <div class="cell grid-x">';
155 233
234 + $autoMail = [
235 + 'number_generated' => [
236 + 'name' => acym_translation('ACYM_ISSUE_NB'),
237 + 'default' => '#1',
238 + ],
239 + ];
240 +
156 241 foreach ($autoMail as $tag => $oneTag) {
157 242 $tagInserted = $tag;
158 - if (!empty($oneTag['default'])) $tagInserted = $tag.'|default:'.$oneTag['default'];
159 - $text .= '<div class="grid-x medium-12 cell acym__row__no-listing acym__listing__row__popup text-left" onclick="changeSubscriptionTag(\'automail\');setTag(\'{automail:'.$tagInserted.'}\', jQuery(this));" id="tr_'.$tag.'">
160 - <div class="cell medium-12 small-12 acym__listing__title acym__listing__title__dynamics">'.$oneTag['name'].'</div>
161 - </div>';
243 + if (!empty($oneTag['default'])) {
244 + $tagInserted = $tag.'|default:'.$oneTag['default'];
245 + }
246 +
247 + echo '<div class="grid-x medium-12 cell acym__row__no-listing acym__listing__row__popup text-left" onclick="changeSubscriptionTag(\'automail\');setTag(\'{automail:'.esc_attr(
248 + $tagInserted
249 + ).'}\', jQuery(this));" id="tr_'.esc_attr($tag).'">
250 + <div class="cell medium-12 small-12 acym__listing__title acym__listing__title__dynamics">'.esc_html($oneTag['name']).'</div>
251 + </div>';
162 252 }
163 - $text .= '</div></div>';
164 -
165 - echo $text;
253 + echo '</div></div>';
166 254 }
167 255
168 - public function replaceUserInformation(&$email, &$user, $send = true)
256 + public function replaceUserInformation(object &$email, ?object &$user, bool $send = true): void
169 257 {
170 - $this->_replacelisttags($email, $user, $send);
258 + if (empty($email->id)) {
259 + return;
260 + }
261 + $this->replacelisttags($email, $user, $send);
171 262
263 + // Check if we should add the List-Unsubscribe header
172 264 if (empty($user->id) || !empty($this->addedListUnsubscribe[$email->id][$user->id])) return;
173 265 if (empty($this->unsubscribeLink[$email->id]) || !method_exists($email, 'addCustomHeader')) return;
174 266
175 267
@@ -174,8 +266,9 @@
174 266
175 267
176 268 $this->addedListUnsubscribe[$email->id][$user->id] = true;
177 269
270 + // Prepare the mailto parameters for the header
178 271 $mailto = '';
179 272 if ($this->config->get('auto_bounce', 0)) {
180 273 $mailto = $this->config->get('bounce_email');
181 274 }
@@ -182,8 +275,9 @@
182 275 if (empty($mailto)) {
183 276 $mailto = empty($email->replyemail) ? $this->config->get('replyto_email') : $email->replyemail;
184 277 }
185 278
279 + // No bounce address, no reply-to address on the email or the configuration
186 280 if (empty($mailto)) {
187 281 return;
188 282 }
189 283
@@ -194,11 +288,12 @@
194 288 $lists = $mailClass->getAllListsByMailId($email->id);
195 289 $this->mailLists[$email->id] = empty($lists) ? null : array_keys($lists);
196 290 }
197 291
292 + // Make sure we unsubscribe from the correct lists and not all the lists
198 293 if (!empty($this->mailLists[$email->id])) {
199 294 $userClass = $this->getUserClass();
200 - $userLists = $userClass->getSubscriptionStatus($user->id, [], 1);
295 + $userLists = $userClass->getSubscriptionStatus($user->id, [], UserClass::STATUS_SUBSCRIBED);
201 296 if (!empty($userLists)) {
202 297 $commonLists = array_intersect($this->mailLists[$email->id], array_keys($userLists));
203 298
204 299 if (!empty($commonLists)) {
@@ -206,25 +301,25 @@
206 301 }
207 302 }
208 303 }
209 304
210 - $unsubscribeLink = str_replace(
305 + $unsubscribeLink = htmlspecialchars_decode(str_replace(
211 306 ['{subscriber:id}', '{subscriber:key|urlencode}'],
212 307 [$user->id, urlencode($user->key)],
213 308 $this->unsubscribeLink[$email->id]
214 - );
309 + ));
215 310 $email->addCustomHeader('List-Unsubscribe', '<'.$unsubscribeLink.'&ajax=1>, <mailto:'.$mailto.'?subject=unsubscribe_user_'.$user->id.'&body='.$body.'>');
216 311 $email->addCustomHeader('List-Unsubscribe-Post', 'List-Unsubscribe=One-Click');
217 312 }
218 313
219 - public function replaceContent(&$email, $send = true)
314 + public function replaceContent(object &$email): void
220 315 {
221 - $this->_replaceSubscriptionTags($email);
222 - $this->_replacemailtags($email);
316 + $this->replaceSubscriptionTags($email);
317 + $this->replacemailtags($email);
223 318 $this->replaceAutomailTags($email);
224 319 }
225 320
226 - private function _replacemailtags(&$email)
321 + private function replacemailtags(&$email)
227 322 {
228 323 $result = $this->pluginHelper->extractTags($email, 'mail');
229 324 $tags = [];
230 325
@@ -261,8 +356,9 @@
261 356 $tags[$key] = $oneTag->default;
262 357 }
263 358 }
264 359
360 + // Available tags: {automail:number_generated}
265 361 private function replaceAutomailTags(&$email)
266 362 {
267 363 $result = $this->pluginHelper->extractTags($email, 'automail');
268 364 $tags = [];
@@ -288,9 +384,10 @@
288 384
289 385 $this->pluginHelper->replaceTags($email, $tags);
290 386 }
291 387
292 - private function _replacelisttags(&$email, &$user, $send)
388 + //Available tags: {list:name} , {list:count} , {list:count|listid:0} (to count all users), {list:members}, {list:owner}
389 + private function replacelisttags(&$email, &$user, $send)
293 390 {
294 391 $tags = $this->pluginHelper->extractTags($email, 'list');
295 392 if (empty($tags)) {
296 393 return;
@@ -309,9 +406,9 @@
309 406
310 407 $this->pluginHelper->replaceTags($email, $replaceTags, true);
311 408 }
312 409
313 - private function _getAttachedListid($email, $subid)
410 + private function getAttachedListid($email, $subid)
314 411 {
315 412 $mailid = $email->id;
316 413
317 414 if (isset($this->lists[$mailid][$subid])) {
@@ -341,8 +438,9 @@
341 438 return $listid;
342 439 }
343 440 }
344 441
442 + //We could not find a list id there... maybe there is no subscription in which case we take the first one...
345 443 if (!empty($mailLists)) {
346 444 $this->lists[$mailid][$subid] = array_shift($mailLists);
347 445
348 446 return $this->lists[$mailid][$subid];
@@ -348,8 +446,9 @@
348 446 return $this->lists[$mailid][$subid];
349 447 }
350 448
351 449 if (!empty($subid) && !empty($email->type) && $email->type === MailClass::TYPE_WELCOME) {
450 + //Last list the user subscribed to...
352 451 $listid = acym_loadResult(
353 452 'SELECT list.id
354 453 FROM #__acym_list AS list
355 454 JOIN #__acym_user_has_list AS userlist ON list.id = userlist.list_id
@@ -363,8 +462,9 @@
363 462 }
364 463 }
365 464
366 465 if (!empty($subid) && !empty($email->type) && $email->type === MailClass::TYPE_UNSUBSCRIBE) {
466 + //Last list the user unsubscribed from...
367 467 $listid = acym_loadResult(
368 468 'SELECT list.id
369 469 FROM #__acym_list AS list
370 470 JOIN #__acym_user_has_list AS userlist ON list.id = userlist.list_id
@@ -377,8 +477,9 @@
377 477 return $listid;
378 478 }
379 479 }
380 480
481 + //Still no list? well, lets load the first list the user is subscribed to then
381 482 if (!empty($userLists)) {
382 483 $listIds = array_keys($userLists);
383 484 $this->lists[$mailid][$subid] = array_shift($listIds);
384 485
@@ -406,8 +507,12 @@
406 507
407 508 return implode(isset($parameter->separator) ? $parameter->separator : ', ', $lists);
408 509 }
409 510
511 + /**
512 + * Replace data about the list owner
513 + * Use the tag: {list:owner|field:name} or {list:owner|field:username} or {list:owner|field:email}
514 + */
410 515 private function listowner(&$email, &$user, &$parameter)
411 516 {
412 517 if (empty($user->id)) {
413 518 return '';
@@ -416,9 +521,9 @@
416 521 if (!in_array($parameter->field, ['username', 'name', 'email'])) {
417 522 return 'Field not found : '.$parameter->field;
418 523 }
419 524
420 - $listid = $this->_getAttachedListid($email, $user->id);
525 + $listid = $this->getAttachedListid($email, $user->id);
421 526 if (empty($listid)) {
422 527 return '';
423 528 }
424 529
@@ -439,14 +544,14 @@
439 544 {
440 545 if (empty($user->id)) {
441 546 return '';
442 547 }
443 - $listid = $this->_getAttachedListid($email, $user->id);
548 + $listid = $this->getAttachedListid($email, $user->id);
444 549 if (empty($listid)) {
445 550 return '';
446 551 }
447 552
448 - $this->_loadlist($listid);
553 + $this->loadlist($listid);
449 554
450 555 return !empty($this->listsinfo[$listid]->display_name) ? $this->listsinfo[$listid]->display_name : @$this->listsinfo[$listid]->name;
451 556 }
452 557
@@ -455,19 +560,19 @@
455 560 if (empty($user->id)) {
456 561 return '';
457 562 }
458 563 if (!empty($parameter->listid)) $listid = $parameter->listid;
459 - if (empty($listid)) $listid = $this->_getAttachedListid($email, $user->id);
564 + if (empty($listid)) $listid = $this->getAttachedListid($email, $user->id);
460 565 if (empty($listid)) {
461 566 return '';
462 567 }
463 568
464 - $this->_loadlist($listid);
569 + $this->loadlist($listid);
465 570
466 571 return @$this->listsinfo[$listid]->description;
467 572 }
468 573
469 - private function _loadlist($listid)
574 + private function loadlist($listid)
470 575 {
471 576 if (isset($this->listsinfo[$listid])) {
472 577 return;
473 578 }
@@ -501,9 +606,9 @@
501 606 {
502 607 if (empty($user->id)) {
503 608 return '';
504 609 }
505 - $listid = $this->_getAttachedListid($email, $user->id);
610 + $listid = $this->getAttachedListid($email, $user->id);
506 611 if (empty($listid)) {
507 612 return '';
508 613 }
509 614
@@ -509,11 +614,11 @@
509 614
510 615 return $listid;
511 616 }
512 617
513 - private function _replaceSubscriptionTags(&$email)
618 + private function replaceSubscriptionTags(&$email)
514 619 {
515 - $match = '#(?:{|%7B)(confirm|unsubscribe(?:\|[^}]+)*|unsubscribeall|subscribe(?:\|[^}]+)*)(?:}|%7D)(.*)(?:{|%7B)/(confirm|unsubscribe|unsubscribeall|subscribe)(?:}|%7D)#Uis';
620 + $match = '#(?:{|%7B)(confirm|unsubscribe(?:\|[^}]+)*|unsubscribeall(?:\|[^}]+)*|direct_unsubscribe(?:\|[^}]+)*|disable_tracking(?:\|[^}]+)*|subscribe(?:\|[^}]+)*)(?:}|%7D)(.*)(?:{|%7B)/(confirm|unsubscribe|direct_unsubscribe|unsubscribeall|disable_tracking|subscribe)(?:}|%7D)#Uis';
516 621 $variables = ['subject', 'body'];
517 622 $found = false;
518 623 $results = [];
519 624 foreach ($variables as $var) {
@@ -519,11 +624,13 @@
519 624 foreach ($variables as $var) {
520 625 if (empty($email->$var)) continue;
521 626
522 627 $found = preg_match_all($match, $email->$var, $results[$var]) || $found;
628 + //we unset the results so that we won't handle it later... it will save some memory and processing
523 629 if (empty($results[$var][0])) unset($results[$var]);
524 630 }
525 631
632 + //If we didn't find anything...
526 633 if (!$found) return;
527 634
528 635 $tags = [];
529 636 $this->addedListUnsubscribe[$email->id] = [];
@@ -528,11 +635,12 @@
528 635 $tags = [];
529 636 $this->addedListUnsubscribe[$email->id] = [];
530 637 foreach ($results as $var => $allresults) {
531 638 foreach ($allresults[0] as $i => $oneTag) {
639 + //Don't need to process twice a tag we already have!
532 640 if (isset($tags[$oneTag])) continue;
533 641
534 - $tags[$oneTag] = $this->_replaceSubscriptionTag($allresults, $i, $email);
642 + $tags[$oneTag] = $this->replaceSubscriptionTag($allresults, $i, $email);
535 643 }
536 644 }
537 645
538 646 $this->pluginHelper->replaceTags($email, $tags);
@@ -537,9 +645,9 @@
537 645
538 646 $this->pluginHelper->replaceTags($email, $tags);
539 647 }
540 648
541 - private function _replaceSubscriptionTag(&$allresults, $i, &$email)
649 + private function replaceSubscriptionTag(&$allresults, $i, &$email)
542 650 {
543 651 $parameters = $this->pluginHelper->extractTag($allresults[1][$i]);
544 652
545 653 $lang = $this->getLanguage($email->links_language);
@@ -544,8 +652,9 @@
544 652
545 653 $lang = $this->getLanguage($email->links_language);
546 654
547 655 if ($parameters->id === 'confirm') {
656 + // subscription confirmation link
548 657 $myLink = acym_frontendLink('frontusers&task=confirm&userId={subscriber:id}&userKey={subscriber:key|urlencode}'.$lang);
549 658 if (empty($allresults[2][$i])) {
550 659 return $myLink;
551 660 }
@@ -551,8 +660,9 @@
551 660 }
552 661
553 662 return '<a target="_blank" href="'.$myLink.'"><span class="acym_confirm acym_link">'.$allresults[2][$i].'</span></a>';
554 663 } elseif ($parameters->id === 'subscribe') {
664 + // direct subscription link
555 665 if (empty($parameters->lists)) {
556 666 return acym_translation('ACYM_EXPORT_SELECT_LIST');
557 667 }
558 668 $lists = explode(',', $parameters->lists);
@@ -565,13 +675,48 @@
565 675 return $myLink;
566 676 }
567 677
568 678 return '<a style="text-decoration:none;" target="_blank" href="'.$myLink.'"><span class="acym_subscribe acym_link">'.$allresults[2][$i].'</span></a>';
679 + } elseif ($parameters->id === 'direct_unsubscribe') {
680 + $mailId = $email->id;
681 + $myLink = acym_frontendLink(
682 + 'frontusers&task=unsubscribe'
683 + .'&userId={subscriber:id}'
684 + .'&userKey={subscriber:key|urlencode}'
685 + .'&direct=1'
686 + .'&mail_id='.$mailId
687 + .$lang
688 + );
689 + if (!empty($parameters->redirect)) {
690 + $myLink .= '&redirectunsub='.urlencode($parameters->redirect);
691 + }
692 +
693 + if (empty($allresults[2][$i])) {
694 + return $myLink;
695 + }
696 +
697 + return '<a style="text-decoration:none;" target="_blank" href="'.$myLink.'"><span class="acym_unsubscribe_direct acym_link">'.$allresults[2][$i].'</span></a>';
698 + } elseif ($parameters->id === 'disable_tracking') {
699 + $myLink = acym_frontendLink(
700 + 'frontusers&task=disableTracking'
701 + .'&userId={subscriber:id}'
702 + .'&userKey={subscriber:key|urlencode}'
703 + .'&mail_id='.$email->id
704 + .$lang
705 + );
706 +
707 + if (empty($allresults[2][$i])) {
708 + return $myLink;
709 + }
710 +
711 + return '<a style="text-decoration:none;" target="_blank" href="'.$myLink.'"><span class="acym_disable_tracking acym_link">'.$allresults[2][$i].'</span></a>';
569 712 } else {
570 713 $baseLink = 'frontusers'.$lang.'&mail_id='.$email->id;
571 714 if ($parameters->id === 'unsubscribe') {
572 715 $unsubscribeLink = $baseLink.'&task=unsubscribe&userId={subscriber:id}&userKey={subscriber:key|urlencode}';
573 - $unsubscribeLink .= '&'.acym_noTemplate();
716 + if (ACYM_CMS !== 'wordpress') {
717 + $unsubscribeLink .= '&'.acym_noTemplate();
718 + }
574 719 $unsubClass = 'acym_unsubscribe';
575 720 } else {
576 721 $unsubscribeLink = $baseLink.'&task=unsubscribeAll&user_id={subscriber:id}&user_key={subscriber:key|urlencode}';
577 722 $unsubClass = 'acym_unsubscribe_all_lists';
@@ -583,8 +728,12 @@
583 728 $needToCompleteLink = false;
584 729 }
585 730
586 731 $unsubscribeLink = acym_frontendLink($unsubscribeLink, $needToCompleteLink);
732 +
733 + if ($parameters->id === 'unsubscribeall' && !empty($parameters->redirect)) {
734 + $unsubscribeLink .= (strpos($unsubscribeLink, '?') === false ? '?' : '&').'redirectunsub='.urlencode($parameters->redirect);
735 + }
587 736
588 737 $this->unsubscribeLink[$email->id] = $unsubscribeLink;
589 738
590 739 if (empty($allresults[2][$i])) {