Completed
Pull Request — 5.6 (#2830)
by Jeroen
14:14
created

Command/GoogleAnalyticsDataCollectCommand.php (1 issue)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
3
namespace Kunstmaan\DashboardBundle\Command;
4
5
use Doctrine\ORM\EntityManagerInterface;
6
use Kunstmaan\DashboardBundle\Command\Helper\Analytics\ChartDataCommandHelper;
7
use Kunstmaan\DashboardBundle\Command\Helper\Analytics\GoalCommandHelper;
8
use Kunstmaan\DashboardBundle\Command\Helper\Analytics\MetricsCommandHelper;
9
use Kunstmaan\DashboardBundle\Command\Helper\Analytics\UsersCommandHelper;
10
use Kunstmaan\DashboardBundle\Entity\AnalyticsConfig;
11
use Kunstmaan\DashboardBundle\Entity\AnalyticsOverview;
12
use Kunstmaan\DashboardBundle\Entity\AnalyticsSegment;
13
use Kunstmaan\DashboardBundle\Helper\Google\Analytics\ServiceHelper;
14
use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand;
15
use Symfony\Component\Console\Input\InputInterface;
16
use Symfony\Component\Console\Input\InputOption;
17
use Symfony\Component\Console\Output\OutputInterface;
18
19
/**
20
 * @final since 5.1
21
 * NEXT_MAJOR extend from `Command` and remove `$this->getContainer` usages
22
 */
23
class GoogleAnalyticsDataCollectCommand extends ContainerAwareCommand
24
{
25
    /** @var EntityManagerInterface */
26
    private $em;
27
28
    /** @var OutputInterface */
29
    private $output;
30
31
    /** @var int */
32
    private $errors = 0;
33
34
    /** @var ServiceHelper */
35
    private $serviceHelper;
36
37
    /**
38
     * @param EntityManagerInterface|null $em
39
     * @param ServiceHelper               $serviceHelper
40
     */
41 View Code Duplication
    public function __construct(/* EntityManagerInterface */ $em = null, ServiceHelper $serviceHelper = null)
42
    {
43
        parent::__construct();
44
45
        if (!$em instanceof EntityManagerInterface) {
46
            @trigger_error(sprintf('Passing a command name as the first argument of "%s" is deprecated since version symfony 3.4 and will be removed in symfony 4.0. If the command was registered by convention, make it a service instead. ', __METHOD__), E_USER_DEPRECATED);
47
48
            $this->setName(null === $em ? 'kuma:dashboard:widget:googleanalytics:data:collect' : $em);
49
50
            return;
51
        }
52
53
        $this->em = $em;
54
        $this->serviceHelper = $serviceHelper;
55
    }
56
57
    /**
58
     * Configures the current command.
59
     */
60
    protected function configure()
61
    {
62
        $this
63
            ->setName('kuma:dashboard:widget:googleanalytics:data:collect')
64
            ->setDescription('Collect the Google Analytics dashboard widget data')
65
            ->addOption(
66
                'config',
67
                null,
68
                InputOption::VALUE_OPTIONAL,
69
                'Specify to only update one config',
70
                false
71
            )
72
            ->addOption(
73
                'segment',
74
                null,
75
                InputOption::VALUE_OPTIONAL,
76
                'Specify to only update one segment',
77
                false
78
            )
79
            ->addOption(
80
                'overview',
81
                null,
82
                InputOption::VALUE_OPTIONAL,
83
                'Specify to only update one overview',
84
                false
85
            );
86
    }
87
88
    /**
89
     * @return int|void|null
90
     */
91
    protected function execute(InputInterface $input, OutputInterface $output)
92
    {
93
        if (null === $this->em) {
94
            $this->em = $this->getContainer()->get('doctrine.orm.entity_manager');
95
        }
96
97
        if (null === $this->serviceHelper) {
98
            $this->serviceHelper = $this->getContainer()->get('kunstmaan_dashboard.helper.google.analytics.service');
99
        }
100
101
        $this->output = $output;
102
103
        // check if token is set
104
        $configHelper = $this->getContainer()->get('kunstmaan_dashboard.helper.google.analytics.config');
105
        if (!$configHelper->tokenIsSet()) {
106
            $this->output->writeln('You haven\'t configured a Google account yet');
107
108
            return 0;
109
        }
110
111
        // get params
112
        $configId = false;
113
        $segmentId = false;
114
        $overviewId = false;
115
116
        try {
117
            $configId = $input->getOption('config');
118
            $segmentId = $input->getOption('segment');
119
            $overviewId = $input->getOption('overview');
120
        } catch (\Exception $e) {
121
        }
122
123
        // get the overviews
124
        try {
125
            $overviews = [];
126
127
            if ($overviewId) {
128
                $overviews[] = $this->getSingleOverview($overviewId);
129
            } elseif ($segmentId) {
130
                $overviews = $this->getOverviewsOfSegment($segmentId);
131
            } elseif ($configId) {
132
                $overviews = $this->getOverviewsOfConfig($configId);
133
            } else {
134
                $overviews = $this->getAllOverviews();
135
            }
136
137
            // update the overviews
138
            $this->updateData($overviews);
139
            $result = '<fg=green>Google Analytics data updated with <fg=red>' . $this->errors . '</fg=red> error';
140
            $result .= $this->errors != 1 ? 's</fg=green>' : '</fg=green>';
141
            $this->output->writeln($result); // done
142
143
            return 0;
144
        } catch (\Exception $e) {
145
            $this->output->writeln($e->getMessage());
146
147
            return 1;
148
        }
149
    }
150
151
    /**
152
     * get a single overview
153
     *
154
     * @param int $overviewId
155
     *
156
     * @return AnalyticsOverview
157
     */
158
    private function getSingleOverview($overviewId)
159
    {
160
        // get specified overview
161
        $overviewRepository = $this->em->getRepository(AnalyticsOverview::class);
162
        $overview = $overviewRepository->find($overviewId);
163
164
        if (!$overview) {
165
            throw new \Exception('Unkown overview ID');
166
        }
167
168
        return $overview;
169
    }
170
171
    /**
172
     * get all overviews of a segment
173
     *
174
     * @param int $segmentId
175
     *
176
     * @return array
177
     */
178 View Code Duplication
    private function getOverviewsOfSegment($segmentId)
179
    {
180
        // get specified segment
181
        $segmentRepository = $this->em->getRepository(AnalyticsSegment::class);
182
        $segment = $segmentRepository->find($segmentId);
183
184
        if (!$segment) {
185
            throw new \Exception('Unkown segment ID');
186
        }
187
188
        // init the segment
189
        $segmentRepository->initSegment($segment);
190
191
        // get the overviews
192
        return $segment->getOverviews();
193
    }
194
195
    /**
196
     * get all overviews of a config
197
     *
198
     * @param int $configId
199
     *
200
     * @return array
201
     */
202
    private function getOverviewsOfConfig($configId)
203
    {
204
        $configRepository = $this->em->getRepository(AnalyticsConfig::class);
205
        $segmentRepository = $this->em->getRepository(AnalyticsSegment::class);
206
        $overviewRepository = $this->em->getRepository(AnalyticsOverview::class);
207
        // get specified config
208
        $config = $configRepository->find($configId);
209
210
        if (!$config) {
211
            throw new \Exception('Unkown config ID');
212
        }
213
214
        // create default overviews for this config if none exist yet
215
        if (!\count($config->getOverviews())) {
216
            $overviewRepository->addOverviews($config);
217
        }
218
219
        // init all the segments for this config
220
        $segments = $config->getSegments();
221
        foreach ($segments as $segment) {
222
            $segmentRepository->initSegment($segment);
223
        }
224
225
        // get the overviews
226
        return $config->getOverviews();
227
    }
228
229
    /**
230
     * get all overviews
231
     *
232
     * @return array
0 ignored issues
show
Consider making the return type a bit more specific; maybe use object[].

This check looks for the generic type array as a return type and suggests a more specific type. This type is inferred from the actual code.

Loading history...
233
     */
234 View Code Duplication
    private function getAllOverviews()
235
    {
236
        $configRepository = $this->em->getRepository(AnalyticsConfig::class);
237
        $overviewRepository = $this->em->getRepository(AnalyticsOverview::class);
238
        $segmentRepository = $this->em->getRepository(AnalyticsSegment::class);
239
        $configs = $configRepository->findAll();
240
241
        foreach ($configs as $config) {
242
            // add overviews if none exist yet
243
            if (\count($config->getOverviews()) == 0) {
244
                $overviewRepository->addOverviews($config);
245
            }
246
247
            // init all the segments for this config
248
            $segments = $config->getSegments();
249
            foreach ($segments as $segment) {
250
                $segmentRepository->initSegment($segment);
251
            }
252
        }
253
254
        // get all overviews
255
        return $overviewRepository->findAll();
256
    }
257
258
    /**
259
     * update the overviews
260
     *
261
     * @param array $overviews collection of all overviews which need to be updated
262
     */
263
    public function updateData($overviews)
264
    {
265
        // helpers
266
        $queryHelper = $this->getContainer()->get('kunstmaan_dashboard.helper.google.analytics.query');
267
        $configHelper = $this->getContainer()->get('kunstmaan_dashboard.helper.google.analytics.config');
268
        $metrics = new MetricsCommandHelper($configHelper, $queryHelper, $this->output, $this->em);
269
        $chartData = new ChartDataCommandHelper($configHelper, $queryHelper, $this->output, $this->em);
270
        $goals = new GoalCommandHelper($configHelper, $queryHelper, $this->output, $this->em);
271
        $visitors = new UsersCommandHelper($configHelper, $queryHelper, $this->output, $this->em);
272
273
        // get data per overview
274
        foreach ($overviews as $overview) {
275
            $configHelper->init($overview->getConfig()->getId());
276
            /* @var AnalyticsOverview $overview */
277
            $this->output->writeln('Fetching data for overview "<fg=green>' . $overview->getTitle() . '</fg=green>"');
278
279
            try {
280
                // metric data
281
                $metrics->getData($overview);
282
                if ($overview->getSessions()) { // if there are any visits
283
                    // day-specific data
284
                    $chartData->getData($overview);
285
286
                    // get goals
287
                    $goals->getData($overview);
288
289
                    // visitor types
290
                    $visitors->getData($overview);
291
                } else {
292
                    // reset overview
293
                    $this->reset($overview);
294
                    $this->output->writeln("\t" . 'No visitors');
295
                }
296
                // persist entity back to DB
297
                $this->output->writeln("\t" . 'Persisting..');
298
                $this->em->persist($overview);
299
                $this->em->flush();
300
301
                $this->em->getRepository(AnalyticsConfig::class)->setUpdated($overview->getConfig()->getId());
302
            } catch (\Google_ServiceException $e) {
303
                $error = explode(')', $e->getMessage());
304
                $error = $error[1];
305
                $this->output->writeln("\t" . '<fg=red>Invalid segment: </fg=red>' . $error);
306
                ++$this->errors;
307
            }
308
        }
309
    }
310
311
    /**
312
     * Reset the data for the overview
313
     *
314
     * @param AnalyticsOverview $overview The overview
315
     */
316
    private function reset(AnalyticsOverview $overview)
317
    {
318
        // reset overview
319
        $overview->setNewUsers(0);
320
        $overview->setReturningUsers(0);
321
    }
322
}
323