Issues (3627)

EventListener/DetermineWinnerSubscriber.php (1 issue)

1
<?php
2
3
/*
4
 * @copyright   2019 Mautic Contributors. All rights reserved
5
 * @author      Mautic
6
 *
7
 * @link        http://mautic.org
8
 *
9
 * @license     GNU/GPLv3 http://www.gnu.org/licenses/gpl-3.0.html
10
 */
11
12
namespace Mautic\FormBundle\EventListener;
13
14
use Mautic\CoreBundle\Event\DetermineWinnerEvent;
15
use Mautic\EmailBundle\Entity\Email;
16
use Mautic\FormBundle\Entity\SubmissionRepository;
17
use Mautic\FormBundle\FormEvents;
18
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
19
use Symfony\Component\Translation\TranslatorInterface;
20
21
class DetermineWinnerSubscriber implements EventSubscriberInterface
22
{
23
    /**
24
     * @var SubmissionRepository
25
     */
26
    private $submissionRepository;
27
28
    /**
29
     * @var TranslatorInterface
30
     */
31
    private $translator;
32
33
    public function __construct(SubmissionRepository $submissionRepository, TranslatorInterface $translator)
34
    {
35
        $this->submissionRepository = $submissionRepository;
36
        $this->translator           = $translator;
37
    }
38
39
    /**
40
     * @return array
41
     */
42
    public static function getSubscribedEvents()
43
    {
44
        return [
45
            FormEvents::ON_DETERMINE_SUBMISSION_RATE_WINNER => ['onDetermineSubmissionWinner', 0],
46
        ];
47
    }
48
49
    /**
50
     * Determines the winner of A/B test based on number of form submissions.
51
     */
52
    public function onDetermineSubmissionWinner(DetermineWinnerEvent $event)
53
    {
54
        $parameters = $event->getParameters();
55
        $parent     = $parameters['parent'];
56
        $children   = $parameters['children'];
57
58
        //if this is an email A/B test, then link email to page to form submission
59
        //if it is a page A/B test, then link form submission to page
60
        $type = ($parent instanceof Email) ? 'email' : 'page';
61
62
        $ids = [$parent->getId()];
63
64
        foreach ($children as $c) {
65
            if ($c->isPublished()) {
66
                $id    = $c->getId();
67
                $ids[] = $id;
68
            }
69
        }
70
71
        $startDate = $parent->getVariantStartDate();
72
        if (null != $startDate && !empty($ids)) {
73
            $counts = ('page' == $type) ? $this->submissionRepository->getSubmissionCountsByPage($ids, $startDate) : $this->submissionRepository->getSubmissionCountsByEmail($ids, $startDate);
74
75
            if ($counts) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $counts of type array<mixed,mixed> is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
76
                $submissions = $support = $data = [];
77
                $hasResults  = [];
78
79
                $submissionLabel = $this->translator->trans('mautic.form.abtest.label.submissions');
80
                $hitLabel        = ('page' == $type) ? $this->translator->trans('mautic.form.abtest.label.hits') : $this->translator->trans('mautic.form.abtest.label.sentemils');
81
82
                foreach ($counts as $stats) {
83
                    $submissionRate            = ($stats['total']) ? round(($stats['count'] / $stats['total']) * 100, 2) : 0;
84
                    $submissions[$stats['id']] = $submissionRate;
85
                    $data[$submissionLabel][]  = $stats['count'];
86
                    $data[$hitLabel][]         = $stats['total'];
87
                    $support['labels'][]       = $stats['id'].':'.$stats['name'].' ('.$submissionRate.'%)';
88
                    $hasResults[]              = $stats['id'];
89
                }
90
91
                //make sure that parent and published children are included
92
                if (!in_array($parent->getId(), $hasResults)) {
93
                    $data[$submissionLabel][] = 0;
94
                    $data[$hitLabel][]        = 0;
95
                    $support['labels'][]      = (('page' == $type) ? $parent->getTitle() : $parent->getName()).' (0%)';
96
                }
97
98
                foreach ($children as $c) {
99
                    if ($c->isPublished()) {
100
                        if (!in_array($c->getId(), $hasResults)) {
101
                            $data[$submissionLabel][] = 0;
102
                            $data[$hitLabel][]        = 0;
103
                            $support['labels'][]      = (('page' == $type) ? $c->getTitle() : $c->getName()).' (0%)';
104
                        }
105
                    }
106
                }
107
                $support['data'] = $data;
108
109
                //set max for scales
110
                $maxes = [];
111
                foreach ($support['data'] as $data) {
112
                    $maxes[] = max($data);
113
                }
114
                $top                   = max($maxes);
115
                $support['step_width'] = (ceil($top / 10) * 10);
116
117
                //put in order from least to greatest just because
118
                asort($submissions);
119
120
                //who's the winner?
121
                $max = max($submissions);
122
123
                //get the page ids with the most number of submissions
124
                $winners = array_keys($submissions, $max);
125
126
                $event->setAbTestResults([
127
                    'winners'         => $winners,
128
                    'support'         => $support,
129
                    'basedOn'         => 'form.submissions',
130
                    'supportTemplate' => 'MauticPageBundle:SubscribedEvents\AbTest:bargraph.html.php',
131
                ]);
132
133
                return;
134
            }
135
        }
136
137
        $event->setAbTestResults([
138
            'winners' => [],
139
            'support' => [],
140
            'basedOn' => 'form.submissions',
141
        ]);
142
    }
143
}
144