Passed
Push — v1 ( 7dfb05...0f87a2 )
by Andrew
07:09 queued 04:02
created

Webperf::getCpNavItem()   B

Complexity

Conditions 6
Paths 16

Size

Total Lines 46
Code Lines 32

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 32
dl 0
loc 46
rs 8.7857
c 0
b 0
f 0
cc 6
nc 16
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\ProfileTarget;
15
use nystudio107\webperf\models\RecommendationDataSample;
16
use nystudio107\webperf\models\Settings;
17
use nystudio107\webperf\services\DataSamples as DataSamplesService;
18
use nystudio107\webperf\services\Beacons as BeaconsService;
19
use nystudio107\webperf\services\Recommendations as RecommendationsService;
20
use nystudio107\webperf\variables\WebperfVariable;
21
use nystudio107\webperf\widgets\Metrics as MetricsWidget;
22
23
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...
24
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...
25
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...
26
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...
27
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...
28
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...
29
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...
30
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...
31
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...
32
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...
33
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...
34
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...
35
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...
36
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...
37
38
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...
39
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...
40
41
/**
42
 * Class Webperf
43
 *
44
 * @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...
45
 * @package   Webperf
0 ignored issues
show
Coding Style introduced by
Tag value indented incorrectly; expected 1 spaces but found 3
Loading history...
46
 * @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...
47
 *
48
 * @property  RecommendationsService  $recommendations
0 ignored issues
show
Coding Style introduced by
Tag value indented incorrectly; expected 1 spaces but found 2
Loading history...
49
 * @property  DataSamplesService      $dataSamples
0 ignored issues
show
Coding Style introduced by
Tag value indented incorrectly; expected 1 spaces but found 2
Loading history...
50
 * @property  BeaconsService          $beacons
0 ignored issues
show
Coding Style introduced by
Tag value indented incorrectly; expected 1 spaces but found 2
Loading history...
51
 * @property  ProfileTarget           $profileTarget
0 ignored issues
show
Coding Style introduced by
Tag value indented incorrectly; expected 1 spaces but found 2
Loading history...
52
 */
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...
53
class Webperf extends Plugin
54
{
55
    // Constants
56
    // =========================================================================
57
58
    const RECOMMENDATIONS_CACHE_KEY = 'webperf-recommendations';
59
    const RECOMMENDATIONS_CACHE_DURATION = 60;
60
61
    // Static Properties
62
    // =========================================================================
63
64
    /**
0 ignored issues
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
65
     * @var Webperf
66
     */
67
    public static $plugin;
68
69
    /**
0 ignored issues
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
70
     * @var Settings
71
     */
72
    public static $settings;
73
74
    /**
0 ignored issues
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
75
     * @var int|null
76
     */
77
    public static $requestUuid;
78
79
    /**
0 ignored issues
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
80
     * @var int|null
81
     */
82
    public static $requestUrl;
83
84
    /**
0 ignored issues
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
85
     * @var bool
86
     */
87
    public static $beaconIncluded = false;
88
89
    /**
0 ignored issues
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
90
     * @var string
91
     */
92
    public static $renderType = 'html';
93
94
    // Public Properties
95
    // =========================================================================
96
97
    /**
0 ignored issues
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
98
     * @var string
99
     */
100
    public $schemaVersion = '1.0.0';
101
102
    // Public Methods
103
    // =========================================================================
104
105
    /**
0 ignored issues
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
106
     * @inheritdoc
107
     */
0 ignored issues
show
Coding Style introduced by
Missing @return tag in function comment
Loading history...
108
    public function init()
109
    {
110
        parent::init();
111
        // Initialize properties
112
        self::$plugin = $this;
113
        self::$settings = $this->getSettings();
114
        try {
115
            self::$requestUuid = random_int(0, PHP_INT_MAX);
116
        } catch (\Exception $e) {
117
            self::$requestUuid = null;
118
        }
119
        $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...
120
        // Add in our components
121
        $this->addComponents();
122
        // Install event listeners
123
        $this->installEventListeners();
124
        // Load that we've loaded
125
        Craft::info(
126
            Craft::t(
127
                'webperf',
128
                '{name} plugin loaded',
129
                ['name' => $this->name]
130
            ),
131
            __METHOD__
132
        );
133
    }
134
135
    /**
0 ignored issues
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
136
     * @inheritdoc
137
     */
0 ignored issues
show
Coding Style introduced by
Missing @return tag in function comment
Loading history...
138
    public function getSettingsResponse()
139
    {
140
        // Just redirect to the plugin settings page
141
        Craft::$app->getResponse()->redirect(UrlHelper::cpUrl('webperf/settings'));
142
    }
143
144
    /**
0 ignored issues
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
145
     * @inheritdoc
146
     */
0 ignored issues
show
Coding Style introduced by
Missing @return tag in function comment
Loading history...
147
    public function getCpNavItem()
148
    {
149
        $subNavs = [];
150
        $navItem = parent::getCpNavItem();
151
        $cache = Craft::$app->getCache();
152
        // See if there are any recommendations to add as a badge
153
        $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...
154
            $data = [];
155
            $now = new \DateTime();
156
            $end = $now->format('Y-m-d');
157
            $start = $now->modify('-1 year')->format('Y-m-d');
158
            $stats = Webperf::$plugin->recommendations->data('', $start, $end);
159
            if (!empty($stats)) {
160
                $recSample = new RecommendationDataSample($stats);
161
                $data = Webperf::$plugin->recommendations->list($recSample);
162
            }
163
            return count($data);
164
        }, 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...
165
        if ($recommendations) {
166
            $navItem['badgeCount'] = $recommendations;
167
        }
168
        $currentUser = Craft::$app->getUser()->getIdentity();
169
        // Only show sub-navs the user has permission to view
170
        if ($currentUser->can('webperf:dashboard')) {
171
            $subNavs['dashboard'] = [
172
                'label' => 'Dashboard',
173
                'url' => 'webperf/dashboard',
174
            ];
175
        }
176
        if ($currentUser->can('webperf:pages')) {
177
            $subNavs['pages'] = [
178
                'label' => 'Pages',
179
                'url' => 'webperf/pages',
180
            ];
181
        }
182
        if ($currentUser->can('webperf:settings')) {
183
            $subNavs['settings'] = [
184
                'label' => 'Settings',
185
                'url' => 'webperf/settings',
186
            ];
187
        }
188
        $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...
189
            'subnav' => $subNavs,
190
        ]);
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...
191
192
        return $navItem;
