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