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

Command/Helper/Analytics/GoalCommandHelper.php (1 issue)

Check that a function or method returns the type specified in the @return annotation

Documentation Informational

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\Helper\Analytics;
4
5
use Kunstmaan\DashboardBundle\Entity\AnalyticsGoal;
6
use Kunstmaan\DashboardBundle\Entity\AnalyticsOverview;
7
8
class GoalCommandHelper extends AbstractAnalyticsCommandHelper
9
{
10
    /**
11
     * @return array
12
     */
13
    private function getAllGoals()
14
    {
15
        // Get the goals from the saved profile. These are a maximum of 20 goals.
16
        $goals = $this
17
            ->query
18
            ->getServiceHelper()
19
            ->getService()
20
            ->management_goals
21
            ->listManagementGoals(
22
                $this->configHelper->getAccountId(),
23
                $this->configHelper->getPropertyId(),
24
                $this->configHelper->getProfileId()
25
            )
26
            ->items;
27
28
        if (\is_array($goals)) {
29
            return $goals;
30
        }
31
32
        return false;
33
    }
34
35
    /**
36
     * @return array
0 ignored issues
show
Should the return type not be false|string[]?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
37
     */
38
    private function prepareMetrics()
39
    {
40
        $goals = $this->getAllGoals();
41
        if (!$goals) {
42
            return false;
43
        }
44
45
        $metrics = [];
46
        foreach ($goals as $key => $value) {
47
            $metrics[] = 'ga:goal' . ($key + 1) . 'Completions';
48
        }
49
        // Create the metric parameter string, there is a limit of 10 metrics per query, and a max of 20 goals available.
50
        if (\count($metrics) <= 10) {
51
            $part1 = implode(',', $metrics);
52
53
            return [$part1];
54
        }
55
56
        $part1 = implode(',', \array_slice($metrics, 0, 10));
57
        $part2 = implode(',', \array_slice($metrics, 10, 10));
58
59
        return [$part1, $part2];
60
    }
61
62
    /**
63
     * @param $metrics
64
     * @param $dimensions
65
     *
66
     * @return mixed
67
     */
68 View Code Duplication
    private function requestGoalResults(AnalyticsOverview $overview, $metrics, $dimensions)
69
    {
70
        $timestamps = $this->getTimestamps($overview);
71
72
        // execute query
73
        $results = $this->query->getResultsByDate(
74
            $timestamps['begin'],
75
            $timestamps['end'],
76
            $metrics,
77
            $dimensions
78
        );
79
80
        return $results->getRows();
81
    }
82
83
    /**
84
     * get data and save it for the overview
85
     *
86
     * @param AnalyticsOverview $overview The overview
87
     */
88
    public function getData(&$overview)
89
    {
90
        $this->output->writeln("\t" . 'Fetching goals..');
91
92
        // calculate timespan
93
        $timespan = $overview->getTimespan() - $overview->getStartOffset();
94
        if ($timespan <= 1) {
95
            $extra = ['dimensions' => 'ga:date,ga:hour'];
96
            $start = 2;
97
        } elseif ($timespan <= 7) {
98
            $extra = ['dimensions' => 'ga:date,ga:hour'];
99
            $start = 2;
100
        } elseif ($timespan <= 31) {
101
            $extra = ['dimensions' => 'ga:week,ga:day,ga:date'];
102
            $start = 3;
103
        } else {
104
            $extra = ['dimensions' => 'ga:isoYearIsoWeek'];
105
            $start = 1;
106
        }
107
108
        // add segment
109
        if ($overview->getSegment()) {
110
            $extra['segment'] = $overview->getSegment()->getQuery();
111
        }
112
113
        $goals = $this->getAllGoals();
114
        if (!$goals) {
115
            return;
116
        }
117
        $goaldata = [];
118
119
        // Create an array with for each goal an entry to create the metric parameter.
120
        foreach ($goals as $key => $value) {
121
            ++$key;
122
            $goaldata[] = ['position' => $key, 'name' => $value->name];
123
        }
124
125
        $metrics = $this->prepareMetrics();
126
127
        $rows = $this->requestGoalResults($overview, $metrics[0], $extra);
128
        // Execute an extra query if there are more than 10 goals to query
129
        if (\count($metrics) > 1) {
130
            $rows2 = $this->requestGoalResults($overview, $metrics[1], $extra);
131
            $rows2size = \count($rows2);
132
            for ($i = 0; $i < $rows2size; ++$i) {
133
                // Merge the results of the extra query data with the previous query data.
134
                $rows[$i] = array_merge($rows[$i], \array_slice($rows2[$i], $start, \count($rows2) - $start));
135
            }
136
        }
137
138
        // Create a result array to be parsed and create Goal objects from
139
        $goalCollection = [];
140
        $goaldatasize = \count($goaldata);
141
        for ($i = 0; $i < $goaldatasize; ++$i) {
142
            $goalEntry = [];
143
            foreach ($rows as $row) {
144
                // Create a timestamp for each goal visit (this depends on the timespan of the overview: split per hour, day, week, month)
145 View Code Duplication
                if ($timespan <= 1) {
146
                    $timestamp = mktime(
147
                        $row[1],
148
                        0,
149
                        0,
150
                        substr($row[0], 4, 2),
151
                        substr($row[0], 6, 2),
152
                        substr($row[0], 0, 4)
153
                    );
154
                    $timestamp = date('Y-m-d H:00', $timestamp);
155
                } elseif ($timespan <= 7) {
156
                    $timestamp = mktime(
157
                        $row[1],
158
                        0,
159
                        0,
160
                        substr($row[0], 4, 2),
161
                        substr($row[0], 6, 2),
162
                        substr($row[0], 0, 4)
163
                    );
164
                    $timestamp = date('Y-m-d H:00', $timestamp);
165
                } elseif ($timespan <= 31) {
166
                    $timestamp = mktime(
167
                        0,
168
                        0,
169
                        0,
170
                        substr($row[2], 4, 2),
171
                        substr($row[2], 6, 2),
172
                        substr($row[2], 0, 4)
173
                    );
174
                    $timestamp = date('Y-m-d H:00', $timestamp);
175
                } else {
176
                    $timestamp = strtotime(substr($row[0], 0, 4) . 'W' . substr($row[0], 4, 2));
177
                    $timestamp = date('Y-m-d H:00', $timestamp);
178
                }
179
                $goalEntry[$timestamp] = $row[$i + $start];
180
            }
181
            $goalCollection['goal' . $goaldata[$i]['position']]['name'] = $goaldata[$i]['name'];
182
            $goalCollection['goal' . $goaldata[$i]['position']]['position'] = $goaldata[$i]['position'];
183
            $goalCollection['goal' . $goaldata[$i]['position']]['visits'] = $goalEntry;
184
        }
185
186
        // Parse the goals and append them to the overview.
187
        $this->parseGoals($overview, $goalCollection);
188
    }
189
190
    /**
191
     * Fetch a specific goals
192
     *
193
     * @param AnalyticsOverview $overview       The overview
194
     * @param                   $goalCollection
195
     */
196
    private function parseGoals(&$overview, $goalCollection)
197
    {
198
        $timespan = $overview->getTimespan() - $overview->getStartOffset();
199
        $goals = $overview->getGoals();
200
        if ($goals) {
201
            // delete existing entries
202
            foreach ($goals as $goal) {
203
                $this->em->remove($goal);
204
            }
205
            $this->em->flush();
206
        }
207
208
        foreach ($goalCollection as $goalEntry) {
209
            // create a new goal
210
            $goal = new AnalyticsGoal();
211
            $goal->setOverview($overview);
212
            $goal->setName($goalEntry['name']);
213
            $goal->setPosition($goalEntry['position']);
214
215
            $chartData = [];
216
            $totalVisits = 0;
217
            $goalVisits = 0;
218
            $i = 0;
219
            // Fill the chartdata array
220
            foreach ($goalEntry['visits'] as $timestamp => $visits) {
221
                $totalVisits += $visits;
222
                if ($timespan <= 7 && $timespan > 1) {
223
                    $goalVisits += $visits;
224
                    if ($i % 5 == 0) {
225
                        $chartData[] = ['timestamp' => $timestamp, 'conversions' => $goalVisits];
226
                        $goalVisits = 0;
227
                    }
228
                } else {
229
                    $chartData[] = ['timestamp' => $timestamp, 'conversions' => $visits];
230
                }
231
                ++$i;
232
            }
233
234
            // set the data
235
            $goal->setVisits($totalVisits);
236
            $goal->setChartData(json_encode($chartData));
237
            $this->em->persist($goal);
238
239
            $this->output->writeln(
240
                "\t\t" . 'Fetched goal ' . $goal->getPosition() . ': "' . $goal->getName() . '" @ ' . $totalVisits
241
            );
242
        }
243
    }
244
}
245