Passed
Push — v4 ( 013176...bd2dd0 )
by Andrew
32:27 queued 13:30
created

Retour::installGlobalEventListeners()   F

Complexity

Conditions 19
Paths 1

Size

Total Lines 161
Code Lines 98

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 380

Importance

Changes 2
Bugs 0 Features 0
Metric Value
eloc 98
c 2
b 0
f 0
dl 0
loc 161
ccs 0
cts 127
cp 0
rs 3.6569
cc 19
nc 1
nop 0
crap 380

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
/**
3
 * Retour plugin for Craft CMS
4
 *
5
 * Retour allows you to intelligently redirect legacy URLs, so that you don't
6
 * lose SEO value when rebuilding & restructuring a website
7
 *
8
 * @link      https://nystudio107.com/
0 ignored issues
show
Coding Style introduced by
The tag in position 1 should be the @copyright tag
Loading history...
9
 * @copyright Copyright (c) 2018 nystudio107
0 ignored issues
show
Coding Style introduced by
@copyright tag must contain a year and the name of the copyright holder
Loading history...
10
 */
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...
11
12
namespace nystudio107\retour;
13
14
use Craft;
15
use craft\base\Element;
16
use craft\base\Model;
17
use craft\base\Plugin;
18
use craft\events\ElementEvent;
19
use craft\events\ExceptionEvent;
20
use craft\events\PluginEvent;
21
use craft\events\RegisterCacheOptionsEvent;
22
use craft\events\RegisterComponentTypesEvent;
23
use craft\events\RegisterGqlQueriesEvent;
24
use craft\events\RegisterGqlSchemaComponentsEvent;
25
use craft\events\RegisterGqlTypesEvent;
26
use craft\events\RegisterUrlRulesEvent;
27
use craft\events\RegisterUserPermissionsEvent;
28
use craft\helpers\ElementHelper;
29
use craft\helpers\UrlHelper;
30
use craft\services\Dashboard;
31
use craft\services\Elements;
32
use craft\services\Fields;
33
use craft\services\Gql;
34
use craft\services\Plugins;
35
use craft\services\UserPermissions;
36
use craft\utilities\ClearCaches;
37
use craft\web\ErrorHandler;
38
use craft\web\twig\variables\CraftVariable;
39
use craft\web\UrlManager;
40
use nystudio107\retour\fields\ShortLink as ShortLinkField;
41
use nystudio107\retour\gql\interfaces\RetourInterface;
42
use nystudio107\retour\gql\queries\RetourQuery;
43
use nystudio107\retour\models\Settings;
44
use nystudio107\retour\services\ServicesTrait;
45
use nystudio107\retour\variables\RetourVariable;
46
use nystudio107\retour\widgets\RetourWidget;
47
use Twig\Error\RuntimeError;
48
use yii\base\Event;
49
use yii\web\HttpException;
50
51
/** @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...
52
53
/**
54
 * Class Retour
55
 *
56
 * @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 for @author tag indented incorrectly; expected 2 spaces but found 4
Loading history...
57
 * @package   Retour
0 ignored issues
show
Coding Style introduced by
Tag value for @package tag indented incorrectly; expected 1 spaces but found 3
Loading history...
58
 * @since     3.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 for @since tag indented incorrectly; expected 3 spaces but found 5
Loading history...
59
 * @method Settings getSettings()
0 ignored issues
show
Coding Style introduced by
Tag value for @method tag indented incorrectly; expected 2 spaces but found 1
Loading history...
60
 */
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...
61
class Retour extends Plugin
62
{
63
    // Traits
64
    // =========================================================================
65
66
    use ServicesTrait;
67
68
    // Constants
69
    // =========================================================================
70
71
    public const DEVMODE_CACHE_DURATION = 30;
72
73
    // Static Properties
74
    // =========================================================================
75
76
    /**
0 ignored issues
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
77
     * @var Retour
78
     */
79
    public static ?Plugin $plugin = null;
80
81
    /**
0 ignored issues
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
82
     * @var ?Settings
83
     */
84
    public static ?Settings $settings = null;
85
86
    /**
0 ignored issues
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
87
     * @var int
88
     */
89
    public static int $cacheDuration = 0;
90
91
    /**
0 ignored issues
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
92
     * @var ?HttpException
93
     */
94
    public static ?HttpException $currentException = null;
95
96
    // Public Properties
97
    // =========================================================================
98
99
    /**
0 ignored issues
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
100
     * @var string
101
     */
102
    public string $schemaVersion = '3.0.12';
103
104
    /**
0 ignored issues
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
105
     * @var bool
106
     */
107
    public bool $hasCpSection = true;
108
109
    /**
0 ignored issues
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
110
     * @var bool
111
     */
112
    public bool $hasCpSettings = true;
113
114
    // Public Methods
115
    // =========================================================================
116
117
    /**
0 ignored issues
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
118
     * @inheritdoc
119
     */
0 ignored issues
show
Coding Style introduced by
Missing @return tag in function comment
Loading history...
120
    public function init(): void
121
    {
122
        parent::init();
123
        self::$plugin = $this;
124
        // Initialize properties
125
        self::$settings = $this->getSettings();
126
        $this->name = self::$settings->pluginName;
127
        self::$cacheDuration = Craft::$app->getConfig()->getGeneral()->devMode
128
            ? $this::DEVMODE_CACHE_DURATION
129
            : 0;
130
        // Handle any console commands
131
        $request = Craft::$app->getRequest();
132
        if ($request->getIsConsoleRequest()) {
133
            $this->controllerNamespace = 'nystudio107\retour\console\controllers';
134
        }
135
        // Install our event listeners
136
        $this->installEventListeners();
137
        // Log that Retour has been loaded
138
        Craft::info(
139
            Craft::t(
140
                'retour',
141
                '{name} plugin loaded',
142
                ['name' => $this->name]
143
            ),
144
            __METHOD__
145
        );
146
    }
147
148
    /**
149
     * Clear all the caches!
150
     */
0 ignored issues
show
Coding Style introduced by
Missing @return tag in function comment
Loading history...
151
    public function clearAllCaches(): void
152
    {
153
        // Clear all of Retour's caches
154
        self::$plugin->redirects->invalidateCaches();
0 ignored issues
show
Bug introduced by
The method invalidateCaches() does not exist on null. ( Ignorable by Annotation )

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

154
        self::$plugin->redirects->/** @scrutinizer ignore-call */ 
155
                                  invalidateCaches();

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
155
    }
156
157
    /**
0 ignored issues
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
158
     * @inheritdoc
159
     */
0 ignored issues
show
Coding Style introduced by
Missing @return tag in function comment
Loading history...
160
    public function getSettingsResponse(): mixed
161
    {
162
        // Just redirect to the plugin settings page
163
        return Craft::$app->getResponse()->redirect(UrlHelper::cpUrl('retour/settings'));
164
    }
165
166
    /**
0 ignored issues
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
167
     * @inheritdoc
168
     */
0 ignored issues
show
Coding Style introduced by
Missing @return tag in function comment
Loading history...
169
    public function getCpNavItem(): ?array
170
    {
171
        $subNavs = [];
172
        $navItem = parent::getCpNavItem();
173
        $currentUser = Craft::$app->getUser()->getIdentity();
174
        // Only show sub-navs the user has permission to view
175
        if ($currentUser->can('retour:dashboard')) {
0 ignored issues
show
Bug introduced by
The method can() does not exist on yii\web\IdentityInterface. It seems like you code against a sub-type of yii\web\IdentityInterface such as craft\elements\User. ( Ignorable by Annotation )

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

175
        if ($currentUser->/** @scrutinizer ignore-call */ can('retour:dashboard')) {
Loading history...
176
            $subNavs['dashboard'] = [
177
                'label' => 'Dashboard',
178
                'url' => 'retour/dashboard',
179
            ];
180
        }
181
        if ($currentUser->can('retour:redirects')) {
182
            $subNavs['redirects'] = [
183
                'label' => 'Redirects',
184
                'url' => 'retour/redirects',
185
            ];
186
        }
187
        if ($currentUser->can('retour:shortlinks')) {
188
            $subNavs['shortlinks'] = [
189
                'label' => 'Short Links',
190
                'url' => 'retour/shortlinks',
191
            ];
192
        }
193
        $editableSettings = true;
194
        $general = Craft::$app->getConfig()->getGeneral();
195
        if (!$general->allowAdminChanges) {
196
            $editableSettings = false;
197
        }
198
        if ($currentUser->can('retour:settings') && $editableSettings) {
199
            $subNavs['settings'] = [
200
                'label' => 'Settings',
201
                'url' => 'retour/settings',
202
            ];
203
        }
204
        // Retour doesn't really have an index page, so if the user can't access any sub nav items, we probably shouldn't show the main sub nav item either
205
        if (empty($subNavs)) {
206
            return null;
207
        }
208
        // A single sub nav item is redundant
209
        if (count($subNavs) === 1) {
210
            $subNavs = [];
211
        }
212
        $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...
213
            'subnav' => $subNavs,
214
        ]);
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...
215
216
        return $navItem;
217
    }
