Passed
Push — v1 ( b7e877...c15027 )
by Andrew
15:24 queued 11:41
created

InstantAnalytics::sendPageView()   B

Complexity

Conditions 6
Paths 4

Size

Total Lines 33
Code Lines 21

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 21
dl 0
loc 33
rs 8.9617
c 0
b 0
f 0
cc 6
nc 4
nop 0
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
    /**
0 ignored issues
show
Coding Style introduced by
Parameter $context should have a doc-comment as per coding-style.
Loading history...
154
     * Handle the `{% hook isSendPageView %}`
155
     *
156
     * @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...
157
     *
158
     * @return string|null
159
     */
160
    public function iaSendPageView(/** @noinspection PhpUnusedParameterInspection */ array &$context)
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...
161
    {
162
        $this->sendPageView();
163
164
        return '';
165
    }
166
167
    // Protected Methods
168
    // =========================================================================
169
170
    /**
171
     * Add in our Craft components
172
     */
0 ignored issues
show
Coding Style introduced by
Missing @return tag in function comment
Loading history...
173
    protected function addComponents()
174
    {
175
        $view = Craft::$app->getView();
176
        // Add in our Twig extensions
177
        $view->registerTwigExtension(new InstantAnalyticsTwigExtension());
178
        // Install our template hook
179
        $view->hook('iaSendPageView', [$this, 'iaSendPageView']);
180
        // Register our variables
181
        Event::on(
182
            CraftVariable::class,
183
            CraftVariable::EVENT_INIT,
184
            function (Event $event) {
185
                /** @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...
186
                $variable = $event->sender;
187
                $variable->set('instantAnalytics', InstantAnalyticsVariable::class);
188
            }
189
        );
190
    }
191
192
    /**
193
     * Install our event listeners
194
     */
0 ignored issues
show
Coding Style introduced by
Missing @return tag in function comment
Loading history...
195
    protected function installEventListeners()
196
    {
197
        // Handler: Plugins::EVENT_AFTER_INSTALL_PLUGIN
198
        Event::on(
199
            Plugins::class,
200
            Plugins::EVENT_AFTER_INSTALL_PLUGIN,
201
            function (PluginEvent $event) {
202
                if ($event->plugin === $this) {
203
                    $request = Craft::$app->getRequest();
204
                    if ($request->isCpRequest) {
205
                        Craft::$app->getResponse()->redirect(UrlHelper::cpUrl('instant-analytics/welcome'))->send();
206
                    }
207
                }
208
            }
209
        );
210
        $request = Craft::$app->getRequest();
211
        // Install only for non-console site requests
212
        if ($request->getIsSiteRequest() && !$request->getIsConsoleRequest()) {
213
            $this->installSiteEventListeners();
214
        }
215
        // Install only for non-console AdminCP requests
216
        if ($request->getIsCpRequest() && !$request->getIsConsoleRequest()) {
217
            $this->installCpEventListeners();
218
        }
219
    }
220
221
    /**
222
     * Install site event listeners for site requests only
223
     */
0 ignored issues
show
Coding Style introduced by
Missing @return tag in function comment
Loading history...
224
    protected function installSiteEventListeners()
225
    {
226
        // Handler: UrlManager::EVENT_REGISTER_SITE_URL_RULES
227
        Event::on(
228
            UrlManager::class,
229
            UrlManager::EVENT_REGISTER_SITE_URL_RULES,
230
            function (RegisterUrlRulesEvent $event) {
231
                Craft::debug(
232
                    'UrlManager::EVENT_REGISTER_SITE_URL_RULES',
233
                    __METHOD__
234
                );
235
                // Register our AdminCP routes
236
                $event->rules = array_merge(
237
                    $event->rules,
238
                    $this->customFrontendRoutes()
239
                );
240
            }
241
        );
242
        // Remember the name of the currently rendering template
243
        Event::on(
244
            View::class,
245
            View::EVENT_BEFORE_RENDER_PAGE_TEMPLATE,
246
            function (TemplateEvent $event) {
247
                self::$currentTemplate = $event->template;
248
            }
249
        );
250
        // Remember the name of the currently rendering template
251
        Event::on(
252
            View::class,
253
            View::EVENT_AFTER_RENDER_PAGE_TEMPLATE,
254
            function (TemplateEvent $event) {
255
                $settings = InstantAnalytics::$plugin->getSettings();
256
                if ($settings->autoSendPageView) {
257
                    $this->sendPageView();
258
                }
259
            }
260
        );
261
        // Register our site routes
262
        Event::on(
263
            UrlManager::class,
264
            UrlManager::EVENT_REGISTER_SITE_URL_RULES,
265
            function (RegisterUrlRulesEvent $event) {
266
                $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...
267
                    'instant-analytics/track/track-page-view-url';
268
                $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...
269
                    'instant-analytics/track/track-event-url';
270
            }
271
        );
272
        // Commerce-specific hooks
273
        if (self::$commercePlugin) {
274
            // TODO: pending Commerce for Craft 3
275
        }
276
    }
277
278
    /**
279
     * Install site event listeners for AdminCP requests only
280
     */
0 ignored issues
show
Coding Style introduced by
Missing @return tag in function comment
Loading history...
281
    protected function installCpEventListeners()
282
    {
283
    }
284
285
    /**
286
     * Return the custom frontend routes
287
     *
288
     * @return array
289
     */
290
    protected function customFrontendRoutes(): array
291
    {
292
        return [
293
            // Make webpack async bundle loading work out of published AssetBundles
294
            '/cpresources/instant-analytics/<resourceType:{handle}>/<fileName>' => 'instant-analytics/cp-nav/resource',
295
        ];
296
    }
297
298
    /**
0 ignored issues
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
299
     * @inheritdoc
300
     */
0 ignored issues
show
Coding Style introduced by
Missing @return tag in function comment
Loading history...
301
    protected function createSettingsModel()
302
    {
303
        return new Settings();
304
    }
305
306
    // Private Methods
307
    // =========================================================================
308
309
    /**
310
     * Send a page view with the pre-loaded IAnalytics object
311
     */
0 ignored issues
show
Coding Style introduced by
Missing @return tag in function comment
Loading history...
312
    private function sendPageView()
0 ignored issues
show
Coding Style introduced by
Private method name "InstantAnalytics::sendPageView" must be prefixed with an underscore
Loading history...
313
    {
314
        $request = Craft::$app->getRequest();
315
        if ($request->getIsSiteRequest() && !$request->getIsConsoleRequest() && !self::$pageViewSent) {
316
            self::$pageViewSent = true;
317
            /** @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...
318
            $analytics = InstantAnalytics::$plugin->ia->getGlobals(self::$currentTemplate);
319
            // Bail if we have no analytics object
320
            if ($analytics === null) {
321
                return;
322
            }
323
            // If SEOmatic is installed, set the page title from it
324
            $this->setTitleFromSeomatic($analytics);
325
            // Send the page view
326
            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:317
Loading history...
327
                $response = $analytics->sendPageview();
328
                Craft::info(
329
                    Craft::t(
330
                        'instant-analytics',
331
                        'pageView sent, response:: {response}',
332
                        [
333
                            'response' => print_r($response, true),
334
                        ]
335
                    ),
336
                    __METHOD__
337
                );
338
            } else {
339
                Craft::error(
340
                    Craft::t(
341
                        'instant-analytics',
342
                        'Analytics not sent because googleAnalyticsTracking is not set'
343
                    ),
344
                    __METHOD__
345
                );
346
            }
347
        }
348
    }
349
350
    /**
0 ignored issues
show
Coding Style introduced by
Parameter $analytics should have a doc-comment as per coding-style.
Loading history...
351
     * If SEOmatic is installed, set the page title from it
352
     *
353
     * @param $analytics
0 ignored issues
show
Coding Style Documentation introduced by
Missing parameter name
Loading history...
354
     */
0 ignored issues
show
Coding Style introduced by
Missing @return tag in function comment
Loading history...
355
    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...
356
    {
357
        if (self::$seomaticPlugin && Seomatic::$settings->renderEnabled) {
358
            $titleTag = Seomatic::$plugin->title->get('title');
359
            if ($titleTag) {
360
                $titleArray = $titleTag->renderAttributes();
361
                if (!empty($titleArray['title'])) {
362
                    $analytics->setDocumentTitle($titleArray['title']);
363
                }
364
            }
365
        }
366
    }
367
}
368