Passed
Pull Request — master (#1)
by Evgenii
01:11
created

Content::resolveImageSize()   F

Complexity

Conditions 27
Paths 4120

Size

Total Lines 92
Code Lines 59

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
cc 27
eloc 59
c 2
b 0
f 0
nc 4120
nop 1
dl 0
loc 92
rs 0

How to fix   Long Method    Complexity   

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
namespace Helick\Imgix;
4
5
use Helick\Contracts\Bootable;
6
7
final class Content implements Bootable
8
{
9
    /**
10
     * Boot the service.
11
     *
12
     * @return void
13
     */
14
    public static function boot(): void
15
    {
16
        $self = new static;
17
18
        add_filter('the_content', [$self, 'parse'], 100);
0 ignored issues
show
Bug introduced by
The function add_filter 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

18
        /** @scrutinizer ignore-call */ 
19
        add_filter('the_content', [$self, 'parse'], 100);
Loading history...
19
    }
20
21
    /**
22
     * Parse a given content.
23
     *
24
     * @param string $content
25
     *
26
     * @return string
27
     */
28
    public function parse(string $content): string
29
    {
30
        if (!$images = $this->resolveImages($content)) {
31
            return $content;
32
        }
33
34
        if ($attachmentIds = $this->resolveAttachmentIds($images['img_tags'])) {
35
            _prime_post_caches($attachmentIds, false, true);
0 ignored issues
show
Bug introduced by
The function _prime_post_caches 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

35
            /** @scrutinizer ignore-call */ 
36
            _prime_post_caches($attachmentIds, false, true);
Loading history...
36
        }
37
38
        foreach ($images['img_tags'] as $index => $imageTag) {
39
            $imageUrl = $images['img_urls'][$index];
40
41
            if (!is_processable_image_url($imageUrl)) {
42
                continue;
43
            }
44
45
            [$imageWidth, $imageHeight] = $this->resolveImageSize($imageTag);
46
47
            var_dump($imageUrl, $imageWidth, $imageHeight);
0 ignored issues
show
Security Debugging Code introduced by
var_dump($imageUrl, $imageWidth, $imageHeight) looks like debug code. Are you sure you do not want to remove it?
Loading history...
48
            die;
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
49
        }
50
51
        return $content;
52
    }
53
54
    /**
55
     * @param string $content
56
     *
57
     * @return array
58
     */
59
    private function resolveImages(string $content): array
60
    {
61
        $pattern = '#(?:<a[^>]+?href=["|\'](?P<link_urls>[^\s]+?)["|\'][^>]*?>\s*)'
62
            . '?(?P<img_tags><(?:img|amp-img|amp-anim)[^>]*?\s+?src=["|\']'
63
            . '(?P<img_urls>[^\s]+?)["|\'].*?>){1}(?:\s*</a>)?#is';
64
65
        if (!preg_match_all($pattern, $content, $images)) {
66
            return [];
67
        }
68
69
        $images = array_filter($images, 'is_string', ARRAY_FILTER_USE_KEY);
70
71
        return $images;
72
    }
73
74
    /**
75
     * @param array $tags
76
     *
77
     * @return array
78
     */
79
    private function resolveAttachmentIds(array $tags): array
80
    {
81
        $attachmentIds = [];
82
83
        foreach ($tags as $tag) {
84
            if (preg_match('/wp-image-([\d]+)/i', $tag, $matches)) {
85
                $attachmentIds[(int)$matches[1]] = true;
86
            }
87
        }
88
89
        return array_keys($attachmentIds);
90
    }
91
92
    /**
93
     * @param string $tag
94
     *
95
     * @return array
96
     */
97
    private function resolveImageSize(string $tag): array
98
    {
99
        $width = $height = null;
100
        $crop  = false;
101
102
        // First, let's check the tag attributes for width and height
103
        if (preg_match('#width=["|\']?([\d%]+)["|\']?#i', $tag, $matches)) {
104
            $width = array_pop($matches);
105
        } else {
106
            unset($matches);
107
        }
108
109
        if (preg_match('#height=["|\']?([\d%]+)["|\']?#i', $tag, $matches)) {
110
            $height = array_pop($matches);
111
        } else {
112
            unset($matches);
113
        }
114
115
        $isRelativeWidth  = strpos($width, '%') !== false;
116
        $isRelativeHeight = strpos($height, '%') !== false;
117
118
        if ($isRelativeWidth && $isRelativeHeight) {
119
            $width = $height = null;
120
        }
121
122
        // Second, let's check tag classes for a size
123
        if (preg_match('#class=["|\']?[^"\']*size-([^"\'\s]+)[^"\']*["|\']?#i', $tag, $size)) {
124
            $size = array_pop($size);
125
126
            $isUnsetWidth  = $width === null;
127
            $isUnsetHeight = $height === null;
128
            $isFullSize    = $size === 'full';
129
130
            if ($isUnsetWidth && $isUnsetHeight && !$isFullSize) {
131
                if (in_array($size, ['thumbnail', 'medium', 'medium_large', 'large'], true)) {
132
                    $width  = (int)get_option($size . '_size_w');
0 ignored issues
show
Bug introduced by
The function get_option 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

132
                    $width  = (int)/** @scrutinizer ignore-call */ get_option($size . '_size_w');
Loading history...
133
                    $height = (int)get_option($size . '_size_h');
134
                    $crop   = (bool)get_option($size . '_crop');
135
                } elseif (isset($GLOBALS['_wp_additional_image_sizes'][$size])) {
136
                    $width  = $GLOBALS['_wp_additional_image_sizes'][$size]['width'];
137
                    $height = $GLOBALS['_wp_additional_image_sizes'][$size]['height'];
138
                    $crop   = $GLOBALS['_wp_additional_image_sizes'][$size]['crop'];
139
                }
140
            }
141
        } else {
142
            unset($size);
143
        }
144
145
        // Third, let's check for the attachment
146
        if (preg_match('#class=["|\']?[^"\']*wp-image-([\d]+)[^"\']*["|\']?#i', $tag, $attachmentId)) {
147
            $attachmentId = (int)array_pop($attachmentId);
148
149
            $attachment = get_post($attachmentId);
0 ignored issues
show
Bug introduced by
The function get_post 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

149
            $attachment = /** @scrutinizer ignore-call */ get_post($attachmentId);
Loading history...
150
151
            if ($attachment && !is_wp_error($attachment) && $attachment->post_type === 'attachment') {
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

151
            if ($attachment && !/** @scrutinizer ignore-call */ is_wp_error($attachment) && $attachment->post_type === 'attachment') {
Loading history...
152
                [$attachmentUrl, $attachmentWidth, $attachmentHeight] = wp_get_attachment_image_src(
0 ignored issues
show
Bug introduced by
The function wp_get_attachment_image_src 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

152
                [$attachmentUrl, $attachmentWidth, $attachmentHeight] = /** @scrutinizer ignore-call */ wp_get_attachment_image_src(
Loading history...
153
                    $attachmentId,
154
                    $size ?? 'full'
155
                );
156
157
                if (is_processable_image_url($attachmentUrl)) {
158
                    $hasBiggerWidth  = $width !== null && $width > $attachmentWidth;
159
                    $hasBiggerHeight = $height !== null && $height > $attachmentHeight;
160
161
                    if ($hasBiggerWidth || $hasBiggerHeight) {
162
                        $width  = $width === null ? null : min($width, $attachmentWidth);
163
                        $height = $height === null ? null : min($height, $attachmentHeight);
164
                    }
165
166
                    $isUnsetWidth  = $width === null;
167
                    $isUnsetHeight = $height === null;
168
169
                    if ($isUnsetWidth && $isUnsetHeight) {
170
                        $width  = $attachmentWidth;
171
                        $height = $attachmentHeight;
172
                        $crop   = false;
173
                    } elseif (isset($size)) {
174
                        if (in_array($size, ['thumbnail', 'medium', 'medium_large', 'large'], true)) {
175
                            $crop = (bool)get_option($size . '_crop');
176
                        } elseif (isset($GLOBALS['_wp_additional_image_sizes'][$size])) {
177
                            $crop = $GLOBALS['_wp_additional_image_sizes'][$size]['crop'];
178
                        }
179
                    }
180
                }
181
            } else {
182
                unset($attachmentId, $attachment);
183
            }
184
        } else {
185
            unset($attachmentId);
186
        }
187
188
        return compact('width', 'height', 'crop');
189
    }
190
191
    /**
192
     * @param string $tag
193
     *
194
     * @return array
195
     */
196
    private function resolveDimensionsFromTagAttributes(string $tag): array
0 ignored issues
show
Unused Code introduced by
The method resolveDimensionsFromTagAttributes() is not used, and could be removed.

This check looks for private methods that have been defined, but are not used inside the class.

Loading history...
197
    {
198
        $width = $height = null;
199
200
        if (preg_match('#width=["|\']?([\d%]+)["|\']?#i', $tag, $matches)) {
201
            $width = array_pop($matches);
202
        } else {
203
            unset($matches);
204
        }
205
206
        if (preg_match('#height=["|\']?([\d%]+)["|\']?#i', $tag, $matches)) {
207
            $height = array_pop($matches);
208
        } else {
209
            unset($matches);
210
        }
211
212
        $isRelativeWidth  = $width && strpos($width, '%') !== false;
213
        $isRelativeHeight = $height && strpos($height, '%') !== false;
214
215
        if ($isRelativeWidth && $isRelativeHeight) {
216
            $width = $height = null;
217
        }
218
219
        return [$width, $height];
220
    }
221
222
    /**
223
     * @param string $tag
224
     *
225
     * @return array
226
     */
227
    private function resolveDimensionsFromTagClass(string $tag): array
0 ignored issues
show
Unused Code introduced by
The method resolveDimensionsFromTagClass() is not used, and could be removed.

This check looks for private methods that have been defined, but are not used inside the class.

Loading history...
228
    {
229
        $width = $height = null;
230
        $crop  = false;
231
232
        if (preg_match('#class=["|\']?[^"\']*size-([^"\'\s]+)[^"\']*["|\']?#i', $tag, $size)) {
233
            $size = array_pop($size);
234
235
            $isFullSize = $size === 'full';
236
237
            if (!$isFullSize) {
238
                $withinBuiltinSizes    = in_array($size, ['thumbnail', 'medium', 'medium_large', 'large'], true);
239
                $withinAdditionalSizes = isset($GLOBALS['_wp_additional_image_sizes'][$size]);
240
241
                if ($withinBuiltinSizes) {
242
                    $width  = (int)get_option($size . '_size_w');
0 ignored issues
show
Bug introduced by
The function get_option 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

242
                    $width  = (int)/** @scrutinizer ignore-call */ get_option($size . '_size_w');
Loading history...
243
                    $height = (int)get_option($size . '_size_h');
244
                    $crop   = (bool)get_option($size . '_crop');
245
                } elseif ($withinAdditionalSizes) {
246
                    $width  = $GLOBALS['_wp_additional_image_sizes'][$size]['width'];
247
                    $height = $GLOBALS['_wp_additional_image_sizes'][$size]['height'];
248
                    $crop   = $GLOBALS['_wp_additional_image_sizes'][$size]['crop'];
249
                }
250
            }
251
        } else {
252
            unset($size);
253
        }
254
255
        return [$width, $height, $crop];
256
    }
257
258
    /**
259
     * @param string $url
260
     *
261
     * @return array
262
     */
263
    private function resolveDimensionsFromUrl(string $url): array
0 ignored issues
show
Unused Code introduced by
The method resolveDimensionsFromUrl() is not used, and could be removed.

This check looks for private methods that have been defined, but are not used inside the class.

Loading history...
264
    {
265
        $width = $height = null;
266
267
        if (preg_match('#-(\d+)x(\d+)\.(?:' . implode('|', supported_formats()) . '){1}$#i', $url, $matches)) {
268
            $width  = (int)$matches[1];
269
            $height = (int)$matches[2];
270
        } else {
271
            unset($matches);
272
        }
273
274
        return [$width, $height];
275
    }
276
}
277