PluginProbe
AcyMailing – An Ultimate Newsletter Plugin and Marketing Automation Solution for WordPress / 11.1.1
AcyMailing – An Ultimate Newsletter Plugin and Marketing Automation Solution for WordPress v11.1.1
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/Classes/MailClass.php +0 -1520 10.2.2 → 11.1.1 View file →
@@ -1,1520 +1,0 @@
1 -<?php
2 -
3 -namespace AcyMailing\Classes;
4 -
5 -use AcyMailing\Helpers\MailerHelper;
6 -use AcyMailing\Helpers\PaginationHelper;
7 -use AcyMailing\Helpers\PluginHelper;
8 -use AcyMailing\Core\AcymClass;
9 -
10 -class MailClass extends AcymClass
11 -{
12 - var $templateNames = [];
13 -
14 - public $exceptKeysDecode = [];
15 - public $autosave;
16 - public $access;
17 - public $templateId;
18 -
19 - const FIELDS_ENCODING = ['name', 'subject', 'body', 'autosave', 'preheader'];
20 -
21 - const TYPE_STANDARD = 'standard';
22 - const TYPE_NOTIFICATION = 'notification';
23 - const TYPE_OVERRIDE = 'override';
24 - const TYPE_WELCOME = 'welcome';
25 - const TYPE_UNSUBSCRIBE = 'unsubscribe';
26 - const TYPE_AUTOMATION = 'automation';
27 - const TYPE_FOLLOWUP = 'followup';
28 - const TYPE_MAILBOX_ACTION = 'mailbox_action';
29 - const TYPE_TEMPLATE = 'template';
30 - const TYPE_SCENARIO = 'scenario';
31 -
32 - const ALL_TYPES = [
33 - self::TYPE_STANDARD,
34 - self::TYPE_NOTIFICATION,
35 - self::TYPE_OVERRIDE,
36 - self::TYPE_WELCOME,
37 - self::TYPE_UNSUBSCRIBE,
38 - self::TYPE_AUTOMATION,
39 - self::TYPE_FOLLOWUP,
40 - self::TYPE_MAILBOX_ACTION,
41 - self::TYPE_TEMPLATE,
42 - self::TYPE_SCENARIO,
43 - ];
44 -
45 - const TYPES_TRANSACTIONAL = [
46 - self::TYPE_NOTIFICATION,
47 - self::TYPE_OVERRIDE,
48 - self::TYPE_WELCOME,
49 - self::TYPE_UNSUBSCRIBE,
50 - self::TYPE_TEMPLATE,
51 - self::TYPE_SCENARIO,
52 - ];
53 -
54 - const TYPES_WITH_STATS = [
55 - self::TYPE_STANDARD,
56 - self::TYPE_AUTOMATION,
57 - self::TYPE_WELCOME,
58 - self::TYPE_UNSUBSCRIBE,
59 - self::TYPE_FOLLOWUP,
60 - self::TYPE_MAILBOX_ACTION,
61 - self::TYPE_SCENARIO,
62 - ];
63 -
64 - const TYPES_NO_NAME = [
65 - self::TYPE_NOTIFICATION,
66 - self::TYPE_OVERRIDE,
67 - ];
68 -
69 - const MAX_ALLOWED_TEMPLATE_FILES = 100;
70 - const MAX_ALLOWED_TEMPLATE_SIZE = 20971520;
71 - const ALLOWED_TEMPLATE_FILE_TYPES = [
72 - 'image/jpeg',
73 - 'image/png',
74 - 'image/gif',
75 - 'text/html',
76 - 'image/x-ms-bmp',
77 - 'image/bmp',
78 - 'text/plain',
79 - 'image/vnd.microsoft.icon',
80 - ];
81 -
82 - public function __construct()
83 - {
84 - parent::__construct();
85 -
86 - $this->table = 'mail';
87 - $this->pkey = 'id';
88 - }
89 -
90 - public function getMatchingElements(array $settings = []): array
91 - {
92 - $query = 'SELECT mail.* FROM #__acym_mail AS mail';
93 - $queryCount = 'SELECT COUNT(mail.id) AS total FROM #__acym_mail AS mail';
94 -
95 - $filters = [];
96 - $tagJoin = '';
97 -
98 - if (!empty($settings['tag'])) {
99 - $tagJoin = ' JOIN #__acym_tag AS tag ON mail.id = tag.id_element ';
100 - $filters[] = 'tag.name = '.acym_escapeDB($settings['tag']);
101 - $filters[] = 'tag.type = "mail"';
102 - }
103 - $query .= $tagJoin;
104 - $queryCount .= $tagJoin;
105 -
106 - if (!empty($settings['search'])) {
107 - $filters[] = 'mail.name LIKE '.acym_escapeDB('%'.acym_utf8Encode($settings['search']).'%');
108 - }
109 -
110 - if (!empty($settings['gettingTemplates'])) {
111 - $filters[] = 'mail.type = '.acym_escapeDB(self::TYPE_TEMPLATE);
112 - if (!acym_isAdmin()) {
113 - $currentUserId = acym_currentUserId();
114 - $condition = 'mail.creator_id = '.intval($currentUserId);
115 -
116 - $userGroups = acym_getGroupsByUser($currentUserId);
117 - if (!empty($userGroups)) {
118 - $condition .= ' OR access LIKE "%,'.implode(',%" OR access LIKE "%,', $userGroups).',%"';
119 - }
120 -
121 - $filters[] = $condition;
122 - }
123 - } else {
124 - if (!empty($settings['automation']) || empty($settings['onlyStandard'])) {
125 - $filters[] = 'mail.type != '.acym_escapeDB(self::TYPE_NOTIFICATION);
126 - $filters[] = 'mail.type != '.acym_escapeDB(self::TYPE_OVERRIDE);
127 - } else {
128 - $filters[] = 'mail.type IN ('.acym_escapeDB(self::TYPE_STANDARD).', '.acym_escapeDB(self::TYPE_TEMPLATE).')';
129 - }
130 -
131 - if (empty($settings['automation'])) {
132 - $filters[] = 'mail.type IN ('.acym_escapeDB(self::TYPE_TEMPLATE).', '.acym_escapeDB(self::TYPE_WELCOME).', '.acym_escapeDB(self::TYPE_UNSUBSCRIBE).')';
133 - }
134 -
135 - if (!empty($settings['creator_id'])) {
136 - $mailTypeCondition = 'mail.type IN ('.acym_escapeDB(self::TYPE_TEMPLATE).', '.acym_escapeDB(self::TYPE_WELCOME).', '.acym_escapeDB(self::TYPE_UNSUBSCRIBE).')';
137 - $userGroups = acym_getGroupsByUser($settings['creator_id']);
138 - $groupCondition = '(mail.access LIKE "%,'.implode(',%" OR mail.access LIKE "%,', $userGroups).',%")';
139 - $filter = 'mail.creator_id = '.intval($settings['creator_id']).' OR ('.$mailTypeCondition.' AND '.$groupCondition.')';
140 -
141 - if (!acym_isAdmin() && !empty($settings['element_tab'])) {
142 - $filter = '('.$filter.')
143 - OR list.cms_user_id = '.intval($settings['creator_id']).'
144 - OR (list.access LIKE "%,'.implode(',%" OR list.access LIKE "%,', $userGroups).',%")';
145 - }
146 -
147 - $filters['list'] = '('.$filter.')';
148 - }
149 - }
150 -
151 - $filters[] = 'mail.parent_id IS NULL';
152 -
153 - if (!empty($settings['drag_editor'])) {
154 - $filters[] = 'mail.drag_editor = 1';
155 - }
156 -
157 - if (!empty($settings['element_tab'])) {
158 - $statJoin = ' LEFT JOIN #__acym_mail_stat AS mail_stat ON mail.id = mail_stat.mail_id ';
159 - $listJoin = acym_isAdmin() ? '' : ' LEFT JOIN #__acym_list AS list ON list.'.acym_escape($settings['element_tab']).'_id = mail.id';
160 - $query = 'SELECT DISTINCT mail.*, mail_stat.sent as subscribers, mail_stat.open_unique FROM #__acym_mail AS mail'.$statJoin.$tagJoin.$listJoin;
161 - $filters[] = 'mail.type = '.acym_escapeDB($settings['element_tab']);
162 - }
163 -
164 - if (!empty($filters)) {
165 - $query .= ' WHERE ('.implode(') AND (', $filters).')';
166 - if (!acym_isAdmin()) {
167 - unset($filters['list']);
168 - }
169 - $queryCount .= ' WHERE ('.implode(') AND (', $filters).')';
170 - }
171 -
172 - if (!empty($settings['ordering']) && !empty($settings['ordering_sort_order'])) {
173 - $query .= ' ORDER BY mail.'.acym_secureDBColumn($settings['ordering']).' '.acym_secureDBColumn(strtoupper($settings['ordering_sort_order']));
174 - }
175 -
176 - if (empty($settings['offset']) || $settings['offset'] < 0) {
177 - $settings['offset'] = 0;
178 - }
179 -
180 - if (empty($settings['elementsPerPage']) || $settings['elementsPerPage'] < 1) {
181 - $pagination = new PaginationHelper();
182 - $settings['elementsPerPage'] = $pagination->getListLimit();
183 - }
184 -
185 - $results['elements'] = $this->decode(acym_loadObjectList($query, '', $settings['offset'], $settings['elementsPerPage']));
186 - $results['total'] = acym_loadObject($queryCount);
187 -
188 - if (!empty($settings['element_tab'])) {
189 - $this->getAllListIdsForWelcomeUnsub($results['elements'], $settings['element_tab']);
190 - }
191 -
192 - $results['status'] = [];
193 -
194 - if (!empty($settings['element_tab'])) {
195 - $urlClickClass = new UrlClickClass();
196 - for ($i = 0 ; $i < count($results['elements']) ; $i++) {
197 - $results['elements'][$i]->open = 0;
198 - if (!empty($results['elements'][$i]->subscribers)) {
199 - $results['elements'][$i]->open = number_format($results['elements'][$i]->open_unique / $results['elements'][$i]->subscribers * 100, 2);
200 -
201 - $clicksNb = $urlClickClass->getNumberUsersClicked($results['elements'][$i]->id);
202 - $results['elements'][$i]->click = number_format($clicksNb / $results['elements'][$i]->subscribers * 100, 2);
203 - }
204 - }
205 - }
206 -
207 - return $results;
208 - }
209 -
210 - private function getAllListIdsForWelcomeUnsub(&$elements, $type)
211 - {
212 - if (empty($elements)) return true;
213 - $column = $type == self::TYPE_WELCOME ? 'welcome_id' : 'unsubscribe_id';
214 -
215 - foreach ($elements as $key => $element) {
216 - $elements[$key]->lists = acym_loadObjectList('SELECT color, name FROM #__acym_list WHERE '.$column.' = '.intval($element->id));
217 - }
218 -
219 - return true;
220 - }
221 -
222 - public function getAll(?string $key = null): array
223 - {
224 - $allMails = parent::getAll($key);
225 -
226 - return $this->decode($allMails);
227 - }
228 -
229 - public function getOneById($id, $needTranslatedSettings = false)
230 - {
231 - $mail = $this->decode(acym_loadObject('SELECT * FROM #__acym_mail WHERE id = '.intval($id)));
232 -
233 - if (!empty($mail)) {
234 - $tagsClass = new TagClass();
235 - $mail->tags = $tagsClass->getAllTagsByElementId(TagClass::TYPE_MAIL, intval($id));
236 - }
237 -
238 - if (isset($mail->access) && !is_array($mail->access)) $mail->access = explode(',', $mail->access);
239 -
240 - if (!empty($mail->parent_id) && $needTranslatedSettings) {
241 - $this->getTranslatedSettingsMail($mail);
242 - }
243 -
244 - return $mail;
245 - }
246 -
247 - private function getTranslatedSettingsMail(&$mail)
248 - {
249 - $parentMailTranslation = acym_loadResult('SELECT translation FROM #__acym_mail WHERE id = '.intval($mail->parent_id));
250 - $parentMailTranslation = empty($parentMailTranslation) ? [] : json_decode($parentMailTranslation, true);
251 -
252 - $translationConfig = $this->config->get('sender_info_translation', '');
253 - $translationConfig = empty($translationConfig) ? [] : json_decode($translationConfig, true);
254 -
255 - if (!empty($parentMailTranslation[$mail->language])) {
256 - $senderTranslation = $parentMailTranslation[$mail->language];
257 - } elseif (!empty($translationConfig[$mail->language])) {
258 - $senderTranslation = $translationConfig[$mail->language];
259 - $senderTranslation['reply_to_email'] = $senderTranslation['replyto_email'];
260 - $senderTranslation['reply_to_name'] = $senderTranslation['replyto_name'];
261 - } else {
262 - return $mail;
263 - }
264 -
265 - $mail->from_name = $senderTranslation['from_name'];
266 - $mail->from_email = $senderTranslation['from_email'];
267 - $mail->reply_to_name = $senderTranslation['reply_to_name'];
268 - $mail->reply_to_email = $senderTranslation['reply_to_email'];
269 -
270 - return $mail;
271 - }
272 -
273 - public function getOneByName(string $name, bool $needTranslatedSettings = false, string $type = '')
274 - {
275 - $query = 'SELECT * FROM #__acym_mail WHERE `parent_id` IS NULL AND `name` = '.acym_escapeDB(acym_utf8Encode($name));
276 - if (!empty($type)) {
277 - $query .= ' AND `type` = '.acym_escapeDB($type);
278 - }
279 -
280 - $mail = $this->decode(acym_loadObject($query));
281 -
282 - if (!empty($mail)) {
283 - $tagsClass = new TagClass();
284 - $mail->tags = $tagsClass->getAllTagsByElementId(TagClass::TYPE_MAIL, intval($mail->id));
285 - }
286 -
287 - if (!empty($mail->parent_id) && $needTranslatedSettings) {
288 - $this->getTranslatedSettingsMail($mail);
289 - }
290 -
291 - return $mail;
292 - }
293 -
294 - public function getMailsByType(?string $typeMail, array $settings)
295 - {
296 - if (empty($settings['key'])) {
297 - $settings['key'] = '';
298 - }
299 - if (empty($settings['offset'])) {
300 - $settings['offset'] = 0;
301 - }
302 - if (empty($settings['mailsPerPage'])) {
303 - $settings['mailsPerPage'] = 12;
304 - }
305 - $search = $settings['filters']['search'] ?? '';
306 -
307 - $query = 'SELECT * FROM #__acym_mail AS mail';
308 - $queryCount = 'SELECT count(*) FROM #__acym_mail AS mail';
309 -
310 - $filters = [];
311 - if (!empty($typeMail)) {
312 - $filters[] = 'mail.type = '.acym_escapeDB($typeMail);
313 - }
314 -
315 - if (!empty($search)) {
316 - $filters[] = 'mail.name LIKE '.acym_escapeDB('%'.$search.'%');
317 - }
318 -
319 - if (!empty($filters)) {
320 - $query .= ' WHERE ('.implode(') AND (', $filters).')';
321 - $queryCount .= ' WHERE ('.implode(') AND (', $filters).')';
322 - }
323 -
324 - $query .= ' ORDER BY id DESC';
325 -
326 - $results['mails'] = $this->decode(acym_loadObjectList($query, $settings['key'], $settings['offset'], $settings['mailsPerPage']));
327 - $results['total'] = acym_loadResult($queryCount);
328 -
329 - return $results;
330 - }
331 -
332 - public function getAllListsWithCountSubscribersByMailIds($ids)
333 - {
334 - acym_arrayToInteger($ids);
335 - if (empty($ids)) {
336 - return [];
337 - }
338 -
339 - $query = 'SELECT mailLists.list_id, mailLists.mail_id, list.*, COUNT(userLists.user_id) AS subscribers
340 - FROM #__acym_mail_has_list AS mailLists
341 - JOIN #__acym_list AS list ON mailLists.list_id = list.id
342 - LEFT JOIN #__acym_user_has_list AS userLists
343 - JOIN #__acym_user AS acyuser ON userLists.user_id = acyuser.id
344 - AND userLists.status = 1
345 - AND acyuser.active = 1 ';
346 -
347 - if ($this->config->get('require_confirmation', 1) == 1) {
348 - $query .= ' AND acyuser.confirmed = 1 ';
349 - }
350 -
351 - $query .= 'ON list.id = userLists.list_id
352 - WHERE mailLists.mail_id IN ('.implode(',', $ids).')
353 - GROUP BY mailLists.list_id, mailLists.mail_id';
354 -
355 - acym_query('SET SQL_BIG_SELECTS=1');
356 -
357 - return acym_loadObjectList($query);
358 - }
359 -
360 - public function getAllListsByMailIds($ids)
361 - {
362 - acym_arrayToInteger($ids);
363 - if (empty($ids)) {
364 - return [];
365 - }
366 -
367 - $query = 'SELECT mailLists.mail_id, list.name, list.color
368 - FROM #__acym_mail_has_list AS mailLists
369 - JOIN #__acym_list AS list ON mailLists.list_id = list.id
370 - WHERE mailLists.mail_id IN ('.implode(',', $ids).')';
371 -
372 - return acym_loadObjectList($query);
373 - }
374 -
375 - public function getAllListsByMailId($id)
376 - {
377 - if (is_array($id)) $id = $id[0];
378 -
379 - $mail = $this->getOneById($id);
380 - if (empty($mail)) return [];
381 -
382 - if (self::TYPE_WELCOME === $mail->type) {
383 - $query = 'SELECT * FROM #__acym_list WHERE welcome_id = '.intval($id);
384 - } elseif (self::TYPE_FOLLOWUP === $mail->type) {
385 - $query = 'SELECT list.* FROM #__acym_followup_has_mail AS followup_mail
386 - JOIN #__acym_followup AS followup ON followup.id = followup_mail.followup_id AND followup_mail.mail_id = '.intval($id).'
387 - JOIN #__acym_list AS list ON list.id = followup.list_id';
388 - } else {
389 - $query = 'SELECT list.*
390 - FROM #__acym_mail_has_list AS mailLists
391 - JOIN #__acym_mail AS mail ON (mailLists.mail_id = mail.id OR mailLists.mail_id = mail.parent_id) AND mail.id = '.intval($id).'
392 - JOIN #__acym_list AS list ON mailLists.list_id = list.id';
393 - }
394 -
395 - return acym_loadObjectList($query, 'id');
396 - }
397 -
398 - public function getAllListsByMailIdAndUserId($mailId, $userId)
399 - {
400 - if (empty($mailId) || empty($userId)) return [];
401 -
402 - $query = 'SELECT list.* FROM #__acym_list AS list';
403 - $query .= ' JOIN #__acym_user_has_list AS userlist ON list.id = userlist.list_id AND userlist.user_id = '.intval($userId);
404 - $query .= ' JOIN #__acym_mail_has_list AS maillist ON maillist.list_id = list.id AND maillist.mail_id = '.intval($mailId);
405 -
406 - return acym_loadObjectList($query);
407 - }
408 -
409 - public function save($mailToSave)
410 - {
411 - $mail = clone $mailToSave;
412 -
413 - if (isset($mail->tags)) {
414 - $tags = $mail->tags;
415 - unset($mail->tags);
416 - }
417 -
418 - if (empty($mail->id)) {
419 - $mail->creation_date = acym_date('now', 'Y-m-d H:i:s', false);
420 - if (empty($mail->creator_id)) $mail->creator_id = acym_currentUserId();
421 - }
422 -
423 - $mail = $this->encode($mail);
424 -
425 - $mail->autosave = null;
426 -
427 -
428 - if (isset($mail->thumbnail) && ((empty($mail->thumbnail) && !is_null($mail->thumbnail)) || strpos($mail->thumbnail, 'data:image/png;base64') !== false)) {
429 - unset($mail->thumbnail);
430 - }
431 -
432 - if (!isset($mail->access)) {
433 - $mail->access = '';
434 - }
435 -
436 - foreach ($mail as $oneAttribute => $value) {
437 - if (empty($value) || in_array($oneAttribute, ['thumbnail', 'settings'])) {
438 - continue;
439 - }
440 -
441 - if ($oneAttribute === 'access' && is_array($mail->$oneAttribute)) {
442 - $value = ','.trim(implode(',', $mail->$oneAttribute), ',').',';
443 - $mail->$oneAttribute = $value;
444 - }
445 -
446 - if (is_array($value)) {
447 - $mail->$oneAttribute = json_encode($value);
448 - }
449 -
450 - if (in_array($oneAttribute, ['body', 'headers'])) {
451 - $mail->$oneAttribute = preg_replace('#<input[^>]*value="[^"]*"[^>]*>#Uis', '', $mail->$oneAttribute);
452 - $mail->$oneAttribute = preg_replace('#<script.*</script>#Uis', '', $mail->$oneAttribute);
453 -
454 - $mail->$oneAttribute = str_replace(' contenteditable="true"', '', $mail->$oneAttribute);
455 - } else {
456 - $mail->$oneAttribute = strip_tags($mail->$oneAttribute);
457 - }
458 - }
459 -
460 - $mailID = parent::save($mail);
461 -
462 - if (!empty($mailID) && isset($tags)) {
463 - $tagClass = new TagClass();
464 - $tagClass->setTags(TagClass::TYPE_MAIL, intval($mailID), $tags);
465 - }
466 -
467 - return $mailID;
468 - }
469 -
470 - public function autoSave($mail, $language = 'main')
471 - {
472 - if (empty($mail->id)) return false;
473 - $mail->autosave = str_replace(' contenteditable="true"', '', $mail->autosave);
474 -
475 - if (acym_isMultilingual() && $language !== 'main') {
476 - $translationId = $this->getTranslationId($mail->id, $language);
477 - if (empty($translationId)) {
478 - $parentCopy = $this->getOneById($mail->id);
479 - if (empty($parentCopy)) return false;
480 -
481 - unset($parentCopy->id);
482 - $parentCopy->parent_id = $mail->id;
483 - $parentCopy->language = $language;
484 - $translationId = $this->save($parentCopy);
485 - }
486 - $mail->id = $translationId;
487 - }
488 -
489 - $mail = $this->encode($mail);
490 -
491 - return parent::save($mail);
492 - }
493 -
494 - public function delete($elements)
495 - {
496 - if (empty($elements)) return 0;
497 - if (!is_array($elements)) $elements = [$elements];
498 -
499 - $this->deleteMediaFolder($elements);
500 - acym_arrayToInteger($elements);
501 -
502 - $favoriteTemplate = (int)$this->config->get('favorite_template', 0);
503 - if (in_array($favoriteTemplate, $elements)) {
504 - $this->config->save(['favorite_template' => 0]);
505 - }
506 -
507 - $allThumbnailToDelete = acym_loadResultArray('SELECT DISTINCT thumbnail FROM #__acym_mail WHERE id IN ('.implode(',', $elements).')');
508 -
509 - $translations = acym_loadResultArray('SELECT id FROM #__acym_mail WHERE parent_id IN ('.implode(',', $elements).')');
510 - $elements = array_merge($elements, $translations);
511 - if (!empty($translations)) {
512 - acym_query('UPDATE #__acym_mail SET `parent_id` = null WHERE `id` IN ('.implode(',', $translations).')');
513 - }
514 -
515 - acym_query('UPDATE #__acym_list SET welcome_id = null WHERE welcome_id IN ('.implode(',', $elements).')');
516 - acym_query('UPDATE #__acym_list SET unsubscribe_id = null WHERE unsubscribe_id IN ('.implode(',', $elements).')');
517 - acym_query('DELETE FROM #__acym_queue WHERE mail_id IN ('.implode(',', $elements).')');
518 - acym_query('DELETE FROM #__acym_mail_has_list WHERE mail_id IN ('.implode(',', $elements).')');
519 - acym_query('DELETE FROM #__acym_tag WHERE `type` = "mail" AND `id_element` IN ('.implode(',', $elements).')');
520 - acym_query('DELETE FROM #__acym_user_stat WHERE mail_id IN ('.implode(',', $elements).')');
521 - acym_query('DELETE FROM #__acym_url_click WHERE mail_id IN ('.implode(',', $elements).')');
522 - acym_query('DELETE FROM #__acym_mail_stat WHERE mail_id IN ('.implode(',', $elements).')');
523 - acym_query('DELETE FROM #__acym_followup_has_mail WHERE mail_id IN ('.implode(',', $elements).')');
524 - acym_query('DELETE FROM #__acym_mail_archive WHERE mail_id IN ('.implode(',', $elements).')');
525 -
526 - $return = parent::delete($elements);
527 -
528 - $this->deleteUnusedThumbnails($allThumbnailToDelete);
529 -
530 - return $return;
531 - }
532 -
533 - public function deleteMediaFolder($elements)
534 - {
535 - if (empty($elements)) return;
536 -
537 - acym_arrayToInteger($elements);
538 - $results = acym_loadResultArray('SELECT mail_settings FROM #__acym_mail WHERE mail_settings IS NOT NULL AND id IN ('.implode(',', $elements).')');
539 -
540 - foreach ($results as $template) {
541 - $settings = json_decode($template, true);
542 -
543 - if (empty($settings['media_folder']) || !file_exists(ACYM_TEMPLATE.$settings['media_folder'])) continue;
544 - acym_deleteFolder(ACYM_TEMPLATE.$settings['media_folder']);
545 - }
546 - }
547 -
548 - public function deleteUnusedThumbnails($thumbnails)
549 - {
550 - if (empty($thumbnails)) return;
551 -
552 - if (!is_array($thumbnails)) $thumbnails = [$thumbnails];
553 - foreach ($thumbnails as $key => $oneThumb) {
554 - $thumbnails[$key] = acym_escapeDB($oneThumb);
555 - }
556 -
557 - $stillUsedThumbnails = acym_loadResultArray('SELECT thumbnail FROM #__acym_mail WHERE thumbnail IN ('.implode(',', $thumbnails).')');
558 - $thumbnailToDelete = array_diff($thumbnails, $stillUsedThumbnails);
559 - foreach ($thumbnailToDelete as $one) {
560 - if (!empty($one) && file_exists(ACYM_UPLOAD_FOLDER_THUMBNAIL.$one)) {
561 - unlink(ACYM_UPLOAD_FOLDER_THUMBNAIL.$one);
562 - }
563 - }
564 - }
565 -
566 - public function deleteOneAttachment($mailId, $idAttachment)
567 - {
568 - $mailId = intval($mailId);
569 - if (empty($mailId)) {
570 - return false;
571 - }
572 - $mail = $this->getOneById($mailId);
573 -
574 - $attachments = $mail->attachments;
575 - if (empty($attachments)) {
576 - return false;
577 - }
578 - $decodedAttach = json_decode($attachments, true);
579 - unset($decodedAttach[$idAttachment]);
580 - $newAttachments = [];
581 - if (!empty($decodedAttach)) {
582 - foreach ($decodedAttach as $oneAttach) {
583 - $newAttachments[] = $oneAttach;
584 - }
585 - }
586 - $attachDb = json_encode($newAttachments);
587 -
588 - return acym_query('UPDATE #__acym_mail SET attachments = '.acym_escapeDB($attachDb).' WHERE id = '.intval($mailId).' OR parent_id = '.intval($mailId));
589 - }
590 -
591 - public function createTemplateFile($id)
592 - {
593 - if (empty($id)) {
594 - return '';
595 - }
596 - $cssfile = ACYM_TEMPLATE.'css'.DS.'template_'.$id.'.css';
597 -
598 - $template = $this->getOneById($id);
599 - if (empty($template->id)) {
600 - return '';
601 - }
602 - $css = $this->buildCSS($template->stylesheet);
603 -
604 - if (empty($css)) {
605 - return '';
606 - }
607 -
608 - acym_createDir(ACYM_TEMPLATE.'css');
609 -
610 - if (acym_writeFile($cssfile, $css)) {
611 - return $cssfile;
612 - } else {
613 - acym_enqueueMessage('Could not create the file '.$cssfile, 'error');
614 -
615 - return '';
616 - }
617 - }
618 -
619 - public function buildCSS($stylesheet): string
620 - {
621 - if (empty($stylesheet)) {
622 - return '';
623 - }
624 -
625 - $inline = '';
626 -
627 - if (preg_match_all('#@import[^;]*;#is', $stylesheet, $results)) {
628 - foreach ($results[0] as $oneResult) {
629 - $inline .= trim($oneResult)."\n";
630 - $stylesheet = str_replace($oneResult, '', $stylesheet);
631 - }
632 - }
633 -
634 - $inline .= $stylesheet;
635 -
636 - return $inline;
637 - }
638 -
639 - public function doupload(): bool
640 - {
641 - $zipFilePath = $this->uploadTemplate();
642 - if (empty($zipFilePath)) {
643 - return false;
644 - }
645 -
646 - $templateFolder = $this->extractTemplate($zipFilePath);
647 - if (empty($templateFolder)) {
648 - return false;
649 - }
650 -
651 - if (!$this->installExtractedTemplate($templateFolder)) {
652 - return false;
653 - }
654 -
655 - return true;
656 - }
657 -
658 - private function uploadTemplate()
659 - {
660 - $importFile = acym_getVar('file', 'uploadedfile', '', 'files');
661 -
662 - $fileError = $importFile['error'];
663 - if ($fileError > 0) {
664 - switch ($fileError) {
665 - case 1:
666 - acym_enqueueMessage(acym_translation('ACYM_FILE_UPLOAD_ERROR_1'), 'error');
667 -
668 - return false;
669 - case 2:
670 - acym_enqueueMessage(acym_translation('ACYM_FILE_UPLOAD_ERROR_2'), 'error');
671 -
672 - return false;
673 - case 3:
674 - acym_enqueueMessage(acym_translation('ACYM_FILE_UPLOAD_ERROR_3'), 'error');
675 -
676 - return false;
677 - case 4:
678 - acym_enqueueMessage(acym_translation('ACYM_FILE_UPLOAD_ERROR_4'), 'error');
679 -
680 - return false;
681 - default:
682 - acym_enqueueMessage(acym_translationSprintf('ACYM_FILE_UPLOAD_ERROR_5', $fileError), 'error');
683 -
684 - return false;
685 - }
686 - }
687 - if (empty($importFile['name'])) {
688 - acym_enqueueMessage(acym_translation('ACYM_BROWSE_FILE'), 'error');
689 -
690 - return false;
691 - }
692 -
693 - $uploadPath = acym_cleanPath(ACYM_ROOT.ACYM_MEDIA_FOLDER.'templates');
694 -
695 - if (!is_writable($uploadPath)) {
696 - @chmod($uploadPath, '0755');
697 - if (!is_writable($uploadPath)) {
698 - acym_enqueueMessage(acym_translationSprintf('ACYM_WRITABLE_FOLDER', $uploadPath), 'warning');
699 - }
700 - }
701 -
702 - if (!(bool)ini_get('file_uploads')) {
703 - acym_enqueueMessage(acym_translationSprintf('ACYM_FILE_UPLOAD_ERROR_6'), 'error');
704 -
705 - return false;
706 - }
707 -
708 - if (!extension_loaded('zlib')) {
709 - acym_raiseError(500, acym_translation('ACYM_MISSING_ZLIB'));
710 -
711 - return false;
712 - }
713 -
714 - $filename = strtolower(acym_makeSafeFile($importFile['name']));
715 - $extension = strtolower(substr($filename, strrpos($filename, '.') + 1));
716 -
717 - $allowedFileType = true;
718 - if ($extension !== 'zip') {
719 - $allowedFileType = false;
720 - } elseif (!in_array($importFile['type'], ['application/zip', 'application/x-zip-compressed'])) {
721 - $allowedFileType = false;
722 - } elseif (function_exists('mime_content_type') && !in_array(mime_content_type($importFile['tmp_name']), ['application/zip', 'application/x-zip-compressed'])) {
723 - $allowedFileType = false;
724 - }
725 -
726 - if (!$allowedFileType) {
727 - acym_enqueueMessage(acym_translationSprintf('ACYM_ACCEPTED_TYPE', $extension, 'zip'), 'error');
728 -
729 - return false;
730 - }
731 -
732 - if (class_exists('ZipArchive')) {
733 - $zip = new \ZipArchive();
734 - if (filesize($importFile['tmp_name']) > self::MAX_ALLOWED_TEMPLATE_SIZE || !$zip->open($importFile['tmp_name']) || $zip->count() > self::MAX_ALLOWED_TEMPLATE_FILES) {
735 - acym_enqueueMessage(acym_translation('ACYM_UPLOADED_ARCHIVE_NOT_ALLOWED'), 'error');
736 -
737 - return false;
738 - }
739 -
740 - $zip->close();
741 - }
742 -
743 - $tmpPath = acym_getCMSConfig('tmp_path', ACYM_MEDIA.'tmp'.DS);
744 - $zipFilePath = acym_cleanPath($tmpPath.DS.$filename);
745 -
746 - $uploaded = acym_uploadFile($importFile['tmp_name'], $zipFilePath);
747 - if (!$uploaded) {
748 - acym_enqueueMessage(acym_translationSprintf('ACYM_FILE_UPLOAD_ERROR_7', $importFile['tmp_name'], $zipFilePath), 'error');
749 -
750 - return false;
751 - }
752 -
753 - return $zipFilePath;
754 - }
755 -
756 - public function extractTemplate($zipFilePath, $deleteZip = true)
757 - {
758 - $extractdir = acym_cleanPath(dirname($zipFilePath).DS.uniqid().uniqid().uniqid().'_template');
759 -
760 - $result = acym_extractArchive($zipFilePath, $extractdir);
761 -
762 - if (!$result) {
763 - acym_enqueueMessage(acym_translationSprintf('ACYM_FILE_UPLOAD_ERROR_9', $zipFilePath, $extractdir), 'error');
764 -
765 - return false;
766 - }
767 -
768 - if ($deleteZip) {
769 - acym_deleteFile($zipFilePath);
770 - }
771 -
772 - $allFiles = acym_getFiles($extractdir, '.', true, true, [], []);
773 - foreach ($allFiles as $oneFile) {
774 - if (function_exists('mime_content_type')) {
775 - $fileType = mime_content_type($oneFile);
776 - if (in_array($fileType, self::ALLOWED_TEMPLATE_FILE_TYPES) && preg_match('#\.(jpg|gif|png|jpeg|ico|bmp|html|htm|css|webp)$#i', $oneFile)) {
777 - continue;
778 - }
779 - } elseif (preg_match('#\.(jpg|gif|png|jpeg|ico|bmp|html|htm|css|webp)$#i', $oneFile)) {
780 - continue;
781 - }
782 -
783 - if (acym_deleteFile($oneFile)) {
784 - acym_enqueueMessage(acym_translationSprintf('ACYM_FILE_UPLOAD_ERROR_8', $oneFile), 'warning');
785 - }
786 - }
787 -
788 - return $extractdir;
789 - }
790 -
791 - public function installExtractedTemplate($templateFolder)
792 - {
793 - if ($this->detecttemplates($templateFolder)) {
794 - $messages = $this->templateNames;
795 - array_unshift($messages, acym_translationSprintf('ACYM_TEMPLATES_INSTALL', count($this->templateNames)));
796 - acym_enqueueMessage($messages);
797 - if (is_dir($templateFolder)) acym_deleteFolder($templateFolder);
798 -
799 - return true;
800 - }
801 -
802 - acym_enqueueMessage(acym_translationSprintf('ACYM_FILE_UPLOAD_ERROR_10'), 'error');
803 - if (is_dir($templateFolder)) acym_deleteFolder($templateFolder);
804 -
805 - return false;
806 - }
807 -
808 - public function detecttemplates($folder)
809 - {
810 - $allFiles = acym_getFiles($folder);
811 - if (!empty($allFiles)) {
812 - foreach ($allFiles as $oneFile) {
813 - if (preg_match('#^.*(html|htm)$#i', $oneFile)) {
814 - if ($this->_installtemplate($folder.DS.$oneFile)) return true;
815 - }
816 - }
817 - }
818 -
819 - $status = false;
820 - $allFolders = acym_getFolders($folder);
821 - if (!empty($allFolders)) {
822 - foreach ($allFolders as $oneFolder) {
823 - $status = $this->detecttemplates($folder.DS.$oneFolder) || $status;
824 - }
825 - }
826 -
827 - return $status;
828 - }
829 -
830 - private function _installtemplate($filepath)
831 - {
832 - $fileContent = acym_fileGetContent($filepath);
833 -
834 - $newTemplate = new \stdClass();
835 - $newTemplate->name = trim(preg_replace('#[^a-z0-9]#i', ' ', substr(dirname($filepath), strpos($filepath, '_template'))));
836 - if (preg_match('#< *title[^>]*>(.*)< */ *title *>#Uis', $fileContent, $results) && !empty($results[1])) $newTemplate->name = $results[1];
837 -
838 - if (preg_match('#< *meta *name="fromname" *content="([^"]*)"#Uis', $fileContent, $results) && !empty($results[1])) $newTemplate->fromname = $results[1];
839 - if (preg_match('#< *meta *name="fromemail" *content="([^"]*)"#Uis', $fileContent, $results) && !empty($results[1])) $newTemplate->fromemail = $results[1];
840 - if (preg_match('#< *meta *name="replyname" *content="([^"]*)"#Uis', $fileContent, $results) && !empty($results[1])) $newTemplate->replyname = $results[1];
841 - if (preg_match('#< *meta *name="replyemail" *content="([^"]*)"#Uis', $fileContent, $results) && !empty($results[1])) $newTemplate->replyemail = $results[1];
842 - if (preg_match('#< *meta *name="subject" *content="([^"]*)"#Uis', $fileContent, $results) && !empty($results[1])) $newTemplate->subject = $results[1];
843 - if (preg_match('#< *meta *name="settings" *content="([^"]*)"#Uis', $fileContent, $results) && !empty($results[1])) {
844 - $newTemplate->settings = htmlspecialchars_decode($results[1]);
845 - }
846 -
847 - $newFolder = preg_replace('#[^a-z0-9]#i', '_', strtolower($newTemplate->name));
848 - $newTemplateFolder = $newFolder;
849 - $i = 1;
850 - while (is_dir(ACYM_TEMPLATE.$newTemplateFolder)) {
851 - $newTemplateFolder = $newFolder.'_'.$i;
852 - $i++;
853 - }
854 - $newTemplate->mail_settings = ['media_folder' => $newTemplateFolder];
855 -
856 - $moveResult = acym_copyFolder(dirname($filepath), ACYM_TEMPLATE.$newTemplateFolder);
857 - if ($moveResult !== true) {
858 - acym_display([acym_translationSprintf('ACYM_ERROR_COPYING_FOLDER_TO', dirname($filepath), ACYM_TEMPLATE.$newTemplateFolder), $moveResult], 'error');
859 -
860 - return false;
861 - }
862 -
863 - if (!file_exists(ACYM_TEMPLATE.$newTemplateFolder.DS.'index.html')) {
864 - $indexFile = '<html><body bgcolor="#FFFFFF"></body></html>';
865 - acym_writeFile(ACYM_TEMPLATE.$newTemplateFolder.DS.'index.html', $indexFile);
866 - }
867 -
868 - $fileContent = str_replace(
869 - [
870 - 'src="./',
871 - 'src="../',
872 - 'src="images/',
873 - 'url("images/',
874 - 'url(&quot;images/',
875 - ],
876 - [
877 - 'src="'.ACYM_TEMPLATE_URL.$newTemplateFolder.'/',
878 - 'src="'.ACYM_TEMPLATE_URL,
879 - 'src="'.ACYM_TEMPLATE_URL.$newTemplateFolder.'/images/',
880 - 'url("'.ACYM_TEMPLATE_URL.$newTemplateFolder.'/images/',
881 - 'url(&quot;'.ACYM_TEMPLATE_URL.$newTemplateFolder.'/images/',
882 - ],
883 - $fileContent
884 - );
885 -
886 - $fileContent = preg_replace('#(src|background)[ ]*=[ ]*\"(?!(https?://|/))(?:\.\./|\./)?#', '$1="'.ACYM_TEMPLATE_URL.$newTemplateFolder.'/', $fileContent);
887 -
888 - if (preg_match('#< *body[^>]*>(.*)< */ *body *>#Uis', $fileContent, $results)) {
889 - $newTemplate->body = $results[1];
890 - } else {
891 - $newTemplate->body = $fileContent;
892 - }
893 -
894 - $newTemplate->stylesheet = '';
895 - if (preg_match_all('#< *style[^>]*>(.*)< */ *style *>#Uis', $fileContent, $results)) {
896 - $newTemplate->stylesheet .= preg_replace('#(<!--|-->)#s', '', implode("\n", $results[1]));
897 - }
898 - $cssFiles = [];
899 - $cssFiles[ACYM_TEMPLATE.$newTemplateFolder] = acym_getFiles(ACYM_TEMPLATE.$newTemplateFolder, '\.css$');
900 - $subFolders = acym_getFolders(ACYM_TEMPLATE.$newTemplateFolder);
901 - foreach ($subFolders as $oneFolder) {
902 - $cssFiles[ACYM_TEMPLATE.$newTemplateFolder.DS.$oneFolder] = acym_getFiles(ACYM_TEMPLATE.$newTemplateFolder.DS.$oneFolder, '\.css$');
903 - }
904 -
905 - foreach ($cssFiles as $cssFolder => $cssFile) {
906 - if (empty($cssFile)) continue;
907 - $newTemplate->stylesheet .= "\n".acym_fileGetContent($cssFolder.DS.reset($cssFile));
908 - }
909 -
910 - if (!empty($newTemplate->stylesheet)) {
911 - if (preg_match('#body *\{[^\}]*background-color:([^;\}]*)[;\}]#Uis', $newTemplate->stylesheet, $backgroundresults)) {
912 - $newTemplate->stylesheet = preg_replace('#(body *\{[^\}]*)background-color:[^;\}]*[;\}]#Uis', '$1', $newTemplate->stylesheet);
913 - }
914 -
915 - $quickstyle = [
916 - 'tag_h1' => 'h1',
917 - 'tag_h2' => 'h2',
918 - 'tag_h3' => 'h3',
919 - 'tag_h4' => 'h4',
920 - 'tag_h5' => 'h5',
921 - 'tag_h6' => 'h6',
922 - 'tag_a' => 'a',
923 - 'tag_ul' => 'ul',
924 - 'tag_li' => 'li',
925 - 'acym_unsub' => '\.acym_unsub',
926 - 'acym_online' => '\.acym_online',
927 - 'acym_title' => '\.acym_title',
928 - 'acym_content' => '\.acym_content',
929 - 'acym_readmore' => '\.acym_readmore',
930 - ];
931 - foreach ($quickstyle as $styledb => $oneStyle) {
932 - if (preg_match('#[^a-z\. ,] *'.$oneStyle.' *{([^}]*)}#Uis', $newTemplate->stylesheet, $quickstyleresults)) {
933 - $newTemplate->stylesheet = str_replace($quickstyleresults[0], '', $newTemplate->stylesheet);
934 - }
935 - }
936 - }
937 -
938 - $foldersForPicts = [$newTemplateFolder];
939 - $otherFolders = acym_getFolders(ACYM_TEMPLATE.$newTemplateFolder);
940 - foreach ($otherFolders as $oneFold) {
941 - $foldersForPicts[] = $newTemplateFolder.DS.$oneFold;
942 - }
943 - $allPictures = [];
944 - foreach ($foldersForPicts as $oneFolder) {
945 - $allPictures[$oneFolder] = acym_getFiles(ACYM_TEMPLATE.$oneFolder);
946 - }
947 -
948 - $uploadsFolder = ACYM_UPLOAD_FOLDER_THUMBNAIL;
949 -
950 - $newConfig = new \stdClass();
951 - $thumbNb = intval($this->config->get('numberThumbnail', 2));
952 -
953 - foreach ($allPictures as $folder => $pictfolders) {
954 - foreach ($pictfolders as $onePict) {
955 - if (!preg_match('#\.(jpg|gif|png|jpeg|ico|bmp)$#i', $onePict)) continue;
956 - if (preg_match('#(thumbnail|screenshot|muestra)#i', $onePict)) {
957 - $thumbNb++;
958 - $newNamePict = 'thumbnail_'.$thumbNb.'.png';
959 - copy(ACYM_TEMPLATE.str_replace(DS, '/', $folder).'/'.$onePict, $uploadsFolder.$newNamePict);
960 - $newTemplate->thumbnail = $newNamePict;
961 - }
962 - }
963 - }
964 -
965 - $newConfig->numberThumbnail = $thumbNb;
966 - $this->config->save($newConfig);
967 -
968 - $newTemplate->drag_editor = strpos($newTemplate->body, 'acym__wysid__template__content') !== false ? 1 : 0;
969 - $newTemplate->type = self::TYPE_TEMPLATE;
970 - $newTemplate->creation_date = acym_date('now', 'Y-m-d H:i:s', false);
971 -
972 - $tempid = $this->save($newTemplate);
973 -
974 - $this->templateId = $tempid;
975 - $this->templateNames[] = $newTemplate->name;
976 -
977 - return true;
978 - }
979 -
980 - public function sendAutomation($mailId, $userIds, $sendingDate, $automationAdmin = [])
981 - {
982 - if (empty($mailId)) return acym_translationSprintf('ACYM_EMAILS_ADDED_QUEUE', 0);
983 - if (empty($sendingDate)) return acym_translation('ACYM_WRONG_DATE');
984 - if (empty($userIds)) return acym_translation('ACYM_USER_NOT_FOUND');
985 - acym_arrayToInteger($userIds);
986 -
987 - if (isset($automationAdmin['automationAdmin']) && $automationAdmin['automationAdmin']) {
988 - $userClass = new UserClass();
989 - $mail = $this->getOneById($mailId);
990 - $user = $userClass->getOneById($automationAdmin['user_id']);
991 -
992 - if (empty($mail) || empty($user)) return false;
993 -
994 - $mailerHelper = new MailerHelper();
995 - $pluginHelper = new PluginHelper();
996 - $extractedTags = $pluginHelper->extractTags($mail, 'subscriber');
997 - if (!empty($extractedTags)) {
998 - foreach ($extractedTags as $dtext => $oneTag) {
999 - if (empty($oneTag->info) || $oneTag->info != 'current' || empty($user->{$oneTag->id})) continue;
1000 -
1001 - $mailerHelper->addParam(str_replace(['{', '}'], '', $dtext), $user->{$oneTag->id});
1002 - }
1003 - }
1004 -
1005 - if (!empty($automationAdmin['user_id'])) {
1006 - $userClass = new UserClass();
1007 - $user = $userClass->getOneById($automationAdmin['user_id']);
1008 - if (!empty($user)) {
1009 - $userField = $userClass->getAllUserFields($user);
1010 - foreach ($userField as $map => $value) {
1011 - $mailerHelper->addParam('user:'.$map, $value);
1012 - }
1013 - }
1014 - }
1015 -
1016 - $emailsSent = 0;
1017 - foreach ($userIds as $userId) {
1018 - if ($mailerHelper->sendOne($mail->id, $userId)) {
1019 - $emailsSent++;
1020 - }
1021 - }
1022 -
1023 - return $emailsSent;
1024 - }
1025 -
1026 - $result = acym_query(
1027 - 'INSERT IGNORE INTO #__acym_queue (`mail_id`, `user_id`, `sending_date`)
1028 - SELECT '.intval($mailId).', user.id, '.acym_escapeDB($sendingDate).'
1029 - FROM #__acym_user AS user
1030 - WHERE user.active = 1 AND user.id IN ('.implode(',', $userIds).')'
1031 - );
1032 -
1033 -
1034 - $mailStatClass = new MailStatClass();
1035 - $mailStat = $mailStatClass->getOneRowByMailId($mailId);
1036 -
1037 - $newMailStat = [
1038 - 'mail_id' => intval($mailId),
1039 - 'total_subscribers' => intval($result),
1040 - ];
1041 - if (empty($mailStat)) {
1042 - $newMailStat['send_date'] = $sendingDate;
1043 - }
1044 -
1045 - $mailStatClass->save($newMailStat);
1046 -
1047 - if ($result === 0) {
1048 - return acym_translation('ACYM_CAMPAIGN_ALREADY_QUEUED');
1049 - }
1050 -
1051 - return $result;
1052 - }
1053 -
1054 - public function encode($mails = [])
1055 - {
1056 - $isArray = true;
1057 - if (!is_array($mails)) {
1058 - $mails = [$mails];
1059 -
1060 - $isArray = false;
1061 - }
1062 -
1063 - $encodedMails = array_map([$this, 'removePoweredByAcyMailing'], $mails);
1064 -
1065 - $encodedMails = array_map([$this, 'utf8Encode'], $encodedMails);
1066 -
1067 - return $isArray ? $encodedMails : $encodedMails[0];
1068 - }
1069 -
1070 - public function decode($mails = [])
1071 - {
1072 - $isArray = true;
1073 - if (!is_array($mails)) {
1074 - $mails = [$mails];
1075 -
1076 - $isArray = false;
1077 - }
1078 -
1079 - $decodedMails = array_map([$this, 'utf8Decode'], $mails);
1080 -
1081 - $decodedMails = array_map([$this, 'addPoweredByAcyMailing'], $decodedMails);
1082 -
1083 - foreach ($decodedMails as $i => $oneMail) {
1084 - if (!isset($oneMail->access) || is_array($oneMail->access)) continue;
1085 - $decodedMails[$i]->access = empty($oneMail->access) ? '' : explode(',', $oneMail->access);
1086 - }
1087 -
1088 - return $isArray ? $decodedMails : $decodedMails[0];
1089 - }
1090 -
1091 - protected function utf8Decode($mail)
1092 - {
1093 - if (!empty($mail)) {
1094 - foreach (self::FIELDS_ENCODING as $oneField) {
1095 - if (in_array($oneField, $this->exceptKeysDecode)) {
1096 - continue;
1097 - }
1098 -
1099 - if (is_array($mail)) {
1100 - if (empty($mail[$oneField])) continue;
1101 - $value = &$mail[$oneField];
1102 - } else {
1103 - if (empty($mail->$oneField)) continue;
1104 - $value = &$mail->$oneField;
1105 - }
1106 -
1107 - $value = acym_utf8Decode($value);
1108 - }
1109 - }
1110 -
1111 - return $mail;
1112 - }
1113 -
1114 - protected function addPoweredByAcyMailing($mail)
1115 - {
1116 - if (empty($mail->body)) {
1117 - return $mail;
1118 - }
1119 -
1120 - if ($this->config->get('display_built_by', 0) != 1) {
1121 - if (strpos($mail->body, 'acym__powered_by_acymailing') !== false) {
1122 - $mailBodyDom = new \DOMDocument();
1123 - @$mailBodyDom->loadHTML('<?xml encoding="utf-8" ?>'.$mail->body);
1124 - $tables = $mailBodyDom->getElementsByTagName('table');
1125 - foreach ($tables as $table) {
1126 - if ($table->getAttribute('id') != 'acym__powered_by_acymailing') continue;
1127 - $table->parentNode->removeChild($table);
1128 - break;
1129 - }
1130 - $mail->body = $mailBodyDom->saveHTML();
1131 - }
1132 -
1133 - return $mail;
1134 - }
1135 -
1136 - if (strpos($mail->body, 'acym__powered_by_acymailing') !== false) {
1137 - return $mail;
1138 - }
1139 -
1140 - $isWysidEditor = strpos($mail->body, 'acym__wysid__template') !== false;
1141 - $urlPoweredByImage = ACYM_IMAGES.'editor/poweredby_black.png';
1142 -
1143 - if (!$isWysidEditor) {
1144 - $poweredByHTML = '<p id="acym__powered_by_acymailing">';
1145 - $poweredByHTML .= '<a href="'.ACYM_ACYMAILING_WEBSITE.'?utm_campaign=powered_by_v7&utm_source=acymailing_plugin&utm_medium=built_with_footer" target="blank">';
1146 - $poweredByHTML .= '<img alt="Email built with AcyMailing" height="40" width="199" style="height: 40px; width:199px; max-width: 100%; height: auto; box-sizing: border-box; padding: 0 5px; display: block; margin-left: auto; margin-right: auto;" src="'.$urlPoweredByImage.'"/>';
1147 - $poweredByHTML .= '</a></p>';
1148 -
1149 - $mail->body = $mail->body.$poweredByHTML;
1150 - } else {
1151 - $poweredByWYSID = '<table id="acym__powered_by_acymailing" class="row" bgcolor="#ffffff" style="background-color: transparent" cellpadding="0" cellspacing="0" border="0">
1152 - <tbody bgcolor style="background-color: inherit;">
1153 - <tr>
1154 - <th class="small-12 medium-12 large-12 columns" valign="top" style="height: auto;">
1155 - <table border="0" cellpadding="0" cellspacing="0"
1156 - style="min-height: 0px; display: table; height: auto;">
1157 - <tbody style="min-height: 0px; display: table-row-group;">
1158 - <tr
1159 - style="position: relative; top: inherit; left: inherit; right: inherit; bottom: inherit; height: auto;">
1160 - <td class="large-12">
1161 - <div style="position: relative;">
1162 - <p style="word-break: break-word; text-align: center;">
1163 - <a href="'.ACYM_ACYMAILING_WEBSITE.'?utm_campaign=powered_by_v7&utm_source=acymailing_plugin&utm_medium=built_with_footer" target="_blank">
1164 - <img src="'.$urlPoweredByImage.'"
1165 - title="poweredby" alt="Email built with AcyMailing"
1166 - style="height: 40px; width:199px; max-width: 100%; height: auto; box-sizing: border-box; padding: 0px 5px; display: inline-block; margin-left: auto; margin-right: auto;"
1167 - height="40" width="199">
1168 - </a>
1169 - </p>
1170 - </div>
1171 - </td>
1172 - </tr>
1173 - </tbody>
1174 - </table>
1175 - </th>
1176 - </tr>
1177 - </tbody>
1178 -</table>';
1179 -
1180 - $mailBodyDom = new \DOMDocument();
1181 - @$mailBodyDom->loadHTML('<?xml encoding="utf-8" ?>'.$mail->body);
1182 -
1183 - $htmlToAddDom = new \DOMDocument();
1184 - @$htmlToAddDom->loadHTML('<?xml encoding="utf-8" ?>'.$poweredByWYSID);
1185 - $tableToAdd = $htmlToAddDom->getElementById('acym__powered_by_acymailing');
1186 -
1187 - $tds = $mailBodyDom->getElementsByTagName('td');
1188 - foreach ($tds as $td) {
1189 - $classes = explode(' ', $td->getAttribute('class'));
1190 - if (!in_array('acym__wysid__row', $classes)) continue;
1191 - if (!empty($tableToAdd)) $td->appendChild($mailBodyDom->importNode($tableToAdd, true));
1192 - break;
1193 - }
1194 - $mail->body = $mailBodyDom->saveHTML();
1195 - }
1196 -
1197 - return $mail;
1198 - }
1199 -
1200 - protected function removePoweredByAcyMailing($mail)
1201 - {
1202 - if (empty($mail->body)) return $mail;
1203 -
1204 - if (strpos($mail->body, 'acym__wysid__template') !== false) return $mail;
1205 -
1206 - $regexPoweredByAcyMailing = '#<p id="acym__powered_by_acymailing.*<\/p>#U';
1207 -
1208 - $mail->body = preg_replace($regexPoweredByAcyMailing, '', $mail->body);
1209 -
1210 - return $mail;
1211 - }
1212 -
1213 - protected function utf8Encode($mail)
1214 - {
1215 - if (!empty($mail)) {
1216 - foreach (self::FIELDS_ENCODING as $oneField) {
1217 - if (is_array($mail)) {
1218 - if (empty($mail[$oneField])) continue;
1219 - $value = &$mail[$oneField];
1220 - } else {
1221 - if (empty($mail->$oneField)) continue;
1222 - $value = &$mail->$oneField;
1223 - }
1224 -
1225 - $value = acym_utf8Encode($value);
1226 - }
1227 - }
1228 -
1229 - return $mail;
1230 - }
1231 -
1232 - public function getTranslationId($parentId, $langCode)
1233 - {
1234 - return acym_loadResult(
1235 - 'SELECT `id`
1236 - FROM #__acym_mail
1237 - WHERE `parent_id` = '.intval($parentId).'
1238 - AND `language` = '.acym_escapeDB($langCode)
1239 - );
1240 - }
1241 -
1242 - public function getTranslationsById($mailId, $full = false, $includeParent = false)
1243 - {
1244 - $data = $full ? '*' : '`language`, `subject`, `preheader`, `body`, `autosave`';
1245 - $where = $includeParent ? ' OR `id` = '.intval($mailId) : '';
1246 -
1247 - return $this->decode(
1248 - acym_loadObjectList(
1249 - 'SELECT '.$data.'
1250 - FROM #__acym_mail
1251 - WHERE `parent_id` = '.intval($mailId).$where,
1252 - 'language'
1253 - )
1254 - );
1255 - }
1256 -
1257 - public function deleteByTranslationLang($languageCodes)
1258 - {
1259 - if (!is_array($languageCodes)) $languageCodes = [$languageCodes];
1260 - if (empty($languageCodes)) return;
1261 -
1262 - foreach ($languageCodes as $key => $oneLangCode) {
1263 - $languageCodes[$key] = acym_escapeDB($oneLangCode);
1264 - }
1265 -
1266 - $this->delete(
1267 - acym_loadResultArray(
1268 - 'SELECT `id`
1269 - FROM #__acym_mail
1270 - WHERE `parent_id` IS NOT NULL
1271 - AND `language` IN ('.implode(', ', $languageCodes).')'
1272 - )
1273 - );
1274 - }
1275 -
1276 - public function getMultilingualMails(int $parentId)
1277 - {
1278 - $mails = $this->decode(
1279 - acym_loadObjectList(
1280 - 'SELECT * FROM #__acym_mail WHERE parent_id = '.intval($parentId).' OR id = '.intval($parentId),
1281 - 'language'
1282 - )
1283 - );
1284 -
1285 - return $this->translateMailSettings($mails);
1286 - }
1287 -
1288 - private function translateMailSettings($mails)
1289 - {
1290 - if (empty($mails)) return $mails;
1291 -
1292 - $defaultLanguage = $this->config->get('multilingual_default');
1293 -
1294 - if (empty($mails[$defaultLanguage])) {
1295 - $firstMail = reset($mails);
1296 - if (empty($firstMail) || empty($firstMail->parent_id)) return $mails;
1297 - $mainMail = $this->getOneById($firstMail->parent_id);
1298 - } else {
1299 - $mainMail = $mails[$defaultLanguage];
1300 - }
1301 -
1302 - if (!empty($mainMail->translation)) {
1303 - $translation = json_decode($mainMail->translation, true);
1304 -
1305 - foreach ($mails as $lang => $mail) {
1306 - if (empty($mail->parent_id) || empty($translation[$lang])) continue;
1307 -
1308 - if (!empty($translation[$lang]['from_name'])) $mails[$lang]->from_name = $translation[$lang]['from_name'];
1309 - if (!empty($translation[$lang]['from_email'])) $mails[$lang]->from_email = $translation[$lang]['from_email'];
1310 - if (!empty($translation[$lang]['reply_to_name'])) $mails[$lang]->reply_to_name = $translation[$lang]['reply_to_name'];
1311 - if (!empty($translation[$lang]['reply_to_email'])) $mails[$lang]->reply_to_email = $translation[$lang]['reply_to_email'];
1312 - }
1313 - }
1314 -
1315 - return $mails;
1316 - }
1317 -
1318 - public function getMailAttachments($mailId)
1319 - {
1320 - return acym_loadResult('SELECT attachments FROM #__acym_mail WHERE id = '.intval($mailId));
1321 - }
1322 -
1323 - public function isTransactionalMail($mail): bool
1324 - {
1325 - return $mail->type !== self::TYPE_STANDARD;
1326 - }
1327 -
1328 - public function isOneTimeMail($mail): bool
1329 - {
1330 - return in_array(
1331 - $mail->type,
1332 - [
1333 - self::TYPE_NOTIFICATION,
1334 - self::TYPE_OVERRIDE,
1335 - self::TYPE_WELCOME,
1336 - self::TYPE_UNSUBSCRIBE,
1337 - self::TYPE_TEMPLATE,
1338 - ]
1339 - );
1340 - }
1341 -
1342 - public function getAutomaticMailIds($mailIds)
1343 - {
1344 - acym_arrayToInteger($mailIds);
1345 -
1346 - $query = 'SELECT DISTINCT campaign2.mail_id
1347 - FROM #__acym_campaign AS campaign1
1348 - JOIN #__acym_campaign AS campaign2 ON campaign1.id = campaign2.parent_id
1349 - WHERE campaign1.mail_id IN ('.implode(',', $mailIds).')';
1350 - $generatedMailIds = acym_loadResultArray($query);
1351 -
1352 - if (empty($generatedMailIds)) return [];
1353 -
1354 - acym_arrayToInteger($generatedMailIds);
1355 -
1356 - return $generatedMailIds;
1357 - }
1358 -
1359 - public function getMultilingualMailIds($mailIds)
1360 - {
1361 - acym_arrayToInteger($mailIds);
1362 -
1363 - $query = 'SELECT DISTINCT mail2.id
1364 - FROM #__acym_mail AS mail1
1365 - JOIN #__acym_mail AS mail2 ON mail1.id = mail2.parent_id
1366 - WHERE mail1.id IN ('.implode(',', $mailIds).')';
1367 -
1368 - $multipleMailIds = acym_loadResultArray($query);
1369 -
1370 - if (empty($multipleMailIds)) return [];
1371 -
1372 - acym_arrayToInteger($multipleMailIds);
1373 -
1374 - return $multipleMailIds;
1375 - }
1376 -
1377 - public function duplicateMail($mailId, $type = null)
1378 - {
1379 - $mail = $this->getOneById($mailId);
1380 -
1381 - if (empty($mail)) {
1382 - return false;
1383 - }
1384 -
1385 - $newMail = new \stdClass();
1386 - $newMail->name = $mail->name.'_copy';
1387 - $newMail->thumbnail = '';
1388 - $newMail->type = empty($type) ? $mail->type : $type;
1389 - $newMail->drag_editor = $mail->drag_editor;
1390 - $newMail->body = $mail->body;
1391 - $newMail->subject = $mail->subject;
1392 - $newMail->from_name = $mail->from_name;
1393 - $newMail->from_email = $mail->from_email;
1394 - $newMail->reply_to_name = $mail->reply_to_name;
1395 - $newMail->reply_to_email = $mail->reply_to_email;
1396 - $newMail->bcc = $mail->bcc;
1397 - $newMail->settings = $mail->settings;
1398 - $newMail->stylesheet = $mail->stylesheet;
1399 - $newMail->attachments = $mail->attachments;
1400 - $newMail->headers = $mail->headers;
1401 - $newMail->preheader = $mail->preheader;
1402 -
1403 - $newMail->id = $this->save($newMail);
1404 -
1405 - return $newMail;
1406 - }
1407 -
1408 - public function getTemplatesForMailboxAction()
1409 - {
1410 - return $this->decode(
1411 - acym_loadObjectList(
1412 - 'SELECT `id`, `name`
1413 - FROM #__acym_mail
1414 - WHERE `type` = '.acym_escapeDB(self::TYPE_TEMPLATE).'
1415 - AND `body` LIKE '.acym_escapeDB('%'.acym_utf8Encode('{emailcontent}').'%')
1416 - )
1417 - );
1418 - }
1419 -
1420 - public function hasUserAccess(int $mailId): bool
1421 - {
1422 - $userId = acym_currentUserId();
1423 - if (empty($userId)) {
1424 - return false;
1425 - }
1426 -
1427 - if (acym_isAdmin()) {
1428 - return true;
1429 - }
1430 -
1431 - return acym_loadResult(
1432 - 'SELECT COUNT(*)
1433 - FROM #__acym_mail
1434 - WHERE id = '.intval($mailId).'
1435 - AND (creator_id = '.intval($userId).'
1436 - OR type = '.acym_escapeDB(self::TYPE_TEMPLATE).')'
1437 - ) > 0;
1438 - }
1439 -
1440 -
1441 - public function getVersionsById($mailId, $includeParent = false)
1442 - {
1443 - $where = $includeParent ? ' OR `id` = '.intval($mailId) : '';
1444 -
1445 - return $this->decode(
1446 - acym_loadObjectList(
1447 - 'SELECT *
1448 - FROM #__acym_mail
1449 - WHERE `parent_id` = '.intval($mailId).$where.' ORDER BY id ASC',
1450 - 'id'
1451 - )
1452 - );
1453 - }
1454 -
1455 - public function getParentAndChildMails($parentId)
1456 - {
1457 - $mails = $this->decode(
1458 - acym_loadObjectList(
1459 - 'SELECT * FROM #__acym_mail WHERE parent_id = '.intval($parentId).' OR id = '.intval($parentId),
1460 - 'id'
1461 - )
1462 - );
1463 -
1464 - return $mails;
1465 - }
1466 -
1467 - public function getAllTemplatesByType($options)
1468 - {
1469 - $limit = $options['limit'] ?? 10;
1470 - $offset = $options['offset'] ?? 0;
1471 - $filters = $options['filters'] ?? [];
1472 - $search = $filters['search'] ?? '';
1473 - $templateType = $filters['templateType'] ?? '';
1474 -
1475 - $query = 'SELECT * FROM #__acym_mail';
1476 - $conditions = ['`type` = '.acym_escapeDB(self::TYPE_TEMPLATE)];
1477 -
1478 - if (!empty($search)) {
1479 - $conditions[] = '(name LIKE '.acym_escapeDB('%'.$search.'%').' OR subject LIKE '.acym_escapeDB('%'.$search.'%').')';
1480 - }
1481 -
1482 - if (!empty($templateType)) {
1483 - if ($templateType === 'drag') {
1484 - $conditions[] = 'drag_editor = 1';
1485 - } else {
1486 - $conditions[] = 'drag_editor = 0';
1487 - }
1488 - }
1489 -
1490 - $query .= ' WHERE '.implode(' AND ', $conditions);
1491 -
1492 - return $this->decode(acym_loadObjectList($query, '', $offset, $limit));
1493 - }
1494 -
1495 - public function updateFollowupPriority($oldPriority, $newPriority)
1496 - {
1497 - if ($oldPriority == 0 && $newPriority == 1) {
1498 - $updatePriorityQuery = 'UPDATE `#__acym_queue` AS `queue`
1499 - INNER JOIN `#__acym_mail` AS `mail` ON `queue`.`mail_id` = `mail`.`id`
1500 - SET `queue`.`priority` = 1
1501 - WHERE `mail`.`type` = "'.self::TYPE_FOLLOWUP.'"';
1502 -
1503 - return acym_query($updatePriorityQuery);
1504 - }
1505 - }
1506 -
1507 - public function getCampaignIdByMailId(int $mailId): int
1508 - {
1509 - $mainMailId = $this->getMainMailId($mailId);
1510 -
1511 - return intval(acym_loadResult('SELECT id FROM #__acym_campaign WHERE mail_id = '.intval($mainMailId)));
1512 - }
1513 -
1514 - public function getMainMailId(int $mailId): int
1515 - {
1516 - $parentId = acym_loadResult('SELECT parent_id FROM #__acym_mail WHERE id = '.intval($mailId));
1517 -
1518 - return empty($parentId) ? $mailId : intval($parentId);
1519 - }
1520 -}