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

ConfigHelper::init()   B

Complexity

Conditions 5
Paths 6

Size

Total Lines 23
Code Lines 14

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 23
rs 8.5906
cc 5
eloc 14
nc 6
nop 1
1
<?php
2
3
namespace Kunstmaan\DashboardBundle\Helper\Google\Analytics;
4
5
use Doctrine\ORM\EntityManager;
6
use Kunstmaan\DashboardBundle\Repository\AnalyticsConfigRepository;
7
8
/**
9
 * Class ConfigHelper
10
 */
11
class ConfigHelper
12
{
13
    /** @var ServiceHelper */
14
    private $serviceHelper;
15
16
    /** @var string $token */
17
    private $token = false;
18
19
    /** @var string $accountId */
20
    private $propertyId = false;
21
22
    /** @var string $accountId */
23
    private $accountId = false;
24
25
    /** @var string $profileId */
26
    private $profileId = false;
27
28
    /** @var EntityManager $em */
29
    private $em;
30
31
    /**
32
     * ConfigHelper constructor.
33
     *
34
     * @param ServiceHelper $serviceHelper
35
     * @param EntityManager $em
36
     *
37
     * @throws \Doctrine\ORM\OptimisticLockException
38
     */
39
    public function __construct(ServiceHelper $serviceHelper, EntityManager $em)
0 ignored issues
show
Bug introduced by
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...
40
    {
41
        $this->serviceHelper = $serviceHelper;
42
        $this->em = $em;
43
        $this->init();
44
    }
45
46
    /**
47
     * @param bool $configId
48
     *
49
     * @throws \Doctrine\ORM\OptimisticLockException
50
     */
51
    public function init($configId = false)
52
    {
53
        // if token is already saved in the database
54
        if ($this->getToken($configId) && '' !== $this->getToken($configId)) {
55
            $client = $this
56
                ->serviceHelper
57
                ->getClientHelper()
58
                ->getClient();
59
60
            $client->setAccessToken($this->getToken($configId));
61
62
            if ($client->isAccessTokenExpired()) {
63
                $client->fetchAccessTokenWithRefreshToken();
64
                $this->saveToken(json_encode($client->getAccessToken()));
65
            }
66
        }
67
68
        if ($configId) {
69
            $this->getAccountId($configId);
70
            $this->getPropertyId($configId);
71
            $this->getProfileId($configId);
72
        }
73
    }
74
75
    /* =============================== TOKEN =============================== */
76
77
    /**
78
     * @param bool $configId
79
     *
80
     * @return string
81
     * @throws \Doctrine\ORM\OptimisticLockException
82
     */
83 View Code Duplication
    private function getToken($configId = false)
0 ignored issues
show
Duplication introduced by
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...
84
    {
85
        if (!$this->token || $configId) {
86
            /** @var AnalyticsConfigRepository $analyticsConfigRepository */
87
            $analyticsConfigRepository = $this->em->getRepository('KunstmaanDashboardBundle:AnalyticsConfig');
88
            if ($configId) {
89
                $this->token = $analyticsConfigRepository->find($configId)->getToken();
90
            } else {
91
                $this->token = $analyticsConfigRepository->findFirst()->getToken();
92
            }
93
        }
94
95
        return $this->token;
96
    }
97
98
    /**
99
     * @param string $token
100
     * @param bool   $configId
101
     *
102
     * @throws \Doctrine\ORM\OptimisticLockException
103
     */
104
    public function saveToken($token, $configId = false)
105
    {
106
        $this->token = $token;
107
        $this->em->getRepository('KunstmaanDashboardBundle:AnalyticsConfig')->saveToken($token, $configId);
108
    }
109
110
    /**
111
     * @return bool
112
     *
113
     * @throws \Doctrine\ORM\OptimisticLockException
114
     */
115
    public function tokenIsSet()
116
    {
117
        return $this->getToken() && '' !== $this->getToken();
118
    }
119
120
    /* =============================== ACCOUNT =============================== */
121
122
    /**
123
     * Get a list of all available accounts
124
     *
125
     * @return array $data A list of all properties
126
     */
127
    public function getAccounts()
128
    {
129
        $accounts = $this->serviceHelper->getService()->management_accounts->listManagementAccounts()->getItems();
130
        $data = [];
131
132
        foreach ($accounts as $account) {
133
            $data[$account->getName()] = [
134
                'accountId' => $account->getId(),
135
                'accountName' => $account->getName(),
136
            ];
137
        }
138
        ksort($data);
139
140
        return $data;
141
    }
142
143
    /**
144
     * @param bool $configId
145
     *
146
     * @return string
147
     * @throws \Doctrine\ORM\OptimisticLockException
148
     */
149 View Code Duplication
    public function getAccountId($configId = false)
0 ignored issues
show
Duplication introduced by
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...
150
    {
151
        if (!$this->accountId || $configId) {
152
            /** @var AnalyticsConfigRepository $analyticsConfigRepository */
153
            $analyticsConfigRepository = $this->em->getRepository('KunstmaanDashboardBundle:AnalyticsConfig');
154
            if ($configId) {
155
                $this->accountId = $analyticsConfigRepository->find($configId)->getAccountId();
156
            } else {
157
                $this->accountId = $analyticsConfigRepository->findFirst()->getAccountId();
158
            }
159
        }
160
161
        return $this->accountId;
162
    }
163
164
    /**
165
     * @param string $accountId
166
     * @param bool   $configId
167
     *
168
     * @throws \Doctrine\ORM\OptimisticLockException
169
     */
170
    public function saveAccountId($accountId, $configId = false)
171
    {
172
        $this->accountId = $accountId;
173
        $this->em->getRepository('KunstmaanDashboardBundle:AnalyticsConfig')->saveAccountId($accountId, $configId);
174
    }
175
176
    /**
177
     * @return bool
178
     * @throws \Doctrine\ORM\OptimisticLockException
179
     */
180
    public function accountIsSet()
181
    {
182
        return $this->getAccountId() && '' !== $this->getAccountId();
183
    }
184
185
    /* =============================== PROPERTY =============================== */
186
187
    /**
188
     * @param bool $accountId
189
     *
190
     * @return array|bool
0 ignored issues
show
Documentation introduced by
Consider making the return type a bit more specific; maybe use false|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...
191
     * @throws \Doctrine\ORM\OptimisticLockException
192
     */
193
    public function getProperties($accountId = false)
194
    {
195
        if (!$accountId && !$this->getAccountId()) {
196
            return false;
197
        }
198
199
        if ($accountId) {
200
            $webproperties = $this->serviceHelper->getService()->management_webproperties->listManagementWebproperties($accountId);
201
        } else {
202
            $webproperties = $this->serviceHelper->getService()->management_webproperties->listManagementWebproperties($this->getAccountId());
203
        }
204
        $data = [];
205
206
        foreach ($webproperties->getItems() as $property) {
207
            $profiles = $this->getProfiles($accountId, $property->getId());
208
            if (\count($profiles) > 0) {
209
                $data[$property->getName()] = [
210
                    'propertyId' => $property->getId(),
211
                    'propertyName' => $property->getName().' ('.$property->getWebsiteUrl().')',
212
                ];
213
            }
214
        }
215
        ksort($data);
216
217
        return $data;
218
    }
219
220
    /**
221
     * @param bool $configId
222
     *
223
     * @return string
224
     * @throws \Doctrine\ORM\OptimisticLockException
225
     */
226 View Code Duplication
    public function getPropertyId($configId = false)
0 ignored issues
show
Duplication introduced by
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...
227
    {
228
        if (!$this->propertyId || $configId) {
229
            /** @var AnalyticsConfigRepository $analyticsConfigRepository */
230
            $analyticsConfigRepository = $this->em->getRepository('KunstmaanDashboardBundle:AnalyticsConfig');
231
            if ($configId) {
232
                $this->propertyId = $analyticsConfigRepository->find($configId)->getPropertyId();
233
            } else {
234
                $this->propertyId = $analyticsConfigRepository->findFirst()->getPropertyId();
235
            }
236
        }
237
238
        return $this->propertyId;
239
    }
240
241
    /**
242
     * @param      $propertyId
243
     * @param bool $configId
244
     *
245
     * @throws \Doctrine\ORM\OptimisticLockException
246
     */
247
    public function savePropertyId($propertyId, $configId = false)
248
    {
249
        $this->propertyId = $propertyId;
250
        $this->em->getRepository('KunstmaanDashboardBundle:AnalyticsConfig')->savePropertyId($propertyId, $configId);
251
    }
252
253
    /**
254
     * @return bool
255
     * @throws \Doctrine\ORM\OptimisticLockException
256
     */
257
    public function propertyIsSet()
258
    {
259
        return null !== $this->getPropertyId() && '' !== $this->getPropertyId();
260
    }
261
262
    /* =============================== PROFILE =============================== */
263
264
    /**
265
     * @param bool $accountId
266
     * @param bool $propertyId
267
     *
268
     * @return array|bool
0 ignored issues
show
Documentation introduced by
Consider making the return type a bit more specific; maybe use false|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...
269
     * @throws \Doctrine\ORM\OptimisticLockException
270
     */
271
    public function getProfiles($accountId = false, $propertyId = false)
272
    {
273
        if ((!$this->getAccountId() && !$accountId) || (!$this->getPropertyId() && !$propertyId)) {
274
            return false;
275
        }
276
277
        // get views
278
        if ($accountId && $propertyId) {
279
            $profiles = $this->serviceHelper->getService()->management_profiles->listManagementProfiles(
280
                $accountId,
281
                $propertyId
282
            );
283
        } else {
284
            $profiles = $this->serviceHelper->getService()->management_profiles->listManagementProfiles(
285
                $this->getAccountId(),
286
                $this->getPropertyId()
287
            );
288
        }
289
290
        $data = [];
291
        if (\is_array($profiles->getItems())) {
292
            foreach ($profiles->getItems() as $profile) {
293
                $data[$profile->name] = [
294
                    'profileId' => $profile->id,
295
                    'profileName' => $profile->name,
296
                    'created' => $profile->created,
297
                ];
298
            }
299
        }
300
        ksort($data);
301
302
        return $data;
303
    }
304
305
    /**
306
     * @param bool $configId
307
     *
308
     * @return string
309
     * @throws \Doctrine\ORM\OptimisticLockException
310
     */
311 View Code Duplication
    public function getProfileId($configId = false)
0 ignored issues
show
Duplication introduced by
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...
312
    {
313
        if (!$this->profileId || $configId) {
314
            /** @var AnalyticsConfigRepository $analyticsConfigRepository */
315
            $analyticsConfigRepository = $this->em->getRepository('KunstmaanDashboardBundle:AnalyticsConfig');
316
            if ($configId) {
317
                $this->profileId = $analyticsConfigRepository->find($configId)->getProfileId();
318
            } else {
319
                $this->profileId = $analyticsConfigRepository->findFirst()->getProfileId();
320
            }
321
        }
322
323
        return $this->profileId;
324
    }
325
326
    /**
327
     * @param      $profileId
328
     * @param bool $configId
329
     *
330
     * @throws \Doctrine\ORM\OptimisticLockException
331
     */
332
    public function saveProfileId($profileId, $configId = false)
333
    {
334
        $this->profileId = $profileId;
335
        $this->em->getRepository('KunstmaanDashboardBundle:AnalyticsConfig')->saveProfileId($profileId, $configId);
336
    }
337
338
    /**
339
     * @return bool
340
     * @throws \Doctrine\ORM\OptimisticLockException
341
     */
342
    public function profileIsSet()
343
    {
344
        return null !== $this->getProfileId() && '' !== $this->getProfileId();
345
    }
346
347
    /**
348
     * Get the active profile
349
     *
350
     * @return mixed
351
     *
352
     * @throws \Exception
353
     */
354
    public function getActiveProfile()
355
    {
356
        $profiles = $this->getProfiles();
357
        $profileId = $this->getProfileId();
358
359
        if (!\is_array($profiles)) {
360
            throw new \Exception('<fg=red>The config is invalid</fg=red>');
361
        }
362
363
        foreach ($profiles as $profile) {
364
            if ($profile['profileId'] === $profileId) {
365
                return $profile;
366
            }
367
        }
368
    }
369
370
    /* =============================== PROFILE SEGMENTS =============================== */
371
    /**
372
     * get all segments for the saved profile
373
     *
374
     * @return array
0 ignored issues
show
Documentation introduced by
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...
375
     */
376
    public function getProfileSegments()
377
    {
378
        $profileSegments = $this
379
            ->serviceHelper
380
            ->getService()
381
            ->management_segments
382
            ->listManagementSegments()
383
            ->getItems();
384
385
        $builtin = [];
386
        $own = [];
387
        foreach ($profileSegments as $segment) {
388
            if ($segment->type === 'BUILT_IN') {
389
                $builtin[] = [
390
                    'name' => $segment->name,
391
                    'query' => $segment->segmentId,
392
                ];
393
            } else {
394
                $own[] = [
395
                    'name' => $segment->name,
396
                    'query' => $segment->segmentId,
397
                ];
398
            }
399
        }
400
401
        return ['builtin' => $builtin, 'own' => $own];
402
    }
403
404
    /* =============================== CONFIG =============================== */
405
406
    /**
407
     * @param string $configName
408
     * @param bool   $configId
409
     *
410
     * @throws \Doctrine\ORM\OptimisticLockException
411
     */
412
    public function saveConfigName($configName, $configId = false)
413
    {
414
        $this->em->getRepository('KunstmaanDashboardBundle:AnalyticsConfig')->saveConfigName($configName, $configId);
415
    }
416
417
    /* =============================== AUTH URL =============================== */
418
419
    /**
420
     * get the authUrl
421
     *
422
     * @return string $authUrl
423
     */
424
    public function getAuthUrl()
425
    {
426
        return $this
427
            ->serviceHelper
428
            ->getClientHelper()
429
            ->getClient()
430
            ->createAuthUrl();
431
    }
432
}
433