ImageOptimize::setImageTransformComponent()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 12
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 8
c 0
b 0
f 0
dl 0
loc 12
rs 10
cc 2
nc 2
nop 0
1
<?php
2
/**
3
 * ImageOptimize plugin for Craft CMS
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 Craft;
14
use craft\base\Field;
15
use craft\base\Model;
16
use craft\base\Plugin;
17
use craft\elements\Asset;
18
use craft\events\DefineAssetThumbUrlEvent;
19
use craft\events\DefineAssetUrlEvent;
20
use craft\events\ElementEvent;
21
use craft\events\FieldEvent;
22
use craft\events\ImageTransformerOperationEvent;
23
use craft\events\PluginEvent;
24
use craft\events\RegisterComponentTypesEvent;
25
use craft\events\RegisterTemplateRootsEvent;
26
use craft\events\RegisterUrlRulesEvent;
27
use craft\events\ReplaceAssetEvent;
28
use craft\events\VolumeEvent;
29
use craft\helpers\ArrayHelper;
30
use craft\helpers\UrlHelper;
31
use craft\imagetransforms\ImageTransformer;
32
use craft\models\FieldLayout;
33
use craft\services\Assets;
34
use craft\services\Elements;
35
use craft\services\Fields;
36
use craft\services\Plugins;
37
use craft\services\Utilities;
38
use craft\services\Volumes;
39
use craft\web\Controller;
40
use craft\web\TemplateResponseBehavior;
41
use craft\web\twig\variables\CraftVariable;
42
use craft\web\UrlManager;
43
use craft\web\View;
44
use nystudio107\imageoptimize\fields\OptimizedImages;
45
use nystudio107\imageoptimize\imagetransforms\CraftImageTransform;
46
use nystudio107\imageoptimize\imagetransforms\ImageTransformInterface;
47
use nystudio107\imageoptimize\models\Settings;
48
use nystudio107\imageoptimize\services\ServicesTrait;
49
use nystudio107\imageoptimize\utilities\ImageOptimizeUtility;
50
use nystudio107\imageoptimize\variables\ImageOptimizeVariable;
51
use ReflectionClassConstant;
52
use ReflectionException;
53
use yii\base\Event;
54
use yii\base\Exception;
55
use yii\base\InvalidConfigException;
56
use yii\web\Response;
57
use function function_exists;
58
59
/** @noinspection MissingPropertyAnnotationsInspection */
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...
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 for @author tag indented incorrectly; expected 2 spaces but found 4
Loading history...
65
 * @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...
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 for @since tag indented incorrectly; expected 3 spaces but found 5
Loading history...
67
 *
68
 * @property ImageTransformInterface $transformMethod
