Passed
Push — master ( a06d21...f74981 )
by Nicolaas
08:50
created

PerfectCMSImages::move_to_right_folder()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 1
c 0
b 0
f 0
nc 1
nop 1
dl 0
loc 3
rs 10
1
<?php
2
3
namespace Sunnysideup\PerfectCmsImages\Api;
4
5
use Psr\Log\LoggerInterface;
6
use SilverStripe\Assets\Filesystem;
7
use SilverStripe\Assets\Folder;
8
use SilverStripe\Assets\Image;
9
use SilverStripe\Core\Config\Config;
10
use SilverStripe\Core\Flushable;
11
use SilverStripe\Core\Injector\Injector;
12
use Sunnysideup\PerfectCmsImages\Forms\PerfectCmsImagesUploadField;
13
use Sunnysideup\PerfectCmsImages\Model\File\PerfectCmsImageDataExtension;
14
15
class PerfectCMSImages implements Flushable
16
{
17
    /**
18
     *.htaccess content for assets ...
19
     *
20
     * @var string
21
     */
22
    private static $htaccess_content = <<<'EOT'
23
<IfModule mod_rewrite.c>
24
    RewriteEngine On
25
    RewriteBase /
26
27
    RewriteCond %{REQUEST_FILENAME} !-f
28
    RewriteCond %{REQUEST_FILENAME} !-d
29
    RewriteRule ^(.+)\.(v[A-Za-z0-9]+)\.(js|css|png|jpg|gif|svg|webp)$ $1.$3 [L]
30
</IfModule>
31
32
EOT;
33
34
    /**
35
     * background image for padded images...
36
     *
37
     * @var string
38
     */
39
    private static $perfect_cms_images_background_padding_color = '#cccccc';
40
41
    /**
42
     * used to set the max width of the media value for mobile images,
43
     * eg <source srcset="small.jpg, small2x.jpg 2x" media="(max-width: 600px)">.
44
     *
45
     * @var string
46
     */
47
    private static $mobile_media_max_width = '600px';
48
49
    /*
50
     * details of the images
51
     *     - width: 3200
52
     *     - height: 3200
53
     *     - folder: "myfolder"
54
     *     - filetype: "try jpg"
55
     *     - enforce_size: false
56
     *     - folder: my-image-folder-a
57
     *     - filetype: "jpg or a png with a transparant background"
58
     *     - use_retina: true
59
     *     - padding_bg_colour: '#dddddd'
60
     *     - crop: true
61
     *
62
     * @var array
63
     */
64
    private static $perfect_cms_images_image_definitions = [];
65
66
    /*
67
     * Images Titles will be appended to the links only
68
     * if the ClassName of the Image is in this array
69
     * @var array
70
     *
71
     */
72
    private static $perfect_cms_images_append_title_to_image_links_classes = [
73
        Image::class,
74
    ];
75
76
    private static $retina_multiplier = 2;
77
78
    /**
79
     * force resample, put htaccess content if it does not exists.
80
     */
81
    public static function flush()
82
    {
83
        if (! Config::inst()->get(Image::class, 'force_resample')) {
84
            Config::modify()->update(Image::class, 'force_resample', true);
85
        }
86
87
        if (class_exists('HashPathExtension')) {
88
            if (! file_exists(ASSETS_PATH)) {
89
                Filesystem::makeFolder(ASSETS_PATH);
90
            }
91
92
            $fileName = ASSETS_PATH . '/.htaccess';
93
            if (! file_exists($fileName)) {
94
                $string = Config::inst()->get(PerfectCMSImages::class, 'htaccess_content');
95
                file_put_contents($fileName, $string);
96
            }
97
        }
98
    }
99
100
    public static function get_description_for_cms(string $name): string
101
    {
102
        $widthRecommendation = PerfectCMSImages::get_width($name);
103
        $heightRecommendation = PerfectCMSImages::get_height($name);
104
        $useRetina = PerfectCMSImages::use_retina($name);
105
        $recommendedFileType = PerfectCMSImages::get_file_type($name);
106
        $multiplier = PerfectCMSImages::get_multiplier($useRetina);
107
        if ('' === $recommendedFileType) {
108
            $recommendedFileType = 'jpg';
109
        }
110
111
        if (0 !== (int) $widthRecommendation) {
112
            //cater for retina
113
            $widthRecommendation *= $multiplier;
114
            $actualWidthDescription = $widthRecommendation . 'px';
115
        } else {
116
            $actualWidthDescription = $widthRecommendation;
0 ignored issues
show
Unused Code introduced by
The assignment to $actualWidthDescription is dead and can be removed.
Loading history...
117
            $actualWidthDescription = 'flexible';
118
        }
119
120
        if (0 !== (int) $heightRecommendation) {
121
            //cater for retina
122
            $heightRecommendation *= $multiplier;
123
            $actualHeightDescription = $heightRecommendation . 'px';
124
        } else {
125
            $actualHeightDescription = $heightRecommendation;
0 ignored issues
show
Unused Code introduced by
The assignment to $actualHeightDescription is dead and can be removed.
Loading history...
126
            $actualHeightDescription = 'flexible';
127
        }
128
129
        $rightTitle = '<span>';
130
131
        if ('flexible' === $actualWidthDescription) {
132
            $rightTitle .= 'Image width is flexible';
133
        } else {
134
            $rightTitle .= "Image should to be <strong>{$actualWidthDescription}</strong> wide";
135
        }
136
137
        $rightTitle .= ' and ';
138
139
        if ('flexible' === $actualHeightDescription) {
140
            $rightTitle .= 'height is flexible';
141
        } else {
142
            $rightTitle .= " <strong>{$actualHeightDescription}</strong> tall";
143
        }
144
145
        $rightTitle .= '<br />';
146
        $maxSizeInKilobytes = PerfectCMSImages::max_size_in_kilobytes($name);
147
        if (0 !== $maxSizeInKilobytes) {
148
            $rightTitle .= 'Maximum file size: ' . round($maxSizeInKilobytes / 1024, 2) . ' megabyte.';
149
            $rightTitle .= '<br />';
150
        }
151
152
        if ('' !== $recommendedFileType) {
153
            if (strlen($recommendedFileType) < 5) {
154
                $rightTitle .= 'The recommend file type (file extension) is <strong>' . $recommendedFileType . '</strong>.';
155
            } else {
156
                $rightTitle .= '<strong>' . $recommendedFileType . '</strong>';
157
            }
158
        }
159
160
        return $rightTitle . '</span>';
161
    }
162
163
    public static function use_retina(string $name): bool
164
    {
165
        return self::get_one_value_for_image($name, 'use_retina', true);
0 ignored issues
show
Bug Best Practice introduced by
The expression return self::get_one_val...me, 'use_retina', true) could return the type null|string which is incompatible with the type-hinted return boolean. Consider adding an additional type-check to rule them out.
Loading history...
Bug introduced by
true of type true is incompatible with the type null|string expected by parameter $default of Sunnysideup\PerfectCmsIm...t_one_value_for_image(). ( Ignorable by Annotation )

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

165
        return self::get_one_value_for_image($name, 'use_retina', /** @scrutinizer ignore-type */ true);
Loading history...
166
    }
