PluginProbe
QuickWebP – WebP & AVIF Image Optimizer, Compression & SEO for WordPress / 3.3.0
QuickWebP – WebP & AVIF Image Optimizer, Compression & SEO for WordPress v3.3.0
4.1.1 4.1.0 4.0.1 4.0.0 3.3.1 3.3.0 trunk 1.0.0 2.0.0 2.1.0 3.0.0 3.1.0 3.2.0 3.2.1 3.2.2 3.2.3 3.2.4 3.2.5 3.2.6 3.2.7 3.2.8
quickwebp / admin / class-image-optimizer.php

class-image-optimizer.php in QuickWebP – WebP & AVIF Image Optimizer, Compression & SEO for WordPress 3.3.0, at admin/class-image-optimizer.php

805 lines 24.8 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 use Intervention\Image\ImageManager;
4
5 /**
6 * The core functionality for image optimizing.
7 *
8 * @link http://webdeclic.com
9 * @since 1.0.0
10 *
11 * @package Quickwebp
12 * @subpackage Quickwebp/admin
13 */
14 class Quickwebp_Image_Optimizer {
15
16 /**
17 * The ID of this plugin.
18 *
19 * @since 1.0.0
20 * @access private
21 * @var string $plugin_name The ID of this plugin.
22 */
23 private $plugin_name;
24
25 /**
26 * The version of this plugin.
27 *
28 * @since 1.0.0
29 * @access private
30 * @var string $version The current version of this plugin.
31 */
32 private $version;
33
34 /**
35 * Allowed mime types for the optimazation
36 */
37 public $allowed_mime_types;
38
39 /**
40 * Initialize the class and set its properties.
41 *
42 * @since 1.0.0
43 * @param string $plugin_name The name of this plugin.
44 * @param string $version The version of this plugin.
45 */
46 public function __construct( $plugin_name, $version ) {
47
48 $this->plugin_name = $plugin_name;
49 $this->version = $version;
50 $this->allowed_mime_types = array( 'image/jpeg', 'image/png', 'image/webp' );
51
52 }
53
54 /**
55 * Optimize an image added in wp_media
56 */
57 public function image_optimizition( $file ) {
58
59 $settings = $this->get_settings();
60
61 $image_file = $this->file_is_image( $file, $settings );
62 if ( ! $image_file ) {
63 return $file;
64 }
65
66 if ( $settings['quickwebp_settings_conversion'] != '1' ) {
67 return $image_file;
68 }
69
70 $save_original = is_array( $settings['quickwebp_settings_conversion_save_original'] ) ? $settings['quickwebp_settings_conversion_save_original'] : array();
71 if ( in_array( 'checked', $save_original ) ) {
72 return $image_file;
73 }
74
75 $extension_to_use = $this->image_extension_loaded( $settings );
76 if ( ! $extension_to_use ) {
77 return $image_file;
78 }
79
80 $manager = new ImageManager(array('driver'=>$extension_to_use));
81 $image = $manager->make($image_file['tmp_name']);
82
83 $exif_data = @exif_read_data( $image_file['tmp_name'] );
84 if ( ! empty( $exif_data['Orientation'] ) ) {
85 $orientation = (int) $exif_data['Orientation'];
86 $orientation = apply_filters( 'wp_image_maybe_exif_rotate', $orientation, $image_file['tmp_name'] );
87 if ( $orientation && 1 !== $orientation ) {
88 switch ( $orientation ) {
89 case 2:
90 // Flip horizontally.
91 $result = $image->flip( false, true );
92 break;
93 case 3:
94 /*
95 * Rotate 180 degrees or flip horizontally and vertically.
96 * Flipping seems faster and uses less resources.
97 */
98 $result = $image->flip( true, true );
99 break;
100 case 4:
101 // Flip vertically.
102 $result = $image->flip( true, false );
103 break;
104 case 5:
105 // Rotate 90 degrees counter-clockwise and flip vertically.
106 $result = $image->rotate( 90 );
107 if ( ! is_wp_error( $result ) ) {
108 $result = $image->flip( true, false );
109 }
110 break;
111 case 6:
112 // Rotate 90 degrees clockwise (270 counter-clockwise).
113 $result = $image->rotate( 270 );
114 break;
115 case 7:
116 // Rotate 90 degrees counter-clockwise and flip horizontally.
117 $result = $image->rotate( 90 );
118 if ( ! is_wp_error( $result ) ) {
119 $result = $image->flip( false, true );
120 }
121 break;
122 case 8:
123 // Rotate 90 degrees counter-clockwise.
124 $result = $image->rotate( 90 );
125 break;
126 }
127 }
128 }
129 $quality = $this->get_quality( $image_file['tmp_name'], $settings );
130
131 $image->sharpen($settings['quickwebp_settings_conversion_sharpen']);
132 $image->save( $image_file['tmp_name'], $quality, 'webp' );
133
134 $size_after = $image->filesize();
135 $mime = $image->mime();
136
137 $image_file['size'] = $size_after;
138 $image_file['type'] = $mime;
139
140 return $image_file;
141 }
142
143 /**
144 * Get the package used by the server
145 *
146 */
147 public function image_extension_loaded( $settings ) {
148
149 $accepted_librarys = array( 'gd', 'imagick' );
150 $library_to_use = $settings['quickwebp_settings_library'];
151
152 if ( in_array( $library_to_use, $accepted_librarys ) ) {
153
154 return $library_to_use;
155 }
156
157 return false;
158 }
159
160 /**
161 * Check if the file is an image
162 *
163 */
164 public function file_is_image( $file, $settings ) {
165
166 $file_name = isset($file['name']) ? $file['name'] : '';
167 $file_type = isset($file['type']) ? $file['type'] : '';
168 $file_tmp_name = isset($file['tmp_name']) ? $file['tmp_name'] : '';
169 $file_error = isset($file['error']) ? $file['error'] : '';
170 $file_size = isset($file['size']) ? $file['size'] : '';
171
172 if ( empty($file_tmp_name) ) {
173 return false;
174 }
175
176 $allowed_mime_types = apply_filters( 'quickwebp_mime_types_allowed', $this->allowed_mime_types );
177 $is_image = wp_getimagesize($file_tmp_name);
178 $mime_type = wp_get_image_mime($file_tmp_name);
179 if ( ! $is_image || ! in_array( $mime_type, $allowed_mime_types ) ) {
180 return false;
181 }
182
183 $name = $file_name;
184
185 if ( $settings['quickwebp_settings_cleanup'] == '1' ) {
186 $name = quickwebp_sanitize_name($file_name);
187 }
188
189 return array(
190 'original_name' => $file_name,
191 'name' => $name,
192 'type' => $file_type,
193 'tmp_name' => $file_tmp_name,
194 'error' => $file_error,
195 'size' => $file_size
196 );
197 }
198
199 /**
200 * Get the optimization settings
201 */
202 public function get_settings() {
203
204 return array(
205 'quickwebp_settings_conversion' => get_option('quickwebp_settings_conversion', quickwebp_settings_default('quickwebp_settings_conversion') ),
206 'quickwebp_settings_conversion_quality' => get_option('quickwebp_settings_conversion_quality', quickwebp_settings_default('quickwebp_settings_conversion_quality') ),
207 'quickwebp_settings_conversion_sharpen' => get_option('quickwebp_settings_conversion_sharpen', quickwebp_settings_default('quickwebp_settings_conversion_sharpen') ),
208 'quickwebp_settings_conversion_ignore_webp' => get_option('quickwebp_settings_conversion_ignore_webp', quickwebp_settings_default('quickwebp_settings_conversion_ignore_webp') ),
209 'quickwebp_settings_conversion_save_original' => get_option('quickwebp_settings_conversion_save_original', quickwebp_settings_default('quickwebp_settings_conversion_save_original') ),
210 'quickwebp_settings_resize' => get_option('quickwebp_settings_resize', quickwebp_settings_default('quickwebp_settings_resize') ),
211 'quickwebp_settings_resize_value' => get_option('quickwebp_settings_resize_value', quickwebp_settings_default('quickwebp_settings_resize_value') ),
212 'quickwebp_settings_completion' => get_option('quickwebp_settings_completion', quickwebp_settings_default('quickwebp_settings_completion') ),
213 'quickwebp_settings_completion_options' => get_option('quickwebp_settings_completion_options', quickwebp_settings_default('quickwebp_settings_completion_options') ),
214 'quickwebp_settings_cleanup' => get_option('quickwebp_settings_cleanup', quickwebp_settings_default('quickwebp_settings_cleanup') ),
215 'quickwebp_settings_library' => get_option( 'quickwebp_settings_library', quickwebp_settings_default('quickwebp_settings_library') )
216 );
217 }
218
219 /**
220 * Get the optimization settings
221 */
222 public function get_ajax_settings() {
223
224 $raw_settings = isset( $_POST['settings'] ) ? wp_unslash( $_POST['settings'] ) : '';
225 $settings = is_string( $raw_settings ) ? json_decode( $raw_settings, true ) : array();
226
227 if ( ! is_array( $settings ) ) {
228 $settings = array();
229 }
230
231 return array(
232 'quickwebp_settings_conversion' => isset( $settings['quickwebp_settings_conversion'] ) ? sanitize_text_field( (string) $settings['quickwebp_settings_conversion'] ) : '',
233 'quickwebp_settings_conversion_quality' => isset( $settings['quickwebp_settings_conversion_quality'] ) ? absint( $settings['quickwebp_settings_conversion_quality'] ) : 0,
234 'quickwebp_settings_conversion_sharpen' => isset( $settings['quickwebp_settings_conversion_sharpen'] ) ? absint( $settings['quickwebp_settings_conversion_sharpen'] ) : 0,
235 'quickwebp_settings_conversion_ignore_webp' => isset( $settings['quickwebp_settings_conversion_ignore_webp'] ) && is_array( $settings['quickwebp_settings_conversion_ignore_webp'] ) ? array_map( 'sanitize_text_field', $settings['quickwebp_settings_conversion_ignore_webp'] ) : array(),
236 'quickwebp_settings_resize' => isset( $settings['quickwebp_settings_resize'] ) ? sanitize_text_field( (string) $settings['quickwebp_settings_resize'] ) : '',
237 'quickwebp_settings_resize_value' => isset( $settings['quickwebp_settings_resize_value'] ) ? absint( $settings['quickwebp_settings_resize_value'] ) : 0,
238 'quickwebp_settings_completion' => isset( $settings['quickwebp_settings_completion'] ) ? sanitize_text_field( (string) $settings['quickwebp_settings_completion'] ) : '',
239 'quickwebp_settings_completion_options' => isset( $settings['quickwebp_settings_completion_options'] ) && is_array( $settings['quickwebp_settings_completion_options'] ) ? array_map( 'sanitize_text_field', $settings['quickwebp_settings_completion_options'] ) : array(),
240 'quickwebp_settings_cleanup' => isset( $settings['quickwebp_settings_cleanup'] ) ? sanitize_text_field( (string) $settings['quickwebp_settings_cleanup'] ) : '',
241 'quickwebp_settings_library' => isset( $settings['quickwebp_settings_library'] ) ? sanitize_text_field( (string) $settings['quickwebp_settings_library'] ) : ''
242 );
243 }
244
245 /**
246 * Add data to the attachment
247 */
248 public function add_data_to_attachment( $metadata, $attachment_id, $context ) {
249
250 $settings = $this->get_settings();
251 if ( $settings['quickwebp_settings_completion'] != '1' ) {
252 return $metadata;
253 }
254
255 if ( $context != 'create' ) {
256 return $metadata;
257 }
258
259 if ( isset($_FILES['async-upload']['original_name']) ) {
260
261 $original_name = sanitize_file_name( wp_unslash( $_FILES['async-upload']['original_name'] ) );
262 $original_name = pathinfo( $original_name, PATHINFO_FILENAME );
263
264 $post_arr = array(
265 'ID' => $attachment_id,
266 'meta_input' => array()
267 );
268
269 $completion_options = is_array($settings['quickwebp_settings_completion_options']) ? $settings['quickwebp_settings_completion_options'] : array();
270
271 if ( in_array( 'title', $completion_options ) ) {
272 $post_arr['post_title'] = $original_name;
273 }
274
275 if ( in_array( 'caption', $completion_options ) ) {
276 $post_arr['post_excerpt'] = $original_name;
277 }
278
279 if ( in_array( 'alt', $completion_options ) ) {
280 $post_arr['meta_input']['_wp_attachment_image_alt'] = $original_name;
281 }
282
283 if ( in_array( 'description', $completion_options ) ) {
284 $post_arr['post_content'] = $original_name;
285 }
286
287 wp_update_post( $post_arr );
288 }
289
290 $save_original = is_array( $settings['quickwebp_settings_conversion_save_original'] ) ? $settings['quickwebp_settings_conversion_save_original'] : array();
291 if ( in_array( 'checked', $save_original ) ) {
292 $sizes = $this->get_media_files( $attachment_id );
293 $new_sizes = array();
294
295 foreach ( $sizes as $key => $size ) {
296 $result = $this->optimize_local_file( $size );
297
298 if ( $result ) {
299 $new_sizes[$key] = $result;
300 }
301 }
302
303 if ( ! empty( $new_sizes ) ) {
304
305 update_post_meta( $attachment_id, 'quickwebp_already_optimized', '1' );
306 update_post_meta( $attachment_id, 'quickwebp_data', $new_sizes );
307 delete_post_meta( $attachment_id, 'quickwebp_has_error' );
308 } else {
309 update_post_meta( $attachment_id, 'quickwebp_has_error', '1' );
310 }
311 }
312
313 return $metadata;
314 }
315
316 /**
317 * Get the quality
318 */
319 public function get_quality( $file, $settings ) {
320
321 $ignore_webp = is_array( $settings['quickwebp_settings_conversion_ignore_webp'] ) ? $settings['quickwebp_settings_conversion_ignore_webp'] : array();
322 $quality = $settings['quickwebp_settings_conversion_quality'];
323 $mime_type = wp_get_image_mime($file);
324
325 switch ( $mime_type ) {
326
327 case 'image/webp':
328 if ( in_array( 'checked', $ignore_webp ) ){
329 $quality = 99;
330 }
331 break;
332 }
333
334 return $quality;
335 }
336
337 /**
338 * Change the default size of wp editor
339 */
340 public function change_wp_max_size( $max_size = 2560 ) {
341
342 $settings = $this->get_settings();
343 $resize_active = $settings['quickwebp_settings_resize'];
344 $resize_value = $settings['quickwebp_settings_resize_value'];
345
346 if ( $resize_active == '1' ) {
347 $max_size = $resize_value;
348 }
349
350 return $max_size;
351 }
352
353 /**
354 * Change the default quality of wp editor
355 */
356 public function change_wp_quality( $default_quality, $mime_type ) {
357
358 $default_quality = 90;
359
360 return $default_quality;
361 }
362
363 /**
364 * Optimize image through ajax
365 */
366 public function image_optimizition_ajax() {
367
368 if ( ! current_user_can( 'upload_files' ) ) {
369 wp_send_json_error( __( 'You are not allowed to upload files.', QUICKWEBP_TEXT_DOMAIN ), 403 );
370 }
371
372 // verify the nonce.
373 $nonce = isset( $_POST['nonce'] ) ? sanitize_text_field( wp_unslash( $_POST['nonce'] ) ) : '';
374 if( !wp_verify_nonce( $nonce, 'image_optimize_nonce' ) ) {
375 wp_send_json_error( __( 'Refresh the page and try again.', QUICKWEBP_TEXT_DOMAIN ) );
376 }
377
378 // Get settings
379 $settings = $this->get_ajax_settings();
380
381 // Get the file
382 $file = count($_FILES) > 0 ? array_shift($_FILES) : array();
383 if ( empty($file) ) {
384 wp_send_json_error( __( 'No image uploaded, try again.', QUICKWEBP_TEXT_DOMAIN ) );
385 }
386
387
388 $image_file = $this->file_is_image( $file, $settings );
389 if ( ! $image_file ) {
390 wp_send_json_error( __( 'No image uploaded, try again.', QUICKWEBP_TEXT_DOMAIN ) );
391 }
392
393 if ( $settings['quickwebp_settings_conversion'] != '1' ) {
394
395 $image_file['new_size'] = $image_file['size'];
396 $image_file['new_type'] = $image_file['type'];
397 $this->return_ajax_data( $image_file );
398 }
399
400 $extension_to_use = $this->image_extension_loaded( $settings );
401 if ( ! $extension_to_use ) {
402
403 $image_file['new_size'] = $image_file['size'];
404 $image_file['new_type'] = $image_file['type'];
405 $this->return_ajax_data( $image_file );
406 }
407
408 $manager = new ImageManager(array('driver'=>$extension_to_use));
409 $image = $manager->make($image_file['tmp_name']);
410 $quality = $this->get_quality( $image_file['tmp_name'], $settings );
411
412 $image->sharpen( $settings['quickwebp_settings_conversion_sharpen'] );
413 $image->save( $image_file['tmp_name'], $quality, 'webp' );
414
415 $image_file['new_size'] = $image->filesize();
416 $image_file['new_type'] = $image->mime();
417 $this->return_ajax_data( $image_file );
418 }
419
420 /**
421 * Return ajax data
422 */
423 public function return_ajax_data( $data ) {
424
425 $return = array(
426 'original_name' => $data['original_name'],
427 'size' => $data['size'],
428 'type' => $this->type_from_mime_type( $data['type'] ),
429 'mime_type' => $data['type'],
430 'image' => 'data:'.$data['new_type'].';base64,' . base64_encode( file_get_contents( $data['tmp_name'] ) ),
431 'name' => $data['name'],
432 'new_size' => $data['new_size'],
433 'new_type' => $this->type_from_mime_type( $data['new_type'] ),
434 'new_mime_type' => $data['new_type']
435 );
436
437 wp_send_json_success( $return );
438 }
439
440 /**
441 * Get the type from the mime type
442 */
443 public function type_from_mime_type( $mime_type ) {
444
445 $array = array(
446 'image/jpeg' => 'JPEG',
447 'image/png' => 'PNG',
448 'image/webp' => 'WebP'
449 );
450
451 return $array[$mime_type] ?? '';
452 }
453
454 /**
455 * Get the unoptimized media ids
456 */
457 public function get_unoptimized_media_ids() {
458
459 $statuses = array(
460 'inherit' => 'inherit',
461 'private' => 'private',
462 );
463 $custom_statuses = get_post_stati( array( 'public' => true ) );
464 unset( $custom_statuses['publish'] );
465 if ( $custom_statuses ) {
466 $statuses = array_merge( $statuses, $custom_statuses );
467 }
468
469 $mime_types = $this->allowed_mime_types;
470 $index = array_search( 'image/webp', $mime_types );
471 unset( $mime_types[$index] );
472
473 $media_ids = get_posts( array(
474 'post_type' => 'attachment',
475 'post_mime_type' => $mime_types,
476 'post_status' => array_keys( $statuses ),
477 'posts_per_page' => -1,
478 'fields' => 'ids',
479 'meta_query' => array(
480 'relation' => 'AND',
481 array(
482 'key' => 'quickwebp_has_error',
483 'compare' => 'NOT EXISTS'
484 ),
485 array(
486 'relation' => 'OR',
487 array(
488 'key' => 'quickwebp_already_optimized',
489 'compare' => 'NOT EXISTS'
490 ),
491 array(
492 'key' => 'quickwebp_already_optimized',
493 'compare' => '=',
494 'value' => '0'
495 )
496 ),
497 ),
498 ) );
499
500 return $media_ids;
501
502 }
503
504 /**
505 * Get the list of media files
506 */
507 public function get_media_files( $media_id ) {
508
509 $fullsize_path = get_attached_file( $media_id );
510
511 if ( ! $fullsize_path ) {
512 return array();
513 }
514
515 $media_data = wp_get_attachment_image_src( $media_id, 'full' );
516 $file_type = wp_check_filetype( $fullsize_path );
517
518 $all_sizes = [
519 'full' => [
520 'size' => 'full',
521 'path' => $fullsize_path,
522 'width' => $media_data[1],
523 'height' => $media_data[2],
524 'mime-type' => $file_type['type'],
525 'disabled' => false,
526 ],
527 ];
528
529 $sizes = wp_get_attachment_metadata( $media_id, true );
530 $sizes = ! empty( $sizes['sizes'] ) && is_array( $sizes['sizes'] ) ? $sizes['sizes'] : [];
531
532 $dir_path = trailingslashit( dirname( $fullsize_path ) );
533
534 foreach ( $sizes as $size => $size_data ) {
535 $all_sizes[ $size ] = [
536 'size' => $size,
537 'path' => $dir_path . $size_data['file'],
538 'width' => $size_data['width'],
539 'height' => $size_data['height'],
540 'mime-type' => $size_data['mime-type'],
541 'disabled' => false
542 ];
543 }
544
545 return $all_sizes;
546 }
547
548 /**
549 * Validate that a post is an optimizable attachment.
550 */
551 public function get_valid_attachment( $attachment_id ) {
552
553 $attachment_id = absint( $attachment_id );
554 if ( ! $attachment_id ) {
555 return false;
556 }
557
558 $attachment = get_post( $attachment_id );
559 if ( ! $attachment || 'attachment' !== $attachment->post_type ) {
560 return false;
561 }
562
563 $mime_types = $this->allowed_mime_types;
564 $index = array_search( 'image/webp', $mime_types, true );
565 if ( false !== $index ) {
566 unset( $mime_types[ $index ] );
567 }
568
569 $mime_type = get_post_mime_type( $attachment_id );
570 if ( ! in_array( $mime_type, $mime_types, true ) ) {
571 return false;
572 }
573
574 return $attachment;
575 }
576
577 /**
578 * Check whether the current user can manage a specific attachment.
579 */
580 public function current_user_can_manage_attachment( $attachment_id ) {
581
582 return current_user_can( 'upload_files' ) && current_user_can( 'edit_post', $attachment_id );
583 }
584
585 /**
586 * Check whether a generated WebP path is safe to delete.
587 */
588 public function is_safe_generated_webp_path( $path ) {
589
590 if ( empty( $path ) || ! is_string( $path ) ) {
591 return false;
592 }
593
594 $uploads = wp_get_upload_dir();
595 if ( empty( $uploads['basedir'] ) ) {
596 return false;
597 }
598
599 $normalized_path = wp_normalize_path( $path );
600 $normalized_base = trailingslashit( wp_normalize_path( $uploads['basedir'] ) );
601
602 if ( 0 !== strpos( $normalized_path, $normalized_base ) ) {
603 return false;
604 }
605
606 return '.webp' === strtolower( substr( $normalized_path, -5 ) );
607 }
608
609 /**
610 * Get the generated WebP files for an attachment.
611 */
612 public function get_generated_webp_paths( $attachment_id ) {
613
614 $paths = array();
615 $sizes = $this->get_media_files( $attachment_id );
616
617 foreach ( $sizes as $size ) {
618 $path = isset( $size['path'] ) ? $size['path'] . '.webp' : '';
619
620 if ( $this->is_safe_generated_webp_path( $path ) ) {
621 $paths[] = $path;
622 }
623 }
624
625 return array_values( array_unique( $paths ) );
626 }
627
628 /**
629 * Optimize a local file
630 */
631 public function optimize_local_file( $size ) {
632
633 $settings = $this->get_settings();
634
635 $extension_to_use = $this->image_extension_loaded( $settings );
636 if ( ! $extension_to_use ) {
637 return false;
638 }
639
640 if ( !is_file($size['path']) ) {
641 return false;
642 }
643
644 $real_type = mime_content_type( $size['path']);
645 if ( !in_array( $real_type, $this->allowed_mime_types ) ) {
646 return false;
647 }
648
649 try {
650 $size_before = filesize( $size['path'] );
651 $manager = new ImageManager(array('driver'=>$extension_to_use));
652 $image = $manager->make($size['path']);
653 $quality = $this->get_quality( $size['path'], $settings );
654 $webp_path = $size['path'].'.webp';
655
656 $image->sharpen($settings['quickwebp_settings_conversion_sharpen']);
657 $image->save( $webp_path, $quality, 'webp' );
658 $size_after = $image->filesize();
659 $image->destroy();
660
661 $deference = $size_before - $size_after;
662 $percent = $deference / $size_before * 100;
663
664 return array(
665 'success' => 1,
666 'original_size' => $size_before,
667 'optimized_size' => $size_after,
668 'percent' => round( $percent, 2 ),
669 'path' => $webp_path
670 );
671 } catch (\Throwable $th) {
672 return false;
673 }
674 }
675
676 /**
677 * Optimize a single media
678 */
679 public function single_optimizition_ajax() {
680
681 // verify the nonce.
682 $nonce = isset( $_POST['nonce'] ) ? sanitize_text_field( wp_unslash( $_POST['nonce'] ) ) : '';
683 if( !wp_verify_nonce( $nonce, 'quickwebp_admin_attachment' ) ) {
684 wp_send_json_error( __( 'Refresh the page and try again.', QUICKWEBP_TEXT_DOMAIN ) );
685 }
686
687 // Sanitize data
688 $attachment_id = isset( $_POST['attachment_id'] ) ? absint( wp_unslash( $_POST['attachment_id'] ) ) : 0;
689
690 if ( ! $attachment_id ) {
691 wp_send_json_error( __( 'No attachment id.', QUICKWEBP_TEXT_DOMAIN ) );
692 }
693
694 if ( ! $this->get_valid_attachment( $attachment_id ) ) {
695 wp_send_json_error( __( 'Not a valid image.', QUICKWEBP_TEXT_DOMAIN ), 400 );
696 }
697
698 if ( ! $this->current_user_can_manage_attachment( $attachment_id ) ) {
699 wp_send_json_error( __( 'You are not allowed to manage this attachment.', QUICKWEBP_TEXT_DOMAIN ), 403 );
700 }
701
702 $already_optimized = get_post_meta( $attachment_id, 'quickwebp_already_optimized', true );
703 if ( $already_optimized === '1' ) {
704 wp_send_json_error( __( 'Already optimized.', QUICKWEBP_TEXT_DOMAIN ) );
705 }
706
707 $sizes = $this->get_media_files( $attachment_id );
708 $new_sizes = array();
709
710 foreach ( $sizes as $key => $size ) {
711
712 $result = $this->optimize_local_file( $size );
713
714 if ( $result ) {
715 $new_sizes[$key] = $result;
716 }
717 }
718
719 if ( ! empty( $new_sizes ) ) {
720 update_post_meta( $attachment_id, 'quickwebp_already_optimized', '1' );
721 update_post_meta( $attachment_id, 'quickwebp_data', $new_sizes );
722 delete_post_meta( $attachment_id, 'quickwebp_has_error' );
723 } else {
724 update_post_meta( $attachment_id, 'quickwebp_has_error', '1' );
725 }
726
727 $wp_media_extend = new Quickwebp_Wp_Media_Extends( $this->plugin_name, $this->version );
728 $html = $wp_media_extend->attachment_data( $new_sizes, $attachment_id );
729
730 wp_send_json_success( $html );
731 }
732
733 /**
734 * Undo a single media optimization
735 */
736 public function undo_single_optimizition_ajax() {
737
738 // verify the nonce.
739 $nonce = isset( $_POST['nonce'] ) ? sanitize_text_field( wp_unslash( $_POST['nonce'] ) ) : '';
740 if( !wp_verify_nonce( $nonce, 'quickwebp_admin_attachment' ) ) {
741 wp_send_json_error( __( 'Refresh the page and try again.', QUICKWEBP_TEXT_DOMAIN ) );
742 }
743
744 // Sanitize data
745 $attachment_id = isset( $_POST['attachment_id'] ) ? absint( wp_unslash( $_POST['attachment_id'] ) ) : 0;
746
747 if ( ! $attachment_id ) {
748 wp_send_json_error( __( 'No attachment id.', QUICKWEBP_TEXT_DOMAIN ) );
749 }
750
751 if ( ! $this->get_valid_attachment( $attachment_id ) ) {
752 wp_send_json_error( __( 'Not a valid image.', QUICKWEBP_TEXT_DOMAIN ), 400 );
753 }
754
755 if ( ! $this->current_user_can_manage_attachment( $attachment_id ) ) {
756 wp_send_json_error( __( 'You are not allowed to manage this attachment.', QUICKWEBP_TEXT_DOMAIN ), 403 );
757 }
758
759 $already_optimized = get_post_meta( $attachment_id, 'quickwebp_already_optimized', true );
760 if ( $already_optimized === '1' ) {
761
762 $this->remove_related_files( $attachment_id );
763 delete_post_meta( $attachment_id, 'quickwebp_already_optimized' );
764 delete_post_meta( $attachment_id, 'quickwebp_data' );
765
766 $wp_media_extend = new Quickwebp_Wp_Media_Extends( $this->plugin_name, $this->version );
767 $html = $wp_media_extend->optimize_btn( $attachment_id );
768
769 wp_send_json_success( $html );
770
771 } else {
772 wp_send_json_error( __( 'Not optimized.', QUICKWEBP_TEXT_DOMAIN ) );
773 }
774
775 }
776
777 /**
778 * Remove the related files of an optimized attachment
779 */
780 public function remove_related_files( $id ) {
781
782 $paths = $this->get_generated_webp_paths( $id );
783
784 foreach ( $paths as $path ) {
785 if ( file_exists( $path ) ) {
786 wp_delete_file( $path );
787 }
788 }
789
790 }
791
792 /**
793 * Trigger before delete attachment
794 */
795 public function before_delete_attachment( $post_id, $post ) {
796
797 $already_optimized = get_post_meta( $post_id, 'quickwebp_already_optimized', true );
798 if ( $already_optimized === '1' ) {
799
800 $this->remove_related_files( $post_id );
801 }
802
803 }
804
805 }