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/acymailer/plugin.php +199 -122 10.11.1 → 11.1.0 View file →
@@ -52,28 +52,36 @@
52 52 parent::__construct();
53 53 $this->pluginDescription->name = self::SENDING_METHOD_NAME;
54 54 }
55 55
56 - protected function callApiSendingMethod(string $url, array $data = [], array $headers = [], string $type = 'GET', array $authentication = [], bool $dataDecoded = false): array
57 - {
56 + protected function callApiSendingMethod(
57 + string $url,
58 + array $data = [],
59 + array $headers = [],
60 + string $type = 'GET',
61 + array $authentication = [],
62 + bool $dataDecoded = false,
63 + array $files = []
64 + ): array {
58 65 if (strpos($url, self::SENDING_METHOD_API_URL) === false) {
59 66 $url = self::SENDING_METHOD_API_URL.'api/'.$url;
60 67 }
61 68
62 69 $defaultHeaders = [
63 - 'accept' => 'application/json',
64 - 'content-type' => 'application/json',
70 + 'Accept' => 'application/json',
71 + 'Content-Type' => 'application/json',
65 72 'API-KEY' => $this->config->get(self::SENDING_METHOD_ID.'_apikey', ''),
66 73 'Version' => $this->config->get('version'),
67 74 ];
68 75
76 + $usedHeaders = array_map('strtolower', array_keys($headers));
69 77 foreach ($defaultHeaders as $key => $value) {
70 - if (!isset($headers[$key])) {
78 + if (!in_array(strtolower($key), $usedHeaders, true)) {
71 79 $headers[$key] = $value;
72 80 }
73 81 }
74 82
75 - $result = parent::callApiSendingMethod($url, $data, $headers, $type, $authentication, $dataDecoded);
83 + $result = parent::callApiSendingMethod($url, $data, $headers, $type, $authentication, $dataDecoded, $files);
76 84 if (!empty($result['error_curl'])) {
77 85 $result['message'] = $result['error_curl'];
78 86 $this->errors[] = $result['error_curl'];
79 87 $this->errorCallback();
@@ -106,14 +114,14 @@
106 114 ?>
107 115 <div class="grid-x grid-margin-x margin-top-1" id="activate_ass_method_notice">
108 116 <label class="cell medium-7 acym_vcenter">
109 117 <i class="acymicon-info-circle" id="acymailer_info_icon"></i>
110 - <?php echo acym_translation('ACYM_ACTIVATE_ACYMAILER'); ?>
118 + <?php echo esc_html(acym_translation('ACYM_ACTIVATE_ACYMAILER')); ?>
111 119 </label>
112 120 <button type="button"
113 - id="acym__configuration__activate__acymailer"
114 - class="cell shrink button margin-bottom-0">
115 - <?php echo acym_translation('ACYM_SEE_THE_SENDING_METHOD'); ?>
121 + id="acym__configuration__activate__acymailer"
122 + class="cell shrink button margin-bottom-0">
123 + <?php echo esc_html(acym_translation('ACYM_SEE_THE_SENDING_METHOD')); ?>
116 124 </button>
117 125 </div>
118 126 <?php
119 127 }
@@ -131,24 +139,22 @@
131 139 });
132 140 }
133 141
134 142 $unverifiedDomains = $this->getDomainsUnVerified();
135 -
136 - ob_start();
137 143 ?>
138 - <div class="send_settings cell grid-x acym_vcenter" id="<?php echo self::SENDING_METHOD_ID; ?>_settings">
144 + <div class="send_settings cell grid-x acym_vcenter" id="<?php echo esc_attr(self::SENDING_METHOD_ID); ?>_settings">
139 145 <div class="cell grid-x acym__sending__methods__one__settings <?php echo empty($data['step']) ? 'xlarge-10 xxlarge-8' : ''; ?>">
140 146 <?php if (!acym_level(ACYM_ESSENTIAL) && empty($data['step'])) { ?>
141 147 <div class="acym_vcenter acym__config__acymailer__warning margin-top-1 cell grid-x large-8 xlarge-6 xxlarge-5">
142 148 <label for="acym__configuration__license-key" class="cell">
143 - <?php echo acym_translation('ACYM_YOUR_LICENSE_KEY'); ?>
149 + <?php echo esc_html(acym_translation('ACYM_YOUR_LICENSE_KEY')); ?>
144 150 </label>
145 - <input type="text" name="config[license_key]" id="acym__configuration__license-key" class="cell auto" value="<?php echo acym_escape($licenseKey); ?>">
151 + <input type="text" name="config[license_key]" id="acym__configuration__license-key" class="cell auto" value="<?php echo esc_attr($licenseKey); ?>">
146 152 <button type="button"
147 - id="acym__configuration__button__license"
148 - class="cell shrink medium-3 button margin-top-1 medium-margin-top-0 medium-margin-left-1"
149 - data-acym-linked="<?php echo empty($licenseKey) ? 0 : 1; ?>">
150 - <?php echo acym_translation(empty($licenseKey) ? 'ACYM_ATTACH_MY_LICENSE' : 'ACYM_UNLINK_MY_LICENSE'); ?>
153 + id="acym__configuration__button__license"
154 + class="cell shrink medium-3 button margin-top-1 medium-margin-top-0 medium-margin-left-1"
155 + data-acym-linked="<?php echo empty($licenseKey) ? 0 : 1; ?>">
156 + <?php echo esc_html(acym_translation(empty($licenseKey) ? 'ACYM_ATTACH_MY_LICENSE' : 'ACYM_UNLINK_MY_LICENSE')); ?>
151 157 </button>
152 158 </div>
153 159 <?php }
154 160 if (empty($licenseKey)) { ?>
@@ -156,11 +162,11 @@
156 162 <i class="acymicon-exclamation-triangle acym__color__orange"></i>
157 163 <span class="margin-right-1">
158 164 <?php
159 165 $pricingPage = ACYM_ACYMAILING_WEBSITE.'pricing?utm_source=acymailing_plugin&utm_medium=sendingmethod&utm_campaign=purchase';
160 - echo acym_translation(acym_level(ACYM_ESSENTIAL) ? 'ACYM_NO_LICENSE' : 'ACYM_NO_LICENSE_STARTER');
166 + echo esc_html(acym_translation(acym_level(ACYM_ESSENTIAL) ? 'ACYM_NO_LICENSE' : 'ACYM_NO_LICENSE_STARTER'));
161 167 ?>
162 - <a target="_blank" href="<?php echo $pricingPage; ?>"><?php echo acym_translation('ACYM_GET_A_LICENSE'); ?></a>
168 + <a target="_blank" href="<?php echo esc_url($pricingPage); ?>"><?php echo esc_html(acym_translation('ACYM_GET_A_LICENSE')); ?></a>
163 169 </span>
164 170 </div>
165 171 <?php } elseif (empty($acyMailerKey)) { ?>
166 172 <div class="cell acym_vcenter acym__config__acymailer__warning margin-top-1">
@@ -167,21 +173,23 @@
167 173 <i class="acymicon-exclamation-triangle acym__color__orange"></i>
168 174 <span>
169 175 <?php
170 176 $subscriptionsPage = ACYM_ACYMAILING_WEBSITE.'account/license?utm_source=acymailing_plugin&utm_medium=sendingmethod&utm_campaign=purchase';
171 - echo acym_translation('ACYM_API_KEY_NOT_ALLOWING_METHOD');
177 + echo esc_html(acym_translation('ACYM_API_KEY_NOT_ALLOWING_METHOD'));
172 178 ?>
173 - <a target="_blank" href="<?php echo $subscriptionsPage; ?>"><?php echo acym_translation('ACYM_SWITCH_MY_LICENSE'); ?></a>
179 + <a target="_blank" href="<?php echo esc_url($subscriptionsPage); ?>"><?php echo esc_html(
180 + acym_translation('ACYM_SWITCH_MY_LICENSE')
181 + ); ?></a>
174 182 </span>
175 183 </div>
176 184
177 185 <div class="acym__configuration__acymailer__check-license cell grid-x">
178 - <div class="cell"><?php echo acym_translation('ACYM_CHECK_SENDING_SERVICE_LICENSE'); ?></div>
186 + <div class="cell"><?php echo esc_html(acym_translation('ACYM_CHECK_SENDING_SERVICE_LICENSE')); ?></div>
179 187 <button
180 188 data-task="attachLicenseAcymailer"
181 189 id="acym__configuration__acymailer__verify-license"
182 190 class="cell medium-shrink button margin-left-0 margin-top-1 acy_button_submit">
183 - <?php echo acym_translation('ACYM_CHECK_LICENSE'); ?>
191 + <?php echo esc_html(acym_translation('ACYM_CHECK_LICENSE')); ?>
184 192 </button>
185 193 </div>
186 194 <?php } else { ?>
187 195 <div class="cell grid-x">
@@ -188,22 +196,24 @@
188 196 <?php if (!empty($domainsWaiting)) { ?>
189 197 <div class="cell <?php echo empty($data['step']) ? 'large-8' : ''; ?> grid-x acym_vcenter acym__config__acymailer__warning">
190 198 <i class="cell small-2 margin-right-0 acymicon-access-time acym__color__orange"></i>
191 199 <div class="cell small-10 grid-x">
192 - <span class="cell"><?php echo acym_translation('ACYM_DOMAINS_WAITING_VALIDATION_ADD_CNAME'); ?></span>
193 - <a href="<?php echo ACYM_DOCUMENTATION; ?>external-sending-method/acymailing-sending-service#how-to-add-the-dns-entries-on-my-server"
200 + <span class="cell"><?php echo esc_html(acym_translation('ACYM_DOMAINS_WAITING_VALIDATION_ADD_CNAME')); ?></span>
201 + <a href="<?php echo esc_url(
202 + ACYM_DOCUMENTATION
203 + ); ?>external-sending-method/acymailing-sending-service#how-to-add-the-dns-entries-on-my-server"
194 204 target="_blank"
195 205 class="cell">
196 - <?php echo acym_translation('ACYM_CHECK_THIS_TUTORIAL'); ?>
206 + <?php echo esc_html(acym_translation('ACYM_CHECK_THIS_TUTORIAL')); ?>
197 207 </a>
198 208 </div>
199 209 </div>
200 210 <div class="cell <?php echo empty($data['step']) ? 'large-4' : ''; ?> margin-top-1 margin-bottom-1">
201 211 <button id="acym__config__acymailer__update-domain-status"
202 - type="button"
203 - class="button button-secondary float-right"
204 - sending-method-id="<?php echo self::SENDING_METHOD_ID; ?>">
205 - <i class="acymicon-autorenew"></i><?php echo acym_translation('ACYM_UPDATE_DOMAIN_STATUS'); ?>
212 + type="button"
213 + class="button button-secondary float-right"
214 + sending-method-id="<?php echo esc_attr(self::SENDING_METHOD_ID); ?>">
215 + <i class="acymicon-autorenew"></i><?php echo esc_html(acym_translation('ACYM_UPDATE_DOMAIN_STATUS')); ?>
206 216 </button>
207 217 </div>
208 218 <?php } ?>
209 219 </div>
@@ -210,27 +220,29 @@
210 220 <div class="grid-x acym__listing cell">
211 221 <div class="grid-x cell acym__listing__header">
212 222 <div class="grid-x medium-auto small-11 cell acym__listing__header__title__container">
213 223 <div class="cell small-8 medium-auto acym__listing__header__title">
214 - <?php echo acym_translation('ACYM_DOMAIN_NAME'); ?>
224 + <?php echo esc_html(acym_translation('ACYM_DOMAIN_NAME')); ?>
215 225 </div>
216 226 <div class="cell hide-for-small-only medium-2 acym__listing__header__title text-center">
217 - <?php echo acym_translation('ACYM_STATUS'); ?>
227 + <?php echo esc_html(acym_translation('ACYM_STATUS')); ?>
218 228 </div>
219 229 <div class="cell hide-for-small-only medium-2 acym__listing__header__title text-center">
220 - <?php echo acym_translation('ACYM_BOUNCE_RATE').acym_info(['textShownInTooltip' => 'ACYM_BOUNCE_RATE_DESC']); ?>
230 + <?php echo esc_html(acym_translation('ACYM_BOUNCE_RATE'));
231 + acym_info(['textShownInTooltip' => 'ACYM_BOUNCE_RATE_DESC']); ?>
221 232 </div>
222 233 <div class="cell hide-for-small-only medium-2 acym__listing__header__title text-center">
223 - <?php echo acym_translation('ACYM_COMPLAINT_RATE').acym_info(['textShownInTooltip' => 'ACYM_COMPLAINT_RATE_DESC']); ?>
234 + <?php echo esc_html(acym_translation('ACYM_COMPLAINT_RATE'));
235 + acym_info(['textShownInTooltip' => 'ACYM_COMPLAINT_RATE_DESC']); ?>
224 236 </div>
225 237 <div class="cell small-4 medium-2 acym__listing__header__title text-center">
226 - <?php echo acym_translation('ACYM_ACTIONS'); ?>
238 + <?php echo esc_html(acym_translation('ACYM_ACTIONS')); ?>
227 239 </div>
228 240 </div>
229 241 </div>
230 242 <?php if (empty($domains)) { ?>
231 243 <div class="grid-x cell margin-top-1 align-center">
232 - <?php echo acym_translation('ACYM_NO_DOMAINS_YET'); ?>
244 + <?php echo esc_html(acym_translation('ACYM_NO_DOMAINS_YET')); ?>
233 245 </div>
234 246 <?php } else {
235 247 foreach ($domains as &$domain) {
236 248 $isValid = true;
@@ -237,9 +249,9 @@
237 249 foreach ($domain['CnameRecords'] as $i => $cnameRecord) {
238 250 $domain['CnameRecords'][$i]['isValid'] = $this->checkCnameEntry($cnameRecord['name'], $cnameRecord['value']);
239 251 $isValid = $isValid && $domain['CnameRecords'][$i]['isValid'];
240 252 $domain['CnameRecords'][$i]['tooltipMessages'] = $this->cnameErrors;
241 - $this->cnameErrors = [];
253 + $this->cnameErrors = [];
242 254 }
243 255
244 256 if (!$isValid && $domain['status'] === 'SUCCESS') {
245 257 $domain['status'] = 'PENDING';
@@ -245,22 +257,22 @@
245 257 $domain['status'] = 'PENDING';
246 258 $this->config->saveConfig([self::SENDING_METHOD_ID.'_domains' => json_encode($domains)]);
247 259 }
248 260
249 - $bounceRateParams = $this->getRateColor(
261 + $bounceRateColorClass = $this->getRateColor(
250 262 empty($domain['bounce_rate']) ? 0 : $domain['bounce_rate'],
251 263 empty($domain['allowed_bounce_rate']) ? 0 : $domain['allowed_bounce_rate'],
252 264 empty($domain['warning_bounce_rate']) ? 0 : $domain['warning_bounce_rate']
253 265 );
254 - $complaintRateParams = $this->getRateColor(
266 + $complaintRateColorClass = $this->getRateColor(
255 267 empty($domain['complaint_rate']) ? 0 : $domain['complaint_rate'],
256 268 empty($domain['allowed_complaint_rate']) ? 0 : $domain['allowed_complaint_rate'],
257 269 empty($domain['warning_complaint_rate']) ? 0 : $domain['warning_complaint_rate']
258 270 );
259 271 ?>
260 - <div acym-data-domain="<?php echo $domain['domain']; ?>" class="grid-x cell align-middle acym__listing__row">
272 + <div acym-data-domain="<?php echo esc_attr($domain['domain']); ?>" class="grid-x cell align-middle acym__listing__row">
261 273 <div class="cell small-6 medium-auto grid-x acym__listing__title__container">
262 - <?php echo acym_escape($domain['domain']); ?>
274 + <?php echo esc_html($domain['domain']); ?>
263 275 </div>
264 276 <div class="cell small-1 medium-2 grid-x acym__listing__title__container align-center">
265 277 <?php
266 278 switch ($domain['status']) {
@@ -276,9 +288,9 @@
276 288 $iconClass = 'acymicon-access-time acym__color__orange notValidated';
277 289 $tooltipText = acym_translation('ACYM_A_CNAME_MISSING');
278 290 }
279 291
280 - echo acym_tooltip(
292 + acym_tooltip(
281 293 [
282 294 'hoveredText' => '<i class="acym__config__acymailer__status__icon '.$iconClass.'"></i>',
283 295 'textShownInTooltip' => $tooltipText,
284 296 ]
@@ -284,28 +296,42 @@
284 296 ]
285 297 );
286 298 ?>
287 299 </div>
288 - <div class="cell hide-for-small-only medium-2 grid-x acym__listing__title__container align-center <?php echo $bounceRateParams['color']; ?>">
289 - <?php echo empty($domain['bounce_rate']) ? '-' : round($domain['bounce_rate'], 2).'%';
290 - echo $bounceRateParams['icon'];
300 + <div class="cell hide-for-small-only medium-2 grid-x acym__listing__title__container align-center <?php echo esc_attr(
301 + $bounceRateColorClass
302 + ); ?>">
303 + <?php echo empty($domain['bounce_rate']) ? '-' : esc_html(round($domain['bounce_rate'], 2)).'%';
304 + $this->displayRateIcon(
305 + empty($domain['bounce_rate']) ? 0 : $domain['bounce_rate'],
306 + empty($domain['allowed_bounce_rate']) ? 0 : $domain['allowed_bounce_rate'],
307 + empty($domain['warning_bounce_rate']) ? 0 : $domain['warning_bounce_rate']
308 + );
291 309 ?>
292 310 </div>
293 - <div class="cell hide-for-small-only medium-2 grid-x acym__listing__title__container align-center <?php echo $complaintRateParams['color']; ?>">
294 - <?php echo empty($domain['complaint_rate']) ? '-' : round($domain['complaint_rate'], 2).'%';
295 - echo $complaintRateParams['icon'];
311 + <div class="cell hide-for-small-only medium-2 grid-x acym__listing__title__container align-center <?php echo esc_attr(
312 + $complaintRateColorClass
313 + ); ?>">
314 + <?php echo empty($domain['complaint_rate']) ? '-' : esc_html(round($domain['complaint_rate'], 2)).'%';
315 + $this->displayRateIcon(
316 + empty($domain['complaint_rate']) ? 0 : $domain['complaint_rate'],
317 + empty($domain['allowed_complaint_rate']) ? 0 : $domain['allowed_complaint_rate'],
318 + empty($domain['warning_complaint_rate']) ? 0 : $domain['warning_complaint_rate']
319 + );
296 320 ?>
297 321 </div>
298 322 <div class="cell small-4 medium-2 grid-x margin-left-1 medium-margin-left-0 acym__listing__title__container align-center">
299 323 <?php ob_start(); ?>
300 324 <div class="cell grid-x acym__config__acymailer__cname__modal">
301 - <h6 class="cell text-center margin-top-2 margin-bottom-1"><?php echo acym_translation('ACYM_DNS_ENTRIES'); ?></h6>
325 + <h6 class="cell text-center margin-top-2 margin-bottom-1"><?php echo esc_html(acym_translation('ACYM_DNS_ENTRIES')); ?></h6>
302 326 <div class="grid-x cell align-center margin-top-1 margin-bottom-2 acym_vcenter">
303 - <p class="cell shrink"><?php echo acym_translation('ACYM_DO_NOT_KNOW_HOW_DO_IT'); ?> </p>
304 - <a href="<?php echo ACYM_DOCUMENTATION; ?>external-sending-method/acymailing-sending-service#how-to-add-the-dns-entries-on-my-server"
327 + <p class="cell shrink"><?php echo esc_html(acym_translation('ACYM_DO_NOT_KNOW_HOW_DO_IT')); ?> </p>
328 + <a href="<?php echo esc_url(
329 + ACYM_DOCUMENTATION
330 + ); ?>external-sending-method/acymailing-sending-service#how-to-add-the-dns-entries-on-my-server"
305 331 class="cell shrink acym__config__acymailer__cname__modal__link"
306 332 target="_blank">
307 - <?php echo acym_translation('ACYM_STEP_BY_STEP_GUIDE'); ?>
333 + <?php echo esc_html(acym_translation('ACYM_STEP_BY_STEP_GUIDE')); ?>
308 334 </a>
309 335 </div>
310 336 <div class="grid-x acym__listing cell">
311 337 <div class="grid-x acym__listing cell">
@@ -310,45 +336,33 @@
310 336 <div class="grid-x acym__listing cell">
311 337 <div class="grid-x acym__listing cell">
312 338 <div class="cell grid-x grid-margin-x margin-left-0 padding-bottom-1 acym__listing__header">
313 339 <div class="cell small-10 hide-for-medium acym__listing__header__title">
314 - <?php echo acym_translation('ACYM_NAME').' / '.acym_translation('ACYM_VALUE'); ?>
340 + <?php echo esc_html(acym_translation('ACYM_NAME').' / '.acym_translation('ACYM_VALUE')); ?>
315 341 </div>
316 342 <div class="cell small-5 show-for-medium acym__listing__header__title">
317 - <?php echo acym_translation('ACYM_NAME'); ?>
343 + <?php echo esc_html(acym_translation('ACYM_NAME')); ?>
318 344 </div>
319 345 <div class="cell small-5 show-for-medium acym__listing__header__title">
320 - <?php echo acym_translation('ACYM_VALUE'); ?>
346 + <?php echo esc_html(acym_translation('ACYM_VALUE')); ?>
321 347 </div>
322 348 <div class="cell small-2 acym__listing__header__title text-center">
323 - <?php echo acym_translation('ACYM_STATUS'); ?>
349 + <?php echo esc_html(acym_translation('ACYM_STATUS')); ?>
324 350 </div>
325 351 </div>
326 - <?php
327 - foreach ($domain['CnameRecords'] as $cnameRecord) {
328 - if ($cnameRecord['isValid']) {
329 - $cnameStatus = '<i class="acym__config__acymailer__status__icon acymicon-check-circle acym__color__green"></i>';
330 - } else {
331 - $cnameStatus = acym_tooltip(
332 - [
333 - 'hoveredText' => '<i class="acym__config__acymailer__status__icon acymicon-close acym__color__red"></i>',
334 - 'textShownInTooltip' => implode('<br/>', $cnameRecord['tooltipMessages']),
335 - ]
336 - );
337 - }
338 - ?>
352 + <?php foreach ($domain['CnameRecords'] as $cnameRecord) { ?>
339 353 <div class="cell grid-x grid-margin-x margin-left-0 align-middle acym__listing__row">
340 354 <div class="cell small-11 medium-5 cname-name">
341 - <?php echo $cnameRecord['name']; ?>
355 + <?php echo esc_html($cnameRecord['name']); ?>
342 356 </div>
343 357 <div class="cell small-1 hide-for-medium cname-value">
344 - <?php echo $cnameStatus; ?>
358 + <?php $this->displayCnameStatus($cnameRecord); ?>
345 359 </div>
346 360 <div class="cell small-11 medium-5 cname-value">
347 - <?php echo $cnameRecord['value']; ?>
361 + <?php echo esc_html($cnameRecord['value']); ?>
348 362 </div>
349 363 <div class="cell medium-2 show-for-medium text-center">
350 - <?php echo $cnameStatus; ?>
364 + <?php $this->displayCnameStatus($cnameRecord); ?>
351 365 </div>
352 366 </div>
353 367 <?php } ?>
354 368 </div>
@@ -355,15 +369,19 @@
355 369 </div>
356 370 </div>
357 371 <?php
358 372 $modalContent = ob_get_clean();
359 - $buttonModal = acym_tooltip(
373 + ob_start();
374 + acym_tooltip(
360 375 [
361 - 'hoveredText' => '<i class="acymicon-cogs acym__config__acymailer__domain--settings cursor-pointer acym__color__blue" acym-data-domain="'.$domain['domain'].'"></i>',
376 + 'hoveredText' => '<i class="acymicon-cogs acym__config__acymailer__domain--settings cursor-pointer acym__color__blue" acym-data-domain="'.esc_attr(
377 + $domain['domain']
378 + ).'"></i>',
362 379 'textShownInTooltip' => acym_translation('ACYM_SHOW_DNS_SETTINGS'),
363 380 ]
364 381 );
365 - echo acym_modal(
382 + $buttonModal = ob_get_clean();
383 + acym_modal(
366 384 $buttonModal,
367 385 $modalContent,
368 386 null,
369 387 [],
@@ -372,11 +390,11 @@
372 390 true,
373 391 'acym__config__acymailer__cname__modal__container'
374 392 );
375 393
376 - echo acym_tooltip(
394 + acym_tooltip(
377 395 [
378 - 'hoveredText' => '<i class="acymicon-delete acym__config__acymailer__domain--delete cursor-pointer" acym-data-domain="'.acym_escape(
396 + 'hoveredText' => '<i class="acymicon-delete acym__config__acymailer__domain--delete cursor-pointer" acym-data-domain="'.esc_attr(
379 397 $domain['domain']
380 398 ).'"></i>',
381 399 'textShownInTooltip' => acym_translation('ACYM_DELETE'),
382 400 ]
@@ -391,19 +409,19 @@
391 409 </div>
392 410 <div class="cell grid-x acym_vcenter acym__sending__methods__one__settings padding-top-1">
393 411 <div class="cell grid-x">
394 412 <div class="cell small-7 medium-4 large-3 margin-next-1">
395 - <input id="<?php echo self::SENDING_METHOD_ID; ?>_domain"
396 - class="cell medium-6 large-4 xlarge-3"
397 - type="text"
398 - autocomplete="off"
399 - value="">
400 - <span id="<?php echo self::SENDING_METHOD_ID; ?>_domain_error" class="medium-6 large-4 xlarge-3"></span>
413 + <input id="<?php echo esc_attr(self::SENDING_METHOD_ID); ?>_domain"
414 + class="cell medium-6 large-4 xlarge-3"
415 + type="text"
416 + autocomplete="off"
417 + value="">
418 + <span id="<?php echo esc_attr(self::SENDING_METHOD_ID); ?>_domain_error" class="medium-6 large-4 xlarge-3"></span>
401 419 <?php
402 420 if (!empty($unverifiedDomains)) { ?>
403 421 <span id="acym__acymailer__unverifiedDomains">
404 422 <?php foreach ($unverifiedDomains as $oneDomain) { ?>
405 - <span class="acym__acymailer__oneSuggestion"><?php echo $oneDomain; ?></span>
423 + <span class="acym__acymailer__oneSuggestion"><?php echo esc_html($oneDomain); ?></span>
406 424 <?php } ?>
407 425 </span>
408 426 <?php } ?>
409 427 </div>
@@ -408,11 +426,11 @@
408 426 <?php } ?>
409 427 </div>
410 428 <div id="acym__configuration__sending__method_addDomain_submit" class="cell grid-x small-4 medium-6 large-8 acym_vcenter">
411 429 <button type="button"
412 - id="acym__configuration__sending__method-addDomain"
413 - class="cell shrink button button-secondary">
414 - <?php echo acym_translation('ACYM_ADD_A_DOMAIN'); ?>
430 + id="acym__configuration__sending__method-addDomain"
431 + class="cell shrink button button-secondary">
432 + <?php echo esc_html(acym_translation('ACYM_ADD_A_DOMAIN')); ?>
415 433 </button>
416 434 <i class="margin-left-1 acym_vcenter acymicon-circle-o-notch acymicon-spin is-hidden"
417 435 id="acym__configuration__sending__method_add_domain-wait"></i>
418 436 <div class="cell shrink grid-x acym_vcenter" id="acym__configuration__acymailer__add__error">
@@ -424,9 +442,9 @@
424 442 </div>
425 443 <?php if (!$this->isLogFileEmpty()) { ?>
426 444 <div class="cell grid-x acym__sending__methods__log">
427 445 <?php
428 - echo acym_modal(
446 + acym_modal(
429 447 acym_translation('ACYM_REPORT_SEE'),
430 448 '',
431 449 null,
432 450 [],
@@ -442,9 +460,8 @@
442 460 <?php } ?>
443 461 </div>
444 462 </div>
445 463 <?php
446 - $data['sendingMethodsHtmlSettings'][self::SENDING_METHOD_ID] = ob_get_clean();
447 464 }
448 465
449 466 public function onAcymTestCredentialSendingMethod($sendingMethod, $credentials)
450 467 {
@@ -510,8 +527,9 @@
510 527
511 528 return;
512 529 }
513 530
531 + // In Amazon SES, you must verify each identity used as a "From", "Source", "Sender", or "Return-Path" address.
514 532 $domainsUsed = [
515 533 acym_getDomain($from['email']),
516 534 acym_getDomain($replyTo['email']),
517 535 ];
@@ -521,8 +539,9 @@
521 539 }
522 540
523 541 $domainsUsed = array_unique($domainsUsed);
524 542
543 + // Maybe don't try to send if one of these domains is not validated?
525 544 $verifiedDomains = $this->getVerifiedDomains();
526 545
527 546 $unverifiedDomains = array_diff($domainsUsed, $verifiedDomains);
528 547 if (!empty($unverifiedDomains)) {
@@ -572,8 +591,9 @@
572 591 $response['message'] .= acym_translation('ACYM_GET_MORE_CREDITS');
573 592 $response['message'] .= '</a>';
574 593 }
575 594
595 + // Don't unsubscribe/remove recipients if the error isn't related to them
576 596 if (!empty($responseMailer['code']) && in_array($responseMailer['code'], [18, 26, 28])) {
577 597 $mailerHelper->failedCounting = false;
578 598 }
579 599
@@ -701,9 +721,17 @@
701 721 acym_sendAjaxResponse($message, [], false);
702 722 } elseif (!empty($responseApi['message']) && $responseApi['message'] === 'Invalid private key') {
703 723 acym_sendAjaxResponse(acym_translation('ACYM_AUTHENTICATION_FAILS_WITH_API_KEY'), [], false);
704 724 } elseif (!$this->checkSuccessCode($this->responseCode) && (empty($responseApi['code']) || !in_array($responseApi['code'], [5, 4, 3]))) {
725 + /*
726 + We may ask the API for the deletion of a domain while:
727 + - it already doesn't exist (error code 5)
728 + - it doesn't belong to the current API key (error code 4)
729 + - it isn't linked to this website (error code 3)
705 730
731 + In all 3 cases, we don't want to keep this domain in the AcyMailing configuration, so we remove it and consider the deletion as a success
732 + */
733 +
706 734 $message = acym_translation('ACYM_ERROR_ON_CALL_ACYBA_WEBSITE').': '.$this->translate($responseApi);
707 735 if (!empty($responseApi['logs'])) {
708 736 acym_logError($responseApi['logs'], self::SENDING_METHOD_ID);
709 737 }
@@ -855,8 +883,9 @@
855 883 $creditsShowed = $response['remaining_credits'];
856 884
857 885 if (!empty($response['is_multisite'])) {
858 886 $fromEmail = $this->config->get('from_email', '');
887 + // If the license is multisite we check and increment credits on the domain of the from email
859 888 $domain = explode('@', $fromEmail)[1];
860 889
861 890 if (empty($domain) || empty($response['domains'][$domain])) {
862 891 $html = acym_translation('ACYM_DOMAIN_FROM_EMAIL_NOT_VALID_ASS');
@@ -870,26 +899,38 @@
870 899 }
871 900 }
872 901 }
873 902
903 + // Add security empty text message
874 904 if (empty($creditsShowed)) {
875 905 $creditsShowed = '0';
876 906 }
907 +
908 + ob_start();
909 + acym_tooltip(
910 + [
911 + 'hoveredText' => $creditsShowed,
912 + 'textShownInTooltip' => acym_translation('ACYM_GET_MORE_CREDITS'),
913 + 'classContainer' => 'credits_remaining',
914 + 'link' => ACYM_ACYMAILING_WEBSITE,
915 + ]
916 + );
917 + $tooltip = ob_get_clean();
877 918 $html = acym_translationSprintf(
878 919 'ACYM_SENDING_METHOD_X_UNITY',
879 920 self::SENDING_METHOD_NAME,
880 - acym_tooltip(
881 - [
882 - 'hoveredText' => $creditsShowed,
883 - 'textShownInTooltip' => acym_translation('ACYM_GET_MORE_CREDITS'),
884 - 'classContainer' => 'credits_remaining',
885 - 'link' => ACYM_ACYMAILING_WEBSITE,
886 - ]
887 - ),
888 - '<span class="acym_not_bold">'.acym_translation($unityTranslation).'</span>'
921 + $tooltip,
922 + '<span class="acym_not_bold">'.esc_html(acym_translation($unityTranslation)).'</span>'
889 923 );
890 924 }
891 925
926 + /**
927 + * Called before loading the emails of a batch to get the credits left
928 + *
929 + * @param int $creditsLeft
930 + *
931 + * @return void
932 + */
892 933 public function onAcymCreditsLeft(&$creditsLeft)
893 934 {
894 935 $sendingMethod = $this->config->get('mailer_method', '');
895 936 if (empty($sendingMethod) || $sendingMethod != self::SENDING_METHOD_ID) return;
@@ -952,8 +993,9 @@
952 993 if ($this->config->get('mailer_method') !== self::SENDING_METHOD_ID) {
953 994 return [];
954 995 }
955 996
997 + // In Amazon SES, you must verify each identity used as a "From", "Source", "Sender", or "Return-Path" address.
956 998 $allDomains = [];
957 999
958 1000 $allDomains[] = acym_getDomain($this->config->get('from_email'));
959 1001 if ($this->config->get('from_as_replyto') === '0') {
@@ -978,39 +1020,46 @@
978 1020
979 1021 return array_diff($allDomains, $verifiedDomains);
980 1022 }
981 1023
982 - private function getRateColor($rate, $allowedRate, $warningRate): array
1024 + private function getRateColor(float $rate, float $allowedRate, float $warningRate): string
983 1025 {
984 1026 if (empty($rate) || empty($allowedRate) || empty($warningRate)) {
985 - return ['color' => '', 'icon' => ''];
1027 + return '';
986 1028 }
987 1029
988 1030 if ($rate > $allowedRate) {
989 - return [
990 - 'color' => 'acym__color__red',
991 - 'icon' => acym_tooltip(
992 - [
993 - 'hoveredText' => '<i class="acym__config__acymailer__rate-status__icon acymicon-close acym__color__red"></i>',
994 - 'textShownInTooltip' => acym_translation('ACYM_RATE_BLOCKED'),
995 - ]
996 - ),
997 - ];
1031 + return 'acym__color__red';
998 1032 } elseif ($rate >= $warningRate) {
999 - return [
1000 - 'color' => 'acym__color__orange',
1001 - 'icon' => acym_tooltip(
1002 - [
1003 - 'hoveredText' => '<i class="acym__config__acymailer__rate-status__icon acymicon-exclamation-triangle acym__color__orange"></i>',
1004 - 'textShownInTooltip' => acym_translation('ACYM_RATE_WARNING'),
1005 - ]
1006 - ),
1007 - ];
1033 + return 'acym__color__orange';
1008 1034 }
1009 1035
1010 - return ['color' => '', 'icon' => ''];
1036 + return '';
1011 1037 }
1012 1038
1039 + private function displayRateIcon(float $rate, float $allowedRate, float $warningRate): void
1040 + {
1041 + if (empty($rate) || empty($allowedRate) || empty($warningRate)) {
1042 + return;
1043 + }
1044 +
1045 + if ($rate > $allowedRate) {
1046 + acym_tooltip(
1047 + [
1048 + 'hoveredText' => '<i class="acym__config__acymailer__rate-status__icon acymicon-close acym__color__red"></i>',
1049 + 'textShownInTooltip' => acym_translation('ACYM_RATE_BLOCKED'),
1050 + ]
1051 + );
1052 + } elseif ($rate >= $warningRate) {
1053 + acym_tooltip(
1054 + [
1055 + 'hoveredText' => '<i class="acym__config__acymailer__rate-status__icon acymicon-exclamation-triangle acym__color__orange"></i>',
1056 + 'textShownInTooltip' => acym_translation('ACYM_RATE_WARNING'),
1057 + ]
1058 + );
1059 + }
1060 + }
1061 +
1013 1062 private function updateDomainRates($domainsRates)
1014 1063 {
1015 1064 $domains = $this->config->get(self::SENDING_METHOD_ID.'_domains', []);
1016 1065
@@ -1086,8 +1135,9 @@
1086 1135 }
1087 1136
1088 1137 private function checkSuccessCode($responseCode): bool
1089 1138 {
1139 + // we can add more success response codes if needed but for now, that's all the success response codes the API can send
1090 1140 return in_array($responseCode, [200, 201]);
1091 1141 }
1092 1142
1093 1143 private function translate($response)
@@ -1129,8 +1179,19 @@
1129 1179
1130 1180 return $finalMessage;
1131 1181 }
1132 1182
1183 + /**
1184 + * Emails not needing an unsubscribe link:
1185 + * - Sending a test from config, from campaign tab or from editor
1186 + * - Forwarding a bounce message
1187 + * - Sending a spam-test
1188 + * - Overriding website emails
1189 + * - Sending notification messages
1190 + * - Unsubscribe emails
1191 + * - Sending the walkthrough email
1192 + * - Forwarding an email to a specific address from mailbox actions
1193 + */
1133 1194 private function isUnsubscribeLinkMissing($mailerHelper): bool
1134 1195 {
1135 1196 if ($mailerHelper->isTest || $mailerHelper->isForward || $mailerHelper->isSpamTest || empty($mailerHelper->mail)) {
1136 1197 return false;
@@ -1155,13 +1216,15 @@
1155 1216 private function checkDomainsDNS($domains): array
1156 1217 {
1157 1218 $remainingDomains = [];
1158 1219 foreach ($domains as $oneDomain) {
1220 + // No DNS entries yet, we have to check the domain to get DNS entries
1159 1221 if (empty($oneDomain['CnameRecords'])) {
1160 1222 $remainingDomains[] = $oneDomain;
1161 1223 continue;
1162 1224 }
1163 1225
1226 + // Check if all DNS entries are valid before calling the API
1164 1227 foreach ($oneDomain['CnameRecords'] as $oneRecord) {
1165 1228 if (!$this->checkCnameEntry($oneRecord['name'], $oneRecord['value'])) {
1166 1229 $domainPosition = strpos($oneRecord['name'], '_domainkey') + 11;
1167 1230 $domainName = substr($oneRecord['name'], $domainPosition);
@@ -1217,6 +1280,20 @@
1217 1280
1218 1281 $this->cnameErrors[] = acym_translation('ACYM_DNS_NOT_CNAME');
1219 1282
1220 1283 return false;
1284 + }
1285 +
1286 + private function displayCnameStatus(array $cnameRecord): void
1287 + {
1288 + if ($cnameRecord['isValid']) {
1289 + echo '<i class="acym__config__acymailer__status__icon acymicon-check-circle acym__color__green"></i>';
1290 + } else {
1291 + acym_tooltip(
1292 + [
1293 + 'hoveredText' => '<i class="acym__config__acymailer__status__icon acymicon-close acym__color__red"></i>',
1294 + 'textShownInTooltip' => implode('<br/>', $cnameRecord['tooltipMessages']),
1295 + ]
1296 + );
1297 + }
1221 1298 }
1222 1299 }