218
219
    // Protected Methods
220
    // =========================================================================
221
222
    /**
223
     * Install our event listeners.
224
     */
0 ignored issues
show
Coding Style introduced by
Missing @return tag in function comment
Loading history...
225
    protected function installEventListeners(): void
226
    {
227
        // Install our event listeners only if our table schema exists
228
        if ($this->tableSchemaExists()) {
229
            $request = Craft::$app->getRequest();
230
            // Add in our event listeners that are needed for every request
231
            $this->installGlobalEventListeners();
232
            // Install only for non-console site requests
233
            if ($request->getIsSiteRequest() && !$request->getIsConsoleRequest()) {
234
                $this->installSiteEventListeners();
235
            }
236
            // Install only for non-console Control Panel requests
237
            if ($request->getIsCpRequest() && !$request->getIsConsoleRequest()) {
238
                $this->installCpEventListeners();
239
            }
240
        }
241
        // Handler: ClearCaches::EVENT_REGISTER_CACHE_OPTIONS
242
        Event::on(
243
            ClearCaches::class,
244
            ClearCaches::EVENT_REGISTER_CACHE_OPTIONS,
245
            function(RegisterCacheOptionsEvent $event) {
0 ignored issues
show
Coding Style introduced by
Expected 1 space after FUNCTION keyword; 0 found
Loading history...
246
                Craft::debug(
247
                    'ClearCaches::EVENT_REGISTER_CACHE_OPTIONS',
248
                    __METHOD__
249
                );
250
                // Register our Control Panel routes
251
                $event->options = array_merge(
252
                    $event->options,
253
                    $this->customAdminCpCacheOptions()
254
                );
255
            }
256
        );
257
        // Handler: EVENT_AFTER_INSTALL_PLUGIN
258
        Event::on(
259
            Plugins::class,
260
            Plugins::EVENT_AFTER_INSTALL_PLUGIN,
261
            function(PluginEvent $event) {
0 ignored issues
show
Coding Style introduced by
Expected 1 space after FUNCTION keyword; 0 found
Loading history...
262
                if ($event->plugin === $this) {
0 ignored issues
show
introduced by
The condition $event->plugin === $this is always false.
Loading history...
263
                    // Invalidate our caches after we've been installed
264
                    $this->clearAllCaches();
265
                    // Send them to our welcome screen
266
                    $request = Craft::$app->getRequest();
267
                    if ($request->isCpRequest) {
268
                        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...
269
                            'retour/dashboard',
270
                            [
271
                                'showWelcome' => true,
272
                            ]
273
                        ))->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...
274
                    }
275
                }
276
            }
