run:R W Run
7.85 KB
2026-03-11 16:18:51
R W Run
3.54 KB
2026-03-11 16:18:51
R W Run
148.33 KB
2026-03-11 16:18:51
R W Run
11.45 KB
2026-03-11 16:18:51
R W Run
3.58 KB
2026-03-11 16:18:51
R W Run
2.53 KB
2026-03-11 16:18:51
R W Run
2.6 KB
2026-03-11 16:18:51
R W Run
6.59 KB
2026-03-11 16:18:51
R W Run
14.83 KB
2026-03-11 16:18:51
R W Run
21.18 KB
2026-03-11 16:18:51
R W Run
48.13 KB
2026-03-11 16:18:51
R W Run
4.07 KB
2026-03-11 16:18:51
R W Run
5.3 KB
2026-03-11 16:18:51
R W Run
8.28 KB
2026-03-11 16:18:51
R W Run
26.73 KB
2026-03-11 16:18:51
R W Run
2.8 KB
2026-03-11 16:18:51
R W Run
15.2 KB
2026-03-11 16:18:51
R W Run
192.08 KB
2026-03-11 16:18:51
R W Run
11.77 KB
2026-03-11 16:18:51
R W Run
3.2 KB
2026-03-11 16:18:51
R W Run
22.89 KB
2026-03-11 16:18:51
R W Run
12.77 KB
2026-03-11 16:18:51
R W Run
4.08 KB
2026-03-11 16:18:51
R W Run
26.27 KB
2026-03-11 16:18:51
R W Run
4.97 KB
2026-03-11 16:18:51
R W Run
5.57 KB
2026-03-11 16:18:51
R W Run
13.93 KB
2026-03-11 16:18:51
R W Run
4.09 KB
2026-03-11 16:18:51
R W Run
6.79 KB
2026-03-11 16:18:51
R W Run
60.45 KB
2026-03-11 16:18:51
R W Run
32.4 KB
2026-03-11 16:18:51
R W Run
18.24 KB
2026-03-11 16:18:51
R W Run
66.01 KB
2026-03-11 16:18:51
R W Run
23.84 KB
2026-03-11 16:18:51
R W Run
17.72 KB
2026-03-11 16:18:51
R W Run
22.71 KB
2026-03-11 16:18:51
R W Run
18.05 KB
2026-03-11 16:18:51
R W Run
22.76 KB
2026-03-11 16:18:51
R W Run
7.34 KB
2026-03-11 16:18:51
R W Run
4.51 KB
2026-03-11 16:18:51
R W Run
9.02 KB
2026-03-11 16:18:51
R W Run
1.46 KB
2026-03-11 16:18:51
R W Run
51.76 KB
2026-03-11 16:18:51
R W Run
25.29 KB
2026-03-11 16:18:51
R W Run
21.61 KB
2026-03-11 16:18:51
R W Run
27.77 KB
2026-03-11 16:18:51
R W Run
15.35 KB
2026-03-11 16:18:51
R W Run
24.54 KB
2026-03-11 16:18:51
R W Run
56.44 KB
2026-03-11 16:18:51
R W Run
1.42 KB
2026-03-11 16:18:51
R W Run
63.66 KB
2026-03-11 16:18:51
R W Run
31.9 KB
2026-03-11 16:18:51
R W Run
14.44 KB
2026-03-11 16:18:51
R W Run
36.47 KB
2026-03-11 16:18:51
R W Run
14 KB
2026-03-11 16:18:51
R W Run
121.89 KB
2026-03-11 16:18:51
R W Run
6.26 KB
2026-03-11 16:18:51
R W Run
20.73 KB
2026-03-11 16:18:51
R W Run
15.23 KB
2026-03-11 16:18:51
R W Run
10.14 KB
2026-03-11 16:18:51
R W Run
6.94 KB
2026-03-11 16:18:51
R W Run
1.44 KB
2026-03-11 16:18:51
R W Run
46.85 KB
2026-03-11 16:18:51
R W Run
18.61 KB
2026-03-11 16:18:51
R W Run
6.08 KB
2026-03-11 16:18:51
R W Run
20.06 KB
2026-03-11 16:18:51
R W Run
5.73 KB
2026-03-11 16:18:51
R W Run
68.18 KB
2026-03-11 16:18:51
R W Run
40.8 KB
2026-03-11 16:18:51
R W Run
1.44 KB
2026-03-11 16:18:51
R W Run
25.26 KB
2026-03-11 16:18:51
R W Run
95.94 KB
2026-03-11 16:18:51
R W Run
43.12 KB
2026-03-11 16:18:51
R W Run
41.73 KB
2026-03-11 16:18:51
R W Run
6.46 KB
2026-03-11 16:18:51
R W Run
3.71 KB
2026-03-11 16:18:51
R W Run
116.31 KB
2026-03-11 16:18:51
R W Run
9.39 KB
2026-03-11 16:18:51
R W Run
64.34 KB
2026-03-11 16:18:51
R W Run
44.73 KB
2026-03-11 16:18:51
R W Run
1.27 KB
2026-03-11 16:18:51
R W Run
3.68 KB
2026-03-11 16:18:51
R W Run
33.53 KB
2026-03-11 16:18:51
R W Run
48.84 KB
2026-03-11 16:18:51
R W Run
26.35 KB
2026-03-11 16:18:51
R W Run
1.12 KB
2026-03-11 16:18:51
R W Run
4.19 KB
2026-03-11 16:18:51
R W Run
38.19 KB
2026-03-11 16:18:51
R W Run
91.33 KB
2026-03-11 16:18:51
R W Run
80.39 KB
2026-03-11 16:18:51
R W Run
32.67 KB
2026-03-11 16:18:51
R W Run
16.18 KB
2026-03-11 16:18:51
R W Run
44.46 KB
2026-03-11 16:18:51
R W Run
6.23 KB
2026-03-11 16:18:51
R W Run
8.23 KB
2026-03-11 16:18:51
R W Run
96.96 KB
2026-03-11 16:18:51
R W Run
6.83 KB
2026-03-11 16:18:51
R W Run
46.62 KB
2026-03-11 16:18:51
R W Run
10.82 KB
2026-03-11 16:18:51
R W Run
68.86 KB
2026-03-11 16:18:51
R W Run
33.63 KB
2026-03-11 16:18:51
R W Run
113.3 KB
2026-03-11 16:18:51
R W Run
22.98 KB
2026-03-11 16:18:51
R W Run
10.66 KB
2026-03-11 16:18:51
R W Run
error_log
📄image.php
1<?php
2/**
3 * File contains all the administration image manipulation functions.
4 *
5 * @package WordPress
6 * @subpackage Administration
7 */
8
9/**
10 * Crops an image to a given size.
11 *
12 * @since 2.1.0
13 *
14 * @param string|int $src The source file or Attachment ID.
15 * @param int $src_x The start x position to crop from.
16 * @param int $src_y The start y position to crop from.
17 * @param int $src_w The width to crop.
18 * @param int $src_h The height to crop.
19 * @param int $dst_w The destination width.
20 * @param int $dst_h The destination height.
21 * @param bool|false $src_abs Optional. If the source crop points are absolute.
22 * @param string|false $dst_file Optional. The destination file to write to.
23 * @return string|WP_Error New filepath on success, WP_Error on failure.
24 */
25function wp_crop_image( $src, $src_x, $src_y, $src_w, $src_h, $dst_w, $dst_h, $src_abs = false, $dst_file = false ) {
26 $src_file = $src;
27 if ( is_numeric( $src ) ) { // Handle int as attachment ID.
28 $src_file = get_attached_file( $src );
29
30 if ( ! file_exists( $src_file ) ) {
31 /*
32 * If the file doesn't exist, attempt a URL fopen on the src link.
33 * This can occur with certain file replication plugins.
34 */
35 $src = _load_image_to_edit_path( $src, 'full' );
36 } else {
37 $src = $src_file;
38 }
39 }
40
41 $editor = wp_get_image_editor( $src );
42 if ( is_wp_error( $editor ) ) {
43 return $editor;
44 }
45
46 $src = $editor->crop( $src_x, $src_y, $src_w, $src_h, $dst_w, $dst_h, $src_abs );
47 if ( is_wp_error( $src ) ) {
48 return $src;
49 }
50
51 if ( ! $dst_file ) {
52 $dst_file = str_replace( wp_basename( $src_file ), 'cropped-' . wp_basename( $src_file ), $src_file );
53 }
54
55 /*
56 * The directory containing the original file may no longer exist when
57 * using a replication plugin.
58 */
59 wp_mkdir_p( dirname( $dst_file ) );
60
61 $dst_file = dirname( $dst_file ) . '/' . wp_unique_filename( dirname( $dst_file ), wp_basename( $dst_file ) );
62
63 $result = $editor->save( $dst_file );
64 if ( is_wp_error( $result ) ) {
65 return $result;
66 }
67
68 if ( ! empty( $result['path'] ) ) {
69 return $result['path'];
70 }
71
72 return $dst_file;
73}
74
75/**
76 * Compare the existing image sub-sizes (as saved in the attachment meta)
77 * to the currently registered image sub-sizes, and return the difference.
78 *
79 * Registered sub-sizes that are larger than the image are skipped.
80 *
81 * @since 5.3.0
82 *
83 * @param int $attachment_id The image attachment post ID.
84 * @return array[] Associative array of arrays of image sub-size information for
85 * missing image sizes, keyed by image size name.
86 */
87function wp_get_missing_image_subsizes( $attachment_id ) {
88 if ( ! wp_attachment_is_image( $attachment_id ) ) {
89 return array();
90 }
91
92 $registered_sizes = wp_get_registered_image_subsizes();
93 $image_meta = wp_get_attachment_metadata( $attachment_id );
94
95 // Meta error?
96 if ( empty( $image_meta ) ) {
97 return $registered_sizes;
98 }
99
100 // Use the originally uploaded image dimensions as full_width and full_height.
101 if ( ! empty( $image_meta['original_image'] ) ) {
102 $image_file = wp_get_original_image_path( $attachment_id );
103 $imagesize = wp_getimagesize( $image_file );
104 }
105
106 if ( ! empty( $imagesize ) ) {
107 $full_width = $imagesize[0];
108 $full_height = $imagesize[1];
109 } else {
110 $full_width = (int) $image_meta['width'];
111 $full_height = (int) $image_meta['height'];
112 }
113
114 $possible_sizes = array();
115
116 // Skip registered sizes that are too large for the uploaded image.
117 foreach ( $registered_sizes as $size_name => $size_data ) {
118 if ( image_resize_dimensions( $full_width, $full_height, $size_data['width'], $size_data['height'], $size_data['crop'] ) ) {
119 $possible_sizes[ $size_name ] = $size_data;
120 }
121 }
122
123 if ( empty( $image_meta['sizes'] ) ) {
124 $image_meta['sizes'] = array();
125 }
126
127 /*
128 * Remove sizes that already exist. Only checks for matching "size names".
129 * It is possible that the dimensions for a particular size name have changed.
130 * For example the user has changed the values on the Settings -> Media screen.
131 * However we keep the old sub-sizes with the previous dimensions
132 * as the image may have been used in an older post.
133 */
134 $missing_sizes = array_diff_key( $possible_sizes, $image_meta['sizes'] );
135
136 /**
137 * Filters the array of missing image sub-sizes for an uploaded image.
138 *
139 * @since 5.3.0
140 *
141 * @param array[] $missing_sizes Associative array of arrays of image sub-size information for
142 * missing image sizes, keyed by image size name.
143 * @param array $image_meta The image meta data.
144 * @param int $attachment_id The image attachment post ID.
145 */
146 return apply_filters( 'wp_get_missing_image_subsizes', $missing_sizes, $image_meta, $attachment_id );
147}
148
149/**
150 * If any of the currently registered image sub-sizes are missing,
151 * create them and update the image meta data.
152 *
153 * @since 5.3.0
154 *
155 * @param int $attachment_id The image attachment post ID.
156 * @return array|WP_Error The updated image meta data array or WP_Error object
157 * if both the image meta and the attached file are missing.
158 */
159function wp_update_image_subsizes( $attachment_id ) {
160 $image_meta = wp_get_attachment_metadata( $attachment_id );
161 $image_file = wp_get_original_image_path( $attachment_id );
162
163 if ( empty( $image_meta ) || ! is_array( $image_meta ) ) {
164 /*
165 * Previously failed upload?
166 * If there is an uploaded file, make all sub-sizes and generate all of the attachment meta.
167 */
168 if ( ! empty( $image_file ) ) {
169 $image_meta = wp_create_image_subsizes( $image_file, $attachment_id );
170 } else {
171 return new WP_Error( 'invalid_attachment', __( 'The attached file cannot be found.' ) );
172 }
173 } else {
174 $missing_sizes = wp_get_missing_image_subsizes( $attachment_id );
175
176 if ( empty( $missing_sizes ) ) {
177 return $image_meta;
178 }
179
180 // This also updates the image meta.
181 $image_meta = _wp_make_subsizes( $missing_sizes, $image_file, $image_meta, $attachment_id );
182 }
183
184 /** This filter is documented in wp-admin/includes/image.php */
185 $image_meta = apply_filters( 'wp_generate_attachment_metadata', $image_meta, $attachment_id, 'update' );
186
187 // Save the updated metadata.
188 wp_update_attachment_metadata( $attachment_id, $image_meta );
189
190 return $image_meta;
191}
192
193/**
194 * Updates the attached file and image meta data when the original image was edited.
195 *
196 * @since 5.3.0
197 * @since 6.0.0 The `$filesize` value was added to the returned array.
198 * @access private
199 *
200 * @param array $saved_data The data returned from WP_Image_Editor after successfully saving an image.
201 * @param string $original_file Path to the original file.
202 * @param array $image_meta The image meta data.
203 * @param int $attachment_id The attachment post ID.
204 * @return array The updated image meta data.
205 */
206function _wp_image_meta_replace_original( $saved_data, $original_file, $image_meta, $attachment_id ) {
207 $new_file = $saved_data['path'];
208
209 // Update the attached file meta.
210 update_attached_file( $attachment_id, $new_file );
211
212 // Width and height of the new image.
213 $image_meta['width'] = $saved_data['width'];
214 $image_meta['height'] = $saved_data['height'];
215
216 // Make the file path relative to the upload dir.
217 $image_meta['file'] = _wp_relative_upload_path( $new_file );
218
219 // Add image file size.
220 $image_meta['filesize'] = wp_filesize( $new_file );
221
222 // Store the original image file name in image_meta.
223 $image_meta['original_image'] = wp_basename( $original_file );
224
225 return $image_meta;
226}
227
228/**
229 * Creates image sub-sizes, adds the new data to the image meta `sizes` array, and updates the image metadata.
230 *
231 * Intended for use after an image is uploaded. Saves/updates the image metadata after each
232 * sub-size is created. If there was an error, it is added to the returned image metadata array.
233 *
234 * @since 5.3.0
235 *
236 * @param string $file Full path to the image file.
237 * @param int $attachment_id Attachment ID to process.
238 * @return array The image attachment meta data.
239 */
240function wp_create_image_subsizes( $file, $attachment_id ) {
241 $imagesize = wp_getimagesize( $file );
242
243 if ( empty( $imagesize ) ) {
244 // File is not an image.
245 return array();
246 }
247
248 // Default image meta.
249 $image_meta = array(
250 'width' => $imagesize[0],
251 'height' => $imagesize[1],
252 'file' => _wp_relative_upload_path( $file ),
253 'filesize' => wp_filesize( $file ),
254 'sizes' => array(),
255 );
256
257 // Fetch additional metadata from EXIF/IPTC.
258 $exif_meta = wp_read_image_metadata( $file );
259
260 if ( $exif_meta ) {
261 $image_meta['image_meta'] = $exif_meta;
262 }
263
264 /**
265 * Filters the "BIG image" threshold value.
266 *
267 * If the original image width or height is above the threshold, it will be scaled down. The threshold is
268 * used as max width and max height. The scaled down image will be used as the largest available size, including
269 * the `_wp_attached_file` post meta value.
270 *
271 * Returning `false` from the filter callback will disable the scaling.
272 *
273 * @since 5.3.0
274 *
275 * @param int $threshold The threshold value in pixels. Default 2560.
276 * @param array $imagesize {
277 * Indexed array of the image width and height in pixels.
278 *
279 * @type int $0 The image width.
280 * @type int $1 The image height.
281 * }
282 * @param string $file Full path to the uploaded image file.
283 * @param int $attachment_id Attachment post ID.
284 */
285 $threshold = (int) apply_filters( 'big_image_size_threshold', 2560, $imagesize, $file, $attachment_id );
286
287 /*
288 * If the original image's dimensions are over the threshold,
289 * scale the image and use it as the "full" size.
290 */
291 $scale_down = false;
292 $convert = false;
293
294 if ( $threshold && ( $image_meta['width'] > $threshold || $image_meta['height'] > $threshold ) ) {
295 // The image will be converted if needed on saving.
296 $scale_down = true;
297 } else {
298 // The image may need to be converted regardless of its dimensions.
299 $output_format = wp_get_image_editor_output_format( $file, $imagesize['mime'] );
300
301 if (
302 is_array( $output_format ) &&
303 array_key_exists( $imagesize['mime'], $output_format ) &&
304 $output_format[ $imagesize['mime'] ] !== $imagesize['mime']
305 ) {
306 $convert = true;
307 }
308 }
309
310 if ( $scale_down || $convert ) {
311 $editor = wp_get_image_editor( $file );
312
313 if ( is_wp_error( $editor ) ) {
314 // This image cannot be edited.
315 return $image_meta;
316 }
317
318 if ( $scale_down ) {
319 // Resize the image. This will also convet it if needed.
320 $resized = $editor->resize( $threshold, $threshold );
321 } elseif ( $convert ) {
322 // The image will be converted (if possible) when saved.
323 $resized = true;
324 }
325
326 $rotated = null;
327
328 // If there is EXIF data, rotate according to EXIF Orientation.
329 if ( ! is_wp_error( $resized ) && is_array( $exif_meta ) ) {
330 $resized = $editor->maybe_exif_rotate();
331 $rotated = $resized; // bool true or WP_Error
332 }
333
334 if ( ! is_wp_error( $resized ) ) {
335 /*
336 * Append "-scaled" to the image file name. It will look like "my_image-scaled.jpg".
337 * This doesn't affect the sub-sizes names as they are generated from the original image (for best quality).
338 */
339 if ( $scale_down ) {
340 $saved = $editor->save( $editor->generate_filename( 'scaled' ) );
341 } elseif ( $convert ) {
342 // Pass an empty string to avoid adding a suffix to converted file names.
343 $saved = $editor->save( $editor->generate_filename( '' ) );
344 } else {
345 $saved = $editor->save();
346 }
347
348 if ( ! is_wp_error( $saved ) ) {
349 $image_meta = _wp_image_meta_replace_original( $saved, $file, $image_meta, $attachment_id );
350
351 // If the image was rotated update the stored EXIF data.
352 if ( true === $rotated && ! empty( $image_meta['image_meta']['orientation'] ) ) {
353 $image_meta['image_meta']['orientation'] = 1;
354 }
355 } else {
356 // TODO: Log errors.
357 }
358 } else {
359 // TODO: Log errors.
360 }
361 } elseif ( ! empty( $exif_meta['orientation'] ) && 1 !== (int) $exif_meta['orientation'] ) {
362 // Rotate the whole original image if there is EXIF data and "orientation" is not 1.
363 $editor = wp_get_image_editor( $file );
364
365 if ( is_wp_error( $editor ) ) {
366 // This image cannot be edited.
367 return $image_meta;
368 }
369
370 // Rotate the image.
371 $rotated = $editor->maybe_exif_rotate();
372
373 if ( true === $rotated ) {
374 // Append `-rotated` to the image file name.
375 $saved = $editor->save( $editor->generate_filename( 'rotated' ) );
376
377 if ( ! is_wp_error( $saved ) ) {
378 $image_meta = _wp_image_meta_replace_original( $saved, $file, $image_meta, $attachment_id );
379
380 // Update the stored EXIF data.
381 if ( ! empty( $image_meta['image_meta']['orientation'] ) ) {
382 $image_meta['image_meta']['orientation'] = 1;
383 }
384 } else {
385 // TODO: Log errors.
386 }
387 }
388 }
389
390 /*
391 * Initial save of the new metadata.
392 * At this point the file was uploaded and moved to the uploads directory
393 * but the image sub-sizes haven't been created yet and the `sizes` array is empty.
394 */
395 wp_update_attachment_metadata( $attachment_id, $image_meta );
396
397 $new_sizes = wp_get_registered_image_subsizes();
398
399 /**
400 * Filters the image sizes automatically generated when uploading an image.
401 *
402 * @since 2.9.0
403 * @since 4.4.0 Added the `$image_meta` argument.
404 * @since 5.3.0 Added the `$attachment_id` argument.
405 *
406 * @param array $new_sizes Associative array of image sizes to be created.
407 * @param array $image_meta The image meta data: width, height, file, sizes, etc.
408 * @param int $attachment_id The attachment post ID for the image.
409 */
410 $new_sizes = apply_filters( 'intermediate_image_sizes_advanced', $new_sizes, $image_meta, $attachment_id );
411
412 return _wp_make_subsizes( $new_sizes, $file, $image_meta, $attachment_id );
413}
414
415/**
416 * Low-level function to create image sub-sizes.
417 *
418 * Updates the image meta after each sub-size is created.
419 * Errors are stored in the returned image metadata array.
420 *
421 * @since 5.3.0
422 * @access private
423 *
424 * @param array $new_sizes Array defining what sizes to create.
425 * @param string $file Full path to the image file.
426 * @param array $image_meta The attachment meta data array.
427 * @param int $attachment_id Attachment ID to process.
428 * @return array The attachment meta data with updated `sizes` array. Includes an array of errors encountered while resizing.
429 */
430function _wp_make_subsizes( $new_sizes, $file, $image_meta, $attachment_id ) {
431 if ( empty( $image_meta ) || ! is_array( $image_meta ) ) {
432 // Not an image attachment.
433 return array();
434 }
435
436 // Check if any of the new sizes already exist.
437 if ( isset( $image_meta['sizes'] ) && is_array( $image_meta['sizes'] ) ) {
438 foreach ( $image_meta['sizes'] as $size_name => $size_meta ) {
439 /*
440 * Only checks "size name" so we don't override existing images even if the dimensions
441 * don't match the currently defined size with the same name.
442 * To change the behavior, unset changed/mismatched sizes in the `sizes` array in image meta.
443 */
444 if ( array_key_exists( $size_name, $new_sizes ) ) {
445 unset( $new_sizes[ $size_name ] );
446 }
447 }
448 } else {
449 $image_meta['sizes'] = array();
450 }
451
452 if ( empty( $new_sizes ) ) {
453 // Nothing to do...
454 return $image_meta;
455 }
456
457 /*
458 * Sort the image sub-sizes in order of priority when creating them.
459 * This ensures there is an appropriate sub-size the user can access immediately
460 * even when there was an error and not all sub-sizes were created.
461 */
462 $priority = array(
463 'medium' => null,
464 'large' => null,
465 'thumbnail' => null,
466 'medium_large' => null,
467 );
468
469 $new_sizes = array_filter( array_merge( $priority, $new_sizes ) );
470
471 $editor = wp_get_image_editor( $file );
472
473 if ( is_wp_error( $editor ) ) {
474 // The image cannot be edited.
475 return $image_meta;
476 }
477
478 // If stored EXIF data exists, rotate the source image before creating sub-sizes.
479 if ( ! empty( $image_meta['image_meta'] ) ) {
480 $rotated = $editor->maybe_exif_rotate();
481
482 if ( is_wp_error( $rotated ) ) {
483 // TODO: Log errors.
484 }
485 }
486
487 if ( method_exists( $editor, 'make_subsize' ) ) {
488 foreach ( $new_sizes as $new_size_name => $new_size_data ) {
489 $new_size_meta = $editor->make_subsize( $new_size_data );
490
491 if ( is_wp_error( $new_size_meta ) ) {
492 // TODO: Log errors.
493 } else {
494 // Save the size meta value.
495 $image_meta['sizes'][ $new_size_name ] = $new_size_meta;
496 wp_update_attachment_metadata( $attachment_id, $image_meta );
497 }
498 }
499 } else {
500 // Fall back to `$editor->multi_resize()`.
501 $created_sizes = $editor->multi_resize( $new_sizes );
502
503 if ( ! empty( $created_sizes ) ) {
504 $image_meta['sizes'] = array_merge( $image_meta['sizes'], $created_sizes );
505 wp_update_attachment_metadata( $attachment_id, $image_meta );
506 }
507 }
508
509 return $image_meta;
510}
511
512/**
513 * Copy parent attachment properties to newly cropped image.
514 *
515 * @since 6.5.0
516 *
517 * @param string $cropped Path to the cropped image file.
518 * @param int $parent_attachment_id Parent file Attachment ID.
519 * @param string $context Control calling the function.
520 * @return array Properties of attachment.
521 */
522function wp_copy_parent_attachment_properties( $cropped, $parent_attachment_id, $context = '' ) {
523 $parent = get_post( $parent_attachment_id );
524 $parent_url = wp_get_attachment_url( $parent->ID );
525 $parent_basename = wp_basename( $parent_url );
526 $url = str_replace( wp_basename( $parent_url ), wp_basename( $cropped ), $parent_url );
527
528 $size = wp_getimagesize( $cropped );
529 $image_type = $size ? $size['mime'] : 'image/jpeg';
530
531 $sanitized_post_title = sanitize_file_name( $parent->post_title );
532 $use_original_title = (
533 ( '' !== trim( $parent->post_title ) ) &&
534 /*
535 * Check if the original image has a title other than the "filename" default,
536 * meaning the image had a title when originally uploaded or its title was edited.
537 */
538 ( $parent_basename !== $sanitized_post_title ) &&
539 ( pathinfo( $parent_basename, PATHINFO_FILENAME ) !== $sanitized_post_title )
540 );
541 $use_original_description = ( '' !== trim( $parent->post_content ) );
542
543 $attachment = array(
544 'post_title' => $use_original_title ? $parent->post_title : wp_basename( $cropped ),
545 'post_content' => $use_original_description ? $parent->post_content : $url,
546 'post_mime_type' => $image_type,
547 'guid' => $url,
548 'context' => $context,
549 );
550
551 // Copy the image caption attribute (post_excerpt field) from the original image.
552 if ( '' !== trim( $parent->post_excerpt ) ) {
553 $attachment['post_excerpt'] = $parent->post_excerpt;
554 }
555
556 // Copy the image alt text attribute from the original image.
557 if ( '' !== trim( $parent->_wp_attachment_image_alt ) ) {
558 $attachment['meta_input'] = array(
559 '_wp_attachment_image_alt' => wp_slash( $parent->_wp_attachment_image_alt ),
560 );
561 }
562
563 $attachment['post_parent'] = $parent_attachment_id;
564
565 return $attachment;
566}
567
568/**
569 * Generates attachment meta data and create image sub-sizes for images.
570 *
571 * @since 2.1.0
572 * @since 6.0.0 The `$filesize` value was added to the returned array.
573 * @since 6.7.0 The 'image/heic' mime type is supported.
574 *
575 * @param int $attachment_id Attachment ID to process.
576 * @param string $file Filepath of the attached image.
577 * @return array Metadata for attachment.
578 */
579function wp_generate_attachment_metadata( $attachment_id, $file ) {
580 $attachment = get_post( $attachment_id );
581
582 $metadata = array();
583 $support = false;
584 $mime_type = get_post_mime_type( $attachment );
585
586 if ( 'image/heic' === $mime_type || ( preg_match( '!^image/!', $mime_type ) && file_is_displayable_image( $file ) ) ) {
587 // Make thumbnails and other intermediate sizes.
588 $metadata = wp_create_image_subsizes( $file, $attachment_id );
589 } elseif ( wp_attachment_is( 'video', $attachment ) ) {
590 $metadata = wp_read_video_metadata( $file );
591 $support = current_theme_supports( 'post-thumbnails', 'attachment:video' ) || post_type_supports( 'attachment:video', 'thumbnail' );
592 } elseif ( wp_attachment_is( 'audio', $attachment ) ) {
593 $metadata = wp_read_audio_metadata( $file );
594 $support = current_theme_supports( 'post-thumbnails', 'attachment:audio' ) || post_type_supports( 'attachment:audio', 'thumbnail' );
595 }
596
597 /*
598 * wp_read_video_metadata() and wp_read_audio_metadata() return `false`
599 * if the attachment does not exist in the local filesystem,
600 * so make sure to convert the value to an array.
601 */
602 if ( ! is_array( $metadata ) ) {
603 $metadata = array();
604 }
605
606 if ( $support && ! empty( $metadata['image']['data'] ) ) {
607 // Check for existing cover.
608 $hash = md5( $metadata['image']['data'] );
609 $posts = get_posts(
610 array(
611 'fields' => 'ids',
612 'post_type' => 'attachment',
613 'post_mime_type' => $metadata['image']['mime'],
614 'post_status' => 'inherit',
615 'posts_per_page' => 1,
616 'meta_key' => '_cover_hash',
617 'meta_value' => $hash,
618 )
619 );
620 $exists = reset( $posts );
621
622 if ( ! empty( $exists ) ) {
623 update_post_meta( $attachment_id, '_thumbnail_id', $exists );
624 } else {
625 $ext = '.jpg';
626 switch ( $metadata['image']['mime'] ) {
627 case 'image/gif':
628 $ext = '.gif';
629 break;
630 case 'image/png':
631 $ext = '.png';
632 break;
633 case 'image/webp':
634 $ext = '.webp';
635 break;
636 }
637 $basename = str_replace( '.', '-', wp_basename( $file ) ) . '-image' . $ext;
638 $uploaded = wp_upload_bits( $basename, '', $metadata['image']['data'] );
639 if ( false === $uploaded['error'] ) {
640 $image_attachment = array(
641 'post_mime_type' => $metadata['image']['mime'],
642 'post_type' => 'attachment',
643 'post_content' => '',
644 );
645 /**
646 * Filters the parameters for the attachment thumbnail creation.
647 *
648 * @since 3.9.0
649 *
650 * @param array $image_attachment An array of parameters to create the thumbnail.
651 * @param array $metadata Current attachment metadata.
652 * @param array $uploaded {
653 * Information about the newly-uploaded file.
654 *
655 * @type string $file Filename of the newly-uploaded file.
656 * @type string $url URL of the uploaded file.
657 * @type string $type File type.
658 * }
659 */
660 $image_attachment = apply_filters( 'attachment_thumbnail_args', $image_attachment, $metadata, $uploaded );
661
662 $sub_attachment_id = wp_insert_attachment( $image_attachment, $uploaded['file'] );
663 add_post_meta( $sub_attachment_id, '_cover_hash', $hash );
664 $attach_data = wp_generate_attachment_metadata( $sub_attachment_id, $uploaded['file'] );
665 wp_update_attachment_metadata( $sub_attachment_id, $attach_data );
666 update_post_meta( $attachment_id, '_thumbnail_id', $sub_attachment_id );
667 }
668 }
669 } elseif ( 'application/pdf' === $mime_type ) {
670 // Try to create image thumbnails for PDFs.
671
672 $fallback_sizes = array(
673 'thumbnail',
674 'medium',
675 'large',
676 );
677
678 /**
679 * Filters the image sizes generated for non-image mime types.
680 *
681 * @since 4.7.0
682 *
683 * @param string[] $fallback_sizes An array of image size names.
684 * @param array $metadata Current attachment metadata.
685 */
686 $fallback_sizes = apply_filters( 'fallback_intermediate_image_sizes', $fallback_sizes, $metadata );
687
688 $registered_sizes = wp_get_registered_image_subsizes();
689 $merged_sizes = array_intersect_key( $registered_sizes, array_flip( $fallback_sizes ) );
690
691 // Force thumbnails to be soft crops.
692 if ( isset( $merged_sizes['thumbnail'] ) && is_array( $merged_sizes['thumbnail'] ) ) {
693 $merged_sizes['thumbnail']['crop'] = false;
694 }
695
696 // Only load PDFs in an image editor if we're processing sizes.
697 if ( ! empty( $merged_sizes ) ) {
698 $editor = wp_get_image_editor( $file );
699
700 if ( ! is_wp_error( $editor ) ) { // No support for this type of file.
701 /*
702 * PDFs may have the same file filename as JPEGs.
703 * Ensure the PDF preview image does not overwrite any JPEG images that already exist.
704 */
705 $dirname = dirname( $file ) . '/';
706 $ext = '.' . pathinfo( $file, PATHINFO_EXTENSION );
707 $preview_file = $dirname . wp_unique_filename( $dirname, wp_basename( $file, $ext ) . '-pdf.jpg' );
708
709 $uploaded = $editor->save( $preview_file, 'image/jpeg' );
710 unset( $editor );
711
712 // Resize based on the full size image, rather than the source.
713 if ( ! is_wp_error( $uploaded ) ) {
714 $image_file = $uploaded['path'];
715 unset( $uploaded['path'] );
716
717 $metadata['sizes'] = array(
718 'full' => $uploaded,
719 );
720
721 // Save the meta data before any image post-processing errors could happen.
722 wp_update_attachment_metadata( $attachment_id, $metadata );
723
724 // Create sub-sizes saving the image meta after each.
725 $metadata = _wp_make_subsizes( $merged_sizes, $image_file, $metadata, $attachment_id );
726 }
727 }
728 }
729 }
730
731 // Remove the blob of binary data from the array.
732 unset( $metadata['image']['data'] );
733
734 // Capture file size for cases where it has not been captured yet, such as PDFs.
735 if ( ! isset( $metadata['filesize'] ) && file_exists( $file ) ) {
736 $metadata['filesize'] = wp_filesize( $file );
737 }
738
739 /**
740 * Filters the generated attachment meta data.
741 *
742 * @since 2.1.0
743 * @since 5.3.0 The `$context` parameter was added.
744 *
745 * @param array $metadata An array of attachment meta data.
746 * @param int $attachment_id Current attachment ID.
747 * @param string $context Additional context. Can be 'create' when metadata was initially created for new attachment
748 * or 'update' when the metadata was updated.
749 */
750 return apply_filters( 'wp_generate_attachment_metadata', $metadata, $attachment_id, 'create' );
751}
752
753/**
754 * Converts a fraction string to a decimal.
755 *
756 * @since 2.5.0
757 *
758 * @param string $str Fraction string.
759 * @return int|float Returns calculated fraction or integer 0 on invalid input.
760 */
761function wp_exif_frac2dec( $str ) {
762 if ( ! is_scalar( $str ) || is_bool( $str ) ) {
763 return 0;
764 }
765
766 if ( ! is_string( $str ) ) {
767 return $str; // This can only be an integer or float, so this is fine.
768 }
769
770 // Fractions passed as a string must contain a single `/`.
771 if ( substr_count( $str, '/' ) !== 1 ) {
772 if ( is_numeric( $str ) ) {
773 return (float) $str;
774 }
775
776 return 0;
777 }
778
779 list( $numerator, $denominator ) = explode( '/', $str );
780
781 // Both the numerator and the denominator must be numbers.
782 if ( ! is_numeric( $numerator ) || ! is_numeric( $denominator ) ) {
783 return 0;
784 }
785
786 // The denominator must not be zero.
787 if ( 0 == $denominator ) { // phpcs:ignore Universal.Operators.StrictComparisons.LooseEqual -- Deliberate loose comparison.
788 return 0;
789 }
790
791 return $numerator / $denominator;
792}
793
794/**
795 * Converts the exif date format to a unix timestamp.
796 *
797 * @since 2.5.0
798 *
799 * @param string $str A date string expected to be in Exif format (Y:m:d H:i:s).
800 * @return int|false The unix timestamp, or false on failure.
801 */
802function wp_exif_date2ts( $str ) {
803 list( $date, $time ) = explode( ' ', trim( $str ) );
804 list( $y, $m, $d ) = explode( ':', $date );
805
806 return strtotime( "{$y}-{$m}-{$d} {$time}" );
807}
808
809/**
810 * Gets extended image metadata, exif or iptc as available.
811 *
812 * Retrieves the EXIF metadata aperture, credit, camera, caption, copyright, iso
813 * created_timestamp, focal_length, shutter_speed, and title.
814 *
815 * The IPTC metadata that is retrieved is APP13, credit, byline, created date
816 * and time, caption, copyright, and title. Also includes FNumber, Model,
817 * DateTimeDigitized, FocalLength, ISOSpeedRatings, and ExposureTime.
818 *
819 * @todo Try other exif libraries if available.
820 * @since 2.5.0
821 *
822 * @param string $file
823 * @return array|false Image metadata array on success, false on failure.
824 */
825function wp_read_image_metadata( $file ) {
826 if ( ! file_exists( $file ) ) {
827 return false;
828 }
829
830 $image_size = wp_getimagesize( $file );
831
832 if ( false === $image_size ) {
833 return false;
834 }
835
836 list( , , $image_type ) = $image_size;
837
838 /*
839 * EXIF contains a bunch of data we'll probably never need formatted in ways
840 * that are difficult to use. We'll normalize it and just extract the fields
841 * that are likely to be useful. Fractions and numbers are converted to
842 * floats, dates to unix timestamps, and everything else to strings.
843 */
844 $meta = array(
845 'aperture' => 0,
846 'credit' => '',
847 'camera' => '',
848 'caption' => '',
849 'created_timestamp' => 0,
850 'copyright' => '',
851 'focal_length' => 0,
852 'iso' => 0,
853 'shutter_speed' => 0,
854 'title' => '',
855 'orientation' => 0,
856 'keywords' => array(),
857 );
858
859 $iptc = array();
860 $info = array();
861 /*
862 * Read IPTC first, since it might contain data not available in exif such
863 * as caption, description etc.
864 */
865 if ( is_callable( 'iptcparse' ) ) {
866 wp_getimagesize( $file, $info );
867
868 if ( ! empty( $info['APP13'] ) ) {
869 // Don't silence errors when in debug mode, unless running unit tests.
870 if ( defined( 'WP_DEBUG' ) && WP_DEBUG
871 && ! defined( 'WP_RUN_CORE_TESTS' )
872 ) {
873 $iptc = iptcparse( $info['APP13'] );
874 } else {
875 // Silencing notice and warning is intentional. See https://core.trac.wordpress.org/ticket/42480
876 $iptc = @iptcparse( $info['APP13'] );
877 }
878
879 if ( ! is_array( $iptc ) ) {
880 $iptc = array();
881 }
882
883 // Headline, "A brief synopsis of the caption".
884 if ( ! empty( $iptc['2#105'][0] ) ) {
885 $meta['title'] = trim( $iptc['2#105'][0] );
886 /*
887 * Title, "Many use the Title field to store the filename of the image,
888 * though the field may be used in many ways".
889 */
890 } elseif ( ! empty( $iptc['2#005'][0] ) ) {
891 $meta['title'] = trim( $iptc['2#005'][0] );
892 }
893
894 if ( ! empty( $iptc['2#120'][0] ) ) { // Description / legacy caption.
895 $caption = trim( $iptc['2#120'][0] );
896
897 mbstring_binary_safe_encoding();
898 $caption_length = strlen( $caption );
899 reset_mbstring_encoding();
900
901 if ( empty( $meta['title'] ) && $caption_length < 80 ) {
902 // Assume the title is stored in 2:120 if it's short.
903 $meta['title'] = $caption;
904 }
905
906 $meta['caption'] = $caption;
907 }
908
909 if ( ! empty( $iptc['2#110'][0] ) ) { // Credit.
910 $meta['credit'] = trim( $iptc['2#110'][0] );
911 } elseif ( ! empty( $iptc['2#080'][0] ) ) { // Creator / legacy byline.
912 $meta['credit'] = trim( $iptc['2#080'][0] );
913 }
914
915 if ( ! empty( $iptc['2#055'][0] ) && ! empty( $iptc['2#060'][0] ) ) { // Created date and time.
916 $meta['created_timestamp'] = strtotime( $iptc['2#055'][0] . ' ' . $iptc['2#060'][0] );
917 }
918
919 if ( ! empty( $iptc['2#116'][0] ) ) { // Copyright.
920 $meta['copyright'] = trim( $iptc['2#116'][0] );
921 }
922
923 if ( ! empty( $iptc['2#025'][0] ) ) { // Keywords array.
924 $meta['keywords'] = array_values( $iptc['2#025'] );
925 }
926 }
927 }
928
929 $exif = array();
930
931 /**
932 * Filters the image types to check for exif data.
933 *
934 * @since 2.5.0
935 *
936 * @param int[] $image_types Array of image types to check for exif data. Each value
937 * is usually one of the `IMAGETYPE_*` constants.
938 */
939 $exif_image_types = apply_filters( 'wp_read_image_metadata_types', array( IMAGETYPE_JPEG, IMAGETYPE_TIFF_II, IMAGETYPE_TIFF_MM ) );
940
941 if ( is_callable( 'exif_read_data' ) && in_array( $image_type, $exif_image_types, true ) ) {
942 // Don't silence errors when in debug mode, unless running unit tests.
943 if ( defined( 'WP_DEBUG' ) && WP_DEBUG
944 && ! defined( 'WP_RUN_CORE_TESTS' )
945 ) {
946 $exif = exif_read_data( $file );
947 } else {
948 // Silencing notice and warning is intentional. See https://core.trac.wordpress.org/ticket/42480
949 $exif = @exif_read_data( $file );
950 }
951
952 if ( ! is_array( $exif ) ) {
953 $exif = array();
954 }
955
956 $exif_description = '';
957 $exif_usercomment = '';
958 if ( ! empty( $exif['ImageDescription'] ) ) {
959 $exif_description = trim( $exif['ImageDescription'] );
960 }
961
962 if ( ! empty( $exif['COMPUTED']['UserComment'] ) ) {
963 $exif_usercomment = trim( $exif['COMPUTED']['UserComment'] );
964 }
965
966 if ( $exif_description ) {
967 mbstring_binary_safe_encoding();
968 $description_length = strlen( $exif_description );
969 reset_mbstring_encoding();
970 if ( empty( $meta['title'] ) && $description_length < 80 ) {
971 // Assume the title is stored in ImageDescription.
972 $meta['title'] = $exif_description;
973 }
974
975 // If both user comments and description are present.
976 if ( empty( $meta['caption'] ) && $exif_usercomment ) {
977 if ( ! empty( $meta['title'] ) && $exif_description === $meta['title'] ) {
978 $caption = $exif_usercomment;
979 } else {
980 if ( $exif_description === $exif_usercomment ) {
981 $caption = $exif_description;
982 } else {
983 $caption = trim( $exif_description . ' ' . $exif_usercomment );
984 }
985 }
986 $meta['caption'] = $caption;
987 }
988
989 if ( empty( $meta['caption'] ) && $exif_usercomment ) {
990 $meta['caption'] = $exif_usercomment;
991 }
992
993 if ( empty( $meta['caption'] ) ) {
994 $meta['caption'] = $exif_description;
995 }
996 } elseif ( empty( $meta['caption'] ) && $exif_usercomment ) {
997 $meta['caption'] = $exif_usercomment;
998 $description_length = strlen( $exif_usercomment );
999 if ( empty( $meta['title'] ) && $description_length < 80 ) {
1000 $meta['title'] = trim( $exif_usercomment );
1001 }
1002 } elseif ( empty( $meta['caption'] ) && ! empty( $exif['Comments'] ) ) {
1003 $meta['caption'] = trim( $exif['Comments'] );
1004 }
1005
1006 if ( empty( $meta['credit'] ) ) {
1007 if ( ! empty( $exif['Artist'] ) ) {
1008 $meta['credit'] = trim( $exif['Artist'] );
1009 } elseif ( ! empty( $exif['Author'] ) ) {
1010 $meta['credit'] = trim( $exif['Author'] );
1011 }
1012 }
1013
1014 if ( empty( $meta['copyright'] ) && ! empty( $exif['Copyright'] ) ) {
1015 $meta['copyright'] = trim( $exif['Copyright'] );
1016 }
1017 if ( ! empty( $exif['FNumber'] ) && is_scalar( $exif['FNumber'] ) ) {
1018 $meta['aperture'] = round( wp_exif_frac2dec( $exif['FNumber'] ), 2 );
1019 }
1020 if ( ! empty( $exif['Model'] ) ) {
1021 $meta['camera'] = trim( $exif['Model'] );
1022 }
1023 if ( empty( $meta['created_timestamp'] ) && ! empty( $exif['DateTimeDigitized'] ) ) {
1024 $meta['created_timestamp'] = wp_exif_date2ts( $exif['DateTimeDigitized'] );
1025 }
1026 if ( ! empty( $exif['FocalLength'] ) ) {
1027 $meta['focal_length'] = (string) $exif['FocalLength'];
1028 if ( is_scalar( $exif['FocalLength'] ) ) {
1029 $meta['focal_length'] = (string) wp_exif_frac2dec( $exif['FocalLength'] );
1030 }
1031 }
1032 if ( ! empty( $exif['ISOSpeedRatings'] ) ) {
1033 $meta['iso'] = is_array( $exif['ISOSpeedRatings'] ) ? reset( $exif['ISOSpeedRatings'] ) : $exif['ISOSpeedRatings'];
1034 $meta['iso'] = trim( $meta['iso'] );
1035 }
1036 if ( ! empty( $exif['ExposureTime'] ) ) {
1037 $meta['shutter_speed'] = (string) $exif['ExposureTime'];
1038 if ( is_scalar( $exif['ExposureTime'] ) ) {
1039 $meta['shutter_speed'] = (string) wp_exif_frac2dec( $exif['ExposureTime'] );
1040 }
1041 }
1042 if ( ! empty( $exif['Orientation'] ) ) {
1043 $meta['orientation'] = $exif['Orientation'];
1044 }
1045 }
1046
1047 foreach ( array( 'title', 'caption', 'credit', 'copyright', 'camera', 'iso' ) as $key ) {
1048 if ( $meta[ $key ] && ! wp_is_valid_utf8( $meta[ $key ] ) ) {
1049 $meta[ $key ] = utf8_encode( $meta[ $key ] );
1050 }
1051 }
1052
1053 foreach ( $meta['keywords'] as $key => $keyword ) {
1054 if ( ! wp_is_valid_utf8( $keyword ) ) {
1055 $meta['keywords'][ $key ] = utf8_encode( $keyword );
1056 }
1057 }
1058
1059 $meta = wp_kses_post_deep( $meta );
1060
1061 /**
1062 * Filters the array of meta data read from an image's exif data.
1063 *
1064 * @since 2.5.0
1065 * @since 4.4.0 The `$iptc` parameter was added.
1066 * @since 5.0.0 The `$exif` parameter was added.
1067 *
1068 * @param array $meta Image meta data.
1069 * @param string $file Path to image file.
1070 * @param int $image_type Type of image, one of the `IMAGETYPE_XXX` constants.
1071 * @param array $iptc IPTC data.
1072 * @param array $exif EXIF data.
1073 */
1074 return apply_filters( 'wp_read_image_metadata', $meta, $file, $image_type, $iptc, $exif );
1075}
1076
1077/**
1078 * Validates that file is an image.
1079 *
1080 * @since 2.5.0
1081 *
1082 * @param string $path File path to test if valid image.
1083 * @return bool True if valid image, false if not valid image.
1084 */
1085function file_is_valid_image( $path ) {
1086 $size = wp_getimagesize( $path );
1087 return ! empty( $size );
1088}
1089
1090/**
1091 * Validates that file is suitable for displaying within a web page.
1092 *
1093 * @since 2.5.0
1094 *
1095 * @param string $path File path to test.
1096 * @return bool True if suitable, false if not suitable.
1097 */
1098function file_is_displayable_image( $path ) {
1099 $displayable_image_types = array( IMAGETYPE_GIF, IMAGETYPE_JPEG, IMAGETYPE_PNG, IMAGETYPE_BMP, IMAGETYPE_ICO, IMAGETYPE_WEBP, IMAGETYPE_AVIF );
1100
1101 $info = wp_getimagesize( $path );
1102 if ( empty( $info ) ) {
1103 $result = false;
1104 } elseif ( ! in_array( $info[2], $displayable_image_types, true ) ) {
1105 $result = false;
1106 } else {
1107 $result = true;
1108 }
1109
1110 /**
1111 * Filters whether the current image is displayable in the browser.
1112 *
1113 * @since 2.5.0
1114 *
1115 * @param bool $result Whether the image can be displayed. Default true.
1116 * @param string $path Path to the image.
1117 */
1118 return apply_filters( 'file_is_displayable_image', $result, $path );
1119}
1120
1121/**
1122 * Loads an image resource for editing.
1123 *
1124 * @since 2.9.0
1125 *
1126 * @param int $attachment_id Attachment ID.
1127 * @param string $mime_type Image mime type.
1128 * @param string|int[] $size Optional. Image size. Accepts any registered image size name, or an array
1129 * of width and height values in pixels (in that order). Default 'full'.
1130 * @return resource|GdImage|false The resulting image resource or GdImage instance on success,
1131 * false on failure.
1132 */
1133function load_image_to_edit( $attachment_id, $mime_type, $size = 'full' ) {
1134 $filepath = _load_image_to_edit_path( $attachment_id, $size );
1135 if ( empty( $filepath ) ) {
1136 return false;
1137 }
1138
1139 switch ( $mime_type ) {
1140 case 'image/jpeg':
1141 $image = imagecreatefromjpeg( $filepath );
1142 break;
1143 case 'image/png':
1144 $image = imagecreatefrompng( $filepath );
1145 break;
1146 case 'image/gif':
1147 $image = imagecreatefromgif( $filepath );
1148 break;
1149 case 'image/webp':
1150 $image = false;
1151 if ( function_exists( 'imagecreatefromwebp' ) ) {
1152 $image = imagecreatefromwebp( $filepath );
1153 }
1154 break;
1155 default:
1156 $image = false;
1157 break;
1158 }
1159
1160 if ( is_gd_image( $image ) ) {
1161 /**
1162 * Filters the current image being loaded for editing.
1163 *
1164 * @since 2.9.0
1165 *
1166 * @param resource|GdImage $image Current image.
1167 * @param int $attachment_id Attachment ID.
1168 * @param string|int[] $size Requested image size. Can be any registered image size name, or
1169 * an array of width and height values in pixels (in that order).
1170 */
1171 $image = apply_filters( 'load_image_to_edit', $image, $attachment_id, $size );
1172
1173 if ( function_exists( 'imagealphablending' ) && function_exists( 'imagesavealpha' ) ) {
1174 imagealphablending( $image, false );
1175 imagesavealpha( $image, true );
1176 }
1177 }
1178
1179 return $image;
1180}
1181
1182/**
1183 * Retrieves the path or URL of an attachment's attached file.
1184 *
1185 * If the attached file is not present on the local filesystem (usually due to replication plugins),
1186 * then the URL of the file is returned if `allow_url_fopen` is supported.
1187 *
1188 * @since 3.4.0
1189 * @access private
1190 *
1191 * @param int $attachment_id Attachment ID.
1192 * @param string|int[] $size Optional. Image size. Accepts any registered image size name, or an array
1193 * of width and height values in pixels (in that order). Default 'full'.
1194 * @return string|false File path or URL on success, false on failure.
1195 */
1196function _load_image_to_edit_path( $attachment_id, $size = 'full' ) {
1197 $filepath = get_attached_file( $attachment_id );
1198
1199 if ( $filepath && file_exists( $filepath ) ) {
1200 if ( 'full' !== $size ) {
1201 $data = image_get_intermediate_size( $attachment_id, $size );
1202
1203 if ( $data ) {
1204 $filepath = path_join( dirname( $filepath ), $data['file'] );
1205
1206 /**
1207 * Filters the path to an attachment's file when editing the image.
1208 *
1209 * The filter is evaluated for all image sizes except 'full'.
1210 *
1211 * @since 3.1.0
1212 *
1213 * @param string $path Path to the current image.
1214 * @param int $attachment_id Attachment ID.
1215 * @param string|int[] $size Requested image size. Can be any registered image size name, or
1216 * an array of width and height values in pixels (in that order).
1217 */
1218 $filepath = apply_filters( 'load_image_to_edit_filesystempath', $filepath, $attachment_id, $size );
1219 }
1220 }
1221 } elseif ( function_exists( 'fopen' ) && ini_get( 'allow_url_fopen' ) ) {
1222 /**
1223 * Filters the path to an attachment's URL when editing the image.
1224 *
1225 * The filter is only evaluated if the file isn't stored locally and `allow_url_fopen` is enabled on the server.
1226 *
1227 * @since 3.1.0
1228 *
1229 * @param string|false $image_url Current image URL.
1230 * @param int $attachment_id Attachment ID.
1231 * @param string|int[] $size Requested image size. Can be any registered image size name, or
1232 * an array of width and height values in pixels (in that order).
1233 */
1234 $filepath = apply_filters( 'load_image_to_edit_attachmenturl', wp_get_attachment_url( $attachment_id ), $attachment_id, $size );
1235 }
1236
1237 /**
1238 * Filters the returned path or URL of the current image.
1239 *
1240 * @since 2.9.0
1241 *
1242 * @param string|false $filepath File path or URL to current image, or false.
1243 * @param int $attachment_id Attachment ID.
1244 * @param string|int[] $size Requested image size. Can be any registered image size name, or
1245 * an array of width and height values in pixels (in that order).
1246 */
1247 return apply_filters( 'load_image_to_edit_path', $filepath, $attachment_id, $size );
1248}
1249
1250/**
1251 * Copies an existing image file.
1252 *
1253 * @since 3.4.0
1254 * @access private
1255 *
1256 * @param int $attachment_id Attachment ID.
1257 * @return string|false New file path on success, false on failure.
1258 */
1259function _copy_image_file( $attachment_id ) {
1260 $dst_file = get_attached_file( $attachment_id );
1261 $src_file = $dst_file;
1262
1263 if ( ! file_exists( $src_file ) ) {
1264 $src_file = _load_image_to_edit_path( $attachment_id );
1265 }
1266
1267 if ( $src_file ) {
1268 $dst_file = str_replace( wp_basename( $dst_file ), 'copy-' . wp_basename( $dst_file ), $dst_file );
1269 $dst_file = dirname( $dst_file ) . '/' . wp_unique_filename( dirname( $dst_file ), wp_basename( $dst_file ) );
1270
1271 /*
1272 * The directory containing the original file may no longer
1273 * exist when using a replication plugin.
1274 */
1275 wp_mkdir_p( dirname( $dst_file ) );
1276
1277 if ( ! copy( $src_file, $dst_file ) ) {
1278 $dst_file = false;
1279 }
1280 } else {
1281 $dst_file = false;
1282 }
1283
1284 return $dst_file;
1285}
1286
Ui Ux Design – Teachers Night Out https://cardgames4educators.com Wed, 16 Oct 2024 22:24:18 +0000 en-US hourly 1 https://wordpress.org/?v=6.9.4 https://cardgames4educators.com/wp-content/uploads/2024/06/cropped-Card-4-Educators-logo-32x32.png Ui Ux Design – Teachers Night Out https://cardgames4educators.com 32 32 Masters In English How English Speaker https://cardgames4educators.com/masters-in-english-how-english-speaker/ https://cardgames4educators.com/masters-in-english-how-english-speaker/#comments Mon, 27 May 2024 08:54:45 +0000 https://themexriver.com/wp/kadu/?p=1