193
    }
194
195
    // Protected Methods
196
    // =========================================================================
197
198
    /**
199
     * Add in our components
200
     */
0 ignored issues
show
Coding Style introduced by
Missing @return tag in function comment
Loading history...
201
    protected function addComponents()
202
    {
203
        $request = Craft::$app->getRequest();
204
        if ($request->getIsSiteRequest() && !$request->getIsConsoleRequest()) {
205
            $this->setRequestUrl();
206
            try {
207
                $uri = $request->getPathInfo();
208
            } catch (InvalidConfigException $e) {
209
                $uri = '';
210
            }
211
            // Ignore our own controllers
212
            if (self::$settings->includeCraftProfiling && strpos($uri, 'webperf/') === false) {
213
                // Add in the ProfileTarget component
214
                try {
215
                    $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...
216
                        'class' => ProfileTarget::class,
217
                        'levels' => ['profile'],
218
                        'categories' => [],
219
                        'logVars' => [],
220
                        'except' => [],
221
                    ]);
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...
222
                } catch (InvalidConfigException $e) {
223
                    Craft::error($e->getMessage(), __METHOD__);
224
                }
225
                // Attach our log target
226
                Craft::$app->getLog()->targets['webperf'] = $this->profileTarget;
227
            }
228
        }
229
    }
230
231
    /**
232
     * Set the request URL
233
     *
234
     * @param bool $force
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
235
     */
0 ignored issues
show
Coding Style introduced by
Missing @return tag in function comment
Loading history...
236
    protected function setRequestUrl(bool $force = false)
237
    {
238
        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...
239
        if (!self::$settings->includeBeacon || $force || self::$settings->staticCachedSite) {
240
            $request = Craft::$app->getRequest();
241
            self::$requestUrl = UrlHelper::stripQueryString(
242
                urldecode($request->getAbsoluteUrl())
243
            );
244
        }
245
    }
246
247
    /**
248
     * Install our event listeners.
249
     */
0 ignored issues
show
Coding Style introduced by
Missing @return tag in function comment
Loading history...
250
    protected function installEventListeners()
