PluginProbe
Optimole – Optimize Images | Convert WebP & AVIF | CDN & Lazy Load | Image Optimization / 4.2.11
Optimole – Optimize Images | Convert WebP & AVIF | CDN & Lazy Load | Image Optimization v4.2.11
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 3.12.1 All 134 releases
optimole-wp / inc / traits / dam_offload_utils.php

dam_offload_utils.php in Optimole – Optimize Images | Convert WebP & AVIF | CDN & Lazy Load | Image Optimization 4.2.11, at inc/traits/dam_offload_utils.php

352 lines 9.2 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 trait Optml_Dam_Offload_Utils {
4 use Optml_Normalizer;
5
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 /**
17 * Checks that the attachment is a DAM image.
18 *
19 * @param int $post_id The attachment ID.
20 *
21 * @return bool
22 */
23 private function is_dam_imported_image( $post_id ) {
24 $meta = get_post_meta( $post_id, Optml_Dam::OM_DAM_IMPORTED_FLAG, true );
25
26 if ( empty( $meta ) ) {
27 return false;
28 }
29
30 return true;
31 }
32
33 /**
34 * Checks if the attachment is offloaded using the old method.
35 *
36 * @param int $id The attachment ID.
37 *
38 * @return bool
39 */
40 private function is_legacy_offloaded_attachment( $id ) {
41 $id = apply_filters( 'optml_ensure_source_attachment_id', $id );
42
43 return ! $this->is_new_offloaded_attachment( $id ) && ! empty( get_post_meta( $id, Optml_Media_Offload::META_KEYS['offloaded'] ) );
44 }
45
46 /**
47 * Check if it's a newly offloaded attachment
48 *
49 * @param int $id The attachment ID.
50 *
51 * @return bool
52 */
53 private function is_new_offloaded_attachment( $id ) {
54 $id = apply_filters( 'optml_ensure_source_attachment_id', $id );
55
56 return ! empty( get_post_meta( $id, Optml_Media_Offload::OM_OFFLOADED_FLAG, true ) );
57 }
58
59 /**
60 * Get all registered image sizes.
61 *
62 * @return array<string, array{width: int, height: int, crop: bool|array<int, string>}>
63 */
64 private function get_all_image_sizes() {
65 $additional_sizes = wp_get_additional_image_sizes();
66 $intermediate = get_intermediate_image_sizes();
67 $all = [];
68
69 foreach ( $intermediate as $size ) {
70 if ( isset( $additional_sizes[ $size ] ) ) {
71 $all[ $size ] = [
72 'width' => $additional_sizes[ $size ]['width'],
73 'height' => $additional_sizes[ $size ]['height'],
74 'crop' => isset( $additional_sizes[ $size ]['crop'] ) ? $additional_sizes[ $size ]['crop'] : false,
75 ];
76 } else {
77 $all[ $size ] = [
78 'width' => (int) get_option( $size . '_size_w' ),
79 'height' => (int) get_option( $size . '_size_h' ),
80 'crop' => get_option( $size . '_crop' ),
81 ];
82 }
83
84 if ( ! empty( $additional_sizes[ $size ]['crop'] ) ) {
85 $all[ $size ]['crop'] = is_array( $additional_sizes[ $size ]['crop'] ) ? $additional_sizes[ $size ]['crop'] : (bool) $additional_sizes[ $size ]['crop'];
86
87 } else {
88 $all[ $size ]['crop'] = (bool) get_option( $size . '_crop' );
89 }
90 }
91
92 return $all;
93 }
94
95 /**
96 * Get the dimension from optimized url.
97 *
98 * @param string $url The image url.
99 *
100 * @return array{0: string|false, 1: string|false} Contains the width and height values in this order.
101 */
102 private function parse_dimension_from_optimized_url( $url ) {
103 $catch = [];
104 $height = false;
105 $width = false;
106 preg_match( '/\/w:(.*)\/h:(.*)\/q:/', $url, $catch );
107 if ( isset( $catch[1] ) && isset( $catch[2] ) ) {
108 $width = $catch[1];
109 $height = $catch[2];
110 }
111 return [ $width, $height ];
112 }
113
114 /**
115 * Check if we're in the attachment edit page.
116 *
117 * /wp-admin/post.php?post=<id>&action=edit
118 *
119 * Send whatever comes from the DAM.
120 *
121 * @param int $attachment_id attachment id.
122 *
123 * @return bool
124 */
125 private function is_attachment_edit_page( $attachment_id ) {
126 if ( ! is_admin() ) {
127 return false;
128 }
129
130 if ( ! function_exists( 'get_current_screen' ) ) {
131 return false;
132 }
133
134 $screen = get_current_screen();
135
136 if ( ! isset( $screen->base ) ) {
137 return false;
138 }
139
140 if ( $screen->base !== 'post' ) {
141 return false;
142 }
143
144 if ( $screen->post_type !== 'attachment' ) {
145 return false;
146 }
147
148 if ( $screen->id !== 'attachment' ) {
149 return false;
150 }
151
152 if ( ! isset( $_GET['post'] ) ) {
153 return false;
154 }
155
156 if ( (int) sanitize_text_field( $_GET['post'] ) !== $attachment_id ) {
157 return false;
158 }
159
160 return true;
161 }
162
163 /**
164 * Used to filter the image metadata. Adds optimized image url for all image sizes.
165 *
166 * @param array<string, mixed> $metadata The attachment metadata.
167 * @param int $id The attachment id.
168 *
169 * @return array<string, mixed>
170 */
171 private function get_altered_metadata_for_remote_images( $metadata, $id ) {
172
173 $post = get_post( $id );
174
175 $sizes_meta = [];
176
177 // SVG files don't have a width/height so we add a dummy one. These are vector images so it doesn't matter.
178 $is_svg = ( $post->post_mime_type === Optml_Config::$image_extensions['svg'] );
179
180 if ( $is_svg ) {
181 $metadata['width'] = 150;
182 $metadata['height'] = 150;
183 }
184
185 if ( ! isset( $metadata['height'] ) || ! isset( $metadata['width'] ) ) {
186 return $metadata;
187 }
188 $sizes = Optml_App_Replacer::image_sizes();
189 foreach ( $sizes as $size => $args ) {
190 // check if the image is portrait or landscape using attachment metadata.
191 $dimensions = $this->size_to_dimension( $size, $metadata );
192 $sizes_meta[ $size ] = [
193 'file' => $metadata['file'],
194 'width' => $dimensions['width'],
195 'height' => $dimensions['height'],
196 'mime-type' => $post->post_mime_type,
197 ];
198 }
199
200 $metadata['sizes'] = $sizes_meta;
201
202 return $metadata;
203 }
204
205 /**
206 * Get the scaled URL.
207 *
208 * @param string $url Original URL.
209 *
210 * @return string
211 */
212 private function get_scaled_url( $url ) {
213 $extension = pathinfo( $url, PATHINFO_EXTENSION );
214
215 return str_replace( '.' . $extension, '-scaled.' . $extension, $url );
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 }
227
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 /**
278 * Get the attachment ID from URL.
279 *
280 * @param string $input_url The attachment URL.
281 *
282 * @return int
283 */
284 private function attachment_url_to_post_id( $input_url ) {
285 $cached = Optml_Attachment_Cache::get_cached_attachment_id( $input_url );
286
287 if ( $cached !== false ) {
288 return (int) $cached;
289 }
290
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 );
298
299 return $attachment_id;
300 }
301 }
302 }
303
304 $url = $this->strip_image_size( $input_url );
305
306 $attachment_id = attachment_url_to_postid( $url );
307
308 if ( $attachment_id === 0 && ! $this->is_scaled_url( $url ) ) {
309 $scaled_url = $this->get_scaled_url( $url );
310
311 $attachment_id = attachment_url_to_postid( $scaled_url );
312 }
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 */
318 if ( $attachment_id === 0 ) {
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 }
331 }
332 Optml_Attachment_Cache::set_cached_attachment_id( $input_url, $attachment_id );
333
334 return $attachment_id;
335 }
336
337 /**
338 * Strips the image size from the URL.
339 *
340 * @param string $url URL to strip.
341 *
342 * @return string
343 */
344 private function strip_image_size( $url ) {
345 if ( preg_match( '#(-\d+x\d+(?:_c)?|(@2x))\.(' . implode( '|', array_keys( Optml_Config::$image_extensions ) ) . '){1}$#i', $url, $src_parts ) ) {
346 $url = str_replace( $src_parts[1], '', $url );
347 }
348
349 return $url;
350 }
351 }
352