Passed
Push — develop ( d502bc...2115be )
by Andrew
04:39
created

ThumborImageTransform::getFocalPoint()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 23
Code Lines 16

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 16
dl 0
loc 23
rs 9.7333
c 0
b 0
f 0
cc 2
nc 2
nop 1
1
<?php
2
/**
3
 * ImageOptimize plugin for Craft CMS 3.x
4
 *
5
 * Automatically optimize images after they've been transformed
6
 *
7
 * @link      https://nystudio107.com
0 ignored issues
show
Coding Style introduced by
The tag in position 1 should be the @copyright tag
Loading history...
8
 * @copyright Copyright (c) 2017 nystudio107
0 ignored issues
show
Coding Style introduced by
@copyright tag must contain a year and the name of the copyright holder
Loading history...
9
 */
0 ignored issues
show
Coding Style introduced by
PHP version not specified
Loading history...
Coding Style introduced by
Missing @category tag in file comment
Loading history...
Coding Style introduced by
Missing @package tag in file comment
Loading history...
Coding Style introduced by
Missing @author tag in file comment
Loading history...
Coding Style introduced by
Missing @license tag in file comment
Loading history...
10
11
namespace nystudio107\imageoptimize\imagetransforms;
12
13
use nystudio107\imageoptimize\ImageOptimize;
14
15
use craft\elements\Asset;
16
use craft\models\AssetTransform;
17
use Thumbor\Url\Builder as UrlBuilder;
18
19
use Craft;
20
21
/**
0 ignored issues
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
22
 * @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 indented incorrectly; expected 2 spaces but found 4
Loading history...
23
 * @package   ImageOptimize
0 ignored issues
show
Coding Style introduced by
Tag value indented incorrectly; expected 1 spaces but found 3
Loading history...
24
 * @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 indented incorrectly; expected 3 spaces but found 5
Loading history...
25
 */
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...
26
class ThumborImageTransform extends ImageTransform
27
{
28
    // Static Methods
29
    // =========================================================================
30
31
    /**
0 ignored issues
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
32
     * @inheritdoc
33
     */
0 ignored issues
show
Coding Style introduced by
Missing @return tag in function comment
Loading history...
34
    public static function displayName(): string
35
    {
36
        return Craft::t('image-optimize', 'Thumbor');
37
    }
38
39
    // Public Properties
40
    // =========================================================================
41
42
    /**
0 ignored issues
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
43
     * @var string
44
     */
45
    public $baseUrl;
46
47
    /**
0 ignored issues
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
48
     * @var string
49
     */
50
    public $securityKey;
51
52
    // Public Methods
53
    // =========================================================================
54
55
    /**
0 ignored issues
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
56
     * @param Asset               $asset
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
57
     * @param AssetTransform|null $transform
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
58
     * @param array               $params
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
59
     *
60
     * @return string|null
61
     * @throws \yii\base\Exception
62
     * @throws \yii\base\InvalidConfigException
63
     */
64
    public function getTransformUrl(Asset $asset, $transform, array $params = [])
65
    {
66
        return (string)$this->getUrlBuilderForTransform($asset, $transform, $params);
67
    }
68
69
    /**
0 ignored issues
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
70
     * @param string              $url
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
71
     * @param Asset               $asset
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
72
     * @param AssetTransform|null $transform
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
73
     * @param array               $params
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
74
     *
75
     * @return string
76
     * @throws \yii\base\Exception
77
     * @throws \yii\base\InvalidConfigException
78
     */
79
    public function getWebPUrl(string $url, Asset $asset, $transform, array $params = []): string
80
    {
81
        $builder = $this->getUrlBuilderForTransform($asset, $transform, $params)
82
            ->addFilter('format', 'webp');
83
84
        return (string)$builder;
85
    }
86
87
    /**
0 ignored issues
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
88
     * @param string $url
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
89
     * @param array  $params
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
90
     *
91
     * @return bool
92
     */
93
    public function purgeUrl(string $url, array $params = []): bool
94
    {
95
        return false;
96
    }
97
98
    /**
0 ignored issues
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
99
     * @return array
100
     */
101
    public function getTransformParams(): array
102
    {
103
        $settings = ImageOptimize::$plugin->getSettings();
104
        $params = [
105
            'baseUrl' => $settings->thumborBaseUrl,
0 ignored issues
show
Bug Best Practice introduced by
The property thumborBaseUrl does not exist on nystudio107\imageoptimize\models\Settings. Since you implemented __get, consider adding a @property annotation.
Loading history...
106
            'securityKey' => $settings->thumborSecurityKey,
0 ignored issues
show
Bug Best Practice introduced by
The property thumborSecurityKey does not exist on nystudio107\imageoptimize\models\Settings. Since you implemented __get, consider adding a @property annotation.
Loading history...
107
        ];
108
109
        return $params;
110
    }
111
112
    // Private Methods
113
    // =========================================================================
114
115
    /**
0 ignored issues
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
116
     * @param Asset               $asset
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
117
     * @param AssetTransform|null $transform
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
118
     * @param array               $params
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
119
     *
120
     * @return UrlBuilder
121
     * @throws \yii\base\Exception
122
     * @throws \yii\base\InvalidConfigException
123
     */
124
    private function getUrlBuilderForTransform(Asset $asset, $transform, array $params = []): UrlBuilder
0 ignored issues
show
Coding Style introduced by
Private method name "ThumborImageTransform::getUrlBuilderForTransform" must be prefixed with an underscore
Loading history...
125
    {
126
        $assetUri = $this->getAssetUri($asset);
127
        $baseUrl = $params['baseUrl'];
128
        $securityKey = $params['securityKey'] ?: null;
129
        $builder = UrlBuilder::construct($baseUrl, $securityKey, $assetUri);
130
        $settings = ImageOptimize::$plugin->getSettings();
131
132
        if ($transform->mode === 'fit') {
133
            // https://thumbor.readthedocs.io/en/latest/usage.html#fit-in
134
            $builder->fitIn($transform->width, $transform->height);
135
        } elseif ($transform->mode === 'stretch') {
136
            $builder
0 ignored issues
show
Bug introduced by
The call to Thumbor\Url\Builder::addFilter() has too few arguments starting with args. ( Ignorable by Annotation )

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

136
                ->/** @scrutinizer ignore-call */ addFilter('upscale');

This check compares calls to functions or methods with their respective definitions. If the call has less arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
137
                ->resize($transform->width, $transform->height)
138
                ->addFilter('upscale');
139
140
            // https://github.com/thumbor/thumbor/issues/1123
141
            Craft::warning('Thumbor has no equivalent to the "stretch" transform mode. The resulting image will be resized and cropped, but not stretched.', __METHOD__);
142
        } else {
143
144
            // https://thumbor.readthedocs.io/en/latest/usage.html#image-size
145
            $builder->resize($transform->width, $transform->height);
146
147
            if ($focalPoint = $this->getFocalPoint($asset)) {
148
                // https://thumbor.readthedocs.io/en/latest/focal.html
149
                $builder->addFilter('focal', $focalPoint);
150
            } elseif (preg_match('/(top|center|bottom)-(left|center|right)/', $transform->position, $matches)) {
151
                $v = str_replace('center', 'middle', $matches[1]);
152
                $h = $matches[2];
153
154
                // https://thumbor.readthedocs.io/en/latest/usage.html#horizontal-align
155
                $builder->valign($v)->halign($h);
156
            }
157
        }
158
159
        // https://thumbor.readthedocs.io/en/latest/format.html
160
        if ($format = $this->getFormat($transform)) {
161
            $builder->addFilter('format', $format);
162
        }
163
164
        // https://thumbor.readthedocs.io/en/latest/quality.html
165
        if ($quality = $this->getQuality($transform)) {
166
            $builder->addFilter('quality', $quality);
167
        }
168
169
        if (property_exists($transform, 'interlace')) {
170
            Craft::warning('Thumbor enables progressive JPEGs on the server-level, not as a request option. See https://thumbor.readthedocs.io/en/latest/jpegtran.html', __METHOD__);
171
        }
172
173
        if ($settings->autoSharpenScaledImages) {
174
            // See if the image has been scaled >= 50%
175
            $widthScale = $asset->getWidth() / ($transform->width ?? $asset->getWidth());
176
            $heightScale = $asset->getHeight() / ($transform->height ?? $asset->getHeight());
177
            if (($widthScale >= 2.0) || ($heightScale >= 2.0)) {
178
                // https://thumbor.readthedocs.io/en/latest/sharpen.html
179
                $builder->addFilter('sharpen', .5, .5, 'true');
0 ignored issues
show
Unused Code introduced by
The call to Thumbor\Url\Builder::addFilter() has too many arguments starting with 'true'. ( Ignorable by Annotation )

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

179
                $builder->/** @scrutinizer ignore-call */ 
180
                          addFilter('sharpen', .5, .5, 'true');

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
180
            }
181
        }
182
183
        return $builder;
184
    }
185
186
    /**
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...
187
     * @return string|null
188
     */
189
    private function getFocalPoint(Asset $asset)
0 ignored issues
show
Coding Style introduced by
Private method name "ThumborImageTransform::getFocalPoint" must be prefixed with an underscore
Loading history...
190
    {
191
        $focalPoint = $asset->getFocalPoint();
192
193
        if (!$focalPoint) {
194
            return null;
195
        }
196
197
        $box = array_map('intval', [
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...
198
            'top' => $focalPoint['y'] * $asset->height - 1,
199
            'left' => $focalPoint['x'] * $asset->width - 1,
200
            'bottom' => $focalPoint['y'] * $asset->height + 1,
201
            'right' => $focalPoint['x'] * $asset->width + 1,
202
        ]);
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...
203
204
        return implode('', [
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...
205
            $box['left'],
206
            'x',
207
            $box['top'],
208
            ':',
209
            $box['right'],
210
            'x',
211
            $box['bottom'],
212
        ]);
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...
213
    }
214
215
    /**
0 ignored issues
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
216
     * @param AssetTransform|null $transform
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
217
     *
218
     * @return string|null
219
     */
220
    private function getFormat($transform)
0 ignored issues
show
Coding Style introduced by
Private method name "ThumborImageTransform::getFormat" must be prefixed with an underscore
Loading history...
221
    {
222
        $format = str_replace('jpg', 'jpeg', $transform->format);
223
224
        return $format ?: null;
225
    }
226
227
    /**
0 ignored issues
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
228
     * @param AssetTransform|null $transform
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
229
     *
230
     * @return int
231
     */
232
    private function getQuality($transform)
0 ignored issues
show
Coding Style introduced by
Private method name "ThumborImageTransform::getQuality" must be prefixed with an underscore
Loading history...
233
    {
234
        return $transform->quality ?? Craft::$app->getConfig()->getGeneral()->defaultImageQuality;
235
    }
236
237
    /**
0 ignored issues
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
238
     * @inheritdoc
239
     */
0 ignored issues
show
Coding Style introduced by
Missing @return tag in function comment
Loading history...
240
    public function rules()
241
    {
242
        $rules = parent::rules();
243
        $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...
244
            [['baseUrl', 'securityKey'], 'default', 'value' => ''],
245
            [['baseUrl', 'securityKey'], 'string'],
246
        ]);
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...
247
248
        return $rules;
249
    }
250
}
251