Completed
Push — master ( 6d6774...64f3ed )
by Jeroen
11:23 queued 05:13
created

Command/GoogleAnalyticsDataCollectCommand.php (1 issue)

calls on non-objects.

Bug Major

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 Kunstmaan\DashboardBundle\Command\Helper\Analytics\ChartDataCommandHelper;
6
use Kunstmaan\DashboardBundle\Command\Helper\Analytics\GoalCommandHelper;
7
use Kunstmaan\DashboardBundle\Command\Helper\Analytics\MetricsCommandHelper;
8
use Kunstmaan\DashboardBundle\Command\Helper\Analytics\UsersCommandHelper;
9
use Kunstmaan\DashboardBundle\Entity\AnalyticsConfig;
10
use Kunstmaan\DashboardBundle\Entity\AnalyticsOverview;
11
use Kunstmaan\DashboardBundle\Entity\AnalyticsSegment;
12
use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand;
13
use Symfony\Component\Console\Input\InputInterface;
14
use Symfony\Component\Console\Input\InputOption;
15
use Symfony\Component\Console\Output\OutputInterface;
16
use Doctrine\ORM\EntityManagerInterface;
17
use Kunstmaan\DashboardBundle\Helper\Google\Analytics\ServiceHelper;
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
     * @param InputInterface  $input
90
     * @param OutputInterface $output
91
     *
92
     * @return int|null|void
93
     */
94
    protected function execute(InputInterface $input, OutputInterface $output)
95
    {
96
        if (null === $this->em) {
97
            $this->em = $this->getContainer()->get('doctrine.orm.entity_manager');
98
        }
99
100
        if (null === $this->serviceHelper) {
101
            $this->serviceHelper = $this->getContainer()->get('kunstmaan_dashboard.helper.google.analytics.service');
102
        }
103
104
        $this->output = $output;
105
106
        // check if token is set
107
        $configHelper = $this->getContainer()->get('kunstmaan_dashboard.helper.google.analytics.config');
108
        if (!$configHelper->tokenIsSet()) {
109
            $this->output->writeln('You haven\'t configured a Google account yet');
110
111
            return 0;
112
        }
113
114
        // get params
115
        $configId = false;
116
        $segmentId = false;
117
        $overviewId = false;
118
119
        try {
120
            $configId = $input->getOption('config');
121
            $segmentId = $input->getOption('segment');
122
            $overviewId = $input->getOption('overview');
123
        } catch (\Exception $e) {
124
        }
125
126
        // get the overviews
127
        try {
128
            $overviews = [];
129
130
            if ($overviewId) {
131
                $overviews[] = $this->getSingleOverview($overviewId);
132
            } elseif ($segmentId) {
133
                $overviews = $this->getOverviewsOfSegment($segmentId);
134
            } elseif ($configId) {
135
                $overviews = $this->getOverviewsOfConfig($configId);
136
            } else {
137
                $overviews = $this->getAllOverviews();
138
            }
139
140
            // update the overviews
141
            $this->updateData($overviews);
142
            $result = '<fg=green>Google Analytics data updated with <fg=red>'.$this->errors.'</fg=red> error';
143
            $result .= $this->errors != 1 ? 's</fg=green>' : '</fg=green>';
144
            $this->output->writeln($result); // done
145
146
            return 0;
147
        } catch (\Exception $e) {
148
            $this->output->writeln($e->getMessage());
149
150
            return 1;
151
        }
152
    }
153
154
    /**
155
     * get a single overview
156
     *
157
     * @param int $overviewId
158
     *
159
     * @return AnalyticsOverview
160
     */
161
    private function getSingleOverview($overviewId)
162
    {
163
        // get specified overview
164
        $overviewRepository = $this->em->getRepository(AnalyticsOverview::class);
165
        $overview = $overviewRepository->find($overviewId);
166
167
        if (!$overview) {
168
            throw new \Exception('Unkown overview ID');
169
        }
170
171
        return $overview;
172
    }
173
174
    /**
175
     * get all overviews of a segment
176
     *
177
     * @param int $segmentId
178
     *
179
     * @return array
180
     */
181 View Code Duplication
    private function getOverviewsOfSegment($segmentId)
182
    {
183
        // get specified segment
184
        $segmentRepository = $this->em->getRepository(AnalyticsSegment::class);
185
        $segment = $segmentRepository->find($segmentId);
186
187
        if (!$segment) {
188
            throw new \Exception('Unkown segment ID');
189
        }
190
191
        // init the segment
192
        $segmentRepository->initSegment($segment);
193
194
        // get the overviews
195
        return $segment->getOverviews();
196
    }
