Passed
Push — develop ( 5e1c96...396370 )
by Andrew
04:41
created

ImageOptimize   B

Complexity

Total Complexity 48

Size/Duplication

Total Lines 545
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
wmc 48
eloc 252
dl 0
loc 545
rs 8.5599
c 0
b 0
f 0

15 Methods

Rating   Name   Duplication   Size   Complexity  
A init() 0 23 2
A createSettingsModel() 0 3 1
A settingsHtml() 0 39 5
A installElementEventHandlers() 0 44 4
A customFrontendRoutes() 0 3 1
A installCpEventListeners() 0 19 3
A setImageTransformComponent() 0 13 2
A installCraftQLEventHandlers() 0 7 2
B installMiscEventHandlers() 0 68 10
A installSiteEventListeners() 0 15 1
B installAssetEventHandlers() 0 101 3
A installEventHandlers() 0 14 5
A getSettingsResponse() 0 13 1
A addComponents() 0 23 1
B checkForOptimizedImagesField() 0 21 7

How to fix   Complexity   

Complex Class

Complex classes like ImageOptimize often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use ImageOptimize, and based on these observations, apply Extract Interface, too.

1
<?php
2
/**
3
 * ImageOptimize plugin for Craft CMS 3.x
4
 *
5
 * Automatically optimize images after they've been transformed
6
 *
7
 * @link      https://nystudio107.com
0 ignored issues
show
Coding Style introduced by
The tag in position 1 should be the @copyright tag
Loading history...
8
 * @copyright Copyright (c) 2017 nystudio107
0 ignored issues
show
Coding Style introduced by
@copyright tag must contain a year and the name of the copyright holder
Loading history...
9
 */
