Passed
Pull Request — v1 (#264)
by
unknown
17:05 queued 09:51
created

ImageOptimize::installCpEventListeners()   A

Complexity

Conditions 3
Paths 1

Size

Total Lines 19
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 13
c 1
b 0
f 0
dl 0
loc 19
rs 9.8333
cc 3
nc 1
nop 0
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\assetbundles\imageoptimize\ImageOptimizeAsset;
14
use nystudio107\imageoptimize\fields\OptimizedImages;
15
use nystudio107\imageoptimize\imagetransforms\CraftImageTransform;
16
use nystudio107\imageoptimize\imagetransforms\ImageTransformInterface;
17
use nystudio107\imageoptimize\listeners\GetCraftQLSchema;
18
use nystudio107\imageoptimize\models\Settings;
19
use nystudio107\imageoptimize\services\Optimize as OptimizeService;
20
use nystudio107\imageoptimize\services\OptimizedImages as OptimizedImagesService;
21
use nystudio107\imageoptimize\services\Placeholder as PlaceholderService;
22
use nystudio107\imageoptimize\utilities\ImageOptimizeUtility;
23
use nystudio107\imageoptimize\variables\ImageOptimizeVariable;
24
25
use nystudio107\pluginmanifest\services\ManifestService;
0 ignored issues
show
Bug introduced by
The type nystudio107\pluginmanife...ervices\ManifestService 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
27
use Craft;
28
use craft\base\Field;
29
use craft\base\Plugin;
30
use craft\base\Volume;
31
use craft\elements\Asset;
32
use craft\events\AssetTransformImageEvent;
33
use craft\events\ElementEvent;
34
use craft\events\FieldEvent;
35
use craft\events\GetAssetThumbUrlEvent;
36
use craft\events\GetAssetUrlEvent;
37
use craft\events\GenerateTransformEvent;
38
use craft\events\PluginEvent;
39
use craft\events\RegisterComponentTypesEvent;
40
use craft\events\RegisterTemplateRootsEvent;
41
use craft\events\RegisterUrlRulesEvent;
42
use craft\events\ReplaceAssetEvent;
43
use craft\events\VolumeEvent;
44
use craft\helpers\ArrayHelper;
45
use craft\helpers\UrlHelper;
46
use craft\models\FieldLayout;
47
use craft\services\Assets;
48
use craft\services\AssetTransforms;
49
use craft\services\Elements;
50
use craft\services\Fields;
51
use craft\services\Plugins;
52
use craft\services\Utilities;
53
use craft\services\Volumes;
54
use craft\web\twig\variables\CraftVariable;
55
use craft\web\Controller;
56
use craft\web\UrlManager;
57
use craft\web\View;
58
59
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...
60
61
use yii\base\Event;
62
use yii\base\Exception;
63
use yii\base\InvalidConfigException;
64
65
/** @noinspection MissingPropertyAnnotationsInspection */
0 ignored issues
show
Coding Style introduced by
The close 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 open comment tag must be the only content on the line
Loading history...
66
67
/**
68
 * Class ImageOptimize
69
 *
70
 * @author    nystudio107
0 ignored issues
show
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...
Coding Style introduced by
The tag in position 1 should be the @package tag
Loading history...
71
 * @package   ImageOptimize
0 ignored issues
show
Coding Style introduced by
Tag value for @package tag indented incorrectly; expected 1 spaces but found 3
Loading history...
72
 * @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 for @since tag indented incorrectly; expected 3 spaces but found 5
Loading history...
73
 *
74
 * @property OptimizeService         $optimize
75
 * @property PlaceholderService      $placeholder
76
 * @property OptimizedImagesService  $optimizedImages
77
 * @property ImageTransformInterface $transformMethod
78
 * @property ManifestService         $manifest
79
 * @property Settings                $settings
80
 * @method   Settings                getSettings()
81
 */
0 ignored issues
show
Coding Style introduced by
Missing @link tag in class comment
Loading history...
Coding Style introduced by
Missing @license tag in class comment
Loading history...
Coding Style introduced by
Missing @category tag in class comment
Loading history...
82
class ImageOptimize extends Plugin
83
{
84
85
    // Constants
86
    // =========================================================================
87
88
    const CRAFTQL_PLUGIN_HANDLE = 'craftql';
89
90
    // Static Properties
91
    // =========================================================================
92
93
    /**
0 ignored issues
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
94
     * @var ImageOptimize
95
     */
96
    public static $plugin;
97
98
    /**
0 ignored issues
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
99
     * @var bool
100
     */
101
    public static $generatePlaceholders = true;
102
103
    /**
0 ignored issues
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
104
     * @var bool
105
     */
106
    public static $craft31 = false;
107
108
    /**
0 ignored issues
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
109
     * @var bool
110
     */
111
    public static $craft35 = false;
112
113
    // Static Methods
114
    // =========================================================================
115
116
    /**
0 ignored issues
show
Coding Style introduced by
Parameter $parent should have a doc-comment as per coding-style.
Loading history...
Coding Style introduced by
Parameter $id should have a doc-comment as per coding-style.
Loading history...
Coding Style introduced by
Parameter $config should have a doc-comment as per coding-style.
Loading history...
Coding Style introduced by
Missing short description in doc comment
Loading history...
117
     * @inheritdoc
118
     */
119
    public function __construct($id, $parent = null, array $config = [])
120
    {
121
        $config['components'] = [
122
            'optimize' => OptimizeService::class,
123
            'optimizedImages' => OptimizedImagesService::class,
124
            'placeholder' => PlaceholderService::class,
125
            // Register the manifest service
126
            'manifest' => [
127
                'class' => ManifestService::class,
128
                'assetClass' => ImageOptimizeAsset::class,
129
                'devServerManifestPath' => 'http://craft-imageoptimize-buildchain:8080/',
130
                'devServerPublicPath' => 'http://craft-imageoptimize-buildchain:8080/',
131
            ],
132
        ];
133
134
        parent::__construct($id, $parent, $config);
135
    }
136
137
    // Public Properties
138
    // =========================================================================
139
140
    /**
0 ignored issues
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
141
     * @var string
142
     */
143
    public $schemaVersion = '1.0.0';
144
145
    /**
0 ignored issues
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
146
     * @var bool
147
     */
148
    public $hasCpSection = false;
149
150
    /**
0 ignored issues
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
151
     * @var bool
152
     */
153
    public $hasCpSettings = true;
154
155
    // Public Methods
156
    // =========================================================================
157
158
    /**
0 ignored issues
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
159
     * @inheritdoc
160
     */
0 ignored issues
show
Coding Style introduced by
Missing @return tag in function comment
Loading history...
161
    public function init()
162
    {
163
        parent::init();
164
        self::$plugin = $this;
165
        self::$craft31 = version_compare(Craft::$app->getVersion(), '3.1', '>=');
0 ignored issues
show
Documentation Bug introduced by
It seems like version_compare(Craft::a...Version(), '3.1', '>=') can also be of type integer. However, the property $craft31 is declared as type boolean. 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...
166
        self::$craft35 = version_compare(Craft::$app->getVersion(), '3.5', '>=');
0 ignored issues
show
Documentation Bug introduced by
It seems like version_compare(Craft::a...Version(), '3.5', '>=') can also be of type integer. However, the property $craft35 is declared as type boolean. 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...
167
        // Handle any console commands
168
        $request = Craft::$app->getRequest();
169
        if ($request->getIsConsoleRequest()) {
170
            $this->controllerNamespace = 'nystudio107\imageoptimize\console\controllers';
171
        }
172
        // Set the image transform component
173
        $this->setImageTransformComponent();
174
        // Add in our Craft components
175
        $this->addComponents();
176
        // Install our global event handlers
177
        $this->installEventHandlers();
178
        // Log that the plugin has loaded
179
        Craft::info(
180
            Craft::t(
181
                'image-optimize',
182
                '{name} plugin loaded',
183
                ['name' => $this->name]
184
            ),
185
            __METHOD__
186
        );
187
    }
188
189
    /**
0 ignored issues
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
190
     * @inheritdoc
191
     */
0 ignored issues
show
Coding Style introduced by
Missing @return tag in function comment
Loading history...
192
    public function getSettingsResponse()
193
    {
194
        $view = Craft::$app->getView();
195
        $namespace = $view->getNamespace();
196
        $view->setNamespace('settings');
197
        $settingsHtml = $this->settingsHtml();
198
        $view->setNamespace($namespace);
199
        /** @var Controller $controller */
0 ignored issues
show
Coding Style introduced by
The close comment tag must be the only content on the line
Loading history...
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...
200
        $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...
201
202
        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...
203
            'plugin'       => $this,
204
            'settingsHtml' => $settingsHtml,
205
        ]);
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...
206
    }
