Passed
Push — develop ( 1fd00d...bbfe99 )
by Andrew
04:32
created

OptimizedImages::getSettingsHtml()   B

Complexity

Conditions 9
Paths 82

Size

Total Lines 65
Code Lines 44

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 44
dl 0
loc 65
rs 7.6604
c 0
b 0
f 0
cc 9
nc 82
nop 0

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

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 craft\fields\Matrix;
14
use nystudio107\imageoptimize\assetbundles\optimizedimagesfield\OptimizedImagesFieldAsset;
15
use nystudio107\imageoptimize\ImageOptimize;
16
use nystudio107\imageoptimize\models\OptimizedImage;
17
18
use Craft;
19
use craft\base\ElementInterface;
20
use craft\base\Field;
21
use craft\elements\Asset;
22
use craft\helpers\Json;
23
use craft\validators\ArrayValidator;
24
25
use yii\base\InvalidConfigException;
26
use yii\db\Exception;
27
use yii\db\Schema;
28
29
/** @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...
30
31
/**
0 ignored issues
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
32
 * @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...
33
 * @package   ImageOptimize
34
 * @since     1.2.0
0 ignored issues
show
Coding Style introduced by
The tag in position 3 should be the @author tag
Loading history...
35
 */
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...
36
class OptimizedImages extends Field
37
{
38
    // Constants
39
    // =========================================================================
40
41
    const DEFAULT_ASPECT_RATIOS = [
42
        ['x' => 16, 'y' => 9],
43
    ];
44
    const DEFAULT_IMAGE_VARIANTS = [
45
        [
46
            'width'          => 1200,
47
            'useAspectRatio' => true,
48
            'aspectRatioX'   => 16.0,
49
            'aspectRatioY'   => 9.0,
50
            'retinaSizes'    => ['1'],
51
            'quality'        => 82,
52
            'format'         => 'jpg',
53
        ],
54
    ];
55
56
    // Public Properties
57
    // =========================================================================
58
59
    /**
0 ignored issues
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
60
     * @var bool
61
     */
62
    public $displayOptimizedImageVariants = true;
63
64
    /**
0 ignored issues
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
65
     * @var bool
66
     */
67
    public $displayDominantColorPalette = true;
68
69
    /**
0 ignored issues
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
70
     * @var bool
71
     */
72
    public $displayLazyLoadPlaceholderImages = true;
73
74
    /**
0 ignored issues
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
75
     * @var array
76
     */
77
    public $variants = [];
78
79
    // Private Properties
80
    // =========================================================================
81
82
    /**
0 ignored issues
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
83
     * @var array
84
     */
85
    private $aspectRatios = [];
0 ignored issues
show
Coding Style introduced by
Private member variable "aspectRatios" must be prefixed with an underscore
Loading history...
86
87
    // Static Methods
88
    // =========================================================================
89
90
    /**
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...
91
     * @inheritdoc
92
     */
93
    public function __construct(array $config = [])
94
    {
95
        // Unset any deprecated properties
96
        if (!empty($config)) {
97
            unset($config['transformMethod'], $config['imgixDomain']);
98
        }
99
        parent::__construct($config);
100
    }
101
102
    // Public Methods
103
    // =========================================================================
104
105
    /**
0 ignored issues
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
106
     * @inheritdoc
107
     */
0 ignored issues
show
Coding Style introduced by
Missing @return tag in function comment
Loading history...
108
    public static function displayName(): string
109
    {
110
        return 'OptimizedImages';
111
    }
112
113
    /**
0 ignored issues
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
114
     * @inheritdoc
115
     */
0 ignored issues
show
Coding Style introduced by
Missing @return tag in function comment
Loading history...
116
    public function init()
117
    {
118
        parent::init();
119
120
        // Handle cases where the plugin has been uninstalled
121
        if (ImageOptimize::$plugin !== null) {
122
            $settings = ImageOptimize::$plugin->getSettings();
123
            if ($settings) {
0 ignored issues
show
introduced by
$settings is of type nystudio107\imageoptimize\models\Settings, thus it always evaluated to true.
Loading history...
124
                if (empty($this->variants)) {
125
                    $this->variants = $settings->defaultVariants;
126
                }
127
                $this->aspectRatios = $settings->defaultAspectRatios;
128
            }
129
        }
130
        // If the user has deleted all default aspect ratios, provide a fallback
131
        if (empty($this->aspectRatios)) {
132
            $this->aspectRatios = self::DEFAULT_ASPECT_RATIOS;
133
        }
134
        // If the user has deleted all default variants, provide a fallback
135
        if (empty($this->variants)) {
136
            $this->variants = self::DEFAULT_IMAGE_VARIANTS;
137
        }
138
    }
139
140
    /**
0 ignored issues
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
141
     * @inheritdoc
142
     */
0 ignored issues
show
Coding Style introduced by
Missing @return tag in function comment
Loading history...
143
    public function rules()
144
    {
145
        $rules = parent::rules();
146
        $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...
147
            ['variants', ArrayValidator::class],
148
        ]);
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...
149
150
        return $rules;