0 ignored issues
show
Coding Style introduced by
PHP version not specified
Loading history...
Coding Style introduced by
Missing @category tag in file comment
Loading history...
Coding Style introduced by
Missing @package tag in file comment
Loading history...
Coding Style introduced by
Missing @author tag in file comment
Loading history...
Coding Style introduced by
Missing @license tag in file comment
Loading history...
10
11
namespace nystudio107\imageoptimize;
12
13
use nystudio107\imageoptimize\fields\OptimizedImages;
14
use nystudio107\imageoptimize\imagetransforms\ImageTransformInterface;
15
use nystudio107\imageoptimize\listeners\GetCraftQLSchema;
16
use nystudio107\imageoptimize\models\Settings;
17
use nystudio107\imageoptimize\services\Optimize as OptimizeService;
18
use nystudio107\imageoptimize\services\OptimizedImages as OptimizedImagesService;
19
use nystudio107\imageoptimize\services\Placeholder as PlaceholderService;
20
use nystudio107\imageoptimize\variables\ImageOptimizeVariable;
21
22
use Craft;
23
use craft\base\Field;
24
use craft\base\Plugin;
25
use craft\base\Volume;
26
use craft\elements\Asset;
27
use craft\events\AssetTransformImageEvent;
28
use craft\events\ElementEvent;
29
use craft\events\FieldEvent;
30
use craft\events\GetAssetThumbUrlEvent;
31
use craft\events\GetAssetUrlEvent;
32
use craft\events\GenerateTransformEvent;
33
use craft\events\PluginEvent;
34
use craft\events\RegisterComponentTypesEvent;
35
use craft\events\RegisterTemplateRootsEvent;
36
use craft\events\RegisterUrlRulesEvent;
37
use craft\events\ReplaceAssetEvent;
38
use craft\events\VolumeEvent;
39
use craft\helpers\ArrayHelper;
40
use craft\helpers\UrlHelper;
41
use craft\models\FieldLayout;
42
use craft\services\Assets;
43
use craft\services\AssetTransforms;
44
use craft\services\Elements;
45
use craft\services\Fields;
46
use craft\services\Plugins;
47
use craft\services\Volumes;
48
use craft\web\twig\variables\CraftVariable;
49
use craft\web\Controller;
50
use craft\web\UrlManager;
51
use craft\web\View;
52
53
use markhuot\CraftQL\CraftQL;
0 ignored issues
show
Bug introduced by
The type markhuot\CraftQL\CraftQL 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...
54
55
use yii\base\Event;
56
use yii\base\Exception;
57
use yii\base\InvalidConfigException;
58
59
/** @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...
60
61
/**
62
 * Class ImageOptimize
63
 *
64
 * @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...
65
 * @package   ImageOptimize
0 ignored issues
show
Coding Style introduced by
Tag value indented incorrectly; expected 1 spaces but found 3
Loading history...
66
 * @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...
67
 *
68
 * @property OptimizeService         optimize
69
 * @property PlaceholderService      placeholder
70
 * @property OptimizedImagesService  optimizedImages
71
 * @property ImageTransformInterface transformMethod
72
 * @property Settings                $settings
73
 * @method   Settings                getSettings()
74
 */
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...
75
class ImageOptimize extends Plugin
76
{
77
78
    // Constants
79
    // =========================================================================
80
81
    const CRAFTQL_PLUGIN_HANDLE = 'craftql';
82
83
    // Static Properties
84
    // =========================================================================
85
86
    /**
0 ignored issues
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
87
     * @var ImageOptimize
88
     */
89
    public static $plugin;
90
91
    /**
0 ignored issues
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
92
     * @var array
93
     */
94
    public static $transformParams = [];
95
96
    /**
0 ignored issues
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
97
     * @var bool
98
     */
99
    public static $generatePlaceholders = true;
100
101
    // Public Methods
102
    // =========================================================================
103
104
    /**
0 ignored issues
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
105
     * @inheritdoc
106
     */
0 ignored issues
show
Coding Style introduced by
Missing @return tag in function comment
Loading history...
107
    public function init()
108
    {
109
        parent::init();
110
        self::$plugin = $this;
111
        // Handle any console commands
112
        $request = Craft::$app->getRequest();
113
        if ($request->getIsConsoleRequest()) {
114
            $this->controllerNamespace = 'nystudio107\imageoptimize\console\controllers';
115
        }
116
        // Set the image transform component
117
        $this->setImageTransformComponent();
118
        // Add in our Craft components
119
        $this->addComponents();
120
        // Install our global event handlers
121
        $this->installEventHandlers();
122
        // Log that the plugin has loaded
123
        Craft::info(
124
            Craft::t(
125
                'image-optimize',
126
                '{name} plugin loaded',
127
                ['name' => $this->name]
128
            ),
129
            __METHOD__
130
        );
131
    }
132
133
    /**
0 ignored issues
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
134
     * @inheritdoc
135
     */
0 ignored issues
show
Coding Style introduced by
Missing @return tag in function comment
Loading history...
136
    public function getSettingsResponse()
137
    {
138
        $view = Craft::$app->getView();
139
        $namespace = $view->getNamespace();
140
        $view->setNamespace('settings');
141
        $settingsHtml = $this->settingsHtml();
142
        $view->setNamespace($namespace);
143
        /** @var Controller $controller */
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...
144
        $controller = Craft::$app->controller;
0 ignored issues
show
Documentation Bug introduced by
It seems like Craft::app->controller can also be of type yii\web\Controller. However, the property $controller is declared as type yii\console\Controller. Maybe add an additional type check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.

For example, imagine you have a variable $accountId that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to the id property of an instance of the Account class. This class holds a proper account, so the id value must no longer be false.

Either this assignment is in error or a type check should be added for that assignment.

class Id
{
    public $id;

    public function __construct($id)
    {
        $this->id = $id;
    }

}

class Account
{
    /** @var  Id $id */
    public $id;
}

$account_id = false;

if (starsAreRight()) {
    $account_id = new Id(42);
}

$account = new Account();
if ($account instanceof Id)
{
    $account->id = $account_id;
}
Loading history...
145
146
        return $controller->renderTemplate('image-optimize/settings/index.twig', [
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...
147
            'plugin'       => $this,
148
            'settingsHtml' => $settingsHtml,
149
        ]);
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...
150
    }
151
152
    /**
0 ignored issues
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
153
     * @inheritdoc
154
     */
0 ignored issues
show
Coding Style introduced by
Missing @return tag in function comment
Loading history...
155
    public function settingsHtml()
156
    {
157
        // Get only the user-editable settings
158
        $settings = $this->getSettings();
159
160
        // Get the image transform types
161
        $allImageTransformTypes = ImageOptimize::$plugin->optimize->getAllImageTransformTypes();
162
        $imageTransformTypeOptions = [];
163
        /** @var ImageTransformInterface $class */
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...
164
        foreach ($allImageTransformTypes as $class) {
165
            if ($class::isSelectable()) {
166
                $imageTransformTypeOptions[] = [
167
                    'value' => $class,
168
                    'label' => $class::displayName(),
169
                ];
170
            }
171
        }
172
        // Sort them by name
173
        ArrayHelper::multisort($imageTransformTypeOptions, 'label');
174
175
        // Render the settings template
176
        try {
177
            return Craft::$app->getView()->renderTemplate(
178
                'image-optimize/settings/_settings.twig',
179
                [
180
                    'settings'        => $settings,
181
                    'gdInstalled'     => \function_exists('imagecreatefromjpeg'),
182
                    'imageTransformTypeOptions' => $imageTransformTypeOptions,
183
                    'allImageTransformTypes' => $allImageTransformTypes,
184
                    'imageTransform' => ImageOptimize::$plugin->transformMethod,
185
                ]
186
            );
187
        } catch (\Twig_Error_Loader $e) {
188
            Craft::error($e->getMessage(), __METHOD__);
189
        } catch (Exception $e) {
190
            Craft::error($e->getMessage(), __METHOD__);
191
        }
192
193
        return '';
194
    }
195
196
    // Protected Methods
197
    // =========================================================================
198
199
    /**
0 ignored issues
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
200
     * @inheritdoc
201
     */
0 ignored issues
show
Coding Style introduced by
Missing @return tag in function comment
Loading history...
202
    protected function createSettingsModel()
203
    {
204
        return new Settings();
205
    }
206
207
    /**
208
     * Set the transformMethod component
209
     */
0 ignored issues
show
Coding Style introduced by
Missing @return tag in function comment
Loading history...
210
    protected function setImageTransformComponent()
211
    {
212
        $settings = $this->getSettings();
213
        $definition = array_merge(
214
            $settings->imageTransformTypeSettings[$settings->transformClass] ?? [],
215
            ['class' => $settings->transformClass]
216
        );
217
        try {
218
            $this->set('transformMethod', $definition);
219
        } catch (InvalidConfigException $e) {
220
            Craft::error($e->getMessage(), __METHOD__);
221
        }
222
        self::$transformParams = ImageOptimize::$plugin->transformMethod->getTransformParams();
223
    }
224
225
    /**
226
     * Add in our Craft components
227
     */
0 ignored issues
show
Coding Style introduced by
Missing @return tag in function comment
Loading history...
228
    protected function addComponents()
229
    {
230
        // Register our variables
231
        Event::on(
232
            CraftVariable::class,
233
            CraftVariable::EVENT_INIT,
234
            function (Event $event) {
235
                /** @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...
236
                $variable = $event->sender;
237
                $variable->set('imageOptimize', ImageOptimizeVariable::class);
238
            }
239
        );
240
241
        // Register our Field
242
        Event::on(
243
            Fields::class,
244
            Fields::EVENT_REGISTER_FIELD_TYPES,
245
            function (RegisterComponentTypesEvent $event) {
246
                Craft::debug(
247
                    'Fields::EVENT_REGISTER_FIELD_TYPES',
248
                    __METHOD__
249
                );
250
                $event->types[] = OptimizedImages::class;
251
            }
252
        );
253
    }
254
255
    /**
256
     * Install our event handlers
257
     */
0 ignored issues
show
Coding Style introduced by
Missing @return tag in function comment
Loading history...
258
    protected function installEventHandlers()
259
    {
260
        $this->installAssetEventHandlers();
261
        $this->installElementEventHandlers();
262
        $this->installMiscEventHandlers();
263
        $this->installCraftQLEventHandlers();
264
        $request = Craft::$app->getRequest();
265
        // Install only for non-console site requests
266
        if ($request->getIsSiteRequest() && !$request->getIsConsoleRequest()) {
267
            $this->installSiteEventListeners();
268
        }
269
        // Install only for non-console cp requests
270
        if ($request->getIsCpRequest() && !$request->getIsConsoleRequest()) {
271
            $this->installCpEventListeners();
272
        }
273
    }
274
275
    /**
276
     * Install our Asset event handlers
277
     */
0 ignored issues
show
Coding Style introduced by
Missing @return tag in function comment
Loading history...
278
    protected function installAssetEventHandlers()
279
    {
280
        // Handler: Assets::EVENT_GET_ASSET_URL
281
        Event::on(
282
            Assets::class,
283
            Assets::EVENT_GET_ASSET_URL,
284
            function (GetAssetUrlEvent $event) {
285
                Craft::debug(
286
                    'Assets::EVENT_GET_ASSET_URL',
287
                    __METHOD__
288
                );
289
                // Return the URL to the asset URL or null to let Craft handle it
290
                $event->url = ImageOptimize::$plugin->optimize->handleGetAssetUrlEvent(
291
                    $event
292
                );
293
            }
294
        );
295
296
        // Handler: Assets::EVENT_GET_ASSET_THUMB_URL
297
        Event::on(
298
            Assets::class,
299
            Assets::EVENT_GET_ASSET_THUMB_URL,
300
            function (GetAssetThumbUrlEvent $event) {
301
                Craft::debug(
302
                    'Assets::EVENT_GET_ASSET_THUMB_URL',
303
                    __METHOD__
304
                );
305
                // Return the URL to the asset URL or null to let Craft handle it
306
                $event->url = ImageOptimize::$plugin->optimize->handleGetAssetThumbUrlEvent(
307
                    $event
308
                );
309
            }
310
        );
311
312
        // Handler: AssetTransforms::EVENT_GENERATE_TRANSFORM
313
        Event::on(
314
            AssetTransforms::class,
315
            AssetTransforms::EVENT_GENERATE_TRANSFORM,
316
            function (GenerateTransformEvent $event) {
317
                Craft::debug(
318
                    'AssetTransforms::EVENT_GENERATE_TRANSFORM',
319
                    __METHOD__
320
                );
321
                // Return the path to the optimized image to _createTransformForAsset()
322
                $event->tempPath = ImageOptimize::$plugin->optimize->handleGenerateTransformEvent(
323
                    $event
324
                );
325
            }
326
        );
327
328
        // Handler: AssetTransforms::EVENT_AFTER_DELETE_TRANSFORMS
329
        Event::on(
330
            AssetTransforms::class,
331
            AssetTransforms::EVENT_AFTER_DELETE_TRANSFORMS,
332
            function (AssetTransformImageEvent $event) {
333
                Craft::debug(
334
                    'AssetTransforms::EVENT_AFTER_DELETE_TRANSFORMS',
335
                    __METHOD__
336
                );
337
                // Clean up any stray variant files
338
                ImageOptimize::$plugin->optimize->handleAfterDeleteTransformsEvent(
339
                    $event
340
                );
341
            }
342
        );
343
344
        // Handler: Assets::EVENT_BEFORE_REPLACE_ASSET
345
        Event::on(
346
            Assets::class,
347
            Assets::EVENT_BEFORE_REPLACE_ASSET,
348
            function (ReplaceAssetEvent $event) {
349
                Craft::debug(
350
                    'Assets::EVENT_BEFORE_REPLACE_ASSET',
351
                    __METHOD__
352
                );
353
                /** @var Asset $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...
354
                $element = $event->asset;
355
                // Purge the URL
356
                $purgeUrl = ImageOptimize::$plugin->transformMethod->getPurgeUrl(
357
                    $element,
358
                    ImageOptimize::$transformParams
359
                );
360
                if ($purgeUrl) {
361
                    ImageOptimize::$plugin->transformMethod->purgeUrl($purgeUrl, ImageOptimize::$transformParams);
362
                }
363
            }
364
        );
365
366
        // Handler: Assets::EVENT_AFTER_REPLACE_ASSET
367
        Event::on(
368
            Assets::class,
369
            Assets::EVENT_AFTER_REPLACE_ASSET,
370
            function (ReplaceAssetEvent $event) {
371
                Craft::debug(
372
                    'Assets::EVENT_AFTER_REPLACE_ASSET',
373
                    __METHOD__
374
                );
375
                /** @var Asset $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...
376
                $element = $event->asset;
377
                if ($element->id !== null) {
378
                    ImageOptimize::$plugin->optimizedImages->resaveAsset($element->id);
379
                }
380
            }
381
        );
382
    }
383
384
    /**
385
     * Install our Element event handlers
386
     */
0 ignored issues
show
Coding Style introduced by
Missing @return tag in function comment
Loading history...
387
    protected function installElementEventHandlers()
388
    {
389
        // Handler: Elements::EVENT_BEFORE_SAVE_ELEMENT
390
        Event::on(
391
            Assets::class,
392
            Elements::EVENT_BEFORE_SAVE_ELEMENT,
393
            function (ElementEvent $event) {
394
                Craft::debug(
395
                    'Elements::EVENT_BEFORE_SAVE_ELEMENT',
396
                    __METHOD__
397
                );
398
                /** @var Asset $asset */
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...
399
                $asset = $event->element;
400
                if (!$event->isNew) {
401
                    // Purge the URL
402
                    $purgeUrl = ImageOptimize::$plugin->transformMethod->getPurgeUrl(
403
                        $asset,
404
                        ImageOptimize::$transformParams
405
                    );
406
                    if ($purgeUrl) {
407
                        ImageOptimize::$plugin->transformMethod->purgeUrl($purgeUrl, ImageOptimize::$transformParams);
408
                    }
409
                }
410
            }
411
        );
412
413
        // Handler: Elements::EVENT_BEFORE_DELETE_ELEMENT
414
        Event::on(
415
            Asset::class,
416
            Elements::EVENT_BEFORE_DELETE_ELEMENT,
417
            function (ElementEvent $event) {
418
                Craft::debug(
419
                    'Elements::EVENT_BEFORE_DELETE_ELEMENT',
420
                    __METHOD__
421
                );
422
                /** @var Asset $asset */
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...
423
                $asset = $event->element;
424
                // Purge the URL
425
                $purgeUrl = ImageOptimize::$plugin->transformMethod->getPurgeUrl(
426
                    $asset,
427
                    ImageOptimize::$transformParams
428
                );
429
                if ($purgeUrl) {
430
                    ImageOptimize::$plugin->transformMethod->purgeUrl($purgeUrl, ImageOptimize::$transformParams);
431
                }
432
            }
433
        );
434
    }
435
436
    /**
437
     * Install our miscellaneous event handlers
438
     */
0 ignored issues
show
Coding Style introduced by
Missing @return tag in function comment
Loading history...
439
    protected function installMiscEventHandlers()
440
    {
441
        // Handler: Fields::EVENT_AFTER_SAVE_FIELD
442
        Event::on(
443
            Fields::class,
444
            Fields::EVENT_AFTER_SAVE_FIELD,
445
            function (FieldEvent $event) {
446
                Craft::debug(
447
                    'Fields::EVENT_AFTER_SAVE_FIELD',
448
                    __METHOD__
449
                );
450
                $settings = $this->getSettings();
451
                /** @var Field $field */
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...
452
                if (!$event->isNew && $settings->automaticallyResaveImageVariants) {
453
                    $this->checkForOptimizedImagesField($event);
454
                }
455
            }
456
        );
457
458
        // Handler: Plugins::EVENT_AFTER_SAVE_PLUGIN_SETTINGS
459
        Event::on(
460
            Plugins::class,
461
            Plugins::EVENT_AFTER_SAVE_PLUGIN_SETTINGS,
462
            function (PluginEvent $event) {
463
                if ($event->plugin === $this) {
464
                    Craft::debug(
465
                        'Plugins::EVENT_AFTER_SAVE_PLUGIN_SETTINGS',
466
                        __METHOD__
467
                    );
468
                    $settings = $this->getSettings();
469
                    if ($settings->automaticallyResaveImageVariants) {
470
                        // After they have changed the settings, resave all of the assets
471
                        ImageOptimize::$plugin->optimizedImages->resaveAllVolumesAssets();
472
                    }
473
                }
474
            }
475
        );
476
477
        // Handler: Volumes::EVENT_AFTER_SAVE_VOLUME
478
        Event::on(
479
            Volumes::class,
480
            Volumes::EVENT_AFTER_SAVE_VOLUME,
481
            function (VolumeEvent $event) {
482
                Craft::debug(
483
                    'Volumes::EVENT_AFTER_SAVE_VOLUME',
484
                    __METHOD__
485
                );
486
                $settings = $this->getSettings();
487
                // Only worry about this volume if it's not new
488
                if (!$event->isNew && $settings->automaticallyResaveImageVariants) {
489
                    /** @var Volume $volume */
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...
490
                    $volume = $event->volume;
491
                    if ($volume !== null) {
492
                        ImageOptimize::$plugin->optimizedImages->resaveVolumeAssets($volume);
493
                    }
494
                }
495
            }
496
        );
497
498
        // Handler: Plugins::EVENT_AFTER_INSTALL_PLUGIN
499
        Event::on(
500
            Plugins::class,
501
            Plugins::EVENT_AFTER_INSTALL_PLUGIN,
502
            function (PluginEvent $event) {
503
                if ($event->plugin === $this) {
504
                    $request = Craft::$app->getRequest();
505
                    if ($request->isCpRequest) {
506
                        Craft::$app->getResponse()->redirect(UrlHelper::cpUrl('image-optimize/welcome'))->send();
507
                    }
508
                }
509
            }
510
        );
511
    }
512
513
    /**
514
     * Install our CraftQL event handlers
515
     */
0 ignored issues
show
Coding Style introduced by
Missing @return tag in function comment
Loading history...
516
    protected function installCraftQLEventHandlers()
517
    {
518
        if (class_exists(CraftQL::class)) {
519
            Event::on(
520
                OptimizedImages::class,
521
                GetCraftQLSchema::EVENT_GET_FIELD_SCHEMA,
522
                [new GetCraftQLSchema, 'handle']
523
            );
524
        }
525
    }
526
527
    /**
528
     * Install site event listeners for site requests only
529
     */
0 ignored issues
show
Coding Style introduced by
Missing @return tag in function comment
Loading history...
530
    protected function installSiteEventListeners()
531
    {
532
        // Handler: UrlManager::EVENT_REGISTER_SITE_URL_RULES
533
        Event::on(
534
            UrlManager::class,
535
            UrlManager::EVENT_REGISTER_SITE_URL_RULES,
536
            function (RegisterUrlRulesEvent $event) {
537
                Craft::debug(
538
                    'UrlManager::EVENT_REGISTER_SITE_URL_RULES',
539
                    __METHOD__
540
                );
541
                // Register our Control Panel routes
542
                $event->rules = array_merge(
543
                    $event->rules,
544
                    $this->customFrontendRoutes()
545
                );
546
            }
547
        );
548
    }
549
550
    /**
551
     * Install site event listeners for cp requests only
552
     */
0 ignored issues
show
Coding Style introduced by
Missing @return tag in function comment
Loading history...
553
    protected function installCpEventListeners()
554
    {
555
        // Handler: Plugins::EVENT_AFTER_LOAD_PLUGINS
556
        Event::on(
557
            Plugins::class,
558
            Plugins::EVENT_AFTER_LOAD_PLUGINS,
559
            function () {
560
                    // Install these only after all other plugins have loaded
561
                    Event::on(
562
                        View::class,
563
                        View::EVENT_REGISTER_CP_TEMPLATE_ROOTS,
564
                        function (RegisterTemplateRootsEvent $e) {
565
                            // Register the root directodies
566
                            $allImageTransformTypes = ImageOptimize::$plugin->optimize->getAllImageTransformTypes();
567
                            /** @var ImageTransformInterface $imageTransformType */
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...
568
                            foreach ($allImageTransformTypes as $imageTransformType) {
569
                                list($id, $baseDir) = $imageTransformType::getTemplatesRoot();
570
                                if (is_dir($baseDir)) {
571
                                    $e->roots[$id] = $baseDir;
572
                                }
573
                            }
574
                        }
575
                    );
576
            }
577
        );
578
    }
579
580
    /**
581
     * Return the custom frontend routes
582
     *
583
     * @return array
584
     */
585
    protected function customFrontendRoutes(): array
586
    {
587
        return [
588
        ];
589
    }
590
591
    /**
592
     * If the Field being saved is an OptimizedImages field, re-save the
593
     * responsive image variants automatically
594
     *
595
     * @param FieldEvent $event
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
596
     *
597
     * @throws \yii\base\InvalidConfigException
598
     */
0 ignored issues
show
Coding Style introduced by
Missing @return tag in function comment
Loading history...
599
    protected function checkForOptimizedImagesField(FieldEvent $event)
600
    {
601
        $thisField = $event->field;
602
        if ($thisField instanceof OptimizedImages) {
603
            $volumes = Craft::$app->getVolumes()->getAllVolumes();
604
            foreach ($volumes as $volume) {
605
                $needToReSave = false;
606
                /** @var FieldLayout $fieldLayout */
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...
607
                /** @var Volume $volume */
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...
608
                $fieldLayout = $volume->getFieldLayout();
609
                // Loop through the fields in the layout to see if it contains our field
610
                if ($fieldLayout) {
611
                    $fields = $fieldLayout->getFields();
612
                    foreach ($fields as $field) {
613
                        /** @var Field $field */
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...
614
                        if ($thisField->handle === $field->handle) {
615
                            $needToReSave = true;
616
                        }
617
                    }
618
                    if ($needToReSave) {
619
                        ImageOptimize::$plugin->optimizedImages->resaveVolumeAssets($volume);
620
                    }
621
                }
622
            }
623
        }
624
    }
625
}
626