Passed
Push — master ( 1227ba...d46f74 )
by Nicolaas
01:58
created

PerfectCMSImages::get_padding_bg_colour()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 4
c 1
b 0
f 0
nc 1
nop 1
dl 0
loc 6
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
     * @var string
20
     */
21
    private static $htaccess_content = <<<EOT
22
<IfModule mod_rewrite.c>
23
    RewriteEngine On
24
    RewriteBase /
25
26
    RewriteCond %{REQUEST_FILENAME} !-f
27
    RewriteCond %{REQUEST_FILENAME} !-d
28
    RewriteRule ^(.+)\.(v[A-Za-z0-9]+)\.(js|css|png|jpg|gif|svg|webp)$ $1.$3 [L]
29
</IfModule>
30
31
EOT;
32
33
    /**
34
     * background image for padded images...
35
     *
36
     * @var string
37
     */
38
    private static $perfect_cms_images_background_padding_color = '#cccccc';
39
40
    /**
41
     * used to set the max width of the media value for mobile images,
42
     * eg <source srcset="small.jpg, small2x.jpg 2x" media="(max-width: 600px)">
43
     *
44
     * @var string
45
     */
46
    private static $mobile_media_max_width = '600px';
47
48
    /***
49
     * details of the images
50
     *     - width: 3200
51
     *     - height: 3200
52
     *     - folder: "myfolder"
53
     *     - filetype: "try jpg"
54
     *     - enforce_size: false
55
     *     - folder: my-image-folder-a
56
     *     - filetype: "jpg or a png with a transparant background"
57
     *     - use_retina: true
58
     *     - padding_bg_colour: '#dddddd'
59
     *     - crop: true
60
     *
61
     * @var array
62
     */
63
    private static $perfect_cms_images_image_definitions = [];
64
65
    /***
66
     * Images Titles will be appended to the links only
67
     * if the ClassName of the Image is in this array
68
     * @var array
69
     *
70
     */
71
    private static $perfect_cms_images_append_title_to_image_links_classes = [
72
        Image::class,
73
    ];
74
75
    private static $retina_multiplier = 2;
76
77
    /**
78
     * force resample, put htaccess content if it does not exists.
79
     */
80
    public static function flush()
81
    {
82
        if (! Config::inst()->get(Image::class, 'force_resample')) {
83
            Config::modify()->update(Image::class, 'force_resample', true);
84
        }
85
        if (class_exists('HashPathExtension')) {
86
            if (! file_exists(ASSETS_PATH)) {
87
                Filesystem::makeFolder(ASSETS_PATH);
88
            }
89
            $fileName = ASSETS_PATH . '/.htaccess';
90
            if (! file_exists($fileName)) {
91
                $string = Config::inst()->get(PerfectCMSImages::class, 'htaccess_content');
92
                file_put_contents($fileName, $string);
93
            }
94
        }
95
    }
96
97
    public static function get_description_for_cms(string $name): string