207
208
    /**
0 ignored issues
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
209
     * @inheritdoc
210
     */
0 ignored issues
show
Coding Style introduced by
Missing @return tag in function comment
Loading history...
211
    public function settingsHtml()
212
    {
213
        // Get only the user-editable settings
214
        $settings = $this->getSettings();
215
216
        // Get the image transform types
217
        $allImageTransformTypes = ImageOptimize::$plugin->optimize->getAllImageTransformTypes();
218
        $imageTransformTypeOptions = [];
219
        /** @var ImageTransformInterface $class */
0 ignored issues
show
Coding Style introduced by
The close comment tag must be the only content on the line
Loading history...
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...
220
        foreach ($allImageTransformTypes as $class) {
221
            if ($class::isSelectable()) {
222
                $imageTransformTypeOptions[] = [
223
                    'value' => $class,
224
                    'label' => $class::displayName(),
225
                ];
226
            }
227
        }
228
        // Sort them by name
229
        ArrayHelper::multisort($imageTransformTypeOptions, 'label');
230
231
        // Render the settings template
232
        try {
233
            return Craft::$app->getView()->renderTemplate(
234
                'image-optimize/settings/_settings.twig',
235
                [
236
                    'settings'        => $settings,
237
                    'gdInstalled'     => \function_exists('imagecreatefromjpeg'),
238
                    'imageTransformTypeOptions' => $imageTransformTypeOptions,
239
                    'allImageTransformTypes' => $allImageTransformTypes,
240
                    'imageTransform' => ImageOptimize::$plugin->transformMethod,
241
                ]
242
            );
243
        } catch (\Twig\Error\LoaderError $e) {
244
            Craft::error($e->getMessage(), __METHOD__);
245
        } catch (Exception $e) {
246
            Craft::error($e->getMessage(), __METHOD__);
247
        }
248
249
        return '';
250
    }