251
    {
252
        $request = Craft::$app->getRequest();
253
        // Add in our event listeners that are needed for every request
254
        $this->installGlobalEventListeners();
255
        // Install only for non-console site requests
256
        if ($request->getIsSiteRequest() && !$request->getIsConsoleRequest()) {
257
            $this->installSiteEventListeners();
258
        }
259
        // Install only for non-console Control Panel requests
260
        if ($request->getIsCpRequest() && !$request->getIsConsoleRequest()) {
261
            $this->installCpEventListeners();
262
        }
263
        // Handler: EVENT_AFTER_INSTALL_PLUGIN
264
        Event::on(
265
            Plugins::class,
266
            Plugins::EVENT_AFTER_INSTALL_PLUGIN,
267
            function (PluginEvent $event) {
268
                if ($event->plugin === $this) {
269
                    // Invalidate our caches after we've been installed
270
                    $this->clearAllCaches();
271
                    // Send them to our welcome screen
272
                    $request = Craft::$app->getRequest();
273
                    if ($request->isCpRequest) {
274
                        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...
275
                            'webperf/dashboard',
276
                            [
277
                                'showWelcome' => true,
278
                            ]
279
                        ))->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...
280
                    }
281
                }
282
            }
283
        );
284
    }
285
286
    /**
287
     * Install global event listeners for all request types
288
     */
0 ignored issues
show
Coding Style introduced by
Missing @return tag in function comment
Loading history...
289
    protected function installGlobalEventListeners()
