Passed
Push — develop ( fa3678...7584a1 )
by Andrew
04:05
created

InstantAnalytics   A

Complexity

Total Complexity 30

Size/Duplication

Total Lines 313
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
wmc 30
eloc 115
dl 0
loc 313
rs 10
c 0
b 0
f 0

11 Methods

Rating   Name   Duplication   Size   Complexity  
A installCpEventListeners() 0 2 1
A createSettingsModel() 0 3 1
A setTitleFromSeomatic() 0 8 5
A iaSendPageView() 0 5 1
B installEventListeners() 0 23 7
A init() 0 21 1
A addComponents() 0 15 1
A installSiteEventListeners() 0 50 3
A settingsHtml() 0 35 4
A sendPageView() 0 29 5
A customFrontendRoutes() 0 5 1
1
<?php
2
/**
3
 * Instant Analytics plugin for Craft CMS 3.x
4
 *
5
 * Instant Analytics brings full Google Analytics support to your Twig templates
6
 *
7
 * @link      https://nystudio107.com
0 ignored issues
show
Coding Style introduced by
The tag in position 1 should be the @copyright tag
Loading history...
8
 * @copyright Copyright (c) 2017 nystudio107
0 ignored issues
show
Coding Style introduced by
@copyright tag must contain a year and the name of the copyright holder
Loading history...
9
 */
0 ignored issues
show
Coding Style introduced by
PHP version not specified
Loading history...
Coding Style introduced by
Missing @category tag in file comment
Loading history...
Coding Style introduced by
Missing @package tag in file comment
Loading history...
Coding Style introduced by
Missing @author tag in file comment
Loading history...
Coding Style introduced by
Missing @license tag in file comment
Loading history...
10
11
namespace nystudio107\instantanalytics;
12
13
use nystudio107\instantanalytics\helpers\IAnalytics;
14
use nystudio107\instantanalytics\helpers\Field as FieldHelper;
15
use nystudio107\instantanalytics\models\Settings;
16
use nystudio107\instantanalytics\services\Commerce as CommerceService;
17
use nystudio107\instantanalytics\services\IA as IAService;
18
use nystudio107\instantanalytics\variables\InstantAnalyticsVariable;
19
use nystudio107\instantanalytics\twigextensions\InstantAnalyticsTwigExtension;
20
21
use Craft;
22
use craft\base\Plugin;
23
use craft\events\PluginEvent;
24
use craft\events\RegisterUrlRulesEvent;
25
use craft\events\TemplateEvent;
26
use craft\helpers\UrlHelper;
27
use craft\services\Plugins;
28
use craft\web\twig\variables\CraftVariable;
29
use craft\web\UrlManager;
30
use craft\web\View;
31
32
use nystudio107\seomatic\Seomatic;
0 ignored issues
show
Bug introduced by
The type nystudio107\seomatic\Seomatic was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
33
34
use yii\base\Event;
35
use yii\base\Exception;
36
37
/** @noinspection MissingPropertyAnnotationsInspection */
0 ignored issues
show
Coding Style introduced by
The open comment tag must be the only content on the line
Loading history...
Coding Style introduced by
Missing short description in doc comment
Loading history...
Coding Style introduced by
The close comment tag must be the only content on the line
Loading history...
38
39
/**
0 ignored issues
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
40
 * @author    nystudio107
0 ignored issues
show
Coding Style introduced by
The tag in position 1 should be the @package tag
Loading history...
Coding Style introduced by
Content of the @author tag must be in the form "Display Name <[email protected]>"
Loading history...
Coding Style introduced by
Tag value indented incorrectly; expected 2 spaces but found 4
Loading history...
41
 * @package   InstantAnalytics
0 ignored issues
show
Coding Style introduced by
Tag value indented incorrectly; expected 1 spaces but found 3
Loading history...
42
 * @since     1.0.0
0 ignored issues
show
Coding Style introduced by
The tag in position 3 should be the @author tag
Loading history...
Coding Style introduced by
Tag value indented incorrectly; expected 3 spaces but found 5
Loading history...
43
 *
44
 * @property  IAService       $ia
0 ignored issues
show
Coding Style introduced by
Tag value indented incorrectly; expected 1 spaces but found 2
Loading history...
45
 * @property  CommerceService $commerce
0 ignored issues
show
Coding Style introduced by
Tag value indented incorrectly; expected 1 spaces but found 2
Loading history...
46
 */