Erat himenaeos neque id sagittis massa. Hac suscipit pulvinar dignissim platea magnis eu. Don tellus a pharetra inceptos efficitur dui pulvinar. Feugiat facilisis penatibus pulvinar nunc dictumst donec odio platea habitasse. Lacus porta dolor purus elit ante bibendum tortor netus taciti nullam cubilia. Erat per suspendisse placerat morbi egestas pulvinar bibendum sollicitudin nec. Euismod cubilia eleifend velit himenaeos sodales lectus. Leo maximus cras ac porttitor aliquam torquent pulvinar odio volutpat parturient. Quisque risus finibus suspendisse mus purus magnis facilisi condimentum consectetur dui. Curae elit suspendisse cursus vehicula.

Turpis taciti class non vel pretium quis pulvinar tempor lobortis nunc. Libero phasellus parturient sapien volutpat malesuada ornare. Cubilia dignissim sollicitudin rhoncus lacinia maximus. Cras lorem fermentum bibendum pellentesque nisl etiam ligula enim cubilia. Vulputate pede sapien torquent montes tempus malesuada in mattis dis turpis vitae. Porta est tempor ex eget feugiat vulputate ipsum. Justo nec iaculis habitant diam arcu fermentum.

We offer comprehen sive emplo ment services such as assistance wit employer compliance.Our company is your strategic HR partner as instead of HR. john smithson

Cubilia dignissim sollicitudin rhoncus lacinia maximus. Cras lorem fermentum bibendum pellentesque nisl etiam ligula enim cubilia. Vulputate pede sapien torquent montes tempus malesuada in mattis dis turpis vitae.

Exploring Learning Landscapes in Academic

Feugiat facilisis penatibus pulvinar nunc dictumst donec odio platea habitasse. Lacus porta dolor purus elit ante bibendum tortor netus taciti nullam cubilia. Erat per suspendisse placerat morbi egestas pulvinar bibendum sollicitudin nec. Euismod cubilia eleifend velit himenaeos sodales lectus. Leo maximus cras ac porttitor aliquam torquent.

]]>
https://cardgames4educators.com/masters-in-english-how-english-speaker/feed/ 1