| 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 |