98
    {
99
        $widthRecommendation = PerfectCMSImages::get_width($name);
100
        $heightRecommendation = PerfectCMSImages::get_height($name);
101
        $useRetina = PerfectCMSImages::use_retina($name);
102
        $recommendedFileType = PerfectCMSImages::get_file_type($name);
103
        $multiplier = PerfectCMSImages::get_multiplier($useRetina);
104
        if ($recommendedFileType === '') {
105
            $recommendedFileType = 'jpg';
106
        }
107
        if ($widthRecommendation !== 0) {
108
            if ((int) $widthRecommendation !== 0) {
109
                //cater for retina
110
                $widthRecommendation *= $multiplier;
111
                $actualWidthDescription = $widthRecommendation . 'px';
112
            } else {
113
                $actualWidthDescription = $widthRecommendation;
114
            }
115
        } else {
116
            $actualWidthDescription = 'flexible';
117
        }
118
        if ($heightRecommendation) {
119
            if ((int) $heightRecommendation !== 0) {
120
                //cater for retina
121
                $heightRecommendation *= $multiplier;
122
                $actualHeightDescription = $heightRecommendation . 'px';
123
            } else {
124
                $actualHeightDescription = $heightRecommendation;
125
            }
126
        } else {
127
            $actualHeightDescription = 'flexible';
128
        }
129
130
        $rightTitle = '<span>';
131
132
        if ($actualWidthDescription === 'flexible') {
133
            $rightTitle .= 'Image width is flexible';
134
        } else {
135
            $rightTitle .= "Image should to be <strong>{$actualWidthDescription}</strong> wide";
136
        }
137
138
        $rightTitle .= ' and ';
139
140
        if ($actualHeightDescription === 'flexible') {
141
            $rightTitle .= 'height is flexible';
142
        } else {
143
            $rightTitle .= " <strong>{$actualHeightDescription}</strong> tall";
144
        }
145
146
        $rightTitle .= '<br />';
147
        $maxSizeInKilobytes = PerfectCMSImages::max_size_in_kilobytes($name);
148
        if ($maxSizeInKilobytes !== 0) {
149
            $rightTitle .= 'Maximum file size: ' . round($maxSizeInKilobytes / 1024, 2) . ' megabyte.';
150
            $rightTitle .= '<br />';
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
164
    public static function use_retina(string $name): bool
165
    {
166
        return self::get_one_value_for_image($name, 'use_retina', 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

166
        return self::get_one_value_for_image($name, 'use_retina', /** @scrutinizer ignore-type */ true);
Loading history...
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...
167
    }
168
169
170
    public static function get_multiplier(bool $useRetina): int
171
    {
172
        $multiplier = 1;
173
        if ($useRetina) {
174
            $multiplier = Config::inst()->get(PerfectCMSImages::class, 'retina_multiplier');
175
        }
176
        if (! $multiplier) {
177
            $multiplier = 1;
178
        }
179
        return $multiplier;
180
    }
181
182
183
    public static function is_crop(string $name): bool
184
    {
185
        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

185
        return self::get_one_value_for_image($name, 'crop', /** @scrutinizer ignore-type */ false);
Loading history...
186
    }
187
188
    /**
189
     * @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...
190
     */
191
    public static function get_width(string $name, bool $forceInteger = false)
192
    {
193
        $v = self::get_one_value_for_image($name, 'width', 0);
194
        if ($forceInteger) {
195
            $v = (int) $v - 0;
196
        }
197
198
        return $v;
199
    }
200
201
    /**
202
     * @return int|string
203
     */
204
    public static function get_height(string $name, bool $forceInteger = false)
205
    {
206
        $v = self::get_one_value_for_image($name, 'height', 0);
207
        if ($forceInteger) {
208
            $v = (int) $v - 0;
209
        }
210
211
        return $v;
212
    }
213
214
    /**
215
     * @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...
216
     */
217
    public static function get_mobile_width(string $name, bool $forceInteger = false)
218
    {
219
        $v = self::get_one_value_for_image($name, 'mobile_width', 0);
220
        if ($forceInteger) {
221
            $v = (int) $v - 0;
222
        }
223
224
        return $v;
225
    }
226
227
    /**
228
     * @return int|string
229
     */
230
    public static function get_mobile_height(string $name, bool $forceInteger = false)
231
    {
232
        $v = self::get_one_value_for_image($name, 'mobile_height', 0);
233
        if ($forceInteger) {
234
            $v = (int) $v - 0;
235
        }
236
237
        return $v;
238
    }
239
240
241
    public static function get_folder(string $name): string
242
    {
243
        return self::get_one_value_for_image($name, 'folder', 'other-images');
244
    }
245
246
247
    public static function max_size_in_kilobytes(string $name): int
248
    {
249
        $maxSizeInKilobytes = self::get_one_value_for_image($name, 'max_size_in_kilobytes', 0);
250
        if (! $maxSizeInKilobytes) {
251
            $maxSizeInKilobytes = Config::inst()->get(PerfectCmsImagesUploadField::class, 'max_size_in_kilobytes');
252
        }
253
        return (int) $maxSizeInKilobytes - 0;
254
    }
255
256
257
    public static function get_file_type(string $name): string
258
    {
259
        return self::get_one_value_for_image($name, 'filetype', 'jpg');
260
    }
261
262
263
    public static function get_enforce_size(string $name): bool
264
    {
265
        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

265
        return self::get_one_value_for_image($name, 'enforce_size', /** @scrutinizer ignore-type */ false);
Loading history...
266
    }
267
268
    /**
269
     * @return string|null
270
     */
271
    public static function get_mobile_media_width(string $name)
272
    {
273
        return self::get_one_value_for_image(
274
            $name,
275
            'mobile_media_max_width',
276
            Config::inst()->get(PerfectCMSImages::class, 'mobile_media_max_width')
277
        );
278
    }
279
280
281
    public static function get_padding_bg_colour(string $name): string
282
    {
283
        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...
284
            $name,
285
            'padding_bg_colour',
286
            Config::inst()->get(PerfectCmsImageDataExtension::class, 'perfect_cms_images_background_padding_color')
287
        );
288
    }
289
290
291
    protected static function image_info_available(string $name): bool
292
    {
293
        $sizes = self::get_all_values_for_images();
294
        //print_r($sizes);die();
295
        return isset($sizes[$name]);
296
    }
297
298
    /**
299
     * @param string    $default
300
     *
301
     * @return mixed
302
     */
303
    protected static function get_one_value_for_image(string $name, string $key, ?string $default = '')
304
    {
305
        $sizes = self::get_all_values_for_images();
306
        if (isset($sizes[$name]) && isset($sizes[$name][$key])) {
307
            return $sizes[$name][$key];
308
        }
309
        Injector::inst()->get(LoggerInterface::class)->info('no information for image with the name: ' . $name . '.' . $key);
310
311
        return $default;
312
    }
313
314
315
    protected static function get_all_values_for_images(): array
316
    {
317
        return Config::inst()->get(
318
            PerfectCmsImageDataExtension::class,
319
            'perfect_cms_images_image_definitions'
320
        ) ?: [];
321
    }
322
}
323