← 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])) { |