EWWW Image Optimizer - Version 5.6.0

Version Description

  • added: if exec() is disabled, free cloud-based JPG compression will be enabled
  • added: tool to remove originals for converted images
  • changed: improved handling of WPML replicas in media library list mode and bulk optimizer
  • fixed: JS WebP, picture WebP, and Easy IO errors with WP Offload Media 2.4
  • fixed: JS WebP cannot find local paths when WP_CONTENT_DIR is outside ABSPATH
  • fixed: Easy IO hard crops images when requested height/width is 9999
  • fixed: Lazy Load and WebP parsers running on customizer preview pane
Download this release

Release Info

Developer nosilver4u
Plugin Icon 128x128 EWWW Image Optimizer
Version 5.6.0
Comparing to
See all releases

Code changes from version 5.5.0 to 5.6.0

aux-optimize.php CHANGED
@@ -355,6 +355,83 @@ function ewww_image_optimizer_aux_images_clear_all() {
355
  die();
356
  }
357
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
358
  /**
359
  * Cleanup duplicate and unreferenced records from the images table.
360
  *
@@ -366,7 +443,7 @@ function ewww_image_optimizer_aux_images_clear_all() {
366
  function ewww_image_optimizer_aux_images_clean() {
367
  ewwwio_debug_message( '<b>' . __FUNCTION__ . '()</b>' );
368
  // Verify that an authorized user has called function.
369
- $permissions = apply_filters( 'ewww_image_optimizer_bulk_permissions', '' );
370
  if ( empty( $_REQUEST['ewww_wpnonce'] ) || ! wp_verify_nonce( sanitize_key( $_REQUEST['ewww_wpnonce'] ), 'ewww-image-optimizer-tools' ) || ! current_user_can( $permissions ) ) {
371
  ewwwio_ob_clean();
372
  die( wp_json_encode( array( 'error' => esc_html__( 'Access token has expired, please reload the page.', 'ewww-image-optimizer' ) ) ) );
@@ -383,8 +460,6 @@ function ewww_image_optimizer_aux_images_clean() {
383
 
384
  $already_optimized = $wpdb->get_results( $wpdb->prepare( "SELECT path,orig_size,image_size,id,backup,updated FROM $wpdb->ewwwio_images WHERE pending=0 AND image_size > 0 ORDER BY id DESC LIMIT %d,%d", $offset, $per_page ), ARRAY_A );
385
 
386
- $upload_info = wp_get_upload_dir();
387
- $upload_path = $upload_info['basedir'];
388
  foreach ( $already_optimized as $optimized_image ) {
389
  $file = ewww_image_optimizer_absolutize_path( $optimized_image['path'] );
390
  ewwwio_debug_message( "checking $file for duplicates and dereferences" );
@@ -1221,6 +1296,8 @@ function ewww_image_optimizer_aux_images_cleanup( $auto = false ) {
1221
  add_action( 'wp_ajax_bulk_aux_images_table', 'ewww_image_optimizer_aux_images_table' );
1222
  add_action( 'wp_ajax_bulk_aux_images_table_count', 'ewww_image_optimizer_aux_images_table_count' );
1223
  add_action( 'wp_ajax_bulk_aux_images_table_clear', 'ewww_image_optimizer_aux_images_clear_all' );
 
 
1224
  add_action( 'wp_ajax_bulk_aux_images_table_clean', 'ewww_image_optimizer_aux_images_clean' );
1225
  add_action( 'wp_ajax_bulk_aux_images_meta_clean', 'ewww_image_optimizer_aux_meta_clean' );
1226
  add_action( 'wp_ajax_bulk_aux_images_remove', 'ewww_image_optimizer_aux_images_remove' );
355
  die();
356
  }
357
 
358
+ /**
359
+ * Find the number of converted images in the ewwwio_images table.
360
+ *
361
+ * @global object $wpdb
362
+ */
363
+ function ewww_image_optimizer_aux_images_count_converted() {
364
+ ewwwio_debug_message( '<b>' . __FUNCTION__ . '()</b>' );
365
+ // Verify that an authorized user has called function.
366
+ $permissions = apply_filters( 'ewww_image_optimizer_admin_permissions', '' );
367
+ if ( empty( $_REQUEST['ewww_wpnonce'] ) || ! wp_verify_nonce( sanitize_key( $_REQUEST['ewww_wpnonce'] ), 'ewww-image-optimizer-tools' ) || ! current_user_can( $permissions ) ) {
368
+ ewwwio_ob_clean();
369
+ die( wp_json_encode( array( 'error' => esc_html__( 'Access token has expired, please reload the page.', 'ewww-image-optimizer' ) ) ) );
370
+ }
371
+ ewwwio_ob_clean();
372
+ global $wpdb;
373
+ $count = $wpdb->get_var( "SELECT COUNT(*) FROM $wpdb->ewwwio_images WHERE converted != ''" );
374
+ die( wp_json_encode( array( 'total_converted' => $count ) ) );
375
+ }
376
+
377
+ /**
378
+ * Cleanup originals of converted images using records from the ewwwio_images table.
379
+ *
380
+ * @global object $wpdb
381
+ */
382
+ function ewww_image_optimizer_aux_images_converted_clean() {
383
+ ewwwio_debug_message( '<b>' . __FUNCTION__ . '()</b>' );
384
+ // Verify that an authorized user has called function.
385
+ $permissions = apply_filters( 'ewww_image_optimizer_admin_permissions', '' );
386
+ if ( empty( $_REQUEST['ewww_wpnonce'] ) || ! wp_verify_nonce( sanitize_key( $_REQUEST['ewww_wpnonce'] ), 'ewww-image-optimizer-tools' ) || ! current_user_can( $permissions ) ) {
387
+ ewwwio_ob_clean();
388
+ die( wp_json_encode( array( 'error' => esc_html__( 'Access token has expired, please reload the page.', 'ewww-image-optimizer' ) ) ) );
389
+ }
390
+ global $wpdb;
391
+ if ( strpos( $wpdb->charset, 'utf8' ) === false ) {
392
+ ewww_image_optimizer_db_init();
393
+ global $ewwwdb;
394
+ } else {
395
+ $ewwwdb = $wpdb;
396
+ }
397
+ $completed = 0;
398
+ $per_page = 50;
399
+
400
+ $converted_images = $wpdb->get_results( $wpdb->prepare( "SELECT path,converted,id FROM $wpdb->ewwwio_images WHERE converted != '' ORDER BY id DESC LIMIT %d", $per_page ), ARRAY_A );
401
+
402
+ if ( empty( $converted_images ) || ! is_countable( $converted_images ) || 0 === count( $converted_images ) ) {
403
+ die( wp_json_encode( array( 'finished' => 1 ) ) );
404
+ }
405
+
406
+ // Because some plugins might have loose filters (looking at your WPML).
407
+ remove_all_filters( 'wp_delete_file' );
408
+
409
+ foreach ( $converted_images as $optimized_image ) {
410
+ $completed++;
411
+ $file = ewww_image_optimizer_absolutize_path( $optimized_image['converted'] );
412
+ ewwwio_debug_message( "$file was converted, checking if it still exists" );
413
+ if ( ! ewww_image_optimizer_stream_wrapped( $file ) && ewwwio_is_file( $file ) ) {
414
+ ewwwio_debug_message( "removing original: $file" );
415
+ if ( ewwwio_delete_file( $file ) ) {
416
+ ewwwio_debug_message( "removed $file" );
417
+ } else {
418
+ /* translators: %s: file name */
419
+ die( wp_json_encode( array( 'error' => sprintf( esc_html__( 'Could not delete %s, please remove manually or fix permissions and try again.', 'ewww-image-optimizer' ), esc_html( $file ) ) ) ) );
420
+ }
421
+ }
422
+ $wpdb->update(
423
+ $wpdb->ewwwio_images,
424
+ array(
425
+ 'converted' => '',
426
+ ),
427
+ array(
428
+ 'id' => $optimized_image['id'],
429
+ )
430
+ );
431
+ } // End foreach().
432
+ die( wp_json_encode( array( 'completed' => $completed ) ) );
433
+ }
434
+
435
  /**
436
  * Cleanup duplicate and unreferenced records from the images table.
437
  *
443
  function ewww_image_optimizer_aux_images_clean() {
444
  ewwwio_debug_message( '<b>' . __FUNCTION__ . '()</b>' );
445
  // Verify that an authorized user has called function.
446
+ $permissions = apply_filters( 'ewww_image_optimizer_admin_permissions', '' );
447
  if ( empty( $_REQUEST['ewww_wpnonce'] ) || ! wp_verify_nonce( sanitize_key( $_REQUEST['ewww_wpnonce'] ), 'ewww-image-optimizer-tools' ) || ! current_user_can( $permissions ) ) {
448
  ewwwio_ob_clean();
449
  die( wp_json_encode( array( 'error' => esc_html__( 'Access token has expired, please reload the page.', 'ewww-image-optimizer' ) ) ) );
460
 
461
  $already_optimized = $wpdb->get_results( $wpdb->prepare( "SELECT path,orig_size,image_size,id,backup,updated FROM $wpdb->ewwwio_images WHERE pending=0 AND image_size > 0 ORDER BY id DESC LIMIT %d,%d", $offset, $per_page ), ARRAY_A );
462
 
 
 
463
  foreach ( $already_optimized as $optimized_image ) {
464
  $file = ewww_image_optimizer_absolutize_path( $optimized_image['path'] );
465
  ewwwio_debug_message( "checking $file for duplicates and dereferences" );
1296
  add_action( 'wp_ajax_bulk_aux_images_table', 'ewww_image_optimizer_aux_images_table' );
1297
  add_action( 'wp_ajax_bulk_aux_images_table_count', 'ewww_image_optimizer_aux_images_table_count' );
1298
  add_action( 'wp_ajax_bulk_aux_images_table_clear', 'ewww_image_optimizer_aux_images_clear_all' );
1299
+ add_action( 'wp_ajax_bulk_aux_images_count_converted', 'ewww_image_optimizer_aux_images_count_converted' );
1300
+ add_action( 'wp_ajax_bulk_aux_images_converted_clean', 'ewww_image_optimizer_aux_images_converted_clean' );
1301
  add_action( 'wp_ajax_bulk_aux_images_table_clean', 'ewww_image_optimizer_aux_images_clean' );
1302
  add_action( 'wp_ajax_bulk_aux_images_meta_clean', 'ewww_image_optimizer_aux_meta_clean' );
1303
  add_action( 'wp_ajax_bulk_aux_images_remove', 'ewww_image_optimizer_aux_images_remove' );
bulk.php CHANGED
@@ -89,6 +89,17 @@ function ewww_image_optimizer_display_tools() {
89
  echo "<form id='ewww-clear-table' class='ewww-tool-form' method='post' action=''>\n" .
90
  "<input type='submit' class='button-secondary action' value='" . esc_attr__( 'Erase Optimization History', 'ewww-image-optimizer' ) . "' />\n" .
91
  "</form>\n</div>\n";
 
 
 
 
 
 
 
 
 
 
 
92
  $as3cf_remove = false;
93
  if ( class_exists( 'Amazon_S3_And_CloudFront' ) ) {
94
  global $as3cf;
@@ -107,6 +118,7 @@ function ewww_image_optimizer_display_tools() {
107
  echo "<div id='ewww-clean-table-progressbar' style='display:none;'></div>";
108
  echo "<div id='ewww-clean-table-progress' style='display:none;'></div>";
109
  }
 
110
  global $wpdb;
111
  echo '<hr class="ewww-tool-divider">';
112
  echo "<div>\n<p id='ewww-clean-meta-info' class='ewww-tool-info'>" .
@@ -442,9 +454,7 @@ function ewww_image_optimizer_reduce_query_count( $max_query ) {
442
  * The image count(s) found during the search.
443
  *
444
  * @type int $full_count The number of original uploads found.
445
- * @type int $unoptimized_full The number of original uploads that have not been optimized.
446
  * @type int $resize_count The number of thumbnails/resizes found.
447
- * @type int $unoptimized_re The number of resizes that are not optimized.
448
  * }
449
  */
450
  function ewww_image_optimizer_count_optimized( $gallery ) {
@@ -452,8 +462,6 @@ function ewww_image_optimizer_count_optimized( $gallery ) {
452
  ewwwio_debug_message( "scanning for $gallery" );
453
  global $wpdb;
454
  $full_count = 0;
455
- $unoptimized_full = 0;
456
- $unoptimized_re = 0;
457
  $resize_count = 0;
458
  $attachment_query = '';
459
  $started = microtime( true ); // Retrieve the time when the counting starts.
@@ -498,17 +506,11 @@ function ewww_image_optimizer_count_optimized( $gallery ) {
498
  if ( ! is_array( $meta ) ) {
499
  continue;
500
  }
501
- if ( empty( $meta['ewww_image_optimizer'] ) ) {
502
- $unoptimized_full++;
503
- }
504
  $ngg_sizes = $ewwwngg->maybe_get_more_sizes( $sizes, $meta );
505
  if ( ewww_image_optimizer_iterable( $ngg_sizes ) ) {
506
  foreach ( $ngg_sizes as $size ) {
507
  if ( 'full' !== $size ) {
508
  $resize_count++;
509
- if ( empty( $meta[ $size ]['ewww_image_optimizer'] ) ) {
510
- $unoptimized_re++;
511
- }
512
  }
513
  }
514
  }
@@ -547,20 +549,11 @@ function ewww_image_optimizer_count_optimized( $gallery ) {
547
  if ( ! is_array( $meta ) ) {
548
  continue;
549
  }
550
- if ( empty( $meta['ewww_image_optimizer'] ) ) {
551
- $unoptimized_full++;
552
- }
553
  if ( ! empty( $meta['webview'] ) ) {
554
  $resize_count++;
555
- if ( empty( $meta['webview']['ewww_image_optimizer'] ) ) {
556
- $unoptimized_re++;
557
- }
558
  }
559
  if ( ! empty( $meta['thumbnail'] ) ) {
560
  $resize_count++;
561
- if ( empty( $meta['thumbnail']['ewww_image_optimizer'] ) ) {
562
- $unoptimized_re++;
563
- }
564
  }
565
  }
566
  $full_count += count( $attachments );
@@ -585,9 +578,9 @@ function ewww_image_optimizer_count_optimized( $gallery ) {
585
  }
586
  $elapsed = microtime( true ) - $started;
587
  ewwwio_debug_message( "counting images took $elapsed seconds" );
588
- ewwwio_debug_message( "found $full_count fullsize ($unoptimized_full unoptimized), and $resize_count resizes ($unoptimized_re unoptimized)" );
589
  ewwwio_memory( __FUNCTION__ );
590
- return array( $full_count, $unoptimized_full, $resize_count, $unoptimized_re );
591
  }
592
 
593
  /**
@@ -841,6 +834,8 @@ function ewww_image_optimizer_fetch_metadata_batch( $attachments_in ) {
841
  continue;
842
  } elseif ( 'tiny_compress_images' === $attachment['meta_key'] ) {
843
  $attachment_meta[ $attachment['post_id'] ]['tinypng'] = true;
 
 
844
  }
845
  if ( ! empty( $attachment['post_mime_type'] ) && empty( $attachment_meta[ $attachment['post_id'] ]['type'] ) ) {
846
  $attachment_meta[ $attachment['post_id'] ]['type'] = $attachment['post_mime_type'];
@@ -1063,6 +1058,11 @@ function ewww_image_optimizer_media_scan( $hook = '' ) {
1063
  clearstatcache();
1064
  $pending = false;
1065
  $remote_file = false;
 
 
 
 
 
1066
  if ( in_array( $selected_id, $bad_attachments, true ) ) { // a known broken attachment, which would mean we already tried this once before...
1067
  ewwwio_debug_message( "skipping bad attachment $selected_id" );
1068
  $skipped_ids[] = $selected_id;
89
  echo "<form id='ewww-clear-table' class='ewww-tool-form' method='post' action=''>\n" .
90
  "<input type='submit' class='button-secondary action' value='" . esc_attr__( 'Erase Optimization History', 'ewww-image-optimizer' ) . "' />\n" .
91
  "</form>\n</div>\n";
92
+
93
+ echo '<hr class="ewww-tool-divider">';
94
+ echo "<div>\n<p id='ewww-clean-converted-info' class='ewww-tool-info'>" .
95
+ esc_html__( 'If you have converted images (PNG to JPG and friends) without deleting the originals, you may remove them when ready.', 'ewww-image-optimizer' ) . "<br>\n" .
96
+ '<i>' . esc_html__( 'Please perform a site backup before proceeding.', 'ewww-image-optimizer' ) . "</i></p>\n";
97
+ echo "<form id='ewww-clean-converted' class='ewww-tool-form' method='post' action=''>\n" .
98
+ "<input type='submit' class='button-secondary action' value='" . esc_attr__( 'Remove Converted Originals', 'ewww-image-optimizer' ) . "' />\n" .
99
+ "</form>\n</div>\n";
100
+ echo "<div id='ewww-clean-converted-progressbar' style='display:none;'></div>";
101
+ echo "<div id='ewww-clean-converted-progress' style='display:none;'></div>";
102
+
103
  $as3cf_remove = false;
104
  if ( class_exists( 'Amazon_S3_And_CloudFront' ) ) {
105
  global $as3cf;
118
  echo "<div id='ewww-clean-table-progressbar' style='display:none;'></div>";
119
  echo "<div id='ewww-clean-table-progress' style='display:none;'></div>";
120
  }
121
+
122
  global $wpdb;
123
  echo '<hr class="ewww-tool-divider">';
124
  echo "<div>\n<p id='ewww-clean-meta-info' class='ewww-tool-info'>" .
454
  * The image count(s) found during the search.
455
  *
456
  * @type int $full_count The number of original uploads found.
 
457
  * @type int $resize_count The number of thumbnails/resizes found.
 
458
  * }
459
  */
460
  function ewww_image_optimizer_count_optimized( $gallery ) {
462
  ewwwio_debug_message( "scanning for $gallery" );
463
  global $wpdb;
464
  $full_count = 0;
 
 
465
  $resize_count = 0;
466
  $attachment_query = '';
467
  $started = microtime( true ); // Retrieve the time when the counting starts.
506
  if ( ! is_array( $meta ) ) {
507
  continue;
508
  }
 
 
 
509
  $ngg_sizes = $ewwwngg->maybe_get_more_sizes( $sizes, $meta );
510
  if ( ewww_image_optimizer_iterable( $ngg_sizes ) ) {
511
  foreach ( $ngg_sizes as $size ) {
512
  if ( 'full' !== $size ) {
513
  $resize_count++;
 
 
 
514
  }
515
  }
516
  }
549
  if ( ! is_array( $meta ) ) {
550
  continue;
551
  }
 
 
 
552
  if ( ! empty( $meta['webview'] ) ) {
553
  $resize_count++;
 
 
 
554
  }
555
  if ( ! empty( $meta['thumbnail'] ) ) {
556
  $resize_count++;
 
 
 
557
  }
558
  }
559
  $full_count += count( $attachments );
578
  }
579
  $elapsed = microtime( true ) - $started;
580
  ewwwio_debug_message( "counting images took $elapsed seconds" );
581
+ ewwwio_debug_message( "found $full_count fullsize and $resize_count resizes" );
582
  ewwwio_memory( __FUNCTION__ );
583
+ return array( $full_count, $resize_count );
584
  }
585
 
