Total Complexity | 52 |
Total Lines | 268 |
Duplicated Lines | 0 % |
Changes | 3 | ||
Bugs | 0 | Features | 0 |
Complex classes like Content 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 Content, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
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); |
||
|
|||
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); |
||
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); |
||
48 | die; |
||
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 |
||
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'); |
||
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); |
||
150 | |||
151 | if ($attachment && !is_wp_error($attachment) && $attachment->post_type === 'attachment') { |
||
152 | [$attachmentUrl, $attachmentWidth, $attachmentHeight] = wp_get_attachment_image_src( |
||
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 |
||
220 | } |
||
221 | |||
222 | /** |
||
223 | * @param string $tag |
||
224 | * |
||
225 | * @return array |
||
226 | */ |
||
227 | private function resolveDimensionsFromTagClass(string $tag): array |
||
256 | } |
||
257 | |||
258 | /** |
||
259 | * @param string $url |
||
260 | * |
||
261 | * @return array |
||
262 | */ |
||
263 | private function resolveDimensionsFromUrl(string $url): array |
||
277 |