PluginProbe
AcyMailing – An Ultimate Newsletter Plugin and Marketing Automation Solution for WordPress / 10.0.1
AcyMailing – An Ultimate Newsletter Plugin and Marketing Automation Solution for WordPress v10.0.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
acymailing / back / Controllers / Stats / GlobalStats.php

GlobalStats.php in AcyMailing – An Ultimate Newsletter Plugin and Marketing Automation Solution for WordPress 10.0.1, at back/Controllers/Stats/GlobalStats.php

748 lines 28.8 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace AcyMailing\Controllers\Stats;
4
5 use AcyMailing\Classes\CampaignClass;
6 use AcyMailing\Classes\MailClass;
7 use AcyMailing\Classes\MailStatClass;
8 use AcyMailing\Classes\UrlClickClass;
9 use AcyMailing\Classes\UserStatClass;
10 use AcyMailing\Helpers\ExportHelper;
11 use AcyMailing\Helpers\MailerHelper;
12 use AcyMailing\Helpers\PaginationHelper;
13 use AcyMailing\Helpers\WorkflowHelper;
14
15 trait GlobalStats
16 {
17 public function globalStats()
18 {
19 acym_setVar('layout', 'global_stats');
20
21 $data = [];
22
23 $this->prepareDefaultPageInfo($data);
24
25 $this->prepareOpenTimeChart($data);
26 $this->preparecharts($data);
27 $this->prepareListReceivers($data);
28 $this->prepareDefaultRoundCharts($data);
29 $this->prepareDefaultLineChart($data);
30 $this->prepareDefaultDevicesChart($data);
31 $this->prepareDefaultBrowsersChart($data);
32 if (count($this->selectedMailIds) == 1) {
33 if ($data['isAbTest']) {
34 $this->prepareAbTestMails($data);
35 } elseif (acym_isMultilingual()) {
36 $this->prepareMultilingualMails($data);
37 }
38 }
39 $this->prepareMailFilter($data);
40
41 parent::display($data);
42 }
43
44 private function prepareMailFilter(&$data)
45 {
46 $data['input_mail_ids'] = '';
47
48 if (!empty($this->multiLanguageMailAdded) || !empty($this->generatedMailAdded)) {
49 $this->selectedMailIds = array_filter(
50 $this->selectedMailIds,
51 function ($mailId) {
52 return !in_array($mailId, $this->multiLanguageMailAdded) && !in_array($mailId, $this->generatedMailAdded);
53 }
54 );
55 }
56
57 if (count($this->selectedMailIds) > 1) {
58 $data['input_mail_ids'] = '<input type="hidden" value="'.implode(',', $this->selectedMailIds).'" name="mail_ids">';
59 }
60
61 $attributes = [
62 'class' => 'acym__select acym_select2_ajax acym__stats__select__mails',
63 'data-placeholder' => acym_translation('ACYM_ALL_EMAILS'),
64 'data-ctrl' => 'stats',
65 'data-task' => 'searchSentMail',
66 'data-min' => '0',
67 'id' => 'mail_ids',
68 ];
69
70 if (!empty($this->selectedMailIds)) $attributes['data-selected'] = implode(',', $this->selectedMailIds);
71
72 $data['mail_filter'] = acym_selectMultiple(
73 [],
74 'mail_ids',
75 [],
76 $attributes
77 );
78
79 $data['emailVersionsFilters'] = '';
80
81 if (!empty($data['emailVersions'])) {
82 $data['emailVersionsFilters'] = acym_select(
83 $data['emailVersions'],
84 'mail_id_version',
85 $this->selectedMailIds[0],
86 [
87 'class' => 'acym__select acym__stats__select__language',
88 ]
89 );
90 }
91 if (!empty($data['emailTranslations'])) {
92 $data['emailVersionsFilters'] = acym_select(
93 $data['emailTranslations'],
94 'mail_id_version',
95 $this->selectedMailIds[0],
96 [
97 'class' => 'acym__select acym__stats__select__language',
98 ]
99 );
100 }
101 }
102
103 private function prepareClickStats(&$data)
104 {
105 if (empty($data['selectedMailid'])) return;
106
107 $urlClickClass = new UrlClickClass();
108 $allClickInfo = $urlClickClass->getAllLinkFromEmail($this->selectedMailIds[0]);
109
110 $data['url_click'] = [];
111 $data['url_click']['allClick'] = $allClickInfo['allClick'];
112
113 $allPercentage = [];
114 foreach ($allClickInfo['urls_click'] as $url) {
115 $percentage = 0;
116 if (empty($url->click)) {
117 $data['url_click'][$url->name] = ['percentage' => $percentage, 'numberClick' => '0'];
118 } else {
119 $percentage = intval(($url->click * 100) / $allClickInfo['allClick']);
120 $data['url_click'][$url->name] = ['percentage' => $percentage, 'numberClick' => $url->click];
121 }
122 $allPercentage[] = $percentage;
123 }
124
125 $helperMailer = new MailerHelper();
126 if (!empty($data['mailInformation'])) {
127 $helperMailer->body = $data['mailInformation']->body;
128 $helperMailer->statClick($data['mailInformation']->id, 0, true);
129 $data['mailInformation']->body = preg_replace('#&(amp;)?autoSubId=[^"]+"#Uis', '"', $helperMailer->body);
130 }
131
132 if (!empty($allPercentage)) {
133 $maxPercentage = max($allPercentage);
134
135 foreach ($data['url_click'] as $name => $val) {
136 if ($name === 'allClick') continue;
137 $percentageRecalc = intval(($val['percentage'] * 100) / $maxPercentage);
138 if ($percentageRecalc <= 33) {
139 $data['url_click'][$name]['color'] = '0, 164, 255';
140 } elseif ($percentageRecalc <= 66) {
141 $data['url_click'][$name]['color'] = '248, 31, 255';
142 } else {
143 $data['url_click'][$name]['color'] = '255, 82, 89';
144 }
145 }
146 }
147
148 $data['url_click'] = json_encode($data['url_click']);
149
150 $data['url_foundation_email'] = ACYM_CSS.'libraries/foundation_email.min.css?v='.filemtime(ACYM_MEDIA.'css'.DS.'libraries'.DS.'foundation_email.min.css');
151 $data['url_click_map_email'] = ACYM_CSS.'click_map.min.css?v='.filemtime(ACYM_MEDIA.'css'.DS.'click_map.min.css');
152 }
153
154 public function prepareDefaultRoundCharts(&$data)
155 {
156 $charts = [
157 'delivery' => [
158 'percentage' => 95,
159 'text' => 'ACYM_SUCCESSFULLY_SENT',
160 ],
161 'open' => [
162 'percentage' => 25,
163 'text' => 'ACYM_OPEN_RATE',
164 ],
165 'click' => [
166 'percentage' => 10,
167 'text' => 'ACYM_CLICK_RATE',
168 ],
169 'fail' => [
170 'percentage' => 2,
171 'text' => 'ACYM_BOUNCE_RATE',
172 ],
173 'unsub' => [
174 'percentage' => 3,
175 'text' => 'ACYM_UNSUBSCRIBE',
176 ],
177 ];
178
179 $data['example_round_chart'] = '';
180 foreach ($charts as $type => $oneChart) {
181 if ($type == 'unsub' && empty($this->selectedMailIds)) continue;
182 $data['example_round_chart'] .= '<div class="cell acym__stats__donut__one-chart">';
183 $data['example_round_chart'] .= acym_roundChart(
184 '',
185 $oneChart['percentage'],
186 $type,
187 '',
188 acym_translation($oneChart['text'])
189 );
190 $data['example_round_chart'] .= '</div>';
191 }
192 }
193
194 public function prepareDefaultLineChart(&$data)
195 {
196 $dataMonth = [];
197 $dataMonth['Jan 18'] = ['open' => '150', 'click' => '40'];
198 $dataDay = [];
199 $dataDay['23 Jan'] = ['open' => '150', 'click' => '40'];
200 $dataHour = [];
201 $dataHour['23 Jan 08:00'] = ['open' => '25', 'click' => '10'];
202 $dataHour['23 Jan 09:00'] = ['open' => '50', 'click' => '10'];
203 $dataHour['23 Jan 10:00'] = ['open' => '16', 'click' => '10'];
204 $dataHour['23 Jan 11:00'] = ['open' => '59', 'click' => '10'];
205 $data['example_line_chart'] = acym_lineChart('', $dataMonth, $dataDay, $dataHour);
206 }
207
208 public function prepareDefaultDevicesChart(&$data)
209 {
210 $allDevices = array_merge(UserStatClass::DESKTOP_DEVICES, UserStatClass::MOBILE_DEVICES);
211 $defaultData = [];
212
213 for ($i = 0 ; $i < 10 ; $i++) {
214 $oneDevice = array_rand($allDevices);
215 $defaultData[$allDevices[$oneDevice]] = rand(20, 10000);
216 }
217
218 $data['example_devices_chart'] = acym_pieChart('', $defaultData, '', acym_translation('ACYM_DEVICES'));
219 }
220
221 public function prepareDefaultBrowsersChart(&$data)
222 {
223 $exampleData = [
224 'Google Chrome' => rand(20, 10000),
225 'Firefox' => rand(20, 10000),
226 'Safari' => rand(20, 10000),
227 'Microsoft Edge' => rand(20, 10000),
228 'Outlook' => rand(20, 10000),
229 'Apple Mail' => rand(20, 10000),
230 'Thunderbird' => rand(20, 10000),
231 ];
232
233 $data['example_source_chart'] = acym_pieChart('', $exampleData, '', acym_translation('ACYM_OPENED_WITH'));
234 }
235
236 public function setDataForChartLine()
237 {
238 $newStart = acym_date(acym_getVar('string', 'start'), 'Y-m-d H:i:s');
239 $newEnd = acym_date(acym_getVar('string', 'end'), 'Y-m-d H:i:s');
240 $mailIds = acym_getVar('int', 'id');
241
242 if (empty($mailIds)) {
243 $mailIds = [];
244 }
245
246 $mailClass = new MailClass();
247 if (!empty($mailIds)) {
248 $mailIds = $mailClass->getAutomaticMailIds($mailIds);
249 }
250
251 if (!empty($mailIds) && !is_array($mailIds)) {
252 $mailIds = [$mailIds];
253 }
254
255 if ($newStart >= $newEnd) {
256 echo 'error';
257 exit;
258 }
259
260 $statsCampaignSelected = new \stdClass();
261 $this->prepareLineChart($statsCampaignSelected, $mailIds, $newStart, $newEnd);
262
263 echo @acym_lineChart('', $statsCampaignSelected->month, $statsCampaignSelected->day, $statsCampaignSelected->hour, true);
264 exit;
265 }
266
267 private function getValues($modifier, $intervalCode, $campaignOpens, $campaignClicks, $dateCode, $hour = false)
268 {
269 $opens = [];
270 foreach ($campaignOpens as $one) {
271 $opens[acym_date(acym_getTime($one->open_date), $dateCode)] = $one->open;
272 }
273
274 $clicks = [];
275 foreach ($campaignClicks as $one) {
276 $clicks[acym_date(acym_getTime($one->date_click), $dateCode)] = $one->click;
277 }
278
279 $begin = new \DateTime(empty($campaignClicks) ? $campaignOpens[0]->open_date : min([$campaignOpens[0]->open_date, $campaignClicks[0]->date_click]));
280 $end = new \DateTime(empty($campaignClicks) ? end($campaignOpens)->open_date : max([end($campaignOpens)->open_date, end($campaignClicks)->date_click]));
281
282 $end->modify('+1 '.$modifier);
283
284 $interval = new \DateInterval($intervalCode);
285 $daterange = new \DatePeriod($begin, $interval, $end);
286
287 $result = [];
288 foreach ($daterange as $date) {
289 $one = $date->format($dateCode);
290
291 $current = [];
292 $current['open'] = empty($opens[$one]) ? 0 : $opens[$one];
293 $current['click'] = empty($clicks[$one]) ? 0 : $clicks[$one];
294
295 $key = $hour ? $one.':00' : $one;
296 $result[$key] = $current;
297 }
298
299 return $result;
300 }
301
302 public function prepareLineChart(&$statsCampaignSelected, $mailIdsOfCampaign, $newStart = '', $newEnd = '')
303 {
304 $campaignClass = new CampaignClass();
305 $statsCampaignSelected->hasStats = true;
306
307 $campaignOpenByMonth = $campaignClass->getOpenByMonth($mailIdsOfCampaign, $newStart, $newEnd);
308 $campaignOpenByDay = $campaignClass->getOpenByDay($mailIdsOfCampaign, $newStart, $newEnd);
309 $campaignOpenByHour = $campaignClass->getOpenByHour($mailIdsOfCampaign, $newStart, $newEnd);
310
311 if (empty($campaignOpenByMonth) || empty($campaignOpenByDay) || empty($campaignOpenByHour)) {
312 $statsCampaignSelected->hasStats = false;
313
314 return;
315 }
316
317 $urlClickClass = new UrlClickClass();
318 $campaignClickByMonth = $urlClickClass->getAllClickByMailMonth($mailIdsOfCampaign, $newStart, $newEnd);
319 $campaignClickByDay = $urlClickClass->getAllClickByMailDay($mailIdsOfCampaign, $newStart, $newEnd);
320 $campaignClickByHour = $urlClickClass->getAllClickByMailHour($mailIdsOfCampaign, $newStart, $newEnd);
321
322 $statsCampaignSelected->month = $this->getValues('day', 'P1M', $campaignOpenByMonth, $campaignClickByMonth, 'Y-m');
323 $statsCampaignSelected->day = $this->getValues('hour', 'P1D', $campaignOpenByDay, $campaignClickByDay, 'Y-m-d');
324 $statsCampaignSelected->hour = $this->getValues('min', 'PT1H', $campaignOpenByHour, $campaignClickByHour, 'Y-m-d H:i', true);
325
326 $allHour = array_keys($statsCampaignSelected->hour);
327
328 $statsCampaignSelected->startEndDateHour = [];
329 $statsCampaignSelected->startEndDateHour['start'] = $allHour[0];
330 $statsCampaignSelected->startEndDateHour['end'] = end($allHour);
331 }
332
333 public function exportGlobal()
334 {
335 $exportType = acym_getVar('string', 'export_type', 'charts');
336
337 $functionName = 'exportGlobal'.ucfirst($exportType);
338
339 if (!method_exists($this, $functionName)) {
340 acym_enqueueMessage(acym_translation('ACYM_EXPORT_METHOD_NOT_FOUND'), 'error');
341 $this->listing();
342
343 return;
344 }
345
346 $this->$functionName();
347 }
348
349 public function prepareOpenTimeChart(&$data)
350 {
351 $userStatClass = new UserStatClass();
352 $statsDB = $userStatClass->getOpenTimeStats($this->selectedMailIds);
353
354 if (empty($statsDB['total_open'])) {
355 $data['openTime'] = $userStatClass->getDefaultStat();
356 $data['empty_open'] = true;
357
358 return true;
359 }
360 $data['empty_open'] = false;
361
362 $stats = [];
363
364 for ($day = 0 ; $day < 7 ; $day++) {
365 $stats[$day] = [];
366 for ($hour = 0 ; $hour < 8 ; $hour++) {
367 if (empty($statsDB['stats'][$day.'_'.$hour]) || empty($statsDB['total_open'])) {
368 $percentage = 0;
369 } else {
370 $percentage = ($statsDB['stats'][$day.'_'.$hour]->open_total * 100) / $statsDB['total_open'];
371 }
372 $stats[$day][$hour] = round($percentage);
373 }
374 }
375
376 $data['openTime'] = $stats;
377
378 return true;
379 }
380
381 public function prepareStatByList(&$data)
382 {
383 $mailid = (count(array_unique($data['selectedMailid'])) != 1) ? 0 : $data['selectedMailid'][0];
384
385 if (empty($mailid)) {
386 return;
387 }
388
389 $mailSelected = $this->getVarFiltersListing('int', 'mail_id_language', $mailid);
390
391 $mailClass = new MailClass();
392 $mail = $mailClass->getOneById($mailSelected);
393 $mainMailId = empty($mail->parent_id) ? $mail->id : $mail->parent_id;
394
395 $data['lists'] = [];
396 $data['emailsSent'] = [];
397 $data['emailsOpen'] = [];
398 $data['bounces'] = [];
399 $data['unsubscribed'] = [];
400 $data['click'] = [];
401 $data['listsStats'] = [];
402 $data['userPerList'] = [];
403
404 $query = 'SELECT l.id, l.name, l.color FROM #__acym_list l';
405 $query .= ' JOIN #__acym_mail_has_list ml on l.id = ml.list_id';
406 $query .= ' WHERE ml.mail_id = '.$mainMailId;
407
408 $data['lists'] = acym_loadObjectList($query, 'id');
409 $listIds = implode(',', array_keys($data['lists']));
410
411 if (!empty($listIds)) {
412 $query = 'SELECT ul.list_id, SUM(us.sent) as nbSent, SUM(IF(us.open >= 1, 1, 0)) as nbOpen, SUM(us.bounce) as nbBounce, SUM(us.unsubscribe) as nbUnsub from #__acym_user_has_list ul';
413 $query .= ' JOIN #__acym_user_stat us on ul.user_id = us.user_id';
414 $query .= ' WHERE ul.list_id in ('.$listIds.') AND us.mail_id = '.$mailSelected;
415 $query .= ' GROUP BY ul.list_id;';
416 $data['listsStats'] = acym_loadObjectList($query, 'list_id');
417
418 $query = 'SELECT ul.list_id, COUNT(uc.click) as nbClick';
419 $query .= ' FROM #__acym_user_has_list ul ';
420 $query .= ' JOIN #__acym_url_click uc on ul.user_id = uc.user_id';
421 $query .= ' WHERE ul.list_id in ('.$listIds.') AND uc.mail_id = '.$mailSelected;
422 $query .= ' GROUP BY ul.list_id;';
423
424 $data['nbClick'] = acym_loadObjectList($query, 'list_id');
425
426 $query = 'SELECT ul.list_id, COUNT(ul.user_id) as nbUser';
427 $query .= ' FROM #__acym_user_has_list ul';
428 $query .= ' JOIN #__acym_user_stat us ON ul.user_id = us.user_id';
429 $query .= ' WHERE ul.list_id in ('.$listIds.') AND us.mail_id = '.$mailSelected;
430 $query .= ' GROUP BY ul.list_id;';
431
432 $data['userPerList'] = acym_loadObjectList($query, 'list_id');
433 }
434
435 foreach ($data['listsStats'] as $listId => $item) {
436 $data['emailsSent'][$listId] = [
437 'label' => $data['lists'][$listId]->name,
438 'value' => $item->nbSent,
439 'color' => $data['lists'][$listId]->color,
440 ];
441 $data['emailsOpen'][$listId] = [
442 'label' => $data['lists'][$listId]->name,
443 'value' => round(($item->nbOpen * 100) / $item->nbSent),
444 'color' => $data['lists'][$listId]->color,
445 ];
446 $data['bounces'][$listId] = [
447 'label' => $data['lists'][$listId]->name,
448 'value' => round(($item->nbBounce * 100) / $item->nbSent),
449 'color' => $data['lists'][$listId]->color,
450 ];
451 $data['unsubscribed'][$listId] = [
452 'label' => $data['lists'][$listId]->name,
453 'value' => round(($item->nbUnsub * 100) / $item->nbSent),
454 'color' => $data['lists'][$listId]->color,
455 ];
456 }
457
458 foreach ($data['userPerList'] as $listId => $item) {
459 $nbUser = $item->nbUser;
460 $data['click'][$listId] = ['label' => $data['lists'][$listId]->name, 'value' => 0, 'color' => $data['lists'][$listId]->color];
461
462 if ($nbUser > 0 && !empty($data['nbClick'][$listId]->nbClick)) {
463 $data['click'][$listId]['value'] = round(($data['nbClick'][$listId]->nbClick * 100) / $nbUser);
464 }
465 }
466 }
467
468 private function prepareAbTestMails(&$data)
469 {
470 if (empty($this->selectedMailIds)) return;
471
472 $mailClass = new MailClass();
473
474 $mailVersions = [];
475
476 if (empty($data['mailInformation']->parent_id)) {
477 $mailVersions = $mailClass->getParentAndChildMails($data['mailInformation']->id);
478 } elseif (!empty($data['mailInformation']->parent_id)) {
479 $parentEmail = $mailClass->getOneById($data['mailInformation']->parent_id);
480 if (empty($parentEmail)) return;
481 $mailVersions = $mailClass->getParentAndChildMails($parentEmail->id);
482 }
483
484 $data['emailVersions'] = [];
485
486 foreach ($mailVersions as $email) {
487 $data['emailVersions'][$email->id] = $email->name.' - '.$email->subject;
488 }
489 }
490
491 private function prepareMultilingualMails(&$data)
492 {
493 if (empty($this->selectedMailIds)) return;
494
495 $mailClass = new MailClass();
496
497 $translatedEmails = [];
498
499 if (empty($data['mailInformation']->parent_id)) {
500 $translatedEmails = $mailClass->getTranslationsById($data['mailInformation']->id, true, true);
501 } elseif (!empty($data['mailInformation']->parent_id)) {
502 $parentEmail = $mailClass->getOneById($data['mailInformation']->parent_id);
503 if (empty($parentEmail)) return;
504 $translatedEmails = $mailClass->getTranslationsById($parentEmail->id, true, true);
505 }
506
507 $data['emailTranslations'] = [];
508 $allLanguages = acym_getLanguages();
509
510 foreach ($translatedEmails as $email) {
511 if (!empty($email->language)) {
512 $data['emailTranslations'][$email->id] = empty($allLanguages[$email->language]) ? $email->language
513 : $allLanguages[$email->language]->name;
514 }
515 }
516 }
517
518 private function prepareOpenSourcesStats(&$data)
519 {
520 $userStatClass = new UserStatClass();
521 $openedFromStats = $userStatClass->getOpenSourcesStats($this->selectedMailIds);
522
523 $formattedSources = [];
524 foreach ($openedFromStats as $oneSource) {
525 if (empty($oneSource->number)) continue;
526
527 if (empty($oneSource->opened_with)) $oneSource->opened_with = acym_translation('ACYM_UNKNOWN');
528 $formattedSources[$oneSource->opened_with] = $oneSource->number;
529 }
530
531 $data['openedWith'] = $formattedSources;
532 }
533
534 private function prepareDevicesStats(&$data)
535 {
536 $campaignClass = new CampaignClass();
537
538 $devicesCampaign = $campaignClass->getDevicesWithCountByMailId($this->selectedMailIds);
539
540 $formattedDevices = [];
541 foreach ($devicesCampaign as $oneDevice) {
542 if (empty($oneDevice->number)) continue;
543
544 if (in_array($oneDevice->device, array_keys(UserStatClass::MOBILE_DEVICES))) {
545 $deviceName = UserStatClass::MOBILE_DEVICES[$oneDevice->device];
546 } elseif (in_array($oneDevice->device, array_keys(UserStatClass::DESKTOP_DEVICES))) {
547 $deviceName = UserStatClass::DESKTOP_DEVICES[$oneDevice->device];
548 } else {
549 $deviceName = acym_translation('ACYM_UNKNOWN');
550 }
551
552 $formattedDevices[$deviceName] = $oneDevice->number;
553 }
554
555 $data['devices'] = $formattedDevices;
556 }
557
558 public function preparecharts(&$data)
559 {
560 $mailStatClass = new MailStatClass();
561
562 $data['mail'] = $mailStatClass->getSentFailByMailIds($this->selectedMailIds);
563 if (empty($data['mail'])) return;
564
565 $campaignClass = new CampaignClass();
566 $urlClickClass = new UrlClickClass();
567
568 $data['mail']->totalMail = $data['mail']->sent + $data['mail']->fail;
569 $data['mail']->percentageSent = empty($data['mail']->totalMail) ? 0 : number_format(($data['mail']->sent * 100) / $data['mail']->totalMail, 2);
570 $data['mail']->allSent = empty($data['mail']->totalMail)
571 ? acym_translationSprintf('ACYM_X_MAIL_SUCCESSFULLY_SENT_OF_X', 0, 0)
572 : acym_translationSprintf(
573 'ACYM_X_MAIL_SUCCESSFULLY_SENT_OF_X',
574 $data['mail']->sent,
575 $data['mail']->totalMail
576 );
577
578 $openRateCampaign = empty($this->selectedMailIds) ? $campaignClass->getOpenRateAllCampaign() : $campaignClass->getOpenRateCampaigns($this->selectedMailIds);
579 $data['mail']->percentageOpen = empty($openRateCampaign->sent) ? 0 : number_format(($openRateCampaign->open_unique * 100) / $openRateCampaign->sent, 2);
580 $data['mail']->allOpen = empty($openRateCampaign->sent)
581 ? acym_translationSprintf('ACYM_X_MAIL_OPENED_OF_X', 0, 0)
582 : acym_translationSprintf(
583 'ACYM_X_MAIL_OPENED_OF_X',
584 $openRateCampaign->open_unique,
585 $openRateCampaign->sent
586 );
587
588 $clickRateCampaign = $urlClickClass->getNumberUsersClicked($this->selectedMailIds);
589 $data['mail']->percentageClick = empty($data['mail']->sent) ? 0 : number_format(($clickRateCampaign * 100) / $data['mail']->sent, 2);
590 $data['mail']->allClick = empty($data['mail']->sent)
591 ? acym_translationSprintf('ACYM_X_MAIL_CLICKED_OF_X', 0, 0)
592 : acym_translationSprintf(
593 'ACYM_X_MAIL_CLICKED_OF_X',
594 $clickRateCampaign,
595 $data['mail']->sent
596 );
597
598 $bounceRateCampaign = empty($this->selectedMailIds) ? $campaignClass->getBounceRateAllCampaign() : $campaignClass->getBounceRateCampaigns($this->selectedMailIds);
599 $data['mail']->percentageBounce = empty($data['mail']->sent) ? 0 : number_format(($bounceRateCampaign->bounce_unique * 100) / $data['mail']->sent, 2);
600 $data['mail']->allBounce = empty($data['mail']->sent)
601 ? acym_translationSprintf('ACYM_X_BOUNCE_OF_X', 0, 0)
602 : acym_translationSprintf(
603 'ACYM_X_BOUNCE_OF_X',
604 $bounceRateCampaign->bounce_unique,
605 $data['mail']->sent
606 );
607
608 if (!empty($this->selectedMailIds)) {
609 $mailStat = $mailStatClass->getByMailIds($this->selectedMailIds);
610 $data['mail']->percentageUnsub = empty($data['mail']->sent) ? 0 : number_format(($mailStat->unsubscribe_total * 100) / $data['mail']->sent, 2);
611 $data['mail']->allUnsub = empty($data['mail']->sent)
612 ? acym_translationSprintf('ACYM_X_USERS_UNSUBSCRIBED_OF_X', 0, 0)
613 : acym_translationSprintf(
614 'ACYM_X_USERS_UNSUBSCRIBED_OF_X',
615 $mailStat->unsubscribe_total,
616 $data['mail']->sent
617 );
618 }
619
620 $this->prepareDevicesStats($data);
621 $this->prepareOpenSourcesStats($data);
622 $this->prepareLineChart($data['mail'], $this->selectedMailIds);
623 }
624
625 private function decode(&$detailedStats, $columnsToDecode = ['mail_subject', 'mail_name'])
626 {
627 foreach ($detailedStats as $oneDetailedStat) {
628 foreach ($columnsToDecode as $column) {
629 if (!empty($oneDetailedStat->$column)) {
630 $oneDetailedStat->$column = acym_utf8Decode($oneDetailedStat->$column);
631 }
632 }
633 }
634 }
635
636 private function prepareLinksDetailsListing(&$data)
637 {
638 $data['search'] = $this->getVarFiltersListing('string', 'links_details_search', '');
639 $data['ordering'] = $this->getVarFiltersListing('string', 'links_details_ordering', 'id');
640 $data['orderingSortOrder'] = $this->getVarFiltersListing('string', 'links_details_ordering_sort_order', 'desc');
641
642 if (empty($this->selectedMailIds)) return;
643
644 $pagination = new PaginationHelper();
645 $urlClickClass = new UrlClickClass();
646
647 $detailedStatsPerPage = $pagination->getListLimit();
648 $page = $this->getVarFiltersListing('int', 'links_details_pagination_page', 1);
649
650 $urlClicks = $urlClickClass->getUrlsFromMailsWithDetails(
651 [
652 'ordering' => $data['ordering'],
653 'search' => $data['search'],
654 'detailedStatsPerPage' => $detailedStatsPerPage,
655 'offset' => ($page - 1) * $detailedStatsPerPage,
656 'ordering_sort_order' => $data['orderingSortOrder'],
657 'mail_ids' => $this->selectedMailIds,
658 ]
659 );
660
661 $this->decode($urlClicks['links_details']);
662
663 $pagination->setStatus($urlClicks['total'], $page, $detailedStatsPerPage);
664
665 $data['pagination'] = $pagination;
666 $data['links_details'] = $urlClicks['links_details'];
667 $data['query'] = $urlClicks['query'];
668 }
669
670 private function prepareListReceivers(&$data)
671 {
672 if (empty($this->selectedMailIds)) return;
673
674 $mailStatClass = new MailStatClass();
675 $mailClass = new MailClass();
676
677 $data['mailStat'] = $mailStatClass->getByMailIds($this->selectedMailIds);
678 $data['lists'] = $mailClass->getAllListsByMailId($this->selectedMailIds);
679 }
680
681 private function exportGlobalFormatted()
682 {
683 $exportHelper = new ExportHelper();
684 $data = [];
685 $this->prepareDefaultPageInfo($data);
686 $data['show_date_filters'] = true;
687 $data['page_title'] = false;
688 $timeLinechart = acym_getVar('string', 'time_linechart', 'month');
689
690
691 $this->prepareMailFilter($data);
692 $this->prepareClickStats($data);
693 $this->preparecharts($data);
694 $this->prepareDefaultRoundCharts($data);
695 $this->prepareDefaultLineChart($data);
696 $this->prepareDefaultDevicesChart($data);
697 $this->prepareDefaultBrowsersChart($data);
698
699 $globalDonut = [
700 $data['mail']->percentageSent,
701 $data['mail']->percentageOpen,
702 $data['mail']->percentageClick,
703 $data['mail']->percentageBounce,
704 $data['mail']->percentageUnsub,
705 ];
706 $mailName = empty($this->selectedMailIds) ? acym_translation('ACYM_ALL_MAILS') : $data['mailInformation']->name;
707 $globalLine = $data['mail']->$timeLinechart;
708
709 $exportHelper->exportStatsFormattedCSV($mailName, $globalDonut, $globalLine, $timeLinechart);
710 exit;
711 }
712
713 private function exportGlobalFull()
714 {
715 $exportHelper = new ExportHelper();
716 $data = [];
717 $this->prepareDefaultPageInfo($data);
718
719 $where = '';
720 if (!empty($this->selectedMailIds)) $where = 'WHERE mail_id IN ('.implode(',', $this->selectedMailIds).')';
721
722 $columnsMailStat = acym_getColumns('mail_stat');
723 $columnsToExport = [];
724
725 $columnsToExport['mail.subject'] = acym_translation('ACYM_EMAIL_SUBJECT');
726 foreach ($columnsMailStat as $column) {
727 if ($column === 'mail_id') {
728 continue;
729 }
730
731 $translation = acym_translation('ACYM_'.strtoupper($column).'_COLUMN_STAT');
732 if ($column === 'send_date') {
733 $translation = acym_translation('ACYM_SEND_DATE');
734 } elseif ($column === 'click_total') {
735 $translation = acym_translation('ACYM_TOTAL_CLICKS');
736 } elseif ($column === 'click_unique') {
737 $translation = acym_translation('ACYM_UNIQUE_CLICKS');
738 }
739
740 $columnsToExport['mailstat.'.$column] = $translation;
741 }
742
743 $query = 'SELECT '.implode(', ', array_keys($columnsToExport)).' FROM #__acym_mail_stat AS mailstat LEFT JOIN #__acym_mail AS mail ON mail.id = mailstat.mail_id '.$where;
744 $exportHelper->exportStatsFullCSV($query, $columnsToExport);
745 exit;
746 }
747 }
748