167
168
    public static function get_multiplier(bool $useRetina): int
169
    {
170
        $multiplier = 1;
171
        if ($useRetina) {
172
            $multiplier = Config::inst()->get(PerfectCMSImages::class, 'retina_multiplier');
173
        }
174
175
        if (! $multiplier) {
176
            $multiplier = 1;
177
        }
178
179
        return $multiplier;
180
    }
181
182
    public static function is_crop(string $name): bool
183
    {
184
        return self::get_one_value_for_image($name, 'crop', false);
0 ignored issues
show
Bug Best Practice introduced by
The expression return self::get_one_val...e($name, 'crop', false) could return the type null|string which is incompatible with the type-hinted return boolean. Consider adding an additional type-check to rule them out.
Loading history...
Bug introduced by
false of type false is incompatible with the type null|string expected by parameter $default of Sunnysideup\PerfectCmsIm...t_one_value_for_image(). ( Ignorable by Annotation )

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

184
        return self::get_one_value_for_image($name, 'crop', /** @scrutinizer ignore-type */ false);
Loading history...
185
    }
186
187
    /**
188
     * @return int?string
0 ignored issues
show
Documentation Bug introduced by
The doc comment int?string at position 0 could not be parsed: Unknown type name 'int?string' at position 0 in int?string.
Loading history...
189
     */
190
    public static function get_width(string $name, bool $forceInteger = false)
191
    {
192
        $v = self::get_one_value_for_image($name, 'width', 0);
193
        if ($forceInteger) {
194
            $v = (int) $v - 0;
195
        }
196
197
        return $v;
198
    }
199
200
    /**
201
     * @return int|string
202
     */
203
    public static function get_height(string $name, bool $forceInteger = false)
204
    {
205
        $v = self::get_one_value_for_image($name, 'height', 0);
206
        if ($forceInteger) {
207
            $v = (int) $v - 0;
208
        }
209
210
        return $v;
211
    }
212
213
    /**
214
     * @return int?string
0 ignored issues
show
Documentation Bug introduced by
The doc comment int?string at position 0 could not be parsed: Unknown type name 'int?string' at position 0 in int?string.
Loading history...
215
     */
216
    public static function get_mobile_width(string $name, bool $forceInteger = false)