151
    }
152
153
    /**
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...
154
     * @inheritdoc
155
     */
0 ignored issues
show
Coding Style introduced by
Missing @return tag in function comment
Loading history...
156
    public function afterElementSave(ElementInterface $asset, bool $isNew)
157
    {
158
        parent::afterElementSave($asset, $isNew);
159
        // Update our OptimizedImages Field data now that the Asset has been saved
160
        if ($asset !== null && $asset instanceof Asset && $asset->id !== null) {
161
            // If the scenario is Asset::SCENARIO_FILEOPS or Asset::SCENARIO_ESSENTIALS treat it as a new asset
162
            $scenario = $asset->getScenario();
163
            if ($isNew || $scenario === Asset::SCENARIO_FILEOPS || $asset->propagating) {
164
                /**
165
                 * If this is a newly uploaded/created Asset, we can save the variants
166
                 * via a queue job to prevent it from blocking
167
                 */
168
                ImageOptimize::$plugin->optimizedImages->resaveAsset($asset->id);
169
            } else {
170
                /**
171
                 * If it's not a newly uploaded/created Asset, they may have edited
172
                 * the image with the ImageEditor, so we need to update the variants
173
                 * immediately, so the AssetSelectorHud displays the new images
174
                 */
175
                try {
176
                    ImageOptimize::$plugin->optimizedImages->updateOptimizedImageFieldData($this, $asset);
177
                } catch (Exception $e) {
178
                    Craft::error($e->getMessage(), __METHOD__);
179
                }
180
            }
181
        }
182
    }
183
184
    /**
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...
185
     * @inheritdoc
186
     */
0 ignored issues
show
Coding Style introduced by
Missing @return tag in function comment
Loading history...
187
    public function normalizeValue($value, ElementInterface $asset = null)
188
    {
189
        // If we're passed in a string, assume it's JSON-encoded, and decode it
190
        if (\is_string($value) && !empty($value)) {
191
            $value = Json::decodeIfJson($value);
192
        }
193
        // If we're passed in an array, make a model from it
194
        if (\is_array($value)) {
195
            // Create a new OptimizedImage model and populate it
196
            $model = new OptimizedImage($value);
197
        } elseif ($value instanceof OptimizedImage) {
198
            $model = $value;
199
        } else {
200
            // Just create a new empty model
201
            $model = new OptimizedImage(null);
202
        }
203
204
        return $model;
205
    }
206
207
    /**
0 ignored issues
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
208
     * @inheritdoc
209
     */
0 ignored issues
show
Coding Style introduced by
Missing @return tag in function comment
Loading history...
210
    public function getContentColumnType(): string
211
    {
212
        return Schema::TYPE_TEXT;
213
    }
214
215
    // Protected Methods
216
    // =========================================================================
217
218
    /**
0 ignored issues
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
219
     * @inheritdoc
220
     */
0 ignored issues
show
Coding Style introduced by
Missing @return tag in function comment
Loading history...
221
    public function getSettingsHtml()
222
    {
223
        $namespace = Craft::$app->getView()->getNamespace();
224
        if (strpos($namespace, Matrix::class) !== false) {
225
            // Render an error template, since the field only works when attached to an Asset
226
            try {
227
                return Craft::$app->getView()->renderTemplate(
228
                    'image-optimize/_components/fields/OptimizedImages_error',
229
                    [
230
                    ]
231
                );
232
            } catch (\Twig_Error_Loader $e) {
233
                Craft::error($e->getMessage(), __METHOD__);
234
            } catch (\yii\base\Exception $e) {
235
                Craft::error($e->getMessage(), __METHOD__);
236
            }
237
        }
238
239
        try {
240
            $reflect = new \ReflectionClass($this);
241
            $thisId = $reflect->getShortName();
242
        } catch (\ReflectionException $e) {
243
            Craft::error($e->getMessage(), __METHOD__);
244
            $thisId = 0;
245
        }
246
        $id = Craft::$app->getView()->formatInputId($thisId);
247
        $namespacedId = Craft::$app->getView()->namespaceInputId($id);
248
        $namespacePrefix = Craft::$app->getView()->namespaceInputName($thisId);
249
        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...
250
            '"'.$namespacedId.'", '.
251
            '"'.$namespacePrefix.'"'.
252
            ');');
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...
253
254
        // Prep our aspect ratios