277
        );
278
    }
279
280
    /**
281
     * Determine whether our table schema exists or not; this is needed because
282
     * migrations such as the install migration and base_install migration may
283
     * not have been run by the time our init() method has been called
284
     *
285
     * @return bool
286
     */
287
    protected function tableSchemaExists(): bool
288
    {
289
        return (Craft::$app->db->schema->getTableSchema('{{%retour_redirects}}') !== null);
290
    }
291
292
    /**
293
     * Install global event listeners for all request types
294
     */
0 ignored issues
show
Coding Style introduced by
Missing @return tag in function comment
Loading history...
295
    protected function installGlobalEventListeners(): void
296
    {
297
        Event::on(
298
            CraftVariable::class,
299
            CraftVariable::EVENT_INIT,
300
            function(Event $event) {
0 ignored issues
show
Coding Style introduced by
Expected 1 space after FUNCTION keyword; 0 found
Loading history...
301
                /** @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...
302
                $variable = $event->sender;
303
                $variable->set('retour', [
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...
304
                    'class' => RetourVariable::class,
305
                    'viteService' => $this->vite,
306
                ]);
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...
307
            }
308
        );
309
310
        $prepareRedirectOnElementChange = function(ElementEvent $event) {
0 ignored issues
show
Coding Style introduced by
Expected 1 space after FUNCTION keyword; 0 found
Loading history...
311
            /** @var Element $element */
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...
312
            $element = $event->element;
313
            if (!$event->isNew && $element->getUrl() !== null && !$element->propagating) {
314
                $checkElementSlug = true;
315
                // If we're running Craft 3.2 or later, also check that isn't not a draft or revision
316
                if (ElementHelper::isDraftOrRevision($element)) {
317
                    $checkElementSlug = false;
318
                }
319
                // Only do this for elements that aren't new, pass $checkElementSlug, and the user
320
                // has turned on the setting
321
                if (self::$settings->createUriChangeRedirects && $checkElementSlug) {
322
                    // Make sure this isn't a transitioning temporary draft/revision and that it's
323
                    // not propagating to other sites
324
                    if (!str_contains($element->uri, '__temp_')) {
325
                        Retour::$plugin->events->stashElementUris($element);
0 ignored issues
show
Bug introduced by
The method stashElementUris() does not exist on null. ( Ignorable by Annotation )

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

325
                        Retour::$plugin->events->/** @scrutinizer ignore-call */ 
326
                                                 stashElementUris($element);

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
326
                    }
327
                }
328
            }
329
        };
330
331
        $insertRedirectOnElementChange = function(ElementEvent $event) {
0 ignored issues
show
Coding Style introduced by
Expected 1 space after FUNCTION keyword; 0 found
Loading history...
332
            /** @var Element $element */
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...
333
            $element = $event->element;
334
            if ($element !== null && !$event->isNew && $element->getUrl() !== null) {
335
                $checkElementSlug = true;
336
                if (ElementHelper::isDraftOrRevision($element)) {
337
                    $checkElementSlug = false;
338
                }
339
                if (self::$settings->createUriChangeRedirects && $checkElementSlug) {
340
                    Retour::$plugin->events->handleElementUriChange($element);
341
                }
342
            }
343
        };
344
345
        // Handler: Elements::EVENT_BEFORE_SAVE_ELEMENT
346
        Event::on(
347
            Elements::class,
348
            Elements::EVENT_BEFORE_SAVE_ELEMENT,
349
            static function(ElementEvent $event) use ($prepareRedirectOnElementChange) {
0 ignored issues
show
Coding Style introduced by
Expected 1 space after FUNCTION keyword; 0 found
Loading history...
350
                Craft::debug(
351
                    'Elements::EVENT_BEFORE_SAVE_ELEMENT',
352
                    __METHOD__
353
                );
354
                $prepareRedirectOnElementChange($event);
355
            }
356
        );
357
        // Handler: Elements::EVENT_AFTER_SAVE_ELEMENT
358
        Event::on(
359
            Elements::class,
360
            Elements::EVENT_AFTER_SAVE_ELEMENT,
361
            static function(ElementEvent $event) use ($insertRedirectOnElementChange) {
0 ignored issues
show
Coding Style introduced by
Expected 1 space after FUNCTION keyword; 0 found
Loading history...
362
                Craft::debug(
363
                    'Elements::EVENT_AFTER_SAVE_ELEMENT',
364
                    __METHOD__
365
                );
366
                $insertRedirectOnElementChange($event);
367
            }
368
        );
369
        // Handler: Elements::EVENT_BEFORE_UPDATE_SLUG_AND_URI
370
        Event::on(
371
            Elements::class,
372
            Elements::EVENT_BEFORE_UPDATE_SLUG_AND_URI,
373
            static function(ElementEvent $event) use ($prepareRedirectOnElementChange) {
0 ignored issues
show
Coding Style introduced by
Expected 1 space after FUNCTION keyword; 0 found
Loading history...
374
                Craft::debug(
375
                    'Elements::EVENT_BEFORE_UPDATE_SLUG_AND_URI',
376
                    __METHOD__
377
                );
378
                $prepareRedirectOnElementChange($event);
379
            }
380
        );
381
        // Handler: Elements::EVENT_AFTER_UPDATE_SLUG_AND_URI
382
        Event::on(
383
            Elements::class,
384
            Elements::EVENT_AFTER_UPDATE_SLUG_AND_URI,
385
            static function(ElementEvent $event) use ($insertRedirectOnElementChange) {
0 ignored issues
show
Coding Style introduced by
Expected 1 space after FUNCTION keyword; 0 found
Loading history...
386
                Craft::debug(
387
                    'Elements::EVENT_AFTER_UPDATE_SLUG_AND_URI',
388
                    __METHOD__
389
                );
390
                $insertRedirectOnElementChange($event);
391
            }
392
        );
393
        // Handler: Plugins::EVENT_AFTER_LOAD_PLUGINS
394
        Event::on(
395
            Plugins::class,
396
            Plugins::EVENT_AFTER_LOAD_PLUGINS,
397
            function() {
0 ignored issues
show
Coding Style introduced by
Expected 1 space after FUNCTION keyword; 0 found
Loading history...
398
                // Install these only after all other plugins have loaded
399
                $request = Craft::$app->getRequest();
400
                // Only respond to non-console site requests
401
                if ($request->getIsSiteRequest() && !$request->getIsConsoleRequest()) {
402
                    $this->handleSiteRequest();
403
                }
404
                // Respond to Control Panel requests
405
                if ($request->getIsCpRequest() && !$request->getIsConsoleRequest()) {
406
                    $this->handleAdminCpRequest();
407
                }
408
            }
409
        );
410
        // Handler: Fields::EVENT_REGISTER_FIELD_TYPES
411
        Event::on(
412
            Fields::class,
413
            Fields::EVENT_REGISTER_FIELD_TYPES,
414
            function(RegisterComponentTypesEvent $event) {
0 ignored issues
show
Coding Style introduced by
Expected 1 space after FUNCTION keyword; 0 found
Loading history...
415
                $event->types[] = ShortLinkField::class;
416
            }
417
        );
418
        // Handler: Gql::EVENT_REGISTER_GQL_TYPES
419
        Event::on(
420
            Gql::class,
421
            Gql::EVENT_REGISTER_GQL_TYPES,
422
            static function(RegisterGqlTypesEvent $event) {
0 ignored issues
show
Coding Style introduced by
Expected 1 space after FUNCTION keyword; 0 found
Loading history...
423
                Craft::debug(
424
                    'Gql::EVENT_REGISTER_GQL_TYPES',
425
                    __METHOD__
426
                );
427
                $event->types[] = RetourInterface::class;
428
            }
429
        );
430
        // Handler: Gql::EVENT_REGISTER_GQL_QUERIES
431
        Event::on(
432
            Gql::class,
433
            Gql::EVENT_REGISTER_GQL_QUERIES,
434
            static function(RegisterGqlQueriesEvent $event) {
0 ignored issues
show
Coding Style introduced by
Expected 1 space after FUNCTION keyword; 0 found
Loading history...
435
                Craft::debug(
436
                    'Gql::EVENT_REGISTER_GQL_QUERIES',
437
                    __METHOD__
438
                );
439
                $queries = RetourQuery::getQueries();
440
                foreach ($queries as $key => $value) {
441
                    $event->queries[$key] = $value;
442
                }
443
            }
444
        );
445
        // Handler: Gql::EVENT_REGISTER_SCHEMA_COMPONENTS
446
        Event::on(
447
            Gql::class,
448
            Gql::EVENT_REGISTER_GQL_SCHEMA_COMPONENTS,
449
            static function(RegisterGqlSchemaComponentsEvent $event) {
0 ignored issues
show
Coding Style introduced by
Expected 1 space after FUNCTION keyword; 0 found
Loading history...
450
                Craft::debug(
451
                    'Gql::EVENT_REGISTER_GQL_SCHEMA_COMPONENTS',
452
                    __METHOD__
453
                );
454
                $label = Craft::t('retour', 'Retour');
455
                $event->queries[$label]['retour.all:read'] = ['label' => Craft::t('retour', 'Query Retour data')];
456
            }
457
        );
458
    }
459
460
    /**
461
     * Handle site requests.  We do it only after we receive the event
462
     * EVENT_AFTER_LOAD_PLUGINS so that any pending db migrations can be run
463
     * before our event listeners kick in
464
     */
0 ignored issues
show
Coding Style introduced by
Missing @return tag in function comment
Loading history...
465
    protected function handleSiteRequest(): void
466
    {
467
        // Handler: ErrorHandler::EVENT_BEFORE_HANDLE_EXCEPTION
468
        Event::on(
469
            ErrorHandler::class,
470
            ErrorHandler::EVENT_BEFORE_HANDLE_EXCEPTION,
471
            static function(ExceptionEvent $event) {
0 ignored issues
show
Coding Style introduced by
Expected 1 space after FUNCTION keyword; 0 found
Loading history...
472
                Craft::debug(
473
                    'ErrorHandler::EVENT_BEFORE_HANDLE_EXCEPTION',
474
                    __METHOD__
475
                );
476
                $exception = $event->exception;
477
                // If this is a Twig Runtime exception, use the previous one instead
478
                if ($exception instanceof RuntimeError &&
479
                    ($previousException = $exception->getPrevious()) !== null) {
0 ignored issues
show
Coding Style introduced by
Each line in a multi-line IF statement must begin with a boolean operator
Loading history...
Coding Style introduced by
Closing parenthesis of a multi-line IF statement must be on a new line
Loading history...
480
                    $exception = $previousException;
481
                }
482
                // If this is a 404 error, see if we can handle it
483
                if ($exception instanceof HttpException && $exception->statusCode === 404) {
484
                    self::$currentException = $exception;
485
                    Retour::$plugin->redirects->handle404();
0 ignored issues
show
Bug introduced by
The method handle404() does not exist on null. ( Ignorable by Annotation )

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

485
                    Retour::$plugin->redirects->/** @scrutinizer ignore-call */ 
486
                                                handle404();

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
486
                }
487
            }
488
        );
489
    }
490
491
    /**
492
     * Handle Control Panel requests. We do it only after we receive the event
493
     * EVENT_AFTER_LOAD_PLUGINS so that any pending db migrations can be run
494
     * before our event listeners kick in
495
     */
0 ignored issues
show
Coding Style introduced by
Missing @return tag in function comment
Loading history...
496
    protected function handleAdminCpRequest(): void
497
    {
498
    }
499
500
    /**
501
     * Install site event listeners for site requests only
502
     */
0 ignored issues
show
Coding Style introduced by
Missing @return tag in function comment
Loading history...
503
    protected function installSiteEventListeners(): void
504
    {
505
        // Handler: UrlManager::EVENT_REGISTER_SITE_URL_RULES
506
        Event::on(
507
            UrlManager::class,
508
            UrlManager::EVENT_REGISTER_SITE_URL_RULES,
509
            function(RegisterUrlRulesEvent $event) {
0 ignored issues
show
Coding Style introduced by
Expected 1 space after FUNCTION keyword; 0 found
Loading history...
510
                Craft::debug(
511
                    'UrlManager::EVENT_REGISTER_SITE_URL_RULES',
512
                    __METHOD__
513
                );
514
                // Register our Control Panel routes
515
                $event->rules = array_merge(
516
                    $event->rules,
517
                    $this->customFrontendRoutes()
518
                );
519
            }
520
        );
521
    }
522
523
    /**
524
     * Return the custom frontend routes
525
     *
526
     * @return array
527
     */
528
    protected function customFrontendRoutes(): array
529
    {
530
        return [
531
        ];
532
    }
533
534
    /**
535
     * Install site event listeners for Control Panel requests only
536
     */
0 ignored issues
show
Coding Style introduced by
Missing @return tag in function comment
Loading history...
537
    protected function installCpEventListeners(): void
538
    {
539
        // Handler: Dashboard::EVENT_REGISTER_WIDGET_TYPES
540
        Event::on(
541
            Dashboard::class,
542
            Dashboard::EVENT_REGISTER_WIDGET_TYPES,
543
            function(RegisterComponentTypesEvent $event) {
0 ignored issues
show
Coding Style introduced by
Expected 1 space after FUNCTION keyword; 0 found
Loading history...
544
                $currentUser = Craft::$app->getUser()->getIdentity();
545
                if ($currentUser->can('accessPlugin-retour')) {
546
                    $event->types[] = RetourWidget::class;
547
                }
548
            }
549
        );
550
        // Handler: UrlManager::EVENT_REGISTER_CP_URL_RULES
551
        Event::on(
552
            UrlManager::class,
553
            UrlManager::EVENT_REGISTER_CP_URL_RULES,
554
            function(RegisterUrlRulesEvent $event) {
0 ignored issues
show
Coding Style introduced by
Expected 1 space after FUNCTION keyword; 0 found
Loading history...
555
                Craft::debug(
556
                    'UrlManager::EVENT_REGISTER_CP_URL_RULES',
557
                    __METHOD__
558
                );
559
                // Register our Control Panel routes
560
                $event->rules = array_merge(
561
                    $event->rules,
562
                    $this->customAdminCpRoutes()
563
                );
564
            }
565
        );
566
        // Handler: UserPermissions::EVENT_REGISTER_PERMISSIONS
567
        Event::on(
568
            UserPermissions::class,
569
            UserPermissions::EVENT_REGISTER_PERMISSIONS,
570
            function(RegisterUserPermissionsEvent $event) {
0 ignored issues
show
Coding Style introduced by
Expected 1 space after FUNCTION keyword; 0 found
Loading history...
571
                Craft::debug(
572
                    'UserPermissions::EVENT_REGISTER_PERMISSIONS',
573
                    __METHOD__
574
                );
575
                // Register our custom permissions
576
                $event->permissions[] = [
577
                    'heading' => Craft::t('retour', 'Retour'),
578
                    'permissions' => $this->customAdminCpPermissions(),
579
                ];
580
            }
581
        );
582
    }
583
584
    /**
585
     * Return the custom Control Panel routes
586
     *
587
     * @return array
588
     */
589
    protected function customAdminCpRoutes(): array
590
    {
591
        return [
592
            'retour' => '',
593
594
            'retour/redirects' => 'retour/redirects/redirects',
595
            'retour/redirects/<siteHandle:{handle}>' => 'retour/redirects/redirects',
596
597
            'retour/edit-redirect/<redirectId:\d+>' => 'retour/redirects/edit-redirect',
598
599
            'retour/add-redirect' => 'retour/redirects/edit-redirect',
600
            'retour/add-redirect/<siteId:\d+>' => 'retour/redirects/edit-redirect',
601
602
            'retour/dashboard' => 'retour/statistics/dashboard',
603
            'retour/dashboard/<siteHandle:{handle}>' => 'retour/statistics/dashboard',
604
605
            'retour/shortlinks' => 'retour/redirects/shortlinks',
606
            'retour/shortlinks/<siteHandle:{handle}>' => 'retour/redirects/shortlinks',
607
608
            'retour/settings' => 'retour/settings/plugin-settings',
609
        ];
610
    }
611
612
    /**
613
     * Returns the custom Control Panel user permissions.
614
     *
615
     * @return array
616
     */
617
    protected function customAdminCpPermissions(): array
618
    {
619
        return [
620
            'retour:dashboard' => [
621
                'label' => Craft::t('retour', 'Dashboard'),
622
            ],
623
            'retour:redirects' => [
624
                'label' => Craft::t('retour', 'Redirects'),
625
            ],
626
            'retour:shortlinks' => [
627
                'label' => Craft::t('retour', 'Short Links'),
628
            ],
629
            'retour:settings' => [
630
                'label' => Craft::t('retour', 'Settings'),
631
            ],
632
        ];
633
    }
634
635
    /**
636
     * Returns the custom Control Panel cache options.
637
     *
638
     * @return array
639
     */
640
    protected function customAdminCpCacheOptions(): array
641
    {
642
        return [
643
            [
644
                'key' => 'retour-redirect-caches',
645
                'label' => Craft::t('retour', 'Retour redirect caches'),
646
                'action' => [self::$plugin->redirects, 'invalidateCaches'],
647
            ],
648
        ];
649
    }
650
651
    /**
0 ignored issues
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
652
     * @inheritdoc
653
     */
0 ignored issues
show
Coding Style introduced by
Missing @return tag in function comment
Loading history...
654
    protected function createSettingsModel(): ?Model
655
    {
656
        return new Settings();
657
    }
658
}
659