586
  /**
834
  continue;
835
  } elseif ( 'tiny_compress_images' === $attachment['meta_key'] ) {
836
  $attachment_meta[ $attachment['post_id'] ]['tinypng'] = true;
837
+ } elseif ( 'wpml_media_processed' === $attachment['meta_key'] ) {
838
+ $attachment_meta[ $attachment['post_id'] ]['wpml_media_processed'] = (bool) $attachment['meta_value'];
839
  }
840
  if ( ! empty( $attachment['post_mime_type'] ) && empty( $attachment_meta[ $attachment['post_id'] ]['type'] ) ) {
841
  $attachment_meta[ $attachment['post_id'] ]['type'] = $attachment['post_mime_type'];
1058
  clearstatcache();
1059
  $pending = false;
1060
  $remote_file = false;
1061
+ if ( ! empty( $attachment_meta[ $selected_id ]['wpml_media_processed'] ) ) {
1062
+ ewwwio_debug_message( "skipping WPML replica image $selected_id" );
1063
+ $skipped_ids[] = $selected_id;
1064
+ continue;
1065
+ }
1066
  if ( in_array( $selected_id, $bad_attachments, true ) ) { // a known broken attachment, which would mean we already tried this once before...
1067
  ewwwio_debug_message( "skipping bad attachment $selected_id" );
1068
  $skipped_ids[] = $selected_id;
changelog.txt CHANGED
@@ -1,3 +1,12 @@
 
 
 
 
 
 
 
 
 
1
  = 5.5.0 =
2
  * added: GIF to WebP conversion with API and Easy IO
3
  * changed: plugin removed from disallowed list on WP Engine!
1
+ = 5.6.0 =
2
+ * added: if exec() is disabled, free cloud-based JPG compression will be enabled
3
+ * added: tool to remove originals for converted images
4
+ * changed: improved handling of WPML replicas in media library list mode and bulk optimizer
5
+ * fixed: JS WebP, picture WebP, and Easy IO errors with WP Offload Media 2.4
6
+ * fixed: JS WebP cannot find local paths when WP_CONTENT_DIR is outside ABSPATH
7
+ * fixed: Easy IO hard crops images when requested height/width is 9999
8
+ * fixed: Lazy Load and WebP parsers running on customizer preview pane
9
+
10
  = 5.5.0 =
11
  * added: GIF to WebP conversion with API and Easy IO
12
  * changed: plugin removed from disallowed list on WP Engine!
classes/class-eio-alt-webp.php CHANGED
@@ -104,9 +104,13 @@ class EIO_Alt_Webp extends EIO_Page_Parser {
104
  if ( is_wp_error( $s3_region ) ) {
105
  $s3_region = '';
106
  }
107
- $s3_domain = $as3cf->get_provider()->get_url_domain( $s3_bucket, $s3_region, null, array(), true );
108
- ewwwio_debug_message( "found S3 domain of $s3_domain with bucket $s3_bucket and region $s3_region" );
 
 
 
109
  if ( ! empty( $s3_domain ) && $as3cf->get_setting( 'serve-from-s3' ) ) {
 
110
  $this->webp_paths[] = $s3_scheme . '://' . $s3_domain . '/';
111
  $this->s3_active = $s3_domain;
112
  if ( $as3cf->get_setting( 'enable-object-prefix' ) ) {
@@ -367,6 +371,7 @@ class EIO_Alt_Webp extends EIO_Page_Parser {
367
  is_embed() ||
368
  is_feed() ||
369
  is_preview() ||
 
370
  ( defined( 'REST_REQUEST' ) && REST_REQUEST ) ||
371
  preg_match( '/^<\?xml/', $buffer ) ||
372
  strpos( $buffer, 'amp-boilerplate' ) ||
104
  if ( is_wp_error( $s3_region ) ) {
105
  $s3_region = '';
106
  }
107
+ if ( ! empty( $s3_bucket ) && ! is_wp_error( $s3_bucket ) && method_exists( $as3cf, 'get_provider' ) ) {
108
+ $s3_domain = $as3cf->get_provider()->get_url_domain( $s3_bucket, $s3_region, null, array(), true );
109
+ } elseif ( ! empty( $s3_bucket ) && ! is_wp_error( $s3_bucket ) && method_exists( $as3cf, 'get_storage_provider' ) ) {
110
+ $s3_domain = $as3cf->get_storage_provider()->get_url_domain( $s3_bucket, $s3_region );
111
+ }
112
  if ( ! empty( $s3_domain ) && $as3cf->get_setting( 'serve-from-s3' ) ) {
113
+ ewwwio_debug_message( "found S3 domain of $s3_domain with bucket $s3_bucket and region $s3_region" );
114
  $this->webp_paths[] = $s3_scheme . '://' . $s3_domain . '/';
115
  $this->s3_active = $s3_domain;
116
  if ( $as3cf->get_setting( 'enable-object-prefix' ) ) {
371
  is_embed() ||
372
  is_feed() ||
373
  is_preview() ||
374
+ is_customize_preview() ||
375
  ( defined( 'REST_REQUEST' ) && REST_REQUEST ) ||
376
  preg_match( '/^<\?xml/', $buffer ) ||
377
  strpos( $buffer, 'amp-boilerplate' ) ||
classes/class-eio-base.php CHANGED
@@ -154,7 +154,7 @@ if ( ! class_exists( 'EIO_Base' ) ) {
154
  * @param string $message Debug information to add to the log.
155
  */
