Completed
Push — master ( 06c1ce...67d37c )
by Jeroen
06:20
created

Helper/Google/Analytics/ConfigHelper.php (15 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
3
namespace Kunstmaan\DashboardBundle\Helper\Google\Analytics;
4
5
use Doctrine\ORM\EntityManager;
6
7
class ConfigHelper
8
{
9
    /** @var ServiceHelper */
10
    private $serviceHelper;
11
12
    /** @var string */
13
    private $token = false;
14
15
    /** @var string */
16
    private $propertyId = false;
17
18
    /** @var string */
19
    private $accountId = false;
20
21
    /** @var string */
22
    private $profileId = false;
23
24
    /** @var EntityManager */
25
    private $em;
26
27
    /**
28
     * constructor
29
     *
30
     * @param ServiceHelper $serviceHelper
31
     * @param EntityManager $em
32
     */
33
    public function __construct(ServiceHelper $serviceHelper, EntityManager $em)
0 ignored issues
show
You have injected the EntityManager via parameter $em. This is generally not recommended as it might get closed and become unusable. Instead, it is recommended to inject the ManagerRegistry and retrieve the EntityManager via getManager() each time you need it.

The EntityManager might become unusable for example if a transaction is rolled back and it gets closed. Let’s assume that somewhere in your application, or in a third-party library, there is code such as the following:

function someFunction(ManagerRegistry $registry) {
    $em = $registry->getManager();
    $em->getConnection()->beginTransaction();
    try {
        // Do something.
        $em->getConnection()->commit();
    } catch (\Exception $ex) {
        $em->getConnection()->rollback();
        $em->close();

        throw $ex;
    }
}

If that code throws an exception and the EntityManager is closed. Any other code which depends on the same instance of the EntityManager during this request will fail.

On the other hand, if you instead inject the ManagerRegistry, the getManager() method guarantees that you will always get a usable manager instance.

Loading history...
34
    {
35
        $this->serviceHelper = $serviceHelper;
36
        $this->em = $em;
37
        $this->init();
38
    }
39
40
    /**
41
     * Tries to initialise the Client object
42
     *
43
     * @param int $configId
0 ignored issues
show
Should the type for parameter $configId not be false|integer?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
44
     */
45
    public function init($configId = false)
46
    {
47
        // if token is already saved in the database
48
        if ($this->getToken($configId) && '' !== $this->getToken($configId)) {
0 ignored issues
show
It seems like $configId defined by parameter $configId on line 45 can also be of type integer; however, Kunstmaan\DashboardBundl...onfigHelper::getToken() does only seem to accept boolean, maybe add an additional type check?

This check looks at variables that have been passed in as parameters and are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
49
            $this
50
                ->serviceHelper
51
                ->getClientHelper()
52
                ->getClient()
53
                ->setAccessToken($this->getToken($configId));
0 ignored issues
show
It seems like $configId defined by parameter $configId on line 45 can also be of type integer; however, Kunstmaan\DashboardBundl...onfigHelper::getToken() does only seem to accept boolean, maybe add an additional type check?

This check looks at variables that have been passed in as parameters and are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
54
        }
55
56
        if ($configId) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $configId of type false|integer is loosely compared to true; this is ambiguous if the integer can be zero. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For integer values, zero is a special case, in particular the following results might be unexpected:

0   == false // true
0   == null  // true
123 == false // false
123 == null  // false

// It is often better to use strict comparison
0 === false // false
0 === null  // false
Loading history...
57
            $this->getAccountId($configId);
0 ignored issues
show
$configId is of type integer, but the function expects a boolean.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
58
            $this->getPropertyId($configId);
0 ignored issues
show
$configId is of type integer, but the function expects a boolean.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
59
            $this->getProfileId($configId);
0 ignored issues
show
$configId is of type integer, but the function expects a boolean.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
60
        }
61
    }
62
63
    /* =============================== TOKEN =============================== */
64
65
    /**
66
     * Get the token from the database
67
     *
68
     * @return string $token
69
     */
70 View Code Duplication
    private function getToken($configId = false)
0 ignored issues
show
This method seems to be duplicated in 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...
71
    {
72
        if (!$this->token || $configId) {
73
            /** @var AnalyticsConfigRepository $analyticsConfigRepository */
74
            $analyticsConfigRepository = $this->em->getRepository('KunstmaanDashboardBundle:AnalyticsConfig');
75
            if ($configId) {
76
                $this->token = $analyticsConfigRepository->find($configId)->getToken();
77
            } else {
78
                $this->token = $analyticsConfigRepository->findFirst()->getToken();
79
            }
80
        }
81
82
        return $this->token;
83
    }
84
85
    /**
86
     * Save the token to the database
87
     */
88
    public function saveToken($token, $configId = false)
89
    {
90
        $this->token = $token;
91
        $this->em->getRepository('KunstmaanDashboardBundle:AnalyticsConfig')->saveToken($token, $configId);
92
    }
93
94
    /**
95
     * Check if token is set
96
     *
97
     * @return bool $result
98
     */
99
    public function tokenIsSet()
100
    {
101
        return $this->getToken() && '' !== $this->getToken();
102
    }
103
104
    /* =============================== ACCOUNT =============================== */
105
106
    /**
107
     * Get a list of all available accounts
108
     *
109
     * @return array $data A list of all properties
110
     */
111
    public function getAccounts()
112
    {
113
        $accounts = $this->serviceHelper->getService()->management_accounts->listManagementAccounts()->getItems();
114
        $data = array();
115
116
        foreach ($accounts as $account) {
117
            $data[$account->getName()] = array(
118
                    'accountId' => $account->getId(),
119
                    'accountName' => $account->getName(),
120
                );
121
        }
122
        ksort($data);
123
124
        return $data;
125
    }
126
127
    /**
128
     * Get the accountId from the database
129
     *
130
     * @return string $accountId
131
     */
132 View Code Duplication
    public function getAccountId($configId = false)
0 ignored issues
show
This method seems to be duplicated in 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...
133
    {
134
        if (!$this->accountId || $configId) {
135
            /** @var AnalyticsConfigRepository $analyticsConfigRepository */
136
            $analyticsConfigRepository = $this->em->getRepository('KunstmaanDashboardBundle:AnalyticsConfig');
137
            if ($configId) {
138
                $this->accountId = $analyticsConfigRepository->find($configId)->getAccountId();
139
            } else {
140
                $this->accountId = $analyticsConfigRepository->findFirst()->getAccountId();
141
            }
142
        }
143
144
        return $this->accountId;
145
    }
146
147
    /**
148
     * Save the accountId to the database
149
     */
150
    public function saveAccountId($accountId, $configId = false)
151
    {
152
        $this->accountId = $accountId;
153
        $this->em->getRepository('KunstmaanDashboardBundle:AnalyticsConfig')->saveAccountId($accountId, $configId);
154
    }
155
156
    /**
157
     * Check if token is set
158
     *
159
     * @return bool $result
160
     */
161
    public function accountIsSet()
162
    {
163
        return $this->getAccountId() && '' !== $this->getAccountId();
164
    }
165
166
    /* =============================== PROPERTY =============================== */
167
168
    /**
169
     * Get a list of all available properties
170
     *
171
     * @return array $data A list of all properties
0 ignored issues
show
Should the return type not be false|array? Also, consider making the array more specific, something like array<String>, or 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.

If the return type contains the type array, this check recommends the use of a more specific type like String[] or array<String>.

Loading history...
172
     */
173
    public function getProperties($accountId = false)
174
    {
175
        if (!$this->getAccountId() && !$accountId) {
176
            return false;
177
        }
178
179
        if ($accountId) {
180
            $webproperties = $this->serviceHelper->getService()->management_webproperties->listManagementWebproperties($accountId);
181
        } else {
182
            $webproperties = $this->serviceHelper->getService()->management_webproperties->listManagementWebproperties($this->getAccountId());
183
        }
184
        $data = array();
185
186
        foreach ($webproperties->getItems() as $property) {
187
            $profiles = $this->getProfiles($accountId, $property->getId());
188
            if (\count($profiles) > 0) {
189
                $data[$property->getName()] = array(
190
                        'propertyId' => $property->getId(),
191
                        'propertyName' => $property->getName() . ' (' . $property->getWebsiteUrl() . ')',
192
                    );
193
            }
194
        }
195
        ksort($data);
196
197
        return $data;
198
    }
199
200
    /**
201
     * Get the propertyId from the database
202
     *
203
     * @return string $propertyId
204
     */
205 View Code Duplication
    public function getPropertyId($configId = false)
0 ignored issues
show
This method seems to be duplicated in 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...
206
    {
207
        if (!$this->propertyId || $configId) {
208
            /** @var AnalyticsConfigRepository $analyticsConfigRepository */
209
            $analyticsConfigRepository = $this->em->getRepository('KunstmaanDashboardBundle:AnalyticsConfig');
210
            if ($configId) {
211
                $this->propertyId = $analyticsConfigRepository->find($configId)->getPropertyId();
212
            } else {
213
                $this->propertyId = $analyticsConfigRepository->findFirst()->getPropertyId();
214
            }
215
        }
216
217
        return $this->propertyId;
218
    }
219
220
    /**
221
     * Save the propertyId to the database
222
     */
223
    public function savePropertyId($propertyId, $configId = false)
224
    {
225
        $this->propertyId = $propertyId;
226
        $this->em->getRepository('KunstmaanDashboardBundle:AnalyticsConfig')->savePropertyId($propertyId, $configId);
227
    }
228
229
    /**
230
     * Check if propertyId is set
231
     *
232
     * @return bool $result
233
     */
234
    public function propertyIsSet()
235
    {
236
        return null !== $this->getPropertyId() && '' !== $this->getPropertyId();
237
    }
238
239
    /* =============================== PROFILE =============================== */
240
241
    /**
242
     * Get a list of all available profiles
243
     *
244
     * @return array $data A list of all properties
0 ignored issues
show
Should the return type not be false|array? Also, consider making the array more specific, something like array<String>, or 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.

If the return type contains the type array, this check recommends the use of a more specific type like String[] or array<String>.

Loading history...
245
     */
246
    public function getProfiles($accountId = false, $propertyId = false)
247
    {
248
        if ((!$this->getAccountId() && !$accountId) || (!$this->getPropertyId() && !$propertyId)) {
249
            return false;
250
        }
251
252
        // get views
253
        if ($accountId && $propertyId) {
254
            $profiles = $this->serviceHelper->getService()->management_profiles->listManagementProfiles(
255
                    $accountId,
256
                    $propertyId
257
                );
258
        } else {
259
            $profiles = $this->serviceHelper->getService()->management_profiles->listManagementProfiles(
260
                    $this->getAccountId(),
261
                    $this->getPropertyId()
262
                );
263
        }
264
265
        $data = array();
266
        if (\is_array($profiles->getItems())) {
267
            foreach ($profiles->getItems() as $profile) {
268
                $data[$profile->name] = array(
269
                            'profileId' => $profile->id,
270
                            'profileName' => $profile->name,
271
                            'created' => $profile->created,
272
                        );
273
            }
274
        }
275
        ksort($data);
276
277
        return $data;
278
    }
279
280
    /**
281
     * Get the propertyId from the database
282
     *
283
     * @return string $propertyId
284
     */
285 View Code Duplication
    public function getProfileId($configId = false)
0 ignored issues
show
This method seems to be duplicated in 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...
286
    {
287
        if (!$this->profileId || $configId) {
288
            /** @var AnalyticsConfigRepository $analyticsConfigRepository */
289
            $analyticsConfigRepository = $this->em->getRepository('KunstmaanDashboardBundle:AnalyticsConfig');
290
            if ($configId) {
291
                $this->profileId = $analyticsConfigRepository->find($configId)->getProfileId();
292
            } else {
293
                $this->profileId = $analyticsConfigRepository->findFirst()->getProfileId();
294
            }
295
        }
296
297
        return $this->profileId;
298
    }
299
300
    /**
301
     * Save the profileId to the database
302
     */
303
    public function saveProfileId($profileId, $configId = false)
304
    {
305
        $this->profileId = $profileId;
306
        $this->em->getRepository('KunstmaanDashboardBundle:AnalyticsConfig')->saveProfileId($profileId, $configId);
307
    }
308
309
    /**
310
     * Check if token is set
311
     *
312
     * @return bool $result
313
     */
314
    public function profileIsSet()
315
    {
316
        return null !== $this->getProfileId() && '' !== $this->getProfileId();
317
    }
318
319
    /**
320
     * Get the active profile
321
     *
322
     * @return the profile
323
     */
324
    public function getActiveProfile()
325
    {
326
        $profiles = $this->getProfiles();
327
        $profileId = $this->getProfileId();
328
329
        if (!\is_array($profiles)) {
330
            throw new \Exception('<fg=red>The config is invalid</fg=red>');
331
        }
332
333
        foreach ($profiles as $profile) {
334
            if ($profile['profileId'] == $profileId) {
335
                return $profile;
336
            }
337
        }
338
    }
339
340
    /* =============================== PROFILE SEGMENTS =============================== */
341
342
    /**
343
     * get all segments for the saved profile
344
     *
345
     * @return array
0 ignored issues
show
Consider making the return type a bit more specific; maybe use array<string,array>.

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...
346
     */
347
    public function getProfileSegments()
348
    {
349
        $profileSegments = $this
350
                    ->serviceHelper
351
                    ->getService()
352
                    ->management_segments
353
                    ->listManagementSegments()
354
                    ->items;
355
356
        $builtin = array();
357
        $own = array();
358
        foreach ($profileSegments as $segment) {
359
            if ($segment->type == 'BUILT_IN') {
360
                $builtin[] = array(
361
                        'name' => $segment->name,
362
                        'query' => $segment->segmentId,
363
                    );
364
            } else {
365
                $own[] = array(
366
                        'name' => $segment->name,
367
                        'query' => $segment->segmentId,
368
                    );
369
            }
370
        }
371
372
        return array('builtin' => $builtin, 'own' => $own);
373
    }
374
375
    /* =============================== CONFIG =============================== */
376
377
    /**
378
     * Save the config to the database
379
     */
380
    public function saveConfigName($configName, $configId = false)
381
    {
382
        $this->em->getRepository('KunstmaanDashboardBundle:AnalyticsConfig')->saveConfigName($configName, $configId);
383
    }
384
385
    /* =============================== AUTH URL =============================== */
386
387
    /**
388
     * get the authUrl
389
     *
390
     * @return string $authUrl
391
     */
392
    public function getAuthUrl()
393
    {
394
        return $this
395
                ->serviceHelper
396
                ->getClientHelper()
397
                ->getClient()
398
                ->createAuthUrl();
399
    }
400
}
401