0 ignored issues
show
Coding Style introduced by
Missing @category tag in class comment
Loading history...
Coding Style introduced by
Missing @license tag in class comment
Loading history...
Coding Style introduced by
Missing @link tag in class comment
Loading history...
47
class InstantAnalytics extends Plugin
48
{
49
    // Constants
50
    // =========================================================================
51
52
    const COMMERCE_PLUGIN_HANDLE = 'commerce';
53
    const SEOMATIC_PLUGIN_HANDLE = 'seomatic';
54
55
    // Static Properties
56
    // =========================================================================
57
58
    /**
0 ignored issues
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
59
     * @var InstantAnalytics
60
     */
61
    public static $plugin;
62
63
    /**
0 ignored issues
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
64
     * @var Plugin|null
65
     */
66
    public static $commercePlugin;
67
68
    /**
0 ignored issues
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
69
     * @var Plugin|null
70
     */
71
    public static $seomaticPlugin;
72
73
    /**
0 ignored issues
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
74
     * @var string
75
     */
76
    public static $currentTemplate = '';
77
78
    /**
0 ignored issues
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
79
     * @var bool
80
     */
81
    public static $pageViewSent = false;
82
83
    // Public Methods
84
    // =========================================================================
85
86
    /**
0 ignored issues
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
87
     * @inheritdoc
88
     */
0 ignored issues
show
Coding Style introduced by
Missing @return tag in function comment
Loading history...
89
    public function init()
90
    {
91
        parent::init();
92
        self::$plugin = $this;
93
94
        // Determine if Craft Commerce is installed & enabled
95
        self::$commercePlugin = Craft::$app->getPlugins()->getPlugin(self::COMMERCE_PLUGIN_HANDLE);
96
        // Determine if SEOmatic is installed & enabled
97
        self::$seomaticPlugin = Craft::$app->getPlugins()->getPlugin(self::SEOMATIC_PLUGIN_HANDLE);
98
        // Add in our Craft components
99
        $this->addComponents();
100
        // Install our global event handlers
101
        $this->installEventListeners();
102
103
        Craft::info(
104
            Craft::t(
105
                'instant-analytics',
106
                '{name} plugin loaded',
107
                ['name' => $this->name]
108
            ),
109
            __METHOD__
110
        );
111
    }
112
113
    /**
0 ignored issues
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
114
     * @inheritdoc
115
     */
0 ignored issues
show
Coding Style introduced by
Missing @return tag in function comment
Loading history...
116
    public function settingsHtml()
117
    {
118
        $commerceFields = [];
119
120
        if (self::$commercePlugin) {
121
            /**
122
             * TODO: pending Commerce for Craft 3
123
             * $productTypes = craft()->commerce_productTypes->getAllProductTypes();
124
             * foreach ($productTypes as $productType) {
125
             * $productFields = $this->_getPullFieldsFromLayoutId($productType->fieldLayoutId);
126
             * $commerceFields = array_merge($commerceFields, $productFields);
127
             * if ($productType->hasVariants) {
128
             * $variantFields = $this->_getPullFieldsFromLayoutId($productType->variantFieldLayoutId);
129
             * $commerceFields = array_merge($commerceFields, $variantFields);
130
             * }
131
             * }
132
             */
133
        }
134
135
        // Rend the settings template
136
        try {
137
            return Craft::$app->getView()->renderTemplate(
138
                'instant-analytics/settings',
139
                [
140
                    'settings'       => $this->getSettings(),
141
                    'commerceFields' => $commerceFields,
142
                ]
143
            );
144
        } catch (\Twig_Error_Loader $e) {
145
            Craft::error($e->getMessage(), __METHOD__);
146
        } catch (Exception $e) {
147
            Craft::error($e->getMessage(), __METHOD__);
148
        }
149
150
        return '';
151
    }
152
153
    // Protected Methods
154
    // =========================================================================
155
156
157
    /**
158
     * Add in our Craft components
159
     */
0 ignored issues
show
Coding Style introduced by
Missing @return tag in function comment
Loading history...
160
    protected function addComponents()
161
    {
162
        $view = Craft::$app->getView();
163
        // Add in our Twig extensions
164
        $view->registerTwigExtension(new InstantAnalyticsTwigExtension());
165
        // Install our template hook
166
        $view->hook('iaSendPageView', [$this, 'iaSendPageView']);
167
        // Register our variables
168
        Event::on(
169
            CraftVariable::class,
170
            CraftVariable::EVENT_INIT,
171
            function (Event $event) {
172
                /** @var CraftVariable $variable */
0 ignored issues
show
Coding Style introduced by
The open comment tag must be the only content on the line
Loading history...
Coding Style introduced by
Missing short description in doc comment
Loading history...
Coding Style introduced by
The close comment tag must be the only content on the line
Loading history...
173
                $variable = $event->sender;
174
                $variable->set('instantAnalytics', InstantAnalyticsVariable::class);
175
            }
176
        );
177
    }
178
179
    /**
180
     * Install our event listeners
181
     */
0 ignored issues
show
Coding Style introduced by
Missing @return tag in function comment
Loading history...
182
    protected function installEventListeners()
183
    {
184
        // Handler: Plugins::EVENT_AFTER_INSTALL_PLUGIN
185
        Event::on(
186
            Plugins::class,
187
            Plugins::EVENT_AFTER_INSTALL_PLUGIN,
188
            function (PluginEvent $event) {
189
                if ($event->plugin === $this) {
190
                    $request = Craft::$app->getRequest();
191
                    if ($request->isCpRequest) {
192
                        Craft::$app->getResponse()->redirect(UrlHelper::cpUrl('instant-analytics/welcome'))->send();
193
                    }
194
                }
195
            }
196
        );
197
        $request = Craft::$app->getRequest();
198
        // Install only for non-console site requests
199
        if ($request->getIsSiteRequest() && !$request->getIsConsoleRequest()) {
200
            $this->installSiteEventListeners();
201
        }
202
        // Install only for non-console AdminCP requests
203
        if ($request->getIsCpRequest() && !$request->getIsConsoleRequest()) {
204
            $this->installCpEventListeners();
205
        }
206
    }
207
208
    /**
209
     * Install site event listeners for site requests only
210
     */
0 ignored issues
show
Coding Style introduced by
Missing @return tag in function comment
Loading history...
211
    protected function installSiteEventListeners()
212
    {
213
        // Handler: UrlManager::EVENT_REGISTER_SITE_URL_RULES
214
        Event::on(
215
            UrlManager::class,
216
            UrlManager::EVENT_REGISTER_SITE_URL_RULES,
217
            function (RegisterUrlRulesEvent $event) {
218
                Craft::debug(
219
                    'UrlManager::EVENT_REGISTER_SITE_URL_RULES',
220
                    __METHOD__
221
                );
222
                // Register our AdminCP routes
223
                $event->rules = array_merge(
224
                    $event->rules,
225
                    $this->customFrontendRoutes()
226
                );
227
            }
228
        );
229
        // Remember the name of the currently rendering template
230
        Event::on(
231
            View::class,
232
            View::EVENT_BEFORE_RENDER_PAGE_TEMPLATE,
233
            function (TemplateEvent $event) {
234
                self::$currentTemplate = $event->template;
235
            }
236
        );
237
        // Remember the name of the currently rendering template
238
        Event::on(
239
            View::class,
240
            View::EVENT_AFTER_RENDER_PAGE_TEMPLATE,
241
            function (TemplateEvent $event) {
242
                $settings = InstantAnalytics::$plugin->getSettings();
243
                if ($settings->autoSendPageView) {
244
                    $this->sendPageView();
245
                }
246
            }
247
        );
248
        // Register our site routes
249
        Event::on(
250
            UrlManager::class,
251
            UrlManager::EVENT_REGISTER_SITE_URL_RULES,
252
            function (RegisterUrlRulesEvent $event) {
253
                $event->rules['instantanalytics/pageViewTrack/<filename:[-\w\.*]+>?'] =
0 ignored issues
show
Coding Style introduced by
Multi-line assignments must have the equal sign on the second line
Loading history...
254
                    'instant-analytics/track/track-page-view-url';
255
                $event->rules['instantanalytics/eventTrack/<filename:[-\w\.*]+>?'] =
0 ignored issues
show
Coding Style introduced by
Multi-line assignments must have the equal sign on the second line
Loading history...
256
                    'instant-analytics/track/track-event-url';
257
            }
258
        );
259
        // Commerce-specific hooks
260
        if (self::$commercePlugin) {
261
            // TODO: pending Commerce for Craft 3
262
        }
263
    }
264
265
    /**
266
     * Install site event listeners for AdminCP requests only
267
     */
0 ignored issues
show
Coding Style introduced by
Missing @return tag in function comment
Loading history...
268
    protected function installCpEventListeners()
269
    {
270
    }
271
272
    /**
273
     * Return the custom frontend routes
274
     *
275
     * @return array
276
     */
277
    protected function customFrontendRoutes(): array
278
    {
279
        return [
280
            // Make webpack async bundle loading work out of published AssetBundles
281
            '/cpresources/instant-analytics/<resourceType:{handle}>/<fileName>' => 'instant-analytics/cp-nav/resource',
282
        ];
283
    }
284
285
    /**
0 ignored issues
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
286
     * @inheritdoc
287
     */
0 ignored issues
show
Coding Style introduced by
Missing @return tag in function comment
Loading history...
288
    protected function createSettingsModel()
289
    {
290
        return new Settings();
291
    }
292
293
    // Private Methods
294
    // =========================================================================
295
296
    /**
297
     * Send a page view with the pre-loaded IAnalytics object
298
     */
0 ignored issues
show
Coding Style introduced by
Missing @return tag in function comment
Loading history...
299
    private function sendPageView()
0 ignored issues
show
Coding Style introduced by
Private method name "InstantAnalytics::sendPageView" must be prefixed with an underscore
Loading history...
300
    {
301
        $request = Craft::$app->getRequest();
302
        if ($request->getIsSiteRequest() && !$request->getIsConsoleRequest() && !self::$pageViewSent) {
303
            self::$pageViewSent = true;
304
            /** @var IAnalytics $analytics */
0 ignored issues
show
Coding Style introduced by
The open comment tag must be the only content on the line
Loading history...
Coding Style introduced by
Missing short description in doc comment
Loading history...
Coding Style introduced by
The close comment tag must be the only content on the line
Loading history...
305
            $analytics = InstantAnalytics::$plugin->ia->getGlobals(self::$currentTemplate);
306
            // If SEOmatic is installed, set the page title from it
307
            $this->setTitleFromSeomatic($analytics);
308
            // Send the page view
309
            if ($analytics) {
0 ignored issues
show
introduced by
$analytics is of type nystudio107\instantanalytics\helpers\IAnalytics, thus it always evaluated to true. If $analytics can have other possible types, add them to src/InstantAnalytics.php:304
Loading history...
310
                $response = $analytics->sendPageview();
311
                Craft::info(
312
                    Craft::t(
313
                        'instant-analytics',
314
                        'pageView sent, response:: {response}',
315
                        [
316
                            'response' => print_r($response, true),
317
                        ]
318
                    ),
319
                    __METHOD__
320
                );
321
            } else {
322
                Craft::error(
323
                    Craft::t(
324
                        'instant-analytics',
325
                        'Analytics not sent because googleAnalyticsTracking is not set'
326
                    ),
327
                    __METHOD__
328
                );
329
            }
330
        }
331
    }
332
333
    /**
0 ignored issues
show
Coding Style introduced by
Parameter $context should have a doc-comment as per coding-style.
Loading history...
334
     * Handle the `{% hook isSendPageView %}`
335
     *
336
     * @param array &$context
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
Coding Style introduced by
Doc comment for parameter &$context does not match actual variable name $context
Loading history...
337
     *
338
     * @return string|null
339
     */
340
    private function iaSendPageView(/** @noinspection PhpUnusedParameterInspection */ array &$context)
0 ignored issues
show
Coding Style introduced by
Private method name "InstantAnalytics::iaSendPageView" must be prefixed with an underscore
Loading history...
Coding Style introduced by
The open comment tag must be the only content on the line
Loading history...
Coding Style introduced by
Missing short description in doc comment
Loading history...
Coding Style introduced by
The close comment tag must be the only content on the line
Loading history...
341
    {
342
        $this->sendPageView();
343
344
        return '';
345
    }
346
347
    /**
0 ignored issues
show
Coding Style introduced by
Parameter $analytics should have a doc-comment as per coding-style.
Loading history...
348
     * If SEOmatic is installed, set the page title from it
349
     *
350
     * @param $analytics
0 ignored issues
show
Coding Style Documentation introduced by
Missing parameter name
Loading history...
351
     */
0 ignored issues
show
Coding Style introduced by
Missing @return tag in function comment
Loading history...
352
    private function setTitleFromSeomatic(IAnalytics $analytics)
0 ignored issues
show
Coding Style introduced by
Private method name "InstantAnalytics::setTitleFromSeomatic" must be prefixed with an underscore
Loading history...
353
    {
354
        if (self::$seomaticPlugin && Seomatic::$settings->renderEnabled) {
355
            $titleTag = Seomatic::$plugin->title->get('title');
356
            if ($titleTag) {
357
                $titleArray = $titleTag->renderAttributes();
358
                if (!empty($titleArray['title'])) {
359
                    $analytics->setDocumentTitle($titleArray['title']);
360
                }
361
            }
362
        }
363
    }
364
}
365