156
  function debug_message( $message ) {
157
- if ( ! is_string( $message ) ) {
158
  return;
159
  }
160
  if ( defined( 'WP_CLI' ) && WP_CLI ) {
@@ -433,7 +433,9 @@ if ( ! class_exists( 'EIO_Base' ) ) {
433
  */
434
  function url_to_path_exists( $url, $extension = '' ) {
435
  $this->debug_message( '<b>' . __METHOD__ . '()</b>' );
436
- if ( 0 === strpos( $url, $this->relative_home_url ) ) {
 
 
437
  $path = str_replace( $this->relative_home_url, ABSPATH, $url );
438
  } elseif ( 0 === strpos( $url, $this->home_url ) ) {
439
  $path = str_replace( $this->home_url, ABSPATH, $url );
@@ -446,10 +448,6 @@ if ( ! class_exists( 'EIO_Base' ) ) {
446
  $this->debug_message( 'local file found' );
447
  return $path_parts[0];
448
  }
449
- if ( $this->is_file( $path . $extension ) ) {
450
- $this->debug_message( 'local file found' );
451
- return $path;
452
- }
453
  return false;
454
  }
455
 
@@ -493,8 +491,10 @@ if ( ! class_exists( 'EIO_Base' ) ) {
493
  $s3_region = '';
494
  }
495
  $s3_domain = '';
496
- if ( ! empty( $s3_bucket ) && ! is_wp_error( $s3_bucket ) ) {
497
  $s3_domain = $as3cf->get_provider()->get_url_domain( $s3_bucket, $s3_region, null, array(), true );
 
 
498
  }
499
  if ( ! empty( $s3_domain ) && $as3cf->get_setting( 'serve-from-s3' ) ) {
500
  $this->s3_active = true;
154
  * @param string $message Debug information to add to the log.
155
  */
156
  function debug_message( $message ) {
157
+ if ( ! is_string( $message ) && ! is_int( $message ) && ! is_float( $message ) ) {
158
  return;
159
  }
160
  if ( defined( 'WP_CLI' ) && WP_CLI ) {
433
  */
434
  function url_to_path_exists( $url, $extension = '' ) {
435
  $this->debug_message( '<b>' . __METHOD__ . '()</b>' );
436
+ if ( 0 === strpos( $url, WP_CONTENT_URL ) ) {
437
+ $path = str_replace( WP_CONTENT_URL, WP_CONTENT_DIR, $url );
438
+ } elseif ( 0 === strpos( $url, $this->relative_home_url ) ) {
439
  $path = str_replace( $this->relative_home_url, ABSPATH, $url );
440
  } elseif ( 0 === strpos( $url, $this->home_url ) ) {
441
  $path = str_replace( $this->home_url, ABSPATH, $url );
448
  $this->debug_message( 'local file found' );
449
  return $path_parts[0];
450
  }
 
 
 
 
451
  return false;
452
  }
453
 
491
  $s3_region = '';
492
  }
493
  $s3_domain = '';
494
+ if ( ! empty( $s3_bucket ) && ! is_wp_error( $s3_bucket ) && method_exists( $as3cf, 'get_provider' ) ) {
495
  $s3_domain = $as3cf->get_provider()->get_url_domain( $s3_bucket, $s3_region, null, array(), true );
496
+ } elseif ( ! empty( $s3_bucket ) && ! is_wp_error( $s3_bucket ) && method_exists( $as3cf, 'get_storage_provider' ) ) {
497
+ $s3_domain = $as3cf->get_storage_provider()->get_url_domain( $s3_bucket, $s3_region );
498
  }
499
  if ( ! empty( $s3_domain ) && $as3cf->get_setting( 'serve-from-s3' ) ) {
500
  $this->s3_active = true;
classes/class-eio-lazy-load.php CHANGED
@@ -169,6 +169,7 @@ if ( ! class_exists( 'EIO_Lazy_Load' ) ) {
169
  is_embed() ||
170
  is_feed() ||
171
  is_preview() ||
 
172
  ( defined( 'REST_REQUEST' ) && REST_REQUEST ) ||
173
  wp_script_is( 'twentytwenty-twentytwenty', 'enqueued' ) ||
174
  preg_match( '/^<\?xml/', $buffer ) ||
169
  is_embed() ||
170
  is_feed() ||
171
  is_preview() ||
172
+ is_customize_preview() ||
173
  ( defined( 'REST_REQUEST' ) && REST_REQUEST ) ||
174
  wp_script_is( 'twentytwenty-twentytwenty', 'enqueued' ) ||
175
  preg_match( '/^<\?xml/', $buffer ) ||
classes/class-eio-picture-webp.php CHANGED
@@ -88,9 +88,13 @@ class EIO_Picture_Webp extends EIO_Page_Parser {
88
  if ( is_wp_error( $s3_region ) ) {
89
  $s3_region = '';
90
  }
91
- $s3_domain = $as3cf->get_provider()->get_url_domain( $s3_bucket, $s3_region, null, array(), true );
92
- ewwwio_debug_message( "found S3 domain of $s3_domain with bucket $s3_bucket and region $s3_region" );
 
 
 
93
  if ( ! empty( $s3_domain ) && $as3cf->get_setting( 'serve-from-s3' ) ) {
 
94
  $this->webp_paths[] = $s3_scheme . '://' . $s3_domain . '/';
95
  $this->s3_active = $s3_domain;
96
  if ( $as3cf->get_setting( 'enable-object-prefix' ) ) {
@@ -179,8 +183,10 @@ class EIO_Picture_Webp extends EIO_Page_Parser {
179
  strpos( $uri, 'et_fb=' ) !== false ||
180
  strpos( $uri, 'tatsu=' ) !== false ||
181
  ( ! empty( $_POST['action'] ) && 'tatsu_get_concepts' === sanitize_text_field( wp_unslash( $_POST['action'] ) ) ) || // phpcs:ignore WordPress.Security.NonceVerification
 
182
  is_feed() ||
183
  is_preview() ||
 
184
  ( defined( 'REST_REQUEST' ) && REST_REQUEST ) ||
185
  preg_match( '/^<\?xml/', $buffer ) ||
186
  strpos( $buffer, 'amp-boilerplate' ) ||
88
  if ( is_wp_error( $s3_region ) ) {
89
  $s3_region = '';
90
  }
91
+ if ( ! empty( $s3_bucket ) && ! is_wp_error( $s3_bucket ) && method_exists( $as3cf, 'get_provider' ) ) {
92
+ $s3_domain = $as3cf->get_provider()->get_url_domain( $s3_bucket, $s3_region, null, array(), true );
93
+ } elseif ( ! empty( $s3_bucket ) && ! is_wp_error( $s3_bucket ) && method_exists( $as3cf, 'get_storage_provider' ) ) {
94
+ $s3_domain = $as3cf->get_storage_provider()->get_url_domain( $s3_bucket, $s3_region );
95
+ }
96
  if ( ! empty( $s3_domain ) && $as3cf->get_setting( 'serve-from-s3' ) ) {
97
+ ewwwio_debug_message( "found S3 domain of $s3_domain with bucket $s3_bucket and region $s3_region" );
98
  $this->webp_paths[] = $s3_scheme . '://' . $s3_domain . '/';
99
  $this->s3_active = $s3_domain;
100
  if ( $as3cf->get_setting( 'enable-object-prefix' ) ) {
183
  strpos( $uri, 'et_fb=' ) !== false ||
184
  strpos( $uri, 'tatsu=' ) !== false ||
185
  ( ! empty( $_POST['action'] ) && 'tatsu_get_concepts' === sanitize_text_field( wp_unslash( $_POST['action'] ) ) ) || // phpcs:ignore WordPress.Security.NonceVerification
186
+ is_embed() ||
187
  is_feed() ||
188
  is_preview() ||
189
+ is_customize_preview() ||
190
  ( defined( 'REST_REQUEST' ) && REST_REQUEST ) ||
191
  preg_match( '/^<\?xml/', $buffer ) ||
192
  strpos( $buffer, 'amp-boilerplate' ) ||
classes/class-ewww-flag.php CHANGED
@@ -101,7 +101,7 @@ if ( ! class_exists( 'EWWW_Flag' ) ) {
101
  return;
102
  }
103
  }
104
- list( $fullsize_count, $unoptimized_count, $resize_count, $unoptimized_resize_count ) = ewww_image_optimizer_count_optimized( 'flag' );
105
  // Bail-out if there aren't any images to optimize.
106
  if ( $fullsize_count < 1 ) {
107
  echo '<p>' . esc_html__( 'You do not appear to have uploaded any images yet.', 'ewww-image-optimizer' ) . '</p>';
@@ -114,6 +114,7 @@ if ( ! class_exists( 'EWWW_Flag' ) ) {
114
  ewww_image_optimizer_cloud_verify();
115
  echo '<a id="ewww-bulk-credits-available" target="_blank" class="page-title-action" style="float:right;" href="https://ewww.io/my-account/">' . esc_html__( 'Image credits available:', 'ewww-image-optimizer' ) . ' ' . esc_html( ewww_image_optimizer_cloud_quota() ) . '</a>';
116
  }
 
117
  // Retrieve the value of the 'bulk resume' option and set the button text for the form to use.
118
  $resume = get_option( 'ewww_image_optimizer_bulk_flag_resume' );
119
  if ( empty( $resume ) ) {
@@ -123,13 +124,13 @@ if ( ! class_exists( 'EWWW_Flag' ) ) {
123
  }
124
  $delay = ewww_image_optimizer_get_option( 'ewww_image_optimizer_delay' ) ? ewww_image_optimizer_get_option( 'ewww_image_optimizer_delay' ) : 0;
125
  /* translators: 1-4: number(s) of images */
126
- $selected_images_text = sprintf( __( '%1$d images have been selected (%2$d unoptimized), with %3$d resizes (%4$d unoptimized).', 'ewww-image-optimizer' ), $fullsize_count, $unoptimized_count, $resize_count, $unoptimized_resize_count );
127
  ?>
128
  <div id="ewww-bulk-loading"></div>
129
  <div id="ewww-bulk-progressbar"></div>
130
  <div id="ewww-bulk-counter"></div>
131
  <form id="ewww-bulk-stop" style="display:none;" method="post" action="">
132
- <br /><input type="submit" class="button-secondary action" value="<?php esc_attr_e( 'Stop Optimizing', 'ewww-image-optimizer' ); ?>" />
133
  </form>
134
  <div id="ewww-bulk-widgets" class="metabox-holder" style="display:none">
135
  <div class="meta-box-sortables">
@@ -153,14 +154,19 @@ if ( ! class_exists( 'EWWW_Flag' ) ) {
153
  </div>
154
  </div>
155
  </div>
156
- <form class="ewww-bulk-form">
157
- <p><label for="ewww-force" style="font-weight: bold"><?php esc_html_e( 'Force re-optimize', 'ewww-image-optimizer' ); ?></label>&emsp;<input type="checkbox" id="ewww-force" name="ewww-force"></p>
158
- <p><label for="ewww-delay" style="font-weight: bold"><?php esc_html_e( 'Choose how long to pause between images (in seconds, 0 = disabled)', 'ewww-image-optimizer' ); ?></label>&emsp;<input type="text" id="ewww-delay" name="ewww-delay" value="<?php echo (int) $delay; ?>"></p>
159
- <div id="ewww-delay-slider" style="width:50%"></div>
 
 
 
 
 
 
160
  </form>
161
  <div id="ewww-bulk-forms" style="float:none;">
162
- <p class="ewww-bulk-info"><?php echo esc_html( $selected_images_text ); ?><br />
163
- <?php esc_html_e( 'Previously optimized images will be skipped by default.', 'ewww-image-optimizer' ); ?></p>
164
  <form id="ewww-bulk-start" class="ewww-bulk-form" method="post" action="">
165
  <input type="submit" class="button-primary action" value="<?php echo esc_attr( $button_text ); ?>" />
166
  </form>
@@ -168,11 +174,11 @@ if ( ! class_exists( 'EWWW_Flag' ) ) {
168
  // If there was a previous operation, offer the option to reset the option in the db.
169
  if ( ! empty( $resume ) ) :
170
  ?>
171
- <p class="ewww-bulk-info"><?php esc_html_e( 'If you would like to start over again, press the Reset Status button to reset the bulk operation status.', 'ewww-image-optimizer' ); ?></p>
172
  <form method="post" class="ewww-bulk-form" action="">
173
  <?php wp_nonce_field( 'ewww-image-optimizer-bulk', 'ewww_wpnonce' ); ?>
174
  <input type="hidden" name="ewww_reset" value="1">
175
- <button id="bulk-reset" type="submit" class="button-secondary action"><?php esc_html_e( 'Reset Status', 'ewww-image-optimizer' ); ?></button>
176
  </form>
177
  <?php
178
  endif;
@@ -773,7 +779,7 @@ if ( ! class_exists( 'EWWW_Flag' ) ) {
773
  }
774
  break;
775
  case 'image/png':
776
- if ( ! EWWW_IMAGE_OPTIMIZER_PNGOUT && ! EWWW_IMAGE_OPTIMIZER_OPTIPNG && ! $skip['optipng'] && ! $skip['pngout'] ) {
777
  /* translators: %s: name of a tool like jpegtran */
778
  echo '<div>' . sprintf( esc_html__( '%s is missing', 'ewww-image-optimizer' ), '<em>optipng/pngout</em>' ) . '</div></div>';
779
  return;
101
  return;
102
  }
103
  }
104
+ list( $fullsize_count, $resize_count ) = ewww_image_optimizer_count_optimized( 'flag' );
105
  // Bail-out if there aren't any images to optimize.
106
  if ( $fullsize_count < 1 ) {
107
  echo '<p>' . esc_html__( 'You do not appear to have uploaded any images yet.', 'ewww-image-optimizer' ) . '</p>';
114
  ewww_image_optimizer_cloud_verify();
115
  echo '<a id="ewww-bulk-credits-available" target="_blank" class="page-title-action" style="float:right;" href="https://ewww.io/my-account/">' . esc_html__( 'Image credits available:', 'ewww-image-optimizer' ) . ' ' . esc_html( ewww_image_optimizer_cloud_quota() ) . '</a>';
116
  }
117
+ echo '<div id="ewww-bulk-warning" class="ewww-bulk-info notice notice-warning"><p>' . esc_html__( 'Bulk Optimization will alter your original images and cannot be undone. Please be sure you have a backup of your images before proceeding.', 'ewww-image-optimizer' ) . '</p></div>';
118
  // Retrieve the value of the 'bulk resume' option and set the button text for the form to use.
119
  $resume = get_option( 'ewww_image_optimizer_bulk_flag_resume' );
120
  if ( empty( $resume ) ) {
124
  }
125
  $delay = ewww_image_optimizer_get_option( 'ewww_image_optimizer_delay' ) ? ewww_image_optimizer_get_option( 'ewww_image_optimizer_delay' ) : 0;
126
  /* translators: 1-4: number(s) of images */
127
+ $selected_images_text = sprintf( __( '%1$d images have been selected, with %2$d resized versions.', 'ewww-image-optimizer' ), $fullsize_count, $resize_count );
128
  ?>
129
  <div id="ewww-bulk-loading"></div>
130
  <div id="ewww-bulk-progressbar"></div>
131
  <div id="ewww-bulk-counter"></div>
132
  <form id="ewww-bulk-stop" style="display:none;" method="post" action="">
133
+ <br /><input type="submit" class="button-secondary action" value="<?php esc_attr_e( 'Stop Optimizing', 'ewww-image-optimizer' ); ?>" />
134
  </form>
135
  <div id="ewww-bulk-widgets" class="metabox-holder" style="display:none">
136
  <div class="meta-box-sortables">
154
  </div>
155
  </div>
156
  </div>
157
+ <form id="ewww-bulk-controls" class="ewww-bulk-form">
158
+ <p><label for="ewww-force" style="font-weight: bold"><?php esc_html_e( 'Force re-optimize', 'ewww-image-optimizer' ); ?></label><?php ewwwio_help_link( 'https://docs.ewww.io/article/65-force-re-optimization', '5bb640a7042863158cc711cd' ); ?>
159
+ &emsp;<input type="checkbox" idp="ewww-force" name="ewww-force">
160
+ &nbsp;<?php esc_html_e( 'Previously optimized images will be skipped by default, check this box before scanning to override.', 'ewww-image-optimizer' ); ?>
161
+ &nbsp;<a href="tools.php?page=ewww-image-optimizer-tools"><?php esc_html_e( 'View optimization history.', 'ewww-image-optimizer' ); ?></a>
162
+ </p>
163
+ <p>
164
+ <label for="ewww-delay" style="font-weight: bold"><?php esc_html_e( 'Pause between images', 'ewww-image-optimizer' ); ?></label>&emsp;<input type="text" id="ewww-delay" name="ewww-delay" value="<?php echo (int) $delay; ?>"> <?php esc_html_e( 'in seconds, 0 = disabled', 'ewww-image-optimizer' ); ?>
165
+ </p>
166
+ <div id="ewww-delay-slider"></div>
167
  </form>
168
  <div id="ewww-bulk-forms" style="float:none;">
169
+ <p class="ewww-bulk-info"><?php echo esc_html( $selected_images_text ); ?></p>
 
170
  <form id="ewww-bulk-start" class="ewww-bulk-form" method="post" action="">
171
  <input type="submit" class="button-primary action" value="<?php echo esc_attr( $button_text ); ?>" />
172
  </form>
174
  // If there was a previous operation, offer the option to reset the option in the db.
175
  if ( ! empty( $resume ) ) :
176
  ?>
177
+ <p class="ewww-bulk-info" style="margin-top:3em;"><?php esc_html_e( 'Would you like clear the queue and start over?', 'ewww-image-optimizer' ); ?></p>
178
  <form method="post" class="ewww-bulk-form" action="">
179
  <?php wp_nonce_field( 'ewww-image-optimizer-bulk', 'ewww_wpnonce' ); ?>
180
  <input type="hidden" name="ewww_reset" value="1">
181
+ <button id="bulk-reset" type="submit" class="button-secondary action"><?php esc_html_e( 'Clear Queue', 'ewww-image-optimizer' ); ?></button>
182
  </form>
183
  <?php
184
  endif;
779
  }
780
  break;
781
  case 'image/png':
782
+ if ( ( ! $skip['optipng'] && ! EWWW_IMAGE_OPTIMIZER_OPTIPNG ) || ( ! $skip['pngout'] && ! EWWW_IMAGE_OPTIMIZER_PNGOUT ) ) {
783
  /* translators: %s: name of a tool like jpegtran */
784
  echo '<div>' . sprintf( esc_html__( '%s is missing', 'ewww-image-optimizer' ), '<em>optipng/pngout</em>' ) . '</div></div>';
785
  return;
classes/class-ewww-nextcellent.php CHANGED
@@ -74,7 +74,6 @@ if ( ! class_exists( 'EWWW_Nextcellent' ) ) {
74
  * Optimizes a new image from the queue.
75
  *
76
  * @global object $ewww_image Contains more information about the image currently being processed.
77
- * @global object $nggdb
78
  *
79
  * @param int $id The ID number of the image.
80
  * @param array $meta The image metadata.
@@ -87,9 +86,6 @@ if ( ! class_exists( 'EWWW_Nextcellent' ) ) {
87
  $ewww_image->resize = 'full';
88
  // Run the optimizer on the current image.
89
  $fres = ewww_image_optimizer( $file_path, 2, false, false, true );
90
- // Update the metadata for the optimized image.
91
- global $nggdb;
92
- $nggdb->update_image_meta( $id, array( 'ewww_image_optimizer' => $fres[1] ) );
93
  }
94
 
95
  /**
@@ -115,8 +111,6 @@ if ( ! class_exists( 'EWWW_Nextcellent' ) ) {
115
  $ewww_image->resize = 'full';
116
  // Run the optimizer on the current image.
117
  $res = ewww_image_optimizer( ABSPATH . $file_path, 2, false, false, true );
118
- // Update the metadata for the optimized image.
119
- nggdb::update_image_meta( $image['id'], array( 'ewww_image_optimizer' => $res[1] ) );
120
  }
121
  }
122
 
@@ -256,9 +250,6 @@ if ( ! class_exists( 'EWWW_Nextcellent' ) ) {
256
  $ewww_image->resize = 'full';
257
  // Run the optimizer on the current image.
258
  $fres = ewww_image_optimizer( $file_path, 2, false, false, true );
259
- // Update the metadata for the optimized image.
260
- global $nggdb;
261
- $nggdb->update_image_meta( $id, array( 'ewww_image_optimizer' => $fres[1] ) );
262
  // Get the filepath of the thumbnail image.
263
  $thumb_path = $meta->image->thumbPath;
264
  $ewww_image = new EWWW_Image( $id, 'nextcell', $thumb_path );
@@ -617,8 +608,6 @@ if ( ! class_exists( 'EWWW_Nextcellent' ) ) {
617
  } else {
618
  $output['new_nonce'] = '';
619
  }
620
- // Need this file to work with metadata.
621
- require_once( WP_CONTENT_DIR . '/plugins/nextcellent-gallery-nextgen-legacy/lib/meta.php' );
622
  // Find out what time we started, in microseconds.
623
  $started = microtime( true );
624
  // Get the list of attachments remaining from the db.
74
  * Optimizes a new image from the queue.
75
  *
76
  * @global object $ewww_image Contains more information about the image currently being processed.
 
77
  *
78
  * @param int $id The ID number of the image.
79
  * @param array $meta The image metadata.
86
  $ewww_image->resize = 'full';
87
  // Run the optimizer on the current image.
88
  $fres = ewww_image_optimizer( $file_path, 2, false, false, true );
 
 
 
89
  }
90
 
91
  /**
111
  $ewww_image->resize = 'full';
112
  // Run the optimizer on the current image.
113
  $res = ewww_image_optimizer( ABSPATH . $file_path, 2, false, false, true );
 
 
114
  }
115
  }
116
 
250
  $ewww_image->resize = 'full';
251
  // Run the optimizer on the current image.
252
  $fres = ewww_image_optimizer( $file_path, 2, false, false, true );
 
 
 
253
  // Get the filepath of the thumbnail image.
254
  $thumb_path = $meta->image->thumbPath;
255
  $ewww_image = new EWWW_Image( $id, 'nextcell', $thumb_path );
608
  } else {
609
  $output['new_nonce'] = '';
610
  }
 
 
611
  // Find out what time we started, in microseconds.
612
  $started = microtime( true );
613
  // Get the list of attachments remaining from the db.
classes/class-ewww-nextgen.php CHANGED
@@ -17,6 +17,14 @@ if ( ! class_exists( 'EWWW_Nextgen' ) ) {
17
  * managing galleries.
18
  */
19
  class EWWW_Nextgen {
 
 
 
 
 
 
 
 
20
  /**
21
  * Initializes the nextgen integration functions.
22
  */
@@ -114,7 +122,7 @@ if ( ! class_exists( 'EWWW_Nextgen' ) ) {
114
  function maybe_get_more_sizes( $sizes, $meta ) {
115
  if ( 2 === count( $sizes ) && ewww_image_optimizer_iterable( $meta ) ) {
116
  foreach ( $meta as $meta_key => $meta_val ) {
117
- if ( 'backup' !== $meta_key && is_array( $meta_val ) && isset( $meta_val['width'] ) ) {
118
  $sizes[] = $meta_key;
119
  }
120
  }
@@ -174,6 +182,7 @@ if ( ! class_exists( 'EWWW_Nextgen' ) ) {
174
  $storage = $registry->get_utility( 'I_Gallery_Storage' );
175
  }
176
  global $ewww_image;
 
177
  // Find the image id.
178
  if ( is_array( $image ) ) {
179
  $image_id = $image['id'];
@@ -204,17 +213,9 @@ if ( ! class_exists( 'EWWW_Nextgen' ) ) {
204
  // Optimize the image and grab the results.
205
  $res = ewww_image_optimizer( $file_path, 2, false, false, $full_size );
206
  ewwwio_debug_message( "results {$res[1]}" );
207
- // Only if we're dealing with the full-size original.
208
- if ( 'full' === $size ) {
209
- // Update the metadata for the optimized image.
210
- $image->meta_data['ewww_image_optimizer'] = $res[1];
211
- } else {
212
- $image->meta_data[ $size ]['ewww_image_optimizer'] = $res[1];
213
- }
214
  }
215
  }
216
- ewwwio_debug_message( 'storing results for image' );
217
- nggdb::update_image_meta( $image_id, $image->meta_data );
218
  return $image;
219
  }
220
 
@@ -462,7 +463,7 @@ if ( ! class_exists( 'EWWW_Nextgen' ) ) {
462
  break;
463
  case 'image/png':
464
  // If the PNG tools are missing, tell the user.
465
- if ( ! EWWW_IMAGE_OPTIMIZER_PNGOUT && ! EWWW_IMAGE_OPTIMIZER_OPTIPNG && ! $skip['optipng'] && ! $skip['pngout'] ) {
466
  /* translators: %s: name of a tool like jpegtran */
467
  $msg = '<div>' . sprintf( esc_html__( '%s is missing', 'ewww-image-optimizer' ), '<em>optipng/pngout</em>' ) . '</div>';
468
  }
@@ -623,7 +624,7 @@ if ( ! class_exists( 'EWWW_Nextgen' ) ) {
623
  return;
624
  }
625
  }
626
- list( $fullsize_count, $unoptimized_count, $resize_count, $unoptimized_resize_count ) = ewww_image_optimizer_count_optimized( 'ngg' );
627
  // Make sure there are some attachments to process.
628
  if ( $fullsize_count < 1 ) {
629
  echo '<p>' . esc_html__( 'You do not appear to have uploaded any images yet.', 'ewww-image-optimizer' ) . '</p>';
@@ -637,6 +638,7 @@ if ( ! class_exists( 'EWWW_Nextgen' ) ) {
637
  ewww_image_optimizer_cloud_verify();
638
  echo '<a id="ewww-bulk-credits-available" target="_blank" class="page-title-action" style="float:right;" href="https://ewww.io/my-account/">' . esc_html__( 'Image credits available:', 'ewww-image-optimizer' ) . ' ' . esc_html( ewww_image_optimizer_cloud_quota() ) . '</a>';
639
  }
 
640
  // Retrieve the value of the 'bulk resume' option and set the button text for the form to use.
641
  $resume = get_option( 'ewww_image_optimizer_bulk_ngg_resume' );
642
  if ( empty( $resume ) ) {
@@ -646,7 +648,7 @@ if ( ! class_exists( 'EWWW_Nextgen' ) ) {
646
  }
647
  $delay = ewww_image_optimizer_get_option( 'ewww_image_optimizer_delay' ) ? ewww_image_optimizer_get_option( 'ewww_image_optimizer_delay' ) : 0;
648
  /* translators: 1-4: number(s) of images */
649
- $selected_images_text = sprintf( __( '%1$d images have been selected (%2$d unoptimized), with %3$d resizes (%4$d unoptimized).', 'ewww-image-optimizer' ), $fullsize_count, $unoptimized_count, $resize_count, $unoptimized_resize_count );
650
  ?>
651
  <div id="ewww-bulk-loading"></div>
652
  <div id="ewww-bulk-progressbar"></div>
@@ -676,26 +678,31 @@ if ( ! class_exists( 'EWWW_Nextgen' ) ) {
676
  </div>
677
  </div>
678
  </div>
679
- <form class="ewww-bulk-form">
680
- <p><label for="ewww-force" style="font-weight: bold"><?php esc_html_e( 'Force re-optimize', 'ewww-image-optimizer' ); ?></label>&emsp;<input type="checkbox" id="ewww-force" name="ewww-force"></p>
681
- <p><label for="ewww-delay" style="font-weight: bold"><?php esc_html_e( 'Choose how long to pause between images (in seconds, 0 = disabled)', 'ewww-image-optimizer' ); ?></label>&emsp;<input type="text" id="ewww-delay" name="ewww-delay" value="<?php echo (int) $delay; ?>"></p>
682
- <div id="ewww-delay-slider" style="width:50%"></div>
 
 
 
 
 
 
683
  </form>
684
  <div id="ewww-bulk-forms">
685
- <p class="ewww-bulk-info"><?php echo esc_html( $selected_images_text ); ?><br />
686
- <?php esc_html_e( 'Previously optimized images will be skipped by default.', 'ewww-image-optimizer' ); ?></p>
687
- <form id="ewww-bulk-start" class="ewww-bulk-form" method="post" action="">
688
- <input type="submit" class="button-primary action" value="<?php echo esc_attr( $button_text ); ?>" />
689
- </form>
690
  <?php
691
  // If there is a previous bulk operation to resume, give the user the option to reset the resume flag.
692
  if ( ! empty( $resume ) ) {
693
  ?>
694
- <p class="ewww-bulk-info"><?php esc_html_e( 'If you would like to start over again, press the Reset Status button to reset the bulk operation status.', 'ewww-image-optimizer' ); ?></p>
695
  <form id="ewww-bulk-reset" class="ewww-bulk-form" method="post" action="">
696
  <?php wp_nonce_field( 'ewww-image-optimizer-bulk-reset', 'ewww_wpnonce' ); ?>
697
  <input type="hidden" name="ewww_reset" value="1">
698
- <input type="submit" class="button-secondary action" value="<?php esc_attr_e( 'Reset Status', 'ewww-image-optimizer' ); ?>" />
699
  </form>
700
  <?php
701
  }
@@ -934,25 +941,23 @@ if ( ! class_exists( 'EWWW_Nextgen' ) ) {
934
  }
935
  // Output the results of the optimization.
936
  $output['results'] = sprintf( '<p>' . esc_html__( 'Optimized image:', 'ewww-image-optimizer' ) . ' <strong>%s</strong><br>', esc_html( basename( $storage->object->get_image_abspath( $image, 'full' ) ) ) );
937
- // Get an array of sizes available for the $image.
938
- $sizes = $storage->get_image_sizes( $image );
939
- $sizes = $this->maybe_get_more_sizes( $sizes, $image->meta_data );
940
- if ( ewww_image_optimizer_iterable( $sizes ) ) {
941
- foreach ( $sizes as $size ) {
942
  if ( 'backup' === $size ) {
943
  continue;
944
  } elseif ( 'full' === $size ) {
945
  /* Translators: %s: The compression results/savings */
946
- $output['results'] .= sprintf( esc_html__( 'Full size - %s', 'ewww-image-optimizer' ) . '<br>', esc_html( $image->meta_data['ewww_image_optimizer'] ) );
947
  } elseif ( 'thumbnail' === $size ) {
948
  // Output the results of the thumb optimization.
949
  /* Translators: %s: The compression results/savings */
950
- $output['results'] .= sprintf( esc_html__( 'Thumbnail - %s', 'ewww-image-optimizer' ) . '<br>', esc_html( $image->meta_data[ $size ]['ewww_image_optimizer'] ) );
951
  } else {
952
  // Output savings for any other sizes, if they ever exist...
953
- $output['results'] .= ucfirst( $size ) . ' - ' . esc_html( $image->meta_data[ $size ]['ewww_image_optimizer'] ) . '<br>';
954
  }
955
  }
 
956
  }
957
  // Output how much time we spent.
958
  $elapsed = microtime( true ) - $started;
17
  * managing galleries.
18
  */
19
  class EWWW_Nextgen {
20
+ /**
21
+ * Stores results for the bulk process.
22
+ *
23
+ * @access private
24
+ * @var array $bulk_sizes
25
+ */
26
+ private $bulk_sizes = array();
27
+
28
  /**
29
  * Initializes the nextgen integration functions.
30
  */
122
  function maybe_get_more_sizes( $sizes, $meta ) {
123
  if ( 2 === count( $sizes ) && ewww_image_optimizer_iterable( $meta ) ) {
124
  foreach ( $meta as $meta_key => $meta_val ) {
125
+ if ( 'backup' !== $meta_key && is_array( $meta_val ) && isset( $meta_val['width'] ) && ! in_array( $meta_key, $sizes, true ) ) {
126
  $sizes[] = $meta_key;
127
  }
128
  }
182
  $storage = $registry->get_utility( 'I_Gallery_Storage' );
183
  }
184
  global $ewww_image;
185
+ $this->bulk_sizes = array();
186
  // Find the image id.
187
  if ( is_array( $image ) ) {
188
  $image_id = $image['id'];
213
  // Optimize the image and grab the results.
214
  $res = ewww_image_optimizer( $file_path, 2, false, false, $full_size );
215
  ewwwio_debug_message( "results {$res[1]}" );
216
+ $this->bulk_sizes[ $size ] = $res[1];
 
 
 
 
 
 
217
  }
218
  }
 
 
219
  return $image;
220
  }
221
 
463
  break;
464
  case 'image/png':
465
  // If the PNG tools are missing, tell the user.
466
+ if ( ( ! $skip['optipng'] && ! EWWW_IMAGE_OPTIMIZER_OPTIPNG ) || ( ! $skip['pngout'] && ! EWWW_IMAGE_OPTIMIZER_PNGOUT ) ) {
467
  /* translators: %s: name of a tool like jpegtran */
468
  $msg = '<div>' . sprintf( esc_html__( '%s is missing', 'ewww-image-optimizer' ), '<em>optipng/pngout</em>' ) . '</div>';
469
  }
624
  return;
625
  }
626
  }
627
+ list( $fullsize_count, $resize_count ) = ewww_image_optimizer_count_optimized( 'ngg' );
628
  // Make sure there are some attachments to process.
629
  if ( $fullsize_count < 1 ) {
630
  echo '<p>' . esc_html__( 'You do not appear to have uploaded any images yet.', 'ewww-image-optimizer' ) . '</p>';
638
  ewww_image_optimizer_cloud_verify();
639
  echo '<a id="ewww-bulk-credits-available" target="_blank" class="page-title-action" style="float:right;" href="https://ewww.io/my-account/">' . esc_html__( 'Image credits available:', 'ewww-image-optimizer' ) . ' ' . esc_html( ewww_image_optimizer_cloud_quota() ) . '</a>';
640
  }
641
+ echo '<div id="ewww-bulk-warning" class="ewww-bulk-info notice notice-warning"><p>' . esc_html__( 'Bulk Optimization will alter your original images and cannot be undone. Please be sure you have a backup of your images before proceeding.', 'ewww-image-optimizer' ) . '</p></div>';
642
  // Retrieve the value of the 'bulk resume' option and set the button text for the form to use.
643
  $resume = get_option( 'ewww_image_optimizer_bulk_ngg_resume' );
644
  if ( empty( $resume ) ) {
648
  }
649
  $delay = ewww_image_optimizer_get_option( 'ewww_image_optimizer_delay' ) ? ewww_image_optimizer_get_option( 'ewww_image_optimizer_delay' ) : 0;
650
  /* translators: 1-4: number(s) of images */
651
+ $selected_images_text = sprintf( __( '%1$d images have been selected, with %2$d resized versions.', 'ewww-image-optimizer' ), $fullsize_count, $resize_count );
652
  ?>
653
  <div id="ewww-bulk-loading"></div>
654
  <div id="ewww-bulk-progressbar"></div>
678
  </div>
679
  </div>
680
  </div>
681
+ <form id="ewww-bulk-controls" class="ewww-bulk-form">
682
+ <p><label for="ewww-force" style="font-weight: bold"><?php esc_html_e( 'Force re-optimize', 'ewww-image-optimizer' ); ?></label><?php ewwwio_help_link( 'https://docs.ewww.io/article/65-force-re-optimization', '5bb640a7042863158cc711cd' ); ?>
683
+ &emsp;<input type="checkbox" id="ewww-force" name="ewww-force">
684
+ &nbsp;<?php esc_html_e( 'Previously optimized images will be skipped by default, check this box before scanning to override.', 'ewww-image-optimizer' ); ?>
685
+ &nbsp;<a href="tools.php?page=ewww-image-optimizer-tools"><?php esc_html_e( 'View optimization history.', 'ewww-image-optimizer' ); ?></a>
686
+ </p>
687
+ <p>
688
+ <label for="ewww-delay" style="font-weight: bold"><?php esc_html_e( 'Pause between images', 'ewww-image-optimizer' ); ?></label>&emsp;<input type="text" id="ewww-delay" name="ewww-delay" value="<?php echo (int) $delay; ?>"> <?php esc_html_e( 'in seconds, 0 = disabled', 'ewww-image-optimmizer' ); ?>
689
+ </p>
690
+ <div id="ewww-delay-slider"></div>
691
  </form>
692
  <div id="ewww-bulk-forms">
693
+ <p class="ewww-bulk-info"><?php echo esc_html( $selected_images_text ); ?></p>
694
+ <form id="ewww-bulk-start" class="ewww-bulk-form" method="post" action="">
695
+ <input type="submit" class="button-primary action" value="<?php echo esc_attr( $button_text ); ?>" />
696
+ </form>
 
697
  <?php
698
  // If there is a previous bulk operation to resume, give the user the option to reset the resume flag.
699
  if ( ! empty( $resume ) ) {
700
  ?>
701
+ <p class="ewww-bulk-info" style="margin-top:3em;"><?php esc_html_e( 'Would like to clear the queue and start over?', 'ewww-image-optimizer' ); ?></p>
702
  <form id="ewww-bulk-reset" class="ewww-bulk-form" method="post" action="">
703
  <?php wp_nonce_field( 'ewww-image-optimizer-bulk-reset', 'ewww_wpnonce' ); ?>
704
  <input type="hidden" name="ewww_reset" value="1">
705
+ <input type="submit" class="button-secondary action" value="<?php esc_attr_e( 'Clear Queue', 'ewww-image-optimizer' ); ?>" />
706
  </form>
707
  <?php
708
  }
941
  }
942
  // Output the results of the optimization.
943
  $output['results'] = sprintf( '<p>' . esc_html__( 'Optimized image:', 'ewww-image-optimizer' ) . ' <strong>%s</strong><br>', esc_html( basename( $storage->object->get_image_abspath( $image, 'full' ) ) ) );
944
+ if ( ewww_image_optimizer_iterable( $this->bulk_sizes ) ) {
945
+ foreach ( $this->bulk_sizes as $size => $results_msg ) {
 
 
 
946
  if ( 'backup' === $size ) {
947
  continue;
948
  } elseif ( 'full' === $size ) {
949
  /* Translators: %s: The compression results/savings */
950
+ $output['results'] .= sprintf( esc_html__( 'Full size - %s', 'ewww-image-optimizer' ) . '<br>', esc_html( $results_msg ) );
951
  } elseif ( 'thumbnail' === $size ) {
952
  // Output the results of the thumb optimization.
953
  /* Translators: %s: The compression results/savings */
954
+ $output['results'] .= sprintf( esc_html__( 'Thumbnail - %s', 'ewww-image-optimizer' ) . '<br>', esc_html( $results_msg ) );
955
  } else {
956
  // Output savings for any other sizes, if they ever exist...
957
+ $output['results'] .= ucfirst( $size ) . ' - ' . esc_html( $results_msg ) . '<br>';
958
  }
959
  }
960
+ $this->bulk_sizes = array();
961
  }
962
  // Output how much time we spent.
963
  $elapsed = microtime( true ) - $started;
classes/class-exactdn.php CHANGED
@@ -115,6 +115,10 @@ if ( ! class_exists( 'ExactDN' ) ) {
115
  return 'you are doing it wrong';
116
  }
117
 
 
 
 
 
118
  // Make sure we have an ExactDN domain to use.
119
  if ( ! $this->setup() ) {
120
  return;
@@ -132,6 +136,9 @@ if ( ! class_exists( 'ExactDN' ) ) {
132
  $uri = add_query_arg( null, null );
133
  $this->debug_message( "request uri is $uri" );
134
 
 
 
 
135
  /**
136
  * Allow pre-empting the parsers by page.
137
  *
@@ -1701,8 +1708,8 @@ if ( ! class_exists( 'ExactDN' ) ) {
1701
  );
1702
  } elseif ( is_array( $size ) ) {
1703
  // Pull width and height values from the provided array, if possible.
1704
- $width = isset( $size[0] ) ? (int) $size[0] : false;
1705
- $height = isset( $size[1] ) ? (int) $size[1] : false;
1706
 
1707
  // Don't bother if necessary parameters aren't passed.
1708
  if ( ! $width || ! $height ) {
@@ -1907,8 +1914,8 @@ if ( ! class_exists( 'ExactDN' ) ) {
1907
  $constrained_size = wp_constrain_dimensions( $fullwidth, $fullheight, $reqwidth );
1908
  $expected_size = array( $reqwidth, $reqheight );
1909
 
1910
- $this->debug_message( $constrained_size[0] );
1911
- $this->debug_message( $constrained_size[1] );
1912
  if ( abs( $constrained_size[0] - $expected_size[0] ) <= 1 && abs( $constrained_size[1] - $expected_size[1] ) <= 1 ) {
1913
  $this->debug_message( 'soft cropping' );
1914
  $crop = 'soft';
115
  return 'you are doing it wrong';
116
  }
117
 
118
+ // Bail out on customizer.
119
+ if ( is_customize_preview() ) {
120
+ return;
121
+ }
122
  // Make sure we have an ExactDN domain to use.
123
  if ( ! $this->setup() ) {
124
  return;
136
  $uri = add_query_arg( null, null );
137
  $this->debug_message( "request uri is $uri" );
138
 
139
+ if ( '/robots.txt' === $uri ) {
140
+ return;
141
+ }
142
  /**
143
  * Allow pre-empting the parsers by page.
144
  *
1708
  );
1709
  } elseif ( is_array( $size ) ) {
1710
  // Pull width and height values from the provided array, if possible.
1711
+ $width = isset( $size[0] ) && $size[0] < 9999 ? (int) $size[0] : false;
1712
+ $height = isset( $size[1] ) && $size[1] < 9999 ? (int) $size[1] : false;
1713
 
1714
  // Don't bother if necessary parameters aren't passed.
1715
  if ( ! $width || ! $height ) {
1914
  $constrained_size = wp_constrain_dimensions( $fullwidth, $fullheight, $reqwidth );
1915
  $expected_size = array( $reqwidth, $reqheight );
1916
 
1917
+ $this->debug_message( 'constrained w: ' . $constrained_size[0] );
1918
+ $this->debug_message( 'constrained h: ' . $constrained_size[1] );
1919
  if ( abs( $constrained_size[0] - $expected_size[0] ) <= 1 && abs( $constrained_size[1] - $expected_size[1] ) <= 1 ) {
1920
  $this->debug_message( 'soft cropping' );
1921
  $crop = 'soft';
common.php CHANGED
@@ -14,7 +14,7 @@ if ( ! defined( 'ABSPATH' ) ) {
14
  exit;
15
  }
16
 
17
- define( 'EWWW_IMAGE_OPTIMIZER_VERSION', '550' );
18
 
19
  // Initialize a couple globals.
20
  $eio_debug = '';
@@ -539,6 +539,7 @@ function ewww_image_optimizer_init() {
539
  }
540
  }
541
  if ( ewww_image_optimizer_iterable( $active_plugins ) ) {
 
542
  foreach ( $active_plugins as $active_plugin ) {
543
  if ( strpos( $active_plugin, '/nggallery.php' ) || strpos( $active_plugin, '\nggallery.php' ) ) {
544
  $ngg = ewww_image_optimizer_get_plugin_version( trailingslashit( WP_PLUGIN_DIR ) . $active_plugin );
@@ -4143,15 +4144,15 @@ function ewww_image_optimizer_cloud_optimizer( $file, $type, $convert = false, $
4143
  ewww_image_optimizer_debug_log();
4144
  }
4145
  $ewww_status = get_transient( 'ewww_image_optimizer_cloud_status' );
4146
- $started = microtime( true );
4147
  if ( preg_match( '/exceeded/', $ewww_status ) ) {
 
4148
  if ( ! ewww_image_optimizer_cloud_verify() ) {
4149
  return array( $file, false, 'key verification failed', 0, '' );
4150
  }
 
 
 
4151
  }
4152
- // Calculate how much time has elapsed since we started.
4153
- $elapsed = microtime( true ) - $started;
4154
- ewwwio_debug_message( "cloud verify took $elapsed seconds" );
4155
  $ewww_status = get_transient( 'ewww_image_optimizer_cloud_status' );
4156
  if ( ( ! empty( $ewww_status ) && preg_match( '/exceeded/', $ewww_status ) ) || ewww_image_optimizer_get_option( 'ewww_image_optimizer_cloud_exceeded' ) > time() ) {
4157
  ewwwio_debug_message( 'license exceeded, image not processed' );
@@ -4248,9 +4249,10 @@ function ewww_image_optimizer_cloud_optimizer( $file, $type, $convert = false, $
4248
  ewwwio_debug_message( "webp: $webp" );
4249
  ewwwio_debug_message( "jpg fill: $jpg_fill" );
4250
  ewwwio_debug_message( "jpg quality: $jpg_quality" );
4251
- $api_key = ewww_image_optimizer_get_option( 'ewww_image_optimizer_cloud_key' );
4252
- if ( empty( $api_key ) ) {
4253
- return array( $file, false, 'key verification failed', 0, '' );
 
4254
  }
4255
  $url = 'http://optimize.exactlywww.com/v2/';
4256
  $ssl = wp_http_supports( array( 'ssl' ) );
@@ -6014,7 +6016,7 @@ function ewww_image_optimizer_autoconvert( $file ) {
6014
  ewwwio_debug_message( 'not a large PNG, skipping' );
6015
  return;
6016
  }
6017
- if ( ewww_image_optimizer_png_alpha( $file ) && ! ewww_image_optimizer_jpg_background() ) {
6018
  ewwwio_debug_message( 'alpha detected, skipping' );
6019
  return;
6020
  }
@@ -7868,7 +7870,7 @@ function ewww_image_optimizer_custom_column( $column_name, $id, $meta = null ) {
7868
  // Retrieve the metadata.
7869
  $meta = wp_get_attachment_metadata( $id );
7870
  }
7871
- echo '<div id="ewww-media-status-' . (int) $id . '">';
7872
  if ( ewww_image_optimizer_get_option( 'ewww_image_optimizer_debug' ) && ewww_image_optimizer_function_exists( 'print_r' ) ) {
7873
  $print_meta = print_r( $meta, true );
7874
  $print_meta = preg_replace( array( '/ /', '/\n+/' ), array( '&nbsp;', '<br />' ), $print_meta );
@@ -7952,12 +7954,18 @@ function ewww_image_optimizer_custom_column( $column_name, $id, $meta = null ) {
7952
  break;
7953
  case 'image/png':
7954
  // If pngout and optipng are missing and should not be skipped.
7955
- if ( ! $skip['optipng'] && ! $skip['pngout'] && ! EWWW_IMAGE_OPTIMIZER_PNGOUT && ! EWWW_IMAGE_OPTIMIZER_OPTIPNG ) {
7956
  $msg = '<div>' . sprintf(
7957
  /* translators: %s: name of a tool like jpegtran */
7958
  __( '%s is missing', 'ewww-image-optimizer' ),
7959
  '<em>optipng</em>'
7960
  ) . '</div>';
 
 
 
 
 
 
7961
  } else {
7962
  $convert_link = __( 'PNG to JPG', 'ewww-image-optimizer' );
7963
  $convert_desc = __( 'WARNING: This is not a lossless conversion and requires GD or ImageMagick. JPG is much better than PNG for photographic use because it compresses the image and discards data. Transparent images will only be converted if a background color has been set.', 'ewww-image-optimizer' );
@@ -7971,6 +7979,12 @@ function ewww_image_optimizer_custom_column( $column_name, $id, $meta = null ) {
7971
  __( '%s is missing', 'ewww-image-optimizer' ),
7972
  '<em>gifsicle</em>'
7973
  ) . '</div>';
 
 
 
 
 
 
7974
  } else {
7975
  $convert_link = __( 'GIF to PNG', 'ewww-image-optimizer' );
7976
  $convert_desc = __( 'PNG is generally better than GIF, but does not support animation. Animated images will not be converted.', 'ewww-image-optimizer' );
@@ -8004,9 +8018,10 @@ function ewww_image_optimizer_custom_column( $column_name, $id, $meta = null ) {
8004
  $backup_available = false;
8005
  $file_parts = pathinfo( $file_path );
8006
  $basename = $file_parts['filename'];
 
8007
  // If necessary, use get_post_meta( $post_id, '_wp_attachment_backup_sizes', true ); to only use basename for edited attachments, but that requires extra queries, so kiss for now.
8008
  if ( $ewww_cdn ) {
8009
- if ( ewww_image_optimizer_image_is_pending( $id, 'media-async' ) ) {
8010
  echo '<div>' . esc_html__( 'In Progress', 'ewww-image-optimizer' ) . '</div>';
8011
  $in_progress = true;
8012
  }
@@ -8019,19 +8034,25 @@ function ewww_image_optimizer_custom_column( $column_name, $id, $meta = null ) {
8019
  if ( $migrated ) {
8020
  $optimized_images = $wpdb->get_results( $wpdb->prepare( "SELECT image_size,orig_size,resize,converted,level,backup,updated FROM $wpdb->ewwwio_images WHERE attachment_id = %d AND gallery = 'media' AND image_size <> 0 ORDER BY orig_size DESC", $id ), ARRAY_A );
8021
  }
 
 
 
 
 
 
8022
  }
8023
  // If optimizer data exists in the db.
8024
  if ( ! empty( $optimized_images ) ) {
8025
- list( $detail_output, $converted, $backup_available ) = ewww_image_optimizer_custom_column_results( $id, $optimized_images );
8026
  echo wp_kses_post( $detail_output );
8027
  // Output the optimizer actions.
8028
  if ( current_user_can( apply_filters( 'ewww_image_optimizer_manual_permissions', '' ) ) ) {
8029
  // Display a link to re-optimize manually.
8030
  echo '<div>' . sprintf(
8031
  '<a class="ewww-manual-optimize" data-id="%1$d" data-nonce="%2$s" href="%3$s">%4$s</a>',
8032
- (int) $id,
8033
  esc_attr( $ewww_manual_nonce ),
8034
- esc_url( admin_url( "admin.php?action=ewww_image_optimizer_manual_optimize&ewww_manual_nonce=$ewww_manual_nonce&ewww_force=1&ewww_attachment_ID=$id" ) ),
8035
  ( ewww_image_optimizer_restore_possible( $optimized_images, $compression_level ) ? esc_html__( 'Restore & Re-optimize', 'ewww-image-optimizer' ) : esc_html__( 'Re-optimize', 'ewww-image-optimizer' ) )
8036
  ) .
8037
  wp_kses_post( ewww_image_optimizer_variant_level_notice( $optimized_images, $compression_level ) ) .
@@ -8040,9 +8061,9 @@ function ewww_image_optimizer_custom_column( $column_name, $id, $meta = null ) {
8040
  if ( $backup_available && current_user_can( apply_filters( 'ewww_image_optimizer_manual_permissions', '' ) ) ) {
8041
  echo '<div>' . sprintf(
8042
  '<a class="ewww-manual-cloud-restore" data-id="%1$d" data-nonce="%2$s" href="%3$s">%4$s</a>',
8043
- (int) $id,
8044
  esc_attr( $ewww_manual_nonce ),
8045
- esc_url( admin_url( "admin.php?action=ewww_image_optimizer_manual_cloud_restore&ewww_manual_nonce=$ewww_manual_nonce&ewww_attachment_ID=$id" ) ),
8046
  esc_html__( 'Restore original', 'ewww-image-optimizer' )
8047
  ) . '</div>';
8048
  }
@@ -8063,9 +8084,9 @@ function ewww_image_optimizer_custom_column( $column_name, $id, $meta = null ) {
8063
  }
8064
  echo '<div>' . sprintf(
8065
  '<a class="ewww-manual-optimize" data-id="%1$d" data-nonce="%2$s" href="%3$s">%4$s</a>',
8066
- (int) $id,
8067
  esc_attr( $ewww_manual_nonce ),
8068
- esc_url( admin_url( "admin.php?action=ewww_image_optimizer_manual_optimize&ewww_manual_nonce=$ewww_manual_nonce&ewww_attachment_ID=$id" ) ),
8069
  esc_html__( 'Optimize now!', 'ewww-image-optimizer' )
8070
  ) .
8071
  '</div>';
@@ -8074,7 +8095,7 @@ function ewww_image_optimizer_custom_column( $column_name, $id, $meta = null ) {
8074
  return;
8075
  } // End if().
8076
  // End of output for CDN images.
8077
- if ( ewww_image_optimizer_image_is_pending( $id, 'media-async' ) ) {
8078
  echo '<div>' . esc_html__( 'In Progress', 'ewww-image-optimizer' ) . '</div>';
8079
  $in_progress = true;
8080
  }
@@ -8087,10 +8108,16 @@ function ewww_image_optimizer_custom_column( $column_name, $id, $meta = null ) {
8087
  if ( $migrated ) {
8088
  $optimized_images = $wpdb->get_results( $wpdb->prepare( "SELECT image_size,orig_size,resize,converted,level,backup,updated FROM $wpdb->ewwwio_images WHERE attachment_id = %d AND gallery = 'media' AND image_size <> 0 ORDER BY orig_size DESC", $id ), ARRAY_A );
8089
  }
 
 
 
 
 
 
8090
  }
8091
  // If optimizer data exists.
8092
  if ( ! empty( $optimized_images ) ) {
8093
- list( $detail_output, $converted, $backup_available ) = ewww_image_optimizer_custom_column_results( $id, $optimized_images );
8094
  echo wp_kses_post( $detail_output );
8095
 
8096
  // Link to webp upgrade script.
@@ -8113,19 +8140,19 @@ function ewww_image_optimizer_custom_column( $column_name, $id, $meta = null ) {
8113
  // Output a link to re-optimize manually.
8114
  echo '<div>' . sprintf(
8115
  '<a class="ewww-manual-optimize" data-id="%1$d" data-nonce="%2$s" href="%3$s">%4$s</a>',
8116
- (int) $id,
8117
  esc_attr( $ewww_manual_nonce ),
8118
- esc_url( admin_url( "admin.php?action=ewww_image_optimizer_manual_optimize&ewww_manual_nonce=$ewww_manual_nonce&ewww_force=1&ewww_attachment_ID=$id" ) ),
8119
  ( ewww_image_optimizer_restore_possible( $optimized_images, $compression_level ) ? esc_html__( 'Restore & Re-optimize', 'ewww-image-optimizer' ) : esc_html__( 'Re-optimize', 'ewww-image-optimizer' ) )
8120
  );
8121
  echo wp_kses_post( ewww_image_optimizer_variant_level_notice( $optimized_images, $compression_level ) );
8122
  if ( ! ewww_image_optimizer_get_option( 'ewww_image_optimizer_disable_convert_links' ) && 'ims_image' !== get_post_type( $id ) && ! empty( $convert_desc ) ) {
8123
  printf(
8124
  ' | <a class="ewww-manual-convert" data-id="%1$d" data-nonce="%2$s" title="%3$s" href="%4$s">%5$s</a>',
8125
- (int) $id,
8126
  esc_attr( $ewww_manual_nonce ),
8127
  esc_attr( $convert_desc ),
8128
- esc_url( admin_url( "admin.php?action=ewww_image_optimizer_manual_optimize&ewww_manual_nonce=$ewww_manual_nonce&ewww_attachment_ID=$id&ewww_convert=1&ewww_force=1" ) ),
8129
  esc_html( $convert_link )
8130
  );
8131
  }
@@ -8138,17 +8165,17 @@ function ewww_image_optimizer_custom_column( $column_name, $id, $meta = null ) {
8138
  if ( $restorable && current_user_can( apply_filters( 'ewww_image_optimizer_manual_permissions', '' ) ) ) {
8139
  echo '<div>' . sprintf(
8140
  '<a class="ewww-manual-restore" data-id="%1$d" data-nonce="%2$s" href="%3$s">%4$s</a>',
8141
- (int) $id,
8142
  esc_attr( $ewww_manual_nonce ),
8143
- esc_url( admin_url( "admin.php?action=ewww_image_optimizer_manual_restore&ewww_manual_nonce=$ewww_manual_nonce&ewww_attachment_ID=$id" ) ),
8144
  esc_html__( 'Restore original', 'ewww-image-optimizer' )
8145
  ) . '</div>';
8146
  } elseif ( $backup_available && current_user_can( apply_filters( 'ewww_image_optimizer_manual_permissions', '' ) ) ) {
8147
  echo '<div>' . sprintf(
8148
  '<a class="ewww-manual-cloud-restore" data-id="%1$d" data-nonce="%2$s" href="%3$s">%4$s</a>',
8149
- (int) $id,
8150
  esc_attr( $ewww_manual_nonce ),
8151
- esc_url( admin_url( "admin.php?action=ewww_image_optimizer_manual_cloud_restore&ewww_manual_nonce=$ewww_manual_nonce&ewww_attachment_ID=$id" ) ),
8152
  esc_html__( 'Restore original', 'ewww-image-optimizer' )
8153
  ) . '</div>';
8154
  }
@@ -8188,18 +8215,18 @@ function ewww_image_optimizer_custom_column( $column_name, $id, $meta = null ) {
8188
  // Give the user the option to optimize the image right now.
8189
  printf(
8190
  '<div><a class="ewww-manual-optimize" data-id="%1$d" data-nonce="%2$s" href="%3$s">%4$s</a>',
8191
- (int) $id,
8192
  esc_attr( $ewww_manual_nonce ),
8193
- esc_url( admin_url( "admin.php?action=ewww_image_optimizer_manual_optimize&ewww_manual_nonce=$ewww_manual_nonce&ewww_attachment_ID=$id" ) ),
8194
  esc_html__( 'Optimize now!', 'ewww-image-optimizer' )
8195
  );
8196
  if ( ! ewww_image_optimizer_get_option( 'ewww_image_optimizer_disable_convert_links' ) && 'ims_image' !== get_post_type( $id ) && ! empty( $convert_desc ) ) {
8197
  printf(
8198
  ' | <a class="ewww-manual-convert" data-id="%1$d" data-nonce="%2$s" title="%3$s" href="%4$s">%5$s</a>',
8199
- (int) $id,
8200
  esc_attr( $ewww_manual_nonce ),
8201
  esc_attr( $convert_desc ),
8202
- esc_url( admin_url( "admin.php?action=ewww_image_optimizer_manual_optimize&ewww_manual_nonce=$ewww_manual_nonce&ewww_attachment_ID=$id&ewww_convert=1&ewww_force=1" ) ),
8203
  esc_html( $convert_link )
8204
  );
8205
  }
@@ -8222,6 +8249,9 @@ function ewww_image_optimizer_restore_possible( $optimized_images, $compression_
8222
  if ( empty( $compression_level ) ) {
8223
  return '';
8224
  }
 
 
 
8225
  ewwwio_debug_message( '<b>' . __FUNCTION__ . '()</b>' );
8226
  foreach ( $optimized_images as $optimized_image ) {
8227
  if ( 'full' === $optimized_image['resize'] ) {
@@ -8379,6 +8409,68 @@ function ewww_image_optimizer_custom_column_results( $id, $optimized_images ) {
8379
  return array( $output, $converted, $backup_available );
8380
  }
8381
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
8382
  /**
8383
  * Removes optimization from metadata, because we store it all in the images table now.
8384
  *
@@ -9517,6 +9609,16 @@ function ewww_image_optimizer_options( $network = 'singlesite' ) {
9517
  $compress_recommendations = array();
9518
  $resize_recommendations = array();
9519
 
 
 
 
 
 
 
 
 
 
 
9520
  $verify_cloud = '';
9521
  if ( ewww_image_optimizer_get_option( 'ewww_image_optimizer_cloud_key' ) ) {
9522
  ewww_image_optimizer_set_option( 'ewww_image_optimizer_cloud_exceeded', 0 );
@@ -9526,12 +9628,12 @@ function ewww_image_optimizer_options( $network = 'singlesite' ) {
9526
  if ( ewww_image_optimizer_get_option( 'ewww_image_optimizer_jpg_level' ) > 20 ) {
9527
  $compress_score += 50;
9528
  } else {
9529
- $compress_recommendations[] = esc_html__( 'Enable premium compression for JPG images.', 'ewww-image-optimizer' );
9530
  }
9531
  if ( ewww_image_optimizer_get_option( 'ewww_image_optimizer_png_level' ) > 20 ) {
9532
  $compress_score += 20;
9533
  } else {
9534
- $compress_recommendations[] = esc_html__( 'Enable premium compression for PNG images.', 'ewww-image-optimizer' );
9535
  }
9536
  }
9537
  $disable_level = false;
@@ -9549,8 +9651,11 @@ function ewww_image_optimizer_options( $network = 'singlesite' ) {
9549
  update_option( 'ewww_image_optimizer_lazy_load', false );
9550
  update_option( 'ewww_image_optimizer_webp_for_cdn', false );
9551
  update_option( 'ewww_image_optimizer_picture_webp', false );
9552
- $compress_score += 80;
9553
- $resize_score += 50;
 
 
 
9554
  } elseif (
9555
  ( ! class_exists( 'Jetpack_Photon' ) || ! Jetpack::is_module_active( 'photon' ) ) &&
9556
  class_exists( 'ExactDN' ) &&
@@ -9564,12 +9669,12 @@ function ewww_image_optimizer_options( $network = 'singlesite' ) {
9564
  if ( ewww_image_optimizer_get_option( 'exactdn_lossy' ) ) {
9565
  $compress_score = 100;
9566
  } elseif ( ewww_image_optimizer_get_option( 'ewww_image_optimizer_jpg_level' ) < 30 ) {
9567
- $compress_recommendations[] = esc_html__( 'Enable premium compression.', 'ewww-image-optimizer' ) . ewwwio_get_help_link( 'https://docs.ewww.io/article/47-getting-more-from-exactdn', '59de6631042863379ddc953c' );
9568
  }
9569
  $exactdn_enabled = true;
9570
  }
9571
  } elseif ( ! ewww_image_optimizer_get_option( 'ewww_image_optimizer_exactdn' ) ) {
9572
- $resize_recommendations[] = esc_html__( 'Enable Easy IO for automatic resizing.', 'ewww-image-optimizer' ) . ewwwio_get_help_link( 'https://docs.ewww.io/article/44-introduction-to-exactdn', '59bc5ad6042863033a1ce370,5c0042892c7d3a31944e88a4' );
9573
  delete_option( 'ewww_image_optimizer_exactdn_domain' );
9574
  delete_option( 'ewww_image_optimizer_exactdn_plan_id' );
9575
  delete_option( 'ewww_image_optimizer_exactdn_failures' );
@@ -9603,13 +9708,13 @@ function ewww_image_optimizer_options( $network = 'singlesite' ) {
9603
  } elseif ( defined( 'IMSANITY_VERSION' ) ) {
9604
  $resize_score += 30;
9605
  } else {
9606
- $resize_recommendations[] = esc_html__( 'Configure maximum image dimensions in Resize settings.', 'ewww-image-optimizer' ) . ewwwio_get_help_link( 'https://docs.ewww.io/article/41-resize-settings', '59849911042863033a1ba5f9' );
9607
  }
9608
  $jpg_quality = apply_filters( 'jpeg_quality', 82, 'image_resize' );
9609
- if ( $jpg_quality < 90 && $jpg_quality > 50 ) {
9610
  $resize_score += 20;
9611
  } else {
9612
- $resize_recommendations[] = esc_html__( 'JPG quality level should be between 50 and 90 for optimal resizing.', 'ewww-image-optimizer' ) . ewwwio_get_help_link( 'https://docs.ewww.io/article/11-advanced-configuration', '58542afac697912ffd6c18c0,58543c69c697912ffd6c19a7' );
9613
  }
9614
  $skip = ewww_image_optimizer_skip_tools();
9615
  if ( ! $skip['jpegtran'] && ! EWWW_IMAGE_OPTIMIZER_NOEXEC ) {
@@ -9622,7 +9727,7 @@ function ewww_image_optimizer_options( $network = 'singlesite' ) {
9622
  if ( ! empty( $jpegtran_installed ) ) {
9623
  $compress_score += 5;
9624
  } else {
9625
- $compress_recommendations[] = esc_html__( 'Install jpegtran.', 'ewww-image-optimizer' ) . ewwwio_get_help_link( 'https://docs.ewww.io/article/6-the-plugin-says-i-m-missing-something', '585371e3c697912ffd6c0ba1' );
9626
  }
9627
  }
9628
  if ( ! $skip['optipng'] && ! EWWW_IMAGE_OPTIMIZER_NOEXEC ) {
@@ -9635,7 +9740,7 @@ function ewww_image_optimizer_options( $network = 'singlesite' ) {
9635
  if ( ! empty( $optipng_version ) ) {
9636
  $compress_score += 5;
9637
  } else {
9638
- $compress_recommendations[] = esc_html__( 'Install optipng.', 'ewww-image-optimizer' ) . ewwwio_get_help_link( 'https://docs.ewww.io/article/6-the-plugin-says-i-m-missing-something', '585371e3c697912ffd6c0ba1' );
9639
  }
9640
  }
9641
  if ( ! $skip['pngout'] && ! EWWW_IMAGE_OPTIMIZER_NOEXEC ) {
@@ -9648,7 +9753,7 @@ function ewww_image_optimizer_options( $network = 'singlesite' ) {
9648
  if ( ! empty( $pngout_version ) ) {
9649
  $compress_score += 5;
9650
  } else {
9651
- $compress_recommendations[] = esc_html__( 'Install pngout', 'ewww-image-optimizer' ) . ': <a href="' . admin_url( 'admin.php?action=ewww_image_optimizer_install_pngout' ) . '">' . esc_html__( 'automatically', 'ewww-image-optimizer' ) . '</a> | <a href="https://docs.ewww.io/article/13-installing-pngout" data-beacon-article="5854531bc697912ffd6c1afa">' . esc_html__( 'manually', 'ewww-image-optimizer' ) . '</a>';
9652
  }
9653
  }
9654
  if ( ! $skip['pngquant'] && ! EWWW_IMAGE_OPTIMIZER_NOEXEC ) {
@@ -9661,7 +9766,7 @@ function ewww_image_optimizer_options( $network = 'singlesite' ) {
9661
  if ( ! empty( $pngquant_version ) ) {
9662
  $compress_score += 5;
9663
  } else {
9664
- $compress_recommendations[] = esc_html__( 'Install pngquant.', 'ewww-image-optimizer' ) . ewwwio_get_help_link( 'https://docs.ewww.io/article/6-the-plugin-says-i-m-missing-something', '585371e3c697912ffd6c0ba1' );
9665
  }
9666
  }
9667
  if ( ! $skip['gifsicle'] && ! EWWW_IMAGE_OPTIMIZER_NOEXEC ) {
@@ -9674,7 +9779,7 @@ function ewww_image_optimizer_options( $network = 'singlesite' ) {
9674
  if ( ! empty( $gifsicle_version ) ) {
9675
  $compress_score += 5;
9676
  } else {
9677
- $compress_recommendations[] = esc_html__( 'Install gifsicle.', 'ewww-image-optimizer' ) . ewwwio_get_help_link( 'https://docs.ewww.io/article/6-the-plugin-says-i-m-missing-something', '585371e3c697912ffd6c0ba1' );
9678
  }
9679
  }
9680
  if ( EWWW_IMAGE_OPTIMIZER_CWEBP && ! $skip['webp'] && ! EWWW_IMAGE_OPTIMIZER_NOEXEC ) {
@@ -9687,13 +9792,27 @@ function ewww_image_optimizer_options( $network = 'singlesite' ) {
9687
  if ( ! empty( $webp_version ) ) {
9688
  $compress_score += 5;
9689
  } else {
9690
- $compress_recommendations[] = esc_html__( 'Install webp.', 'ewww-image-optimizer' ) . ewwwio_get_help_link( 'https://docs.ewww.io/article/6-the-plugin-says-i-m-missing-something', '585371e3c697912ffd6c0ba1' );
9691
  }
9692
  }
9693
- if ( ewww_image_optimizer_get_option( 'ewww_image_optimizer_metadata_remove' ) ) {
 
 
 
9694
  $compress_score += 5;
9695
- } else {
9696
- $compress_recommendations[] = esc_html__( 'Remove metadata from JPG images.', 'ewww-image-optimizer' ) . ewwwio_get_help_link( 'https://docs.ewww.io/article/7-basic-configuration', '585373d5c697912ffd6c0bb2' );
 
 
 
 
 
 
 
 
 
 
 
9697
  }
9698
 
9699
  // Check that an image library exists for converting resizes. Originals can be done via the API, but resizes are done locally for speed.
@@ -10093,14 +10212,14 @@ function ewww_image_optimizer_options( $network = 'singlesite' ) {
10093
  <?php esc_html_e( 'No Compression', 'ewww-image-optimizer' ); ?>
10094
  </option>
10095
  <?php if ( defined( 'EWWW_IMAGE_OPTIMIZER_TOOL_PATH' ) ) : ?>
10096
- <option value='10' <?php selected( ewww_image_optimizer_get_option( 'ewww_image_optimizer_png_level' ), 10 ); ?>>
10097
  <?php esc_html_e( 'Pixel Perfect', 'ewww-image-optimizer' ); ?>
10098
  </option>
10099
  <?php endif; ?>
10100
  <option <?php disabled( $disable_level ); ?> value='20' <?php selected( ewww_image_optimizer_get_option( 'ewww_image_optimizer_png_level' ), 20 ); ?><?php selected( ewww_image_optimizer_get_option( 'ewww_image_optimizer_png_level' ), 30 ); ?>>
10101
  <?php esc_html_e( 'Pixel Perfect Plus', 'ewww-image-optimizer' ); ?> *
10102
  </option>
10103
- <option value='40' <?php selected( ewww_image_optimizer_get_option( 'ewww_image_optimizer_png_level' ), 40 ); ?>>
10104
  <?php esc_html_e( 'Premium', 'ewww-image-optimizer' ) . ' ' . $maybe_api_level; ?>
10105
  </option>
10106
  <option <?php disabled( $disable_level ); ?> value='50' <?php selected( ewww_image_optimizer_get_option( 'ewww_image_optimizer_png_level' ), 50 ); ?>>
@@ -10119,7 +10238,7 @@ function ewww_image_optimizer_options( $network = 'singlesite' ) {
10119
  <option value='0' <?php selected( ewww_image_optimizer_get_option( 'ewww_image_optimizer_gif_level' ), 0 ); ?>>
10120
  <?php esc_html_e( 'No Compression', 'ewww-image-optimizer' ); ?>
10121
  </option>
10122
- <option value='10' <?php selected( ewww_image_optimizer_get_option( 'ewww_image_optimizer_gif_level' ), 10 ); ?>>
10123
  <?php esc_html_e( 'Pixel Perfect', 'ewww-image-optimizer' ) . ' ' . $maybe_api_level; ?>
10124
  </option>
10125
  </select>
@@ -10220,6 +10339,9 @@ function ewww_image_optimizer_options( $network = 'singlesite' ) {
10220
  <a class='ewww-docs-root' href='https://ewww.io/contact-us/'>
10221
  <?php esc_html_e( 'Then, let us know so we can find a fix for the problem.', 'ewww-image-optimizer' ); ?>
10222
  </a>
 
 
 
10223
  </p>
10224
  <table class='form-table'>
10225
  <tr>
@@ -10707,14 +10829,21 @@ function ewww_image_optimizer_options( $network = 'singlesite' ) {
10707
 
10708
  <div id='ewww-webp-settings'>
10709
  <noscript><h2><?php esc_html_e( 'WebP', 'ewww-image-optimizer' ); ?></h2></noscript>
10710
- <?php if ( ! ewww_image_optimizer_get_option( 'ewww_image_optimizer_exactdn' ) && ! ewww_image_optimizer_easy_active() ) : ?>
10711
  <p>
10712
  <?php esc_html_e( 'Once WebP conversion is enabled, WebP images will be generated for new uploads, but you will need to use the Bulk Optimizer for existing uploads.', 'ewww-image-optimizer' ); ?><br>
10713
  <a href='https://ewww.io/easy/'><?php esc_html_e( 'Get Easy IO for automatic WebP conversion and delivery.', 'ewww-image-optimizer' ); ?></a>
10714
  </p>
10715
  <?php endif; ?>
10716
  <table class='form-table'>
10717
- <?php if ( ! ewww_image_optimizer_easy_active() || ewww_image_optimizer_get_option( 'ewww_image_optimizer_webp' ) ) : ?>
 
 
 
 
 
 
 
10718
  <tr>
10719
  <th scope='row'>
10720
  <label for='ewww_image_optimizer_webp'><?php esc_html_e( 'WebP Conversion', 'ewww-image-optimizer' ); ?></label>
@@ -10722,16 +10851,16 @@ function ewww_image_optimizer_options( $network = 'singlesite' ) {
10722
  </th>
10723
  <td>
10724
  <input type='checkbox' id='ewww_image_optimizer_webp' name='ewww_image_optimizer_webp' value='true' <?php checked( ewww_image_optimizer_get_option( 'ewww_image_optimizer_webp' ) ); ?> />
10725
- <span><?php esc_html_e( 'JPG to WebP conversion is lossy, but quality loss is minimal. PNG/GIF to WebP conversion is lossless.', 'ewww-image-optimizer' ); ?></span>
10726
  <p class='description'>
10727
- <?php esc_html_e( 'Originals are never deleted, and WebP images should only be served to supported browsers.', 'ewww-image-optimizer' ); ?>
10728
  <a href='#ewww-webp-rewrite'><?php echo esc_html( $rewrite_notice ); ?></a>
10729
  </p>
10730
  </td>
10731
  </tr>
10732
  <?php endif; ?>
10733
 
10734
- <?php if ( ! ewww_image_optimizer_ce_webp_enabled() && ! ewww_image_optimizer_easy_active() ) : ?>
10735
  <tr>
10736
  <th scope='row'>
10737
  <label for='ewww_image_optimizer_webp_for_cdn'><?php esc_html_e( 'JS WebP Rewriting', 'ewww-image-optimizer' ); ?></label>
@@ -10790,7 +10919,7 @@ function ewww_image_optimizer_options( $network = 'singlesite' ) {
10790
  </tr>
10791
  <?php endif; ?>
10792
 
10793
- <?php if ( ! ewww_image_optimizer_easy_active() || ewww_image_optimizer_get_option( 'ewww_image_optimizer_webp' ) ) : ?>
10794
  <tr>
10795
  <th scope='row'>
10796
  <label for='ewww_image_optimizer_webp_force'><?php esc_html_e( 'Force WebP', 'ewww-image-optimizer' ); ?></label>
@@ -11278,7 +11407,7 @@ function ewww_image_optimizer_admin_bar_menu() {
11278
  * @param string $message Debug information to add to the log.
11279
  */
11280
  function ewwwio_debug_message( $message ) {
11281
- if ( ! is_string( $message ) ) {
11282
  return;
11283
  }
11284
  if ( defined( 'WP_CLI' ) && WP_CLI ) {
14
  exit;
15
  }
16
 
17
+ define( 'EWWW_IMAGE_OPTIMIZER_VERSION', '560.0' );
18
 
19
  // Initialize a couple globals.
20
  $eio_debug = '';
539
  }
540
  }
541
  if ( ewww_image_optimizer_iterable( $active_plugins ) ) {
542
+ ewwwio_debug_message( 'checking active plugins' );
543
  foreach ( $active_plugins as $active_plugin ) {
544
  if ( strpos( $active_plugin, '/nggallery.php' ) || strpos( $active_plugin, '\nggallery.php' ) ) {
545
  $ngg = ewww_image_optimizer_get_plugin_version( trailingslashit( WP_PLUGIN_DIR ) . $active_plugin );
4144
  ewww_image_optimizer_debug_log();
4145
  }
4146
  $ewww_status = get_transient( 'ewww_image_optimizer_cloud_status' );
 
4147
  if ( preg_match( '/exceeded/', $ewww_status ) ) {
4148
+ $started = microtime( true );
4149
  if ( ! ewww_image_optimizer_cloud_verify() ) {
4150
  return array( $file, false, 'key verification failed', 0, '' );
4151
  }
4152
+ // Calculate how much time has elapsed since we started.
4153
+ $elapsed = microtime( true ) - $started;
4154
+ ewwwio_debug_message( "cloud verify took $elapsed seconds" );
4155
  }
 
 
 
4156
  $ewww_status = get_transient( 'ewww_image_optimizer_cloud_status' );
4157
  if ( ( ! empty( $ewww_status ) && preg_match( '/exceeded/', $ewww_status ) ) || ewww_image_optimizer_get_option( 'ewww_image_optimizer_cloud_exceeded' ) > time() ) {
4158
  ewwwio_debug_message( 'license exceeded, image not processed' );
4249
  ewwwio_debug_message( "webp: $webp" );
4250
  ewwwio_debug_message( "jpg fill: $jpg_fill" );
4251
  ewwwio_debug_message( "jpg quality: $jpg_quality" );
4252
+ $free_exec = EWWW_IMAGE_OPTIMIZER_NOEXEC && 'image/jpeg' === $type;
4253
+ $api_key = ewww_image_optimizer_get_option( 'ewww_image_optimizer_cloud_key' );
4254
+ if ( empty( $api_key ) && ! $free_exec ) {
4255
+ return array( $file, false, 'key verification failed', 0, '' );
4256
  }
4257
  $url = 'http://optimize.exactlywww.com/v2/';
4258
  $ssl = wp_http_supports( array( 'ssl' ) );
6016
  ewwwio_debug_message( 'not a large PNG, skipping' );
6017
  return;
6018
  }
6019
+ if ( ewww_image_optimizer_png_alpha( $file ) && ( ! ewww_image_optimizer_get_option( 'ewww_image_optimizer_png_to_jpg' ) || ! ewww_image_optimizer_jpg_background() ) ) {
6020
  ewwwio_debug_message( 'alpha detected, skipping' );
6021
  return;
6022
  }
7870
  // Retrieve the metadata.
7871
  $meta = wp_get_attachment_metadata( $id );
7872
  }
7873
+ echo '<div id="ewww-media-status-' . (int) $id . '" class="ewww-media-status" data-id="' . (int) $id . '">';
7874
  if ( ewww_image_optimizer_get_option( 'ewww_image_optimizer_debug' ) && ewww_image_optimizer_function_exists( 'print_r' ) ) {
7875
  $print_meta = print_r( $meta, true );
7876
  $print_meta = preg_replace( array( '/ /', '/\n+/' ), array( '&nbsp;', '<br />' ), $print_meta );
7954
  break;
7955
  case 'image/png':
7956
  // If pngout and optipng are missing and should not be skipped.
7957
+ if ( ( ! $skip['optipng'] && ! EWWW_IMAGE_OPTIMIZER_OPTIPNG ) || ( ! $skip['pngout'] && ! EWWW_IMAGE_OPTIMIZER_PNGOUT ) ) {
7958
  $msg = '<div>' . sprintf(
7959
  /* translators: %s: name of a tool like jpegtran */
7960
  __( '%s is missing', 'ewww-image-optimizer' ),
7961
  '<em>optipng</em>'
7962
  ) . '</div>';
7963
+ } elseif ( ! ewww_image_optimizer_get_option( 'ewww_image_optimizer_png_level' ) ) {
7964
+ $msg = '<div>' . sprintf(
7965
+ /* translators: %s: JPG, PNG, GIF, or PDF */
7966
+ __( '%s compression disabled', 'ewww-image-optimizer' ),
7967
+ 'PNG'
7968
+ ) . '</div>';
7969
  } else {
7970
  $convert_link = __( 'PNG to JPG', 'ewww-image-optimizer' );
7971
  $convert_desc = __( 'WARNING: This is not a lossless conversion and requires GD or ImageMagick. JPG is much better than PNG for photographic use because it compresses the image and discards data. Transparent images will only be converted if a background color has been set.', 'ewww-image-optimizer' );
7979
  __( '%s is missing', 'ewww-image-optimizer' ),
7980
  '<em>gifsicle</em>'
7981
  ) . '</div>';
7982
+ } elseif ( ! ewww_image_optimizer_get_option( 'ewww_image_optimizer_gif_level' ) ) {
7983
+ $msg = '<div>' . sprintf(
7984
+ /* translators: %s: JPG, PNG, GIF, or PDF */
7985
+ __( '%s compression disabled', 'ewww-image-optimizer' ),
7986
+ 'GIF'
7987
+ ) . '</div>';
7988
  } else {
7989
  $convert_link = __( 'GIF to PNG', 'ewww-image-optimizer' );
7990
  $convert_desc = __( 'PNG is generally better than GIF, but does not support animation. Animated images will not be converted.', 'ewww-image-optimizer' );
8018
  $backup_available = false;
8019
  $file_parts = pathinfo( $file_path );
8020
  $basename = $file_parts['filename'];
8021
+ $action_id = ewww_image_optimizer_get_primary_wpml_id( $id );
8022
  // If necessary, use get_post_meta( $post_id, '_wp_attachment_backup_sizes', true ); to only use basename for edited attachments, but that requires extra queries, so kiss for now.
8023
  if ( $ewww_cdn ) {
8024
+ if ( ewww_image_optimizer_image_is_pending( $action_id, 'media-async' ) ) {
8025
  echo '<div>' . esc_html__( 'In Progress', 'ewww-image-optimizer' ) . '</div>';
8026
  $in_progress = true;
8027
  }
8034
  if ( $migrated ) {
8035
  $optimized_images = $wpdb->get_results( $wpdb->prepare( "SELECT image_size,orig_size,resize,converted,level,backup,updated FROM $wpdb->ewwwio_images WHERE attachment_id = %d AND gallery = 'media' AND image_size <> 0 ORDER BY orig_size DESC", $id ), ARRAY_A );
8036
  }
8037
+ if ( ! $optimized_images ) {
8038
+ list( $possible_action_id, $optimized_images ) = ewww_image_optimizer_get_wpml_results( $id );
8039
+ if ( $optimized_images ) {
8040
+ $action_id = $possible_action_id;
8041
+ }
8042
+ }
8043
  }
8044
  // If optimizer data exists in the db.
8045
  if ( ! empty( $optimized_images ) ) {
8046
+ list( $detail_output, $converted, $backup_available ) = ewww_image_optimizer_custom_column_results( $action_id, $optimized_images );
8047
  echo wp_kses_post( $detail_output );
8048
  // Output the optimizer actions.
8049
  if ( current_user_can( apply_filters( 'ewww_image_optimizer_manual_permissions', '' ) ) ) {
8050
  // Display a link to re-optimize manually.
8051
  echo '<div>' . sprintf(
8052
  '<a class="ewww-manual-optimize" data-id="%1$d" data-nonce="%2$s" href="%3$s">%4$s</a>',
8053
+ (int) $action_id,
8054
  esc_attr( $ewww_manual_nonce ),
8055
+ esc_url( admin_url( "admin.php?action=ewww_image_optimizer_manual_optimize&ewww_manual_nonce=$ewww_manual_nonce&ewww_force=1&ewww_attachment_ID=$action_id" ) ),
8056
  ( ewww_image_optimizer_restore_possible( $optimized_images, $compression_level ) ? esc_html__( 'Restore & Re-optimize', 'ewww-image-optimizer' ) : esc_html__( 'Re-optimize', 'ewww-image-optimizer' ) )
8057
  ) .
8058
  wp_kses_post( ewww_image_optimizer_variant_level_notice( $optimized_images, $compression_level ) ) .
8061
  if ( $backup_available && current_user_can( apply_filters( 'ewww_image_optimizer_manual_permissions', '' ) ) ) {
8062
  echo '<div>' . sprintf(
8063
  '<a class="ewww-manual-cloud-restore" data-id="%1$d" data-nonce="%2$s" href="%3$s">%4$s</a>',
8064
+ (int) $action_id,
8065
  esc_attr( $ewww_manual_nonce ),
8066
+ esc_url( admin_url( "admin.php?action=ewww_image_optimizer_manual_cloud_restore&ewww_manual_nonce=$ewww_manual_nonce&ewww_attachment_ID=$action_id" ) ),
8067
  esc_html__( 'Restore original', 'ewww-image-optimizer' )
8068
  ) . '</div>';
8069
  }
8084
  }
8085
  echo '<div>' . sprintf(
8086
  '<a class="ewww-manual-optimize" data-id="%1$d" data-nonce="%2$s" href="%3$s">%4$s</a>',
8087
+ (int) $action_id,
8088
  esc_attr( $ewww_manual_nonce ),
8089
+ esc_url( admin_url( "admin.php?action=ewww_image_optimizer_manual_optimize&ewww_manual_nonce=$ewww_manual_nonce&ewww_attachment_ID=$action_id" ) ),
8090
  esc_html__( 'Optimize now!', 'ewww-image-optimizer' )
8091
  ) .
8092
  '</div>';
8095
  return;
8096
  } // End if().
8097
  // End of output for CDN images.
8098
+ if ( ewww_image_optimizer_image_is_pending( $action_id, 'media-async' ) ) {
8099
  echo '<div>' . esc_html__( 'In Progress', 'ewww-image-optimizer' ) . '</div>';
8100
  $in_progress = true;
8101
  }
8108
  if ( $migrated ) {
8109
  $optimized_images = $wpdb->get_results( $wpdb->prepare( "SELECT image_size,orig_size,resize,converted,level,backup,updated FROM $wpdb->ewwwio_images WHERE attachment_id = %d AND gallery = 'media' AND image_size <> 0 ORDER BY orig_size DESC", $id ), ARRAY_A );
8110
  }
8111
+ if ( ! $optimized_images ) {
8112
+ list( $possible_action_id, $optimized_images ) = ewww_image_optimizer_get_wpml_results( $id );
8113
+ if ( $optimized_images ) {
8114
+ $action_id = $possible_action_id;
8115
+ }
8116
+ }
8117
  }
8118
  // If optimizer data exists.
8119
  if ( ! empty( $optimized_images ) ) {
8120
+ list( $detail_output, $converted, $backup_available ) = ewww_image_optimizer_custom_column_results( $action_id, $optimized_images );
8121
  echo wp_kses_post( $detail_output );
8122
 
8123
  // Link to webp upgrade script.
8140
  // Output a link to re-optimize manually.
8141
  echo '<div>' . sprintf(
8142
  '<a class="ewww-manual-optimize" data-id="%1$d" data-nonce="%2$s" href="%3$s">%4$s</a>',
8143
+ (int) $action_id,
8144
  esc_attr( $ewww_manual_nonce ),
8145
+ esc_url( admin_url( "admin.php?action=ewww_image_optimizer_manual_optimize&ewww_manual_nonce=$ewww_manual_nonce&ewww_force=1&ewww_attachment_ID=$action_id" ) ),
8146
  ( ewww_image_optimizer_restore_possible( $optimized_images, $compression_level ) ? esc_html__( 'Restore & Re-optimize', 'ewww-image-optimizer' ) : esc_html__( 'Re-optimize', 'ewww-image-optimizer' ) )
8147
  );
8148
  echo wp_kses_post( ewww_image_optimizer_variant_level_notice( $optimized_images, $compression_level ) );
8149
  if ( ! ewww_image_optimizer_get_option( 'ewww_image_optimizer_disable_convert_links' ) && 'ims_image' !== get_post_type( $id ) && ! empty( $convert_desc ) ) {
8150
  printf(
8151
  ' | <a class="ewww-manual-convert" data-id="%1$d" data-nonce="%2$s" title="%3$s" href="%4$s">%5$s</a>',
8152
+ (int) $action_id,
8153
  esc_attr( $ewww_manual_nonce ),
8154
  esc_attr( $convert_desc ),
8155
+ esc_url( admin_url( "admin.php?action=ewww_image_optimizer_manual_optimize&ewww_manual_nonce=$ewww_manual_nonce&ewww_attachment_ID=$action_id&ewww_convert=1&ewww_force=1" ) ),
8156
  esc_html( $convert_link )
8157
  );
8158
  }
8165
  if ( $restorable && current_user_can( apply_filters( 'ewww_image_optimizer_manual_permissions', '' ) ) ) {
8166
  echo '<div>' . sprintf(
8167
  '<a class="ewww-manual-restore" data-id="%1$d" data-nonce="%2$s" href="%3$s">%4$s</a>',
8168
+ (int) $action_id,
8169
  esc_attr( $ewww_manual_nonce ),
8170
+ esc_url( admin_url( "admin.php?action=ewww_image_optimizer_manual_restore&ewww_manual_nonce=$ewww_manual_nonce&ewww_attachment_ID=$action_id" ) ),
8171
  esc_html__( 'Restore original', 'ewww-image-optimizer' )
8172
  ) . '</div>';
8173
  } elseif ( $backup_available && current_user_can( apply_filters( 'ewww_image_optimizer_manual_permissions', '' ) ) ) {
8174
  echo '<div>' . sprintf(
8175
  '<a class="ewww-manual-cloud-restore" data-id="%1$d" data-nonce="%2$s" href="%3$s">%4$s</a>',
8176
+ (int) $action_id,
8177
  esc_attr( $ewww_manual_nonce ),
8178
+ esc_url( admin_url( "admin.php?action=ewww_image_optimizer_manual_cloud_restore&ewww_manual_nonce=$ewww_manual_nonce&ewww_attachment_ID=$action_id" ) ),
8179
  esc_html__( 'Restore original', 'ewww-image-optimizer' )
8180
  ) . '</div>';
8181
  }
8215
  // Give the user the option to optimize the image right now.
8216
  printf(
8217
  '<div><a class="ewww-manual-optimize" data-id="%1$d" data-nonce="%2$s" href="%3$s">%4$s</a>',
8218
+ (int) $action_id,
8219
  esc_attr( $ewww_manual_nonce ),
8220
+ esc_url( admin_url( "admin.php?action=ewww_image_optimizer_manual_optimize&ewww_manual_nonce=$ewww_manual_nonce&ewww_attachment_ID=$action_id" ) ),
8221
  esc_html__( 'Optimize now!', 'ewww-image-optimizer' )
8222
  );
8223
  if ( ! ewww_image_optimizer_get_option( 'ewww_image_optimizer_disable_convert_links' ) && 'ims_image' !== get_post_type( $id ) && ! empty( $convert_desc ) ) {
8224
  printf(
8225
  ' | <a class="ewww-manual-convert" data-id="%1$d" data-nonce="%2$s" title="%3$s" href="%4$s">%5$s</a>',
8226
+ (int) $action_id,
8227
  esc_attr( $ewww_manual_nonce ),
8228
  esc_attr( $convert_desc ),
8229
+ esc_url( admin_url( "admin.php?action=ewww_image_optimizer_manual_optimize&ewww_manual_nonce=$ewww_manual_nonce&ewww_attachment_ID=$action_id&ewww_convert=1&ewww_force=1" ) ),
8230
  esc_html( $convert_link )
8231
  );
8232
  }
8249
  if ( empty( $compression_level ) ) {
8250
  return '';
8251
  }
8252
+ if ( ! ewww_image_optimizer_get_option( 'ewww_image_optimizer_cloud_key' ) ) {
8253
+ return '';
8254
+ }
8255
  ewwwio_debug_message( '<b>' . __FUNCTION__ . '()</b>' );
8256
  foreach ( $optimized_images as $optimized_image ) {
8257
  if ( 'full' === $optimized_image['resize'] ) {
8409
  return array( $output, $converted, $backup_available );
8410
  }
8411
 
8412
+ /**
8413
+ * If attachment is translated by WPML, get the primary ID number.
8414
+ *
8415
+ * @param int $id The attachment ID number to search for in the WPML tables.
8416
+ * @return int The primary/original ID number.
8417
+ */
8418
+ function ewww_image_optimizer_get_primary_wpml_id( $id ) {
8419
+ if ( ! defined( 'ICL_SITEPRESS_VERSION' ) ) {
8420
+ return $id;
8421
+ }
8422
+ if ( get_post_meta( $id, 'wpml_media_processed', true ) ) {
8423
+ $trid = apply_filters( 'wpml_element_trid', null, $id, 'post_attachment' );
8424
+ if ( ! empty( $trid ) ) {
8425
+ $translations = apply_filters( 'wpml_get_element_translations', null, $trid, 'post_attachment' );
8426
+ if ( ewww_image_optimizer_iterable( $translations ) ) {
8427
+ $possible_ids = array();
8428
+ foreach ( $translations as $translation ) {
8429
+ if ( ! empty( $translation->element_id ) ) {
8430
+ $possible_ids[] = (int) $translation->element_id;
8431
+ }
8432
+ }
8433
+ if ( ewww_image_optimizer_iterable( $possible_ids ) ) {
8434
+ sort( $possible_ids );
8435
+ return $possible_ids[0];
8436
+ }
8437
+ }
8438
+ }
8439
+ }
8440
+ return $id;
8441
+ }
8442
+ /**
8443
+ * Gets results for WPML replicates.
8444
+ *
8445
+ * @param int $id The attachment ID number to search for in the WPML tables.
8446
+ * @return array The resultant attachment ID, and a list of image optimization results.
8447
+ */
8448
+ function ewww_image_optimizer_get_wpml_results( $id ) {
8449
+ if ( ! defined( 'ICL_SITEPRESS_VERSION' ) ) {
8450
+ return array( $id, array() );
8451
+ }
8452
+ ewwwio_debug_message( '<b>' . __FUNCTION__ . '()</b>' );
8453
+ $trid = apply_filters( 'wpml_element_trid', null, $id, 'post_attachment' );
8454
+ if ( empty( $trid ) ) {
8455
+ return array( $id, array() );
8456
+ }
8457
+ $translations = apply_filters( 'wpml_get_element_translations', null, $trid, 'post_attachment' );
8458
+ if ( empty( $translations ) ) {
8459
+ return array( $id, array() );
8460
+ }
8461
+ global $wpdb;
8462
+ foreach ( $translations as $translation ) {
8463
+ if ( empty( $translation->element_id ) ) {
8464
+ continue;
8465
+ }
8466
+ ewwwio_debug_message( "checking {$translation->element_id} for results with WPML" );
8467
+ $optimized_images = $wpdb->get_results( $wpdb->prepare( "SELECT image_size,orig_size,resize,converted,level,backup,updated FROM $wpdb->ewwwio_images WHERE attachment_id = %d AND gallery = 'media' AND image_size <> 0 ORDER BY orig_size DESC", $translation->element_id ), ARRAY_A );
8468
+ if ( ! empty( $optimized_images ) ) {
8469
+ return array( (int) $translation->element_id, $optimized_images );
8470
+ }
8471
+ }
8472
+ return array( $id, array() );
8473
+ }
8474
  /**
8475
  * Removes optimization from metadata, because we store it all in the images table now.
8476
  *
9609
  $compress_recommendations = array();
9610
  $resize_recommendations = array();
9611
 
9612
+ $free_exec = false;
9613
+ if (
9614
+ defined( 'EWWW_IMAGE_OPTIMIZER_NOEXEC' ) && EWWW_IMAGE_OPTIMIZER_NOEXEC &&
9615
+ 10 === (int) ewww_image_optimizer_get_option( 'ewww_image_optimizer_jpg_level' ) &&
9616
+ ! ewww_image_optimizer_get_option( 'ewww_image_optimizer_cloud_key' ) &&
9617
+ ! ewww_image_optimizer_easy_active()
9618
+ ) {
9619
+ $free_exec = true;
9620
+ $compress_score += 5;
9621
+ }
9622
  $verify_cloud = '';
9623
  if ( ewww_image_optimizer_get_option( 'ewww_image_optimizer_cloud_key' ) ) {
9624
  ewww_image_optimizer_set_option( 'ewww_image_optimizer_cloud_exceeded', 0 );
9628
  if ( ewww_image_optimizer_get_option( 'ewww_image_optimizer_jpg_level' ) > 20 ) {
9629
  $compress_score += 50;
9630
  } else {
9631
+ $compress_recommendations[] = __( 'Enable premium compression for JPG images.', 'ewww-image-optimizer' );
9632
  }
9633
  if ( ewww_image_optimizer_get_option( 'ewww_image_optimizer_png_level' ) > 20 ) {
9634
  $compress_score += 20;
9635
  } else {
9636
+ $compress_recommendations[] = __( 'Enable premium compression for PNG images.', 'ewww-image-optimizer' );
9637
  }
9638
  }
9639
  $disable_level = false;
9651
  update_option( 'ewww_image_optimizer_lazy_load', false );
9652
  update_option( 'ewww_image_optimizer_webp_for_cdn', false );
9653
  update_option( 'ewww_image_optimizer_picture_webp', false );
9654
+ $compress_score = 50;
9655
+ $resize_score += 50;
9656
+ if ( get_option( 'exactdn_lossy' ) ) {
9657
+ $compress_score = 100;
9658
+ }
9659
  } elseif (
9660
  ( ! class_exists( 'Jetpack_Photon' ) || ! Jetpack::is_module_active( 'photon' ) ) &&
9661
  class_exists( 'ExactDN' ) &&
9669
  if ( ewww_image_optimizer_get_option( 'exactdn_lossy' ) ) {
9670
  $compress_score = 100;
9671
  } elseif ( ewww_image_optimizer_get_option( 'ewww_image_optimizer_jpg_level' ) < 30 ) {
9672
+ $compress_recommendations[] = __( 'Enable premium compression.', 'ewww-image-optimizer' ) . ewwwio_get_help_link( 'https://docs.ewww.io/article/47-getting-more-from-exactdn', '59de6631042863379ddc953c' );
9673
  }
9674
  $exactdn_enabled = true;
9675
  }
9676
  } elseif ( ! ewww_image_optimizer_get_option( 'ewww_image_optimizer_exactdn' ) ) {
9677
+ $resize_recommendations[] = __( 'Enable Easy IO for automatic resizing.', 'ewww-image-optimizer' ) . ewwwio_get_help_link( 'https://docs.ewww.io/article/44-introduction-to-exactdn', '59bc5ad6042863033a1ce370,5c0042892c7d3a31944e88a4' );
9678
  delete_option( 'ewww_image_optimizer_exactdn_domain' );
9679
  delete_option( 'ewww_image_optimizer_exactdn_plan_id' );
9680
  delete_option( 'ewww_image_optimizer_exactdn_failures' );
9708
  } elseif ( defined( 'IMSANITY_VERSION' ) ) {
9709
  $resize_score += 30;
9710
  } else {
9711
+ $resize_recommendations[] = __( 'Configure maximum image dimensions in Resize settings.', 'ewww-image-optimizer' ) . ewwwio_get_help_link( 'https://docs.ewww.io/article/41-resize-settings', '59849911042863033a1ba5f9' );
9712
  }
9713
  $jpg_quality = apply_filters( 'jpeg_quality', 82, 'image_resize' );
9714
+ if ( $jpg_quality < 91 && $jpg_quality > 49 ) {
9715
  $resize_score += 20;
9716
  } else {
9717
+ $resize_recommendations[] = __( 'JPG quality level should be between 50 and 90 for optimal resizing.', 'ewww-image-optimizer' ) . ewwwio_get_help_link( 'https://docs.ewww.io/article/11-advanced-configuration', '58542afac697912ffd6c18c0,58543c69c697912ffd6c19a7' );
9718
  }
9719
  $skip = ewww_image_optimizer_skip_tools();
9720
  if ( ! $skip['jpegtran'] && ! EWWW_IMAGE_OPTIMIZER_NOEXEC ) {
9727
  if ( ! empty( $jpegtran_installed ) ) {
9728
  $compress_score += 5;
9729
  } else {
9730
+ $compress_recommendations[] = __( 'Install jpegtran.', 'ewww-image-optimizer' ) . ewwwio_get_help_link( 'https://docs.ewww.io/article/6-the-plugin-says-i-m-missing-something', '585371e3c697912ffd6c0ba1' );
9731
  }
9732
  }
9733
  if ( ! $skip['optipng'] && ! EWWW_IMAGE_OPTIMIZER_NOEXEC ) {
9740
  if ( ! empty( $optipng_version ) ) {
9741
  $compress_score += 5;
9742
  } else {
9743
+ $compress_recommendations[] = __( 'Install optipng.', 'ewww-image-optimizer' ) . ewwwio_get_help_link( 'https://docs.ewww.io/article/6-the-plugin-says-i-m-missing-something', '585371e3c697912ffd6c0ba1' );
9744
  }
9745
  }
9746
  if ( ! $skip['pngout'] && ! EWWW_IMAGE_OPTIMIZER_NOEXEC ) {
9753
  if ( ! empty( $pngout_version ) ) {
9754
  $compress_score += 5;
9755
  } else {
9756
+ $compress_recommendations[] = __( 'Install pngout', 'ewww-image-optimizer' ) . ': <a href="' . admin_url( 'admin.php?action=ewww_image_optimizer_install_pngout' ) . '">' . esc_html__( 'automatically', 'ewww-image-optimizer' ) . '</a> | <a href="https://docs.ewww.io/article/13-installing-pngout" data-beacon-article="5854531bc697912ffd6c1afa">' . esc_html__( 'manually', 'ewww-image-optimizer' ) . '</a>';
9757
  }
9758
  }
9759
  if ( ! $skip['pngquant'] && ! EWWW_IMAGE_OPTIMIZER_NOEXEC ) {
9766
  if ( ! empty( $pngquant_version ) ) {
9767
  $compress_score += 5;
9768
  } else {
9769
+ $compress_recommendations[] = __( 'Install pngquant.', 'ewww-image-optimizer' ) . ewwwio_get_help_link( 'https://docs.ewww.io/article/6-the-plugin-says-i-m-missing-something', '585371e3c697912ffd6c0ba1' );
9770
  }
9771
  }
9772
  if ( ! $skip['gifsicle'] && ! EWWW_IMAGE_OPTIMIZER_NOEXEC ) {
9779
  if ( ! empty( $gifsicle_version ) ) {
9780
  $compress_score += 5;
9781
  } else {
9782
+ $compress_recommendations[] = __( 'Install gifsicle.', 'ewww-image-optimizer' ) . ewwwio_get_help_link( 'https://docs.ewww.io/article/6-the-plugin-says-i-m-missing-something', '585371e3c697912ffd6c0ba1' );
9783
  }
9784
  }
9785
  if ( EWWW_IMAGE_OPTIMIZER_CWEBP && ! $skip['webp'] && ! EWWW_IMAGE_OPTIMIZER_NOEXEC ) {
9792
  if ( ! empty( $webp_version ) ) {
9793
  $compress_score += 5;
9794
  } else {
9795
+ $compress_recommendations[] = __( 'Install webp.', 'ewww-image-optimizer' ) . ewwwio_get_help_link( 'https://docs.ewww.io/article/6-the-plugin-says-i-m-missing-something', '585371e3c697912ffd6c0ba1' );
9796
  }
9797
  }
9798
+ if (
9799
+ ( $free_exec || ! empty( $jpegtran_installed ) || ewww_image_optimizer_easy_active() || ewww_image_optimizer_get_option( 'ewww_image_optimizer_cloud_key' ) ) &&
9800
+ ewww_image_optimizer_get_option( 'ewww_image_optimizer_metadata_remove' )
9801
+ ) {
9802
  $compress_score += 5;
9803
+ } elseif ( ! ewww_image_optimizer_get_option( 'ewww_image_optimizer_metadata_remove' ) ) {
9804
+ $compress_recommendations[] = __( 'Remove metadata from JPG images.', 'ewww-image-optimizer' ) . ewwwio_get_help_link( 'https://docs.ewww.io/article/7-basic-configuration', '585373d5c697912ffd6c0bb2' );
9805
+ }
9806
+ if ( ! ewww_image_optimizer_easy_active() && ! $free_exec ) {
9807
+ if ( 0 === (int) ewww_image_optimizer_get_option( 'ewww_image_optimizer_jpg_level' ) ) {
9808
+ $compress_recommendations[] = __( 'Enable JPG compression.', 'ewww-image-optimizer' );
9809
+ }
9810
+ if ( 0 === (int) ewww_image_optimizer_get_option( 'ewww_image_optimizer_png_level' ) ) {
9811
+ $compress_recommendations[] = __( 'Enable PNG compression.', 'ewww-image-optimizer' );
9812
+ }
9813
+ if ( 0 === (int) ewww_image_optimizer_get_option( 'ewww_image_optimizer_gif_level' ) ) {
9814
+ $compress_recommendations[] = __( 'Enable GIF compression.', 'ewww-image-optimizer' );
9815
+ }
9816
  }
9817
 
9818
  // Check that an image library exists for converting resizes. Originals can be done via the API, but resizes are done locally for speed.
10212
  <?php esc_html_e( 'No Compression', 'ewww-image-optimizer' ); ?>
10213
  </option>
10214
  <?php if ( defined( 'EWWW_IMAGE_OPTIMIZER_TOOL_PATH' ) ) : ?>
10215
+ <option <?php disabled( $free_exec ); ?> value='10' <?php selected( ewww_image_optimizer_get_option( 'ewww_image_optimizer_png_level' ), 10 ); ?>>
10216
  <?php esc_html_e( 'Pixel Perfect', 'ewww-image-optimizer' ); ?>
10217
  </option>
10218
  <?php endif; ?>
10219
  <option <?php disabled( $disable_level ); ?> value='20' <?php selected( ewww_image_optimizer_get_option( 'ewww_image_optimizer_png_level' ), 20 ); ?><?php selected( ewww_image_optimizer_get_option( 'ewww_image_optimizer_png_level' ), 30 ); ?>>
10220
  <?php esc_html_e( 'Pixel Perfect Plus', 'ewww-image-optimizer' ); ?> *
10221
  </option>
10222
+ <option <?php disabled( $free_exec ); ?> value='40' <?php selected( ewww_image_optimizer_get_option( 'ewww_image_optimizer_png_level' ), 40 ); ?>>
10223
  <?php esc_html_e( 'Premium', 'ewww-image-optimizer' ) . ' ' . $maybe_api_level; ?>
10224
  </option>
10225
  <option <?php disabled( $disable_level ); ?> value='50' <?php selected( ewww_image_optimizer_get_option( 'ewww_image_optimizer_png_level' ), 50 ); ?>>
10238
  <option value='0' <?php selected( ewww_image_optimizer_get_option( 'ewww_image_optimizer_gif_level' ), 0 ); ?>>
10239
  <?php esc_html_e( 'No Compression', 'ewww-image-optimizer' ); ?>
10240
  </option>
10241
+ <option <?php disabled( $free_exec ); ?> value='10' <?php selected( ewww_image_optimizer_get_option( 'ewww_image_optimizer_gif_level' ), 10 ); ?>>
10242
  <?php esc_html_e( 'Pixel Perfect', 'ewww-image-optimizer' ) . ' ' . $maybe_api_level; ?>
10243
  </option>
10244
  </select>
10339
  <a class='ewww-docs-root' href='https://ewww.io/contact-us/'>
10340
  <?php esc_html_e( 'Then, let us know so we can find a fix for the problem.', 'ewww-image-optimizer' ); ?>
10341
  </a>
10342
+ <?php if ( $exactdn_enabled && 1 === $exactdn->get_plan_id() ) : ?>
10343
+ <br><i>* <?php esc_html_e( 'Upgrade to a Pro or Developer subscription to unlock additional options below.', 'ewww-image-optimizer' ); ?></i>
10344
+ <?php endif; ?>
10345
  </p>
10346
  <table class='form-table'>
10347
  <tr>
10829
 
10830
  <div id='ewww-webp-settings'>
10831
  <noscript><h2><?php esc_html_e( 'WebP', 'ewww-image-optimizer' ); ?></h2></noscript>
10832
+ <?php if ( ! $free_exec && ! ewww_image_optimizer_easy_active() ) : ?>
10833
  <p>
10834
  <?php esc_html_e( 'Once WebP conversion is enabled, WebP images will be generated for new uploads, but you will need to use the Bulk Optimizer for existing uploads.', 'ewww-image-optimizer' ); ?><br>
10835
  <a href='https://ewww.io/easy/'><?php esc_html_e( 'Get Easy IO for automatic WebP conversion and delivery.', 'ewww-image-optimizer' ); ?></a>
10836
  </p>
10837
  <?php endif; ?>
10838
  <table class='form-table'>
10839
+ <?php if ( $free_exec ) : ?>
10840
+ <tr>
10841
+ <th>&nbsp;</th>
10842
+ <td>
10843
+ <p class='description'><?php esc_html_e( 'WebP conversion requires an API key or Easy IO subscription.', 'ewww-image-optimizer' ); ?></p>
10844
+ </td>
10845
+ </tr>
10846
+ <?php elseif ( ! ewww_image_optimizer_easy_active() || ewww_image_optimizer_get_option( 'ewww_image_optimizer_webp' ) ) : ?>
10847
  <tr>
10848
  <th scope='row'>
10849
  <label for='ewww_image_optimizer_webp'><?php esc_html_e( 'WebP Conversion', 'ewww-image-optimizer' ); ?></label>
10851
  </th>
10852
  <td>
10853
  <input type='checkbox' id='ewww_image_optimizer_webp' name='ewww_image_optimizer_webp' value='true' <?php checked( ewww_image_optimizer_get_option( 'ewww_image_optimizer_webp' ) ); ?> />
10854
+ <span><?php esc_html_e( 'Convert your images to the next generation format for supported browsers, while retaining originals for other browsers.', 'ewww-image-optimizer' ); ?></span>
10855
  <p class='description'>
10856
+ <?php echo ( ewww_image_optimizer_get_option( 'ewww_image_optimizer_cloud_key' ) ? '' : esc_html__( 'GIF to WebP conversion requires an active API key.', 'ewww-image-optimizer' ) ); ?>
10857
  <a href='#ewww-webp-rewrite'><?php echo esc_html( $rewrite_notice ); ?></a>
10858
  </p>
10859
  </td>
10860
  </tr>
10861
  <?php endif; ?>
10862
 
10863
+ <?php if ( ! $free_exec && ( ! ewww_image_optimizer_ce_webp_enabled() && ! ewww_image_optimizer_easy_active() ) ) : ?>
10864
  <tr>
10865
  <th scope='row'>
10866
  <label for='ewww_image_optimizer_webp_for_cdn'><?php esc_html_e( 'JS WebP Rewriting', 'ewww-image-optimizer' ); ?></label>
10919
  </tr>
10920
  <?php endif; ?>
10921
 
10922
+ <?php if ( ! $free_exec && ( ! ewww_image_optimizer_easy_active() || ewww_image_optimizer_get_option( 'ewww_image_optimizer_webp_force' ) ) ) : ?>
10923
  <tr>
10924
  <th scope='row'>
10925
  <label for='ewww_image_optimizer_webp_force'><?php esc_html_e( 'Force WebP', 'ewww-image-optimizer' ); ?></label>
11407
  * @param string $message Debug information to add to the log.
11408
  */
11409
  function ewwwio_debug_message( $message ) {
11410
+ if ( ! is_string( $message ) && ! is_int( $message ) && ! is_float( $message ) ) {
11411
  return;
11412
  }
11413
  if ( defined( 'WP_CLI' ) && WP_CLI ) {
ewww-image-optimizer.php CHANGED
@@ -13,7 +13,7 @@ Plugin Name: EWWW Image Optimizer
13
  Plugin URI: https://wordpress.org/plugins/ewww-image-optimizer/
14
  Description: Reduce file sizes for images within WordPress including NextGEN Gallery and GRAND FlAGallery. Uses jpegtran, optipng/pngout, and gifsicle.
15
  Author: Exactly WWW
16
- Version: 5.5.0
17
  Author URI: https://ewww.io/
18
  License: GPLv3
19
  */
@@ -53,12 +53,6 @@ if ( ! defined( 'PHP_VERSION_ID' ) || PHP_VERSION_ID < 50600 ) {
53
  require_once( plugin_dir_path( __FILE__ ) . 'classes/class-ewwwio-install-cloud.php' );
54
  // Loads the plugin translations.
55
  add_action( 'plugins_loaded', 'ewww_image_optimizer_false_init' );
56
- } elseif ( defined( 'FLYWHEEL_CONFIG_DIR' ) ) {
57
- add_action( 'network_admin_notices', 'ewww_image_optimizer_notice_flywheel' );
58
- add_action( 'admin_notices', 'ewww_image_optimizer_notice_flywheel' );
59
- require_once( plugin_dir_path( __FILE__ ) . 'classes/class-ewwwio-install-cloud.php' );
60
- // Loads the plugin translations.
61
- add_action( 'plugins_loaded', 'ewww_image_optimizer_false_init' );
62
  } elseif ( defined( 'WPNET_INIT_PLUGIN_VERSION' ) ) {
63
  add_action( 'network_admin_notices', 'ewww_image_optimizer_notice_wpnetnz' );
64
  add_action( 'admin_notices', 'ewww_image_optimizer_notice_wpnetnz' );
13
  Plugin URI: https://wordpress.org/plugins/ewww-image-optimizer/
14
  Description: Reduce file sizes for images within WordPress including NextGEN Gallery and GRAND FlAGallery. Uses jpegtran, optipng/pngout, and gifsicle.
15
  Author: Exactly WWW
16
+ Version: 5.6.0
17
  Author URI: https://ewww.io/
18
  License: GPLv3
19
  */
53
  require_once( plugin_dir_path( __FILE__ ) . 'classes/class-ewwwio-install-cloud.php' );
54
  // Loads the plugin translations.
55
  add_action( 'plugins_loaded', 'ewww_image_optimizer_false_init' );
 
 
 
 
 
 
56
  } elseif ( defined( 'WPNET_INIT_PLUGIN_VERSION' ) ) {
57
  add_action( 'network_admin_notices', 'ewww_image_optimizer_notice_wpnetnz' );
58
  add_action( 'admin_notices', 'ewww_image_optimizer_notice_wpnetnz' );
includes/eio-tools.js CHANGED
@@ -253,6 +253,61 @@ jQuery(document).ready(function($) {
253
  }
254
  return false;
255
  });
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
256
  $('#ewww-clean-table').submit(function() {
257
  ewww_total_pages = Math.ceil(ewww_vars.image_count / 500);
258
  $('.ewww-tool-info').hide();
253
  }
254
  return false;
255
  });
256
+ var ewww_total_converted = 0;
257
+ $('#ewww-clean-converted').submit(function() {
258
+ var ewww_converted_data = {
259
+ action: 'bulk_aux_images_count_converted',
260
+ ewww_wpnonce: ewww_vars._wpnonce,
261
+ };
262
+ $.post(ajaxurl, ewww_converted_data, function(response) {
263
+ try {
264
+ var ewww_response = $.parseJSON(response);
265
+ } catch (err) {
266
+ $('#ewww-clean-converted-progress').html('<span style="color: red"><b>' + ewww_vars.invalid_response + '</b></span>');
267
+ console.log( response );
268
+ return false;
269
+ }
270
+ ewww_total_converted = ewww_response.total_converted;
271
+ $('.ewww-tool-info').hide();
272
+ $('.ewww-tool-form').hide();
273
+ $('.ewww-tool-divider').hide();
274
+ $('#ewww-clean-converted-progressbar').progressbar({ max: ewww_total_converted });
275
+ $('#ewww-clean-converted-progress').html('<p> 0/' + ewww_total_converted + '</p>');
276
+ $('#ewww-clean-converted-progressbar').show();
277
+ $('#ewww-clean-converted-progress').show();
278
+ ewwwRemoveOriginals(0);
279
+ });
280
+ return false;
281
+ });
282
+ function ewwwRemoveOriginals(converted_offset){
283
+ var ewww_converted_data = {
284
+ action: 'bulk_aux_images_converted_clean',
285
+ ewww_wpnonce: ewww_vars._wpnonce,
286
+ };
287
+ $.post(ajaxurl, ewww_converted_data, function(response) {
288
+ try {
289
+ var ewww_response = $.parseJSON(response);
290
+ } catch (err) {
291
+ $('#ewww-clean-converted-progressbar').hide();
292
+ $('#ewww-clean-converted-progress').html('<span style="color: red"><b>' + ewww_vars.invalid_response + '</b></span>');
293
+ console.log( response );
294
+ return false;
295
+ }
296
+ if ( ewww_response.error ) {
297
+ $('#ewww-clean-converted-progressbar').hide();
298
+ $('#ewww-clean-converted-progress').html('<span style="color: red"><b>' + ewww_response.error + '</b></span>');
299
+ return false;
300
+ }
301
+ if(ewww_response.finished) {
302
+ $('#ewww-clean-converted-progress').html(ewww_vars.finished);
303
+ return false;
304
+ }
305
+ converted_offset += ewww_response.completed;
306
+ $('#ewww-clean-converted-progressbar').progressbar("option", "value", converted_offset);
307
+ $('#ewww-clean-converted-progress').html('<p>' + converted_offset + '/' + ewww_total_converted + '</p>');
308
+ ewwwRemoveOriginals(converted_offset);
309
+ });
310
+ }
311
  $('#ewww-clean-table').submit(function() {
312
  ewww_total_pages = Math.ceil(ewww_vars.image_count / 500);
313
  $('.ewww-tool-info').hide();
includes/media.js CHANGED
@@ -7,6 +7,7 @@ jQuery(document).on('click', '.ewww-manual-optimize', function() {
7
  ewww_force: 1,
8
  ewww_attachment_ID: post_id,
9
  };
 
10
  jQuery('#ewww-media-status-' + post_id ).html( ewww_vars.optimizing );
11
  jQuery.post(ajaxurl, ewww_manual_optimize_data, function(response) {
12
  var ewww_manual_response = jQuery.parseJSON(response);
@@ -32,6 +33,7 @@ jQuery(document).on('click', '.ewww-manual-convert', function() {
32
  ewww_convert: 1,
33
  ewww_attachment_ID: post_id,
34
  };
 
35
  jQuery('#ewww-media-status-' + post_id ).html( ewww_vars.optimizing );
36
  jQuery.post(ajaxurl, ewww_manual_optimize_data, function(response) {
37
  var ewww_manual_response = jQuery.parseJSON(response);
@@ -55,6 +57,7 @@ jQuery(document).on('click', '.ewww-manual-restore', function() {
55
  ewww_manual_nonce: ewww_nonce,
56
  ewww_attachment_ID: post_id,
57
  };
 
58
  jQuery('#ewww-media-status-' + post_id ).html( ewww_vars.restoring );
59
  jQuery.post(ajaxurl, ewww_manual_optimize_data, function(response) {
60
  var ewww_manual_response = jQuery.parseJSON(response);
@@ -78,6 +81,7 @@ jQuery(document).on('click', '.ewww-manual-cloud-restore', function() {
78
  ewww_manual_nonce: ewww_nonce,
79
  ewww_attachment_ID: post_id,
80
  };
 
81
  jQuery('#ewww-media-status-' + post_id ).html( ewww_vars.restoring );
82
  jQuery.post(ajaxurl, ewww_manual_optimize_data, function(response) {
83
  var ewww_manual_response = jQuery.parseJSON(response);
7
  ewww_force: 1,
8
  ewww_attachment_ID: post_id,
9
  };
10
+ post_id = jQuery(this).closest('.ewww-media-status').data('id');
11
  jQuery('#ewww-media-status-' + post_id ).html( ewww_vars.optimizing );
12
  jQuery.post(ajaxurl, ewww_manual_optimize_data, function(response) {
13
  var ewww_manual_response = jQuery.parseJSON(response);
33
  ewww_convert: 1,
34
  ewww_attachment_ID: post_id,
35
  };
36
+ post_id = jQuery(this).closest('.ewww-media-status').data('id');
37
  jQuery('#ewww-media-status-' + post_id ).html( ewww_vars.optimizing );
38
  jQuery.post(ajaxurl, ewww_manual_optimize_data, function(response) {
39
  var ewww_manual_response = jQuery.parseJSON(response);
57
  ewww_manual_nonce: ewww_nonce,
58
  ewww_attachment_ID: post_id,
59
  };
60
+ post_id = jQuery(this).closest('.ewww-media-status').data('id');
61
  jQuery('#ewww-media-status-' + post_id ).html( ewww_vars.restoring );
62
  jQuery.post(ajaxurl, ewww_manual_optimize_data, function(response) {
63
  var ewww_manual_response = jQuery.parseJSON(response);
81
  ewww_manual_nonce: ewww_nonce,
82
  ewww_attachment_ID: post_id,
83
  };
84
+ post_id = jQuery(this).closest('.ewww-media-status').data('id');
85
  jQuery('#ewww-media-status-' + post_id ).html( ewww_vars.restoring );
86
  jQuery.post(ajaxurl, ewww_manual_optimize_data, function(response) {
87
  var ewww_manual_response = jQuery.parseJSON(response);
readme.txt CHANGED
@@ -5,7 +5,7 @@ Tags: optimize, image, convert, webp, resize, compress, lazy load, optimization,
5
  Requires at least: 5.0
6
  Tested up to: 5.4
7
  Requires PHP: 5.6
8
- Stable tag: 5.5.0
9
  License: GPLv3
10
 
11
  Speed up your website to better connect with your visitors. Properly compress and size/scale images. Includes lazy load and WebP convert.
@@ -173,6 +173,15 @@ https://developers.google.com/web/tools/lighthouse/audits/optimize-images
173
  * Feature requests can be viewed and submitted at https://feedback.ewww.io
174
  * If you would like to help translate this plugin in your language, get started here: https://translate.wordpress.org/projects/wp-plugins/ewww-image-optimizer/
175
 
 
 
 
 
 
 
 
 
 
176
  = 5.5.0 =
177
  * added: GIF to WebP conversion with API and Easy IO
178
  * changed: plugin removed from disallowed list on WP Engine!
5
  Requires at least: 5.0
6
  Tested up to: 5.4
7
  Requires PHP: 5.6
8
+ Stable tag: 5.6.0
9
  License: GPLv3
10
 
11
  Speed up your website to better connect with your visitors. Properly compress and size/scale images. Includes lazy load and WebP convert.
173
  * Feature requests can be viewed and submitted at https://feedback.ewww.io
174
  * If you would like to help translate this plugin in your language, get started here: https://translate.wordpress.org/projects/wp-plugins/ewww-image-optimizer/
175
 
176
+ = 5.6.0 =
177
+ * added: if exec() is disabled, free cloud-based JPG compression will be enabled
178
+ * added: tool to remove originals for converted images
179
+ * changed: improved handling of WPML replicas in media library list mode and bulk optimizer
180
+ * fixed: JS WebP, picture WebP, and Easy IO errors with WP Offload Media 2.4
181
+ * fixed: JS WebP cannot find local paths when WP_CONTENT_DIR is outside ABSPATH
182
+ * fixed: Easy IO hard crops images when requested height/width is 9999
183
+ * fixed: Lazy Load and WebP parsers running on customizer preview pane
184
+
185
  = 5.5.0 =
186
  * added: GIF to WebP conversion with API and Easy IO
187
  * changed: plugin removed from disallowed list on WP Engine!
unique.php CHANGED
@@ -49,7 +49,13 @@ function ewww_image_optimizer_exec_init() {
49
  if ( EWWW_IMAGE_OPTIMIZER_CLOUD ) {
50
  ewwwio_debug_message( 'cloud options enabled, shutting off binaries' );
51
  ewww_image_optimizer_disable_tools();
52
- } elseif ( defined( 'WPCOMSH_VERSION' ) || ! empty( $_ENV['PANTHEON_ENVIRONMENT'] ) || defined( 'WPE_PLUGIN_VERSION' ) ) {
 
 
 
 
 
 
53
  if (
54
  ! ewww_image_optimizer_get_option( 'ewww_image_optimizer_cloud_key' ) &&
55
  ( ! is_object( $exactdn ) || ! $exactdn->get_exactdn_domain() )
@@ -60,7 +66,7 @@ function ewww_image_optimizer_exec_init() {
60
  if ( ! defined( 'EWWW_IMAGE_OPTIMIZER_NOEXEC' ) ) {
61
  define( 'EWWW_IMAGE_OPTIMIZER_NOEXEC', true );
62
  }
63
- ewwwio_debug_message( 'WPE/wp.com/pantheon site, disabling tools' );
64
  ewww_image_optimizer_disable_tools();
65
  // Check if this is an unsupported OS (not Linux or Mac OSX or FreeBSD or Windows or SunOS).
66
  } elseif ( 'Linux' !== PHP_OS && 'Darwin' !== PHP_OS && 'FreeBSD' !== PHP_OS && 'WINNT' !== PHP_OS && 'SunOS' !== PHP_OS ) {
@@ -160,14 +166,38 @@ function ewww_image_optimizer_notice_hosting_requires_api() {
160
  $webhost = 'Pantheon';
161
  } elseif ( defined( 'WPE_PLUGIN_VERSION' ) ) {
162
  $webhost = 'WP Engine';
 
 
 
 
163
  } else {
164
  return;
165
  }
166
- echo "<div id='ewww-image-optimizer-cloud-key-required' class='notice notice-warning'><p><strong>" .
 
 
 
167
  /* translators: %s: Name of a web host, like WordPress.com or Pantheon. */
168
- sprintf( esc_html__( 'The EWWW Image Optimizer needs an API key or Easy IO subscription to optimize images on %s sites.', 'ewww-image-optimizer-cloud' ), esc_html( $webhost ) ) .
169
- "</strong> <a href='https://ewww.io/plans/'>" . esc_html__( 'Start your trial.', 'ewww-image-optimizer-cloud' ) .
170
- "</a> <a href='" . esc_url( $settings_url ) . "'>" . esc_html__( 'Then, activate it on the settings page.', 'ewww-image-optimizer-cloud' ) . '</a></p></div>';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
171
  }
172
 
173
  /**
@@ -177,7 +207,9 @@ function ewww_image_optimizer_notice_os() {
177
  ewwwio_debug_message( '<b>' . __FUNCTION__ . '()</b>' );
178
  echo "<div id='ewww-image-optimizer-warning-os' class='notice notice-error'><p><strong>" .
179
  esc_html__( 'The free mode of EWWW Image Optimizer is only supported on Linux, FreeBSD, Mac OSX, Solaris, and Windows.', 'ewww-image-optimizer' ) .
180
- '</strong></p></div>';
 
 
181
  }
182
 
183
  /**
@@ -450,7 +482,7 @@ function ewww_image_optimizer_skip_tools() {
450
  $skip['pngquant'] = true;
451
  $skip['webp'] = true;
452
  // If the user has disabled a tool, we aren't going to bother checking to see if it is there.
453
- if ( ! ewww_image_optimizer_get_option( 'ewww_image_optimizer_jpg_level' ) || ewww_image_optimizer_get_option( 'ewww_image_optimizer_jpg_level' ) > 10 ) {
454
  $skip['jpegtran'] = true;
455
  }
456
  if ( ! ewww_image_optimizer_get_option( 'ewww_image_optimizer_png_level' ) || ( ewww_image_optimizer_get_option( 'ewww_image_optimizer_cloud_key' ) && ewww_image_optimizer_get_option( 'ewww_image_optimizer_png_level' ) > 10 ) ) {
@@ -503,10 +535,12 @@ function ewww_image_optimizer_dismiss_exec_notice() {
503
  if ( ! current_user_can( apply_filters( 'ewww_image_optimizer_admin_permissions', 'manage_options' ) ) ) {
504
  wp_die( esc_html__( 'Access denied.', 'ewww-image-optimizer' ) );
505
  }
506
- update_option( 'ewww_image_optimizer_jpg_level', 0 );
507
  update_option( 'ewww_image_optimizer_png_level', 0 );
508
  update_option( 'ewww_image_optimizer_gif_level', 0 );
509
  update_option( 'ewww_image_optimizer_pdf_level', 0 );
 
 
510
  wp_die();
511
  }
512
 
@@ -519,42 +553,42 @@ function ewww_image_optimizer_notice_utils( $quiet = null ) {
519
  ewwwio_debug_message( '<b>' . __FUNCTION__ . '()</b>' );
520
  // Check if exec is disabled.
521
  if ( ewww_image_optimizer_exec_check() ) {
522
- $no_compression = false;
523
- if (
524
- ! ewww_image_optimizer_get_option( 'ewww_image_optimizer_jpg_level' ) &&
525
- ! ewww_image_optimizer_get_option( 'ewww_image_optimizer_png_level' ) &&
526
- ! ewww_image_optimizer_get_option( 'ewww_image_optimizer_gif_level' )
527
- ) {
528
- $no_compression = true;
529
- }
530
  // Need to be a little particular with the quiet parameter.
531
- if ( 'quiet' !== $quiet && ! $no_compression ) {
532
  $exactdn_dismiss = ewww_image_optimizer_get_option( 'ewww_image_optimizer_exactdn' ) ? true : false;
533
  ob_start();
534
- $notice_class = 'notice notice-error';
535
  $notice_action = __( 'An API key or Easy IO subscription will allow you to offload the compression to our dedicated servers instead.', 'ewww-image-optimizer' );
 
 
536
  if ( ewww_image_optimizer_get_option( 'ewww_image_optimizer_exactdn' ) ) {
537
- $notice_class = 'notice notice-warning is-dismissible';
538
  $notice_action = __( 'Sites that use Easy IO already have built-in image optimization and may dismiss this notice to disable local compression.', 'ewww-image-optimizer' );
539
  }
540
  // Display a warning if exec() is disabled, can't run local tools without it.
541
  echo "<div id='ewww-image-optimizer-warning-exec' class='" . esc_attr( $notice_class ) . "'><p>" .
542
- esc_html__( 'EWWW Image Optimizer requires exec() to perform local compression. Your system administrator has disabled the exec() function, ask them to enable it.', 'ewww-image-optimizer' ) . '<br>' .
543
- esc_html( $notice_action ) .
544
- '</p></div>';
545
- echo
546
- "<script>\n" .
547
- "jQuery(document).on('click', '#ewww-image-optimizer-warning-exec .notice-dismiss', function() {\n" .
548
- "\tvar ewww_dismiss_exec_data = {\n" .
549
- "\t\taction: 'ewww_dismiss_exec_notice',\n" .
550
- "\t};\n" .
551
- "\tjQuery.post(ajaxurl, ewww_dismiss_exec_data, function(response) {\n" .
552
- "\t\tif (response) {\n" .
553
- "\t\t\tconsole.log(response);\n" .
554
- "\t\t}\n" .
555
- "\t});\n" .
556
- "});\n" .
557
- "</script>\n";
 
 
 
 
 
 
 
558
  if (
559
  ewww_image_optimizer_get_option( 'ewww_image_optimizer_exactdn' ) &&
560
  ! ewww_image_optimizer_get_option( 'ewww_image_optimizer_local_mode' )
@@ -1903,6 +1937,10 @@ function ewww_image_optimizer( $file, $gallery_type = 4, $converted = false, $ne
1903
  }
1904
  break;
1905
  }
 
 
 
 
1906
  // If we get this far, we are using local (jpegtran) optimization, so do an autorotate on the image.
1907
  ewww_image_optimizer_autorotate( $file );
1908
  // Get the (possibly new) original image size.
49
  if ( EWWW_IMAGE_OPTIMIZER_CLOUD ) {
50
  ewwwio_debug_message( 'cloud options enabled, shutting off binaries' );
51
  ewww_image_optimizer_disable_tools();
52
+ } elseif (
53
+ defined( 'WPCOMSH_VERSION' ) ||
54
+ ! empty( $_ENV['PANTHEON_ENVIRONMENT'] ) ||
55
+ defined( 'WPE_PLUGIN_VERSION' ) ||
56
+ defined( 'FLYWHEEL_CONFIG_DIR' ) ||
57
+ defined( 'KINSTAMU_VERSION' )
58
+ ) {
59
  if (
60
  ! ewww_image_optimizer_get_option( 'ewww_image_optimizer_cloud_key' ) &&
61
  ( ! is_object( $exactdn ) || ! $exactdn->get_exactdn_domain() )
66
  if ( ! defined( 'EWWW_IMAGE_OPTIMIZER_NOEXEC' ) ) {
67
  define( 'EWWW_IMAGE_OPTIMIZER_NOEXEC', true );
68
  }
69
+ ewwwio_debug_message( 'WPE/wp.com/pantheon/flywheel site, disabling tools' );
70
  ewww_image_optimizer_disable_tools();
71
  // Check if this is an unsupported OS (not Linux or Mac OSX or FreeBSD or Windows or SunOS).
72
  } elseif ( 'Linux' !== PHP_OS && 'Darwin' !== PHP_OS && 'FreeBSD' !== PHP_OS && 'WINNT' !== PHP_OS && 'SunOS' !== PHP_OS ) {
166
  $webhost = 'Pantheon';
167
  } elseif ( defined( 'WPE_PLUGIN_VERSION' ) ) {
168
  $webhost = 'WP Engine';
169
+ } elseif ( defined( 'FLYWHEEL_CONFIG_DIR' ) ) {
170
+ $webhost = 'Flywheel';
171
+ } elseif ( defined( 'KINSTAMU_VERSION' ) ) {
172
+ $webhost = 'Kinsta';
173
  } else {
174
  return;
175
  }
176
+ if ( ewww_image_optimizer_get_option( 'ewww_image_optimizer_dismiss_exec_notice' ) ) {
177
+ return;
178
+ }
179
+ echo "<div id='ewww-image-optimizer-warning-exec' class='notice notice-warning is-dismissible'><p>" .
180
  /* translators: %s: Name of a web host, like WordPress.com or Pantheon. */
181
+ sprintf( esc_html__( 'Normally, %s sites require cloud-based optimization, because server-based optimization is disallowed. However, we are trying something new, and offering free cloud-based JPG compression. Those who upgrade to our premium service receive much higher compression, PNG/GIF/PDF compression, WebP conversion, and image backups.', 'ewww-image-optimizer' ), esc_html( $webhost ) ) .
182
+ '<br><strong>' .
183
+ /* translators: %s: link to 'start your free trial' */
184
+ sprintf( esc_html__( 'Dismiss this notice to continue with free cloud-based JPG compression or %s.', 'ewww-image-optimizer' ), "<a href='https://ewww.io/plans/'>" . esc_html__( 'start your premium trial', 'ewww-image-optimizer' ) . '</a>' );
185
+ ewwwio_help_link( 'https://docs.ewww.io/article/29-what-is-exec-and-why-do-i-need-it', '592dd12d0428634b4a338c39' );
186
+ echo '</strong></p></div>';
187
+ ?>
188
+ <script>
189
+ jQuery(document).on('click', '#ewww-image-optimizer-warning-exec .notice-dismiss', function() {
190
+ var ewww_dismiss_exec_data = {
191
+ action: 'ewww_dismiss_exec_notice',
192
+ };
193
+ jQuery.post(ajaxurl, ewww_dismiss_exec_data, function(response) {
194
+ if (response) {
195
+ console.log(response);
196
+ }
197
+ });
198
+ });
199
+ </script>
200
+ <?php
201
  }
202
 
203
  /**
207
  ewwwio_debug_message( '<b>' . __FUNCTION__ . '()</b>' );
208
  echo "<div id='ewww-image-optimizer-warning-os' class='notice notice-error'><p><strong>" .
209
  esc_html__( 'The free mode of EWWW Image Optimizer is only supported on Linux, FreeBSD, Mac OSX, Solaris, and Windows.', 'ewww-image-optimizer' ) .
210
+ '</strong><br>' .
211
+ "<a href='https://ewww.io/plans/'>" . esc_html__( 'Visit our site to start your free trial with cloud-based optimization.', 'ewww-image-optimizer' ) . '</a>' .
212
+ '</p></div>';
213
  }
214
 
215
  /**
482
  $skip['pngquant'] = true;
483
  $skip['webp'] = true;
484
  // If the user has disabled a tool, we aren't going to bother checking to see if it is there.
485
+ if ( ! ewww_image_optimizer_get_option( 'ewww_image_optimizer_jpg_level' ) || ewww_image_optimizer_get_option( 'ewww_image_optimizer_jpg_level' ) > 10 || ( defined( 'EWWW_IMAGE_OPTIMIZER_NOEXEC' ) && EWWW_IMAGE_OPTIMIZER_NOEXEC ) ) {
486
  $skip['jpegtran'] = true;
487
  }
488
  if ( ! ewww_image_optimizer_get_option( 'ewww_image_optimizer_png_level' ) || ( ewww_image_optimizer_get_option( 'ewww_image_optimizer_cloud_key' ) && ewww_image_optimizer_get_option( 'ewww_image_optimizer_png_level' ) > 10 ) ) {
535
  if ( ! current_user_can( apply_filters( 'ewww_image_optimizer_admin_permissions', 'manage_options' ) ) ) {
536
  wp_die( esc_html__( 'Access denied.', 'ewww-image-optimizer' ) );
537
  }
538
+ update_option( 'ewww_image_optimizer_jpg_level', 10 );
539
  update_option( 'ewww_image_optimizer_png_level', 0 );
540
  update_option( 'ewww_image_optimizer_gif_level', 0 );
541
  update_option( 'ewww_image_optimizer_pdf_level', 0 );
542
+ update_option( 'ewww_image_optimizer_dismiss_exec_notice', 1 );
543
+ update_site_option( 'ewww_image_optimizer_dismiss_exec_notice', 1 );
544
  wp_die();
545
  }
546
 
553
  ewwwio_debug_message( '<b>' . __FUNCTION__ . '()</b>' );
554
  // Check if exec is disabled.
555
  if ( ewww_image_optimizer_exec_check() ) {
 
 
 
 
 
 
 
 
556
  // Need to be a little particular with the quiet parameter.
557
+ if ( 'quiet' !== $quiet && ! ewww_image_optimizer_get_option( 'ewww_image_optimizer_dismiss_exec_notice' ) ) {
558
  $exactdn_dismiss = ewww_image_optimizer_get_option( 'ewww_image_optimizer_exactdn' ) ? true : false;
559
  ob_start();
560
+ $notice_class = 'notice notice-warning is-dismissible';
561
  $notice_action = __( 'An API key or Easy IO subscription will allow you to offload the compression to our dedicated servers instead.', 'ewww-image-optimizer' );
562
+ /* translators: %s: link to 'start your free trial' */
563
+ $notice_action = sprintf( __( 'You may ask your system administrator to enable exec(), dismiss this notice to continue with free cloud-based compression or %s.', 'ewww-image-optimizer' ), "<a href='https://ewww.io/plans/'>" . __( 'start your premium trial', 'ewww-image-optimizer' ) . '</a>' ) . '</p></div>';
564
  if ( ewww_image_optimizer_get_option( 'ewww_image_optimizer_exactdn' ) ) {
 
565
  $notice_action = __( 'Sites that use Easy IO already have built-in image optimization and may dismiss this notice to disable local compression.', 'ewww-image-optimizer' );
566
  }
567
  // Display a warning if exec() is disabled, can't run local tools without it.
568
  echo "<div id='ewww-image-optimizer-warning-exec' class='" . esc_attr( $notice_class ) . "'><p>" .
569
+ esc_html__( ' Normally, sites where the exec() function is banned require cloud-based optimization, because free server-based optimization will not work. However, we are trying something new, and offering free cloud-based JPG compression. Those who upgrade to our premium service receive much higher compression, PNG/GIF/PDF compression, WebP conversion, and image backups.', 'ewww-image-optimizer' ) . '<br>' .
570
+ '<strong>' .
571
+ ( ewww_image_optimizer_get_option( 'ewww_image_optimizer_exactdn' ) || get_option( 'easyio_exactdn' ) ?
572
+ esc_html__( 'Sites that use Easy IO already have built-in image optimization and may dismiss this notice to disable local compression.', 'ewww-image-optimizer' )
573
+ :
574
+ /* translators: %s: link to 'start your free trial' */
575
+ sprintf( esc_html__( 'You may ask your system administrator to enable exec(), dismiss this notice to continue with free cloud-based compression or %s.', 'ewww-image-optimizer' ), "<a href='https://ewww.io/plans/'>" . esc_html__( 'start your premium trial', 'ewww-image-optimizer' ) . '</a>' )
576
+ );
577
+ ewwwio_help_link( 'https://docs.ewww.io/article/29-what-is-exec-and-why-do-i-need-it', '592dd12d0428634b4a338c39' );
578
+ echo '</strong></p></div>';
579
+ echo
580
+ "<script>\n" .
581
+ "jQuery(document).on('click', '#ewww-image-optimizer-warning-exec .notice-dismiss', function() {\n" .
582
+ "\tvar ewww_dismiss_exec_data = {\n" .
583
+ "\t\taction: 'ewww_dismiss_exec_notice',\n" .
584
+ "\t};\n" .
585
+ "\tjQuery.post(ajaxurl, ewww_dismiss_exec_data, function(response) {\n" .
586
+ "\t\tif (response) {\n" .
587
+ "\t\t\tconsole.log(response);\n" .
588
+ "\t\t}\n" .
589
+ "\t});\n" .
590
+ "});\n" .
591
+ "</script>\n";
592
  if (
593
  ewww_image_optimizer_get_option( 'ewww_image_optimizer_exactdn' ) &&
594
  ! ewww_image_optimizer_get_option( 'ewww_image_optimizer_local_mode' )
1937
  }
1938
  break;
1939
  }
1940
+ if ( 10 === (int) $compression_level && EWWW_IMAGE_OPTIMIZER_NOEXEC ) {
1941
+ list( $file, $converted, $result, $new_size, $backup_hash ) = ewww_image_optimizer_cloud_optimizer( $file, $type );
1942
+ break;
1943
+ }
1944
  // If we get this far, we are using local (jpegtran) optimization, so do an autorotate on the image.
1945
  ewww_image_optimizer_autorotate( $file );
1946
  // Get the (possibly new) original image size.