Issues (3627)

LeadBundle/Command/CheckQueryBuildersCommand.php (2 issues)

1
<?php
2
3
/*
4
 * @copyright   2014 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\LeadBundle\Command;
13
14
use Mautic\CoreBundle\Command\ModeratedCommand;
15
use Mautic\LeadBundle\Entity\LeadList;
16
use Mautic\LeadBundle\Model\ListModel;
17
use Mautic\LeadBundle\Segment\Exception\FieldNotFoundException;
18
use Mautic\LeadBundle\Segment\Exception\SegmentNotFoundException;
19
use Monolog\Logger;
20
use Symfony\Component\Console\Input\InputInterface;
21
use Symfony\Component\Console\Input\InputOption;
22
use Symfony\Component\Console\Output\OutputInterface;
23
24
class CheckQueryBuildersCommand extends ModeratedCommand
25
{
26
    /** @var Logger */
27
    private $logger;
28
29
    /** @var bool */
30
    private $skipOld = false;
31
32
    protected function configure()
33
    {
34
        $this
35
            ->setName('mautic:segments:check-builders')
36
            ->setDescription('Compare output of query builders for given segments')
37
            ->addOption('--segment-id', '-i', InputOption::VALUE_OPTIONAL, 'Set the ID of segment to process')
38
            ->addOption('--skip-old', null, InputOption::VALUE_NONE, 'Skip old query builder');
39
40
        parent::configure();
41
    }
42
43
    protected function execute(InputInterface $input, OutputInterface $output)
44
    {
45
        $container    = $this->getContainer();
46
        $this->logger = $container->get('monolog.logger.mautic');
47
48
        /** @var \Mautic\LeadBundle\Model\ListModel $listModel */
49
        $listModel = $container->get('mautic.lead.model.list');
50
51
        $id            = $input->getOption('segment-id');
52
        $verbose       = $input->getOption('verbose');
53
        $this->skipOld = $input->getOption('skip-old');
54
55
        $failed = $ok = 0;
56
57
        if ($id && '+' != substr($id, strlen($id) - 1, 1)) {
58
            $list = $listModel->getEntity($id);
59
60
            if (!$list) {
61
                $output->writeln('<error>Segment with id "'.$id.'" not found');
0 ignored issues
show
Are you sure $id of type string|string[]|true can be used in concatenation? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

61
                $output->writeln('<error>Segment with id "'./** @scrutinizer ignore-type */ $id.'" not found');
Loading history...
62
63
                return 1;
64
            }
65
            $response = $this->runSegment($output, $verbose, $list, $listModel);
66
            if ($response) {
67
                ++$ok;
68
            } else {
69
                ++$failed;
70
            }
71
        } else {
72
            $lists = $listModel->getEntities(
73
                [
74
                    'iterator_mode' => true,
75
                    'orderBy'       => 'l.id',
76
                ]
77
            );
78
79
            while (false !== ($l = $lists->next())) {
80
                // Get first item; using reset as the key will be the ID and not 0
81
                $l = reset($l);
82
83
                if ('+' == substr($id, strlen($id) - 1, 1) and $l->getId() < intval(trim($id, '+'))) {
84
                    continue;
85
                }
86
                $response = $this->runSegment($output, $verbose, $l, $listModel);
87
                if (!$response) {
88
                    ++$failed;
89
                } else {
90
                    ++$ok;
91
                }
92
            }
93
94
            unset($l);
95
96
            unset($lists);
97
        }
98
99
        $total = $ok + $failed;
100
        $total = $total ?: 1; //prevent division be zero error
101
102
        $output->writeln('');
103
        $output->writeln(
104
            sprintf(
105
                '<info>Total success rate: %d%%, %d succeeded: and <error>%s</error>%s failed...</info> ',
106
                round(($ok / $total) * 100),
107
                $ok,
108
                ($failed ? $failed : ''),
109
                (!$failed ? $failed : '')
110
            )
111
        );
112
113
        return $failed ? 1 : 0;
114
    }
115
116
    private function format_period($inputSeconds)
117
    {
118
        $now = \DateTime::createFromFormat('U.u', number_format($inputSeconds, 6, '.', ''));
119
120
        return $now->format('H:i:s.u');
121
    }
122
123
    private function runSegment(OutputInterface $output, $verbose, LeadList $l, ListModel $listModel)
0 ignored issues
show
The parameter $verbose is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

123
    private function runSegment(OutputInterface $output, /** @scrutinizer ignore-unused */ $verbose, LeadList $l, ListModel $listModel)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
124
    {
125
        if (!$l->isPublished()) {
126
            $msg = sprintf('Segment #%d is not published', $l->getId());
127
            $output->writeln($msg);
128
            $this->logger->info($msg);
129
130
            return true;
131
        }
132
133
        $output->write('<info>Running segment '.$l->getId().'...');
134
135
        if (!$this->skipOld) {
136
            $this->logger->info(sprintf('Running OLD segment #%d', $l->getId()));
137
138
            $timer1    = microtime(true);
139
            $processed = $listModel->getVersionOld($l);
140
            $timer1    = microtime(true) - $timer1;
141
        } else {
142
            $processed = ['count' => -1, 'maxId' => -1];
143
            $timer1    = 0;
144
        }
145
146
        $this->logger->info(sprintf('Running NEW segment #%d', $l->getId()));
147
148
        $timer2 = microtime(true);
149
        try {
150
            $processed2 = $listModel->getVersionNew($l);
151
        } catch (SegmentNotFoundException $exception) {
152
            $processed2 = [
153
                [
154
                    'count' => -1,
155
                    'maxId' => -1,
156
                ],
157
            ];
158
            $output->write('<error>'.$exception->getMessage().' </error>');
159
        } catch (FieldNotFoundException $exception) {
160
            $processed2 = [
161
                [
162
                    'count' => -1,
163
                    'maxId' => -1,
164
                ],
165
            ];
166
167
            $output->write('<error>'.$exception->getMessage().' </error>');
168
        }
169
170
        $timer2 = microtime(true) - $timer2;
171
172
        $processed2 = array_shift($processed2);
173
174
        if ((intval($processed['count']) != intval($processed2['count'])) or (intval($processed['maxId']) != intval($processed2['maxId']))) {
175
            $output->write('<error>FAILED - ');
176
        } else {
177
            $output->write('<info>OK - ');
178
        }
179
180
        $output->write(
181
            sprintf(
182
                'old: c: %d, m: %d, time: %s(est)  <--> new: c: %d, m: %s, time: %s',
183
                $processed['count'],
184
                $processed['maxId'],
185
                $this->format_period($timer1),
186
                $processed2['count'],
187
                $processed2['maxId'],
188
                $this->format_period($timer2)
189
            )
190
        );
191
192
        if ((intval($processed['count']) != intval($processed2['count'])) or (intval($processed['maxId']) != intval($processed2['maxId']))) {
193
            $output->writeln('</error>');
194
        } else {
195
            $output->writeln('</info>');
196
        }
197
198
        $failed = ((intval($processed['count']) != intval($processed2['count'])) or (intval($processed['maxId']) != intval($processed2['maxId'])));
199
200
        return !$failed;
201
    }
202
}
203