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/elasticemail/plugin.php +307 -0 11.1.1 → 11.1.0 View file →
@@ -1,0 +1,307 @@
1 +<?php
2 +
3 +use AcyMailerPhp\Mailer;
4 +use AcyMailing\Classes\CampaignClass;
5 +use AcyMailing\Classes\MailClass;
6 +use AcyMailing\Helpers\MailerHelper;
7 +use AcyMailing\Core\AcymPlugin;
8 +
9 +class plgAcymElasticemail extends AcymPlugin
10 +{
11 + const SENDING_METHOD_ID = 'elasticemail';
12 + const SENDING_METHOD_NAME = 'Elastic Email';
13 + const SENDING_METHOD_API_URL = 'https://api.elasticemail.com/v4/';
14 +
15 + private $mailClass;
16 + private $campaignClass;
17 + private $attachmentsFetched = false;
18 + private $uploadedAttachments = [];
19 +
20 + public function __construct()
21 + {
22 + parent::__construct();
23 + $this->pluginDescription->name = self::SENDING_METHOD_NAME;
24 + }
25 +
26 + public function onAcymGetSendingMethods(&$data, $isMailer = false)
27 + {
28 + $data['sendingMethods'][self::SENDING_METHOD_ID] = [
29 + 'name' => $this->pluginDescription->name,
30 + 'image' => ACYM_IMAGES.'mailers/elasticemail.png',
31 + ];
32 + }
33 +
34 + public function onAcymGetSendingMethodsHtmlSetting(&$data)
35 + {
36 + ?>
37 + <div class="send_settings grid-x cell" id="<?php echo esc_attr(self::SENDING_METHOD_ID); ?>_settings">
38 + <div class="cell grid-x acym_vcenter acym__sending__methods__one__settings">
39 + <label for="<?php echo esc_attr(self::SENDING_METHOD_ID); ?>_password" class="cell shrink margin-right-1">
40 + <?php echo esc_html(acym_translation('ACYM_API_KEY')); ?>
41 + </label>
42 + <?php
43 + $this->getLinks(
44 + 'https://elasticemail.com/referral-reward?r=7b884a0b-b979-4473-8803-06ae39d76599',
45 + 'https://elasticemail.com/email-api-pricing?r=7b884a0b-b979-4473-8803-06ae39d76599'
46 + );
47 + ?>
48 + <input id="<?php echo esc_attr(self::SENDING_METHOD_ID); ?>_password"
49 + class="cell"
50 + type="text"
51 + name="config[<?php echo esc_attr(self::SENDING_METHOD_ID); ?>_password]"
52 + value="<?php echo esc_attr(str_repeat('*', strlen($this->config->get(self::SENDING_METHOD_ID.'_password')))); ?>">
53 + <?php $this->getTestCredentialsSendingMethodButton(self::SENDING_METHOD_ID); ?>
54 + </div>
55 + </div>
56 + <?php
57 + }
58 +
59 + public function onAcymTestCredentialSendingMethod($sendingMethod, $credentials)
60 + {
61 + if ($sendingMethod !== self::SENDING_METHOD_ID) {
62 + return;
63 + }
64 +
65 + $response = $this->callApiSendingMethod(
66 + self::SENDING_METHOD_API_URL.'files?limit=1',
67 + [],
68 + $this->getAuthenticationHeaders($credentials),
69 + );
70 +
71 + if (!empty($response['error_curl'])) {
72 + acym_sendAjaxResponse(acym_translationSprintf('ACYM_ERROR_OCCURRED_WHILE_CALLING_API', $response['error_curl']), [], false);
73 + } elseif (!empty($response['Error'])) {
74 + $message = $response['Error'] === 'APIKey Expired'
75 + ? acym_translation('ACYM_AUTHENTICATION_FAILS_WITH_API_KEY')
76 + : acym_translationSprintf(
77 + 'ACYM_API_RETURN_THIS_ERROR',
78 + $response['Error']
79 + );
80 + acym_sendAjaxResponse($message, [], false);
81 + } else {
82 + acym_sendAjaxResponse(acym_translation('ACYM_API_KEY_CORRECT'));
83 + }
84 + }
85 +
86 + public function onAcymSendEmail(
87 + array &$response,
88 + MailerHelper $mailerHelper,
89 + array $to,
90 + array $from,
91 + array $reply_to,
92 + array $bcc = [],
93 + array $attachments = [],
94 + $sendingMethodListParams = []
95 + ): void {
96 + // https://elasticemail.com/developers/api-documentation/rest-api#operation/emailsTransactionalPost
97 + if ($mailerHelper->externalMailer !== self::SENDING_METHOD_ID) {
98 + return;
99 + }
100 +
101 + $data = [
102 + 'recipients' => new stdClass(),
103 + 'content' => new stdClass(),
104 + ];
105 +
106 + $this->handleAddresses($data, $mailerHelper, $from, $reply_to, $to, $bcc);
107 + $this->handleEmailContent($data, $mailerHelper);
108 + $this->handleAttachments($data, $attachments);
109 + $this->handleHeaders($data, $mailerHelper);
110 + $this->handleGA($data, $mailerHelper);
111 +
112 + $responseMailer = $this->callApiSendingMethod(
113 + self::SENDING_METHOD_API_URL.'emails/transactional',
114 + $data,
115 + $this->getAuthenticationHeaders(),
116 + 'POST'
117 + );
118 +
119 + if (!empty($responseMailer['Error'])) {
120 + $response['error'] = true;
121 + $response['message'] = $responseMailer['Error'];
122 + } else {
123 + $response['error'] = false;
124 + }
125 + }
126 +
127 + public function onAcymSendingMethodOptions(&$data)
128 + {
129 + $data['embedImage'][self::SENDING_METHOD_ID] = false;
130 + }
131 +
132 + private function handleAddresses(array &$data, MailerHelper $mailerHelper, array $from, array $reply_to, array $to, array $bcc): void
133 + {
134 + $data['recipients']->to = [$to['email']];
135 +
136 + if (!empty($bcc)) {
137 + $data['recipients']->bcc = [$bcc[0][0]];
138 + }
139 +
140 + $data['content']->From = empty($from['name']) ? $from['email'] : $from['name'].' <'.$from['email'].'>';
141 + $data['content']->ReplyTo = empty($reply_to['name']) ? $reply_to['email'] : $reply_to['name'].' <'.$reply_to['email'].'>';
142 +
143 + $bounceAddress = $this->getBounceAddress($mailerHelper);
144 + if (!empty($bounceAddress)) {
145 + $data['content']->EnvelopeFrom = $bounceAddress;
146 + }
147 + }
148 +
149 + private function handleEmailContent(array &$data, MailerHelper $mailerHelper): void
150 + {
151 + $data['content']->Subject = $mailerHelper->Subject;
152 + $data['content']->Body = [
153 + (object)[
154 + 'ContentType' => 'HTML',
155 + 'Content' => $mailerHelper->Body,
156 + 'Charset' => 'utf-8',
157 + ],
158 + ];
159 +
160 + if (!empty($mailerHelper->AltBody)) {
161 + $data['content']->Body[] = (object)[
162 + 'ContentType' => 'PlainText',
163 + 'Content' => $mailerHelper->AltBody,
164 + 'Charset' => 'utf-8',
165 + ];
166 + }
167 + }
168 +
169 + private function handleAttachments(array &$data, array $attachments): void
170 + {
171 + if (empty($attachments)) {
172 + return;
173 + }
174 +
175 + if (!$this->attachmentsFetched) {
176 + $this->attachmentsFetched = true;
177 +
178 + // Uploaded attachments expire after 35 days by default, so 1000 should be more than enough
179 + $uploadedAttachments = $this->callApiSendingMethod(
180 + self::SENDING_METHOD_API_URL.'files?limit=1000',
181 + [],
182 + $this->getAuthenticationHeaders()
183 + );
184 +
185 + if (empty($uploadedAttachments['Error'])) {
186 + foreach ($uploadedAttachments as $oneAttachment) {
187 + $this->uploadedAttachments[] = $oneAttachment['FileName'];
188 + }
189 + }
190 + }
191 +
192 + $data['content']->AttachFiles = [];
193 + foreach ($attachments as $attachment) {
194 + $fileName = $this->cleanFileName($attachment[1]);
195 +
196 + if (!in_array($fileName, $this->uploadedAttachments)) {
197 + $uploadedAttachment = $this->callApiSendingMethod(
198 + self::SENDING_METHOD_API_URL.'files',
199 + [
200 + 'BinaryContent' => $attachment['contentEncoded'],
201 + 'Name' => $fileName,
202 + 'ContentType' => $attachment[4],
203 + ],
204 + $this->getAuthenticationHeaders(),
205 + 'POST'
206 + );
207 +
208 + if (empty($uploadedAttachment['FileName'])) {
209 + continue;
210 + }
211 +
212 + $this->uploadedAttachments[] = $fileName;
213 + }
214 +
215 + $data['content']->AttachFiles[] = $fileName;
216 + }
217 + }
218 +
219 + private function handleHeaders(array &$data, MailerHelper $mailerHelper): void
220 + {
221 + $data['content']->Headers = new stdClass();
222 + $data['content']->Headers->Date = Mailer::rfcDate();
223 +
224 + if (empty($mailerHelper->CustomHeader)) {
225 + return;
226 + }
227 +
228 + foreach ($mailerHelper->CustomHeader as $oneHeader) {
229 + $data['content']->Headers->{$oneHeader[0]} = $oneHeader[1];
230 + }
231 + }
232 +
233 + private function handleGA(array &$data, MailerHelper $mailerHelper): void
234 + {
235 + $trackingSystem = $this->config->get('trackingsystem', 'acymailing');
236 + if (strpos($trackingSystem, 'google') === false || empty($mailerHelper->mailId)) {
237 + return;
238 + }
239 + $data['content']->Utm = new stdClass();
240 + $data['content']->Utm->Source = 'newsletter';
241 + $data['content']->Utm->Medium = 'email';
242 + $data['content']->Utm->Campaign = acym_getAlias($data['content']->Subject);
243 +
244 + if (empty($this->mailClass)) {
245 + $this->mailClass = new MailClass();
246 + }
247 + $campaignId = $this->mailClass->getCampaignIdByMailId($mailerHelper->mailId);
248 +
249 + if (empty($campaignId)) {
250 + $data['content']->Utm->Source .= '_'.$mailerHelper->mailId;
251 + } else {
252 + if (empty($this->campaignClass)) {
253 + $this->campaignClass = new CampaignClass();
254 + }
255 + $campaign = $this->campaignClass->getOneById($campaignId);
256 +
257 + if (empty($campaign)) {
258 + return;
259 + }
260 +
261 + $data['content']->Utm->Source .= '_'.$campaignId;
262 +
263 + if (!empty($campaign->sending_params['utm_source'])) {
264 + $data['content']->Utm->Source = $campaign->sending_params['utm_source'];
265 + }
266 +
267 + if (!empty($campaign->sending_params['utm_medium'])) {
268 + $data['content']->Utm->Medium = $campaign->sending_params['utm_medium'];
269 + }
270 +
271 + if (!empty($campaign->sending_params['utm_campaign'])) {
272 + $data['content']->Utm->Campaign = $campaign->sending_params['utm_campaign'];
273 + }
274 + }
275 + }
276 +
277 + private function getAuthenticationHeaders(array $credentials = []): array
278 + {
279 + if (
280 + !isset($credentials[self::SENDING_METHOD_ID.'_password'])
281 + || (
282 + !empty($credentials[self::SENDING_METHOD_ID.'_password'])
283 + && empty(trim($credentials[self::SENDING_METHOD_ID.'_password'], '*'))
284 + )
285 + ) {
286 + return [
287 + 'X-ElasticEmail-ApiKey: '.$this->config->get(self::SENDING_METHOD_ID.'_password'),
288 + 'Content-Type: application/json',
289 + ];
290 + }
291 +
292 + return [
293 + 'X-ElasticEmail-ApiKey: '.$credentials[self::SENDING_METHOD_ID.'_password'],
294 + 'Content-Type: application/json',
295 + ];
296 + }
297 +
298 + private function cleanFileName(string $fileName): string
299 + {
300 + // Replace accents with their non-accented equivalent
301 + if (function_exists('iconv')) {
302 + $fileName = iconv('UTF-8', 'ASCII//TRANSLIT', $fileName);
303 + }
304 +
305 + return preg_replace('#[^a-z0-9\.\-\_]#i', '_', $fileName);
306 + }
307 +}