Completed
Pull Request — 6.0 (#1872)
by Sander
102:24 queued 60:56
created

Command/GoogleAnalyticsDataCollectCommand.php (3 issues)

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
namespace Kunstmaan\DashboardBundle\Command;
3
4
use Doctrine\ORM\EntityManager;
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\AnalyticsOverview;
10
use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand;
11
use Symfony\Component\Console\Input\InputInterface;
12
use Symfony\Component\Console\Input\InputOption;
13
use Symfony\Component\Console\Output\OutputInterface;
14
15
class GoogleAnalyticsDataCollectCommand extends ContainerAwareCommand
16
{
17
    /** @var EntityManager $em */
18
    private $em;
19
20
    /** @var OutputInterface $output */
21
    private $output;
22
23
    /** @var int $errors */
24
    private $errors = 0;
25
26
    /**
27
     * Configures the current command.
28
     */
29
    protected function configure()
30
    {
31
        $this
32
            ->setName('kuma:dashboard:widget:googleanalytics:data:collect')
33
            ->setDescription('Collect the Google Analytics dashboard widget data')
34
            ->addOption(
35
                'config',
36
                null,
37
                InputOption::VALUE_OPTIONAL,
38
                'Specify to only update one config',
39
                false
40
            )
41
            ->addOption(
42
                'segment',
43
                null,
44
                InputOption::VALUE_OPTIONAL,
45
                'Specify to only update one segment',
46
                false
47
            )
48
            ->addOption(
49
                'overview',
50
                null,
51
                InputOption::VALUE_OPTIONAL,
52
                'Specify to only update one overview',
53
                false
54
            );
55
    }
56
57
    /**
58
     * Inits instance variables for global usage.
59
     *
60
     * @param OutputInterface $output The output
61
     */
62
    private function init($output)
63
    {
64
        $this->output = $output;
65
        $this->serviceHelper = $this->getContainer()->get('kunstmaan_dashboard.helper.google.analytics.service');
0 ignored issues
show
The property serviceHelper does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
66
        $this->em = $this->getContainer()->get('doctrine')->getManager();
67
    }
68
69
    protected function execute(InputInterface $input, OutputInterface $output)
70
    {
71
        // init
72
        $this->init($output);
73
74
        // check if token is set
75
        $configHelper = $this->getContainer()->get('kunstmaan_dashboard.helper.google.analytics.config');
76
        if (!$configHelper->tokenIsSet()) {
77
            $this->output->writeln('You haven\'t configured a Google account yet');
78
            return;
79
        }
80
81
        // get params
82
        $configId = false;
83
        $segmentId = false;
84
        $overviewId = false;
85
        try {
86
            $configId  = $input->getOption('config');
87
            $segmentId = $input->getOption('segment');
88
            $overviewId = $input->getOption('overview');
89
        } catch (\Exception $e) {}
90
91
        // get the overviews
92
        try {
93
            $overviews = array();
94
95
            if ($overviewId) {
96
                $overviews[] = $this->getSingleOverview($overviewId);
97 View Code Duplication
            } else if ($segmentId) {
0 ignored issues
show
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
98
                $overviews = $this->getOverviewsOfSegment($segmentId);
99
            } else if ($configId) {
100
                $overviews = $this->getOverviewsOfConfig($configId);
101
            } else {
102
                $overviews = $this->getAllOverviews();
103
            }
104
105
            // update the overviews
106
            $this->updateData($overviews);
107
            $result = '<fg=green>Google Analytics data updated with <fg=red>'.$this->errors.'</fg=red> error';
108
            $result .= $this->errors != 1 ? 's</fg=green>' : '</fg=green>';
109
            $this->output->writeln($result); // done
110
        } catch (\Exception $e) {
111
            $this->output->writeln($e->getMessage());
112
        }
113
114
    }
115
116
    /**
117
     * get a single overview
118
     * @param int $overviewId
119
     * @return AnalyticsOverview
120
     */
121
    private function getSingleOverview($overviewId)
122
    {
123
        // get specified overview
124
        $overviewRepository = $this->em->getRepository('KunstmaanDashboardBundle:AnalyticsOverview');
125
        $overview = $overviewRepository->find($overviewId);
126
127
        if (!$overview) {
128
            throw new \Exception('Unkown overview ID');
129
        }
130
131
        return $overview;
132
    }
133
134
    /**
135
     * get all overviews of a segment
136
     * @param int $segmentId
137
     * @return array
138
     */
139 View Code Duplication
    private function getOverviewsOfSegment($segmentId)
140
    {
141
        // get specified segment
142
        $segmentRepository = $this->em->getRepository('KunstmaanDashboardBundle:AnalyticsSegment');
143
        $segment = $segmentRepository->find($segmentId);
144
145
        if (!$segment) {
146
            throw new \Exception('Unkown segment ID');
147
        }
148
149
        // init the segment
150
        $segmentRepository->initSegment($segment);
151
152
        // get the overviews
153
        return $segment->getOverviews();
154
    }
155
156
    /**
157
     * get all overviews of a config
158
     * @param int $configId
159
     * @return array
160
     */
161
    private function getOverviewsOfConfig($configId)
162
    {
163
        $configRepository = $this->em->getRepository('KunstmaanDashboardBundle:AnalyticsConfig');
164
        $segmentRepository = $this->em->getRepository('KunstmaanDashboardBundle:AnalyticsSegment');
165
        $overviewRepository = $this->em->getRepository('KunstmaanDashboardBundle:AnalyticsOverview');
166
        // get specified config
167
        $config = $configRepository->find($configId);
168
169
        if (!$config) {
170
            throw new \Exception('Unkown config ID');
171
        }
172
173
        // create default overviews for this config if none exist yet
174
        if (!count($config->getOverviews())) {
175
            $overviewRepository->addOverviews($config);
176
        }
177
178
        // init all the segments for this config
179
        $segments = $config->getSegments();
180
        foreach ($segments as $segment) {
181
            $segmentRepository->initSegment($segment);
182
        }
183
184
        // get the overviews
185
        return $config->getOverviews();
186
    }
187
188
    /**
189
     * get all overviews
190
     *
191
     * @return array
192
     */
193
    private function getAllOverviews()
194
    {
195
        $configRepository = $this->em->getRepository('KunstmaanDashboardBundle:AnalyticsConfig');
196
        $overviewRepository = $this->em->getRepository('KunstmaanDashboardBundle:AnalyticsOverview');
197
        $segmentRepository = $this->em->getRepository('KunstmaanDashboardBundle:AnalyticsSegment');
198
        $configs = $configRepository->findAll();
199
200
        foreach ($configs as $config) {
201
            // add overviews if none exist yet
202
            if (count($config->getOverviews()) == 0) {
203
                $overviewRepository->addOverviews($config);
204
            }
205
206
            // init all the segments for this config
207
            $segments = $config->getSegments();
208
            foreach ($segments as $segment) {
209
                $segmentRepository->initSegment($segment);
210
            }
211
        }
212
213
        // get all overviews
214
        return $overviewRepository->findAll();
215
    }
216
217
    /**
218
     * update the overviews
219
     *
220
     * @param array $overviews collection of all overviews which need to be updated
221
     */
222
    public function updateData($overviews)
223
    {
224
        // helpers
225
        $queryHelper = $this->getContainer()->get('kunstmaan_dashboard.helper.google.analytics.query');
226
        $configHelper = $this->getContainer()->get('kunstmaan_dashboard.helper.google.analytics.config');
227
        $metrics = new MetricsCommandHelper($configHelper, $queryHelper, $this->output, $this->em);
228
        $chartData = new ChartDataCommandHelper($configHelper, $queryHelper, $this->output, $this->em);
229
        $goals = new GoalCommandHelper($configHelper, $queryHelper, $this->output, $this->em);
230
        $visitors = new UsersCommandHelper($configHelper, $queryHelper, $this->output, $this->em);
231
232
        // get data per overview
233
        foreach ($overviews as $overview) {
234
            $configHelper->init($overview->getConfig()->getId());
235
            /** @var AnalyticsOverview $overview */
236
            $this->output->writeln('Fetching data for overview "<fg=green>' . $overview->getTitle() . '</fg=green>"');
237
238
            try {
239
                // metric data
240
                $metrics->getData($overview);
241
                if ($overview->getSessions()) { // if there are any visits
242
                    // day-specific data
243
                    $chartData->getData($overview);
244
245
                    // get goals
246
                    $goals->getData($overview);
247
248
                    // visitor types
249
                    $visitors->getData($overview);
250
                } else {
251
                    // reset overview
252
                    $this->reset($overview);
253
                    $this->output->writeln("\t" . 'No visitors');
254
                }
255
            // persist entity back to DB
256
                $this->output->writeln("\t" . 'Persisting..');
257
                $this->em->persist($overview);
258
                $this->em->flush($overview);
259
260
                $this->em->getRepository('KunstmaanDashboardBundle:AnalyticsConfig')->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...
261
            } catch (\Google_ServiceException $e) {
262
                $error = explode(')', $e->getMessage());
263
                $error = $error[1];
264
                $this->output->writeln("\t" . '<fg=red>Invalid segment: </fg=red>' .$error);
265
                $this->errors += 1;
266
            }
267
        }
268
    }
269
270
271
    /**
272
     * Reset the data for the overview
273
     *
274
     * @param AnalyticsOverview $overview The overview
275
     */
276
    private function reset(AnalyticsOverview $overview)
277
    {
278
        // reset overview
279
        $overview->setNewUsers(0);
280
        $overview->setReturningUsers(0);
281
    }
282
}
283