251
252
    // Protected Methods
253
    // =========================================================================
254
255
    /**
0 ignored issues
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
256
     * @inheritdoc
257
     */
0 ignored issues
show
Coding Style introduced by
Missing @return tag in function comment
Loading history...
258
    protected function createSettingsModel()
259
    {
260
        return new Settings();
261
    }
262
263
    /**
264
     * Set the transformMethod component
265
     */
0 ignored issues
show
Coding Style introduced by
Missing @return tag in function comment
Loading history...
266
    protected function setImageTransformComponent()
267
    {
268
        $settings = $this->getSettings();
269
        $definition = array_merge(
270
            $settings->imageTransformTypeSettings[$settings->transformClass] ?? [],
271
            ['class' => $settings->transformClass]
272
        );
273
        try {
274
            $this->set('transformMethod', $definition);
275
        } catch (InvalidConfigException $e) {
276
            Craft::error($e->getMessage(), __METHOD__);
277
        }
278
    }
279
280
    /**
281
     * Add in our Craft components
282
     */
0 ignored issues
show
Coding Style introduced by
Missing @return tag in function comment
Loading history...
283
    protected function addComponents()
284
    {
285
        // Register our variables
286
        Event::on(
287
            CraftVariable::class,
288
            CraftVariable::EVENT_INIT,
289
            function (Event $event) {
290
                /** @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...
291
                $variable = $event->sender;
292
                $variable->set('imageOptimize', [
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...
293
                    'class' => ImageOptimizeVariable::class,
294
                    'manifestService' => $this->manifest,
295
                ]);
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...
296
            }
297
        );
298
299
        // Register our Field
300
        Event::on(
301
            Fields::class,
302
            Fields::EVENT_REGISTER_FIELD_TYPES,
303
            function (RegisterComponentTypesEvent $event) {
304
                Craft::debug(
305
                    'Fields::EVENT_REGISTER_FIELD_TYPES',
306
                    __METHOD__
307
                );
308
                $event->types[] = OptimizedImages::class;
309
            }
310
        );
311
312
        // Register our Utility only if they are using the CraftImageTransform method
313
        if (ImageOptimize::$plugin->transformMethod instanceof CraftImageTransform) {
314
            Event::on(
315
                Utilities::class,
316
                Utilities::EVENT_REGISTER_UTILITY_TYPES,
317
                function (RegisterComponentTypesEvent $event) {
318
                    $event->types[] = ImageOptimizeUtility::class;
319
                }
320
            );
321
        }
322
    }
323
324
    /**
325
     * Install our event handlers
326
     */
0 ignored issues
show
Coding Style introduced by
Missing @return tag in function comment
Loading history...
327
    protected function installEventHandlers()
328
    {
329
        $this->installAssetEventHandlers();
330
        $this->installElementEventHandlers();
331
        $this->installMiscEventHandlers();
332
        $this->installCraftQLEventHandlers();
333
        $request = Craft::$app->getRequest();
334
        // Install only for non-console site requests
335
        if ($request->getIsSiteRequest() && !$request->getIsConsoleRequest()) {
336
            $this->installSiteEventListeners();
337
        }
338
        // Install only for non-console cp requests
339
        if ($request->getIsCpRequest() && !$request->getIsConsoleRequest()) {
340
            $this->installCpEventListeners();
341
        }
342
    }
343
344
    /**
345
     * Install our Asset event handlers
346
     */
0 ignored issues
show
Coding Style introduced by
Missing @return tag in function comment
Loading history...
347
    protected function installAssetEventHandlers()
348
    {
349
        // Handler: Assets::EVENT_GET_ASSET_URL
350
        Event::on(
351
            Assets::class,
352
            Assets::EVENT_GET_ASSET_URL,
353
            function (GetAssetUrlEvent $event) {
354
                Craft::debug(
355
                    'Assets::EVENT_GET_ASSET_URL',
356
                    __METHOD__
357
                );
358
                // Return the URL to the asset URL or null to let Craft handle it
359
                $event->url = ImageOptimize::$plugin->optimize->handleGetAssetUrlEvent(
360
                    $event
361
                );
362
            }
363
        );
364
365
        // Handler: Assets::EVENT_GET_ASSET_THUMB_URL
366
        Event::on(
367
            Assets::class,
368
            Assets::EVENT_GET_ASSET_THUMB_URL,
369
            function (GetAssetThumbUrlEvent $event) {
370
                Craft::debug(
371
                    'Assets::EVENT_GET_ASSET_THUMB_URL',
372
                    __METHOD__
373
                );
374
                // Return the URL to the asset URL or null to let Craft handle it
375
                $event->url = ImageOptimize::$plugin->optimize->handleGetAssetThumbUrlEvent(
376
                    $event
377
                );
378
            }
379
        );
380
381
        // Handler: AssetTransforms::EVENT_GENERATE_TRANSFORM
382
        Event::on(
383
            AssetTransforms::class,
384
            AssetTransforms::EVENT_GENERATE_TRANSFORM,
385
            function (GenerateTransformEvent $event) {
386
                Craft::debug(
387
                    'AssetTransforms::EVENT_GENERATE_TRANSFORM',
388
                    __METHOD__
389
                );
390
                // Return the path to the optimized image to _createTransformForAsset()
391
                $event->tempPath = ImageOptimize::$plugin->optimize->handleGenerateTransformEvent(
392
                    $event
393
                );
394
            }
395
        );
396
397
        // Handler: AssetTransforms::EVENT_AFTER_DELETE_TRANSFORMS
398
        Event::on(
399
            AssetTransforms::class,
400
            AssetTransforms::EVENT_AFTER_DELETE_TRANSFORMS,
401
            function (AssetTransformImageEvent $event) {
402
                Craft::debug(
403
                    'AssetTransforms::EVENT_AFTER_DELETE_TRANSFORMS',
404
                    __METHOD__
405
                );
406
                // Clean up any stray variant files
407
                ImageOptimize::$plugin->optimize->handleAfterDeleteTransformsEvent(
408
                    $event
409
                );
410
            }
411
        );
412
413
        // Handler: Assets::EVENT_BEFORE_REPLACE_ASSET
414
        Event::on(
415
            Assets::class,
416
            Assets::EVENT_BEFORE_REPLACE_ASSET,
417
            function (ReplaceAssetEvent $event) {
418
                Craft::debug(
419
                    'Assets::EVENT_BEFORE_REPLACE_ASSET',
420
                    __METHOD__
421
                );
422
                /** @var Asset $element */
0 ignored issues
show
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...
Coding Style introduced by
The open comment tag must be the only content on the line
Loading history...
423
                $element = $event->asset;
424
                // Purge the URL
425
                $purgeUrl = ImageOptimize::$plugin->transformMethod->getPurgeUrl($element);
426
                if ($purgeUrl) {
427
                    ImageOptimize::$plugin->transformMethod->purgeUrl($purgeUrl);
428
                }
429
            }
430
        );
431
432
        // Handler: Assets::EVENT_AFTER_REPLACE_ASSET
433
        Event::on(
434
            Assets::class,
435
            Assets::EVENT_AFTER_REPLACE_ASSET,
436
            function (ReplaceAssetEvent $event) {
437
                Craft::debug(
438
                    'Assets::EVENT_AFTER_REPLACE_ASSET',
439
                    __METHOD__
440
                );
441
                /** @var Asset $element */
0 ignored issues
show
Coding Style introduced by
The close 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 open comment tag must be the only content on the line
Loading history...
442
                $element = $event->asset;
443
                if ($element->id !== null) {
444
                    ImageOptimize::$plugin->optimizedImages->resaveAsset($element->id);
445
                }
446
            }
447
        );
448
    }
449
450
    /**
451
     * Install our Element event handlers
452
     */
0 ignored issues
show
Coding Style introduced by
Missing @return tag in function comment
Loading history...
453
    protected function installElementEventHandlers()
454
    {
455
        // Handler: Elements::EVENT_BEFORE_SAVE_ELEMENT
456
        Event::on(
457
            Assets::class,
458
            Elements::EVENT_BEFORE_SAVE_ELEMENT,
459
            function (ElementEvent $event) {
460
                Craft::debug(
461
                    'Elements::EVENT_BEFORE_SAVE_ELEMENT',
462
                    __METHOD__
463
                );
464
                /** @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...
465
                $asset = $event->element;
466
                if (!$event->isNew) {
467
                    // Purge the URL
468
                    $purgeUrl = ImageOptimize::$plugin->transformMethod->getPurgeUrl($asset);
469
                    if ($purgeUrl) {
470
                        ImageOptimize::$plugin->transformMethod->purgeUrl($purgeUrl);
471
                    }
472
                }
473
            }
474
        );
475
476
        // Handler: Elements::EVENT_BEFORE_DELETE_ELEMENT
477
        Event::on(
478
            Asset::class,
479
            Elements::EVENT_BEFORE_DELETE_ELEMENT,
480
            function (ElementEvent $event) {
481
                Craft::debug(
482
                    'Elements::EVENT_BEFORE_DELETE_ELEMENT',
483
                    __METHOD__
484
                );
485
                /** @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
The close comment tag must be the only content on the line
Loading history...
Coding Style introduced by
Missing short description in doc comment
Loading history...
486
                $asset = $event->element;
487
                // Purge the URL
488
                $purgeUrl = ImageOptimize::$plugin->transformMethod->getPurgeUrl($asset);
489
                if ($purgeUrl) {
490
                    ImageOptimize::$plugin->transformMethod->purgeUrl($purgeUrl);
491
                }
492
            }
493
        );
494
    }
495
496
    /**
497
     * Install our miscellaneous event handlers
498
     */
0 ignored issues
show
Coding Style introduced by
Missing @return tag in function comment
Loading history...
499
    protected function installMiscEventHandlers()
500
    {
501
        // Handler: Fields::EVENT_AFTER_SAVE_FIELD
502
        Event::on(
503
            Fields::class,
504
            Fields::EVENT_AFTER_SAVE_FIELD,
505
            function (FieldEvent $event) {
506
                Craft::debug(
507
                    'Fields::EVENT_AFTER_SAVE_FIELD',
508
                    __METHOD__
509
                );
510
                $settings = $this->getSettings();
511
                /** @var Field $field */
0 ignored issues
show
Coding Style introduced by
The close comment tag must be the only content on the line
Loading history...
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...
512
                if (!$event->isNew && $settings->automaticallyResaveImageVariants) {
513
                    $this->checkForOptimizedImagesField($event);
514
                }
515
            }
516
        );
517
518
        // Handler: Plugins::EVENT_AFTER_SAVE_PLUGIN_SETTINGS
519
        Event::on(
520
            Plugins::class,
521
            Plugins::EVENT_AFTER_SAVE_PLUGIN_SETTINGS,
522
            function (PluginEvent $event) {
523
                if ($event->plugin === $this) {
524
                    Craft::debug(
525
                        'Plugins::EVENT_AFTER_SAVE_PLUGIN_SETTINGS',
526
                        __METHOD__
527
                    );
528
                    $settings = $this->getSettings();
529
                    if ($settings->automaticallyResaveImageVariants) {
530
                        // After they have changed the settings, resave all of the assets
531
                        ImageOptimize::$plugin->optimizedImages->resaveAllVolumesAssets();
532
                    }
533
                }
534
            }
535
        );
536
537
        // Handler: Volumes::EVENT_AFTER_SAVE_VOLUME
538
        Event::on(
539
            Volumes::class,
540
            Volumes::EVENT_AFTER_SAVE_VOLUME,
541
            function (VolumeEvent $event) {
542
                Craft::debug(
543
                    'Volumes::EVENT_AFTER_SAVE_VOLUME',
544
                    __METHOD__
545
                );
546
                $settings = $this->getSettings();
547
                // Only worry about this volume if it's not new
548
                if (!$event->isNew && $settings->automaticallyResaveImageVariants) {
549
                    /** @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...
550
                    $volume = $event->volume;
551
                    if ($volume !== null) {
552
                        ImageOptimize::$plugin->optimizedImages->resaveVolumeAssets($volume);
553
                    }
554
                }
555
            }
556
        );
557
558
        // Handler: Plugins::EVENT_AFTER_INSTALL_PLUGIN
559
        Event::on(
560
            Plugins::class,
561
            Plugins::EVENT_AFTER_INSTALL_PLUGIN,
562
            function (PluginEvent $event) {
563
                if ($event->plugin === $this) {
564
                    $request = Craft::$app->getRequest();
565
                    if ($request->isCpRequest) {
566
                        Craft::$app->getResponse()->redirect(UrlHelper::cpUrl('image-optimize/welcome'))->send();
567
                    }
568
                }
569
            }
570
        );
571
    }
572
573
    /**
574
     * Install our CraftQL event handlers
575
     */
0 ignored issues
show
Coding Style introduced by
Missing @return tag in function comment
Loading history...
576
    protected function installCraftQLEventHandlers()
577
    {
578
        if (class_exists(CraftQL::class)) {
579
            Event::on(
580
                OptimizedImages::class,
581
                GetCraftQLSchema::EVENT_GET_FIELD_SCHEMA,
582
                [new GetCraftQLSchema, 'handle']
583
            );
584
        }
585
    }
586
587
    /**
588
     * Install site event listeners for site requests only
589
     */
0 ignored issues
show
Coding Style introduced by
Missing @return tag in function comment
Loading history...
590
    protected function installSiteEventListeners()
591
    {
592
        // Handler: UrlManager::EVENT_REGISTER_SITE_URL_RULES
593
        Event::on(
594
            UrlManager::class,
595
            UrlManager::EVENT_REGISTER_SITE_URL_RULES,
596
            function (RegisterUrlRulesEvent $event) {
597
                Craft::debug(
598
                    'UrlManager::EVENT_REGISTER_SITE_URL_RULES',
599
                    __METHOD__
600
                );
601
                // Register our Control Panel routes
602
                $event->rules = array_merge(
603
                    $event->rules,
604
                    $this->customFrontendRoutes()
605
                );
606
            }
607
        );
608
    }
609
610
    /**
611
     * Install site event listeners for cp requests only
612
     */
0 ignored issues
show
Coding Style introduced by
Missing @return tag in function comment
Loading history...
613
    protected function installCpEventListeners()
614
    {
615
        // Handler: Plugins::EVENT_AFTER_LOAD_PLUGINS
616
        Event::on(
617
            Plugins::class,
618
            Plugins::EVENT_AFTER_LOAD_PLUGINS,
619
            function () {
620
                    // Install these only after all other plugins have loaded
621
                    Event::on(
622
                        View::class,
623
                        View::EVENT_REGISTER_CP_TEMPLATE_ROOTS,
624
                        function (RegisterTemplateRootsEvent $e) {
625
                            // Register the root directodies
626
                            $allImageTransformTypes = ImageOptimize::$plugin->optimize->getAllImageTransformTypes();
627
                            /** @var ImageTransformInterface $imageTransformType */
0 ignored issues
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
Coding Style introduced by
The open comment tag must be the only content on the line
Loading history...
Coding Style introduced by
The close comment tag must be the only content on the line
Loading history...
628
                            foreach ($allImageTransformTypes as $imageTransformType) {
629
                                list($id, $baseDir) = $imageTransformType::getTemplatesRoot();
630
                                if (is_dir($baseDir)) {
631
                                    $e->roots[$id] = $baseDir;
632
                                }
633
                            }
634
                        }
635
                    );
636
            }
637
        );
638
    }
639
640
    /**
641
     * Return the custom frontend routes
642
     *
643
     * @return array
644
     */
645
    protected function customFrontendRoutes(): array
646
    {
647
        return [
648
        ];
649
    }
650
651
    /**
652
     * If the Field being saved is an OptimizedImages field, re-save the
653
     * responsive image variants automatically
654
     *
655
     * @param FieldEvent $event
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
656
     *
657
     * @throws \yii\base\InvalidConfigException
658
     */
0 ignored issues
show
Coding Style introduced by
Missing @return tag in function comment
Loading history...
659
    protected function checkForOptimizedImagesField(FieldEvent $event)
660
    {
661
        $thisField = $event->field;
662
        if ($thisField instanceof OptimizedImages) {
663
            $volumes = Craft::$app->getVolumes()->getAllVolumes();
664
            foreach ($volumes as $volume) {
665
                $needToReSave = false;
666
                /** @var FieldLayout $fieldLayout */
0 ignored issues
show
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...
Coding Style introduced by
The open comment tag must be the only content on the line
Loading history...
667
                /** @var Volume $volume */
0 ignored issues
show
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...
Coding Style introduced by
The open comment tag must be the only content on the line
Loading history...
668
                $fieldLayout = $volume->getFieldLayout();
669
                // Loop through the fields in the layout to see if it contains our field
670
                if ($fieldLayout) {
671
                    $fields = $fieldLayout->getFields();
672
                    foreach ($fields as $field) {
673
                        /** @var Field $field */
0 ignored issues
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
Coding Style introduced by
The open comment tag must be the only content on the line
Loading history...
Coding Style introduced by
The close comment tag must be the only content on the line
Loading history...
674
                        if ($thisField->handle === $field->handle) {
675
                            $needToReSave = true;
676
                        }
677
                    }
678
                    if ($needToReSave) {
679
                        ImageOptimize::$plugin->optimizedImages->resaveVolumeAssets($volume, $thisField->id);
0 ignored issues
show
Bug introduced by
It seems like $thisField->id can also be of type string; however, parameter $fieldId of nystudio107\imageoptimiz...s::resaveVolumeAssets() does only seem to accept integer|null, maybe add an additional type check? ( Ignorable by Annotation )

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

679
                        ImageOptimize::$plugin->optimizedImages->resaveVolumeAssets($volume, /** @scrutinizer ignore-type */ $thisField->id);
Loading history...
680
                    }
681
                }
682
            }
683
        }
684
    }
685
}
686