Passed
Push — v4 ( c983fa...92005e )
by Benjamin
04:27
created

SettingsController::actionEditSite()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 10
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 7
nc 1
nop 1
dl 0
loc 10
rs 9.4285
c 0
b 0
f 0
1
<?php
2
/**
3
 * @link      https://dukt.net/craft/analytics/
4
 * @copyright Copyright (c) 2018, Dukt
5
 * @license   https://dukt.net/craft/analytics/docs/license
6
 */
7
8
namespace dukt\analytics\controllers;
9
10
use Craft;
11
use craft\errors\InvalidPluginException;
12
use craft\web\Controller;
13
use dukt\analytics\models\SiteView;
14
use dukt\analytics\models\View;
15
use dukt\analytics\web\assets\settings\SettingsAsset;
16
use dukt\analytics\Plugin as Analytics;
17
use Exception;
18
use Google_Service_Exception;
19
use League\OAuth2\Client\Provider\Exception\IdentityProviderException;
20
use yii\web\NotFoundHttpException;
21
use yii\web\Response;
22
23
class SettingsController extends Controller
24
{
25
    // Public Methods
26
    // =========================================================================
27
28
    /**
29
     * Index.
30
     *
31
     * @param null $plugin
0 ignored issues
show
Documentation Bug introduced by
Are you sure the doc-type for parameter $plugin is correct as it would always require null to be passed?
Loading history...
32
     *
33
     * @return Response
34
     * @throws \craft\errors\SiteNotFoundException
35
     * @throws \yii\base\InvalidConfigException
36
     */
37
    public function actionIndex($plugin = null): Response
38
    {
39
        $isOauthProviderConfigured = Analytics::$plugin->getAnalytics()->isOauthProviderConfigured();
40
41
        if ($isOauthProviderConfigured) {
42
            $errors = [];
43
44
            try {
45
                if (!$plugin) {
46
                    $plugin = Craft::$app->getPlugins()->getPlugin('analytics');
47
                }
48
49
                $provider = Analytics::$plugin->oauth->getOauthProvider();
50
                $token = Analytics::$plugin->oauth->getToken();
51
52
                if ($token) {
53
                    $oauthAccount = Analytics::$plugin->cache->get(['getAccount', $token]);
54
55
                    if (!$oauthAccount) {
56
                        $oauthAccount = $provider->getResourceOwner($token);
57
                        Analytics::$plugin->cache->set(['getAccount', $token], $oauthAccount);
58
                    }
59
60
                    if ($oauthAccount) {
61
                        Craft::info("Account:\r\n".print_r($oauthAccount, true), __METHOD__);
62
63
                        $settings = $plugin->getSettings();
64
                    }
65
                }
66
            } catch (Google_Service_Exception $e) {
67
                Craft::info('Couldn’t get OAuth account: '.$e->getMessage(), __METHOD__);
68
69
                foreach ($e->getErrors() as $error) {
70
                    $errors[] = $error['message'];
71
                }
72
            } catch (IdentityProviderException $e) {
73
                $error = $e->getMessage();
74
75
                $data = $e->getResponseBody();
76
77
                if (isset($data['error_description'])) {
78
                    $error = $data['error_description'];
79
                }
80
81
                $errors[] = $error;
82
            } catch (Exception $e) {
83
                if (method_exists($e, 'getResponse')) {
84
                    Craft::info('Couldn’t get OAuth account: '.$e->getResponse(), __METHOD__);
85
                } else {
86
                    Craft::info('Couldn’t get OAuth account: '.$e->getMessage(), __METHOD__);
87
                }
88
89
                $errors[] = $e->getMessage();
90
            }
91
        }
92
93
        $token = ($token ?? null);
94
95
        Craft::$app->getView()->registerAssetBundle(SettingsAsset::class);
96
97
        return $this->renderTemplate('analytics/settings/_index', [
98
            'isOauthProviderConfigured' => $isOauthProviderConfigured,
99
100
            'errors' => $errors ?? null,
101
            'oauthAccount' => $oauthAccount ?? null,
102
            'provider' => $provider ?? null,
103
            'settings' => $settings ?? null,
104
            'token' => $token ?? null,
105
106
            'javascriptOrigin' => Analytics::$plugin->oauth->getJavascriptOrigin(),
107
            'redirectUri' => Analytics::$plugin->oauth->getRedirectUri(),
108
            'googleIconUrl' => Craft::$app->assetManager->getPublishedUrl('@dukt/analytics/icons/google.svg', true),
109
        ]);
110
    }
111
112
    /**
113
     * OAuth Settings.
114
     *
115
     * @return Response
116
     * @throws \craft\errors\SiteNotFoundException
117
     */
118
    public function actionOauth(): Response
119
    {
120
        return $this->renderTemplate('analytics/settings/_oauth', [
121
            'javascriptOrigin' => Analytics::$plugin->oauth->getJavascriptOrigin(),
122
            'redirectUri' => Analytics::$plugin->oauth->getRedirectUri(),
123
            'googleIconUrl' => Craft::$app->assetManager->getPublishedUrl('@dukt/analytics/icons/google.svg', true),
124
            'settings' => Analytics::$plugin->getSettings(),
125
        ]);
126
    }
127
128
    /**
129
     * Saves the settings.
130
     *
131
     * @return null|Response
132
     * @throws InvalidPluginException
133
     * @throws \yii\web\BadRequestHttpException
134
     */
135
    public function actionSaveSettings()
136
    {
137
        $this->requirePostRequest();
138
139
        $pluginHandle = Craft::$app->getRequest()->getRequiredBodyParam('pluginHandle');
140
        $settings = Craft::$app->getRequest()->getBodyParam('settings');
141
142
        $plugin = Craft::$app->getPlugins()->getPlugin($pluginHandle);
0 ignored issues
show
Bug introduced by
It seems like $pluginHandle can also be of type array; however, parameter $handle of craft\services\Plugins::getPlugin() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

142
        $plugin = Craft::$app->getPlugins()->getPlugin(/** @scrutinizer ignore-type */ $pluginHandle);
Loading history...
143
144
        if (!$plugin)
145
        {
146
            throw new InvalidPluginException($pluginHandle);
0 ignored issues
show
Bug introduced by
It seems like $pluginHandle can also be of type array; however, parameter $handle of craft\errors\InvalidPluginException::__construct() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

146
            throw new InvalidPluginException(/** @scrutinizer ignore-type */ $pluginHandle);
Loading history...
147
        }
148
149
        $settings = Analytics::$plugin->getApis()->getAnalytics()->populateAccountExplorerSettings($settings);
0 ignored issues
show
Bug introduced by
It seems like $settings can also be of type string; however, parameter $settings of dukt\analytics\apis\Anal...countExplorerSettings() does only seem to accept array, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

149
        $settings = Analytics::$plugin->getApis()->getAnalytics()->populateAccountExplorerSettings(/** @scrutinizer ignore-type */ $settings);
Loading history...
150
151
        if (Craft::$app->getPlugins()->savePluginSettings($plugin, $settings))
152
        {
153
            Craft::$app->getSession()->setNotice(Craft::t('analytics', 'Plugin settings saved.'));
154
155
            return $this->redirectToPostedUrl();
156
        }
157
158
        Craft::$app->getSession()->setError(Craft::t('analytics', 'Couldn’t save plugin settings.'));
159
160
        // Send the plugin back to the template
161
        Craft::$app->getUrlManager()->setRouteParams([
162
            'plugin' => $plugin
163
        ]);
164
165
        return null;
166
    }
167
168
    /**
169
     * Returns the account explorer data.
170
     *
171
     * @return Response
172
     */
173
    public function actionGetAccountExplorerData(): Response
174
    {
175
        $accountExplorerData = Analytics::$plugin->getApis()->getAnalytics()->getAccountExplorerData();
176
177
        Analytics::$plugin->cache->set(['accountExplorerData'], $accountExplorerData);
178
179
        return $this->asJson($accountExplorerData);
180
    }
181
182
    /**
183
     * Views index.
184
     *
185
     * @return Response
186
     */
187
    public function actionViews(): Response
188
    {
189
        $isOauthProviderConfigured = Analytics::$plugin->getAnalytics()->isOauthProviderConfigured();
190
191
        $variables['isConnected'] = false;
0 ignored issues
show
Comprehensibility Best Practice introduced by
$variables was never initialized. Although not strictly required by PHP, it is generally a good practice to add $variables = array(); before regardless.
Loading history...
192
193
        try {
194
            $token = Analytics::$plugin->oauth->getToken();
195
196
            if($isOauthProviderConfigured && $token) {
197
                $variables['isConnected'] = true;
198
                $variables['reportingViews'] = Analytics::$plugin->getViews()->getViews();
199
            }
200
        } catch (IdentityProviderException $e) {
201
            $variables['error'] = $e->getMessage();
202
203
            $data = $e->getResponseBody();
204
205
            if (isset($data['error_description'])) {
206
                $variables['error'] = $data['error_description'];
207
            }
208
        }
209
210
        return $this->renderTemplate('analytics/settings/views/_index', $variables);
211
    }
212
213
    /**
214
     * Edit a view.
215
     *
216
     * @param int|null  $viewId
217
     * @param View|null $reportingView
218
     *
219
     * @return Response
220
     * @throws NotFoundHttpException
221
     * @throws \craft\errors\SiteNotFoundException
222
     * @throws \yii\base\InvalidConfigException
223
     */
224
    public function actionEditView(int $viewId = null, View $reportingView = null): Response
225
    {
226
        $variables['isNewView'] = false;
0 ignored issues
show
Comprehensibility Best Practice introduced by
$variables was never initialized. Although not strictly required by PHP, it is generally a good practice to add $variables = array(); before regardless.
Loading history...
227
228
        if ($viewId !== null) {
229
            if ($reportingView === null) {
230
                $reportingView = Analytics::$plugin->getViews()->getViewById($viewId);
231
232
                if (!$reportingView) {
233
                    throw new NotFoundHttpException('View not found');
234
                }
235
            }
236
237
            $variables['title'] = $reportingView->name;
238
            $variables['reportingView'] = $reportingView;
239
        } else {
240
            if ($reportingView === null) {
241
                $reportingView = new View();
242
                $variables['isNewView'] = true;
243
            }
244
            $variables['title'] = Craft::t('analytics', 'Create a new view');
245
        }
246
247
        $variables['reportingView'] = $reportingView;
248
249
        $isOauthProviderConfigured = Analytics::$plugin->getAnalytics()->isOauthProviderConfigured();
250
251
        if($isOauthProviderConfigured) {
252
            $errors = [];
253
254
            try {
255
                $plugin = Craft::$app->getPlugins()->getPlugin('analytics');
256
257
                $provider = Analytics::$plugin->oauth->getOauthProvider();
258
                $token = Analytics::$plugin->oauth->getToken();
259
260
                if ($token) {
261
                    $oauthAccount = Analytics::$plugin->cache->get(['getAccount', $token]);
262
263
                    if (!$oauthAccount) {
264
                        $oauthAccount = $provider->getResourceOwner($token);
265
                        Analytics::$plugin->cache->set(['getAccount', $token], $oauthAccount);
266
                    }
267
268
                    if ($oauthAccount) {
269
                        Craft::info("Account:\r\n".print_r($oauthAccount, true), __METHOD__);
270
271
                        $settings = $plugin->getSettings();
272
273
274
                        // Account
275
276
                        $accountExplorerData = Analytics::$plugin->cache->get(['accountExplorerData']);
277
278
                        $accountOptions = [];
279
280
                        if (isset($accountExplorerData['accounts'])) {
281
                            foreach ($accountExplorerData['accounts'] as $account) {
282
                                $accountOptions[] = ['label' => $account['name'], 'value' => $account['id']];
283
                            }
284
                        } else {
285
                            $accountOptions[] = ['label' => $reportingView->gaAccountName, 'value' => $reportingView->gaAccountId];
286
                        }
287
288
289
                        // Web Properties
290
291
                        $propertyOptions = [];
292
293
                        if (isset($accountExplorerData['properties'])) {
294
                            foreach ($accountExplorerData['properties'] as $webProperty) {
295
                                $propertyOptions[] = ['label' => $webProperty['name'], 'value' => $webProperty['id']];
296
                            }
297
                        } else {
298
                            $propertyOptions[] = ['label' => $reportingView->gaPropertyName, 'value' => $reportingView->gaPropertyId];
299
                        }
300
301
302
                        // Views
303
304
                        $viewOptions = [];
305
306
                        if (isset($accountExplorerData['views'])) {
307
                            foreach ($accountExplorerData['views'] as $dataView) {
308
                                $viewOptions[] = ['label' => $dataView['name'], 'value' => $dataView['id']];
309
                            }
310
                        } else {
311
                            $viewOptions[] = ['label' => $reportingView->gaViewName, 'value' => $reportingView->gaViewId];
312
                        }
313
314
                        $accountExplorerOptions = [
315
                            'accounts' => $accountOptions,
316
                            'properties' => $propertyOptions,
317
                            'views' => $viewOptions,
318
                        ];
319
320
                        $accountId = $settings->accountId;
321
                        $webPropertyId = $settings->webPropertyId;
322
                        $googleAnalyticsviewId = $settings->profileId;
323
                    }
324
                }
325
            } catch (\Google_Service_Exception $e) {
326
                Craft::info('Couldn’t get OAuth account: '.$e->getMessage(), __METHOD__);
327
328
                foreach ($e->getErrors() as $error) {
329
                    array_push($errors, $error['message']);
330
                }
331
            } catch (\Exception $e) {
332
                if (method_exists($e, 'getResponse')) {
333
                    Craft::info('Couldn’t get OAuth account: '.$e->getResponse(), __METHOD__);
334
                } else {
335
                    Craft::info('Couldn’t get OAuth account: '.$e->getMessage(), __METHOD__);
336
                }
337
338
                array_push($errors, $e->getMessage());
339
            }
340
        }
341
342
        $token = ($token ?? null);
343
344
        Craft::$app->getView()->registerAssetBundle(SettingsAsset::class);
345
346
        $variables['isOauthProviderConfigured'] = $isOauthProviderConfigured;
347
        $variables['accountExplorerData'] = ($accountExplorerData ?? null);
348
        $variables['accountExplorerOptions'] = ($accountExplorerOptions ?? null);
349
        $variables['accountId'] = ($accountId ?? null);
350
        $variables['errors'] = ($errors ?? null);
351
        $variables['oauthAccount'] = ($oauthAccount ?? null);
352
        $variables['provider'] = ($provider ?? null);
353
        $variables['settings'] = ($settings ?? null);
354
        $variables['token'] = ($token ?? null);
355
        $variables['viewId'] = ($googleAnalyticsviewId ?? null);
356
        $variables['webPropertyId'] = ($webPropertyId ?? null);
357
358
        $variables['javascriptOrigin'] = Analytics::$plugin->oauth->getJavascriptOrigin();
359
        $variables['redirectUri'] = Analytics::$plugin->oauth->getRedirectUri();
360
        $variables['googleIconUrl'] = Craft::$app->assetManager->getPublishedUrl('@dukt/analytics/icons/google.svg', true);
361
362
        return $this->renderTemplate('analytics/settings/views/_edit', $variables);
363
    }
364
365
    /**
366
     * Saves a view.
367
     *
368
     * @return null|Response
369
     * @throws \dukt\analytics\errors\InvalidViewException
370
     * @throws \yii\web\BadRequestHttpException
371
     */
372
    public function actionSaveView()
373
    {
374
        $this->requirePostRequest();
375
376
        $reportingView = new View();
377
378
        // Set the simple stuff
379
        $request = Craft::$app->getRequest();
380
        $reportingView->id = $request->getBodyParam('viewId');
381
        $reportingView->name = $request->getBodyParam('name');
0 ignored issues
show
Documentation Bug introduced by
It seems like $request->getBodyParam('name') can also be of type array. However, the property $name is declared as type string. Maybe add an additional type check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.

For example, imagine you have a variable $accountId that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to the id property of an instance of the Account class. This class holds a proper account, so the id value must no longer be false.

Either this assignment is in error or a type check should be added for that assignment.

class Id
{
    public $id;

    public function __construct($id)
    {
        $this->id = $id;
    }

}

class Account
{
    /** @var  Id $id */
    public $id;
}

$account_id = false;

if (starsAreRight()) {
    $account_id = new Id(42);
}

$account = new Account();
if ($account instanceof Id)
{
    $account->id = $account_id;
}
Loading history...
382
383
        $accountExplorer = $request->getBodyParam('accountExplorer');
384
385
        $reportingView->gaAccountId = $accountExplorer['account'];
386
        $reportingView->gaPropertyId = $accountExplorer['property'];
387
        $reportingView->gaViewId = $accountExplorer['view'];
388
389
390
        $accountExplorerData = Analytics::$plugin->getApis()->getAnalytics()->getAccountExplorerData();
391
392
        foreach($accountExplorerData['accounts'] as $dataAccount) {
393
            if($dataAccount['id'] == $reportingView->gaAccountId) {
394
                $reportingView->gaAccountName = $dataAccount['name'];
395
            }
396
        }
397
398
        foreach($accountExplorerData['properties'] as $dataProperty) {
399
            if($dataProperty['id'] == $reportingView->gaPropertyId) {
400
                $reportingView->gaPropertyName = $dataProperty['name'];
401
            }
402
        }
403
        foreach($accountExplorerData['views'] as $dataView) {
404
            if($dataView['id'] == $reportingView->gaViewId) {
405
                $reportingView->gaViewName = $dataView['name'];
406
                $reportingView->gaViewCurrency = $dataView['currency'];
407
            }
408
        }
409
410
        // Save it
411
        if (!Analytics::$plugin->getViews()->saveView($reportingView)) {
412
            Craft::$app->getSession()->setError(Craft::t('analytics', 'Couldn’t save the view.'));
413
414
            // Send the view back to the template
415
            Craft::$app->getUrlManager()->setRouteParams([
416
                'reportingView' => $reportingView
417
            ]);
418
419
            return null;
420
        }
421
422
        Craft::$app->getSession()->setNotice(Craft::t('analytics', 'View saved.'));
423
424
        return $this->redirectToPostedUrl($reportingView);
425
    }
426
427
    /**
428
     * Deletes a view.
429
     *
430
     * @return Response
431
     * @throws \Throwable
432
     * @throws \yii\db\StaleObjectException
433
     * @throws \yii\web\BadRequestHttpException
434
     */
435
    public function actionDeleteView(): Response
436
    {
437
        $this->requirePostRequest();
438
        $this->requireAcceptsJson();
439
440
        $request = Craft::$app->getRequest();
441
        $viewId = $request->getRequiredBodyParam('id');
442
443
        Analytics::$plugin->getViews()->deleteViewById($viewId);
444
445
        return $this->asJson(['success' => true]);
446
    }
447
448
    /**
449
     * Sites index.
450
     *
451
     * @return Response
452
     */
453
    public function actionSites(): Response
454
    {
455
        $isOauthProviderConfigured = Analytics::$plugin->getAnalytics()->isOauthProviderConfigured();
456
457
        $variables['isConnected'] = false;
0 ignored issues
show
Comprehensibility Best Practice introduced by
$variables was never initialized. Although not strictly required by PHP, it is generally a good practice to add $variables = array(); before regardless.
Loading history...
458
459
        try {
460
            $token = Analytics::$plugin->oauth->getToken();
461
462
            if ($isOauthProviderConfigured && $token) {
463
                $variables['isConnected'] = true;
464
                $variables['sites'] = Craft::$app->getSites()->getAllSites();
465
                $variables['siteViews'] = Analytics::$plugin->getViews()->getSiteViews();
466
            }
467
        } catch (IdentityProviderException $e) {
468
            $variables['error'] = $e->getMessage();
469
470
            $data = $e->getResponseBody();
471
472
            if (isset($data['error_description'])) {
473
                $variables['error'] = $data['error_description'];
474
            }
475
        }
476
477
        return $this->renderTemplate('analytics/settings/sites/_index', $variables);
478
    }
479
480
    /**
481
     * Edit a site.
482
     *
483
     * @param $siteId
484
     *
485
     * @return Response
486
     */
487
    public function actionEditSite($siteId): Response
488
    {
489
        $site = Craft::$app->getSites()->getSiteById($siteId);
490
        $siteView = Analytics::$plugin->getViews()->getSiteViewBySiteId($siteId);
491
        $reportingViews = Analytics::$plugin->getViews()->getViews();
492
493
        return $this->renderTemplate('analytics/settings/sites/_edit', [
494
            'site' => $site,
495
            'siteView' => $siteView,
496
            'reportingViews' => $reportingViews,
497
        ]);
498
    }
499
500
    /**
501
     * Saves a site.
502
     *
503
     * @return null|Response
504
     * @throws \yii\db\Exception
505
     * @throws \yii\web\BadRequestHttpException
506
     */
507
    public function actionSaveSite()
508
    {
509
        $this->requirePostRequest();
510
511
        $siteView = new SiteView();
512
513
        // Set the simple stuff
514
        $request = Craft::$app->getRequest();
515
        $siteView->siteId = $request->getBodyParam('siteId');
516
        $siteView->viewId = $request->getBodyParam('viewId');
517
518
        // Save it
519
        if (!Analytics::$plugin->getViews()->saveSiteView($siteView)) {
520
            Craft::$app->getSession()->setError(Craft::t('analytics', 'Couldn’t save the site view.'));
521
522
            // Send the view back to the template
523
            Craft::$app->getUrlManager()->setRouteParams([
524
                'siteView' => $siteView
525
            ]);
526
527
            return null;
528
        }
529
530
        Craft::$app->getSession()->setNotice(Craft::t('analytics', 'Site view saved.'));
531
532
        return $this->redirectToPostedUrl($siteView);
533
    }
534
}