197
198
    /**
199
     * get all overviews of a config
200
     *
201
     * @param int $configId
202
     *
203
     * @return array
204
     */
205
    private function getOverviewsOfConfig($configId)
206
    {
207
        $configRepository = $this->em->getRepository(AnalyticsConfig::class);
208
        $segmentRepository = $this->em->getRepository(AnalyticsSegment::class);
209
        $overviewRepository = $this->em->getRepository(AnalyticsOverview::class);
210
        // get specified config
211
        $config = $configRepository->find($configId);
212
213
        if (!$config) {
214
            throw new \Exception('Unkown config ID');
215
        }
216
217
        // create default overviews for this config if none exist yet
218
        if (!\count($config->getOverviews())) {
219
            $overviewRepository->addOverviews($config);
220
        }
221
222
        // init all the segments for this config
223
        $segments = $config->getSegments();
224
        foreach ($segments as $segment) {
225
            $segmentRepository->initSegment($segment);
226
        }
227
228
        // get the overviews
229
        return $config->getOverviews();
230
    }
231
232
    /**
233
     * get all overviews
234
     *
235
     * @return array
236
     */
237 View Code Duplication
    private function getAllOverviews()
238
    {
239
        $configRepository = $this->em->getRepository(AnalyticsConfig::class);
240
        $overviewRepository = $this->em->getRepository(AnalyticsOverview::class);
241
        $segmentRepository = $this->em->getRepository(AnalyticsSegment::class);
242
        $configs = $configRepository->findAll();
243
244
        foreach ($configs as $config) {
245
            // add overviews if none exist yet
246
            if (\count($config->getOverviews()) == 0) {
247
                $overviewRepository->addOverviews($config);
248
            }
249
250
            // init all the segments for this config
251
            $segments = $config->getSegments();
252
            foreach ($segments as $segment) {
253
                $segmentRepository->initSegment($segment);
254
            }
255
        }
256
257
        // get all overviews
258
        return $overviewRepository->findAll();
259
    }
260
261
    /**
262
     * update the overviews
263
     *
264
     * @param array $overviews collection of all overviews which need to be updated
265
     */
266
    public function updateData($overviews)
267
    {
268
        // helpers
269
        $queryHelper = $this->getContainer()->get('kunstmaan_dashboard.helper.google.analytics.query');
270
        $configHelper = $this->getContainer()->get('kunstmaan_dashboard.helper.google.analytics.config');
271
        $metrics = new MetricsCommandHelper($configHelper, $queryHelper, $this->output, $this->em);
272
        $chartData = new ChartDataCommandHelper($configHelper, $queryHelper, $this->output, $this->em);
273
        $goals = new GoalCommandHelper($configHelper, $queryHelper, $this->output, $this->em);
274
        $visitors = new UsersCommandHelper($configHelper, $queryHelper, $this->output, $this->em);
275
276
        // get data per overview
277
        foreach ($overviews as $overview) {
278
            $configHelper->init($overview->getConfig()->getId());
279
            /* @var AnalyticsOverview $overview */
280
            $this->output->writeln('Fetching data for overview "<fg=green>' . $overview->getTitle() . '</fg=green>"');
281
282
            try {
283
                // metric data
284
                $metrics->getData($overview);
285
                if ($overview->getSessions()) { // if there are any visits
286
                    // day-specific data
287
                    $chartData->getData($overview);
288
289
                    // get goals
290
                    $goals->getData($overview);
291
292
                    // visitor types
293
                    $visitors->getData($overview);
294
                } else {
295
                    // reset overview
296
                    $this->reset($overview);
297
                    $this->output->writeln("\t" . 'No visitors');
298
                }
299
                // persist entity back to DB
300
                $this->output->writeln("\t" . 'Persisting..');
301
                $this->em->persist($overview);
302
                $this->em->flush();
303
304
                $this->em->getRepository(AnalyticsConfig::class)->setUpdated($overview->getConfig()->getId());
0 ignored issues
show
The method getId cannot be called on $overview->getConfig() (of type integer).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
305
            } catch (\Google_ServiceException $e) {
306
                $error = explode(')', $e->getMessage());
307
                $error = $error[1];
308
                $this->output->writeln("\t" . '<fg=red>Invalid segment: </fg=red>' .$error);
309
                ++$this->errors;
310
            }
311
        }
312
    }
313
314
    /**
315
     * Reset the data for the overview
316
     *
317
     * @param AnalyticsOverview $overview The overview
318
     */
319
    private function reset(AnalyticsOverview $overview)
320
    {
321
        // reset overview
322
        $overview->setNewUsers(0);
323
        $overview->setReturningUsers(0);
324
    }
325
}
326