PluginProbe
Imagify Image Optimization: Optimize Images | Compress & Convert to WebP/AVIF / 1.4.5
Imagify Image Optimization: Optimize Images | Compress & Convert to WebP/AVIF v1.4.5
2.3.4 2.3.3 2.3.2 2.3.1 2.3.0 2.2.9 2.2.8 trunk 1.10 1.3.3 1.3.4 1.3.5 1.3.5.1 1.3.5.2 1.3.6 1.3.6.1 1.4 1.4.1 1.4.2 1.4.3 1.4.4 1.4.5 1.4.6 1.4.7 1.5 All 103 releases
imagify / inc / admin / ajax.php

ajax.php in Imagify Image Optimization: Optimize Images | Compress & Convert to WebP/AVIF 1.4.5, at inc/admin/ajax.php

592 lines 18.5 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 defined( 'ABSPATH' ) or die( 'Cheatin\' uh?' );
3
4 /**
5 * Process all thumbnails of a specific image with Imagify with the manual method.
6 *
7 * @since 1.0
8 */
9 add_action( 'wp_ajax_imagify_manual_upload' , '_do_admin_post_imagify_manual_upload' );
10 add_action( 'admin_post_imagify_manual_upload' , '_do_admin_post_imagify_manual_upload' );
11 function _do_admin_post_imagify_manual_upload() {
12 if ( defined( 'DOING_AJAX' ) ) {
13 check_ajax_referer( 'imagify-manual-upload' );
14 } else {
15 check_admin_referer( 'imagify-manual-upload' );
16 }
17
18 if ( ! isset( $_GET['attachment_id'] ) || ! current_user_can( 'upload_files' ) ) {
19 if ( defined( 'DOING_AJAX' ) ) {
20 wp_send_json_error();
21 } else {
22 wp_nonce_ays( '' );
23 }
24 }
25
26 $attachment_id = $_GET['attachment_id'];
27
28 set_transient( 'imagify-async-in-progress-' . $attachment_id, true, 10 * MINUTE_IN_SECONDS );
29
30 $attachment = new Imagify_Attachment( $attachment_id );
31
32 // Optimize it!!!!!
33 $attachment->optimize();
34
35 if ( ! defined( 'DOING_AJAX' ) ) {
36 wp_safe_redirect( wp_get_referer() );
37 die();
38 }
39
40 // Return the optimization statistics
41 $output = get_imagify_attachment_optimization_text( $attachment_id );
42 wp_send_json_success( $output );
43 }
44
45 /**
46 * Process a manual upload by overriding the optimization level.
47 *
48 * @since 1.0
49 */
50 add_action( 'wp_ajax_imagify_manual_override_upload', '_do_admin_post_imagify_manual_override_upload' );
51 add_action( 'admin_post_imagify_manual_override_upload', '_do_admin_post_imagify_manual_override_upload' );
52 function _do_admin_post_imagify_manual_override_upload() {
53 if ( defined( 'DOING_AJAX' ) ) {
54 check_ajax_referer( 'imagify-manual-override-upload' );
55 } else {
56 check_admin_referer( 'imagify-manual-override-upload' );
57 }
58
59 if ( ! isset( $_GET['attachment_id'] ) || ! current_user_can( 'upload_files' ) ) {
60 if ( defined( 'DOING_AJAX' ) ) {
61 wp_send_json_error();
62 } else {
63 wp_nonce_ays( '' );
64 }
65 }
66
67 $attachment = new Imagify_Attachment( $_GET['attachment_id'] );
68
69 // Restore the backup file
70 $attachment->restore();
71
72 // Optimize it!!!!!
73 $attachment->optimize( (int) $_GET['optimization_level'] );
74
75 if ( ! defined( 'DOING_AJAX' ) ) {
76 wp_safe_redirect( wp_get_referer() );
77 die();
78 }
79
80 // Return the optimization statistics
81 $output = get_imagify_attachment_optimization_text( $attachment->id );
82 wp_send_json_success( $output );
83 }
84
85 /**
86 * Process a restoration to the original attachment.
87 *
88 * @since 1.0
89 */
90 add_action( 'wp_ajax_imagify_restore_upload', '_do_admin_post_imagify_restore_upload' );
91 add_action( 'admin_post_imagify_restore_upload', '_do_admin_post_imagify_restore_upload' );
92 function _do_admin_post_imagify_restore_upload() {
93 if ( defined( 'DOING_AJAX' ) ) {
94 check_ajax_referer( 'imagify-restore-upload' );
95 } else {
96 check_admin_referer( 'imagify-restore-upload' );
97 }
98
99 if ( ! isset( $_GET['attachment_id'] ) || ! current_user_can( 'upload_files' ) ) {
100 if ( defined( 'DOING_AJAX' ) ) {
101 wp_send_json_error();
102 } else {
103 wp_nonce_ays( '' );
104 }
105 }
106
107 $attachment = new Imagify_Attachment( $_GET['attachment_id'] );
108
109 // Restore the backup file
110 $attachment->restore();
111
112 if ( ! defined( 'DOING_AJAX' ) ) {
113 wp_safe_redirect( wp_get_referer() );
114 die();
115 }
116
117 // Return the optimization button
118 $output = '<a id="imagify-upload-' . $attachment->id . '" href="' . get_imagify_admin_url( 'manual-upload', $attachment->id ) . '" class="button-primary button-imagify-manual-upload" data-waiting-label="' . esc_attr__( 'Optimizing...', 'imagify' ) . '">' . __( 'Optimize', 'imagify' ) . '</a>';
119 wp_send_json_success( $output );
120 }
121
122 /**
123 * Get all unoptimized attachment ids.
124 *
125 * @since 1.0
126 */
127 add_action( 'wp_ajax_imagify_get_unoptimized_attachment_ids', '_do_wp_ajax_imagify_get_unoptimized_attachment_ids' );
128 function _do_wp_ajax_imagify_get_unoptimized_attachment_ids() {
129 check_ajax_referer( 'imagify-bulk-upload', 'imagifybulkuploadnonce' );
130
131 if ( ! current_user_can( 'upload_files' ) ) {
132 wp_send_json_error();
133 }
134
135 $user = new Imagify_User();
136
137 if ( $user->is_over_quota() ) {
138 wp_send_json_error( array( 'message' => 'over-quota' ) );
139 }
140
141 @set_time_limit( 0 );
142
143 $optimization_level = $_GET['optimization_level'];
144 $optimization_level = ( -1 != $optimization_level ) ? $optimization_level : get_imagify_option( 'optimization_level', 1 );
145 $optimization_level = (int) $optimization_level;
146
147 $meta_query = array(
148 'relation' => 'OR',
149 array(
150 'key' => '_imagify_optimization_level',
151 'value' => $optimization_level,
152 'compare' => '!='
153 ),
154 array(
155 'key' => '_imagify_optimization_level',
156 'compare' => 'NOT EXISTS'
157 ),
158 array(
159 'key' => '_imagify_status',
160 'value' => 'error',
161 'compare' => '='
162 ),
163 );
164
165 /**
166 * Filter the unoptimized attachments limit query
167 *
168 * @since 1.4.4
169 *
170 * @param int The limit (-1 for unlimited)
171 */
172 $unoptimized_attachment_limit = apply_filters( 'imagify_unoptimized_attachment_limit', 10000 );
173
174 $args = array(
175 'fields' => 'ids',
176 'post_type' => 'attachment',
177 'post_status' => 'any',
178 'post_mime_type' => get_imagify_mime_type(),
179 'meta_query' => $meta_query,
180 'posts_per_page' => $unoptimized_attachment_limit,
181 'orderby' => 'ID',
182 'order' => 'DESC',
183 'no_found_rows' => true,
184 'update_post_term_cache' => false,
185 );
186
187 global $wpdb;
188
189 $data = array();
190 $attachments = new WP_Query( $args );
191 $ids = $attachments->posts;
192 $ids = array_filter( (array) $ids );
193 $sql_ids = implode( ',', $ids );
194
195 if ( empty( $sql_ids ) ) {
196 wp_send_json_error( array( 'message' => 'no-images' ) );
197 }
198
199 // Get attachments filename
200 $attachments_filename = $wpdb->get_col(
201 "SELECT pm.meta_value
202 FROM $wpdb->postmeta as pm
203 WHERE pm.meta_key= '_wp_attached_file'
204 AND pm.post_id IN ($sql_ids)
205 ORDER BY pm.post_id DESC"
206 );
207
208 $attachments_filename = array_combine( $ids, $attachments_filename );
209
210 // Get attachments data
211 $attachments_data = $wpdb->get_results(
212 "SELECT pm.post_id as id, pm.meta_value as value
213 FROM $wpdb->postmeta as pm
214 WHERE pm.meta_key= '_imagify_data'
215 AND pm.post_id IN ($sql_ids)
216 ORDER BY pm.post_id DESC"
217 , ARRAY_A
218 );
219
220 $attachments_data = imagify_query_results_combine( $ids, $attachments_data );
221 $attachments_data = array_map( 'maybe_unserialize', $attachments_data );
222
223 // Get attachments optimization level
224 $attachments_optimization_level = $wpdb->get_results(
225 "SELECT pm.post_id as id, pm.meta_value as value
226 FROM $wpdb->postmeta as pm
227 WHERE pm.meta_key= '_imagify_optimization_level'
228 AND pm.post_id IN ($sql_ids)
229 ORDER BY pm.post_id DESC"
230 , ARRAY_A
231 );
232
233 $attachments_optimization_level = imagify_query_results_combine( $ids, $attachments_optimization_level );
234
235 // Get attachments status
236 $attachments_status = $wpdb->get_results(
237 "SELECT pm.post_id as id, pm.meta_value as value
238 FROM $wpdb->postmeta as pm
239 WHERE pm.meta_key= '_imagify_status'
240 AND pm.post_id IN ($sql_ids)
241 ORDER BY pm.post_id DESC"
242 , ARRAY_A
243 );
244
245 $attachments_status = imagify_query_results_combine( $ids, $attachments_status );
246
247 // Save the optimization level in a transient to retrieve it later during the process
248 set_transient( 'imagify_bulk_optimization_level', $optimization_level );
249
250 foreach( $ids as $id ) {
251 /** This filter is documented in inc/functions/process.php */
252 $file_path = apply_filters( 'imagify_file_path', get_imagify_attached_file( $attachments_filename[ $id ] ) );
253
254 if ( file_exists( $file_path ) ) {
255 $attachment_data = ( isset( $attachments_data[ $id ] ) ) ? $attachments_data[ $id ] : false;
256 $attachment_error = '';
257
258 if ( isset( $attachment_data['sizes']['full']['error'] ) ) {
259 $attachment_error = $attachment_data['sizes']['full']['error'];
260 }
261
262 $attachment_error = trim( $attachment_error );
263 $attachment_status = ( isset( $attachments_status[ $id ] ) ) ? $attachments_status[ $id ] : false;
264 $attachment_optimization_level = ( isset( $attachments_optimization_level[ $id ] ) ) ? $attachments_optimization_level[ $id ] : false;
265 $attachment_backup_path = get_imagify_attachment_backup_path( $file_path );
266
267 // Don't try to re-optimize if the optimization level is still the same
268 if ( $optimization_level === $attachment_optimization_level && is_string( $attachment_error ) ) {
269 continue;
270 }
271
272 // Don't try to re-optimize if there is no backup file
273 if ( $optimization_level !== $attachment_optimization_level && ! file_exists( $attachment_backup_path ) && $attachment_status == 'success' ) {
274 continue;
275 }
276
277 // Don't try to re-optimize images already compressed
278 if ( $attachment_optimization_level >= $optimization_level && $attachment_status == 'already_optimized' ) {
279 continue;
280 }
281
282 // Don't try to re-optimize images with an empty error message
283 if ( $attachment_status == 'error' && empty( $attachment_error ) ) {
284 continue;
285 }
286
287 $data[ '_' . $id ] = get_imagify_attachment_url( $attachments_filename[ $id ] );
288 }
289 }
290
291 if ( (bool) $data ) {
292 wp_send_json_success( $data );
293 }
294
295 wp_send_json_error( array( 'message' => 'no-images' ) );
296 }
297
298 /**
299 * Process all thumbnails of a specific image with Imagify with the bulk method.
300 *
301 * @since 1.0
302 */
303 add_action( 'wp_ajax_imagify_bulk_upload', '_do_wp_ajax_imagify_bulk_upload' );
304 function _do_wp_ajax_imagify_bulk_upload() {
305 check_ajax_referer( 'imagify-bulk-upload', 'imagifybulkuploadnonce' );
306
307 if ( ! isset( $_POST['image'] ) || ! current_user_can( 'upload_files' ) ) {
308 wp_send_json_error();
309 }
310
311 $attachment_id = (int) $_POST['image'];
312 $attachment = new Imagify_Attachment( $_POST['image'] );
313 $optimization_level = get_transient( 'imagify_bulk_optimization_level' );
314
315 // Restore it if the optimization level is updated
316 if ( $optimization_level !== $attachment->get_optimization_level() ) {
317 $attachment->restore();
318 }
319
320 // Optimize it!!!!!
321 $attachment->optimize( $optimization_level );
322
323 // Return the optimization statistics
324 $fullsize_data = $attachment->get_size_data();
325 $stats_data = $attachment->get_stats_data();
326 $user = new Imagify_User();
327 $data = array();
328
329 if ( ! $attachment->is_optimized() ) {
330 $data['success'] = false;
331 $data['error'] = $fullsize_data['error'];
332
333 wp_send_json_error( $data );
334 }
335
336 $data['success'] = true;
337 $data['original_size'] = $fullsize_data['original_size'];
338 $data['new_size'] = $fullsize_data['optimized_size'];
339 $data['percent'] = $fullsize_data['percent'];
340 $data['overall_saving'] = $stats_data['original_size'] - $stats_data['optimized_size'];
341 $data['original_overall_size'] = $stats_data['original_size'];
342 $data['new_overall_size'] = $stats_data['optimized_size'];
343 $data['thumbnails'] = $attachment->get_optimized_sizes_count();
344
345 wp_send_json_success( $data );
346 }
347
348 /**
349 * Create a new Imagify account.
350 *
351 * @since 1.0
352 */
353 add_action( 'wp_ajax_imagify_signup', '_do_wp_ajax_imagify_signup' );
354 function _do_wp_ajax_imagify_signup() {
355 check_ajax_referer( 'imagify-signup', 'imagifysignupnonce' );
356
357 if ( ! isset( $_GET['email'] ) ) {
358 wp_send_json_error();
359 }
360
361 $data = array(
362 'email' => $_GET['email'],
363 'password' => wp_generate_password( 12, false ),
364 'lang' => get_locale()
365 );
366
367 $response = add_imagify_user( $data );
368
369 if ( is_wp_error( $response ) ) {
370 wp_send_json_error( $response->get_error_message() );
371 }
372
373 wp_send_json_success();
374 }
375
376 /**
377 * Process an API key check validity.
378 *
379 * @since 1.0
380 */
381 add_action( 'wp_ajax_imagify_check_api_key_validity', '_do_wp_ajax_imagify_check_api_key_validity' );
382 function _do_wp_ajax_imagify_check_api_key_validity() {
383 check_ajax_referer( 'imagify-check-api-key', 'imagifycheckapikeynonce' );
384
385 if ( ! isset( $_GET['api_key'] ) ) {
386 wp_send_json_error();
387 }
388
389 $response = get_imagify_status( $_GET['api_key'] );
390
391 if ( is_wp_error( $response ) ) {
392 wp_send_json_error( $response->get_error_message() );
393 }
394
395 $options = get_site_option( IMAGIFY_SETTINGS_SLUG );
396 $options['api_key'] = sanitize_key( $_GET['api_key'] );
397
398 update_site_option( IMAGIFY_SETTINGS_SLUG, $options );
399
400 wp_send_json_success();
401 }
402
403 /**
404 * Process a dismissed notice.
405 *
406 * @since 1.0
407 */
408 add_action( 'wp_ajax_imagify_dismiss_notice', '_do_admin_post_imagify_dismiss_notice' );
409 add_action( 'admin_post_imagify_dismiss_notice', '_do_admin_post_imagify_dismiss_notice' );
410 function _do_admin_post_imagify_dismiss_notice() {
411 if ( defined( 'DOING_AJAX' ) ) {
412 check_ajax_referer( 'imagify-dismiss-notice' );
413 } else {
414 check_admin_referer( 'imagify-dismiss-notice' );
415 }
416
417 if ( ! isset( $_GET['notice'] ) || ! current_user_can( 'manage_options' ) ) {
418 if ( defined( 'DOING_AJAX' ) ) {
419 wp_send_json_error();
420 } else {
421 wp_nonce_ays( '' );
422 }
423 }
424
425 $notice = $_GET['notice'];
426
427 imagify_dismiss_notice( $notice );
428
429 /**
430 * Fires when a notice is dismissed.
431 *
432 * @since 1.4.2
433 *
434 * @param int $notice The notice slug
435 */
436 do_action( 'imagify_dismiss_notice', $notice );
437
438 if ( ! defined( 'DOING_AJAX' ) ) {
439 wp_safe_redirect( wp_get_referer() );
440 die();
441 }
442
443 wp_send_json_success();
444 }
445
446 /**
447 * Disable a plugin which can be in conflict with Imagify
448 *
449 * @since 1.2
450 */
451 add_action( 'admin_post_imagify_deactivate_plugin', '_imagify_deactivate_plugin' );
452 function _imagify_deactivate_plugin() {
453 if ( ! wp_verify_nonce( $_GET['_wpnonce'], 'imagifydeactivatepluginnonce' ) ) {
454 wp_nonce_ays( '' );
455 }
456
457 deactivate_plugins( $_GET['plugin'] );
458
459 wp_safe_redirect( wp_get_referer() );
460 die();
461 }
462
463 /**
464 * Get admin bar profile output
465 *
466 * @since 1.2.3
467 */
468 add_action( 'wp_ajax_imagify_get_admin_bar_profile', '_do_wp_ajax_imagify_get_admin_bar_profile' );
469 function _do_wp_ajax_imagify_get_admin_bar_profile() {
470 check_ajax_referer( 'imagify-get-admin-bar-profile', 'imagifygetadminbarprofilenonce' );
471
472 $user = new Imagify_User();
473 $unconsumed_quota = $user->get_percent_unconsumed_quota();
474 $meteo_icon = '<img src="' . IMAGIFY_ASSETS_IMG_URL . 'sun.svg" width="37" height="38" alt="" />';
475 $bar_class = 'positive';
476 $message = '';
477
478 if ( $unconsumed_quota >= 21 && $unconsumed_quota <= 50 ) {
479 $bar_class = 'neutral';
480 $meteo_icon = '<img src="' . IMAGIFY_ASSETS_IMG_URL . 'cloudy-sun.svg" width="37" height="38" alt="" />';
481 }
482 elseif ( $unconsumed_quota <= 20 ) {
483 $bar_class = 'negative';
484 $meteo_icon = '<img src="' . IMAGIFY_ASSETS_IMG_URL . 'stormy.svg" width="38" height="36" alt="" />';
485 }
486
487 if ( $unconsumed_quota <= 20 && $unconsumed_quota > 0 ) {
488 $message = '
489 <div class="imagify-error">
490 <p><i class="dashicons dashicons-warning" aria-hidden="true"></i><strong>' . __( 'Oops, It\'s almost over!', 'imagify' ) . '</strong></p>
491 <p>' . sprintf( __( 'You have almost used all your credit.%sDon\'t forget to upgrade your subscription to continue optimizing your images.', 'imagify' ), '<br/><br/>' ) . '</p>
492 <p class="center txt-center text-center"><a class="btn btn-ghost" href="' . IMAGIFY_APP_MAIN . '/#/subscription" target="_blank">' . __( 'View My Subscription', 'imagify' ) . '</a></p>
493 </div>
494 ';
495 }
496
497 if ( $unconsumed_quota === 0 ) {
498 $message = '
499 <div class="imagify-error">
500 <p><i class="dashicons dashicons-warning" aria-hidden="true"></i><strong>' . __( 'Oops, It\'s Over!', 'imagify' ) . '</strong></p>
501 <p>' . sprintf( __( 'You have consumed all your credit for this month. You will have <strong>%s back on %s</strong>.', 'imagify' ), size_format( $user->quota * 1048576 ), date_i18n( get_option( 'date_format' ), strtotime( $user->next_date_update ) ) ) . '</p>
502 <p class="center txt-center text-center"><a class="btn btn-ghost" href="' . IMAGIFY_APP_MAIN . '/#/subscription" target="_blank">' . __( 'Upgrade My Subscription', 'imagify' ) . '</a></p>
503 </div>
504 ';
505 }
506
507 // custom HTML
508 $quota_section = '
509 <div class="imagify-admin-bar-quota">
510 <div class="imagify-abq-row">';
511
512 if ( 1 === $user->plan_id ) {
513 $quota_section .= '
514 <div class="imagify-meteo-icon">
515 ' . $meteo_icon . '
516 </div>';
517 }
518
519 $quota_section .= '
520 <div class="imagify-account">
521 <p class="imagify-meteo-title">' . __( 'Account status', 'imagify' ) . '</p>
522 <p class="imagify-meteo-subs">' . __( 'Your subscription:', 'imagify' ) . '&nbsp;<strong class="imagify-user-plan">' . $user->plan_label . '</strong></p>
523 </div>
524 </div>';
525
526 if ( 1 === $user->plan_id ) {
527 $quota_section .= '
528 <div class="imagify-abq-row">
529 <div class="imagify-space-left">
530 <p>' . sprintf( __( 'You have %s space credit left', 'imagify'), '<span class="imagify-unconsumed-percent">' . $unconsumed_quota . '%</span>' ) . '</p>
531 <div class="imagify-bar-' . $bar_class . '">
532 <div style="width: ' . $unconsumed_quota . '%;" class="imagify-unconsumed-bar imagify-progress"></div>
533 </div>
534 </div>
535 </div>';
536 }
537
538 $quota_section .= '
539 <p class="imagify-abq-row">
540 <a class="imagify-account-link" href="' . IMAGIFY_APP_MAIN . '/#/subscription" target="_blank">
541 <span class="dashicons dashicons-admin-users"></span>
542 <span class="button-text">' . __( 'View my subscription', 'imagify' ) . '</span>
543 </a>
544 </p>
545 </div>
546 ' . $message;
547
548 wp_send_json_success( $quota_section );
549 }
550
551 /**
552 * Optimize image on picture editing with async request
553 *
554 * @since 1.4
555 **/
556 add_action( 'wp_ajax_imagify_async_optimize_save_image_editor_file', '_do_admin_post_async_optimize_save_image_editor_file' );
557 function _do_admin_post_async_optimize_save_image_editor_file() {
558 if ( isset( $_POST['do'], $_POST['postid'] )
559 && check_ajax_referer( 'image_editor-' . $_POST['postid'] )
560 && get_post_meta( $_POST['postid'], '_imagify_data', true )
561 ) {
562
563 $attachment_id = $_POST['postid'];
564 $optimization_level = get_post_meta( $attachment_id, '_imagify_optimization_level', true );
565 $attachment = new Imagify_Attachment( $attachment_id );
566 $metadata = wp_get_attachment_metadata( $attachment_id );
567
568 // Remove old optimization data
569 delete_post_meta( $attachment_id, '_imagify_data' );
570 delete_post_meta( $attachment_id, '_imagify_status' );
571 delete_post_meta( $attachment_id, '_imagify_optimization_level' );
572
573 if ( 'restore' === $_POST['do'] ) {
574 // Restore the backup file
575 $attachment->restore();
576
577 // Get old metadata to regenerate all thumbnails
578 $metadata = array( 'sizes' => array() );
579 $backup_sizes = (array) get_post_meta( $attachment_id, '_wp_attachment_backup_sizes', true );
580
581 foreach ( $backup_sizes as $size_key => $size_data ) {
582 $size_key = str_replace( '-origin', '' , $size_key );
583 $metadata['sizes'][ $size_key ] = $size_data;
584 }
585 }
586
587 // Optimize it!!!!!
588 $attachment->optimize( $optimization_level, $metadata );
589
590 die( 1 );
591 }
592 }