217
    {
218
        $v = self::get_one_value_for_image($name, 'mobile_width', 0);
219
        if ($forceInteger) {
220
            $v = (int) $v - 0;
221
        }
222
223
        return $v;
224
    }
225
226
    /**
227
     * @return int|string
228
     */
229
    public static function get_mobile_height(string $name, bool $forceInteger = false)
230
    {
231
        $v = self::get_one_value_for_image($name, 'mobile_height', 0);
232
        if ($forceInteger) {
233
            $v = (int) $v - 0;
234
        }
235
236
        return $v;
237
    }
238
239
    public static function get_folder(string $name): string
240
    {
241
        return self::get_one_value_for_image($name, 'folder', 'other-images');
242
    }
243
244
    public static function move_to_right_folder(string $name): bool
245
    {
246
        return self::get_one_value_for_image($name, 'move_to_right_folder', true);
0 ignored issues
show
Bug introduced by
true of type true is incompatible with the type null|string expected by parameter $default of Sunnysideup\PerfectCmsIm...t_one_value_for_image(). ( Ignorable by Annotation )

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

246
        return self::get_one_value_for_image($name, 'move_to_right_folder', /** @scrutinizer ignore-type */ true);
Loading history...
Bug Best Practice introduced by
The expression return self::get_one_val...to_right_folder', true) could return the type null|string which is incompatible with the type-hinted return boolean. Consider adding an additional type-check to rule them out.
Loading history...
247
    }
248
249
    public static function loading_style(string $name) : string
250
    {
251
        return self::get_one_value_for_image($name, 'loading_style', 'lazy');
252
    }
253
254
    public static function max_size_in_kilobytes(string $name): int
255
    {
256
        $maxSizeInKilobytes = self::get_one_value_for_image($name, 'max_size_in_kilobytes', 0);
257
        if (! $maxSizeInKilobytes) {
258
            $maxSizeInKilobytes = Config::inst()->get(PerfectCmsImagesUploadField::class, 'max_size_in_kilobytes');
259
        }
260
261
        return (int) $maxSizeInKilobytes - 0;
262
    }
263
264
    public static function get_file_type(string $name): string
265
    {
266
        return self::get_one_value_for_image($name, 'filetype', 'jpg');
267
    }
268
269
    public static function get_enforce_size(string $name): bool
270
    {
271
        return self::get_one_value_for_image($name, 'enforce_size', false);
0 ignored issues
show
Bug Best Practice introduced by
The expression return self::get_one_val... 'enforce_size', false) could return the type null|string which is incompatible with the type-hinted return boolean. Consider adding an additional type-check to rule them out.
Loading history...
Bug introduced by
false of type false is incompatible with the type null|string expected by parameter $default of Sunnysideup\PerfectCmsIm...t_one_value_for_image(). ( Ignorable by Annotation )

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

271
        return self::get_one_value_for_image($name, 'enforce_size', /** @scrutinizer ignore-type */ false);
Loading history...
272
    }
273
274
    /**
275
     * @return null|string
276
     */
277
    public static function get_mobile_media_width(string $name)
278
    {
279
        return self::get_one_value_for_image(
280
            $name,
281
            'mobile_media_max_width',
282
            Config::inst()->get(PerfectCMSImages::class, 'mobile_media_max_width')
283
        );
284
    }
285
286
    public static function get_padding_bg_colour(string $name): string
287
    {
288
        return self::get_one_value_for_image(
0 ignored issues
show
Bug Best Practice introduced by
The expression return self::get_one_val...ground_padding_color')) could return the type null which is incompatible with the type-hinted return string. Consider adding an additional type-check to rule them out.
Loading history...
289
            $name,
290
            'padding_bg_colour',
291
            Config::inst()->get(PerfectCmsImageDataExtension::class, 'perfect_cms_images_background_padding_color')
292
        );
293
    }
294
295
    public static function image_info_available(string $name): bool
296
    {
297
        $sizes = self::get_all_values_for_images();
298
        //print_r($sizes);die();
299
        return isset($sizes[$name]);
300
    }
301
302
    /**
303
     * @param string $default
304
     *
305
     * @return mixed
306
     */
307
    protected static function get_one_value_for_image(string $name, string $key, ?string $default = '')
308
    {
309
        $sizes = self::get_all_values_for_images();
310
        if (isset($sizes[$name], $sizes[$name][$key])) {
311
            return $sizes[$name][$key];
312
        }
313
314
        // Injector::inst()->get(LoggerInterface::class)->info('no information for image with the name: ' . $name . '.' . $key);
315
316
        return $default;
317
    }
318
319
    protected static function get_all_values_for_images(): array
320
    {
321
        return Config::inst()->get(
322
            PerfectCmsImageDataExtension::class,
323
            'perfect_cms_images_image_definitions'
324
        ) ?: [];
325
    }
326
}
327