PluginProbe
QuickWebP – WebP & AVIF Image Optimizer, Compression & SEO for WordPress / 3.2.8
QuickWebP – WebP & AVIF Image Optimizer, Compression & SEO for WordPress v3.2.8
4.1.2 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.2.8, at admin/class-image-optimizer.php

797 lines 24.1 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 $settings = isset($_POST['settings']) ? sanitize_text_field($_POST['settings']) : array();
225 $settings = json_decode( stripslashes( $settings ), true );
226
227 return array(
228 'quickwebp_settings_conversion' => isset( $settings['quickwebp_settings_conversion'] ) ? $settings['quickwebp_settings_conversion'] : '',
229 'quickwebp_settings_conversion_quality' => isset( $settings['quickwebp_settings_conversion_quality'] ) ? $settings['quickwebp_settings_conversion_quality'] : '',
230 'quickwebp_settings_conversion_sharpen' => isset( $settings['quickwebp_settings_conversion_sharpen'] ) ? $settings['quickwebp_settings_conversion_sharpen'] : '',
231 'quickwebp_settings_conversion_ignore_webp' => isset( $settings['quickwebp_settings_conversion_ignore_webp'] ) ? $settings['quickwebp_settings_conversion_ignore_webp'] : array(),
232 'quickwebp_settings_resize' => isset( $settings['quickwebp_settings_resize'] ) ? $settings['quickwebp_settings_resize'] : '',
233 'quickwebp_settings_resize_value' => isset( $settings['quickwebp_settings_resize_value'] ) ? $settings['quickwebp_settings_resize_value'] : '',
234 'quickwebp_settings_completion' => isset( $settings['quickwebp_settings_completion'] ) ? $settings['quickwebp_settings_completion'] : '',
235 'quickwebp_settings_completion_options' => isset( $settings['quickwebp_settings_completion_options'] ) ? $settings['quickwebp_settings_completion_options'] : array(),
236 'quickwebp_settings_cleanup' => isset( $settings['quickwebp_settings_cleanup'] ) ? $settings['quickwebp_settings_cleanup'] : '',
237 'quickwebp_settings_library' => isset( $settings['quickwebp_settings_library'] ) ? $settings['quickwebp_settings_library'] : ''
238 );
239 }
240
241 /**
242 * Add data to the attachment
243 */
244 public function add_data_to_attachment( $metadata, $attachment_id, $context ) {
245
246 $settings = $this->get_settings();
247 if ( $settings['quickwebp_settings_completion'] != '1' ) {
248 return $metadata;
249 }
250
251 if ( $context != 'create' ) {
252 return $metadata;
253 }
254
255 if ( isset($_FILES['async-upload']['original_name']) ) {
256
257 $original_name = sanitize_text_field( $_FILES['async-upload']['original_name'] );
258 $original_name = pathinfo( $original_name, PATHINFO_FILENAME );
259
260 $post_arr = array(
261 'ID' => $attachment_id,
262 'meta_input' => array()
263 );
264
265 $completion_options = is_array($settings['quickwebp_settings_completion_options']) ? $settings['quickwebp_settings_completion_options'] : array();
266
267 if ( in_array( 'title', $completion_options ) ) {
268 $post_arr['post_title'] = $original_name;
269 }
270
271 if ( in_array( 'caption', $completion_options ) ) {
272 $post_arr['post_excerpt'] = $original_name;
273 }
274
275 if ( in_array( 'alt', $completion_options ) ) {
276 $post_arr['meta_input']['_wp_attachment_image_alt'] = $original_name;
277 }
278
279 if ( in_array( 'description', $completion_options ) ) {
280 $post_arr['post_content'] = $original_name;
281 }
282
283 wp_update_post( $post_arr );
284 }
285
286 $save_original = is_array( $settings['quickwebp_settings_conversion_save_original'] ) ? $settings['quickwebp_settings_conversion_save_original'] : array();
287 if ( in_array( 'checked', $save_original ) ) {
288 $sizes = $this->get_media_files( $attachment_id );
289 $new_sizes = array();
290
291 foreach ( $sizes as $key => $size ) {
292 $result = $this->optimize_local_file( $size );
293
294 if ( $result ) {
295 $new_sizes[$key] = $result;
296 }
297 }
298
299 if ( ! empty( $new_sizes ) ) {
300
301 update_post_meta( $attachment_id, 'quickwebp_already_optimized', '1' );
302 update_post_meta( $attachment_id, 'quickwebp_data', $new_sizes );
303 delete_post_meta( $attachment_id, 'quickwebp_has_error' );
304 } else {
305 update_post_meta( $attachment_id, 'quickwebp_has_error', '1' );
306 }
307 }
308
309 return $metadata;
310 }
311
312 /**
313 * Get the quality
314 */
315 public function get_quality( $file, $settings ) {
316
317 $ignore_webp = is_array( $settings['quickwebp_settings_conversion_ignore_webp'] ) ? $settings['quickwebp_settings_conversion_ignore_webp'] : array();
318 $quality = $settings['quickwebp_settings_conversion_quality'];
319 $mime_type = wp_get_image_mime($file);
320
321 switch ( $mime_type ) {
322
323 case 'image/webp':
324 if ( in_array( 'checked', $ignore_webp ) ){
325 $quality = 99;
326 }
327 break;
328 }
329
330 return $quality;
331 }
332
333 /**
334 * Change the default size of wp editor
335 */
336 public function change_wp_max_size( $max_size = 2560 ) {
337
338 $settings = $this->get_settings();
339 $resize_active = $settings['quickwebp_settings_resize'];
340 $resize_value = $settings['quickwebp_settings_resize_value'];
341
342 if ( $resize_active == '1' ) {
343 $max_size = $resize_value;
344 }
345
346 return $max_size;
347 }
348
349 /**
350 * Change the default quality of wp editor
351 */
352 public function change_wp_quality( $default_quality, $mime_type ) {
353
354 $default_quality = 90;
355
356 return $default_quality;
357 }
358
359 /**
360 * Optimize image through ajax
361 */
362 public function image_optimizition_ajax() {
363
364 // verify the nonce.
365 $nonce = isset($_POST['nonce']) ? $_POST['nonce'] : '';
366 if( !wp_verify_nonce( $nonce, 'image_optimize_nonce' ) ) {
367 wp_send_json_error( __( 'Refresh the page and try again.', QUICKWEBP_TEXT_DOMAIN ) );
368 }
369
370 // Get settings
371 $settings = $this->get_ajax_settings();
372
373 // Get the file
374 $file = count($_FILES) > 0 ? array_shift($_FILES) : array();
375 if ( empty($file) ) {
376 wp_send_json_error( __( 'No image uploaded, try again.', QUICKWEBP_TEXT_DOMAIN ) );
377 }
378
379
380 $image_file = $this->file_is_image( $file, $settings );
381 if ( ! $image_file ) {
382 wp_send_json_error( __( 'No image uploaded, try again.', QUICKWEBP_TEXT_DOMAIN ) );
383 }
384
385 if ( $settings['quickwebp_settings_conversion'] != '1' ) {
386
387 $image_file['new_size'] = $image_file['size'];
388 $image_file['new_type'] = $image_file['type'];
389 $this->return_ajax_data( $image_file );
390 }
391
392 $extension_to_use = $this->image_extension_loaded( $settings );
393 if ( ! $extension_to_use ) {
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 $manager = new ImageManager(array('driver'=>$extension_to_use));
401 $image = $manager->make($image_file['tmp_name']);
402 $quality = $this->get_quality( $image_file['tmp_name'], $settings );
403
404 $image->sharpen( $settings['quickwebp_settings_conversion_sharpen'] );
405 $image->save( $image_file['tmp_name'], $quality, 'webp' );
406
407 $image_file['new_size'] = $image->filesize();
408 $image_file['new_type'] = $image->mime();
409 $this->return_ajax_data( $image_file );
410 }
411
412 /**
413 * Return ajax data
414 */
415 public function return_ajax_data( $data ) {
416
417 $return = array(
418 'original_name' => $data['original_name'],
419 'size' => $data['size'],
420 'type' => $this->type_from_mime_type( $data['type'] ),
421 'mime_type' => $data['type'],
422 'image' => 'data:'.$data['new_type'].';base64,' . base64_encode( file_get_contents( $data['tmp_name'] ) ),
423 'name' => $data['name'],
424 'new_size' => $data['new_size'],
425 'new_type' => $this->type_from_mime_type( $data['new_type'] ),
426 'new_mime_type' => $data['new_type']
427 );
428
429 wp_send_json_success( $return );
430 }
431
432 /**
433 * Get the type from the mime type
434 */
435 public function type_from_mime_type( $mime_type ) {
436
437 $array = array(
438 'image/jpeg' => 'JPEG',
439 'image/png' => 'PNG',
440 'image/webp' => 'WebP'
441 );
442
443 return $array[$mime_type] ?? '';
444 }
445
446 /**
447 * Get the unoptimized media ids
448 */
449 public function get_unoptimized_media_ids() {
450
451 $statuses = array(
452 'inherit' => 'inherit',
453 'private' => 'private',
454 );
455 $custom_statuses = get_post_stati( array( 'public' => true ) );
456 unset( $custom_statuses['publish'] );
457 if ( $custom_statuses ) {
458 $statuses = array_merge( $statuses, $custom_statuses );
459 }
460
461 $mime_types = $this->allowed_mime_types;
462 $index = array_search( 'image/webp', $mime_types );
463 unset( $mime_types[$index] );
464
465 $media_ids = get_posts( array(
466 'post_type' => 'attachment',
467 'post_mime_type' => $mime_types,
468 'post_status' => array_keys( $statuses ),
469 'posts_per_page' => -1,
470 'fields' => 'ids',
471 'meta_query' => array(
472 'relation' => 'AND',
473 array(
474 'key' => 'quickwebp_has_error',
475 'compare' => 'NOT EXISTS'
476 ),
477 array(
478 'relation' => 'OR',
479 array(
480 'key' => 'quickwebp_already_optimized',
481 'compare' => 'NOT EXISTS'
482 ),
483 array(
484 'key' => 'quickwebp_already_optimized',
485 'compare' => '=',
486 'value' => '0'
487 )
488 ),
489 ),
490 ) );
491
492 return $media_ids;
493
494 }
495
496 /**
497 * Get the list of media files
498 */
499 public function get_media_files( $media_id ) {
500
501 $fullsize_path = get_attached_file( $media_id );
502
503 if ( ! $fullsize_path ) {
504 return array();
505 }
506
507 $media_data = wp_get_attachment_image_src( $media_id, 'full' );
508 $file_type = wp_check_filetype( $fullsize_path );
509
510 $all_sizes = [
511 'full' => [
512 'size' => 'full',
513 'path' => $fullsize_path,
514 'width' => $media_data[1],
515 'height' => $media_data[2],
516 'mime-type' => $file_type['type'],
517 'disabled' => false,
518 ],
519 ];
520
521 $sizes = wp_get_attachment_metadata( $media_id, true );
522 $sizes = ! empty( $sizes['sizes'] ) && is_array( $sizes['sizes'] ) ? $sizes['sizes'] : [];
523
524 $dir_path = trailingslashit( dirname( $fullsize_path ) );
525
526 foreach ( $sizes as $size => $size_data ) {
527 $all_sizes[ $size ] = [
528 'size' => $size,
529 'path' => $dir_path . $size_data['file'],
530 'width' => $size_data['width'],
531 'height' => $size_data['height'],
532 'mime-type' => $size_data['mime-type'],
533 'disabled' => false
534 ];
535 }
536
537 return $all_sizes;
538 }
539
540 /**
541 * Validate that a post is an optimizable attachment.
542 */
543 public function get_valid_attachment( $attachment_id ) {
544
545 $attachment_id = absint( $attachment_id );
546 if ( ! $attachment_id ) {
547 return false;
548 }
549
550 $attachment = get_post( $attachment_id );
551 if ( ! $attachment || 'attachment' !== $attachment->post_type ) {
552 return false;
553 }
554
555 $mime_types = $this->allowed_mime_types;
556 $index = array_search( 'image/webp', $mime_types, true );
557 if ( false !== $index ) {
558 unset( $mime_types[ $index ] );
559 }
560
561 $mime_type = get_post_mime_type( $attachment_id );
562 if ( ! in_array( $mime_type, $mime_types, true ) ) {
563 return false;
564 }
565
566 return $attachment;
567 }
568
569 /**
570 * Check whether the current user can manage a specific attachment.
571 */
572 public function current_user_can_manage_attachment( $attachment_id ) {
573
574 return current_user_can( 'upload_files' ) && current_user_can( 'edit_post', $attachment_id );
575 }
576
577 /**
578 * Check whether a generated WebP path is safe to delete.
579 */
580 public function is_safe_generated_webp_path( $path ) {
581
582 if ( empty( $path ) || ! is_string( $path ) ) {
583 return false;
584 }
585
586 $uploads = wp_get_upload_dir();
587 if ( empty( $uploads['basedir'] ) ) {
588 return false;
589 }
590
591 $normalized_path = wp_normalize_path( $path );
592 $normalized_base = trailingslashit( wp_normalize_path( $uploads['basedir'] ) );
593
594 if ( 0 !== strpos( $normalized_path, $normalized_base ) ) {
595 return false;
596 }
597
598 return '.webp' === strtolower( substr( $normalized_path, -5 ) );
599 }
600
601 /**
602 * Get the generated WebP files for an attachment.
603 */
604 public function get_generated_webp_paths( $attachment_id ) {
605
606 $paths = array();
607 $sizes = $this->get_media_files( $attachment_id );
608
609 foreach ( $sizes as $size ) {
610 $path = isset( $size['path'] ) ? $size['path'] . '.webp' : '';
611
612 if ( $this->is_safe_generated_webp_path( $path ) ) {
613 $paths[] = $path;
614 }
615 }
616
617 return array_values( array_unique( $paths ) );
618 }
619
620 /**
621 * Optimize a local file
622 */
623 public function optimize_local_file( $size ) {
624
625 $settings = $this->get_settings();
626
627 $extension_to_use = $this->image_extension_loaded( $settings );
628 if ( ! $extension_to_use ) {
629 return false;
630 }
631
632 if ( !is_file($size['path']) ) {
633 return false;
634 }
635
636 $real_type = mime_content_type( $size['path']);
637 if ( !in_array( $real_type, $this->allowed_mime_types ) ) {
638 return false;
639 }
640
641 try {
642 $size_before = filesize( $size['path'] );
643 $manager = new ImageManager(array('driver'=>$extension_to_use));
644 $image = $manager->make($size['path']);
645 $quality = $this->get_quality( $size['path'], $settings );
646 $webp_path = $size['path'].'.webp';
647
648 $image->sharpen($settings['quickwebp_settings_conversion_sharpen']);
649 $image->save( $webp_path, $quality, 'webp' );
650 $size_after = $image->filesize();
651 $image->destroy();
652
653 $deference = $size_before - $size_after;
654 $percent = $deference / $size_before * 100;
655
656 return array(
657 'success' => 1,
658 'original_size' => $size_before,
659 'optimized_size' => $size_after,
660 'percent' => round( $percent, 2 ),
661 'path' => $webp_path
662 );
663 } catch (\Throwable $th) {
664 return false;
665 }
666 }
667
668 /**
669 * Optimize a single media
670 */
671 public function single_optimizition_ajax() {
672
673 // verify the nonce.
674 $nonce = isset($_POST['nonce']) ? $_POST['nonce'] : '';
675 if( !wp_verify_nonce( $nonce, 'quickwebp_admin_attachment' ) ) {
676 wp_send_json_error( __( 'Refresh the page and try again.', QUICKWEBP_TEXT_DOMAIN ) );
677 }
678
679 // Sanitize data
680 $attachment_id = isset( $_POST['attachment_id'] ) ? absint( wp_unslash( $_POST['attachment_id'] ) ) : 0;
681
682 if ( ! $attachment_id ) {
683 wp_send_json_error( __( 'No attachment id.', QUICKWEBP_TEXT_DOMAIN ) );
684 }
685
686 if ( ! $this->get_valid_attachment( $attachment_id ) ) {
687 wp_send_json_error( __( 'Not a valid image.', QUICKWEBP_TEXT_DOMAIN ), 400 );
688 }
689
690 if ( ! $this->current_user_can_manage_attachment( $attachment_id ) ) {
691 wp_send_json_error( __( 'You are not allowed to manage this attachment.', QUICKWEBP_TEXT_DOMAIN ), 403 );
692 }
693
694 $already_optimized = get_post_meta( $attachment_id, 'quickwebp_already_optimized', true );
695 if ( $already_optimized === '1' ) {
696 wp_send_json_error( __( 'Already optimized.', QUICKWEBP_TEXT_DOMAIN ) );
697 }
698
699 $sizes = $this->get_media_files( $attachment_id );
700 $new_sizes = array();
701
702 foreach ( $sizes as $key => $size ) {
703
704 $result = $this->optimize_local_file( $size );
705
706 if ( $result ) {
707 $new_sizes[$key] = $result;
708 }
709 }
710
711 if ( ! empty( $new_sizes ) ) {
712 update_post_meta( $attachment_id, 'quickwebp_already_optimized', '1' );
713 update_post_meta( $attachment_id, 'quickwebp_data', $new_sizes );
714 delete_post_meta( $attachment_id, 'quickwebp_has_error' );
715 } else {
716 update_post_meta( $attachment_id, 'quickwebp_has_error', '1' );
717 }
718
719 $wp_media_extend = new Quickwebp_Wp_Media_Extends( $this->plugin_name, $this->version );
720 $html = $wp_media_extend->attachment_data( $new_sizes, $attachment_id );
721
722 wp_send_json_success( $html );
723 }
724
725 /**
726 * Undo a single media optimization
727 */
728 public function undo_single_optimizition_ajax() {
729
730 // verify the nonce.
731 $nonce = isset($_POST['nonce']) ? $_POST['nonce'] : '';
732 if( !wp_verify_nonce( $nonce, 'quickwebp_admin_attachment' ) ) {
733 wp_send_json_error( __( 'Refresh the page and try again.', QUICKWEBP_TEXT_DOMAIN ) );
734 }
735
736 // Sanitize data
737 $attachment_id = isset( $_POST['attachment_id'] ) ? absint( wp_unslash( $_POST['attachment_id'] ) ) : 0;
738
739 if ( ! $attachment_id ) {
740 wp_send_json_error( __( 'No attachment id.', QUICKWEBP_TEXT_DOMAIN ) );
741 }
742
743 if ( ! $this->get_valid_attachment( $attachment_id ) ) {
744 wp_send_json_error( __( 'Not a valid image.', QUICKWEBP_TEXT_DOMAIN ), 400 );
745 }
746
747 if ( ! $this->current_user_can_manage_attachment( $attachment_id ) ) {
748 wp_send_json_error( __( 'You are not allowed to manage this attachment.', QUICKWEBP_TEXT_DOMAIN ), 403 );
749 }
750
751 $already_optimized = get_post_meta( $attachment_id, 'quickwebp_already_optimized', true );
752 if ( $already_optimized === '1' ) {
753
754 $this->remove_related_files( $attachment_id );
755 delete_post_meta( $attachment_id, 'quickwebp_already_optimized' );
756 delete_post_meta( $attachment_id, 'quickwebp_data' );
757
758 $wp_media_extend = new Quickwebp_Wp_Media_Extends( $this->plugin_name, $this->version );
759 $html = $wp_media_extend->optimize_btn( $attachment_id );
760
761 wp_send_json_success( $html );
762
763 } else {
764 wp_send_json_error( __( 'Not optimized.', QUICKWEBP_TEXT_DOMAIN ) );
765 }
766
767 }
768
769 /**
770 * Remove the related files of an optimized attachment
771 */
772 public function remove_related_files( $id ) {
773
774 $paths = $this->get_generated_webp_paths( $id );
775
776 foreach ( $paths as $path ) {
777 if ( file_exists( $path ) ) {
778 wp_delete_file( $path );
779 }
780 }
781
782 }
783
784 /**
785 * Trigger before delete attachment
786 */
787 public function before_delete_attachment( $post_id, $post ) {
788
789 $already_optimized = get_post_meta( $post_id, 'quickwebp_already_optimized', true );
790 if ( $already_optimized === '1' ) {
791
792 $this->remove_related_files( $post_id );
793 }
794
795 }
796
797 }