290
    {
291
        // Handler: CraftVariable::EVENT_INIT
292
        Event::on(
293
            CraftVariable::class,
294
            CraftVariable::EVENT_INIT,
295
            function (Event $event) {
296
                /** @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...
297
                $variable = $event->sender;
298
                $variable->set('webperf', WebperfVariable::class);
299
            }
300
        );
301
        // Handler: Plugins::EVENT_AFTER_LOAD_PLUGINS
302
        Event::on(
303
            Plugins::class,
304
            Plugins::EVENT_AFTER_LOAD_PLUGINS,
305
            function () {
306
                // Install these only after all other plugins have loaded
307
                $request = Craft::$app->getRequest();
308
                // Only respond to non-console site requests
309
                if ($request->getIsSiteRequest() && !$request->getIsConsoleRequest()) {
310
                    $this->handleSiteRequest();
311
                }
312
                // Respond to Control Panel requests
313
                if ($request->getIsCpRequest() && !$request->getIsConsoleRequest()) {
314
                    $this->handleAdminCpRequest();
315
                }
316
            }
317
        );
318
    }
319
320
    /**
321
     * Install site event listeners for site requests only
322
     */
0 ignored issues
show
Coding Style introduced by
Missing @return tag in function comment
Loading history...
323
    protected function installSiteEventListeners()
324
    {
325
        // Handler: UrlManager::EVENT_REGISTER_SITE_URL_RULES
326
        Event::on(
327
            UrlManager::class,
328
            UrlManager::EVENT_REGISTER_SITE_URL_RULES,
329
            function (RegisterUrlRulesEvent $event) {
330
                Craft::debug(
331
                    'UrlManager::EVENT_REGISTER_SITE_URL_RULES',
332
                    __METHOD__
333
                );
334
                // Register our Control Panel routes
335
                $event->rules = array_merge(
336
                    $event->rules,
337
                    $this->customFrontendRoutes()
338
                );
339
            }
340
        );
341
    }
342
343
    /**
344
     * Install site event listeners for Control Panel requests only
345
     */
0 ignored issues
show
Coding Style introduced by
Missing @return tag in function comment
Loading history...
346
    protected function installCpEventListeners()
347
    {
348
        // Handler: UrlManager::EVENT_REGISTER_CP_URL_RULES
349
        Event::on(
350
            UrlManager::class,
351
            UrlManager::EVENT_REGISTER_CP_URL_RULES,
352
            function (RegisterUrlRulesEvent $event) {
353
                Craft::debug(
354
                    'UrlManager::EVENT_REGISTER_CP_URL_RULES',
355
                    __METHOD__
356
                );
357
                // Register our Control Panel routes
358
                $event->rules = array_merge(
359
                    $event->rules,
360
                    $this->customAdminCpRoutes()
361
                );
362
            }
363
        );
364
        // Handler: Dashboard::EVENT_REGISTER_WIDGET_TYPES
365
        Event::on(
366
            Dashboard::class,
367
            Dashboard::EVENT_REGISTER_WIDGET_TYPES,
368
            function (RegisterComponentTypesEvent $event) {
369
                $event->types[] = MetricsWidget::class;
370
            }
371
        );
372
        // Handler: UserPermissions::EVENT_REGISTER_PERMISSIONS
373
        Event::on(
374
            UserPermissions::class,
375
            UserPermissions::EVENT_REGISTER_PERMISSIONS,
376
            function (RegisterUserPermissionsEvent $event) {
377
                Craft::debug(
378
                    'UserPermissions::EVENT_REGISTER_PERMISSIONS',
379
                    __METHOD__
380
                );
381
                // Register our custom permissions
382
                $event->permissions[Craft::t('webperf', 'Webperf')] = $this->customAdminCpPermissions();
383
            }
384
        );
385
    }
386
387
    /**
388
     * Handle site requests.  We do it only after we receive the event
389
     * EVENT_AFTER_LOAD_PLUGINS so that any pending db migrations can be run
390
     * before our event listeners kick in
391
     */
0 ignored issues
show
Coding Style introduced by
Missing @return tag in function comment
Loading history...
392
    protected function handleSiteRequest()
393
    {
394
        // Don't include the beacon for response codes >= 400
395
        $response = Craft::$app->getResponse();
396
        if ($response->statusCode < 400) {
397
            // Handler: View::EVENT_END_PAGE
398
            Event::on(
399
                View::class,
400
                View::EVENT_END_PAGE,
401
                function () {
402
                    Craft::debug(
403
                        'View::EVENT_END_PAGE',
404
                        __METHOD__
405
                    );
406
                    $view = Craft::$app->getView();
407
                    // The page is done rendering, include our beacon
408
                    if (Webperf::$settings->includeBeacon && $view->getIsRenderingPageTemplate()) {
409
                        switch (self::$renderType) {
410
                            case 'html':
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 24 spaces, found 28
Loading history...
411
                                Webperf::$plugin->beacons->includeHtmlBeacon();
412
                                self::$beaconIncluded = true;
413
                                break;
414
                            case 'amp-html':
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 24 spaces, found 28
Loading history...
415
                                Webperf::$plugin->beacons->includeAmpHtmlScript();
416
                                break;
417
                        }
418
                    }
419
                }
420
            );
421
            // Handler: View::EVENT_END_BODY
422
            Event::on(
423
                View::class,
424
                View::EVENT_END_BODY,
425
                function () {
426
                    Craft::debug(
427
                        'View::EVENT_END_BODY',
428
                        __METHOD__
429
                    );
430
                    $view = Craft::$app->getView();
431
                    // The page is done rendering, include our beacon
432
                    if (Webperf::$settings->includeBeacon && $view->getIsRenderingPageTemplate()) {
433
                        switch (self::$renderType) {
434
                            case 'html':
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 24 spaces, found 28
Loading history...
435
                                break;
436
                            case 'amp-html':
0 ignored issues
show
Coding Style introduced by
Line indented incorrectly; expected 24 spaces, found 28
Loading history...
437
                                Webperf::$plugin->beacons->includeAmpHtmlBeacon();
438
                                self::$beaconIncluded = true;
439
                                break;
440
                        }
441
                    }
442
                }
443
            );
444
            // Handler: Application::EVENT_AFTER_REQUEST
445
            Event::on(
446
                Application::class,
447
                Application::EVENT_AFTER_REQUEST,
448
                function () {
449
                    Craft::debug(
450
                        'Application::EVENT_AFTER_REQUEST',
451
                        __METHOD__
452
                    );
453
                    // If the beacon wasn't included, allow for the Craft timings
454
                    if (!self::$beaconIncluded) {
455
                        $this->setRequestUrl(true);
456
                    }
457
                }
458
            );
459
        }
460
    }
461
462
    /**
463
     * Handle Control Panel requests. We do it only after we receive the event
464
     * EVENT_AFTER_LOAD_PLUGINS so that any pending db migrations can be run
465
     * before our event listeners kick in
466
     */
0 ignored issues
show
Coding Style introduced by
Missing @return tag in function comment
Loading history...
467
    protected function handleAdminCpRequest()
468
    {
469
    }
470
471
    /**
472
     * Clear all the caches!
473
     */
0 ignored issues
show
Coding Style introduced by
Missing @return tag in function comment
Loading history...
474
    public function clearAllCaches()
475
    {
476
    }
477
478
    /**
0 ignored issues
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
479
     * @inheritdoc
480
     */
0 ignored issues
show
Coding Style introduced by
Missing @return tag in function comment
Loading history...
481
    protected function createSettingsModel()
482
    {
483
        return new Settings();
484
    }
485
486
    /**
0 ignored issues
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
487
     * @inheritdoc
488
     */
0 ignored issues
show
Coding Style introduced by
Missing @return tag in function comment
Loading history...
489
    protected function settingsHtml(): string
490
    {
491
        return Craft::$app->view->renderTemplate(
492
            'webperf/settings',
493
            [
494
                'settings' => $this->getSettings()
495
            ]
496
        );
497
    }
498
499
    /**
500
     * Return the custom frontend routes
501
     *
502
     * @return array
503
     */
504
    protected function customFrontendRoutes(): array
505
    {
506
        return [
507
            // Beacon
508
            '/webperf/metrics/beacon' => 'webperf/metrics/beacon',
509
            // Render
510
            '/webperf/render/amp-iframe' => 'webperf/render/amp-iframe',
511
            // Tables
512
            '/webperf/tables/pages-index' => 'webperf/tables/pages-index',
513
            '/webperf/tables/page-detail' => 'webperf/tables/page-detail',
514
            // Charts
515
            '/webperf/charts/dashboard-stats-average/<column:{handle}>'
516
            => 'webperf/charts/dashboard-stats-average',
517
            '/webperf/charts/dashboard-stats-average/<column:{handle}>/<siteId:\d+>'
518
            => 'webperf/charts/dashboard-stats-average',
519
520
            '/webperf/charts/dashboard-slowest-pages/<column:{handle}>/<limit:\d+>'
521
            => 'webperf/charts/dashboard-slowest-pages',
522
            '/webperf/charts/dashboard-slowest-pages/<column:{handle}>/<limit:\d+>/<siteId:\d+>'
523
            => 'webperf/charts/dashboard-slowest-pages',
524
525
            '/webperf/charts/pages-area-chart'
526
            => 'webperf/charts/pages-area-chart',
527
            '/webperf/charts/pages-area-chart/<siteId:\d+>'
528
            => 'webperf/charts/pages-area-chart',
529
530
            '/webperf/recommendations/list'
531
            => 'webperf/recommendations/list',
532
            '/webperf/recommendations/list/<siteId:\d+>'
533
            => 'webperf/recommendations/list',
534
535
            '/webperf/charts/widget/<days>' => 'webperf/charts/widget',
536
        ];
537
    }
538
    /**
539
     * Return the custom Control Panel routes
540
     *
541
     * @return array
542
     */
543
    protected function customAdminCpRoutes(): array
544
    {
545
        return [
546
            'webperf' => 'webperf/sections/dashboard',
547
            'webperf/dashboard' => 'webperf/sections/dashboard',
548
            'webperf/dashboard/<siteHandle:{handle}>' => 'webperf/sections/dashboard',
549
550
            'webperf/pages' => 'webperf/sections/pages-index',
551
            'webperf/pages/<siteHandle:{handle}>' => 'webperf/sections/pages-index',
552
553
            'webperf/page-detail' => 'webperf/sections/page-detail',
554
            'webperf/page-detail/<siteHandle:{handle}>' => 'webperf/sections/page-detail',
555
556
            'webperf/settings' => 'webperf/settings/plugin-settings',
557
        ];
558
    }
559
560
    /**
561
     * Returns the custom Control Panel user permissions.
562
     *
563
     * @return array
564
     */
565
    protected function customAdminCpPermissions(): array
566
    {
567
        return [
568
            'webperf:dashboard' => [
569
                'label' => Craft::t('webperf', 'Dashboard'),
570
            ],
571
            'webperf:pages' => [
572
                'label' => Craft::t('webperf', 'Pages'),
573
            ],
574
            'webperf:page-detail' => [
575
                'label' => Craft::t('webperf', 'Page Detail'),
576
            ],
577
            'webperf:recommendations' => [
578
                'label' => Craft::t('webperf', 'Recommendations'),
579
            ],
580
            'webperf:delete-data-samples' => [
581
                'label' => Craft::t('webperf', 'Delete Data Samples'),
582
            ],
583
            'webperf:settings' => [
584
                'label' => Craft::t('webperf', 'Settings'),
585
            ],
586
        ];
587
    }
588
}
589