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
![]() |
|||||||
8 | * @copyright Copyright (c) 2017 nystudio107 |
||||||
0 ignored issues
–
show
|
|||||||
9 | */ |
||||||
0 ignored issues
–
show
|
|||||||
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
|
|||||||
60 | |||||||
61 | /** |
||||||
62 | * Class ImageOptimize |
||||||
63 | * |
||||||
64 | * @author nystudio107 |
||||||
0 ignored issues
–
show
Content of the @author tag must be in the form "Display Name <[email protected]>"
![]() |
|||||||
65 | * @package ImageOptimize |
||||||
0 ignored issues
–
show
|
|||||||
66 | * @since 1.0.0 |
||||||
0 ignored issues
–
show
|
|||||||
67 | * |
||||||
68 | * @property ImageTransformInterface $transformMethod |
||||||
69 | */ |
||||||
0 ignored issues
–
show
|
|||||||
70 | class ImageOptimize extends Plugin |
||||||
71 | { |
||||||
72 | // Traits |
||||||
73 | // ========================================================================= |
||||||
74 | |||||||
75 | use ServicesTrait; |
||||||
76 | |||||||
77 | // Static Properties |
||||||
78 | // ========================================================================= |
||||||
79 | |||||||
80 | /** |
||||||
0 ignored issues
–
show
|
|||||||
81 | * @var ?ImageOptimize |
||||||
82 | */ |
||||||
83 | public static ?ImageOptimize $plugin = null; |
||||||
84 | |||||||
85 | /** |
||||||
0 ignored issues
–
show
|
|||||||
86 | * @var bool |
||||||
87 | */ |
||||||
88 | public static bool $generatePlaceholders = true; |
||||||
89 | |||||||
90 | // Public Properties |
||||||
91 | // ========================================================================= |
||||||
92 | /** |
||||||
0 ignored issues
–
show
|
|||||||
93 | * @var string |
||||||
94 | */ |
||||||
95 | public string $schemaVersion = '1.0.0'; |
||||||
96 | |||||||
97 | /** |
||||||
0 ignored issues
–
show
|
|||||||
98 | * @var bool |
||||||
99 | */ |
||||||
100 | public bool $hasCpSection = false; |
||||||
101 | |||||||
102 | /** |
||||||
0 ignored issues
–
show
|
|||||||
103 | * @var bool |
||||||
104 | */ |
||||||
105 | public bool $hasCpSettings = true; |
||||||
106 | |||||||
107 | // Public Methods |
||||||
108 | // ========================================================================= |
||||||
109 | |||||||
110 | /** |
||||||
0 ignored issues
–
show
|
|||||||
111 | * @inheritdoc |
||||||
112 | */ |
||||||
0 ignored issues
–
show
|
|||||||
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
|
|||||||
140 | * @inheritdoc |
||||||
141 | */ |
||||||
0 ignored issues
–
show
|
|||||||
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
|
|||||||
150 | $controller = Craft::$app->controller; |
||||||
0 ignored issues
–
show
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 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;
}
![]() |
|||||||
151 | |||||||
152 | return $controller->renderTemplate('image-optimize/settings/index.twig', [ |
||||||
0 ignored issues
–
show
|
|||||||
153 | 'plugin' => $this, |
||||||
154 | 'settingsHtml' => $settingsHtml, |
||||||
155 | ]); |
||||||
0 ignored issues
–
show
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.
![]() |
|||||||
156 | } |
||||||
157 | |||||||
158 | /** |
||||||
0 ignored issues
–
show
|
|||||||
159 | * @inheritdoc |
||||||
160 | */ |
||||||
0 ignored issues
–
show
|
|||||||
161 | public function settingsHtml(): ?string |
||||||
162 | { |
||||||
163 | // Get only the user-editable settings |
||||||
164 | /** @var Settings $settings */ |
||||||
0 ignored issues
–
show
|
|||||||
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
|
|||||||
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
|
|||||||
205 | * @inheritdoc |
||||||
206 | */ |
||||||
0 ignored issues
–
show
|
|||||||
207 | protected function createSettingsModel(): ?Model |
||||||
208 | { |
||||||
209 | return new Settings(); |
||||||
210 | } |
||||||
211 | |||||||
212 | /** |
||||||
213 | * Set the transformMethod component |
||||||
214 | */ |
||||||
0 ignored issues
–
show
|
|||||||
215 | protected function setImageTransformComponent(): void |
||||||
216 | { |
||||||
217 | /** @var Settings $settings */ |
||||||
0 ignored issues
–
show
|
|||||||
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
|
|||||||
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
|
|||||||
240 | /** @var CraftVariable $variable */ |
||||||
0 ignored issues
–
show
|
|||||||
241 | $variable = $event->sender; |
||||||
242 | $variable->set('imageOptimize', [ |
||||||
0 ignored issues
–
show
|
|||||||
243 | 'class' => ImageOptimizeVariable::class, |
||||||
244 | 'viteService' => $this->vite, |
||||||
245 | ]); |
||||||
0 ignored issues
–
show
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.
![]() |
|||||||
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
|
|||||||
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
|
|||||||
268 | $event->types[] = ImageOptimizeUtility::class; |
||||||
269 | } |
||||||
270 | ); |
||||||
271 | } |
||||||
272 | } |
||||||
273 | |||||||
274 | /** |
||||||
275 | * Install our event handlers |
||||||
276 | */ |
||||||
0 ignored issues
–
show
|
|||||||
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
|
|||||||
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
|
|||||||
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
|
|||||||
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
|
|||||||
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
|
|||||||
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
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
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.');
}
![]() 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
![]() |
|||||||
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
|
|||||||
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
|
|||||||
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
|
|||||||
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
|
|||||||
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
|
|||||||
422 | Craft::debug( |
||||||
423 | 'Elements::EVENT_BEFORE_SAVE_ELEMENT', |
||||||
424 | __METHOD__ |
||||||
425 | ); |
||||||
426 | /** @var Asset $asset */ |
||||||
0 ignored issues
–
show
|
|||||||
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
|
|||||||
443 | Craft::debug( |
||||||
444 | 'Elements::EVENT_BEFORE_DELETE_ELEMENT', |
||||||
445 | __METHOD__ |
||||||
446 | ); |
||||||
447 | /** @var Asset $asset */ |
||||||
0 ignored issues
–
show
|
|||||||
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
|
|||||||
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
|
|||||||
468 | Craft::debug( |
||||||
469 | 'Fields::EVENT_AFTER_SAVE_FIELD', |
||||||
470 | __METHOD__ |
||||||
471 | ); |
||||||
472 | /** @var Settings $settings */ |
||||||
0 ignored issues
–
show
|
|||||||
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
|
|||||||
485 | if ($event->plugin === $this) { |
||||||
0 ignored issues
–
show
|
|||||||
486 | Craft::debug( |
||||||
487 | 'Plugins::EVENT_AFTER_SAVE_PLUGIN_SETTINGS', |
||||||
488 | __METHOD__ |
||||||
489 | ); |
||||||
490 | /** @var ?Settings $settings */ |
||||||
0 ignored issues
–
show
|
|||||||
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
|
|||||||
505 | Craft::debug( |
||||||
506 | 'Volumes::EVENT_AFTER_SAVE_VOLUME', |
||||||
507 | __METHOD__ |
||||||
508 | ); |
||||||
509 | /** @var ?Settings $settings */ |
||||||
0 ignored issues
–
show
|
|||||||
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
|
|||||||
524 | if ($event->plugin === $this) { |
||||||
0 ignored issues
–
show
|
|||||||
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
|
|||||||
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
|
|||||||
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
|
|||||||
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
|
|||||||
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
|
|||||||
572 | // Register the root directodies |
||||||
573 | $allImageTransformTypes = ImageOptimize::$plugin->optimize->getAllImageTransformTypes(); |
||||||
574 | /** @var ImageTransformInterface $imageTransformType */ |
||||||
0 ignored issues
–
show
|
|||||||
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
|
|||||||
603 | */ |
||||||
0 ignored issues
–
show
|
|||||||
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
|
|||||||
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
|
|||||||
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 |