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/Controllers/Lists/Edition.php +0 -488 10.11.1 → 11.1.1 View file →
@@ -1,488 +1,0 @@
1 -<?php
2 -
3 -namespace AcyMailing\Controllers\Lists;
4 -
5 -use AcyMailing\Classes\HistoryClass;
6 -use AcyMailing\Classes\ListClass;
7 -use AcyMailing\Classes\MailClass;
8 -use AcyMailing\Classes\MailStatClass;
9 -use AcyMailing\Classes\TagClass;
10 -use AcyMailing\Classes\UrlClickClass;
11 -use AcyMailing\Controllers\ListsController;
12 -use AcyMailing\Helpers\EntitySelectHelper;
13 -use AcyMailing\Helpers\WorkflowHelper;
14 -
15 -trait Edition
16 -{
17 - public function settings(): void
18 - {
19 - acym_setVar('layout', 'settings');
20 -
21 - $tab = acym_getVar('string', 'step', ListsController::LIST_EDITION_TABS_GENERAL);
22 -
23 - if (empty($tab)) {
24 - $tab = ListsController::LIST_EDITION_TABS_GENERAL;
25 - }
26 -
27 - $data = [];
28 - $data['svg'] = acym_loaderLogo(false);
29 - $data['workflowHelper'] = new WorkflowHelper();
30 - $data['currentTab'] = $tab;
31 - $data['tabs'] = [
32 - 'general' => ListsController::LIST_EDITION_TABS_GENERAL,
33 - 'subscribers' => ListsController::LIST_EDITION_TABS_SUBSCRIBERS,
34 - 'unsubscriptions' => ListsController::LIST_EDITION_TABS_UNSUBSCRIPTIONS,
35 - ];
36 -
37 - $listId = acym_getVar('int', 'listId', 0);
38 -
39 - if (!$this->prepareListSettings($data, $listId)) return;
40 -
41 - if ($tab === ListsController::LIST_EDITION_TABS_GENERAL) {
42 - $this->prepareTagsSettings($data, $listId);
43 - $this->prepareListStat($data, $listId);
44 - $this->prepareListStatEvolution($data, $listId);
45 - $this->prepareWelcomeUnsubData($data);
46 - $this->prepareMultilingualOption($data);
47 - } elseif ($tab === ListsController::LIST_EDITION_TABS_SUBSCRIBERS) {
48 - $this->prepareSubscribersEntitySelect($data, $listId);
49 - $this->prepareSubscribersSettings($data, $listId);
50 - } elseif ($tab === ListsController::LIST_EDITION_TABS_UNSUBSCRIPTIONS) {
51 - $this->prepareUnsubReasons($data);
52 - }
53 -
54 - parent::display($data);
55 - }
56 -
57 - private function prepareListSettings(array &$data, int $listId): bool
58 - {
59 - if (empty($listId)) {
60 - $listInformation = new \stdClass();
61 - $listInformation->id = '';
62 - $listInformation->name = '';
63 - $listInformation->frontLabel = '';
64 - $listInformation->description = '';
65 - $listInformation->active = 1;
66 - $listInformation->visible = 1;
67 - $listInformation->color = '#'.implode('', [
68 - ListClass::COLOR_PARTS[rand(0, 15)],
69 - ListClass::COLOR_PARTS[rand(0, 15)],
70 - ListClass::COLOR_PARTS[rand(0, 15)],
71 - ListClass::COLOR_PARTS[rand(0, 15)],
72 - ListClass::COLOR_PARTS[rand(0, 15)],
73 - ListClass::COLOR_PARTS[rand(0, 15)],
74 - ]);
75 - $listInformation->welcome_id = '';
76 - $listInformation->unsubscribe_id = '';
77 - $listInformation->access = [];
78 - $listInformation->tracking = 1;
79 - $listInformation->translation = [];
80 - $listInformation->display_name = '';
81 -
82 - $this->breadcrumb[acym_translation('ACYM_NEW_LIST')] = acym_completeLink('lists&task=settings');
83 - } else {
84 - $listClass = new ListClass();
85 - $listInformation = $listClass->getOneById($listId);
86 - if (is_null($listInformation)) {
87 - acym_enqueueMessage(acym_translation('ACYM_LIST_DOESNT_EXIST'), 'error');
88 - $this->listing();
89 -
90 - return false;
91 - }
92 -
93 -
94 - $subscribersCount = $listClass->getSubscribersCountPerStatusByListIds([$listId]);
95 -
96 - $this->breadcrumb[acym_escape($listInformation->name)] = acym_completeLink('lists&task=settings&listId='.$listId);
97 -
98 - $listInformation->access = empty($listInformation->access) ? [] : explode(',', $listInformation->access);
99 -
100 - $currentUser = acym_currentUserId();
101 - if (!acym_isAdmin() && ($listInformation->cms_user_id != $currentUser)) {
102 - $userGroups = acym_getGroupsByUser($currentUser);
103 - $canAccess = false;
104 -
105 - foreach ($userGroups as $group) {
106 - if (in_array($group, $listInformation->access)) $canAccess = true;
107 - }
108 -
109 - if (!$canAccess) {
110 - acym_enqueueMessage(acym_translation('ACYM_YOU_DONT_HAVE_ACCESS_TO_THIS_LIST'), 'error');
111 -
112 - $this->listing();
113 -
114 - return false;
115 - }
116 - }
117 - }
118 -
119 - $listInformation->subscribers = [
120 - 'unsubscribed_users' => 0,
121 - 'sendable_users' => 0,
122 - 'unconfirmed_users' => 0,
123 - 'inactive_users' => 0,
124 - ];
125 - if (!empty($subscribersCount)) {
126 - $listStats = array_shift($subscribersCount);
127 - $listInformation->subscribers = [
128 - 'unsubscribed_users' => $listStats->unsubscribed_users,
129 - 'sendable_users' => $listStats->sendable_users,
130 - 'unconfirmed_users' => $listStats->unconfirmed_users,
131 - 'inactive_users' => $listStats->inactive_users,
132 - ];
133 - }
134 -
135 - $data['listInformation'] = $listInformation;
136 -
137 - return true;
138 - }
139 -
140 - private function prepareTagsSettings(array &$data, int $listId): void
141 - {
142 - $tagClass = new TagClass();
143 - $data['allTags'] = $tagClass->getAllTagsByType(TagClass::TYPE_LIST);
144 - $data['listTagsName'] = [];
145 - $listsTags = $tagClass->getAllTagsByElementId(TagClass::TYPE_LIST, $listId);
146 - foreach ($listsTags as $oneTag) {
147 - $data['listTagsName'][] = $oneTag;
148 - }
149 - }
150 -
151 - private function prepareSubscribersSettings(array &$data, int $listId): void
152 - {
153 - $data['ordering'] = acym_getVar('string', 'users_ordering', 'id');
154 - $data['orderingSortOrder'] = acym_getVar('string', 'users_ordering_sort_order', 'desc');
155 - $data['classSortOrder'] = $data['orderingSortOrder'] == 'asc' ? 'acymicon-sort-amount-asc' : 'acymicon-sort-amount-desc';
156 - $listClass = new ListClass();
157 - $data['subscribers'] = $listClass->getSubscribersForList(
158 - [
159 - 'listIds' => [$listId],
160 - 'offset' => 0,
161 - 'limit' => 500,
162 - 'status' => 1,
163 - 'orderBy' => $data['ordering'],
164 - 'orderBySort' => $data['orderingSortOrder'],
165 - ]
166 - );
167 - foreach ($data['subscribers'] as &$oneSub) {
168 - if ($oneSub->subscription_date == '0000-00-00 00:00:00') continue;
169 - $oneSub->subscription_date = acym_date(strtotime($oneSub->subscription_date), acym_translation('ACYM_DATE_FORMAT_LC2'));
170 - }
171 - }
172 -
173 - private function prepareSubscribersEntitySelect(array &$data, int $listId): void
174 - {
175 - if (empty($listId)) {
176 - $data['subscribersEntitySelect'] = '';
177 -
178 - return;
179 - }
180 -
181 - $entityHelper = new EntitySelectHelper();
182 -
183 - $data['subscribersEntitySelect'] = acym_modal(
184 - acym_translation('ACYM_MANAGE_SUBSCRIBERS'),
185 - $entityHelper->entitySelect(
186 - 'user',
187 - ['join' => 'join_list-'.$listId],
188 - $entityHelper->getColumnsForUser('userlist.user_id'),
189 - ['text' => acym_translation('ACYM_CONFIRM'), 'action' => 'saveSubscribers'],
190 - true,
191 - '',
192 - 'subscriber'
193 - ),
194 - 'acym__lists__settings__subscribers__entity__modal',
195 - [],
196 - ['class' => 'cell medium-6 large-shrink button button-secondary']
197 - );
198 - }
199 -
200 - private function prepareListStat(array &$data, int $listId): void
201 - {
202 - $data['listStats'] = ['deliveryRate' => 0, 'openRate' => 0, 'clickRate' => 0, 'failRate' => 0, 'bounceRate' => 0];
203 - if (empty($listId)) return;
204 - $listClass = new ListClass();
205 - $mails = $listClass->getMailsByListId($listId);
206 - if (empty($mails)) return;
207 -
208 - $mailStatClass = new MailStatClass();
209 - $mailsStat = $mailStatClass->getCumulatedStatsByMailIds($mails);
210 -
211 - if (intval($mailsStat->sent) + intval($mailsStat->fails) === 0) return;
212 -
213 - $totalSent = intval($mailsStat->sent) + intval($mailsStat->fails);
214 - if (empty($mailsStat->open)) $mailsStat->open = 0;
215 - if (empty($mailsStat->fails)) $mailsStat->fails = 0;
216 - if (empty($mailsStat->bounces)) $mailsStat->bounces = 0;
217 -
218 - $data['listStats']['openRate'] = number_format($mailsStat->open / $totalSent * 100, 2);
219 - $data['listStats']['deliveryRate'] = number_format(($mailsStat->sent - $mailsStat->bounces) / $totalSent * 100, 2);
220 - $data['listStats']['failRate'] = number_format($mailsStat->fails / $totalSent * 100, 2);
221 - $data['listStats']['bounceRate'] = number_format($mailsStat->bounces / $totalSent * 100, 2);
222 -
223 - $urlClickClass = new UrlClickClass();
224 - $nbClicks = $urlClickClass->getClickRateByMailIds($mails);
225 - $data['listStats']['clickRate'] = number_format($nbClicks / $totalSent * 100, 2);
226 - }
227 -
228 - private function prepareListStatEvolution(array &$data, int $listId): void
229 - {
230 - $data['evol'] = [];
231 - $listClass = new ListClass();
232 - $subEvolStat = $listClass->getYearSubEvolutionPerList($listId);
233 - if (empty($subEvolStat['subscribers']) && empty($subEvolStat['unsubscribers'])) return;
234 -
235 - $firstMonth = date('n') + 1;
236 - $zeroReached = false;
237 - $evolSub = [];
238 - $evolUnsub = [];
239 - for ($i = 0; $i < 12; $i++) {
240 - $month = ($firstMonth + $i) % 13;
241 - if ($month == 0) $zeroReached = true;
242 - if ($zeroReached) $month += 1;
243 - $evolSub[$month] = $month.'_0';
244 - $evolUnsub[$month] = $month.'_0';
245 - }
246 -
247 - foreach ($subEvolStat['subscribers'] as $unit => $monthData) {
248 - $evolSub[$monthData->monthSub] = $monthData->monthSub.'_'.$monthData->nbUser;
249 - }
250 -
251 - foreach ($subEvolStat['unsubscribers'] as $unit => $monthData) {
252 - $evolUnsub[$monthData->monthUnsub] = $monthData->monthUnsub.'_'.$monthData->nbUser;
253 - }
254 -
255 - foreach ($evolSub as $month => $oneEvol) {
256 - $data['evol'][0][] = $oneEvol;
257 - $data['evol'][1][] = $evolUnsub[$month];
258 - }
259 - }
260 -
261 - protected function prepareWelcomeUnsubData(array &$data): void
262 - {
263 - $data['tmpls'] = [];
264 - if (empty($data['listInformation']->id)) return;
265 - $listClass = new ListClass();
266 - $mailClass = new MailClass();
267 -
268 - foreach ([MailClass::TYPE_WELCOME => 'welcome', MailClass::TYPE_UNSUBSCRIBE => 'unsub'] as $full => $short) {
269 - $mailId = acym_getVar('int', $short.'mailid', 0);
270 - if (empty($data['listInformation']->{$full.'_id'}) && !empty($mailId)) {
271 - $data['listInformation']->{$full.'_id'} = $mailId;
272 - $listInfoSave = clone $data['listInformation'];
273 - unset($listInfoSave->subscribers);
274 - $savedListId = $listClass->save($listInfoSave);
275 - if (empty($savedListId)) {
276 - acym_enqueueMessage(acym_translation('ACYM_ERROR_SAVE_LIST'), 'error');
277 - }
278 - }
279 -
280 - $returnLink = acym_completeLink('lists&task=settings&listId='.$data['listInformation']->id.'&edition=1&'.$short.'mailid={mailid}');
281 - $favoriteTemplate = $this->config->get('favorite_template', 0);
282 - $startFrom = empty($favoriteTemplate) ? '' : '&from='.$favoriteTemplate;
283 -
284 - if (empty($data['listInformation']->{$full.'_id'})) {
285 - $data['tmpls'][$short.'TmplUrl'] = acym_completeLink(
286 - 'mails&task=edit&step=editEmail&type='.$full.'&type_editor=acyEditor&list_id='.$data['listInformation']->id.'&return='.urlencode(
287 - base64_encode($returnLink)
288 - ).$startFrom
289 - );
290 - } else {
291 - $data['tmpls'][$short.'TmplUrl'] = acym_completeLink(
292 - 'mails&task=edit&id='.$data['listInformation']->{$full.'_id'}.'&type='.$full.'&list_id='.$data['listInformation']->id.'&return='.urlencode(
293 - base64_encode($returnLink)
294 - ).$startFrom
295 - );
296 - }
297 -
298 - $data['tmpls'][$full] = !empty($data['listInformation']->{$full.'_id'}) ? $mailClass->getOneById($data['listInformation']->{$full.'_id'}) : '';
299 - }
300 - }
301 -
302 - public function unsetMail(string $type): void
303 - {
304 - $listClass = new ListClass();
305 - $id = acym_getVar('int', 'listId', 0);
306 - $list = $listClass->getOneById($id);
307 -
308 - if (empty($list)) {
309 - acym_enqueueMessage(acym_translation('ACYM_ERROR_SAVE_LIST'), 'error');
310 - $this->listing();
311 -
312 - return;
313 - }
314 -
315 - if (!$listClass->hasUserAccess($id)) {
316 - die('Access denied for list '.acym_escape($id));
317 - }
318 -
319 - $list->$type = null;
320 -
321 - $savedListId = $listClass->save($list);
322 - if (!empty($savedListId)) {
323 - acym_setVar('listId', $id);
324 - $this->settings();
325 - } else {
326 - acym_enqueueMessage(acym_translation('ACYM_ERROR_SAVE_LIST'), 'error');
327 - $this->listing();
328 - }
329 - }
330 -
331 - public function unsetWelcome(): void
332 - {
333 - $this->unsetMail('welcome_id');
334 - }
335 -
336 - public function unsetUnsubscribe(): void
337 - {
338 - $this->unsetMail('unsubscribe_id');
339 - }
340 -
341 - public function apply(): void
342 - {
343 - $this->save(false);
344 - }
345 -
346 - public function save(bool $goToListing = true): void
347 - {
348 - acym_checkToken();
349 -
350 - $step = acym_getVar('string', 'step');
351 - if ($step === self::LIST_EDITION_TABS_GENERAL) {
352 - $listClass = new ListClass();
353 - $formData = (object)acym_getVar('array', 'list', []);
354 -
355 - $listId = acym_getVar('int', 'listId', 0);
356 - if (!empty($listId)) {
357 - $formData->id = $listId;
358 - }
359 -
360 - $allowedFields = acym_getColumns('list');
361 - $listInformation = new \stdClass();
362 - if (empty($formData->welcome_id)) unset($formData->welcome_id);
363 - if (empty($formData->unsubscribe_id)) unset($formData->unsubscribe_id);
364 - foreach ($formData as $name => $data) {
365 - if (!in_array($name, $allowedFields)) {
366 - continue;
367 - }
368 - $listInformation->{$name} = $data;
369 - }
370 -
371 - $listInformation->tags = acym_getVar('array', 'list_tags', []);
372 -
373 - if (acym_isAdmin()) {
374 - $listInformation->access = empty($listInformation->access) ? '' : ','.implode(',', $listInformation->access).',';
375 - } elseif (!empty($formData->id) && !$listClass->hasUserAccess($formData->id)) {
376 - die('Cannot save list '.acym_escape($formData->id));
377 - }
378 -
379 - $listId = $listClass->save($listInformation);
380 -
381 - if (!empty($listId)) {
382 - acym_setVar('listId', $listId);
383 - acym_enqueueMessage(acym_translationSprintf('ACYM_LIST_IS_SAVED', $listInformation->name), 'success');
384 - $this->saveSubscribersTolist();
385 - } else {
386 - acym_enqueueMessage(acym_translation('ACYM_ERROR_SAVING'), 'error');
387 - if (!empty($listClass->errors)) {
388 - acym_enqueueMessage($listClass->errors, 'error');
389 - }
390 - }
391 - }
392 -
393 - if ($goToListing) {
394 - $this->listing();
395 - } else {
396 - $this->settings();
397 - }
398 - }
399 -
400 - private function saveSubscribersTolist(): bool
401 - {
402 - $selected = acym_getVar('string', 'acym__entity_select__selected', '[]');
403 - $unselected = acym_getVar('string', 'acym__entity_select__unselected', '[]');
404 - $usersIds = json_decode(empty($selected) ? '[]' : $selected, true);
405 - $usersIdsUnselected = json_decode(empty($unselected) ? '[]' : $unselected, true);
406 - $listId = acym_getVar('int', 'listId', 0);
407 -
408 - $listClass = new ListClass();
409 - if (empty($listId) || !$listClass->hasUserAccess($listId)) return false;
410 -
411 - acym_arrayToInteger($usersIdsUnselected);
412 - if (!empty($usersIdsUnselected)) {
413 - acym_query(
414 - 'UPDATE #__acym_user_has_list
415 - SET status = 0, unsubscribe_date = '.acym_escapeDB(acym_date(time(), 'Y-m-d H:i:s')).'
416 - WHERE list_id = '.intval($listId).'
417 - AND user_id IN ('.implode(', ', $usersIdsUnselected).')'
418 - );
419 - }
420 -
421 - acym_arrayToInteger($usersIds);
422 - if (!empty($usersIds)) {
423 - acym_query(
424 - 'INSERT IGNORE #__acym_user_has_list (`user_id`, `list_id`, `status`, `subscription_date`) (SELECT id, '.intval($listId).', 1, '.acym_escapeDB(
425 - acym_date(time(), 'Y-m-d H:i:s')
426 - ).' FROM #__acym_user AS user WHERE user.id IN ('.implode(', ', $usersIds).')) ON DUPLICATE KEY UPDATE status = 1'
427 - );
428 - }
429 -
430 - return true;
431 - }
432 -
433 - public function saveSubscribers(): void
434 - {
435 - acym_checkToken();
436 -
437 - $this->saveSubscribersTolist();
438 - $listId = acym_getVar('int', 'listId', 0);
439 - acym_setVar('listId', $listId);
440 -
441 - $this->settings();
442 - }
443 -
444 - private function sortDataByList(array $data): array
445 - {
446 - $sortedData = [];
447 -
448 - foreach ($data as $entry) {
449 - $pattern = '/(?<!EXECUTED_BY::)\b\d+\b/';
450 - preg_match_all($pattern, $entry->data, $listNumbers);
451 -
452 - foreach ($listNumbers[0] as $listNumber) {
453 - if (!isset($sortedData[$listNumber])) {
454 - $sortedData[$listNumber] = [];
455 - }
456 -
457 - $sortedData[$listNumber][] = $entry->unsubscribe_reason;
458 - }
459 - }
460 -
461 - return $sortedData;
462 - }
463 -
464 - private function prepareUnsubReasons(array &$data): void
465 - {
466 - $historyClass = new HistoryClass();
467 - $allReasonsData = $historyClass->getAllUnsubReasons();
468 -
469 - $sortedData = $this->sortDataByList($allReasonsData);
470 - $listId = acym_getVar('int', 'listId', 0);
471 - $currentListData = $sortedData[$listId] ?? [];
472 - $reasonCounts = array_count_values($currentListData);
473 -
474 - $allAnswers = $historyClass->getAllMainLanguageUnsubReasons();
475 - $newReasonCounts = [];
476 - foreach ($reasonCounts as $key => $value) {
477 - if (is_numeric($key) && isset($allAnswers[$key - 1])) {
478 - $newReasonCounts[$allAnswers[$key - 1]] = $value;
479 - } else {
480 - $newReasonCounts[$key] = $value;
481 - }
482 - }
483 -
484 - arsort($newReasonCounts);
485 -
486 - $data['unsubReasons'] = $newReasonCounts;
487 - }
488 -}