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 +248 -100 10.0.1 → 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,54 +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
172 - if ($this->config->get('unsubscribe_header', 1) == 0) return;
263 + // Check if we should add the List-Unsubscribe header
173 264 if (empty($user->id) || !empty($this->addedListUnsubscribe[$email->id][$user->id])) return;
174 265 if (empty($this->unsubscribeLink[$email->id]) || !method_exists($email, 'addCustomHeader')) return;
175 266
176 267
@@ -175,8 +266,9 @@
175 266
176 267
177 268 $this->addedListUnsubscribe[$email->id][$user->id] = true;
178 269
270 + // Prepare the mailto parameters for the header
179 271 $mailto = '';
180 272 if ($this->config->get('auto_bounce', 0)) {
181 273 $mailto = $this->config->get('bounce_email');
182 274 }
@@ -183,8 +275,9 @@
183 275 if (empty($mailto)) {
184 276 $mailto = empty($email->replyemail) ? $this->config->get('replyto_email') : $email->replyemail;
185 277 }
186 278
279 + // No bounce address, no reply-to address on the email or the configuration
187 280 if (empty($mailto)) {
188 281 return;
189 282 }
190 283
@@ -195,11 +288,12 @@
195 288 $lists = $mailClass->getAllListsByMailId($email->id);
196 289 $this->mailLists[$email->id] = empty($lists) ? null : array_keys($lists);
197 290 }
198 291
292 + // Make sure we unsubscribe from the correct lists and not all the lists
199 293 if (!empty($this->mailLists[$email->id])) {
200 294 $userClass = $this->getUserClass();
201 - $userLists = $userClass->getSubscriptionStatus($user->id, [], 1);
295 + $userLists = $userClass->getSubscriptionStatus($user->id, [], UserClass::STATUS_SUBSCRIBED);
202 296 if (!empty($userLists)) {
203 297 $commonLists = array_intersect($this->mailLists[$email->id], array_keys($userLists));
204 298
205 299 if (!empty($commonLists)) {
@@ -207,25 +301,25 @@
207 301 }
208 302 }
209 303 }
210 304
211 - $unsubscribeLink = str_replace(
305 + $unsubscribeLink = htmlspecialchars_decode(str_replace(
212 306 ['{subscriber:id}', '{subscriber:key|urlencode}'],
213 307 [$user->id, urlencode($user->key)],
214 308 $this->unsubscribeLink[$email->id]
215 - );
309 + ));
216 310 $email->addCustomHeader('List-Unsubscribe', '<'.$unsubscribeLink.'&ajax=1>, <mailto:'.$mailto.'?subject=unsubscribe_user_'.$user->id.'&body='.$body.'>');
217 311 $email->addCustomHeader('List-Unsubscribe-Post', 'List-Unsubscribe=One-Click');
218 312 }
219 313
220 - public function replaceContent(&$email, $send = true)
314 + public function replaceContent(object &$email): void
221 315 {
222 - $this->_replaceSubscriptionTags($email);
223 - $this->_replacemailtags($email);
316 + $this->replaceSubscriptionTags($email);
317 + $this->replacemailtags($email);
224 318 $this->replaceAutomailTags($email);
225 319 }
226 320
227 - private function _replacemailtags(&$email)
321 + private function replacemailtags(&$email)
228 322 {
229 323 $result = $this->pluginHelper->extractTags($email, 'mail');
230 324 $tags = [];
231 325
@@ -262,8 +356,9 @@
262 356 $tags[$key] = $oneTag->default;
263 357 }
264 358 }
265 359
360 + // Available tags: {automail:number_generated}
266 361 private function replaceAutomailTags(&$email)
267 362 {
268 363 $result = $this->pluginHelper->extractTags($email, 'automail');
269 364 $tags = [];
@@ -289,9 +384,10 @@
289 384
290 385 $this->pluginHelper->replaceTags($email, $tags);
291 386 }
292 387
293 - 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)
294 390 {
295 391 $tags = $this->pluginHelper->extractTags($email, 'list');
296 392 if (empty($tags)) {
297 393 return;
@@ -310,9 +406,9 @@
310 406
311 407 $this->pluginHelper->replaceTags($email, $replaceTags, true);
312 408 }
313 409
314 - private function _getAttachedListid($email, $subid)
410 + private function getAttachedListid($email, $subid)
315 411 {
316 412 $mailid = $email->id;
317 413
318 414 if (isset($this->lists[$mailid][$subid])) {
@@ -342,8 +438,9 @@
342 438 return $listid;
343 439 }
344 440 }
345 441
442 + //We could not find a list id there... maybe there is no subscription in which case we take the first one...
346 443 if (!empty($mailLists)) {
347 444 $this->lists[$mailid][$subid] = array_shift($mailLists);
348 445
349 446 return $this->lists[$mailid][$subid];
@@ -349,8 +446,9 @@
349 446 return $this->lists[$mailid][$subid];
350 447 }
351 448
352 449 if (!empty($subid) && !empty($email->type) && $email->type === MailClass::TYPE_WELCOME) {
450 + //Last list the user subscribed to...
353 451 $listid = acym_loadResult(
354 452 'SELECT list.id
355 453 FROM #__acym_list AS list
356 454 JOIN #__acym_user_has_list AS userlist ON list.id = userlist.list_id
@@ -364,8 +462,9 @@
364 462 }
365 463 }
366 464
367 465 if (!empty($subid) && !empty($email->type) && $email->type === MailClass::TYPE_UNSUBSCRIBE) {
466 + //Last list the user unsubscribed from...
368 467 $listid = acym_loadResult(
369 468 'SELECT list.id
370 469 FROM #__acym_list AS list
371 470 JOIN #__acym_user_has_list AS userlist ON list.id = userlist.list_id
@@ -378,8 +477,9 @@
378 477 return $listid;
379 478 }
380 479 }
381 480
481 + //Still no list? well, lets load the first list the user is subscribed to then
382 482 if (!empty($userLists)) {
383 483 $listIds = array_keys($userLists);
384 484 $this->lists[$mailid][$subid] = array_shift($listIds);
385 485
@@ -407,31 +507,37 @@
407 507
408 508 return implode(isset($parameter->separator) ? $parameter->separator : ', ', $lists);
409 509 }
410 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 + */
411 515 private function listowner(&$email, &$user, &$parameter)
412 516 {
413 517 if (empty($user->id)) {
414 518 return '';
415 519 }
416 - $listid = $this->_getAttachedListid($email, $user->id);
520 +
521 + if (!in_array($parameter->field, ['username', 'name', 'email'])) {
522 + return 'Field not found : '.$parameter->field;
523 + }
524 +
525 + $listid = $this->getAttachedListid($email, $user->id);
417 526 if (empty($listid)) {
418 - return "";
527 + return '';
419 528 }
420 529
421 530 global $acymCmsUserVars;
422 531 if (!isset($this->listsowner[$listid])) {
423 532 $this->listsowner[$listid] = acym_loadObject(
424 - 'SELECT user.* FROM #__acym_list AS list JOIN '.$acymCmsUserVars->table.' AS user ON user.'.$acymCmsUserVars->id.' = list.cms_user_id WHERE list.id = '.intval(
425 - $listid
426 - )
533 + 'SELECT `user`.* FROM #__acym_list AS `list`
534 + JOIN '.$acymCmsUserVars->table.' AS `user`
535 + ON `user`.'.$acymCmsUserVars->id.' = `list`.cms_user_id
536 + WHERE `list`.id = '.intval($listid)
427 537 );
428 538 }
429 539
430 - if (!in_array($parameter->field, [$acymCmsUserVars->username, $acymCmsUserVars->name, $acymCmsUserVars->email])) {
431 - return 'Field not found : '.$parameter->field;
432 - }
433 -
434 540 return @$this->listsowner[$listid]->{$acymCmsUserVars->{$parameter->field}};
435 541 }
436 542
437 543 private function listname(&$email, &$user, &$parameter)
@@ -438,14 +544,14 @@
438 544 {
439 545 if (empty($user->id)) {
440 546 return '';
441 547 }
442 - $listid = $this->_getAttachedListid($email, $user->id);
548 + $listid = $this->getAttachedListid($email, $user->id);
443 549 if (empty($listid)) {
444 550 return '';
445 551 }
446 552
447 - $this->_loadlist($listid);
553 + $this->loadlist($listid);
448 554
449 555 return !empty($this->listsinfo[$listid]->display_name) ? $this->listsinfo[$listid]->display_name : @$this->listsinfo[$listid]->name;
450 556 }
451 557
@@ -454,19 +560,19 @@
454 560 if (empty($user->id)) {
455 561 return '';
456 562 }
457 563 if (!empty($parameter->listid)) $listid = $parameter->listid;
458 - if (empty($listid)) $listid = $this->_getAttachedListid($email, $user->id);
564 + if (empty($listid)) $listid = $this->getAttachedListid($email, $user->id);
459 565 if (empty($listid)) {
460 566 return '';
461 567 }
462 568
463 - $this->_loadlist($listid);
569 + $this->loadlist($listid);
464 570
465 571 return @$this->listsinfo[$listid]->description;
466 572 }
467 573
468 - private function _loadlist($listid)
574 + private function loadlist($listid)
469 575 {
470 576 if (isset($this->listsinfo[$listid])) {
471 577 return;
472 578 }
@@ -500,9 +606,9 @@
500 606 {
501 607 if (empty($user->id)) {
502 608 return '';
503 609 }
504 - $listid = $this->_getAttachedListid($email, $user->id);
610 + $listid = $this->getAttachedListid($email, $user->id);
505 611 if (empty($listid)) {
506 612 return '';
507 613 }
508 614
@@ -508,11 +614,11 @@
508 614
509 615 return $listid;
510 616 }
511 617
512 - private function _replaceSubscriptionTags(&$email)
618 + private function replaceSubscriptionTags(&$email)
513 619 {
514 - $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';
515 621 $variables = ['subject', 'body'];
516 622 $found = false;
517 623 $results = [];
518 624 foreach ($variables as $var) {
@@ -518,11 +624,13 @@
518 624 foreach ($variables as $var) {
519 625 if (empty($email->$var)) continue;
520 626
521 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
522 629 if (empty($results[$var][0])) unset($results[$var]);
523 630 }
524 631
632 + //If we didn't find anything...
525 633 if (!$found) return;
526 634
527 635 $tags = [];
528 636 $this->addedListUnsubscribe[$email->id] = [];
@@ -527,11 +635,12 @@
527 635 $tags = [];
528 636 $this->addedListUnsubscribe[$email->id] = [];
529 637 foreach ($results as $var => $allresults) {
530 638 foreach ($allresults[0] as $i => $oneTag) {
639 + //Don't need to process twice a tag we already have!
531 640 if (isset($tags[$oneTag])) continue;
532 641
533 - $tags[$oneTag] = $this->_replaceSubscriptionTag($allresults, $i, $email);
642 + $tags[$oneTag] = $this->replaceSubscriptionTag($allresults, $i, $email);
534 643 }
535 644 }
536 645
537 646 $this->pluginHelper->replaceTags($email, $tags);
@@ -536,9 +645,9 @@
536 645
537 646 $this->pluginHelper->replaceTags($email, $tags);
538 647 }
539 648
540 - private function _replaceSubscriptionTag(&$allresults, $i, &$email)
649 + private function replaceSubscriptionTag(&$allresults, $i, &$email)
541 650 {
542 651 $parameters = $this->pluginHelper->extractTag($allresults[1][$i]);
543 652
544 653 $lang = $this->getLanguage($email->links_language);
@@ -543,8 +652,9 @@
543 652
544 653 $lang = $this->getLanguage($email->links_language);
545 654
546 655 if ($parameters->id === 'confirm') {
656 + // subscription confirmation link
547 657 $myLink = acym_frontendLink('frontusers&task=confirm&userId={subscriber:id}&userKey={subscriber:key|urlencode}'.$lang);
548 658 if (empty($allresults[2][$i])) {
549 659 return $myLink;
550 660 }
@@ -550,8 +660,9 @@
550 660 }
551 661
552 662 return '<a target="_blank" href="'.$myLink.'"><span class="acym_confirm acym_link">'.$allresults[2][$i].'</span></a>';
553 663 } elseif ($parameters->id === 'subscribe') {
664 + // direct subscription link
554 665 if (empty($parameters->lists)) {
555 666 return acym_translation('ACYM_EXPORT_SELECT_LIST');
556 667 }
557 668 $lists = explode(',', $parameters->lists);
@@ -564,13 +675,46 @@
564 675 return $myLink;
565 676 }
566 677
567 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>';
568 712 } else {
569 713 $baseLink = 'frontusers'.$lang.'&mail_id='.$email->id;
570 714 if ($parameters->id === 'unsubscribe') {
571 715 $unsubscribeLink = $baseLink.'&task=unsubscribe&userId={subscriber:id}&userKey={subscriber:key|urlencode}';
572 - if ($this->config->get('unsubpage_header') != 1) {
716 + if (ACYM_CMS !== 'wordpress') {
573 717 $unsubscribeLink .= '&'.acym_noTemplate();
574 718 }
575 719 $unsubClass = 'acym_unsubscribe';
576 720 } else {
@@ -584,8 +728,12 @@
584 728 $needToCompleteLink = false;
585 729 }
586 730
587 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 + }
588 736
589 737 $this->unsubscribeLink[$email->id] = $unsubscribeLink;
590 738
591 739 if (empty($allresults[2][$i])) {