255
        $aspectRatios = [];
256
        $index = 1;
257
        foreach ($this->aspectRatios as $aspectRatio) {
258
            if ($index % 6 === 0) {
259
                $aspectRatio['break'] = true;
260
            }
261
            $aspectRatios[] = $aspectRatio;
262
            $index++;
263
        }
264
        $aspectRatio = ['x' => 2, 'y' => 2, 'custom' => true];
265
        $aspectRatios[] = $aspectRatio;
266
267
        // Render the settings template
268
        try {
269
            return Craft::$app->getView()->renderTemplate(
270
                'image-optimize/_components/fields/OptimizedImages_settings',
271
                [
272
                    'field'        => $this,
273
                    'aspectRatios' => $aspectRatios,
274
                    'id'           => $id,
275
                    'name'         => $this->handle,
276
                    'namespace'    => $namespacedId,
277
                ]
278
            );
279
        } catch (\Twig_Error_Loader $e) {
280
            Craft::error($e->getMessage(), __METHOD__);
281
        } catch (\yii\base\Exception $e) {
282
            Craft::error($e->getMessage(), __METHOD__);
283
        }
284
285
        return '';
286
    }
287
288
    /**
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...
289
     * @inheritdoc
290
     */
0 ignored issues
show
Coding Style introduced by
Missing @return tag in function comment
Loading history...
291
    public function getInputHtml($value, ElementInterface $element = null): string
292
    {
293
        if ($element !== null && $element instanceof Asset && $this->handle !== null) {
294
            /** @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...
295
            // Register our asset bundle
296
            try {
297
                Craft::$app->getView()->registerAssetBundle(OptimizedImagesFieldAsset::class);
298
            } catch (InvalidConfigException $e) {
299
                Craft::error($e->getMessage(), __METHOD__);
300
            }
301
302
            // Get our id and namespace
303
            $id = Craft::$app->getView()->formatInputId($this->handle);
304
            $nameSpaceId = Craft::$app->getView()->namespaceInputId($id);
305
306
            // Variables to pass down to our field JavaScript to let it namespace properly
307
            $jsonVars = [
308
                'id'        => $id,
309
                'name'      => $this->handle,
310
                'namespace' => $nameSpaceId,
311
                'prefix'    => Craft::$app->getView()->namespaceInputId(''),
312
            ];
313
            $jsonVars = Json::encode($jsonVars);
314
            $view = Craft::$app->getView();
315
            $view->registerJs("$('#{$nameSpaceId}-field').ImageOptimizeOptimizedImages(".$jsonVars.");");
316
317
            $settings = ImageOptimize::$plugin->getSettings();
318
319
            // Render the input template
320
            try {
321
                return Craft::$app->getView()->renderTemplate(
322
                    'image-optimize/_components/fields/OptimizedImages_input',
323
                    [
324
                        'name'        => $this->handle,
325
                        'value'       => $value,
326
                        'variants'    => $this->variants,
327
                        'field'       => $this,
328
                        'settings'    => $settings,
329
                        'elementId'   => $element->id,
330
                        'format'      => $element->getExtension(),
331
                        'id'          => $id,
332
                        'nameSpaceId' => $nameSpaceId,
333
                    ]
334
                );
335
            } catch (\Twig_Error_Loader $e) {
336
                Craft::error($e->getMessage(), __METHOD__);
337
            } catch (\yii\base\Exception $e) {
338
                Craft::error($e->getMessage(), __METHOD__);
339
            }
340
        }
341
342
        // Render an error template, since the field only works when attached to an Asset
343
        try {
344
            return Craft::$app->getView()->renderTemplate(
345
                'image-optimize/_components/fields/OptimizedImages_error',
346
                [
347
                ]
348
            );
349
        } catch (\Twig_Error_Loader $e) {
350
            Craft::error($e->getMessage(), __METHOD__);
351
        } catch (\yii\base\Exception $e) {
352
            Craft::error($e->getMessage(), __METHOD__);
353
        }
354
355
        return '';
356
    }
357
}
358