Passed
Push — develop ( 56bf7e...bfabc0 )
by Andrew
04:58
created

OptimizedImages::getContentColumnType()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 3
rs 10
c 0
b 0
f 0
cc 1
eloc 1
nc 1
nop 0
1
<?php
2
/**
3
 * Image Optimize 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\fields;
12
13
use nystudio107\imageoptimize\ImageOptimize;
14
use nystudio107\imageoptimize\fields\OptimizedImages as OptimizedImagesField;
15
use nystudio107\imageoptimize\gql\types\generators\OptimizedImagesGenerator;
16
use nystudio107\imageoptimize\assetbundles\imageoptimize\ImageOptimizeAsset;
17
use nystudio107\imageoptimize\helpers\Manifest as ManifestHelper;
18
use nystudio107\imageoptimize\variables\ManifestVariable;
19
use nystudio107\imageoptimize\models\OptimizedImage;
20
21
use Craft;
22
use craft\base\ElementInterface;
23
use craft\base\Field;
24
use craft\base\Volume;
25
use craft\elements\Asset;
26
use craft\fields\Matrix;
27
use craft\helpers\Html;
28
use craft\helpers\Json;
29
use craft\models\FieldLayout;
30
use craft\validators\ArrayValidator;
31
32
use yii\base\InvalidConfigException;
33
use yii\db\Exception;
34
use yii\db\Schema;
35
36
use verbb\supertable\fields\SuperTableField;
0 ignored issues
show
Bug introduced by
The type verbb\supertable\fields\SuperTableField 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...
37
38
/** @noinspection MissingPropertyAnnotationsInspection */
0 ignored issues
show
Coding Style introduced by
The open comment tag must be the only content on the line
Loading history...
Coding Style introduced by
Missing short description in doc comment
Loading history...
Coding Style introduced by
The close comment tag must be the only content on the line
Loading history...
39
40
/**
0 ignored issues
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
41
 * @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...
42
 * @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...
43
 * @since     1.2.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...
44
 */
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...
45
class OptimizedImages extends Field
46
{
47
    // Constants
48
    // =========================================================================
49
50
    const DEFAULT_ASPECT_RATIOS = [
51
        ['x' => 16, 'y' => 9],
52
    ];
53
    const DEFAULT_IMAGE_VARIANTS = [
54
        [
55
            'width'          => 1200,
56
            'useAspectRatio' => true,
57
            'aspectRatioX'   => 16.0,
58
            'aspectRatioY'   => 9.0,
59
            'retinaSizes'    => ['1'],
60
            'quality'        => 82,
61
            'format'         => 'jpg',
62
        ],
63
    ];
64
65
    // Public Properties
66
    // =========================================================================
67
68
    /**
0 ignored issues
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
69
     * @var array
70
     */
71
    public $fieldVolumeSettings = [];
72
73
    /**
0 ignored issues
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
74
     * @var array
75
     */
76
    public $ignoreFilesOfType = [];
77
78
    /**
0 ignored issues
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
79
     * @var bool
80
     */
81
    public $displayOptimizedImageVariants = true;
82
83
    /**
0 ignored issues
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
84
     * @var bool
85
     */
86
    public $displayDominantColorPalette = true;
87
88
    /**
0 ignored issues
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
89
     * @var bool
90
     */
91
    public $displayLazyLoadPlaceholderImages = true;
92
93
    /**
0 ignored issues
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
94
     * @var array
95
     */
96
    public $variants = [];
97
98
    // Private Properties
99
    // =========================================================================
100
101
    /**
0 ignored issues
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
102
     * @var array
103
     */
104
    private $aspectRatios = [];
0 ignored issues
show
Coding Style introduced by
Private member variable "aspectRatios" must be prefixed with an underscore
Loading history...
105
106
    // Static Methods
107
    // =========================================================================
108
109
    /**
0 ignored issues
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
Coding Style introduced by
Parameter $config should have a doc-comment as per coding-style.
Loading history...
110
     * @inheritdoc
111
     */
112
    public function __construct(array $config = [])
113
    {
114
        // Unset any deprecated properties
115
        if (!empty($config)) {
116
            unset($config['transformMethod'], $config['imgixDomain']);
117
        }
118
        parent::__construct($config);
119
    }
120
121
    // Public Methods
122
    // =========================================================================
123
124
    /**
0 ignored issues
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
125
     * @inheritdoc
126
     */
0 ignored issues
show
Coding Style introduced by
Missing @return tag in function comment
Loading history...
127
    public static function displayName(): string
128
    {
129
        return 'OptimizedImages';
130
    }
131
132
    /**
0 ignored issues
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
133
     * @inheritdoc
134
     */
0 ignored issues
show
Coding Style introduced by
Missing @return tag in function comment
Loading history...
135
    public function init()
136
    {
137
        parent::init();
138
139
        // Handle cases where the plugin has been uninstalled
140
        if (ImageOptimize::$plugin !== null) {
141
            $settings = ImageOptimize::$plugin->getSettings();
142
            if ($settings) {
0 ignored issues
show
introduced by
$settings is of type nystudio107\imageoptimize\models\Settings, thus it always evaluated to true.
Loading history...
143
                if (empty($this->variants)) {
144
                    $this->variants = $settings->defaultVariants;
145
                }
146
                $this->aspectRatios = $settings->defaultAspectRatios;
147
            }
148
        }
149
        // If the user has deleted all default aspect ratios, provide a fallback
150
        if (empty($this->aspectRatios)) {
151
            $this->aspectRatios = self::DEFAULT_ASPECT_RATIOS;
152
        }
153
        // If the user has deleted all default variants, provide a fallback
154
        if (empty($this->variants)) {
155
            $this->variants = self::DEFAULT_IMAGE_VARIANTS;
156
        }
157
    }
158
159
    /**
0 ignored issues
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
160
     * @inheritdoc
161
     */
0 ignored issues
show
Coding Style introduced by
Missing @return tag in function comment
Loading history...
162
    public function rules()
163
    {
164
        $rules = parent::rules();
165
        $rules = array_merge($rules, [
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...
166
            [
167
                [
168
                    'displayOptimizedImageVariants',
169
                    'displayDominantColorPalette',
170
                    'displayLazyLoadPlaceholderImages',
171
                ],
172
                'boolean',
173
            ],
174
            [
175
                [
176
                    'ignoreFilesOfType',
177
                    'variants',
178
                ],
179
                ArrayValidator::class
180
            ],
181
        ]);
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...
182
183
        return $rules;
184
    }
185
186
    /**
0 ignored issues
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
187
     * @inheritdoc
188
     * @since 1.6.2
0 ignored issues
show
Coding Style introduced by
Tag value for @since tag indented incorrectly; expected 6 spaces but found 1
Loading history...
189
     */
0 ignored issues
show
Coding Style introduced by
Missing @return tag in function comment
Loading history...
190
    public function getContentGqlType()
191
    {
192
        $typeArray = OptimizedImagesGenerator::generateTypes($this);
193
194
        return [
195
            'name' => $this->handle,
196
            'description' => 'Optimized Images field',
197
            'type' => array_shift($typeArray),
198
        ];
199
    }
200
201
    /**
0 ignored issues
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
202
     * @inheritdoc
203
     * @since 2.0.0
0 ignored issues
show
Coding Style introduced by
Tag value for @since tag indented incorrectly; expected 6 spaces but found 1
Loading history...
204
     */
0 ignored issues
show
Coding Style introduced by
Missing @return tag in function comment
Loading history...
205
    public function useFieldset(): bool
206
    {
207
        return true;
208
    }
209
210
    /**
0 ignored issues
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
Coding Style introduced by
Parameter $asset should have a doc-comment as per coding-style.
Loading history...
Coding Style introduced by
Parameter $isNew should have a doc-comment as per coding-style.
Loading history...
211
     * @inheritdoc
212
     */
0 ignored issues
show
Coding Style introduced by
Missing @return tag in function comment
Loading history...
213
    public function afterElementSave(ElementInterface $asset, bool $isNew)
214
    {
215
        parent::afterElementSave($asset, $isNew);
216
        // Update our OptimizedImages Field data now that the Asset has been saved
217
        if ($asset !== null && $asset instanceof Asset && $asset->id !== null) {
218
            // If this element is propagating, we don't need to redo the image saving for each site
219
            if (!$asset->propagating) {
220
                // If the scenario is Asset::SCENARIO_FILEOPS treat it as a new asset
221
                $scenario = $asset->getScenario();
222
                if ($isNew || $scenario === Asset::SCENARIO_FILEOPS ) {
223
                    /**
224
                     * If this is a newly uploaded/created Asset, we can save the variants
225
                     * via a queue job to prevent it from blocking
226
                     */
227
                    ImageOptimize::$plugin->optimizedImages->resaveAsset($asset->id);
228
                } else {
229
                    /**
230
                     * If it's not a newly uploaded/created Asset, they may have edited
231
                     * the image with the ImageEditor, so we need to update the variants
232
                     * immediately, so the AssetSelectorHud displays the new images
233
                     */
234
                    try {
235
                        ImageOptimize::$plugin->optimizedImages->updateOptimizedImageFieldData($this, $asset);
236
                    } catch (Exception $e) {
237
                        Craft::error($e->getMessage(), __METHOD__);
238
                    }
239
                }
240
            }
241
        }
242
    }
243
244
    /**
0 ignored issues
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
Coding Style introduced by
Parameter $value should have a doc-comment as per coding-style.
Loading history...
Coding Style introduced by
Parameter $asset should have a doc-comment as per coding-style.
Loading history...
245
     * @inheritdoc
246
     */
0 ignored issues
show
Coding Style introduced by
Missing @return tag in function comment
Loading history...
247
    public function normalizeValue($value, ElementInterface $asset = null)
248
    {
249
        // If we're passed in a string, assume it's JSON-encoded, and decode it
250
        if (\is_string($value) && !empty($value)) {
251
            $value = Json::decodeIfJson($value);
252
        }
253
        // If we're passed in an array, make a model from it
254
        if (\is_array($value)) {
255
            // Create a new OptimizedImage model and populate it
256
            $model = new OptimizedImage($value);
257
        } elseif ($value instanceof OptimizedImage) {
258
            $model = $value;
259
        } else {
260
            // Just create a new empty model
261
            $model = new OptimizedImage(null);
262
        }
263
264
        return $model;
265
    }
266
267
    /**
0 ignored issues
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
268
     * @inheritdoc
269
     */
0 ignored issues
show
Coding Style introduced by
Missing @return tag in function comment
Loading history...
270
    public function getContentColumnType(): string
271
    {
272
        return Schema::TYPE_TEXT;
273
    }
274
275
    /**
0 ignored issues
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
276
     * @inheritdoc
277
     */
0 ignored issues
show
Coding Style introduced by
Missing @return tag in function comment
Loading history...
278
    public function getSettingsHtml()
279
    {
280
        $namespace = Craft::$app->getView()->getNamespace();
281
        if (strpos($namespace, Matrix::class) !== false || strpos($namespace, SuperTableField::class) !== false) {
282
            // Render an error template, since the field only works when attached to an Asset
283
            try {
284
                return Craft::$app->getView()->renderTemplate(
285
                    'image-optimize/_components/fields/OptimizedImages_error',
286
                    [
287
                    ]
288
                );
289
            } catch (\Twig\Error\LoaderError $e) {
290
                Craft::error($e->getMessage(), __METHOD__);
291
            } catch (\yii\base\Exception $e) {
292
                Craft::error($e->getMessage(), __METHOD__);
293
            }
294
        }
295
296
        try {
297
            $reflect = new \ReflectionClass($this);
298
            $thisId = $reflect->getShortName();
299
        } catch (\ReflectionException $e) {
300
            Craft::error($e->getMessage(), __METHOD__);
301
            $thisId = 0;
302
        }
303
        // Get our id and namespace
304
        if (ImageOptimize::$craft35) {
305
            $id = Html::id($thisId);
306
        } else {
307
            $id = Craft::$app->getView()->formatInputId($thisId);
308
        }
309
        $namespacedId = Craft::$app->getView()->namespaceInputId($id);
310
        $namespacePrefix = Craft::$app->getView()->namespaceInputName($thisId);
311
        $sizesWrapperId = Craft::$app->getView()->namespaceInputId('sizes-wrapper');
312
        Craft::$app->getView()->registerJs('new Craft.OptimizedImagesInput('.
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...
313
            '"'.$namespacedId.'", '.
314
            '"'.$namespacePrefix.'",'.
315
            '"'.$sizesWrapperId.'"'.
316
            ');');
0 ignored issues
show
Coding Style introduced by
This line of the multi-line function call does not seem to be indented correctly. Expected 8 spaces, but found 12.
Loading history...
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...
317
318
        // Prep our aspect ratios
319
        $aspectRatios = [];
320
        $index = 1;
321
        foreach ($this->aspectRatios as $aspectRatio) {
322
            if ($index % 6 === 0) {
323
                $aspectRatio['break'] = true;
324
            }
325
            $aspectRatios[] = $aspectRatio;
326
            $index++;
327
        }
328
        $aspectRatio = ['x' => 2, 'y' => 2, 'custom' => true];
329
        $aspectRatios[] = $aspectRatio;
330
        // Get only the user-editable settings
331
        $settings = ImageOptimize::$plugin->getSettings();
332
333
        // Register our CSS
334
        $cssModules = [
335
            'vendors.css',
336
            'styles.css',
337
        ];
338
        foreach($cssModules as $cssModule) {
0 ignored issues
show
Coding Style introduced by
Expected "foreach (...) {\n"; found "foreach(...) {\n"
Loading history...
339
            $css = ManifestHelper::getModule(ManifestVariable::$config, $cssModule, 'legacy', true);
340
            if ($css) {
341
                Craft::$app->getView()->registerCssFile($css);
342
            }
343
        }
344
345
        // Render the settings template
346
        try {
347
            return Craft::$app->getView()->renderTemplate(
348
                'image-optimize/_components/fields/OptimizedImages_settings',
349
                [
350
                    'field'        => $this,
351
                    'settings'     => $settings,
352
                    'aspectRatios' => $aspectRatios,
353
                    'id'           => $id,
354
                    'name'         => $this->handle,
355
                    'namespace'    => $namespacedId,
356
                    'fieldVolumes' => $this->getFieldVolumeInfo($this->handle),
357
                ]
358
            );
359
        } catch (\Twig\Error\LoaderError $e) {
360
            Craft::error($e->getMessage(), __METHOD__);
361
        } catch (\yii\base\Exception $e) {
362
            Craft::error($e->getMessage(), __METHOD__);
363
        }
364
365
        return '';
366
    }
367
368
    /**
0 ignored issues
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
Coding Style introduced by
Parameter $value should have a doc-comment as per coding-style.
Loading history...
Coding Style introduced by
Parameter $element should have a doc-comment as per coding-style.
Loading history...
369
     * @inheritdoc
370
     */
0 ignored issues
show
Coding Style introduced by
Missing @return tag in function comment
Loading history...
371
    public function getInputHtml($value, ElementInterface $element = null): string
372
    {
373
        if ($element !== null && $element instanceof Asset && $this->handle !== null) {
374
            /** @var Asset $element */
0 ignored issues
show
Coding Style introduced by
The open comment tag must be the only content on the line
Loading history...
Coding Style introduced by
Missing short description in doc comment
Loading history...
Coding Style introduced by
The close comment tag must be the only content on the line
Loading history...
375
            // Register our asset bundle
376
            try {
377
                Craft::$app->getView()->registerAssetBundle(ImageOptimizeAsset::class);
378
            } catch (InvalidConfigException $e) {
379
                Craft::error($e->getMessage(), __METHOD__);
380
            }
381
382
            // Get our id and namespace
383
            if (ImageOptimize::$craft35) {
384
                $id = Html::id($this->handle);
385
            } else {
386
                $id = Craft::$app->getView()->formatInputId($this->handle);
387
            }
388
            $nameSpaceId = Craft::$app->getView()->namespaceInputId($id);
389
390
            // Variables to pass down to our field JavaScript to let it namespace properly
391
            $jsonVars = [
392
                'id'        => $id,
393
                'name'      => $this->handle,
394
                'namespace' => $nameSpaceId,
395
                'prefix'    => Craft::$app->getView()->namespaceInputId(''),
396
            ];
397
            $jsonVars = Json::encode($jsonVars);
398
            $view = Craft::$app->getView();
399
            $view->registerJs("$('#{$nameSpaceId}-field').ImageOptimizeOptimizedImages(".$jsonVars.");");
400
401
            $settings = ImageOptimize::$plugin->getSettings();
402
            $createVariants = ImageOptimize::$plugin->optimizedImages->shouldCreateVariants($this, $element);
403
404
            // Register our CSS
405
            $cssModules = [
406
                'vendors.css',
407
                'styles.css',
408
            ];
409
            foreach($cssModules as $cssModule) {
0 ignored issues
show
Coding Style introduced by
Expected "foreach (...) {\n"; found "foreach(...) {\n"
Loading history...
410
                $css = ManifestHelper::getModule(ManifestVariable::$config, $cssModule, 'legacy', true);
411
                if ($css) {
412
                    Craft::$app->getView()->registerCssFile($css);
413
                }
414
            }
415
416
            // Render the input template
417
            try {
418
                return Craft::$app->getView()->renderTemplate(
419
                    'image-optimize/_components/fields/OptimizedImages_input',
420
                    [
421
                        'name'           => $this->handle,
422
                        'value'          => $value,
423
                        'variants'       => $this->variants,
424
                        'field'          => $this,
425
                        'settings'       => $settings,
426
                        'elementId'      => $element->id,
427
                        'format'         => $element->getExtension(),
428
                        'id'             => $id,
429
                        'nameSpaceId'    => $nameSpaceId,
430
                        'createVariants' => $createVariants,
431
                    ]
432
                );
433
            } catch (\Twig\Error\LoaderError $e) {
434
                Craft::error($e->getMessage(), __METHOD__);
435
            } catch (\yii\base\Exception $e) {
436
                Craft::error($e->getMessage(), __METHOD__);
437
            }
438
        }
439
440
        // Render an error template, since the field only works when attached to an Asset
441
        try {
442
            return Craft::$app->getView()->renderTemplate(
443
                'image-optimize/_components/fields/OptimizedImages_error',
444
                [
445
                ]
446
            );
447
        } catch (\Twig\Error\LoaderError $e) {
448
            Craft::error($e->getMessage(), __METHOD__);
449
        } catch (\yii\base\Exception $e) {
450
            Craft::error($e->getMessage(), __METHOD__);
451
        }
452
453
        return '';
454
    }
455
456
    // Protected Methods
457
    // =========================================================================
458
459
    /**
460
     * Returns an array of asset volumes and their sub-folders
461
     *
462
     * @param string|null $fieldHandle
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
463
     *
464
     * @return array
465
     * @throws InvalidConfigException
466
     */
467
    protected function getFieldVolumeInfo($fieldHandle): array
468
    {
469
        $result = [];
470
        if ($fieldHandle !== null) {
471
            $volumes = Craft::$app->getVolumes()->getAllVolumes();
472
            $assets = Craft::$app->getAssets();
473
            foreach ($volumes as $volume) {
474
                if (is_subclass_of($volume, Volume::class)) {
475
                    /** @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...
476
                    if ($this->volumeHasField($volume, $fieldHandle)) {
477
                        $tree = $assets->getFolderTreeByVolumeIds([$volume->id]);
478
                        $result[] = [
479
                            'name' => $volume->name,
480
                            'handle' => $volume->handle,
481
                            'subfolders' => $this->assembleSourceList($tree),
482
                        ];
483
                    }
484
                }
485
            }
486
        }
487
488
        return $result;
489
    }
490
491
    /**
492
     * See if the passed $volume has an OptimizedImagesField with the handle $fieldHandle
493
     *
494
     * @param Volume $volume
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
495
     *
496
     * @param string $fieldHandle
0 ignored issues
show
Coding Style introduced by
Parameter tags must be grouped together in a doc comment
Loading history...
Coding Style introduced by
Missing parameter comment
Loading history...
497
     *
498
     * @return bool
499
     * @throws InvalidConfigException
500
     */
501
    protected function volumeHasField(Volume $volume, string $fieldHandle): bool
502
    {
503
        $result = false;
504
        /** @var FieldLayout $fieldLayout */
0 ignored issues
show
Coding Style introduced by
The open comment tag must be the only content on the line
Loading history...
Coding Style introduced by
Missing short description in doc comment
Loading history...
Coding Style introduced by
The close comment tag must be the only content on the line
Loading history...
505
        $fieldLayout = $volume->getFieldLayout();
506
        // Loop through the fields in the layout to see if there is an OptimizedImages field
507
        if ($fieldLayout) {
0 ignored issues
show
introduced by
$fieldLayout is of type craft\models\FieldLayout, thus it always evaluated to true.
Loading history...
508
            $fields = $fieldLayout->getFields();
509
            foreach ($fields as $field) {
510
                if ($field instanceof OptimizedImagesField && $field->handle === $fieldHandle) {
511
                    $result = true;
512
                }
513
            }
514
        }
515
516
        return $result;
517
    }
518
519
    /**
520
     * Transforms an asset folder tree into a source list.
521
     *
522
     * @param array $folders
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
523
     * @param bool  $includeNestedFolders
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
524
     *
525
     * @return array
526
     */
527
    protected function assembleSourceList(array $folders, bool $includeNestedFolders = true): array
528
    {
529
        $sources = [];
530
531
        foreach ($folders as $folder) {
532
            $children = $folder->getChildren();
533
            foreach ($children as $child) {
534
                $sources[$child->uid] = $child->name;
535
            }
536
        }
537
538
        return $sources;
539
    }
540
}
541