PluginProbe
Optimole – Optimize Images | Convert WebP & AVIF | CDN & Lazy Load | Image Optimization / trunk
Optimole – Optimize Images | Convert WebP & AVIF | CDN & Lazy Load | Image Optimization vtrunk
4.2.14 4.2.13 4.2.12 4.2.11 4.2.10 4.2.9 4.2.8 4.2.7 4.2.6 4.2.5 2.5.5 2.5.6 2.5.7 3.0.0 3.0.1 3.1.0 3.1.1 3.1.2 3.1.3 3.10.0 3.11.0 3.11.1 3.11.2 3.11.3 3.12.0 All 135 releases
← All changes | inc/traits/dam_offload_utils.php +122 -32 3.11.0 → trunk View file →
@@ -1,8 +1,20 @@
1 1 <?php
2 2
3 3 trait Optml_Dam_Offload_Utils {
4 + use Optml_Normalizer;
5 +
4 6 /**
7 + * Check if this contains the DAM flag.
8 + *
9 + * @param string $url The URL to check.
10 + *
11 + * @return bool
12 + */
13 + private function is_dam_url( $url ) {
14 + return strpos( $url, Optml_Dam::URL_DAM_FLAG ) !== false;
15 + }
16 + /**
5 17 * Checks that the attachment is a DAM image.
6 18 *
7 19 * @param int $post_id The attachment ID.
8 20 *
@@ -25,8 +37,10 @@
25 37 *
26 38 * @return bool
27 39 */
28 40 private function is_legacy_offloaded_attachment( $id ) {
41 + $id = apply_filters( 'optml_ensure_source_attachment_id', $id );
42 +
29 43 return ! $this->is_new_offloaded_attachment( $id ) && ! empty( get_post_meta( $id, Optml_Media_Offload::META_KEYS['offloaded'] ) );
30 44 }
31 45
32 46 /**
@@ -36,8 +50,10 @@
36 50 *
37 51 * @return bool
38 52 */
39 53 private function is_new_offloaded_attachment( $id ) {
54 + $id = apply_filters( 'optml_ensure_source_attachment_id', $id );
55 +
40 56 return ! empty( get_post_meta( $id, Optml_Media_Offload::OM_OFFLOADED_FLAG, true ) );
41 57 }
42 58
43 59 /**
@@ -42,9 +58,9 @@
42 58
43 59 /**
44 60 * Get all registered image sizes.
45 61 *
46 - * @return array
62 + * @return array<string, array{width: int, height: int, crop: bool|array<int, string>}>
47 63 */
48 64 private function get_all_image_sizes() {
49 65 $additional_sizes = wp_get_additional_image_sizes();
50 66 $intermediate = get_intermediate_image_sizes();
@@ -80,14 +96,14 @@
80 96 * Get the dimension from optimized url.
81 97 *
82 98 * @param string $url The image url.
83 99 *
84 - * @return array Contains the width and height values in this order.
100 + * @return array{0: string|false, 1: string|false} Contains the width and height values in this order.
85 101 */
86 102 private function parse_dimension_from_optimized_url( $url ) {
87 103 $catch = [];
88 - $height = 'auto';
89 - $width = 'auto';
104 + $height = false;
105 + $width = false;
90 106 preg_match( '/\/w:(.*)\/h:(.*)\/q:/', $url, $catch );
91 107 if ( isset( $catch[1] ) && isset( $catch[2] ) ) {
92 108 $width = $catch[1];
93 109 $height = $catch[2];
@@ -146,15 +162,14 @@
146 162
147 163 /**
148 164 * Used to filter the image metadata. Adds optimized image url for all image sizes.
149 165 *
150 - * @param array $metadata The attachment metadata.
151 - * @param int $id The attachment id.
166 + * @param array<string, mixed> $metadata The attachment metadata.
167 + * @param int $id The attachment id.
152 168 *
153 - * @return mixed
169 + * @return array<string, mixed>
154 170 */
155 171 private function get_altered_metadata_for_remote_images( $metadata, $id ) {
156 - $sizes = $this->get_all_image_sizes();
157 172
158 173 $post = get_post( $id );
159 174
160 175 $sizes_meta = [];
@@ -169,26 +184,16 @@
169 184
170 185 if ( ! isset( $metadata['height'] ) || ! isset( $metadata['width'] ) ) {
171 186 return $metadata;
172 187 }
173 -
188 + $sizes = Optml_App_Replacer::image_sizes();
174 189 foreach ( $sizes as $size => $args ) {
175 190 // check if the image is portrait or landscape using attachment metadata.
176 - $is_portrait = $metadata['height'] > $metadata['width'];
177 -
178 - // proportionally set the width/height based on this if image is uncropped.
179 - if ( ! (bool) $args['crop'] ) {
180 - if ( $is_portrait ) {
181 - $args['width'] = (int) ( $args['height'] * round( $metadata['width'] / $metadata['height'] ) );
182 - } else {
183 - $args['height'] = (int) ( $args['width'] * round( $metadata['height'] / $metadata['width'] ) );
184 - }
185 - }
186 -
191 + $dimensions = $this->size_to_dimension( $size, $metadata );
187 192 $sizes_meta[ $size ] = [
188 193 'file' => $metadata['file'],
189 - 'width' => $args['width'],
190 - 'height' => $args['height'],
194 + 'width' => $dimensions['width'],
195 + 'height' => $dimensions['height'],
191 196 'mime-type' => $post->post_mime_type,
192 197 ];
193 198 }
194 199
@@ -208,39 +213,125 @@
208 213 $extension = pathinfo( $url, PATHINFO_EXTENSION );
209 214
210 215 return str_replace( '.' . $extension, '-scaled.' . $extension, $url );
211 216 }
217 + /**
218 + * Check if the URL is a scaled image.
219 + *
220 + * @param string $url The URL to check.
221 + *
222 + * @return bool
223 + */
224 + private function is_scaled_url( $url ) {
225 + return strpos( $url, '-scaled.' ) !== false;
226 + }
212 227
213 228 /**
229 + * Check if the image has been offloaded completely.
230 + *
231 + * @param int $id The attachment ID.
232 + *
233 + * @return bool
234 + */
235 + private function is_completed_offload( $id ) {
236 + // This is the flag that is used to mark the image as offloaded at the end.
237 + $completed = ! empty( get_post_meta( $id, Optml_Media_Offload::OM_OFFLOADED_FLAG, true ) );
238 + if ( $completed ) {
239 + return true;
240 + }
241 + // In some rare cases the image is offloaded but the flag is not set so we can alternatively check this using the file path.
242 + $meta = wp_get_attachment_metadata( $id );
243 + if ( ! isset( $meta['file'] ) ) {
244 + return false;
245 + }
246 + if ( Optml_Media_Offload::is_uploaded_image( $meta['file'] ) ) {
247 + return true;
248 + }
249 +
250 + return false;
251 + }
252 + /**
253 + * Get the attachment ID from optimole ID.
254 + *
255 + * @param string $optimole_id The optimole ID.
256 + *
257 + * @return int
258 + */
259 + private function get_attachement_id_from_optimole_id( string $optimole_id ): int {
260 + global $wpdb;
261 +
262 + $id = $wpdb->get_var(
263 + $wpdb->prepare(
264 + "
265 + SELECT post_id
266 + FROM {$wpdb->postmeta}
267 + WHERE meta_key = %s
268 + AND meta_value = %s
269 + LIMIT 1
270 + ",
271 + Optml_Dam::OM_DAM_IMPORTED_FLAG,
272 + $optimole_id
273 + )
274 + );
275 + return empty( $id ) ? 0 : (int) $id;
276 + }
277 + /**
214 278 * Get the attachment ID from URL.
215 279 *
216 - * @param string $url The attachment URL.
280 + * @param string $input_url The attachment URL.
217 281 *
218 282 * @return int
219 283 */
220 - private function attachment_url_to_post_id( $url ) {
221 - $cached = Optml_Attachment_Cache::get_cached_attachment_id( $url );
284 + private function attachment_url_to_post_id( $input_url ) {
285 + $cached = Optml_Attachment_Cache::get_cached_attachment_id( $input_url );
222 286
223 287 if ( $cached !== false ) {
224 - return $cached;
288 + return (int) $cached;
225 289 }
226 290
227 - $url = $this->strip_image_size( $url );
291 + if ( Optml_Media_Offload::is_uploaded_image( $input_url ) ) {
292 + // The DAM are stored as attachments of format /id:<attachment_id>/<original_url>
293 + $pattern = '#/' . Optml_Media_Offload::KEYS['uploaded_flag'] . '([^/]+)#';
294 + if ( preg_match( $pattern, $input_url, $m ) ) {
295 + $attachment_id = $this->get_attachement_id_from_optimole_id( $m[1] );
296 + if ( $attachment_id !== 0 ) {
297 + Optml_Attachment_Cache::set_cached_attachment_id( $input_url, $attachment_id );
228 298
299 + return $attachment_id;
300 + }
301 + }
302 + }
303 +
304 + $url = $this->strip_image_size( $input_url );
305 +
229 306 $attachment_id = attachment_url_to_postid( $url );
230 307
231 - if ( $attachment_id === 0 ) {
308 + if ( $attachment_id === 0 && ! $this->is_scaled_url( $url ) ) {
232 309 $scaled_url = $this->get_scaled_url( $url );
233 310
234 311 $attachment_id = attachment_url_to_postid( $scaled_url );
235 312 }
236 313
314 + /*
315 + * TODO: The logic is a mess, we need to refactor at some point.
316 + * Websites may transition between 'www' subdomains and apex domains, potentially breaking references to hosted images. This can cause issues when attempting to match attachment IDs if images are linked using outdated domains. The logic is checking for alternative domains and consider the use of 'scaled' prefixes in image URLs for large images, which might affect ID matching.
317 + */
237 318 if ( $attachment_id === 0 ) {
238 - return $attachment_id;
319 + if ( strpos( $url, 'www.' ) !== false ) {
320 + $variant_url = str_replace( 'www.', '', $url );
321 + $attachment_id = attachment_url_to_postid( $variant_url );
322 + } else {
323 + $variant_url = str_replace( '://', '://www.', $url );
324 + $attachment_id = attachment_url_to_postid( $variant_url );
325 + }
326 + if ( $attachment_id === 0 && ! $this->is_scaled_url( $variant_url ) ) {
327 + $scaled_url = $this->get_scaled_url( $variant_url );
328 +
329 + $attachment_id = attachment_url_to_postid( $scaled_url );
330 + }
239 331 }
332 + Optml_Attachment_Cache::set_cached_attachment_id( $input_url, $attachment_id );
240 333
241 - Optml_Attachment_Cache::set_cached_attachment_id( $url, $attachment_id );
242 -
243 334 return $attachment_id;
244 335 }
245 336
246 337 /**
@@ -255,7 +346,6 @@
255 346 $url = str_replace( $src_parts[1], '', $url );
256 347 }
257 348
258 349 return $url;
259 -
260 350 }
261 351 }