MetaSliderImageHelper   B
last analyzed

Complexity

Total Complexity 47

Size/Duplication

Total Lines 313
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 135
dl 0
loc 313
rs 8.64
c 0
b 0
f 0
wmc 47

6 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 11 1
B get_image_url() 0 49 8
A get_original_image_dimensions() 0 23 4
A get_destination_file_name() 0 9 1
B resize_image() 0 46 6
F get_crop_dimensions() 0 109 27

How to fix   Complexity   

Complex Class

Complex classes like MetaSliderImageHelper often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use MetaSliderImageHelper, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
/**
4
 * Helper class for resizing images, returning the correct URL to the image etc
5
 */
6
class MetaSliderImageHelper
7
{
8
    private $smart_crop = 'false';
9
    private $container_width; // slideshow width
10
    private $container_height; // slideshow height
11
    private $id; // slide/attachment ID
12
    private $url;
13
    private $path; // path to attachment on server
14
    private $use_image_editor;
15
16
    /**
17
     * Constructor
18
     *
19
     * @param int    $slide_id
20
     * @param int    $width  - required width of image
21
     * @param int    $height - required height of image
22
     * @param string $smart_crop
23
     * @param bool   $use_image_editor
24
     */
25
    public function __construct($slide_id, $width, $height, $smart_crop, $use_image_editor = true)
26
    {
27
        $upload_dir = wp_upload_dir();
0 ignored issues
show
Bug introduced by
The function wp_upload_dir was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

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

27
        $upload_dir = /** @scrutinizer ignore-call */ wp_upload_dir();
Loading history...
28
29
        $this->id               = $slide_id;
30
        $this->url              = $upload_dir['baseurl'] . '/' . get_post_meta($slide_id, '_wp_attached_file', true);
0 ignored issues
show
Bug introduced by
The function get_post_meta was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

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

30
        $this->url              = $upload_dir['baseurl'] . '/' . /** @scrutinizer ignore-call */ get_post_meta($slide_id, '_wp_attached_file', true);
Loading history...
31
        $this->path             = get_attached_file($slide_id);
0 ignored issues
show
Bug introduced by
The function get_attached_file was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

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

31
        $this->path             = /** @scrutinizer ignore-call */ get_attached_file($slide_id);
Loading history...
32
        $this->container_width  = $width;
33
        $this->container_height = $height;
34
        $this->smart_crop       = $smart_crop;
35
        $this->use_image_editor = $use_image_editor;
36
    }
37
38
    /**
39
     * Return the crop dimensions.
40
     *
41
     * Smart Crop: If the image is smaller than the container width or height, then return
42
     * dimensions that respect the container size ratio. This ensures image displays in a
43
     * sane manner in responsive sliders
44
     *
45
     * @param  int $image_width
46
     * @param  int $image_height
47
     * @return array   image dimensions
48
     */
49
    private function get_crop_dimensions($image_width, $image_height)
50
    {
51
        if ('false' === $this->smart_crop) {
52
            return ['width' => $this->container_width, 'height' => $this->container_height];
53
        }
54
55
        $container_width  = $this->container_width;
56
        $container_height = $this->container_height;
57
58
        /**
59
         * Slideshow Width == Slide Width
60
         */
61
        if ($image_width == $container_width && $image_height == $container_height) {
62
            $new_slide_width  = $container_width;
63
            $new_slide_height = $container_height;
64
        }
65
66
        if ($image_width == $container_width && $image_height < $container_height) {
67
            $new_slide_height = $image_height;
68
            $new_slide_width  = $container_width / ($container_height / $image_height);
69
        }
70
71
        if ($image_width == $container_width && $image_height > $container_height) {
72
            $new_slide_width  = $container_width;
73
            $new_slide_height = $container_height;
74
        }
75
76
        /**
77
         * Slideshow Width < Slide Width
78
         */
79
        if ($image_width < $container_width && $image_height == $container_height) {
80
            $new_slide_width  = $image_width;
81
            $new_slide_height = $image_height / ($container_width / $image_width);
82
        }
83
84
        /**
85
         * Slide is smaller than slidehow - both width and height
86
         */
87
        if ($image_width < $container_width && $image_height < $container_height) {
88
            if ($container_width > $container_height) {
89
                // wide
90
91
                if ($image_width > $image_height) {
92
                    // wide
93
                    $new_slide_height = $image_height;
94
                    $new_slide_width  = $container_width / ($container_height / $image_height);
95
96
                    if ($new_slide_width > $image_width) {
97
                        $new_slide_width  = $image_width;
98
                        $new_slide_height = $container_height / ($container_width / $image_width);
99
                    }
100
                } else {
101
                    // tall
102
                    $new_slide_width  = $image_width;
103
                    $new_slide_height = $container_height / ($container_width / $image_width);
104
105
                    if ($new_slide_height > $image_height) {
106
                        $new_slide_height = $image_height;
107
                        $new_slide_width  = $container_width / ($container_height / $image_height);
108
                    }
109
                }
110
            } else {
111
                // tall
112
                if ($image_width > $image_height) {
113
                    // wide
114
                    $new_slide_height = $image_height;
115
                    $new_slide_width  = $container_width / ($container_height / $image_height);
116
117
                    if ($new_slide_width > $image_width) {
118
                        $new_slide_width  = $image_width;
119
                        $new_slide_height = $container_height / ($container_width / $image_width);
120
                    }
121
                } else {
122
                    // tall
123
                    $new_slide_width  = $image_width;
124
                    $new_slide_height = $container_height / ($container_width / $image_width);
125
126
                    if ($new_slide_height > $image_height) {
127
                        $new_slide_height = $image_height;
128
                        $new_slide_width  = $container_width / ($container_height / $image_height);
129
                    }
130
                }
131
            }
132
        }
133
134
        if ($image_width < $container_width && $image_height > $container_height) {
135
            $new_slide_width  = $image_width;
136
            $new_slide_height = $container_height / ($container_width / $image_width);
137
        }
138
139
        /**
140
         * Slideshow Width > Slide Width
141
         */
142
        if ($image_width > $container_width && $image_height == $container_height) {
143
            $new_slide_width  = $container_width;
144
            $new_slide_height = $container_height;
145
        }
146
147
        if ($image_width > $container_width && $image_height < $container_height) {
148
            $new_slide_height = $image_height;
149
            $new_slide_width  = $container_width / ($container_height / $image_height);
150
        }
151
152
        if ($image_width > $container_width && $image_height > $container_height) {
153
            $new_slide_width  = $container_width;
154
            $new_slide_height = $container_height;
155
        }
156
157
        return ['width' => floor($new_slide_width), 'height' => floor($new_slide_height)];
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $new_slide_width does not seem to be defined for all execution paths leading up to this point.
Loading history...
Comprehensibility Best Practice introduced by
The variable $new_slide_height does not seem to be defined for all execution paths leading up to this point.
Loading history...
158
    }
159
160
    /**
161
     * Return the image URL, crop the image to the correct dimensions if required
162
     *
163
     * @return string resized image URL
164
     */
165
    public function get_image_url()
166
    {
167
        // Get the image file path
168
        if (!mb_strlen($this->path)) {
169
            return $this->url;
170
        }
171
172
        // if the file exists, just return it without going any further
173
        $dest_file_name = $this->get_destination_file_name([
174
                                                               'width'  => $this->container_width,
175
                                                               'height' => $this->container_height,
176
                                                           ]);
177
178
        if (file_exists($dest_file_name)) {
179
            return str_replace(basename($this->url), basename($dest_file_name), $this->url);
180
        }
181
182
        // file doesn't exist, detect required size
183
        $orig_size = $this->get_original_image_dimensions();
184
185
        // bail out if we can't find the image dimensions
186
        if (false === $orig_size) {
0 ignored issues
show
introduced by
The condition false === $orig_size is always false.
Loading history...
187
            return $this->url;
188
        }
189
190
        // required size
191
        $dest_size = $this->get_crop_dimensions($orig_size['width'], $orig_size['height']);
192
193
        // check if a resize is needed
194
        if ($orig_size['width'] == $dest_size['width'] && $orig_size['height'] == $dest_size['height']) {
195
            return $this->url;
196
        }
197
198
        $dest_file_name = $this->get_destination_file_name($dest_size);
199
200
        if (file_exists($dest_file_name)) {
201
            // good. no need for resize, just return the URL
202
            $dest_url = str_replace(basename($this->url), basename($dest_file_name), $this->url);
203
        } elseif ($this->use_image_editor) {
204
            // resize, assuming we're allowed to use the image editor
205
            $dest_url = $this->resize_image($orig_size, $dest_size, $dest_file_name);
206
        } else {
207
            // fall back to the full URL
208
            $dest_url = $this->url;
209
        }
210
211
        $dest_url = apply_filters('metaslider_resized_image_url', $dest_url, $this->url);
0 ignored issues
show
Bug introduced by
The function apply_filters was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

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

211
        $dest_url = /** @scrutinizer ignore-call */ apply_filters('metaslider_resized_image_url', $dest_url, $this->url);
Loading history...
212
213
        return $dest_url;
214
    }
215
216
    /**
217
     * Get the image dimensions for the original image.
218
     *
219
     * Fall back to using the WP_Image_Editor if the size is not stored in metadata
220
     *
221
     * @return array
222
     */
223
    private function get_original_image_dimensions()
224
    {
225
        $size = [];
0 ignored issues
show
Unused Code introduced by
The assignment to $size is dead and can be removed.
Loading history...
226
227
        // try and get the image size from metadata
228
        $meta = wp_get_attachment_metadata($this->id);
0 ignored issues
show
Bug introduced by
The function wp_get_attachment_metadata was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

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

228
        $meta = /** @scrutinizer ignore-call */ wp_get_attachment_metadata($this->id);
Loading history...
229
230
        if (isset($meta['width'], $meta['height'])) {
231
            return $meta;
232
        }
233
234
        if ($this->use_image_editor) {
235
            // get the size from the image itself
236
            $image = wp_get_image_editor($this->path);
0 ignored issues
show
Bug introduced by
The function wp_get_image_editor was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

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

236
            $image = /** @scrutinizer ignore-call */ wp_get_image_editor($this->path);
Loading history...
237
238
            if (!is_wp_error($image)) {
0 ignored issues
show
Bug introduced by
The function is_wp_error was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

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

238
            if (!/** @scrutinizer ignore-call */ is_wp_error($image)) {
Loading history...
239
                $size = $image->get_size();
240
241
                return $size;
242
            }
243
        }
244
245
        return false;
0 ignored issues
show
Bug Best Practice introduced by
The expression return false returns the type false which is incompatible with the documented return type array.
Loading history...
246
    }
247
248
    /**
249
     * Return the file name for the required image size
250
     *
251
     * @param  array $dest_size image dimensions (width/height) in pixels
252
     * @return string
253
     */
254
    private function get_destination_file_name($dest_size)
255
    {
256
        $info           = pathinfo($this->path);
257
        $dir            = $info['dirname'];
258
        $ext            = $info['extension'];
259
        $name           = wp_basename($this->path, ".$ext");
0 ignored issues
show
Bug introduced by
The function wp_basename was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

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

259
        $name           = /** @scrutinizer ignore-call */ wp_basename($this->path, ".$ext");
Loading history...
260
        $dest_file_name = "{$dir}/{$name}-{$dest_size['width']}x{$dest_size['height']}.{$ext}";
261
262
        return $dest_file_name;
263
    }
264
265
    /**
266
     * Use WP_Image_Editor to create a resized image and return the URL for that image
267
     *
268
     * @param  array $orig_size
269
     * @param  array $dest_size
270
     * @param        $dest_file_name
271
     * @return string
272
     */
273
    private function resize_image($orig_size, $dest_size, $dest_file_name)
274
    {
275
        // load image
276
        $image = wp_get_image_editor($this->path);
0 ignored issues
show
Bug introduced by
The function wp_get_image_editor was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

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

276
        $image = /** @scrutinizer ignore-call */ wp_get_image_editor($this->path);
Loading history...
277
278
        // editor will return an error if the path is invalid
279
        if (is_wp_error($image)) {
0 ignored issues
show
Bug introduced by
The function is_wp_error was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

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

279
        if (/** @scrutinizer ignore-call */ is_wp_error($image)) {
Loading history...
280
            if (is_admin()) {
0 ignored issues
show
Bug introduced by
The function is_admin was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

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

280
            if (/** @scrutinizer ignore-call */ is_admin()) {
Loading history...
281
                echo '<div id="message" class="error">';
282
                echo '<p><strong>ERROR</strong> ' . $image->get_error_message() . " Check <a href='http://codex.wordpress.org/Changing_File_Permissions' target='_blank'>file permissions</a></p>";
283
                echo "<button class='toggle'>Show Details</button>";
284
                echo "<div class='message' style='display: none;'><br >Slide ID: {$this->id}<pre>";
285
                var_dump($image);
0 ignored issues
show
Security Debugging Code introduced by
var_dump($image) looks like debug code. Are you sure you do not want to remove it?
Loading history...
286
                echo '</pre></div>';
287
                echo '</div>';
288
            }
289
290
            return $this->url;
291
        }
292
293
        $dims = image_resize_dimensions($orig_size['width'], $orig_size['height'], $dest_size['width'], $dest_size['height'], true);
0 ignored issues
show
Bug introduced by
The function image_resize_dimensions was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

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

293
        $dims = /** @scrutinizer ignore-call */ image_resize_dimensions($orig_size['width'], $orig_size['height'], $dest_size['width'], $dest_size['height'], true);
Loading history...
294
295
        if ($dims) {
296
            list($dst_x, $dst_y, $src_x, $src_y, $dst_w, $dst_h, $src_w, $src_h) = $dims;
297
            $image->crop($src_x, $src_y, $src_w, $src_h, $dst_w, $dst_h);
298
        }
299
300
        $saved = $image->save($dest_file_name);
301
302
        if (is_wp_error($saved)) {
303
            return $this->url;
304
        }
305
306
        // Record the new size so that the file is correctly removed when the media file is deleted.
307
        $backup_sizes = get_post_meta($this->id, '_wp_attachment_backup_sizes', true);
0 ignored issues
show
Bug introduced by
The function get_post_meta was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

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

307
        $backup_sizes = /** @scrutinizer ignore-call */ get_post_meta($this->id, '_wp_attachment_backup_sizes', true);
Loading history...
308
309
        if (!is_array($backup_sizes)) {
310
            $backup_sizes = [];
311
        }
312
313
        $backup_sizes["resized-{$dest_size['width']}x{$dest_size['height']}"] = $saved;
314
        update_post_meta($this->id, '_wp_attachment_backup_sizes', $backup_sizes);
0 ignored issues
show
Bug introduced by
The function update_post_meta was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

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

314
        /** @scrutinizer ignore-call */ 
315
        update_post_meta($this->id, '_wp_attachment_backup_sizes', $backup_sizes);
Loading history...
315
316
        $url = str_replace(basename($this->url), basename($saved['path']), $this->url);
317
318
        return $url;
319
    }
320
}
321