69
 */
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...
70
class ImageOptimize extends Plugin
71
{
72
    // Traits
73
    // =========================================================================
74
75
    use ServicesTrait;
76
77
    // Static Properties
78
    // =========================================================================
79
80
    /**
0 ignored issues
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
81
     * @var ?ImageOptimize
82
     */
83
    public static ?ImageOptimize $plugin = null;
84
85
    /**
0 ignored issues
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
86
     * @var bool
87
     */
88
    public static bool $generatePlaceholders = true;
89
90
    // Public Properties
91
    // =========================================================================
92
    /**
0 ignored issues
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
93
     * @var string
94
     */
95
    public string $schemaVersion = '1.0.0';
96
97
    /**
0 ignored issues
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
98
     * @var bool
99
     */
100
    public bool $hasCpSection = false;
101
102
    /**
0 ignored issues
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
103
     * @var bool
104
     */
105
    public bool $hasCpSettings = true;
106
107
    // Public Methods
108
    // =========================================================================
109
110
    /**
0 ignored issues
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
111
     * @inheritdoc
112
     */
0 ignored issues
show
Coding Style introduced by
Missing @return tag in function comment
Loading history...
113
    public function init(): void
114
    {
115
        parent::init();
116
        self::$plugin = $this;
117
        // Handle any console commands
118
        $request = Craft::$app->getRequest();
119
        if ($request->getIsConsoleRequest()) {
120
            $this->controllerNamespace = 'nystudio107\imageoptimize\console\controllers';
121
        }
122
        // Set the image transform component
123
        $this->setImageTransformComponent();
124
        // Add in our Craft components
125
        $this->addComponents();
126
        // Install our global event handlers
127
        $this->installEventHandlers();
128
        // Log that the plugin has loaded
129
        Craft::info(
130
            Craft::t(
131
                'image-optimize',
132
                '{name} plugin loaded',
133
                ['name' => $this->name]
134
            ),
135
            __METHOD__
136
        );
137
    }
138
139
    /**
0 ignored issues
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
140
     * @inheritdoc
141
     */
0 ignored issues
show
Coding Style introduced by
Missing @return tag in function comment
Loading history...
142
    public function getSettingsResponse(): TemplateResponseBehavior|Response
143
    {
144
        $view = Craft::$app->getView();
145
        $namespace = $view->getNamespace();
146
        $view->setNamespace('settings');
147
        $settingsHtml = $this->settingsHtml();
148
        $view->setNamespace($namespace);
149
        /** @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
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...
150
        $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...
151
152
        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...
153
            'plugin' => $this,
154
            'settingsHtml' => $settingsHtml,
155
        ]);
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...
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 settingsHtml(): ?string
162
    {
163
        // Get only the user-editable settings
164
        /** @var Settings $settings */
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...
165
        $settings = $this->getSettings();
166
167
        // Get the image transform types
168
        $allImageTransformTypes = self::$plugin->optimize->getAllImageTransformTypes();
169
        $imageTransformTypeOptions = [];
170
        /** @var ImageTransformInterface $class */
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...
171
        foreach ($allImageTransformTypes as $class) {
172
            if ($class::isSelectable()) {
173
                $imageTransformTypeOptions[] = [
174
                    'value' => $class,
175
                    'label' => $class::displayName(),
176
                ];
177
            }
178
        }
179
        // Sort them by name
180
        ArrayHelper::multisort($imageTransformTypeOptions, 'label');
181
182
        // Render the settings template
183
        try {
184
            return Craft::$app->getView()->renderTemplate(
185
                'image-optimize/settings/_settings.twig',
186
                [
187
                    'settings' => $settings,
188
                    'gdInstalled' => function_exists('imagecreatefromjpeg'),
189
                    'imageTransformTypeOptions' => $imageTransformTypeOptions,
190
                    'allImageTransformTypes' => $allImageTransformTypes,
191
                    'imageTransform' => self::$plugin->transformMethod,
192
                ]
193
            );
194
        } catch (Exception $e) {
195
            Craft::error($e->getMessage(), __METHOD__);
196
        }
197
198
        return '';
199
    }
200
201
    // Protected Methods
202
    // =========================================================================
203
204
    /**
0 ignored issues
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
205
     * @inheritdoc
206
     */
0 ignored issues
show
Coding Style introduced by
Missing @return tag in function comment
Loading history...
207
    protected function createSettingsModel(): ?Model
208
    {
209
        return new Settings();
210
    }
211
212
    /**
213
     * Set the transformMethod component
214
     */
0 ignored issues
show
Coding Style introduced by
Missing @return tag in function comment
Loading history...
215
    protected function setImageTransformComponent(): void
216
    {
217
        /** @var Settings $settings */
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...
218
        $settings = $this->getSettings();
219
        $definition = array_merge(
220
            $settings->imageTransformTypeSettings[$settings->transformClass] ?? [],
221
            ['class' => $settings->transformClass]
222
        );
223
        try {
224
            $this->set('transformMethod', $definition);
225
        } catch (InvalidConfigException $e) {
226
            Craft::error($e->getMessage(), __METHOD__);
227
        }
228
    }
229
230
    /**
231
     * Add in our Craft components
232
     */
0 ignored issues
show
Coding Style introduced by
Missing @return tag in function comment
Loading history...
233
    protected function addComponents(): void
234
    {
235
        // Register our variables
236
        Event::on(
237
            CraftVariable::class,
238
            CraftVariable::EVENT_INIT,
239
            function(Event $event) {
0 ignored issues
show
Coding Style introduced by
Expected 1 space after FUNCTION keyword; 0 found
Loading history...
240
                /** @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...
241
                $variable = $event->sender;
242
                $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...
243
                    'class' => ImageOptimizeVariable::class,
244
                    'viteService' => $this->vite,
245
                ]);
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...
246
            }
247
        );
248
249
        // Register our Field
250
        Event::on(
251
            Fields::class,
252
            Fields::EVENT_REGISTER_FIELD_TYPES,
253
            static function(RegisterComponentTypesEvent $event) {
0 ignored issues
show
Coding Style introduced by
Expected 1 space after FUNCTION keyword; 0 found
Loading history...
254
                Craft::debug(
255
                    'Fields::EVENT_REGISTER_FIELD_TYPES',
256
                    __METHOD__
257
                );
258
                $event->types[] = OptimizedImages::class;
259
            }
260
        );
261
262
        // Register our Utility only if they are using the CraftImageTransform method
263
        if (self::$plugin->transformMethod instanceof CraftImageTransform) {
264
            Event::on(
265
                Utilities::class,
266
                Utilities::EVENT_REGISTER_UTILITIES,
267
                static function(RegisterComponentTypesEvent $event) {
0 ignored issues
show
Coding Style introduced by
Expected 1 space after FUNCTION keyword; 0 found
Loading history...
268
                    $event->types[] = ImageOptimizeUtility::class;
269
                }
270
            );
271
        }
272
    }
273
274
    /**
275
     * Install our event handlers
276
     */
0 ignored issues
show
Coding Style introduced by
Missing @return tag in function comment
Loading history...
277
    protected function installEventHandlers(): void
278
    {
279
        $this->installAssetEventHandlers();
280
        $this->installElementEventHandlers();
281
        $this->installMiscEventHandlers();
282
        $request = Craft::$app->getRequest();
283
        // Install only for non-console site requests
284
        if ($request->getIsSiteRequest() && !$request->getIsConsoleRequest()) {
285
            $this->installSiteEventListeners();
286
        }
287
        // Install only for non-console cp requests
288
        if ($request->getIsCpRequest() && !$request->getIsConsoleRequest()) {
289
            $this->installCpEventListeners();
290
        }
291
    }
292
293
    /**
294
     * Install our Asset event handlers
295
     */
0 ignored issues
show
Coding Style introduced by
Missing @return tag in function comment
Loading history...
296
    protected function installAssetEventHandlers(): void
297
    {
298
        // Use Asset::EVENT_BEFORE_DEFINE_URL if it's available
299
        // ref: https://github.com/craftcms/cms/issues/13018
300
        try {
301
            $ref = new ReflectionClassConstant(Asset::class, 'EVENT_BEFORE_DEFINE_URL');
302
        } /** @noinspection PhpRedundantCatchClauseInspection */ catch (ReflectionException) {
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...
303
            $ref = null;
304
        }
305
        $eventName = $ref?->getDeclaringClass()->name === Asset::class
306
            ? Asset::EVENT_BEFORE_DEFINE_URL
307
            : Asset::EVENT_DEFINE_URL;
308
        // Handler: Assets::EVENT_DEFINE_URL
309
        Event::on(
310
            Asset::class,
311
            $eventName,
312
            static function(DefineAssetUrlEvent $event): void {
0 ignored issues
show
Coding Style introduced by
Expected 1 space after FUNCTION keyword; 0 found
Loading history...
313
                Craft::debug(
314
                    'Asset::EVENT_DEFINE_URL',
315
                    __METHOD__
316
                );
317
                // Return the URL to the asset URL or null to let Craft handle it
318
                $event->url = ImageOptimize::$plugin->optimize->handleGetAssetUrlEvent(
319
                    $event
320
                );
321
            }
322
        );
323
324
        // Handler: Assets::EVENT_GET_ASSET_THUMB_URL
325
        Event::on(
326
            Assets::class,
327
            Assets::EVENT_DEFINE_THUMB_URL,
328
            static function(DefineAssetThumbUrlEvent $event): void {
0 ignored issues
show
Coding Style introduced by
Expected 1 space after FUNCTION keyword; 0 found
Loading history...
329
                Craft::debug(
330
                    'Assets::EVENT_DEFINE_THUMB_URL',
331
                    __METHOD__
332
                );
333
                // Return the URL to the asset URL or null to let Craft handle it
334
                $event->url = ImageOptimize::$plugin->optimize->handleGetAssetThumbUrlEvent(
335
                    $event
336
                );
337
            }
338
        );
339
340
        // Handler: ImageTransformer::EVENT_TRANSFORM_IMAGE
341
        Event::on(
342
            ImageTransformer::class,
343
            ImageTransformer::EVENT_TRANSFORM_IMAGE,
344
            static function(ImageTransformerOperationEvent $event): void {
0 ignored issues
show
Coding Style introduced by
Expected 1 space after FUNCTION keyword; 0 found
Loading history...
345
                Craft::debug(
346
                    'ImageTransformer::EVENT_TRANSFORM_IMAGE',
347
                    __METHOD__
348
                );
349
                // Return the path to the optimized image to _createTransformForAsset()
350
                $tempPath = ImageOptimize::$plugin->optimize->handleGenerateTransformEvent(
351
                    $event
352
                );
353
                if ($tempPath) {
354
                    // Remove the old Craft generated transform that's still sitting in the temp directory.
355
                    @unlink($event->tempPath);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition for unlink(). This can introduce security issues, and is generally not recommended. ( Ignorable by Annotation )

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

355
                    /** @scrutinizer ignore-unhandled */ @unlink($event->tempPath);

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
Bug introduced by
It seems like $event->tempPath can also be of type null; however, parameter $filename of unlink() does only seem to accept string, 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

355
                    @unlink(/** @scrutinizer ignore-type */ $event->tempPath);
Loading history...
356
                    $event->tempPath = $tempPath;
357
                }
358
            }
359
        );
360
361
        // Handler: ImageTransformer::EVENT_DELETE_TRANSFORMED_IMAGE
362
        Event::on(
363
            ImageTransformer::class,
364
            ImageTransformer::EVENT_DELETE_TRANSFORMED_IMAGE,
365
            static function(ImageTransformerOperationEvent $event): void {
0 ignored issues
show
Coding Style introduced by
Expected 1 space after FUNCTION keyword; 0 found
Loading history...
366
                Craft::debug(
367
                    'ImageTransformer::EVENT_DELETE_TRANSFORMED_IMAGE',
368
                    __METHOD__
369
                );
370
                // Clean up any stray variant files
371
                ImageOptimize::$plugin->optimize->handleAfterDeleteTransformsEvent(
372
                    $event
373
                );
374
            }
375
        );
376
377
        // Handler: Assets::EVENT_BEFORE_REPLACE_ASSET
378
        Event::on(
379
            Assets::class,
380
            Assets::EVENT_BEFORE_REPLACE_ASSET,
381
            static function(ReplaceAssetEvent $event) {
0 ignored issues
show
Coding Style introduced by
Expected 1 space after FUNCTION keyword; 0 found
Loading history...
382
                Craft::debug(
383
                    'Assets::EVENT_BEFORE_REPLACE_ASSET',
384
                    __METHOD__
385
                );
386
                $element = $event->asset;
387
                // Purge the URL
388
                $purgeUrl = ImageOptimize::$plugin->transformMethod->getPurgeUrl($element);
389
                if ($purgeUrl) {
390
                    ImageOptimize::$plugin->transformMethod->purgeUrl($purgeUrl);
391
                }
392
            }
393
        );
394
395
        // Handler: Assets::EVENT_AFTER_REPLACE_ASSET
396
        Event::on(
397
            Assets::class,
398
            Assets::EVENT_AFTER_REPLACE_ASSET,
399
            static function(ReplaceAssetEvent $event) {
0 ignored issues
show
Coding Style introduced by
Expected 1 space after FUNCTION keyword; 0 found
Loading history...
400
                Craft::debug(
401
                    'Assets::EVENT_AFTER_REPLACE_ASSET',
402
                    __METHOD__
403
                );
404
                $element = $event->asset;
405
                if ($element->id !== null) {
406
                    ImageOptimize::$plugin->optimizedImages->resaveAsset($element->id, true);
407
                }
408
            }
409
        );
410
    }
411
412
    /**
413
     * Install our Element event handlers
414
     */
0 ignored issues
show
Coding Style introduced by
Missing @return tag in function comment
Loading history...
415
    protected function installElementEventHandlers(): void
416
    {
417
        // Handler: Elements::EVENT_BEFORE_SAVE_ELEMENT
418
        Event::on(
419
            Assets::class,
420
            Elements::EVENT_BEFORE_SAVE_ELEMENT,
421
            static function(ElementEvent $event) {
0 ignored issues
show
Coding Style introduced by
Expected 1 space after FUNCTION keyword; 0 found
Loading history...
422
                Craft::debug(
423
                    'Elements::EVENT_BEFORE_SAVE_ELEMENT',
424
                    __METHOD__
425
                );
426
                /** @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...
427
                $asset = $event->element;
428
                if (!$event->isNew) {
429
                    // Purge the URL
430
                    $purgeUrl = ImageOptimize::$plugin->transformMethod->getPurgeUrl($asset);
431
                    if ($purgeUrl) {
432
                        ImageOptimize::$plugin->transformMethod->purgeUrl($purgeUrl);
433
                    }
434
                }
435
            }
436
        );
437
438
        // Handler: Elements::EVENT_BEFORE_DELETE_ELEMENT
439
        Event::on(
440
            Asset::class,
441
            Elements::EVENT_BEFORE_DELETE_ELEMENT,
442
            static function(ElementEvent $event) {
0 ignored issues
show
Coding Style introduced by
Expected 1 space after FUNCTION keyword; 0 found
Loading history...
443
                Craft::debug(
444
                    'Elements::EVENT_BEFORE_DELETE_ELEMENT',
445
                    __METHOD__
446
                );
447
                /** @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...
448
                $asset = $event->element;
449
                // Purge the URL
450
                $purgeUrl = ImageOptimize::$plugin->transformMethod->getPurgeUrl($asset);
451
                if ($purgeUrl) {
452
                    ImageOptimize::$plugin->transformMethod->purgeUrl($purgeUrl);
453
                }
454
            }
455
        );
456
    }
457
458
    /**
459
     * Install our miscellaneous event handlers
460
     */
0 ignored issues
show
Coding Style introduced by
Missing @return tag in function comment
Loading history...
461
    protected function installMiscEventHandlers(): void
462
    {
463
        // Handler: Fields::EVENT_AFTER_SAVE_FIELD
464
        Event::on(
465
            Fields::class,
466
            Fields::EVENT_AFTER_SAVE_FIELD,
467
            function(FieldEvent $event) {
0 ignored issues
show
Coding Style introduced by
Expected 1 space after FUNCTION keyword; 0 found
Loading history...
468
                Craft::debug(
469
                    'Fields::EVENT_AFTER_SAVE_FIELD',
470
                    __METHOD__
471
                );
472
                /** @var Settings $settings */
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...
473
                $settings = $this->getSettings();
474
                if (!$event->isNew && $settings->automaticallyResaveImageVariants) {
475
                    $this->checkForOptimizedImagesField($event);
476
                }
477
            }
478
        );
479
480
        // Handler: Plugins::EVENT_AFTER_SAVE_PLUGIN_SETTINGS
481
        Event::on(
482
            Plugins::class,
483
            Plugins::EVENT_AFTER_SAVE_PLUGIN_SETTINGS,
484
            function(PluginEvent $event) {
0 ignored issues
show
Coding Style introduced by
Expected 1 space after FUNCTION keyword; 0 found
Loading history...
485
                if ($event->plugin === $this) {
0 ignored issues
show
introduced by
The condition $event->plugin === $this is always false.
Loading history...
486
                    Craft::debug(
487
                        'Plugins::EVENT_AFTER_SAVE_PLUGIN_SETTINGS',
488
                        __METHOD__
489
                    );
490
                    /** @var ?Settings $settings */
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...
491
                    $settings = $this->getSettings();
492
                    if (($settings !== null) && $settings->automaticallyResaveImageVariants) {
493
                        // After they have changed the settings, resave all the assets
494
                        ImageOptimize::$plugin->optimizedImages->resaveAllVolumesAssets();
495
                    }
496
                }
497
            }
498
        );
499
500
        // Handler: Volumes::EVENT_AFTER_SAVE_VOLUME
501
        Event::on(
502
            Volumes::class,
503
            Volumes::EVENT_AFTER_SAVE_VOLUME,
504
            function(VolumeEvent $event) {
0 ignored issues
show
Coding Style introduced by
Expected 1 space after FUNCTION keyword; 0 found
Loading history...
505
                Craft::debug(
506
                    'Volumes::EVENT_AFTER_SAVE_VOLUME',
507
                    __METHOD__
508
                );
509
                /** @var ?Settings $settings */
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...
510
                $settings = $this->getSettings();
511
                // Only worry about this volume if it's not new
512
                if (($settings !== null) && !$event->isNew && $settings->automaticallyResaveImageVariants) {
513
                    $volume = $event->volume;
514
                    ImageOptimize::$plugin->optimizedImages->resaveVolumeAssets($volume);
515
                }
516
            }
517
        );
518
519
        // Handler: Plugins::EVENT_AFTER_INSTALL_PLUGIN
520
        Event::on(
521
            Plugins::class,
522
            Plugins::EVENT_AFTER_INSTALL_PLUGIN,
523
            function(PluginEvent $event) {
0 ignored issues
show
Coding Style introduced by
Expected 1 space after FUNCTION keyword; 0 found
Loading history...
524
                if ($event->plugin === $this) {
0 ignored issues
show
introduced by
The condition $event->plugin === $this is always false.
Loading history...
525
                    $request = Craft::$app->getRequest();
526
                    if ($request->isCpRequest) {
527
                        Craft::$app->getResponse()->redirect(UrlHelper::cpUrl('image-optimize/welcome'))->send();
528
                    }
529
                }
530
            }
531
        );
532
    }
533
534
    /**
535
     * Install site event listeners for site requests only
536
     */
0 ignored issues
show
Coding Style introduced by
Missing @return tag in function comment
Loading history...
537
    protected function installSiteEventListeners(): void
538
    {
539
        // Handler: UrlManager::EVENT_REGISTER_SITE_URL_RULES
540
        Event::on(
541
            UrlManager::class,
542
            UrlManager::EVENT_REGISTER_SITE_URL_RULES,
543
            function(RegisterUrlRulesEvent $event) {
0 ignored issues
show
Coding Style introduced by
Expected 1 space after FUNCTION keyword; 0 found
Loading history...
544
                Craft::debug(
545
                    'UrlManager::EVENT_REGISTER_SITE_URL_RULES',
546
                    __METHOD__
547
                );
548
                // Register our Control Panel routes
549
                $event->rules = array_merge(
550
                    $event->rules,
551
                    $this->customFrontendRoutes()
552
                );
553
            }
554
        );
555
    }
556
557
    /**
558
     * Install site event listeners for cp requests only
559
     */
0 ignored issues
show
Coding Style introduced by
Missing @return tag in function comment
Loading history...
560
    protected function installCpEventListeners(): void
561
    {
562
        // Handler: Plugins::EVENT_AFTER_LOAD_PLUGINS
563
        Event::on(
564
            Plugins::class,
565
            Plugins::EVENT_AFTER_LOAD_PLUGINS,
566
            static function() {
0 ignored issues
show
Coding Style introduced by
Expected 1 space after FUNCTION keyword; 0 found
Loading history...
567
                // Install these only after all other plugins have loaded
568
                Event::on(
569
                    View::class,
570
                    View::EVENT_REGISTER_CP_TEMPLATE_ROOTS,
571
                    static function(RegisterTemplateRootsEvent $e) {
0 ignored issues
show
Coding Style introduced by
Expected 1 space after FUNCTION keyword; 0 found
Loading history...
572
                        // Register the root directodies
573
                        $allImageTransformTypes = ImageOptimize::$plugin->optimize->getAllImageTransformTypes();
574
                        /** @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...
575
                        foreach ($allImageTransformTypes as $imageTransformType) {
576
                            [$id, $baseDir] = $imageTransformType::getTemplatesRoot();
577
                            if (is_dir($baseDir)) {
578
                                $e->roots[$id] = $baseDir;
579
                            }
580
                        }
581
                    }
582
                );
583
            }
584
        );
585
    }
586
587
    /**
588
     * Return the custom frontend routes
589
     *
590
     * @return array
591
     */
592
    protected function customFrontendRoutes(): array
593
    {
594
        return [
595
        ];
596
    }
597
598
    /**
599
     * If the Field being saved is an OptimizedImages field, re-save the
600
     * responsive image variants automatically
601
     *
602
     * @param FieldEvent $event
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
603
     */
0 ignored issues
show
Coding Style introduced by
Missing @return tag in function comment
Loading history...
604
    protected function checkForOptimizedImagesField(FieldEvent $event): void
605
    {
606
        $thisField = $event->field;
607
        if ($thisField instanceof OptimizedImages) {
608
            $volumes = Craft::$app->getVolumes()->getAllVolumes();
609
            foreach ($volumes as $volume) {
610
                $needToReSave = false;
611
                /** @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
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...
612
                $fieldLayout = $volume->getFieldLayout();
613
                // Loop through the fields in the layout to see if it contains our field
614
                if ($fieldLayout) {
615
                    $fields = $fieldLayout->getCustomFields();
616
                    foreach ($fields as $field) {
617
                        /** @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...
618
                        if ($thisField->handle === $field->handle) {
619
                            $needToReSave = true;
620
                        }
621
                    }
622
                    if ($needToReSave) {
623
                        self::$plugin->optimizedImages->resaveVolumeAssets($volume, $thisField->id);
624
                    }
625
                }
626
            }
627
        }
628
    }
629
}
630