Passed
Push — develop ( 84fc18...b7b691 )
by Andrew
03:27
created

Webperf::installGlobalEventListeners()   A

Complexity

Conditions 5
Paths 1

Size

Total Lines 26
Code Lines 15

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 15
dl 0
loc 26
rs 9.4555
c 0
b 0
f 0
cc 5
nc 1
nop 0
1
<?php
2
/**
3
 * Webperf plugin for Craft CMS 3.x
4
 *
5
 * Monitor the performance of your webpages through real-world user timing data
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) 2019 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\webperf;
12
13
use nystudio107\webperf\base\CraftDataSample;
14
use nystudio107\webperf\log\ErrorsTarget;
15
use nystudio107\webperf\log\ProfileTarget;
16
use nystudio107\webperf\models\RecommendationDataSample;
17
use nystudio107\webperf\models\Settings;
18
use nystudio107\webperf\services\DataSamples as DataSamplesService;
19
use nystudio107\webperf\services\ErrorSamples as ErrorSamplesService;
20
use nystudio107\webperf\services\Beacons as BeaconsService;
21
use nystudio107\webperf\services\Recommendations as RecommendationsService;
22
use nystudio107\webperf\variables\WebperfVariable;
23
use nystudio107\webperf\widgets\Metrics as MetricsWidget;
24
25
use Craft;
0 ignored issues
show
Bug introduced by
The type Craft 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...
26
use craft\base\Plugin;
0 ignored issues
show
Bug introduced by
The type craft\base\Plugin 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...
27
use craft\services\Plugins;
0 ignored issues
show
Bug introduced by
The type craft\services\Plugins 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...
28
use craft\events\PluginEvent;
0 ignored issues
show
Bug introduced by
The type craft\events\PluginEvent 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...
29
use craft\events\RegisterComponentTypesEvent;
0 ignored issues
show
Bug introduced by
The type craft\events\RegisterComponentTypesEvent 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...
30
use craft\events\RegisterUserPermissionsEvent;
0 ignored issues
show
Bug introduced by
The type craft\events\RegisterUserPermissionsEvent 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...
31
use craft\events\RegisterUrlRulesEvent;
0 ignored issues
show
Bug introduced by
The type craft\events\RegisterUrlRulesEvent 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...
32
use craft\helpers\UrlHelper;
0 ignored issues
show
Bug introduced by
The type craft\helpers\UrlHelper 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
use craft\services\Dashboard;
0 ignored issues
show
Bug introduced by
The type craft\services\Dashboard 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...
34
use craft\services\UserPermissions;
0 ignored issues
show
Bug introduced by
The type craft\services\UserPermissions 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...
35
use craft\web\Application;
0 ignored issues
show
Bug introduced by
The type craft\web\Application 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...
36
use craft\web\twig\variables\CraftVariable;
0 ignored issues
show
Bug introduced by
The type craft\web\twig\variables\CraftVariable 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...
37
use craft\web\UrlManager;
0 ignored issues
show
Bug introduced by
The type craft\web\UrlManager 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...
38
use craft\web\View;
0 ignored issues
show
Bug introduced by
The type craft\web\View 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...
39
40
use yii\base\Event;
0 ignored issues
show
Bug introduced by
The type yii\base\Event 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...
41
use yii\base\InvalidConfigException;
0 ignored issues
show
Bug introduced by
The type yii\base\InvalidConfigException 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...
42
43
/**
44
 * Class Webperf
45
 *
46
 * @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...
47
 * @package   Webperf
0 ignored issues
show
Coding Style introduced by
Tag value indented incorrectly; expected 1 spaces but found 3
Loading history...
48
 * @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...
49
 *
50
 * @property  RecommendationsService  $recommendations
0 ignored issues
show
Coding Style introduced by
Tag value indented incorrectly; expected 1 spaces but found 2
Loading history...
51
 * @property  DataSamplesService      $dataSamples
0 ignored issues
show
Coding Style introduced by
Tag value indented incorrectly; expected 1 spaces but found 2
Loading history...
52
 * @property  ErrorSamplesService     $errorSamples
0 ignored issues
show
Coding Style introduced by
Tag value indented incorrectly; expected 1 spaces but found 2
Loading history...
53
 * @property  BeaconsService          $beacons
0 ignored issues
show
Coding Style introduced by
Tag value indented incorrectly; expected 1 spaces but found 2
Loading history...
54
 * @property  ErrorsTarget            $errorsTarget
0 ignored issues
show
Coding Style introduced by
Tag value indented incorrectly; expected 1 spaces but found 2
Loading history...
55
 * @property  ProfileTarget           $profileTarget
0 ignored issues
show
Coding Style introduced by
Tag value indented incorrectly; expected 1 spaces but found 2
Loading history...
56
 */
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...
57
class Webperf extends Plugin
58
{
59
    // Constants
60
    // =========================================================================
61
62
    const RECOMMENDATIONS_CACHE_KEY = 'webperf-recommendations';
63
    const RECOMMENDATIONS_CACHE_DURATION = 60;
64
65
    // Static Properties
66
    // =========================================================================
67
68
    /**
0 ignored issues
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
69
     * @var Webperf
70
     */
71
    public static $plugin;
72
73
    /**
0 ignored issues
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
74
     * @var Settings
75
     */
76
    public static $settings;
77
78
    /**
0 ignored issues
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
79
     * @var int|null
80
     */
81
    public static $requestUuid;
82
83
    /**
0 ignored issues
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
84
     * @var int|null
85
     */
86
    public static $requestUrl;
87
88
    /**
0 ignored issues
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
89
     * @var bool
90
     */
91
    public static $beaconIncluded = false;
92
93
    /**
0 ignored issues
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
94
     * @var string
95
     */
96
    public static $renderType = 'html';
97
98
    // Public Properties
99
    // =========================================================================
100
101
    /**
0 ignored issues
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
102
     * @var string
103
     */
104
    public $schemaVersion = '1.0.0';
105
106
    // Public Methods
107
    // =========================================================================
108
109
    /**
0 ignored issues
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
110
     * @inheritdoc
111
     */
0 ignored issues
show
Coding Style introduced by
Missing @return tag in function comment
Loading history...
112
    public function init()
113
    {
114
        parent::init();
115
        // Initialize properties
116
        self::$plugin = $this;
117
        self::$settings = $this->getSettings();
118
        try {
119
            self::$requestUuid = random_int(0, PHP_INT_MAX);
120
        } catch (\Exception $e) {
121
            self::$requestUuid = null;
122
        }
123
        $this->name = self::$settings->pluginName;
0 ignored issues
show
Bug Best Practice introduced by
The property name does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
124
        // Add in our components
125
        $this->addComponents();
126
        // Install event listeners
127
        $this->installEventListeners();
128
        // Load that we've loaded
129
        Craft::info(
130
            Craft::t(
131
                'webperf',
132
                '{name} plugin loaded',
133
                ['name' => $this->name]
134
            ),
135
            __METHOD__
136
        );
137
    }
138
139
    /**
0 ignored issues
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
140
     * @inheritdoc
141
     */
0 ignored issues
show
Coding Style introduced by
Missing @return tag in function comment
Loading history...
142
    public function getSettingsResponse()
143
    {
144
        // Just redirect to the plugin settings page
145
        Craft::$app->getResponse()->redirect(UrlHelper::cpUrl('webperf/settings'));
146
    }
147
148
    /**
0 ignored issues
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
149
     * @inheritdoc
150
     */
0 ignored issues
show
Coding Style introduced by
Missing @return tag in function comment
Loading history...
151
    public function getCpNavItem()
152
    {
153
        $subNavs = [];
154
        $navItem = parent::getCpNavItem();
155
        $cache = Craft::$app->getCache();
156
        // See if there are any recommendations to add as a badge
157
        $recommendations = $cache->getOrSet(self::RECOMMENDATIONS_CACHE_KEY, function () {
0 ignored issues
show
Coding Style introduced by
The opening parenthesis of a multi-line function call should be the last content on the line.
Loading history...
158
            $data = [];
159
            $now = new \DateTime();
160
            $end = $now->format('Y-m-d');
161
            $start = $now->modify('-1 year')->format('Y-m-d');
162
            $stats = Webperf::$plugin->recommendations->data('', $start, $end);
163
            if (!empty($stats)) {
164
                $recSample = new RecommendationDataSample($stats);
165
                $data = Webperf::$plugin->recommendations->list($recSample);
166
            }
167
            return count($data);
168
        }, self::RECOMMENDATIONS_CACHE_DURATION);
0 ignored issues
show
Coding Style introduced by
For multi-line function calls, the closing parenthesis should be on a new line.

If a function call spawns multiple lines, the coding standard suggests to move the closing parenthesis to a new line:

someFunctionCall(
    $firstArgument,
    $secondArgument,
    $thirdArgument
); // Closing parenthesis on a new line.
Loading history...
169
        if ($recommendations) {
170
            $navItem['badgeCount'] = $recommendations;
171
        }
172
        $currentUser = Craft::$app->getUser()->getIdentity();
173
        // Only show sub-navs the user has permission to view
174
        if ($currentUser->can('webperf:dashboard')) {
175
            $subNavs['dashboard'] = [
176
                'label' => 'Dashboard',
177
                'url' => 'webperf/dashboard',
178
            ];
179
        }
180
        if ($currentUser->can('webperf:performance')) {
181
            $subNavs['performance'] = [
182
                'label' => 'Performance',
183
                'url' => 'webperf/performance',
184
            ];
185
        }
186
        if ($currentUser->can('webperf:settings')) {
187
            $subNavs['settings'] = [
188
                'label' => 'Settings',
189
                'url' => 'webperf/settings',
190
            ];
191
        }
192
        $navItem = array_merge($navItem, [
0 ignored issues
show
Coding Style introduced by
The opening parenthesis of a multi-line function call should be the last content on the line.
Loading history...
193
            'subnav' => $subNavs,
194
        ]);
0 ignored issues
show
Coding Style introduced by
For multi-line function calls, the closing parenthesis should be on a new line.

If a function call spawns multiple lines, the coding standard suggests to move the closing parenthesis to a new line:

someFunctionCall(
    $firstArgument,
    $secondArgument,
    $thirdArgument
); // Closing parenthesis on a new line.
Loading history...
195
196
        return $navItem;
197
    }
198
199
    // Protected Methods
200
    // =========================================================================
201
202
    /**
203
     * Add in our components
204
     */
0 ignored issues
show
Coding Style introduced by
Missing @return tag in function comment
Loading history...
205
    protected function addComponents()
206
    {
207
        $request = Craft::$app->getRequest();
208
        if ($request->getIsSiteRequest() && !$request->getIsConsoleRequest()) {
209
            $this->setRequestUrl();
210
            try {
211
                $uri = $request->getPathInfo();
212
            } catch (InvalidConfigException $e) {
213
                $uri = '';
214
            }
215
            // Ignore our own controllers
216
            if (self::$settings->includeCraftProfiling && strpos($uri, 'webperf/') === false) {
217
                // Add in the ProfileTarget component
218
                try {
219
                    $this->set('profileTarget', [
0 ignored issues
show
Coding Style introduced by
The opening parenthesis of a multi-line function call should be the last content on the line.
Loading history...
220
                        'class' => ProfileTarget::class,
221
                        'levels' => ['profile'],
222
                        'categories' => [],
223
                        'logVars' => [],
224
                        'except' => [],
225
                    ]);
0 ignored issues
show
Coding Style introduced by
For multi-line function calls, the closing parenthesis should be on a new line.

If a function call spawns multiple lines, the coding standard suggests to move the closing parenthesis to a new line:

someFunctionCall(
    $firstArgument,
    $secondArgument,
    $thirdArgument
); // Closing parenthesis on a new line.
Loading history...
226
                } catch (InvalidConfigException $e) {
227
                    Craft::error($e->getMessage(), __METHOD__);
228
                }
229
                // Attach our log target
230
                Craft::$app->getLog()->targets['webperf-profile'] = $this->profileTarget;
231
                // Add in the ErrorsTarget component
232
                $except = [];
233
                // If devMode is on, exclude errors/warnings from `seomatic`
234
                if (Craft::$app->getConfig()->getGeneral()->devMode) {
235
                    $except = ['seomatic'];
236
                }
237
                try {
238
                    $this->set('errorsTarget', [
0 ignored issues
show
Coding Style introduced by
The opening parenthesis of a multi-line function call should be the last content on the line.
Loading history...
239
                        'class' => ErrorsTarget::class,
240
                        'levels' => ['error','warning'],
241
                        'categories' => [],
242
                        'logVars' => [],
243
                        'except' => $except,
244
                    ]);
0 ignored issues
show
Coding Style introduced by
For multi-line function calls, the closing parenthesis should be on a new line.

If a function call spawns multiple lines, the coding standard suggests to move the closing parenthesis to a new line:

someFunctionCall(
    $firstArgument,
    $secondArgument,
    $thirdArgument
); // Closing parenthesis on a new line.
Loading history...
245
                } catch (InvalidConfigException $e) {
246
                    Craft::error($e->getMessage(), __METHOD__);
247
                }
248
                // Attach our log target
249
                Craft::$app->getLog()->targets['webperf-errors'] = $this->errorsTarget;
250
            }
251
        }
252
    }
253
254
    /**
255
     * Set the request URL
256
     *
257
     * @param bool $force
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
258
     */
0 ignored issues
show
Coding Style introduced by
Missing @return tag in function comment
Loading history...
259
    protected function setRequestUrl(bool $force = false)
260
    {
261
        self::$requestUrl = CraftDataSample::PLACEHOLDER_URL;
0 ignored issues
show
Documentation Bug introduced by
It seems like nystudio107\webperf\base...Sample::PLACEHOLDER_URL of type string is incompatible with the declared type integer|null of property $requestUrl.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
262
        if (!self::$settings->includeBeacon || $force || self::$settings->staticCachedSite) {
263
            $request = Craft::$app->getRequest();
264
            self::$requestUrl = UrlHelper::stripQueryString(
265
                urldecode($request->getAbsoluteUrl())
266
            );
267
        }
268
    }
269
270
    /**
271
     * Install our event listeners.
272
     */
0 ignored issues
show
Coding Style introduced by
Missing @return tag in function comment
Loading history...
273
    protected function installEventListeners()
274
    {
275
        $request = Craft::$app->getRequest();
276
        // Add in our event listeners that are needed for every request
277
        $this->installGlobalEventListeners();
278
        // Install only for non-console site requests
279
        if ($request->getIsSiteRequest() && !$request->getIsConsoleRequest()) {
280
            $this->installSiteEventListeners();
281
        }
282
        // Install only for non-console Control Panel requests
283
        if ($request->getIsCpRequest() && !$request->getIsConsoleRequest()) {
284
            $this->installCpEventListeners();
285
        }
286
        // Handler: EVENT_AFTER_INSTALL_PLUGIN
287
        Event::on(
288
            Plugins::class,
289
            Plugins::EVENT_AFTER_INSTALL_PLUGIN,
290
            function (PluginEvent $event) {
291
                if ($event->plugin === $this) {
292
                    // Invalidate our caches after we've been installed
293
                    $this->clearAllCaches();
294
                    // Send them to our welcome screen
295
                    $request = Craft::$app->getRequest();
296
                    if ($request->isCpRequest) {
297
                        Craft::$app->getResponse()->redirect(UrlHelper::cpUrl(
0 ignored issues
show
Coding Style introduced by
The opening parenthesis of a multi-line function call should be the last content on the line.
Loading history...
298
                            'webperf/dashboard',
299
                            [
300
                                'showWelcome' => true,
301
                            ]
302
                        ))->send();
0 ignored issues
show
Coding Style introduced by
For multi-line function calls, the closing parenthesis should be on a new line.

If a function call spawns multiple lines, the coding standard suggests to move the closing parenthesis to a new line:

someFunctionCall(
    $firstArgument,
    $secondArgument,
    $thirdArgument
); // Closing parenthesis on a new line.
Loading history...
303
                    }
304
                }
305
            }
306
        );
307
    }
308
309
    /**
310
     * Install global event listeners for all request types
311
     */
0 ignored issues
show
Coding Style introduced by
Missing @return tag in function comment
Loading history...
312
    protected function installGlobalEventListeners()
313
    {
314
        // Handler: CraftVariable::EVENT_INIT
315
        Event::on(
316
            CraftVariable::class,
317
            CraftVariable::EVENT_INIT,
318
            function (Event $event) {
319
                /** @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...
320
                $variable = $event->sender;
321
                $variable->set('webperf', WebperfVariable::class);
322
            }
323
        );
324
        // Handler: Plugins::EVENT_AFTER_LOAD_PLUGINS
325
        Event::on(
326
            Plugins::class,
327
            Plugins::EVENT_AFTER_LOAD_PLUGINS,
328
            function () {
329
                // Install these only after all other plugins have loaded
330
                $request = Craft::$app->getRequest();
331
                // Only respond to non-console site requests
332
                if ($request->getIsSiteRequest() && !$request->getIsConsoleRequest()) {
333
                    $this->handleSiteRequest();
334
                }
335
                // Respond to Control Panel requests
336
                if ($request->getIsCpRequest() && !$request->getIsConsoleRequest()) {
337
                    $this->handleAdminCpRequest();
338
                }
339
            }
340
        );
341
    }
342
343
    /**
344
     * Install site event listeners for site requests only
345
     */
0 ignored issues
show
Coding Style introduced by
Missing @return tag in function comment
Loading history...
346
    protected function installSiteEventListeners()
347
    {
348
        // Handler: UrlManager::EVENT_REGISTER_SITE_URL_RULES
349
        Event::on(
350
            UrlManager::class,
351
            UrlManager::EVENT_REGISTER_SITE_URL_RULES,
352
            function (RegisterUrlRulesEvent $event) {
353
                Craft::debug(
354
                    'UrlManager::EVENT_REGISTER_SITE_URL_RULES',
355
                    __METHOD__
356
                );
357
                // Register our Control Panel routes
358
                $event->rules = array_merge(
359
                    $event->rules,
360
                    $this->customFrontendRoutes()
361
                );
362
            }
363
        );
364
    }
365
366
    /**
367
     * Install site event listeners for Control Panel requests only
368
     */
0 ignored issues
show
Coding Style introduced by
Missing @return tag in function comment
Loading history...
369
    protected function installCpEventListeners()
370
    {
371
        // Handler: UrlManager::EVENT_REGISTER_CP_URL_RULES
372
        Event::on(
373
            UrlManager::class,
374
            UrlManager::EVENT_REGISTER_CP_URL_RULES,
375
            function (RegisterUrlRulesEvent $event) {
376
                Craft::debug(
377
                    'UrlManager::EVENT_REGISTER_CP_URL_RULES',
378
                    __METHOD__
379
                );
380
                // Register our Control Panel routes
381
                $event->rules = array_merge(
382
                    $event->rules,
383
                    $this->customAdminCpRoutes()
384
                );
385
            }
386
        );
387
        // Handler: Dashboard::EVENT_REGISTER_WIDGET_TYPES
388
        Event::on(
389
            Dashboard::class,
390
            Dashboard::EVENT_REGISTER_WIDGET_TYPES,
391
            function (RegisterComponentTypesEvent $event) {
392
                $event->types[] = MetricsWidget::class;
393
            }
394
        );
395
        // Handler: UserPermissions::EVENT_REGISTER_PERMISSIONS
396
        Event::on(
397
            UserPermissions::class,
398
            UserPermissions::EVENT_REGISTER_PERMISSIONS,
399
            function (RegisterUserPermissionsEvent $event) {
400
                Craft::debug(
401
                    'UserPermissions::EVENT_REGISTER_PERMISSIONS',
402
                    __METHOD__
403
                );
404
                // Register our custom permissions
405
                $event->permissions[Craft::t('webperf', 'Webperf')] = $this->customAdminCpPermissions();
406
            }
407
        );
408
    }
409
410
    /**
411
     * Handle site requests.  We do it only after we receive the event
412
     * EVENT_AFTER_LOAD_PLUGINS so that any pending db migrations can be run
413
     * before our event listeners kick in
414
     */
0 ignored issues
show
Coding Style introduced by
Missing @return tag in function comment
Loading history...
415
    protected function handleSiteRequest()
416
    {
417
        // Don't include the beacon for response codes >= 400
418
        $response = Craft::$app->getResponse();
419
        if ($response->statusCode < 400) {
420
            // Handler: View::EVENT_END_PAGE
421
            Event::on(
422
                View::class,
423
                View::EVENT_END_PAGE,
424
                function () {
425
                    Craft::debug(
426
                        'View::EVENT_END_PAGE',
427
                        __METHOD__
428
                    );
429
                    $view = Craft::$app->getView();
430
                    // The page is done rendering, include our beacon
431
                    if (Webperf::$settings->includeBeacon && $view->getIsRenderingPageTemplate()) {
432
                        switch (self::$renderType) {
433
                            case 'html':
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 24 spaces, found 28
Loading history...
434
                                Webperf::$plugin->beacons->includeHtmlBeacon();
435
                                self::$beaconIncluded = true;
436
                                break;
437
                            case 'amp-html':
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 24 spaces, found 28
Loading history...
438
                                Webperf::$plugin->beacons->includeAmpHtmlScript();
439
                                break;
440
                        }
441
                    }
442
                }
443
            );
444
            // Handler: View::EVENT_END_BODY
445
            Event::on(
446
                View::class,
447
                View::EVENT_END_BODY,
448
                function () {
449
                    Craft::debug(
450
                        'View::EVENT_END_BODY',
451
                        __METHOD__
452
                    );
453
                    $view = Craft::$app->getView();
454
                    // The page is done rendering, include our beacon
455
                    if (Webperf::$settings->includeBeacon && $view->getIsRenderingPageTemplate()) {
456
                        switch (self::$renderType) {
457
                            case 'html':
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 24 spaces, found 28
Loading history...
458
                                break;
459
                            case 'amp-html':
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 24 spaces, found 28
Loading history...
460
                                Webperf::$plugin->beacons->includeAmpHtmlBeacon();
461
                                self::$beaconIncluded = true;
462
                                break;
463
                        }
464
                    }
465
                }
466
            );
467
            // Handler: Application::EVENT_AFTER_REQUEST
468
            Event::on(
469
                Application::class,
470
                Application::EVENT_AFTER_REQUEST,
471
                function () {
472
                    Craft::debug(
473
                        'Application::EVENT_AFTER_REQUEST',
474
                        __METHOD__
475
                    );
476
                    // If the beacon wasn't included, allow for the Craft timings
477
                    if (!self::$beaconIncluded) {
478
                        $this->setRequestUrl(true);
479
                    }
480
                }
481
            );
482
        }
483
    }
484
485
    /**
486
     * Handle Control Panel requests. We do it only after we receive the event
487
     * EVENT_AFTER_LOAD_PLUGINS so that any pending db migrations can be run
488
     * before our event listeners kick in
489
     */
0 ignored issues
show
Coding Style introduced by
Missing @return tag in function comment
Loading history...
490
    protected function handleAdminCpRequest()
491
    {
492
    }
493
494
    /**
495
     * Clear all the caches!
496
     */
0 ignored issues
show
Coding Style introduced by
Missing @return tag in function comment
Loading history...
497
    public function clearAllCaches()
498
    {
499
    }
500
501
    /**
0 ignored issues
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
502
     * @inheritdoc
503
     */
0 ignored issues
show
Coding Style introduced by
Missing @return tag in function comment
Loading history...
504
    protected function createSettingsModel()
505
    {
506
        return new Settings();
507
    }
508
509
    /**
0 ignored issues
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
510
     * @inheritdoc
511
     */
0 ignored issues
show
Coding Style introduced by
Missing @return tag in function comment
Loading history...
512
    protected function settingsHtml(): string
513
    {
514
        return Craft::$app->view->renderTemplate(
515
            'webperf/settings',
516
            [
517
                'settings' => $this->getSettings()
518
            ]
519
        );
520
    }
521
522
    /**
523
     * Return the custom frontend routes
524
     *
525
     * @return array
526
     */
527
    protected function customFrontendRoutes(): array
528
    {
529
        return [
530
            // Beacon
531
            '/webperf/metrics/beacon' => 'webperf/metrics/beacon',
532
            // Render
533
            '/webperf/render/amp-iframe' => 'webperf/render/amp-iframe',
534
            // Tables
535
            '/webperf/tables/pages-index' => 'webperf/tables/pages-index',
536
            '/webperf/tables/page-detail' => 'webperf/tables/page-detail',
537
            // Charts
538
            '/webperf/charts/dashboard-stats-average/<column:{handle}>'
539
            => 'webperf/charts/dashboard-stats-average',
540
            '/webperf/charts/dashboard-stats-average/<column:{handle}>/<siteId:\d+>'
541
            => 'webperf/charts/dashboard-stats-average',
542
543
            '/webperf/charts/dashboard-slowest-pages/<column:{handle}>/<limit:\d+>'
544
            => 'webperf/charts/dashboard-slowest-pages',
545
            '/webperf/charts/dashboard-slowest-pages/<column:{handle}>/<limit:\d+>/<siteId:\d+>'
546
            => 'webperf/charts/dashboard-slowest-pages',
547
548
            '/webperf/charts/pages-area-chart'
549
            => 'webperf/charts/pages-area-chart',
550
            '/webperf/charts/pages-area-chart/<siteId:\d+>'
551
            => 'webperf/charts/pages-area-chart',
552
553
            '/webperf/recommendations/list'
554
            => 'webperf/recommendations/list',
555
            '/webperf/recommendations/list/<siteId:\d+>'
556
            => 'webperf/recommendations/list',
557
558
            '/webperf/charts/widget/<days>' => 'webperf/charts/widget',
559
        ];
560
    }
561
    /**
562
     * Return the custom Control Panel routes
563
     *
564
     * @return array
565
     */
566
    protected function customAdminCpRoutes(): array
567
    {
568
        return [
569
            'webperf' => 'webperf/sections/dashboard',
570
            'webperf/dashboard' => 'webperf/sections/dashboard',
571
            'webperf/dashboard/<siteHandle:{handle}>' => 'webperf/sections/dashboard',
572
573
            'webperf/performance' => 'webperf/sections/pages-index',
574
            'webperf/performance/<siteHandle:{handle}>' => 'webperf/sections/pages-index',
575
576
            'webperf/performance/page-detail' => 'webperf/sections/page-detail',
577
            'webperf/performance/page-detail/<siteHandle:{handle}>' => 'webperf/sections/page-detail',
578
579
            'webperf/settings' => 'webperf/settings/plugin-settings',
580
        ];
581
    }
582
583
    /**
584
     * Returns the custom Control Panel user permissions.
585
     *
586
     * @return array
587
     */
588
    protected function customAdminCpPermissions(): array
589
    {
590
        return [
591
            'webperf:dashboard' => [
592
                'label' => Craft::t('webperf', 'Dashboard'),
593
            ],
594
            'webperf:performance' => [
595
                'label' => Craft::t('webperf', 'Performance'),
596
            ],
597
            'webperf:page-detail' => [
598
                'label' => Craft::t('webperf', 'Page Detail'),
599
            ],
600
            'webperf:recommendations' => [
601
                'label' => Craft::t('webperf', 'Recommendations'),
602
            ],
603
            'webperf:delete-data-samples' => [
604
                'label' => Craft::t('webperf', 'Delete Data Samples'),
605
            ],
606
            'webperf:settings' => [
607
                'label' => Craft::t('webperf', 'Settings'),
608
            ],
609
        ];
610
    }
611
}
612