EWWW Image Optimizer - Version 5.4.1

Version Description

  • fixed: Bulk Optimizer sticks on stage 2 when there are no images to optimize
  • fixed: transparency in PNG images with color type 0 or 2 not detected
  • fixed: transparency false positives for PNG images with color types 4 and 6
  • fixed: lazy load skips img elements with unquoted src attributes
  • fixed: images converted by PNG to JPG (and friends) do not have restore links in library
Download this release

Release Info

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

Code changes from version 5.3.2 to 5.4.1

.travis.yml CHANGED
@@ -46,7 +46,7 @@ before_script:
46
  composer global require phpunit/phpunit ^7
47
  fi
48
  - |
49
- - composer global require squizlabs/php_codesniffer:3.5.0 wp-coding-standards/wpcs dealerdirect/phpcodesniffer-composer-installer
50
 
51
  script:
52
  - if [[ "$WPSNIFF" == "1" ]]; then phpcs --standard=phpcs.ruleset.xml --extensions=php .; fi
46
  composer global require phpunit/phpunit ^7
47
  fi
48
  - |
49
+ - composer global require squizlabs/php_codesniffer:3.5.0 wp-coding-standards/wpcs dealerdirect/phpcodesniffer-composer-installer phpcompatibility/phpcompatibility-wp
50
 
51
  script:
52
  - if [[ "$WPSNIFF" == "1" ]]; then phpcs --standard=phpcs.ruleset.xml --extensions=php .; fi
aux-optimize.php CHANGED
@@ -27,37 +27,44 @@ function ewww_image_optimizer_aux_images() {
27
 
28
  global $eio_debug;
29
  if ( ewww_image_optimizer_get_option( 'ewww_image_optimizer_debug' ) ) {
30
- ewww_image_optimizer_options( 'debug-silent' );
31
- $output .= '<div style="clear:both;"></div>';
32
- $output .= '<p><b>' . esc_html__( 'Debugging Information', 'ewww-image-optimizer' ) . ':</b> <button id="ewww-copy-debug" class="button button-secondary" type="button">' . esc_html__( 'Copy', 'ewww-image-optimizer' ) . '</button>';
33
  if ( ewwwio_is_file( WP_CONTENT_DIR . '/ewww/debug.log' ) ) {
34
- $output .= "&emsp;<a href='" . admin_url( 'admin.php?action=ewww_image_optimizer_view_debug_log' ) . "'>" .
35
  esc_html( 'View Debug Log', 'ewww-image-optimizer' ) . "</a> - <a href='" .
36
- admin_url( 'admin.php?action=ewww_image_optimizer_delete_debug_log' ) . "'>" .
37
  esc_html( 'Remove Debug Log', 'ewww-image-optimizer' ) . '</a>';
38
  }
39
- $output .= '</p>';
40
- $output .= '<div id="ewww-debug-info" contenteditable="true">' . $eio_debug . '</div>';
 
 
 
 
 
 
 
 
41
  } else {
42
  ewww_image_optimizer_set_option( 'ewww_image_optimizer_debug', true );
43
- ewww_image_optimizer_options( 'debug-silent' );
44
  ewww_image_optimizer_set_option( 'ewww_image_optimizer_debug', false );
45
  }
46
- echo $output;
47
  if ( ewww_image_optimizer_get_option( 'ewww_image_optimizer_enable_help' ) ) {
48
  $current_user = wp_get_current_user();
49
  $help_email = $current_user->user_email;
50
  $hs_debug = '';
51
  if ( ! empty( $eio_debug ) ) {
52
- $hs_debug = str_replace( array( "'", '<br>', '<b>', '</b>' ), array( "\'", '\n', '<', '>' ), $eio_debug );
53
  }
54
  ?>
55
  <script type="text/javascript">!function(e,t,n){function a(){var e=t.getElementsByTagName("script")[0],n=t.createElement("script");n.type="text/javascript",n.async=!0,n.src="https://beacon-v2.helpscout.net",e.parentNode.insertBefore(n,e)}if(e.Beacon=n=function(t,n,a){e.Beacon.readyQueue.push({method:t,options:n,data:a})},n.readyQueue=[],"complete"===t.readyState)return a();e.attachEvent?e.attachEvent("onload",a):e.addEventListener("load",a,!1)}(window,document,window.Beacon||function(){});</script>
56
  <script type="text/javascript">
57
  window.Beacon('init', 'aa9c3d3b-d4bc-4e9b-b6cb-f11c9f69da87');
58
  Beacon( 'prefill', {
59
- email: '<?php echo utf8_encode( $help_email ); ?>',
60
- text: '\n\n----------------------------------------\n<?php echo $hs_debug; ?>',
61
  });
62
  </script>
63
  <?php
@@ -77,9 +84,9 @@ function ewww_image_optimizer_aux_images() {
77
  function ewww_image_optimizer_aux_images_table() {
78
  // Verify that an authorized user has called function.
79
  $permissions = apply_filters( 'ewww_image_optimizer_bulk_permissions', '' );
80
- if ( ! wp_verify_nonce( $_REQUEST['ewww_wpnonce'], 'ewww-image-optimizer-tools' ) || ! current_user_can( $permissions ) ) {
81
  ewwwio_ob_clean();
82
- die( ewwwio_json_encode( array( 'error' => esc_html__( 'Access token has expired, please reload the page.', 'ewww-image-optimizer' ) ) ) );
83
  }
84
  global $wpdb;
85
  if ( strpos( $wpdb->charset, 'utf8' ) === false ) {
@@ -90,9 +97,9 @@ function ewww_image_optimizer_aux_images_table() {
90
  }
91
  $debug_query = ! empty( $_REQUEST['ewww_debug'] ) ? 1 : 0;
92
  $per_page = 50;
93
- $offset = $per_page * (int) $_POST['ewww_offset'];
94
- $search = sanitize_text_field( $_POST['ewww_search'] );
95
- $total = (int) $_POST['ewww_total_pages'];
96
  $output = array();
97
  if ( ! empty( $search ) ) {
98
  $already_optimized = $ewwwdb->get_results( $ewwwdb->prepare( "SELECT path,orig_size,image_size,id,backup,attachment_id,gallery,updates,trace,UNIX_TIMESTAMP(updated) AS updated FROM $ewwwdb->ewwwio_images WHERE pending=0 AND image_size > 0 AND updates > %d AND path LIKE %s ORDER BY " . ( $debug_query ? 'updates,id' : 'id' ) . ' DESC LIMIT %d,%d', $debug_query, '%' . $ewwwdb->esc_like( $search ) . '%', $offset, $per_page ), ARRAY_A );
@@ -288,7 +295,7 @@ function ewww_image_optimizer_aux_images_table() {
288
  } // End if().
289
  } // End foreach().
290
  $output['table'] .= '</table>';
291
- die( ewwwio_json_encode( $output ) );
292
  }
293
 
294
  /**
@@ -302,16 +309,21 @@ function ewww_image_optimizer_aux_images_table() {
302
  function ewww_image_optimizer_aux_images_remove() {
303
  // Verify that an authorized user has called function.
304
  $permissions = apply_filters( 'ewww_image_optimizer_bulk_permissions', '' );
305
- if ( ! wp_verify_nonce( $_REQUEST['ewww_wpnonce'], 'ewww-image-optimizer-tools' ) || ! current_user_can( $permissions ) ) {
306
  ewwwio_ob_clean();
307
  die( esc_html__( 'Access token has expired, please reload the page.', 'ewww-image-optimizer' ) );
308
  }
309
  ewwwio_ob_clean();
310
  global $wpdb;
 
 
 
 
 
311
  if ( $wpdb->delete(
312
  $wpdb->ewwwio_images,
313
  array(
314
- 'id' => $_POST['ewww_image_id'],
315
  )
316
  ) ) {
317
  echo '1';
@@ -330,7 +342,7 @@ function ewww_image_optimizer_aux_images_remove() {
330
  function ewww_image_optimizer_aux_images_clear_all() {
331
  // Verify that an authorized user has called function.
332
  $permissions = apply_filters( 'ewww_image_optimizer_admin_permissions', '' );
333
- if ( ! wp_verify_nonce( $_REQUEST['ewww_wpnonce'], 'ewww-image-optimizer-tools' ) || ! current_user_can( $permissions ) ) {
334
  ewwwio_ob_clean();
335
  die( esc_html__( 'Access token has expired, please reload the page.', 'ewww-image-optimizer' ) );
336
  }
@@ -355,9 +367,9 @@ function ewww_image_optimizer_aux_images_clean() {
355
  ewwwio_debug_message( '<b>' . __FUNCTION__ . '()</b>' );
356
  // Verify that an authorized user has called function.
357
  $permissions = apply_filters( 'ewww_image_optimizer_bulk_permissions', '' );
358
- if ( ! wp_verify_nonce( $_REQUEST['ewww_wpnonce'], 'ewww-image-optimizer-tools' ) || ! current_user_can( $permissions ) ) {
359
  ewwwio_ob_clean();
360
- die( ewwwio_json_encode( array( 'error' => esc_html__( 'Access token has expired, please reload the page.', 'ewww-image-optimizer' ) ) ) );
361
  }
362
  global $wpdb;
363
  if ( strpos( $wpdb->charset, 'utf8' ) === false ) {
@@ -367,7 +379,7 @@ function ewww_image_optimizer_aux_images_clean() {
367
  $ewwwdb = $wpdb;
368
  }
369
  $per_page = 500;
370
- $offset = $per_page * (int) $_POST['ewww_offset'];
371
 
372
  $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 );
373
 
@@ -389,7 +401,7 @@ function ewww_image_optimizer_aux_images_clean() {
389
  );
390
  }
391
  } // End foreach().
392
- die( ewwwio_json_encode( array( 'success' => 1 ) ) );
393
  }
394
 
395
  /**
@@ -401,9 +413,9 @@ function ewww_image_optimizer_aux_meta_clean() {
401
  ewwwio_debug_message( '<b>' . __FUNCTION__ . '()</b>' );
402
  // Verify that an authorized user has called function.
403
  $permissions = apply_filters( 'ewww_image_optimizer_bulk_permissions', '' );
404
- if ( ! wp_verify_nonce( $_REQUEST['ewww_wpnonce'], 'ewww-image-optimizer-tools' ) || ! current_user_can( $permissions ) ) {
405
  ewwwio_ob_clean();
406
- die( ewwwio_json_encode( array( 'error' => esc_html__( 'Access token has expired, please reload the page.', 'ewww-image-optimizer' ) ) ) );
407
  }
408
  global $wpdb;
409
  if ( strpos( $wpdb->charset, 'utf8' ) === false ) {
@@ -413,7 +425,7 @@ function ewww_image_optimizer_aux_meta_clean() {
413
  $ewwwdb = $wpdb;
414
  }
415
  $per_page = 50;
416
- $offset = (int) $_POST['ewww_offset'];
417
  ewwwio_debug_message( "getting $per_page attachments, starting at $offset" );
418
 
419
  $attachments = $wpdb->get_col(
@@ -426,7 +438,7 @@ function ewww_image_optimizer_aux_meta_clean() {
426
  )
427
  );
428
  if ( empty( $attachments ) ) {
429
- die( ewwwio_json_encode( array( 'done' => 1 ) ) );
430
  }
431
  foreach ( $attachments as $attachment_id ) {
432
  ewwwio_debug_message( "checking $attachment_id for migration" );
@@ -435,7 +447,7 @@ function ewww_image_optimizer_aux_meta_clean() {
435
  ewww_image_optimizer_migrate_meta_to_db( $attachment_id, $meta );
436
  }
437
  }
438
- die( ewwwio_json_encode( array( 'success' => $per_page ) ) );
439
  }
440
 
441
  /**
@@ -448,9 +460,15 @@ function ewww_image_optimizer_aux_meta_clean() {
448
  function ewww_image_optimizer_aux_images_table_count() {
449
  global $wpdb;
450
  $count = $wpdb->get_var( "SELECT COUNT(*) FROM $wpdb->ewwwio_images WHERE pending=0 AND image_size > 0" );
451
- if ( ! empty( $_REQUEST['ewww_inline'] ) ) {
 
 
 
 
 
 
452
  ewwwio_ob_clean();
453
- echo $count;
454
  ewwwio_memory( __FUNCTION__ );
455
  die();
456
  }
@@ -723,6 +741,9 @@ function ewww_image_optimizer_image_scan( $dir, $started = 0 ) {
723
  }
724
  global $wpdb;
725
  global $optimized_list;
 
 
 
726
  $images = array();
727
  $reset_images = array();
728
  if ( ! is_dir( $dir ) ) {
@@ -732,18 +753,6 @@ function ewww_image_optimizer_image_scan( $dir, $started = 0 ) {
732
  ewwwio_debug_message( "scanning folder for images: $dir" );
733
  $iterator = new RecursiveIteratorIterator( new RecursiveDirectoryIterator( $dir ), RecursiveIteratorIterator::CHILD_FIRST, RecursiveIteratorIterator::CATCH_GET_CHILD );
734
  $start = microtime( true );
735
- // Make the Force Re-optimize option persistent.
736
- if ( ! empty( $_REQUEST['ewww_force'] ) ) {
737
- set_transient( 'ewww_image_optimizer_force_reopt', true, HOUR_IN_SECONDS );
738
- } else {
739
- delete_transient( 'ewww_image_optimizer_force_reopt' );
740
- }
741
- // Make the Smart Re-optimize option persistent.
742
- if ( ! empty( $_REQUEST['ewww_force_smart'] ) ) {
743
- set_transient( 'ewww_image_optimizer_smart_reopt', true, HOUR_IN_SECONDS );
744
- } else {
745
- delete_transient( 'ewww_image_optimizer_smart_reopt' );
746
- }
747
  if ( empty( $optimized_list ) || ! is_array( $optimized_list ) ) {
748
  ewww_image_optimizer_optimized_list();
749
  }
@@ -771,7 +780,7 @@ function ewww_image_optimizer_image_scan( $dir, $started = 0 ) {
771
  }
772
  if (
773
  $started &&
774
- ! empty( $_REQUEST['ewww_scan'] ) && 'scheduled' !== $_REQUEST['ewww_scan'] &&
775
  0 === $file_counter % 100 &&
776
  microtime( true ) - $started > apply_filters( 'ewww_image_optimizer_timeout', 15 )
777
  ) {
@@ -784,7 +793,7 @@ function ewww_image_optimizer_image_scan( $dir, $started = 0 ) {
784
  ewwwio_ob_clean();
785
  ewww_image_optimizer_debug_log();
786
  die(
787
- ewwwio_json_encode(
788
  array(
789
  'remaining' => '<p>' . esc_html__( 'Stage 2, please wait.', 'ewww-image-optimizer' ) . "&nbsp;<img src='$loading_image' /></p>",
790
  'notice' => '',
@@ -793,7 +802,7 @@ function ewww_image_optimizer_image_scan( $dir, $started = 0 ) {
793
  );
794
  } elseif (
795
  $started &&
796
- ! empty( $_REQUEST['ewww_scan'] ) && 'scheduled' === $_REQUEST['ewww_scan'] &&
797
  0 === $file_counter % 100 &&
798
  microtime( true ) - $started > apply_filters( 'ewww_image_optimizer_timeout', 15 )
799
  ) {
@@ -811,18 +820,18 @@ function ewww_image_optimizer_image_scan( $dir, $started = 0 ) {
811
  )
812
  )->dispatch();
813
  wp_die();
814
- } elseif ( ! empty( $_REQUEST['ewww_scan'] ) && 'scheduled' === $_REQUEST['ewww_scan'] && get_option( 'ewwwio_stop_scheduled_scan' ) ) {
815
  ewwwio_debug_message( 'ending current scan iteration because of stop_scan' );
816
  delete_option( 'ewwwio_stop_scheduled_scan' );
817
  ewww_image_optimizer_debug_log();
818
  wp_die();
819
  }
820
- if ( ! empty( $_REQUEST['ewww_scan'] ) && 0 === $file_counter % 100 && ! ewwwio_check_memory_available( 2097000 ) ) {
821
  ewwwio_debug_message( 'ending current scan iteration because of memory constraints' );
822
  if ( $file_counter < 100 ) {
823
  ewwwio_ob_clean();
824
  die(
825
- ewwwio_json_encode(
826
  array(
827
  'error' => esc_html__( 'Stage 2 unable to complete due to memory restrictions. Please increase the memory_limit setting for PHP and try again.', 'ewww-image-optimizer' ),
828
  )
@@ -838,7 +847,7 @@ function ewww_image_optimizer_image_scan( $dir, $started = 0 ) {
838
  ewwwio_ob_clean();
839
  ewww_image_optimizer_debug_log();
840
  die(
841
- ewwwio_json_encode(
842
  array(
843
  'remaining' => '<p>' . esc_html__( 'Stage 2, please wait.', 'ewww-image-optimizer' ) . "&nbsp;<img src='$loading_image' /></p>",
844
  'notice' => '',
@@ -888,13 +897,13 @@ function ewww_image_optimizer_image_scan( $dir, $started = 0 ) {
888
  continue;
889
  }
890
  $compression_level = ewww_image_optimizer_get_level( $mime );
891
- if ( ! empty( $_REQUEST['ewww_force_smart'] ) && ewww_image_optimizer_level_mismatch( $already_optimized['level'], $compression_level ) ) {
892
  $reset_images[] = (int) $already_optimized['id'];
893
  ewwwio_debug_message( "smart re-opt found level mismatch for $path, db says " . $already_optimized['level'] . " vs. current $compression_level" );
894
  } elseif ( $should_resize ) {
895
  $reset_images[] = (int) $already_optimized['id'];
896
  ewwwio_debug_message( "resize other existing found candidate for scaling: $path" );
897
- } elseif ( (int) $already_optimized['image_size'] === $image_size && empty( $_REQUEST['ewww_force'] ) ) {
898
  ewwwio_debug_message( "match found for $path" );
899
  continue;
900
  } else {
@@ -1000,18 +1009,7 @@ function ewww_image_optimizer_aux_images_convert() {
1000
  */
1001
  function ewww_image_optimizer_aux_images_script( $hook = '' ) {
1002
  ewwwio_debug_message( '<b>' . __FUNCTION__ . '()</b>' );
1003
- // Make sure we are being called from the proper page.
1004
- if ( wp_doing_ajax() && empty( $_REQUEST['ewww_scan'] ) ) {
1005
- ewwwio_debug_message( 'scan called from ajax with no ewww_scan' );
1006
- return;
1007
- }
1008
  session_write_close();
1009
- if ( ! empty( $_REQUEST['ewww_force'] ) ) {
1010
- ewwwio_debug_message( 'forcing re-optimize: true' );
1011
- }
1012
- if ( ! empty( $_REQUEST['ewww_force_smart'] ) ) {
1013
- ewwwio_debug_message( 'forcing (smart) re-optimize: true' );
1014
- }
1015
  // Retrieve the time when the scan starts.
1016
  $started = microtime( true );
1017
  if ( ! get_transient( 'ewww_image_optimizer_skip_aux' ) ) {
@@ -1138,7 +1136,7 @@ function ewww_image_optimizer_aux_images_script( $hook = '' ) {
1138
  }
1139
  }
1140
  } // End if().
1141
- $image_count = ewww_image_optimizer_aux_images_table_count_pending();
1142
  ewwwio_debug_message( "found $image_count images to optimize while scanning" );
1143
  update_option( 'ewww_image_optimizer_aux_folders_completed', array(), false );
1144
  update_option( 'ewww_image_optimizer_aux_resume', '' );
@@ -1164,12 +1162,12 @@ function ewww_image_optimizer_aux_images_script( $hook = '' ) {
1164
  }
1165
  ewwwio_ob_clean();
1166
  die(
1167
- ewwwio_json_encode(
1168
  array(
1169
  'ready' => $image_count,
1170
  'message' => $ready_msg,
1171
  /* translators: %s: number of images */
1172
- 'start_button' => sprintf( esc_attr__( 'Optimize %s images', 'ewww-image-optimizer' ), number_format_i18n( $image_count ) ),
1173
  )
1174
  )
1175
  );
@@ -1205,7 +1203,7 @@ function ewww_image_optimizer_aux_images_cleanup( $auto = false ) {
1205
  ewwwio_debug_message( '<b>' . __FUNCTION__ . '()</b>' );
1206
  // Verify that an authorized user has started the optimizer.
1207
  $permissions = apply_filters( 'ewww_image_optimizer_bulk_permissions', '' );
1208
- if ( ! $auto && ( ! wp_verify_nonce( $_REQUEST['ewww_wpnonce'], 'ewww-image-optimizer-bulk' ) || ! current_user_can( $permissions ) ) ) {
1209
  ewwwio_ob_clean();
1210
  die( esc_html__( 'Access denied.', 'ewww-image-optimizer' ) );
1211
  }
27
 
28
  global $eio_debug;
29
  if ( ewww_image_optimizer_get_option( 'ewww_image_optimizer_debug' ) ) {
30
+ ewwwio_debug_info();
31
+ echo '<div style="clear:both;"></div>';
32
+ echo '<p><b>' . esc_html__( 'Debugging Information', 'ewww-image-optimizer' ) . ':</b> <button id="ewww-copy-debug" class="button button-secondary" type="button">' . esc_html__( 'Copy', 'ewww-image-optimizer' ) . '</button>';
33
  if ( ewwwio_is_file( WP_CONTENT_DIR . '/ewww/debug.log' ) ) {
34
+ echo "&emsp;<a href='" . esc_url( admin_url( 'admin.php?action=ewww_image_optimizer_view_debug_log' ) ) . "'>" .
35
  esc_html( 'View Debug Log', 'ewww-image-optimizer' ) . "</a> - <a href='" .
36
+ esc_url( admin_url( 'admin.php?action=ewww_image_optimizer_delete_debug_log' ) ) . "'>" .
37
  esc_html( 'Remove Debug Log', 'ewww-image-optimizer' ) . '</a>';
38
  }
39
+ echo '</p>';
40
+ echo '<div id="ewww-debug-info" contenteditable="true">' .
41
+ wp_kses(
42
+ $eio_debug,
43
+ array(
44
+ 'br' => array(),
45
+ 'b' => array(),
46
+ )
47
+ ) .
48
+ '</div>';
49
  } else {
50
  ewww_image_optimizer_set_option( 'ewww_image_optimizer_debug', true );
51
+ ewwwio_debug_info();
52
  ewww_image_optimizer_set_option( 'ewww_image_optimizer_debug', false );
53
  }
 
54
  if ( ewww_image_optimizer_get_option( 'ewww_image_optimizer_enable_help' ) ) {
55
  $current_user = wp_get_current_user();
56
  $help_email = $current_user->user_email;
57
  $hs_debug = '';
58
  if ( ! empty( $eio_debug ) ) {
59
+ $hs_debug = str_replace( array( "'", '<br>', '<b>', '</b>', '=>' ), array( "\'", '\n', '**', '**', '=' ), $eio_debug );
60
  }
61
  ?>
62
  <script type="text/javascript">!function(e,t,n){function a(){var e=t.getElementsByTagName("script")[0],n=t.createElement("script");n.type="text/javascript",n.async=!0,n.src="https://beacon-v2.helpscout.net",e.parentNode.insertBefore(n,e)}if(e.Beacon=n=function(t,n,a){e.Beacon.readyQueue.push({method:t,options:n,data:a})},n.readyQueue=[],"complete"===t.readyState)return a();e.attachEvent?e.attachEvent("onload",a):e.addEventListener("load",a,!1)}(window,document,window.Beacon||function(){});</script>
63
  <script type="text/javascript">
64
  window.Beacon('init', 'aa9c3d3b-d4bc-4e9b-b6cb-f11c9f69da87');
65
  Beacon( 'prefill', {
66
+ email: '<?php echo esc_js( utf8_encode( $help_email ) ); ?>',
67
+ text: '\n\n----------------------------------------\n<?php echo wp_kses_post( $hs_debug ); ?>',
68
  });
69
  </script>
70
  <?php
84
  function ewww_image_optimizer_aux_images_table() {
85
  // Verify that an authorized user has called function.
86
  $permissions = apply_filters( 'ewww_image_optimizer_bulk_permissions', '' );
87
+ if ( empty( $_REQUEST['ewww_wpnonce'] ) || ! wp_verify_nonce( sanitize_key( $_REQUEST['ewww_wpnonce'] ), 'ewww-image-optimizer-tools' ) || ! current_user_can( $permissions ) ) {
88
  ewwwio_ob_clean();
89
+ die( wp_json_encode( array( 'error' => esc_html__( 'Access token has expired, please reload the page.', 'ewww-image-optimizer' ) ) ) );
90
  }
91
  global $wpdb;
92
  if ( strpos( $wpdb->charset, 'utf8' ) === false ) {
97
  }
98
  $debug_query = ! empty( $_REQUEST['ewww_debug'] ) ? 1 : 0;
99
  $per_page = 50;
100
+ $offset = empty( $_POST['ewww_offset'] ) ? 0 : $per_page * (int) $_POST['ewww_offset'];
101
+ $search = empty( $_POST['ewww_search'] ) ? '' : sanitize_text_field( wp_unslash( $_POST['ewww_search'] ) );
102
+ $total = empty( $_POST['ewww_total_pages'] ) ? 0 : (int) $_POST['ewww_total_pages'];
103
  $output = array();
104
  if ( ! empty( $search ) ) {
105
  $already_optimized = $ewwwdb->get_results( $ewwwdb->prepare( "SELECT path,orig_size,image_size,id,backup,attachment_id,gallery,updates,trace,UNIX_TIMESTAMP(updated) AS updated FROM $ewwwdb->ewwwio_images WHERE pending=0 AND image_size > 0 AND updates > %d AND path LIKE %s ORDER BY " . ( $debug_query ? 'updates,id' : 'id' ) . ' DESC LIMIT %d,%d', $debug_query, '%' . $ewwwdb->esc_like( $search ) . '%', $offset, $per_page ), ARRAY_A );
295
  } // End if().
296
  } // End foreach().
297
  $output['table'] .= '</table>';
298
+ die( wp_json_encode( $output ) );
299
  }
300
 
301
  /**
309
  function ewww_image_optimizer_aux_images_remove() {
310
  // Verify that an authorized user has called function.
311
  $permissions = apply_filters( 'ewww_image_optimizer_bulk_permissions', '' );
312
+ if ( empty( $_REQUEST['ewww_wpnonce'] ) || ! wp_verify_nonce( sanitize_key( $_REQUEST['ewww_wpnonce'] ), 'ewww-image-optimizer-tools' ) || ! current_user_can( $permissions ) ) {
313
  ewwwio_ob_clean();
314
  die( esc_html__( 'Access token has expired, please reload the page.', 'ewww-image-optimizer' ) );
315
  }
316
  ewwwio_ob_clean();
317
  global $wpdb;
318
+ if ( empty( $_POST['ewww_image_id'] ) ) {
319
+ die();
320
+ } else {
321
+ $id = (int) $_POST['ewww_image_id'];
322
+ }
323
  if ( $wpdb->delete(
324
  $wpdb->ewwwio_images,
325
  array(
326
+ 'id' => $id,
327
  )
328
  ) ) {
329
  echo '1';
342
  function ewww_image_optimizer_aux_images_clear_all() {
343
  // Verify that an authorized user has called function.
344
  $permissions = apply_filters( 'ewww_image_optimizer_admin_permissions', '' );
345
+ if ( empty( $_REQUEST['ewww_wpnonce'] ) || ! wp_verify_nonce( sanitize_key( $_REQUEST['ewww_wpnonce'] ), 'ewww-image-optimizer-tools' ) || ! current_user_can( $permissions ) ) {
346
  ewwwio_ob_clean();
347
  die( esc_html__( 'Access token has expired, please reload the page.', 'ewww-image-optimizer' ) );
348
  }
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' ) ) ) );
373
  }
374
  global $wpdb;
375
  if ( strpos( $wpdb->charset, 'utf8' ) === false ) {
379
  $ewwwdb = $wpdb;
380
  }
381
  $per_page = 500;
382
+ $offset = empty( $_POST['ewww_offset'] ) ? 0 : $per_page * (int) $_POST['ewww_offset'];
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
 
401
  );
402
  }
403
  } // End foreach().
404
+ die( wp_json_encode( array( 'success' => 1 ) ) );
405
  }
406
 
407
  /**
413
  ewwwio_debug_message( '<b>' . __FUNCTION__ . '()</b>' );
414
  // Verify that an authorized user has called function.
415
  $permissions = apply_filters( 'ewww_image_optimizer_bulk_permissions', '' );
416
+ if ( empty( $_REQUEST['ewww_wpnonce'] ) || ! wp_verify_nonce( sanitize_key( $_REQUEST['ewww_wpnonce'] ), 'ewww-image-optimizer-tools' ) || ! current_user_can( $permissions ) ) {
417
  ewwwio_ob_clean();
418
+ die( wp_json_encode( array( 'error' => esc_html__( 'Access token has expired, please reload the page.', 'ewww-image-optimizer' ) ) ) );
419
  }
420
  global $wpdb;
421
  if ( strpos( $wpdb->charset, 'utf8' ) === false ) {
425
  $ewwwdb = $wpdb;
426
  }
427
  $per_page = 50;
428
+ $offset = empty( $_POST['ewww_offset'] ) ? 0 : (int) $_POST['ewww_offset'];
429
  ewwwio_debug_message( "getting $per_page attachments, starting at $offset" );
430
 
431
  $attachments = $wpdb->get_col(
438
  )
439
  );
440
  if ( empty( $attachments ) ) {
441
+ die( wp_json_encode( array( 'done' => 1 ) ) );
442
  }
443
  foreach ( $attachments as $attachment_id ) {
444
  ewwwio_debug_message( "checking $attachment_id for migration" );
447
  ewww_image_optimizer_migrate_meta_to_db( $attachment_id, $meta );
448
  }
449
  }
450
+ die( wp_json_encode( array( 'success' => $per_page ) ) );
451
  }
452
 
453
  /**
460
  function ewww_image_optimizer_aux_images_table_count() {
461
  global $wpdb;
462
  $count = $wpdb->get_var( "SELECT COUNT(*) FROM $wpdb->ewwwio_images WHERE pending=0 AND image_size > 0" );
463
+ // Verify that an authorized user has called function.
464
+ $permissions = apply_filters( 'ewww_image_optimizer_bulk_permissions', '' );
465
+ if ( ! empty( $_REQUEST['ewww_inline'] ) &&
466
+ ( empty( $_REQUEST['ewww_wpnonce'] ) || ! wp_verify_nonce( sanitize_key( $_REQUEST['ewww_wpnonce'] ), 'ewww-image-optimizer-tools' ) || ! current_user_can( $permissions ) )
467
+ ) {
468
+ die();
469
+ } elseif ( ! empty( $_REQUEST['ewww_inline'] ) ) {
470
  ewwwio_ob_clean();
471
+ echo (int) $count;
472
  ewwwio_memory( __FUNCTION__ );
473
  die();
474
  }
741
  }
742
  global $wpdb;
743
  global $optimized_list;
744
+ global $ewww_scan;
745
+ global $ewww_force;
746
+ global $ewww_force_smart;
747
  $images = array();
748
  $reset_images = array();
749
  if ( ! is_dir( $dir ) ) {
753
  ewwwio_debug_message( "scanning folder for images: $dir" );
754
  $iterator = new RecursiveIteratorIterator( new RecursiveDirectoryIterator( $dir ), RecursiveIteratorIterator::CHILD_FIRST, RecursiveIteratorIterator::CATCH_GET_CHILD );
755
  $start = microtime( true );
 
 
 
 
 
 
 
 
 
 
 
 
756
  if ( empty( $optimized_list ) || ! is_array( $optimized_list ) ) {
757
  ewww_image_optimizer_optimized_list();
758
  }
780
  }
781
  if (
782
  $started &&
783
+ 'scheduled' !== $ewww_scan &&
784
  0 === $file_counter % 100 &&
785
  microtime( true ) - $started > apply_filters( 'ewww_image_optimizer_timeout', 15 )
786
  ) {
793
  ewwwio_ob_clean();
794
  ewww_image_optimizer_debug_log();
795
  die(
796
+ wp_json_encode(
797
  array(
798
  'remaining' => '<p>' . esc_html__( 'Stage 2, please wait.', 'ewww-image-optimizer' ) . "&nbsp;<img src='$loading_image' /></p>",
799
  'notice' => '',
802
  );
803
  } elseif (
804
  $started &&
805
+ 'scheduled' === $ewww_scan &&
806
  0 === $file_counter % 100 &&
807
  microtime( true ) - $started > apply_filters( 'ewww_image_optimizer_timeout', 15 )
808
  ) {
820
  )
821
  )->dispatch();
822
  wp_die();
823
+ } elseif ( 'scheduled' === $ewww_scan && get_option( 'ewwwio_stop_scheduled_scan' ) ) {
824
  ewwwio_debug_message( 'ending current scan iteration because of stop_scan' );
825
  delete_option( 'ewwwio_stop_scheduled_scan' );
826
  ewww_image_optimizer_debug_log();
827
  wp_die();
828
  }
829
+ if ( $ewww_scan && 0 === $file_counter % 100 && ! ewwwio_check_memory_available( 2097000 ) ) {
830
  ewwwio_debug_message( 'ending current scan iteration because of memory constraints' );
831
  if ( $file_counter < 100 ) {
832
  ewwwio_ob_clean();
833
  die(
834
+ wp_json_encode(
835
  array(
836
  'error' => esc_html__( 'Stage 2 unable to complete due to memory restrictions. Please increase the memory_limit setting for PHP and try again.', 'ewww-image-optimizer' ),
837
  )
847
  ewwwio_ob_clean();
848
  ewww_image_optimizer_debug_log();
849
  die(
850
+ wp_json_encode(
851
  array(
852
  'remaining' => '<p>' . esc_html__( 'Stage 2, please wait.', 'ewww-image-optimizer' ) . "&nbsp;<img src='$loading_image' /></p>",
853
  'notice' => '',
897
  continue;
898
  }
899
  $compression_level = ewww_image_optimizer_get_level( $mime );
900
+ if ( ! empty( $ewww_force_smart ) && ewww_image_optimizer_level_mismatch( $already_optimized['level'], $compression_level ) ) {
901
  $reset_images[] = (int) $already_optimized['id'];
902
  ewwwio_debug_message( "smart re-opt found level mismatch for $path, db says " . $already_optimized['level'] . " vs. current $compression_level" );
903
  } elseif ( $should_resize ) {
904
  $reset_images[] = (int) $already_optimized['id'];
905
  ewwwio_debug_message( "resize other existing found candidate for scaling: $path" );
906
+ } elseif ( (int) $already_optimized['image_size'] === $image_size && empty( $ewww_force ) ) {
907
  ewwwio_debug_message( "match found for $path" );
908
  continue;
909
  } else {
1009
  */
1010
  function ewww_image_optimizer_aux_images_script( $hook = '' ) {
1011
  ewwwio_debug_message( '<b>' . __FUNCTION__ . '()</b>' );
 
 
 
 
 
1012
  session_write_close();
 
 
 
 
 
 
1013
  // Retrieve the time when the scan starts.
1014
  $started = microtime( true );
1015
  if ( ! get_transient( 'ewww_image_optimizer_skip_aux' ) ) {
1136
  }
1137
  }
1138
  } // End if().
1139
+ $image_count = (int) ewww_image_optimizer_aux_images_table_count_pending();
1140
  ewwwio_debug_message( "found $image_count images to optimize while scanning" );
1141
  update_option( 'ewww_image_optimizer_aux_folders_completed', array(), false );
1142
  update_option( 'ewww_image_optimizer_aux_resume', '' );
1162
  }
1163
  ewwwio_ob_clean();
1164
  die(
1165
+ wp_json_encode(
1166
  array(
1167
  'ready' => $image_count,
1168
  'message' => $ready_msg,
1169
  /* translators: %s: number of images */
1170
+ 'start_button' => esc_attr( sprintf( __( 'Optimize %s images', 'ewww-image-optimizer' ), number_format_i18n( $image_count ) ) ),
1171
  )
1172
  )
1173
  );
1203
  ewwwio_debug_message( '<b>' . __FUNCTION__ . '()</b>' );
1204
  // Verify that an authorized user has started the optimizer.
1205
  $permissions = apply_filters( 'ewww_image_optimizer_bulk_permissions', '' );
1206
+ if ( ! $auto && ( empty( $_REQUEST['ewww_wpnonce'] ) || ! wp_verify_nonce( sanitize_key( $_REQUEST['ewww_wpnonce'] ), 'ewww-image-optimizer-bulk' ) || ! current_user_can( $permissions ) ) ) {
1207
  ewwwio_ob_clean();
1208
  die( esc_html__( 'Access denied.', 'ewww-image-optimizer' ) );
1209
  }
bulk.php CHANGED
@@ -21,7 +21,13 @@ function ewww_image_optimizer_display_tools() {
21
  if ( ! class_exists( 'WP_Background_Process' ) ) {
22
  require_once( EWWW_IMAGE_OPTIMIZER_PLUGIN_PATH . 'background.php' );
23
  }
24
- if ( ! empty( $_POST['action'] ) && 'ewww_image_optimizer_clear_queue' === $_POST['action'] && current_user_can( 'manage_options' ) && wp_verify_nonce( $_POST['ewww_nonce'], 'ewww_image_optimizer_clear_queue' ) ) {
 
 
 
 
 
 
25
  $ewwwio_media_background->cancel_process();
26
  $ewwwio_image_background->cancel_process();
27
  update_option( 'ewwwio_stop_scheduled_scan', true, false );
@@ -37,57 +43,39 @@ function ewww_image_optimizer_display_tools() {
37
  return;
38
  }
39
 
40
- $output = '';
41
- $output .= "<div id='ewww-aux-forms'>\n";
42
- /* translators: %s: number of images */
43
- $output .= "<p id='ewww-table-info' class='ewww-tool-info'>" . sprintf( esc_html__( 'The plugin keeps track of already optimized images to prevent re-optimization. There are %s images that have been optimized so far.', 'ewww-image-optimizer' ), number_format_i18n( $already_optimized ) ) . "</p>\n";
44
- $output .= "<form id='ewww-show-table' class='ewww-tool-form' method='post' action=''>\n" .
 
45
  '<button type="submit" class="button-primary action">' . esc_html__( 'Show Optimized Images', 'ewww-image-optimizer' ) . "</button>\n" .
46
  "</form>\n";
47
 
48
- $queue_status = esc_html__( 'idle', 'ewww-image-optimizer' );
 
 
 
 
 
49
  if ( $ewwwio_media_background->is_process_running() ) {
50
- $queue_status = esc_html__( 'running', 'ewww-image-optimizer' );
51
  }
52
  if ( $ewwwio_image_background->is_process_running() ) {
53
- $queue_status = esc_html__( 'running', 'ewww-image-optimizer' );
54
  }
55
 
56
- $navigation = "<div class='tablenav ewww-aux-table' style='display:none'>\n" .
57
- '<form class="ewww-search-form" style="float:left;">' . "\n" .
58
- '<label for="ewww-search-input" class="screen-reader-text">' . esc_html__( 'Search', 'ewww-image-optimizer' ) . '</label>' . "\n" .
59
- '<input type="search" class="ewww-search-input search" name="ewww-search-input" value="">' . "\n" .
60
- '<input type="submit" class="ewww-search-submit button" value="' . esc_attr__( 'Search', 'ewww-image-optimizer' ) . '">' . "\n" .
61
- '<span class="ewww-search-count"></span>' . "\n" .
62
- '</form>' . "\n" .
63
- '<div class="tablenav-pages ewww-aux-table">' . "\n" .
64
- '<span class="displaying-num ewww-aux-table"></span>' . "\n" .
65
- '<span class="pagination-links ewww-aux-table">' . "\n" .
66
- '<a class="tablenav-pages-navspan button first-page" style="display:none">&laquo;</a>' . "\n" .
67
- '<a class="tablenav-pages-navspan button prev-page" style="display:none">&lsaquo;</a>' . "\n" .
68
- /* translators: 1: current page in list of images 2: total pages for list of images */
69
- '<span class="current-page">' . sprintf( esc_html__( 'page %1$d of %2$d', 'ewww-image-optimizer' ), 1, 0 ) . "</span>\n" .
70
- '<a class="tablenav-pages-navspan button next-page" style="display:none">&rsaquo;</a>' . "\n" .
71
- '<a class="tablenav-pages-navspan button last-page" style="display:none">&raquo;</a>' .
72
- '</span>' . "\n" .
73
- '</div>' . "\n" .
74
- '</div>' . "\n";
75
-
76
- $output .= $navigation . '<div id="ewww-bulk-table" class="ewww-aux-table"></div>' . "$navigation\n" .
77
- "</div>\n";
78
- echo $output;
79
-
80
  echo '<hr class="ewww-tool-divider">';
81
  $queue_count = $ewwwio_media_background->count_queue();
82
  $queue_count += $ewwwio_image_background->count_queue();
83
  /* translators: %s: idle/running */
84
- echo "<p id='ewww-queue-info' class='ewww-tool-info'>" . sprintf( esc_html__( 'Current queue status: %s', 'ewww-image-optimizer' ), $queue_status ) . "<br>\n";
85
  if ( $queue_count ) {
86
  /* translators: %d: number of images */
87
- echo sprintf( esc_html__( 'There are %d images in the queue currently.', 'ewww-image-optimizer' ), $queue_count ) . "</p>\n";
88
  $nonce = wp_create_nonce( 'ewww_image_optimizer_clear_queue' );
89
  echo "<form id='ewww-clear-queue' class='ewww-tool-form' method='post' action=''>\n" .
90
- "<input type='hidden' id='ewww_nonce' name='ewww_nonce' value='$nonce'>" .
91
  "<input type='hidden' name='action' value='ewww_image_optimizer_clear_queue'>" .
92
  '<button type="submit" class="button-secondary action">' . esc_html__( 'Clear Queue', 'ewww-image-optimizer' ) . "</button>\n" .
93
  "</form>\n";
@@ -123,7 +111,7 @@ function ewww_image_optimizer_display_tools() {
123
  echo '<hr class="ewww-tool-divider">';
124
  echo "<div>\n<p id='ewww-clean-meta-info' class='ewww-tool-info'>" .
125
  /* translators: 1: postmeta table name 2: ewwwio_images table name */
126
- sprintf( esc_html__( 'Sites using EWWW IO for 3+ years may have optimization data that still needs to be migrated between the %1$s and %2$s tables.', 'ewww-image-optimizer' ), $wpdb->postmeta, $wpdb->ewwwio_images ) . "</p>\n";
127
  echo "<form id='ewww-clean-meta' class='ewww-tool-form' method='post' action=''>\n" .
128
  "<input type='submit' class='button-secondary action' value='" . esc_attr__( 'Migrate Optimization Records', 'ewww-image-optimizer' ) . "' />\n" .
129
  "</form>\n</div>\n";
@@ -139,6 +127,31 @@ function ewww_image_optimizer_display_tools() {
139
  echo "</div>\n";
140
  }
141
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
142
  /**
143
  * Prepares the javascript functions for the tools page.
144
  *
@@ -202,7 +215,7 @@ function ewww_image_optimizer_bulk_preview() {
202
  return;
203
  }
204
  if ( ewww_image_optimizer_get_option( 'ewww_image_optimizer_cloud_key' ) ) {
205
- echo '<a id="ewww-bulk-credits-available" target="_blank" style="margin-left:20px" class="page-title-action" href="https://ewww.io/my-account/">' . esc_html__( 'Image credits available:', 'ewww-image-optimizer' ) . ' ' . ewww_image_optimizer_cloud_quota() . '</a>';
206
  echo '<hr class="wp-header-end">';
207
  }
208
  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>';
@@ -232,16 +245,16 @@ function ewww_image_optimizer_bulk_preview() {
232
  $resize_count = count( $resizes );
233
  }
234
  $resize_count = ( ! empty( $resize_count ) && $resize_count > 1 ? $resize_count : 6 );
235
- if ( ! empty( $_REQUEST['ids'] ) && ( preg_match( '/^[\d,]+$/', $_REQUEST['ids'] ) || is_numeric( $_REQUEST['ids'] ) ) ) {
236
  echo '<p class="ewww-media-info ewww-bulk-info">' .
237
  /* translators: 1: number of images 2: number of registered image sizes */
238
- sprintf( esc_html( _n( '%1$s uploaded item in the Media Library has been selected with up to %2$d image files per upload.', '%1$s uploaded items in the Media Library have been selected with up to %2$d image files per upload.', $fullsize_count, 'ewww-image-optimizer' ) ), number_format_i18n( $fullsize_count ), $resize_count ) .
239
  ' ' . esc_html__( 'The total number of images found will be displayed before optimization begins.', 'ewww-image-optimizer' ) .
240
  '</p>';
241
  } else {
242
  echo '<p class="ewww-media-info ewww-bulk-info">' .
243
  /* translators: 1: number of images 2: number of registered image sizes */
244
- sprintf( esc_html( _n( '%1$s uploaded item in the Media Library has been selected with up to %2$d image files per upload.', '%1$s uploaded items in the Media Library have been selected with up to %2$d image files per upload.', $fullsize_count, 'ewww-image-optimizer' ) ), number_format_i18n( $fullsize_count ), $resize_count ) .
245
  ' ' . esc_html__( 'The total number of images found will be displayed before optimization begins.', 'ewww-image-optimizer' ) .
246
  '<br />' .
247
  esc_html__( 'The active theme, BuddyPress, WP Symposium, and folders that you have configured will also be scanned for unoptimized images.', 'ewww-image-optimizer' ) .
@@ -263,11 +276,12 @@ function ewww_image_optimizer_bulk_preview() {
263
  * Outputs the status area and delay/force controls for the Bulk optimize page.
264
  */
265
  function ewww_image_optimizer_bulk_head_output() {
 
266
  $loading_image = plugins_url( '/images/wpspin.gif', __FILE__ );
267
  $delay = ewww_image_optimizer_get_option( 'ewww_image_optimizer_delay' ) ? (int) ewww_image_optimizer_get_option( 'ewww_image_optimizer_delay' ) : 0;
268
  ?>
269
  <div id="ewww-bulk-loading">
270
- <p id="ewww-loading" class="ewww-bulk-info" style="display:none"><?php esc_html_e( 'Importing', 'ewww-image-optimizer' ); ?>&nbsp;<img src='<?php echo $loading_image; ?>' /></p>
271
  </div>
272
  <div id="ewww-bulk-progressbar"></div>
273
  <div id="ewww-bulk-timer" style="float:right;"></div>
@@ -298,15 +312,15 @@ function ewww_image_optimizer_bulk_head_output() {
298
  </div>
299
  </div>
300
  <form id="ewww-bulk-controls" class="ewww-bulk-form">
301
- <p><label for="ewww-force" style="font-weight: bold"><?php esc_html_e( 'Force re-optimize', 'ewww-image-optimizer' ); ?></label><?php echo ewwwio_help_link( 'https://docs.ewww.io/article/65-force-re-optimization', '5bb640a7042863158cc711cd' ); ?>
302
- &emsp;<input type="checkbox" id="ewww-force" name="ewww-force"<?php echo ( get_transient( 'ewww_image_optimizer_force_reopt' ) || ! empty( $_REQUEST['ewww_force'] ) ) ? ' checked' : ''; ?>>
303
  &nbsp;<?php esc_html_e( 'Previously optimized images will be skipped by default, check this box before scanning to override.', 'ewww-image-optimizer' ); ?>
304
  &nbsp;<a href="tools.php?page=ewww-image-optimizer-tools"><?php esc_html_e( 'View optimization history.', 'ewww-image-optimizer' ); ?></a>
305
  </p>
306
  <?php ewww_image_optimizer_bulk_variant_option(); ?>
307
  <?php ewww_image_optimizer_bulk_webp_only(); ?>
308
  <p>
309
- <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 $delay; ?>"> <?php esc_html_e( 'in seconds, 0 = disabled', 'ewww-image-optimmizer' ); ?>
310
  </p>
311
  <div id="ewww-delay-slider"></div>
312
  </form>
@@ -323,9 +337,10 @@ function ewww_image_optimizer_bulk_variant_option() {
323
  if ( ! ewww_image_optimizer_get_option( 'ewww_image_optimizer_cloud_key' ) ) {
324
  return;
325
  }
 
326
  ?>
327
  <p><label for="ewww-force-smart" style="font-weight: bold"><?php esc_html_e( 'Smart Re-optimize', 'ewww-image-optimizer' ); ?></label>
328
- &emsp;<input type="checkbox" id="ewww-force-smart" name="ewww-force-smart"<?php echo ( get_transient( 'ewww_image_optimizer_smart_reopt' ) || ! empty( $_REQUEST['ewww_force_smart'] ) ) ? ' checked' : ''; ?>>
329
  &nbsp;<?php esc_html_e( 'If compression settings have changed, re-optimize images that were compressed on the old settings. If possible, images compressed in Premium mode will be restored to originals beforehand.', 'ewww-image-optimizer' ); ?>
330
  </p>
331
  <?php
@@ -338,9 +353,10 @@ function ewww_image_optimizer_bulk_webp_only() {
338
  if ( ! ewww_image_optimizer_get_option( 'ewww_image_optimizer_webp' ) ) {
339
  return;
340
  }
 
341
  ?>
342
  <p><label for="ewww-webp-only" style="font-weight: bold"><?php esc_html_e( 'WebP Only', 'ewww-image-optimizer' ); ?></label>
343
- &emsp;<input type="checkbox" id="ewww-webp-only" name="ewww-webp-only"<?php echo ( ! empty( $_REQUEST['ewww_webp_only'] ) ) ? ' checked' : ''; ?>>
344
  &nbsp;<?php esc_html_e( 'Skip compression and only attempt WebP conversion.', 'ewww-image-optimizer' ); ?>
345
  </p>
346
  <?php
@@ -357,10 +373,10 @@ function ewww_image_optimizer_bulk_webp_only() {
357
  function ewww_image_optimizer_bulk_action_output( $button_text, $fullsize_count, $resume = '' ) {
358
  $loading_image = plugins_url( '/images/wpspin.gif', __FILE__ );
359
  /* translators: %s: number of images */
360
- $scanning_starter_message = sprintf( esc_html__( 'Stage 1, %s items left to scan.', 'ewww-image-optimizer' ), number_format_i18n( $fullsize_count ) );
361
  if ( 'true' === $resume ) {
362
  /* translators: %s: number of images, formatted for locale */
363
- $button_text = sprintf( esc_attr__( 'Optimize %s images', 'ewww-image-optimizer' ), number_format_i18n( $fullsize_count ) );
364
  $scan_hide = 'style="display:none"';
365
  $start_hide = '';
366
  } else {
@@ -370,12 +386,12 @@ function ewww_image_optimizer_bulk_action_output( $button_text, $fullsize_count,
370
  }
371
  ?>
372
  <p id="ewww-nothing" class="ewww-bulk-info" style="display:none"><?php echo esc_html_e( 'There are no images to optimize.', 'ewww-image-optimizer' ); ?></p>
373
- <p id="ewww-scanning" class="ewww-bulk-info" style="display:none"><?php echo $scanning_starter_message; ?>&nbsp;<img src='<?php echo $loading_image; ?>' alt='loading'/></p>
374
- <form id="ewww-aux-start" class="ewww-bulk-form" <?php echo $scan_hide; ?> method="post" action="">
375
  <input id="ewww-aux-first" type="submit" class="button-primary action" value="<?php esc_attr_e( 'Scan for unoptimized images', 'ewww-image-optimizer' ); ?>" />
376
  </form>
377
- <form id="ewww-bulk-start" class="ewww-bulk-form" <?php echo $start_hide; ?> method="post" action="">
378
- <input id="ewww-bulk-first" type="submit" class="button-primary action" value="<?php echo $button_text; ?>" />
379
  </form>
380
  <?php
381
  }
@@ -450,7 +466,7 @@ function ewww_image_optimizer_count_optimized( $gallery ) {
450
  break;
451
  case 'ngg':
452
  // See if we were given attachment IDs to work with via GET/POST.
453
- if ( ! empty( $_REQUEST['doaction'] ) || get_option( 'ewww_image_optimizer_bulk_ngg_resume' ) ) {
454
  // Retrieve the attachment IDs that were pre-loaded in the database.
455
  $attachment_ids = get_option( 'ewww_image_optimizer_bulk_ngg_attachments' );
456
  array_walk( $attachment_ids, 'intval' );
@@ -513,7 +529,7 @@ function ewww_image_optimizer_count_optimized( $gallery ) {
513
  } // End while().
514
  break;
515
  case 'flag':
516
- if ( ! empty( $_REQUEST['doaction'] ) || get_option( 'ewww_image_optimizer_bulk_flag_resume' ) ) {
517
  // Retrieve the attachment IDs that were pre-loaded in the database.
518
  $attachment_ids = get_option( 'ewww_image_optimizer_bulk_flag_attachments' );
519
  array_walk( $attachment_ids, 'intval' );
@@ -592,10 +608,12 @@ function ewww_image_optimizer_bulk_script( $hook ) {
592
  return;
593
  }
594
  global $wpdb;
 
 
595
  // Initialize the $attachments variable.
596
  $attachments = array();
597
  // Check to see if we are supposed to reset the bulk operation and verify we are authorized to do so.
598
- if ( ! empty( $_REQUEST['ewww_reset'] ) && wp_verify_nonce( $_REQUEST['ewww_wpnonce'], 'ewww-image-optimizer-bulk-reset' ) ) {
599
  ewwwio_debug_message( 'resetting resume flags' );
600
  // Set the 'bulk resume' option to an empty string to reset the bulk operation.
601
  update_option( 'ewww_image_optimizer_bulk_resume', '' );
@@ -605,9 +623,15 @@ function ewww_image_optimizer_bulk_script( $hook ) {
605
  ewww_image_optimizer_delete_pending();
606
  }
607
  // Check to see if we are supposed to convert the auxiliary images table and verify we are authorized to do so.
608
- if ( ! empty( $_REQUEST['ewww_convert'] ) && wp_verify_nonce( $_REQUEST['ewww_wpnonce'], 'ewww-image-optimizer-aux-images-convert' ) ) {
609
  ewww_image_optimizer_aux_images_convert();
610
  }
 
 
 
 
 
 
611
  // Check the 'bulk resume' option.
612
  $resume = get_option( 'ewww_image_optimizer_bulk_resume' );
613
  $scanning = get_option( 'ewww_image_optimizer_aux_resume' );
@@ -621,17 +645,16 @@ function ewww_image_optimizer_bulk_script( $hook ) {
621
  }
622
  // See if we were given attachment IDs to work with via GET/POST.
623
  $ids = array();
624
- if ( ! empty( $_REQUEST['ids'] ) && ( preg_match( '/^[\d,]+$/', $_REQUEST['ids'], $request_ids ) || is_numeric( $_REQUEST['ids'] ) ) ) {
625
  ewww_image_optimizer_delete_pending();
626
  set_transient( 'ewww_image_optimizer_skip_aux', true, 3 * MINUTE_IN_SECONDS );
627
- if ( is_numeric( $_REQUEST['ids'] ) ) {
628
  $ids[] = (int) $_REQUEST['ids'];
629
  } else {
630
  $ids = explode( ',', $request_ids[0] );
631
  array_walk( $ids, 'intval' );
632
  }
633
  $sample_post_type = get_post_type( $ids[0] );
634
- // ewwwio_debug_message( "ids: " . $request_ids[0] ); // keeping just in case.
635
  ewwwio_debug_message( "post type (checking for ims_gallery): $sample_post_type" );
636
  if ( 'ims_gallery' === $sample_post_type ) {
637
  $attachments = array();
@@ -753,11 +776,6 @@ function ewww_image_optimizer_optimized_list() {
753
  }
754
  unset( $optimized['path'] );
755
  $optimized_list[ $optimized_path ] = $optimized;
756
- // $optimized_list[ $optimized_path ]['image_size'] = $optimized['image_size'];
757
- // $optimized_list[ $optimized_path ]['id'] = $optimized['id'];
758
- // $optimized_list[ $optimized_path ]['pending'] = $optimized['pending'];
759
- // $optimized_list[ $optimized_path ]['attachment_id'] = $optimized['attachment_id'];
760
- // $optimized_list[ $optimized_path ]['updated'] = $optimized['updated'];
761
  }
762
  ewwwio_memory( 'removed original records' );
763
  $offset += $max_query;
@@ -887,13 +905,13 @@ function ewww_image_optimizer_media_scan( $hook = '' ) {
887
  ewwwio_debug_message( 'bailing no cli' );
888
  ewww_image_optimizer_debug_log();
889
  ewwwio_ob_clean();
890
- die( ewwwio_json_encode( array( 'error' => esc_html__( 'Access denied.', 'ewww-image-optimizer' ) ) ) );
891
  }
892
- if ( ! empty( $_REQUEST['ewww_scan'] ) && ( ! wp_verify_nonce( $_REQUEST['ewww_wpnonce'], 'ewww-image-optimizer-bulk' ) || ! current_user_can( $permissions ) ) ) {
893
  ewwwio_debug_message( 'bailing no nonce' );
894
  ewww_image_optimizer_debug_log();
895
  ewwwio_ob_clean();
896
- die( ewwwio_json_encode( array( 'error' => esc_html__( 'Access token has expired, please reload the page.', 'ewww-image-optimizer' ) ) ) );
897
  }
898
  global $wpdb;
899
  if ( strpos( $wpdb->charset, 'utf8' ) === false ) {
@@ -902,6 +920,33 @@ function ewww_image_optimizer_media_scan( $hook = '' ) {
902
  } else {
903
  $ewwwdb = $wpdb;
904
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
905
  global $optimized_list;
906
  $queued_ids = array();
907
  $skipped_ids = array();
@@ -931,20 +976,6 @@ function ewww_image_optimizer_media_scan( $hook = '' ) {
931
 
932
  $attachment_ids = ewww_image_optimizer_get_unscanned_attachments( 'media', $max_query );
933
 
934
- // Make the Force Re-optimize option persistent.
935
- if ( ! empty( $_REQUEST['ewww_force'] ) ) {
936
- set_transient( 'ewww_image_optimizer_force_reopt', true, HOUR_IN_SECONDS );
937
- } else {
938
- delete_transient( 'ewww_image_optimizer_force_reopt' );
939
- }
940
-
941
- // Make the Smart Re-optimize option persistent.
942
- if ( ! empty( $_REQUEST['ewww_force_smart'] ) ) {
943
- set_transient( 'ewww_image_optimizer_smart_reopt', true, HOUR_IN_SECONDS );
944
- } else {
945
- delete_transient( 'ewww_image_optimizer_smart_reopt' );
946
- }
947
-
948
  if ( ! empty( $attachment_ids ) && count( $attachment_ids ) > 300 ) {
949
  ewww_image_optimizer_debug_log();
950
  ewww_image_optimizer_optimized_list();
@@ -955,7 +986,7 @@ function ewww_image_optimizer_media_scan( $hook = '' ) {
955
 
956
  list( $bad_attachments, $bad_attachment ) = ewww_image_optimizer_get_bad_attachments();
957
 
958
- if ( empty( $attachment_ids ) ) {
959
  // When the media library is finished, run the aux script function to scan for additional images.
960
  ewww_image_optimizer_aux_images_script();
961
  }
@@ -996,7 +1027,7 @@ function ewww_image_optimizer_media_scan( $hook = '' ) {
996
  } else {
997
  ewwwio_debug_message( 'no array found' );
998
  ewwwio_ob_clean();
999
- die( ewwwio_json_encode( array( 'error' => esc_html__( 'List of attachment IDs not found.', 'ewww-image-optimizer' ) ) ) );
1000
  }
1001
 
1002
  $attachment_meta = ewww_image_optimizer_fetch_metadata_batch( $attachments_in );
@@ -1115,8 +1146,8 @@ function ewww_image_optimizer_media_scan( $hook = '' ) {
1115
  $should_resize = ewww_image_optimizer_should_resize( $file_path, true );
1116
  if (
1117
  ! empty( $attachment_meta[ $selected_id ]['tinypng'] ) &&
1118
- empty( $_REQUEST['ewww_force'] ) &&
1119
- empty( $_REQUEST['ewww_webp_only'] ) &&
1120
  ! $should_resize
1121
  ) {
1122
  ewwwio_debug_message( "TinyPNG already compressed $selected_id" );
@@ -1129,7 +1160,7 @@ function ewww_image_optimizer_media_scan( $hook = '' ) {
1129
 
1130
  $attachment_images['full'] = $file_path;
1131
 
1132
- $retina_path = ewww_image_optimizer_hidpi_optimize( $file_path, true );
1133
  if ( $retina_path ) {
1134
  $attachment_images['full-retina'] = $retina_path;
1135
  }
@@ -1206,7 +1237,7 @@ function ewww_image_optimizer_media_scan( $hook = '' ) {
1206
  ewwwio_debug_message( "found retina via wr2x_get_retina $retina_path" );
1207
  $attachment_images[ $size . '-retina' ] = $retina_path;
1208
  } else {
1209
- $retina_path = ewww_image_optimizer_hidpi_optimize( $resize_path, true );
1210
  if ( $retina_path ) {
1211
  ewwwio_debug_message( "found retina via hidpi_opt $retina_path" );
1212
  $attachment_images[ $size . '-retina' ] = $retina_path;
@@ -1307,13 +1338,13 @@ function ewww_image_optimizer_media_scan( $hook = '' ) {
1307
  }
1308
  $compression_level = ewww_image_optimizer_get_level( $mime );
1309
  $smart_reopt = false;
1310
- if ( ! empty( $_REQUEST['ewww_force_smart'] ) && ewww_image_optimizer_level_mismatch( $already_optimized['level'], $compression_level ) ) {
1311
  $smart_reopt = true;
1312
  }
1313
  if ( 'full' === $size && $should_resize ) {
1314
  $smart_reopt = true;
1315
  }
1316
- if ( (int) $already_optimized['image_size'] === (int) $image_size && empty( $_REQUEST['ewww_force'] ) && ! $smart_reopt ) {
1317
  ewwwio_debug_message( "match found for $file_path" );
1318
  ewww_image_optimizer_debug_log();
1319
  continue;
@@ -1477,7 +1508,7 @@ function ewww_image_optimizer_media_scan( $hook = '' ) {
1477
  if ( $remaining ) {
1478
  ewwwio_ob_clean();
1479
  die(
1480
- ewwwio_json_encode(
1481
  array(
1482
  /* translators: %s: number of images */
1483
  'remaining' => sprintf( esc_html__( 'Stage 1, %s items left to scan.', 'ewww-image-optimizer' ), number_format_i18n( $remaining ) ) . "&nbsp;<img src='$loading_image' />",
@@ -1490,7 +1521,7 @@ function ewww_image_optimizer_media_scan( $hook = '' ) {
1490
  } else {
1491
  ewwwio_ob_clean();
1492
  die(
1493
- ewwwio_json_encode(
1494
  array(
1495
  'remaining' => esc_html__( 'Stage 2, please wait.', 'ewww-image-optimizer' ) . "&nbsp;<img src='$loading_image' />",
1496
  'notice' => $notice,
@@ -1508,13 +1539,13 @@ function ewww_image_optimizer_media_scan( $hook = '' ) {
1508
  function ewww_image_optimizer_bulk_quota_update() {
1509
  // Verify that an authorized user has made the request.
1510
  $permissions = apply_filters( 'ewww_image_optimizer_bulk_permissions', '' );
1511
- if ( ! wp_verify_nonce( $_REQUEST['ewww_wpnonce'], 'ewww-image-optimizer-bulk' ) || ! current_user_can( $permissions ) ) {
1512
  ewwwio_ob_clean();
1513
  die( esc_html__( 'Access token has expired, please reload the page.', 'ewww-image-optimizer' ) );
1514
  }
1515
  ewwwio_ob_clean();
1516
  if ( ewww_image_optimizer_get_option( 'ewww_image_optimizer_cloud_key' ) ) {
1517
- echo esc_html__( 'Image credits available:', 'ewww-image-optimizer' ) . ' ' . ewww_image_optimizer_cloud_quota();
1518
  }
1519
  ewwwio_memory( __FUNCTION__ );
1520
  die();
@@ -1527,9 +1558,9 @@ function ewww_image_optimizer_bulk_initialize() {
1527
  ewwwio_debug_message( '<b>' . __FUNCTION__ . '()</b>' );
1528
  // Verify that an authorized user has made the request.
1529
  $permissions = apply_filters( 'ewww_image_optimizer_bulk_permissions', '' );
1530
- if ( ! wp_verify_nonce( $_REQUEST['ewww_wpnonce'], 'ewww-image-optimizer-bulk' ) || ! current_user_can( $permissions ) ) {
1531
  ewwwio_ob_clean();
1532
- die( ewwwio_json_encode( array( 'error' => esc_html__( 'Access token has expired, please reload the page.', 'ewww-image-optimizer' ) ) ) );
1533
  }
1534
  session_write_close();
1535
  $output = array();
@@ -1551,7 +1582,7 @@ function ewww_image_optimizer_bulk_initialize() {
1551
  $output['start_time'] = time();
1552
  ewwwio_memory( __FUNCTION__ );
1553
  ewwwio_ob_clean();
1554
- die( ewwwio_json_encode( $output ) );
1555
  }
1556
 
1557
  /**
@@ -1571,8 +1602,8 @@ function ewww_image_optimizer_bulk_skip_image( $image ) {
1571
  */
1572
  function ewww_image_optimizer_bulk_counter_measures( $image ) {
1573
  ewwwio_debug_message( '<b>' . __FUNCTION__ . '()</b>' );
1574
- if ( ! empty( $_REQUEST['ewww_error_counter'] ) ) {
1575
- $error_counter = (int) $_REQUEST['ewww_error_counter'];
1576
  if ( 30 !== $error_counter ) {
1577
  $failed_file = get_transient( 'ewww_image_optimizer_failed_file' );
1578
  $previous_incomplete_file = get_transient( 'ewww_image_optimizer_bulk_current_image' );
@@ -1725,15 +1756,25 @@ function ewww_image_optimizer_bulk_counter_measures( $image ) {
1725
  */
1726
  function ewww_image_optimizer_bulk_loop( $hook = '', $delay = 0 ) {
1727
  ewwwio_debug_message( '<b>' . __FUNCTION__ . '()</b>' );
 
 
 
1728
  global $ewww_defer;
1729
  $ewww_defer = false;
1730
  $output = array();
1731
  $time_adjustment = 0;
1732
  // Verify that an authorized user has started the optimizer.
1733
  $permissions = apply_filters( 'ewww_image_optimizer_bulk_permissions', '' );
1734
- if ( 'ewww-image-optimizer-cli' !== $hook && ( ! wp_verify_nonce( $_REQUEST['ewww_wpnonce'], 'ewww-image-optimizer-bulk' ) || ! current_user_can( $permissions ) ) ) {
 
 
 
 
 
 
 
1735
  ewwwio_ob_clean();
1736
- die( ewwwio_json_encode( array( 'error' => esc_html__( 'Access token has expired, please reload the page.', 'ewww-image-optimizer' ) ) ) );
1737
  }
1738
  session_write_close();
1739
  // Retrieve the time when the optimizer starts.
@@ -1742,19 +1783,27 @@ function ewww_image_optimizer_bulk_loop( $hook = '', $delay = 0 ) {
1742
  set_transient( 'ewww_image_optimizer_no_scheduled_optimization', true, 10 * MINUTE_IN_SECONDS );
1743
  // Make the Force Re-optimize option persistent.
1744
  if ( ! empty( $_REQUEST['ewww_force'] ) ) {
 
1745
  set_transient( 'ewww_image_optimizer_force_reopt', true, HOUR_IN_SECONDS );
1746
  } else {
 
1747
  delete_transient( 'ewww_image_optimizer_force_reopt' );
1748
  }
1749
  // Make the Smart Re-optimize option persistent.
1750
  if ( ! empty( $_REQUEST['ewww_force_smart'] ) ) {
 
1751
  set_transient( 'ewww_image_optimizer_smart_reopt', true, HOUR_IN_SECONDS );
1752
  } else {
 
1753
  delete_transient( 'ewww_image_optimizer_smart_reopt' );
1754
  }
 
 
 
 
1755
  // Find out if our nonce is on it's last leg/tick.
1756
  if ( ! empty( $_REQUEST['ewww_wpnonce'] ) ) {
1757
- $tick = wp_verify_nonce( $_REQUEST['ewww_wpnonce'], 'ewww-image-optimizer-bulk' );
1758
  if ( 2 === $tick ) {
1759
  $output['new_nonce'] = wp_create_nonce( 'ewww-image-optimizer-bulk' );
1760
  } else {
@@ -1773,7 +1822,7 @@ function ewww_image_optimizer_bulk_loop( $hook = '', $delay = 0 ) {
1773
  if ( ! $image->file ) {
1774
  ewwwio_ob_clean();
1775
  die(
1776
- ewwwio_json_encode(
1777
  array(
1778
  'done' => 1,
1779
  'completed' => 0,
@@ -1828,7 +1877,7 @@ function ewww_image_optimizer_bulk_loop( $hook = '', $delay = 0 ) {
1828
  delete_transient( 'ewww_image_optimizer_bulk_counter_measures' );
1829
  delete_transient( 'ewww_image_optimizer_bulk_current_image' );
1830
  ewwwio_ob_clean();
1831
- die( ewwwio_json_encode( $output ) );
1832
  }
1833
  // Delete a pending record if the optimization failed for whatever reason.
1834
  if ( ! $file && $image->id ) {
@@ -1864,7 +1913,7 @@ function ewww_image_optimizer_bulk_loop( $hook = '', $delay = 0 ) {
1864
  }
1865
  $image->file = $file;
1866
  $image->converted = $original;
1867
- $meta['file'] = trailingslashit( dirname( $meta['file'] ) ) . basename( $file );
1868
  $image->update_converted_attachment( $meta );
1869
  $meta = $image->convert_sizes( $meta );
1870
  }
@@ -1981,7 +2030,7 @@ function ewww_image_optimizer_bulk_loop( $hook = '', $delay = 0 ) {
1981
  }
1982
  $output['current_time'] = time();
1983
  ewwwio_ob_clean();
1984
- die( ewwwio_json_encode( $output ) );
1985
  }
1986
 
1987
  /**
@@ -1991,9 +2040,12 @@ function ewww_image_optimizer_bulk_update_meta() {
1991
  ewwwio_debug_message( '<b>' . __FUNCTION__ . '()</b>' );
1992
  // Verify that an authorized user has started the optimizer.
1993
  $permissions = apply_filters( 'ewww_image_optimizer_bulk_permissions', '' );
1994
- if ( ! wp_verify_nonce( $_REQUEST['ewww_wpnonce'], 'ewww-image-optimizer-bulk' ) || ! current_user_can( $permissions ) ) {
1995
  ewwwio_ob_clean();
1996
- die( ewwwio_json_encode( array( 'error' => esc_html__( 'Access token has expired, please reload the page.', 'ewww-image-optimizer' ) ) ) );
 
 
 
1997
  }
1998
  $attachment_id = (int) $_REQUEST['attachment_id'];
1999
  ewwwio_debug_message( "saving attachment meta for $attachment_id" );
@@ -2010,7 +2062,7 @@ function ewww_image_optimizer_bulk_update_meta() {
2010
  }
2011
  wp_update_attachment_metadata( $attachment_id, $meta );
2012
  do_action( 'ewww_image_optimizer_after_optimize_attachment', $attachment_id, $meta );
2013
- die( ewwwio_json_encode( array( 'success' => 1 ) ) );
2014
  }
2015
 
2016
  /**
@@ -2019,7 +2071,7 @@ function ewww_image_optimizer_bulk_update_meta() {
2019
  function ewww_image_optimizer_bulk_cleanup() {
2020
  // Verify that an authorized user has started the optimizer.
2021
  $permissions = apply_filters( 'ewww_image_optimizer_bulk_permissions', '' );
2022
- if ( ! wp_verify_nonce( $_REQUEST['ewww_wpnonce'], 'ewww-image-optimizer-bulk' ) || ! current_user_can( $permissions ) ) {
2023
  ewwwio_ob_clean();
2024
  die( '<p><b>' . esc_html__( 'Access token has expired, please reload the page.', 'ewww-image-optimizer' ) . '</b></p>' );
2025
  }
21
  if ( ! class_exists( 'WP_Background_Process' ) ) {
22
  require_once( EWWW_IMAGE_OPTIMIZER_PLUGIN_PATH . 'background.php' );
23
  }
24
+ if (
25
+ ! empty( $_POST['ewww_nonce'] ) &&
26
+ wp_verify_nonce( sanitize_key( $_POST['ewww_nonce'] ), 'ewww_image_optimizer_clear_queue' ) &&
27
+ ! empty( $_POST['action'] ) &&
28
+ 'ewww_image_optimizer_clear_queue' === $_POST['action'] &&
29
+ current_user_can( 'manage_options' )
30
+ ) {
31
  $ewwwio_media_background->cancel_process();
32
  $ewwwio_image_background->cancel_process();
33
  update_option( 'ewwwio_stop_scheduled_scan', true, false );
43
  return;
44
  }
45
 
46
+ echo "<div id='ewww-aux-forms'>\n";
47
+ echo "<p id='ewww-table-info' class='ewww-tool-info'>" .
48
+ /* translators: %s: number of images */
49
+ sprintf( esc_html__( 'The plugin keeps track of already optimized images to prevent re-optimization. There are %s images that have been optimized so far.', 'ewww-image-optimizer' ), esc_html( number_format_i18n( $already_optimized ) ) ) .
50
+ "</p>\n";
51
+ echo "<form id='ewww-show-table' class='ewww-tool-form' method='post' action=''>\n" .
52
  '<button type="submit" class="button-primary action">' . esc_html__( 'Show Optimized Images', 'ewww-image-optimizer' ) . "</button>\n" .
53
  "</form>\n";
54
 
55
+ ewwwio_table_nav_controls();
56
+ echo '<div id="ewww-bulk-table" class="ewww-aux-table"></div>';
57
+ ewwwio_table_nav_controls();
58
+ echo "\n</div>\n";
59
+
60
+ $queue_status = __( 'idle', 'ewww-image-optimizer' );
61
  if ( $ewwwio_media_background->is_process_running() ) {
62
+ $queue_status = __( 'running', 'ewww-image-optimizer' );
63
  }
64
  if ( $ewwwio_image_background->is_process_running() ) {
65
+ $queue_status = __( 'running', 'ewww-image-optimizer' );
66
  }
67
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
68
  echo '<hr class="ewww-tool-divider">';
69
  $queue_count = $ewwwio_media_background->count_queue();
70
  $queue_count += $ewwwio_image_background->count_queue();
71
  /* translators: %s: idle/running */
72
+ echo "<p id='ewww-queue-info' class='ewww-tool-info'>" . sprintf( esc_html__( 'Current queue status: %s', 'ewww-image-optimizer' ), esc_html( $queue_status ) ) . "<br>\n";
73
  if ( $queue_count ) {
74
  /* translators: %d: number of images */
75
+ echo sprintf( esc_html__( 'There are %d images in the queue currently.', 'ewww-image-optimizer' ), (int) $queue_count ) . "</p>\n";
76
  $nonce = wp_create_nonce( 'ewww_image_optimizer_clear_queue' );
77
  echo "<form id='ewww-clear-queue' class='ewww-tool-form' method='post' action=''>\n" .
78
+ "<input type='hidden' id='ewww_nonce' name='ewww_nonce' value='" . esc_attr( $nonce ) . "'>" .
79
  "<input type='hidden' name='action' value='ewww_image_optimizer_clear_queue'>" .
80
  '<button type="submit" class="button-secondary action">' . esc_html__( 'Clear Queue', 'ewww-image-optimizer' ) . "</button>\n" .
81
  "</form>\n";
111
  echo '<hr class="ewww-tool-divider">';
112
  echo "<div>\n<p id='ewww-clean-meta-info' class='ewww-tool-info'>" .
113
  /* translators: 1: postmeta table name 2: ewwwio_images table name */
114
+ esc_html( sprintf( __( 'Sites using EWWW IO for 3+ years may have optimization data that still needs to be migrated between the %1$s and %2$s tables.', 'ewww-image-optimizer' ), $wpdb->postmeta, $wpdb->ewwwio_images ) ) . "</p>\n";
115
  echo "<form id='ewww-clean-meta' class='ewww-tool-form' method='post' action=''>\n" .
116
  "<input type='submit' class='button-secondary action' value='" . esc_attr__( 'Migrate Optimization Records', 'ewww-image-optimizer' ) . "' />\n" .
117
  "</form>\n</div>\n";
127
  echo "</div>\n";
128
  }
129
 
130
+ /**
131
+ * Outputs the navigation controls for the optimized images table.
132
+ */
133
+ function ewwwio_table_nav_controls() {
134
+ echo "<div class='tablenav ewww-aux-table' style='display:none'>\n" .
135
+ '<form class="ewww-search-form" style="float:left;">' . "\n" .
136
+ '<label for="ewww-search-input" class="screen-reader-text">' . esc_html__( 'Search', 'ewww-image-optimizer' ) . '</label>' . "\n" .
137
+ '<input type="search" class="ewww-search-input search" name="ewww-search-input" value="">' . "\n" .
138
+ '<input type="submit" class="ewww-search-submit button" value="' . esc_attr__( 'Search', 'ewww-image-optimizer' ) . '">' . "\n" .
139
+ '<span class="ewww-search-count"></span>' . "\n" .
140
+ '</form>' . "\n" .
141
+ '<div class="tablenav-pages ewww-aux-table">' . "\n" .
142
+ '<span class="displaying-num ewww-aux-table"></span>' . "\n" .
143
+ '<span class="pagination-links ewww-aux-table">' . "\n" .
144
+ '<a class="tablenav-pages-navspan button first-page" style="display:none">&laquo;</a>' . "\n" .
145
+ '<a class="tablenav-pages-navspan button prev-page" style="display:none">&lsaquo;</a>' . "\n" .
146
+ /* translators: 1: current page in list of images 2: total pages for list of images */
147
+ '<span class="current-page">' . sprintf( esc_html__( 'page %1$d of %2$d', 'ewww-image-optimizer' ), 1, 0 ) . "</span>\n" .
148
+ '<a class="tablenav-pages-navspan button next-page" style="display:none">&rsaquo;</a>' . "\n" .
149
+ '<a class="tablenav-pages-navspan button last-page" style="display:none">&raquo;</a>' .
150
+ '</span>' . "\n" .
151
+ '</div>' . "\n" .
152
+ '</div>' . "\n";
153
+ }
154
+
155
  /**
156
  * Prepares the javascript functions for the tools page.
157
  *
215
  return;
216
  }
217
  if ( ewww_image_optimizer_get_option( 'ewww_image_optimizer_cloud_key' ) ) {
218
+ echo '<a id="ewww-bulk-credits-available" target="_blank" style="margin-left:20px" class="page-title-action" href="https://ewww.io/my-account/">' . esc_html__( 'Image credits available:', 'ewww-image-optimizer' ) . ' ' . esc_html( ewww_image_optimizer_cloud_quota() ) . '</a>';
219
  echo '<hr class="wp-header-end">';
220
  }
221
  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>';
245
  $resize_count = count( $resizes );
246
  }
247
  $resize_count = ( ! empty( $resize_count ) && $resize_count > 1 ? $resize_count : 6 );
248
+ if ( ! empty( $_REQUEST['ids'] ) && ( preg_match( '/^[\d,]+$/', sanitize_text_field( wp_unslash( $_REQUEST['ids'] ) ) ) || is_numeric( sanitize_text_field( wp_unslash( $_REQUEST['ids'] ) ) ) ) ) { // phpcs:ignore WordPress.Security.NonceVerification
249
  echo '<p class="ewww-media-info ewww-bulk-info">' .
250
  /* translators: 1: number of images 2: number of registered image sizes */
251
+ esc_html( sprintf( _n( '%1$s uploaded item in the Media Library has been selected with up to %2$d image files per upload.', '%1$s uploaded items in the Media Library have been selected with up to %2$d image files per upload.', $fullsize_count, 'ewww-image-optimizer' ), number_format_i18n( $fullsize_count ), $resize_count ) ) .
252
  ' ' . esc_html__( 'The total number of images found will be displayed before optimization begins.', 'ewww-image-optimizer' ) .
253
  '</p>';
254
  } else {
255
  echo '<p class="ewww-media-info ewww-bulk-info">' .
256
  /* translators: 1: number of images 2: number of registered image sizes */
257
+ esc_html( sprintf( _n( '%1$s uploaded item in the Media Library has been selected with up to %2$d image files per upload.', '%1$s uploaded items in the Media Library have been selected with up to %2$d image files per upload.', $fullsize_count, 'ewww-image-optimizer' ), number_format_i18n( $fullsize_count ), $resize_count ) ) .
258
  ' ' . esc_html__( 'The total number of images found will be displayed before optimization begins.', 'ewww-image-optimizer' ) .
259
  '<br />' .
260
  esc_html__( 'The active theme, BuddyPress, WP Symposium, and folders that you have configured will also be scanned for unoptimized images.', 'ewww-image-optimizer' ) .
276
  * Outputs the status area and delay/force controls for the Bulk optimize page.
277
  */
278
  function ewww_image_optimizer_bulk_head_output() {
279
+ global $ewww_force;
280
  $loading_image = plugins_url( '/images/wpspin.gif', __FILE__ );
281
  $delay = ewww_image_optimizer_get_option( 'ewww_image_optimizer_delay' ) ? (int) ewww_image_optimizer_get_option( 'ewww_image_optimizer_delay' ) : 0;
282
  ?>
283
  <div id="ewww-bulk-loading">
284
+ <p id="ewww-loading" class="ewww-bulk-info" style="display:none"><?php esc_html_e( 'Importing', 'ewww-image-optimizer' ); ?>&nbsp;<img src='<?php echo esc_url( $loading_image ); ?>' /></p>
285
  </div>
286
  <div id="ewww-bulk-progressbar"></div>
287
  <div id="ewww-bulk-timer" style="float:right;"></div>
312
  </div>
313
  </div>
314
  <form id="ewww-bulk-controls" class="ewww-bulk-form">
315
+ <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' ); ?>
316
+ &emsp;<input type="checkbox" id="ewww-force" name="ewww-force"<?php echo ( get_transient( 'ewww_image_optimizer_force_reopt' ) || ! empty( $ewww_force ) ) ? ' checked' : ''; ?>>
317
  &nbsp;<?php esc_html_e( 'Previously optimized images will be skipped by default, check this box before scanning to override.', 'ewww-image-optimizer' ); ?>
318
  &nbsp;<a href="tools.php?page=ewww-image-optimizer-tools"><?php esc_html_e( 'View optimization history.', 'ewww-image-optimizer' ); ?></a>
319
  </p>
320
  <?php ewww_image_optimizer_bulk_variant_option(); ?>
321
  <?php ewww_image_optimizer_bulk_webp_only(); ?>
322
  <p>
323
+ <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' ); ?>
324
  </p>
325
  <div id="ewww-delay-slider"></div>
326
  </form>
337
  if ( ! ewww_image_optimizer_get_option( 'ewww_image_optimizer_cloud_key' ) ) {
338
  return;
339
  }
340
+ global $ewww_force_smart;
341
  ?>
342
  <p><label for="ewww-force-smart" style="font-weight: bold"><?php esc_html_e( 'Smart Re-optimize', 'ewww-image-optimizer' ); ?></label>
343
+ &emsp;<input type="checkbox" id="ewww-force-smart" name="ewww-force-smart"<?php echo ( get_transient( 'ewww_image_optimizer_smart_reopt' ) || ! empty( $ewww_force_smart ) ) ? ' checked' : ''; ?>>
344
  &nbsp;<?php esc_html_e( 'If compression settings have changed, re-optimize images that were compressed on the old settings. If possible, images compressed in Premium mode will be restored to originals beforehand.', 'ewww-image-optimizer' ); ?>
345
  </p>
346
  <?php
353
  if ( ! ewww_image_optimizer_get_option( 'ewww_image_optimizer_webp' ) ) {
354
  return;
355
  }
356
+ global $ewww_webp_only;
357
  ?>
358
  <p><label for="ewww-webp-only" style="font-weight: bold"><?php esc_html_e( 'WebP Only', 'ewww-image-optimizer' ); ?></label>
359
+ &emsp;<input type="checkbox" id="ewww-webp-only" name="ewww-webp-only"<?php echo ( ! empty( $ewww_webp_only ) ) ? ' checked' : ''; ?>>
360
  &nbsp;<?php esc_html_e( 'Skip compression and only attempt WebP conversion.', 'ewww-image-optimizer' ); ?>
361
  </p>
362
  <?php
373
  function ewww_image_optimizer_bulk_action_output( $button_text, $fullsize_count, $resume = '' ) {
374
  $loading_image = plugins_url( '/images/wpspin.gif', __FILE__ );
375
  /* translators: %s: number of images */
376
+ $scanning_starter_message = sprintf( __( 'Stage 1, %s items left to scan.', 'ewww-image-optimizer' ), number_format_i18n( $fullsize_count ) );
377
  if ( 'true' === $resume ) {
378
  /* translators: %s: number of images, formatted for locale */
379
+ $button_text = sprintf( __( 'Optimize %s images', 'ewww-image-optimizer' ), number_format_i18n( $fullsize_count ) );
380
  $scan_hide = 'style="display:none"';
381
  $start_hide = '';
382
  } else {
386
  }
387
  ?>
388
  <p id="ewww-nothing" class="ewww-bulk-info" style="display:none"><?php echo esc_html_e( 'There are no images to optimize.', 'ewww-image-optimizer' ); ?></p>
389
+ <p id="ewww-scanning" class="ewww-bulk-info" style="display:none"><?php echo esc_html( $scanning_starter_message ); ?>&nbsp;<img src='<?php echo esc_url( $loading_image ); ?>' alt='loading'/></p>
390
+ <form id="ewww-aux-start" class="ewww-bulk-form" <?php echo ( 'true' === $resume ? 'style="display:none"' : '' ); ?> method="post" action="">
391
  <input id="ewww-aux-first" type="submit" class="button-primary action" value="<?php esc_attr_e( 'Scan for unoptimized images', 'ewww-image-optimizer' ); ?>" />
392
  </form>
393
+ <form id="ewww-bulk-start" class="ewww-bulk-form" <?php echo ( 'true' === $resume ? '' : 'style="display:none"' ); ?> method="post" action="">
394
+ <input id="ewww-bulk-first" type="submit" class="button-primary action" value="<?php echo esc_attr( $button_text ); ?>" />
395
  </form>
396
  <?php
397
  }
466
  break;
467
  case 'ngg':
468
  // See if we were given attachment IDs to work with via GET/POST.
469
+ if ( ! empty( $_REQUEST['doaction'] ) || get_option( 'ewww_image_optimizer_bulk_ngg_resume' ) ) { // phpcs:ignore WordPress.Security.NonceVerification
470
  // Retrieve the attachment IDs that were pre-loaded in the database.
471
  $attachment_ids = get_option( 'ewww_image_optimizer_bulk_ngg_attachments' );
472
  array_walk( $attachment_ids, 'intval' );
529
  } // End while().
530
  break;
531
  case 'flag':
532
+ if ( ! empty( $_REQUEST['doaction'] ) || get_option( 'ewww_image_optimizer_bulk_flag_resume' ) ) { // phpcs:ignore WordPress.Security.NonceVerification
533
  // Retrieve the attachment IDs that were pre-loaded in the database.
534
  $attachment_ids = get_option( 'ewww_image_optimizer_bulk_flag_attachments' );
535
  array_walk( $attachment_ids, 'intval' );
608
  return;
609
  }
610
  global $wpdb;
611
+ global $ewww_force;
612
+ global $ewww_webp_only;
613
  // Initialize the $attachments variable.
614
  $attachments = array();
615
  // Check to see if we are supposed to reset the bulk operation and verify we are authorized to do so.
616
+ if ( ! empty( $_REQUEST['ewww_reset'] ) && ! empty( $_REQUEST['ewww_wpnonce'] ) && wp_verify_nonce( sanitize_key( $_REQUEST['ewww_wpnonce'] ), 'ewww-image-optimizer-bulk-reset' ) ) {
617
  ewwwio_debug_message( 'resetting resume flags' );
618
  // Set the 'bulk resume' option to an empty string to reset the bulk operation.
619
  update_option( 'ewww_image_optimizer_bulk_resume', '' );
623
  ewww_image_optimizer_delete_pending();
624
  }
625
  // Check to see if we are supposed to convert the auxiliary images table and verify we are authorized to do so.
626
+ if ( ! empty( $_REQUEST['ewww_convert'] ) && ! empty( $_REQUEST['ewww_wpnonce'] ) && wp_verify_nonce( sanitize_key( $_REQUEST['ewww_wpnonce'] ), 'ewww-image-optimizer-aux-images-convert' ) ) {
627
  ewww_image_optimizer_aux_images_convert();
628
  }
629
+ if ( ! empty( $_GET['ewww_webp_only'] ) ) {
630
+ $ewww_webp_only = true;
631
+ }
632
+ if ( ! empty( $_GET['ewww_force'] ) ) {
633
+ $ewww_force = true;
634
+ }
635
  // Check the 'bulk resume' option.
636
  $resume = get_option( 'ewww_image_optimizer_bulk_resume' );
637
  $scanning = get_option( 'ewww_image_optimizer_aux_resume' );
645
  }
646
  // See if we were given attachment IDs to work with via GET/POST.
647
  $ids = array();
648
+ if ( ! empty( $_REQUEST['ids'] ) && ( preg_match( '/^[\d,]+$/', sanitize_text_field( wp_unslash( $_REQUEST['ids'] ) ), $request_ids ) || is_numeric( sanitize_text_field( wp_unslash( $_REQUEST['ids'] ) ) ) ) ) {
649
  ewww_image_optimizer_delete_pending();
650
  set_transient( 'ewww_image_optimizer_skip_aux', true, 3 * MINUTE_IN_SECONDS );
651
+ if ( is_numeric( sanitize_text_field( wp_unslash( $_REQUEST['ids'] ) ) ) ) {
652
  $ids[] = (int) $_REQUEST['ids'];
653
  } else {
654
  $ids = explode( ',', $request_ids[0] );
655
  array_walk( $ids, 'intval' );
656
  }
657
  $sample_post_type = get_post_type( $ids[0] );
 
658
  ewwwio_debug_message( "post type (checking for ims_gallery): $sample_post_type" );
659
  if ( 'ims_gallery' === $sample_post_type ) {
660
  $attachments = array();
776
  }
777
  unset( $optimized['path'] );
778
  $optimized_list[ $optimized_path ] = $optimized;
 
 
 
 
 
779
  }
780
  ewwwio_memory( 'removed original records' );
781
  $offset += $max_query;
905
  ewwwio_debug_message( 'bailing no cli' );
906
  ewww_image_optimizer_debug_log();
907
  ewwwio_ob_clean();
908
+ die( wp_json_encode( array( 'error' => esc_html__( 'Access denied.', 'ewww-image-optimizer' ) ) ) );
909
  }
910
+ if ( ! empty( $_REQUEST['ewww_scan'] ) && ( empty( $_REQUEST['ewww_wpnonce'] ) || ! wp_verify_nonce( sanitize_key( $_REQUEST['ewww_wpnonce'] ), 'ewww-image-optimizer-bulk' ) || ! current_user_can( $permissions ) ) ) {
911
  ewwwio_debug_message( 'bailing no nonce' );
912
  ewww_image_optimizer_debug_log();
913
  ewwwio_ob_clean();
914
+ die( wp_json_encode( array( 'error' => esc_html__( 'Access token has expired, please reload the page.', 'ewww-image-optimizer' ) ) ) );
915
  }
916
  global $wpdb;
917
  if ( strpos( $wpdb->charset, 'utf8' ) === false ) {
920
  } else {
921
  $ewwwdb = $wpdb;
922
  }
923
+ global $ewww_scan;
924
+ global $ewww_force;
925
+ global $ewww_force_smart;
926
+ global $ewww_webp_only;
927
+ $ewww_scan = empty( $_REQUEST['ewww_scan'] ) ? '' : sanitize_key( $_REQUEST['ewww_scan'] );
928
+ // Make the Force Re-optimize option persistent.
929
+ if ( ! empty( $_REQUEST['ewww_force'] ) ) {
930
+ ewwwio_debug_message( 'forcing re-optimize: true' );
931
+ $ewww_force = true;
932
+ set_transient( 'ewww_image_optimizer_force_reopt', true, HOUR_IN_SECONDS );
933
+ } else {
934
+ $ewww_force = false;
935
+ delete_transient( 'ewww_image_optimizer_force_reopt' );
936
+ }
937
+ // Make the Smart Re-optimize option persistent.
938
+ if ( ! empty( $_REQUEST['ewww_force_smart'] ) ) {
939
+ ewwwio_debug_message( 'forcing (smart) re-optimize: true' );
940
+ $ewww_force_smart = true;
941
+ set_transient( 'ewww_image_optimizer_smart_reopt', true, HOUR_IN_SECONDS );
942
+ } else {
943
+ $ewww_force_smart = false;
944
+ delete_transient( 'ewww_image_optimizer_smart_reopt' );
945
+ }
946
+ $ewww_webp_only = false;
947
+ if ( ! empty( $_REQUEST['ewww_webp_only'] ) ) {
948
+ $ewww_webp_only = true;
949
+ }
950
  global $optimized_list;
951
  $queued_ids = array();
952
  $skipped_ids = array();
976
 
977
  $attachment_ids = ewww_image_optimizer_get_unscanned_attachments( 'media', $max_query );
978
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
979
  if ( ! empty( $attachment_ids ) && count( $attachment_ids ) > 300 ) {
980
  ewww_image_optimizer_debug_log();
981
  ewww_image_optimizer_optimized_list();
986
 
987
  list( $bad_attachments, $bad_attachment ) = ewww_image_optimizer_get_bad_attachments();
988
 
989
+ if ( empty( $attachment_ids ) && $ewww_scan ) {
990
  // When the media library is finished, run the aux script function to scan for additional images.
991
  ewww_image_optimizer_aux_images_script();
992
  }
1027
  } else {
1028
  ewwwio_debug_message( 'no array found' );
1029
  ewwwio_ob_clean();
1030
+ die( wp_json_encode( array( 'error' => esc_html__( 'List of attachment IDs not found.', 'ewww-image-optimizer' ) ) ) );
1031
  }
1032
 
1033
  $attachment_meta = ewww_image_optimizer_fetch_metadata_batch( $attachments_in );
1146
  $should_resize = ewww_image_optimizer_should_resize( $file_path, true );
1147
  if (
1148
  ! empty( $attachment_meta[ $selected_id ]['tinypng'] ) &&
1149
+ empty( $ewww_force ) &&
1150
+ empty( $ewww_webp_only ) &&
1151
  ! $should_resize
1152
  ) {
1153
  ewwwio_debug_message( "TinyPNG already compressed $selected_id" );
1160
 
1161
  $attachment_images['full'] = $file_path;
1162
 
1163
+ $retina_path = ewww_image_optimizer_get_hidpi_path( $file_path );
1164
  if ( $retina_path ) {
1165
  $attachment_images['full-retina'] = $retina_path;
1166
  }
1237
  ewwwio_debug_message( "found retina via wr2x_get_retina $retina_path" );
1238
  $attachment_images[ $size . '-retina' ] = $retina_path;
1239
  } else {
1240
+ $retina_path = ewww_image_optimizer_get_hidpi_path( $resize_path );
1241
  if ( $retina_path ) {
1242
  ewwwio_debug_message( "found retina via hidpi_opt $retina_path" );
1243
  $attachment_images[ $size . '-retina' ] = $retina_path;
1338
  }
1339
  $compression_level = ewww_image_optimizer_get_level( $mime );
1340
  $smart_reopt = false;
1341
+ if ( ! empty( $ewww_force_smart ) && ewww_image_optimizer_level_mismatch( $already_optimized['level'], $compression_level ) ) {
1342
  $smart_reopt = true;
1343
  }
1344
  if ( 'full' === $size && $should_resize ) {
1345
  $smart_reopt = true;
1346
  }
1347
+ if ( (int) $already_optimized['image_size'] === (int) $image_size && empty( $ewww_force ) && ! $smart_reopt ) {
1348
  ewwwio_debug_message( "match found for $file_path" );
1349
  ewww_image_optimizer_debug_log();
1350
  continue;
1508
  if ( $remaining ) {
1509
  ewwwio_ob_clean();
1510
  die(
1511
+ wp_json_encode(
1512
  array(
1513
  /* translators: %s: number of images */
1514
  'remaining' => sprintf( esc_html__( 'Stage 1, %s items left to scan.', 'ewww-image-optimizer' ), number_format_i18n( $remaining ) ) . "&nbsp;<img src='$loading_image' />",
1521
  } else {
1522
  ewwwio_ob_clean();
1523
  die(
1524
+ wp_json_encode(
1525
  array(
1526
  'remaining' => esc_html__( 'Stage 2, please wait.', 'ewww-image-optimizer' ) . "&nbsp;<img src='$loading_image' />",
1527
  'notice' => $notice,
1539
  function ewww_image_optimizer_bulk_quota_update() {
1540
  // Verify that an authorized user has made the request.
1541
  $permissions = apply_filters( 'ewww_image_optimizer_bulk_permissions', '' );
1542
+ if ( empty( $_REQUEST['ewww_wpnonce'] ) || ! wp_verify_nonce( sanitize_key( $_REQUEST['ewww_wpnonce'] ), 'ewww-image-optimizer-bulk' ) || ! current_user_can( $permissions ) ) {
1543
  ewwwio_ob_clean();
1544
  die( esc_html__( 'Access token has expired, please reload the page.', 'ewww-image-optimizer' ) );
1545
  }
1546
  ewwwio_ob_clean();
1547
  if ( ewww_image_optimizer_get_option( 'ewww_image_optimizer_cloud_key' ) ) {
1548
+ echo esc_html__( 'Image credits available:', 'ewww-image-optimizer' ) . ' ' . esc_html( ewww_image_optimizer_cloud_quota() );
1549
  }
1550
  ewwwio_memory( __FUNCTION__ );
1551
  die();
1558
  ewwwio_debug_message( '<b>' . __FUNCTION__ . '()</b>' );
1559
  // Verify that an authorized user has made the request.
1560
  $permissions = apply_filters( 'ewww_image_optimizer_bulk_permissions', '' );
1561
+ if ( empty( $_REQUEST['ewww_wpnonce'] ) || ! wp_verify_nonce( sanitize_key( $_REQUEST['ewww_wpnonce'] ), 'ewww-image-optimizer-bulk' ) || ! current_user_can( $permissions ) ) {
1562
  ewwwio_ob_clean();
1563
+ die( wp_json_encode( array( 'error' => esc_html__( 'Access token has expired, please reload the page.', 'ewww-image-optimizer' ) ) ) );
1564
  }
1565
  session_write_close();
1566
  $output = array();
1582
  $output['start_time'] = time();
1583
  ewwwio_memory( __FUNCTION__ );
1584
  ewwwio_ob_clean();
1585
+ die( wp_json_encode( $output ) );
1586
  }
1587
 
1588
  /**
1602
  */
1603
  function ewww_image_optimizer_bulk_counter_measures( $image ) {
1604
  ewwwio_debug_message( '<b>' . __FUNCTION__ . '()</b>' );
1605
+ if ( ! empty( $_REQUEST['ewww_error_counter'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification
1606
+ $error_counter = (int) $_REQUEST['ewww_error_counter']; // phpcs:ignore WordPress.Security.NonceVerification
1607
  if ( 30 !== $error_counter ) {
1608
  $failed_file = get_transient( 'ewww_image_optimizer_failed_file' );
1609
  $previous_incomplete_file = get_transient( 'ewww_image_optimizer_bulk_current_image' );
1756
  */
1757
  function ewww_image_optimizer_bulk_loop( $hook = '', $delay = 0 ) {
1758
  ewwwio_debug_message( '<b>' . __FUNCTION__ . '()</b>' );
1759
+ global $ewww_force;
1760
+ global $ewww_force_smart;
1761
+ global $ewww_webp_only;
1762
  global $ewww_defer;
1763
  $ewww_defer = false;
1764
  $output = array();
1765
  $time_adjustment = 0;
1766
  // Verify that an authorized user has started the optimizer.
1767
  $permissions = apply_filters( 'ewww_image_optimizer_bulk_permissions', '' );
1768
+ if (
1769
+ 'ewww-image-optimizer-cli' !== $hook &&
1770
+ (
1771
+ empty( $_REQUEST['ewww_wpnonce'] ) ||
1772
+ ! wp_verify_nonce( sanitize_key( $_REQUEST['ewww_wpnonce'] ), 'ewww-image-optimizer-bulk' ) ||
1773
+ ! current_user_can( $permissions )
1774
+ )
1775
+ ) {
1776
  ewwwio_ob_clean();
1777
+ die( wp_json_encode( array( 'error' => esc_html__( 'Access token has expired, please reload the page.', 'ewww-image-optimizer' ) ) ) );
1778
  }
1779
  session_write_close();
1780
  // Retrieve the time when the optimizer starts.
1783
  set_transient( 'ewww_image_optimizer_no_scheduled_optimization', true, 10 * MINUTE_IN_SECONDS );
1784
  // Make the Force Re-optimize option persistent.
1785
  if ( ! empty( $_REQUEST['ewww_force'] ) ) {
1786
+ $ewww_force = true;
1787
  set_transient( 'ewww_image_optimizer_force_reopt', true, HOUR_IN_SECONDS );
1788
  } else {
1789
+ $ewww_force = false;
1790
  delete_transient( 'ewww_image_optimizer_force_reopt' );
1791
  }
1792
  // Make the Smart Re-optimize option persistent.
1793
  if ( ! empty( $_REQUEST['ewww_force_smart'] ) ) {
1794
+ $ewww_force_smart = true;
1795
  set_transient( 'ewww_image_optimizer_smart_reopt', true, HOUR_IN_SECONDS );
1796
  } else {
1797
+ $ewww_force_smart = false;
1798
  delete_transient( 'ewww_image_optimizer_smart_reopt' );
1799
  }
1800
+ $ewww_webp_only = false;
1801
+ if ( ! empty( $_REQUEST['ewww_webp_only'] ) ) {
1802
+ $ewww_webp_only = true;
1803
+ }
1804
  // Find out if our nonce is on it's last leg/tick.
1805
  if ( ! empty( $_REQUEST['ewww_wpnonce'] ) ) {
1806
+ $tick = wp_verify_nonce( sanitize_key( $_REQUEST['ewww_wpnonce'] ), 'ewww-image-optimizer-bulk' );
1807
  if ( 2 === $tick ) {
1808
  $output['new_nonce'] = wp_create_nonce( 'ewww-image-optimizer-bulk' );
1809
  } else {
1822
  if ( ! $image->file ) {
1823
  ewwwio_ob_clean();
1824
  die(
1825
+ wp_json_encode(
1826
  array(
1827
  'done' => 1,
1828
  'completed' => 0,
1877
  delete_transient( 'ewww_image_optimizer_bulk_counter_measures' );
1878
  delete_transient( 'ewww_image_optimizer_bulk_current_image' );
1879
  ewwwio_ob_clean();
1880
+ die( wp_json_encode( $output ) );
1881
  }
1882
  // Delete a pending record if the optimization failed for whatever reason.
1883
  if ( ! $file && $image->id ) {
1913
  }
1914
  $image->file = $file;
1915
  $image->converted = $original;
1916
+ $meta['file'] = _wp_relative_upload_path( $file );
1917
  $image->update_converted_attachment( $meta );
1918
  $meta = $image->convert_sizes( $meta );
1919
  }
2030
  }
2031
  $output['current_time'] = time();
2032
  ewwwio_ob_clean();
2033
+ die( wp_json_encode( $output ) );
2034
  }
2035
 
2036
  /**
2040
  ewwwio_debug_message( '<b>' . __FUNCTION__ . '()</b>' );
2041
  // Verify that an authorized user has started the optimizer.
2042
  $permissions = apply_filters( 'ewww_image_optimizer_bulk_permissions', '' );
2043
+ if ( empty( $_REQUEST['ewww_wpnonce'] ) || ! wp_verify_nonce( sanitize_key( $_REQUEST['ewww_wpnonce'] ), 'ewww-image-optimizer-bulk' ) || ! current_user_can( $permissions ) ) {
2044
  ewwwio_ob_clean();
2045
+ die( wp_json_encode( array( 'error' => esc_html__( 'Access token has expired, please reload the page.', 'ewww-image-optimizer' ) ) ) );
2046
+ }
2047
+ if ( empty( $_REQUEST['attachment_id'] ) ) {
2048
+ die( wp_json_encode( array( 'success' => 0 ) ) );
2049
  }
2050
  $attachment_id = (int) $_REQUEST['attachment_id'];
2051
  ewwwio_debug_message( "saving attachment meta for $attachment_id" );
2062
  }
2063
  wp_update_attachment_metadata( $attachment_id, $meta );
2064
  do_action( 'ewww_image_optimizer_after_optimize_attachment', $attachment_id, $meta );
2065
+ die( wp_json_encode( array( 'success' => 1 ) ) );
2066
  }
2067
 
2068
  /**
2071
  function ewww_image_optimizer_bulk_cleanup() {
2072
  // Verify that an authorized user has started the optimizer.
2073
  $permissions = apply_filters( 'ewww_image_optimizer_bulk_permissions', '' );
2074
+ if ( empty( $_REQUEST['ewww_wpnonce'] ) || ! wp_verify_nonce( sanitize_key( $_REQUEST['ewww_wpnonce'] ), 'ewww-image-optimizer-bulk' ) || ! current_user_can( $permissions ) ) {
2075
  ewwwio_ob_clean();
2076
  die( '<p><b>' . esc_html__( 'Access token has expired, please reload the page.', 'ewww-image-optimizer' ) . '</b></p>' );
2077
  }
changelog.txt CHANGED
@@ -1,3 +1,28 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  = 5.3.2 =
2
  * added: defer jQuery also with EXACTDN_DEFER_JQUERY override
3
  * added: Lazy Load supports VC grid layouts retrieved via AJAX
1
+ = 5.4.1 =
2
+ * fixed: Bulk Optimizer sticks on stage 2 when there are no images to optimize
3
+ * fixed: transparency in PNG images with color type 0 or 2 not detected
4
+ * fixed: transparency false positives for PNG images with color types 4 and 6
5
+ * fixed: lazy load skips img elements with unquoted src attributes
6
+ * fixed: images converted by PNG to JPG (and friends) do not have restore links in library
7
+
8
+ = 5.4.0 =
9
+ * added: EXACTDN_DEFER_JQUERY_SAFE override for when inline scripts depend on jQuery
10
+ * changed: code rewrite to validate output escaping, input sanitization, and markup on settings page
11
+ * changed: use data-cfasync=false to prevent deferring inline JS WebP script
12
+ * changed: Easy IO uses better query-string fall-back for plugins
13
+ * changed: Easy IO enforces https if available rather than protocol-relative URLs
14
+ * changed: resize detection ignores images smaller than 25px
15
+ * changed: settings streamlined when using Easy IO
16
+ * fixed: parallel optimization on multisite fails due to missing db prefix
17
+ * fixed: error when saving JS WebP on network/multsite admin
18
+ * fixed: images not resized when Media File Renamer is active
19
+ * fixed: PHP warning while using <picture> WebP
20
+ * fixed: Lazy Load, JS WebP and <picture> WebP have nested fall-back img elements if an image is found multiple times in a page
21
+ * fixed: Easy IO mangles srcset URLs when src URL is relative instead of absolute
22
+ * fixed: Easy IO URLs leaking into block editor for new uploads
23
+ * fixed: WebP rewriting with WP Offload Media skips sub-domains of blog domain
24
+ * deprecated: support for Image Store plugin (abandoned)
25
+
26
  = 5.3.2 =
27
  * added: defer jQuery also with EXACTDN_DEFER_JQUERY override
28
  * added: Lazy Load supports VC grid layouts retrieved via AJAX
classes/class-eio-alt-webp.php CHANGED
@@ -74,6 +74,7 @@ class EIO_Alt_Webp extends EIO_Page_Parser {
74
  if ( ewww_image_optimizer_ce_webp_enabled() ) {
75
  return false;
76
  }
 
77
  // Start an output buffer before any output starts.
78
  /* add_action( 'template_redirect', array( $this, 'buffer_start' ), 0 ); */
79
  add_filter( 'ewww_image_optimizer_filter_page_output', array( $this, 'filter_page_output' ), 20 );
@@ -83,10 +84,6 @@ class EIO_Alt_Webp extends EIO_Page_Parser {
83
  // Load up the minified script so we can inline it.
84
  $this->inline_script = file_get_contents( EWWW_IMAGE_OPTIMIZER_PLUGIN_PATH . 'includes/load_webp.min.js' );
85
 
86
- $this->home_url = trailingslashit( get_site_url() );
87
- ewwwio_debug_message( "home url: $this->home_url" );
88
- $this->relative_home_url = preg_replace( '/https?:/', '', $this->home_url );
89
- ewwwio_debug_message( "relative home url: $this->relative_home_url" );
90
  $upload_dir = wp_get_upload_dir();
91
  $this->content_url = trailingslashit( ! empty( $upload_dir['baseurl'] ) ? $upload_dir['baseurl'] : content_url( 'uploads' ) );
92
  ewwwio_debug_message( "content_url: $this->content_url" );
@@ -114,11 +111,11 @@ class EIO_Alt_Webp extends EIO_Page_Parser {
114
  $this->s3_active = $s3_domain;
115
  if ( $as3cf->get_setting( 'enable-object-prefix' ) ) {
116
  $this->s3_object_prefix = $as3cf->get_setting( 'object-prefix' );
117
- ewwwio_debug_message( $as3cf->get_setting( 'object-prefix' ) );
118
  }
119
  if ( $as3cf->get_setting( 'object-versioning' ) ) {
120
  $this->s3_object_version = true;
121
- ewwwio_debug_message( 'object versioning enabled' );
122
  }
123
  }
124
  }
@@ -129,14 +126,14 @@ class EIO_Alt_Webp extends EIO_Page_Parser {
129
  $this->webp_domains[] = $webp_domain;
130
  }
131
  }
132
- ewwwio_debug_message( 'checking any images matching these patterns for webp: ' . implode( ',', $this->webp_paths ) );
133
- ewwwio_debug_message( 'rewriting any images matching these domains to webp: ' . implode( ',', $this->webp_domains ) );
134
- if ( class_exists( 'ExactDN' ) && ewww_image_optimizer_get_option( 'ewww_image_optimizer_exactdn' ) ) {
135
  global $exactdn;
136
  $this->exactdn_domain = $exactdn->get_exactdn_domain();
137
  if ( $this->exactdn_domain ) {
138
  $this->parsing_exactdn = true;
139
- ewwwio_debug_message( 'parsing an exactdn page' );
140
  }
141
  }
142
 
@@ -354,17 +351,19 @@ class EIO_Alt_Webp extends EIO_Page_Parser {
354
  function filter_page_output( $buffer ) {
355
  ewwwio_debug_message( '<b>' . __METHOD__ . '()</b>' );
356
  // If any of this is true, don't filter the page.
357
- $uri = $_SERVER['REQUEST_URI'];
 
358
  if (
359
  empty( $buffer ) ||
360
  is_admin() ||
361
- ! empty( $_GET['cornerstone'] ) ||
362
  strpos( $uri, 'cornerstone-endpoint' ) !== false ||
363
  did_action( 'cornerstone_boot_app' ) || did_action( 'cs_before_preview_frame' ) ||
364
  '/print/' === substr( $uri, -7 ) ||
365
- ! empty( $_GET['et_fb'] ) ||
366
- ! empty( $_GET['tatsu'] ) ||
367
- ( ! empty( $_POST['action'] ) && 'tatsu_get_concepts' === $_POST['action'] ) ||
 
368
  is_embed() ||
369
  is_feed() ||
370
  is_preview() ||
@@ -374,51 +373,7 @@ class EIO_Alt_Webp extends EIO_Page_Parser {
374
  $this->is_amp() ||
375
  ewww_image_optimizer_ce_webp_enabled()
376
  ) {
377
- if ( empty( $buffer ) ) {
378
- ewwwio_debug_message( 'empty buffer' );
379
- }
380
- if ( is_admin() ) {
381
- ewwwio_debug_message( 'is_admin' );
382
- }
383
- if ( ! empty( $_GET['cornerstone'] ) || strpos( $uri, 'cornerstone-endpoint' ) !== false ) {
384
- ewwwio_debug_message( 'cornerstone editor' );
385
- }
386
- if ( did_action( 'cornerstone_boot_app' ) || did_action( 'cs_before_preview_frame' ) ) {
387
- ewwwio_debug_message( 'cornerstone app/preview' );
388
- }
389
- if ( '/print/' === substr( $uri, -7 ) ) {
390
- $this->debug_message( 'print page template' );
391
- }
392
- if ( ! empty( $_GET['et_fb'] ) ) {
393
- ewwwio_debug_message( 'et_fb' );
394
- }
395
- if ( ! empty( $_GET['tatsu'] ) || ( ! empty( $_POST['action'] ) && 'tatsu_get_concepts' === $_POST['action'] ) ) {
396
- ewwwio_debug_message( 'tatsu' );
397
- }
398
- if ( is_embed() ) {
399
- $this->debug_message( 'is_embed' );
400
- }
401
- if ( is_feed() ) {
402
- ewwwio_debug_message( 'is_feed' );
403
- }
404
- if ( is_preview() ) {
405
- ewwwio_debug_message( 'is_preview' );
406
- }
407
- if ( defined( 'REST_REQUEST' ) && REST_REQUEST ) {
408
- ewwwio_debug_message( 'rest request' );
409
- }
410
- if ( preg_match( '/^<\?xml/', $buffer ) ) {
411
- ewwwio_debug_message( 'not html, xml tag found' );
412
- }
413
- if ( strpos( $buffer, 'amp-boilerplate' ) ) {
414
- ewwwio_debug_message( 'AMP page processing' );
415
- }
416
- if ( $this->is_amp() ) {
417
- ewwwio_debug_message( 'AMP page processing (is_amp)' );
418
- }
419
- if ( ewww_image_optimizer_ce_webp_enabled() ) {
420
- ewwwio_debug_message( 'Cache Enabler WebP enabled' );
421
- }
422
  return $buffer;
423
  }
424
 
@@ -480,8 +435,10 @@ class EIO_Alt_Webp extends EIO_Page_Parser {
480
  }
481
  $nscript = $this->attr_copy( $image, $nscript );
482
  $this->set_attribute( $nscript, 'class', 'ewww_webp' );
483
- ewwwio_debug_message( "going to swap\n$image\nwith\n$nscript" . $image . '</noscript>' );
484
- $buffer = str_replace( $image, $nscript . $image . '</noscript>', $buffer );
 
 
485
  } elseif ( ! empty( $file ) && strpos( $image, 'data-lazy-src=' ) ) {
486
  // BJ Lazy Load & WP Rocket.
487
  $new_image = $image;
@@ -878,7 +835,7 @@ class EIO_Alt_Webp extends EIO_Page_Parser {
878
  if ( $webp_domain === $this->home_domain ) {
879
  continue;
880
  }
881
- ewwwio_debug_message( "looking for $webp_domain in $url" );
882
  if (
883
  ! empty( $this->s3_active ) &&
884
  false !== strpos( $url, $this->s3_active ) &&
@@ -899,10 +856,10 @@ class EIO_Alt_Webp extends EIO_Page_Parser {
899
  }
900
  }
901
  foreach ( $this->webp_paths as $webp_path ) {
902
- if ( false !== strpos( $webp_path, $this->home_domain ) || false === strpos( $webp_path, 'http' ) ) {
903
  continue;
904
  }
905
- ewwwio_debug_message( "looking for $webp_path in $url" );
906
  if (
907
  ! empty( $this->s3_active ) &&
908
  false !== strpos( $url, $this->s3_active ) &&
@@ -959,26 +916,13 @@ class EIO_Alt_Webp extends EIO_Page_Parser {
959
  /**
960
  * Converts a URL to a file-system path and checks if the resulting path exists.
961
  *
962
- * @param string $image The image URL to mangle.
 
963
  * @return bool True if a local file exists correlating to the URL, false otherwise.
964
  */
965
- function url_to_path_exists( $image ) {
966
- ewwwio_debug_message( '<b>' . __METHOD__ . '()</b>' );
967
- $image = $this->maybe_strip_object_version( $image );
968
- if ( 0 === strpos( $image, $this->relative_home_url ) ) {
969
- $imagepath = str_replace( $this->relative_home_url, ABSPATH, $image );
970
- } elseif ( 0 === strpos( $image, $this->home_url ) ) {
971
- $imagepath = str_replace( $this->home_url, ABSPATH, $image );
972
- } else {
973
- ewwwio_debug_message( 'not a valid local image' );
974
- return false;
975
- }
976
- $path_parts = explode( '?', $imagepath );
977
- if ( ewwwio_is_file( $path_parts[0] . '.webp' ) || ewwwio_is_file( $imagepath . '.webp' ) ) {
978
- ewwwio_debug_message( 'local .webp image found' );
979
- return true;
980
- }
981
- return false;
982
  }
983
 
984
  /**
@@ -1158,7 +1102,7 @@ class EIO_Alt_Webp extends EIO_Page_Parser {
1158
  return;
1159
  }
1160
  ewwwio_debug_message( 'loading webp script without wp_add_inline_script' );
1161
- echo '<script type="text/javascript">' . $this->inline_script . '</script>';
1162
  }
1163
  }
1164
 
74
  if ( ewww_image_optimizer_ce_webp_enabled() ) {
75
  return false;
76
  }
77
+ parent::__construct();
78
  // Start an output buffer before any output starts.
79
  /* add_action( 'template_redirect', array( $this, 'buffer_start' ), 0 ); */
80
  add_filter( 'ewww_image_optimizer_filter_page_output', array( $this, 'filter_page_output' ), 20 );
84
  // Load up the minified script so we can inline it.
85
  $this->inline_script = file_get_contents( EWWW_IMAGE_OPTIMIZER_PLUGIN_PATH . 'includes/load_webp.min.js' );
86
 
 
 
 
 
87
  $upload_dir = wp_get_upload_dir();
88
  $this->content_url = trailingslashit( ! empty( $upload_dir['baseurl'] ) ? $upload_dir['baseurl'] : content_url( 'uploads' ) );
89
  ewwwio_debug_message( "content_url: $this->content_url" );
111
  $this->s3_active = $s3_domain;
112
  if ( $as3cf->get_setting( 'enable-object-prefix' ) ) {
113
  $this->s3_object_prefix = $as3cf->get_setting( 'object-prefix' );
114
+ $this->debug_message( $as3cf->get_setting( 'object-prefix' ) );
115
  }
116
  if ( $as3cf->get_setting( 'object-versioning' ) ) {
117
  $this->s3_object_version = true;
118
+ $this->debug_message( 'object versioning enabled' );
119
  }
120
  }
121
  }
126
  $this->webp_domains[] = $webp_domain;
127
  }
128
  }
129
+ $this->debug_message( 'checking any images matching these patterns for webp: ' . implode( ',', $this->webp_paths ) );
130
+ $this->debug_message( 'rewriting any images matching these domains to webp: ' . implode( ',', $this->webp_domains ) );
131
+ if ( class_exists( 'ExactDN' ) && $this->get_option( 'ewww_image_optimizer_exactdn' ) ) {
132
  global $exactdn;
133
  $this->exactdn_domain = $exactdn->get_exactdn_domain();
134
  if ( $this->exactdn_domain ) {
135
  $this->parsing_exactdn = true;
136
+ $this->debug_message( 'parsing an exactdn page' );
137
  }
138
  }
139
 
351
  function filter_page_output( $buffer ) {
352
  ewwwio_debug_message( '<b>' . __METHOD__ . '()</b>' );
353
  // If any of this is true, don't filter the page.
354
+ $uri = add_query_arg( null, null );
355
+ $this->debug_message( "request uri is $uri" );
356
  if (
357
  empty( $buffer ) ||
358
  is_admin() ||
359
+ strpos( $uri, 'cornerstone=' ) !== false ||
360
  strpos( $uri, 'cornerstone-endpoint' ) !== false ||
361
  did_action( 'cornerstone_boot_app' ) || did_action( 'cs_before_preview_frame' ) ||
362
  '/print/' === substr( $uri, -7 ) ||
363
+ strpos( $uri, 'elementor-preview=' ) !== false ||
364
+ strpos( $uri, 'et_fb=' ) !== false ||
365
+ strpos( $uri, 'tatsu=' ) !== false ||
366
+ ( ! empty( $_POST['action'] ) && 'tatsu_get_concepts' === sanitize_text_field( wp_unslash( $_POST['action'] ) ) ) || // phpcs:ignore WordPress.Security.NonceVerification
367
  is_embed() ||
368
  is_feed() ||
369
  is_preview() ||
373
  $this->is_amp() ||
374
  ewww_image_optimizer_ce_webp_enabled()
375
  ) {
376
+ ewwwio_debug_message( 'JS WebP disabled' );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
377
  return $buffer;
378
  }
379
 
435
  }
436
  $nscript = $this->attr_copy( $image, $nscript );
437
  $this->set_attribute( $nscript, 'class', 'ewww_webp' );
438
+ $ns_img = $image;
439
+ $this->set_attribute( $ns_img, 'data-eio', 'j', true );
440
+ ewwwio_debug_message( "going to swap\n$image\nwith\n$nscript" . $ns_img . '</noscript>' );
441
+ $buffer = str_replace( $image, $nscript . $ns_img . '</noscript>', $buffer );
442
  } elseif ( ! empty( $file ) && strpos( $image, 'data-lazy-src=' ) ) {
443
  // BJ Lazy Load & WP Rocket.
444
  $new_image = $image;
835
  if ( $webp_domain === $this->home_domain ) {
836
  continue;
837
  }
838
+ ewwwio_debug_message( "looking for domain $webp_domain in $url" );
839
  if (
840
  ! empty( $this->s3_active ) &&
841
  false !== strpos( $url, $this->s3_active ) &&
856
  }
857
  }
858
  foreach ( $this->webp_paths as $webp_path ) {
859
+ if ( false === strpos( $webp_path, 'http' ) ) {
860
  continue;
861
  }
862
+ ewwwio_debug_message( "looking for path $webp_path in $url" );
863
  if (
864
  ! empty( $this->s3_active ) &&
865
  false !== strpos( $url, $this->s3_active ) &&
916
  /**
917
  * Converts a URL to a file-system path and checks if the resulting path exists.
918
  *
919
+ * @param string $url The URL to mangle.
920
+ * @param string $extension An optional extension to append during is_file().
921
  * @return bool True if a local file exists correlating to the URL, false otherwise.
922
  */
923
+ function url_to_path_exists( $url, $extension = '' ) {
924
+ $url = $this->maybe_strip_object_version( $url );
925
+ return parent::url_to_path_exists( $url, '.webp' );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
926
  }
927
 
928
  /**
1102
  return;
1103
  }
1104
  ewwwio_debug_message( 'loading webp script without wp_add_inline_script' );
1105
+ echo '<script data-cfasync="false" type="text/javascript">' . $this->inline_script . '</script>'; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
1106
  }
1107
  }
1108
 
classes/class-eio-base.php CHANGED
@@ -36,10 +36,18 @@ if ( ! class_exists( 'EIO_Base' ) ) {
36
  * Site (URL) for the plugin to use.
37
  *
38
  * @access public
39
- * @var string $content_url
40
  */
41
  public $site_url = '';
42
 
 
 
 
 
 
 
 
 
43
  /**
44
  * Plugin version for the plugin.
45
  *
@@ -70,6 +78,8 @@ if ( ! class_exists( 'EIO_Base' ) ) {
70
  * @param string $child_class_path The location of the child class extending the base class.
71
  */
72
  function __construct( $child_class_path = '' ) {
 
 
73
  if ( strpos( $child_class_path, 'plugins/ewww' ) ) {
74
  $this->content_url = content_url( 'ewww/' );
75
  $this->content_dir = WP_CONTENT_DIR . '/ewww/';
@@ -79,10 +89,17 @@ if ( ! class_exists( 'EIO_Base' ) ) {
79
  $this->content_dir = WP_CONTENT_DIR . '/easyio/';
80
  $this->version = EASYIO_VERSION;
81
  $this->prefix = 'easyio_';
 
 
 
 
 
82
  } else {
83
  $this->content_url = content_url( 'ewww/' );
84
  }
85
  $this->debug_message( '<b>' . __METHOD__ . '()</b>' );
 
 
86
  }
87
 
88
  /**
@@ -94,6 +111,7 @@ if ( ! class_exists( 'EIO_Base' ) ) {
94
  global $eio_debug;
95
  global $ewwwio_temp_debug;
96
  global $easyio_temp_debug;
 
97
  $debug_log = $this->content_dir . 'debug.log';
98
  if ( ! is_dir( $this->content_dir ) && is_writable( WP_CONTENT_DIR ) ) {
99
  wp_mkdir_p( $this->content_dir );
@@ -102,6 +120,7 @@ if ( ! class_exists( 'EIO_Base' ) ) {
102
  if (
103
  ! empty( $eio_debug ) &&
104
  empty( $easyio_temp_debug ) &&
 
105
  $debug_enabled &&
106
  is_dir( $this->content_dir ) &&
107
  is_writable( $this->content_dir )
@@ -144,7 +163,8 @@ if ( ! class_exists( 'EIO_Base' ) ) {
144
  }
145
  global $ewwwio_temp_debug;
146
  global $easyio_temp_debug;
147
- if ( $easyio_temp_debug || $ewwwio_temp_debug || $this->get_option( $this->prefix . 'debug' ) ) {
 
148
  $memory_limit = $this->memory_limit();
149
  if ( strlen( $message ) + 4000000 + memory_get_usage( true ) <= $memory_limit ) {
150
  global $eio_debug;
@@ -170,13 +190,13 @@ if ( ! class_exists( 'EIO_Base' ) ) {
170
  if ( function_exists( 'ini_get' ) ) {
171
  $disabled = @ini_get( 'disable_functions' );
172
  if ( $debug ) {
173
- easyio_debug_message( "disable_functions: $disabled" );
174
  }
175
  }
176
  if ( extension_loaded( 'suhosin' ) && function_exists( 'ini_get' ) ) {
177
  $suhosin_disabled = @ini_get( 'suhosin.executor.func.blacklist' );
178
  if ( $debug ) {
179
- easyio_debug_message( "suhosin_blacklist: $suhosin_disabled" );
180
  }
181
  if ( ! empty( $suhosin_disabled ) ) {
182
  $suhosin_disabled = explode( ',', $suhosin_disabled );
@@ -245,6 +265,7 @@ if ( ! class_exists( 'EIO_Base' ) ) {
245
  if (
246
  ! $single &&
247
  is_multisite() &&
 
248
  is_plugin_active_for_network( constant( strtoupper( $this->prefix ) . 'PLUGIN_FILE_REL' ) ) &&
249
  ! get_site_option( $this->prefix . 'allow_multisite_override' )
250
  ) {
@@ -298,6 +319,43 @@ if ( ! class_exists( 'EIO_Base' ) ) {
298
  }
299
  return false;
300
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
301
 
302
  /**
303
  * Make sure an array/object can be parsed by a foreach().
@@ -366,6 +424,35 @@ if ( ! class_exists( 'EIO_Base' ) ) {
366
  return $success;
367
  }
368
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
369
  /**
370
  * A wrapper for PHP's parse_url, prepending assumed scheme for network path
371
  * URLs. PHP versions 5.4.6 and earlier do not correctly parse without scheme.
36
  * Site (URL) for the plugin to use.
37
  *
38
  * @access public
39
+ * @var string $site_url
40
  */
41
  public $site_url = '';
42
 
43
+ /**
44
+ * Home (URL) for the plugin to use.
45
+ *
46
+ * @access public
47
+ * @var string $home_url
48
+ */
49
+ public $home_url = '';
50
+
51
  /**
52
  * Plugin version for the plugin.
53
  *
78
  * @param string $child_class_path The location of the child class extending the base class.
79
  */
80
  function __construct( $child_class_path = '' ) {
81
+ $this->home_url = trailingslashit( get_site_url() );
82
+ $this->relative_home_url = preg_replace( '/https?:/', '', $this->home_url );
83
  if ( strpos( $child_class_path, 'plugins/ewww' ) ) {
84
  $this->content_url = content_url( 'ewww/' );
85
  $this->content_dir = WP_CONTENT_DIR . '/ewww/';
89
  $this->content_dir = WP_CONTENT_DIR . '/easyio/';
90
  $this->version = EASYIO_VERSION;
91
  $this->prefix = 'easyio_';
92
+ } elseif ( strpos( $child_class_path, 'plugins/swis' ) ) {
93
+ $this->content_url = content_url( 'swis/' );
94
+ $this->content_dir = WP_CONTENT_DIR . '/swis/';
95
+ $this->version = SWIS_PLUGIN_VERSION;
96
+ $this->prefix = 'swis_';
97
  } else {
98
  $this->content_url = content_url( 'ewww/' );
99
  }
100
  $this->debug_message( '<b>' . __METHOD__ . '()</b>' );
101
+ $this->debug_message( "home url: $this->home_url" );
102
+ $this->debug_message( "relative home url: $this->relative_home_url" );
103
  }
104
 
105
  /**
111
  global $eio_debug;
112
  global $ewwwio_temp_debug;
113
  global $easyio_temp_debug;
114
+ global $swis_temp_debug;
115
  $debug_log = $this->content_dir . 'debug.log';
116
  if ( ! is_dir( $this->content_dir ) && is_writable( WP_CONTENT_DIR ) ) {
117
  wp_mkdir_p( $this->content_dir );
120
  if (
121
  ! empty( $eio_debug ) &&
122
  empty( $easyio_temp_debug ) &&
123
+ empty( $swis_temp_debug ) &&
124
  $debug_enabled &&
125
  is_dir( $this->content_dir ) &&
126
  is_writable( $this->content_dir )
163
  }
164
  global $ewwwio_temp_debug;
165
  global $easyio_temp_debug;
166
+ global $swis_temp_debug;
167
+ if ( $swis_temp_debug || $easyio_temp_debug || $ewwwio_temp_debug || $this->get_option( $this->prefix . 'debug' ) ) {
168
  $memory_limit = $this->memory_limit();
169
  if ( strlen( $message ) + 4000000 + memory_get_usage( true ) <= $memory_limit ) {
170
  global $eio_debug;
190
  if ( function_exists( 'ini_get' ) ) {
191
  $disabled = @ini_get( 'disable_functions' );
192
  if ( $debug ) {
193
+ $this->debug_message( "disable_functions: $disabled" );
194
  }
195
  }
196
  if ( extension_loaded( 'suhosin' ) && function_exists( 'ini_get' ) ) {
197
  $suhosin_disabled = @ini_get( 'suhosin.executor.func.blacklist' );
198
  if ( $debug ) {
199
+ $this->debug_message( "suhosin_blacklist: $suhosin_disabled" );
200
  }
201
  if ( ! empty( $suhosin_disabled ) ) {
202
  $suhosin_disabled = explode( ',', $suhosin_disabled );
265
  if (
266
  ! $single &&
267
  is_multisite() &&
268
+ defined( strtoupper( $this->prefix ) . 'PLUGIN_FILE_REL' ) &&
269
  is_plugin_active_for_network( constant( strtoupper( $this->prefix ) . 'PLUGIN_FILE_REL' ) ) &&
270
  ! get_site_option( $this->prefix . 'allow_multisite_override' )
271
  ) {
319
  }
320
  return false;
321
  }
322
+ /**
323
+ * Check if file exists, and that it is local rather than using a protocol like http:// or phar://
324
+ *
325
+ * @param string $file The path of the file to check.
326
+ * @return bool True if the file exists and is local, false otherwise.
327
+ */
328
+ function is_file( $file ) {
329
+ if ( false !== strpos( $file, '://' ) ) {
330
+ return false;
331
+ }
332
+ if ( false !== strpos( $file, 'phar://' ) ) {
333
+ return false;
334
+ }
335
+ $file = realpath( $file );
336
+ $wp_dir = realpath( ABSPATH );
337
+ $upload_dir = wp_get_upload_dir();
338
+ $upload_dir = realpath( $upload_dir['basedir'] );
339
+
340
+ $content_dir = realpath( WP_CONTENT_DIR );
341
+ if ( empty( $content_dir ) ) {
342
+ $content_dir = $wp_dir;
343
+ }
344
+ if ( empty( $upload_dir ) ) {
345
+ $upload_dir = $content_dir;
346
+ }
347
+ $plugin_dir = realpath( constant( strtoupper( $this->prefix ) . 'PLUGIN_PATH' ) );
348
+ if (
349
+ false === strpos( $file, $upload_dir ) &&
350
+ false === strpos( $file, $content_dir ) &&
351
+ false === strpos( $file, $wp_dir ) &&
352
+ false === strpos( $file, $plugin_dir )
353
+ ) {
354
+ return false;
355
+ }
356
+ return is_file( $file );
357
+ }
358
+
359
 
360
  /**
361
  * Make sure an array/object can be parsed by a foreach().
424
  return $success;
425
  }
426
 
427
+ /**
428
+ * Converts a URL to a file-system path and checks if the resulting path exists.
429
+ *
430
+ * @param string $url The URL to mangle.
431
+ * @param string $extension An optional extension to append during is_file().
432
+ * @return bool|string The path if a local file exists correlating to the URL, false otherwise.
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 );
440
+ } else {
441
+ $this->debug_message( 'not a valid local image' );
442
+ return false;
443
+ }
444
+ $path_parts = explode( '?', $path );
445
+ if ( $this->is_file( $path_parts[0] . $extension ) ) {
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
+
456
  /**
457
  * A wrapper for PHP's parse_url, prepending assumed scheme for network path
458
  * URLs. PHP versions 5.4.6 and earlier do not correctly parse without scheme.
classes/class-eio-hs-beacon.php CHANGED
@@ -27,20 +27,6 @@ if ( ! class_exists( 'EIO_HS_Beacon' ) ) {
27
  add_action( 'admin_action_eio_opt_out_of_hs_beacon', array( $this, 'check_for_optout' ) );
28
  }
29
 
30
- /**
31
- * Check for a new opt-in on settings save
32
- *
33
- * @param bool $input The enable_help setting.
34
- * @return bool The unaltered setting.
35
- */
36
- public function check_for_settings_optin( $input ) {
37
- $this->debug_message( '<b>' . __METHOD__ . '()</b>' );
38
- if ( isset( $_POST[ $this->prefix . 'enable_help' ] ) && $_POST[ $this->prefix . 'enable_help' ] ) {
39
- $this->set_option( $this->prefix . 'enable_help_notice', 1 );
40
- }
41
- return $input;
42
- }
43
-
44
  /**
45
  * Check for a new opt-in via the admin notice
46
  */
@@ -48,7 +34,7 @@ if ( ! class_exists( 'EIO_HS_Beacon' ) ) {
48
  $this->debug_message( '<b>' . __METHOD__ . '()</b>' );
49
  $this->set_option( $this->prefix . 'enable_help', 1 );
50
  $this->set_option( $this->prefix . 'enable_help_notice', 1 );
51
- wp_redirect( remove_query_arg( 'action', wp_get_referer() ) );
52
  exit;
53
  }
54
 
@@ -60,7 +46,7 @@ if ( ! class_exists( 'EIO_HS_Beacon' ) ) {
60
  delete_option( $this->prefix . 'enable_help' );
61
  delete_network_option( null, $this->prefix . 'enable_help' );
62
  $this->set_option( $this->prefix . 'enable_help_notice', 1 );
63
- wp_redirect( remove_query_arg( 'action', wp_get_referer() ) );
64
  exit;
65
  }
66
 
@@ -74,10 +60,10 @@ if ( ! class_exists( 'EIO_HS_Beacon' ) ) {
74
  public function admin_notice( $network_class = '' ) {
75
  $this->debug_message( '<b>' . __METHOD__ . '()</b>' );
76
  $hide_notice = $this->get_option( $this->prefix . 'enable_help_notice' );
77
- if ( 'network-multisite' === $network_class && get_site_option( $this->prefix . 'allow_multisite_override' ) ) {
78
  return;
79
  }
80
- if ( 'network-singlesite' === $network_class && ! get_site_option( $this->prefix . 'allow_multisite_override' ) ) {
81
  return;
82
  }
83
 
27
  add_action( 'admin_action_eio_opt_out_of_hs_beacon', array( $this, 'check_for_optout' ) );
28
  }
29
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
30
  /**
31
  * Check for a new opt-in via the admin notice
32
  */
34
  $this->debug_message( '<b>' . __METHOD__ . '()</b>' );
35
  $this->set_option( $this->prefix . 'enable_help', 1 );
36
  $this->set_option( $this->prefix . 'enable_help_notice', 1 );
37
+ wp_safe_redirect( remove_query_arg( 'action', wp_get_referer() ) );
38
  exit;
39
  }
40
 
46
  delete_option( $this->prefix . 'enable_help' );
47
  delete_network_option( null, $this->prefix . 'enable_help' );
48
  $this->set_option( $this->prefix . 'enable_help_notice', 1 );
49
+ wp_safe_redirect( remove_query_arg( 'action', wp_get_referer() ) );
50
  exit;
51
  }
52
 
60
  public function admin_notice( $network_class = '' ) {
61
  $this->debug_message( '<b>' . __METHOD__ . '()</b>' );
62
  $hide_notice = $this->get_option( $this->prefix . 'enable_help_notice' );
63
+ if ( 'network-multisite-over' === $network_class ) {
64
  return;
65
  }
66
+ if ( 'network-singlesite' === $network_class ) {
67
  return;
68
  }
69
 
classes/class-eio-lazy-load.php CHANGED
@@ -121,13 +121,6 @@ if ( ! class_exists( 'EIO_Lazy_Load' ) ) {
121
  $this->validate_user_exclusions();
122
  }
123
 
124
- /**
125
- * Starts an output buffer and registers the callback function to do WebP replacement.
126
- */
127
- function buffer_start() {
128
- ob_start( array( $this, 'filter_page_output' ) );
129
- }
130
-
131
  /**
132
  * Replaces images within a srcset attribute, just a placeholder at the moment.
133
  *
@@ -159,18 +152,19 @@ if ( ! class_exists( 'EIO_Lazy_Load' ) ) {
159
  return $buffer;
160
  }
161
  // Don't lazy load in these cases...
162
- $uri = $_SERVER['REQUEST_URI'];
 
163
  if (
164
  empty( $buffer ) ||
165
- ! empty( $_GET['cornerstone'] ) ||
166
  strpos( $uri, 'cornerstone-endpoint' ) !== false ||
167
- ! empty( $_GET['ct_builder'] ) ||
168
  did_action( 'cornerstone_boot_app' ) || did_action( 'cs_before_preview_frame' ) ||
169
  '/print/' === substr( $uri, -7 ) ||
170
- ! empty( $_GET['elementor-preview'] ) ||
171
- ! empty( $_GET['et_fb'] ) ||
172
- ! empty( $_GET['tatsu'] ) ||
173
- ( ! empty( $_POST['action'] ) && 'tatsu_get_concepts' === $_POST['action'] ) ||
174
  ! apply_filters( 'eio_do_lazyload', true ) ||
175
  is_embed() ||
176
  is_feed() ||
@@ -184,10 +178,10 @@ if ( ! class_exists( 'EIO_Lazy_Load' ) ) {
184
  if ( empty( $buffer ) ) {
185
  $this->debug_message( 'empty buffer' );
186
  }
187
- if ( ! empty( $_GET['cornerstone'] ) || strpos( $uri, 'cornerstone-endpoint' ) !== false ) {
188
  $this->debug_message( 'cornerstone editor' );
189
  }
190
- if ( ! empty( $_GET['ct_builder'] ) ) {
191
  $this->debug_message( 'oxygen builder' );
192
  }
193
  if ( did_action( 'cornerstone_boot_app' ) || did_action( 'cs_before_preview_frame' ) ) {
@@ -196,13 +190,13 @@ if ( ! class_exists( 'EIO_Lazy_Load' ) ) {
196
  if ( '/print/' === substr( $uri, -7 ) ) {
197
  $this->debug_message( 'print page template' );
198
  }
199
- if ( ! empty( $_GET['elementor-preview'] ) ) {
200
  $this->debug_message( 'elementor preview' );
201
  }
202
- if ( ! empty( $_GET['et_fb'] ) ) {
203
  $this->debug_message( 'et_fb' );
204
  }
205
- if ( ! empty( $_GET['tatsu'] ) || ( ! empty( $_POST['action'] ) && 'tatsu_get_concepts' === $_POST['action'] ) ) {
206
  $this->debug_message( 'tatsu' );
207
  }
208
  if ( ! apply_filters( 'eio_do_lazyload', true ) ) {
@@ -255,8 +249,10 @@ if ( ! class_exists( 'EIO_Lazy_Load' ) ) {
255
  $this->debug_message( 'found a valid image tag' );
256
  $this->debug_message( "original image tag: $image" );
257
  $orig_img = $image;
 
258
  $image = $this->parse_img_tag( $image, $file );
259
- $noscript = '<noscript>' . $orig_img . '</noscript>';
 
260
  $buffer = str_replace( $orig_img, $image . $noscript, $buffer );
261
  }
262
  } // End foreach().
@@ -308,8 +304,10 @@ if ( ! class_exists( 'EIO_Lazy_Load' ) ) {
308
  if ( $this->validate_image_tag( $image ) ) {
309
  $this->debug_message( 'found a valid image tag (inside picture)' );
310
  $orig_img = $image;
 
311
  $image = $this->parse_img_tag( $image, $file );
312
- $noscript = '<noscript>' . $orig_img . '</noscript>';
 
313
  $picture = str_replace( $orig_img, $image . $noscript, $picture );
314
  $this->debug_message( 'lazified sources for picture element' );
315
  $buffer = str_replace( $pictures[ $index ], $picture, $buffer );
@@ -372,12 +370,12 @@ if ( ! class_exists( 'EIO_Lazy_Load' ) ) {
372
  }
373
 
374
  if (
375
- ! empty( $_POST['action'] ) &&
376
- ! empty( $_POST['vc_action'] ) &&
377
- ! empty( $_POST['tag'] ) &&
378
- 'vc_get_vc_grid_data' === $_POST['action'] &&
379
- 'vc_get_vc_grid_data' === $_POST['vc_action'] &&
380
- 'vc_media_grid' === $_POST['tag']
381
  ) {
382
  return $image;
383
  }
@@ -720,11 +718,11 @@ if ( ! class_exists( 'EIO_Lazy_Load' ) ) {
720
  if ( ! wp_doing_ajax() ) {
721
  return $allow;
722
  }
723
- if ( ! empty( $_POST['action'] ) && 'vc_get_vc_grid_data' === $_POST['action'] ) {
724
  $this->debug_message( 'allowing lazy on vc grid' );
725
  return true;
726
  }
727
- if ( ! empty( $_POST['action'] ) && 'Essential_Grid_Front_request_ajax' === $_POST['action'] ) {
728
  /* return true; */
729
  }
730
  return $allow;
121
  $this->validate_user_exclusions();
122
  }
123
 
 
 
 
 
 
 
 
124
  /**
125
  * Replaces images within a srcset attribute, just a placeholder at the moment.
126
  *
152
  return $buffer;
153
  }
154
  // Don't lazy load in these cases...
155
+ $uri = add_query_arg( null, null );
156
+ $this->debug_message( "request uri is $uri" );
157
  if (
158
  empty( $buffer ) ||
159
+ strpos( $uri, 'cornerstone=' ) !== false ||
160
  strpos( $uri, 'cornerstone-endpoint' ) !== false ||
161
+ strpos( $uri, 'ct_builder=' ) !== false ||
162
  did_action( 'cornerstone_boot_app' ) || did_action( 'cs_before_preview_frame' ) ||
163
  '/print/' === substr( $uri, -7 ) ||
164
+ strpos( $uri, 'elementor-preview=' ) !== false ||
165
+ strpos( $uri, 'et_fb=' ) !== false ||
166
+ strpos( $uri, 'tatsu=' ) !== false ||
167
+ ( ! empty( $_POST['action'] ) && 'tatsu_get_concepts' === sanitize_text_field( wp_unslash( $_POST['action'] ) ) ) || // phpcs:ignore WordPress.Security.NonceVerification
168
  ! apply_filters( 'eio_do_lazyload', true ) ||
169
  is_embed() ||
170
  is_feed() ||
178
  if ( empty( $buffer ) ) {
179
  $this->debug_message( 'empty buffer' );
180
  }
181
+ if ( strpos( $uri, 'cornerstone=' ) !== false || strpos( $uri, 'cornerstone-endpoint' ) !== false ) {
182
  $this->debug_message( 'cornerstone editor' );
183
  }
184
+ if ( strpos( $uri, 'ct_builder=' ) !== false ) {
185
  $this->debug_message( 'oxygen builder' );
186
  }
187
  if ( did_action( 'cornerstone_boot_app' ) || did_action( 'cs_before_preview_frame' ) ) {
190
  if ( '/print/' === substr( $uri, -7 ) ) {
191
  $this->debug_message( 'print page template' );
192
  }
193
+ if ( strpos( $uri, 'elementor-preview=' ) !== false ) {
194
  $this->debug_message( 'elementor preview' );
195
  }
196
+ if ( strpos( $uri, 'et_fb=' ) !== false ) {
197
  $this->debug_message( 'et_fb' );
198
  }
199
+ if ( strpos( $uri, 'tatsu=' ) !== false || ( ! empty( $_POST['action'] ) && 'tatsu_get_concepts' === $_POST['action'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification
200
  $this->debug_message( 'tatsu' );
201
  }
202
  if ( ! apply_filters( 'eio_do_lazyload', true ) ) {
249
  $this->debug_message( 'found a valid image tag' );
250
  $this->debug_message( "original image tag: $image" );
251
  $orig_img = $image;
252
+ $ns_img = $image;
253
  $image = $this->parse_img_tag( $image, $file );
254
+ $this->set_attribute( $ns_img, 'data-eio', 'l', true );
255
+ $noscript = '<noscript>' . $ns_img . '</noscript>';
256
  $buffer = str_replace( $orig_img, $image . $noscript, $buffer );
257
  }
258
  } // End foreach().
304
  if ( $this->validate_image_tag( $image ) ) {
305
  $this->debug_message( 'found a valid image tag (inside picture)' );
306
  $orig_img = $image;
307
+ $ns_img = $image;
308
  $image = $this->parse_img_tag( $image, $file );
309
+ $this->set_attribute( $ns_img, 'data-eio', 'l', true );
310
+ $noscript = '<noscript>' . $ns_img . '</noscript>';
311
  $picture = str_replace( $orig_img, $image . $noscript, $picture );
312
  $this->debug_message( 'lazified sources for picture element' );
313
  $buffer = str_replace( $pictures[ $index ], $picture, $buffer );
370
  }
371
 
372
  if (
373
+ ! empty( $_POST['action'] ) && // phpcs:ignore WordPress.Security.NonceVerification
374
+ ! empty( $_POST['vc_action'] ) && // phpcs:ignore WordPress.Security.NonceVerification
375
+ ! empty( $_POST['tag'] ) && // phpcs:ignore WordPress.Security.NonceVerification
376
+ 'vc_get_vc_grid_data' === $_POST['action'] && // phpcs:ignore WordPress.Security.NonceVerification
377
+ 'vc_get_vc_grid_data' === $_POST['vc_action'] && // phpcs:ignore WordPress.Security.NonceVerification
378
+ 'vc_media_grid' === $_POST['tag'] // phpcs:ignore WordPress.Security.NonceVerification
379
  ) {
380
  return $image;
381
  }
718
  if ( ! wp_doing_ajax() ) {
719
  return $allow;
720
  }
721
+ if ( ! empty( $_POST['action'] ) && 'vc_get_vc_grid_data' === $_POST['action'] ) { // phpcs:ignore WordPress.Security.NonceVerification
722
  $this->debug_message( 'allowing lazy on vc grid' );
723
  return true;
724
  }
725
+ if ( ! empty( $_POST['action'] ) && 'Essential_Grid_Front_request_ajax' === $_POST['action'] ) { // phpcs:ignore WordPress.Security.NonceVerification
726
  /* return true; */
727
  }
728
  return $allow;
classes/class-eio-page-parser.php CHANGED
@@ -334,11 +334,16 @@ if ( ! class_exists( 'EIO_Page_Parser' ) ) {
334
  if ( $replace ) {
335
  // Don't forget, back references cannot be used in character classes.
336
  $new_element = preg_replace( '#\s' . $name . '\s*=\s*("|\')(?!\1).*?\1#is', " $name=$1$value$1", $element );
337
- if ( strpos( $new_element, "$name=" ) ) {
338
  $element = $new_element;
339
  return;
340
  }
341
- $element = preg_replace( '#\s' . $name . '\s*=\s*[^"\'][^\s>]+#is', ' ', $element );
 
 
 
 
 
342
  }
343
  $closing = ' />';
344
  if ( false === strpos( $element, '/>' ) ) {
334
  if ( $replace ) {
335
  // Don't forget, back references cannot be used in character classes.
336
  $new_element = preg_replace( '#\s' . $name . '\s*=\s*("|\')(?!\1).*?\1#is', " $name=$1$value$1", $element );
337
+ if ( strpos( $new_element, "$name=" ) && $new_element !== $element ) {
338
  $element = $new_element;
339
  return;
340
  }
341
+ $new_element = preg_replace( '#\s' . $name . '\s*=\s*[^"\'][^\s>]+#is', ' ', $element );
342
+ if ( preg_match( '#\s' . $name . '\s*=\s*#', $new_element ) && $new_element === $element ) {
343
+ $this->debug_message( "$name replacement failed, still exists in $element" );
344
+ return;
345
+ }
346
+ $element = $new_element;
347
  }
348
  $closing = ' />';
349
  if ( false === strpos( $element, '/>' ) ) {
classes/class-eio-picture-webp.php CHANGED
@@ -166,17 +166,19 @@ class EIO_Picture_Webp extends EIO_Page_Parser {
166
  function filter_page_output( $buffer ) {
167
  ewwwio_debug_message( '<b>' . __METHOD__ . '()</b>' );
168
  // If any of this is true, don't filter the page.
169
- $uri = $_SERVER['REQUEST_URI'];
 
170
  if (
171
  empty( $buffer ) ||
172
  is_admin() ||
173
- ! empty( $_GET['cornerstone'] ) ||
174
  strpos( $uri, 'cornerstone-endpoint' ) !== false ||
175
  did_action( 'cornerstone_boot_app' ) || did_action( 'cs_before_preview_frame' ) ||
176
  '/print/' === substr( $uri, -7 ) ||
177
- ! empty( $_GET['et_fb'] ) ||
178
- ! empty( $_GET['tatsu'] ) ||
179
- ( ! empty( $_POST['action'] ) && 'tatsu_get_concepts' === $_POST['action'] ) ||
 
180
  is_feed() ||
181
  is_preview() ||
182
  ( defined( 'REST_REQUEST' ) && REST_REQUEST ) ||
@@ -185,48 +187,7 @@ class EIO_Picture_Webp extends EIO_Page_Parser {
185
  $this->is_amp() ||
186
  ewww_image_optimizer_ce_webp_enabled()
187
  ) {
188
- if ( empty( $buffer ) ) {
189
- ewwwio_debug_message( 'empty buffer' );
190
- }
191
- if ( is_admin() ) {
192
- ewwwio_debug_message( 'is_admin' );
193
- }
194
- if ( ! empty( $_GET['cornerstone'] ) || strpos( $uri, 'cornerstone-endpoint' ) !== false ) {
195
- ewwwio_debug_message( 'cornerstone editor' );
196
- }
197
- if ( did_action( 'cornerstone_boot_app' ) || did_action( 'cs_before_preview_frame' ) ) {
198
- ewwwio_debug_message( 'cornerstone app/preview' );
199
- }
200
- if ( '/print/' === substr( $uri, -7 ) ) {
201
- $this->debug_message( 'print page template' );
202
- }
203
- if ( ! empty( $_GET['et_fb'] ) ) {
204
- ewwwio_debug_message( 'et_fb' );
205
- }
206
- if ( ! empty( $_GET['tatsu'] ) || ( ! empty( $_POST['action'] ) && 'tatsu_get_concepts' === $_POST['action'] ) ) {
207
- ewwwio_debug_message( 'tatsu' );
208
- }
209
- if ( is_feed() ) {
210
- ewwwio_debug_message( 'is_feed' );
211
- }
212
- if ( is_preview() ) {
213
- ewwwio_debug_message( 'is_preview' );
214
- }
215
- if ( defined( 'REST_REQUEST' ) && REST_REQUEST ) {
216
- ewwwio_debug_message( 'rest request' );
217
- }
218
- if ( preg_match( '/^<\?xml/', $buffer ) ) {
219
- ewwwio_debug_message( 'not html, xml tag found' );
220
- }
221
- if ( strpos( $buffer, 'amp-boilerplate' ) ) {
222
- ewwwio_debug_message( 'AMP page processing' );
223
- }
224
- if ( $this->is_amp() ) {
225
- ewwwio_debug_message( 'AMP page processing (is_amp)' );
226
- }
227
- if ( ewww_image_optimizer_ce_webp_enabled() ) {
228
- ewwwio_debug_message( 'Cache Enabler WebP enabled' );
229
- }
230
  return $buffer;
231
  }
232
 
@@ -258,7 +219,9 @@ class EIO_Picture_Webp extends EIO_Page_Parser {
258
  if ( empty( $srcset_webp ) || $srcset_webp === $file ) {
259
  continue;
260
  }
261
- $picture_tag = "<picture><source srcset=\"$srcset_webp\" $sizes_attr type='image/webp'>$image</picture>";
 
 
262
  ewwwio_debug_message( "going to swap\n$image\nwith\n$picture_tag" );
263
  $buffer = str_replace( $image, $picture_tag, $buffer );
264
  }
@@ -306,7 +269,7 @@ class EIO_Picture_Webp extends EIO_Page_Parser {
306
  }
307
  }
308
  foreach ( $this->webp_paths as $webp_path ) {
309
- if ( false !== strpos( $webp_path, $this->home_domain ) || false === strpos( $webp_path, 'http' ) ) {
310
  continue;
311
  }
312
  ewwwio_debug_message( "looking for $webp_path in $url" );
@@ -366,26 +329,13 @@ class EIO_Picture_Webp extends EIO_Page_Parser {
366
  /**
367
  * Converts a URL to a file-system path and checks if the resulting path exists.
368
  *
369
- * @param string $image The image URL to mangle.
 
370
  * @return bool True if a local file exists correlating to the URL, false otherwise.
371
  */
372
- function url_to_path_exists( $image ) {
373
- ewwwio_debug_message( '<b>' . __METHOD__ . '()</b>' );
374
- $image = $this->maybe_strip_object_version( $image );
375
- if ( 0 === strpos( $image, $this->relative_home_url ) ) {
376
- $imagepath = str_replace( $this->relative_home_url, ABSPATH, $image );
377
- } elseif ( 0 === strpos( $image, $this->home_url ) ) {
378
- $imagepath = str_replace( $this->home_url, ABSPATH, $image );
379
- } else {
380
- ewwwio_debug_message( 'not a valid local image' );
381
- return false;
382
- }
383
- $path_parts = explode( '?', $imagepath );
384
- if ( ewwwio_is_file( $path_parts[0] . '.webp' ) || ewwwio_is_file( $imagepath . '.webp' ) ) {
385
- ewwwio_debug_message( 'local .webp image found' );
386
- return true;
387
- }
388
- return false;
389
  }
390
 
391
  /**
166
  function filter_page_output( $buffer ) {
167
  ewwwio_debug_message( '<b>' . __METHOD__ . '()</b>' );
168
  // If any of this is true, don't filter the page.
169
+ $uri = add_query_arg( null, null );
170
+ $this->debug_message( "request uri is $uri" );
171
  if (
172
  empty( $buffer ) ||
173
  is_admin() ||
174
+ strpos( $uri, 'cornerstone=' ) !== false ||
175
  strpos( $uri, 'cornerstone-endpoint' ) !== false ||
176
  did_action( 'cornerstone_boot_app' ) || did_action( 'cs_before_preview_frame' ) ||
177
  '/print/' === substr( $uri, -7 ) ||
178
+ strpos( $uri, 'elementor-preview=' ) !== false ||
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 ) ||
187
  $this->is_amp() ||
188
  ewww_image_optimizer_ce_webp_enabled()
189
  ) {
190
+ ewwwio_debug_message( 'picture WebP disabled' );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
191
  return $buffer;
192
  }
193
 
219
  if ( empty( $srcset_webp ) || $srcset_webp === $file ) {
220
  continue;
221
  }
222
+ $pic_img = $image;
223
+ $this->set_attribute( $pic_img, 'data-eio', 'p', true );
224
+ $picture_tag = "<picture><source srcset=\"$srcset_webp\" $sizes_attr type='image/webp'>$pic_img</picture>";
225
  ewwwio_debug_message( "going to swap\n$image\nwith\n$picture_tag" );
226
  $buffer = str_replace( $image, $picture_tag, $buffer );
227
  }
269
  }
270
  }
271
  foreach ( $this->webp_paths as $webp_path ) {
272
+ if ( false === strpos( $webp_path, 'http' ) ) {
273
  continue;
274
  }
275
  ewwwio_debug_message( "looking for $webp_path in $url" );
329
  /**
330
  * Converts a URL to a file-system path and checks if the resulting path exists.
331
  *
332
+ * @param string $url The URL to mangle.
333
+ * @param string $extension An optional extension to append during is_file().
334
  * @return bool True if a local file exists correlating to the URL, false otherwise.
335
  */
336
+ function url_to_path_exists( $url, $extension = '' ) {
337
+ $url = $this->maybe_strip_object_version( $url );
338
+ return parent::url_to_path_exists( $url, '.webp' );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
339
  }
340
 
341
  /**
classes/class-ewww-flag.php CHANGED
@@ -24,7 +24,7 @@ if ( ! class_exists( 'EWWW_Flag' ) ) {
24
  */
25
  function __construct() {
26
  add_filter( 'flag_manage_images_columns', array( $this, 'ewww_manage_images_columns' ) );
27
- add_action( 'flag_manage_gallery_custom_column', array( $this, 'ewww_manage_image_custom_column_wrapper' ), 10, 2 );
28
  add_action( 'admin_enqueue_scripts', array( $this, 'ewww_flag_manual_actions_script' ), 21 );
29
  if ( current_user_can( apply_filters( 'ewww_image_optimizer_bulk_permissions', '' ) ) ) {
30
  add_action( 'flag_manage_images_bulkaction', array( $this, 'ewww_manage_images_bulkaction' ) );
@@ -80,6 +80,15 @@ if ( ! class_exists( 'EWWW_Flag' ) ) {
80
  ewwwio_debug_message( '<b>' . __METHOD__ . '()</b>' );
81
  // If there is POST data, make sure bulkaction and doaction are the values we want.
82
  if ( ! empty( $_POST ) && empty( $_REQUEST['ewww_reset'] ) ) {
 
 
 
 
 
 
 
 
 
83
  // If there is no requested bulk action, do nothing.
84
  if ( empty( $_REQUEST['bulkaction'] ) ) {
85
  return;
@@ -88,7 +97,7 @@ if ( ! class_exists( 'EWWW_Flag' ) ) {
88
  if ( empty( $_REQUEST['doaction'] ) || ! is_array( $_REQUEST['doaction'] ) ) {
89
  return;
90
  }
91
- if ( ! preg_match( '/^bulk_optimize/', $_REQUEST['bulkaction'] ) ) {
92
  return;
93
  }
94
  }
@@ -103,18 +112,18 @@ if ( ! class_exists( 'EWWW_Flag' ) ) {
103
  <?php
104
  if ( ewww_image_optimizer_get_option( 'ewww_image_optimizer_cloud_key' ) ) {
105
  ewww_image_optimizer_cloud_verify();
106
- 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' ) . ' ' . ewww_image_optimizer_cloud_quota() . '</a>';
107
  }
108
  // Retrieve the value of the 'bulk resume' option and set the button text for the form to use.
109
  $resume = get_option( 'ewww_image_optimizer_bulk_flag_resume' );
110
  if ( empty( $resume ) ) {
111
- $button_text = esc_attr__( 'Start optimizing', 'ewww-image-optimizer' );
112
  } else {
113
- $button_text = esc_attr__( 'Resume previous optimization', 'ewww-image-optimizer' );
114
  }
115
  $delay = ewww_image_optimizer_get_option( 'ewww_image_optimizer_delay' ) ? ewww_image_optimizer_get_option( 'ewww_image_optimizer_delay' ) : 0;
116
  /* translators: 1-4: number(s) of images */
117
- $selected_images_text = sprintf( esc_html__( '%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 );
118
  ?>
119
  <div id="ewww-bulk-loading"></div>
120
  <div id="ewww-bulk-progressbar"></div>
@@ -146,14 +155,14 @@ if ( ! class_exists( 'EWWW_Flag' ) ) {
146
  </div>
147
  <form class="ewww-bulk-form">
148
  <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>
149
- <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 $delay; ?>"></p>
150
  <div id="ewww-delay-slider" style="width:50%"></div>
151
  </form>
152
- <div id="ewww-bulk-forms">
153
- <p class="ewww-bulk-info"><?php echo $selected_images_text; ?><br />
154
  <?php esc_html_e( 'Previously optimized images will be skipped by default.', 'ewww-image-optimizer' ); ?></p>
155
  <form id="ewww-bulk-start" class="ewww-bulk-form" method="post" action="">
156
- <input type="submit" class="button-primary action" value="<?php echo $button_text; ?>" />
157
  </form>
158
  <?php
159
  // If there was a previous operation, offer the option to reset the option in the db.
@@ -216,8 +225,15 @@ if ( ! class_exists( 'EWWW_Flag' ) ) {
216
  if ( ! $this->is_bulk_page( $hook ) && ! $this->is_gallery_page( $hook ) ) {
217
  return;
218
  }
 
 
 
 
 
 
 
219
  // If there is no requested bulk action, do nothing.
220
- if ( $this->is_gallery_page( $hook ) && ( empty( $_REQUEST['bulkaction'] ) || 0 === strpos( $_REQUEST['bulkaction'], 'bulk_optimize' ) ) ) {
221
  return;
222
  }
223
  // If there is no media to optimize, do nothing.
@@ -235,7 +251,10 @@ if ( ! class_exists( 'EWWW_Flag' ) ) {
235
  if ( ! empty( $_REQUEST['doaction'] ) ) {
236
  ewwwio_debug_message( 'possible batch image request' );
237
  // See if the bulk operation requested is from the manage images page.
238
- if ( 'manage-images' === $_REQUEST['page'] && 'bulk_optimize_images' === $_REQUEST['bulkaction'] ) {
 
 
 
239
  // Check the referring page and nonce.
240
  check_admin_referer( 'flag_updategallery' );
241
  // We don't allow previous operations to resume if the user is asking to optimize specific images.
@@ -245,7 +264,7 @@ if ( ! class_exists( 'EWWW_Flag' ) ) {
245
  ewwwio_debug_message( 'batch image request from image list' );
246
  }
247
  // See if the bulk operation requested is from the manage galleries page.
248
- if ( 'manage-galleries' === $_REQUEST['page'] && 'bulk_optimize_galleries' === $_REQUEST['bulkaction'] ) {
249
  // Check the referring page and nonce.
250
  check_admin_referer( 'flag_bulkgallery' );
251
  global $flagdb;
@@ -396,7 +415,7 @@ if ( ! class_exists( 'EWWW_Flag' ) ) {
396
  wp_die( esc_html__( 'You do not have permission to optimize images.', 'ewww-image-optimizer' ) );
397
  }
398
  ewwwio_ob_clean();
399
- wp_die( ewwwio_json_encode( array( 'error' => esc_html__( 'You do not have permission to optimize images.', 'ewww-image-optimizer' ) ) ) );
400
  }
401
  // Make sure we have an attachment ID.
402
  if ( empty( $_REQUEST['ewww_attachment_ID'] ) ) {
@@ -404,17 +423,19 @@ if ( ! class_exists( 'EWWW_Flag' ) ) {
404
  wp_die( esc_html__( 'No attachment ID was provided.', 'ewww-image-optimizer' ) );
405
  }
406
  ewwwio_ob_clean();
407
- wp_die( ewwwio_json_encode( array( 'error' => esc_html__( 'No attachment ID was provided.', 'ewww-image-optimizer' ) ) ) );
408
  }
409
  $id = intval( $_REQUEST['ewww_attachment_ID'] );
410
- if ( empty( $_REQUEST['ewww_manual_nonce'] ) || ! wp_verify_nonce( $_REQUEST['ewww_manual_nonce'], "ewww-manual-$id" ) ) {
411
  if ( ! wp_doing_ajax() ) {
412
  wp_die( esc_html__( 'Access denied.', 'ewww-image-optimizer' ) );
413
  }
414
  ewwwio_ob_clean();
415
- wp_die( ewwwio_json_encode( array( 'error' => esc_html__( 'Access denied.', 'ewww-image-optimizer' ) ) ) );
416
  }
417
  global $ewww_image;
 
 
418
  if ( ! class_exists( 'flagMeta' ) ) {
419
  require_once( FLAG_ABSPATH . 'lib/meta.php' );
420
  }
@@ -442,15 +463,13 @@ if ( ! class_exists( 'EWWW_Flag' ) ) {
442
  if ( ! wp_doing_ajax() ) {
443
  // Get the referring page...
444
  $sendback = wp_get_referer();
445
- // and clean it up a bit.
446
- $sendback = preg_replace( '|[^a-z0-9-~+_.?#=&;,/:]|i', '', $sendback );
447
  // Send the user back where they came from.
448
- wp_redirect( $sendback );
449
  die;
450
  }
451
- $success = $this->ewww_manage_image_custom_column( $id );
452
  ewwwio_ob_clean();
453
- wp_die( ewwwio_json_encode( array( 'success' => $success ) ) );
454
  }
455
 
456
  /**
@@ -465,7 +484,7 @@ if ( ! class_exists( 'EWWW_Flag' ) ) {
465
  wp_die( esc_html__( 'You do not have permission to optimize images.', 'ewww-image-optimizer' ) );
466
  }
467
  ewwwio_ob_clean();
468
- wp_die( ewwwio_json_encode( array( 'error' => esc_html__( 'You do not have permission to optimize images.', 'ewww-image-optimizer' ) ) ) );
469
  }
470
  // Make sure function wasn't called without an attachment to work with.
471
  if ( false === isset( $_REQUEST['ewww_attachment_ID'] ) ) {
@@ -473,24 +492,24 @@ if ( ! class_exists( 'EWWW_Flag' ) ) {
473
  wp_die( esc_html__( 'No attachment ID was provided.', 'ewww-image-optimizer' ) );
474
  }
475
  ewwwio_ob_clean();
476
- wp_die( ewwwio_json_encode( array( 'error' => esc_html__( 'No attachment ID was provided.', 'ewww-image-optimizer' ) ) ) );
477
  }
478
  // Store the attachment $id.
479
  $id = intval( $_REQUEST['ewww_attachment_ID'] );
480
- if ( empty( $_REQUEST['ewww_manual_nonce'] ) || ! wp_verify_nonce( $_REQUEST['ewww_manual_nonce'], "ewww-manual-$id" ) ) {
481
  if ( ! wp_doing_ajax() ) {
482
  wp_die( esc_html__( 'Access denied.', 'ewww-image-optimizer' ) );
483
  }
484
  ewwwio_ob_clean();
485
- wp_die( ewwwio_json_encode( array( 'error' => esc_html__( 'Access denied.', 'ewww-image-optimizer' ) ) ) );
486
  }
487
  if ( ! class_exists( 'flagMeta' ) ) {
488
  require_once( FLAG_ABSPATH . 'lib/meta.php' );
489
  }
490
  ewww_image_optimizer_cloud_restore_from_meta_data( $id, 'flag' );
491
- $success = $this->ewww_manage_image_custom_column( $id );
492
  ewwwio_ob_clean();
493
- wp_die( ewwwio_json_encode( array( 'success' => $success ) ) );
494
  }
495
 
496
  /**
@@ -499,7 +518,7 @@ if ( ! class_exists( 'EWWW_Flag' ) ) {
499
  function ewww_flag_bulk_init() {
500
  ewwwio_debug_message( '<b>' . __METHOD__ . '()</b>' );
501
  $permissions = apply_filters( 'ewww_image_optimizer_bulk_permissions', '' );
502
- if ( ! wp_verify_nonce( $_REQUEST['ewww_wpnonce'], 'ewww-image-optimizer-bulk' ) || ! current_user_can( $permissions ) ) {
503
  ewwwio_ob_clean();
504
  wp_die( esc_html__( 'Access denied.', 'ewww-image-optimizer' ) );
505
  }
@@ -514,7 +533,7 @@ if ( ! class_exists( 'EWWW_Flag' ) ) {
514
  if ( ! is_array( $attachments ) ) {
515
  $output['error'] = esc_html__( 'Error retrieving list of images' );
516
  ewwwio_ob_clean();
517
- wp_die( ewwwio_json_encode( $output ) );
518
  }
519
  $id = array_shift( $attachments );
520
  $file_name = $this->ewww_flag_bulk_filename( $id );
@@ -526,7 +545,7 @@ if ( ! class_exists( 'EWWW_Flag' ) ) {
526
  $output['results'] = '<p>' . esc_html__( 'Optimizing', 'ewww-image-optimizer' ) . ' <b>' . $file_name . "</b>&nbsp;<img src='$loading_image' alt='loading'/></p>";
527
  }
528
  ewwwio_ob_clean();
529
- wp_die( ewwwio_json_encode( $output ) );
530
  }
531
 
532
  /**
@@ -559,14 +578,14 @@ if ( ! class_exists( 'EWWW_Flag' ) ) {
559
  $ewww_defer = false;
560
  $output = array();
561
  $permissions = apply_filters( 'ewww_image_optimizer_bulk_permissions', '' );
562
- if ( ! wp_verify_nonce( $_REQUEST['ewww_wpnonce'], 'ewww-image-optimizer-bulk' ) || ! current_user_can( $permissions ) ) {
563
  $output['error'] = esc_html__( 'Access token has expired, please reload the page.', 'ewww-image-optimizer' );
564
  ewwwio_ob_clean();
565
- wp_die( ewwwio_json_encode( $output ) );
566
  }
567
  session_write_close();
568
  // Find out if our nonce is on it's last leg/tick.
569
- $tick = wp_verify_nonce( $_REQUEST['ewww_wpnonce'], 'ewww-image-optimizer-bulk' );
570
  if ( 2 === $tick ) {
571
  $output['new_nonce'] = wp_create_nonce( 'ewww-image-optimizer-bulk' );
572
  } else {
@@ -591,7 +610,7 @@ if ( ! class_exists( 'EWWW_Flag' ) ) {
591
  if ( ! empty( $ewww_status ) && preg_match( '/exceeded/', $ewww_status ) ) {
592
  $output['error'] = esc_html__( 'License Exceeded', 'ewww-image-optimizer' );
593
  ewwwio_ob_clean();
594
- wp_die( ewwwio_json_encode( $output ) );
595
  }
596
  // Let the user know what happened.
597
  $output['results'] = sprintf( '<p>' . esc_html__( 'Optimized image:', 'ewww-image-optimizer' ) . ' <strong>%s</strong><br>', esc_html( $meta->image->filename ) );
@@ -635,7 +654,7 @@ if ( ! class_exists( 'EWWW_Flag' ) ) {
635
  $output['done'] = 1;
636
  }
637
  ewwwio_ob_clean();
638
- wp_die( ewwwio_json_encode( $output ) );
639
  }
640
 
641
  /**
@@ -644,7 +663,7 @@ if ( ! class_exists( 'EWWW_Flag' ) ) {
644
  function ewww_flag_bulk_cleanup() {
645
  ewwwio_debug_message( '<b>' . __METHOD__ . '()</b>' );
646
  $permissions = apply_filters( 'ewww_image_optimizer_bulk_permissions', '' );
647
- if ( ! wp_verify_nonce( $_REQUEST['ewww_wpnonce'], 'ewww-image-optimizer-bulk' ) || ! current_user_can( $permissions ) ) {
648
  ewwwio_ob_clean();
649
  wp_die( esc_html__( 'Access token has expired, please reload the page.', 'ewww-image-optimizer' ) );
650
  }
@@ -698,18 +717,25 @@ if ( ! class_exists( 'EWWW_Flag' ) ) {
698
  /**
699
  * Output the EWWW IO information on the gallery display.
700
  *
701
- * @param int $id The ID number of the image being displayed.
 
702
  */
703
- function ewww_manage_image_custom_column( $id ) {
 
 
 
704
  ewwwio_debug_message( '<b>' . __METHOD__ . '()</b>' );
705
- $output = "<div id='ewww-flag-status-$id'>";
706
  // Get the metadata.
707
  $meta = new flagMeta( $id );
708
  if ( ewww_image_optimizer_get_option( 'ewww_image_optimizer_debug' ) && ewww_image_optimizer_function_exists( 'print_r' ) ) {
709
- $print_meta = print_r( $meta->image->meta_data, true );
710
- $print_meta = preg_replace( array( '/ /', '/\n+/' ), array( '&nbsp;', '<br />' ), esc_html( $print_meta ) );
711
- $debug_button = esc_html__( 'Show Metadata', 'ewww-image-optimizer' );
712
- echo "<button type='button' class='ewww-show-debug-meta button button-secondary' data-id='$id'>$debug_button</button><div id='ewww-debug-meta-$id' style='font-size: 10px;padding: 10px;margin:3px -10px 10px;line-height: 1.1em;display: none;'>$print_meta</div>";
 
 
 
713
  }
714
  // Get the image path from the meta.
715
  $file_path = $meta->image->imagePath;
@@ -742,27 +768,27 @@ if ( ! class_exists( 'EWWW_Flag' ) ) {
742
  case 'image/jpeg':
743
  if ( ! EWWW_IMAGE_OPTIMIZER_JPEGTRAN && ! $skip['jpegtran'] ) {
744
  /* translators: %s: name of a tool like jpegtran */
745
- $msg = '<div>' . sprintf( esc_html__( '%s is missing', 'ewww-image-optimizer' ), '<em>jpegtran</em>' ) . '</div>';
 
746
  }
747
  break;
748
  case 'image/png':
749
  if ( ! EWWW_IMAGE_OPTIMIZER_PNGOUT && ! EWWW_IMAGE_OPTIMIZER_OPTIPNG && ! $skip['optipng'] && ! $skip['pngout'] ) {
750
  /* translators: %s: name of a tool like jpegtran */
751
- $msg = '<div>' . sprintf( esc_html__( '%s is missing', 'ewww-image-optimizer' ), '<em>optipng/pngout</em>' ) . '</div>';
 
752
  }
753
  break;
754
  case 'image/gif':
755
  if ( ! EWWW_IMAGE_OPTIMIZER_GIFSICLE && ! $skip['gifsicle'] ) {
756
  /* translators: %s: name of a tool like jpegtran */
757
- $msg = '<div>' . sprintf( esc_html__( '%s is missing', 'ewww-image-optimizer' ), '<em>gifsicle</em>' ) . '</div>';
 
758
  }
759
  break;
760
  default:
761
- $msg = '<div>' . esc_html__( 'Unsupported file type', 'ewww-image-optimizer' ) . '</div>';
762
- }
763
- // Let user know if the file type is unsupported.
764
- if ( $msg ) {
765
- return $msg;
766
  }
767
  $backup_available = false;
768
  global $wpdb;
@@ -770,51 +796,48 @@ if ( ! class_exists( 'EWWW_Flag' ) ) {
770
  $ewww_manual_nonce = wp_create_nonce( 'ewww-manual-' . $id );
771
  if ( ! empty( $optimized_images ) ) {
772
  list( $detail_output, $converted, $backup_available ) = ewww_image_optimizer_custom_column_results( $id, $optimized_images );
773
- $output .= $detail_output;
774
  if ( current_user_can( apply_filters( 'ewww_image_optimizer_manual_permissions', '' ) ) ) {
775
- $output .= sprintf(
776
- '<a class="ewww-manual-optimize" data-id="%1$d" data-nonce="%2$s" href="' . admin_url( 'admin.php?action=ewww_flag_manual' ) . '&amp;ewww_manual_nonce=%2$s&amp;ewww_force=1&amp;ewww_attachment_ID=%1$d">%3$s</a>',
777
- $id,
778
- $ewww_manual_nonce,
779
  esc_html__( 'Re-optimize', 'ewww-image-optimizer' )
780
  );
781
  if ( $backup_available ) {
782
- $output .= sprintf(
783
- '<br><a class="ewww-manual-cloud-restore" data-id="%1$d" data-nonce="%2$s" href="' . admin_url( 'admin.php?action=ewww_flag_cloud_restore' ) . '&amp;ewww_manual_nonce=%2$s&amp;ewww_attachment_ID=%1$d">%3$s</a>',
784
- $id,
785
- $ewww_manual_nonce,
786
  esc_html__( 'Restore original', 'ewww-image-optimizer' )
787
  );
788
  }
789
  }
790
  } elseif ( ewww_image_optimizer_image_is_pending( $id, 'flag-async' ) ) {
791
- $output .= esc_html__( 'In Progress', 'ewww-image-optimizer' );
792
  // Otherwise, tell the user that they can optimize the image now.
793
  } else {
794
  if ( current_user_can( apply_filters( 'ewww_image_optimizer_manual_permissions', '' ) ) ) {
795
- $output .= sprintf(
796
- '<a class="ewww-manual-optimize" data-id="%1$d" data-nonce="%2$s" href="' . admin_url( 'admin.php?action=ewww_flag_manual' ) . '&amp;ewww_manual_nonce=%2$s&amp;ewww_attachment_ID=%1$d">%3$s</a>',
797
- $id,
798
- $ewww_manual_nonce,
799
  esc_html__( 'Optimize now!', 'ewww-image-optimizer' )
800
  );
801
  }
802
  }
803
- $output .= '</div>';
804
- return $output;
805
  }
806
 
807
  /**
808
- * Wrapper around the custom column display when being called normally (no AJAX).
809
  *
810
- * @param string $column_name The name of the current column.
811
- * @param int $id The ID number of the image to display.
812
  */
813
- function ewww_manage_image_custom_column_wrapper( $column_name, $id ) {
814
- // Check to make sure we're outputing our custom column.
815
- if ( 'ewww_image_optimizer' === $column_name ) {
816
- echo $this->ewww_manage_image_custom_column( $id );
817
- }
818
  }
819
  }
820
 
24
  */
25
  function __construct() {
26
  add_filter( 'flag_manage_images_columns', array( $this, 'ewww_manage_images_columns' ) );
27
+ add_action( 'flag_manage_gallery_custom_column', array( $this, 'ewww_manage_image_custom_column' ), 10, 2 );
28
  add_action( 'admin_enqueue_scripts', array( $this, 'ewww_flag_manual_actions_script' ), 21 );
29
  if ( current_user_can( apply_filters( 'ewww_image_optimizer_bulk_permissions', '' ) ) ) {
30
  add_action( 'flag_manage_images_bulkaction', array( $this, 'ewww_manage_images_bulkaction' ) );
80
  ewwwio_debug_message( '<b>' . __METHOD__ . '()</b>' );
81
  // If there is POST data, make sure bulkaction and doaction are the values we want.
82
  if ( ! empty( $_POST ) && empty( $_REQUEST['ewww_reset'] ) ) {
83
+ if (
84
+ empty( $_REQUEST['_wpnonce'] ) ||
85
+ (
86
+ ! wp_verify_nonce( sanitize_key( $_REQUEST['_wpnonce'] ), 'flag_bulkgallery' ) &&
87
+ ! wp_verify_nonce( sanitize_key( $_REQUEST['_wpnonce'] ), 'flag_updategallery' )
88
+ )
89
+ ) {
90
+ wp_die( esc_html__( 'Access denied.', 'ewww-image-optimizer' ) );
91
+ }
92
  // If there is no requested bulk action, do nothing.
93
  if ( empty( $_REQUEST['bulkaction'] ) ) {
94
  return;
97
  if ( empty( $_REQUEST['doaction'] ) || ! is_array( $_REQUEST['doaction'] ) ) {
98
  return;
99
  }
100
+ if ( ! preg_match( '/^bulk_optimize/', sanitize_key( $_REQUEST['bulkaction'] ) ) ) {
101
  return;
102
  }
103
  }
112
  <?php
113
  if ( ewww_image_optimizer_get_option( 'ewww_image_optimizer_cloud_key' ) ) {
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 ) ) {
120
+ $button_text = __( 'Start optimizing', 'ewww-image-optimizer' );
121
  } else {
122
+ $button_text = __( 'Resume previous optimization', 'ewww-image-optimizer' );
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>
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>
167
  <?php
168
  // If there was a previous operation, offer the option to reset the option in the db.
225
  if ( ! $this->is_bulk_page( $hook ) && ! $this->is_gallery_page( $hook ) ) {
226
  return;
227
  }
228
+ $nonce_verified = false;
229
+ if ( ! empty( $_REQUEST['_wpnonce'] ) && wp_verify_nonce( sanitize_key( $_REQUEST['_wpnonce'] ), 'flag_bulkgallery' ) ) {
230
+ $nonce_verified = true;
231
+ }
232
+ if ( ! empty( $_REQUEST['_wpnonce'] ) && wp_verify_nonce( sanitize_key( $_REQUEST['_wpnonce'] ), 'flag_updategallery' ) ) {
233
+ $nonce_verified = true;
234
+ }
235
  // If there is no requested bulk action, do nothing.
236
+ if ( $this->is_gallery_page( $hook ) && ( empty( $_REQUEST['bulkaction'] ) || false === strpos( sanitize_key( $_REQUEST['bulkaction'] ), 'bulk_optimize' ) ) ) {
237
  return;
238
  }
239
  // If there is no media to optimize, do nothing.
251
  if ( ! empty( $_REQUEST['doaction'] ) ) {
252
  ewwwio_debug_message( 'possible batch image request' );
253
  // See if the bulk operation requested is from the manage images page.
254
+ if ( ! empty( $_REQUEST['page'] ) ) {
255
+ ewwwio_debug_message( sanitize_key( $_REQUEST['page'] ) );
256
+ }
257
+ if ( ! empty( $_REQUEST['page'] ) && 'flag-manage-gallery' === $_REQUEST['page'] && ! empty( $_REQUEST['bulkaction'] ) && 'bulk_optimize_images' === $_REQUEST['bulkaction'] ) {
258
  // Check the referring page and nonce.
259
  check_admin_referer( 'flag_updategallery' );
260
  // We don't allow previous operations to resume if the user is asking to optimize specific images.
264
  ewwwio_debug_message( 'batch image request from image list' );
265
  }
266
  // See if the bulk operation requested is from the manage galleries page.
267
+ if ( ! empty( $_REQUEST['page'] ) && 'flag-manage-gallery' === $_REQUEST['page'] && ! empty( $_REQUEST['bulkaction'] ) && 'bulk_optimize_galleries' === $_REQUEST['bulkaction'] ) {
268
  // Check the referring page and nonce.
269
  check_admin_referer( 'flag_bulkgallery' );
270
  global $flagdb;
415
  wp_die( esc_html__( 'You do not have permission to optimize images.', 'ewww-image-optimizer' ) );
416
  }
417
  ewwwio_ob_clean();
418
+ wp_die( wp_json_encode( array( 'error' => esc_html__( 'You do not have permission to optimize images.', 'ewww-image-optimizer' ) ) ) );
419
  }
420
  // Make sure we have an attachment ID.
421
  if ( empty( $_REQUEST['ewww_attachment_ID'] ) ) {
423
  wp_die( esc_html__( 'No attachment ID was provided.', 'ewww-image-optimizer' ) );
424
  }
425
  ewwwio_ob_clean();
426
+ wp_die( wp_json_encode( array( 'error' => esc_html__( 'No attachment ID was provided.', 'ewww-image-optimizer' ) ) ) );
427
  }
428
  $id = intval( $_REQUEST['ewww_attachment_ID'] );
429
+ if ( empty( $_REQUEST['ewww_manual_nonce'] ) || ! wp_verify_nonce( sanitize_key( $_REQUEST['ewww_manual_nonce'] ), "ewww-manual-$id" ) ) {
430
  if ( ! wp_doing_ajax() ) {
431
  wp_die( esc_html__( 'Access denied.', 'ewww-image-optimizer' ) );
432
  }
433
  ewwwio_ob_clean();
434
+ wp_die( wp_json_encode( array( 'error' => esc_html__( 'Access denied.', 'ewww-image-optimizer' ) ) ) );
435
  }
436
  global $ewww_image;
437
+ global $ewww_force;
438
+ $ewww_force = ! empty( $_REQUEST['ewww_force'] ) ? true : false;
439
  if ( ! class_exists( 'flagMeta' ) ) {
440
  require_once( FLAG_ABSPATH . 'lib/meta.php' );
441
  }
463
  if ( ! wp_doing_ajax() ) {
464
  // Get the referring page...
465
  $sendback = wp_get_referer();
 
 
466
  // Send the user back where they came from.
467
+ wp_safe_redirect( $sendback );
468
  die;
469
  }
470
+ $success = $this->ewww_manage_image_custom_column_capture( $id );
471
  ewwwio_ob_clean();
472
+ wp_die( wp_json_encode( array( 'success' => $success ) ) );
473
  }
474
 
475
  /**
484
  wp_die( esc_html__( 'You do not have permission to optimize images.', 'ewww-image-optimizer' ) );
485
  }
486
  ewwwio_ob_clean();
487
+ wp_die( wp_json_encode( array( 'error' => esc_html__( 'You do not have permission to optimize images.', 'ewww-image-optimizer' ) ) ) );
488
  }
489
  // Make sure function wasn't called without an attachment to work with.
490
  if ( false === isset( $_REQUEST['ewww_attachment_ID'] ) ) {
492
  wp_die( esc_html__( 'No attachment ID was provided.', 'ewww-image-optimizer' ) );
493
  }
494
  ewwwio_ob_clean();
495
+ wp_die( wp_json_encode( array( 'error' => esc_html__( 'No attachment ID was provided.', 'ewww-image-optimizer' ) ) ) );
496
  }
497
  // Store the attachment $id.
498
  $id = intval( $_REQUEST['ewww_attachment_ID'] );
499
+ if ( empty( $_REQUEST['ewww_manual_nonce'] ) || ! wp_verify_nonce( sanitize_key( $_REQUEST['ewww_manual_nonce'] ), "ewww-manual-$id" ) ) {
500
  if ( ! wp_doing_ajax() ) {
501
  wp_die( esc_html__( 'Access denied.', 'ewww-image-optimizer' ) );
502
  }
503
  ewwwio_ob_clean();
504
+ wp_die( wp_json_encode( array( 'error' => esc_html__( 'Access denied.', 'ewww-image-optimizer' ) ) ) );
505
  }
506
  if ( ! class_exists( 'flagMeta' ) ) {
507
  require_once( FLAG_ABSPATH . 'lib/meta.php' );
508
  }
509
  ewww_image_optimizer_cloud_restore_from_meta_data( $id, 'flag' );
510
+ $success = $this->ewww_manage_image_custom_column_capture( $id );
511
  ewwwio_ob_clean();
512
+ wp_die( wp_json_encode( array( 'success' => $success ) ) );
513
  }
514
 
515
  /**
518
  function ewww_flag_bulk_init() {
519
  ewwwio_debug_message( '<b>' . __METHOD__ . '()</b>' );
520
  $permissions = apply_filters( 'ewww_image_optimizer_bulk_permissions', '' );
521
+ if ( empty( $_REQUEST['ewww_wpnonce'] ) || ! wp_verify_nonce( sanitize_key( $_REQUEST['ewww_wpnonce'] ), 'ewww-image-optimizer-bulk' ) || ! current_user_can( $permissions ) ) {
522
  ewwwio_ob_clean();
523
  wp_die( esc_html__( 'Access denied.', 'ewww-image-optimizer' ) );
524
  }
533
  if ( ! is_array( $attachments ) ) {
534
  $output['error'] = esc_html__( 'Error retrieving list of images' );
535
  ewwwio_ob_clean();
536
+ wp_die( wp_json_encode( $output ) );
537
  }
538
  $id = array_shift( $attachments );
539
  $file_name = $this->ewww_flag_bulk_filename( $id );
545
  $output['results'] = '<p>' . esc_html__( 'Optimizing', 'ewww-image-optimizer' ) . ' <b>' . $file_name . "</b>&nbsp;<img src='$loading_image' alt='loading'/></p>";
546
  }
547
  ewwwio_ob_clean();
548
+ wp_die( wp_json_encode( $output ) );
549
  }
550
 
551
  /**
578
  $ewww_defer = false;
579
  $output = array();
580
  $permissions = apply_filters( 'ewww_image_optimizer_bulk_permissions', '' );
581
+ if ( empty( $_REQUEST['ewww_wpnonce'] ) || ! wp_verify_nonce( sanitize_key( $_REQUEST['ewww_wpnonce'] ), 'ewww-image-optimizer-bulk' ) || ! current_user_can( $permissions ) ) {
582
  $output['error'] = esc_html__( 'Access token has expired, please reload the page.', 'ewww-image-optimizer' );
583
  ewwwio_ob_clean();
584
+ wp_die( wp_json_encode( $output ) );
585
  }
586
  session_write_close();
587
  // Find out if our nonce is on it's last leg/tick.
588
+ $tick = wp_verify_nonce( sanitize_key( $_REQUEST['ewww_wpnonce'] ), 'ewww-image-optimizer-bulk' );
589
  if ( 2 === $tick ) {
590
  $output['new_nonce'] = wp_create_nonce( 'ewww-image-optimizer-bulk' );
591
  } else {
610
  if ( ! empty( $ewww_status ) && preg_match( '/exceeded/', $ewww_status ) ) {
611
  $output['error'] = esc_html__( 'License Exceeded', 'ewww-image-optimizer' );
612
  ewwwio_ob_clean();
613
+ wp_die( wp_json_encode( $output ) );
614
  }
615
  // Let the user know what happened.
616
  $output['results'] = sprintf( '<p>' . esc_html__( 'Optimized image:', 'ewww-image-optimizer' ) . ' <strong>%s</strong><br>', esc_html( $meta->image->filename ) );
654
  $output['done'] = 1;
655
  }
656
  ewwwio_ob_clean();
657
+ wp_die( wp_json_encode( $output ) );
658
  }
659
 
660
  /**
663
  function ewww_flag_bulk_cleanup() {
664
  ewwwio_debug_message( '<b>' . __METHOD__ . '()</b>' );
665
  $permissions = apply_filters( 'ewww_image_optimizer_bulk_permissions', '' );
666
+ if ( empty( $_REQUEST['ewww_wpnonce'] ) || ! wp_verify_nonce( sanitize_key( $_REQUEST['ewww_wpnonce'] ), 'ewww-image-optimizer-bulk' ) || ! current_user_can( $permissions ) ) {
667
  ewwwio_ob_clean();
668
  wp_die( esc_html__( 'Access token has expired, please reload the page.', 'ewww-image-optimizer' ) );
669
  }
717
  /**
718
  * Output the EWWW IO information on the gallery display.
719
  *
720
+ * @param string $column_name The name of the current column.
721
+ * @param int $id The ID number of the image being displayed.
722
  */
723
+ function ewww_manage_image_custom_column( $column_name, $id ) {
724
+ if ( 'ewww_image_optimizer' !== $column_name ) {
725
+ return;
726
+ }
727
  ewwwio_debug_message( '<b>' . __METHOD__ . '()</b>' );
728
+ echo '<div id="ewww-flag-status-' . (int) $id . '">';
729
  // Get the metadata.
730
  $meta = new flagMeta( $id );
731
  if ( ewww_image_optimizer_get_option( 'ewww_image_optimizer_debug' ) && ewww_image_optimizer_function_exists( 'print_r' ) ) {
732
+ $print_meta = print_r( $meta->image->meta_data, true );
733
+ echo '<button type="button" class="ewww-show-debug-meta button button-secondary" data-id="' . (int) $id . '">' .
734
+ esc_html__( 'Show Metadata', 'ewww-image-optimizer' ) .
735
+ '</button><div id="ewww-debug-meta-' . (int) $id .
736
+ '" style="font-size: 10px;padding: 10px;margin:3px -10px 10px;line-height: 1.1em;display: none;">' .
737
+ wp_kses_post( preg_replace( array( '/ /', '/\n+/' ), array( '&nbsp;', '<br />' ), $print_meta ) ) .
738
+ '</div>';
739
  }
740
  // Get the image path from the meta.
741
  $file_path = $meta->image->imagePath;
768
  case 'image/jpeg':
769
  if ( ! EWWW_IMAGE_OPTIMIZER_JPEGTRAN && ! $skip['jpegtran'] ) {
770
  /* translators: %s: name of a tool like jpegtran */
771
+ echo '<div>' . sprintf( esc_html__( '%s is missing', 'ewww-image-optimizer' ), '<em>jpegtran</em>' ) . '</div></div>';
772
+ return;
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;
780
  }
781
  break;
782
  case 'image/gif':
783
  if ( ! EWWW_IMAGE_OPTIMIZER_GIFSICLE && ! $skip['gifsicle'] ) {
784
  /* translators: %s: name of a tool like jpegtran */
785
+ echo '<div>' . sprintf( esc_html__( '%s is missing', 'ewww-image-optimizer' ), '<em>gifsicle</em>' ) . '</div></div>';
786
+ return;
787
  }
788
  break;
789
  default:
790
+ echo '<div>' . esc_html__( 'Unsupported file type', 'ewww-image-optimizer' ) . '</div></div>';
791
+ return;
 
 
 
792
  }
793
  $backup_available = false;
794
  global $wpdb;
796
  $ewww_manual_nonce = wp_create_nonce( 'ewww-manual-' . $id );
797
  if ( ! empty( $optimized_images ) ) {
798
  list( $detail_output, $converted, $backup_available ) = ewww_image_optimizer_custom_column_results( $id, $optimized_images );
799
+ echo wp_kses_post( $detail_output );
800
  if ( current_user_can( apply_filters( 'ewww_image_optimizer_manual_permissions', '' ) ) ) {
801
+ printf(
802
+ '<a class="ewww-manual-optimize" data-id="%1$d" data-nonce="%2$s" href="' . esc_url( admin_url( 'admin.php?action=ewww_flag_manual' ) ) . '&amp;ewww_manual_nonce=%2$s&amp;ewww_force=1&amp;ewww_attachment_ID=%1$d">%3$s</a>',
803
+ (int) $id,
804
+ esc_attr( $ewww_manual_nonce ),
805
  esc_html__( 'Re-optimize', 'ewww-image-optimizer' )
806
  );
807
  if ( $backup_available ) {
808
+ printf(
809
+ '<br><a class="ewww-manual-cloud-restore" data-id="%1$d" data-nonce="%2$s" href="' . esc_url( admin_url( 'admin.php?action=ewww_flag_cloud_restore' ) ) . '&amp;ewww_manual_nonce=%2$s&amp;ewww_attachment_ID=%1$d">%3$s</a>',
810
+ (int) $id,
811
+ esc_attr( $ewww_manual_nonce ),
812
  esc_html__( 'Restore original', 'ewww-image-optimizer' )
813
  );
814
  }
815
  }
816
  } elseif ( ewww_image_optimizer_image_is_pending( $id, 'flag-async' ) ) {
817
+ echo '<div>' . esc_html__( 'In Progress', 'ewww-image-optimizer' ) . '</div>';
818
  // Otherwise, tell the user that they can optimize the image now.
819
  } else {
820
  if ( current_user_can( apply_filters( 'ewww_image_optimizer_manual_permissions', '' ) ) ) {
821
+ printf(
822
+ '<div><a class="ewww-manual-optimize" data-id="%1$d" data-nonce="%2$s" href="' . esc_url( admin_url( 'admin.php?action=ewww_flag_manual' ) ) . '&amp;ewww_manual_nonce=%2$s&amp;ewww_attachment_ID=%1$d">%3$s</a></div>',
823
+ (int) $id,
824
+ esc_attr( $ewww_manual_nonce ),
825
  esc_html__( 'Optimize now!', 'ewww-image-optimizer' )
826
  );
827
  }
828
  }
829
+ echo '</div>';
 
830
  }
831
 
832
  /**
833
+ * Wrapper around the custom column display to capture and return the output, usually for AJAX.
834
  *
835
+ * @param int $id The ID number of the image to display.
 
836
  */
837
+ function ewww_manage_image_custom_column_capture( $id ) {
838
+ ob_start();
839
+ $this->ewww_manage_image_custom_column( 'ewww_image_optimizer', $id );
840
+ return ob_get_clean();
 
841
  }
842
  }
843
 
classes/class-ewww-image.php CHANGED
@@ -114,6 +114,7 @@ class EWWW_Image {
114
  if ( ! is_string( $gallery ) ) {
115
  $gallery = '';
116
  }
 
117
  global $wpdb;
118
  if ( strpos( $wpdb->charset, 'utf8' ) === false ) {
119
  ewww_image_optimizer_db_init();
@@ -462,7 +463,7 @@ class EWWW_Image {
462
  */
463
  private function convert_retina( $file ) {
464
  ewwwio_debug_message( '<b>' . __METHOD__ . '()</b>' );
465
- $retina_path = ewww_image_optimizer_hidpi_optimize( $file, true );
466
  if ( ! $retina_path ) {
467
  return;
468
  }
114
  if ( ! is_string( $gallery ) ) {
115
  $gallery = '';
116
  }
117
+ $id = (int) $id;
118
  global $wpdb;
119
  if ( strpos( $wpdb->charset, 'utf8' ) === false ) {
120
  ewww_image_optimizer_db_init();
463
  */
464
  private function convert_retina( $file ) {
465
  ewwwio_debug_message( '<b>' . __METHOD__ . '()</b>' );
466
+ $retina_path = ewww_image_optimizer_get_hidpi_path( $file );
467
  if ( ! $retina_path ) {
468
  return;
469
  }
classes/class-ewww-nextcellent.php CHANGED
@@ -33,7 +33,6 @@ if ( ! class_exists( 'EWWW_Nextcellent' ) ) {
33
  add_action( 'wp_ajax_ewww_ngg_cloud_restore', array( $this, 'ewww_ngg_cloud_restore' ) );
34
  add_action( 'admin_action_ewww_ngg_manual', array( $this, 'ewww_ngg_manual' ) );
35
  add_action( 'admin_menu', array( $this, 'ewww_ngg_bulk_menu' ) );
36
- add_action( 'admin_head-galleries_page_nggallery-manage-gallery', array( $this, 'ewww_ngg_bulk_actions_script' ) );
37
  add_action( 'admin_enqueue_scripts', array( $this, 'ewww_ngg_bulk_script' ), 9 );
38
  add_action( 'wp_ajax_bulk_ngg_preview', array( $this, 'ewww_ngg_bulk_preview' ) );
39
  add_action( 'wp_ajax_bulk_ngg_init', array( $this, 'ewww_ngg_bulk_init' ) );
@@ -133,11 +132,17 @@ if ( ! class_exists( 'EWWW_Nextcellent' ) ) {
133
  ewwwio_debug_message( '<b>' . __METHOD__ . '()</b>' );
134
  global $ewww_defer;
135
  global $ewww_image;
 
 
 
 
 
 
136
  if ( file_exists( $filename ) ) {
137
  if ( ! empty( $_POST['id'] ) ) {
138
  $id = (int) $_POST['id'];
139
- } elseif ( ! empty( $_POST['image'] ) && is_numeric( $_POST['image'] ) ) {
140
- $id = (int) $_POST['image'];
141
  }
142
  $ewww_image = new EWWW_Image( $id, 'nextcell', $filename );
143
  $ewww_image->resize = 'thumbnail';
@@ -157,7 +162,7 @@ if ( ! class_exists( 'EWWW_Nextcellent' ) ) {
157
  wp_die( esc_html__( 'You do not have permission to optimize images.', 'ewww-image-optimizer' ) );
158
  }
159
  ewwwio_ob_clean();
160
- wp_die( ewwwio_json_encode( array( 'error' => esc_html__( 'You do not have permission to optimize images.', 'ewww-image-optimizer' ) ) ) );
161
  }
162
  // Make sure function wasn't called without an attachment to work with.
163
  if ( empty( $_REQUEST['ewww_attachment_ID'] ) ) {
@@ -165,28 +170,28 @@ if ( ! class_exists( 'EWWW_Nextcellent' ) ) {
165
  wp_die( esc_html__( 'No attachment ID was provided.', 'ewww-image-optimizer' ) );
166
  }
167
  ewwwio_ob_clean();
168
- wp_die( ewwwio_json_encode( array( 'error' => esc_html__( 'No attachment ID was provided.', 'ewww-image-optimizer' ) ) ) );
169
  }
170
  // Store the attachment $id.
171
  $id = intval( $_REQUEST['ewww_attachment_ID'] );
172
- if ( empty( $_REQUEST['ewww_manual_nonce'] ) || ! wp_verify_nonce( $_REQUEST['ewww_manual_nonce'], "ewww-manual-$id" ) ) {
173
  if ( ! wp_doing_ajax() ) {
174
  wp_die( esc_html__( 'Access denied.', 'ewww-image-optimizer' ) );
175
  }
176
  ewwwio_ob_clean();
177
- wp_die( ewwwio_json_encode( array( 'error' => esc_html__( 'Access denied.', 'ewww-image-optimizer' ) ) ) );
178
  }
 
 
179
  $this->ewww_ngg_optimize( $id );
180
  $success = $this->ewww_manage_image_custom_column( 'ewww_image_optimizer', $id, true );
181
  if ( ! wp_doing_ajax() ) {
182
  // Get the referring page, and send the user back there.
183
- $sendback = wp_get_referer();
184
- $sendback = preg_replace( '|[^a-z0-9-~+_.?#=&;,/:]|i', '', $sendback );
185
- wp_redirect( $sendback );
186
  die;
187
  }
188
  ewwwio_ob_clean();
189
- wp_die( ewwwio_json_encode( array( 'success' => $success ) ) );
190
  }
191
 
192
  /**
@@ -200,29 +205,29 @@ if ( ! class_exists( 'EWWW_Nextcellent' ) ) {
200
  wp_die( esc_html__( 'You do not have permission to optimize images.', 'ewww-image-optimizer' ) );
201
  }
202
  ewwwio_ob_clean();
203
- wp_die( ewwwio_json_encode( array( 'error' => esc_html__( 'You do not have permission to optimize images.', 'ewww-image-optimizer' ) ) ) );
204
  }
205
  // Make sure function wasn't called without an attachment to work with.
206
- if ( false === isset( $_REQUEST['ewww_attachment_ID'] ) ) {
207
  if ( ! wp_doing_ajax() ) {
208
  wp_die( esc_html__( 'No attachment ID was provided.', 'ewww-image-optimizer' ) );
209
  }
210
  ewwwio_ob_clean();
211
- wp_die( ewwwio_json_encode( array( 'error' => esc_html__( 'No attachment ID was provided.', 'ewww-image-optimizer' ) ) ) );
212
  }
213
  // Sanitize the attachment $id.
214
- $id = intval( $_REQUEST['ewww_attachment_ID'] );
215
- if ( empty( $_REQUEST['ewww_manual_nonce'] ) || ! wp_verify_nonce( $_REQUEST['ewww_manual_nonce'], "ewww-manual-$id" ) ) {
216
  if ( ! wp_doing_ajax() ) {
217
  wp_die( esc_html__( 'Access denied.', 'ewww-image-optimizer' ) );
218
  }
219
  ewwwio_ob_clean();
220
- wp_die( ewwwio_json_encode( array( 'error' => esc_html__( 'Access denied.', 'ewww-image-optimizer' ) ) ) );
221
  }
222
  ewww_image_optimizer_cloud_restore_from_meta_data( $id, 'nextcell' );
223
  $success = $this->ewww_manage_image_custom_column( 'ewww_image_optimizer', $id, true );
224
  ewwwio_ob_clean();
225
- wp_die( ewwwio_json_encode( array( 'success' => $success ) ) );
226
  }
227
 
228
  /**
@@ -285,12 +290,14 @@ if ( ! class_exists( 'EWWW_Nextcellent' ) ) {
285
  function ewww_manage_image_custom_column( $column_name, $id, $return = false ) {
286
  // Once we've found our custom column.
287
  if ( 'ewww_image_optimizer' === $column_name ) {
 
 
 
288
  // Need this file to work with metadata.
289
  require_once( WP_CONTENT_DIR . '/plugins/nextcellent-gallery-nextgen-legacy/lib/meta.php' );
290
  // Get the metadata for the image.
291
- $meta = new nggMeta( $id );
292
- $output = "<div id='ewww-nextcellent-status-$id'>";
293
- $msg = '';
294
  // Get the file path of the image.
295
  $file_path = $meta->image->imagePath;
296
  // Get the mimetype of the image.
@@ -307,33 +314,41 @@ if ( ! class_exists( 'EWWW_Nextcellent' ) ) {
307
  // If jpegtran is missing, tell the user.
308
  if ( ! EWWW_IMAGE_OPTIMIZER_JPEGTRAN && ! $skip['jpegtran'] ) {
309
  /* translators: %s: name of a tool like jpegtran */
310
- $msg = '<div>' . sprintf( esc_html__( '%s is missing', 'ewww-image-optimizer' ), '<em>jpegtran</em>' ) . '</div>';
 
 
 
 
311
  }
312
  break;
313
  case 'image/png':
314
  // If the PNG tools are missing, tell the user.
315
- if ( ! EWWW_IMAGE_OPTIMIZER_PNGOUT && ! EWWW_IMAGE_OPTIMIZER_OPTIPNG && ! $skip['optipng'] && ! $skip['pngout'] ) {
316
  /* translators: %s: name of a tool like jpegtran */
317
- $msg = '<div>' . sprintf( esc_html__( '%s is missing', 'ewww-image-optimizer' ), '<em>optipng/pngout</em>' ) . '</div>';
 
 
 
 
318
  }
319
  break;
320
  case 'image/gif':
321
  // If gifsicle is missing, tell the user.
322
  if ( ! EWWW_IMAGE_OPTIMIZER_GIFSICLE && ! $skip['gifsicle'] ) {
323
  /* translators: %s: name of a tool like jpegtran */
324
- $msg = '<div>' . sprintf( esc_html__( '%s is missing', 'ewww-image-optimizer' ), '<em>gifsicle</em>' ) . '</div>';
 
 
 
 
325
  }
326
  break;
327
  default:
328
- $msg = '<div>' . esc_html__( 'Unsupported file type', 'ewww-image-optimizer' ) . '</div>';
329
- }
330
- // File isn't in a format we can work with, we don't work with strangers.
331
- if ( $msg ) {
332
- if ( $return ) {
333
- return $msg;
334
- }
335
- echo $msg;
336
- return;
337
  }
338
  if ( ! empty( $meta->image->meta_data['ewww_image_optimizer'] ) ) {
339
  ewww_image_optimizer_update_file_from_meta( $file_path, 'nextcell', $id, 'full' );
@@ -347,41 +362,40 @@ if ( ! class_exists( 'EWWW_Nextcellent' ) ) {
347
  // If we have a valid status, display it, the image size, and give a re-optimize link.
348
  if ( ! empty( $optimized_images ) ) {
349
  list( $detail_output, $converted, $backup_available ) = ewww_image_optimizer_custom_column_results( $id, $optimized_images );
350
- $output .= $detail_output;
351
  if ( current_user_can( apply_filters( 'ewww_image_optimizer_manual_permissions', '' ) ) ) {
352
- $output .= sprintf(
353
- '<a class="ewww-manual-optimize" data-id="%1$d" data-nonce="%2$s" href="' . admin_url( 'admin.php?action=ewww_ngg_manual' ) . '&amp;ewww_manual_nonce=%2$s&amp;ewww_force=1&amp;ewww_attachment_ID=%1$d">%3$s</a>',
354
- $id,
355
- $ewww_manual_nonce,
356
  esc_html__( 'Re-optimize', 'ewww-image-optimizer' )
357
  );
358
  if ( $backup_available ) {
359
- $output .= sprintf(
360
- '<br><a class="ewww-manual-cloud-restore" data-id="%1$d" data-nonce="%2$s" href="' . admin_url( 'admin.php?action=ewww_ngg_cloud_restore' ) . '&amp;ewww_manual_nonce=%2$s&amp;ewww_attachment_ID=%1$d">%3$s</a>',
361
- $id,
362
- $ewww_manual_nonce,
363
  esc_html__( 'Restore original', 'ewww-image-optimizer' )
364
  );
365
  }
366
  }
367
  } elseif ( ewww_image_optimizer_image_is_pending( $id, 'nextc-async' ) ) {
368
- $output .= esc_html__( 'In Progress', 'ewww-image-optimizer' );
369
  // Otherwise, give the image size, and a link to optimize right now.
370
  } else {
371
  if ( current_user_can( apply_filters( 'ewww_image_optimizer_manual_permissions', '' ) ) ) {
372
- $output .= sprintf(
373
- '<a class="ewww-manual-optimize" data-id="%1$d" data-nonce="%2$s" href="' . admin_url( 'admin.php?action=ewww_ngg_manual' ) . '&amp;ewww_manual_nonce=%2$s&amp;ewww_attachment_ID=%1$d">%3$s</a>',
374
- $id,
375
- $ewww_manual_nonce,
376
  esc_html__( 'Optimize now!', 'ewww-image-optimizer' )
377
  );
378
  }
379
  }
380
- $output .= '</div>';
381
  if ( $return ) {
382
- return $output;
383
  }
384
- echo $output;
385
  } // End if().
386
  }
387
 
@@ -389,16 +403,6 @@ if ( ! class_exists( 'EWWW_Nextcellent' ) ) {
389
  * Output the html for the bulk optimize page.
390
  */
391
  function ewww_ngg_bulk_preview() {
392
- if ( ! empty( $_REQUEST['doaction'] ) ) {
393
- // If there is no requested bulk action, do nothing.
394
- if ( empty( $_REQUEST['bulkaction'] ) ) {
395
- return;
396
- }
397
- // If there is no media to optimize, do nothing.
398
- if ( empty( $_REQUEST['doaction'] ) || ! is_array( $_REQUEST['doaction'] ) ) {
399
- return;
400
- }
401
- }
402
  // Retrieve the attachments array from the db.
403
  $attachments = get_option( 'ewww_image_optimizer_bulk_ngg_attachments' );
404
  // Make sure there are some attachments to process.
@@ -412,17 +416,17 @@ if ( ! class_exists( 'EWWW_Nextcellent' ) ) {
412
  <?php
413
  if ( ewww_image_optimizer_get_option( 'ewww_image_optimizer_cloud_key' ) ) {
414
  ewww_image_optimizer_cloud_verify();
415
- 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' ) . ' ' . ewww_image_optimizer_cloud_quota() . '</a>';
416
  }
417
  // Retrieve the value of the 'bulk resume' option and set the button text for the form to use.
418
  $resume = get_option( 'ewww_image_optimizer_bulk_ngg_resume' );
419
  if ( empty( $resume ) ) {
420
- $button_text = esc_attr__( 'Start optimizing', 'ewww-image-optimizer' );
421
  } else {
422
- $button_text = esc_attr__( 'Resume previous bulk operation', 'ewww-image-optimizer' );
423
  }
424
  /* translators: %d: number of images */
425
- $selected_images_text = sprintf( esc_html( _n( 'There is %d image ready to optimize.', 'There are %d images ready to optimize.', count( $attachments ), 'ewww-image-optimizer' ) ), count( $attachments ) );
426
  ?>
427
  <div id="ewww-bulk-loading"></div>
428
  <div id="ewww-bulk-progressbar"></div>
@@ -453,11 +457,11 @@ if ( ! class_exists( 'EWWW_Nextcellent' ) ) {
453
  </div>
454
  </div>
455
  <div id="ewww-bulk-forms">
456
- <p class="ewww-bulk-info"><?php echo $selected_images_text; ?><br />
457
  <?php esc_html_e( 'Previously optimized images will be skipped by default.', 'ewww-image-optimizer' ); ?></p>
458
  <form id="ewww-bulk-start" class="ewww-bulk-form" method="post" action="">
459
  <input type="hidden" id="ewww-delay" name="ewww-delay" value="0">
460
- <input type="submit" class="button-secondary action" value="<?php echo $button_text; ?>" />
461
  </form>
462
  <?php
463
  // If there is a previous bulk operation to resume, give the user the option to reset the resume flag.
@@ -472,9 +476,6 @@ if ( ! class_exists( 'EWWW_Nextcellent' ) ) {
472
  <?php
473
  }
474
  echo '</div></div>';
475
- if ( ! empty( $_REQUEST['ewww_inline'] ) ) {
476
- wp_die();
477
- }
478
  return;
479
  }
480
 
@@ -486,69 +487,29 @@ if ( ! class_exists( 'EWWW_Nextcellent' ) ) {
486
  * @param string $hook The hook identifier for the current page.
487
  */
488
  function ewww_ngg_bulk_script( $hook ) {
489
- ewwwio_debug_message( '<b>' . __METHOD__ . '()</b>' );
490
- $i18ngg = strtolower( __( 'Galleries', 'nggallery' ) );
491
- ewwwio_debug_message( "i18n string for galleries: $i18ngg" );
492
- // Make sure we are on a legitimate page and that we have the proper POST variables if necessary.
493
- if ( $i18ngg . '_page_ewww-ngg-bulk' !== $hook && $i18ngg . '_page_nggallery-manage-gallery' !== $hook ) {
494
- return;
495
- }
496
- if ( $i18ngg . '_page_nggallery-manage-gallery' === $hook && ( empty( $_REQUEST['bulkaction'] ) || 'bulk_optimize' !== $_REQUEST['bulkaction'] ) ) {
497
- return;
498
- }
499
- if ( $i18ngg . '_page_nggallery-manage-gallery' === $hook && ( empty( $_REQUEST['doaction'] ) || ! is_array( $_REQUEST['doaction'] ) ) ) {
500
  return;
501
  }
 
502
  $images = null;
503
  // See if the user wants to reset the previous bulk status.
504
- if ( ! empty( $_REQUEST['ewww_reset'] ) && wp_verify_nonce( $_REQUEST['ewww_wpnonce'], 'ewww-image-optimizer-bulk-reset' ) ) {
505
  update_option( 'ewww_image_optimizer_bulk_ngg_resume', '' );
506
  }
507
  // See if there is a previous operation to resume.
508
  $resume = get_option( 'ewww_image_optimizer_bulk_ngg_resume' );
509
  // If we've been given a bulk action to perform.
510
- if ( ! empty( $_REQUEST['doaction'] ) ) {
511
- // If we are optimizing a specific group of images.
512
- if ( 'manage-images' === $_REQUEST['page'] && 'bulk_optimize' === $_REQUEST['bulkaction'] ) {
513
- ewwwio_debug_message( 'optimizing a group of images' );
514
- check_admin_referer( 'ngg_updategallery' );
515
- // Reset the resume status, not allowed here.
516
- update_option( 'ewww_image_optimizer_bulk_ngg_resume', '' );
517
- // Retrieve the image IDs from POST.
518
- $images = array_map( 'intval', $_REQUEST['doaction'] );
519
- }
520
- // If we are optimizing a specific group of galleries.
521
- if ( 'manage-galleries' === $_REQUEST['page'] && 'bulk_optimize' === $_REQUEST['bulkaction'] ) {
522
- ewwwio_debug_message( 'optimizing a group of galleries' );
523
- check_admin_referer( 'ngg_bulkgallery' );
524
- global $nggdb;
525
- // Reset the resume status, not allowed here.
526
- update_option( 'ewww_image_optimizer_bulk_ngg_resume', '' );
527
- $ids = array();
528
- $gids = array_map( 'intval', $_REQUEST['doaction'] );
529
- // For each gallery we are given.
530
- foreach ( $gids as $gid ) {
531
- // Get a list of IDs.
532
- $gallery_list = $nggdb->get_gallery( $gid );
533
- // For each ID.
534
- foreach ( $gallery_list as $image ) {
535
- // Add it to the array.
536
- $images[] = $image->pid;
537
- }
538
- }
539
- }
540
- } elseif ( ! empty( $resume ) ) {
541
  // Otherwise, if we have an operation to resume.
542
  ewwwio_debug_message( 'resuming a previous operation (maybe)' );
543
  // Get the list of attachment IDs from the db.
544
  $images = get_option( 'ewww_image_optimizer_bulk_ngg_attachments' );
545
  // Otherwise, if we are on the standard bulk page, get all the images in the db.
546
- } elseif ( $hook === $i18ngg . '_page_ewww-ngg-bulk' ) {
547
  ewwwio_debug_message( 'starting from scratch, grabbing all the images' );
548
  global $wpdb;
549
  $images = $wpdb->get_col( "SELECT pid FROM $wpdb->nggpictures ORDER BY sortorder ASC" );
550
- } else {
551
- ewwwio_debug_message( $hook );
552
  } // End if().
553
 
554
  // Store the image IDs to process in the db.
@@ -584,10 +545,10 @@ if ( ! class_exists( 'EWWW_Nextcellent' ) ) {
584
  function ewww_ngg_bulk_init() {
585
  $permissions = apply_filters( 'ewww_image_optimizer_bulk_permissions', '' );
586
  $output = array();
587
- if ( ! wp_verify_nonce( $_REQUEST['ewww_wpnonce'], 'ewww-image-optimizer-bulk' ) || ! current_user_can( $permissions ) ) {
588
  $output['error'] = esc_html__( 'Access denied.', 'ewww-image-optimizer' );
589
  ewwwio_ob_clean();
590
- wp_die( ewwwio_json_encode( $output ) );
591
  }
592
  // Toggle the resume flag to indicate an operation is in progress.
593
  update_option( 'ewww_image_optimizer_bulk_ngg_resume', 'true' );
@@ -599,7 +560,7 @@ if ( ! class_exists( 'EWWW_Nextcellent' ) ) {
599
  if ( ! is_array( $attachments ) ) {
600
  $output['error'] = esc_html__( 'Error retrieving list of images' );
601
  ewwwio_ob_clean();
602
- wp_die( ewwwio_json_encode( $output ) );
603
  }
604
  $id = array_shift( $attachments );
605
  $file_name = $this->ewww_ngg_bulk_filename( $id );
@@ -611,7 +572,7 @@ if ( ! class_exists( 'EWWW_Nextcellent' ) ) {
611
  $output['results'] = '<p>' . esc_html__( 'Optimizing', 'ewww-image-optimizer' ) . ' <b>' . $file_name . "</b>&nbsp;<img src='$loading_image' alt='loading'/></p>";
612
  }
613
  ewwwio_ob_clean();
614
- wp_die( ewwwio_json_encode( $output ) );
615
  }
616
 
617
  /**
@@ -643,14 +604,14 @@ if ( ! class_exists( 'EWWW_Nextcellent' ) ) {
643
  $ewww_defer = false;
644
  $output = array();
645
  $permissions = apply_filters( 'ewww_image_optimizer_bulk_permissions', '' );
646
- if ( ! wp_verify_nonce( $_REQUEST['ewww_wpnonce'], 'ewww-image-optimizer-bulk' ) || ! current_user_can( $permissions ) ) {
647
  $outupt['error'] = esc_html__( 'Access token has expired, please reload the page.', 'ewww-image-optimizer' );
648
  ewwwio_ob_clean();
649
- wp_die( ewwwio_json_encode( $output ) );
650
  }
651
  session_write_close();
652
  // Find out if our nonce is on it's last leg/tick.
653
- $tick = wp_verify_nonce( $_REQUEST['ewww_wpnonce'], 'ewww-image-optimizer-bulk' );
654
  if ( 2 === $tick ) {
655
  $output['new_nonce'] = wp_create_nonce( 'ewww-image-optimizer-bulk' );
656
  } else {
@@ -668,7 +629,7 @@ if ( ! class_exists( 'EWWW_Nextcellent' ) ) {
668
  if ( ! empty( $ewww_status ) && preg_match( '/exceeded/', $ewww_status ) ) {
669
  $output['error'] = esc_html__( 'License Exceeded', 'ewww-image-optimizer' );
670
  ewwwio_ob_clean();
671
- wp_die( ewwwio_json_encode( $output ) );
672
  }
673
  // Output the results of the optimization.
674
  if ( $fres[0] ) {
@@ -699,7 +660,7 @@ if ( ! class_exists( 'EWWW_Nextcellent' ) ) {
699
  $output['done'] = 1;
700
  }
701
  ewwwio_ob_clean();
702
- wp_die( ewwwio_json_encode( $output ) );
703
  }
704
 
705
  /**
@@ -707,7 +668,7 @@ if ( ! class_exists( 'EWWW_Nextcellent' ) ) {
707
  */
708
  function ewww_ngg_bulk_cleanup() {
709
  $permissions = apply_filters( 'ewww_image_optimizer_bulk_permissions', '' );
710
- if ( ! wp_verify_nonce( $_REQUEST['ewww_wpnonce'], 'ewww-image-optimizer-bulk' ) || ! current_user_can( $permissions ) ) {
711
  ewwwio_ob_clean();
712
  wp_die( esc_html__( 'Access token has expired, please reload the page.', 'ewww-image-optimizer' ) );
713
  }
@@ -745,22 +706,6 @@ if ( ! class_exists( 'EWWW_Nextcellent' ) ) {
745
  )
746
  );
747
  }
748
-
749
- /**
750
- * Insert a bulk optimize option in the actions list for the gallery and image management pages (via javascript, since we have no hooks).
751
- */
752
- function ewww_ngg_bulk_actions_script() {
753
- if ( ! current_user_can( apply_filters( 'ewww_image_optimizer_bulk_permissions', '' ) ) ) {
754
- return;
755
- }
756
- ?>
757
- <script type="text/javascript">
758
- jQuery(document).ready(function($){
759
- $('select[name^="bulkaction"] option:last-child').after('<option value="bulk_optimize">Bulk Optimize</option>');
760
- });
761
- </script>
762
- <?php
763
- }
764
  }
765
 
766
  global $ewwwngg;
33
  add_action( 'wp_ajax_ewww_ngg_cloud_restore', array( $this, 'ewww_ngg_cloud_restore' ) );
34
  add_action( 'admin_action_ewww_ngg_manual', array( $this, 'ewww_ngg_manual' ) );
35
  add_action( 'admin_menu', array( $this, 'ewww_ngg_bulk_menu' ) );
 
36
  add_action( 'admin_enqueue_scripts', array( $this, 'ewww_ngg_bulk_script' ), 9 );
37
  add_action( 'wp_ajax_bulk_ngg_preview', array( $this, 'ewww_ngg_bulk_preview' ) );
38
  add_action( 'wp_ajax_bulk_ngg_init', array( $this, 'ewww_ngg_bulk_init' ) );
132
  ewwwio_debug_message( '<b>' . __METHOD__ . '()</b>' );
133
  global $ewww_defer;
134
  global $ewww_image;
135
+ ewwwio_debug_message( 'nextcellent new image thumb' );
136
+ if ( empty( $_REQUEST['_wpnonce'] ) || ! wp_verify_nonce( sanitize_key( $_REQUEST['_wpnonce'] ), 'ngg-ajax' ) ) {
137
+ ewwwio_debug_message( 'failed verification' );
138
+ return;
139
+ }
140
+ ewwwio_debug_message( print_r( $_REQUEST, true ) );
141
  if ( file_exists( $filename ) ) {
142
  if ( ! empty( $_POST['id'] ) ) {
143
  $id = (int) $_POST['id'];
144
+ } elseif ( ! empty( $_POST['image'] ) ) {
145
+ $id = sanitize_key( $_POST['image'] );
146
  }
147
  $ewww_image = new EWWW_Image( $id, 'nextcell', $filename );
148
  $ewww_image->resize = 'thumbnail';
162
  wp_die( esc_html__( 'You do not have permission to optimize images.', 'ewww-image-optimizer' ) );
163
  }
164
  ewwwio_ob_clean();
165
+ wp_die( wp_json_encode( array( 'error' => esc_html__( 'You do not have permission to optimize images.', 'ewww-image-optimizer' ) ) ) );
166
  }
167
  // Make sure function wasn't called without an attachment to work with.
168
  if ( empty( $_REQUEST['ewww_attachment_ID'] ) ) {
170
  wp_die( esc_html__( 'No attachment ID was provided.', 'ewww-image-optimizer' ) );
171
  }
172
  ewwwio_ob_clean();
173
+ wp_die( wp_json_encode( array( 'error' => esc_html__( 'No attachment ID was provided.', 'ewww-image-optimizer' ) ) ) );
174
  }
175
  // Store the attachment $id.
176
  $id = intval( $_REQUEST['ewww_attachment_ID'] );
177
+ if ( empty( $_REQUEST['ewww_manual_nonce'] ) || ! wp_verify_nonce( sanitize_key( $_REQUEST['ewww_manual_nonce'] ), "ewww-manual-$id" ) ) {
178
  if ( ! wp_doing_ajax() ) {
179
  wp_die( esc_html__( 'Access denied.', 'ewww-image-optimizer' ) );
180
  }
181
  ewwwio_ob_clean();
182
+ wp_die( wp_json_encode( array( 'error' => esc_html__( 'Access denied.', 'ewww-image-optimizer' ) ) ) );
183
  }
184
+ global $ewww_force;
185
+ $ewww_force = ! empty( $_REQUEST['ewww_force'] ) ? true : false;
186
  $this->ewww_ngg_optimize( $id );
187
  $success = $this->ewww_manage_image_custom_column( 'ewww_image_optimizer', $id, true );
188
  if ( ! wp_doing_ajax() ) {
189
  // Get the referring page, and send the user back there.
190
+ wp_safe_redirect( wp_get_referer() );
 
 
191
  die;
192
  }
193
  ewwwio_ob_clean();
194
+ wp_die( wp_json_encode( array( 'success' => $success ) ) );
195
  }
196
 
197
  /**
205
  wp_die( esc_html__( 'You do not have permission to optimize images.', 'ewww-image-optimizer' ) );
206
  }
207
  ewwwio_ob_clean();
208
+ wp_die( wp_json_encode( array( 'error' => esc_html__( 'You do not have permission to optimize images.', 'ewww-image-optimizer' ) ) ) );
209
  }
210
  // Make sure function wasn't called without an attachment to work with.
211
+ if ( ! isset( $_REQUEST['ewww_attachment_ID'] ) ) {
212
  if ( ! wp_doing_ajax() ) {
213
  wp_die( esc_html__( 'No attachment ID was provided.', 'ewww-image-optimizer' ) );
214
  }
215
  ewwwio_ob_clean();
216
+ wp_die( wp_json_encode( array( 'error' => esc_html__( 'No attachment ID was provided.', 'ewww-image-optimizer' ) ) ) );
217
  }
218
  // Sanitize the attachment $id.
219
+ $id = (int) $_REQUEST['ewww_attachment_ID'];
220
+ if ( empty( $_REQUEST['ewww_manual_nonce'] ) || ! wp_verify_nonce( sanitize_key( $_REQUEST['ewww_manual_nonce'] ), "ewww-manual-$id" ) ) {
221
  if ( ! wp_doing_ajax() ) {
222
  wp_die( esc_html__( 'Access denied.', 'ewww-image-optimizer' ) );
223
  }
224
  ewwwio_ob_clean();
225
+ wp_die( wp_json_encode( array( 'error' => esc_html__( 'Access denied.', 'ewww-image-optimizer' ) ) ) );
226
  }
227
  ewww_image_optimizer_cloud_restore_from_meta_data( $id, 'nextcell' );
228
  $success = $this->ewww_manage_image_custom_column( 'ewww_image_optimizer', $id, true );
229
  ewwwio_ob_clean();
230
+ wp_die( wp_json_encode( array( 'success' => $success ) ) );
231
  }
232
 
233
  /**
290
  function ewww_manage_image_custom_column( $column_name, $id, $return = false ) {
291
  // Once we've found our custom column.
292
  if ( 'ewww_image_optimizer' === $column_name ) {
293
+ if ( $return ) {
294
+ ob_start();
295
+ }
296
  // Need this file to work with metadata.
297
  require_once( WP_CONTENT_DIR . '/plugins/nextcellent-gallery-nextgen-legacy/lib/meta.php' );
298
  // Get the metadata for the image.
299
+ $meta = new nggMeta( $id );
300
+ echo '<div id="ewww-nextcellent-status-' . (int) $id . '">';
 
301
  // Get the file path of the image.
302
  $file_path = $meta->image->imagePath;
303
  // Get the mimetype of the image.
314
  // If jpegtran is missing, tell the user.
315
  if ( ! EWWW_IMAGE_OPTIMIZER_JPEGTRAN && ! $skip['jpegtran'] ) {
316
  /* translators: %s: name of a tool like jpegtran */
317
+ echo '<div>' . sprintf( esc_html__( '%s is missing', 'ewww-image-optimizer' ), '<em>jpegtran</em>' ) . '</div></div>';
318
+ if ( $return ) {
319
+ return ob_get_clean();
320
+ }
321
+ return;
322
  }
323
  break;
324
  case 'image/png':
325
  // If the PNG tools are missing, tell the user.
326
+ if ( ! EWWW_IMAGE_OPTIMIZER_OPTIPNG && ! $skip['optipng'] ) {
327
  /* translators: %s: name of a tool like jpegtran */
328
+ echo '<div>' . sprintf( esc_html__( '%s is missing', 'ewww-image-optimizer' ), '<em>optipng</em>' ) . '</div></div>';
329
+ if ( $return ) {
330
+ return ob_get_clean();
331
+ }
332
+ return;
333
  }
334
  break;
335
  case 'image/gif':
336
  // If gifsicle is missing, tell the user.
337
  if ( ! EWWW_IMAGE_OPTIMIZER_GIFSICLE && ! $skip['gifsicle'] ) {
338
  /* translators: %s: name of a tool like jpegtran */
339
+ echo '<div>' . sprintf( esc_html__( '%s is missing', 'ewww-image-optimizer' ), '<em>gifsicle</em>' ) . '</div></div>';
340
+ if ( $return ) {
341
+ return ob_get_clean();
342
+ }
343
+ return;
344
  }
345
  break;
346
  default:
347
+ echo '<div>' . esc_html__( 'Unsupported file type', 'ewww-image-optimizer' ) . '</div></div>';
348
+ if ( $return ) {
349
+ return ob_get_clean();
350
+ }
351
+ return;
 
 
 
 
352
  }
353
  if ( ! empty( $meta->image->meta_data['ewww_image_optimizer'] ) ) {
354
  ewww_image_optimizer_update_file_from_meta( $file_path, 'nextcell', $id, 'full' );
362
  // If we have a valid status, display it, the image size, and give a re-optimize link.
363
  if ( ! empty( $optimized_images ) ) {
364
  list( $detail_output, $converted, $backup_available ) = ewww_image_optimizer_custom_column_results( $id, $optimized_images );
365
+ echo wp_kses_post( $detail_output );
366
  if ( current_user_can( apply_filters( 'ewww_image_optimizer_manual_permissions', '' ) ) ) {
367
+ printf(
368
+ '<a class="ewww-manual-optimize" data-id="%1$d" data-nonce="%2$s" href="' . esc_url( admin_url( 'admin.php?action=ewww_ngg_manual' ) ) . '&amp;ewww_manual_nonce=%2$s&amp;ewww_force=1&amp;ewww_attachment_ID=%1$d">%3$s</a>',
369
+ (int) $id,
370
+ esc_attr( $ewww_manual_nonce ),
371
  esc_html__( 'Re-optimize', 'ewww-image-optimizer' )
372
  );
373
  if ( $backup_available ) {
374
+ printf(
375
+ '<br><a class="ewww-manual-cloud-restore" data-id="%1$d" data-nonce="%2$s" href="' . esc_url( admin_url( 'admin.php?action=ewww_ngg_cloud_restore' ) ) . '&amp;ewww_manual_nonce=%2$s&amp;ewww_attachment_ID=%1$d">%3$s</a>',
376
+ (int) $id,
377
+ esc_attr( $ewww_manual_nonce ),
378
  esc_html__( 'Restore original', 'ewww-image-optimizer' )
379
  );
380
  }
381
  }
382
  } elseif ( ewww_image_optimizer_image_is_pending( $id, 'nextc-async' ) ) {
383
+ echo '<div>' . esc_html__( 'In Progress', 'ewww-image-optimizer' ) . '</div>';
384
  // Otherwise, give the image size, and a link to optimize right now.
385
  } else {
386
  if ( current_user_can( apply_filters( 'ewww_image_optimizer_manual_permissions', '' ) ) ) {
387
+ printf(
388
+ '<div><a class="ewww-manual-optimize" data-id="%1$d" data-nonce="%2$s" href="' . esc_url( admin_url( 'admin.php?action=ewww_ngg_manual' ) ) . '&amp;ewww_manual_nonce=%2$s&amp;ewww_attachment_ID=%1$d">%3$s</a></div>',
389
+ (int) $id,
390
+ esc_attr( $ewww_manual_nonce ),
391
  esc_html__( 'Optimize now!', 'ewww-image-optimizer' )
392
  );
393
  }
394
  }
395
+ echo '</div>';
396
  if ( $return ) {
397
+ return ob_get_clean();
398
  }
 
399
  } // End if().
400
  }
401
 
403
  * Output the html for the bulk optimize page.
404
  */
405
  function ewww_ngg_bulk_preview() {
 
 
 
 
 
 
 
 
 
 
406
  // Retrieve the attachments array from the db.
407
  $attachments = get_option( 'ewww_image_optimizer_bulk_ngg_attachments' );
408
  // Make sure there are some attachments to process.
416
  <?php
417
  if ( ewww_image_optimizer_get_option( 'ewww_image_optimizer_cloud_key' ) ) {
418
  ewww_image_optimizer_cloud_verify();
419
+ 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>';
420
  }
421
  // Retrieve the value of the 'bulk resume' option and set the button text for the form to use.
422
  $resume = get_option( 'ewww_image_optimizer_bulk_ngg_resume' );
423
  if ( empty( $resume ) ) {
424
+ $button_text = __( 'Start optimizing', 'ewww-image-optimizer' );
425
  } else {
426
+ $button_text = __( 'Resume previous bulk operation', 'ewww-image-optimizer' );
427
  }
428
  /* translators: %d: number of images */
429
+ $selected_images_text = sprintf( _n( 'There is %d image ready to optimize.', 'There are %d images ready to optimize.', count( $attachments ), 'ewww-image-optimizer' ), count( $attachments ) );
430
  ?>
431
  <div id="ewww-bulk-loading"></div>
432
  <div id="ewww-bulk-progressbar"></div>
457
  </div>
458
  </div>
459
  <div id="ewww-bulk-forms">
460
+ <p class="ewww-bulk-info"><?php echo esc_html( $selected_images_text ); ?><br />
461
  <?php esc_html_e( 'Previously optimized images will be skipped by default.', 'ewww-image-optimizer' ); ?></p>
462
  <form id="ewww-bulk-start" class="ewww-bulk-form" method="post" action="">
463
  <input type="hidden" id="ewww-delay" name="ewww-delay" value="0">
464
+ <input type="submit" class="button-secondary action" value="<?php echo esc_attr( $button_text ); ?>" />
465
  </form>
466
  <?php
467
  // If there is a previous bulk operation to resume, give the user the option to reset the resume flag.
476
  <?php
477
  }
478
  echo '</div></div>';
 
 
 
479
  return;
480
  }
481
 
487
  * @param string $hook The hook identifier for the current page.
488
  */
489
  function ewww_ngg_bulk_script( $hook ) {
490
+ ewwwio_debug_message( $hook );
491
+ if ( 'galleries_page_ewww-ngg-bulk' !== $hook ) {
 
 
 
 
 
 
 
 
 
492
  return;
493
  }
494
+ ewwwio_debug_message( '<b>' . __METHOD__ . '()</b>' );
495
  $images = null;
496
  // See if the user wants to reset the previous bulk status.
497
+ if ( ! empty( $_REQUEST['ewww_reset'] ) && ! empty( $_REQUEST['ewww_wpnonce'] ) && wp_verify_nonce( sanitize_key( $_REQUEST['ewww_wpnonce'] ), 'ewww-image-optimizer-bulk-reset' ) ) {
498
  update_option( 'ewww_image_optimizer_bulk_ngg_resume', '' );
499
  }
500
  // See if there is a previous operation to resume.
501
  $resume = get_option( 'ewww_image_optimizer_bulk_ngg_resume' );
502
  // If we've been given a bulk action to perform.
503
+ if ( ! empty( $resume ) ) {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
504
  // Otherwise, if we have an operation to resume.
505
  ewwwio_debug_message( 'resuming a previous operation (maybe)' );
506
  // Get the list of attachment IDs from the db.
507
  $images = get_option( 'ewww_image_optimizer_bulk_ngg_attachments' );
508
  // Otherwise, if we are on the standard bulk page, get all the images in the db.
509
+ } else {
510
  ewwwio_debug_message( 'starting from scratch, grabbing all the images' );
511
  global $wpdb;
512
  $images = $wpdb->get_col( "SELECT pid FROM $wpdb->nggpictures ORDER BY sortorder ASC" );
 
 
513
  } // End if().
514
 
515
  // Store the image IDs to process in the db.
545
  function ewww_ngg_bulk_init() {
546
  $permissions = apply_filters( 'ewww_image_optimizer_bulk_permissions', '' );
547
  $output = array();
548
+ if ( empty( $_REQUEST['ewww_wpnonce'] ) || ! wp_verify_nonce( sanitize_key( $_REQUEST['ewww_wpnonce'] ), 'ewww-image-optimizer-bulk' ) || ! current_user_can( $permissions ) ) {
549
  $output['error'] = esc_html__( 'Access denied.', 'ewww-image-optimizer' );
550
  ewwwio_ob_clean();
551
+ wp_die( wp_json_encode( $output ) );
552
  }
553
  // Toggle the resume flag to indicate an operation is in progress.
554
  update_option( 'ewww_image_optimizer_bulk_ngg_resume', 'true' );
560
  if ( ! is_array( $attachments ) ) {
561
  $output['error'] = esc_html__( 'Error retrieving list of images' );
562
  ewwwio_ob_clean();
563
+ wp_die( wp_json_encode( $output ) );
564
  }
565
  $id = array_shift( $attachments );
566
  $file_name = $this->ewww_ngg_bulk_filename( $id );
572
  $output['results'] = '<p>' . esc_html__( 'Optimizing', 'ewww-image-optimizer' ) . ' <b>' . $file_name . "</b>&nbsp;<img src='$loading_image' alt='loading'/></p>";
573
  }
574
  ewwwio_ob_clean();
575
+ wp_die( wp_json_encode( $output ) );
576
  }
577
 
578
  /**
604
  $ewww_defer = false;
605
  $output = array();
606
  $permissions = apply_filters( 'ewww_image_optimizer_bulk_permissions', '' );
607
+ if ( empty( $_REQUEST['ewww_wpnonce'] ) || ! wp_verify_nonce( sanitize_key( $_REQUEST['ewww_wpnonce'] ), 'ewww-image-optimizer-bulk' ) || ! current_user_can( $permissions ) ) {
608
  $outupt['error'] = esc_html__( 'Access token has expired, please reload the page.', 'ewww-image-optimizer' );
609
  ewwwio_ob_clean();
610
+ wp_die( wp_json_encode( $output ) );
611
  }
612
  session_write_close();
613
  // Find out if our nonce is on it's last leg/tick.
614
+ $tick = wp_verify_nonce( sanitize_key( $_REQUEST['ewww_wpnonce'] ), 'ewww-image-optimizer-bulk' );
615
  if ( 2 === $tick ) {
616
  $output['new_nonce'] = wp_create_nonce( 'ewww-image-optimizer-bulk' );
617
  } else {
629
  if ( ! empty( $ewww_status ) && preg_match( '/exceeded/', $ewww_status ) ) {
630
  $output['error'] = esc_html__( 'License Exceeded', 'ewww-image-optimizer' );
631
  ewwwio_ob_clean();
632
+ wp_die( wp_json_encode( $output ) );
633
  }
634
  // Output the results of the optimization.
635
  if ( $fres[0] ) {
660
  $output['done'] = 1;
661
  }
662
  ewwwio_ob_clean();
663
+ wp_die( wp_json_encode( $output ) );
664
  }
665
 
666
  /**
668
  */
669
  function ewww_ngg_bulk_cleanup() {
670
  $permissions = apply_filters( 'ewww_image_optimizer_bulk_permissions', '' );
671
+ if ( empty( $_REQUEST['ewww_wpnonce'] ) || ! wp_verify_nonce( sanitize_key( $_REQUEST['ewww_wpnonce'] ), 'ewww-image-optimizer-bulk' ) || ! current_user_can( $permissions ) ) {
672
  ewwwio_ob_clean();
673
  wp_die( esc_html__( 'Access token has expired, please reload the page.', 'ewww-image-optimizer' ) );
674
  }
706
  )
707
  );
708
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
709
  }
710
 
711
  global $ewwwngg;
classes/class-ewww-nextgen.php CHANGED
@@ -255,7 +255,7 @@ if ( ! class_exists( 'EWWW_Nextgen' ) ) {
255
  wp_die( esc_html__( 'You do not have permission to optimize images.', 'ewww-image-optimizer' ) );
256
  }
257
  ewwwio_ob_clean();
258
- wp_die( ewwwio_json_encode( array( 'error' => esc_html__( 'You do not have permission to optimize images.', 'ewww-image-optimizer' ) ) ) );
259
  }
260
  // Make sure function wasn't called without an attachment to work with.
261
  if ( false === isset( $_REQUEST['ewww_attachment_ID'] ) ) {
@@ -263,17 +263,19 @@ if ( ! class_exists( 'EWWW_Nextgen' ) ) {
263
  wp_die( esc_html__( 'No attachment ID was provided.', 'ewww-image-optimizer' ) );
264
  }
265
  ewwwio_ob_clean();
266
- wp_die( ewwwio_json_encode( array( 'error' => esc_html__( 'No attachment ID was provided.', 'ewww-image-optimizer' ) ) ) );
267
  }
268
  // Sanitize the attachment $id.
269
- $id = intval( $_REQUEST['ewww_attachment_ID'] );
270
- if ( empty( $_REQUEST['ewww_manual_nonce'] ) || ! wp_verify_nonce( $_REQUEST['ewww_manual_nonce'], "ewww-manual-$id" ) ) {
271
  if ( ! wp_doing_ajax() ) {
272
  wp_die( esc_html__( 'Access denied.', 'ewww-image-optimizer' ) );
273
  }
274
  ewwwio_ob_clean();
275
- wp_die( ewwwio_json_encode( array( 'error' => esc_html__( 'Access denied.', 'ewww-image-optimizer' ) ) ) );
276
  }
 
 
277
  // Creating the 'registry' object for working with nextgen.
278
  $registry = C_Component_Registry::get_instance();
279
  // Creating a database storage object from the 'registry' object.
@@ -284,17 +286,15 @@ if ( ! class_exists( 'EWWW_Nextgen' ) ) {
284
  $success = $this->ewww_manage_image_custom_column( '', $image );
285
  if ( get_transient( 'ewww_image_optimizer_cloud_status' ) === 'exceeded' || ewww_image_optimizer_get_option( 'ewww_image_optimizer_cloud_exceeded' ) > time() ) {
286
  ewwwio_ob_clean();
287
- wp_die( ewwwio_json_encode( array( 'error' => esc_html__( 'License exceeded', 'ewww-image-optimizer' ) ) ) );
288
  }
289
  if ( ! wp_doing_ajax() ) {
290
  // Get the referring page, and send the user back there.
291
- $sendback = wp_get_referer();
292
- $sendback = preg_replace( '|[^a-z0-9-~+_.?#=&;,/:]|i', '', $sendback );
293
- wp_redirect( $sendback );
294
  die;
295
  }
296
  ewwwio_ob_clean();
297
- wp_die( ewwwio_json_encode( array( 'success' => $success ) ) );
298
  }
299
 
300
  /**
@@ -308,7 +308,7 @@ if ( ! class_exists( 'EWWW_Nextgen' ) ) {
308
  wp_die( esc_html__( 'You do not have permission to optimize images.', 'ewww-image-optimizer' ) );
309
  }
310
  ewwwio_ob_clean();
311
- wp_die( ewwwio_json_encode( array( 'error' => esc_html__( 'You do not have permission to optimize images.', 'ewww-image-optimizer' ) ) ) );
312
  }
313
  // Make sure function wasn't called without an attachment to work with.
314
  if ( false === isset( $_REQUEST['ewww_attachment_ID'] ) ) {
@@ -316,16 +316,16 @@ if ( ! class_exists( 'EWWW_Nextgen' ) ) {
316
  wp_die( esc_html__( 'No attachment ID was provided.', 'ewww-image-optimizer' ) );
317
  }
318
  ewwwio_ob_clean();
319
- wp_die( ewwwio_json_encode( array( 'error' => esc_html__( 'No attachment ID was provided.', 'ewww-image-optimizer' ) ) ) );
320
  }
321
  // Sanitize the attachment $id.
322
  $id = intval( $_REQUEST['ewww_attachment_ID'] );
323
- if ( empty( $_REQUEST['ewww_manual_nonce'] ) || ! wp_verify_nonce( $_REQUEST['ewww_manual_nonce'], "ewww-manual-$id" ) ) {
324
  if ( ! wp_doing_ajax() ) {
325
  wp_die( esc_html__( 'Access denied.', 'ewww-image-optimizer' ) );
326
  }
327
  ewwwio_ob_clean();
328
- wp_die( ewwwio_json_encode( array( 'error' => esc_html__( 'Access denied.', 'ewww-image-optimizer' ) ) ) );
329
  }
330
  // Creating the 'registry' object for working with nextgen.
331
  $registry = C_Component_Registry::get_instance();
@@ -336,7 +336,7 @@ if ( ! class_exists( 'EWWW_Nextgen' ) ) {
336
  ewww_image_optimizer_cloud_restore_from_meta_data( $image->pid, 'nextgen' );
337
  $success = $this->ewww_manage_image_custom_column( '', $image );
338
  ewwwio_ob_clean();
339
- wp_die( ewwwio_json_encode( array( 'success' => $success ) ) );
340
  }
341
 
342
  /**
@@ -419,24 +419,26 @@ if ( ! class_exists( 'EWWW_Nextgen' ) ) {
419
  function ewww_manage_image_custom_column( $column_name, $id ) {
420
  // Once we've found our custom column (newer versions will be blank).
421
  if ( 'ewww_image_optimizer' === $column_name || ! $column_name ) {
 
422
  // Creating the 'registry' object for working with nextgen.
423
  $registry = C_Component_Registry::get_instance();
424
  // Creating a database storage object from the 'registry' object.
425
  $storage = $registry->get_utility( 'I_Gallery_Storage' );
 
426
  if ( is_object( $id ) ) {
427
  $image = $id;
428
  } else {
429
  // Get an image object.
430
  $image = $storage->object->_image_mapper->find( $id );
431
  }
432
- $output = "<div id='ewww-nextgen-status-$image->pid'>";
433
  if ( ewww_image_optimizer_get_option( 'ewww_image_optimizer_debug' ) && ewww_image_optimizer_function_exists( 'print_r' ) ) {
434
  $print_meta = print_r( $image->meta_data, true );
435
  $print_meta = preg_replace( array( '/ /', '/\n+/' ), array( '&nbsp;', '<br />' ), esc_html( $print_meta ) );
436
- $debug_button = esc_html__( 'Show Metadata', 'ewww-image-optimizer' );
437
- $output .= "<button type='button' class='ewww-show-debug-meta button button-secondary' data-id='{$image->pid}' style='background-color:#a9c524;'>$debug_button</button><div id='ewww-debug-meta-{$image->pid}' style='font-size: 10px;padding: 10px;margin:3px -10px 10px;line-height: 1.1em;display: none;'>$print_meta</div>";
 
438
  }
439
- $msg = '';
440
  // Get the absolute path.
441
  $file_path = $storage->get_image_abspath( $image, 'full' );
442
  // Get the mimetype of the image.
@@ -473,11 +475,12 @@ if ( ! class_exists( 'EWWW_Nextgen' ) ) {
473
  $msg = '<div>' . esc_html__( 'Unsupported file type', 'ewww-image-optimizer' ) . '</div>';
474
  }
475
  // File isn't in a format we can work with, we don't work with strangers.
476
- if ( $msg ) {
477
  if ( is_object( $id ) ) {
478
  return $msg;
479
  } else {
480
- echo $msg;
 
481
  return;
482
  }
483
  }
@@ -504,21 +507,22 @@ if ( ! class_exists( 'EWWW_Nextgen' ) ) {
504
  $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 = 'nextgen' AND image_size <> 0 ORDER BY orig_size DESC", $image->pid ), ARRAY_A );
505
  if ( ! empty( $optimized_images ) ) {
506
  list( $detail_output, $converted, $backup_available ) = ewww_image_optimizer_custom_column_results( $image->pid, $optimized_images );
507
- $output .= $detail_output;
508
  // Display the optimization link with the appropriate text.
509
- $output .= $this->ewww_render_optimize_action_link( $image->pid, null, true, $backup_available );
510
  } elseif ( ewww_image_optimizer_image_is_pending( $image->pid, 'nextg-async' ) ) {
511
- $output .= esc_html( 'In Progress', 'ewww-image-optimizer' ) . '<br>';
512
  // Otherwise, give the image size, and a link to optimize right now.
513
  } else {
514
  // Display the optimization link with the appropriate text.
515
- $output .= '<br>' . $this->ewww_render_optimize_action_link( $image->pid, null, false, $backup_available );
 
516
  }
517
- $output .= '</div>';
518
  if ( is_object( $id ) ) {
519
- return $output;
520
  } else {
521
- echo $output;
522
  }
523
  } // End if().
524
  }
@@ -532,12 +536,12 @@ if ( ! class_exists( 'EWWW_Nextgen' ) ) {
532
  * @param object $image A nextgen image object.
533
  * @param bool $optimized Optional. True if the image has already been optimized. Default false.
534
  * @param bool $restorable Optional. True if the image can be restored via the API. Default false.
535
- * @return string The link HTML to display.
536
  */
537
  function ewww_render_optimize_action_link( $id, $image = null, $optimized = false, $restorable = false ) {
538
  if ( ! current_user_can( apply_filters( 'ewww_image_optimizer_manual_permissions', '' ) ) ) {
539
- return '';
540
  }
 
541
  if ( 'optimize' === $id && is_object( $image ) && ! empty( $image->pid ) ) {
542
  $id = $image->pid;
543
  global $wpdb;
@@ -548,29 +552,42 @@ if ( ! class_exists( 'EWWW_Nextgen' ) ) {
548
  }
549
  $ewww_manual_nonce = wp_create_nonce( 'ewww-manual-' . $id );
550
  if ( $optimized ) {
551
- $link = sprintf(
552
- '<a class="ewww-manual-optimize" data-id="%1$d" data-nonce="%2$s" href="' . admin_url( 'admin.php?action=ewww_ngg_manual' ) . '&amp;ewww_manual_nonce=%2$s&amp;ewww_force=1&amp;ewww_attachment_ID=%1$d">%3$s</a>',
553
- $id,
554
- $ewww_manual_nonce,
555
  esc_html__( 'Re-optimize', 'ewww-image-optimizer' )
556
  );
557
  if ( $restorable ) {
558
- $link .= sprintf(
559
- '<br><a class="ewww-manual-cloud-restore" data-id="%1$d" data-nonce="%2$s" href="' . admin_url( 'admin.php?action=ewww_ngg_cloud_restore' ) . '&amp;ewww_manual_nonce=%2$s&amp;ewww_attachment_ID=%1$d">%3$s</a>',
560
- $id,
561
- $ewww_manual_nonce,
562
  esc_html__( 'Restore original', 'ewww-image-optimizer' )
563
  );
564
  }
565
  } else {
566
- $link = sprintf(
567
- '<a class="ewww-manual-optimize" data-id="%1$d" data-nonce="%2$s" href="' . admin_url( 'admin.php?action=ewww_ngg_manual' ) . '&amp;ewww_manual_nonce=%2$s&amp;ewww_attachment_ID=%1$d">%3$s</a>',
568
- $id,
569
- $ewww_manual_nonce,
570
  esc_html__( 'Optimize now!', 'ewww-image-optimizer' )
571
  );
572
  }
573
- return $link;
 
 
 
 
 
 
 
 
 
 
 
 
 
574
  }
575
 
576
  /**
@@ -580,7 +597,7 @@ if ( ! class_exists( 'EWWW_Nextgen' ) ) {
580
  * @return array The updated list of actions.
581
  */
582
  function ewww_manage_images_row_actions( $actions ) {
583
- $actions['optimize'] = array( &$this, 'ewww_render_optimize_action_link' );
584
  return $actions;
585
  }
586
 
@@ -591,6 +608,9 @@ if ( ! class_exists( 'EWWW_Nextgen' ) ) {
591
  */
592
  function ewww_ngg_bulk_preview() {
593
  if ( ! empty( $_REQUEST['doaction'] ) ) {
 
 
 
594
  // If there is no requested bulk action, do nothing.
595
  if ( empty( $_REQUEST['bulkaction'] ) ) {
596
  return;
@@ -612,18 +632,18 @@ if ( ! class_exists( 'EWWW_Nextgen' ) ) {
612
  <?php
613
  if ( ewww_image_optimizer_get_option( 'ewww_image_optimizer_cloud_key' ) ) {
614
  ewww_image_optimizer_cloud_verify();
615
- 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' ) . ' ' . ewww_image_optimizer_cloud_quota() . '</a>';
616
  }
617
  // Retrieve the value of the 'bulk resume' option and set the button text for the form to use.
618
  $resume = get_option( 'ewww_image_optimizer_bulk_ngg_resume' );
619
  if ( empty( $resume ) ) {
620
- $button_text = esc_attr__( 'Start optimizing', 'ewww-image-optimizer' );
621
  } else {
622
- $button_text = esc_attr__( 'Resume previous optimization', 'ewww-image-optimizer' );
623
  }
624
  $delay = ewww_image_optimizer_get_option( 'ewww_image_optimizer_delay' ) ? ewww_image_optimizer_get_option( 'ewww_image_optimizer_delay' ) : 0;
625
  /* translators: 1-4: number(s) of images */
626
- $selected_images_text = sprintf( esc_html__( '%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 );
627
  ?>
628
  <div id="ewww-bulk-loading"></div>
629
  <div id="ewww-bulk-progressbar"></div>
@@ -655,14 +675,14 @@ if ( ! class_exists( 'EWWW_Nextgen' ) ) {
655
  </div>
656
  <form class="ewww-bulk-form">
657
  <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>
658
- <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 $delay; ?>"></p>
659
  <div id="ewww-delay-slider" style="width:50%"></div>
660
  </form>
661
  <div id="ewww-bulk-forms">
662
- <p class="ewww-bulk-info"><?php echo $selected_images_text; ?><br />
663
  <?php esc_html_e( 'Previously optimized images will be skipped by default.', 'ewww-image-optimizer' ); ?></p>
664
  <form id="ewww-bulk-start" class="ewww-bulk-form" method="post" action="">
665
- <input type="submit" class="button-primary action" value="<?php echo $button_text; ?>" />
666
  </form>
667
  <?php
668
  // If there is a previous bulk operation to resume, give the user the option to reset the resume flag.
@@ -680,7 +700,7 @@ if ( ! class_exists( 'EWWW_Nextgen' ) ) {
680
  if ( ewww_image_optimizer_get_option( 'ewww_image_optimizer_debug' ) ) {
681
  global $eio_debug;
682
  echo '<div style="clear:both;"></div>';
683
- echo '<p><strong>' . esc_html__( 'Debugging Information', 'ewww-image-optimizer' ) . ':</strong></p><div style="border:1px solid #e5e5e5;background:#fff;overflow:auto;height:300px;width:800px;">' . $eio_debug . '</div>';
684
  }
685
  echo '</div>';
686
  return;
@@ -711,25 +731,28 @@ if ( ! class_exists( 'EWWW_Nextgen' ) ) {
711
  function ewww_ngg_bulk_script( $hook ) {
712
  ewwwio_debug_message( '<b>' . __METHOD__ . '()</b>' );
713
  ewwwio_debug_message( $hook );
714
- /* if ( strpos( $hook, 'ewww-ngg-bulk' ) === false && strpos( $hook, 'nggallery-manage-gallery' ) === false ) { */
715
  if ( strpos( $hook, 'ewww-ngg-bulk' ) === false ) {
716
  return;
717
  }
 
 
 
 
 
 
 
 
 
718
  if ( ! empty( $_REQUEST['bulkaction'] ) && 'bulk_optimize' !== $_REQUEST['bulkaction'] ) {
719
  return;
720
  }
721
  if ( ! empty( $_REQUEST['doaction'] ) && ! is_array( $_REQUEST['doaction'] ) ) {
722
  return;
723
  }
724
- $images = null;
725
- // See if the user wants to reset the previous bulk status.
726
- if ( ! empty( $_REQUEST['ewww_reset'] ) && wp_verify_nonce( $_REQUEST['ewww_wpnonce'], 'ewww-image-optimizer-bulk-reset' ) ) {
727
- update_option( 'ewww_image_optimizer_bulk_ngg_resume', '' );
728
- }
729
  // See if there is a previous operation to resume.
730
  $resume = get_option( 'ewww_image_optimizer_bulk_ngg_resume' );
731
  // If we've been given a bulk action to perform.
732
- if ( ! empty( $_REQUEST['doaction'] ) ) {
733
  // If we are optimizing a specific group of images.
734
  if ( 'images' === $_REQUEST['bulk_type'] && 'bulk_optimize' === $_REQUEST['bulkaction'] ) {
735
  ewwwio_debug_message( 'detected bulk action from manage images' );
@@ -815,10 +838,10 @@ if ( ! class_exists( 'EWWW_Nextgen' ) ) {
815
  function ewww_ngg_bulk_init() {
816
  $permissions = apply_filters( 'ewww_image_optimizer_bulk_permissions', '' );
817
  $output = array();
818
- if ( ! wp_verify_nonce( $_REQUEST['ewww_wpnonce'], 'ewww-image-optimizer-bulk' ) || ! current_user_can( $permissions ) ) {
819
  $output['error'] = esc_html__( 'Access denied.', 'ewww-image-optimizer' );
820
  ewwwio_ob_clean();
821
- wp_die( ewwwio_json_encode( $output ) );
822
  }
823
  // Toggle the resume flag to indicate an operation is in progress.
824
  update_option( 'ewww_image_optimizer_bulk_ngg_resume', 'true' );
@@ -829,7 +852,7 @@ if ( ! class_exists( 'EWWW_Nextgen' ) ) {
829
  if ( ! is_array( $attachments ) ) {
830
  $output['error'] = esc_html__( 'Error retrieving list of images' );
831
  ewwwio_ob_clean();
832
- wp_die( ewwwio_json_encode( $output ) );
833
  }
834
  $id = array_shift( $attachments );
835
  $file = $this->ewww_ngg_bulk_filename( $id );
@@ -840,7 +863,7 @@ if ( ! class_exists( 'EWWW_Nextgen' ) ) {
840
  $output['results'] = '<p>' . esc_html__( 'Optimizing', 'ewww-image-optimizer' ) . " <b>$file</b>&nbsp;<img src='$loading_image' alt='loading'/></p>";
841
  }
842
  ewwwio_ob_clean();
843
- wp_die( ewwwio_json_encode( $output ) );
844
  }
845
 
846
  /**
@@ -875,14 +898,14 @@ if ( ! class_exists( 'EWWW_Nextgen' ) ) {
875
  $ewww_defer = false;
876
  $output = array();
877
  $permissions = apply_filters( 'ewww_image_optimizer_bulk_permissions', '' );
878
- if ( ! wp_verify_nonce( $_REQUEST['ewww_wpnonce'], 'ewww-image-optimizer-bulk' ) || ! current_user_can( $permissions ) ) {
879
  $output['error'] = esc_html__( 'Access token has expired, please reload the page.', 'ewww-image-optimizer' );
880
  ewwwio_ob_clean();
881
- wp_die( ewwwio_json_encode( $output ) );
882
  }
883
  session_write_close();
884
  // Find out if our nonce is on it's last leg/tick.
885
- $tick = wp_verify_nonce( $_REQUEST['ewww_wpnonce'], 'ewww-image-optimizer-bulk' );
886
  if ( 2 === $tick ) {
887
  $output['new_nonce'] = wp_create_nonce( 'ewww-image-optimizer-bulk' );
888
  } else {
@@ -904,7 +927,7 @@ if ( ! class_exists( 'EWWW_Nextgen' ) ) {
904
  if ( ! empty( $ewww_status ) && preg_match( '/exceeded/', $ewww_status ) ) {
905
  $output['error'] = esc_html__( 'License Exceeded', 'ewww-image-optimizer' );
906
  ewwwio_ob_clean();
907
- wp_die( ewwwio_json_encode( $output ) );
908
  }
909
  // Output the results of the optimization.
910
  $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' ) ) ) );
@@ -948,7 +971,7 @@ if ( ! class_exists( 'EWWW_Nextgen' ) ) {
948
  $output['done'] = 1;
949
  }
950
  ewwwio_ob_clean();
951
- wp_die( ewwwio_json_encode( $output ) );
952
  }
953
 
954
  /**
@@ -956,7 +979,7 @@ if ( ! class_exists( 'EWWW_Nextgen' ) ) {
956
  */
957
  function ewww_ngg_bulk_cleanup() {
958
  $permissions = apply_filters( 'ewww_image_optimizer_bulk_permissions', '' );
959
- if ( ! wp_verify_nonce( $_REQUEST['ewww_wpnonce'], 'ewww-image-optimizer-bulk' ) || ! current_user_can( $permissions ) ) {
960
  ewwwio_ob_clean();
961
  wp_die( esc_html__( 'Access token has expired, please reload the page.', 'ewww-image-optimizer' ) );
962
  }
@@ -989,6 +1012,9 @@ if ( ! class_exists( 'EWWW_Nextgen' ) ) {
989
  */
990
  function ewww_ngg_bulk_action_handler() {
991
  ewwwio_debug_message( '<b>' . __METHOD__ . '()</b>' );
 
 
 
992
  // If the requested page is blank, or not a bulk_optimize, do nothing.
993
  if ( empty( $_REQUEST['nggpage'] ) || empty( $_REQUEST['bulkaction'] ) || 'bulk_optimize' !== $_REQUEST['bulkaction'] ) {
994
  return;
@@ -1006,18 +1032,14 @@ if ( ! class_exists( 'EWWW_Nextgen' ) ) {
1006
  if ( 'manage-galleries' === $_REQUEST['nggpage'] ) {
1007
  $type = 'galleries';
1008
  }
1009
- if ( ! wp_verify_nonce( $_REQUEST['_wpnonce'], 'ngg_bulkgallery' ) ) {
1010
- ewwwio_ob_clean();
1011
- wp_die( esc_html__( 'Access token has expired, please reload the page.', 'ewww-image-optimizer' ) );
1012
- }
1013
- wp_redirect(
1014
  add_query_arg(
1015
  array(
1016
  'page' => 'ewww-ngg-bulk',
1017
- '_wpnonce' => urlencode( $_REQUEST['_wpnonce'] ),
1018
  'bulk_type' => $type,
1019
  'bulkaction' => 'bulk_optimize',
1020
- 'doaction' => urlencode( $_REQUEST['doaction'] ),
1021
  ),
1022
  admin_url( 'admin.php' )
1023
  )
@@ -1031,7 +1053,7 @@ if ( ! class_exists( 'EWWW_Nextgen' ) ) {
1031
  $ewwwngg = new EWWW_Nextgen();
1032
  } // End if().
1033
 
1034
- if ( ! empty( $_REQUEST['page'] ) && 'ngg_other_options' !== $_REQUEST['page'] && ! class_exists( 'EWWWIO_Gallery_Storage' ) && class_exists( 'Mixin' ) && class_exists( 'C_Gallery_Storage' ) ) {
1035
  /**
1036
  * Extension for NextGEN image generation.
1037
  */
255
  wp_die( esc_html__( 'You do not have permission to optimize images.', 'ewww-image-optimizer' ) );
256
  }
257
  ewwwio_ob_clean();
258
+ wp_die( wp_json_encode( array( 'error' => esc_html__( 'You do not have permission to optimize images.', 'ewww-image-optimizer' ) ) ) );
259
  }
260
  // Make sure function wasn't called without an attachment to work with.
261
  if ( false === isset( $_REQUEST['ewww_attachment_ID'] ) ) {
263
  wp_die( esc_html__( 'No attachment ID was provided.', 'ewww-image-optimizer' ) );
264
  }
265
  ewwwio_ob_clean();
266
+ wp_die( wp_json_encode( array( 'error' => esc_html__( 'No attachment ID was provided.', 'ewww-image-optimizer' ) ) ) );
267
  }
268
  // Sanitize the attachment $id.
269
+ $id = (int) $_REQUEST['ewww_attachment_ID'];
270
+ if ( empty( $_REQUEST['ewww_manual_nonce'] ) || ! wp_verify_nonce( sanitize_key( $_REQUEST['ewww_manual_nonce'] ), "ewww-manual-$id" ) ) {
271
  if ( ! wp_doing_ajax() ) {
272
  wp_die( esc_html__( 'Access denied.', 'ewww-image-optimizer' ) );
273
  }
274
  ewwwio_ob_clean();
275
+ wp_die( wp_json_encode( array( 'error' => esc_html__( 'Access denied.', 'ewww-image-optimizer' ) ) ) );
276
  }
277
+ global $ewww_force;
278
+ $ewww_force = ! empty( $_REQUEST['ewww_force'] ) ? true : false;
279
  // Creating the 'registry' object for working with nextgen.
280
  $registry = C_Component_Registry::get_instance();
281
  // Creating a database storage object from the 'registry' object.
286
  $success = $this->ewww_manage_image_custom_column( '', $image );
287
  if ( get_transient( 'ewww_image_optimizer_cloud_status' ) === 'exceeded' || ewww_image_optimizer_get_option( 'ewww_image_optimizer_cloud_exceeded' ) > time() ) {
288
  ewwwio_ob_clean();
289
+ wp_die( wp_json_encode( array( 'error' => esc_html__( 'License exceeded', 'ewww-image-optimizer' ) ) ) );
290
  }
291
  if ( ! wp_doing_ajax() ) {
292
  // Get the referring page, and send the user back there.
293
+ wp_safe_redirect( wp_get_referer() );
 
 
294
  die;
295
  }
296
  ewwwio_ob_clean();
297
+ wp_die( wp_json_encode( array( 'success' => $success ) ) );
298
  }
299
 
300
  /**
308
  wp_die( esc_html__( 'You do not have permission to optimize images.', 'ewww-image-optimizer' ) );
309
  }
310
  ewwwio_ob_clean();
311
+ wp_die( wp_json_encode( array( 'error' => esc_html__( 'You do not have permission to optimize images.', 'ewww-image-optimizer' ) ) ) );
312
  }
313
  // Make sure function wasn't called without an attachment to work with.
314
  if ( false === isset( $_REQUEST['ewww_attachment_ID'] ) ) {
316
  wp_die( esc_html__( 'No attachment ID was provided.', 'ewww-image-optimizer' ) );
317
  }
318
  ewwwio_ob_clean();
319
+ wp_die( wp_json_encode( array( 'error' => esc_html__( 'No attachment ID was provided.', 'ewww-image-optimizer' ) ) ) );
320
  }
321
  // Sanitize the attachment $id.
322
  $id = intval( $_REQUEST['ewww_attachment_ID'] );
323
+ if ( empty( $_REQUEST['ewww_manual_nonce'] ) || ! wp_verify_nonce( sanitize_key( $_REQUEST['ewww_manual_nonce'] ), "ewww-manual-$id" ) ) {
324
  if ( ! wp_doing_ajax() ) {
325
  wp_die( esc_html__( 'Access denied.', 'ewww-image-optimizer' ) );
326
  }
327
  ewwwio_ob_clean();
328
+ wp_die( wp_json_encode( array( 'error' => esc_html__( 'Access denied.', 'ewww-image-optimizer' ) ) ) );
329
  }
330
  // Creating the 'registry' object for working with nextgen.
331
  $registry = C_Component_Registry::get_instance();
336
  ewww_image_optimizer_cloud_restore_from_meta_data( $image->pid, 'nextgen' );
337
  $success = $this->ewww_manage_image_custom_column( '', $image );
338
  ewwwio_ob_clean();
339
+ wp_die( wp_json_encode( array( 'success' => $success ) ) );
340
  }
341
 
342
  /**
419
  function ewww_manage_image_custom_column( $column_name, $id ) {
420
  // Once we've found our custom column (newer versions will be blank).
421
  if ( 'ewww_image_optimizer' === $column_name || ! $column_name ) {
422
+ ewwwio_debug_message( '<b>' . __METHOD__ . '()</b>' );
423
  // Creating the 'registry' object for working with nextgen.
424
  $registry = C_Component_Registry::get_instance();
425
  // Creating a database storage object from the 'registry' object.
426
  $storage = $registry->get_utility( 'I_Gallery_Storage' );
427
+ ob_start();
428
  if ( is_object( $id ) ) {
429
  $image = $id;
430
  } else {
431
  // Get an image object.
432
  $image = $storage->object->_image_mapper->find( $id );
433
  }
434
+ echo '<div id="ewww-nextgen-status-' . (int) $image->pid . '">';
435
  if ( ewww_image_optimizer_get_option( 'ewww_image_optimizer_debug' ) && ewww_image_optimizer_function_exists( 'print_r' ) ) {
436
  $print_meta = print_r( $image->meta_data, true );
437
  $print_meta = preg_replace( array( '/ /', '/\n+/' ), array( '&nbsp;', '<br />' ), esc_html( $print_meta ) );
438
+ $debug_button = __( 'Show Metadata', 'ewww-image-optimizer' );
439
+ echo "<button type='button' class='ewww-show-debug-meta button button-secondary' data-id='" . (int) $image->pid . "' style='background-color:#a9c524;'>" . esc_html( $debug_button ) . '</button>' .
440
+ "<div id='ewww-debug-meta-" . (int) $image->pid . "' style='font-size: 10px;padding: 10px;margin:3px -10px 10px;line-height: 1.1em;display: none;'>" . wp_kses_post( $print_meta ) . '</div>';
441
  }
 
442
  // Get the absolute path.
443
  $file_path = $storage->get_image_abspath( $image, 'full' );
444
  // Get the mimetype of the image.
475
  $msg = '<div>' . esc_html__( 'Unsupported file type', 'ewww-image-optimizer' ) . '</div>';
476
  }
477
  // File isn't in a format we can work with, we don't work with strangers.
478
+ if ( ! empty( $msg ) ) {
479
  if ( is_object( $id ) ) {
480
  return $msg;
481
  } else {
482
+ ob_end_clean();
483
+ echo wp_kses_post( $msg );
484
  return;
485
  }
486
  }
507
  $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 = 'nextgen' AND image_size <> 0 ORDER BY orig_size DESC", $image->pid ), ARRAY_A );
508
  if ( ! empty( $optimized_images ) ) {
509
  list( $detail_output, $converted, $backup_available ) = ewww_image_optimizer_custom_column_results( $image->pid, $optimized_images );
510
+ echo wp_kses_post( $detail_output );
511
  // Display the optimization link with the appropriate text.
512
+ $this->ewww_render_optimize_action_link( $image->pid, null, true, $backup_available );
513
  } elseif ( ewww_image_optimizer_image_is_pending( $image->pid, 'nextg-async' ) ) {
514
+ echo '<div>' . esc_html__( 'In Progress', 'ewww-image-optimizer' ) . '</div>';
515
  // Otherwise, give the image size, and a link to optimize right now.
516
  } else {
517
  // Display the optimization link with the appropriate text.
518
+ echo '<br>';
519
+ $this->ewww_render_optimize_action_link( $image->pid, null, false, $backup_available );
520
  }
521
+ echo '</div>';
522
  if ( is_object( $id ) ) {
523
+ return ob_get_clean();
524
  } else {
525
+ ob_end_flush();
526
  }
527
  } // End if().
528
  }
536
  * @param object $image A nextgen image object.
537
  * @param bool $optimized Optional. True if the image has already been optimized. Default false.
538
  * @param bool $restorable Optional. True if the image can be restored via the API. Default false.
 
539
  */
540
  function ewww_render_optimize_action_link( $id, $image = null, $optimized = false, $restorable = false ) {
541
  if ( ! current_user_can( apply_filters( 'ewww_image_optimizer_manual_permissions', '' ) ) ) {
542
+ return;
543
  }
544
+ ewwwio_debug_message( '<b>' . __METHOD__ . '()</b>' );
545
  if ( 'optimize' === $id && is_object( $image ) && ! empty( $image->pid ) ) {
546
  $id = $image->pid;
547
  global $wpdb;
552
  }
553
  $ewww_manual_nonce = wp_create_nonce( 'ewww-manual-' . $id );
554
  if ( $optimized ) {
555
+ printf(
556
+ '<a class="ewww-manual-optimize" data-id="%1$d" data-nonce="%2$s" href="' . esc_url( admin_url( 'admin.php?action=ewww_ngg_manual' ) ) . '&amp;ewww_manual_nonce=%2$s&amp;ewww_force=1&amp;ewww_attachment_ID=%1$d">%3$s</a>',
557
+ (int) $id,
558
+ esc_attr( $ewww_manual_nonce ),
559
  esc_html__( 'Re-optimize', 'ewww-image-optimizer' )
560
  );
561
  if ( $restorable ) {
562
+ printf(
563
+ '<br><a class="ewww-manual-cloud-restore" data-id="%1$d" data-nonce="%2$s" href="' . esc_url( admin_url( 'admin.php?action=ewww_ngg_cloud_restore' ) ) . '&amp;ewww_manual_nonce=%2$s&amp;ewww_attachment_ID=%1$d">%3$s</a>',
564
+ (int) $id,
565
+ esc_attr( $ewww_manual_nonce ),
566
  esc_html__( 'Restore original', 'ewww-image-optimizer' )
567
  );
568
  }
569
  } else {
570
+ printf(
571
+ '<a class="ewww-manual-optimize" data-id="%1$d" data-nonce="%2$s" href="' . esc_url( admin_url( 'admin.php?action=ewww_ngg_manual' ) ) . '&amp;ewww_manual_nonce=%2$s&amp;ewww_attachment_ID=%1$d">%3$s</a>',
572
+ (int) $id,
573
+ esc_attr( $ewww_manual_nonce ),
574
  esc_html__( 'Optimize now!', 'ewww-image-optimizer' )
575
  );
576
  }
577
+ }
578
+
579
+ /**
580
+ * Capture the output for the action link(s).
581
+ *
582
+ * @param int|string $id The ID number of the nextgen image, or the string 'optimize'.
583
+ * @param object $image A nextgen image object.
584
+ * @return string The output from the action_link function.
585
+ */
586
+ function ewww_render_optimize_action_link_capture( $id, $image = null ) {
587
+ ewwwio_debug_message( '<b>' . __METHOD__ . '()</b>' );
588
+ ob_start();
589
+ $this->ewww_render_optimize_action_link( $id, $image, false, false );
590
+ return ob_get_clean();
591
  }
592
 
593
  /**
597
  * @return array The updated list of actions.
598
  */
599
  function ewww_manage_images_row_actions( $actions ) {
600
+ $actions['optimize'] = array( &$this, 'ewww_render_optimize_action_link_capture' );
601
  return $actions;
602
  }
603
 
608
  */
609
  function ewww_ngg_bulk_preview() {
610
  if ( ! empty( $_REQUEST['doaction'] ) ) {
611
+ if ( empty( $_REQUEST['_wpnonce'] ) || ! wp_verify_nonce( sanitize_key( $_REQUEST['_wpnonce'] ), 'ngg_bulkgallery' ) ) {
612
+ return;
613
+ }
614
  // If there is no requested bulk action, do nothing.
615
  if ( empty( $_REQUEST['bulkaction'] ) ) {
616
  return;
632
  <?php
633
  if ( ewww_image_optimizer_get_option( 'ewww_image_optimizer_cloud_key' ) ) {
634
  ewww_image_optimizer_cloud_verify();
635
+ 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>';
636
  }
637
  // Retrieve the value of the 'bulk resume' option and set the button text for the form to use.
638
  $resume = get_option( 'ewww_image_optimizer_bulk_ngg_resume' );
639
  if ( empty( $resume ) ) {
640
+ $button_text = __( 'Start optimizing', 'ewww-image-optimizer' );
641
  } else {
642
+ $button_text = __( 'Resume previous optimization', 'ewww-image-optimizer' );
643
  }
644
  $delay = ewww_image_optimizer_get_option( 'ewww_image_optimizer_delay' ) ? ewww_image_optimizer_get_option( 'ewww_image_optimizer_delay' ) : 0;
645
  /* translators: 1-4: number(s) of images */
646
+ $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 );
647
  ?>
648
  <div id="ewww-bulk-loading"></div>
649
  <div id="ewww-bulk-progressbar"></div>
675
  </div>
676
  <form class="ewww-bulk-form">
677
  <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>
678
+ <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>
679
  <div id="ewww-delay-slider" style="width:50%"></div>
680
  </form>
681
  <div id="ewww-bulk-forms">
682
+ <p class="ewww-bulk-info"><?php echo esc_html( $selected_images_text ); ?><br />
683
  <?php esc_html_e( 'Previously optimized images will be skipped by default.', 'ewww-image-optimizer' ); ?></p>
684
  <form id="ewww-bulk-start" class="ewww-bulk-form" method="post" action="">
685
+ <input type="submit" class="button-primary action" value="<?php echo esc_attr( $button_text ); ?>" />
686
  </form>
687
  <?php
688
  // If there is a previous bulk operation to resume, give the user the option to reset the resume flag.
700
  if ( ewww_image_optimizer_get_option( 'ewww_image_optimizer_debug' ) ) {
701
  global $eio_debug;
702
  echo '<div style="clear:both;"></div>';
703
+ echo '<p><strong>' . esc_html__( 'Debugging Information', 'ewww-image-optimizer' ) . ':</strong></p><div style="border:1px solid #e5e5e5;background:#fff;overflow:auto;height:300px;width:800px;">' . wp_kses_post( $eio_debug ) . '</div>';
704
  }
705
  echo '</div>';
706
  return;
731
  function ewww_ngg_bulk_script( $hook ) {
732
  ewwwio_debug_message( '<b>' . __METHOD__ . '()</b>' );
733
  ewwwio_debug_message( $hook );
 
734
  if ( strpos( $hook, 'ewww-ngg-bulk' ) === false ) {
735
  return;
736
  }
737
+ $images = null;
738
+ // See if the user wants to reset the previous bulk status.
739
+ if (
740
+ ! empty( $_REQUEST['ewww_reset'] ) &&
741
+ ! empty( $_REQUEST['ewww_wpnonce'] ) &&
742
+ wp_verify_nonce( sanitize_key( $_REQUEST['ewww_wpnonce'] ), 'ewww-image-optimizer-bulk-reset' )
743
+ ) {
744
+ update_option( 'ewww_image_optimizer_bulk_ngg_resume', '' );
745
+ }
746
  if ( ! empty( $_REQUEST['bulkaction'] ) && 'bulk_optimize' !== $_REQUEST['bulkaction'] ) {
747
  return;
748
  }
749
  if ( ! empty( $_REQUEST['doaction'] ) && ! is_array( $_REQUEST['doaction'] ) ) {
750
  return;
751
  }
 
 
 
 
 
752
  // See if there is a previous operation to resume.
753
  $resume = get_option( 'ewww_image_optimizer_bulk_ngg_resume' );
754
  // If we've been given a bulk action to perform.
755
+ if ( ! empty( $_REQUEST['doaction'] ) && ! empty( $_REQUEST['bulkaction'] ) && ! empty( $_REQUEST['bulk_type'] ) ) {
756
  // If we are optimizing a specific group of images.
757
  if ( 'images' === $_REQUEST['bulk_type'] && 'bulk_optimize' === $_REQUEST['bulkaction'] ) {
758
  ewwwio_debug_message( 'detected bulk action from manage images' );
838
  function ewww_ngg_bulk_init() {
839
  $permissions = apply_filters( 'ewww_image_optimizer_bulk_permissions', '' );
840
  $output = array();
841
+ if ( empty( $_REQUEST['ewww_wpnonce'] ) && ! wp_verify_nonce( sanitize_key( $_REQUEST['ewww_wpnonce'] ), 'ewww-image-optimizer-bulk' ) || ! current_user_can( $permissions ) ) {
842
  $output['error'] = esc_html__( 'Access denied.', 'ewww-image-optimizer' );
843
  ewwwio_ob_clean();
844
+ wp_die( wp_json_encode( $output ) );
845
  }
846
  // Toggle the resume flag to indicate an operation is in progress.
847
  update_option( 'ewww_image_optimizer_bulk_ngg_resume', 'true' );
852
  if ( ! is_array( $attachments ) ) {
853
  $output['error'] = esc_html__( 'Error retrieving list of images' );
854
  ewwwio_ob_clean();
855
+ wp_die( wp_json_encode( $output ) );
856
  }
857
  $id = array_shift( $attachments );
858
  $file = $this->ewww_ngg_bulk_filename( $id );
863
  $output['results'] = '<p>' . esc_html__( 'Optimizing', 'ewww-image-optimizer' ) . " <b>$file</b>&nbsp;<img src='$loading_image' alt='loading'/></p>";
864
  }
865
  ewwwio_ob_clean();
866
+ wp_die( wp_json_encode( $output ) );
867
  }
868
 
869
  /**
898
  $ewww_defer = false;
899
  $output = array();
900
  $permissions = apply_filters( 'ewww_image_optimizer_bulk_permissions', '' );
901
+ if ( empty( $_REQUEST['ewww_wpnonce'] ) || ! wp_verify_nonce( sanitize_key( $_REQUEST['ewww_wpnonce'] ), 'ewww-image-optimizer-bulk' ) || ! current_user_can( $permissions ) ) {
902
  $output['error'] = esc_html__( 'Access token has expired, please reload the page.', 'ewww-image-optimizer' );
903
  ewwwio_ob_clean();
904
+ wp_die( wp_json_encode( $output ) );
905
  }
906
  session_write_close();
907
  // Find out if our nonce is on it's last leg/tick.
908
+ $tick = wp_verify_nonce( sanitize_key( $_REQUEST['ewww_wpnonce'] ), 'ewww-image-optimizer-bulk' );
909
  if ( 2 === $tick ) {
910
  $output['new_nonce'] = wp_create_nonce( 'ewww-image-optimizer-bulk' );
911
  } else {
927
  if ( ! empty( $ewww_status ) && preg_match( '/exceeded/', $ewww_status ) ) {
928
  $output['error'] = esc_html__( 'License Exceeded', 'ewww-image-optimizer' );
929
  ewwwio_ob_clean();
930
+ wp_die( wp_json_encode( $output ) );
931
  }
932
  // Output the results of the optimization.
933
  $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' ) ) ) );
971
  $output['done'] = 1;
972
  }
973
  ewwwio_ob_clean();
974
+ wp_die( wp_json_encode( $output ) );
975
  }
976
 
977
  /**
979
  */
980
  function ewww_ngg_bulk_cleanup() {
981
  $permissions = apply_filters( 'ewww_image_optimizer_bulk_permissions', '' );
982
+ if ( empty( $_REQUEST['ewww_wpnonce'] ) || ! wp_verify_nonce( sanitize_key( $_REQUEST['ewww_wpnonce'] ), 'ewww-image-optimizer-bulk' ) || ! current_user_can( $permissions ) ) {
983
  ewwwio_ob_clean();
984
  wp_die( esc_html__( 'Access token has expired, please reload the page.', 'ewww-image-optimizer' ) );
985
  }
1012
  */
1013
  function ewww_ngg_bulk_action_handler() {
1014
  ewwwio_debug_message( '<b>' . __METHOD__ . '()</b>' );
1015
+ if ( empty( $_REQUEST['_wpnonce'] ) || ! wp_verify_nonce( sanitize_key( $_REQUEST['_wpnonce'] ), 'ngg_bulkgallery' ) ) {
1016
+ return;
1017
+ }
1018
  // If the requested page is blank, or not a bulk_optimize, do nothing.
1019
  if ( empty( $_REQUEST['nggpage'] ) || empty( $_REQUEST['bulkaction'] ) || 'bulk_optimize' !== $_REQUEST['bulkaction'] ) {
1020
  return;
1032
  if ( 'manage-galleries' === $_REQUEST['nggpage'] ) {
1033
  $type = 'galleries';
1034
  }
1035
+ wp_safe_redirect(
 
 
 
 
1036
  add_query_arg(
1037
  array(
1038
  'page' => 'ewww-ngg-bulk',
1039
+ '_wpnonce' => sanitize_key( $_REQUEST['_wpnonce'] ),
1040
  'bulk_type' => $type,
1041
  'bulkaction' => 'bulk_optimize',
1042
+ 'doaction' => sanitize_key( $_REQUEST['doaction'] ),
1043
  ),
1044
  admin_url( 'admin.php' )
1045
  )
1053
  $ewwwngg = new EWWW_Nextgen();
1054
  } // End if().
1055
 
1056
+ if ( ! empty( $_REQUEST['page'] ) && 'ngg_other_options' !== $_REQUEST['page'] && ! class_exists( 'EWWWIO_Gallery_Storage' ) && class_exists( 'Mixin' ) && class_exists( 'C_Gallery_Storage' ) ) { // phpcs:ignore WordPress.Security.NonceVerification
1057
  /**
1058
  * Extension for NextGEN image generation.
1059
  */
classes/class-ewwwio-cli.php CHANGED
@@ -69,6 +69,8 @@ class EWWWIO_CLI extends WP_CLI_Command {
69
  if ( ! empty( $assoc_args['force'] ) ) {
70
  WP_CLI::line( __( 'Forcing re-optimization of previously processed images.', 'ewww-image-optimizer' ) );
71
  $_REQUEST['ewww_force'] = true;
 
 
72
  }
73
  /* translators: 1: type of images, like media, or nextgen 2: number of seconds */
74
  WP_CLI::line( sprintf( _x( 'Optimizing %1$s with a %2$d second pause between images.', 'string will be something like "media" or "nextgen"', 'ewww-image-optimizer' ), $library, $delay ) );
69
  if ( ! empty( $assoc_args['force'] ) ) {
70
  WP_CLI::line( __( 'Forcing re-optimization of previously processed images.', 'ewww-image-optimizer' ) );
71
  $_REQUEST['ewww_force'] = true;
72
+ global $ewww_force;
73
+ $ewww_force = 1;
74
  }
75
  /* translators: 1: type of images, like media, or nextgen 2: number of seconds */
76
  WP_CLI::line( sprintf( _x( 'Optimizing %1$s with a %2$d second pause between images.', 'string will be something like "media" or "nextgen"', 'ewww-image-optimizer' ), $library, $delay ) );
classes/class-ewwwio-gd-editor.php CHANGED
@@ -562,7 +562,7 @@ if ( class_exists( 'Bbpp_Animated_Gif' ) ) {
562
  if ( is_writable( $filename ) ) {
563
  $stat = stat( dirname( $filename ) );
564
  $perms = $stat['mode'] & 0000666; // Same permissions as parent folder with executable bits stripped.
565
- chmod( $filename, $perms );
566
  }
567
  ewwwio_memory( __METHOD__ );
568
  return array(
562
  if ( is_writable( $filename ) ) {
563
  $stat = stat( dirname( $filename ) );
564
  $perms = $stat['mode'] & 0000666; // Same permissions as parent folder with executable bits stripped.
565
+ ewwwio_chmod( $filename, $perms );
566
  }
567
  ewwwio_memory( __METHOD__ );
568
  return array(
classes/class-ewwwio-imagick-editor.php CHANGED
@@ -559,7 +559,7 @@ if ( class_exists( 'WP_Thumb_Image_Editor_Imagick' ) ) {
559
  if ( is_writable( $filename ) ) {
560
  $stat = stat( dirname( $filename ) );
561
  $perms = $stat['mode'] & 0000666; // Same permissions as parent folder with executable bits stripped.
562
- chmod( $filename, $perms );
563
  }
564
  ewwwio_memory( __FUNCTION__ );
565
  return array(
559
  if ( is_writable( $filename ) ) {
560
  $stat = stat( dirname( $filename ) );
561
  $perms = $stat['mode'] & 0000666; // Same permissions as parent folder with executable bits stripped.
562
+ ewwwio_chmod( $filename, $perms );
563
  }
564
  ewwwio_memory( __FUNCTION__ );
565
  return array(
classes/class-ewwwio-install-cloud.php CHANGED
@@ -118,14 +118,14 @@ class EWWWIO_Install_Cloud {
118
  } else {
119
  $redirect_url = admin_url( 'plugins.php?ewwwio_cloud_activated=1' );
120
  }
121
- wp_redirect( $redirect_url );
122
  exit( 0 );
123
  } else {
124
- wp_redirect( admin_url( 'plugins.php' ) );
125
  exit( 0 );
126
  }
127
  }
128
- wp_redirect( admin_url( 'plugins.php' ) );
129
  exit( 0 );
130
  }
131
 
118
  } else {
119
  $redirect_url = admin_url( 'plugins.php?ewwwio_cloud_activated=1' );
120
  }
121
+ wp_safe_redirect( $redirect_url );
122
  exit( 0 );
123
  } else {
124
+ wp_safe_redirect( admin_url( 'plugins.php' ) );
125
  exit( 0 );
126
  }
127
  }
128
+ wp_safe_redirect( admin_url( 'plugins.php' ) );
129
  exit( 0 );
130
  }
131
 
classes/class-ewwwio-media-background-process.php CHANGED
@@ -516,10 +516,11 @@ class EWWWIO_Async_Request extends WP_Async_Request {
516
  protected function handle() {
517
  session_write_close();
518
  ewwwio_debug_message( '<b>' . __METHOD__ . '()</b>' );
 
519
  if ( empty( $_POST['ewwwio_size'] ) ) {
520
  $size = '';
521
  } else {
522
- $size = $_POST['ewwwio_size'];
523
  }
524
  if ( empty( $_POST['ewwwio_attachment_id'] ) ) {
525
  $id = 0;
@@ -529,8 +530,9 @@ class EWWWIO_Async_Request extends WP_Async_Request {
529
  if ( empty( $_POST['ewwwio_id'] ) ) {
530
  return;
531
  }
 
532
  global $ewww_image;
533
- $file_path = ewww_image_optimizer_find_file_by_id( $_POST['ewwwio_id'] );
534
  if ( $file_path && 'full' === $size ) {
535
  ewwwio_debug_message( "processing async optimization request for $file_path" );
536
  $ewww_image = new EWWW_Image( $id, 'media', $file_path );
@@ -544,8 +546,8 @@ class EWWWIO_Async_Request extends WP_Async_Request {
544
 
545
  list( $file, $msg, $conv, $original ) = ewww_image_optimizer( $file_path );
546
  } else {
547
- if ( ! empty( $_POST['ewwwio_id'] ) && ! $file_path ) {
548
- ewwwio_debug_message( "could not find file to process async optimization request for {$_POST['ewwwio_id']}" );
549
  } else {
550
  ewwwio_debug_message( 'ignored async optimization request' );
551
  }
@@ -584,6 +586,9 @@ class EWWWIO_Scan_Async_Handler extends WP_Async_Request {
584
  protected function handle() {
585
  session_write_close();
586
  ewwwio_debug_message( '<b>' . __METHOD__ . '()</b>' );
 
 
 
587
  ewww_image_optimizer_aux_images_script( 'ewww-image-optimizer-auto' );
588
  }
589
  }
@@ -614,6 +619,8 @@ class EWWWIO_Async_Key_Verification extends WP_Async_Request {
614
  */
615
  protected function handle() {
616
  session_write_close();
 
 
617
  ewww_image_optimizer_cloud_verify( false );
618
  }
619
  }
@@ -648,10 +655,12 @@ class EWWWIO_Test_Async_Handler extends WP_Async_Request {
648
  */
649
  protected function handle() {
650
  session_write_close();
 
 
651
  if ( empty( $_POST['ewwwio_test_verify'] ) ) {
652
  return;
653
  }
654
- $item = $_POST['ewwwio_test_verify'];
655
  ewwwio_debug_message( "testing async handling, received $item" );
656
  if ( ewww_image_optimizer_detect_wpsf_location_lock() ) {
657
  ewwwio_debug_message( 'detected location lock, not enabling background opt' );
516
  protected function handle() {
517
  session_write_close();
518
  ewwwio_debug_message( '<b>' . __METHOD__ . '()</b>' );
519
+ check_ajax_referer( $this->identifier, 'nonce' );
520
  if ( empty( $_POST['ewwwio_size'] ) ) {
521
  $size = '';
522
  } else {
523
+ $size = sanitize_key( $_POST['ewwwio_size'] );
524
  }
525
  if ( empty( $_POST['ewwwio_attachment_id'] ) ) {
526
  $id = 0;
530
  if ( empty( $_POST['ewwwio_id'] ) ) {
531
  return;
532
  }
533
+ $ewwwio_id = (int) $_POST['ewwwio_id'];
534
  global $ewww_image;
535
+ $file_path = ewww_image_optimizer_find_file_by_id( $ewwwio_id );
536
  if ( $file_path && 'full' === $size ) {
537
  ewwwio_debug_message( "processing async optimization request for $file_path" );
538
  $ewww_image = new EWWW_Image( $id, 'media', $file_path );
546
 
547
  list( $file, $msg, $conv, $original ) = ewww_image_optimizer( $file_path );
548
  } else {
549
+ if ( $ewwwio_id && ! $file_path ) {
550
+ ewwwio_debug_message( "could not find file to process async optimization request for $ewwwio_id" );
551
  } else {
552
  ewwwio_debug_message( 'ignored async optimization request' );
553
  }
586
  protected function handle() {
587
  session_write_close();
588
  ewwwio_debug_message( '<b>' . __METHOD__ . '()</b>' );
589
+ check_ajax_referer( $this->identifier, 'nonce' );
590
+ global $ewww_scan;
591
+ $ewww_scan = empty( $_REQUEST['ewww_scan'] ) ? '' : sanitize_key( $_REQUEST['ewww_scan'] );
592
  ewww_image_optimizer_aux_images_script( 'ewww-image-optimizer-auto' );
593
  }
594
  }
619
  */
620
  protected function handle() {
621
  session_write_close();
622
+ ewwwio_debug_message( '<b>' . __METHOD__ . '()</b>' );
623
+ check_ajax_referer( $this->identifier, 'nonce' );
624
  ewww_image_optimizer_cloud_verify( false );
625
  }
626
  }
655
  */
656
  protected function handle() {
657
  session_write_close();
658
+ ewwwio_debug_message( '<b>' . __METHOD__ . '()</b>' );
659
+ check_ajax_referer( $this->identifier, 'nonce' );
660
  if ( empty( $_POST['ewwwio_test_verify'] ) ) {
661
  return;
662
  }
663
+ $item = sanitize_key( $_POST['ewwwio_test_verify'] );
664
  ewwwio_debug_message( "testing async handling, received $item" );
665
  if ( ewww_image_optimizer_detect_wpsf_location_lock() ) {
666
  ewwwio_debug_message( 'detected location lock, not enabling background opt' );
classes/class-ewwwio-tracking.php CHANGED
@@ -75,7 +75,7 @@ class EWWWIO_Tracking {
75
  $data['wp_version'] = get_bloginfo( 'version' );
76
  $data['php_version'] = PHP_VERSION_ID;
77
  $data['libxml_version'] = defined( 'LIBXML_VERSION' ) ? LIBXML_VERSION : '';
78
- $data['server'] = isset( $_SERVER['SERVER_SOFTWARE'] ) ? $_SERVER['SERVER_SOFTWARE'] : '';
79
  $data['multisite'] = is_multisite();
80
  $data['theme'] = $theme;
81
 
@@ -232,11 +232,11 @@ class EWWWIO_Tracking {
232
  public function check_for_settings_optin( $input ) {
233
  ewwwio_debug_message( '<b>' . __METHOD__ . '()</b>' );
234
  // Send an intial check in on settings save.
235
- if ( isset( $_POST['ewww_image_optimizer_allow_tracking'] ) && $_POST['ewww_image_optimizer_allow_tracking'] ) {
236
  $this->send_checkin( true );
237
  ewww_image_optimizer_set_option( 'ewww_image_optimizer_tracking_notice', 1 );
238
  }
239
- return $input;
240
  }
241
 
242
  /**
@@ -247,7 +247,7 @@ class EWWWIO_Tracking {
247
  ewww_image_optimizer_set_option( 'ewww_image_optimizer_allow_tracking', 1 );
248
  $this->send_checkin( true );
249
  ewww_image_optimizer_set_option( 'ewww_image_optimizer_tracking_notice', 1 );
250
- wp_redirect( remove_query_arg( 'action', wp_get_referer() ) );
251
  exit;
252
  }
253
 
@@ -259,7 +259,7 @@ class EWWWIO_Tracking {
259
  delete_option( 'ewww_image_optimizer_allow_tracking' );
260
  delete_network_option( null, 'ewww_image_optimizer_allow_tracking' );
261
  ewww_image_optimizer_set_option( 'ewww_image_optimizer_tracking_notice', 1 );
262
- wp_redirect( remove_query_arg( 'action', wp_get_referer() ) );
263
  exit;
264
  }
265
 
@@ -323,7 +323,9 @@ class EWWWIO_Tracking {
323
  * @return void
324
  */
325
  public function admin_notice() {
 
326
  $hide_notice = ewww_image_optimizer_get_option( 'ewww_image_optimizer_tracking_notice' );
 
327
  if ( is_multisite() && get_site_option( 'ewww_image_optimizer_allow_multisite_override' ) && get_site_option( 'ewww_image_optimizer_tracking_notice' ) ) {
328
  $hide_notice = true;
329
  }
@@ -347,6 +349,9 @@ class EWWWIO_Tracking {
347
  if ( is_multisite() && is_plugin_active_for_network( EWWW_IMAGE_OPTIMIZER_PLUGIN_FILE_REL ) && ! current_user_can( 'manage_network_options' ) ) {
348
  return;
349
  }
 
 
 
350
  if (
351
  stristr( network_site_url( '/' ), '.local' ) !== false ||
352
  stristr( network_site_url( '/' ), 'dev' ) !== false ||
@@ -355,12 +360,12 @@ class EWWWIO_Tracking {
355
  ) {
356
  ewww_image_optimizer_set_option( 'ewww_image_optimizer_tracking_notice', 1 );
357
  } else {
358
- $admin_email = '<strong>' . esc_html( get_bloginfo( 'admin_email' ) ) . '</strong>';
359
  $optin_url = admin_url( 'admin.php?action=ewww_opt_into_tracking' );
360
  $optout_url = admin_url( 'admin.php?action=ewww_opt_out_of_tracking' );
361
  echo '<div class="updated"><p>';
362
  /* translators: %s: admin email as configured in settings */
363
- printf( esc_html__( 'Allow EWWW Image Optimizer to track plugin usage? Opt-in to tracking and receive 500 free image credits in your admin email: %s. No sensitive data is tracked.', 'ewww-image-optimizer' ), $admin_email );
364
  echo '&nbsp;<a href="https://docs.ewww.io/article/23-usage-tracking" target="_blank" data-beacon-article="591f3a8e2c7d3a057f893d91">' . esc_html__( 'Learn more.', 'ewww-image-optimizer' ) . '</a>';
365
  echo '<a href="' . esc_url( $optin_url ) . '" class="button-secondary" style="margin-left:5px;">' . esc_html__( 'Allow', 'ewww-image-optimizer' ) . '</a>';
366
  echo '<a href="' . esc_url( $optout_url ) . '" class="button-secondary" style="margin-left:5px">' . esc_html__( 'Do not allow', 'ewww-image-optimizer' ) . '</a>';
75
  $data['wp_version'] = get_bloginfo( 'version' );
76
  $data['php_version'] = PHP_VERSION_ID;
77
  $data['libxml_version'] = defined( 'LIBXML_VERSION' ) ? LIBXML_VERSION : '';
78
+ $data['server'] = isset( $_SERVER['SERVER_SOFTWARE'] ) ? sanitize_text_field( wp_unslash( $_SERVER['SERVER_SOFTWARE'] ) ) : '';
79
  $data['multisite'] = is_multisite();
80
  $data['theme'] = $theme;
81
 
232
  public function check_for_settings_optin( $input ) {
233
  ewwwio_debug_message( '<b>' . __METHOD__ . '()</b>' );
234
  // Send an intial check in on settings save.
235
+ if ( $input ) {
236
  $this->send_checkin( true );
237
  ewww_image_optimizer_set_option( 'ewww_image_optimizer_tracking_notice', 1 );
238
  }
239
+ return (bool) $input;
240
  }
241
 
242
  /**
247
  ewww_image_optimizer_set_option( 'ewww_image_optimizer_allow_tracking', 1 );
248
  $this->send_checkin( true );
249
  ewww_image_optimizer_set_option( 'ewww_image_optimizer_tracking_notice', 1 );
250
+ wp_safe_redirect( remove_query_arg( 'action', wp_get_referer() ) );
251
  exit;
252
  }
253
 
259
  delete_option( 'ewww_image_optimizer_allow_tracking' );
260
  delete_network_option( null, 'ewww_image_optimizer_allow_tracking' );
261
  ewww_image_optimizer_set_option( 'ewww_image_optimizer_tracking_notice', 1 );
262
+ wp_safe_redirect( remove_query_arg( 'action', wp_get_referer() ) );
263
  exit;
264
  }
265
 
323
  * @return void
324
  */
325
  public function admin_notice() {
326
+ // If network-active and network notice is hidden, or single-active and single site notice has been hidden, don't show it again.
327
  $hide_notice = ewww_image_optimizer_get_option( 'ewww_image_optimizer_tracking_notice' );
328
+ // But what if they allow overrides? Then the above was checking single-site settings, so we need to check the network admin.
329
  if ( is_multisite() && get_site_option( 'ewww_image_optimizer_allow_multisite_override' ) && get_site_option( 'ewww_image_optimizer_tracking_notice' ) ) {
330
  $hide_notice = true;
331
  }
349
  if ( is_multisite() && is_plugin_active_for_network( EWWW_IMAGE_OPTIMIZER_PLUGIN_FILE_REL ) && ! current_user_can( 'manage_network_options' ) ) {
350
  return;
351
  }
352
+ if ( is_multisite() && ! is_plugin_active_for_network( EWWW_IMAGE_OPTIMIZER_PLUGIN_FILE_REL ) && is_network_admin() ) {
353
+ return;
354
+ }
355
  if (
356
  stristr( network_site_url( '/' ), '.local' ) !== false ||
357
  stristr( network_site_url( '/' ), 'dev' ) !== false ||
360
  ) {
361
  ewww_image_optimizer_set_option( 'ewww_image_optimizer_tracking_notice', 1 );
362
  } else {
363
+ $admin_email = '<strong>' . get_bloginfo( 'admin_email' ) . '</strong>';
364
  $optin_url = admin_url( 'admin.php?action=ewww_opt_into_tracking' );
365
  $optout_url = admin_url( 'admin.php?action=ewww_opt_out_of_tracking' );
366
  echo '<div class="updated"><p>';
367
  /* translators: %s: admin email as configured in settings */
368
+ printf( esc_html__( 'Allow EWWW Image Optimizer to track plugin usage? Opt-in to tracking and receive 500 free image credits in your admin email: %s. No sensitive data is tracked.', 'ewww-image-optimizer' ), wp_kses_post( $admin_email ) );
369
  echo '&nbsp;<a href="https://docs.ewww.io/article/23-usage-tracking" target="_blank" data-beacon-article="591f3a8e2c7d3a057f893d91">' . esc_html__( 'Learn more.', 'ewww-image-optimizer' ) . '</a>';
370
  echo '<a href="' . esc_url( $optin_url ) . '" class="button-secondary" style="margin-left:5px;">' . esc_html__( 'Allow', 'ewww-image-optimizer' ) . '</a>';
371
  echo '<a href="' . esc_url( $optout_url ) . '" class="button-secondary" style="margin-left:5px">' . esc_html__( 'Do not allow', 'ewww-image-optimizer' ) . '</a>';
classes/class-exactdn.php CHANGED
@@ -129,7 +129,9 @@ if ( ! class_exists( 'ExactDN' ) ) {
129
  $this->scheme = $scheme;
130
  }
131
 
132
- $uri = $_SERVER['REQUEST_URI'];
 
 
133
  /**
134
  * Allow pre-empting the parsers by page.
135
  *
@@ -188,8 +190,8 @@ if ( ! class_exists( 'ExactDN' ) ) {
188
 
189
  // Get all the script/css urls and rewrite them (if enabled).
190
  if ( $this->get_option( 'exactdn_all_the_things' ) && $this->plan_id > 1 ) {
191
- add_filter( 'style_loader_src', array( $this, 'parse_enqueue' ), 20 );
192
- add_filter( 'script_loader_src', array( $this, 'parse_enqueue' ), 20 );
193
  if ( defined( 'EXACTDN_DEFER_SCRIPTS' ) && EXACTDN_DEFER_SCRIPTS ) {
194
  add_filter( 'script_loader_tag', array( $this, 'defer_scripts' ), 20 );
195
  }
@@ -203,7 +205,7 @@ if ( ! class_exists( 'ExactDN' ) ) {
203
  }
204
 
205
  // Configure Autoptimize with our CDN domain.
206
- add_filter( 'autoptimize_filter_cssjs_multidomain', array( $this, 'autoptimize_cdn_url' ) );
207
 
208
  $upload_url_parts = $this->parse_url( $this->content_url() );
209
  if ( empty( $upload_url_parts ) ) {
@@ -286,7 +288,7 @@ if ( ! class_exists( 'ExactDN' ) ) {
286
  $home_url = home_url();
287
  $originip = '';
288
  if ( ! empty( $_SERVER['SERVER_ADDR'] ) ) {
289
- $originip = $_SERVER['SERVER_ADDR'];
290
  }
291
 
292
  $url = 'http://optimize.exactlywww.com/exactdn/activate.php';
@@ -862,6 +864,7 @@ if ( ! class_exists( 'ExactDN' ) ) {
862
  $this->debug_message( 'handling lazy image' );
863
  }
864
 
 
865
  // Check for relative urls that start with a slash. Unlikely that we'll attempt relative urls beyond that.
866
  if (
867
  '/' === substr( $src, 0, 1 ) &&
@@ -870,7 +873,8 @@ if ( ! class_exists( 'ExactDN' ) ) {
870
  false === strpos( $this->upload_domain, 'digitaloceanspaces.com' ) &&
871
  false === strpos( $this->upload_domain, 'storage.googleapis.com' )
872
  ) {
873
- $src = '//' . $this->upload_domain . $src;
 
874
  }
875
 
876
  // Check if image URL should be used with ExactDN.
@@ -1097,7 +1101,11 @@ if ( ! class_exists( 'ExactDN' ) ) {
1097
  $exactdn_url = str_replace( '&#038;', '&', esc_url( $exactdn_url ) );
1098
  // Supplant the original source value with our ExactDN URL.
1099
  $this->debug_message( "replacing $src_orig with $exactdn_url" );
1100
- $new_tag = str_replace( $src_orig, $exactdn_url, $new_tag );
 
 
 
 
1101
 
1102
  // If Lazy Load is in use, pass placeholder image through ExactDN.
1103
  if ( isset( $placeholder_src ) && $this->validate_image_url( $placeholder_src ) ) {
@@ -1404,6 +1412,15 @@ if ( ! class_exists( 'ExactDN' ) ) {
1404
  $content = preg_replace( '#(https?:)?//(?:www\.)?' . $escaped_upload_domain . '/([^"\'?>]+?)?(nextgen-image|wp-includes|wp-content)/#i', '$1//' . $this->exactdn_domain . '/$2$3/', $content );
1405
  }
1406
  $content = str_replace( '?wpcontent-bypass?', 'wp-content', $content );
 
 
 
 
 
 
 
 
 
1407
  }
1408
  return $content;
1409
  }
@@ -1419,16 +1436,19 @@ if ( ! class_exists( 'ExactDN' ) ) {
1419
  if ( ! wp_doing_ajax() ) {
1420
  return $allow;
1421
  }
1422
- if ( ! empty( $_POST['action'] ) && 'eddvbugm_viewport_downloads' === $_POST['action'] ) {
1423
  return true;
1424
  }
1425
- if ( ! empty( $_POST['action'] ) && 'vc_get_vc_grid_data' === $_POST['action'] ) {
1426
  return true;
1427
  }
1428
- if ( ! empty( $_POST['action'] ) && 'Essential_Grid_Front_request_ajax' === $_POST['action'] ) {
1429
  return true;
1430
  }
1431
- if ( ! empty( $_POST['action'] ) && 'mabel-rpn-getnew-purchased-products' === $_POST['action'] ) {
 
 
 
1432
  return true;
1433
  }
1434
  return $allow;
@@ -2184,6 +2204,12 @@ if ( ! class_exists( 'ExactDN' ) ) {
2184
  add_filter( 'exactdn_override_image_downsize', '__return_true', PHP_INT_MAX );
2185
  add_filter( 'exactdn_skip_image', '__return_true', PHP_INT_MAX ); // This skips existing srcset indices.
2186
  add_filter( 'exactdn_srcset_multipliers', '__return_false', PHP_INT_MAX ); // This one skips the additional multipliers.
 
 
 
 
 
 
2187
  }
2188
  return $response;
2189
  }
@@ -2546,15 +2572,21 @@ if ( ! class_exists( 'ExactDN' ) ) {
2546
  }
2547
 
2548
  /**
2549
- * Converts a local script/css url to use ExactDN.
2550
  *
2551
- * @param string $tag URL to the resource being parsed.
2552
- * @return string The ExactDN version of the resource, if it was local.
2553
  */
2554
  function defer_scripts( $tag ) {
2555
  if ( is_admin() ) {
2556
  return $tag;
2557
  }
 
 
 
 
 
 
2558
  if ( false !== strpos( $tag, 'jquery.js' ) && ! defined( 'EXACTDN_DEFER_JQUERY' ) ) {
2559
  return $tag;
2560
  }
@@ -2564,12 +2596,6 @@ if ( ! class_exists( 'ExactDN' ) ) {
2564
  }
2565
  return $tag;
2566
  }
2567
- if ( false !== strpos( $tag, 'async' ) ) {
2568
- return $tag;
2569
- }
2570
- if ( false !== strpos( $tag, 'defer' ) ) {
2571
- return $tag;
2572
- }
2573
  $deferred_tag = str_replace( '></script', ' defer></script', $tag );
2574
  if ( $deferred_tag && $deferred_tag !== $tag ) {
2575
  return $deferred_tag;
@@ -2599,6 +2625,7 @@ if ( ! class_exists( 'ExactDN' ) ) {
2599
  if ( false !== strpos( $url, 'xmlrpc.php' ) ) {
2600
  return $url;
2601
  }
 
2602
  /**
2603
  * Allow specific URLs to avoid going through ExactDN.
2604
  *
@@ -2641,14 +2668,16 @@ if ( ! class_exists( 'ExactDN' ) ) {
2641
  return $url;
2642
  }
2643
 
 
 
 
 
 
2644
  global $wp_version;
2645
  // If a resource doesn't have a version string, we add one to help with cache-busting.
2646
  if (
2647
- (
2648
- empty( $parsed_url['query'] ) ||
2649
- ( 'ver=' . $wp_version === $parsed_url['query'] && false !== strpos( $url, 'wp-content/themes/' ) )
2650
- ) &&
2651
- false !== strpos( $url, 'wp-content/' )
2652
  ) {
2653
  $modified = $this->function_exists( 'filemtime' ) ? filemtime( get_template_directory() ) : '';
2654
  if ( empty( $modified ) ) {
@@ -2660,13 +2689,31 @@ if ( ! class_exists( 'ExactDN' ) ) {
2660
  * @param string Defaults to the modified time of the theme folder, and falls back to the plugin version.
2661
  */
2662
  $parsed_url['query'] = apply_filters( 'exactdn_version_string', "m=$modified" );
2663
- } elseif ( empty( $parsed_url['query'] ) ) {
 
 
 
2664
  $parsed_url['query'] = '';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2665
  }
2666
 
2667
- $exactdn_url = '//' . $this->exactdn_domain . '/' . ltrim( $parsed_url['path'], '/' ) . '?' . $parsed_url['query'];
2668
  $this->debug_message( "exactdn css/script url: $exactdn_url" );
2669
- return $exactdn_url;
2670
  }
2671
 
2672
  /**
@@ -2901,10 +2948,10 @@ if ( ! class_exists( 'ExactDN' ) ) {
2901
  * @param array $domains A list of domains considered 'local' by Autoptimize.
2902
  * @return array The same list, with the ExactDN domain appended.
2903
  */
2904
- function autoptimize_cdn_url( $domains ) {
2905
  $this->debug_message( '<b>' . __METHOD__ . '()</b>' );
2906
  if ( is_array( $domains ) && ! in_array( $this->exactdn_domain, $domains, true ) ) {
2907
- $this->debug_message( 'adding to AO list: ' . $this->exactdn_domain );
2908
  $domains[] = $this->exactdn_domain;
2909
  }
2910
  return $domains;
129
  $this->scheme = $scheme;
130
  }
131
 
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
  *
190
 
191
  // Get all the script/css urls and rewrite them (if enabled).
192
  if ( $this->get_option( 'exactdn_all_the_things' ) && $this->plan_id > 1 ) {
193
+ add_filter( 'style_loader_src', array( $this, 'parse_enqueue' ), 9999 );
194
+ add_filter( 'script_loader_src', array( $this, 'parse_enqueue' ), 9999 );
195
  if ( defined( 'EXACTDN_DEFER_SCRIPTS' ) && EXACTDN_DEFER_SCRIPTS ) {
196
  add_filter( 'script_loader_tag', array( $this, 'defer_scripts' ), 20 );
197
  }
205
  }
206
 
207
  // Configure Autoptimize with our CDN domain.
208
+ add_filter( 'autoptimize_filter_cssjs_multidomain', array( $this, 'add_cdn_domain' ) );
209
 
210
  $upload_url_parts = $this->parse_url( $this->content_url() );
211
  if ( empty( $upload_url_parts ) ) {
288
  $home_url = home_url();
289
  $originip = '';
290
  if ( ! empty( $_SERVER['SERVER_ADDR'] ) ) {
291
+ $originip = sanitize_text_field( wp_unslash( $_SERVER['SERVER_ADDR'] ) );
292
  }
293
 
294
  $url = 'http://optimize.exactlywww.com/exactdn/activate.php';
864
  $this->debug_message( 'handling lazy image' );
865
  }
866
 
867
+ $is_relative = false;
868
  // Check for relative urls that start with a slash. Unlikely that we'll attempt relative urls beyond that.
869
  if (
870
  '/' === substr( $src, 0, 1 ) &&
873
  false === strpos( $this->upload_domain, 'digitaloceanspaces.com' ) &&
874
  false === strpos( $this->upload_domain, 'storage.googleapis.com' )
875
  ) {
876
+ $src = '//' . $this->upload_domain . $src;
877
+ $is_relative = true;
878
  }
879
 
880
  // Check if image URL should be used with ExactDN.
1101
  $exactdn_url = str_replace( '&#038;', '&', esc_url( $exactdn_url ) );
1102
  // Supplant the original source value with our ExactDN URL.
1103
  $this->debug_message( "replacing $src_orig with $exactdn_url" );
1104
+ if ( $is_relative ) {
1105
+ $this->set_attribute( $new_tag, 'src', $exactdn_url, true );
1106
+ } else {
1107
+ $new_tag = str_replace( $src_orig, $exactdn_url, $new_tag );
1108
+ }
1109
 
1110
  // If Lazy Load is in use, pass placeholder image through ExactDN.
1111
  if ( isset( $placeholder_src ) && $this->validate_image_url( $placeholder_src ) ) {
1412
  $content = preg_replace( '#(https?:)?//(?:www\.)?' . $escaped_upload_domain . '/([^"\'?>]+?)?(nextgen-image|wp-includes|wp-content)/#i', '$1//' . $this->exactdn_domain . '/$2$3/', $content );
1413
  }
1414
  $content = str_replace( '?wpcontent-bypass?', 'wp-content', $content );
1415
+ if ( defined( 'EXACTDN_DEFER_JQUERY_SAFE' ) && EXACTDN_DEFER_JQUERY_SAFE && false === strpos( $content, 'jQuery' ) ) {
1416
+ preg_match( "#<script\s+type='text/javascript'\s+src='[^']+?/jquery\.js[^']*?'[^>]*?>#is", $content, $jquery_tags );
1417
+ if ( ! empty( $jquery_tags[0] ) && false === strpos( $jquery_tags[0], 'defer' ) && false === strpos( $jquery_tags[0], 'async' ) ) {
1418
+ $deferred_jquery = str_replace( '>', ' defer>', $jquery_tags[0] );
1419
+ if ( $deferred_jquery && $deferred_jquery !== $jquery_tags[0] ) {
1420
+ $content = str_replace( $jquery_tags[0], $deferred_jquery, $content );
1421
+ }
1422
+ }
1423
+ }
1424
  }
1425
  return $content;
1426
  }
1436
  if ( ! wp_doing_ajax() ) {
1437
  return $allow;
1438
  }
1439
+ if ( ! empty( $_POST['action'] ) && 'eddvbugm_viewport_downloads' === $_POST['action'] ) { // phpcs:ignore WordPress.Security.NonceVerification
1440
  return true;
1441
  }
1442
+ if ( ! empty( $_POST['action'] ) && 'vc_get_vc_grid_data' === $_POST['action'] ) { // phpcs:ignore WordPress.Security.NonceVerification
1443
  return true;
1444
  }
1445
+ if ( ! empty( $_POST['action'] ) && 'filter_listing' === $_POST['action'] && ! empty( $_POST['layout'] ) && ! empty( $_POST['paged'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification
1446
  return true;
1447
  }
1448
+ if ( ! empty( $_POST['action'] ) && 'Essential_Grid_Front_request_ajax' === $_POST['action'] ) { // phpcs:ignore WordPress.Security.NonceVerification
1449
+ return true;
1450
+ }
1451
+ if ( ! empty( $_POST['action'] ) && 'mabel-rpn-getnew-purchased-products' === $_POST['action'] ) { // phpcs:ignore WordPress.Security.NonceVerification
1452
  return true;
1453
  }
1454
  return $allow;
2204
  add_filter( 'exactdn_override_image_downsize', '__return_true', PHP_INT_MAX );
2205
  add_filter( 'exactdn_skip_image', '__return_true', PHP_INT_MAX ); // This skips existing srcset indices.
2206
  add_filter( 'exactdn_srcset_multipliers', '__return_false', PHP_INT_MAX ); // This one skips the additional multipliers.
2207
+ } elseif ( is_string( $route ) && false !== strpos( $route, 'wp/v2/media' ) && ! empty( $request['post'] ) && ! empty( $request->get_file_params() ) ) {
2208
+ $this->debug_message( 'REST API media endpoint (new upload)' );
2209
+ // We don't want ExactDN urls anywhere near the editor, so disable everything we can.
2210
+ add_filter( 'exactdn_override_image_downsize', '__return_true', PHP_INT_MAX );
2211
+ add_filter( 'exactdn_skip_image', '__return_true', PHP_INT_MAX ); // This skips existing srcset indices.
2212
+ add_filter( 'exactdn_srcset_multipliers', '__return_false', PHP_INT_MAX ); // This one skips the additional multipliers.
2213
  }
2214
  return $response;
2215
  }
2572
  }
2573
 
2574
  /**
2575
+ * Rewrites a script tag to be deferred.
2576
  *
2577
+ * @param string $tag URL to the script.
2578
+ * @return string The deferred version of the resource, if it was allowed.
2579
  */
2580
  function defer_scripts( $tag ) {
2581
  if ( is_admin() ) {
2582
  return $tag;
2583
  }
2584
+ if ( false !== strpos( $tag, 'async' ) ) {
2585
+ return $tag;
2586
+ }
2587
+ if ( false !== strpos( $tag, 'defer' ) ) {
2588
+ return $tag;
2589
+ }
2590
  if ( false !== strpos( $tag, 'jquery.js' ) && ! defined( 'EXACTDN_DEFER_JQUERY' ) ) {
2591
  return $tag;
2592
  }
2596
  }
2597
  return $tag;
2598
  }
 
 
 
 
 
 
2599
  $deferred_tag = str_replace( '></script', ' defer></script', $tag );
2600
  if ( $deferred_tag && $deferred_tag !== $tag ) {
2601
  return $deferred_tag;
2625
  if ( false !== strpos( $url, 'xmlrpc.php' ) ) {
2626
  return $url;
2627
  }
2628
+
2629
  /**
2630
  * Allow specific URLs to avoid going through ExactDN.
2631
  *
2668
  return $url;
2669
  }
2670
 
2671
+ $scheme = $this->scheme;
2672
+ if ( isset( $parsed_url['scheme'] ) && 'https' === $parsed_url['scheme'] ) {
2673
+ $scheme = 'https';
2674
+ }
2675
+
2676
  global $wp_version;
2677
  // If a resource doesn't have a version string, we add one to help with cache-busting.
2678
  if (
2679
+ false !== strpos( $url, 'wp-content/themes/' ) &&
2680
+ ( empty( $parsed_url['query'] ) || 'ver=' . $wp_version === $parsed_url['query'] )
 
 
 
2681
  ) {
2682
  $modified = $this->function_exists( 'filemtime' ) ? filemtime( get_template_directory() ) : '';
2683
  if ( empty( $modified ) ) {
2689
  * @param string Defaults to the modified time of the theme folder, and falls back to the plugin version.
2690
  */
2691
  $parsed_url['query'] = apply_filters( 'exactdn_version_string', "m=$modified" );
2692
+ } elseif (
2693
+ false !== strpos( $url, 'wp-content/plugins/' ) &&
2694
+ ( empty( $parsed_url['query'] ) || 'ver=' . $wp_version === $parsed_url['query'] )
2695
+ ) {
2696
  $parsed_url['query'] = '';
2697
+ $path = $this->url_to_path_exists( $url );
2698
+ if ( $path ) {
2699
+ $modified = $this->function_exists( 'filemtime' ) ? filemtime( dirname( $path ) ) : '';
2700
+ if ( empty( $modified ) ) {
2701
+ $modified = $this->version;
2702
+ }
2703
+ /**
2704
+ * Allows a custom version string for resources that are missing one.
2705
+ *
2706
+ * @param string Defaults to the modified time of the folder, and falls back to the plugin version.
2707
+ */
2708
+ $parsed_url['query'] = apply_filters( 'exactdn_version_string', "m=$modified" );
2709
+ }
2710
+ } elseif ( empty( $parsed_url['query'] ) ) {
2711
+ $parsed_url['query'] = apply_filters( 'exactdn_version_string', 'm=' . $this->version );
2712
  }
2713
 
2714
+ $exactdn_url = $scheme . '://' . $this->exactdn_domain . '/' . ltrim( $parsed_url['path'], '/' ) . '?' . $parsed_url['query'];
2715
  $this->debug_message( "exactdn css/script url: $exactdn_url" );
2716
+ return $this->url_scheme( $exactdn_url, $scheme );
2717
  }
2718
 
2719
  /**
2948
  * @param array $domains A list of domains considered 'local' by Autoptimize.
2949
  * @return array The same list, with the ExactDN domain appended.
2950
  */
2951
+ function add_cdn_domain( $domains ) {
2952
  $this->debug_message( '<b>' . __METHOD__ . '()</b>' );
2953
  if ( is_array( $domains ) && ! in_array( $this->exactdn_domain, $domains, true ) ) {
2954
+ $this->debug_message( 'adding to CDN domain/host list: ' . $this->exactdn_domain );
2955
  $domains[] = $this->exactdn_domain;
2956
  }
2957
  return $domains;
common.php CHANGED
@@ -14,7 +14,7 @@ if ( ! defined( 'ABSPATH' ) ) {
14
  exit;
15
  }
16
 
17
- define( 'EWWW_IMAGE_OPTIMIZER_VERSION', '532' );
18
 
19
  // Initialize a couple globals.
20
  $eio_debug = '';
@@ -130,8 +130,6 @@ add_action( 'admin_action_ewww_image_optimizer_manual_optimize', 'ewww_image_opt
130
  add_action( 'admin_action_ewww_image_optimizer_manual_restore', 'ewww_image_optimizer_manual' );
131
  // Legacy (non-AJAX) action hook for manually restoring a backup from the API.
132
  add_action( 'admin_action_ewww_image_optimizer_manual_cloud_restore', 'ewww_image_optimizer_manual' );
133
- // Legacy (non-AJAX) action hook for manually attempting conversion on an image.
134
- add_action( 'admin_action_ewww_image_optimizer_manual_convert', 'ewww_image_optimizer_manual' );
135
  // Cleanup routine when an attachment is deleted.
136
  add_action( 'delete_attachment', 'ewww_image_optimizer_delete' );
137
  // Cleanup db records when Enable Media Replace replaces a file.
@@ -142,8 +140,6 @@ add_action( 'sirsc_image_file_deleted', 'ewww_image_optimizer_file_deleted', 10,
142
  add_action( 'admin_menu', 'ewww_image_optimizer_admin_menu', 60 );
143
  // Adds the EWWW IO settings to the network admin menu.
144
  add_action( 'network_admin_menu', 'ewww_image_optimizer_network_admin_menu' );
145
- // Adds Bulk Optimize to the media library bulk actions.
146
- add_filter( 'bulk_actions-upload', 'ewww_image_optimizer_add_bulk_media_actions' );
147
  // Handle the bulk actions from the media library.
148
  add_filter( 'handle_bulk_actions-upload', 'ewww_image_optimizer_bulk_action_handler', 10, 3 );
149
  // Adds scripts to ajaxify the one-click actions on the media library, and register tooltips for conversion links.
@@ -213,7 +209,7 @@ if ( 'done' !== get_option( 'ewww_image_optimizer_relative_migration_status' ) )
213
  function ewww_image_optimizer_parser_init() {
214
  $buffer_start = false;
215
  // If ExactDN is enabled.
216
- if ( ewww_image_optimizer_get_option( 'ewww_image_optimizer_exactdn' ) && empty( $_GET['exactdn_disable'] ) ) {
217
  if ( ! ewww_image_optimizer_get_option( 'exactdn_all_the_things' ) ) {
218
  // Un-configure Autoptimize CDN domain.
219
  if ( defined( 'AUTOPTIMIZE_PLUGIN_DIR' ) && strpos( ewww_image_optimizer_get_option( 'autoptimize_cdn_url' ), 'exactdn' ) ) {
@@ -514,13 +510,20 @@ function ewww_image_optimizer_init() {
514
  }
515
  }
516
 
517
- if ( class_exists( 'Meow_MFRH_Core' ) ) {
518
- // Resizes and auto-rotates images.
519
- add_filter( 'wp_handle_upload_prefilter', 'ewww_image_optimizer_handle_upload', 9 );
520
- } else {
521
- // Resizes and auto-rotates images.
522
- add_filter( 'wp_handle_upload', 'ewww_image_optimizer_handle_upload' );
 
 
 
 
523
  }
 
 
 
524
  if ( class_exists( 'S3_Uploads' ) ) {
525
  ewwwio_debug_message( 's3-uploads detected, deferring resize_upload' );
526
  add_filter( 'ewww_image_optimizer_defer_resizing', '__return_true' );
@@ -587,8 +590,10 @@ function ewww_image_optimizer_upgrade() {
587
  ewww_image_optimizer_set_defaults();
588
  // This will get re-enabled if things are too slow.
589
  ewww_image_optimizer_set_option( 'exactdn_prevent_db_queries', false );
590
- delete_option( 'ewww_image_optimizer_exactdn_verify_method' );
591
- delete_site_option( 'ewww_image_optimizer_exactdn_verify_method' );
 
 
592
  if ( get_option( 'ewww_image_optimizer_version' ) < 297.5 ) {
593
  // Cleanup background test mess.
594
  wp_clear_scheduled_hook( 'wp_ewwwio_test_optimize_cron' );
@@ -686,7 +691,7 @@ function ewww_image_optimizer_retest_background_optimization() {
686
  ewww_image_optimizer_enable_background_optimization();
687
  sleep( 10 );
688
  $sendback = wp_get_referer();
689
- wp_redirect( $sendback );
690
  exit;
691
  }
692
 
@@ -725,103 +730,116 @@ function ewww_image_optimizer_admin_init() {
725
  if ( is_multisite() && is_plugin_active_for_network( EWWW_IMAGE_OPTIMIZER_PLUGIN_FILE_REL ) ) {
726
  ewwwio_debug_message( 'saving network settings' );
727
  // Set the common network settings if they have been POSTed.
728
- if ( isset( $_POST['option_page'] ) && false !== strpos( $_POST['option_page'], 'ewww_image_optimizer_options' ) && wp_verify_nonce( $_REQUEST['_wpnonce'], 'ewww_image_optimizer_options-options' ) && current_user_can( 'manage_network_options' ) && ! get_site_option( 'ewww_image_optimizer_allow_multisite_override' ) && false === strpos( $_POST['_wp_http_referer'], 'options-general' ) ) {
 
 
 
 
 
 
 
 
729
  ewwwio_debug_message( 'network-wide settings, no override' );
730
- $_POST['ewww_image_optimizer_cloud_key'] = empty( $_POST['ewww_image_optimizer_cloud_key'] ) ? '' : $_POST['ewww_image_optimizer_cloud_key'];
731
- update_site_option( 'ewww_image_optimizer_cloud_key', ewww_image_optimizer_cloud_key_sanitize( $_POST['ewww_image_optimizer_cloud_key'] ) );
732
- $_POST['ewww_image_optimizer_debug'] = ( empty( $_POST['ewww_image_optimizer_debug'] ) ? false : true );
733
- update_site_option( 'ewww_image_optimizer_debug', $_POST['ewww_image_optimizer_debug'] );
734
- $_POST['ewww_image_optimizer_metadata_remove'] = ( empty( $_POST['ewww_image_optimizer_metadata_remove'] ) ? false : true );
735
- update_site_option( 'ewww_image_optimizer_metadata_remove', $_POST['ewww_image_optimizer_metadata_remove'] );
736
- $_POST['ewww_image_optimizer_jpg_level'] = empty( $_POST['ewww_image_optimizer_jpg_level'] ) ? '' : $_POST['ewww_image_optimizer_jpg_level'];
737
- update_site_option( 'ewww_image_optimizer_jpg_level', (int) $_POST['ewww_image_optimizer_jpg_level'] );
738
- $_POST['ewww_image_optimizer_png_level'] = empty( $_POST['ewww_image_optimizer_png_level'] ) ? '' : $_POST['ewww_image_optimizer_png_level'];
739
- update_site_option( 'ewww_image_optimizer_png_level', (int) $_POST['ewww_image_optimizer_png_level'] );
740
- $_POST['ewww_image_optimizer_gif_level'] = empty( $_POST['ewww_image_optimizer_gif_level'] ) ? '' : $_POST['ewww_image_optimizer_gif_level'];
741
- update_site_option( 'ewww_image_optimizer_gif_level', (int) $_POST['ewww_image_optimizer_gif_level'] );
742
- $_POST['ewww_image_optimizer_pdf_level'] = empty( $_POST['ewww_image_optimizer_pdf_level'] ) ? '' : $_POST['ewww_image_optimizer_pdf_level'];
743
- update_site_option( 'ewww_image_optimizer_pdf_level', (int) $_POST['ewww_image_optimizer_pdf_level'] );
744
- $_POST['ewww_image_optimizer_delete_originals'] = ( empty( $_POST['ewww_image_optimizer_delete_originals'] ) ? false : true );
745
- update_site_option( 'ewww_image_optimizer_delete_originals', $_POST['ewww_image_optimizer_delete_originals'] );
746
- $_POST['ewww_image_optimizer_jpg_to_png'] = ( empty( $_POST['ewww_image_optimizer_jpg_to_png'] ) ? false : true );
747
- update_site_option( 'ewww_image_optimizer_jpg_to_png', $_POST['ewww_image_optimizer_jpg_to_png'] );
748
- $_POST['ewww_image_optimizer_png_to_jpg'] = ( empty( $_POST['ewww_image_optimizer_png_to_jpg'] ) ? false : true );
749
- update_site_option( 'ewww_image_optimizer_png_to_jpg', $_POST['ewww_image_optimizer_png_to_jpg'] );
750
- $_POST['ewww_image_optimizer_gif_to_png'] = ( empty( $_POST['ewww_image_optimizer_gif_to_png'] ) ? false : true );
751
- update_site_option( 'ewww_image_optimizer_gif_to_png', $_POST['ewww_image_optimizer_gif_to_png'] );
752
- $_POST['ewww_image_optimizer_webp'] = ( empty( $_POST['ewww_image_optimizer_webp'] ) ? false : true );
753
- update_site_option( 'ewww_image_optimizer_webp', $_POST['ewww_image_optimizer_webp'] );
754
- $_POST['ewww_image_optimizer_jpg_background'] = empty( $_POST['ewww_image_optimizer_jpg_background'] ) ? '' : $_POST['ewww_image_optimizer_jpg_background'];
755
- update_site_option( 'ewww_image_optimizer_jpg_background', ewww_image_optimizer_jpg_background( $_POST['ewww_image_optimizer_jpg_background'] ) );
756
- $_POST['ewww_image_optimizer_jpg_quality'] = empty( $_POST['ewww_image_optimizer_jpg_quality'] ) ? '' : $_POST['ewww_image_optimizer_jpg_quality'];
757
- update_site_option( 'ewww_image_optimizer_jpg_quality', ewww_image_optimizer_jpg_quality( $_POST['ewww_image_optimizer_jpg_quality'] ) );
758
- $_POST['ewww_image_optimizer_disable_convert_links'] = ( empty( $_POST['ewww_image_optimizer_disable_convert_links'] ) ? false : true );
759
- update_site_option( 'ewww_image_optimizer_disable_convert_links', $_POST['ewww_image_optimizer_disable_convert_links'] );
760
- $_POST['ewww_image_optimizer_backup_files'] = ( empty( $_POST['ewww_image_optimizer_backup_files'] ) ? false : true );
761
- update_site_option( 'ewww_image_optimizer_backup_files', $_POST['ewww_image_optimizer_backup_files'] );
762
- $_POST['ewww_image_optimizer_auto'] = ( empty( $_POST['ewww_image_optimizer_auto'] ) ? false : true );
763
- update_site_option( 'ewww_image_optimizer_auto', $_POST['ewww_image_optimizer_auto'] );
764
- $_POST['ewww_image_optimizer_aux_paths'] = empty( $_POST['ewww_image_optimizer_aux_paths'] ) ? '' : $_POST['ewww_image_optimizer_aux_paths'];
765
- update_site_option( 'ewww_image_optimizer_aux_paths', ewww_image_optimizer_aux_paths_sanitize( $_POST['ewww_image_optimizer_aux_paths'] ) );
766
- $_POST['ewww_image_optimizer_exclude_paths'] = empty( $_POST['ewww_image_optimizer_exclude_paths'] ) ? '' : $_POST['ewww_image_optimizer_exclude_paths'];
767
- update_site_option( 'ewww_image_optimizer_exclude_paths', ewww_image_optimizer_exclude_paths_sanitize( $_POST['ewww_image_optimizer_exclude_paths'] ) );
768
- $_POST['ewww_image_optimizer_enable_cloudinary'] = ( empty( $_POST['ewww_image_optimizer_enable_cloudinary'] ) ? false : true );
769
- update_site_option( 'ewww_image_optimizer_enable_cloudinary', $_POST['ewww_image_optimizer_enable_cloudinary'] );
770
- $_POST['ewww_image_optimizer_exactdn'] = ( empty( $_POST['ewww_image_optimizer_exactdn'] ) ? false : true );
771
- update_site_option( 'ewww_image_optimizer_exactdn', $_POST['ewww_image_optimizer_exactdn'] );
772
- $_POST['exactdn_all_the_things'] = ( empty( $_POST['exactdn_all_the_things'] ) ? false : true );
773
- update_site_option( 'exactdn_all_the_things', $_POST['exactdn_all_the_things'] );
774
- $_POST['exactdn_lossy'] = ( empty( $_POST['exactdn_lossy'] ) ? false : true );
775
- update_site_option( 'exactdn_lossy', $_POST['exactdn_lossy'] );
776
- $_POST['exactdn_exclude'] = empty( $_POST['exactdn_exclude'] ) ? '' : $_POST['exactdn_exclude'];
777
- update_site_option( 'exactdn_exclude', ewww_image_optimizer_exclude_paths_sanitize( $_POST['exactdn_exclude'] ) );
778
- $_POST['ewww_image_optimizer_lazy_load'] = ( empty( $_POST['ewww_image_optimizer_lazy_load'] ) ? false : true );
779
- update_site_option( 'ewww_image_optimizer_lazy_load', $_POST['ewww_image_optimizer_lazy_load'] );
780
- $_POST['ewww_image_optimizer_use_lqip'] = ( empty( $_POST['ewww_image_optimizer_use_lqip'] ) ? false : true );
781
- update_site_option( 'ewww_image_optimizer_use_lqip', $_POST['ewww_image_optimizer_use_lqip'] );
782
- $_POST['ewww_image_optimizer_ll_exclude'] = empty( $_POST['ewww_image_optimizer_ll_exclude'] ) ? '' : $_POST['ewww_image_optimizer_ll_exclude'];
783
- update_site_option( 'ewww_image_optimizer_ll_exclude', ewww_image_optimizer_exclude_paths_sanitize( $_POST['ewww_image_optimizer_ll_exclude'] ) );
784
- $_POST['ewww_image_optimizer_maxmediawidth'] = empty( $_POST['ewww_image_optimizer_maxmediawidth'] ) ? 0 : $_POST['ewww_image_optimizer_maxmediawidth'];
785
- update_site_option( 'ewww_image_optimizer_maxmediawidth', (int) $_POST['ewww_image_optimizer_maxmediawidth'] );
786
- $_POST['ewww_image_optimizer_maxmediaheight'] = empty( $_POST['ewww_image_optimizer_maxmediaheight'] ) ? 0 : $_POST['ewww_image_optimizer_maxmediaheight'];
787
- update_site_option( 'ewww_image_optimizer_maxmediaheight', (int) $_POST['ewww_image_optimizer_maxmediaheight'] );
788
- $_POST['ewww_image_optimizer_resize_detection'] = ( empty( $_POST['ewww_image_optimizer_resize_detection'] ) ? false : true );
789
- update_site_option( 'ewww_image_optimizer_resize_detection', $_POST['ewww_image_optimizer_resize_detection'] );
790
- $_POST['ewww_image_optimizer_resize_existing'] = ( empty( $_POST['ewww_image_optimizer_resize_existing'] ) ? false : true );
791
- update_site_option( 'ewww_image_optimizer_resize_existing', $_POST['ewww_image_optimizer_resize_existing'] );
792
- $_POST['ewww_image_optimizer_resize_other_existing'] = ( empty( $_POST['ewww_image_optimizer_resize_other_existing'] ) ? false : true );
793
- update_site_option( 'ewww_image_optimizer_resize_other_existing', $_POST['ewww_image_optimizer_resize_other_existing'] );
794
- $_POST['ewww_image_optimizer_parallel_optimization'] = ( empty( $_POST['ewww_image_optimizer_parallel_optimization'] ) ? false : true );
795
- update_site_option( 'ewww_image_optimizer_parallel_optimization', $_POST['ewww_image_optimizer_parallel_optimization'] );
796
- $_POST['ewww_image_optimizer_include_media_paths'] = ( empty( $_POST['ewww_image_optimizer_include_media_paths'] ) ? false : true );
797
- update_site_option( 'ewww_image_optimizer_include_media_paths', $_POST['ewww_image_optimizer_include_media_paths'] );
798
- $_POST['ewww_image_optimizer_include_originals'] = ( empty( $_POST['ewww_image_optimizer_include_originals'] ) ? false : true );
799
- update_site_option( 'ewww_image_optimizer_include_originals', $_POST['ewww_image_optimizer_include_originals'] );
800
- $_POST['ewww_image_optimizer_webp_for_cdn'] = ( empty( $_POST['ewww_image_optimizer_webp_for_cdn'] ) ? false : true );
801
- update_site_option( 'ewww_image_optimizer_webp_for_cdn', $_POST['ewww_image_optimizer_webp_for_cdn'] );
802
- $_POST['ewww_image_optimizer_picture_webp'] = ( empty( $_POST['ewww_image_optimizer_picture_webp'] ) ? false : true );
803
- update_site_option( 'ewww_image_optimizer_picture_webp', $_POST['ewww_image_optimizer_picture_webp'] );
804
- $_POST['ewww_image_optimizer_webp_rewrite_exclude'] = empty( $_POST['ewww_image_optimizer_webp_rewrite_exclude'] ) ? '' : $_POST['ewww_image_optimizer_webp_rewrite_exclude'];
805
- update_site_option( 'ewww_image_optimizer_webp_rewrite_exclude', ewww_image_optimizer_exclude_paths_sanitize( $_POST['ewww_image_optimizer_webp_rewrite_exclude'] ) );
806
- $_POST['ewww_image_optimizer_webp_force'] = ( empty( $_POST['ewww_image_optimizer_webp_force'] ) ? false : true );
807
- update_site_option( 'ewww_image_optimizer_webp_force', $_POST['ewww_image_optimizer_webp_force'] );
808
- $_POST['ewww_image_optimizer_webp_paths'] = ( empty( $_POST['ewww_image_optimizer_webp_paths'] ) ? '' : $_POST['ewww_image_optimizer_webp_paths'] );
809
- update_site_option( 'ewww_image_optimizer_webp_paths', ewww_image_optimizer_webp_paths_sanitize( $_POST['ewww_image_optimizer_webp_paths'] ) );
810
- $_POST['ewww_image_optimizer_allow_multisite_override'] = empty( $_POST['ewww_image_optimizer_allow_multisite_override'] ) ? false : true;
811
- update_site_option( 'ewww_image_optimizer_allow_multisite_override', $_POST['ewww_image_optimizer_allow_multisite_override'] );
812
- $_POST['ewww_image_optimizer_enable_help'] = empty( $_POST['ewww_image_optimizer_enable_help'] ) ? false : true;
813
- update_site_option( 'ewww_image_optimizer_enable_help', $_POST['ewww_image_optimizer_enable_help'] );
814
  global $ewwwio_tracking;
815
- $_POST['ewww_image_optimizer_allow_tracking'] = empty( $_POST['ewww_image_optimizer_allow_tracking'] ) ? false : $ewwwio_tracking->check_for_settings_optin( $_POST['ewww_image_optimizer_allow_tracking'] );
816
- update_site_option( 'ewww_image_optimizer_allow_tracking', $_POST['ewww_image_optimizer_allow_tracking'] );
817
  add_action( 'network_admin_notices', 'ewww_image_optimizer_network_settings_saved' );
818
- } elseif ( isset( $_POST['ewww_image_optimizer_allow_multisite_override_active'] ) && current_user_can( 'manage_network_options' ) && wp_verify_nonce( $_REQUEST['_wpnonce'], 'ewww_image_optimizer_options-options' ) ) {
 
 
 
 
 
819
  ewwwio_debug_message( 'network-wide settings, single-site overriding' );
820
- $_POST['ewww_image_optimizer_allow_multisite_override'] = empty( $_POST['ewww_image_optimizer_allow_multisite_override'] ) ? false : true;
821
- update_site_option( 'ewww_image_optimizer_allow_multisite_override', $_POST['ewww_image_optimizer_allow_multisite_override'] );
822
  global $ewwwio_tracking;
823
- $_POST['ewww_image_optimizer_allow_tracking'] = empty( $_POST['ewww_image_optimizer_allow_tracking'] ) ? false : $ewwwio_tracking->check_for_settings_optin( $_POST['ewww_image_optimizer_allow_tracking'] );
824
- update_site_option( 'ewww_image_optimizer_allow_tracking', $_POST['ewww_image_optimizer_allow_tracking'] );
825
  add_action( 'network_admin_notices', 'ewww_image_optimizer_network_settings_saved' );
826
  } // End if().
827
  } // End if().
@@ -1007,27 +1025,29 @@ function ewww_image_optimizer_ajax_compat_check() {
1007
  return;
1008
  }
1009
  ewwwio_debug_message( '<b>' . __FUNCTION__ . '()</b>' );
 
 
 
 
1010
  // Check for (Force) Regenerate Thumbnails action (includes MLP regenerate).
1011
- if ( ! empty( $_REQUEST['action'] ) ) {
1012
- if (
1013
- 'regeneratethumbnail' === $_REQUEST['action'] ||
1014
- 'rta_regenerate_thumbnails' === $_REQUEST['action'] ||
1015
- 'meauh_save_image' === $_REQUEST['action'] ||
1016
- 'hotspot_save' === $_REQUEST['action']
1017
- ) {
1018
- ewwwio_debug_message( 'doing regeneratethumbnail' );
1019
- ewww_image_optimizer_image_sizes( false );
1020
- return;
1021
- }
1022
- if ( 'mic_crop_image' === $_REQUEST['action'] ) {
1023
- ewwwio_debug_message( 'doing Manual Image Crop' );
1024
- if ( ! defined( 'EWWWIO_EDITOR_OVERWRITE' ) ) {
1025
- define( 'EWWWIO_EDITOR_OVERWRITE', true );
1026
- }
1027
- return;
1028
  }
 
1029
  }
1030
- if ( ! empty( $_REQUEST['action'] ) && false !== strpos( $_REQUEST['action'], 'wc_regenerate_images' ) ) {
1031
  // Unhook all automatic processing, and save an option that (does not autoload) tells the user WC regenerated their images and they should run the bulk optimizer.
1032
  remove_filter( 'wp_image_editors', 'ewww_image_optimizer_load_editor', 60 );
1033
  remove_filter( 'wp_generate_attachment_metadata', 'ewww_image_optimizer_resize_from_meta_data', 15 );
@@ -1035,25 +1055,25 @@ function ewww_image_optimizer_ajax_compat_check() {
1035
  return;
1036
  }
1037
  // Check for Image Watermark plugin.
1038
- if ( ! empty( $_POST['iw-action'] ) ) {
1039
- $action = $_POST['iw-action'];
1040
- ewwwio_debug_message( "doing $action" );
1041
  global $ewww_preempt_editor;
1042
  $ewww_preempt_editor = true;
1043
- if ( 'applywatermark' === $action ) {
1044
  remove_filter( 'wp_generate_attachment_metadata', 'ewww_image_optimizer_resize_from_meta_data', 15 );
1045
  add_action( 'iw_after_apply_watermark', 'ewww_image_optimizer_single_size_optimize', 10, 2 );
1046
  }
1047
  return;
1048
  }
1049
  // Check for other MLP actions, including multi-regen.
1050
- if ( ! empty( $_REQUEST['action'] ) && class_exists( 'MaxGalleriaMediaLib' ) && ( 'regen_mlp_thumbnails' === $_REQUEST['action'] || 'move_media' === $_REQUEST['action'] || 'copy_media' === $_REQUEST['action'] || 'maxgalleria_rename_image' === $_REQUEST['action'] ) ) {
1051
  ewwwio_debug_message( 'doing regen_mlp_thumbnails' );
1052
  ewww_image_optimizer_image_sizes( false );
1053
  return;
1054
  }
1055
  // Check for MLP upload.
1056
- if ( ! empty( $_REQUEST['action'] ) && class_exists( 'MaxGalleriaMediaLib' ) && ! empty( $_REQUEST['nonce'] ) && 'upload_attachment' === $_REQUEST['action'] ) {
1057
  ewwwio_debug_message( 'doing maxgalleria upload' );
1058
  ewww_image_optimizer_image_sizes( false );
1059
  return;
@@ -1063,9 +1083,9 @@ function ewww_image_optimizer_ajax_compat_check() {
1063
  ewwwio_debug_message( 'IRSC action/regen' );
1064
  ewww_image_optimizer_image_sizes( false );
1065
  return;
1066
- } elseif ( ! empty( $_REQUEST['action'] ) && 0 === strpos( $_REQUEST['action'], 'sirsc' ) ) {
1067
  // Image Regenerate and Select Crop (old check).
1068
- ewwwio_debug_message( 'IRSC action/regen' );
1069
  ewww_image_optimizer_image_sizes( false );
1070
  return;
1071
  }
@@ -1161,7 +1181,7 @@ function ewww_image_optimizer_single_size_optimize( $id, $size ) {
1161
  return;
1162
  }
1163
  // If this is a unique size.
1164
- $resize_path = $base_dir . $data['file'];
1165
  if ( 'application/pdf' === $type && 'full' === $size ) {
1166
  $size = 'pdf-full';
1167
  ewwwio_debug_message( 'processing full size pdf preview' );
@@ -1220,6 +1240,9 @@ function ewww_image_optimizer_restapi_compat_check() {
1220
  */
1221
  function ewww_image_optimizer_disable_tools() {
1222
  ewwwio_debug_message( '<b>' . __FUNCTION__ . '()</b>' );
 
 
 
1223
  if ( ! defined( 'EWWW_IMAGE_OPTIMIZER_JPEGTRAN' ) ) {
1224
  define( 'EWWW_IMAGE_OPTIMIZER_JPEGTRAN', false );
1225
  }
@@ -1659,11 +1682,13 @@ function ewww_image_optimizer_scheduled_optimizaton_changed( $new_value, $old_va
1659
  function ewww_image_optimizer_notice_webp_bulk() {
1660
  $already_done = ewww_image_optimizer_aux_images_table_count();
1661
  if ( $already_done > 50 ) {
1662
- $message = esc_html__( 'It looks like you already started optimizing your images, you will need to generate WebP images via the Bulk Optimizer.', 'ewww-image-optimizer' );
1663
- echo "<div id='ewww-image-optimizer-pngout-success' class='notice notice-info'><p><a href='" . admin_url( 'upload.php?page=ewww-image-optimizer-bulk&ewww_webp_only=1&ewww_force=1' ) . "'>$message</a></p></div>";
 
1664
  } else {
1665
- $message = esc_html__( 'Use the Bulk Optimizer to generate WebP images for existing uploads.', 'ewww-image-optimizer' );
1666
- echo "<div id='ewww-image-optimizer-pngout-success' class='notice notice-info'><p><a href='" . admin_url( 'upload.php?page=ewww-image-optimizer-bulk' ) . "'>$message</a></p></div>";
 
1667
  }
1668
  delete_option( 'ewww_image_optimizer_webp_enabled' );
1669
  }
@@ -1672,18 +1697,18 @@ function ewww_image_optimizer_notice_webp_bulk() {
1672
  * Display a success or failure message after PNGOUT installation.
1673
  */
1674
  function ewww_image_optimizer_pngout_installed() {
1675
- if ( 'success' === $_REQUEST['ewww_pngout'] ) {
1676
  echo "<div id='ewww-image-optimizer-pngout-success' class='notice notice-success fade'>\n" .
1677
  '<p>' . esc_html__( 'Pngout was successfully installed.', 'ewww-image-optimizer' ) . "</p>\n" .
1678
  "</div>\n";
1679
  }
1680
- if ( 'failed' === $_REQUEST['ewww_pngout'] ) {
1681
  echo "<div id='ewww-image-optimizer-pngout-failure' class='notice notice-error'>\n" .
1682
  '<p>' . sprintf(
1683
  /* translators: 1: An error message 2: The folder where pngout should be installed */
1684
  esc_html__( 'Pngout was not installed: %1$s. Make sure this folder is writable: %2$s', 'ewww-image-optimizer' ),
1685
- sanitize_text_field( $_REQUEST['ewww_error'] ),
1686
- EWWW_IMAGE_OPTIMIZER_TOOL_PATH
1687
  ) . "</p>\n" .
1688
  "</div>\n";
1689
  }
@@ -1703,7 +1728,7 @@ function ewww_image_optimizer_notice_exactdn_activation_error() {
1703
  esc_html__( 'Could not activate Easy IO, please try again in a few minutes. If this error continues, please see %s for troubleshooting steps.', 'ewww-image-optimizer' ),
1704
  'https://docs.ewww.io/article/66-exactdn-not-verified'
1705
  ) .
1706
- '<br><code>' . $exactdn_activate_error . '</code>' .
1707
  '</p></div>';
1708
  }
1709
 
@@ -1820,7 +1845,14 @@ function ewww_image_optimizer_notice_media_listmode() {
1820
  update_site_option( 'ewww_image_optimizer_dismiss_media_notice', true );
1821
  return;
1822
  }
1823
- echo "<div id='ewww-image-optimizer-media-listmode' class='notice notice-info is-dismissible'><p>" . esc_html__( 'Change the Media Library to List mode for additional image optimization information and actions.', 'ewww-image-optimizer' ) . ewwwio_help_link( 'https://docs.ewww.io/article/62-power-user-options-in-list-mode', '5b61fdd32c7d3a03f89d41c4' ) . '</p></div>';
 
 
 
 
 
 
 
1824
  }
1825
  }
1826
 
@@ -1874,7 +1906,7 @@ function ewww_image_optimizer_notice_beacon() {
1874
  */
1875
  function ewww_image_optimizer_notice_reoptimization() {
1876
  // Allows the user to reset all images back to 1 optimization, which clears the alert.
1877
- if ( ! empty( $_GET['ewww_reset_reopt_nonce'] ) && wp_verify_nonce( $_GET['ewww_reset_reopt_nonce'], 'reset_reoptimization_counters' ) ) {
1878
  global $wpdb;
1879
  $debug_images = $wpdb->query( "UPDATE $wpdb->ewwwio_images SET updates=1 WHERE updates > 1" );
1880
  delete_transient( 'ewww_image_optimizer_images_reoptimized' );
@@ -1894,15 +1926,15 @@ function ewww_image_optimizer_notice_reoptimization() {
1894
  // Do a check for 10+ optimizations on 5+ images.
1895
  if ( ! empty( $reoptimized ) && $reoptimized > 5 ) {
1896
  $debugging_page = admin_url( 'tools.php?page=ewww-image-optimizer-tools' );
1897
- $reset_page = wp_nonce_url( $_SERVER['REQUEST_URI'], 'reset_reoptimization_counters', 'ewww_reset_reopt_nonce' );
1898
  // Display an alert, and let the user reset the warning if they wish.
1899
  echo "<div id='ewww-image-optimizer-warning-reoptimizations' class='error'><p>" .
1900
  sprintf(
1901
  /* translators: %s: A link to the EWWW IO Tools page */
1902
  esc_html__( 'The EWWW Image Optimizer has detected excessive re-optimization of multiple images. Please use the %s page to Show Re-Optimized Images.', 'ewww-image-optimizer' ),
1903
- "<a href='$debugging_page'>" . esc_html__( 'Tools', 'ewww-image-optimizer' ) . '</a>'
1904
  ) .
1905
- " <a href='$reset_page'>" . esc_html__( 'Reset Counters' ) . '</a></p></div>';
1906
  }
1907
  }
1908
  }
@@ -2029,8 +2061,8 @@ function ewww_image_optimizer_editor_save_pre( $image ) {
2029
  * @return array The unaltered attachment metadata.
2030
  */
2031
  function ewww_image_optimizer_pte_check( $data ) {
2032
- if ( ! empty( $_GET['pte-action'] ) ) {
2033
- if ( 'confirm-images' === $_GET['pte-action'] ) {
2034
  add_filter( 'wp_update_attachment_metadata', 'ewww_image_optimizer_resize_from_meta_data', 15, 2 );
2035
  }
2036
  }
@@ -2072,7 +2104,7 @@ function ewww_image_optimizer_path_renamed( $post, $old_filepath, $new_filepath
2072
  $new_webp = $new_filepath . '.webp';
2073
  if ( ewwwio_is_file( $old_webp ) && ! ewwwio_is_file( $new_webp ) ) {
2074
  ewwwio_debug_message( "renaming $old_webp to $new_webp" );
2075
- rename( $old_webp, $new_webp );
2076
  }
2077
  }
2078
 
@@ -2443,7 +2475,7 @@ function ewww_image_optimizer_resize_dup_check() {
2443
  $editor = wp_get_image_editor( $file );
2444
  $resized_image = $editor->resize( 150, 150, true );
2445
  $new_file = $editor->generate_filename();
2446
- echo $new_file;
2447
  if ( ewwwio_is_file( $new_file ) ) {
2448
  echo '<br>file already exists<br>';
2449
  }
@@ -2456,7 +2488,15 @@ function ewww_image_optimizer_resize_dup_check() {
2456
  function ewww_image_optimizer_admin_menu() {
2457
  // Adds bulk optimize to the media library menu.
2458
  $permissions = apply_filters( 'ewww_image_optimizer_bulk_permissions', '' );
2459
- add_media_page( esc_html__( 'Bulk Optimize', 'ewww-image-optimizer' ), esc_html__( 'Bulk Optimize', 'ewww-image-optimizer' ), $permissions, 'ewww-image-optimizer-bulk', 'ewww_image_optimizer_bulk_preview' );
 
 
 
 
 
 
 
 
2460
  add_submenu_page( null, esc_html__( 'Migrate WebP Images', 'ewww-image-optimizer' ), esc_html__( 'Migrate WebP Images', 'ewww-image-optimizer' ), $permissions, 'ewww-image-optimizer-webp-migrate', 'ewww_image_optimizer_webp_migrate_preview' );
2461
 
2462
  // Add tools page.
@@ -2490,11 +2530,6 @@ function ewww_image_optimizer_admin_menu() {
2490
  'ewww_image_optimizer_network_singlesite_options' // Function to call.
2491
  );
2492
  }
2493
- if ( is_plugin_active( 'image-store/ImStore.php' ) || is_plugin_active_for_network( 'image-store/ImStore.php' ) ) {
2494
- // Adds an optimize page for Image Store galleries and images.
2495
- $ims_menu = 'edit.php?post_type=ims_gallery';
2496
- $ewww_ims_page = add_submenu_page( $ims_menu, esc_html__( 'Image Store Optimize', 'ewww-image-optimizer' ), esc_html__( 'Optimize', 'ewww-image-optimizer' ), 'ims_change_settings', 'ewww-ims-optimize', 'ewww_image_optimizer_ims' );
2497
- }
2498
  }
2499
 
2500
  /**
@@ -2517,7 +2552,7 @@ function ewww_image_optimizer_retina( $id, $retina_path ) {
2517
  $webp_path = $temp_path . '.webp';
2518
  ewwwio_debug_message( "retina webp path: $webp_path" );
2519
  if ( ewwwio_is_file( $webp_path ) ) {
2520
- rename( $webp_path, $retina_path . '.webp' );
2521
  }
2522
  $opt_size = ewww_image_optimizer_filesize( $retina_path );
2523
  ewwwio_debug_message( "retina size: $opt_size" );
@@ -2546,74 +2581,6 @@ function ewww_image_optimizer_retina( $id, $retina_path ) {
2546
  ewwwio_memory( __FUNCTION__ );
2547
  }
2548
 
2549
- /**
2550
- * List IMS images and optimization status.
2551
- *
2552
- * @global object $wpdb
2553
- */
2554
- function ewww_image_optimizer_ims() {
2555
- global $wpdb;
2556
- $ims_columns = get_column_headers( 'ims_gallery' );
2557
- echo "<div class='wrap'><h1>" . esc_html__( 'Image Store Optimization', 'ewww-image-optimizer' ) . '</h1>';
2558
- if ( empty( $_REQUEST['ewww_gid'] ) ) {
2559
- $galleries = $wpdb->get_col( "SELECT ID FROM $wpdb->posts WHERE post_type = 'ims_gallery' ORDER BY ID" );
2560
- if ( ewww_image_optimizer_iterable( $galleries ) ) {
2561
- $gallery_string = implode( ',', $galleries );
2562
- echo '<p>' . esc_html__( 'Choose a gallery or', 'ewww-image-optimizer' ) . ' <a href="' . admin_url( "upload.php?page=ewww-image-optimizer-bulk&ids=$gallery_string" ) . '">' . esc_html__( 'optimize all galleries', 'ewww-image-optimizer' ) . '</a></p>';
2563
- echo '<table class="wp-list-table widefat media" cellspacing="0"><thead><tr><th>' . esc_html__( 'Gallery ID', 'ewww-image-optimizer' ) . '</th><th>' . esc_html__( 'Gallery Name', 'ewww-image-optimizer' ) . '</th><th>' . esc_html__( 'Images', 'ewww-image-optimizer' ) . '</th><th>' . esc_html__( 'Image Optimizer', 'ewww-image-optimizer' ) . '</th></tr></thead>';
2564
- foreach ( $galleries as $gid ) {
2565
- $image_count = $wpdb->get_var( $wpdb->prepare( "SELECT count(ID) FROM $wpdb->posts WHERE post_type = 'ims_image' AND post_mime_type LIKE %s AND post_parent = %d", '%image%', $gid ) );
2566
- $gallery_name = get_the_title( $gid );
2567
- echo "<tr><td>$gid</td>";
2568
- echo "<td><a href='" . admin_url( "edit.php?post_type=ims_gallery&page=ewww-ims-optimize&ewww_gid=$gid" ) . "'>$gallery_name</a></td>";
2569
- echo "<td>$image_count</td>";
2570
- echo "<td><a href='" . admin_url( "upload.php?page=ewww-image-optimizer-bulk&ids=$gid" ) . "'>" . esc_html__( 'Optimize Gallery', 'ewww-image-optimizer' ) . '</a></td></tr>';
2571
- }
2572
- echo '</table>';
2573
- } else {
2574
- echo '<p>' . esc_html__( 'No galleries found', 'ewww-image-optimizer' ) . '</p>';
2575
- }
2576
- } else {
2577
- $gid = (int) $_REQUEST['ewww_gid'];
2578
- $attachments = $wpdb->get_col( $wpdb->prepare( "SELECT ID FROM $wpdb->posts WHERE post_type = 'ims_image' AND post_mime_type LIKE %s AND post_parent = %d ORDER BY ID", '%image%', $gid ) );
2579
- if ( ewww_image_optimizer_iterable( $attachments ) ) {
2580
- echo "<p><a href='" . admin_url( "upload.php?page=ewww-image-optimizer-bulk&ids=$gid" ) . "'>" . esc_html__( 'Optimize Gallery', 'ewww-image-optimizer' ) . '</a></p>';
2581
- echo '<table class="wp-list-table widefat media" cellspacing="0"><thead><tr><th>ID</th><th>&nbsp;</th><th>' . esc_html__( 'Title', 'ewww-image-optimizer' ) . '</th><th>' . esc_html__( 'Gallery', 'ewww-image-optimizer' ) . '</th><th>' . esc_html__( 'Image Optimizer', 'ewww-image-optimizer' ) . '</th></tr></thead>';
2582
- $alternate = true;
2583
- foreach ( $attachments as $id ) {
2584
- $meta = get_metadata( 'post', $id );
2585
- if ( empty( $meta['_wp_attachment_metadata'] ) ) {
2586
- continue;
2587
- }
2588
- $meta = maybe_unserialize( $meta['_wp_attachment_metadata'][0] );
2589
- $image_name = get_the_title( $id );
2590
- $gallery_name = get_the_title( $gid );
2591
- $image_url = esc_url( $meta['sizes']['mini']['url'] );
2592
- ?>
2593
- <tr
2594
- <?php
2595
- if ( $alternate ) {
2596
- echo " class='alternate'";
2597
- }
2598
- ?>
2599
- ><td><?php echo $id; ?></td>
2600
- <?php
2601
- echo "<td style='width:80px' class='column-icon'><img src='$image_url' /></td>";
2602
- echo "<td class='title'>$image_name</td>";
2603
- echo "<td>$gallery_name</td><td>";
2604
- ewww_image_optimizer_custom_column( 'ewww-image-optimizer', $id );
2605
- echo '</td></tr>';
2606
- $alternate = ! $alternate;
2607
- }
2608
- echo '</table>';
2609
- } else {
2610
- echo '<p>' . esc_html__( 'No images found', 'ewww-image-optimizer' ) . '</p>';
2611
- }
2612
- } // End if().
2613
- echo '</div>';
2614
- return;
2615
- }
2616
-
2617
  /**
2618
  * Optimize MyArcade screenshots and thumbs.
2619
  *
@@ -2845,29 +2812,29 @@ function ewww_image_optimizer_aux_paths_sanitize( $input ) {
2845
  );
2846
  continue;
2847
  }
2848
- if ( ( ( $abspath && strpos( $path, ABSPATH ) === 0 ) || strpos( $path, $upload_path ) === 0 ) && is_dir( $path ) ) {
2849
  $path_array[] = $path;
2850
  continue;
2851
  }
2852
  // If they put in a relative path.
2853
- if ( $abspath && is_dir( ABSPATH . ltrim( $path, '/' ) ) ) {
2854
  $path_array[] = ABSPATH . ltrim( $path, '/' );
2855
  continue;
2856
  }
2857
  // Or a path relative to the upload dir?
2858
- if ( is_dir( $upload_path . ltrim( $path, '/' ) ) ) {
2859
  $path_array[] = $upload_path . ltrim( $path, '/' );
2860
  continue;
2861
  }
2862
  // What if they put in a url?
2863
  $pathabsurl = ABSPATH . ltrim( str_replace( get_site_url(), '', $path ), '/' );
2864
- if ( $abspath && is_dir( $pathabsurl ) ) {
2865
  $path_array[] = $pathabsurl;
2866
  continue;
2867
  }
2868
  // Or a url in the uploads folder?
2869
  $pathupurl = $upload_path . ltrim( str_replace( $upload_dir['baseurl'], '', $path ), '/' );
2870
- if ( is_dir( $pathupurl ) ) {
2871
  $path_array[] = $pathupurl;
2872
  continue;
2873
  }
@@ -3059,6 +3026,24 @@ function ewww_image_optimizer_adjust_big_image_threshold( $size, $imagesize, $fi
3059
  return $max_size;
3060
  }
3061
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3062
  /**
3063
  * Check filesize, and prevent errors by ensuring file exists, and that the cache has been cleared.
3064
  *
@@ -3068,17 +3053,69 @@ function ewww_image_optimizer_adjust_big_image_threshold( $size, $imagesize, $fi
3068
  function ewww_image_optimizer_filesize( $file ) {
3069
  $file = realpath( $file );
3070
  if ( ewwwio_is_file( $file ) ) {
 
 
3071
  // Flush the cache for filesize.
3072
  clearstatcache();
3073
  // Find out the size of the new PNG file.
3074
- return filesize( $file );
3075
  } else {
3076
  return 0;
3077
  }
3078
  }
3079
 
3080
  /**
3081
- * Check if file exists, and that is is local rather than using a protocol like http:// or phar://
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3082
  *
3083
  * @param string $file The path of the file to check.
3084
  * @return bool True if the file exists and is local, false otherwise.
@@ -3090,6 +3127,8 @@ function ewwwio_is_file( $file ) {
3090
  if ( false !== strpos( $file, 'phar://' ) ) {
3091
  return false;
3092
  }
 
 
3093
  $file = realpath( $file );
3094
  $wp_dir = realpath( ABSPATH );
3095
  $upload_dir = wp_get_upload_dir();
@@ -3111,7 +3150,31 @@ function ewwwio_is_file( $file ) {
3111
  ) {
3112
  return false;
3113
  }
3114
- return is_file( $file );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3115
  }
3116
 
3117
  /**
@@ -3146,16 +3209,18 @@ function ewwwio_delete_file( $file, $dir = '' ) {
3146
  * @param string $mode The mode to apply to the file.
3147
  */
3148
  function ewwwio_chmod( $file, $mode ) {
 
 
3149
  $file = realpath( $file );
3150
  $upload_dir = wp_get_upload_dir();
3151
  if ( false !== strpos( $file, $upload_dir['basedir'] ) ) {
3152
- return chmod( $file, $mode );
3153
  }
3154
  if ( false !== strpos( $file, WP_CONTENT_DIR ) ) {
3155
- return chmod( $file, $mode );
3156
  }
3157
  if ( false !== strpos( $file, ABSPATH ) ) {
3158
- return chmod( $file, $mode );
3159
  }
3160
  return false;
3161
  }
@@ -3176,37 +3241,41 @@ function ewww_image_optimizer_iterable( $var ) {
3176
  */
3177
  function ewww_image_optimizer_manual() {
3178
  ewwwio_debug_message( '<b>' . __FUNCTION__ . '()</b>' );
 
 
3179
  global $ewww_defer;
3180
  $ewww_defer = false;
3181
  // Check permissions of current user.
3182
  $permissions = apply_filters( 'ewww_image_optimizer_manual_permissions', '' );
3183
- if ( false === current_user_can( $permissions ) ) {
3184
  // Display error message if insufficient permissions.
3185
  if ( ! wp_doing_ajax() ) {
3186
  wp_die( esc_html__( 'You do not have permission to optimize images.', 'ewww-image-optimizer' ) );
3187
  }
3188
  ewwwio_ob_clean();
3189
- wp_die( ewwwio_json_encode( array( 'error' => esc_html__( 'You do not have permission to optimize images.', 'ewww-image-optimizer' ) ) ) );
3190
  }
3191
  // Make sure we didn't accidentally get to this page without an attachment to work on.
3192
- if ( false === isset( $_REQUEST['ewww_attachment_ID'] ) ) {
3193
  // Display an error message since we don't have anything to work on.
3194
  if ( ! wp_doing_ajax() ) {
3195
- wp_die( esc_html__( 'No attachment ID was provided.', 'ewww-image-optimizer' ) );
3196
  }
3197
  ewwwio_ob_clean();
3198
- wp_die( ewwwio_json_encode( array( 'error' => esc_html__( 'No attachment ID was provided.', 'ewww-image-optimizer' ) ) ) );
3199
  }
3200
  session_write_close();
3201
- // Store the attachment ID value.
3202
- $attachment_id = intval( $_REQUEST['ewww_attachment_ID'] );
3203
- if ( empty( $_REQUEST['ewww_manual_nonce'] ) || ! wp_verify_nonce( $_REQUEST['ewww_manual_nonce'], 'ewww-manual' ) ) {
3204
  if ( ! wp_doing_ajax() ) {
3205
  wp_die( esc_html__( 'Access denied.', 'ewww-image-optimizer' ) );
3206
  }
3207
  ewwwio_ob_clean();
3208
- wp_die( ewwwio_json_encode( array( 'error' => esc_html__( 'Access denied.', 'ewww-image-optimizer' ) ) ) );
3209
  }
 
 
 
 
3210
  // Retrieve the existing attachment metadata.
3211
  $original_meta = wp_get_attachment_metadata( $attachment_id );
3212
  // If the call was to optimize...
@@ -3222,7 +3291,7 @@ function ewww_image_optimizer_manual() {
3222
  wp_die( esc_html__( 'Access denied.', 'ewww-image-optimizer' ) );
3223
  }
3224
  ewwwio_ob_clean();
3225
- wp_die( ewwwio_json_encode( array( 'error' => esc_html__( 'Access denied.', 'ewww-image-optimizer' ) ) ) );
3226
  }
3227
  $basename = '';
3228
  if ( is_array( $new_meta ) && ! empty( $new_meta['file'] ) ) {
@@ -3238,24 +3307,22 @@ function ewww_image_optimizer_manual() {
3238
  wp_die( esc_html__( 'License exceeded', 'ewww-image-optimizer' ) );
3239
  }
3240
  ewwwio_ob_clean();
3241
- wp_die( ewwwio_json_encode( array( 'error' => esc_html__( 'License exceeded', 'ewww-image-optimizer' ) ) ) );
3242
  }
3243
- $success = ewww_image_optimizer_custom_column( 'ewww-image-optimizer', $attachment_id, $new_meta, true );
3244
  ewww_image_optimizer_debug_log();
3245
  // Do a redirect, if this was called via GET.
3246
  if ( ! wp_doing_ajax() ) {
3247
  // Store the referring webpage location.
3248
  $sendback = wp_get_referer();
3249
- // Sanitize the referring webpage location.
3250
- $sendback = preg_replace( '|[^a-z0-9-~+_.?#=&;,/:]|i', '', $sendback );
3251
  // Send the user back where they came from.
3252
- wp_redirect( $sendback );
3253
- return;
3254
  }
3255
  ewwwio_memory( __FUNCTION__ );
3256
  ewwwio_ob_clean();
3257
  wp_die(
3258
- ewwwio_json_encode(
3259
  array(
3260
  'success' => $success,
3261
  'basename' => $basename,
@@ -3348,26 +3415,26 @@ function ewww_image_optimizer_cloud_restore_single_image_handler() {
3348
  if ( false === current_user_can( $permissions ) ) {
3349
  // Display error message if insufficient permissions.
3350
  ewwwio_ob_clean();
3351
- wp_die( ewwwio_json_encode( array( 'error' => esc_html__( 'You do not have permission to optimize images.', 'ewww-image-optimizer' ) ) ) );
3352
  }
3353
  // Make sure we didn't accidentally get to this page without an attachment to work on.
3354
  if ( empty( $_REQUEST['ewww_image_id'] ) ) {
3355
  // Display an error message since we don't have anything to work on.
3356
  ewwwio_ob_clean();
3357
- wp_die( ewwwio_json_encode( array( 'error' => esc_html__( 'No image ID was provided.', 'ewww-image-optimizer' ) ) ) );
3358
  }
3359
- if ( empty( $_REQUEST['ewww_wpnonce'] ) || ! wp_verify_nonce( $_REQUEST['ewww_wpnonce'], 'ewww-image-optimizer-tools' ) ) {
3360
  ewwwio_ob_clean();
3361
- wp_die( ewwwio_json_encode( array( 'error' => esc_html__( 'Access token has expired, please reload the page.', 'ewww-image-optimizer' ) ) ) );
3362
  }
3363
  session_write_close();
3364
  $image = (int) $_REQUEST['ewww_image_id'];
3365
  if ( ewww_image_optimizer_cloud_restore_single_image( $image ) ) {
3366
  ewwwio_ob_clean();
3367
- wp_die( ewwwio_json_encode( array( 'success' => 1 ) ) );
3368
  }
3369
  ewwwio_ob_clean();
3370
- wp_die( ewwwio_json_encode( array( 'error' => esc_html__( 'Unable to restore image.', 'ewww-image-optimizer' ) ) ) );
3371
  }
3372
 
3373
  /**
@@ -3433,7 +3500,7 @@ function ewww_image_optimizer_cloud_restore_single_image( $image ) {
3433
  return false;
3434
  }
3435
  if ( empty( $old_type ) || $old_type === $new_type ) {
3436
- if ( rename( $image['path'] . '.tmp', $image['path'] ) ) {
3437
  if ( ewwwio_is_file( $image['path'] . '.webp' ) && is_writable( $image['path'] . '.webp' ) ) {
3438
  unlink( $image['path'] . '.webp' );
3439
  }
@@ -3836,10 +3903,8 @@ function ewww_image_optimizer_cloud_verify( $cache = true, $api_key = '' ) {
3836
  if ( ! empty( $api_key ) ) {
3837
  $sanitize = true;
3838
  }
3839
- if ( empty( $api_key ) && ! ( ! empty( $_REQUEST['option_page'] ) && 'ewww_image_optimizer_options' === $_REQUEST['option_page'] ) ) {
3840
  $api_key = ewww_image_optimizer_get_option( 'ewww_image_optimizer_cloud_key' );
3841
- } elseif ( empty( $api_key ) && ! empty( $_POST['ewww_image_optimizer_cloud_key'] ) ) {
3842
- $api_key = $_POST['ewww_image_optimizer_cloud_key'];
3843
  }
3844
  if ( empty( $api_key ) ) {
3845
  if ( ewww_image_optimizer_get_option( 'ewww_image_optimizer_jpg_level' ) > 10 ) {
@@ -3996,42 +4061,34 @@ function ewww_image_optimizer_cloud_quota( $raw = false ) {
3996
  return $quota;
3997
  }
3998
  if ( ! $quota['licensed'] && $quota['consumed'] > 0 ) {
3999
- return esc_html(
4000
- sprintf(
4001
- /* translators: 1: Number of images 2: Number of days until renewal */
4002
- _n( 'optimized %1$d images, renewal is in %2$d day.', 'optimized %1$d images, renewal is in %2$d days.', $quota['days'], 'ewww-image-optimizer' ),
4003
- $quota['consumed'],
4004
- $quota['days']
4005
- )
4006
  );
4007
  } elseif ( ! $quota['licensed'] && $quota['consumed'] < 0 ) {
4008
- return esc_html(
4009
- sprintf(
4010
- /* translators: 1: Number of image credits for the compression API */
4011
- _n( '%1$d image credit remaining.', '%1$d image credits remaining.', abs( $quota['consumed'] ), 'ewww-image-optimizer' ),
4012
- abs( $quota['consumed'] )
4013
- )
4014
  );
4015
  } elseif ( $quota['licensed'] > 0 && $quota['consumed'] <= 0 ) {
4016
  $real_quota = (int) $quota['licensed'] - (int) $quota['consumed'];
4017
- return esc_html(
4018
- sprintf(
4019
- /* translators: 1: Number of image credits for the compression API */
4020
- _n( '%1$d image credit remaining.', '%1$d image credits remaining.', $real_quota, 'ewww-image-optimizer' ),
4021
- $real_quota
4022
- )
4023
  );
4024
  } elseif ( ! $quota['licensed'] && ! $quota['consumed'] && ! $quota['days'] && ! $quota['metered'] ) {
4025
- return esc_html__( 'no credits remaining, please purchase more.', 'ewww-image-optimizer' );
4026
  } else {
4027
- return esc_html(
4028
- sprintf(
4029
- /* translators: 1: Number of image credits used 2: Number of image credits available 3: days until subscription renewal */
4030
- _n( 'used %1$d of %2$d, usage will reset in %3$d day.', 'used %1$d of %2$d, usage will reset in %3$d days.', $quota['days'], 'ewww-image-optimizer' ),
4031
- $quota['consumed'],
4032
- $quota['licensed'],
4033
- $quota['days']
4034
- )
4035
  );
4036
  }
4037
  }
@@ -4090,6 +4147,10 @@ function ewww_image_optimizer_cloud_optimizer( $file, $type, $convert = false, $
4090
  ewwwio_debug_message( 'license exceeded, image not processed' );
4091
  return array( $file, false, 'exceeded', 0, '' );
4092
  }
 
 
 
 
4093
  if ( ewww_image_optimizer_get_option( 'ewww_image_optimizer_metadata_skip_full' ) && $fullsize ) {
4094
  $metadata = 1;
4095
  } elseif ( ewww_image_optimizer_get_option( 'ewww_image_optimizer_metadata_remove' ) ) {
@@ -4152,7 +4213,7 @@ function ewww_image_optimizer_cloud_optimizer( $file, $type, $convert = false, $
4152
  if ( is_object( $ewww_image ) && $ewww_image->file === $file && ! empty( $ewww_image->backup ) ) {
4153
  $hash = $ewww_image->backup;
4154
  }
4155
- if ( empty( $hash ) && ( ! empty( $_REQUEST['ewww_force'] ) || ! empty( $_REQUEST['ewww_force_smart'] ) ) ) {
4156
  $image = ewww_image_optimizer_find_already_optimized( $file );
4157
  if ( ! empty( $image ) && is_array( $image ) && ! empty( $image['backup'] ) ) {
4158
  $hash = $image['backup'];
@@ -4221,7 +4282,7 @@ function ewww_image_optimizer_cloud_optimizer( $file, $type, $convert = false, $
4221
  $payload .= 'Content-Disposition: form-data; name="file"; filename="' . wp_basename( $file ) . '"' . "\r\n";
4222
  $payload .= 'Content-Type: ' . $type . "\r\n";
4223
  $payload .= "\r\n";
4224
- $payload .= file_get_contents( $file );
4225
  $payload .= "\r\n";
4226
  $payload .= '--' . $boundary;
4227
  $payload .= 'Content-Disposition: form-data; name="submitHandler"' . "\r\n";
@@ -4261,18 +4322,19 @@ function ewww_image_optimizer_cloud_optimizer( $file, $type, $convert = false, $
4261
  } elseif ( ewww_image_optimizer_mimetype( $tempfile, 'i' ) === $type ) {
4262
  $newsize = filesize( $tempfile );
4263
  ewwwio_debug_message( "cloud results: $newsize (new) vs. $orig_size (original)" );
4264
- rename( $tempfile, $file );
4265
  } elseif ( ewww_image_optimizer_mimetype( $tempfile, 'i' ) === 'image/webp' ) {
4266
  $newsize = filesize( $tempfile );
4267
  ewwwio_debug_message( "cloud results: $newsize (new) vs. $orig_size (original)" );
4268
- rename( $tempfile, $newfile );
4269
  } elseif ( ! is_null( $newtype ) && ! is_null( $newfile ) && ewww_image_optimizer_mimetype( $tempfile, 'i' ) === $newtype ) {
4270
- $converted = true;
4271
- $newsize = filesize( $tempfile );
4272
- ewwwio_debug_message( "cloud results: $newsize (new) vs. $orig_size (original)" );
4273
  ewwwio_debug_message( "renaming file from $tempfile to $newfile" );
4274
- rename( $tempfile, $newfile );
4275
- $file = $newfile;
 
 
 
 
4276
  } else {
4277
  ewwwio_delete_file( $tempfile );
4278
  }
@@ -4316,6 +4378,8 @@ function ewww_image_optimizer_cloud_autorotate( $file, $type ) {
4316
  ewwwio_debug_message( 'license exceeded, image not rotated' );
4317
  return false;
4318
  }
 
 
4319
  ewwwio_debug_message( "file: $file " );
4320
  ewwwio_debug_message( "type: $type" );
4321
  $api_key = ewww_image_optimizer_get_option( 'ewww_image_optimizer_cloud_key' );
@@ -4355,7 +4419,7 @@ function ewww_image_optimizer_cloud_autorotate( $file, $type ) {
4355
  $payload .= 'Content-Disposition: form-data; name="file"; filename="' . wp_basename( $file ) . '"' . "\r\n";
4356
  $payload .= 'Content-Type: ' . $type . "\r\n";
4357
  $payload .= "\r\n";
4358
- $payload .= file_get_contents( $file );
4359
  $payload .= "\r\n";
4360
  $payload .= '--' . $boundary;
4361
  $payload .= 'Content-Disposition: form-data; name="submitHandler"' . "\r\n";
@@ -4385,14 +4449,14 @@ function ewww_image_optimizer_cloud_autorotate( $file, $type ) {
4385
  if ( preg_match( '/exceeded/', $response['body'] ) ) {
4386
  ewwwio_debug_message( 'License Exceeded' );
4387
  set_transient( 'ewww_image_optimizer_cloud_status', 'exceeded', 3600 );
4388
- unlink( $tempfile );
4389
  } elseif ( ewww_image_optimizer_mimetype( $tempfile, 'i' ) === $type ) {
4390
  $newsize = filesize( $tempfile );
4391
  ewwwio_debug_message( "cloud rotation success: $newsize (new) vs. $orig_size (original)" );
4392
- rename( $tempfile, $file );
4393
  return true;
4394
  } else {
4395
- unlink( $tempfile );
4396
  }
4397
  ewwwio_memory( __FUNCTION__ );
4398
  return false;
@@ -4415,7 +4479,7 @@ function ewww_image_optimizer_cloud_backup( $file ) {
4415
  if ( ! ewww_image_optimizer_get_option( 'ewww_image_optimizer_backup_files' ) ) {
4416
  return false;
4417
  }
4418
- if ( ! ewwwio_is_file( $file ) || ! is_readable( $file ) ) {
4419
  return false;
4420
  }
4421
  if ( ! ewwwio_check_memory_available( filesize( $file ) * 1.1 ) ) { // 1.1 = upload buffer (filesize) multiplied by a factor of 1.1 for extra wiggle room.
@@ -4452,6 +4516,8 @@ function ewww_image_optimizer_cloud_backup( $file ) {
4452
  );
4453
 
4454
  global $ewww_image;
 
 
4455
  if ( is_object( $ewww_image ) && $ewww_image->file === $file && ! empty( $ewww_image->backup ) ) {
4456
  $post_fields['backup'] = $ewww_image->backup;
4457
  } elseif ( is_object( $ewww_image ) && $ewww_image->file === $file && empty( $ewww_image->backup ) ) {
@@ -4475,7 +4541,7 @@ function ewww_image_optimizer_cloud_backup( $file ) {
4475
  $payload .= 'Content-Disposition: form-data; name="file"; filename="' . wp_basename( $file ) . '"' . "\r\n";
4476
  $payload .= 'Content-Type: ' . ewww_image_optimizer_mimetype( $file, 'i' ) . "\r\n";
4477
  $payload .= "\r\n";
4478
- $payload .= file_get_contents( $file );
4479
  $payload .= "\r\n";
4480
  $payload .= '--' . $boundary;
4481
  $payload .= 'Content-Disposition: form-data; name="submitHandler"' . "\r\n";
@@ -4555,6 +4621,8 @@ function ewww_image_optimizer_cloud_resize( $file, $type, $dst_x, $dst_y, $src_x
4555
  ewwwio_debug_message( 'license exceeded, image not rotated' );
4556
  return new WP_Error( 'invalid_key', __( 'License Exceeded', 'ewww-image-optimizer' ) );
4557
  }
 
 
4558
  ewwwio_debug_message( "file: $file " );
4559
  ewwwio_debug_message( "width: $dst_w" );
4560
  ewwwio_debug_message( "height: $dst_h" );
@@ -4603,7 +4671,7 @@ function ewww_image_optimizer_cloud_resize( $file, $type, $dst_x, $dst_y, $src_x
4603
  $payload .= 'Content-Disposition: form-data; name="file"; filename="' . wp_basename( $file ) . '"' . "\r\n";
4604
  $payload .= 'Content-Type: ' . $type . "\r\n";
4605
  $payload .= "\r\n";
4606
- $payload .= file_get_contents( $file );
4607
  $payload .= "\r\n";
4608
  $payload .= '--' . $boundary;
4609
  $payload .= 'Content-Disposition: form-data; name="submitHandler"' . "\r\n";
@@ -4633,16 +4701,16 @@ function ewww_image_optimizer_cloud_resize( $file, $type, $dst_x, $dst_y, $src_x
4633
  if ( false !== strpos( $response['body'], 'error' ) ) {
4634
  $response = json_decode( $response['body'], true );
4635
  ewwwio_debug_message( 'API resize error: ' . $response['error'] );
4636
- unlink( $tempfile );
4637
  return new WP_Error( 'image_resize_error', $response['error'] );
4638
  } elseif ( false !== strpos( ewww_image_optimizer_mimetype( $tempfile, 'i' ), 'image' ) ) {
4639
  $newsize = filesize( $tempfile );
4640
  ewww_image_optimizer_is_animated( $tempfile );
4641
  ewwwio_debug_message( "API resize success: $newsize (new) vs. $orig_size (original)" );
4642
- unlink( $tempfile );
4643
  return $response['body'];
4644
  }
4645
- unlink( $tempfile );
4646
  ewwwio_debug_message( 'API resize error: unknown' );
4647
  return new WP_Error( 'image_resize_error', __( 'Unknown resize error', 'ewww-image-optimizer' ) );
4648
  }
@@ -4706,20 +4774,21 @@ function ewww_image_optimizer_db_init() {
4706
 
4707
  $prefix = $ewwwdb->set_prefix( $table_prefix );
4708
 
4709
- if ( is_wp_error( $prefix ) ) {
4710
- wp_load_translations_early();
4711
- wp_die(
4712
- sprintf(
4713
- /* translators: 1: $table_prefix 2: wp-config.php */
4714
- __( '<strong>ERROR</strong>: %1$s in %2$s can only contain numbers, letters, and underscores.' ),
4715
- '<code>$table_prefix</code>',
4716
- '<code>wp-config.php</code>'
4717
- )
4718
- );
4719
  }
 
4720
  if ( ! isset( $ewwwdb->ewwwio_images ) ) {
4721
  $ewwwdb->ewwwio_images = $ewwwdb->prefix . 'ewwwio_images';
4722
  }
 
 
 
4723
  }
4724
 
4725
  /**
@@ -4849,6 +4918,7 @@ function ewww_image_optimizer_check_table( $file, $orig_size ) {
4849
  ewwwio_debug_message( '<b>' . __FUNCTION__ . '()</b>' );
4850
  ewwwio_debug_message( "checking for $file with size: $orig_size" );
4851
  global $ewww_image;
 
4852
  $image = array();
4853
  if ( ! is_object( $ewww_image ) || ! $ewww_image instanceof EWWW_Image || $ewww_image->file !== $file ) {
4854
  $ewww_image = new EWWW_Image( 0, '', $file );
@@ -4868,7 +4938,7 @@ function ewww_image_optimizer_check_table( $file, $orig_size ) {
4868
  ewwwio_debug_message( "already optimized: {$image['path']} - $already_optimized" );
4869
  ewwwio_memory( __FUNCTION__ );
4870
  // Make sure the image isn't pending.
4871
- if ( $image['pending'] && empty( $_REQUEST['ewww_force_smart'] ) ) {
4872
  global $wpdb;
4873
  $wpdb->update(
4874
  $wpdb->ewwwio_images,
@@ -4911,7 +4981,7 @@ function ewww_image_optimizer_update_table( $attachment, $opt_size, $orig_size,
4911
  // First check if the image was converted, so we don't orphan records.
4912
  if ( $original && $original !== $attachment ) {
4913
  $already_optimized = ewww_image_optimizer_find_already_optimized( $original );
4914
- $converted = $original;
4915
  } else {
4916
  $already_optimized = ewww_image_optimizer_find_already_optimized( $attachment );
4917
  if ( is_array( $already_optimized ) && ! empty( $already_optimized['converted'] ) ) {
@@ -5088,14 +5158,14 @@ function ewww_image_optimizer_aux_images_loop( $attachment = null, $auto = false
5088
  $output = array();
5089
  // Verify that an authorized user has started the optimizer.
5090
  $permissions = apply_filters( 'ewww_image_optimizer_bulk_permissions', '' );
5091
- if ( ! $auto && ( empty( $_REQUEST['ewww_wpnonce'] ) || ! wp_verify_nonce( $_REQUEST['ewww_wpnonce'], 'ewww-image-optimizer-bulk' ) || ! current_user_can( $permissions ) ) ) {
5092
  $output['error'] = esc_html__( 'Access token has expired, please reload the page.', 'ewww-image-optimizer' );
5093
- wp_die( ewwwio_json_encode( $output ) );
5094
  }
5095
  session_write_close();
5096
  if ( ! empty( $_REQUEST['ewww_wpnonce'] ) ) {
5097
  // Find out if our nonce is on it's last leg/tick.
5098
- $tick = wp_verify_nonce( $_REQUEST['ewww_wpnonce'], 'ewww-image-optimizer-bulk' );
5099
  if ( 2 === $tick ) {
5100
  ewwwio_debug_message( 'nonce on its last leg' );
5101
  $output['new_nonce'] = wp_create_nonce( 'ewww-image-optimizer-bulk' );
@@ -5143,7 +5213,7 @@ function ewww_image_optimizer_aux_images_loop( $attachment = null, $auto = false
5143
  if ( ! empty( $ewww_status ) && preg_match( '/exceeded/', $ewww_status ) ) {
5144
  if ( ! $auto ) {
5145
  $output['error'] = esc_html__( 'License Exceeded', 'ewww-image-optimizer' );
5146
- echo ewwwio_json_encode( $output );
5147
  }
5148
  if ( $cli ) {
5149
  WP_CLI::error( __( 'License Exceeded', 'ewww-image-optimizer' ) );
@@ -5172,9 +5242,9 @@ function ewww_image_optimizer_aux_images_loop( $attachment = null, $auto = false
5172
  $next_file = ewww_image_optimizer_absolutize_path( $wpdb->get_var( "SELECT path FROM $wpdb->ewwwio_images WHERE pending=1 LIMIT 1" ) );
5173
  if ( ! empty( $next_file ) ) {
5174
  $loading_image = plugins_url( '/images/wpspin.gif', __FILE__ );
5175
- $output['next_file'] = '<p>' . esc_html__( 'Optimizing', 'ewww-image-optimizer' ) . ' <b>' . esc_html( $next_file ) . "</b>&nbsp;<img src='$loading_image' alt='loading'/></p>";
5176
  }
5177
- echo ewwwio_json_encode( $output );
5178
  ewwwio_memory( __FUNCTION__ );
5179
  wp_die();
5180
  }
@@ -5186,29 +5256,39 @@ function ewww_image_optimizer_aux_images_loop( $attachment = null, $auto = false
5186
  }
5187
 
5188
  /**
5189
- * Looks for a retina version of the original file so that we can optimize that too.
5190
- *
5191
- * @global object $ewww_image Contains more information about the image currently being processed.
5192
  *
5193
- * @param string $orig_path Filename of the 'normal' image.
5194
- * @param bool $return_path True returns the path of the retina image and skips optimization.
5195
  * @param bool $validate_file True verifies the file exists.
5196
- * @return string The filename of the retina image.
5197
  */
5198
- function ewww_image_optimizer_hidpi_optimize( $orig_path, $return_path = false, $validate_file = true ) {
5199
- ewwwio_debug_message( '<b>' . __FUNCTION__ . '()</b>' );
5200
  $hidpi_suffix = apply_filters( 'ewww_image_optimizer_hidpi_suffix', '@2x' );
5201
  $pathinfo = pathinfo( $orig_path );
5202
  if ( empty( $pathinfo['dirname'] ) || empty( $pathinfo['filename'] ) || empty( $pathinfo['extension'] ) ) {
5203
- return;
5204
  }
5205
  $hidpi_path = $pathinfo['dirname'] . '/' . $pathinfo['filename'] . $hidpi_suffix . '.' . $pathinfo['extension'];
5206
  if ( $validate_file && ! ewwwio_is_file( $hidpi_path ) ) {
5207
- return;
5208
  }
5209
- if ( $return_path ) {
5210
- ewwwio_debug_message( "found retina at $hidpi_path" );
5211
- return $hidpi_path;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5212
  }
5213
  global $ewww_image;
5214
  if ( is_object( $ewww_image ) && $ewww_image instanceof EWWW_Image ) {
@@ -5442,7 +5522,7 @@ function ewww_image_optimizer_remote_fetch( $id, $meta ) {
5442
  wp_mkdir_p( dirname( $filename ) );
5443
  }
5444
  if ( ! ewwwio_is_file( $filename ) ) {
5445
- rename( $temp_file, $filename );
5446
  } else {
5447
  unlink( $temp_file );
5448
  }
@@ -5476,7 +5556,7 @@ function ewww_image_optimizer_remote_fetch( $id, $meta ) {
5476
  }
5477
  // If this is a unique size.
5478
  if ( ! $dup_size ) {
5479
- $resize_path = $base_dir . $data['file'];
5480
  $resize_url = $data['gs_link'];
5481
  if ( ewwwio_is_file( $resize_path ) ) {
5482
  continue;
@@ -5487,7 +5567,7 @@ function ewww_image_optimizer_remote_fetch( $id, $meta ) {
5487
  if ( ! is_dir( dirname( $resize_path ) ) ) {
5488
  wp_mkdir_p( dirname( $resize_path ) );
5489
  }
5490
- rename( $temp_file, $resize_path );
5491
  }
5492
  }
5493
  // Store info on the sizes we've processed, so we can check the list for duplicate sizes.
@@ -5511,7 +5591,7 @@ function ewww_image_optimizer_remote_fetch( $id, $meta ) {
5511
  wp_mkdir_p( dirname( $filename ) );
5512
  }
5513
  if ( ! ewwwio_is_file( $filename ) ) {
5514
- rename( $temp_file, $filename );
5515
  } else {
5516
  unlink( $temp_file );
5517
  }
@@ -5531,7 +5611,7 @@ function ewww_image_optimizer_remote_fetch( $id, $meta ) {
5531
  if ( ! is_dir( $base_dir ) ) {
5532
  wp_mkdir_p( $base_dir );
5533
  }
5534
- rename( $temp_file, $resize_path );
5535
  }
5536
  }
5537
  }
@@ -5574,7 +5654,7 @@ function ewww_image_optimizer_remote_fetch( $id, $meta ) {
5574
  if ( ! is_dir( dirname( $resize_path ) ) ) {
5575
  wp_mkdir_p( dirname( $resize_path ) );
5576
  }
5577
- rename( $temp_file, $resize_path );
5578
  }
5579
  }
5580
  // Store info on the sizes we've processed, so we can check the list for duplicate sizes.
@@ -5595,7 +5675,7 @@ function ewww_image_optimizer_remote_fetch( $id, $meta ) {
5595
  wp_mkdir_p( dirname( $filename ) );
5596
  }
5597
  if ( ! ewwwio_is_file( $filename ) ) {
5598
- rename( $temp_file, $filename );
5599
  } else {
5600
  unlink( $temp_file );
5601
  }
@@ -5615,7 +5695,7 @@ function ewww_image_optimizer_remote_fetch( $id, $meta ) {
5615
  if ( ! is_dir( $base_dir ) ) {
5616
  wp_mkdir_p( $base_dir );
5617
  }
5618
- rename( $temp_file, $resize_path );
5619
  }
5620
  }
5621
  }
@@ -5658,7 +5738,7 @@ function ewww_image_optimizer_remote_fetch( $id, $meta ) {
5658
  if ( ! is_dir( dirname( $resize_path ) ) ) {
5659
  wp_mkdir_p( dirname( $resize_path ) );
5660
  }
5661
- rename( $temp_file, $resize_path );
5662
  }
5663
  }
5664
  // Store info on the sizes we've processed, so we can check the list for duplicate sizes.
@@ -6003,20 +6083,25 @@ function ewww_image_optimizer_should_resize_other_image( $file ) {
6003
  function ewww_image_optimizer_resize_upload( $file ) {
6004
  // Parts adapted from Imsanity (THANKS Jason!).
6005
  ewwwio_debug_message( '<b>' . __FUNCTION__ . '()</b>' );
 
6006
  if ( ! $file ) {
6007
  return false;
6008
  }
6009
- if ( ! empty( $_REQUEST['ewww_webp_only'] ) ) {
6010
  return false;
6011
  }
6012
  if ( function_exists( 'wp_raise_memory_limit' ) ) {
6013
  wp_raise_memory_limit( 'image' );
6014
  }
6015
- if ( ! empty( $_REQUEST['post_id'] ) || ( ! empty( $_REQUEST['action'] ) && 'upload-attachment' === $_REQUEST['action'] ) || ( ! empty( $_SERVER['HTTP_REFERER'] ) && strpos( $_SERVER['HTTP_REFERER'], 'media-new.php' ) ) ) {
 
 
 
 
6016
  ewwwio_debug_message( 'resizing image from media library or attached to post' );
6017
  $maxwidth = ewww_image_optimizer_get_option( 'ewww_image_optimizer_maxmediawidth' );
6018
  $maxheight = ewww_image_optimizer_get_option( 'ewww_image_optimizer_maxmediaheight' );
6019
- } elseif ( ! empty( $_SERVER['HTTP_REFERER'] ) && strpos( $_SERVER['HTTP_REFERER'], '/post.php' ) ) {
6020
  ewwwio_debug_message( 'resizing image from the post/page editor' );
6021
  $maxwidth = ewww_image_optimizer_get_option( 'ewww_image_optimizer_maxmediawidth' );
6022
  $maxheight = ewww_image_optimizer_get_option( 'ewww_image_optimizer_maxmediaheight' );
@@ -6030,8 +6115,8 @@ function ewww_image_optimizer_resize_upload( $file ) {
6030
  $maxheight = ewww_image_optimizer_get_option( 'ewww_image_optimizer_maxmediaheight' );
6031
  }
6032
  }
6033
- if ( ! empty( $_SERVER['HTTP_REFERER'] ) ) {
6034
- ewwwio_debug_message( 'uploaded from: ' . $_SERVER['HTTP_REFERER'] );
6035
  }
6036
 
6037
  /**
@@ -6185,7 +6270,7 @@ function ewww_image_optimizer_resize_upload( $file ) {
6185
  ewww_image_optimizer_cloud_backup( $file );
6186
  $new_type = (string) ewww_image_optimizer_mimetype( $new_file, 'i' );
6187
  if ( $type === $new_type ) {
6188
- rename( $new_file, $file );
6189
  } else {
6190
  ewwwio_debug_message( "resizing did not create a valid image: $new_type" );
6191
  unlink( $new_file );
@@ -6255,7 +6340,7 @@ function ewww_image_optimizer_resize_upload( $file ) {
6255
  */
6256
  function ewww_image_optimizer_get_orientation( $file, $type ) {
6257
  ewwwio_debug_message( '<b>' . __FUNCTION__ . '()</b>' );
6258
- if ( function_exists( 'exif_read_data' ) && 'image/jpeg' === $type && is_readable( $file ) ) {
6259
  $exif = @exif_read_data( $file );
6260
  if ( ewww_image_optimizer_function_exists( 'print_r' ) ) {
6261
  ewwwio_debug_message( print_r( $exif, true ) );
@@ -6338,7 +6423,8 @@ function ewww_image_optimizer_find_already_optimized( $attachment ) {
6338
  */
6339
  function ewww_image_optimizer_attachment_check_variant_level( $id, $type, $meta ) {
6340
  ewwwio_debug_message( '<b>' . __FUNCTION__ . '()</b>' );
6341
- if ( empty( $_REQUEST['ewww_force'] ) ) {
 
6342
  return $meta;
6343
  }
6344
  if ( ! ewww_image_optimizer_get_option( 'ewww_image_optimizer_cloud_key' ) || ! ewww_image_optimizer_get_option( 'ewww_image_optimizer_backup_files' ) ) {
@@ -6518,7 +6604,8 @@ function ewww_image_optimizer_test_parallel_opt( $type = '', $id = 0 ) {
6518
  if ( empty( $id ) ) {
6519
  return true;
6520
  }
6521
- if ( ! empty( $_REQUEST['ewww_convert'] ) ) {
 
6522
  return false;
6523
  }
6524
  if ( empty( $type ) ) {
@@ -6610,6 +6697,9 @@ function ewww_image_optimizer_resize_from_meta_data( $meta, $id = null, $log = t
6610
  }
6611
  global $ewww_new_image;
6612
  global $ewww_image;
 
 
 
6613
  $gallery_type = 1;
6614
  ewwwio_debug_message( "attachment id: $id" );
6615
 
@@ -6757,7 +6847,7 @@ function ewww_image_optimizer_resize_from_meta_data( $meta, $id = null, $log = t
6757
  }
6758
  $ewww_image->file = $file;
6759
  $ewww_image->converted = $original;
6760
- $meta['file'] = trailingslashit( dirname( $meta['file'] ) ) . basename( $file );
6761
  $ewww_image->update_converted_attachment( $meta );
6762
  $meta = $ewww_image->convert_sizes( $meta );
6763
  ewwwio_debug_message( 'image was converted' );
@@ -6768,7 +6858,7 @@ function ewww_image_optimizer_resize_from_meta_data( $meta, $id = null, $log = t
6768
  }
6769
 
6770
  // See if we are forcing re-optimization per the user's request.
6771
- if ( ! empty( $_REQUEST['ewww_force'] ) ) {
6772
  $force = true;
6773
  } else {
6774
  $force = false;
@@ -6970,7 +7060,7 @@ function ewww_image_optimizer_resize_from_meta_data( $meta, $id = null, $log = t
6970
  ewwwio_debug_message( "queueing size $size - $filename" );
6971
  $processing_sizes[ $size ] = $filename;
6972
  unset( $parallel_sizes[ $size ] );
6973
- touch( $filename . '.processing' );
6974
  ewwwio_debug_message( "sending off $filename via parallel/async" );
6975
  $ewwwio_async_optimize_media->data(
6976
  array(
@@ -7190,8 +7280,8 @@ function ewww_image_optimizer_as3cf_attachment_file_paths( $paths, $id ) {
7190
  ewwwio_debug_message( "added $path.webp to as3cf queue" );
7191
  } elseif (
7192
  // WOM(pro) is downloading from bucket to server, WebP is enabled, and the local/server file does not exist.
7193
- ! empty( $_REQUEST['action'] ) &&
7194
- 'download' === $_REQUEST['action'] &&
7195
  ewww_image_optimizer_get_option( 'ewww_image_optimizer_webp' ) &&
7196
  is_string( $path ) &&
7197
  ! ewwwio_is_file( $path )
@@ -7620,14 +7710,17 @@ function ewww_image_optimizer_png_alpha( $filename ) {
7620
  if ( false !== strpos( $filename, '../' ) ) {
7621
  return false;
7622
  }
 
 
 
7623
  // Determine what color type is stored in the file.
7624
- $color_type = ord( file_get_contents( $filename, null, null, 25, 1 ) );
7625
  ewwwio_debug_message( "color type: $color_type" );
7626
- // If it is set to RGB alpha or Grayscale alpha.
7627
- if ( 4 === $color_type || 6 === $color_type ) {
7628
  ewwwio_debug_message( 'transparency found' );
7629
  return true;
7630
- } elseif ( 3 === $color_type && ewww_image_optimizer_gd_support() ) {
7631
  $image = imagecreatefrompng( $filename );
7632
  if ( imagecolortransparent( $image ) >= 0 ) {
7633
  ewwwio_debug_message( 'transparency found' );
@@ -7736,77 +7829,72 @@ function ewww_image_optimizer_columns( $defaults ) {
7736
  * @param string $column_name The name of the column being displayed.
7737
  * @param int $id The attachment ID number.
7738
  * @param array $meta Optional. The attachment metadata. Default null.
7739
- * @param bool $return_output Optional. True if output should be returned instead of output.
7740
- * @return string If $return_output, the data that would normally be output directly.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
7741
  */
7742
- function ewww_image_optimizer_custom_column( $column_name, $id, $meta = null, $return_output = false ) {
7743
  ewwwio_debug_message( '<b>' . __FUNCTION__ . '()</b>' );
7744
  // Once we get to the EWWW IO custom column.
7745
  if ( 'ewww-image-optimizer' === $column_name ) {
7746
- $output = '';
7747
- $id = (int) $id;
7748
  if ( is_null( $meta ) ) {
7749
  // Retrieve the metadata.
7750
  $meta = wp_get_attachment_metadata( $id );
7751
  }
7752
- if ( ewww_image_optimizer_get_option( 'ewww_image_optimizer_debug' ) && ! $return_output && ewww_image_optimizer_function_exists( 'print_r' ) ) {
7753
- $print_meta = esc_html( print_r( $meta, true ) );
 
7754
  $print_meta = preg_replace( array( '/ /', '/\n+/' ), array( '&nbsp;', '<br />' ), $print_meta );
7755
- $debug_button = esc_html__( 'Show Metadata', 'ewww-image-optimizer' );
7756
- $output .= "<button type='button' class='ewww-show-debug-meta button button-secondary' data-id='$id'>$debug_button</button><div id='ewww-debug-meta-$id' style='font-size: 10px;padding: 10px;margin:3px -10px 10px;line-height: 1.1em;display: none;'>$print_meta</div>";
7757
  }
7758
- $output .= "<div id='ewww-media-status-$id'>";
7759
  $ewww_cdn = false;
7760
  if ( is_array( $meta ) && ! empty( $meta['file'] ) && false !== strpos( $meta['file'], 'https://images-na.ssl-images-amazon.com' ) ) {
7761
- $output .= esc_html__( 'Amazon-hosted image', 'ewww-image-optimizer' ) . '</div>';
7762
- if ( $return_output ) {
7763
- return $output;
7764
- }
7765
- echo $output;
7766
  return;
7767
  }
7768
  if ( is_array( $meta ) && ! empty( $meta['cloudinary'] ) ) {
7769
- $output .= esc_html__( 'Cloudinary image', 'ewww-image-optimizer' ) . '</div>';
7770
- if ( $return_output ) {
7771
- return $output;
7772
- }
7773
- echo $output;
7774
  return;
7775
  }
7776
  if ( is_array( $meta ) & class_exists( 'WindowsAzureStorageUtil' ) && ! empty( $meta['url'] ) ) {
7777
- $output .= '<div>' . esc_html__( 'Azure Storage image', 'ewww-image-optimizer' ) . '</div>';
7778
  $ewww_cdn = true;
7779
  }
7780
  if ( is_array( $meta ) && class_exists( 'Amazon_S3_And_CloudFront' ) && preg_match( '/^(http|s3|gs)\w*:/', get_attached_file( $id ) ) ) {
7781
- $output .= '<div>' . esc_html__( 'Offloaded Media', 'ewww-image-optimizer' ) . '</div>';
7782
  $ewww_cdn = true;
7783
  }
7784
  if ( is_array( $meta ) && class_exists( 'S3_Uploads' ) && preg_match( '/^(http|s3|gs)\w*:/', get_attached_file( $id ) ) ) {
7785
- $output .= '<div>' . esc_html__( 'Amazon S3 image', 'ewww-image-optimizer' ) . '</div>';
7786
  $ewww_cdn = true;
7787
  }
7788
  if ( is_array( $meta ) & class_exists( 'wpCloud\StatelessMedia\EWWW' ) && ! empty( $meta['gs_link'] ) ) {
7789
- $output .= '<div>' . esc_html__( 'WP Stateless image', 'ewww-image-optimizer' ) . '</div>';
7790
  $ewww_cdn = true;
7791
  }
7792
  list( $file_path, $upload_path ) = ewww_image_optimizer_attachment_path( $meta, $id );
7793
  if ( is_array( $meta ) & function_exists( 'ilab_get_image_sizes' ) && ! empty( $meta['s3'] ) && empty( $file_path ) ) {
7794
- $output .= '<div>' . esc_html__( 'Media Cloud image', 'ewww-image-optimizer' ) . '</div>';
7795
- $ewww_cdn = true;
7796
- if ( $return_output ) {
7797
- return $output;
7798
- }
7799
- echo $output;
7800
  return;
7801
  }
7802
  // If the file does not exist.
7803
  if ( empty( $file_path ) && ! $ewww_cdn ) {
7804
- $output .= esc_html__( 'Could not retrieve file path.', 'ewww-image-optimizer' ) . '</div>';
7805
- ewww_image_optimizer_debug_log();
7806
- if ( $return_output ) {
7807
- return $output;
7808
- }
7809
- echo $output;
7810
  return;
7811
  }
7812
  if ( is_array( $meta ) && ( ! empty( $meta['ewww_image_optimizer'] ) || ! empty( $meta['converted'] ) ) ) {
@@ -7835,18 +7923,18 @@ function ewww_image_optimizer_custom_column( $column_name, $id, $meta = null, $r
7835
  if ( ! $skip['jpegtran'] && defined( 'EWWW_IMAGE_OPTIMIZER_JPEGTRAN' ) && ! EWWW_IMAGE_OPTIMIZER_JPEGTRAN ) {
7836
  $msg = '<div>' . sprintf(
7837
  /* translators: %s: name of a tool like jpegtran */
7838
- esc_html__( '%s is missing', 'ewww-image-optimizer' ),
7839
  '<em>jpegtran</em>'
7840
  ) . '</div>';
7841
  } elseif ( ! ewww_image_optimizer_get_option( 'ewww_image_optimizer_jpg_level' ) ) {
7842
  $msg = '<div>' . sprintf(
7843
  /* translators: %s: JPG, PNG, GIF, or PDF */
7844
- esc_html__( '%s compression disabled', 'ewww-image-optimizer' ),
7845
  'JPG'
7846
  ) . '</div>';
7847
  } else {
7848
- $convert_link = esc_html__( 'JPG to PNG', 'ewww-image-optimizer' );
7849
- $convert_desc = esc_attr__( 'WARNING: Removes metadata. Requires GD or ImageMagick. PNG is generally much better than JPG for logos and other images with a limited range of colors.', 'ewww-image-optimizer' );
7850
  }
7851
  break;
7852
  case 'image/png':
@@ -7854,12 +7942,12 @@ function ewww_image_optimizer_custom_column( $column_name, $id, $meta = null, $r
7854
  if ( ! $skip['optipng'] && ! $skip['pngout'] && ! EWWW_IMAGE_OPTIMIZER_PNGOUT && ! EWWW_IMAGE_OPTIMIZER_OPTIPNG ) {
7855
  $msg = '<div>' . sprintf(
7856
  /* translators: %s: name of a tool like jpegtran */
7857
- esc_html__( '%s is missing', 'ewww-image-optimizer' ),
7858
  '<em>optipng</em>'
7859
  ) . '</div>';
7860
  } else {
7861
- $convert_link = esc_html__( 'PNG to JPG', 'ewww-image-optimizer' );
7862
- $convert_desc = esc_attr__( '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' );
7863
  }
7864
  break;
7865
  case 'image/gif':
@@ -7867,12 +7955,12 @@ function ewww_image_optimizer_custom_column( $column_name, $id, $meta = null, $r
7867
  if ( ! $skip['gifsicle'] && ! EWWW_IMAGE_OPTIMIZER_GIFSICLE ) {
7868
  $msg = '<div>' . sprintf(
7869
  /* translators: %s: name of a tool like jpegtran */
7870
- esc_html__( '%s is missing', 'ewww-image-optimizer' ),
7871
  '<em>gifsicle</em>'
7872
  ) . '</div>';
7873
  } else {
7874
- $convert_link = esc_html__( 'GIF to PNG', 'ewww-image-optimizer' );
7875
- $convert_desc = esc_attr__( 'PNG is generally better than GIF, but does not support animation. Animated images will not be converted.', 'ewww-image-optimizer' );
7876
  }
7877
  break;
7878
  case 'application/pdf':
@@ -7889,14 +7977,10 @@ function ewww_image_optimizer_custom_column( $column_name, $id, $meta = null, $r
7889
  default:
7890
  // Not a supported mimetype.
7891
  $msg = '<div>' . esc_html__( 'Unsupported file type', 'ewww-image-optimizer' ) . '</div>';
7892
- ewww_image_optimizer_debug_log();
7893
  } // End switch().
7894
  $compression_level = ewww_image_optimizer_get_level( $type );
7895
  if ( ! empty( $msg ) ) {
7896
- if ( $return_output ) {
7897
- return $msg;
7898
- }
7899
- echo $msg;
7900
  return;
7901
  }
7902
  $ewww_manual_nonce = wp_create_nonce( 'ewww-manual' );
@@ -7910,7 +7994,7 @@ function ewww_image_optimizer_custom_column( $column_name, $id, $meta = null, $r
7910
  // 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.
7911
  if ( $ewww_cdn ) {
7912
  if ( ewww_image_optimizer_image_is_pending( $id, 'media-async' ) ) {
7913
- $output .= '<div>' . esc_html__( 'In Progress', 'ewww-image-optimizer' ) . '</div>';
7914
  $in_progress = true;
7915
  }
7916
  if ( ! $in_progress ) {
@@ -7926,22 +8010,26 @@ function ewww_image_optimizer_custom_column( $column_name, $id, $meta = null, $r
7926
  // If optimizer data exists in the db.
7927
  if ( ! empty( $optimized_images ) ) {
7928
  list( $detail_output, $converted, $backup_available ) = ewww_image_optimizer_custom_column_results( $id, $optimized_images );
7929
- $output .= $detail_output;
7930
  // Output the optimizer actions.
7931
  if ( current_user_can( apply_filters( 'ewww_image_optimizer_manual_permissions', '' ) ) ) {
7932
  // Display a link to re-optimize manually.
7933
- $output .= '<div>' . sprintf(
7934
- "<a class='ewww-manual-optimize' data-id='$id' data-nonce='$ewww_manual_nonce' href='" . admin_url( 'admin.php?action=ewww_image_optimizer_manual_optimize' ) . "&amp;ewww_manual_nonce=$ewww_manual_nonce&amp;ewww_force=1&amp;ewww_attachment_ID=%d'>%s</a>",
7935
- $id,
 
 
7936
  ( ewww_image_optimizer_restore_possible( $optimized_images, $compression_level ) ? esc_html__( 'Restore & Re-optimize', 'ewww-image-optimizer' ) : esc_html__( 'Re-optimize', 'ewww-image-optimizer' ) )
7937
  ) .
7938
- ewww_image_optimizer_variant_level_notice( $optimized_images, $compression_level ) .
7939
  '</div>';
7940
  }
7941
  if ( $backup_available && current_user_can( apply_filters( 'ewww_image_optimizer_manual_permissions', '' ) ) ) {
7942
- $output .= '<div>' . sprintf(
7943
- "<a class='ewww-manual-cloud-restore' data-id='$id' data-nonce='$ewww_manual_nonce' href='" . admin_url( 'admin.php?action=ewww_image_optimizer_manual_cloud_restore' ) . "&amp;ewww_manual_nonce=$ewww_manual_nonce&amp;ewww_attachment_ID=%d'>%s</a>",
7944
- $id,
 
 
7945
  esc_html__( 'Restore original', 'ewww-image-optimizer' )
7946
  ) . '</div>';
7947
  }
@@ -7952,26 +8040,29 @@ function ewww_image_optimizer_custom_column( $column_name, $id, $meta = null, $r
7952
  if ( isset( $meta['original_image'] ) && ewww_image_optimizer_get_option( 'ewww_image_optimizer_include_originals' ) ) {
7953
  $sizes_to_opt++;
7954
  }
7955
- $output .= '<div>' . sprintf(
7956
  esc_html(
7957
  /* translators: %d: The number of resize/thumbnail images */
7958
  _n( '%d size to compress', '%d sizes to compress', $sizes_to_opt, 'ewww-image-optimizer' )
7959
  ),
7960
- $sizes_to_opt
7961
  ) . '</div>';
7962
  }
7963
- $output .= '<div>' . sprintf( "<a class='ewww-manual-optimize' data-id='$id' data-nonce='$ewww_manual_nonce' href='" . admin_url( 'admin.php?action=ewww_image_optimizer_manual_optimize' ) . "&amp;ewww_manual_nonce=$ewww_manual_nonce&amp;ewww_attachment_ID=%d'>%s</a>", $id, esc_html__( 'Optimize now!', 'ewww-image-optimizer' ) ) . '</div>';
7964
- }
7965
- $output .= '</div>';
7966
- if ( $return_output ) {
7967
- return $output;
 
 
 
7968
  }
7969
- echo $output;
7970
  return;
7971
  } // End if().
7972
  // End of output for CDN images.
7973
  if ( ewww_image_optimizer_image_is_pending( $id, 'media-async' ) ) {
7974
- $output .= esc_html__( 'In Progress', 'ewww-image-optimizer' );
7975
  $in_progress = true;
7976
  }
7977
  if ( ! $in_progress ) {
@@ -7987,12 +8078,12 @@ function ewww_image_optimizer_custom_column( $column_name, $id, $meta = null, $r
7987
  // If optimizer data exists.
7988
  if ( ! empty( $optimized_images ) ) {
7989
  list( $detail_output, $converted, $backup_available ) = ewww_image_optimizer_custom_column_results( $id, $optimized_images );
7990
- $output .= $detail_output;
7991
 
7992
  // Link to webp upgrade script.
7993
  $oldwebpfile = preg_replace( '/\.\w+$/', '.webp', $file_path );
7994
  if ( file_exists( $oldwebpfile ) && current_user_can( apply_filters( 'ewww_image_optimizer_admin_permissions', '' ) ) ) {
7995
- $output .= "<div><a href='" . admin_url( 'options.php?page=ewww-image-optimizer-webp-migrate' ) . "'>" . esc_html__( 'Run WebP upgrade', 'ewww-image-optimizer' ) . '</a></div>';
7996
  }
7997
 
7998
  // Determine filepath for webp.
@@ -8002,38 +8093,49 @@ function ewww_image_optimizer_custom_column( $column_name, $id, $meta = null, $r
8002
  // Get a human readable filesize.
8003
  $webp_size = ewww_image_optimizer_size_format( $webp_size );
8004
  $webpurl = esc_url( wp_get_attachment_url( $id ) . '.webp' );
8005
- $output .= "<div>WebP: <a href=\"$webpurl\">$webp_size</a></div>";
8006
  }
8007
 
8008
- if ( empty( $msg ) && current_user_can( apply_filters( 'ewww_image_optimizer_manual_permissions', '' ) ) ) {
8009
  // Output a link to re-optimize manually.
8010
- $output .= '<div>' . sprintf(
8011
- "<a class='ewww-manual-optimize' data-id='$id' data-nonce='$ewww_manual_nonce' href='" . admin_url( 'admin.php?action=ewww_image_optimizer_manual_optimize' ) . "&amp;ewww_manual_nonce=$ewww_manual_nonce&amp;ewww_force=1&amp;ewww_attachment_ID=%d'>%s</a>",
8012
- $id,
 
 
8013
  ( ewww_image_optimizer_restore_possible( $optimized_images, $compression_level ) ? esc_html__( 'Restore & Re-optimize', 'ewww-image-optimizer' ) : esc_html__( 'Re-optimize', 'ewww-image-optimizer' ) )
8014
  );
8015
- $output .= ewww_image_optimizer_variant_level_notice( $optimized_images, $compression_level );
8016
  if ( ! ewww_image_optimizer_get_option( 'ewww_image_optimizer_disable_convert_links' ) && 'ims_image' !== get_post_type( $id ) && ! empty( $convert_desc ) ) {
8017
- $output .= " | <a class='ewww-manual-convert' data-id='$id' data-nonce='$ewww_manual_nonce' title='$convert_desc' href='" . admin_url( "admin.php?action=ewww_image_optimizer_manual_optimize&amp;ewww_manual_nonce=$ewww_manual_nonce&amp;ewww_attachment_ID=$id" ) . "&amp;ewww_convert=1&amp;ewww_force=1'>$convert_link</a>";
 
 
 
 
 
 
 
8018
  }
8019
- $output .= '</div>';
8020
- } else {
8021
- $output .= $msg;
8022
  }
8023
  $restorable = false;
8024
  if ( $converted && ewwwio_is_file( $converted ) ) {
8025
  $restorable = true;
8026
  }
8027
  if ( $restorable && current_user_can( apply_filters( 'ewww_image_optimizer_manual_permissions', '' ) ) ) {
8028
- $output .= '<div>' . sprintf(
8029
- "<a class='ewww-manual-restore' data-id='$id' data-nonce='$ewww_manual_nonce' href='" . admin_url( 'admin.php?action=ewww_image_optimizer_manual_restore' ) . "&amp;ewww_manual_nonce=$ewww_manual_nonce&amp;ewww_attachment_ID=%d'>%s</a>",
8030
- $id,
 
 
8031
  esc_html__( 'Restore original', 'ewww-image-optimizer' )
8032
  ) . '</div>';
8033
  } elseif ( $backup_available && current_user_can( apply_filters( 'ewww_image_optimizer_manual_permissions', '' ) ) ) {
8034
- $output .= '<div>' . sprintf(
8035
- "<a class='ewww-manual-cloud-restore' data-id='$id' data-nonce='$ewww_manual_nonce' href='" . admin_url( 'admin.php?action=ewww_image_optimizer_manual_cloud_restore' ) . "&amp;ewww_manual_nonce=$ewww_manual_nonce&amp;ewww_attachment_ID=%d'>%s</a>",
8036
- $id,
 
 
8037
  esc_html__( 'Restore original', 'ewww-image-optimizer' )
8038
  ) . '</div>';
8039
  }
@@ -8044,21 +8146,21 @@ function ewww_image_optimizer_custom_column( $column_name, $id, $meta = null, $r
8044
  if ( isset( $meta['original_image'] ) && ewww_image_optimizer_get_option( 'ewww_image_optimizer_include_originals' ) ) {
8045
  $sizes_to_opt++;
8046
  }
8047
- $output .= '<div>' . sprintf(
8048
  esc_html(
8049
  /* translators: %d: The number of resize/thumbnail images */
8050
  _n( '%d size to compress', '%d sizes to compress', $sizes_to_opt, 'ewww-image-optimizer' )
8051
  ),
8052
- $sizes_to_opt
8053
  ) . '</div>';
8054
  } else {
8055
- $output .= '<div>' . esc_html__( 'Not optimized', 'ewww-image-optimizer' ) . '</div>';
8056
  }
8057
  // Tell them the filesize.
8058
- $output .= '<div>' . sprintf(
8059
  /* translators: %s: size of the image */
8060
  esc_html__( 'Image Size: %s', 'ewww-image-optimizer' ),
8061
- $file_size
8062
  ) . '</div>';
8063
  // Determine filepath for webp.
8064
  $webpfile = $file_path . '.webp';
@@ -8067,25 +8169,31 @@ function ewww_image_optimizer_custom_column( $column_name, $id, $meta = null, $r
8067
  // Get a human readable filesize.
8068
  $webp_size = ewww_image_optimizer_size_format( $webp_size );
8069
  $webpurl = esc_url( wp_get_attachment_url( $id ) . '.webp' );
8070
- $output .= "<div>WebP: <a href=\"$webpurl\">$webp_size</a></div>";
8071
  }
8072
- if ( empty( $msg ) && current_user_can( apply_filters( 'ewww_image_optimizer_manual_permissions', '' ) ) ) {
8073
  // Give the user the option to optimize the image right now.
8074
- $output .= sprintf( "<div><a class='ewww-manual-optimize' data-id='$id' data-nonce='$ewww_manual_nonce' href='" . admin_url( 'admin.php?action=ewww_image_optimizer_manual_optimize' ) . "&amp;ewww_manual_nonce=$ewww_manual_nonce&amp;ewww_attachment_ID=%d'>%s</a>", $id, esc_html__( 'Optimize now!', 'ewww-image-optimizer' ) );
 
 
 
 
 
 
8075
  if ( ! ewww_image_optimizer_get_option( 'ewww_image_optimizer_disable_convert_links' ) && 'ims_image' !== get_post_type( $id ) && ! empty( $convert_desc ) ) {
8076
- $output .= " | <a class='ewww-manual-convert' data-id='$id' data-nonce='$ewww_manual_nonce' title='$convert_desc' href='" . admin_url( "admin.php?action=ewww_image_optimizer_manual_optimize&amp;ewww_manual_nonce=$ewww_manual_nonce&amp;ewww_attachment_ID=$id&amp;ewww_convert=1&amp;ewww_force=1" ) . "'>$convert_link</a>";
 
 
 
 
 
 
 
8077
  }
8078
- $output .= '</div>';
8079
- } else {
8080
- $output .= $msg;
8081
  }
8082
  } // End if().
8083
- $output .= '</div>';
8084
- if ( $return_output ) {
8085
- ewww_image_optimizer_debug_log();
8086
- return $output;
8087
- }
8088
- echo $output;
8089
  } // End if().
8090
  ewwwio_memory( __FUNCTION__ );
8091
  ewww_image_optimizer_debug_log();
@@ -8130,7 +8238,7 @@ function ewww_image_optimizer_variant_level_notice( $optimized_images, $compress
8130
  foreach ( $optimized_images as $optimized_image ) {
8131
  if ( 'full' === $optimized_image['resize'] ) {
8132
  if ( is_numeric( $optimized_image['level'] ) && (int) $compression_level > (int) $optimized_image['level'] ) {
8133
- return ' <span title="' . esc_attr__( 'Compressed at a lower level than current setting.' ) . '" style="color:white;background-color:#f1900e;border-radius:50%;font-size:10px;width:16px;height:16px;line-height:16px;text-align:center;display:inline-block;padding-bottom:0px;"><sup>!</sup></span>';
8134
  }
8135
  }
8136
  }
@@ -8226,7 +8334,7 @@ function ewww_image_optimizer_custom_column_results( $id, $optimized_images ) {
8226
  }
8227
  }
8228
  if ( ! empty( $optimized_image['converted'] ) ) {
8229
- $converted = $optimized_image['converted'];
8230
  }
8231
  $sizes_to_opt++;
8232
  if ( ! empty( $optimized_image['resize'] ) ) {
@@ -8385,7 +8493,7 @@ function ewww_image_optimizer_migrate_meta_to_db( $id, $meta, $bail_early = fals
8385
  ewwwio_debug_message( "bailing early for migration of $id" );
8386
  return false;
8387
  }
8388
- $retina_path = ewww_image_optimizer_hidpi_optimize( $file_path, true, false );
8389
  if ( $retina_path ) {
8390
  ewww_image_optimizer_update_file_from_meta( $retina_path, 'media', $id, 'full-retina' );
8391
  }
@@ -8412,14 +8520,14 @@ function ewww_image_optimizer_migrate_meta_to_db( $id, $meta, $bail_early = fals
8412
  continue;
8413
  }
8414
 
8415
- $resize_path = $base_dir . $data['file'];
8416
  $converted = ( is_array( $data ) && ! empty( $data['converted'] ) && ! empty( $data['orig_file'] ) ? trailingslashit( dirname( $resize_path ) ) . basename( $data['orig_file'] ) : false );
8417
  ewww_image_optimizer_update_file_from_meta( $resize_path, 'media', $id, $size, $converted );
8418
  // Search for retina images.
8419
  if ( function_exists( 'wr2x_get_retina' ) ) {
8420
  $retina_path = wr2x_get_retina( $resize_path );
8421
  } else {
8422
- $retina_path = ewww_image_optimizer_hidpi_optimize( $resize_path, true, false );
8423
  }
8424
  if ( $retina_path ) {
8425
  ewww_image_optimizer_update_file_from_meta( $retina_path, 'media', $id, $size . '-retina' );
@@ -8442,7 +8550,7 @@ function ewww_image_optimizer_migrate_meta_to_db( $id, $meta, $bail_early = fals
8442
  $custom_sizes_pathinfo = pathinfo( $file_path );
8443
  $custom_size_path = '';
8444
  foreach ( $meta['custom_sizes'] as $dimensions => $custom_size ) {
8445
- $custom_size_path = $custom_sizes_pathinfo['dirname'] . '/' . $custom_size['file'];
8446
  ewww_image_optimizer_update_file_from_meta( $custom_size_path, 'media', $id, 'custom-size-' . $dimensions );
8447
  }
8448
  }
@@ -8544,7 +8652,7 @@ function ewww_image_optimizer_bulk_action_handler( $redirect_to, $doaction, $pos
8544
  check_admin_referer( 'bulk-media' );
8545
  // Prep the attachment IDs for optimization.
8546
  $ids = implode( ',', array_map( 'intval', $post_ids ) );
8547
- wp_redirect(
8548
  add_query_arg(
8549
  array(
8550
  'page' => 'ewww-image-optimizer-bulk',
@@ -8715,6 +8823,7 @@ function ewww_image_optimizer_settings_script( $hook ) {
8715
  if ( 'settings_page_ewww-image-optimizer-options' !== $hook ) {
8716
  return;
8717
  }
 
8718
  wp_enqueue_script( 'jquery-ui-tooltip' );
8719
  wp_enqueue_script( 'ewwwbulkscript', plugins_url( '/includes/eio.js', __FILE__ ), array( 'jquery' ), EWWW_IMAGE_OPTIMIZER_VERSION );
8720
  wp_enqueue_style( 'jquery-ui-tooltip-custom', plugins_url( '/includes/jquery-ui-1.10.1.custom.css', __FILE__ ), array(), EWWW_IMAGE_OPTIMIZER_VERSION );
@@ -8871,7 +8980,7 @@ function ewww_image_optimizer_webp_rewrite() {
8871
  ewwwio_ob_clean();
8872
  ewwwio_debug_message( '<b>' . __FUNCTION__ . '()</b>' );
8873
  // Verify that the user is properly authorized.
8874
- if ( ! wp_verify_nonce( $_REQUEST['ewww_wpnonce'], 'ewww-image-optimizer-settings' ) ) {
8875
  wp_die( esc_html__( 'Access denied.', 'ewww-image-optimizer' ) );
8876
  }
8877
  if ( ! current_user_can( apply_filters( 'ewww_image_optimizer_admin_permissions', 'manage_options' ) ) ) {
@@ -8895,7 +9004,7 @@ function ewww_image_optimizer_webp_unwrite() {
8895
  ewwwio_ob_clean();
8896
  ewwwio_debug_message( '<b>' . __FUNCTION__ . '()</b>' );
8897
  // Verify that the user is properly authorized.
8898
- if ( ! wp_verify_nonce( $_REQUEST['ewww_wpnonce'], 'ewww-image-optimizer-settings' ) ) {
8899
  wp_die( esc_html__( 'Access denied.', 'ewww-image-optimizer' ) );
8900
  }
8901
  if ( ! current_user_can( apply_filters( 'ewww_image_optimizer_admin_permissions', 'manage_options' ) ) ) {
@@ -9128,40 +9237,11 @@ function ewwwio_is_cf_host() {
9128
  }
9129
 
9130
  /**
9131
- * Wrapper that displays the EWWW IO options in the multisite network admin.
9132
- */
9133
- function ewww_image_optimizer_network_options() {
9134
- ewwwio_debug_message( '<b>' . __FUNCTION__ . '()</b>' );
9135
- add_filter( 'ewww_image_optimizer_settings', 'ewww_image_optimizer_filter_network_settings_page', 9 );
9136
- ewww_image_optimizer_options( 'network-multisite' );
9137
- }
9138
-
9139
- /**
9140
- * Wrapper that displays the EWWW IO options for multisite mode on a single site.
9141
- *
9142
- * By default, the only options displayed are the per-site resizes list, but a network admin can
9143
- * permit site admins to configure their own blog settings.
9144
- */
9145
- function ewww_image_optimizer_network_singlesite_options() {
9146
- ewwwio_debug_message( '<b>' . __FUNCTION__ . '()</b>' );
9147
- add_filter( 'ewww_image_optimizer_settings', 'ewww_image_optimizer_filter_network_singlesite_settings_page', 9 );
9148
- ewww_image_optimizer_options( 'network-singlesite' );
9149
- }
9150
-
9151
- /**
9152
- * Displays the EWWW IO options along with status information, and debugging information.
9153
- *
9154
- * @global string $eio_debug In memory debug log.
9155
- * @global int $wp_version
9156
- *
9157
- * @param string $network Indicates which options should be shown in multisite installations.
9158
  */
9159
- function ewww_image_optimizer_options( $network = 'singlesite' ) {
9160
- global $wp_version;
9161
- global $ewwwio_temp_debug;
9162
  global $ewwwio_upgrading;
9163
  global $content_width;
9164
- ewwwio_debug_message( '<b>' . __FUNCTION__ . '()</b>' );
9165
  ewwwio_debug_version_info();
9166
  ewwwio_debug_message( 'ABSPATH: ' . ABSPATH );
9167
  ewwwio_debug_message( 'WP_CONTENT_DIR: ' . WP_CONTENT_DIR );
@@ -9172,6 +9252,9 @@ function ewww_image_optimizer_options( $network = 'singlesite' ) {
9172
  ewwwio_debug_message( 'wp_upload_dir (basedir): ' . $upload_info['basedir'] );
9173
  ewwwio_debug_message( "content_width: $content_width" );
9174
  ewwwio_debug_message( 'registered stream wrappers: ' . implode( ',', stream_get_wrappers() ) );
 
 
 
9175
  if ( ! defined( 'EWWW_IMAGE_OPTIMIZER_NOEXEC' ) ) {
9176
  if ( defined( 'EWWW_IMAGE_OPTIMIZER_CLOUD' ) && EWWW_IMAGE_OPTIMIZER_CLOUD ) {
9177
  ewww_image_optimizer_disable_tools();
@@ -9180,113 +9263,273 @@ function ewww_image_optimizer_options( $network = 'singlesite' ) {
9180
  ewww_image_optimizer_notice_utils( 'quiet' );
9181
  }
9182
  }
9183
- $network_class = $network;
9184
- if ( empty( $network ) ) {
9185
- $network_class = 'singlesite';
9186
- }
9187
- if ( ! function_exists( 'is_plugin_active_for_network' ) && is_multisite() ) {
9188
- // Need to include the plugin library for the is_plugin_active function.
9189
- require_once( ABSPATH . 'wp-admin/includes/plugin.php' );
9190
- }
9191
- if ( 'debug-silent' !== $network ) {
9192
- global $eio_hs_beacon;
9193
- $eio_hs_beacon->admin_notice( $network_class );
9194
- }
9195
- if ( is_multisite() && is_plugin_active_for_network( EWWW_IMAGE_OPTIMIZER_PLUGIN_FILE_REL ) && ! get_site_option( 'ewww_image_optimizer_allow_multisite_override' ) ) {
9196
- $network_class = 'network-multisite';
9197
- }
9198
- $output = array();
9199
- $output[] = "<script type='text/javascript'>\n" .
9200
- 'jQuery(document).ready(function($) {$(".fade").fadeTo(5000,1).fadeOut(3000);});' . "\n" .
9201
- "</script>\n";
9202
- $output[] = "<style>\n" .
9203
- ".ewww-tab span { font-size: 15px; font-weight: 700; color: #555; text-decoration: none; line-height: 36px; padding: 0 10px; }\n" .
9204
- ".ewww-tab span:hover { color: #464646; }\n" .
9205
- ".ewww-tab { margin: 0 0 0 5px; padding: 0px; border-width: 1px 1px 1px; border-style: solid solid none; border-image: none; border-color: #ccc; display: inline-block; background-color: #e4e4e4; cursor: pointer }\n" .
9206
- ".ewww-tab:hover { background-color: #fff }\n" .
9207
- ".ewww-selected { background-color: #f1f1f1; margin-bottom: -1px; border-bottom: 1px solid #f1f1f1 }\n" .
9208
- ".ewww-selected span { color: #000; }\n" .
9209
- ".ewww-selected:hover { background-color: #f1f1f1; }\n" .
9210
- ".ewww-tab-nav { list-style: none; margin: 10px 0 0; padding-left: 5px; border-bottom: 1px solid #ccc; }\n" .
9211
- "</style>\n";
9212
- $output[] = "<div class='wrap'>\n";
9213
- $output[] = "<h1>EWWW Image Optimizer</h1>\n";
9214
- $output[] = "<!--<div id='ewww-container-left' style='float: left; margin-right: 225px;'>-->\n";
9215
- if ( 'network-multisite' === $network ) {
9216
- $bulk_link = esc_html__( 'Media Library', 'ewww-image-optimizer' ) . ' -> ' . esc_html__( 'Bulk Optimize', 'ewww-image-optimizer' );
9217
  } else {
9218
- $bulk_link = '<a href="' . admin_url( 'upload.php?page=ewww-image-optimizer-bulk' ) . '">' . esc_html__( 'Bulk Optimize', 'ewww-image-optimizer' ) . '</a>';
9219
  }
9220
- $s3_link = '<a href="https://ewww.io/downloads/s3-image-optimizer/">' . esc_html__( 'S3 Image Optimizer', 'ewww-image-optimizer' ) . '</a>';
9221
- $output[] = '<p>' .
9222
- sprintf(
9223
- /* translators: %s: Bulk Optimize (link) */
9224
- esc_html__( 'New images uploaded to the Media Library will be optimized automatically. If you have existing images you would like to optimize, you can use the %s tool.', 'ewww-image-optimizer' ),
9225
- $bulk_link
9226
- ) . ewwwio_help_link( 'https://docs.ewww.io/article/4-getting-started', '5853713bc697912ffd6c0b98' ) . ' ' .
9227
- ( ! class_exists( 'Amazon_S3_And_CloudFront' ) ?
9228
- sprintf(
9229
- /* translators: %s: S3 Image Optimizer (link) */
9230
- esc_html__( 'Images stored in an Amazon S3 bucket can be optimized using our %s.' ),
9231
- $s3_link
9232
- ) : '' ) .
9233
- "</p>\n";
9234
-
9235
- $compress_score = 0;
9236
- $resize_score = 0;
9237
- $status_notices = '';
9238
-
9239
- $compress_recommendations = array();
9240
- $resize_recommendations = array();
9241
-
9242
- $status_output = "<div id='ewww-widgets' class='metabox-holder' style='max-width:1170px;'><div class='meta-box-sortables'><div id='ewww-status' class='postbox'>\n" .
9243
- "<h2 class='ewww-hndle'>" . esc_html__( 'Optimization Status', 'ewww-image-optimizer' ) . "</h2>\n<div class='inside'>";
9244
-
9245
- if ( ! ewww_image_optimizer_get_option( 'ewww_image_optimizer_cloud_key' ) && ! ewww_image_optimizer_get_option( 'ewww_image_optimizer_exactdn' ) ) {
9246
- $status_notices .= "<h3><a href='https://ewww.io/plans/' target='_blank' style='font-weight:bold;text-decoration:none;color:#3eadc9;'>" . esc_html__( 'Premium Upgrades:', 'ewww-image-optimizer' ) . "</a></h3>\n" .
9247
- '<p><i>' . esc_html__( 'Priority Support included with any purchase.', 'ewww-image-optimizer' ) . "</i></p>\n";
9248
  }
9249
- if ( ewww_image_optimizer_get_option( 'ewww_image_optimizer_cloud_key' ) ) {
9250
- $status_notices .= '<p><b>' . esc_html__( 'Cloud optimization API Key', 'ewww-image-optimizer' ) . ':</b> ';
9251
- ewww_image_optimizer_set_option( 'ewww_image_optimizer_cloud_exceeded', 0 );
9252
- $verify_cloud = ewww_image_optimizer_cloud_verify( false );
9253
- if ( false !== strpos( $verify_cloud, 'great' ) ) {
9254
- $compress_score += 30;
9255
- if ( ewww_image_optimizer_get_option( 'ewww_image_optimizer_jpg_level' ) > 20 ) {
9256
- $compress_score += 50;
9257
- } else {
9258
- $compress_recommendations[] = esc_html__( 'Enable premium compression for JPG images.', 'ewww-image-optimizer' );
9259
- }
9260
- if ( ewww_image_optimizer_get_option( 'ewww_image_optimizer_png_level' ) > 20 ) {
9261
- $compress_score += 20;
9262
- } else {
9263
- $compress_recommendations[] = esc_html__( 'Enable premium compression for PNG images.', 'ewww-image-optimizer' );
9264
- }
9265
- $status_notices .= '<span style="color: #3eadc9; font-weight: bolder">' . esc_html__( 'Verified,', 'ewww-image-optimizer' ) . ' </span>' . ewww_image_optimizer_cloud_quota();
9266
- } elseif ( false !== strpos( $verify_cloud, 'exceeded' ) ) {
9267
- $status_notices .= '<span style="color: orange; font-weight: bolder">' . esc_html__( 'Out of credits', 'ewww-image-optimizer' ) . '</span> - <a href="https://ewww.io/buy-credits/" target="_blank">' . esc_html__( 'Purchase more', 'ewww-image-optimizer' ) . '</a>';
9268
- } else {
9269
- $status_notices .= '<span style="color: red; font-weight: bolder">' . esc_html__( 'Not Verified', 'ewww-image-optimizer' ) . '</span>';
9270
- }
9271
- if ( false !== strpos( $verify_cloud, 'great' ) ) {
9272
- $status_notices .= ' <a target="_blank" href="https://history.exactlywww.com/show/?api_key=' . ewww_image_optimizer_get_option( 'ewww_image_optimizer_cloud_key' ) . '">' . esc_html__( 'View Usage', 'ewww-image-optimizer' ) . '</a>';
9273
- }
9274
- $status_notices .= "</p>\n";
9275
- $disable_level = '';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
9276
  } else {
9277
- $status_notices .= '<p><span style="font-weight:bold;color:#3eadc9;">Compress API:</span> <a href="https://ewww.io/buy-credits/" target="_blank">' .
9278
- esc_html__( 'Unlock premium compression, save storage space, and reduce server load.', 'ewww-image-optimizer' ) . '</a></p>';
9279
  delete_option( 'ewww_image_optimizer_cloud_key_invalid' );
9280
  if ( ! class_exists( 'ExactDN' ) && ! ewww_image_optimizer_get_option( 'ewww_image_optimizer_exactdn' ) ) {
9281
- $compress_recommendations[] = esc_html__( 'Enable premium compression with an API key or Easy IO.', 'ewww-image-optimizer' );
9282
  }
9283
- $disable_level = "disabled='disabled'";
9284
  }
9285
  $exactdn_enabled = false;
9286
- global $exactdn;
9287
- if ( class_exists( 'Jetpack_Photon' ) && Jetpack::is_module_active( 'photon' ) && ewww_image_optimizer_get_option( 'ewww_image_optimizer_exactdn' ) ) {
9288
- $status_notices .= '<p><b>Easy IO:</b> <span style="color: red">' . esc_html__( 'Inactive, please disable the Image Performance option on the Jetpack Dashboard.', 'ewww-image-optimizer' ) . '</span></p>';
9289
- } elseif ( get_option( 'easyio_exactdn' ) ) {
9290
  ewww_image_optimizer_webp_rewrite_verify();
9291
  update_option( 'ewww_image_optimizer_exactdn', false );
9292
  update_option( 'ewww_image_optimizer_lazy_load', false );
@@ -9294,13 +9537,12 @@ function ewww_image_optimizer_options( $network = 'singlesite' ) {
9294
  update_option( 'ewww_image_optimizer_picture_webp', false );
9295
  $compress_score += 80;
9296
  $resize_score += 50;
9297
- } elseif ( class_exists( 'ExactDN' ) && ewww_image_optimizer_get_option( 'ewww_image_optimizer_exactdn' ) ) {
9298
- $status_notices .= '<p><b>Easy IO:</b> ';
 
 
 
9299
  if ( $exactdn->get_exactdn_domain() && $exactdn->verify_domain( $exactdn->get_exactdn_domain() ) ) {
9300
- $status_notices .= '<span style="color: #3eadc9; font-weight: bolder">' . esc_html__( 'Verified', 'ewww-image-optimizer' ) . ' </span>';
9301
- if ( defined( 'WP_ROCKET_VERSION' ) ) {
9302
- $status_notices .= '<br><i>' . esc_html__( 'If you use the File Optimization options within WP Rocket, you should also enter your Easy IO CNAME in the WP Rocket CDN settings (reserved for CSS and Javascript):', 'ewww-image-optimizer' ) . ' ' . $exactdn->get_exactdn_domain() . '</i>';
9303
- }
9304
  if ( $compress_score < 50 ) {
9305
  $compress_score = 50;
9306
  }
@@ -9308,24 +9550,12 @@ function ewww_image_optimizer_options( $network = 'singlesite' ) {
9308
  if ( ewww_image_optimizer_get_option( 'exactdn_lossy' ) ) {
9309
  $compress_score = 100;
9310
  } elseif ( ewww_image_optimizer_get_option( 'ewww_image_optimizer_jpg_level' ) < 30 ) {
9311
- $compress_recommendations[] = esc_html__( 'Enable premium compression.', 'ewww-image-optimizer' ) . ewwwio_help_link( 'https://docs.ewww.io/article/47-getting-more-from-exactdn', '59de6631042863379ddc953c' );
9312
  }
9313
  $exactdn_enabled = true;
9314
- } elseif ( $exactdn->get_exactdn_domain() && $exactdn->get_exactdn_option( 'verified' ) ) {
9315
- $status_notices .= '<span style="color: orange; font-weight: bolder">' . esc_html__( 'Temporarily disabled.', 'ewww-image-optimizer' ) . ' </span>';
9316
- } elseif ( $exactdn->get_exactdn_domain() && $exactdn->get_exactdn_option( 'suspended' ) ) {
9317
- $status_notices .= '<span style="color: orange; font-weight: bolder">' . esc_html__( 'Active, not yet verified.', 'ewww-image-optimizer' ) . ' </span>';
9318
- } else {
9319
- ewwwio_debug_message( 'could not verify: ' . $exactdn->get_exactdn_domain() );
9320
- $status_notices .= '<span style="color: red; font-weight: bolder"><a href="https://ewww.io/manage-sites/" target="_blank">' . esc_html__( 'Not Verified', 'ewww-image-optimizer' ) . '</a></span>';
9321
  }
9322
- if ( function_exists( 'remove_query_strings_link' ) || function_exists( 'rmqrst_loader_src' ) || function_exists( 'qsr_remove_query_strings_1' ) ) {
9323
- $status_notices .= '<br><i>' . esc_html__( 'Plugins that remove query strings are unnecessary with Easy IO. You may remove them at your convenience.', 'ewww-image-optimizer' ) . '</i>' . ewwwio_help_link( 'https://docs.ewww.io/article/50-exactdn-and-query-strings', '5a3d278a2c7d3a1943677b52' );
9324
- }
9325
- $status_notices .= '</p>';
9326
  } elseif ( ! ewww_image_optimizer_get_option( 'ewww_image_optimizer_exactdn' ) ) {
9327
- $status_notices .= '<p><span style="font-weight:bold;color:#3eadc9;">Easy IO:</span> <a href="https://ewww.io/resize/" target="_blank">' . esc_html__( 'Comprehensive image optimization with automatic compression, auto-sizing, WebP conversion, and lazy load.', 'ewww-image-optimizer' ) . '</a></p>';
9328
- $resize_recommendations[] = esc_html__( 'Enable Easy IO for automatic resizing.', 'ewww-image-optimizer' ) . ewwwio_help_link( 'https://docs.ewww.io/article/44-introduction-to-exactdn', '59bc5ad6042863033a1ce370,5c0042892c7d3a31944e88a4' );
9329
  delete_option( 'ewww_image_optimizer_exactdn_domain' );
9330
  delete_option( 'ewww_image_optimizer_exactdn_plan_id' );
9331
  delete_option( 'ewww_image_optimizer_exactdn_failures' );
@@ -9341,14 +9571,13 @@ function ewww_image_optimizer_options( $network = 'singlesite' ) {
9341
  delete_site_option( 'ewww_image_optimizer_exactdn_validation' );
9342
  delete_site_option( 'ewww_image_optimizer_exactdn_suspended' );
9343
  }
9344
- if ( $exactdn_enabled && ! ewww_image_optimizer_get_option( 'ewww_image_optimizer_cloud_key' ) ) {
9345
- $output[] = "<script type='text/javascript'>\n" .
9346
- 'var exactdn_enabled = true;' . "\n" .
9347
- "</script>\n";
9348
- } else {
9349
- $output[] = "<script type='text/javascript'>\n" .
9350
- 'var exactdn_enabled = false;' . "\n" .
9351
- "</script>\n";
9352
  }
9353
  if (
9354
  ewww_image_optimizer_get_option( 'ewww_image_optimizer_maxmediawidth' ) ||
@@ -9360,13 +9589,13 @@ function ewww_image_optimizer_options( $network = 'singlesite' ) {
9360
  } elseif ( defined( 'IMSANITY_VERSION' ) ) {
9361
  $resize_score += 30;
9362
  } else {
9363
- $resize_recommendations[] = esc_html__( 'Configure maximum image dimensions in Resize settings.', 'ewww-image-optimizer' ) . ewwwio_help_link( 'https://docs.ewww.io/article/41-resize-settings', '59849911042863033a1ba5f9' );
9364
  }
9365
  $jpg_quality = apply_filters( 'jpeg_quality', 82, 'image_resize' );
9366
  if ( $jpg_quality < 90 && $jpg_quality > 50 ) {
9367
  $resize_score += 20;
9368
  } else {
9369
- $resize_recommendations[] = esc_html__( 'JPG quality level should be between 50 and 90 for optimal resizing.', 'ewww-image-optimizer' ) . ewwwio_help_link( 'https://docs.ewww.io/article/11-advanced-configuration', '58542afac697912ffd6c18c0,58543c69c697912ffd6c19a7' );
9370
  }
9371
  $skip = ewww_image_optimizer_skip_tools();
9372
  if ( ! $skip['jpegtran'] && ! EWWW_IMAGE_OPTIMIZER_NOEXEC ) {
@@ -9379,7 +9608,7 @@ function ewww_image_optimizer_options( $network = 'singlesite' ) {
9379
  if ( ! empty( $jpegtran_installed ) ) {
9380
  $compress_score += 5;
9381
  } else {
9382
- $compress_recommendations[] = esc_html__( 'Install jpegtran.', 'ewww-image-optimizer' ) . ewwwio_help_link( 'https://docs.ewww.io/article/6-the-plugin-says-i-m-missing-something', '585371e3c697912ffd6c0ba1' );
9383
  }
9384
  }
9385
  if ( ! $skip['optipng'] && ! EWWW_IMAGE_OPTIMIZER_NOEXEC ) {
@@ -9392,7 +9621,7 @@ function ewww_image_optimizer_options( $network = 'singlesite' ) {
9392
  if ( ! empty( $optipng_version ) ) {
9393
  $compress_score += 5;
9394
  } else {
9395
- $compress_recommendations[] = esc_html__( 'Install optipng.', 'ewww-image-optimizer' ) . ewwwio_help_link( 'https://docs.ewww.io/article/6-the-plugin-says-i-m-missing-something', '585371e3c697912ffd6c0ba1' );
9396
  }
9397
  }
9398
  if ( ! $skip['pngout'] && ! EWWW_IMAGE_OPTIMIZER_NOEXEC ) {
@@ -9418,7 +9647,7 @@ function ewww_image_optimizer_options( $network = 'singlesite' ) {
9418
  if ( ! empty( $pngquant_version ) ) {
9419
  $compress_score += 5;
9420
  } else {
9421
- $compress_recommendations[] = esc_html__( 'Install pngquant.', 'ewww-image-optimizer' ) . ewwwio_help_link( 'https://docs.ewww.io/article/6-the-plugin-says-i-m-missing-something', '585371e3c697912ffd6c0ba1' );
9422
  }
9423
  }
9424
  if ( ! $skip['gifsicle'] && ! EWWW_IMAGE_OPTIMIZER_NOEXEC ) {
@@ -9431,7 +9660,7 @@ function ewww_image_optimizer_options( $network = 'singlesite' ) {
9431
  if ( ! empty( $gifsicle_version ) ) {
9432
  $compress_score += 5;
9433
  } else {
9434
- $compress_recommendations[] = esc_html__( 'Install gifsicle.', 'ewww-image-optimizer' ) . ewwwio_help_link( 'https://docs.ewww.io/article/6-the-plugin-says-i-m-missing-something', '585371e3c697912ffd6c0ba1' );
9435
  }
9436
  }
9437
  if ( EWWW_IMAGE_OPTIMIZER_CWEBP && ! $skip['webp'] && ! EWWW_IMAGE_OPTIMIZER_NOEXEC ) {
@@ -9444,9 +9673,15 @@ function ewww_image_optimizer_options( $network = 'singlesite' ) {
9444
  if ( ! empty( $webp_version ) ) {
9445
  $compress_score += 5;
9446
  } else {
9447
- $compress_recommendations[] = esc_html__( 'Install webp.', 'ewww-image-optimizer' ) . ewwwio_help_link( 'https://docs.ewww.io/article/6-the-plugin-says-i-m-missing-something', '585371e3c697912ffd6c0ba1' );
9448
  }
9449
  }
 
 
 
 
 
 
9450
  // Check that an image library exists for converting resizes. Originals can be done via the API, but resizes are done locally for speed.
9451
  $toolkit_found = false;
9452
  if ( ewww_image_optimizer_gd_support() ) {
@@ -9461,715 +9696,1181 @@ function ewww_image_optimizer_options( $network = 'singlesite' ) {
9461
  if ( PHP_OS !== 'WINNT' && ! ewww_image_optimizer_full_cloud() && ! EWWW_IMAGE_OPTIMIZER_NOEXEC ) {
9462
  ewww_image_optimizer_find_nix_binary( 'nice', 'n' );
9463
  }
9464
- if ( wp_using_ext_object_cache() ) {
9465
- ewwwio_debug_message( 'using external object cache, really?' );
9466
- } else {
9467
- ewwwio_debug_message( 'not external cache' );
9468
- }
9469
- $status_notices .= "<p>\n"; // This line encloses everything up to the end of the async stuff.
9470
- $status_notices .= '<strong>' . esc_html( 'Background optimization (faster uploads):', 'ewww-image-optimizer' ) . '</strong><br>';
9471
- if ( defined( 'EWWW_DISABLE_ASYNC' ) && EWWW_DISABLE_ASYNC ) {
9472
- $status_notices .= '<span>' . esc_html__( 'Disabled by administrator', 'ewww-image-optimizer' ) . '</span>';
9473
- } elseif ( ! ewww_image_optimizer_function_exists( 'sleep' ) ) {
9474
- $status_notices .= '<span style="color: orange; font-weight: bolder">' . esc_html__( 'Disabled, sleep function missing', 'ewww-image-optimizer' ) . '</span>';
9475
- } elseif ( $ewwwio_upgrading ) {
9476
- $status_notices .= '<span>' . esc_html__( 'Update detected, re-testing', 'ewww-image-optimizer' ) . '</span>';
9477
- } elseif ( ! ewww_image_optimizer_get_option( 'ewww_image_optimizer_background_optimization' ) ) {
9478
- $status_notices .= '<span style="color: orange; font-weight: bolder">' .
9479
- esc_html__( 'Disabled automatically, async requests blocked', 'ewww-image-optimizer' ) .
9480
- ' - <a href="' . admin_url( 'admin.php?action=ewww_image_optimizer_retest_background_optimization' ) . '">' .
9481
- esc_html__( 'Re-test', 'ewww-image-optimizer' ) .
9482
- '</a></span> ' .
9483
- ewwwio_help_link( 'https://docs.ewww.io/article/42-background-and-parallel-optimization-disabled', '598cb8be2c7d3a73488be237' );
9484
- } elseif ( ewww_image_optimizer_detect_wpsf_location_lock() ) {
9485
- $status_notices .= '<span style="color: orange; font-weight: bolder">' . esc_html__( "Disabled by Shield's Lock to Location feature", 'ewww-image-optimizer' ) . '</span>';
9486
- } else {
9487
- $status_notices .= '<span>' . esc_html__( 'Enabled', 'ewww-image-optimizer' ) .
9488
- ' - <a href="' . admin_url( 'admin.php?action=ewww_image_optimizer_retest_background_optimization' ) . '">' .
9489
- esc_html__( 'Re-test', 'ewww-image-optimizer' ) .
9490
- '</a></span>';
 
 
 
9491
  }
9492
- $status_notices .= "</p>\n";
9493
 
9494
- if ( ewww_image_optimizer_get_option( 'ewww_image_optimizer_metadata_remove' ) ) {
9495
- $compress_score += 5;
9496
- } else {
9497
- $compress_recommendations[] = esc_html__( 'Remove metadata from JPG images.', 'ewww-image-optimizer' ) . ewwwio_help_link( 'https://docs.ewww.io/article/7-basic-configuration', '585373d5c697912ffd6c0bb2' );
9498
  }
9499
-
9500
  // Begin building of status inside section.
9501
- $status_output .= '<div class="ewww-row"><ul class="ewww-blocks">';
9502
  $compress_score = min( $compress_score, 100 );
9503
  $resize_score = min( $resize_score, 100 );
9504
 
9505
  $guage_stroke_dasharray = 2 * pi() * 54;
9506
  $compress_stroke_dashoffset = $guage_stroke_dasharray * ( 1 - $compress_score / 100 );
9507
  $resize_stroke_dashoffset = $guage_stroke_dasharray * ( 1 - $resize_score / 100 );
9508
-
9509
- $status_output .= '<li><div id="ewww-compress" class="ewww-status-detail">';
9510
- $compress_guage = '<div id="ewww-compress-guage" class="ewww-guage" data-score="' . $compress_score . '">' .
9511
- '<svg width="120" height="120">' .
9512
- '<circle class="ewww-inactive" r="54" cy="60" cx="60" stroke-width="12"/>' .
9513
- '<circle class="ewww-active" r="54" cy="60" cx="60" stroke-width="12" style="stroke-dasharray: ' . $guage_stroke_dasharray . 'px; stroke-dashoffset: ' . $compress_stroke_dashoffset . 'px;"/>' .
9514
- '</svg>' .
9515
- '<div class="ewww-score">' . $compress_score . '%</div>' .
9516
- '</div><!-- end .ewww-guage -->';
9517
- $status_output .= $compress_guage;
9518
- $status_output .= '<div id="ewww-compress-recommend" class="ewww-recommend"><strong>' . ( $compress_score < 100 ? esc_html__( 'How do I get to 100%?', 'ewww-image-optimizer' ) : esc_html__( 'You got the perfect score!', 'ewww-image-optimizer' ) ) . '</strong>';
9519
- if ( $compress_score < 100 ) {
9520
- $status_output .= '<ul class="ewww-tooltip">';
9521
- foreach ( $compress_recommendations as $c_recommend ) {
9522
- $status_output .= "<li>$c_recommend</li>";
9523
- }
9524
- $status_output .= '</ul>';
9525
- }
9526
- $status_output .= '</div><!-- end .ewww-recommend -->';
9527
- $status_output .= '<p><strong>' . esc_html__( 'Compress', 'ewww-image-optimizer' ) . '</strong></p>';
9528
- $status_output .= '<p>' . esc_html__( 'Reduce the file size of your images without affecting quality.', 'ewww-image-optimizer' ) . '</p>';
9529
- $status_output .= '</div><!-- end .ewww-status-detail --></li>';
9530
-
9531
- $status_output .= '<li><div id="ewww-resize" class="ewww-status-detail">';
9532
- $resize_guage = '<div id="ewww-resize-guage" class="ewww-guage" data-score="' . $resize_score . '">' .
9533
- '<svg width="120" height="120">' .
9534
- '<circle class="ewww-inactive" r="54" cy="60" cx="60" stroke-width="12"/>' .
9535
- '<circle class="ewww-active" r="54" cy="60" cx="60" stroke-width="12" style="stroke-dasharray: ' . $guage_stroke_dasharray . 'px; stroke-dashoffset: ' . $resize_stroke_dashoffset . 'px;"/>' .
9536
- '</svg>' .
9537
- '<div class="ewww-score">' . $resize_score . '%</div>' .
9538
- '</div><!-- end .ewww-guage -->';
9539
- $status_output .= $resize_guage;
9540
- $status_output .= '<div id="ewww-resize-recommend" class="ewww-recommend"><strong>' . ( $resize_score < 100 ? esc_html__( 'How do I get to 100%?', 'ewww-image-optimizer' ) : esc_html__( 'You got the perfect score!', 'ewww-image-optimizer' ) ) . '</strong>';
9541
- if ( $resize_score < 100 ) {
9542
- $status_output .= '<ul class="ewww-tooltip">';
9543
- foreach ( $resize_recommendations as $r_recommend ) {
9544
- $status_output .= "<li>$r_recommend</li>";
9545
- }
9546
- $status_output .= '</ul>';
9547
- }
9548
- $status_output .= '</div><!-- end .ewww-recommend -->';
9549
- $status_output .= '<p><strong>' . esc_html__( 'Resize', 'ewww-image-optimizer' ) . '</strong></p>';
9550
- $status_output .= '<p>' . esc_html__( 'Scale or reduce the dimensions of your images for more savings.', 'ewww-image-optimizer' ) . '</p>';
9551
- $status_output .= '</div><!-- end .ewww-status-detail --></li>';
9552
-
9553
- $total_sizes = ewww_image_optimizer_savings();
9554
- $total_savings = $total_sizes[1] - $total_sizes[0];
 
 
 
9555
  if ( $total_savings > 0 ) {
9556
  $savings_stroke_dashoffset = $guage_stroke_dasharray * ( 1 - $total_savings / $total_sizes[1] );
9557
-
9558
- $status_output .= '<li><div id="ewww-compress" class="ewww-status-detail">';
9559
- $savings_guage = '<div id="ewww-savings-guage" class="ewww-guage" data-score="' . $total_savings / $total_sizes[1] . '">' .
9560
- '<svg width="120" height="120">' .
9561
- '<title>' . round( $total_savings / $total_sizes[1], 3 ) * 100 . '%</title>' .
9562
- '<circle class="ewww-inactive" r="54" cy="60" cx="60" stroke-width="12"/>' .
9563
- '<circle class="ewww-active" r="54" cy="60" cx="60" stroke-width="12" style="stroke-dasharray: ' . $guage_stroke_dasharray . 'px; stroke-dashoffset: ' . $savings_stroke_dashoffset . 'px;"/>' .
9564
- '</svg>' .
9565
- '<div class="ewww-score">' . ewww_image_optimizer_size_format( $total_savings, 2 ) . '</div>' .
9566
- '</div><!-- end .ewww-guage -->';
9567
- $status_output .= $savings_guage;
9568
- $status_output .= '<p style="text-align:center"><strong>' . esc_html__( 'Savings', 'ewww-image-optimizer' ) . '</strong></p>';
9569
- if ( 'network-multisite' !== $network ) {
9570
- $status_output .= '<p><a href="' . admin_url( 'tools.php?page=ewww-image-optimizer-tools' ) . '">' . esc_html__( 'View optimized images.', 'ewww-image-optimizer' ) . '</a></p>';
9571
- }
9572
- $status_output .= '</div><!-- end .ewww-status-detail --></li>';
9573
- }
9574
- ewwwio_debug_message( ewww_image_optimizer_aux_images_table_count() . ' images have been optimized' );
9575
-
9576
- $status_output .= '<li><div class="ewww-status-detail"><div id="ewww-notices">' . $status_notices . '</div></div></li>';
9577
-
9578
- $status_output .= '</ul><!-- end .ewww-blocks --></div><!-- end .ewww-row -->';
9579
- $status_output .= '</div><!-- end .inside -->';
9580
- $status_output .= "</div></div></div>\n";
9581
-
9582
- // End status section.
9583
- $output[] = $status_output;
9584
-
9585
- if ( ( 'network-multisite' !== $network || ! get_site_option( 'ewww_image_optimizer_allow_multisite_override' ) ) && // Display tabs so long as this isn't the network admin OR single-site override is disabled.
9586
- ! ( 'network-singlesite' === $network && ! get_site_option( 'ewww_image_optimizer_allow_multisite_override' ) ) ) { // Also make sure that this isn't single site without override mode.
9587
- $output[] = "<ul class='ewww-tab-nav'>\n" .
9588
- "<li class='ewww-tab ewww-general-nav'><span>" . esc_html__( 'Basic', 'ewww-image-optimizer' ) . "</span></li>\n" .
9589
- ( get_option( 'easyio_exactdn' ) ? '' : "<li class='ewww-tab ewww-exactdn-nav'><span>" . esc_html__( 'Easy Mode', 'ewww-image-optimizer' ) . "</span></li>\n" ) .
9590
- "<li class='ewww-tab ewww-optimization-nav'><span>" . esc_html__( 'Advanced', 'ewww-image-optimizer' ) . "</span></li>\n" .
9591
- "<li class='ewww-tab ewww-resize-nav'><span>" . esc_html__( 'Resize', 'ewww-image-optimizer' ) . "</span></li>\n" .
9592
- "<li class='ewww-tab ewww-conversion-nav'><span>" . esc_html__( 'Convert', 'ewww-image-optimizer' ) . "</span></li>\n" .
9593
- "<li class='ewww-tab ewww-webp-nav'><span>" . esc_html__( 'WebP', 'ewww-image-optimizer' ) . "</span></li>\n" .
9594
- "<li class='ewww-tab ewww-overrides-nav'><span><a href='https://docs.ewww.io/article/40-override-options' target='_blank'><span class='ewww-tab-hidden'>" . esc_html__( 'Overrides', 'ewww-image-optimizer' ) . "</a></span></li>\n" .
9595
- "<li class='ewww-tab ewww-support-nav'><span>" . esc_html__( 'Support', 'ewww-image-optimizer' ) . "</span></li>\n" .
9596
- "<li class='ewww-tab ewww-contribute-nav'><span>" . esc_html__( 'Contribute', 'ewww-image-optimizer' ) . "</span></li>\n" .
9597
- "</ul>\n";
9598
- }
9599
- if ( 'network-multisite' === $network ) {
9600
- $output[] = "<form method='post' action=''>\n";
9601
- } else {
9602
- $output[] = "<form method='post' action='options.php'>\n";
9603
- }
9604
- $output[] = "<input type='hidden' name='option_page' value='ewww_image_optimizer_options' />\n";
9605
- $output[] = "<input type='hidden' name='action' value='update' />\n";
9606
- $output[] = wp_nonce_field( 'ewww_image_optimizer_options-options', '_wpnonce', true, false ) . "\n";
9607
- if ( is_multisite() && is_plugin_active_for_network( EWWW_IMAGE_OPTIMIZER_PLUGIN_FILE_REL ) && ! get_site_option( 'ewww_image_optimizer_allow_multisite_override' ) ) {
9608
- $output[] = '<i class="network-singlesite"><strong>' . esc_html__( 'Configure network-wide settings in the Network Admin.', 'ewww-image-optimizer' ) . "</strong></i>\n";
9609
- }
9610
- if ( ewww_image_optimizer_get_option( 'ewww_image_optimizer_noauto' ) ) {
9611
- ewwwio_debug_message( 'automatic compression disabled' );
9612
- } else {
9613
- ewwwio_debug_message( 'automatic compression enabled' );
9614
- }
9615
- $output[] = "<div id='ewww-general-settings'>\n";
9616
- $output[] = '<noscript><h2>' . esc_html__( 'Basic', 'ewww-image-optimizer' ) . '</h2></noscript>';
9617
- if ( $exactdn_enabled && ! ewww_image_optimizer_get_option( 'ewww_image_optimizer_cloud_key' ) ) {
9618
- $output[] = '<p>' . esc_html__( 'Easy IO copies your images to our CDN for optimization and does not affect the local images stored on your server. The Basic settings are not necessary for performance while Easy IO is active, but can help you to save server storage space.', 'ewww-image-optimizer' ) . "</p>\n";
9619
- }
9620
- $output[] = "<table class='form-table'>\n";
9621
- if ( is_multisite() ) {
9622
- if ( is_plugin_active_for_network( EWWW_IMAGE_OPTIMIZER_PLUGIN_FILE_REL ) ) {
9623
- $output[] = "<tr class='network-only'><th scope='row'><label for='ewww_image_optimizer_allow_multisite_override'>" . esc_html__( 'Allow Single-site Override', 'ewww-image-optimizer' ) . "</label></th><td><input type='checkbox' id='ewww_image_optimizer_allow_multisite_override' name='ewww_image_optimizer_allow_multisite_override' value='true' " . ( get_site_option( 'ewww_image_optimizer_allow_multisite_override' ) ? "checked='true'" : '' ) . ' /> ' . esc_html__( 'Allow individual sites to configure their own settings and override all network options.', 'ewww-image-optimizer' ) . "</td></tr>\n";
9624
- }
9625
- if ( 'network-multisite' === $network && get_site_option( 'ewww_image_optimizer_allow_multisite_override' ) ) {
9626
- $output[] = "<tr><th scope='row'><label for='ewww_image_optimizer_allow_tracking'>" . esc_html__( 'Allow Usage Tracking?', 'ewww-image-optimizer' ) . "</label></th><td><input type='checkbox' id='ewww_image_optimizer_allow_tracking' name='ewww_image_optimizer_allow_tracking' value='true' " . ( get_site_option( 'ewww_image_optimizer_allow_tracking' ) ? "checked='true'" : '' ) . ' /> ' .
9627
- esc_html__( 'Allow EWWW Image Optimizer to anonymously track how this plugin is used and help us make the plugin better. Opt-in to tracking and receive 500 API image credits free. No sensitive data is tracked.', 'ewww-image-optimizer' ) . "</td></tr>\n";
9628
- $output[] = "<input type='hidden' id='ewww_image_optimizer_allow_multisite_override_active' name='ewww_image_optimizer_allow_multisite_override_active' value='0'>";
9629
- if ( get_site_option( 'ewww_image_optimizer_cloud_key' ) ) {
9630
- $output[] = "<input type='hidden' id='ewww_image_optimizer_cloud_key' name='ewww_image_optimizer_cloud_key' value='" . get_site_option( 'ewww_image_optimizer_cloud_key' ) . "' />\n";
9631
- }
9632
- foreach ( $output as $line ) {
9633
- echo $line;
9634
- }
9635
- echo '</table></div><!-- end container general settings -->';
9636
- echo "<p class='submit'><input type='submit' class='button-primary' value='" . esc_attr__( 'Save Changes', 'ewww-image-optimizer' ) . "' /></p>\n";
9637
- echo '</form></div><!-- end container wrap -->';
9638
- ewww_image_optimizer_temp_debug_clear();
9639
- return;
9640
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
9641
  }
9642
- if ( ewww_image_optimizer_get_option( 'ewww_image_optimizer_cloud_key' ) ) {
9643
- $output[] = "<tr class='$network_class'><th scope='row'><label for='ewww_image_optimizer_cloud_notkey'>" .
9644
- esc_html__( 'Optimization API Key', 'ewww-image-optimizer' ) .
9645
- "</label></th><td><input type='text' id='ewww_image_optimizer_cloud_notkey' name='ewww_image_optimizer_cloud_notkey' readonly='readonly' value='****************************" .
9646
- substr( ewww_image_optimizer_get_option( 'ewww_image_optimizer_cloud_key' ), 28 ) .
9647
- "' size='32' /> <a href='" . admin_url( 'admin.php?action=ewww_image_optimizer_remove_cloud_key' ) . "'>" .
9648
- esc_html__( 'Remove API key', 'ewww-image-optimizer' ) . "</a></td></tr>\n";
9649
- $output[] = "<input type='hidden' id='ewww_image_optimizer_cloud_key' name='ewww_image_optimizer_cloud_key' value='" . ewww_image_optimizer_get_option( 'ewww_image_optimizer_cloud_key' ) . "' />\n";
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
9650
  } else {
9651
- $output[] = "<tr class='$network_class'><th scope='row'><label for='ewww_image_optimizer_cloud_key'>" . esc_html__( 'Optimization API Key', 'ewww-image-optimizer' ) . '</label>' . ewwwio_help_link( 'https://docs.ewww.io/article/7-basic-configuration', '585373d5c697912ffd6c0bb2,5ad0c8e7042863075092650b,5a9efec62c7d3a7549516550' ) . "</th><td><input type='text' id='ewww_image_optimizer_cloud_key' name='ewww_image_optimizer_cloud_key' value='' size='32' /> " . esc_html__( 'API Key will be validated when you save your settings.', 'ewww-image-optimizer' ) . " <a href='https://ewww.io/buy-credits/' target='_blank'>" . esc_html__( 'Purchase an API key.', 'ewww-image-optimizer' ) . "</a></td></tr>\n";
9652
- }
9653
- $output[] = "<tr class='$network_class'><th scope='row'><label for='ewww_image_optimizer_metadata_remove'>" . esc_html__( 'Remove Metadata', 'ewww-image-optimizer' ) . '</label>' . ewwwio_help_link( 'https://docs.ewww.io/article/7-basic-configuration', '585373d5c697912ffd6c0bb2' ) . "</th>\n" .
9654
- "<td><input type='checkbox' id='ewww_image_optimizer_metadata_remove' name='ewww_image_optimizer_metadata_remove' value='true' " . ( ewww_image_optimizer_get_option( 'ewww_image_optimizer_metadata_remove' ) ? "checked='true'" : '' ) . ' /> ' . esc_html__( 'This will remove ALL metadata: EXIF, comments, color profiles, and anything else that is not pixel data.', 'ewww-image-optimizer' ) .
9655
- "<p class ='description'>" . esc_html__( 'Color profiles are preserved when using the API or Easy IO.', 'ewww-image-optimizer' ) . "</p></td></tr>\n";
9656
- ewwwio_debug_message( 'remove metadata: ' . ( ewww_image_optimizer_get_option( 'ewww_image_optimizer_metadata_remove' ) ? 'on' : 'off' ) );
9657
-
9658
- $maybe_api_level = ewww_image_optimizer_get_option( 'ewww_image_optimizer_cloud_key' ) ? '*' : '';
9659
-
9660
- $output[] = "<tr class='$network_class'><th scope='row'><label for='ewww_image_optimizer_jpg_level'>" . esc_html__( 'JPG Optimization Level', 'ewww-image-optimizer' ) . '</label>' . ewwwio_help_link( 'https://docs.ewww.io/article/7-basic-configuration', '585373d5c697912ffd6c0bb2' ) . "</th>\n" .
9661
- "<td><span><select id='ewww_image_optimizer_jpg_level' name='ewww_image_optimizer_jpg_level'>\n" .
9662
- "<option value='0'" . selected( ewww_image_optimizer_get_option( 'ewww_image_optimizer_jpg_level' ), 0, false ) . '>' . esc_html__( 'No Compression', 'ewww-image-optimizer' ) . "</option>\n";
9663
- if ( defined( 'EWWW_IMAGE_OPTIMIZER_TOOL_PATH' ) ) {
9664
- $output[] = "<option class='$network_class' value='10'" . selected( ewww_image_optimizer_get_option( 'ewww_image_optimizer_jpg_level' ), 10, false ) . '>' . esc_html__( 'Pixel Perfect', 'ewww-image-optimizer' ) . "</option>\n";
9665
- }
9666
- $output[] = "<option class='$network_class' $disable_level value='20'" . selected( ewww_image_optimizer_get_option( 'ewww_image_optimizer_jpg_level' ), 20, false ) . '>' . esc_html__( 'Pixel Perfect Plus', 'ewww-image-optimizer' ) . " *</option>\n" .
9667
- "<option $disable_level value='30'" . selected( ewww_image_optimizer_get_option( 'ewww_image_optimizer_jpg_level' ), 30, false ) . '>' . esc_html__( 'Premium', 'ewww-image-optimizer' ) . " *</option>\n" .
9668
- "<option $disable_level value='40'" . selected( ewww_image_optimizer_get_option( 'ewww_image_optimizer_jpg_level' ), 40, false ) . '>' . esc_html__( 'Premium Plus', 'ewww-image-optimizer' ) . " *</option>\n" .
9669
- "</select></td></tr>\n";
9670
- ewwwio_debug_message( 'jpg level: ' . ewww_image_optimizer_get_option( 'ewww_image_optimizer_jpg_level' ) );
9671
- $output[] = "<tr class='$network_class'><th scope='row'><label for='ewww_image_optimizer_png_level'>" . esc_html__( 'PNG Optimization Level', 'ewww-image-optimizer' ) . '</label>' . ewwwio_help_link( 'https://docs.ewww.io/article/7-basic-configuration', '585373d5c697912ffd6c0bb2,5854531bc697912ffd6c1afa' ) . "</th>\n" .
9672
- "<td><span><select id='ewww_image_optimizer_png_level' name='ewww_image_optimizer_png_level'>\n" .
9673
- "<option value='0'" . selected( ewww_image_optimizer_get_option( 'ewww_image_optimizer_png_level' ), 0, false ) . '>' . esc_html__( 'No Compression', 'ewww-image-optimizer' ) . "</option>\n";
9674
- if ( defined( 'EWWW_IMAGE_OPTIMIZER_TOOL_PATH' ) ) {
9675
- $output[] = "<option class='$network_class' value='10'" . selected( ewww_image_optimizer_get_option( 'ewww_image_optimizer_png_level' ), 10, false ) . '>' . esc_html__( 'Pixel Perfect', 'ewww-image-optimizer' ) . "</option>\n";
9676
- }
9677
- $output[] = "<option class='$network_class' $disable_level value='20' " . selected( ewww_image_optimizer_get_option( 'ewww_image_optimizer_png_level' ), 20, false ) .
9678
- selected( ewww_image_optimizer_get_option( 'ewww_image_optimizer_png_level' ), 30, false ) . '>' . esc_html__( 'Pixel Perfect Plus', 'ewww-image-optimizer' ) . " *</option>\n" .
9679
- "<option value='40'" . selected( ewww_image_optimizer_get_option( 'ewww_image_optimizer_png_level' ), 40, false ) . '>' . esc_html__( 'Premium', 'ewww-image-optimizer' ) . " $maybe_api_level</option>\n" .
9680
- "<option $disable_level value='50'" . selected( ewww_image_optimizer_get_option( 'ewww_image_optimizer_png_level' ), 50, false ) . '>' . esc_html__( 'Premium Plus', 'ewww-image-optimizer' ) . " *</option>\n" .
9681
- "</select></td></tr>\n";
9682
- ewwwio_debug_message( 'png level: ' . ewww_image_optimizer_get_option( 'ewww_image_optimizer_png_level' ) );
9683
- $output[] = "<tr class='$network_class'><th scope='row'><label for='ewww_image_optimizer_gif_level'>" . esc_html__( 'GIF Optimization Level', 'ewww-image-optimizer' ) . '</label>' . ewwwio_help_link( 'https://docs.ewww.io/article/7-basic-configuration', '585373d5c697912ffd6c0bb2' ) . "</th>\n" .
9684
- "<td><span><select id='ewww_image_optimizer_gif_level' name='ewww_image_optimizer_gif_level'>\n" .
9685
- "<option value='0'" . selected( ewww_image_optimizer_get_option( 'ewww_image_optimizer_gif_level' ), 0, false ) . '>' . esc_html__( 'No Compression', 'ewww-image-optimizer' ) . "</option>\n" .
9686
- "<option value='10'" . selected( ewww_image_optimizer_get_option( 'ewww_image_optimizer_gif_level' ), 10, false ) . '>' . esc_html__( 'Pixel Perfect', 'ewww-image-optimizer' ) . " $maybe_api_level</option>\n" .
9687
- "</select></td></tr>\n";
9688
- ewwwio_debug_message( 'gif level: ' . ewww_image_optimizer_get_option( 'ewww_image_optimizer_gif_level' ) );
9689
- $output[] = "<tr class='$network_class'><th scope='row'><label for='ewww_image_optimizer_pdf_level'>" . esc_html__( 'PDF Optimization Level', 'ewww-image-optimizer' ) . '</label>' . ewwwio_help_link( 'https://docs.ewww.io/article/7-basic-configuration', '585373d5c697912ffd6c0bb2' ) . "</th>\n" .
9690
- "<td><span><select id='ewww_image_optimizer_pdf_level' name='ewww_image_optimizer_pdf_level'>\n" .
9691
- "<option value='0'" . selected( ewww_image_optimizer_get_option( 'ewww_image_optimizer_pdf_level' ), 0, false ) . '>' . esc_html__( 'No Compression', 'ewww-image-optimizer' ) . "</option>\n" .
9692
- "<option $disable_level value='10'" . selected( ewww_image_optimizer_get_option( 'ewww_image_optimizer_pdf_level' ), 10, false ) . '>' . esc_html__( 'Pixel Perfect', 'ewww-image-optimizer' ) . " *</option>\n" .
9693
- "<option $disable_level value='20'" . selected( ewww_image_optimizer_get_option( 'ewww_image_optimizer_pdf_level' ), 20, false ) . '>' . esc_html__( 'High Compression', 'ewww-image-optimizer' ) . " *</option>\n" .
9694
- "</select></td></tr>\n";
9695
- ewwwio_debug_message( 'pdf level: ' . ewww_image_optimizer_get_option( 'ewww_image_optimizer_pdf_level' ) );
9696
- $output[] = "<tr class='$network_class'><th>&nbsp;</th><td>" .
9697
- ( ! ewww_image_optimizer_get_option( 'ewww_image_optimizer_cloud_key' ) ? "<p class='$network_class nocloud'>* <strong><a href='https://ewww.io/buy-credits/' target='_blank'>" . esc_html__( 'Purchase an API key to unlock these optimization levels and get priority support. Achieve up to 80% compression to speed up your site, save storage space, and reduce server load.', 'ewww-image-optimizer' ) . "</a></strong></p>\n" :
9698
- '<p>* ' . esc_html__( 'These levels use the compression API.', 'ewww-image-optimizer' ) ) .
9699
- "<p class='$network_class description'>" . esc_html__( 'All methods used by the EWWW Image Optimizer are intended to produce visually identical images.', 'ewww-image-optimizer' ) . "</p>\n" .
9700
- "</td></tr>\n";
9701
- ewwwio_debug_message( 'bulk delay: ' . ewww_image_optimizer_get_option( 'ewww_image_optimizer_delay' ) );
9702
- $output[] = "<tr class='$network_class'><th scope='row'><label for='ewww_image_optimizer_backup_files'>" . esc_html__( 'Backup Originals', 'ewww-image-optimizer' ) . '</label>' . ewwwio_help_link( 'https://docs.ewww.io/article/7-basic-configuration', '585373d5c697912ffd6c0bb2' ) . '</th>' .
9703
- "<td><input type='checkbox' id='ewww_image_optimizer_backup_files' name='ewww_image_optimizer_backup_files' value='true' " .
9704
- ( ewww_image_optimizer_get_option( 'ewww_image_optimizer_backup_files' ) ? "checked='true'" : '' ) . " $disable_level > " . esc_html__( 'Store a copy of your original images on our secure server for 30 days. *Requires an active API key.', 'ewww-image-optimizer' ) . "</td></tr>\n";
9705
- ewwwio_debug_message( 'backup mode: ' . ( ewww_image_optimizer_get_option( 'ewww_image_optimizer_backup_files' ) ? 'on' : 'off' ) );
9706
- if ( class_exists( 'Cloudinary' ) && Cloudinary::config_get( 'api_secret' ) ) {
9707
- $output[] = "<tr class='$network_class'><th scope='row'><label for='ewww_image_optimizer_enable_cloudinary'>" .
9708
- esc_html__( 'Automatic Cloudinary Upload', 'ewww-image-optimizer' ) .
9709
- "</label></th><td><input type='checkbox' id='ewww_image_optimizer_enable_cloudinary' name='ewww_image_optimizer_enable_cloudinary' value='true' " .
9710
- ( ewww_image_optimizer_get_option( 'ewww_image_optimizer_enable_cloudinary' ) ? "checked='true'" : '' ) . ' /> ' .
9711
- esc_html__( 'When enabled, uploads to the Media Library will be transferred to Cloudinary after optimization. Cloudinary generates resizes, so only the full-size image is uploaded.', 'ewww-image-optimizer' ) .
9712
- "</td></tr>\n";
9713
- ewwwio_debug_message( 'cloudinary upload: ' . ( ewww_image_optimizer_get_option( 'ewww_image_optimizer_enable_cloudinary' ) ? 'on' : 'off' ) );
9714
- }
9715
- $output[] = "</table>\n</div>\n";
9716
-
9717
- $exactdn_enabled = ewww_image_optimizer_get_option( 'ewww_image_optimizer_exactdn' );
9718
- $eio_base = new EIO_Base();
9719
- $easyio_site_url = $eio_base->content_url();
9720
-
9721
- $output[] = "<div id='ewww-exactdn-settings'>\n";
9722
- $output[] = '<noscript><h2>' . esc_html__( 'Easy Mode', 'ewww-image-optimizer' ) . '</h2></noscript>';
9723
- $output[] = '<p>' . esc_html__( 'Having problems? Try disabling Lazy Load and Include All Resources. Finally, disable Easy IO if problems remain.', 'ewww-image-optimizer' ) . "<br>\n" .
9724
- "<a class='ewww-docs-root' href='https://ewww.io/contact-us/'>" . esc_html__( 'Then, let us know so we can find a fix for the problem.', 'ewww-image-optimizer' ) . "</a></p>\n";
9725
- $output[] = "<table class='form-table'>\n";
9726
- $output[] = "<tr class='$network_class'><th scope='row'><label for='ewww_image_optimizer_exactdn'>" . esc_html__( 'Easy IO', 'ewww-image-optimizer' ) .
9727
- '</label>' . ewwwio_help_link( 'https://docs.ewww.io/article/44-introduction-to-exactdn', '59bc5ad6042863033a1ce370,5c0042892c7d3a31944e88a4' ) .
9728
- "</th><td><input type='checkbox' id='ewww_image_optimizer_exactdn' name='ewww_image_optimizer_exactdn' value='true' " .
9729
- ( $exactdn_enabled ? "checked='true'" : '' ) . ' /> ' .
9730
- esc_html__( 'Comprehensive and automatic image optimization:', 'ewww-image-optimizer' ) .
9731
- '<p class="description">' .
9732
- esc_html__( 'Premium Compression', 'ewww-image-optimizer' ) . '<br>' .
9733
- esc_html__( 'Properly scale images to fit any device', 'ewww-image-optimizer' ) . '<br>' .
9734
- esc_html__( 'Automatic WebP Conversion', 'ewww-image-optimizer' ) . '<br>' .
9735
- esc_html__( 'Smart Image Conversion', 'ewww-image-optimizer' ) . '<br>' .
9736
- esc_html__( 'JS/CSS Minification and Compression', 'ewww-image-optimizer' ) . '<br>' .
9737
- esc_html__( 'CDN Included', 'ewww-image-optimizer' ) . '<br>' .
9738
- ( $exactdn_enabled ? '' : '<strong><a href="https://ewww.io/resize/" target="_blank">' . esc_html__( 'Purchase a subscription for your site.', 'ewww-image-optimizer' ) . '</a></strong><br>' .
9739
- '<a href="https://ewww.io/manage-sites/" target="_blank">' . esc_html__( 'Then, add your Site URL to your account:', 'easy-image-optimizer' ) . "</a> $easyio_site_url<br>" ) .
9740
- '<a href="https://docs.ewww.io/article/44-introduction-to-exactdn" target="_blank" data-beacon-article="59bc5ad6042863033a1ce370">' . esc_html__( 'Learn more about Easy IO', 'ewww-image-optimizer' ) . '</a>' .
9741
- "</p></td></tr>\n";
9742
- ewwwio_debug_message( 'ExactDN enabled: ' . ( $exactdn_enabled ? 'on' : 'off' ) );
9743
- $output[] = "<tr class='$network_class'><td>&nbsp;</td>" .
9744
- "<td><input type='checkbox' name='exactdn_all_the_things' value='true' " .
9745
- ( ! $exactdn_enabled || 1 === $exactdn->get_plan_id() ? " id='exactdn_all_the_things_disabled' disabled " : " id='exactdn_all_the_things' " ) .
9746
- ( ewww_image_optimizer_get_option( 'exactdn_all_the_things' ) && ( ! is_object( $exactdn ) || 1 < $exactdn->get_plan_id() ) ? "checked='true'" : '' ) . '> ' .
9747
- "<label for='exactdn_all_the_things'><strong>" . esc_html__( 'Include All Resources', 'ewww-image-optimizer' ) . '</strong></label>' . ewwwio_help_link( 'https://docs.ewww.io/article/47-getting-more-from-exactdn', '59de6631042863379ddc953c' ) .
9748
- "<p class='description'>" . esc_html__( 'Use Easy IO for all resources in wp-includes/ and wp-content/, including JavaScript, CSS, fonts, etc.', 'ewww-image-optimizer' ) . '</p>' .
9749
- "</td></tr>\n";
9750
- ewwwio_debug_message( 'ExactDN all the things: ' . ( ewww_image_optimizer_get_option( 'exactdn_all_the_things' ) ? 'on' : 'off' ) );
9751
- $output[] = "<tr class='$network_class'><td>&nbsp;</td>" .
9752
- "<td><input type='checkbox' name='exactdn_lossy' value='true' " .
9753
- ( ! $exactdn_enabled || 1 === $exactdn->get_plan_id() ? " id='exactdn_lossy_disabled' disabled " : " id='exactdn_lossy' " ) .
9754
- ( ( is_object( $exactdn ) && 1 === $exactdn->get_plan_id() ) || ewww_image_optimizer_get_option( 'exactdn_lossy' ) ? "checked='true'" : '' ) . '> ' .
9755
- "<label for='exactdn_lossy'><strong>" . esc_html__( 'Premium Compression', 'ewww-image-optimizer' ) . '</strong></label>' . ewwwio_help_link( 'https://docs.ewww.io/article/47-getting-more-from-exactdn', '59de6631042863379ddc953c' ) .
9756
- "<p class='description'>" . esc_html__( 'Enable high quality premium compression for all images. Disable to use Pixel Perfect mode instead.', 'ewww-image-optimizer' ) . '</p>' .
9757
- "</td></tr>\n";
9758
- ewwwio_debug_message( 'ExactDN lossy: ' . intval( ewww_image_optimizer_get_option( 'exactdn_lossy' ) ) );
9759
- ewwwio_debug_message( 'ExactDN resize existing: ' . ( ewww_image_optimizer_get_option( 'exactdn_resize_existing' ) ? 'on' : 'off' ) );
9760
- ewwwio_debug_message( 'ExactDN attachment queries: ' . ( ewww_image_optimizer_get_option( 'exactdn_prevent_db_queries' ) ? 'off' : 'on' ) );
9761
- if ( ! $exactdn_enabled || 1 === $exactdn->get_plan_id() ) {
9762
- $output[] = "<input type='hidden' id='exactdn_all_the_things' name='exactdn_all_the_things' " .
9763
- ( ewww_image_optimizer_get_option( 'exactdn_all_the_things' ) ? "value='1'" : "value='0'" ) . ">\n";
9764
- $output[] = "<input type='hidden' id='exactdn_lossy' name='exactdn_lossy' " .
9765
- ( ewww_image_optimizer_get_option( 'exactdn_lossy' ) ? "value='1'" : "value='0'" ) . ">\n";
9766
- $output[] = "<input type='hidden' id='ewww_image_optimizer_use_lqip' name='ewww_image_optimizer_use_lqip' " .
9767
- ( ewww_image_optimizer_get_option( 'ewww_image_optimizer_use_lqip' ) ? "value='1'" : "value='0'" ) . ">\n";
9768
- }
9769
- $eio_exclude_paths = ewww_image_optimizer_get_option( 'exactdn_exclude' ) ? esc_html( implode( "\n", ewww_image_optimizer_get_option( 'exactdn_exclude' ) ) ) : '';
9770
- $output[] = "<tr class='$network_class'><td>&nbsp;</td>" .
9771
- "<td><label for='exactdn_exclude'><strong>" . esc_html__( 'Exclusions', 'ewww-image-optimizer' ) . '</strong></label>' .
9772
- ewwwio_help_link( 'https://docs.ewww.io/article/68-exactdn-exclude', '5c0042892c7d3a31944e88a4' ) . '<br>' .
9773
- "<textarea id='exactdn_exclude' name='exactdn_exclude' rows='3' cols='60'>$eio_exclude_paths</textarea>\n" .
9774
- "<p class='description'>" . esc_html__( 'One exclusion per line, no wildcards (*) needed. Any pattern or path provided will not be routed through Easy IO.', 'ewww-image-optimizer' ) .
9775
- "</p></td></tr>\n";
9776
- ewwwio_debug_message( 'Easy IO exclusions:' );
9777
- ewwwio_debug_message( $eio_exclude_paths );
9778
- $output[] = "<tr class='$network_class'><th scope='row'><label for='ewww_image_optimizer_lazy_load'>" . esc_html__( 'Lazy Load', 'ewww-image-optimizer' ) . '</label>' .
9779
- ewwwio_help_link( 'https://docs.ewww.io/article/74-lazy-load', '5c6c36ed042863543ccd2d9b' ) .
9780
- "</th><td><input type='checkbox' id='ewww_image_optimizer_lazy_load' name='ewww_image_optimizer_lazy_load' value='true' " .
9781
- ( ewww_image_optimizer_get_option( 'ewww_image_optimizer_lazy_load' ) ? "checked='true'" : '' ) . ' /> ' .
9782
- esc_html__( 'Improves actual and perceived loading time as images will be loaded only as they enter (or are about to enter) the viewport.', 'ewww-image-optimizer' ) .
9783
- "<p class='description'>" . esc_html__( 'When used with Easy IO and/or JS WebP Rewriting, the plugin will load the best available image size and format for each device.', 'ewww-image-optimizer' ) . "</br>\n" .
9784
- esc_html__( 'To disable auto-scaling for an image, add "skip-autoscale" to the HTML element via a class or attribute.', 'ewww-image-optimizer' ) . "</p>\n" .
9785
- "</td></tr>\n";
9786
- ewwwio_debug_message( 'lazy load: ' . ( ewww_image_optimizer_get_option( 'ewww_image_optimizer_lazy_load' ) ? 'on' : 'off' ) );
9787
- $output[] = "<tr class='$network_class'><td>&nbsp;</td><td><input type='checkbox' name='ewww_image_optimizer_use_lqip' value='true' " .
9788
- ( ! $exactdn_enabled || 1 === $exactdn->get_plan_id() ? " id='ewww_image_optimizer_use_lqip_disabled' disabled " : " id='ewww_image_optimizer_use_lqip' " ) .
9789
- ( is_object( $exactdn ) && 1 < $exactdn->get_plan_id() && ewww_image_optimizer_get_option( 'ewww_image_optimizer_use_lqip' ) ? "checked='true'" : '' ) . ' /> ' .
9790
- "<label for='ewww_image_optimizer_use_lqip'><strong>LQIP</strong></label>" .
9791
- ewwwio_help_link( 'https://docs.ewww.io/article/75-lazy-load-placeholders', '5c9a7a302c7d3a1544615e47' ) . "\n" .
9792
- "<p class='description'>" . esc_html__( 'Use low-quality versions of your images as placeholders via Easy IO. Can improve user experience, but may be slower than blank placeholders.', 'ewww-image-optimizer' ) . '</p>' .
9793
- "</td></tr>\n";
9794
- ewwwio_debug_message( 'LQIP: ' . ( ewww_image_optimizer_get_option( 'ewww_image_optimizer_use_lqip' ) ? 'on' : 'off' ) );
9795
- $ll_exclude_paths = ewww_image_optimizer_get_option( 'ewww_image_optimizer_ll_exclude' ) ? esc_html( implode( "\n", ewww_image_optimizer_get_option( 'ewww_image_optimizer_ll_exclude' ) ) ) : '';
9796
- $output[] = "<tr class='$network_class'><td>&nbsp;</td>" .
9797
- "<td><label for='ewww_image_optimizer_ll_exclude'><strong>" . esc_html__( 'Exclusions', 'ewww-image-optimizer' ) . '</strong></label>' .
9798
- ewwwio_help_link( 'https://docs.ewww.io/article/74-lazy-load', '5c6c36ed042863543ccd2d9b' ) . '<br>' .
9799
- "<textarea id='ewww_image_optimizer_ll_exclude' name='ewww_image_optimizer_ll_exclude' rows='3' cols='60'>$ll_exclude_paths</textarea>\n" .
9800
- "<p class='description'>" .
9801
- esc_html__( 'One exclusion per line, no wildcards (*) needed. Use any string that matches the desired element(s) or exclude entire element types like "div", "span", etc. The class "skip-lazy" and attribute "data-skip-lazy" are excluded by default.', 'ewww-image-optimizer' ) .
9802
- "</p></td></tr>\n";
9803
- ewwwio_debug_message( 'LL exclusions:' );
9804
- ewwwio_debug_message( $ll_exclude_paths );
9805
- $output[] = "</table>\n</div>\n";
9806
- $output[] = "<div id='ewww-optimization-settings'>\n";
9807
- $output[] = '<noscript><h2>' . esc_html__( 'Advanced', 'ewww-image-optimizer' ) . '</h2></noscript>';
9808
- $output[] = "<table class='form-table'>\n";
9809
- if ( ! ewww_image_optimizer_full_cloud() ) {
9810
- ewwwio_debug_message( 'optipng level: ' . ewww_image_optimizer_get_option( 'ewww_image_optimizer_optipng_level' ) );
9811
- ewwwio_debug_message( 'pngout disabled: ' . ( ewww_image_optimizer_get_option( 'ewww_image_optimizer_disable_pngout' ) ? 'yes' : 'no' ) );
9812
- ewwwio_debug_message( 'pngout level: ' . ewww_image_optimizer_get_option( 'ewww_image_optimizer_pngout_level' ) );
9813
- }
9814
- $output[] = "<tr class='$network_class'><th scope='row'><span><label for='ewww_image_optimizer_jpg_quality'>" . esc_html__( 'JPG Quality Level:', 'ewww-image-optimizer' ) . '</label>' . ewwwio_help_link( 'https://docs.ewww.io/article/11-advanced-configuration', '58542afac697912ffd6c18c0,58543c69c697912ffd6c19a7' ) . "</th><td><input type='text' id='ewww_image_optimizer_jpg_quality' name='ewww_image_optimizer_jpg_quality' class='small-text' value='" . ewww_image_optimizer_jpg_quality() . "' /> " . esc_html__( 'Valid values are 1-100.', 'ewww-image-optimizer' ) . "\n<p class='description'>" . esc_html__( 'Use this to override the default WordPress quality level of 82. Applies to image editing, resizing, PNG to JPG conversion, and JPG to WebP conversion. Does not affect the original uploaded image unless maximum dimensions are set and resizing occurs.', 'ewww-image-optimizer' ) . "</p></td></tr>\n";
9815
- ewwwio_debug_message( 'effective quality: ' . ewww_image_optimizer_set_jpg_quality( 82 ) );
9816
- $output[] = "<tr class='$network_class'><th scope='row'><label for='ewww_image_optimizer_parallel_optimization'>" . esc_html__( 'Parallel Optimization', 'ewww-image-optimizer' ) . '</label>' . ewwwio_help_link( 'https://docs.ewww.io/article/11-advanced-configuration', '58542afac697912ffd6c18c0,598cb8be2c7d3a73488be237' ) . "</th><td><input type='checkbox' id='ewww_image_optimizer_parallel_optimization' name='ewww_image_optimizer_parallel_optimization' value='true' " . ( ewww_image_optimizer_get_option( 'ewww_image_optimizer_parallel_optimization' ) ? "checked='true'" : '' ) . ' /> ' . esc_html__( 'All resizes generated from a single upload are optimized in parallel for faster optimization. If this is causing performance issues, disable parallel optimization to reduce the load on your server.', 'ewww-image-optimizer' ) . "</td></tr>\n";
9817
- ewwwio_debug_message( 'parallel optimization: ' . ( ewww_image_optimizer_get_option( 'ewww_image_optimizer_parallel_optimization' ) ? 'on' : 'off' ) );
9818
- ewwwio_debug_message( 'background optimization: ' . ( ewww_image_optimizer_get_option( 'ewww_image_optimizer_background_optimization' ) ? 'on' : 'off' ) );
9819
- if ( ! $ewwwio_upgrading && ! ewww_image_optimizer_get_option( 'ewww_image_optimizer_background_optimization' ) ) {
9820
- $admin_ajax_url = admin_url( 'admin-ajax.php' );
9821
- if ( strpos( $admin_ajax_url, 'admin-ajax.php' ) ) {
9822
- ewwwio_debug_message( "admin ajax url: $admin_ajax_url" );
9823
- $admin_ajax_host = parse_url( $admin_ajax_url, PHP_URL_HOST );
9824
- ewwwio_debug_message( "admin ajax hostname: $admin_ajax_host" );
9825
- $resolved = gethostbyname( $admin_ajax_host . '.' );
9826
- ewwwio_debug_message( "resolved to $resolved" );
9827
- if ( $resolved === $admin_ajax_host . '.' ) {
9828
- ewwwio_debug_message( 'DNS lookup failed' );
9829
- } else {
9830
- $admin_ajax_url = add_query_arg(
9831
- array(
9832
- 'action' => 'wp_ewwwio_test_optimize',
9833
- 'nonce' => wp_create_nonce( 'wp_ewwwio_test_optimize' ),
9834
- ),
9835
- $admin_ajax_url
9836
- );
9837
- ewwwio_debug_message( "admin ajax POST url: $admin_ajax_url" );
9838
- $async_post_args = array(
9839
- 'body' => array(
9840
- 'ewwwio_test_verify' => '949c34123cf2a4e4ce2f985135830df4a1b2adc24905f53d2fd3f5df5b16293245',
9841
- ),
9842
- 'cookies' => $_COOKIE,
9843
- 'sslverify' => false,
9844
- );
9845
- // Don't lock up other requests while processing.
9846
- session_write_close();
9847
- $async_response = wp_remote_post( esc_url_raw( $admin_ajax_url ), $async_post_args );
9848
- if ( is_wp_error( $async_response ) ) {
9849
- $error_message = $async_response->get_error_message();
9850
- ewwwio_debug_message( "async test failed: $error_message" );
9851
- } elseif ( is_array( $async_response ) && isset( $async_response['body'] ) ) {
9852
- ewwwio_debug_message( 'async success, possibly (response should be empty): ' . esc_html( substr( $async_response['body'], 0, 100 ) ) );
9853
- if ( ! empty( $async_response['response']['code'] ) ) {
9854
- ewwwio_debug_message( 'async response code: ' . $async_response['response']['code'] );
9855
- }
9856
- } else {
9857
- ewwwio_debug_message( 'no async error, but no body either' );
9858
- }
9859
- }
9860
- } else {
9861
- ewwwio_debug_message( "invalid admin ajax url: $admin_ajax_url" );
9862
- }
9863
- }
9864
- $output[] = "<tr class='$network_class'><th scope='row'><label for='ewww_image_optimizer_auto'>" . esc_html__( 'Scheduled Optimization', 'ewww-image-optimizer' ) . '</label>' .
9865
- ewwwio_help_link( 'https://docs.ewww.io/article/11-advanced-configuration', '58542afac697912ffd6c18c0,5853713bc697912ffd6c0b98' ) .
9866
- "</th><td><input type='checkbox' id='ewww_image_optimizer_auto' name='ewww_image_optimizer_auto' value='true' " .
9867
- ( ewww_image_optimizer_get_option( 'ewww_image_optimizer_auto' ) ? "checked='true'" : '' ) . ' /> ' .
9868
- esc_html__( 'This will enable scheduled optimization of unoptimized images for your theme, buddypress, and any additional folders you have configured below. Runs hourly: wp_cron only runs when your site is visited, so it may be even longer between optimizations.', 'ewww-image-optimizer' ) .
9869
- "</td></tr>\n";
9870
- ewwwio_debug_message( 'scheduled optimization: ' . ( ewww_image_optimizer_get_option( 'ewww_image_optimizer_auto' ) ? 'on' : 'off' ) );
9871
  $media_include_disable = '';
9872
  if ( ewww_image_optimizer_get_option( 'ewww_image_optimizer_disable_resizes_opt', false, true ) ) {
9873
- $media_include_disable = 'disabled="disabled"';
9874
- $output[] = "<tr class='$network_class'><th>&nbsp;</th><td>" .
9875
- '<p><span style="color: #3eadc9">' . esc_html__( '*Include Media Library Folders has been disabled because it will cause the scanner to ignore the disabled resizes.', 'ewww-image-optimizer' ) . "</span></p></td></tr>\n";
9876
- }
9877
- $output[] = "<tr class='$network_class'><th scope='row'><label for='ewww_image_optimizer_include_media_paths'>" .
9878
- esc_html__( 'Include Media Folders', 'ewww-image-optimizer' ) . '</label>' .
9879
- ewwwio_help_link( 'https://docs.ewww.io/article/11-advanced-configuration', '58542afac697912ffd6c18c0,5853713bc697912ffd6c0b98' ) .
9880
- "</th><td><input type='checkbox' id='ewww_image_optimizer_include_media_paths' name='ewww_image_optimizer_include_media_paths' $media_include_disable value='true' " .
9881
- ( ewww_image_optimizer_get_option( 'ewww_image_optimizer_include_media_paths' ) && ! ewww_image_optimizer_get_option( 'ewww_image_optimizer_disable_resizes_opt', false, true ) ? "checked='true'" : '' ) . ' /> ' .
9882
- esc_html__( 'Scan all images from the latest two folders of the Media Library during the Bulk Optimizer and Scheduled Optimization.', 'ewww-image-optimizer' ) . "</td></tr>\n";
9883
- ewwwio_debug_message( 'include media library: ' . ( ewww_image_optimizer_get_option( 'ewww_image_optimizer_include_media_paths' ) ? 'on' : 'off' ) );
9884
- $output[] = "<tr class='$network_class'><th scope='row'><label for='ewww_image_optimizer_include_originals'>" .
9885
- esc_html__( 'Include Originals', 'ewww-image-optimizer' ) . '</label>' .
9886
- ewwwio_help_link( 'https://docs.ewww.io/article/11-advanced-configuration', '58542afac697912ffd6c18c0' ) .
9887
- "</th><td><input type='checkbox' id='ewww_image_optimizer_include_originals' name='ewww_image_optimizer_include_originals' value='true' " .
9888
- ( ewww_image_optimizer_get_option( 'ewww_image_optimizer_include_originals' ) ? "checked='true'" : '' ) . ' /> ' .
9889
- esc_html__( 'Optimize the original version of images that have been scaled down by WordPress.', 'ewww-image-optimizer' ) . "</td></tr>\n";
9890
- ewwwio_debug_message( 'include originals: ' . ( ewww_image_optimizer_get_option( 'ewww_image_optimizer_include_originals' ) ? 'on' : 'off' ) );
9891
- $aux_paths = ewww_image_optimizer_get_option( 'ewww_image_optimizer_aux_paths' ) ? esc_html( implode( "\n", ewww_image_optimizer_get_option( 'ewww_image_optimizer_aux_paths' ) ) ) : '';
9892
- $output[] = "<tr class='$network_class'><th scope='row'><label for='ewww_image_optimizer_aux_paths'>" . esc_html__( 'Folders to Optimize', 'ewww-image-optimizer' ) . '</label>'
9893
- . ewwwio_help_link( 'https://docs.ewww.io/article/11-advanced-configuration', '58542afac697912ffd6c18c0,5853713bc697912ffd6c0b98' ) . '</th><td>' .
9894
- /* translators: %s: the folder where WordPress is installed */
9895
- sprintf( esc_html__( 'One path per line, must be within %s. Use full paths, not relative paths.', 'ewww-image-optimizer' ), ABSPATH ) . "<br>\n" .
9896
- "<textarea id='ewww_image_optimizer_aux_paths' name='ewww_image_optimizer_aux_paths' rows='3' cols='60'>$aux_paths</textarea>\n" .
9897
- "<p class='description'>" . esc_html__( 'Provide paths containing images to be optimized using the Bulk Optimizer and Scheduled Optimization.', 'ewww-image-optimizer' ) . "</p></td></tr>\n";
9898
- ewwwio_debug_message( 'folders to optimize:' );
9899
- ewwwio_debug_message( $aux_paths );
9900
-
9901
- $exclude_paths = ewww_image_optimizer_get_option( 'ewww_image_optimizer_exclude_paths' ) ? esc_html( implode( "\n", ewww_image_optimizer_get_option( 'ewww_image_optimizer_exclude_paths' ) ) ) : '';
9902
- $output[] = "<tr class='$network_class'><th scope='row'><label for='ewww_image_optimizer_exclude_paths'>" . esc_html__( 'Folders to Ignore', 'ewww-image-optimizer' ) . '</label>' . ewwwio_help_link( 'https://docs.ewww.io/article/11-advanced-configuration', '58542afac697912ffd6c18c0,5853713bc697912ffd6c0b98' ) . '</th><td>' . esc_html__( 'One path per line, partial paths allowed, but no urls.', 'ewww-image-optimizer' ) . "<br>\n" .
9903
- "<textarea id='ewww_image_optimizer_exclude_paths' name='ewww_image_optimizer_exclude_paths' rows='3' cols='60'>$exclude_paths</textarea>\n" .
9904
- "<p class='description'>" . esc_html__( 'A file that matches any pattern or path provided will not be optimized.', 'ewww-image-optimizer' ) . "</p></td></tr>\n";
9905
- ewwwio_debug_message( 'folders to ignore:' );
9906
- ewwwio_debug_message( $exclude_paths );
9907
- ewwwio_debug_message( 'skip images smaller than: ' . ewww_image_optimizer_get_option( 'ewww_image_optimizer_skip_size' ) . ' bytes' );
9908
- ewwwio_debug_message( 'skip PNG images larger than: ' . ewww_image_optimizer_get_option( 'ewww_image_optimizer_skip_png_size' ) . ' bytes' );
9909
- ewwwio_debug_message( 'exclude originals from lossy: ' . ( ewww_image_optimizer_get_option( 'ewww_image_optimizer_lossy_skip_full' ) ? 'on' : 'off' ) );
9910
- ewwwio_debug_message( 'exclude originals from metadata removal: ' . ( ewww_image_optimizer_get_option( 'ewww_image_optimizer_metadata_skip_full' ) ? 'on' : 'off' ) );
9911
- ewwwio_debug_message( 'use system binaries: ' . ( ewww_image_optimizer_get_option( 'ewww_image_optimizer_skip_bundle' ) ? 'yes' : 'no' ) );
9912
- $output[] = "</table>\n</div>\n";
9913
-
9914
- $output[] = "<div id='ewww-resize-settings'>\n";
9915
- $output[] = '<noscript><h2>' . esc_html__( 'Resize', 'ewww-image-optimizer' ) . '</h2></noscript>';
9916
- $output[] = "<table class='form-table'>\n";
9917
- $output[] = "<tr class='$network_class'><th scope='row'><label for='ewww_image_optimizer_resize_detection'>" . esc_html__( 'Resize Detection', 'ewww-image-optimizer' ) . '</label>' .
9918
- ewwwio_help_link( 'https://docs.ewww.io/article/41-resize-settings', '59849911042863033a1ba5f9' ) .
9919
- "</th><td><input type='checkbox' id='ewww_image_optimizer_resize_detection' name='ewww_image_optimizer_resize_detection' value='true' " .
9920
- ( ewww_image_optimizer_get_option( 'ewww_image_optimizer_resize_detection' ) ? "checked='true'" : '' ) . ' /> ' .
9921
- esc_html__( 'Highlight images that need to be resized because the browser is scaling them down. Only visible for Admin users and adds a button to the admin bar to detect scaled images that have been lazy loaded.', 'ewww-image-optimizer' ) .
9922
- "</td></tr>\n";
9923
- ewwwio_debug_message( 'resize detection: ' . ( ewww_image_optimizer_get_option( 'ewww_image_optimizer_resize_detection' ) ? 'on' : 'off' ) );
9924
- if ( function_exists( 'imsanity_get_max_width_height' ) ) {
9925
- $output[] = "<tr class='$network_class'><th>&nbsp;</th><td>" .
9926
- '<p><span style="color: #3eadc9">' . esc_html__( '*Imsanity settings override the EWWW resize dimensions.', 'ewww-image-optimizer' ) . "</span></p></td></tr>\n";
9927
- }
9928
- $output[] = "<tr class='$network_class'><th scope='row'>" . esc_html__( 'Resize Images', 'ewww-image-optimizer' ) . ewwwio_help_link( 'https://docs.ewww.io/article/41-resize-settings', '59849911042863033a1ba5f9' ) .
9929
- "</th><td><label for='ewww_image_optimizer_maxmediawidth'>" . esc_html__( 'Max Width', 'ewww-image-optimizer' ) .
9930
- "</label> <input type='number' step='1' min='0' class='small-text' id='ewww_image_optimizer_maxmediawidth' name='ewww_image_optimizer_maxmediawidth' value='" .
9931
- ewww_image_optimizer_get_option( 'ewww_image_optimizer_maxmediawidth' ) . ( function_exists( 'imsanity_get_max_width_height' ) ? "' disabled='disabled" : '' ) .
9932
- "' /> <label for='ewww_image_optimizer_maxmediaheight'>" . esc_html__( 'Max Height', 'ewww-image-optimizer' ) .
9933
- "</label> <input type='number' step='1' min='0' class='small-text' id='ewww_image_optimizer_maxmediaheight' name='ewww_image_optimizer_maxmediaheight' value='" .
9934
- ewww_image_optimizer_get_option( 'ewww_image_optimizer_maxmediaheight' ) . ( function_exists( 'imsanity_get_max_width_height' ) ? "' disabled='disabled" : '' ) . "' /> " .
9935
- esc_html__( 'in pixels', 'ewww-image-optimizer' ) . "\n" . "<p class='description'>" . esc_html__( 'Resize uploaded images to these dimensions.', 'ewww-image-optimizer' ) .
9936
- "</td></tr>\n";
9937
- ewwwio_debug_message( 'max media dimensions: ' . ewww_image_optimizer_get_option( 'ewww_image_optimizer_maxmediawidth' ) . ' x ' . ewww_image_optimizer_get_option( 'ewww_image_optimizer_maxmediaheight' ) );
9938
- ewwwio_debug_message( 'max other dimensions: ' . ewww_image_optimizer_get_option( 'ewww_image_optimizer_maxotherwidth' ) . ' x ' . ewww_image_optimizer_get_option( 'ewww_image_optimizer_maxotherheight' ) );
9939
- $output[] = "<tr class='$network_class'><th scope='row'><label for='ewww_image_optimizer_resize_existing'>" . esc_html__( 'Resize Existing Images', 'ewww-image-optimizer' ) . '</label>' .
9940
- ewwwio_help_link( 'https://docs.ewww.io/article/41-resize-settings', '59849911042863033a1ba5f9' ) .
9941
- "</th><td><input type='checkbox' id='ewww_image_optimizer_resize_existing' name='ewww_image_optimizer_resize_existing' value='true' " .
9942
- ( ewww_image_optimizer_get_option( 'ewww_image_optimizer_resize_existing' ) ? "checked='true'" : '' ) . ' /> ' .
9943
- esc_html__( 'Allow resizing of existing Media Library images.', 'ewww-image-optimizer' ) . "</td></tr>\n";
9944
- ewwwio_debug_message( 'resize existing images: ' . ( ewww_image_optimizer_get_option( 'ewww_image_optimizer_resize_existing' ) ? 'on' : 'off' ) );
9945
- $output[] = "<tr class='$network_class'><th scope='row'><label for='ewww_image_optimizer_resize_other_existing'>" . esc_html__( 'Resize Other Images', 'ewww-image-optimizer' ) . '</label>' .
9946
- ewwwio_help_link( 'https://docs.ewww.io/article/41-resize-settings', '59849911042863033a1ba5f9' ) .
9947
- "</th><td><input type='checkbox' id='ewww_image_optimizer_resize_other_existing' name='ewww_image_optimizer_resize_other_existing' value='true' " .
9948
- ( ewww_image_optimizer_get_option( 'ewww_image_optimizer_resize_other_existing' ) ? "checked='true'" : '' ) . ' /> ' .
9949
- esc_html__( 'Allow resizing of existing images outside the Media Library. Use this to resize images specified under the Folders to Optimize setting when running Bulk or Scheduled Optimization.', 'ewww-image-optimizer' ) . "</td></tr>\n";
9950
- ewwwio_debug_message( 'resize existing (non-media) images: ' . ( ewww_image_optimizer_get_option( 'ewww_image_optimizer_resize_other_existing' ) ? 'on' : 'off' ) );
9951
-
9952
- $output[] = '<tr class="network-singlesite"><th scope="row">' . esc_html__( 'Disable Resizes', 'ewww-image-optimizer' ) .
9953
- ewwwio_help_link( 'https://docs.ewww.io/article/41-resize-settings', '59849911042863033a1ba5f9,58598744c697912ffd6c3eb4' ) . '</th><td><p>' .
9954
- esc_html__( 'WordPress, your theme, and other plugins generate various image sizes. You may disable optimization for certain sizes, or completely prevent those sizes from being created.', 'ewww-image-optimizer' ) . '<br>' .
9955
- '<i>' . esc_html__( 'Remember that each image size will affect your API credits.', 'ewww-image-optimizer' ) . "</i></p>\n";
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
9956
  $image_sizes = ewww_image_optimizer_get_image_sizes();
9957
  $disabled_sizes = ewww_image_optimizer_get_option( 'ewww_image_optimizer_disable_resizes', false, true );
9958
  $disabled_sizes_opt = ewww_image_optimizer_get_option( 'ewww_image_optimizer_disable_resizes_opt', false, true );
9959
- $output[] = '<table><tr class="network-singlesite"><th scope="col">' . esc_html__( 'Disable Optimization', 'ewww-image-optimizer' ) . '</th><th scope="col">' . esc_html__( 'Disable Creation', 'ewww-image-optimizer' ) . "</th></tr>\n";
9960
- ewwwio_debug_message( 'disabled resizes:' );
9961
- foreach ( $image_sizes as $size => $dimensions ) {
9962
- if ( empty( $dimensions['width'] ) && empty( $dimensions['height'] ) ) {
9963
- continue;
9964
- }
9965
- if ( 'thumbnail' === $size ) {
9966
- $output[] = "<tr class='network-singlesite'><td><input type='checkbox' id='ewww_image_optimizer_disable_resizes_opt_$size' name='ewww_image_optimizer_disable_resizes_opt[$size]' value='true' " . ( ! empty( $disabled_sizes_opt[ $size ] ) ? "checked='true'" : '' ) . " /></td><td><input type='checkbox' id='ewww_image_optimizer_disable_resizes_$size' name='ewww_image_optimizer_disable_resizes[$size]' value='true' disabled /></td><td><label for='ewww_image_optimizer_disable_resizes_$size'>$size - {$dimensions['width']}x{$dimensions['height']}</label></td></tr>\n";
9967
- } elseif ( 'pdf-full' === $size ) {
9968
- $output[] = "<tr class='network-singlesite'><td>" .
9969
- "<input type='checkbox' id='ewww_image_optimizer_disable_resizes_opt_$size' name='ewww_image_optimizer_disable_resizes_opt[$size]' value='true' " .
9970
- ( ! empty( $disabled_sizes_opt[ $size ] ) ? "checked='true'" : '' ) .
9971
- ' /></td><td>' .
9972
- "<input type='checkbox' id='ewww_image_optimizer_disable_resizes_$size' name='ewww_image_optimizer_disable_resizes[$size]' value='true' " .
9973
- ( ! empty( $disabled_sizes[ $size ] ) ? "checked='true'" : '' ) .
9974
- " /></td><td><label for='ewww_image_optimizer_disable_resizes_$size'>$size - <span class='description'>" .
9975
- esc_html__( 'Disabling creation of the full-size preview for PDF files will disable all PDF preview sizes', 'ewww-image-optimizer' ) . "</span></label></td></tr>\n";
9976
- } else {
9977
- $output[] = "<tr class='network-singlesite'><td><input type='checkbox' id='ewww_image_optimizer_disable_resizes_opt_$size' name='ewww_image_optimizer_disable_resizes_opt[$size]' value='true' " . ( ! empty( $disabled_sizes_opt[ $size ] ) ? "checked='true'" : '' ) . " /></td><td><input type='checkbox' id='ewww_image_optimizer_disable_resizes_$size' name='ewww_image_optimizer_disable_resizes[$size]' value='true' " . ( ! empty( $disabled_sizes[ $size ] ) ? "checked='true'" : '' ) . " /></td><td><label for='ewww_image_optimizer_disable_resizes_$size'>$size - {$dimensions['width']}x{$dimensions['height']}</label></td></tr>\n";
9978
- }
9979
- ewwwio_debug_message( $size . ': ' . ( ! empty( $disabled_sizes_opt[ $size ] ) ? 'optimization=disabled ' : 'optimization=enabled ' ) . ( ! empty( $disabled_sizes[ $size ] ) ? 'creation=disabled' : 'creation=enabled' ) );
9980
- }
9981
- if ( 'network-multisite' !== $network ) {
9982
- $output[] = "</table>\n";
9983
- $output[] = "</td></tr>\n";
9984
- } else {
9985
- $output[] = '<tr><th scope="row">' . esc_html__( 'Disable Resizes', 'ewww-image-optimizer' ) . '</th><td>';
9986
- $output[] = '<p><span style="color: #3eadc9">' . esc_html__( '*Settings to disable creation and optimization of individual sizes must be configured for each individual site.', 'ewww-image-optimizer' ) . "</span></p></td></tr>\n";
9987
- }
9988
- $output[] = "</table>\n</div>\n";
9989
-
9990
- $output[] = "<div id='ewww-conversion-settings'>\n";
9991
- $output[] = '<noscript><h2>' . esc_html__( 'Convert', 'ewww-image-optimizer' ) . '</h2></noscript>';
9992
- $output[] = '<p>' . esc_html__( 'Conversion is only available for images in the Media Library (except WebP). By default, all images have a link available in the Media Library for one-time conversion. Turning on individual conversion operations below will enable conversion filters any time an image is uploaded or modified.', 'ewww-image-optimizer' ) . "<br />\n" .
9993
- '<b>' . esc_html__( 'NOTE:', 'ewww-image-optimizer' ) . '</b> ' . esc_html__( 'The plugin will attempt to update image locations for any posts that contain the images. You may still need to manually update locations/urls for converted images.', 'ewww-image-optimizer' ) . "\n" .
9994
- "</p>\n";
9995
- $output[] = "<table class='form-table'>\n";
9996
- if ( $toolkit_found ) {
9997
- $output[] = "<tr class='$network_class'><th scope='row'><label for='ewww_image_optimizer_disable_convert_links'>" . esc_html__( 'Hide Conversion Links', 'ewww-image-optimizer' ) .
9998
- '</label>' . ewwwio_help_link( 'https://docs.ewww.io/article/14-converting-images', '58545a86c697912ffd6c1b53' ) .
9999
- "</th><td><input type='checkbox' id='ewww_image_optimizer_disable_convert_links' name='ewww_image_optimizer_disable_convert_links' " .
10000
- ( ewww_image_optimizer_get_option( 'ewww_image_optimizer_disable_convert_links' ) ? "checked='true'" : '' ) . ' /> ' .
10001
- esc_html__( 'Site or Network admins can use this to prevent other users from using the conversion links in the Media Library which bypass the settings below.', 'ewww-image-optimizer' ) .
10002
- "</td></tr>\n";
10003
- $output[] = "<tr class='$network_class'><th scope='row'><label for='ewww_image_optimizer_delete_originals'>" . esc_html__( 'Delete Originals', 'ewww-image-optimizer' ) . '</label>' .
10004
- ewwwio_help_link( 'https://docs.ewww.io/article/14-converting-images', '58545a86c697912ffd6c1b53' ) .
10005
- "</th><td><input type='checkbox' id='ewww_image_optimizer_delete_originals' name='ewww_image_optimizer_delete_originals' " .
10006
- ( ewww_image_optimizer_get_option( 'ewww_image_optimizer_delete_originals' ) ? "checked='true'" : '' ) . ' /> ' .
10007
- esc_html__( 'This will remove the original image from the server after a successful conversion.', 'ewww-image-optimizer' ) . "</td></tr>\n";
10008
- ewwwio_debug_message( 'delete originals: ' . ( ewww_image_optimizer_get_option( 'ewww_image_optimizer_delete_originals' ) ? 'on' : 'off' ) );
10009
- $output[] = "<tr class='$network_class'><th scope='row'><label for='ewww_image_optimizer_jpg_to_png'>" .
10010
- /* translators: 1: JPG, GIF or PNG 2: JPG or PNG */
10011
- sprintf( esc_html__( '%1$s to %2$s Conversion', 'ewww-image-optimizer' ), 'JPG', 'PNG' ) .
10012
- '</label>' . ewwwio_help_link( 'https://docs.ewww.io/article/14-converting-images', '58545a86c697912ffd6c1b53' ) .
10013
- "</th><td><span><input type='checkbox' id='ewww_image_optimizer_jpg_to_png' name='ewww_image_optimizer_jpg_to_png' " .
10014
- ( ewww_image_optimizer_get_option( 'ewww_image_optimizer_jpg_to_png' ) ? "checked='true'" : '' ) . ' /> <b>' . esc_html__( 'WARNING:', 'ewww-image-optimizer' ) . '</b> ' .
10015
- esc_html__( 'Removes metadata and increases cpu usage dramatically.', 'ewww-image-optimizer' ) . "</span>\n" .
10016
- "<p class='description'>" . esc_html__( 'PNG is generally much better than JPG for logos and other images with a limited range of colors. Checking this option will slow down JPG processing significantly, and you may want to enable it only temporarily.', 'ewww-image-optimizer' ) .
10017
- "</p></td></tr>\n";
10018
- ewwwio_debug_message( 'jpg2png: ' . ( ewww_image_optimizer_get_option( 'ewww_image_optimizer_jpg_to_png' ) ? 'on' : 'off' ) );
10019
- $output[] = "<tr class='$network_class'><th scope='row'><label for='ewww_image_optimizer_png_to_jpg'>" .
10020
- /* translators: 1: JPG, GIF or PNG 2: JPG or PNG */
10021
- sprintf( esc_html__( '%1$s to %2$s Conversion', 'ewww-image-optimizer' ), 'PNG', 'JPG' ) .
10022
- '</label>' . ewwwio_help_link( 'https://docs.ewww.io/article/14-converting-images', '58545a86c697912ffd6c1b53,58543c69c697912ffd6c19a7,58542afac697912ffd6c18c0' ) .
10023
- "</th><td><span><input type='checkbox' id='ewww_image_optimizer_png_to_jpg' name='ewww_image_optimizer_png_to_jpg' " .
10024
- ( ewww_image_optimizer_get_option( 'ewww_image_optimizer_png_to_jpg' ) ? "checked='true'" : '' ) . ' /> <b>' . esc_html__( 'WARNING:', 'ewww-image-optimizer' ) . '</b> ' .
10025
- esc_html__( 'This is not a lossless conversion.', 'ewww-image-optimizer' ) . "</span>\n" .
10026
- "<p class='description'>" . esc_html__( 'JPG is generally much better than PNG for photographic use because it compresses the image and discards data. PNGs with transparency are not converted by default.', 'ewww-image-optimizer' ) . "</p>\n" .
10027
- "<span><label for='ewww_image_optimizer_jpg_background'> " . esc_html__( 'JPG Background Color:', 'ewww-image-optimizer' ) . "</label> #<input type='text' id='ewww_image_optimizer_jpg_background' name='ewww_image_optimizer_jpg_background' size='6' value='" . ewww_image_optimizer_jpg_background() . "' /> <span style='padding-left: 12px; font-size: 12px; border: solid 1px #555555; background-color: #" . ewww_image_optimizer_jpg_background() . "'>&nbsp;</span> " . esc_html__( 'HEX format (#123def)', 'ewww-image-optimizer' ) . ".</span>\n" .
10028
- "<p class='description'>" . esc_html__( 'Background color is used only if the PNG has transparency. Leave this value blank to skip PNGs with transparency.', 'ewww-image-optimizer' ) . "</p></td></tr>\n";
10029
- ewwwio_debug_message( 'png2jpg: ' . ( ewww_image_optimizer_get_option( 'ewww_image_optimizer_png_to_jpg' ) ? 'on' : 'off' ) );
10030
- $output[] = "<tr class='$network_class'><th scope='row'><label for='ewww_image_optimizer_gif_to_png'>" .
10031
- /* translators: 1: JPG, GIF or PNG 2: JPG or PNG */
10032
- sprintf( esc_html__( '%1$s to %2$s Conversion', 'ewww-image-optimizer' ), 'GIF', 'PNG' ) .
10033
- '</label>' . ewwwio_help_link( 'https://docs.ewww.io/article/14-converting-images', '58545a86c697912ffd6c1b53' ) .
10034
- "</th><td><span><input type='checkbox' id='ewww_image_optimizer_gif_to_png' name='ewww_image_optimizer_gif_to_png' " .
10035
- ( ewww_image_optimizer_get_option( 'ewww_image_optimizer_gif_to_png' ) ? "checked='true'" : '' ) . ' /> ' .
10036
- esc_html__( 'No warnings here, just do it.', 'ewww-image-optimizer' ) . "</span>\n" .
10037
- "<p class='description'> " . esc_html__( 'PNG is generally better than GIF, but animated images cannot be converted.', 'ewww-image-optimizer' ) . "</p></td></tr>\n";
10038
- ewwwio_debug_message( 'gif2png: ' . ( ewww_image_optimizer_get_option( 'ewww_image_optimizer_gif_to_png' ) ? 'on' : 'off' ) );
10039
- } else {
10040
- $output[] = "<tr class='$network_class'><th>&nbsp;</th><td>" .
10041
- '<p><span style="color: #3eadc9">' . esc_html__( 'Image conversion requires one of the following PHP libraries: GD, Imagick, or GMagick.', 'ewww-image-optimizer' ) . "</span></p></td></tr>\n";
10042
- }
10043
- $output[] = "</table>\n</div>\n";
10044
-
10045
- $output[] = "<div id='ewww-webp-settings'>\n";
10046
- $output[] = '<noscript><h2>' . esc_html__( 'WebP', 'ewww-image-optimizer' ) . '</h2></noscript>';
10047
- if ( ! ewww_image_optimizer_get_option( 'ewww_image_optimizer_exactdn' ) && ! ewww_image_optimizer_easy_active() ) {
10048
- $output[] = '<p>' . esc_html__( 'Once JPG/PNG to WebP 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>\n" .
10049
- "<a href='https://ewww.io/easy/'>" . esc_html__( 'Get Easy IO for automatic WebP conversion and delivery.', 'ewww-image-optimizer' ) . "</a></p>\n";
10050
- }
10051
- $output[] = "<table class='form-table'>\n";
10052
- if ( ! ewww_image_optimizer_easy_active() || ewww_image_optimizer_get_option( 'ewww_image_optimizer_webp' ) ) {
10053
- $output[] = "<tr class='$network_class'><th scope='row'><label for='ewww_image_optimizer_webp'>" . esc_html__( 'JPG/PNG to WebP', 'ewww-image-optimizer' ) . '</label>' .
10054
- ewwwio_help_link( 'https://docs.ewww.io/article/16-ewww-io-and-webp-images', '5854745ac697912ffd6c1c89' ) .
10055
- "</th><td><span><input type='checkbox' id='ewww_image_optimizer_webp' name='ewww_image_optimizer_webp' value='true' " .
10056
- ( ewww_image_optimizer_get_option( 'ewww_image_optimizer_webp' ) ? "checked='true'" : '' ) . ' /> ' .
10057
- esc_html__( 'JPG to WebP conversion is lossy, but quality loss is minimal. PNG to WebP conversion is lossless.', 'ewww-image-optimizer' ) .
10058
- "</span>\n<p class='description'>" . esc_html__( 'Originals are never deleted, and WebP images should only be served to supported browsers.', 'ewww-image-optimizer' ) .
10059
- " <a href='#ewww-webp-rewrite'>" . ( ewww_image_optimizer_get_option( 'ewww_image_optimizer_webp' ) && ! ewww_image_optimizer_get_option( 'ewww_image_optimizer_webp_for_cdn' ) && ! ewww_image_optimizer_get_option( 'ewww_image_optimizer_picture_webp' ) ? esc_html__( 'You can use the rewrite rules below to serve WebP images with Apache.', 'ewww-image-optimizer' ) : '' ) . "</a></td></tr>\n";
10060
- ewwwio_debug_message( 'webp conversion: ' . ( ewww_image_optimizer_get_option( 'ewww_image_optimizer_webp' ) ? 'on' : 'off' ) );
10061
- }
10062
- if ( ! ewww_image_optimizer_ce_webp_enabled() && ! ewww_image_optimizer_easy_active() ) {
10063
- $output[] = "<tr class='$network_class'><th scope='row'><label for='ewww_image_optimizer_webp_for_cdn'>" .
10064
- esc_html__( 'JS WebP Rewriting', 'ewww-image-optimizer' ) .
10065
- '</label>' . ewwwio_help_link( 'https://docs.ewww.io/article/16-ewww-io-and-webp-images', '5854745ac697912ffd6c1c89,59443d162c7d3a0747cdf9f0' ) .
10066
- "</th><td><input type='checkbox' id='ewww_image_optimizer_webp_for_cdn' name='ewww_image_optimizer_webp_for_cdn' value='true' " .
10067
- ( ewww_image_optimizer_get_option( 'ewww_image_optimizer_webp_for_cdn' ) ? "checked='true'" : '' ) . ' /> ' .
10068
- esc_html__( 'Use this if the Apache rewrite rules do not work, or if your images are served from a CDN.', 'ewww-image-optimizer' ) . ' ' .
10069
- "\n<p class='description'>" . esc_html__( 'Supports CSS background images with Lazy Load option on the Easy Mode tab.', 'ewww-image-optimizer' ) . '</p>' .
10070
- '</td></tr>';
10071
- ewwwio_debug_message( 'alt webp rewriting: ' . ( ewww_image_optimizer_get_option( 'ewww_image_optimizer_webp_for_cdn' ) ? 'on' : 'off' ) );
10072
- $output[] = "<tr class='$network_class'><th scope='row'><label for='ewww_image_optimizer_picture_webp'>" .
10073
- esc_html__( '<picture> WebP Rewriting', 'ewww-image-optimizer' ) .
10074
- '</label>' . ewwwio_help_link( 'https://docs.ewww.io/article/16-ewww-io-and-webp-images', '5854745ac697912ffd6c1c89,59443d162c7d3a0747cdf9f0' ) .
10075
- "</th><td><input type='checkbox' id='ewww_image_optimizer_picture_webp' name='ewww_image_optimizer_picture_webp' value='true' " .
10076
- ( ewww_image_optimizer_get_option( 'ewww_image_optimizer_picture_webp' ) ? "checked='true'" : '' ) . ' /> ' .
10077
- esc_html__( 'A JavaScript-free rewriting method using picture tags.', 'ewww-image-optimizer' ) . ' ' .
10078
- "\n<p class='description'>" . esc_html__( 'Use this if Apache rewrite rules do not work for your site. Some themes may not display <picture> tags properly, and does not support CSS background images.', 'ewww-image-optimizer' ) . '</p>' .
10079
- '</td></tr>';
10080
- ewwwio_debug_message( 'picture webp rewriting: ' . ( ewww_image_optimizer_get_option( 'ewww_image_optimizer_picture_webp' ) ? 'on' : 'off' ) );
10081
- $webp_exclude_paths = ewww_image_optimizer_get_option( 'ewww_image_optimizer_webp_rewrite_exclude' ) ? esc_html( implode( "\n", ewww_image_optimizer_get_option( 'ewww_image_optimizer_webp_rewrite_exclude' ) ) ) : '';
10082
- $output[] = "<tr class='$network_class'><td>&nbsp;</td>" .
10083
- "<td><label for='ewww_image_optimizer_webp_rewrite_exclude'>" . esc_html__( 'JS WebP and <picture> Web Exclusions', 'ewww-image-optimizer' ) . '</label>' .
10084
- '<br>' .
10085
- "<textarea id='ewww_image_optimizer_webp_rewrite_exclude' name='ewww_image_optimizer_webp_rewrite_exclude' rows='3' cols='60'>$webp_exclude_paths</textarea>\n" .
10086
- "<p class='description'>" .
10087
- esc_html__( 'One exclusion per line, no wildcards (*) needed. Use any string that matches the desired element(s) or exclude entire element types like "div", "span", etc.', 'ewww-image-optimizer' ) .
10088
- "</p></td></tr>\n";
10089
- ewwwio_debug_message( 'WebP Rewrite exclusions:' );
10090
- ewwwio_debug_message( $webp_exclude_paths );
10091
- $webp_paths = ewww_image_optimizer_get_option( 'ewww_image_optimizer_webp_paths' ) ? esc_html( implode( "\n", ewww_image_optimizer_get_option( 'ewww_image_optimizer_webp_paths' ) ) ) : '';
10092
- $output[] = "<tr class='$network_class'><th scope='row'><label for='ewww_image_optimizer_webp_paths'>" . esc_html__( 'WebP URLs', 'ewww-image-optimizer' ) . '</label>' .
10093
- ewwwio_help_link( 'https://docs.ewww.io/article/16-ewww-io-and-webp-images', '5854745ac697912ffd6c1c89' ) . '</th><td><span>' .
10094
- esc_html__( 'Enter additional URL patterns, like a CDN URL, that should be permitted for JS WebP Rewriting. One URL per line, must include the domain name (cdn.example.com).', 'ewww-image-optimizer' ) . '</span>' .
10095
- '<p>' . esc_html__( 'Optionally include a folder with the URL if your CDN path is different from your local path.', 'ewww-image-optimizer' ) . '</p>' .
10096
- "<textarea id='ewww_image_optimizer_webp_paths' name='ewww_image_optimizer_webp_paths' rows='3' cols='60'>$webp_paths</textarea>" .
10097
- "<p class='description'>" . sprintf(
10098
- /* translators: 1: An image URL on a CDN 2: An image URL 3: An example folder URL */
10099
- esc_html__( 'For example, with a CDN URL of %1$s and a local URL of %2$s you would enter %3$s.', 'ewww-image-optimizer' ),
10100
- 'https://cdn.example.com/<strong>files/</strong>2038/01/image.jpg',
10101
- 'https://example.com/<strong>wp-content/uploads/</strong>2038/01/image.jpg',
10102
- 'https://cdn.example.com/<strong>files/</strong>'
10103
- ) . '</p>' .
10104
- "</td></tr>\n";
10105
- ewwwio_debug_message( 'webp paths:' );
10106
- ewwwio_debug_message( $webp_paths );
10107
- } elseif ( ewww_image_optimizer_get_option( 'ewww_image_optimizer_exactdn' ) ) {
10108
- $output[] = "<tr class='$network_class'><th>&nbsp;</th><td><p class='description'>" . esc_html__( 'WebP images are served automatically by Easy IO.', 'ewww-image-optimizer' ) . '</p></td></tr>';
10109
- } elseif ( get_option( 'easyio_exactdn' ) ) {
10110
- $output[] = "<tr class='$network_class'><th>&nbsp;</th><td><p class='description'>" . esc_html__( 'WebP images are served automatically by Easy Image Optimizer.', 'ewww-image-optimizer' ) . '</p></td></tr>';
10111
- }
10112
- if ( ! ewww_image_optimizer_easy_active() || ewww_image_optimizer_get_option( 'ewww_image_optimizer_webp' ) ) {
10113
- $output[] = "<tr class='$network_class'><th scope='row'><label for='ewww_image_optimizer_webp_force'>" . esc_html__( 'Force WebP', 'ewww-image-optimizer' ) . '</label>' .
10114
- ewwwio_help_link( 'https://docs.ewww.io/article/16-ewww-io-and-webp-images', '5854745ac697912ffd6c1c89' ) .
10115
- "</th><td><span><input type='checkbox' id='ewww_image_optimizer_webp_force' name='ewww_image_optimizer_webp_force' value='true' " .
10116
- ( ewww_image_optimizer_get_option( 'ewww_image_optimizer_webp_force' ) ? "checked='true'" : '' ) . ' /> ' .
10117
- esc_html__( 'WebP images will be generated and saved for all JPG/PNG images regardless of their size. The JS WebP Rewriting will not check if a file exists, only that the domain matches the home url, or one of the provided WebP URLs.', 'ewww-image-optimizer' ) . "</span></td></tr>\n";
10118
- ewwwio_debug_message( 'forced webp: ' . ( ewww_image_optimizer_get_option( 'ewww_image_optimizer_webp_force' ) ? 'on' : 'off' ) );
10119
- }
10120
- $output[] = "</table>\n</div>\n";
10121
-
10122
- $output[] = "<div id='ewww-support-settings'>\n";
10123
- $output[] = '<noscript><h2>' . esc_html__( 'Support', 'ewww-image-optimizer' ) . '</h2></noscript>';
10124
- $output[] = "<p><a class='ewww-docs-root' href='https://docs.ewww.io/'>" . esc_html__( 'Documentation', 'ewww-image-optimizer' ) . '</a> | ' .
10125
- "<a class='ewww-docs-root' href='https://ewww.io/contact-us/'>" . esc_html__( 'Plugin Support', 'ewww-image-optimizer' ) . '</a> | ' .
10126
- "<a href='https://ewww.io/status/'>" . esc_html__( 'Server Status', 'ewww-image-optimizer' ) . '</a>' .
10127
- "</p>\n";
10128
- $output[] = "<table class='form-table'>\n";
10129
- $output[] = "<tr class='$network_class'><th scope='row'><label for='ewww_image_optimizer_enable_help'>" . esc_html__( 'Enable Embedded Help', 'ewww-image-optimizer' ) .
10130
- "</label></th><td><input type='checkbox' id='ewww_image_optimizer_enable_help' name='ewww_image_optimizer_enable_help' value='true' " .
10131
- ( ewww_image_optimizer_get_option( 'ewww_image_optimizer_enable_help' ) ? "checked='true'" : '' ) . ' /> ' .
10132
- esc_html__( 'Enable the support beacon, which gives you access to documentation and our support team right from your WordPress dashboard. To assist you more efficiently, we may collect the current url, IP address, browser/device information, and debugging information.', 'ewww-image-optimizer' ) .
10133
- "</td></tr>\n";
10134
- ewwwio_debug_message( 'enable help beacon: ' . ( ewww_image_optimizer_get_option( 'ewww_image_optimizer_enable_help' ) ? 'yes' : 'no' ) );
10135
- $output[] = "<tr class='$network_class'><th scope='row'><label for='ewww_image_optimizer_debug'>" . esc_html__( 'Debugging', 'ewww-image-optimizer' ) . '</label>' .
10136
- ewwwio_help_link( 'https://docs.ewww.io/article/7-basic-configuration', '585373d5c697912ffd6c0bb2' ) . '</th>' .
10137
- "<td><input type='checkbox' id='ewww_image_optimizer_debug' name='ewww_image_optimizer_debug' value='true' " .
10138
- ( ! $ewwwio_temp_debug && ewww_image_optimizer_get_option( 'ewww_image_optimizer_debug' ) ? "checked='true'" : '' ) . ' /> ' .
10139
- esc_html__( 'Use this to provide information for support purposes, or if you feel comfortable digging around in the code to fix a problem you are experiencing.', 'ewww-image-optimizer' ) .
10140
- "</td></tr>\n";
10141
- $output[] = "</table>\n";
10142
-
10143
- $output[] = 'DEBUG_PLACEHOLDER';
10144
-
10145
- $output[] = "</div>\n";
10146
-
10147
- $output[] = "<div id='ewww-contribute-settings'>\n";
10148
- $output[] = '<noscript><h2>' . esc_html__( 'Contribute', 'ewww-image-optimizer' ) . '</h2></noscript>';
10149
- $output[] = '<p><strong>' . esc_html__( 'Here are some ways you can contribute to the development of this plugin:', 'ewww-image-optimizer' ) . "</strong></p>\n";
10150
- $output[] = "<p><a href='https://translate.wordpress.org/projects/wp-plugins/ewww-image-optimizer/'>" . esc_html__( 'Translate EWWW I.O.', 'ewww-image-optimizer' ) . '</a> | ' .
10151
- "<a href='https://wordpress.org/support/plugin/ewww-image-optimizer/reviews/#new-post'>" . esc_html__( 'Write a review', 'ewww-image-optimizer' ) . '</a> | ' .
10152
- "<a href='https://ewww.io/plans/'>" . esc_html__( 'Upgrade to premium image optimization', 'ewww-image-optimizer' ) . "</a></p>\n";
10153
- $output[] = "<table class='form-table'>\n";
10154
- $output[] = "<tr class='$network_class'><th scope='row'><label for='ewww_image_optimizer_allow_tracking'>" . esc_html__( 'Allow Usage Tracking?', 'ewww-image-optimizer' ) . '</label>' .
10155
- ewwwio_help_link( 'https://docs.ewww.io/article/23-usage-tracking', '591f3a8e2c7d3a057f893d91' ) .
10156
- "</th><td><input type='checkbox' id='ewww_image_optimizer_allow_tracking' name='ewww_image_optimizer_allow_tracking' value='true' " .
10157
- ( ewww_image_optimizer_get_option( 'ewww_image_optimizer_allow_tracking' ) ? "checked='true'" : '' ) . ' /> ' .
10158
- esc_html__( 'Allow EWWW Image Optimizer to anonymously track how this plugin is used and help us make the plugin better. Opt-in to tracking and receive 500 API image credits free. No sensitive data is tracked.', 'ewww-image-optimizer' ) .
10159
- "</td></tr>\n";
10160
- $output[] = "</table>\n";
10161
- $output[] = "</div>\n";
10162
-
10163
- $output[] = "<p class='submit'><input type='submit' class='button-primary' value='" . esc_attr__( 'Save Changes', 'ewww-image-optimizer' ) . "' /></p>\n";
10164
- $output[] = "</form>\n";
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
10165
  // Make sure .htaccess rules are terminated when ExactDN is enabled or if Cloudflare is detected.
10166
  $cf_host = ewwwio_is_cf_host();
10167
  if ( ewww_image_optimizer_easy_active() || $cf_host ) {
10168
  ewww_image_optimizer_webp_rewrite_verify();
10169
  }
10170
- if ( ! empty( $_SERVER['SERVER_ADDR'] ) ) {
10171
- ewwwio_debug_message( 'origin: ' . $_SERVER['SERVER_ADDR'] );
10172
- }
10173
  if (
10174
  ! $cf_host &&
10175
  ewww_image_optimizer_get_option( 'ewww_image_optimizer_webp' ) &&
@@ -10178,115 +10879,121 @@ function ewww_image_optimizer_options( $network = 'singlesite' ) {
10178
  ! ewww_image_optimizer_ce_webp_enabled() && ! ewww_image_optimizer_easy_active()
10179
  ) {
10180
  if ( defined( 'PHP_SAPI' ) && false === strpos( PHP_SAPI, 'apache' ) && false === strpos( PHP_SAPI, 'litespeed' ) ) {
10181
- ewwwio_debug_message( 'PHP module: ' . PHP_SAPI );
10182
  $false_positive_headers = esc_html( 'This may be a false positive. If so, the warning should go away once you implement the rewrite rules.' );
10183
  }
10184
  $header_error = '';
10185
  if ( ! apache_mod_loaded( 'mod_rewrite' ) ) {
10186
- ewwwio_debug_message( 'webp missing mod_rewrite' );
10187
  /* translators: %s: mod_rewrite or mod_headers */
10188
- $header_error = '<p><strong>' . sprintf( esc_html( 'Your site appears to be missing %s, please contact your webhost or system administrator to enable this Apache module.' ), 'mod_rewrite' ) . "</strong><br>$false_positive_headers</p>\n";
10189
  }
10190
  if ( ! apache_mod_loaded( 'mod_headers' ) ) {
10191
  /* translators: %s: mod_rewrite or mod_headers */
10192
- $header_error = '<p><strong>' . sprintf( esc_html( 'Your site appears to be missing %s, please contact your webhost or system administrator to enable this Apache module.' ), 'mod_headers' ) . "</strong><br>$false_positive_headers</p>\n";
10193
- ewwwio_debug_message( 'webp missing mod_headers' );
10194
  }
10195
 
10196
  $webp_verified = ewww_image_optimizer_test_webp_mime_verify();
10197
  if ( ! $webp_verified ) {
10198
- $output[] = $header_error;
10199
  }
10200
 
10201
  if ( $webp_verified || ! ewww_image_optimizer_webp_rewrite_verify() ) {
10202
- $output[] = "<form id='ewww-webp-rewrite'>\n";
10203
- $output[] = "<img id='webp-image' src='" . plugins_url( '/images/test.png', __FILE__ ) . '?m=' . time() . "' style='float: right; padding: 0 0 10px 10px;'>\n" .
10204
- "<p id='ewww-webp-rewrite-status'><b>" . esc_html__( 'Rules verified successfully', 'ewww-image-optimizer' ) . "</b></p>\n" .
10205
- "<button type='button' id='ewww-webp-remove' class='button-secondary action'>" . esc_html__( 'Remove Rewrite Rules', 'ewww-image-optimizer' ) . "</button>\n";
10206
- $output[] = "</form>\n";
10207
- ewwwio_debug_message( 'webp .htaccess rewriting enabled' );
10208
- } else {
10209
- $output[] = '<p>' . esc_html__( 'There are many ways to serve WebP images to visitors with supported browsers. You may choose any you wish, but it is recommended to serve them with an .htaccess file using mod_rewrite and mod_headers. The plugin can insert the rules for you if the file is writable, or you can edit .htaccess yourself.', 'ewww-image-optimizer' ) . "</p>\n";
10210
- $output[] = "<form id='ewww-webp-rewrite'>\n";
10211
- $output[] = "<pre id='webp-rewrite-rules' style='background: white; font-color: black; border: 1px solid black; clear: both; padding: 10px;'>\n" .
10212
- "&lt;IfModule mod_rewrite.c&gt;\n" .
10213
- "RewriteEngine On\n" .
10214
- "RewriteCond %{HTTP_ACCEPT} image/webp\n" .
10215
- "RewriteCond %{REQUEST_FILENAME} (.*)\.(jpe?g|png)$\n" .
10216
- "RewriteCond %{REQUEST_FILENAME}\.webp -f\n" .
10217
- "RewriteCond %{QUERY_STRING} !type=original\n" .
10218
- "RewriteRule (.+)\.(jpe?g|png)$ %{REQUEST_FILENAME}.webp [T=image/webp,E=accept:1,L]\n" .
10219
- "&lt;/IfModule&gt;\n" .
10220
- "&lt;IfModule mod_headers.c&gt;\n" .
10221
- "Header append Vary Accept env=REDIRECT_accept\n" .
10222
- "&lt;/IfModule&gt;\n" .
10223
- "AddType image/webp .webp</pre>\n" .
10224
- "<img id='webp-image' src='" . plugins_url( '/images/test.png', __FILE__ ) . '?m=' . time() . "' style='float: right; padding-left: 10px;'>\n" .
10225
- "<p id='ewww-webp-rewrite-status'>" . esc_html__( 'The image to the right will display a WebP image with WEBP in white text, if your site is serving WebP images and your browser supports WebP.', 'ewww-image-optimizer' ) . "</p>\n" .
10226
- "<button type='button' id='ewww-webp-insert' class='button-secondary action'>" . esc_html__( 'Insert Rewrite Rules', 'ewww-image-optimizer' ) . "</button>\n";
10227
- ewwwio_debug_message( 'webp .htaccess rules not detected' );
10228
- }
10229
- $output[] = "</form>\n";
10230
- } elseif ( ewww_image_optimizer_get_option( 'ewww_image_optimizer_webp_for_cdn' ) && ! ewww_image_optimizer_ce_webp_enabled() ) {
10231
- $test_webp_image = plugins_url( '/images/test.png.webp', __FILE__ );
10232
- $test_png_image = plugins_url( '/images/test.png', __FILE__ );
10233
- $output[] = "<noscript data-img='$test_png_image' data-webp='$test_webp_image' data-style='float: right; padding: 0 0 10px 10px;' class='ewww_webp'><img src='$test_png_image' style='float: right; padding: 0 0 10px 10px;'></noscript>\n";
10234
- } elseif ( ewww_image_optimizer_get_option( 'ewww_image_optimizer_picture_webp' ) && ! ewww_image_optimizer_ce_webp_enabled() ) {
10235
- $test_webp_image = plugins_url( '/images/test.png.webp', __FILE__ );
10236
- $test_png_image = plugins_url( '/images/test.png', __FILE__ );
10237
- $output[] = "<picture><source srcset='$test_webp_image' type='image/webp'><img src='$test_png_image' style='float: right; padding: 0 0 10px 10px;'></picture>\n";
10238
- } elseif ( $cf_host && ewww_image_optimizer_get_option( 'ewww_image_optimizer_webp' ) ) {
10239
- $output[] = '<p>' . esc_html__( 'Your site is using Cloudflare, please use JS WebP or <picture> WebP rewriting.', 'ewww-image-optimizer' ) . "</p>\n";
10240
- }
10241
- $output[] = "</div><!-- end container wrap -->\n";
10242
-
10243
- ewwwio_debug_message( 'max_execution_time: ' . ini_get( 'max_execution_time' ) );
10244
- ewww_image_optimizer_stl_check();
10245
- ewww_image_optimizer_function_exists( 'sleep', true );
10246
- ewwwio_check_memory_available();
10247
- if ( 'debug-silent' === $network ) {
10248
- ewww_image_optimizer_temp_debug_clear();
10249
- return;
10250
- }
10251
- $output = apply_filters( 'ewww_image_optimizer_settings', $output );
10252
  if ( ewww_image_optimizer_get_option( 'ewww_image_optimizer_webp_for_cdn' ) && ! ewww_image_optimizer_ce_webp_enabled() && ! ewww_image_optimizer_easy_active() ) {
10253
- global $eio_alt_webp;
 
 
 
10254
  $eio_alt_webp->inline_script();
10255
  }
10256
 
10257
- global $eio_debug;
10258
- if ( ! empty( $eio_debug ) ) {
10259
- $debug_output = '<p style="clear:both"><b>' . esc_html__( 'Debugging Information', 'ewww-image-optimizer' ) . ':</b> <button id="ewww-copy-debug" class="button button-secondary" type="button">' . esc_html__( 'Copy', 'ewww-image-optimizer' ) . '</button>';
10260
- if ( ewwwio_is_file( WP_CONTENT_DIR . '/ewww/debug.log' ) ) {
10261
- $debug_output .= "&emsp;<a href='" . admin_url( 'admin.php?action=ewww_image_optimizer_view_debug_log' ) . "'>" .
10262
- esc_html( 'View Debug Log', 'ewww-image-optimizer' ) . "</a> - <a href='" .
10263
- admin_url( 'admin.php?action=ewww_image_optimizer_delete_debug_log' ) . "'>" .
10264
- esc_html( 'Remove Debug Log', 'ewww-image-optimizer' ) . '</a>';
10265
- }
10266
- $debug_output .= '</p>';
10267
- $debug_output .= '<div id="ewww-debug-info" contenteditable="true">' . $eio_debug . '</div>';
10268
-
10269
- $output = str_replace( 'DEBUG_PLACEHOLDER', $debug_output, $output );
10270
- } else {
10271
- $output = str_replace( 'DEBUG_PLACEHOLDER', '', $output );
10272
- }
10273
-
10274
- echo $output;
10275
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
10276
  if ( ewww_image_optimizer_get_option( 'ewww_image_optimizer_enable_help' ) ) {
10277
  $current_user = wp_get_current_user();
10278
  $help_email = $current_user->user_email;
10279
  $hs_debug = '';
10280
- if ( ! empty( $eio_debug ) ) {
10281
- $hs_debug = str_replace( array( "'", '<br>', '<b>', '</b>' ), array( "\'", '\n', '<', '>' ), $eio_debug );
10282
  }
10283
  ?>
10284
  <script type="text/javascript">!function(e,t,n){function a(){var e=t.getElementsByTagName("script")[0],n=t.createElement("script");n.type="text/javascript",n.async=!0,n.src="https://beacon-v2.helpscout.net",e.parentNode.insertBefore(n,e)}if(e.Beacon=n=function(t,n,a){e.Beacon.readyQueue.push({method:t,options:n,data:a})},n.readyQueue=[],"complete"===t.readyState)return a();e.attachEvent?e.attachEvent("onload",a):e.addEventListener("load",a,!1)}(window,document,window.Beacon||function(){});</script>
10285
  <script type="text/javascript">
10286
  window.Beacon('init', 'aa9c3d3b-d4bc-4e9b-b6cb-f11c9f69da87');
10287
  Beacon( 'prefill', {
10288
- email: '<?php echo utf8_encode( $help_email ); ?>',
10289
- text: '\n\n----------------------------------------\n<?php echo $hs_debug; ?>',
10290
  });
10291
  </script>
10292
  <?php
@@ -10355,24 +11062,38 @@ function ewww_image_optimizer_filter_network_singlesite_settings_page( $input )
10355
  }
10356
 
10357
  /**
10358
- * Displays a help icon linked to the docs.
10359
  *
10360
  * @param string $link A link to the documentation.
10361
  * @param string $hsid The HelpScout ID for the docs article. Optional.
10362
  * @return string An HTML hyperlink element with a help icon.
10363
  */
 
 
 
 
 
 
 
 
 
 
 
 
10364
  function ewwwio_help_link( $link, $hsid = '' ) {
10365
  $help_icon = plugins_url( '/images/question-circle.png', __FILE__ );
10366
  $beacon_attr = '';
10367
  $link_class = 'ewww-help-icon';
10368
  if ( strpos( $hsid, ',' ) ) {
10369
- $beacon_attr = " data-beacon-articles='$hsid'";
10370
  $link_class = 'ewww-help-beacon-multi';
10371
  } elseif ( $hsid ) {
10372
- $beacon_attr = " data-beacon-article='$hsid'";
10373
  $link_class = 'ewww-help-beacon-single';
10374
  }
10375
- return "<a class='$link_class' href='$link' target='_blank' style='margin: 3px'$beacon_attr><img title='" . esc_attr__( 'Help', 'ewww-image-optimizer' ) . "' src='$help_icon'></a>";
 
 
10376
  }
10377
 
10378
  /**
@@ -10417,7 +11138,7 @@ function ewww_image_optimizer_remove_cloud_key( $redirect = true ) {
10417
  ewww_image_optimizer_set_option( 'ewww_image_optimizer_backup_files', '' );
10418
  if ( 'none' !== $redirect ) {
10419
  $sendback = wp_get_referer();
10420
- wp_redirect( esc_url_raw( $sendback ) );
10421
  exit;
10422
  }
10423
  }
@@ -10426,7 +11147,10 @@ function ewww_image_optimizer_remove_cloud_key( $redirect = true ) {
10426
  * Loads script to detect scaled images within the page, only enabled for admins.
10427
  */
10428
  function ewww_image_optimizer_resize_detection_script() {
10429
- if ( ! current_user_can( apply_filters( 'ewww_image_optimizer_admin_permissions', 'edit_others_posts' ) ) || 'wp-login.php' === basename( $_SERVER['SCRIPT_NAME'] ) ) {
 
 
 
10430
  return;
10431
  }
10432
  if ( ewww_image_optimizer_is_amp() ) {
@@ -10440,7 +11164,7 @@ function ewww_image_optimizer_resize_detection_script() {
10440
  "\tmargin: -3px;\n" .
10441
  "}\n" .
10442
  "</style>\n";
10443
- echo '<script type="text/javascript">' . $resize_detection_script . '</script>';
10444
  }
10445
  }
10446
 
@@ -10479,7 +11203,12 @@ function ewww_image_optimizer_is_amp() {
10479
  * Checks if admin bar is visible, and then adds the admin_bar_menu action.
10480
  */
10481
  function ewww_image_optimizer_admin_bar_init() {
10482
- if ( ! current_user_can( apply_filters( 'ewww_image_optimizer_admin_permissions', 'edit_others_posts' ) ) || ! is_admin_bar_showing() || 'wp-login.php' === basename( $_SERVER['SCRIPT_NAME'] ) || is_admin() ) {
 
 
 
 
 
10483
  return;
10484
  }
10485
  if ( ewww_image_optimizer_get_option( 'ewww_image_optimizer_resize_detection' ) ) {
@@ -10600,7 +11329,7 @@ function ewww_image_optimizer_delete_debug_log() {
10600
  unlink( WP_CONTENT_DIR . '/ewww/debug.log' );
10601
  }
10602
  $sendback = wp_get_referer();
10603
- wp_redirect( esc_url_raw( $sendback ) );
10604
  exit;
10605
  }
10606
 
@@ -10654,146 +11383,6 @@ function ewwwio_debug_backtrace() {
10654
  return maybe_serialize( $backtrace );
10655
  }
10656
 
10657
- /**
10658
- * Displays backtraces and information on images that have been optimized multiple times.
10659
- *
10660
- * @global object $wpdb
10661
- * @global object $ewwwdb A clone of $wpdb unless it is lacking utf8 connectivity.
10662
- */
10663
- function ewww_image_optimizer_dynamic_image_debug() {
10664
- ewwwio_debug_message( '<b>' . __FUNCTION__ . '()</b>' );
10665
- echo '<div class="wrap"><h1>' . esc_html__( 'Dynamic Image Debugging', 'ewww-image-optimizer' ) . '</h1>';
10666
- global $wpdb;
10667
- if ( strpos( $wpdb->charset, 'utf8' ) === false ) {
10668
- ewww_image_optimizer_db_init();
10669
- global $ewwwdb;
10670
- } else {
10671
- $ewwwdb = $wpdb;
10672
- }
10673
- $debug_images = $ewwwdb->get_results( "SELECT path,updates,updated,trace FROM $ewwwdb->ewwwio_images WHERE trace IS NOT NULL ORDER BY updates DESC LIMIT 100" );
10674
- if ( ewww_image_optimizer_iterable( $debug_images ) ) {
10675
- foreach ( $debug_images as $image ) {
10676
- $trace = unserialize( $image->trace );
10677
- echo '<p><b>' . esc_html__( 'File path', 'ewww-image-optimizer' ) . ': ' . ewww_image_optimizer_absolutize_path( $image->path ) . '</b><br>';
10678
- echo esc_html__( 'Number of attempted optimizations', 'ewww-image-optimizer' ) . ': ' . $image->updates . '<br>';
10679
- echo esc_html__( 'Last attempted', 'ewww-image-optimizer' ) . ': ' . $image->updated . '<br>';
10680
- echo esc_html__( 'PHP trace', 'ewww-image-optimizer' ) . ':<br>';
10681
- $i = 0;
10682
- if ( is_array( $trace ) ) {
10683
- foreach ( $trace as $function ) {
10684
- if ( ! empty( $function['file'] ) && ! empty( $function['line'] ) ) {
10685
- echo "#$i {$function['function']}() called at {$function['file']}:{$function['line']}<br>";
10686
- } else {
10687
- echo "#$i {$function['function']}() called<br>";
10688
- }
10689
- $i++;
10690
- }
10691
- } else {
10692
- esc_html_e( 'Cannot display trace', 'ewww-image-optimizer' );
10693
- }
10694
- echo '</p>';
10695
- }
10696
- }
10697
- echo '</div>';
10698
- }
10699
-
10700
- /**
10701
- * Displays images that are in the optimization queue.
10702
- *
10703
- * Allows viewing the image queues for debugging, and lets the user clear all queues.
10704
- *
10705
- * @global object $wpdb
10706
- * @global object $ewwwio_media_background Background optimization class object.
10707
- */
10708
- function ewww_image_optimizer_image_queue_debug() {
10709
- ewwwio_debug_message( '<b>' . __FUNCTION__ . '()</b>' );
10710
- global $ewwwio_media_background;
10711
- if ( ! class_exists( 'WP_Background_Process' ) ) {
10712
- require_once( EWWW_IMAGE_OPTIMIZER_PLUGIN_PATH . 'background.php' );
10713
- }
10714
- if ( ! is_object( $ewwwio_media_background ) ) {
10715
- $ewwwio_media_background = new EWWWIO_Media_Background_Process();
10716
- }
10717
- // Let user clear a queue, or all queues.
10718
- if ( isset( $_POST['ewww_image_optimizer_clear_queue'] ) && current_user_can( 'manage_options' ) && wp_verify_nonce( $_POST['ewww_nonce'], 'ewww_image_optimizer_clear_queue' ) ) {
10719
- if ( is_numeric( $_POST['ewww_image_optimizer_clear_queue'] ) ) {
10720
- $queues = (int) $_POST['ewww_image_optimizer_clear_queue'];
10721
- while ( $queues ) {
10722
- $ewwwio_media_background->cancel_process();
10723
- $queues--;
10724
- }
10725
- if ( ! empty( $_POST['ids'] ) && preg_match( '/^[\d,]+$/', $_POST['ids'], $request_ids ) ) {
10726
- $ids = explode( ',', $request_ids[0] );
10727
- foreach ( $ids as $id ) {
10728
- delete_transient( 'ewwwio-background-in-progress-' . $id );
10729
- }
10730
- }
10731
- } else {
10732
- delete_site_option( sanitize_text_field( $_POST['ewww_image_optimizer_clear_queue'] ) );
10733
- if ( ! empty( $_POST['ids'] ) && preg_match( '/^[\d,]+$/', $_POST['ids'], $request_ids ) ) {
10734
- $ids = explode( ',', $request_ids[0] );
10735
- foreach ( $ids as $id ) {
10736
- delete_transient( 'ewwwio-background-in-progress-' . $id );
10737
- }
10738
- }
10739
- }
10740
- }
10741
- echo "<div class='wrap'><h1>" . esc_html__( 'Image Queue Debugging', 'ewww-image-optimizer' ) . '</h1>';
10742
- global $wpdb;
10743
-
10744
- $table = $wpdb->options;
10745
-
10746
- $key = 'wp_ewwwio_media_optimize_batch_%';
10747
- $queues = $wpdb->get_results(
10748
- $wpdb->prepare(
10749
- "SELECT *
10750
- FROM $wpdb->options
10751
- WHERE option_name LIKE %s AND option_value != ''
10752
- ORDER BY option_id ASC",
10753
- $key
10754
- ),
10755
- ARRAY_A
10756
- );
10757
-
10758
- $nonce = wp_create_nonce( 'ewww_image_optimizer_clear_queue' );
10759
- if ( empty( $queues ) ) {
10760
- esc_html_e( 'Nothing to see here, go upload some images!', 'ewww-image-optimizer' );
10761
- } else {
10762
- $queue_count = $ewwwio_media_background->count_queue();
10763
- echo "<p><strong>$queue_count</strong> items in all queues</p>";
10764
- $all_ids = array();
10765
- foreach ( $queues as $queue ) {
10766
- $ids = array();
10767
- echo "<strong>{$queue['option_id']}</strong> - {$queue['option_name']}<br>";
10768
- $items = maybe_unserialize( $queue['option_value'] );
10769
- foreach ( $items as $item ) {
10770
- echo "{$item['id']} - {$item['type']}<br>";
10771
- $all_ids[] = $item['id'];
10772
- $ids[] = $item['id'];
10773
- }
10774
- $queue_count = count( $ids );
10775
- echo "<strong>$queue_count</strong> items in queue<br>";
10776
- $ids = implode( ',', $ids );
10777
- ?>
10778
- <form id="ewww-queue-clear-<?php echo $queue['option_id']; ?>" method="post" style="margin-bottom: 1.5em;" action="">
10779
- <input type="hidden" id="ewww_nonce" name="ewww_nonce" value="<?php echo $nonce; ?>">
10780
- <input type="hidden" name="ewww_image_optimizer_clear_queue" value="<?php echo $queue['option_name']; ?>">
10781
- <input type="hidden" name="ids" value="<?php echo $ids; ?>">
10782
- <button type="submit" class="button-secondary action"><?php esc_html_e( 'Clear this queue', 'ewww-image-optimizer' ); ?></button>
10783
- </form>
10784
- <?php
10785
- }
10786
- $all_ids = implode( ',', $all_ids );
10787
- ?>
10788
- <form id="ewww-queue-clear-all" method="post" style="margin: 2em 0;" action="">
10789
- <input type="hidden" id="ewww_nonce" name="ewww_nonce" value="<?php echo $nonce; ?>">
10790
- <input type="hidden" name="ewww_image_optimizer_clear_queue" value="<?php echo count( $queues ); ?>">
10791
- <input type="hidden" name="ids" value="<?php echo $all_ids; ?>">
10792
- <button type="submit" class="button-secondary action"><?php esc_html_e( 'Clear all queues', 'ewww-image-optimizer' ); ?></button>
10793
- </form>
10794
- <?php }
10795
- }
10796
-
10797
  /**
10798
  * Make sure to clear temp debug option on shutdown.
10799
  */
14
  exit;
15
  }
16
 
17
+ define( 'EWWW_IMAGE_OPTIMIZER_VERSION', '541.0' );
18
 
19
  // Initialize a couple globals.
20
  $eio_debug = '';
130
  add_action( 'admin_action_ewww_image_optimizer_manual_restore', 'ewww_image_optimizer_manual' );
131
  // Legacy (non-AJAX) action hook for manually restoring a backup from the API.
132
  add_action( 'admin_action_ewww_image_optimizer_manual_cloud_restore', 'ewww_image_optimizer_manual' );
 
 
133
  // Cleanup routine when an attachment is deleted.
134
  add_action( 'delete_attachment', 'ewww_image_optimizer_delete' );
135
  // Cleanup db records when Enable Media Replace replaces a file.
140
  add_action( 'admin_menu', 'ewww_image_optimizer_admin_menu', 60 );
141
  // Adds the EWWW IO settings to the network admin menu.
142
  add_action( 'network_admin_menu', 'ewww_image_optimizer_network_admin_menu' );
 
 
143
  // Handle the bulk actions from the media library.
144
  add_filter( 'handle_bulk_actions-upload', 'ewww_image_optimizer_bulk_action_handler', 10, 3 );
145
  // Adds scripts to ajaxify the one-click actions on the media library, and register tooltips for conversion links.
209
  function ewww_image_optimizer_parser_init() {
210
  $buffer_start = false;
211
  // If ExactDN is enabled.
212
+ if ( ewww_image_optimizer_get_option( 'ewww_image_optimizer_exactdn' ) && false === strpos( add_query_arg( null, null ), 'exactdn_disable=1' ) ) {
213
  if ( ! ewww_image_optimizer_get_option( 'exactdn_all_the_things' ) ) {
214
  // Un-configure Autoptimize CDN domain.
215
  if ( defined( 'AUTOPTIMIZE_PLUGIN_DIR' ) && strpos( ewww_image_optimizer_get_option( 'autoptimize_cdn_url' ), 'exactdn' ) ) {
510
  }
511
  }
512
 
513
+ // For the settings page, check for the enable-local param and take appropriate action.
514
+ if ( ! empty( $_GET['enable-local'] ) && ! empty( $_REQUEST['_wpnonce'] ) && wp_verify_nonce( sanitize_key( $_REQUEST['_wpnonce'] ), 'ewww_image_optimizer_options-options' ) ) {
515
+ update_option( 'ewww_image_optimizer_local_mode', true );
516
+ update_site_option( 'ewww_image_optimizer_local_mode', true );
517
+ } elseif ( isset( $_GET['enable-local'] ) && ! (bool) $_GET['enable-local'] && ! empty( $_REQUEST['_wpnonce'] ) && wp_verify_nonce( sanitize_key( $_REQUEST['_wpnonce'] ), 'ewww_image_optimizer_options-options' ) && isset( $_GET['enable-local'] ) ) {
518
+ delete_option( 'ewww_image_optimizer_local_mode', true );
519
+ delete_site_option( 'ewww_image_optimizer_local_mode', true );
520
+ if ( ewww_image_optimizer_get_option( 'ewww_image_optimizer_cloud_key' ) ) {
521
+ ewww_image_optimizer_remove_cloud_key();
522
+ }
523
  }
524
+
525
+ // Resizes and auto-rotates images.
526
+ add_filter( 'wp_handle_upload', 'ewww_image_optimizer_handle_upload' );
527
  if ( class_exists( 'S3_Uploads' ) ) {
528
  ewwwio_debug_message( 's3-uploads detected, deferring resize_upload' );
529
  add_filter( 'ewww_image_optimizer_defer_resizing', '__return_true' );
590
  ewww_image_optimizer_set_defaults();
591
  // This will get re-enabled if things are too slow.
592
  ewww_image_optimizer_set_option( 'exactdn_prevent_db_queries', false );
593
+ if ( ewww_image_optimizer_get_option( 'ewww_image_optimizer_exactdn' ) && ewww_image_optimizer_get_option( 'ewww_image_optimizer_exactdn_verify_method' ) > 0 ) {
594
+ delete_option( 'ewww_image_optimizer_exactdn_verify_method' );
595
+ delete_site_option( 'ewww_image_optimizer_exactdn_verify_method' );
596
+ }
597
  if ( get_option( 'ewww_image_optimizer_version' ) < 297.5 ) {
598
  // Cleanup background test mess.
599
  wp_clear_scheduled_hook( 'wp_ewwwio_test_optimize_cron' );
691
  ewww_image_optimizer_enable_background_optimization();
692
  sleep( 10 );
693
  $sendback = wp_get_referer();
694
+ wp_safe_redirect( $sendback );
695
  exit;
696
  }
697
 
730
  if ( is_multisite() && is_plugin_active_for_network( EWWW_IMAGE_OPTIMIZER_PLUGIN_FILE_REL ) ) {
731
  ewwwio_debug_message( 'saving network settings' );
732
  // Set the common network settings if they have been POSTed.
733
+ if (
734
+ ! empty( $_REQUEST['_wpnonce'] ) &&
735
+ wp_verify_nonce( sanitize_key( $_REQUEST['_wpnonce'] ), 'ewww_image_optimizer_options-options' ) &&
736
+ isset( $_POST['option_page'] ) &&
737
+ false !== strpos( sanitize_text_field( wp_unslash( $_POST['option_page'] ) ), 'ewww_image_optimizer_options' ) &&
738
+ current_user_can( 'manage_network_options' ) &&
739
+ ! get_site_option( 'ewww_image_optimizer_allow_multisite_override' ) &&
740
+ false === strpos( wp_get_referer(), 'options-general' )
741
+ ) {
742
  ewwwio_debug_message( 'network-wide settings, no override' );
743
+ $ewww_image_optimizer_cloud_key = empty( $_POST['ewww_image_optimizer_cloud_key'] ) ? '' : sanitize_key( $_POST['ewww_image_optimizer_cloud_key'] );
744
+ update_site_option( 'ewww_image_optimizer_cloud_key', ewww_image_optimizer_cloud_key_sanitize( $ewww_image_optimizer_cloud_key ) );
745
+ $ewww_image_optimizer_debug = ( empty( $_POST['ewww_image_optimizer_debug'] ) ? false : true );
746
+ update_site_option( 'ewww_image_optimizer_debug', $ewww_image_optimizer_debug );
747
+ $ewww_image_optimizer_metadata_remove = ( empty( $_POST['ewww_image_optimizer_metadata_remove'] ) ? false : true );
748
+ update_site_option( 'ewww_image_optimizer_metadata_remove', $ewww_image_optimizer_metadata_remove );
749
+ $ewww_image_optimizer_jpg_level = empty( $_POST['ewww_image_optimizer_jpg_level'] ) ? '' : (int) $_POST['ewww_image_optimizer_jpg_level'];
750
+ update_site_option( 'ewww_image_optimizer_jpg_level', $ewww_image_optimizer_jpg_level );
751
+ $ewww_image_optimizer_png_level = empty( $_POST['ewww_image_optimizer_png_level'] ) ? '' : (int) $_POST['ewww_image_optimizer_png_level'];
752
+ update_site_option( 'ewww_image_optimizer_png_level', $ewww_image_optimizer_png_level );
753
+ $ewww_image_optimizer_gif_level = empty( $_POST['ewww_image_optimizer_gif_level'] ) ? '' : (int) $_POST['ewww_image_optimizer_gif_level'];
754
+ update_site_option( 'ewww_image_optimizer_gif_level', $ewww_image_optimizer_gif_level );
755
+ $ewww_image_optimizer_pdf_level = empty( $_POST['ewww_image_optimizer_pdf_level'] ) ? '' : (int) $_POST['ewww_image_optimizer_pdf_level'];
756
+ update_site_option( 'ewww_image_optimizer_pdf_level', $ewww_image_optimizer_pdf_level );
757
+ $ewww_image_optimizer_delete_originals = ( empty( $_POST['ewww_image_optimizer_delete_originals'] ) ? false : true );
758
+ update_site_option( 'ewww_image_optimizer_delete_originals', $ewww_image_optimizer_delete_originals );
759
+ $ewww_image_optimizer_jpg_to_png = ( empty( $_POST['ewww_image_optimizer_jpg_to_png'] ) ? false : true );
760
+ update_site_option( 'ewww_image_optimizer_jpg_to_png', $ewww_image_optimizer_jpg_to_png );
761
+ $ewww_image_optimizer_png_to_jpg = ( empty( $_POST['ewww_image_optimizer_png_to_jpg'] ) ? false : true );
762
+ update_site_option( 'ewww_image_optimizer_png_to_jpg', $ewww_image_optimizer_png_to_jpg );
763
+ $ewww_image_optimizer_gif_to_png = ( empty( $_POST['ewww_image_optimizer_gif_to_png'] ) ? false : true );
764
+ update_site_option( 'ewww_image_optimizer_gif_to_png', $ewww_image_optimizer_gif_to_png );
765
+ $ewww_image_optimizer_webp = ( empty( $_POST['ewww_image_optimizer_webp'] ) ? false : true );
766
+ update_site_option( 'ewww_image_optimizer_webp', $ewww_image_optimizer_webp );
767
+ $ewww_image_optimizer_jpg_background = empty( $_POST['ewww_image_optimizer_jpg_background'] ) ? '' : sanitize_text_field( wp_unslash( $_POST['ewww_image_optimizer_jpg_background'] ) );
768
+ update_site_option( 'ewww_image_optimizer_jpg_background', ewww_image_optimizer_jpg_background( $ewww_image_optimizer_jpg_background ) );
769
+ $ewww_image_optimizer_jpg_quality = empty( $_POST['ewww_image_optimizer_jpg_quality'] ) ? '' : (int) $_POST['ewww_image_optimizer_jpg_quality'];
770
+ update_site_option( 'ewww_image_optimizer_jpg_quality', ewww_image_optimizer_jpg_quality( $ewww_image_optimizer_jpg_quality ) );
771
+ $ewww_image_optimizer_disable_convert_links = ( empty( $_POST['ewww_image_optimizer_disable_convert_links'] ) ? false : true );
772
+ update_site_option( 'ewww_image_optimizer_disable_convert_links', $ewww_image_optimizer_disable_convert_links );
773
+ $ewww_image_optimizer_backup_files = ( empty( $_POST['ewww_image_optimizer_backup_files'] ) ? false : true );
774
+ update_site_option( 'ewww_image_optimizer_backup_files', $ewww_image_optimizer_backup_files );
775
+ $ewww_image_optimizer_auto = ( empty( $_POST['ewww_image_optimizer_auto'] ) ? false : true );
776
+ update_site_option( 'ewww_image_optimizer_auto', $ewww_image_optimizer_auto );
777
+ $ewww_image_optimizer_aux_paths = empty( $_POST['ewww_image_optimizer_aux_paths'] ) ? '' : sanitize_textarea_field( wp_unslash( $_POST['ewww_image_optimizer_aux_paths'] ) );
778
+ update_site_option( 'ewww_image_optimizer_aux_paths', ewww_image_optimizer_aux_paths_sanitize( $ewww_image_optimizer_aux_paths ) );
779
+ $ewww_image_optimizer_exclude_paths = empty( $_POST['ewww_image_optimizer_exclude_paths'] ) ? '' : sanitize_textarea_field( wp_unslash( $_POST['ewww_image_optimizer_exclude_paths'] ) );
780
+ update_site_option( 'ewww_image_optimizer_exclude_paths', ewww_image_optimizer_exclude_paths_sanitize( $ewww_image_optimizer_exclude_paths ) );
781
+ $ewww_image_optimizer_enable_cloudinary = ( empty( $_POST['ewww_image_optimizer_enable_cloudinary'] ) ? false : true );
782
+ update_site_option( 'ewww_image_optimizer_enable_cloudinary', $ewww_image_optimizer_enable_cloudinary );
783
+ $ewww_image_optimizer_exactdn = ( empty( $_POST['ewww_image_optimizer_exactdn'] ) ? false : true );
784
+ update_site_option( 'ewww_image_optimizer_exactdn', $ewww_image_optimizer_exactdn );
785
+ $exactdn_all_the_things = ( empty( $_POST['exactdn_all_the_things'] ) ? false : true );
786
+ update_site_option( 'exactdn_all_the_things', $exactdn_all_the_things );
787
+ $exactdn_lossy = ( empty( $_POST['exactdn_lossy'] ) ? false : true );
788
+ update_site_option( 'exactdn_lossy', $exactdn_lossy );
789
+ $exactdn_exclude = empty( $_POST['exactdn_exclude'] ) ? '' : sanitize_textarea_field( wp_unslash( $_POST['exactdn_exclude'] ) );
790
+ update_site_option( 'exactdn_exclude', ewww_image_optimizer_exclude_paths_sanitize( $exactdn_exclude ) );
791
+ $ewww_image_optimizer_lazy_load = ( empty( $_POST['ewww_image_optimizer_lazy_load'] ) ? false : true );
792
+ update_site_option( 'ewww_image_optimizer_lazy_load', $ewww_image_optimizer_lazy_load );
793
+ $ewww_image_optimizer_use_lqip = ( empty( $_POST['ewww_image_optimizer_use_lqip'] ) ? false : true );
794
+ update_site_option( 'ewww_image_optimizer_use_lqip', $ewww_image_optimizer_use_lqip );
795
+ $ewww_image_optimizer_ll_exclude = empty( $_POST['ewww_image_optimizer_ll_exclude'] ) ? '' : sanitize_textarea_field( wp_unslash( $_POST['ewww_image_optimizer_ll_exclude'] ) );
796
+ update_site_option( 'ewww_image_optimizer_ll_exclude', ewww_image_optimizer_exclude_paths_sanitize( $ewww_image_optimizer_ll_exclude ) );
797
+ $ewww_image_optimizer_maxmediawidth = empty( $_POST['ewww_image_optimizer_maxmediawidth'] ) ? 0 : (int) $_POST['ewww_image_optimizer_maxmediawidth'];
798
+ update_site_option( 'ewww_image_optimizer_maxmediawidth', $ewww_image_optimizer_maxmediawidth );
799
+ $ewww_image_optimizer_maxmediaheight = empty( $_POST['ewww_image_optimizer_maxmediaheight'] ) ? 0 : (int) $_POST['ewww_image_optimizer_maxmediaheight'];
800
+ update_site_option( 'ewww_image_optimizer_maxmediaheight', $ewww_image_optimizer_maxmediaheight );
801
+ $ewww_image_optimizer_resize_detection = ( empty( $_POST['ewww_image_optimizer_resize_detection'] ) ? false : true );
802
+ update_site_option( 'ewww_image_optimizer_resize_detection', $ewww_image_optimizer_resize_detection );
803
+ $ewww_image_optimizer_resize_existing = ( empty( $_POST['ewww_image_optimizer_resize_existing'] ) ? false : true );
804
+ update_site_option( 'ewww_image_optimizer_resize_existing', $ewww_image_optimizer_resize_existing );
805
+ $ewww_image_optimizer_resize_other_existing = ( empty( $_POST['ewww_image_optimizer_resize_other_existing'] ) ? false : true );
806
+ update_site_option( 'ewww_image_optimizer_resize_other_existing', $ewww_image_optimizer_resize_other_existing );
807
+ $ewww_image_optimizer_parallel_optimization = ( empty( $_POST['ewww_image_optimizer_parallel_optimization'] ) ? false : true );
808
+ update_site_option( 'ewww_image_optimizer_parallel_optimization', $ewww_image_optimizer_parallel_optimization );
809
+ $ewww_image_optimizer_include_media_paths = ( empty( $_POST['ewww_image_optimizer_include_media_paths'] ) ? false : true );
810
+ update_site_option( 'ewww_image_optimizer_include_media_paths', $ewww_image_optimizer_include_media_paths );
811
+ $ewww_image_optimizer_include_originals = ( empty( $_POST['ewww_image_optimizer_include_originals'] ) ? false : true );
812
+ update_site_option( 'ewww_image_optimizer_include_originals', $ewww_image_optimizer_include_originals );
813
+ $ewww_image_optimizer_webp_for_cdn = ( empty( $_POST['ewww_image_optimizer_webp_for_cdn'] ) ? false : true );
814
+ update_site_option( 'ewww_image_optimizer_webp_for_cdn', $ewww_image_optimizer_webp_for_cdn );
815
+ $ewww_image_optimizer_picture_webp = ( empty( $_POST['ewww_image_optimizer_picture_webp'] ) ? false : true );
816
+ update_site_option( 'ewww_image_optimizer_picture_webp', $ewww_image_optimizer_picture_webp );
817
+ $ewww_image_optimizer_webp_rewrite_exclude = empty( $_POST['ewww_image_optimizer_webp_rewrite_exclude'] ) ? '' : sanitize_textarea_field( wp_unslash( $_POST['ewww_image_optimizer_webp_rewrite_exclude'] ) );
818
+ update_site_option( 'ewww_image_optimizer_webp_rewrite_exclude', ewww_image_optimizer_exclude_paths_sanitize( $ewww_image_optimizer_webp_rewrite_exclude ) );
819
+ $ewww_image_optimizer_webp_force = ( empty( $_POST['ewww_image_optimizer_webp_force'] ) ? false : true );
820
+ update_site_option( 'ewww_image_optimizer_webp_force', $ewww_image_optimizer_webp_force );
821
+ $ewww_image_optimizer_webp_paths = ( empty( $_POST['ewww_image_optimizer_webp_paths'] ) ? '' : sanitize_textarea_field( wp_unslash( $_POST['ewww_image_optimizer_webp_paths'] ) ) );
822
+ update_site_option( 'ewww_image_optimizer_webp_paths', ewww_image_optimizer_webp_paths_sanitize( $ewww_image_optimizer_webp_paths ) );
823
+ $ewww_image_optimizer_allow_multisite_override = empty( $_POST['ewww_image_optimizer_allow_multisite_override'] ) ? false : true;
824
+ update_site_option( 'ewww_image_optimizer_allow_multisite_override', $ewww_image_optimizer_allow_multisite_override );
825
+ $ewww_image_optimizer_enable_help = empty( $_POST['ewww_image_optimizer_enable_help'] ) ? false : true;
826
+ update_site_option( 'ewww_image_optimizer_enable_help', $ewww_image_optimizer_enable_help );
827
  global $ewwwio_tracking;
828
+ $ewww_image_optimizer_allow_tracking = empty( $_POST['ewww_image_optimizer_allow_tracking'] ) ? false : $ewwwio_tracking->check_for_settings_optin( (bool) $_POST['ewww_image_optimizer_allow_tracking'] );
829
+ update_site_option( 'ewww_image_optimizer_allow_tracking', $ewww_image_optimizer_allow_tracking );
830
  add_action( 'network_admin_notices', 'ewww_image_optimizer_network_settings_saved' );
831
+ } elseif (
832
+ isset( $_POST['ewww_image_optimizer_allow_multisite_override_active'] ) &&
833
+ current_user_can( 'manage_network_options' ) &&
834
+ isset( $_REQUEST['_wpnonce'] ) &&
835
+ wp_verify_nonce( sanitize_key( $_REQUEST['_wpnonce'] ), 'ewww_image_optimizer_options-options' )
836
+ ) {
837
  ewwwio_debug_message( 'network-wide settings, single-site overriding' );
838
+ $ewww_image_optimizer_allow_multisite_override = empty( $_POST['ewww_image_optimizer_allow_multisite_override'] ) ? false : true;
839
+ update_site_option( 'ewww_image_optimizer_allow_multisite_override', $ewww_image_optimizer_allow_multisite_override );
840
  global $ewwwio_tracking;
841
+ $ewww_image_optimizer_allow_tracking = empty( $_POST['ewww_image_optimizer_allow_tracking'] ) ? false : $ewwwio_tracking->check_for_settings_optin( (bool) $_POST['ewww_image_optimizer_allow_tracking'] );
842
+ update_site_option( 'ewww_image_optimizer_allow_tracking', $ewww_image_optimizer_allow_tracking );
843
  add_action( 'network_admin_notices', 'ewww_image_optimizer_network_settings_saved' );
844
  } // End if().
845
  } // End if().
1025
  return;
1026
  }
1027
  ewwwio_debug_message( '<b>' . __FUNCTION__ . '()</b>' );
1028
+ $action = ! empty( $_REQUEST['action'] ) ? sanitize_key( $_REQUEST['action'] ) : ''; // phpcs:ignore WordPress.Security.NonceVerification
1029
+ if ( $action ) {
1030
+ ewwwio_debug_message( "doing $action" );
1031
+ }
1032
  // Check for (Force) Regenerate Thumbnails action (includes MLP regenerate).
1033
+ if (
1034
+ 'regeneratethumbnail' === $action ||
1035
+ 'rta_regenerate_thumbnails' === $action ||
1036
+ 'meauh_save_image' === $action ||
1037
+ 'hotspot_save' === $action
1038
+ ) {
1039
+ ewwwio_debug_message( 'doing regeneratethumbnail' );
1040
+ ewww_image_optimizer_image_sizes( false );
1041
+ return;
1042
+ }
1043
+ if ( 'mic_crop_image' === $action ) {
1044
+ ewwwio_debug_message( 'doing Manual Image Crop' );
1045
+ if ( ! defined( 'EWWWIO_EDITOR_OVERWRITE' ) ) {
1046
+ define( 'EWWWIO_EDITOR_OVERWRITE', true );
 
 
 
1047
  }
1048
+ return;
1049
  }
1050
+ if ( false !== strpos( $action, 'wc_regenerate_images' ) ) {
1051
  // Unhook all automatic processing, and save an option that (does not autoload) tells the user WC regenerated their images and they should run the bulk optimizer.
1052
  remove_filter( 'wp_image_editors', 'ewww_image_optimizer_load_editor', 60 );
1053
  remove_filter( 'wp_generate_attachment_metadata', 'ewww_image_optimizer_resize_from_meta_data', 15 );
1055
  return;
1056
  }
1057
  // Check for Image Watermark plugin.
1058
+ $iwaction = ! empty( $_REQUEST['iw-action'] ) ? sanitize_key( $_REQUEST['iw-action'] ) : ''; // phpcs:ignore WordPress.Security.NonceVerification
1059
+ if ( $iwaction ) {
1060
+ ewwwio_debug_message( "doing $iwaction" );
1061
  global $ewww_preempt_editor;
1062
  $ewww_preempt_editor = true;
1063
+ if ( 'applywatermark' === $iwaction ) {
1064
  remove_filter( 'wp_generate_attachment_metadata', 'ewww_image_optimizer_resize_from_meta_data', 15 );
1065
  add_action( 'iw_after_apply_watermark', 'ewww_image_optimizer_single_size_optimize', 10, 2 );
1066
  }
1067
  return;
1068
  }
1069
  // Check for other MLP actions, including multi-regen.
1070
+ if ( class_exists( 'MaxGalleriaMediaLib' ) && ( 'regen_mlp_thumbnails' === $action || 'move_media' === $action || 'copy_media' === $action || 'maxgalleria_rename_image' === $action ) ) {
1071
  ewwwio_debug_message( 'doing regen_mlp_thumbnails' );
1072
  ewww_image_optimizer_image_sizes( false );
1073
  return;
1074
  }
1075
  // Check for MLP upload.
1076
+ if ( class_exists( 'MaxGalleriaMediaLib' ) && ! empty( $_REQUEST['nonce'] ) && 'upload_attachment' === $action ) { // phpcs:ignore WordPress.Security.NonceVerification
1077
  ewwwio_debug_message( 'doing maxgalleria upload' );
1078
  ewww_image_optimizer_image_sizes( false );
1079
  return;
1083
  ewwwio_debug_message( 'IRSC action/regen' );
1084
  ewww_image_optimizer_image_sizes( false );
1085
  return;
1086
+ } elseif ( 0 === strpos( $action, 'sirsc' ) ) {
1087
  // Image Regenerate and Select Crop (old check).
1088
+ ewwwio_debug_message( 'IRSC action/regen (old)' );
1089
  ewww_image_optimizer_image_sizes( false );
1090
  return;
1091
  }
1181
  return;
1182
  }
1183
  // If this is a unique size.
1184
+ $resize_path = $base_dir . wp_basename( $data['file'] );
1185
  if ( 'application/pdf' === $type && 'full' === $size ) {
1186
  $size = 'pdf-full';
1187
  ewwwio_debug_message( 'processing full size pdf preview' );
1240
  */
1241
  function ewww_image_optimizer_disable_tools() {
1242
  ewwwio_debug_message( '<b>' . __FUNCTION__ . '()</b>' );
1243
+ if ( ! defined( 'EWWW_IMAGE_OPTIMIZER_NOEXEC' ) ) {
1244
+ define( 'EWWW_IMAGE_OPTIMIZER_NOEXEC', true );
1245
+ }
1246
  if ( ! defined( 'EWWW_IMAGE_OPTIMIZER_JPEGTRAN' ) ) {
1247
  define( 'EWWW_IMAGE_OPTIMIZER_JPEGTRAN', false );
1248
  }
1682
  function ewww_image_optimizer_notice_webp_bulk() {
1683
  $already_done = ewww_image_optimizer_aux_images_table_count();
1684
  if ( $already_done > 50 ) {
1685
+ echo "<div id='ewww-image-optimizer-pngout-success' class='notice notice-info'><p><a href='" .
1686
+ esc_url( admin_url( 'upload.php?page=ewww-image-optimizer-bulk&ewww_webp_only=1&ewww_force=1' ) ) .
1687
+ "'>" . esc_html__( 'It looks like you already started optimizing your images, you will need to generate WebP images via the Bulk Optimizer.', 'ewww-image-optimizer' ) . '</a></p></div>';
1688
  } else {
1689
+ echo "<div id='ewww-image-optimizer-pngout-success' class='notice notice-info'><p><a href='" .
1690
+ esc_url( admin_url( 'upload.php?page=ewww-image-optimizer-bulk' ) ) .
1691
+ "'>" . esc_html__( 'Use the Bulk Optimizer to generate WebP images for existing uploads.', 'ewww-image-optimizer' ) . '</a></p></div>';
1692
  }
1693
  delete_option( 'ewww_image_optimizer_webp_enabled' );
1694
  }
1697
  * Display a success or failure message after PNGOUT installation.
1698
  */
1699
  function ewww_image_optimizer_pngout_installed() {
1700
+ if ( ! empty( $_REQUEST['ewww_pngout'] ) && 'success' === $_REQUEST['ewww_pngout'] ) { // phpcs:ignore WordPress.Security.NonceVerification
1701
  echo "<div id='ewww-image-optimizer-pngout-success' class='notice notice-success fade'>\n" .
1702
  '<p>' . esc_html__( 'Pngout was successfully installed.', 'ewww-image-optimizer' ) . "</p>\n" .
1703
  "</div>\n";
1704
  }
1705
+ if ( ! empty( $_REQUEST['ewww_pngout'] ) && 'failed' === $_REQUEST['ewww_pngout'] ) { // phpcs:ignore WordPress.Security.NonceVerification
1706
  echo "<div id='ewww-image-optimizer-pngout-failure' class='notice notice-error'>\n" .
1707
  '<p>' . sprintf(
1708
  /* translators: 1: An error message 2: The folder where pngout should be installed */
1709
  esc_html__( 'Pngout was not installed: %1$s. Make sure this folder is writable: %2$s', 'ewww-image-optimizer' ),
1710
+ ( ! empty( $_REQUEST['ewww_error'] ) ? esc_html( sanitize_text_field( wp_unslash( $_REQUEST['ewww_error'] ) ) ) : esc_html( 'unknown error', 'ewww-image-optimizer' ) ), // phpcs:ignore WordPress.Security.NonceVerification
1711
+ esc_html( EWWW_IMAGE_OPTIMIZER_TOOL_PATH )
1712
  ) . "</p>\n" .
1713
  "</div>\n";
1714
  }
1728
  esc_html__( 'Could not activate Easy IO, please try again in a few minutes. If this error continues, please see %s for troubleshooting steps.', 'ewww-image-optimizer' ),
1729
  'https://docs.ewww.io/article/66-exactdn-not-verified'
1730
  ) .
1731
+ '<br><code>' . esc_html( $exactdn_activate_error ) . '</code>' .
1732
  '</p></div>';
1733
  }
1734
 
1845
  update_site_option( 'ewww_image_optimizer_dismiss_media_notice', true );
1846
  return;
1847
  }
1848
+ ?>
1849
+ <div id='ewww-image-optimizer-media-listmode' class='notice notice-info is-dismissible'>
1850
+ <p>
1851
+ <?php esc_html_e( 'Change the Media Library to List mode for additional image optimization information and actions.', 'ewww-image-optimizer' ); ?>
1852
+ <?php ewwwio_help_link( 'https://docs.ewww.io/article/62-power-user-options-in-list-mode', '5b61fdd32c7d3a03f89d41c4' ); ?>
1853
+ </p>
1854
+ </div>
1855
+ <?php
1856
  }
1857
  }
1858
 
1906
  */
1907
  function ewww_image_optimizer_notice_reoptimization() {
1908
  // Allows the user to reset all images back to 1 optimization, which clears the alert.
1909
+ if ( ! empty( $_GET['ewww_reset_reopt_nonce'] ) && wp_verify_nonce( sanitize_key( $_GET['ewww_reset_reopt_nonce'] ), 'reset_reoptimization_counters' ) ) {
1910
  global $wpdb;
1911
  $debug_images = $wpdb->query( "UPDATE $wpdb->ewwwio_images SET updates=1 WHERE updates > 1" );
1912
  delete_transient( 'ewww_image_optimizer_images_reoptimized' );
1926
  // Do a check for 10+ optimizations on 5+ images.
1927
  if ( ! empty( $reoptimized ) && $reoptimized > 5 ) {
1928
  $debugging_page = admin_url( 'tools.php?page=ewww-image-optimizer-tools' );
1929
+ $reset_page = wp_nonce_url( add_query_var( null, null ), 'reset_reoptimization_counters', 'ewww_reset_reopt_nonce' );
1930
  // Display an alert, and let the user reset the warning if they wish.
1931
  echo "<div id='ewww-image-optimizer-warning-reoptimizations' class='error'><p>" .
1932
  sprintf(
1933
  /* translators: %s: A link to the EWWW IO Tools page */
1934
  esc_html__( 'The EWWW Image Optimizer has detected excessive re-optimization of multiple images. Please use the %s page to Show Re-Optimized Images.', 'ewww-image-optimizer' ),
1935
+ "<a href='" . esc_url( $debugging_page ) . "'>" . esc_html__( 'Tools', 'ewww-image-optimizer' ) . '</a>'
1936
  ) .
1937
+ " <a href='" . esc_url( $reset_page ) . "'>" . esc_html__( 'Reset Counters' ) . '</a></p></div>';
1938
  }
1939
  }
1940
  }
2061
  * @return array The unaltered attachment metadata.
2062
  */
2063
  function ewww_image_optimizer_pte_check( $data ) {
2064
+ if ( ! empty( $_GET['pte-action'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification
2065
+ if ( 'confirm-images' === $_GET['pte-action'] ) { // phpcs:ignore WordPress.Security.NonceVerification
2066
  add_filter( 'wp_update_attachment_metadata', 'ewww_image_optimizer_resize_from_meta_data', 15, 2 );
2067
  }
2068
  }
2104
  $new_webp = $new_filepath . '.webp';
2105
  if ( ewwwio_is_file( $old_webp ) && ! ewwwio_is_file( $new_webp ) ) {
2106
  ewwwio_debug_message( "renaming $old_webp to $new_webp" );
2107
+ ewwwio_rename( $old_webp, $new_webp );
2108
  }
2109
  }
2110
 
2475
  $editor = wp_get_image_editor( $file );
2476
  $resized_image = $editor->resize( 150, 150, true );
2477
  $new_file = $editor->generate_filename();
2478
+ echo esc_html( $new_file );
2479
  if ( ewwwio_is_file( $new_file ) ) {
2480
  echo '<br>file already exists<br>';
2481
  }
2488
  function ewww_image_optimizer_admin_menu() {
2489
  // Adds bulk optimize to the media library menu.
2490
  $permissions = apply_filters( 'ewww_image_optimizer_bulk_permissions', '' );
2491
+ if (
2492
+ ! ewww_image_optimizer_get_option( 'ewww_image_optimizer_exactdn' ) ||
2493
+ ewww_image_optimizer_get_option( 'ewww_image_optimizer_cloud_key' ) ||
2494
+ ! ewww_image_optimizer_exec_check()
2495
+ ) {
2496
+ add_media_page( esc_html__( 'Bulk Optimize', 'ewww-image-optimizer' ), esc_html__( 'Bulk Optimize', 'ewww-image-optimizer' ), $permissions, 'ewww-image-optimizer-bulk', 'ewww_image_optimizer_bulk_preview' );
2497
+ // Adds Bulk Optimize to the media library bulk actions.
2498
+ add_filter( 'bulk_actions-upload', 'ewww_image_optimizer_add_bulk_media_actions' );
2499
+ }
2500
  add_submenu_page( null, esc_html__( 'Migrate WebP Images', 'ewww-image-optimizer' ), esc_html__( 'Migrate WebP Images', 'ewww-image-optimizer' ), $permissions, 'ewww-image-optimizer-webp-migrate', 'ewww_image_optimizer_webp_migrate_preview' );
2501
 
2502
  // Add tools page.
2530
  'ewww_image_optimizer_network_singlesite_options' // Function to call.
2531
  );
2532
  }
 
 
 
 
 
2533
  }
2534
 
2535
  /**
2552
  $webp_path = $temp_path . '.webp';
2553
  ewwwio_debug_message( "retina webp path: $webp_path" );
2554
  if ( ewwwio_is_file( $webp_path ) ) {
2555
+ ewwwio_rename( $webp_path, $retina_path . '.webp' );
2556
  }
2557
  $opt_size = ewww_image_optimizer_filesize( $retina_path );
2558
  ewwwio_debug_message( "retina size: $opt_size" );
2581
  ewwwio_memory( __FUNCTION__ );
2582
  }
2583
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2584
  /**
2585
  * Optimize MyArcade screenshots and thumbs.
2586
  *
2812
  );
2813
  continue;
2814
  }
2815
+ if ( ( ( $abspath && strpos( $path, ABSPATH ) === 0 ) || strpos( $path, $upload_path ) === 0 ) && ewwwio_is_dir( $path ) ) {
2816
  $path_array[] = $path;
2817
  continue;
2818
  }
2819
  // If they put in a relative path.
2820
+ if ( $abspath && ewwwio_is_dir( ABSPATH . ltrim( $path, '/' ) ) ) {
2821
  $path_array[] = ABSPATH . ltrim( $path, '/' );
2822
  continue;
2823
  }
2824
  // Or a path relative to the upload dir?
2825
+ if ( ewwwio_is_dir( $upload_path . ltrim( $path, '/' ) ) ) {
2826
  $path_array[] = $upload_path . ltrim( $path, '/' );
2827
  continue;
2828
  }
2829
  // What if they put in a url?
2830
  $pathabsurl = ABSPATH . ltrim( str_replace( get_site_url(), '', $path ), '/' );
2831
+ if ( $abspath && ewwwio_is_dir( $pathabsurl ) ) {
2832
  $path_array[] = $pathabsurl;
2833
  continue;
2834
  }
2835
  // Or a url in the uploads folder?
2836
  $pathupurl = $upload_path . ltrim( str_replace( $upload_dir['baseurl'], '', $path ), '/' );
2837
+ if ( ewwwio_is_dir( $pathupurl ) ) {
2838
  $path_array[] = $pathupurl;
2839
  continue;
2840
  }
3026
  return $max_size;
3027
  }
3028
 
3029
+ /**
3030
+ * Setup the global filesystem class variable.
3031
+ */
3032
+ function ewwwio_get_filesystem() {
3033
+ require_once( ABSPATH . 'wp-admin/includes/class-wp-filesystem-base.php' );
3034
+ require_once( ABSPATH . 'wp-admin/includes/class-wp-filesystem-direct.php' );
3035
+ global $eio_filesystem;
3036
+ if ( ! defined( 'FS_CHMOD_DIR' ) ) {
3037
+ define( 'FS_CHMOD_DIR', ( fileperms( ABSPATH ) & 0777 | 0755 ) );
3038
+ }
3039
+ if ( ! defined( 'FS_CHMOD_FILE' ) ) {
3040
+ define( 'FS_CHMOD_FILE', ( fileperms( ABSPATH . 'index.php' ) & 0777 | 0644 ) );
3041
+ }
3042
+ if ( ! isset( $eio_filesystem ) || ! is_object( $eio_filesystem ) ) {
3043
+ $eio_filesystem = new WP_Filesystem_Direct( '' );
3044
+ }
3045
+ }
3046
+
3047
  /**
3048
  * Check filesize, and prevent errors by ensuring file exists, and that the cache has been cleared.
3049
  *
3053
  function ewww_image_optimizer_filesize( $file ) {
3054
  $file = realpath( $file );
3055
  if ( ewwwio_is_file( $file ) ) {
3056
+ global $eio_filesystem;
3057
+ ewwwio_get_filesystem();
3058
  // Flush the cache for filesize.
3059
  clearstatcache();
3060
  // Find out the size of the new PNG file.
3061
+ return $eio_filesystem->size( $file );
3062
  } else {
3063
  return 0;
3064
  }
3065
  }
3066
 
3067
  /**
3068
+ * Check if a file/directory is readable.
3069
+ *
3070
+ * @param string $file The path to check.
3071
+ * @return bool True if it is, false if it ain't.
3072
+ */
3073
+ function ewwwio_is_readable( $file ) {
3074
+ global $eio_filesystem;
3075
+ ewwwio_get_filesystem();
3076
+ return $eio_filesystem->is_readable( $file );
3077
+ }
3078
+ /**
3079
+ * Check if directory exists, and that it is local rather than using a protocol like http:// or phar://
3080
+ *
3081
+ * @param string $dir The path of the directoy to check.
3082
+ * @return bool True if the directory exists and is local, false otherwise.
3083
+ */
3084
+ function ewwwio_is_dir( $dir ) {
3085
+ if ( false !== strpos( $dir, '://' ) ) {
3086
+ return false;
3087
+ }
3088
+ if ( false !== strpos( $dir, 'phar://' ) ) {
3089
+ return false;
3090
+ }
3091
+ global $eio_filesystem;
3092
+ ewwwio_get_filesystem();
3093
+ $dir = realpath( $dir );
3094
+ $wp_dir = realpath( ABSPATH );
3095
+ $upload_dir = wp_get_upload_dir();
3096
+ $upload_dir = realpath( $upload_dir['basedir'] );
3097
+
3098
+ $content_dir = realpath( WP_CONTENT_DIR );
3099
+ if ( empty( $content_dir ) ) {
3100
+ $content_dir = $wp_dir;
3101
+ }
3102
+ if ( empty( $upload_dir ) ) {
3103
+ $upload_dir = $content_dir;
3104
+ }
3105
+ $plugin_dir = realpath( EWWW_IMAGE_OPTIMIZER_PLUGIN_PATH );
3106
+ if (
3107
+ false === strpos( $dir, $upload_dir ) &&
3108
+ false === strpos( $dir, $content_dir ) &&
3109
+ false === strpos( $dir, $wp_dir ) &&
3110
+ false === strpos( $dir, $plugin_dir )
3111
+ ) {
3112
+ return false;
3113
+ }
3114
+ return $eio_filesystem->is_dir( $dir );
3115
+ }
3116
+
3117
+ /**
3118
+ * Check if file exists, and that it is local rather than using a protocol like http:// or phar://
3119
  *
3120
  * @param string $file The path of the file to check.
3121
  * @return bool True if the file exists and is local, false otherwise.
3127
  if ( false !== strpos( $file, 'phar://' ) ) {
3128
  return false;
3129
  }
3130
+ global $eio_filesystem;
3131
+ ewwwio_get_filesystem();
3132
  $file = realpath( $file );
3133
  $wp_dir = realpath( ABSPATH );
3134
  $upload_dir = wp_get_upload_dir();
3150
  ) {
3151
  return false;
3152
  }
3153
+ return $eio_filesystem->is_file( $file );
3154
+ }
3155
+
3156
+ /**
3157
+ * Check if destination is in an approved location and rename the original.
3158
+ *
3159
+ * @param string $src The path of the original file.
3160
+ * @param string $dst The destination file path.
3161
+ * @return bool True if the file was removed, false otherwise.
3162
+ */
3163
+ function ewwwio_rename( $src, $dst ) {
3164
+ global $eio_filesystem;
3165
+ ewwwio_get_filesystem();
3166
+ $src = realpath( $src );
3167
+ if ( false !== strpos( $dst, WP_CONTENT_DIR ) ) {
3168
+ return $eio_filesystem->move( $src, $dst, true );
3169
+ }
3170
+ if ( false !== strpos( $dst, ABSPATH ) ) {
3171
+ return $eio_filesystem->move( $src, $dst, true );
3172
+ }
3173
+ $upload_dir = wp_get_upload_dir();
3174
+ if ( false !== strpos( $dst, $upload_dir['basedir'] ) ) {
3175
+ return $eio_filesystem->move( $src, $dst, true );
3176
+ }
3177
+ return false;
3178
  }
3179
 
3180
  /**
3209
  * @param string $mode The mode to apply to the file.
3210
  */
3211
  function ewwwio_chmod( $file, $mode ) {
3212
+ global $eio_filesystem;
3213
+ ewwwio_get_filesystem();
3214
  $file = realpath( $file );
3215
  $upload_dir = wp_get_upload_dir();
3216
  if ( false !== strpos( $file, $upload_dir['basedir'] ) ) {
3217
+ return $eio_filesystem->chmod( $file, $mode );
3218
  }
3219
  if ( false !== strpos( $file, WP_CONTENT_DIR ) ) {
3220
+ return $eio_filesystem->chmod( $file, $mode );
3221
  }
3222
  if ( false !== strpos( $file, ABSPATH ) ) {
3223
+ return $eio_filesystem->chmod( $file, $mode );
3224
  }
3225
  return false;
3226
  }
3241
  */
3242
  function ewww_image_optimizer_manual() {
3243
  ewwwio_debug_message( '<b>' . __FUNCTION__ . '()</b>' );
3244
+ global $ewww_force;
3245
+ global $ewww_convert;
3246
  global $ewww_defer;
3247
  $ewww_defer = false;
3248
  // Check permissions of current user.
3249
  $permissions = apply_filters( 'ewww_image_optimizer_manual_permissions', '' );
3250
+ if ( ! current_user_can( $permissions ) ) {
3251
  // Display error message if insufficient permissions.
3252
  if ( ! wp_doing_ajax() ) {
3253
  wp_die( esc_html__( 'You do not have permission to optimize images.', 'ewww-image-optimizer' ) );
3254
  }
3255
  ewwwio_ob_clean();
3256
+ wp_die( wp_json_encode( array( 'error' => esc_html__( 'You do not have permission to optimize images.', 'ewww-image-optimizer' ) ) ) );
3257
  }
3258
  // Make sure we didn't accidentally get to this page without an attachment to work on.
3259
+ if ( empty( $_REQUEST['ewww_attachment_ID'] ) || empty( $_REQUEST['action'] ) ) {
3260
  // Display an error message since we don't have anything to work on.
3261
  if ( ! wp_doing_ajax() ) {
3262
+ wp_die( esc_html__( 'Invalid request.', 'ewww-image-optimizer' ) );
3263
  }
3264
  ewwwio_ob_clean();
3265
+ wp_die( wp_json_encode( array( 'error' => esc_html__( 'Invalid request.', 'ewww-image-optimizer' ) ) ) );
3266
  }
3267
  session_write_close();
3268
+ if ( empty( $_REQUEST['ewww_manual_nonce'] ) || ! wp_verify_nonce( sanitize_key( $_REQUEST['ewww_manual_nonce'] ), 'ewww-manual' ) ) {
 
 
3269
  if ( ! wp_doing_ajax() ) {
3270
  wp_die( esc_html__( 'Access denied.', 'ewww-image-optimizer' ) );
3271
  }
3272
  ewwwio_ob_clean();
3273
+ wp_die( wp_json_encode( array( 'error' => esc_html__( 'Access denied.', 'ewww-image-optimizer' ) ) ) );
3274
  }
3275
+ // Store the attachment ID value.
3276
+ $attachment_id = (int) $_REQUEST['ewww_attachment_ID'];
3277
+ $ewww_force = ! empty( $_REQUEST['ewww_force'] ) ? true : false;
3278
+ $ewww_convert = ! empty( $_REQUEST['ewww_convert'] ) ? true : false;
3279
  // Retrieve the existing attachment metadata.
3280
  $original_meta = wp_get_attachment_metadata( $attachment_id );
3281
  // If the call was to optimize...
3291
  wp_die( esc_html__( 'Access denied.', 'ewww-image-optimizer' ) );
3292
  }
3293
  ewwwio_ob_clean();
3294
+ wp_die( wp_json_encode( array( 'error' => esc_html__( 'Access denied.', 'ewww-image-optimizer' ) ) ) );
3295
  }
3296
  $basename = '';
3297
  if ( is_array( $new_meta ) && ! empty( $new_meta['file'] ) ) {
3307
  wp_die( esc_html__( 'License exceeded', 'ewww-image-optimizer' ) );
3308
  }
3309
  ewwwio_ob_clean();
3310
+ wp_die( wp_json_encode( array( 'error' => esc_html__( 'License exceeded', 'ewww-image-optimizer' ) ) ) );
3311
  }
3312
+ $success = ewww_image_optimizer_custom_column_capture( 'ewww-image-optimizer', $attachment_id, $new_meta );
3313
  ewww_image_optimizer_debug_log();
3314
  // Do a redirect, if this was called via GET.
3315
  if ( ! wp_doing_ajax() ) {
3316
  // Store the referring webpage location.
3317
  $sendback = wp_get_referer();
 
 
3318
  // Send the user back where they came from.
3319
+ wp_safe_redirect( $sendback );
3320
+ die;
3321
  }
3322
  ewwwio_memory( __FUNCTION__ );
3323
  ewwwio_ob_clean();
3324
  wp_die(
3325
+ wp_json_encode(
3326
  array(
3327
  'success' => $success,
3328
  'basename' => $basename,
3415
  if ( false === current_user_can( $permissions ) ) {
3416
  // Display error message if insufficient permissions.
3417
  ewwwio_ob_clean();
3418
+ wp_die( wp_json_encode( array( 'error' => esc_html__( 'You do not have permission to optimize images.', 'ewww-image-optimizer' ) ) ) );
3419
  }
3420
  // Make sure we didn't accidentally get to this page without an attachment to work on.
3421
  if ( empty( $_REQUEST['ewww_image_id'] ) ) {
3422
  // Display an error message since we don't have anything to work on.
3423
  ewwwio_ob_clean();
3424
+ wp_die( wp_json_encode( array( 'error' => esc_html__( 'No image ID was provided.', 'ewww-image-optimizer' ) ) ) );
3425
  }
3426
+ if ( empty( $_REQUEST['ewww_wpnonce'] ) || ! wp_verify_nonce( sanitize_key( $_REQUEST['ewww_wpnonce'] ), 'ewww-image-optimizer-tools' ) ) {
3427
  ewwwio_ob_clean();
3428
+ wp_die( wp_json_encode( array( 'error' => esc_html__( 'Access token has expired, please reload the page.', 'ewww-image-optimizer' ) ) ) );
3429
  }
3430
  session_write_close();
3431
  $image = (int) $_REQUEST['ewww_image_id'];
3432
  if ( ewww_image_optimizer_cloud_restore_single_image( $image ) ) {
3433
  ewwwio_ob_clean();
3434
+ wp_die( wp_json_encode( array( 'success' => 1 ) ) );
3435
  }
3436
  ewwwio_ob_clean();
3437
+ wp_die( wp_json_encode( array( 'error' => esc_html__( 'Unable to restore image.', 'ewww-image-optimizer' ) ) ) );
3438
  }
3439
 
3440
  /**
3500
  return false;
3501
  }
3502
  if ( empty( $old_type ) || $old_type === $new_type ) {
3503
+ if ( ewwwio_rename( $image['path'] . '.tmp', $image['path'] ) ) {
3504
  if ( ewwwio_is_file( $image['path'] . '.webp' ) && is_writable( $image['path'] . '.webp' ) ) {
3505
  unlink( $image['path'] . '.webp' );
3506
  }
3903
  if ( ! empty( $api_key ) ) {
3904
  $sanitize = true;
3905
  }
3906
+ if ( empty( $api_key ) ) {
3907
  $api_key = ewww_image_optimizer_get_option( 'ewww_image_optimizer_cloud_key' );
 
 
3908
  }
3909
  if ( empty( $api_key ) ) {
3910
  if ( ewww_image_optimizer_get_option( 'ewww_image_optimizer_jpg_level' ) > 10 ) {
4061
  return $quota;
4062
  }
4063
  if ( ! $quota['licensed'] && $quota['consumed'] > 0 ) {
4064
+ return sprintf(
4065
+ /* translators: 1: Number of images 2: Number of days until renewal */
4066
+ _n( 'optimized %1$d images, renewal is in %2$d day.', 'optimized %1$d images, renewal is in %2$d days.', $quota['days'], 'ewww-image-optimizer' ),
4067
+ $quota['consumed'],
4068
+ $quota['days']
 
 
4069
  );
4070
  } elseif ( ! $quota['licensed'] && $quota['consumed'] < 0 ) {
4071
+ return sprintf(
4072
+ /* translators: 1: Number of image credits for the compression API */
4073
+ _n( '%1$d image credit remaining.', '%1$d image credits remaining.', abs( $quota['consumed'] ), 'ewww-image-optimizer' ),
4074
+ abs( $quota['consumed'] )
 
 
4075
  );
4076
  } elseif ( $quota['licensed'] > 0 && $quota['consumed'] <= 0 ) {
4077
  $real_quota = (int) $quota['licensed'] - (int) $quota['consumed'];
4078
+ return sprintf(
4079
+ /* translators: 1: Number of image credits for the compression API */
4080
+ _n( '%1$d image credit remaining.', '%1$d image credits remaining.', $real_quota, 'ewww-image-optimizer' ),
4081
+ $real_quota
 
 
4082
  );
4083
  } elseif ( ! $quota['licensed'] && ! $quota['consumed'] && ! $quota['days'] && ! $quota['metered'] ) {
4084
+ return __( 'no credits remaining, please purchase more.', 'ewww-image-optimizer' );
4085
  } else {
4086
+ return sprintf(
4087
+ /* translators: 1: Number of image credits used 2: Number of image credits available 3: days until subscription renewal */
4088
+ _n( 'used %1$d of %2$d, usage will reset in %3$d day.', 'used %1$d of %2$d, usage will reset in %3$d days.', $quota['days'], 'ewww-image-optimizer' ),
4089
+ $quota['consumed'],
4090
+ $quota['licensed'],
4091
+ $quota['days']
 
 
4092
  );
4093
  }
4094
  }
4147
  ewwwio_debug_message( 'license exceeded, image not processed' );
4148
  return array( $file, false, 'exceeded', 0, '' );
4149
  }
4150
+ global $ewww_force;
4151
+ global $ewww_force_smart;
4152
+ global $eio_filesystem;
4153
+ ewwwio_get_filesystem();
4154
  if ( ewww_image_optimizer_get_option( 'ewww_image_optimizer_metadata_skip_full' ) && $fullsize ) {
4155
  $metadata = 1;
4156
  } elseif ( ewww_image_optimizer_get_option( 'ewww_image_optimizer_metadata_remove' ) ) {
4213
  if ( is_object( $ewww_image ) && $ewww_image->file === $file && ! empty( $ewww_image->backup ) ) {
4214
  $hash = $ewww_image->backup;
4215
  }
4216
+ if ( empty( $hash ) && ( ! empty( $ewww_force ) || ! empty( $ewww_force_smart ) ) ) {
4217
  $image = ewww_image_optimizer_find_already_optimized( $file );
4218
  if ( ! empty( $image ) && is_array( $image ) && ! empty( $image['backup'] ) ) {
4219
  $hash = $image['backup'];
4282
  $payload .= 'Content-Disposition: form-data; name="file"; filename="' . wp_basename( $file ) . '"' . "\r\n";
4283
  $payload .= 'Content-Type: ' . $type . "\r\n";
4284
  $payload .= "\r\n";
4285
+ $payload .= $eio_filesystem->get_contents( $file );
4286
  $payload .= "\r\n";
4287
  $payload .= '--' . $boundary;
4288
  $payload .= 'Content-Disposition: form-data; name="submitHandler"' . "\r\n";
4322
  } elseif ( ewww_image_optimizer_mimetype( $tempfile, 'i' ) === $type ) {
4323
  $newsize = filesize( $tempfile );
4324
  ewwwio_debug_message( "cloud results: $newsize (new) vs. $orig_size (original)" );
4325
+ ewwwio_rename( $tempfile, $file );
4326
  } elseif ( ewww_image_optimizer_mimetype( $tempfile, 'i' ) === 'image/webp' ) {
4327
  $newsize = filesize( $tempfile );
4328
  ewwwio_debug_message( "cloud results: $newsize (new) vs. $orig_size (original)" );
4329
+ ewwwio_rename( $tempfile, $newfile );
4330
  } elseif ( ! is_null( $newtype ) && ! is_null( $newfile ) && ewww_image_optimizer_mimetype( $tempfile, 'i' ) === $newtype ) {
 
 
 
4331
  ewwwio_debug_message( "renaming file from $tempfile to $newfile" );
4332
+ if ( ewwwio_rename( $tempfile, $newfile ) ) {
4333
+ $converted = true;
4334
+ $newsize = filesize( $newfile );
4335
+ $file = $newfile;
4336
+ ewwwio_debug_message( "cloud results: $newsize (new) vs. $orig_size (original)" );
4337
+ }
4338
  } else {
4339
  ewwwio_delete_file( $tempfile );
4340
  }
4378
  ewwwio_debug_message( 'license exceeded, image not rotated' );
4379
  return false;
4380
  }
4381
+ global $eio_filesystem;
4382
+ ewwwio_get_filesystem();
4383
  ewwwio_debug_message( "file: $file " );
4384
  ewwwio_debug_message( "type: $type" );
4385
  $api_key = ewww_image_optimizer_get_option( 'ewww_image_optimizer_cloud_key' );
4419
  $payload .= 'Content-Disposition: form-data; name="file"; filename="' . wp_basename( $file ) . '"' . "\r\n";
4420
  $payload .= 'Content-Type: ' . $type . "\r\n";
4421
  $payload .= "\r\n";
4422
+ $payload .= $eio_filesystem->get_contents( $file );
4423
  $payload .= "\r\n";
4424
  $payload .= '--' . $boundary;
4425
  $payload .= 'Content-Disposition: form-data; name="submitHandler"' . "\r\n";
4449
  if ( preg_match( '/exceeded/', $response['body'] ) ) {
4450
  ewwwio_debug_message( 'License Exceeded' );
4451
  set_transient( 'ewww_image_optimizer_cloud_status', 'exceeded', 3600 );
4452
+ ewwwio_delete_file( $tempfile );
4453
  } elseif ( ewww_image_optimizer_mimetype( $tempfile, 'i' ) === $type ) {
4454
  $newsize = filesize( $tempfile );
4455
  ewwwio_debug_message( "cloud rotation success: $newsize (new) vs. $orig_size (original)" );
4456
+ ewwwio_rename( $tempfile, $file );
4457
  return true;
4458
  } else {
4459
+ ewwwio_delete_file( $tempfile );
4460
  }
4461
  ewwwio_memory( __FUNCTION__ );
4462
  return false;
4479
  if ( ! ewww_image_optimizer_get_option( 'ewww_image_optimizer_backup_files' ) ) {
4480
  return false;
4481
  }
4482
+ if ( ! ewwwio_is_file( $file ) || ! ewwwio_is_readable( $file ) ) {
4483
  return false;
4484
  }
4485
  if ( ! ewwwio_check_memory_available( filesize( $file ) * 1.1 ) ) { // 1.1 = upload buffer (filesize) multiplied by a factor of 1.1 for extra wiggle room.
4516
  );
4517
 
4518
  global $ewww_image;
4519
+ global $eio_filesystem;
4520
+ ewwwio_get_filesystem();
4521
  if ( is_object( $ewww_image ) && $ewww_image->file === $file && ! empty( $ewww_image->backup ) ) {
4522
  $post_fields['backup'] = $ewww_image->backup;
4523
  } elseif ( is_object( $ewww_image ) && $ewww_image->file === $file && empty( $ewww_image->backup ) ) {
4541
  $payload .= 'Content-Disposition: form-data; name="file"; filename="' . wp_basename( $file ) . '"' . "\r\n";
4542
  $payload .= 'Content-Type: ' . ewww_image_optimizer_mimetype( $file, 'i' ) . "\r\n";
4543
  $payload .= "\r\n";
4544
+ $payload .= $eio_filesystem->get_contents( $file );
4545
  $payload .= "\r\n";
4546
  $payload .= '--' . $boundary;
4547
  $payload .= 'Content-Disposition: form-data; name="submitHandler"' . "\r\n";
4621
  ewwwio_debug_message( 'license exceeded, image not rotated' );
4622
  return new WP_Error( 'invalid_key', __( 'License Exceeded', 'ewww-image-optimizer' ) );
4623
  }
4624
+ global $eio_filesystem;
4625
+ ewwwio_get_filesystem();
4626
  ewwwio_debug_message( "file: $file " );
4627
  ewwwio_debug_message( "width: $dst_w" );
4628
  ewwwio_debug_message( "height: $dst_h" );
4671
  $payload .= 'Content-Disposition: form-data; name="file"; filename="' . wp_basename( $file ) . '"' . "\r\n";
4672
  $payload .= 'Content-Type: ' . $type . "\r\n";
4673
  $payload .= "\r\n";
4674
+ $payload .= $eio_filesystem->get_contents( $file );
4675
  $payload .= "\r\n";
4676
  $payload .= '--' . $boundary;
4677
  $payload .= 'Content-Disposition: form-data; name="submitHandler"' . "\r\n";
4701
  if ( false !== strpos( $response['body'], 'error' ) ) {
4702
  $response = json_decode( $response['body'], true );
4703
  ewwwio_debug_message( 'API resize error: ' . $response['error'] );
4704
+ ewwwio_delete_file( $tempfile );
4705
  return new WP_Error( 'image_resize_error', $response['error'] );
4706
  } elseif ( false !== strpos( ewww_image_optimizer_mimetype( $tempfile, 'i' ), 'image' ) ) {
4707
  $newsize = filesize( $tempfile );
4708
  ewww_image_optimizer_is_animated( $tempfile );
4709
  ewwwio_debug_message( "API resize success: $newsize (new) vs. $orig_size (original)" );
4710
+ ewwwio_delete_file( $tempfile );
4711
  return $response['body'];
4712
  }
4713
+ ewwwio_delete_file( $tempfile );
4714
  ewwwio_debug_message( 'API resize error: unknown' );
4715
  return new WP_Error( 'image_resize_error', __( 'Unknown resize error', 'ewww-image-optimizer' ) );
4716
  }
4774
 
4775
  $prefix = $ewwwdb->set_prefix( $table_prefix );
4776
 
4777
+ // Setup blog_id and prefix for multisite (and fallback).
4778
+ if ( is_wp_error( $prefix ) || is_multisite() ) {
4779
+ global $wpdb;
4780
+ $ewwwdb->prefix = $wpdb->prefix;
4781
+ $ewwwdb->blogid = $wpdb->blogid;
4782
+ // and just in case we need it...
4783
+ $ewwwdb->base_prefix = $wpdb->base_prefix;
 
 
 
4784
  }
4785
+
4786
  if ( ! isset( $ewwwdb->ewwwio_images ) ) {
4787
  $ewwwdb->ewwwio_images = $ewwwdb->prefix . 'ewwwio_images';
4788
  }
4789
+ if ( ! isset( $ewwwdb->ewwwio_queue ) ) {
4790
+ $ewwwdb->ewwwio_queue = $ewwwdb->prefix . 'ewwwio_queue';
4791
+ }
4792
  }
4793
 
4794
  /**
4918
  ewwwio_debug_message( '<b>' . __FUNCTION__ . '()</b>' );
4919
  ewwwio_debug_message( "checking for $file with size: $orig_size" );
4920
  global $ewww_image;
4921
+ global $ewww_force_smart;
4922
  $image = array();
4923
  if ( ! is_object( $ewww_image ) || ! $ewww_image instanceof EWWW_Image || $ewww_image->file !== $file ) {
4924
  $ewww_image = new EWWW_Image( 0, '', $file );
4938
  ewwwio_debug_message( "already optimized: {$image['path']} - $already_optimized" );
4939
  ewwwio_memory( __FUNCTION__ );
4940
  // Make sure the image isn't pending.
4941
+ if ( $image['pending'] && empty( $ewww_force_smart ) ) {
4942
  global $wpdb;
4943
  $wpdb->update(
4944
  $wpdb->ewwwio_images,
4981
  // First check if the image was converted, so we don't orphan records.
4982
  if ( $original && $original !== $attachment ) {
4983
  $already_optimized = ewww_image_optimizer_find_already_optimized( $original );
4984
+ $converted = ewww_image_optimizer_relativize_path( $original );
4985
  } else {
4986
  $already_optimized = ewww_image_optimizer_find_already_optimized( $attachment );
4987
  if ( is_array( $already_optimized ) && ! empty( $already_optimized['converted'] ) ) {
5158
  $output = array();
5159
  // Verify that an authorized user has started the optimizer.
5160
  $permissions = apply_filters( 'ewww_image_optimizer_bulk_permissions', '' );
5161
+ if ( ! $auto && ( empty( $_REQUEST['ewww_wpnonce'] ) || ! wp_verify_nonce( sanitize_key( $_REQUEST['ewww_wpnonce'] ), 'ewww-image-optimizer-bulk' ) || ! current_user_can( $permissions ) ) ) {
5162
  $output['error'] = esc_html__( 'Access token has expired, please reload the page.', 'ewww-image-optimizer' );
5163
+ wp_die( wp_json_encode( $output ) );
5164
  }
5165
  session_write_close();
5166
  if ( ! empty( $_REQUEST['ewww_wpnonce'] ) ) {
5167
  // Find out if our nonce is on it's last leg/tick.
5168
+ $tick = wp_verify_nonce( sanitize_key( $_REQUEST['ewww_wpnonce'] ), 'ewww-image-optimizer-bulk' );
5169
  if ( 2 === $tick ) {
5170
  ewwwio_debug_message( 'nonce on its last leg' );
5171
  $output['new_nonce'] = wp_create_nonce( 'ewww-image-optimizer-bulk' );
5213
  if ( ! empty( $ewww_status ) && preg_match( '/exceeded/', $ewww_status ) ) {
5214
  if ( ! $auto ) {
5215
  $output['error'] = esc_html__( 'License Exceeded', 'ewww-image-optimizer' );
5216
+ echo wp_json_encode( $output );
5217
  }
5218
  if ( $cli ) {
5219
  WP_CLI::error( __( 'License Exceeded', 'ewww-image-optimizer' ) );
5242
  $next_file = ewww_image_optimizer_absolutize_path( $wpdb->get_var( "SELECT path FROM $wpdb->ewwwio_images WHERE pending=1 LIMIT 1" ) );
5243
  if ( ! empty( $next_file ) ) {
5244
  $loading_image = plugins_url( '/images/wpspin.gif', __FILE__ );
5245
+ $output['next_file'] = '<p>' . esc_html__( 'Optimizing', 'ewww-image-optimizer' ) . ' <b>' . esc_html( $next_file ) . "</b>&nbsp;<img src='$loading_image' alt='loading' /></p>";
5246
  }
5247
+ echo wp_json_encode( $output );
5248
  ewwwio_memory( __FUNCTION__ );
5249
  wp_die();
5250
  }
5256
  }
5257
 
5258
  /**
5259
+ * Look for the retina version of a file.
 
 
5260
  *
5261
+ * @param string $orig_path Filename of the image.
 
5262
  * @param bool $validate_file True verifies the file exists.
5263
+ * @return string The retina/hidpi file, or nothing.
5264
  */
5265
+ function ewww_image_optimizer_get_hidpi_path( $orig_path, $validate_file = true ) {
 
5266
  $hidpi_suffix = apply_filters( 'ewww_image_optimizer_hidpi_suffix', '@2x' );
5267
  $pathinfo = pathinfo( $orig_path );
5268
  if ( empty( $pathinfo['dirname'] ) || empty( $pathinfo['filename'] ) || empty( $pathinfo['extension'] ) ) {
5269
+ return '';
5270
  }
5271
  $hidpi_path = $pathinfo['dirname'] . '/' . $pathinfo['filename'] . $hidpi_suffix . '.' . $pathinfo['extension'];
5272
  if ( $validate_file && ! ewwwio_is_file( $hidpi_path ) ) {
5273
+ return '';
5274
  }
5275
+ ewwwio_debug_message( "found retina at $hidpi_path" );
5276
+ return $hidpi_path;
5277
+ }
5278
+
5279
+ /**
5280
+ * Looks for a retina version of the original file so that we can optimize that too.
5281
+ *
5282
+ * @global object $ewww_image Contains more information about the image currently being processed.
5283
+ *
5284
+ * @param string $orig_path Filename of the 'normal' image.
5285
+ * @return string The filename of the retina image.
5286
+ */
5287
+ function ewww_image_optimizer_hidpi_optimize( $orig_path ) {
5288
+ ewwwio_debug_message( '<b>' . __FUNCTION__ . '()</b>' );
5289
+ $hidpi_path = ewww_image_optimizer_get_hidpi_path( $orig_path );
5290
+ if ( ! $hidpi_path ) {
5291
+ return;
5292
  }
5293
  global $ewww_image;
5294
  if ( is_object( $ewww_image ) && $ewww_image instanceof EWWW_Image ) {
5522
  wp_mkdir_p( dirname( $filename ) );
5523
  }
5524
  if ( ! ewwwio_is_file( $filename ) ) {
5525
+ ewwwio_rename( $temp_file, $filename );
5526
  } else {
5527
  unlink( $temp_file );
5528
  }
5556
  }
5557
  // If this is a unique size.
5558
  if ( ! $dup_size ) {
5559
+ $resize_path = $base_dir . wp_basename( $data['file'] );
5560
  $resize_url = $data['gs_link'];
5561
  if ( ewwwio_is_file( $resize_path ) ) {
5562
  continue;
5567
  if ( ! is_dir( dirname( $resize_path ) ) ) {
5568
  wp_mkdir_p( dirname( $resize_path ) );
5569
  }
5570
+ ewwwio_rename( $temp_file, $resize_path );
5571
  }
5572
  }
5573
  // Store info on the sizes we've processed, so we can check the list for duplicate sizes.
5591
  wp_mkdir_p( dirname( $filename ) );
5592
  }
5593
  if ( ! ewwwio_is_file( $filename ) ) {
5594
+ ewwwio_rename( $temp_file, $filename );
5595
  } else {
5596
  unlink( $temp_file );
5597
  }
5611
  if ( ! is_dir( $base_dir ) ) {
5612
  wp_mkdir_p( $base_dir );
5613
  }
5614
+ ewwwio_rename( $temp_file, $resize_path );
5615
  }
5616
  }
5617
  }
5654
  if ( ! is_dir( dirname( $resize_path ) ) ) {
5655
  wp_mkdir_p( dirname( $resize_path ) );
5656
  }
5657
+ ewwwio_rename( $temp_file, $resize_path );
5658
  }
5659
  }
5660
  // Store info on the sizes we've processed, so we can check the list for duplicate sizes.
5675
  wp_mkdir_p( dirname( $filename ) );
5676
  }
5677
  if ( ! ewwwio_is_file( $filename ) ) {
5678
+ ewwwio_rename( $temp_file, $filename );
5679
  } else {
5680
  unlink( $temp_file );
5681
  }
5695
  if ( ! is_dir( $base_dir ) ) {
5696
  wp_mkdir_p( $base_dir );
5697
  }
5698
+ ewwwio_rename( $temp_file, $resize_path );
5699
  }
5700
  }
5701
  }
5738
  if ( ! is_dir( dirname( $resize_path ) ) ) {
5739
  wp_mkdir_p( dirname( $resize_path ) );
5740
  }
5741
+ ewwwio_rename( $temp_file, $resize_path );
5742
  }
5743
  }
5744
  // Store info on the sizes we've processed, so we can check the list for duplicate sizes.
6083
  function ewww_image_optimizer_resize_upload( $file ) {
6084
  // Parts adapted from Imsanity (THANKS Jason!).
6085
  ewwwio_debug_message( '<b>' . __FUNCTION__ . '()</b>' );
6086
+ global $ewww_webp_only;
6087
  if ( ! $file ) {
6088
  return false;
6089
  }
6090
+ if ( ! empty( $ewww_webp_only ) ) {
6091
  return false;
6092
  }
6093
  if ( function_exists( 'wp_raise_memory_limit' ) ) {
6094
  wp_raise_memory_limit( 'image' );
6095
  }
6096
+ if (
6097
+ ! empty( $_REQUEST['post_id'] ) || // phpcs:ignore WordPress.Security.NonceVerification
6098
+ ( ! empty( $_REQUEST['action'] ) && 'upload-attachment' === $_REQUEST['action'] ) || // phpcs:ignore WordPress.Security.NonceVerification
6099
+ strpos( wp_get_referer(), 'media-new.php' )
6100
+ ) {
6101
  ewwwio_debug_message( 'resizing image from media library or attached to post' );
6102
  $maxwidth = ewww_image_optimizer_get_option( 'ewww_image_optimizer_maxmediawidth' );
6103
  $maxheight = ewww_image_optimizer_get_option( 'ewww_image_optimizer_maxmediaheight' );
6104
+ } elseif ( strpos( wp_get_referer(), '/post.php' ) ) {
6105
  ewwwio_debug_message( 'resizing image from the post/page editor' );
6106
  $maxwidth = ewww_image_optimizer_get_option( 'ewww_image_optimizer_maxmediawidth' );
6107
  $maxheight = ewww_image_optimizer_get_option( 'ewww_image_optimizer_maxmediaheight' );
6115
  $maxheight = ewww_image_optimizer_get_option( 'ewww_image_optimizer_maxmediaheight' );
6116
  }
6117
  }
6118
+ if ( wp_get_referer() ) {
6119
+ ewwwio_debug_message( 'uploaded from: ' . wp_get_referer() );
6120
  }
6121
 
6122
  /**
6270
  ewww_image_optimizer_cloud_backup( $file );
6271
  $new_type = (string) ewww_image_optimizer_mimetype( $new_file, 'i' );
6272
  if ( $type === $new_type ) {
6273
+ ewwwio_rename( $new_file, $file );
6274
  } else {
6275
  ewwwio_debug_message( "resizing did not create a valid image: $new_type" );
6276
  unlink( $new_file );
6340
  */
6341
  function ewww_image_optimizer_get_orientation( $file, $type ) {
6342
  ewwwio_debug_message( '<b>' . __FUNCTION__ . '()</b>' );
6343
+ if ( function_exists( 'exif_read_data' ) && 'image/jpeg' === $type && ewwwio_is_readable( $file ) ) {
6344
  $exif = @exif_read_data( $file );
6345
  if ( ewww_image_optimizer_function_exists( 'print_r' ) ) {
6346
  ewwwio_debug_message( print_r( $exif, true ) );
6423
  */
6424
  function ewww_image_optimizer_attachment_check_variant_level( $id, $type, $meta ) {
6425
  ewwwio_debug_message( '<b>' . __FUNCTION__ . '()</b>' );
6426
+ global $ewww_force;
6427
+ if ( empty( $ewww_force ) ) {
6428
  return $meta;
6429
  }
6430
  if ( ! ewww_image_optimizer_get_option( 'ewww_image_optimizer_cloud_key' ) || ! ewww_image_optimizer_get_option( 'ewww_image_optimizer_backup_files' ) ) {
6604
  if ( empty( $id ) ) {
6605
  return true;
6606
  }
6607
+ global $ewww_convert;
6608
+ if ( ! empty( $ewww_convert ) ) {
6609
  return false;
6610
  }
6611
  if ( empty( $type ) ) {
6697
  }
6698
  global $ewww_new_image;
6699
  global $ewww_image;
6700
+ global $ewww_force;
6701
+ global $eio_filesystem;
6702
+ ewwwio_get_filesystem();
6703
  $gallery_type = 1;
6704
  ewwwio_debug_message( "attachment id: $id" );
6705
 
6847
  }
6848
  $ewww_image->file = $file;
6849
  $ewww_image->converted = $original;
6850
+ $meta['file'] = _wp_relative_upload_path( $file );
6851
  $ewww_image->update_converted_attachment( $meta );
6852
  $meta = $ewww_image->convert_sizes( $meta );
6853
  ewwwio_debug_message( 'image was converted' );
6858
  }
6859
 
6860
  // See if we are forcing re-optimization per the user's request.
6861
+ if ( ! empty( $ewww_force ) ) {
6862
  $force = true;
6863
  } else {
6864
  $force = false;
7060
  ewwwio_debug_message( "queueing size $size - $filename" );
7061
  $processing_sizes[ $size ] = $filename;
7062
  unset( $parallel_sizes[ $size ] );
7063
+ $eio_filesystem->touch( $filename . '.processing' );
7064
  ewwwio_debug_message( "sending off $filename via parallel/async" );
7065
  $ewwwio_async_optimize_media->data(
7066
  array(
7280
  ewwwio_debug_message( "added $path.webp to as3cf queue" );
7281
  } elseif (
7282
  // WOM(pro) is downloading from bucket to server, WebP is enabled, and the local/server file does not exist.
7283
+ ! empty( $_REQUEST['action'] ) && // phpcs:ignore WordPress.Security.NonceVerification
7284
+ 'download' === $_REQUEST['action'] && // phpcs:ignore WordPress.Security.NonceVerification
7285
  ewww_image_optimizer_get_option( 'ewww_image_optimizer_webp' ) &&
7286
  is_string( $path ) &&
7287
  ! ewwwio_is_file( $path )
7710
  if ( false !== strpos( $filename, '../' ) ) {
7711
  return false;
7712
  }
7713
+ global $eio_filesystem;
7714
+ ewwwio_get_filesystem();
7715
+ $file_contents = $eio_filesystem->get_contents( $filename );
7716
  // Determine what color type is stored in the file.
7717
+ $color_type = ord( substr( $file_contents, 25, 1 ) );
7718
  ewwwio_debug_message( "color type: $color_type" );
7719
+ // If we do not have GD and the PNG color type is RGB alpha or Grayscale alpha.
7720
+ if ( ! ewww_image_optimizer_gd_support() && ( 4 === $color_type || 6 === $color_type ) ) {
7721
  ewwwio_debug_message( 'transparency found' );
7722
  return true;
7723
+ } elseif ( ewww_image_optimizer_gd_support() ) {
7724
  $image = imagecreatefrompng( $filename );
7725
  if ( imagecolortransparent( $image ) >= 0 ) {
7726
  ewwwio_debug_message( 'transparency found' );
7829
  * @param string $column_name The name of the column being displayed.
7830
  * @param int $id The attachment ID number.
7831
  * @param array $meta Optional. The attachment metadata. Default null.
7832
+ * @return string The data that would normally be output directly by the custom_column function.
7833
+ */
7834
+ function ewww_image_optimizer_custom_column_capture( $column_name, $id, $meta = null ) {
7835
+ ob_start();
7836
+ ewww_image_optimizer_custom_column( $column_name, $id, $meta );
7837
+ return ob_get_clean();
7838
+ }
7839
+
7840
+ /**
7841
+ * Print column data for optimizer results in the media library.
7842
+ *
7843
+ * @global object $wpdb
7844
+ *
7845
+ * @param string $column_name The name of the column being displayed.
7846
+ * @param int $id The attachment ID number.
7847
+ * @param array $meta Optional. The attachment metadata. Default null.
7848
  */
7849
+ function ewww_image_optimizer_custom_column( $column_name, $id, $meta = null ) {
7850
  ewwwio_debug_message( '<b>' . __FUNCTION__ . '()</b>' );
7851
  // Once we get to the EWWW IO custom column.
7852
  if ( 'ewww-image-optimizer' === $column_name ) {
7853
+ $id = (int) $id;
 
7854
  if ( is_null( $meta ) ) {
7855
  // Retrieve the metadata.
7856
  $meta = wp_get_attachment_metadata( $id );
7857
  }
7858
+ echo '<div id="ewww-media-status-' . (int) $id . '">';
7859
+ if ( ewww_image_optimizer_get_option( 'ewww_image_optimizer_debug' ) && ewww_image_optimizer_function_exists( 'print_r' ) ) {
7860
+ $print_meta = print_r( $meta, true );
7861
  $print_meta = preg_replace( array( '/ /', '/\n+/' ), array( '&nbsp;', '<br />' ), $print_meta );
7862
+ $debug_button = __( 'Show Metadata', 'ewww-image-optimizer' );
7863
+ echo "<button type='button' class='ewww-show-debug-meta button button-secondary' data-id='" . (int) $id . "'>" . esc_html( $debug_button ) . "</button><div id='ewww-debug-meta-" . (int) $id . "' style='font-size: 10px;padding: 10px;margin:3px -10px 10px;line-height: 1.1em;display: none;'>" . wp_kses_post( $print_meta ) . '</div>';
7864
  }
 
7865
  $ewww_cdn = false;
7866
  if ( is_array( $meta ) && ! empty( $meta['file'] ) && false !== strpos( $meta['file'], 'https://images-na.ssl-images-amazon.com' ) ) {
7867
+ echo esc_html__( 'Amazon-hosted image', 'ewww-image-optimizer' ) . '</div>';
 
 
 
 
7868
  return;
7869
  }
7870
  if ( is_array( $meta ) && ! empty( $meta['cloudinary'] ) ) {
7871
+ echo esc_html__( 'Cloudinary image', 'ewww-image-optimizer' ) . '</div>';
 
 
 
 
7872
  return;
7873
  }
7874
  if ( is_array( $meta ) & class_exists( 'WindowsAzureStorageUtil' ) && ! empty( $meta['url'] ) ) {
7875
+ echo '<div>' . esc_html__( 'Azure Storage image', 'ewww-image-optimizer' ) . '</div>';
7876
  $ewww_cdn = true;
7877
  }
7878
  if ( is_array( $meta ) && class_exists( 'Amazon_S3_And_CloudFront' ) && preg_match( '/^(http|s3|gs)\w*:/', get_attached_file( $id ) ) ) {
7879
+ echo '<div>' . esc_html__( 'Offloaded Media', 'ewww-image-optimizer' ) . '</div>';
7880
  $ewww_cdn = true;
7881
  }
7882
  if ( is_array( $meta ) && class_exists( 'S3_Uploads' ) && preg_match( '/^(http|s3|gs)\w*:/', get_attached_file( $id ) ) ) {
7883
+ echo '<div>' . esc_html__( 'Amazon S3 image', 'ewww-image-optimizer' ) . '</div>';
7884
  $ewww_cdn = true;
7885
  }
7886
  if ( is_array( $meta ) & class_exists( 'wpCloud\StatelessMedia\EWWW' ) && ! empty( $meta['gs_link'] ) ) {
7887
+ echo '<div>' . esc_html__( 'WP Stateless image', 'ewww-image-optimizer' ) . '</div>';
7888
  $ewww_cdn = true;
7889
  }
7890
  list( $file_path, $upload_path ) = ewww_image_optimizer_attachment_path( $meta, $id );
7891
  if ( is_array( $meta ) & function_exists( 'ilab_get_image_sizes' ) && ! empty( $meta['s3'] ) && empty( $file_path ) ) {
7892
+ echo esc_html__( 'Media Cloud image', 'ewww-image-optimizer' ) . '</div>';
 
 
 
 
 
7893
  return;
7894
  }
7895
  // If the file does not exist.
7896
  if ( empty( $file_path ) && ! $ewww_cdn ) {
7897
+ echo esc_html__( 'Could not retrieve file path.', 'ewww-image-optimizer' ) . '</div>';
 
 
 
 
 
7898
  return;
7899
  }
7900
  if ( is_array( $meta ) && ( ! empty( $meta['ewww_image_optimizer'] ) || ! empty( $meta['converted'] ) ) ) {
7923
  if ( ! $skip['jpegtran'] && defined( 'EWWW_IMAGE_OPTIMIZER_JPEGTRAN' ) && ! EWWW_IMAGE_OPTIMIZER_JPEGTRAN ) {
7924
  $msg = '<div>' . sprintf(
7925
  /* translators: %s: name of a tool like jpegtran */
7926
+ __( '%s is missing', 'ewww-image-optimizer' ),
7927
  '<em>jpegtran</em>'
7928
  ) . '</div>';
7929
  } elseif ( ! ewww_image_optimizer_get_option( 'ewww_image_optimizer_jpg_level' ) ) {
7930
  $msg = '<div>' . sprintf(
7931
  /* translators: %s: JPG, PNG, GIF, or PDF */
7932
+ __( '%s compression disabled', 'ewww-image-optimizer' ),
7933
  'JPG'
7934
  ) . '</div>';
7935
  } else {
7936
+ $convert_link = __( 'JPG to PNG', 'ewww-image-optimizer' );
7937
+ $convert_desc = __( 'WARNING: Removes metadata. Requires GD or ImageMagick. PNG is generally much better than JPG for logos and other images with a limited range of colors.', 'ewww-image-optimizer' );
7938
  }
7939
  break;
7940
  case 'image/png':
7942
  if ( ! $skip['optipng'] && ! $skip['pngout'] && ! EWWW_IMAGE_OPTIMIZER_PNGOUT && ! EWWW_IMAGE_OPTIMIZER_OPTIPNG ) {
7943
  $msg = '<div>' . sprintf(
7944
  /* translators: %s: name of a tool like jpegtran */
7945
+ __( '%s is missing', 'ewww-image-optimizer' ),
7946
  '<em>optipng</em>'
7947
  ) . '</div>';
7948
  } else {
7949
+ $convert_link = __( 'PNG to JPG', 'ewww-image-optimizer' );
7950
+ $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' );
7951
  }
7952
  break;
7953
  case 'image/gif':
7955
  if ( ! $skip['gifsicle'] && ! EWWW_IMAGE_OPTIMIZER_GIFSICLE ) {
7956
  $msg = '<div>' . sprintf(
7957
  /* translators: %s: name of a tool like jpegtran */
7958
+ __( '%s is missing', 'ewww-image-optimizer' ),
7959
  '<em>gifsicle</em>'
7960
  ) . '</div>';
7961
  } else {
7962
+ $convert_link = __( 'GIF to PNG', 'ewww-image-optimizer' );
7963
+ $convert_desc = __( 'PNG is generally better than GIF, but does not support animation. Animated images will not be converted.', 'ewww-image-optimizer' );
7964
  }
7965
  break;
7966
  case 'application/pdf':
7977
  default:
7978
  // Not a supported mimetype.
7979
  $msg = '<div>' . esc_html__( 'Unsupported file type', 'ewww-image-optimizer' ) . '</div>';
 
7980
  } // End switch().
7981
  $compression_level = ewww_image_optimizer_get_level( $type );
7982
  if ( ! empty( $msg ) ) {
7983
+ echo wp_kses_post( $msg ) . '</div>';
 
 
 
7984
  return;
7985
  }
7986
  $ewww_manual_nonce = wp_create_nonce( 'ewww-manual' );
7994
  // 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.
7995
  if ( $ewww_cdn ) {
7996
  if ( ewww_image_optimizer_image_is_pending( $id, 'media-async' ) ) {
7997
+ echo '<div>' . esc_html__( 'In Progress', 'ewww-image-optimizer' ) . '</div>';
7998
  $in_progress = true;
7999
  }
8000
  if ( ! $in_progress ) {
8010
  // If optimizer data exists in the db.
8011
  if ( ! empty( $optimized_images ) ) {
8012
  list( $detail_output, $converted, $backup_available ) = ewww_image_optimizer_custom_column_results( $id, $optimized_images );
8013
+ echo wp_kses_post( $detail_output );
8014
  // Output the optimizer actions.
8015
  if ( current_user_can( apply_filters( 'ewww_image_optimizer_manual_permissions', '' ) ) ) {
8016
  // Display a link to re-optimize manually.
8017
+ echo '<div>' . sprintf(
8018
+ '<a class="ewww-manual-optimize" data-id="%1$d" data-nonce="%2$s" href="%3$s">%4$s</a>',
8019
+ (int) $id,
8020
+ esc_attr( $ewww_manual_nonce ),
8021
+ 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" ) ),
8022
  ( ewww_image_optimizer_restore_possible( $optimized_images, $compression_level ) ? esc_html__( 'Restore & Re-optimize', 'ewww-image-optimizer' ) : esc_html__( 'Re-optimize', 'ewww-image-optimizer' ) )
8023
  ) .
8024
+ wp_kses_post( ewww_image_optimizer_variant_level_notice( $optimized_images, $compression_level ) ) .
8025
  '</div>';
8026
  }
8027
  if ( $backup_available && current_user_can( apply_filters( 'ewww_image_optimizer_manual_permissions', '' ) ) ) {
8028
+ echo '<div>' . sprintf(
8029
+ '<a class="ewww-manual-cloud-restore" data-id="%1$d" data-nonce="%2$s" href="%3$s">%4$s</a>',
8030
+ (int) $id,
8031
+ esc_attr( $ewww_manual_nonce ),
8032
+ esc_url( admin_url( "admin.php?action=ewww_image_optimizer_manual_cloud_restore&ewww_manual_nonce=$ewww_manual_nonce&ewww_attachment_ID=$id" ) ),
8033
  esc_html__( 'Restore original', 'ewww-image-optimizer' )
8034
  ) . '</div>';
8035
  }
8040
  if ( isset( $meta['original_image'] ) && ewww_image_optimizer_get_option( 'ewww_image_optimizer_include_originals' ) ) {
8041
  $sizes_to_opt++;
8042
  }
8043
+ echo '<div>' . sprintf(
8044
  esc_html(
8045
  /* translators: %d: The number of resize/thumbnail images */
8046
  _n( '%d size to compress', '%d sizes to compress', $sizes_to_opt, 'ewww-image-optimizer' )
8047
  ),
8048
+ (int) $sizes_to_opt
8049
  ) . '</div>';
8050
  }
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) $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_attachment_ID=$id" ) ),
8056
+ esc_html__( 'Optimize now!', 'ewww-image-optimizer' )
8057
+ ) .
8058
+ '</div>';
8059
  }
8060
+ echo '</div>';
8061
  return;
8062
  } // End if().
8063
  // End of output for CDN images.
8064
  if ( ewww_image_optimizer_image_is_pending( $id, 'media-async' ) ) {
8065
+ echo '<div>' . esc_html__( 'In Progress', 'ewww-image-optimizer' ) . '</div>';
8066
  $in_progress = true;
8067
  }
8068
  if ( ! $in_progress ) {
8078
  // If optimizer data exists.
8079
  if ( ! empty( $optimized_images ) ) {
8080
  list( $detail_output, $converted, $backup_available ) = ewww_image_optimizer_custom_column_results( $id, $optimized_images );
8081
+ echo wp_kses_post( $detail_output );
8082
 
8083
  // Link to webp upgrade script.
8084
  $oldwebpfile = preg_replace( '/\.\w+$/', '.webp', $file_path );
8085
  if ( file_exists( $oldwebpfile ) && current_user_can( apply_filters( 'ewww_image_optimizer_admin_permissions', '' ) ) ) {
8086
+ echo "<div><a href='" . esc_url( admin_url( 'options.php?page=ewww-image-optimizer-webp-migrate' ) ) . "'>" . esc_html__( 'Run WebP upgrade', 'ewww-image-optimizer' ) . '</a></div>';
8087
  }
8088
 
8089
  // Determine filepath for webp.
8093
  // Get a human readable filesize.
8094
  $webp_size = ewww_image_optimizer_size_format( $webp_size );
8095
  $webpurl = esc_url( wp_get_attachment_url( $id ) . '.webp' );
8096
+ echo '<div>WebP: <a href="' . esc_url( $webpurl ) . '">' . esc_html( $webp_size ) . '</a></div>';
8097
  }
8098
 
8099
+ if ( current_user_can( apply_filters( 'ewww_image_optimizer_manual_permissions', '' ) ) ) {
8100
  // Output a link to re-optimize manually.
8101
+ echo '<div>' . sprintf(
8102
+ '<a class="ewww-manual-optimize" data-id="%1$d" data-nonce="%2$s" href="%3$s">%4$s</a>',
8103
+ (int) $id,
8104
+ esc_attr( $ewww_manual_nonce ),
8105
+ 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" ) ),
8106
  ( ewww_image_optimizer_restore_possible( $optimized_images, $compression_level ) ? esc_html__( 'Restore & Re-optimize', 'ewww-image-optimizer' ) : esc_html__( 'Re-optimize', 'ewww-image-optimizer' ) )
8107
  );
8108
+ echo wp_kses_post( ewww_image_optimizer_variant_level_notice( $optimized_images, $compression_level ) );
8109
  if ( ! ewww_image_optimizer_get_option( 'ewww_image_optimizer_disable_convert_links' ) && 'ims_image' !== get_post_type( $id ) && ! empty( $convert_desc ) ) {
8110
+ printf(
8111
+ ' | <a class="ewww-manual-convert" data-id="%1$d" data-nonce="%2$s" title="%3$s" href="%4$s">%5$s</a>',
8112
+ (int) $id,
8113
+ esc_attr( $ewww_manual_nonce ),
8114
+ esc_attr( $convert_desc ),
8115
+ 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" ) ),
8116
+ esc_html( $convert_link )
8117
+ );
8118
  }
8119
+ echo '</div>';
 
 
8120
  }
8121
  $restorable = false;
8122
  if ( $converted && ewwwio_is_file( $converted ) ) {
8123
  $restorable = true;
8124
  }
8125
  if ( $restorable && current_user_can( apply_filters( 'ewww_image_optimizer_manual_permissions', '' ) ) ) {
8126
+ echo '<div>' . sprintf(
8127
+ '<a class="ewww-manual-restore" data-id="%1$d" data-nonce="%2$s" href="%3$s">%4$s</a>',
8128
+ (int) $id,
8129
+ esc_attr( $ewww_manual_nonce ),
8130
+ esc_url( admin_url( "admin.php?action=ewww_image_optimizer_manual_restore&ewww_manual_nonce=$ewww_manual_nonce&ewww_attachment_ID=$id" ) ),
8131
  esc_html__( 'Restore original', 'ewww-image-optimizer' )
8132
  ) . '</div>';
8133
  } elseif ( $backup_available && current_user_can( apply_filters( 'ewww_image_optimizer_manual_permissions', '' ) ) ) {
8134
+ echo '<div>' . sprintf(
8135
+ '<a class="ewww-manual-cloud-restore" data-id="%1$d" data-nonce="%2$s" href="%3$s">%4$s</a>',
8136
+ (int) $id,
8137
+ esc_attr( $ewww_manual_nonce ),
8138
+ esc_url( admin_url( "admin.php?action=ewww_image_optimizer_manual_cloud_restore&ewww_manual_nonce=$ewww_manual_nonce&ewww_attachment_ID=$id" ) ),
8139
  esc_html__( 'Restore original', 'ewww-image-optimizer' )
8140
  ) . '</div>';
8141
  }
8146
  if ( isset( $meta['original_image'] ) && ewww_image_optimizer_get_option( 'ewww_image_optimizer_include_originals' ) ) {
8147
  $sizes_to_opt++;
8148
  }
8149
+ echo '<div>' . sprintf(
8150
  esc_html(
8151
  /* translators: %d: The number of resize/thumbnail images */
8152
  _n( '%d size to compress', '%d sizes to compress', $sizes_to_opt, 'ewww-image-optimizer' )
8153
  ),
8154
+ (int) $sizes_to_opt
8155
  ) . '</div>';
8156
  } else {
8157
+ echo '<div>' . esc_html__( 'Not optimized', 'ewww-image-optimizer' ) . '</div>';
8158
  }
8159
  // Tell them the filesize.
8160
+ echo '<div>' . sprintf(
8161
  /* translators: %s: size of the image */
8162
  esc_html__( 'Image Size: %s', 'ewww-image-optimizer' ),
8163
+ esc_html( $file_size )
8164
  ) . '</div>';
8165
  // Determine filepath for webp.
8166
  $webpfile = $file_path . '.webp';
8169
  // Get a human readable filesize.
8170
  $webp_size = ewww_image_optimizer_size_format( $webp_size );
8171
  $webpurl = esc_url( wp_get_attachment_url( $id ) . '.webp' );
8172
+ echo '<div>WebP: <a href="' . esc_url( $webpurl ) . '">' . esc_html( $webp_size ) . '</a></div>';
8173
  }
8174
+ if ( current_user_can( apply_filters( 'ewww_image_optimizer_manual_permissions', '' ) ) ) {
8175
  // Give the user the option to optimize the image right now.
8176
+ printf(
8177
+ '<div><a class="ewww-manual-optimize" data-id="%1$d" data-nonce="%2$s" href="%3$s">%4$s</a>',
8178
+ (int) $id,
8179
+ esc_attr( $ewww_manual_nonce ),
8180
+ esc_url( admin_url( "admin.php?action=ewww_image_optimizer_manual_optimize&ewww_manual_nonce=$ewww_manual_nonce&ewww_attachment_ID=$id" ) ),
8181
+ esc_html__( 'Optimize now!', 'ewww-image-optimizer' )
8182
+ );
8183
  if ( ! ewww_image_optimizer_get_option( 'ewww_image_optimizer_disable_convert_links' ) && 'ims_image' !== get_post_type( $id ) && ! empty( $convert_desc ) ) {
8184
+ printf(
8185
+ ' | <a class="ewww-manual-convert" data-id="%1$d" data-nonce="%2$s" title="%3$s" href="%4$s">%5$s</a>',
8186
+ (int) $id,
8187
+ esc_attr( $ewww_manual_nonce ),
8188
+ esc_attr( $convert_desc ),
8189
+ 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" ) ),
8190
+ esc_html( $convert_link )
8191
+ );
8192
  }
8193
+ echo '</div>';
 
 
8194
  }
8195
  } // End if().
8196
+ echo '</div>';
 
 
 
 
 
8197
  } // End if().
8198
  ewwwio_memory( __FUNCTION__ );
8199
  ewww_image_optimizer_debug_log();
8238
  foreach ( $optimized_images as $optimized_image ) {
8239
  if ( 'full' === $optimized_image['resize'] ) {
8240
  if ( is_numeric( $optimized_image['level'] ) && (int) $compression_level > (int) $optimized_image['level'] ) {
8241
+ return ' <span title="' . esc_attr__( 'Compressed at a lower level than current setting.' ) . '" class="ewww-variant-icon"><sup>!</sup></span>';
8242
  }
8243
  }
8244
  }
8334
  }
8335
  }
8336
  if ( ! empty( $optimized_image['converted'] ) ) {
8337
+ $converted = ewww_image_optimizer_absolutize_path( $optimized_image['converted'] );
8338
  }
8339
  $sizes_to_opt++;
8340
  if ( ! empty( $optimized_image['resize'] ) ) {
8493
  ewwwio_debug_message( "bailing early for migration of $id" );
8494
  return false;
8495
  }
8496
+ $retina_path = ewww_image_optimizer_get_hidpi_path( $file_path, false );
8497
  if ( $retina_path ) {
8498
  ewww_image_optimizer_update_file_from_meta( $retina_path, 'media', $id, 'full-retina' );
8499
  }
8520
  continue;
8521
  }
8522
 
8523
+ $resize_path = $base_dir . wp_basename( $data['file'] );
8524
  $converted = ( is_array( $data ) && ! empty( $data['converted'] ) && ! empty( $data['orig_file'] ) ? trailingslashit( dirname( $resize_path ) ) . basename( $data['orig_file'] ) : false );
8525
  ewww_image_optimizer_update_file_from_meta( $resize_path, 'media', $id, $size, $converted );
8526
  // Search for retina images.
8527
  if ( function_exists( 'wr2x_get_retina' ) ) {
8528
  $retina_path = wr2x_get_retina( $resize_path );
8529
  } else {
8530
+ $retina_path = ewww_image_optimizer_get_hidpi_path( $resize_path, false );
8531
  }
8532
  if ( $retina_path ) {
8533
  ewww_image_optimizer_update_file_from_meta( $retina_path, 'media', $id, $size . '-retina' );
8550
  $custom_sizes_pathinfo = pathinfo( $file_path );
8551
  $custom_size_path = '';
8552
  foreach ( $meta['custom_sizes'] as $dimensions => $custom_size ) {
8553
+ $custom_size_path = $custom_sizes_pathinfo['dirname'] . '/' . wp_basename( $custom_size['file'] );
8554
  ewww_image_optimizer_update_file_from_meta( $custom_size_path, 'media', $id, 'custom-size-' . $dimensions );
8555
  }
8556
  }
8652
  check_admin_referer( 'bulk-media' );
8653
  // Prep the attachment IDs for optimization.
8654
  $ids = implode( ',', array_map( 'intval', $post_ids ) );
8655
+ wp_safe_redirect(
8656
  add_query_arg(
8657
  array(
8658
  'page' => 'ewww-image-optimizer-bulk',
8823
  if ( 'settings_page_ewww-image-optimizer-options' !== $hook ) {
8824
  return;
8825
  }
8826
+ add_thickbox();
8827
  wp_enqueue_script( 'jquery-ui-tooltip' );
8828
  wp_enqueue_script( 'ewwwbulkscript', plugins_url( '/includes/eio.js', __FILE__ ), array( 'jquery' ), EWWW_IMAGE_OPTIMIZER_VERSION );
8829
  wp_enqueue_style( 'jquery-ui-tooltip-custom', plugins_url( '/includes/jquery-ui-1.10.1.custom.css', __FILE__ ), array(), EWWW_IMAGE_OPTIMIZER_VERSION );
8980
  ewwwio_ob_clean();
8981
  ewwwio_debug_message( '<b>' . __FUNCTION__ . '()</b>' );
8982
  // Verify that the user is properly authorized.
8983
+ if ( empty( $_REQUEST['ewww_wpnonce'] ) || ! wp_verify_nonce( sanitize_key( $_REQUEST['ewww_wpnonce'] ), 'ewww-image-optimizer-settings' ) ) {
8984
  wp_die( esc_html__( 'Access denied.', 'ewww-image-optimizer' ) );
8985
  }
8986
  if ( ! current_user_can( apply_filters( 'ewww_image_optimizer_admin_permissions', 'manage_options' ) ) ) {
9004
  ewwwio_ob_clean();
9005
  ewwwio_debug_message( '<b>' . __FUNCTION__ . '()</b>' );
9006
  // Verify that the user is properly authorized.
9007
+ if ( empty( $_REQUEST['ewww_wpnonce'] ) || ! wp_verify_nonce( sanitize_key( $_REQUEST['ewww_wpnonce'] ), 'ewww-image-optimizer-settings' ) ) {
9008
  wp_die( esc_html__( 'Access denied.', 'ewww-image-optimizer' ) );
9009
  }
9010
  if ( ! current_user_can( apply_filters( 'ewww_image_optimizer_admin_permissions', 'manage_options' ) ) ) {
9237
  }
9238
 
9239
  /**
9240
+ * Send our debug information to the log/buffer for the options page (and friends).
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
9241
  */
9242
+ function ewwwio_debug_info() {
 
 
9243
  global $ewwwio_upgrading;
9244
  global $content_width;
 
9245
  ewwwio_debug_version_info();
9246
  ewwwio_debug_message( 'ABSPATH: ' . ABSPATH );
9247
  ewwwio_debug_message( 'WP_CONTENT_DIR: ' . WP_CONTENT_DIR );
9252
  ewwwio_debug_message( 'wp_upload_dir (basedir): ' . $upload_info['basedir'] );
9253
  ewwwio_debug_message( "content_width: $content_width" );
9254
  ewwwio_debug_message( 'registered stream wrappers: ' . implode( ',', stream_get_wrappers() ) );
9255
+ if ( is_multisite() ) {
9256
+ ewwwio_debug_message( 'allowing multisite override: ' . ( get_site_option( 'ewww_image_optimizer_allow_multisite_override' ) ? 'yes' : 'no' ) );
9257
+ }
9258
  if ( ! defined( 'EWWW_IMAGE_OPTIMIZER_NOEXEC' ) ) {
9259
  if ( defined( 'EWWW_IMAGE_OPTIMIZER_CLOUD' ) && EWWW_IMAGE_OPTIMIZER_CLOUD ) {
9260
  ewww_image_optimizer_disable_tools();
9263
  ewww_image_optimizer_notice_utils( 'quiet' );
9264
  }
9265
  }
9266
+ if ( wp_using_ext_object_cache() ) {
9267
+ ewwwio_debug_message( 'using external object cache' );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
9268
  } else {
9269
+ ewwwio_debug_message( 'not external cache' );
9270
  }
9271
+ ewww_image_optimizer_gd_support();
9272
+ ewww_image_optimizer_gmagick_support();
9273
+ ewww_image_optimizer_imagick_support();
9274
+ if ( PHP_OS !== 'WINNT' && ! ewww_image_optimizer_full_cloud() && ! EWWW_IMAGE_OPTIMIZER_NOEXEC ) {
9275
+ ewww_image_optimizer_find_nix_binary( 'nice', 'n' );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
9276
  }
9277
+ ewwwio_debug_message( ewww_image_optimizer_aux_images_table_count() . ' images have been optimized' );
9278
+ if ( ewww_image_optimizer_get_option( 'ewww_image_optimizer_noauto' ) ) {
9279
+ ewwwio_debug_message( 'automatic compression disabled' );
9280
+ } else {
9281
+ ewwwio_debug_message( 'automatic compression enabled' );
9282
+ }
9283
+ ewwwio_debug_message( 'remove metadata: ' . ( ewww_image_optimizer_get_option( 'ewww_image_optimizer_metadata_remove' ) ? 'on' : 'off' ) );
9284
+ ewwwio_debug_message( 'jpg level: ' . ewww_image_optimizer_get_option( 'ewww_image_optimizer_jpg_level' ) );
9285
+ ewwwio_debug_message( 'png level: ' . ewww_image_optimizer_get_option( 'ewww_image_optimizer_png_level' ) );
9286
+ ewwwio_debug_message( 'gif level: ' . ewww_image_optimizer_get_option( 'ewww_image_optimizer_gif_level' ) );
9287
+ ewwwio_debug_message( 'pdf level: ' . ewww_image_optimizer_get_option( 'ewww_image_optimizer_pdf_level' ) );
9288
+ ewwwio_debug_message( 'bulk delay: ' . ewww_image_optimizer_get_option( 'ewww_image_optimizer_delay' ) );
9289
+ ewwwio_debug_message( 'backup mode: ' . ( ewww_image_optimizer_get_option( 'ewww_image_optimizer_backup_files' ) ? 'on' : 'off' ) );
9290
+ ewwwio_debug_message( 'cloudinary upload: ' . ( ewww_image_optimizer_get_option( 'ewww_image_optimizer_enable_cloudinary' ) ? 'on' : 'off' ) );
9291
+ ewwwio_debug_message( 'ExactDN enabled: ' . ( ewww_image_optimizer_get_option( 'ewww_image_optimizer_exactdn' ) ? 'on' : 'off' ) );
9292
+ ewwwio_debug_message( 'ExactDN all the things: ' . ( ewww_image_optimizer_get_option( 'exactdn_all_the_things' ) ? 'on' : 'off' ) );
9293
+ ewwwio_debug_message( 'ExactDN lossy: ' . intval( ewww_image_optimizer_get_option( 'exactdn_lossy' ) ) );
9294
+ ewwwio_debug_message( 'ExactDN resize existing: ' . ( ewww_image_optimizer_get_option( 'exactdn_resize_existing' ) ? 'on' : 'off' ) );
9295
+ ewwwio_debug_message( 'ExactDN attachment queries: ' . ( ewww_image_optimizer_get_option( 'exactdn_prevent_db_queries' ) ? 'off' : 'on' ) );
9296
+ ewwwio_debug_message( 'Easy IO exclusions:' );
9297
+ $eio_exclude_paths = ewww_image_optimizer_get_option( 'exactdn_exclude' ) ? esc_html( implode( "\n", ewww_image_optimizer_get_option( 'exactdn_exclude' ) ) ) : '';
9298
+ ewwwio_debug_message( $eio_exclude_paths );
9299
+ ewwwio_debug_message( 'lazy load: ' . ( ewww_image_optimizer_get_option( 'ewww_image_optimizer_lazy_load' ) ? 'on' : 'off' ) );
9300
+ ewwwio_debug_message( 'LQIP: ' . ( ewww_image_optimizer_get_option( 'ewww_image_optimizer_use_lqip' ) ? 'on' : 'off' ) );
9301
+ ewwwio_debug_message( 'LL exclusions:' );
9302
+ $ll_exclude_paths = ewww_image_optimizer_get_option( 'ewww_image_optimizer_ll_exclude' ) ? esc_html( implode( "\n", ewww_image_optimizer_get_option( 'ewww_image_optimizer_ll_exclude' ) ) ) : '';
9303
+ ewwwio_debug_message( $ll_exclude_paths );
9304
+ if ( ! ewww_image_optimizer_full_cloud() ) {
9305
+ ewwwio_debug_message( 'optipng level: ' . ewww_image_optimizer_get_option( 'ewww_image_optimizer_optipng_level' ) );
9306
+ ewwwio_debug_message( 'pngout disabled: ' . ( ewww_image_optimizer_get_option( 'ewww_image_optimizer_disable_pngout' ) ? 'yes' : 'no' ) );
9307
+ ewwwio_debug_message( 'pngout level: ' . ewww_image_optimizer_get_option( 'ewww_image_optimizer_pngout_level' ) );
9308
+ }
9309
+ ewwwio_debug_message( 'effective quality: ' . ewww_image_optimizer_set_jpg_quality( 82 ) );
9310
+ ewwwio_debug_message( 'parallel optimization: ' . ( ewww_image_optimizer_get_option( 'ewww_image_optimizer_parallel_optimization' ) ? 'on' : 'off' ) );
9311
+ ewwwio_debug_message( 'background optimization: ' . ( ewww_image_optimizer_get_option( 'ewww_image_optimizer_background_optimization' ) ? 'on' : 'off' ) );
9312
+ if ( ! $ewwwio_upgrading && ! ewww_image_optimizer_get_option( 'ewww_image_optimizer_background_optimization' ) ) {
9313
+ $admin_ajax_url = admin_url( 'admin-ajax.php' );
9314
+ if ( strpos( $admin_ajax_url, 'admin-ajax.php' ) ) {
9315
+ ewwwio_debug_message( "admin ajax url: $admin_ajax_url" );
9316
+ $admin_ajax_host = parse_url( $admin_ajax_url, PHP_URL_HOST );
9317
+ ewwwio_debug_message( "admin ajax hostname: $admin_ajax_host" );
9318
+ $resolved = gethostbyname( $admin_ajax_host . '.' );
9319
+ ewwwio_debug_message( "resolved to $resolved" );
9320
+ if ( $resolved === $admin_ajax_host . '.' ) {
9321
+ ewwwio_debug_message( 'DNS lookup failed' );
9322
+ } else {
9323
+ $admin_ajax_url = add_query_arg(
9324
+ array(
9325
+ 'action' => 'wp_ewwwio_test_optimize',
9326
+ 'nonce' => wp_create_nonce( 'wp_ewwwio_test_optimize' ),
9327
+ ),
9328
+ $admin_ajax_url
9329
+ );
9330
+ ewwwio_debug_message( "admin ajax POST url: $admin_ajax_url" );
9331
+ $async_post_args = array(
9332
+ 'body' => array(
9333
+ 'ewwwio_test_verify' => '949c34123cf2a4e4ce2f985135830df4a1b2adc24905f53d2fd3f5df5b16293245',
9334
+ ),
9335
+ 'cookies' => $_COOKIE,
9336
+ 'sslverify' => false,
9337
+ );
9338
+ // Don't lock up other requests while processing.
9339
+ session_write_close();
9340
+ $async_response = wp_remote_post( esc_url_raw( $admin_ajax_url ), $async_post_args );
9341
+ if ( is_wp_error( $async_response ) ) {
9342
+ $error_message = $async_response->get_error_message();
9343
+ ewwwio_debug_message( "async test failed: $error_message" );
9344
+ } elseif ( is_array( $async_response ) && isset( $async_response['body'] ) ) {
9345
+ ewwwio_debug_message( 'async success, possibly (response should be empty): ' . esc_html( substr( $async_response['body'], 0, 100 ) ) );
9346
+ if ( ! empty( $async_response['response']['code'] ) ) {
9347
+ ewwwio_debug_message( 'async response code: ' . $async_response['response']['code'] );
9348
+ }
9349
+ } else {
9350
+ ewwwio_debug_message( 'no async error, but no body either' );
9351
+ }
9352
+ }
9353
+ } else {
9354
+ ewwwio_debug_message( "invalid admin ajax url: $admin_ajax_url" );
9355
+ }
9356
+ }
9357
+ ewwwio_debug_message( 'scheduled optimization: ' . ( ewww_image_optimizer_get_option( 'ewww_image_optimizer_auto' ) ? 'on' : 'off' ) );
9358
+ ewwwio_debug_message( 'include media library: ' . ( ewww_image_optimizer_get_option( 'ewww_image_optimizer_include_media_paths' ) ? 'on' : 'off' ) );
9359
+ ewwwio_debug_message( 'include originals: ' . ( ewww_image_optimizer_get_option( 'ewww_image_optimizer_include_originals' ) ? 'on' : 'off' ) );
9360
+ ewwwio_debug_message( 'folders to optimize:' );
9361
+ $aux_paths = ewww_image_optimizer_get_option( 'ewww_image_optimizer_aux_paths' ) ? esc_html( implode( "\n", ewww_image_optimizer_get_option( 'ewww_image_optimizer_aux_paths' ) ) ) : '';
9362
+ ewwwio_debug_message( $aux_paths );
9363
+ ewwwio_debug_message( 'folders to ignore:' );
9364
+ $exclude_paths = ewww_image_optimizer_get_option( 'ewww_image_optimizer_exclude_paths' ) ? esc_html( implode( "\n", ewww_image_optimizer_get_option( 'ewww_image_optimizer_exclude_paths' ) ) ) : '';
9365
+ ewwwio_debug_message( $exclude_paths );
9366
+ ewwwio_debug_message( 'skip images smaller than: ' . ewww_image_optimizer_get_option( 'ewww_image_optimizer_skip_size' ) . ' bytes' );
9367
+ ewwwio_debug_message( 'skip PNG images larger than: ' . ewww_image_optimizer_get_option( 'ewww_image_optimizer_skip_png_size' ) . ' bytes' );
9368
+ ewwwio_debug_message( 'exclude originals from lossy: ' . ( ewww_image_optimizer_get_option( 'ewww_image_optimizer_lossy_skip_full' ) ? 'on' : 'off' ) );
9369
+ ewwwio_debug_message( 'exclude originals from metadata removal: ' . ( ewww_image_optimizer_get_option( 'ewww_image_optimizer_metadata_skip_full' ) ? 'on' : 'off' ) );
9370
+ ewwwio_debug_message( 'use system binaries: ' . ( ewww_image_optimizer_get_option( 'ewww_image_optimizer_skip_bundle' ) ? 'yes' : 'no' ) );
9371
+ ewwwio_debug_message( 'resize detection: ' . ( ewww_image_optimizer_get_option( 'ewww_image_optimizer_resize_detection' ) ? 'on' : 'off' ) );
9372
+ ewwwio_debug_message( 'max media dimensions: ' . ewww_image_optimizer_get_option( 'ewww_image_optimizer_maxmediawidth' ) . ' x ' . ewww_image_optimizer_get_option( 'ewww_image_optimizer_maxmediaheight' ) );
9373
+ ewwwio_debug_message( 'max other dimensions: ' . ewww_image_optimizer_get_option( 'ewww_image_optimizer_maxotherwidth' ) . ' x ' . ewww_image_optimizer_get_option( 'ewww_image_optimizer_maxotherheight' ) );
9374
+ ewwwio_debug_message( 'resize existing images: ' . ( ewww_image_optimizer_get_option( 'ewww_image_optimizer_resize_existing' ) ? 'on' : 'off' ) );
9375
+ ewwwio_debug_message( 'resize existing (non-media) images: ' . ( ewww_image_optimizer_get_option( 'ewww_image_optimizer_resize_other_existing' ) ? 'on' : 'off' ) );
9376
+ $image_sizes = ewww_image_optimizer_get_image_sizes();
9377
+ ewwwio_debug_message( 'disabled resizes:' );
9378
+ $disabled_sizes = ewww_image_optimizer_get_option( 'ewww_image_optimizer_disable_resizes', false, true );
9379
+ $disabled_sizes_opt = ewww_image_optimizer_get_option( 'ewww_image_optimizer_disable_resizes_opt', false, true );
9380
+ foreach ( $image_sizes as $size => $dimensions ) {
9381
+ if ( empty( $dimensions['width'] ) && empty( $dimensions['height'] ) ) {
9382
+ continue;
9383
+ }
9384
+ ewwwio_debug_message( $size . ': ' . ( ! empty( $disabled_sizes_opt[ $size ] ) ? 'optimization=X ' : 'optimization=+ ' ) . ( ! empty( $disabled_sizes[ $size ] ) ? 'creation=X' : 'creation=+' ) );
9385
+ }
9386
+ ewwwio_debug_message( 'delete originals: ' . ( ewww_image_optimizer_get_option( 'ewww_image_optimizer_delete_originals' ) ? 'on' : 'off' ) );
9387
+ ewwwio_debug_message( 'jpg2png: ' . ( ewww_image_optimizer_get_option( 'ewww_image_optimizer_jpg_to_png' ) ? 'on' : 'off' ) );
9388
+ ewwwio_debug_message( 'png2jpg: ' . ( ewww_image_optimizer_get_option( 'ewww_image_optimizer_png_to_jpg' ) ? 'on' : 'off' ) );
9389
+ ewwwio_debug_message( 'gif2png: ' . ( ewww_image_optimizer_get_option( 'ewww_image_optimizer_gif_to_png' ) ? 'on' : 'off' ) );
9390
+ ewwwio_debug_message( 'png2jpg fill:' );
9391
+ ewww_image_optimizer_jpg_background();
9392
+ ewwwio_debug_message( 'webp conversion: ' . ( ewww_image_optimizer_get_option( 'ewww_image_optimizer_webp' ) ? 'on' : 'off' ) );
9393
+ ewwwio_debug_message( 'alt webp rewriting: ' . ( ewww_image_optimizer_get_option( 'ewww_image_optimizer_webp_for_cdn' ) ? 'on' : 'off' ) );
9394
+ ewwwio_debug_message( 'picture webp rewriting: ' . ( ewww_image_optimizer_get_option( 'ewww_image_optimizer_picture_webp' ) ? 'on' : 'off' ) );
9395
+ ewwwio_debug_message( 'WebP Rewrite exclusions:' );
9396
+ $webp_exclude_paths = ewww_image_optimizer_get_option( 'ewww_image_optimizer_webp_rewrite_exclude' ) ? esc_html( implode( "\n", ewww_image_optimizer_get_option( 'ewww_image_optimizer_webp_rewrite_exclude' ) ) ) : '';
9397
+ ewwwio_debug_message( $webp_exclude_paths );
9398
+ ewwwio_debug_message( 'webp paths:' );
9399
+ $webp_paths = ewww_image_optimizer_get_option( 'ewww_image_optimizer_webp_paths' ) ? esc_html( implode( "\n", ewww_image_optimizer_get_option( 'ewww_image_optimizer_webp_paths' ) ) ) : '';
9400
+ ewwwio_debug_message( $webp_paths );
9401
+ ewwwio_debug_message( 'forced webp: ' . ( ewww_image_optimizer_get_option( 'ewww_image_optimizer_webp_force' ) ? 'on' : 'off' ) );
9402
+ ewwwio_debug_message( 'enable help beacon: ' . ( ewww_image_optimizer_get_option( 'ewww_image_optimizer_enable_help' ) ? 'yes' : 'no' ) );
9403
+ if ( ! empty( $_SERVER['SERVER_ADDR'] ) ) {
9404
+ ewwwio_debug_message( 'origin: ' . sanitize_text_field( wp_unslash( $_SERVER['SERVER_ADDR'] ) ) );
9405
+ }
9406
+ if (
9407
+ ! ewwwio_is_cf_host() &&
9408
+ ewww_image_optimizer_get_option( 'ewww_image_optimizer_webp' ) &&
9409
+ ! ewww_image_optimizer_get_option( 'ewww_image_optimizer_webp_for_cdn' ) &&
9410
+ ! ewww_image_optimizer_get_option( 'ewww_image_optimizer_picture_webp' ) &&
9411
+ ! ewww_image_optimizer_ce_webp_enabled() &&
9412
+ ! ewww_image_optimizer_easy_active()
9413
+ ) {
9414
+ if ( defined( 'PHP_SAPI' ) ) {
9415
+ ewwwio_debug_message( 'PHP module: ' . PHP_SAPI );
9416
+ }
9417
+ if ( ! apache_mod_loaded( 'mod_rewrite' ) ) {
9418
+ ewwwio_debug_message( 'possibly missing mod_rewrite' );
9419
+ }
9420
+ if ( ! apache_mod_loaded( 'mod_headers' ) ) {
9421
+ ewwwio_debug_message( 'possibly missing mod_headers' );
9422
+ }
9423
+ if ( ewww_image_optimizer_test_webp_mime_verify() || ! ewww_image_optimizer_webp_rewrite_verify() ) {
9424
+ ewwwio_debug_message( 'webp .htaccess rewriting enabled' );
9425
+ } else {
9426
+ ewwwio_debug_message( 'webp .htaccess rules not detected' );
9427
+ }
9428
+ }
9429
+ ewwwio_debug_message( 'max_execution_time: ' . ini_get( 'max_execution_time' ) );
9430
+ ewww_image_optimizer_stl_check();
9431
+ ewww_image_optimizer_function_exists( 'sleep', true );
9432
+ ewwwio_check_memory_available();
9433
+ }
9434
+
9435
+
9436
+ /**
9437
+ * Wrapper that displays the EWWW IO options in the multisite network admin.
9438
+ */
9439
+ function ewww_image_optimizer_network_options() {
9440
+ ewwwio_debug_message( '<b>' . __FUNCTION__ . '()</b>' );
9441
+ /* add_filter( 'ewww_image_optimizer_settings', 'ewww_image_optimizer_filter_network_settings_page', 9 ); */
9442
+ ewww_image_optimizer_options( 'network-multisite' );
9443
+ }
9444
+
9445
+ /**
9446
+ * Wrapper that displays the EWWW IO options for multisite mode on a single site.
9447
+ *
9448
+ * By default, the only options displayed are the per-site resizes list, but a network admin can
9449
+ * permit site admins to configure their own blog settings.
9450
+ */
9451
+ function ewww_image_optimizer_network_singlesite_options() {
9452
+ ewwwio_debug_message( '<b>' . __FUNCTION__ . '()</b>' );
9453
+ /* add_filter( 'ewww_image_optimizer_settings', 'ewww_image_optimizer_filter_network_singlesite_settings_page', 9 ); */
9454
+ ewww_image_optimizer_options( 'network-singlesite' );
9455
+ }
9456
+
9457
+ /**
9458
+ * Displays the EWWW IO options along with status information, and debugging information.
9459
+ *
9460
+ * @global string $eio_debug In memory debug log.
9461
+ * @global int $wp_version
9462
+ *
9463
+ * @param string $network Indicates which options should be shown in multisite installations.
9464
+ */
9465
+ function ewww_image_optimizer_options( $network = 'singlesite' ) {
9466
+ ewwwio_debug_message( '<b>' . __FUNCTION__ . '()</b>' );
9467
+ global $ewwwio_temp_debug;
9468
+ global $ewwwio_upgrading;
9469
+ global $eio_debug;
9470
+ global $eio_hs_beacon;
9471
+ global $exactdn;
9472
+ global $eio_alt_webp;
9473
+ $total_savings = 0;
9474
+ if ( false === strpos( $network, 'network-multisite' ) ) {
9475
+ $total_sizes = ewww_image_optimizer_savings();
9476
+ $total_savings = $total_sizes[1] - $total_sizes[0];
9477
+ }
9478
+
9479
+ ewwwio_debug_info();
9480
+ $debug_info = $eio_debug;
9481
+ ewww_image_optimizer_temp_debug_clear();
9482
+
9483
+ if ( empty( $network ) ) {
9484
+ $network = 'singlesite';
9485
+ }
9486
+ if ( 'network-multisite' === $network && get_site_option( 'ewww_image_optimizer_allow_multisite_override' ) ) {
9487
+ $network = 'network-multisite-over';
9488
+ } elseif ( 'network-singlesite' === $network && get_site_option( 'ewww_image_optimizer_allow_multisite_override' ) ) {
9489
+ $network = 'singlesite';
9490
+ }
9491
+ $eio_hs_beacon->admin_notice( $network );
9492
+ ?>
9493
+
9494
+ <script type='text/javascript'>
9495
+ jQuery(document).ready(function($) {$(".fade").fadeTo(5000,1).fadeOut(3000);});
9496
+ </script>
9497
+ <div id='ewww-settings-wrap' class='wrap'>
9498
+ <h1>EWWW Image Optimizer</h1>
9499
+ <?php
9500
+ $compress_score = 0;
9501
+ $resize_score = 0;
9502
+
9503
+ $compress_recommendations = array();
9504
+ $resize_recommendations = array();
9505
+
9506
+ $verify_cloud = '';
9507
+ if ( ewww_image_optimizer_get_option( 'ewww_image_optimizer_cloud_key' ) ) {
9508
+ ewww_image_optimizer_set_option( 'ewww_image_optimizer_cloud_exceeded', 0 );
9509
+ $verify_cloud = ewww_image_optimizer_cloud_verify( false );
9510
+ if ( false !== strpos( $verify_cloud, 'great' ) ) {
9511
+ $compress_score += 30;
9512
+ if ( ewww_image_optimizer_get_option( 'ewww_image_optimizer_jpg_level' ) > 20 ) {
9513
+ $compress_score += 50;
9514
+ } else {
9515
+ $compress_recommendations[] = esc_html__( 'Enable premium compression for JPG images.', 'ewww-image-optimizer' );
9516
+ }
9517
+ if ( ewww_image_optimizer_get_option( 'ewww_image_optimizer_png_level' ) > 20 ) {
9518
+ $compress_score += 20;
9519
+ } else {
9520
+ $compress_recommendations[] = esc_html__( 'Enable premium compression for PNG images.', 'ewww-image-optimizer' );
9521
+ }
9522
+ }
9523
+ $disable_level = false;
9524
  } else {
 
 
9525
  delete_option( 'ewww_image_optimizer_cloud_key_invalid' );
9526
  if ( ! class_exists( 'ExactDN' ) && ! ewww_image_optimizer_get_option( 'ewww_image_optimizer_exactdn' ) ) {
9527
+ $compress_recommendations[] = __( 'Enable premium compression with an API key or Easy IO.', 'ewww-image-optimizer' );
9528
  }
9529
+ $disable_level = true;
9530
  }
9531
  $exactdn_enabled = false;
9532
+ if ( get_option( 'easyio_exactdn' ) ) {
 
 
 
9533
  ewww_image_optimizer_webp_rewrite_verify();
9534
  update_option( 'ewww_image_optimizer_exactdn', false );
9535
  update_option( 'ewww_image_optimizer_lazy_load', false );
9537
  update_option( 'ewww_image_optimizer_picture_webp', false );
9538
  $compress_score += 80;
9539
  $resize_score += 50;
9540
+ } elseif (
9541
+ ( ! class_exists( 'Jetpack_Photon' ) || ! Jetpack::is_module_active( 'photon' ) ) &&
9542
+ class_exists( 'ExactDN' ) &&
9543
+ ewww_image_optimizer_get_option( 'ewww_image_optimizer_exactdn' )
9544
+ ) {
9545
  if ( $exactdn->get_exactdn_domain() && $exactdn->verify_domain( $exactdn->get_exactdn_domain() ) ) {
 
 
 
 
9546
  if ( $compress_score < 50 ) {
9547
  $compress_score = 50;
9548
  }
9550
  if ( ewww_image_optimizer_get_option( 'exactdn_lossy' ) ) {
9551
  $compress_score = 100;
9552
  } elseif ( ewww_image_optimizer_get_option( 'ewww_image_optimizer_jpg_level' ) < 30 ) {
9553
+ $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' );
9554
  }
9555
  $exactdn_enabled = true;
 
 
 
 
 
 
 
9556
  }
 
 
 
 
9557
  } elseif ( ! ewww_image_optimizer_get_option( 'ewww_image_optimizer_exactdn' ) ) {
9558
+ $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' );
 
9559
  delete_option( 'ewww_image_optimizer_exactdn_domain' );
9560
  delete_option( 'ewww_image_optimizer_exactdn_plan_id' );
9561
  delete_option( 'ewww_image_optimizer_exactdn_failures' );
9571
  delete_site_option( 'ewww_image_optimizer_exactdn_validation' );
9572
  delete_site_option( 'ewww_image_optimizer_exactdn_suspended' );
9573
  }
9574
+ $easymode = false;
9575
+ if (
9576
+ $exactdn_enabled &&
9577
+ ! ewww_image_optimizer_get_option( 'ewww_image_optimizer_cloud_key' ) &&
9578
+ ! ewww_image_optimizer_get_option( 'ewww_image_optimizer_local_mode' )
9579
+ ) {
9580
+ $easymode = true;
 
9581
  }
9582
  if (
9583
  ewww_image_optimizer_get_option( 'ewww_image_optimizer_maxmediawidth' ) ||
9589
  } elseif ( defined( 'IMSANITY_VERSION' ) ) {
9590
  $resize_score += 30;
9591
  } else {
9592
+ $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' );
9593
  }
9594
  $jpg_quality = apply_filters( 'jpeg_quality', 82, 'image_resize' );
9595
  if ( $jpg_quality < 90 && $jpg_quality > 50 ) {
9596
  $resize_score += 20;
9597
  } else {
9598
+ $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' );
9599
  }
9600
  $skip = ewww_image_optimizer_skip_tools();
9601
  if ( ! $skip['jpegtran'] && ! EWWW_IMAGE_OPTIMIZER_NOEXEC ) {
9608
  if ( ! empty( $jpegtran_installed ) ) {
9609
  $compress_score += 5;
9610
  } else {
9611
+ $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' );
9612
  }
9613
  }
9614
  if ( ! $skip['optipng'] && ! EWWW_IMAGE_OPTIMIZER_NOEXEC ) {
9621
  if ( ! empty( $optipng_version ) ) {
9622
  $compress_score += 5;
9623
  } else {
9624
+ $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' );
9625
  }
9626
  }
9627
  if ( ! $skip['pngout'] && ! EWWW_IMAGE_OPTIMIZER_NOEXEC ) {
9647
  if ( ! empty( $pngquant_version ) ) {
9648
  $compress_score += 5;
9649
  } else {
9650
+ $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' );
9651
  }
9652
  }
9653
  if ( ! $skip['gifsicle'] && ! EWWW_IMAGE_OPTIMIZER_NOEXEC ) {
9660
  if ( ! empty( $gifsicle_version ) ) {
9661
  $compress_score += 5;
9662
  } else {
9663
+ $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' );
9664
  }
9665
  }
9666
  if ( EWWW_IMAGE_OPTIMIZER_CWEBP && ! $skip['webp'] && ! EWWW_IMAGE_OPTIMIZER_NOEXEC ) {
9673
  if ( ! empty( $webp_version ) ) {
9674
  $compress_score += 5;
9675
  } else {
9676
+ $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' );
9677
  }
9678
  }
9679
+ if ( ewww_image_optimizer_get_option( 'ewww_image_optimizer_metadata_remove' ) ) {
9680
+ $compress_score += 5;
9681
+ } else {
9682
+ $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' );
9683
+ }
9684
+
9685
  // Check that an image library exists for converting resizes. Originals can be done via the API, but resizes are done locally for speed.
9686
  $toolkit_found = false;
9687
  if ( ewww_image_optimizer_gd_support() ) {
9696
  if ( PHP_OS !== 'WINNT' && ! ewww_image_optimizer_full_cloud() && ! EWWW_IMAGE_OPTIMIZER_NOEXEC ) {
9697
  ewww_image_optimizer_find_nix_binary( 'nice', 'n' );
9698
  }
9699
+ $allow_help_html = array(
9700
+ 'a' => array(
9701
+ 'class' => array(),
9702
+ 'href' => array(),
9703
+ 'target' => array(),
9704
+ 'data-beacon-article' => array(),
9705
+ 'data-beacon-articles' => array(),
9706
+ ),
9707
+ 'img' => array(
9708
+ 'title' => array(),
9709
+ 'src' => array(),
9710
+ ),
9711
+ );
9712
+ if ( ! $easymode ) {
9713
+ echo '<p>' . sprintf(
9714
+ /* translators: %s: Bulk Optimize (link) */
9715
+ esc_html__( 'New images uploaded to the Media Library will be optimized automatically. If you have existing images you would like to optimize, you can use the %s tool.', 'ewww-image-optimizer' ),
9716
+ ( 'network-multisite' === esc_attr( $network ) ?
9717
+ esc_html__( 'Media Library', 'ewww-image-optimizer' ) . ' -> ' . esc_html__( 'Bulk Optimize', 'ewww-image-optimizer' ) :
9718
+ '<a href="' . esc_url( admin_url( 'upload.php?page=ewww-image-optimizer-bulk' ) ) . '">' . esc_html__( 'Bulk Optimize', 'ewww-image-optimizer' ) . '</a>'
9719
+ )
9720
+ );
9721
+ ewwwio_help_link( 'https://docs.ewww.io/article/4-getting-started', '5853713bc697912ffd6c0b98' );
9722
+ echo ' ' . ( ! class_exists( 'Amazon_S3_And_CloudFront' ) ?
9723
+ sprintf(
9724
+ /* translators: %s: S3 Image Optimizer (link) */
9725
+ esc_html__( 'Images stored in an Amazon S3 bucket can be optimized using our %s.' ),
9726
+ '<a href="https://ewww.io/downloads/s3-image-optimizer/">' . esc_html__( 'S3 Image Optimizer', 'ewww-image-optimizer' ) . '</a>'
9727
+ ) : '' ) .
9728
+ "</p>\n";
9729
  }
 
9730
 
9731
+ if ( 'network-multisite-over' === $network ) {
9732
+ ob_start();
 
 
9733
  }
 
9734
  // Begin building of status inside section.
 
9735
  $compress_score = min( $compress_score, 100 );
9736
  $resize_score = min( $resize_score, 100 );
9737
 
9738
  $guage_stroke_dasharray = 2 * pi() * 54;
9739
  $compress_stroke_dashoffset = $guage_stroke_dasharray * ( 1 - $compress_score / 100 );
9740
  $resize_stroke_dashoffset = $guage_stroke_dasharray * ( 1 - $resize_score / 100 );
9741
+ ?>
9742
+ <div id='ewww-widgets' class='metabox-holder'>
9743
+ <div class='meta-box-sortables'>
9744
+ <div id='ewww-status' class='postbox'>
9745
+ <h2 class='ewww-hndle'><?php esc_html_e( 'Optimization Status', 'ewww-image-optimizer' ); ?></h2>
9746
+ <div class='inside'>
9747
+ <div class="ewww-row"><ul class="ewww-blocks">
9748
+ <li><div id="ewww-compress" class="ewww-status-detail">
9749
+ <div id="ewww-compress-guage" class="ewww-guage" data-score="<?php echo (int) $compress_score; ?>">
9750
+ <svg width="120" height="120">
9751
+ <circle class="ewww-inactive" r="54" cy="60" cx="60" stroke-width="12" />
9752
+ <circle class="ewww-active" r="54" cy="60" cx="60" stroke-width="12" style="stroke-dasharray: <?php echo esc_attr( $guage_stroke_dasharray ); ?>px; stroke-dashoffset: <?php echo esc_attr( $compress_stroke_dashoffset ); ?>px;" />
9753
+ </svg>
9754
+ <div class="ewww-score"><?php echo (int) $compress_score; ?>%</div>
9755
+ </div><!-- end .ewww-guage -->
9756
+ <div id="ewww-compress-recommend" class="ewww-recommend">
9757
+ <strong><?php echo ( (int) $compress_score < 100 ? esc_html__( 'How do I get to 100%?', 'ewww-image-optimizer' ) : esc_html__( 'You got the perfect score!', 'ewww-image-optimizer' ) ); ?></strong>
9758
+ <?php if ( $compress_score < 100 ) : ?>
9759
+ <ul class="ewww-tooltip">
9760
+ <?php foreach ( $compress_recommendations as $c_recommend ) { ?>
9761
+ <li><?php echo wp_kses( $c_recommend, $allow_help_html ); ?></li>
9762
+ <?php } ?>
9763
+ </ul>
9764
+ <?php endif; ?>
9765
+ </div><!-- end .ewww-recommend -->
9766
+ <p><strong><?php esc_html_e( 'Compress', 'ewww-image-optimizer' ); ?></strong></p>
9767
+ <p><?php esc_html_e( 'Reduce the file size of your images without affecting quality.', 'ewww-image-optimizer' ); ?></p>
9768
+ </div><!-- end .ewww-status-detail --></li>
9769
+ <li><div id="ewww-resize" class="ewww-status-detail">
9770
+ <div id="ewww-resize-guage" class="ewww-guage" data-score="<?php echo (int) $resize_score; ?>">
9771
+ <svg width="120" height="120">
9772
+ <circle class="ewww-inactive" r="54" cy="60" cx="60" stroke-width="12" />
9773
+ <circle class="ewww-active" r="54" cy="60" cx="60" stroke-width="12" style="stroke-dasharray: <?php echo esc_attr( $guage_stroke_dasharray ); ?>px; stroke-dashoffset: <?php echo esc_attr( $resize_stroke_dashoffset ); ?>px;" />
9774
+ </svg>
9775
+ <div class="ewww-score"><?php echo (int) $resize_score; ?>%</div>
9776
+ </div><!-- end .ewww-guage -->
9777
+ <div id="ewww-resize-recommend" class="ewww-recommend">
9778
+ <strong><?php echo ( (int) $resize_score < 100 ? esc_html__( 'How do I get to 100%?', 'ewww-image-optimizer' ) : esc_html__( 'You got the perfect score!', 'ewww-image-optimizer' ) ); ?></strong>
9779
+ <?php if ( $resize_score < 100 ) : ?>
9780
+ <ul class="ewww-tooltip">
9781
+ <?php foreach ( $resize_recommendations as $r_recommend ) { ?>
9782
+ <li><?php echo wp_kses( $r_recommend, $allow_help_html ); ?></li>
9783
+ <?php } ?>
9784
+ </ul>
9785
+ <?php endif; ?>
9786
+ </div><!-- end .ewww-recommend -->
9787
+ <p><strong><?php esc_html_e( 'Resize', 'ewww-image-optimizer' ); ?></strong></p>
9788
+ <p><?php esc_html_e( 'Scale or reduce the dimensions of your images for more savings.', 'ewww-image-optimizer' ); ?></p>
9789
+ </div><!-- end .ewww-status-detail --></li>
9790
+ <?php
9791
  if ( $total_savings > 0 ) {
9792
  $savings_stroke_dashoffset = $guage_stroke_dasharray * ( 1 - $total_savings / $total_sizes[1] );
9793
+ ?>
9794
+ <li><div id="ewww-savings" class="ewww-status-detail">
9795
+ <div id="ewww-savings-guage" class="ewww-guage" data-score="<?php echo esc_attr( $total_savings / $total_sizes[1] ); ?>">
9796
+ <svg width="120" height="120">
9797
+ <title><?php echo esc_html( round( $total_savings / $total_sizes[1], 3 ) * 100 ); ?>%</title>
9798
+ <circle class="ewww-inactive" r="54" cy="60" cx="60" stroke-width="12" />
9799
+ <circle class="ewww-active" r="54" cy="60" cx="60" stroke-width="12" style="stroke-dasharray: <?php echo esc_attr( $guage_stroke_dasharray ); ?>px; stroke-dashoffset: <?php echo esc_attr( $savings_stroke_dashoffset ); ?>px;" />
9800
+ </svg>
9801
+ <div class="ewww-score"><?php echo esc_html( ewww_image_optimizer_size_format( $total_savings, 2 ) ); ?></div>
9802
+ </div><!-- end .ewww-guage -->
9803
+ <p style="text-align:center"><strong><?php esc_html_e( 'Savings', 'ewww-image-optimizer' ); ?></strong></p>
9804
+ <p><a href="<?php echo esc_url( admin_url( 'tools.php?page=ewww-image-optimizer-tools' ) ); ?>"><?php esc_html_e( 'View optimized images.', 'ewww-image-optimizer' ); ?></a></p>
9805
+ </div><!-- end .ewww-status-detail --></li>
9806
+ <?php } ?>
9807
+ <!-- begin notices section -->
9808
+ <li><div class="ewww-status-detail"><div id="ewww-notices">
9809
+ <?php if ( ! ewww_image_optimizer_get_option( 'ewww_image_optimizer_cloud_key' ) && ! ewww_image_optimizer_get_option( 'ewww_image_optimizer_exactdn' ) ) : ?>
9810
+ <h3>
9811
+ <a href='https://ewww.io/plans/' target='_blank' class='ewww-upgrade'><?php esc_html_e( 'Premium Upgrades:', 'ewww-image-optimizer' ); ?></a>
9812
+ </h3>
9813
+ <p><i><?php esc_html_e( 'Priority Support included with any purchase.', 'ewww-image-optimizer' ); ?></i></p>
9814
+ <?php endif; ?>
9815
+ <?php if ( ewww_image_optimizer_get_option( 'ewww_image_optimizer_cloud_key' ) ) : ?>
9816
+ <p><strong><?php esc_html_e( 'Cloud optimization API Key', 'ewww-image-optimizer' ); ?></strong>
9817
+ <?php if ( false !== strpos( $verify_cloud, 'great' ) ) : ?>
9818
+ <span style="color: #3eadc9; font-weight: bolder"><?php esc_html_e( 'Verified,', 'ewww-image-optimizer' ); ?> </span><?php echo esc_html( ewww_image_optimizer_cloud_quota() ); ?>
9819
+ <?php elseif ( false !== strpos( $verify_cloud, 'exceeded' ) ) : ?>
9820
+ <span style="color: orange; font-weight: bolder"><?php esc_html_e( 'Out of credits', 'ewww-image-optimizer' ); ?></span> - <a href="https://ewww.io/buy-credits/" target="_blank"><?php esc_html_e( 'Purchase more', 'ewww-image-optimizer' ); ?></a>
9821
+ <?php else : ?>
9822
+ <span style="color: red; font-weight: bolder"><?php esc_html_e( 'Not Verified', 'ewww-image-optimizer' ); ?></span>
9823
+ <?php endif; ?>
9824
+ <?php if ( false !== strpos( $verify_cloud, 'great' ) ) : ?>
9825
+ <a target="_blank" href="https://history.exactlywww.com/show/?api_key=' . ewww_image_optimizer_get_option( 'ewww_image_optimizer_cloud_key' ) . '"><?php esc_html_e( 'View Usage', 'ewww-image-optimizer' ); ?></a>
9826
+ <?php endif; ?>
9827
+ </p>
9828
+ <?php else : ?>
9829
+ <p>
9830
+ <span style="font-weight:bold;color:#3eadc9;">Compress API:</span>
9831
+ <a href="https://optimize.exactlywww.com/api_key/free-trial.php?TB_iframe=true&width=600&height=375" class="thickbox" target="_blank">
9832
+ <?php if ( $exactdn_enabled || get_option( 'easyio_exactdn' ) ) : ?>
9833
+ <?php esc_html_e( 'Need to save storage space?', 'ewww-image-optimizer' ); ?>
9834
+ <?php else : ?>
9835
+ <?php esc_html_e( 'Unlock premium compression, save storage space, and reduce server load.', 'ewww-image-optimizer' ); ?>
9836
+ <?php endif; ?>
9837
+ </a>
9838
+ </p>
9839
+ <?php endif; ?>
9840
+ <?php if ( class_exists( 'Jetpack_Photon' ) && Jetpack::is_module_active( 'photon' ) && ewww_image_optimizer_get_option( 'ewww_image_optimizer_exactdn' ) ) : ?>
9841
+ <p><b>Easy IO:</b> <span style="color: red"><?php esc_html_e( 'Inactive, please disable the Image Performance option on the Jetpack Dashboard.', 'ewww-image-optimizer' ); ?></span></p>
9842
+ <?php elseif ( ! get_option( 'easyio_exactdn' ) && class_exists( 'ExactDN' ) && ewww_image_optimizer_get_option( 'ewww_image_optimizer_exactdn' ) ) : ?>
9843
+ <p><b>Easy IO:</b>
9844
+ <?php if ( $exactdn->get_exactdn_domain() && $exactdn->verify_domain( $exactdn->get_exactdn_domain() ) ) : ?>
9845
+ <span style="color: #3eadc9; font-weight: bolder"><?php esc_html_e( 'Verified', 'ewww-image-optimizer' ); ?></span>
9846
+ <?php elseif ( $exactdn->get_exactdn_domain() && $exactdn->get_exactdn_option( 'verified' ) ) : ?>
9847
+ <span style="color: orange; font-weight: bolder"><?php esc_html_e( 'Temporarily disabled.', 'ewww-image-optimizer' ); ?></span>
9848
+ <?php elseif ( $exactdn->get_exactdn_domain() && $exactdn->get_exactdn_option( 'suspended' ) ) : ?>
9849
+ <span style="color: orange; font-weight: bolder"><?php esc_html_e( 'Active, not yet verified.', 'ewww-image-optimizer' ); ?></span>';
9850
+ <?php else : ?>
9851
+ <span style="color: red; font-weight: bolder"><a href="https://ewww.io/manage-sites/" target="_blank"><?php esc_html_e( 'Not Verified', 'ewww-image-optimizer' ); ?></a></span>
9852
+ <?php endif; ?>
9853
+ <?php if ( function_exists( 'remove_query_strings_link' ) || function_exists( 'rmqrst_loader_src' ) || function_exists( 'qsr_remove_query_strings_1' ) ) : ?>
9854
+ <br><i><?php esc_html_e( 'Plugins that remove query strings are unnecessary with Easy IO. You may remove them at your convenience.', 'ewww-image-optimizer' ); ?></i><?php ewwwio_help_link( 'https://docs.ewww.io/article/50-exactdn-and-query-strings', '5a3d278a2c7d3a1943677b52' ); ?>
9855
+ <?php endif; ?>
9856
+ </p>
9857
+ <?php elseif ( ! ewww_image_optimizer_get_option( 'ewww_image_optimizer_exactdn' ) && ! get_option( 'easyio_exactdn' ) ) : ?>
9858
+ <p><span style="font-weight:bold;color:#3eadc9;">Easy IO:</span> <a href="https://ewww.io/resize/" target="_blank"><?php esc_html_e( 'Comprehensive image optimization with automatic compression, auto-sizing, WebP conversion, and lazy load.', 'ewww-image-optimizer' ); ?></a></p>
9859
+ <?php endif; ?>
9860
+ <p>
9861
+ <strong><?php esc_html_e( 'Background optimization (faster uploads):', 'ewww-image-optimizer' ); ?></strong><br>
9862
+ <?php if ( defined( 'EWWW_DISABLE_ASYNC' ) && EWWW_DISABLE_ASYNC ) : ?>
9863
+ <span><?php esc_html_e( 'Disabled by administrator', 'ewww-image-optimizer' ); ?></span>
9864
+ <?php elseif ( ! ewww_image_optimizer_function_exists( 'sleep' ) ) : ?>
9865
+ <span style="color: orange; font-weight: bolder"><?php esc_html_e( 'Disabled, sleep function missing', 'ewww-image-optimizer' ); ?></span>
9866
+ <?php elseif ( $ewwwio_upgrading ) : ?>
9867
+ <span><?php esc_html_e( 'Update detected, re-testing', 'ewww-image-optimizer' ); ?></span>
9868
+ <?php elseif ( ! ewww_image_optimizer_get_option( 'ewww_image_optimizer_background_optimization' ) ) : ?>
9869
+ <span style="color: orange; font-weight: bolder">
9870
+ <?php esc_html_e( 'Disabled automatically, async requests blocked', 'ewww-image-optimizer' ); ?>
9871
+ - <a href="<?php echo esc_url( admin_url( 'admin.php?action=ewww_image_optimizer_retest_background_optimization' ) ); ?>">
9872
+ <?php esc_html_e( 'Re-test', 'ewww-image-optimizer' ); ?>
9873
+ </a>
9874
+ </span>
9875
+ <?php ewwwio_help_link( 'https://docs.ewww.io/article/42-background-and-parallel-optimization-disabled', '598cb8be2c7d3a73488be237' ); ?>
9876
+ <?php elseif ( ewww_image_optimizer_detect_wpsf_location_lock() ) : ?>
9877
+ <span style="color: orange; font-weight: bolder"><?php esc_html_e( "Disabled by Shield's Lock to Location feature", 'ewww-image-optimizer' ); ?></span>
9878
+ <?php else : ?>
9879
+ <span><?php esc_html_e( 'Enabled', 'ewww-image-optimizer' ); ?>
9880
+ - <a href="<?php echo esc_url( admin_url( 'admin.php?action=ewww_image_optimizer_retest_background_optimization' ) ); ?>">
9881
+ <?php esc_html_e( 'Re-test', 'ewww-image-optimizer' ); ?>
9882
+ </a>
9883
+ </span>
9884
+ <?php endif; ?>
9885
+ </p>
9886
+ </div></div><!-- end .ewww-status-detail --></li>
9887
+ </ul><!-- end .ewww-blocks --></div><!-- end .ewww-row -->
9888
+ </div><!-- end .inside -->
9889
+ </div>
9890
+ </div>
9891
+ </div>
9892
+
9893
+ <?php
9894
+ if ( 'network-multisite-over' === $network ) {
9895
+ ob_end_clean();
9896
  }
9897
+ ?>
9898
+
9899
+ <?php if ( $exactdn_enabled && ! ewww_image_optimizer_get_option( 'ewww_image_optimizer_cloud_key' ) ) : ?>
9900
+ <script type='text/javascript'>
9901
+ var exactdn_enabled = true;
9902
+ </script>
9903
+ <?php else : ?>
9904
+ <script type='text/javascript'>
9905
+ var exactdn_enabled = false;
9906
+ </script>
9907
+ <?php endif; ?>
9908
+
9909
+ <!-- 'network-multisite-over' and 'network-singlesite' get simpler settings, 'network-singlesite-over' masquerades as 'singlesite' -->
9910
+ <?php if ( ! $easymode && ( 'singlesite' === $network || 'network-multisite' === $network ) ) : ?>
9911
+ <ul class='ewww-tab-nav'>
9912
+ <li class='ewww-tab ewww-general-nav'><span><?php esc_html_e( 'Basic', 'ewww-image-optimizer' ); ?></span></li>
9913
+ <?php if ( ! get_option( 'easyio_exactdn' ) ) : ?>
9914
+ <li class='ewww-tab ewww-exactdn-nav'><span><?php esc_html_e( 'Easy Mode', 'ewww-image-optimizer' ); ?></span></li>
9915
+ <?php endif; ?>
9916
+ <li class='ewww-tab ewww-optimization-nav'><span><?php esc_html_e( 'Advanced', 'ewww-image-optimizer' ); ?></span></li>
9917
+ <li class='ewww-tab ewww-resize-nav'><span><?php esc_html_e( 'Resize', 'ewww-image-optimizer' ); ?></span></li>
9918
+ <li class='ewww-tab ewww-conversion-nav'><span><?php esc_html_e( 'Convert', 'ewww-image-optimizer' ); ?></span></li>
9919
+ <li class='ewww-tab ewww-webp-nav'><span><?php esc_html_e( 'WebP', 'ewww-image-optimizer' ); ?></span></li>
9920
+ <li class='ewww-tab ewww-overrides-nav'><span><a href='https://docs.ewww.io/article/40-override-options' target='_blank'><span class='ewww-tab-hidden'><?php esc_html_e( 'Overrides', 'ewww-image-optimizer' ); ?></a></span></li>
9921
+ <li class='ewww-tab ewww-support-nav'><span><?php esc_html_e( 'Support', 'ewww-image-optimizer' ); ?></span></li>
9922
+ <li class='ewww-tab ewww-contribute-nav'><span><?php esc_html_e( 'Contribute', 'ewww-image-optimizer' ); ?></span></li>
9923
+ </ul>
9924
+ <?php elseif ( $easymode ) : ?>
9925
+ <ul class='ewww-tab-nav'>
9926
+ <li class='ewww-tab ewww-general-nav'><span><?php esc_html_e( 'Basic', 'ewww-image-optimizer' ); ?></span></li>
9927
+ <li class='ewww-tab ewww-exactdn-nav'><span><?php esc_html_e( 'Easy Mode', 'ewww-image-optimizer' ); ?></span></li>
9928
+ <li class='ewww-tab ewww-resize-nav'><span><?php esc_html_e( 'Resize', 'ewww-image-optimizer' ); ?></span></li>
9929
+ <li class='ewww-tab ewww-support-nav'><span><?php esc_html_e( 'Support', 'ewww-image-optimizer' ); ?></span></li>
9930
+ <li class='ewww-tab ewww-contribute-nav'><span><?php esc_html_e( 'Contribute', 'ewww-image-optimizer' ); ?></span></li>
9931
+ </ul>
9932
+ <?php endif; ?>
9933
+ <?php if ( false !== strpos( $network, 'network-multisite' ) ) : ?>
9934
+ <form id='ewww-settings-form' method='post' action=''>
9935
+ <?php else : ?>
9936
+ <form id='ewww-settings-form' method='post' action='options.php'>
9937
+ <?php endif; ?>
9938
+ <input type='hidden' name='option_page' value='ewww_image_optimizer_options' />
9939
+ <input type='hidden' name='action' value='update' />
9940
+ <?php wp_nonce_field( 'ewww_image_optimizer_options-options' ); ?>
9941
+ <?php if ( 'network-singlesite' === $network ) : ?>
9942
+ <i class="network-singlesite"><strong><?php esc_html_e( 'Configure network-wide settings in the Network Admin.', 'ewww-image-optimizer' ); ?></strong></i>
9943
+ <?php ob_start(); ?>
9944
+ <?php endif; ?>
9945
+ <div id='ewww-general-settings'>
9946
+ <noscript><h2><?php esc_html_e( 'Basic', 'ewww-image-optimizer' ); ?></h2></noscript>
9947
+ <?php if ( 'singlesite' === $network && $easymode ) : ?>
9948
+ <p><strong><?php esc_html_e( 'Easy IO is optimizing your site, no more configuration needed!', 'ewww-image-optimizer' ); ?></strong></p>
9949
+ <?php /* translators: %s: Local+Advanced Mode */ ?>
9950
+ <p><?php printf( esc_html__( 'If you need to save storage space, enable %s.', 'ewww-image-optimizer' ), '<a href="' . esc_url( wp_nonce_url( admin_url( 'options-general.php?page=ewww-image-optimizer-options&enable-local=1' ), 'ewww_image_optimizer_options-options' ) ) . '">' . esc_html__( 'Local+Advanced Mode', 'ewww-image-optimizer' ) . '</a>' ); ?></p>
9951
+ <input type='hidden' id='ewww_image_optimizer_metadata_remove' name='ewww_image_optimizer_metadata_remove' value='<?php echo (int) ewww_image_optimizer_get_option( 'ewww_image_optimizer_metadata_remove' ); ?>' />
9952
+ <input type='hidden' id='ewww_image_optimizer_jpg_level' name='ewww_image_optimizer_jpg_level' value='<?php echo (int) ewww_image_optimizer_get_option( 'ewww_image_optimizer_jpg_level' ); ?>'>
9953
+ <input type='hidden' id='ewww_image_optimizer_png_level' name='ewww_image_optimizer_png_level' value='<?php echo (int) ewww_image_optimizer_get_option( 'ewww_image_optimizer_png_level' ); ?>'>
9954
+ <input type='hidden' id='ewww_image_optimizer_gif_level' name='ewww_image_optimizer_gif_level' value='<?php echo (int) ewww_image_optimizer_get_option( 'ewww_image_optimizer_gif_level' ); ?>'>
9955
+ <input type='hidden' id='ewww_image_optimizer_pdf_level' name='ewww_image_optimizer_pdf_level' value='<?php echo (int) ewww_image_optimizer_get_option( 'ewww_image_optimizer_pdf_level' ); ?>'>
9956
+ <?php elseif ( 'singlesite' === $network && ewww_image_optimizer_get_option( 'ewww_image_optimizer_exactdn' ) ) : ?>
9957
+ <p><strong><?php esc_html_e( 'Easy IO is optimizing your site, no more configuration needed!', 'ewww-image-optimizer' ); ?></strong><br>
9958
+ <?php if ( ewww_image_optimizer_get_option( 'ewww_image_optimizer_cloud_key' ) ) : ?>
9959
+ <?php /* translators: %s: Easy Mode */ ?>
9960
+ <?php printf( esc_html__( 'Remove API key and switch to %s.', 'ewww-image-optimizer' ), '<a href="' . esc_url( wp_nonce_url( admin_url( 'options-general.php?page=ewww-image-optimizer-options&enable-local=0' ), 'ewww_image_optimizer_options-options' ) ) . '">' . esc_html__( 'Easy Mode', 'ewww-image-optimizer' ) . '</a>' ); ?></p>
9961
+ <?php else : ?>
9962
+ <?php /* translators: %s: Easy Mode */ ?>
9963
+ <?php printf( esc_html__( 'Switch to %s.', 'ewww-image-optimizer' ), '<a href="' . esc_url( wp_nonce_url( admin_url( 'options-general.php?page=ewww-image-optimizer-options&enable-local=0' ), 'ewww_image_optimizer_options-options' ) ) . '">' . esc_html__( 'Easy Mode', 'ewww-image-optimizer' ) . '</a>' ); ?></p>
9964
+ <?php endif; ?>
9965
+ <?php elseif ( 'singlesite' === $network && get_option( 'easyio_exactdn' ) ) : ?>
9966
+ <p><strong><?php esc_html_e( 'Easy IO is optimizing your site, no more configuration needed!', 'ewww-image-optimizer' ); ?></strong><br>
9967
+ <?php esc_html_e( 'Unless you need to save storage space, you can now disable the EWWW Image Optimizer.', 'ewww-image-optimizer' ); ?></p>
9968
+ <?php endif; ?>
9969
+ <?php ob_start(); ?>
9970
+ <table class='form-table'>
9971
+ <?php if ( 'network-multisite' === $network || 'network-multisite-over' === $network ) : ?>
9972
+ <tr>
9973
+ <th scope='row'>
9974
+ <label for='ewww_image_optimizer_allow_multisite_override'><?php esc_html_e( 'Allow Single-site Override', 'ewww-image-optimizer' ); ?></label>
9975
+ </th>
9976
+ <td>
9977
+ <input type='checkbox' id='ewww_image_optimizer_allow_multisite_override' name='ewww_image_optimizer_allow_multisite_override' value='true' <?php checked( get_site_option( 'ewww_image_optimizer_allow_multisite_override' ) ); ?> /><?php esc_html_e( 'Allow individual sites to configure their own settings and override all network options.', 'ewww-image-optimizer' ); ?>
9978
+ </td>
9979
+ </tr>
9980
+ <?php endif; ?>
9981
+ <?php if ( 'network-multisite-over' === $network ) : ?>
9982
+ <tr>
9983
+ <th scope='row'>
9984
+ <label for='ewww_image_optimizer_allow_tracking'><?php esc_html_e( 'Allow Usage Tracking?', 'ewww-image-optimizer' ); ?></label>
9985
+ </th>
9986
+ <td>
9987
+ <input type='checkbox' id='ewww_image_optimizer_allow_tracking' name='ewww_image_optimizer_allow_tracking' value='true' <?php checked( get_site_option( 'ewww_image_optimizer_allow_tracking' ) ); ?> />
9988
+ <?php esc_html_e( 'Allow EWWW Image Optimizer to anonymously track how this plugin is used and help us make the plugin better. Opt-in to tracking and receive 500 API image credits free. No sensitive data is tracked.', 'ewww-image-optimizer' ); ?>
9989
+ </td>
9990
+ </tr>
9991
+ </table>
9992
+ <input type='hidden' id='ewww_image_optimizer_allow_multisite_override_active' name='ewww_image_optimizer_allow_multisite_override_active' value='0'>
9993
+ <?php if ( get_site_option( 'ewww_image_optimizer_cloud_key' ) ) : ?>
9994
+ <input type='hidden' id='ewww_image_optimizer_cloud_key' name='ewww_image_optimizer_cloud_key' value='<?php echo esc_attr( get_site_option( 'ewww_image_optimizer_cloud_key' ) ); ?>' />
9995
+ <?php endif; ?>
9996
+ </div><!-- end container general settings -->
9997
+ <p class='submit'><input type='submit' class='button-primary' value='<?php esc_attr_e( 'Save Changes', 'ewww-image-optimizer' ); ?>' /></p>
9998
+ </form>
9999
+ </div><!-- end container wrap -->
10000
+ <?php
10001
+ return;
10002
+ endif;
10003
+ ?>
10004
+ <?php if ( ewww_image_optimizer_get_option( 'ewww_image_optimizer_cloud_key' ) ) : ?>
10005
+ <tr>
10006
+ <th scope='row'>
10007
+ <label for='ewww_image_optimizer_cloud_notkey'><?php esc_html_e( 'Optimization API Key', 'ewww-image-optimizer' ); ?></label>
10008
+ </th>
10009
+ <td>
10010
+ <input type='text' id='ewww_image_optimizer_cloud_notkey' name='ewww_image_optimizer_cloud_notkey' readonly='readonly' value='****************************<?php echo esc_attr( substr( ewww_image_optimizer_get_option( 'ewww_image_optimizer_cloud_key' ), 28 ) ); ?>' size='32' />
10011
+ <a href='<?php echo esc_url( admin_url( 'admin.php?action=ewww_image_optimizer_remove_cloud_key' ) ); ?>'>
10012
+ <?php esc_html_e( 'Remove API key', 'ewww-image-optimizer' ); ?>
10013
+ </a>
10014
+ <input type='hidden' id='ewww_image_optimizer_cloud_key' name='ewww_image_optimizer_cloud_key' value='<?php echo esc_attr( ewww_image_optimizer_get_option( 'ewww_image_optimizer_cloud_key' ) ); ?>' />
10015
+ </td>
10016
+ </tr>
10017
+ <?php else : ?>
10018
+ <tr>
10019
+ <th scope='row'>
10020
+ <label for='ewww_image_optimizer_cloud_key'><?php esc_html_e( 'Optimization API Key', 'ewww-image-optimizer' ); ?></label>
10021
+ <?php ewwwio_help_link( 'https://docs.ewww.io/article/7-basic-configuration', '585373d5c697912ffd6c0bb2,5ad0c8e7042863075092650b,5a9efec62c7d3a7549516550' ); ?>
10022
+ </th>
10023
+ <td>
10024
+ <input type='text' id='ewww_image_optimizer_cloud_key' name='ewww_image_optimizer_cloud_key' value='' size='32' />
10025
+ <?php esc_html_e( 'API Key will be validated when you save your settings.', 'ewww-image-optimizer' ); ?>
10026
+ <a href='https://optimize.exactlywww.com/api_key/free-trial.php?TB_iframe=true&width=600&height=375' class='thickbox' target='_blank'>
10027
+ <?php esc_html_e( 'Get a free trial key.', 'ewww-image-optimizer' ); ?>
10028
+ </a>
10029
+ </td>
10030
+ </tr>
10031
+ <?php endif; ?>
10032
+ <tr>
10033
+ <th scope='row'>
10034
+ <label for='ewww_image_optimizer_metadata_remove'><?php esc_html_e( 'Remove Metadata', 'ewww-image-optimizer' ); ?></label>
10035
+ <?php ewwwio_help_link( 'https://docs.ewww.io/article/7-basic-configuration', '585373d5c697912ffd6c0bb2' ); ?>
10036
+ </th>
10037
+ <td>
10038
+ <input type='checkbox' id='ewww_image_optimizer_metadata_remove' name='ewww_image_optimizer_metadata_remove' value='true' <?php checked( ewww_image_optimizer_get_option( 'ewww_image_optimizer_metadata_remove' ) ); ?> />
10039
+ <?php esc_html_e( 'This will remove ALL metadata: EXIF, comments, color profiles, and anything else that is not pixel data.', 'ewww-image-optimizer' ); ?>
10040
+ <p class ='description'><?php esc_html_e( 'Color profiles are preserved when using the API or Easy IO.', 'ewww-image-optimizer' ); ?></p>
10041
+ </td>
10042
+ </tr>
10043
+ <?php $maybe_api_level = ewww_image_optimizer_get_option( 'ewww_image_optimizer_cloud_key' ) ? '*' : ''; ?>
10044
+ <tr>
10045
+ <th scope='row'>
10046
+ <label for='ewww_image_optimizer_jpg_level'><?php esc_html_e( 'JPG Optimization Level', 'ewww-image-optimizer' ); ?></label>
10047
+ <?php ewwwio_help_link( 'https://docs.ewww.io/article/7-basic-configuration', '585373d5c697912ffd6c0bb2' ); ?>
10048
+ </th>
10049
+ <td>
10050
+ <select id='ewww_image_optimizer_jpg_level' name='ewww_image_optimizer_jpg_level'>
10051
+ <option value='0' <?php selected( ewww_image_optimizer_get_option( 'ewww_image_optimizer_jpg_level' ), 0 ); ?>>
10052
+ <?php esc_html_e( 'No Compression', 'ewww-image-optimizer' ); ?>
10053
+ </option>
10054
+ <?php if ( defined( 'EWWW_IMAGE_OPTIMIZER_TOOL_PATH' ) ) : ?>
10055
+ <option value='10' <?php selected( ewww_image_optimizer_get_option( 'ewww_image_optimizer_jpg_level' ), 10 ); ?>>
10056
+ <?php esc_html_e( 'Pixel Perfect', 'ewww-image-optimizer' ); ?>
10057
+ </option>
10058
+ <?php endif; ?>
10059
+ <option <?php disabled( $disable_level ); ?> value='20' <?php selected( ewww_image_optimizer_get_option( 'ewww_image_optimizer_jpg_level' ), 20 ); ?>>
10060
+ <?php esc_html_e( 'Pixel Perfect Plus', 'ewww-image-optimizer' ); ?> *
10061
+ </option>
10062
+ <option <?php disabled( $disable_level ); ?> value='30' <?php selected( ewww_image_optimizer_get_option( 'ewww_image_optimizer_jpg_level' ), 30 ); ?>>
10063
+ <?php esc_html_e( 'Premium', 'ewww-image-optimizer' ); ?> *
10064
+ </option>
10065
+ <option <?php disabled( $disable_level ); ?> value='40' <?php selected( ewww_image_optimizer_get_option( 'ewww_image_optimizer_jpg_level' ), 40 ); ?>>
10066
+ <?php esc_html_e( 'Premium Plus', 'ewww-image-optimizer' ); ?> *
10067
+ </option>
10068
+ </select>
10069
+ </td>
10070
+ </tr>
10071
+ <tr>
10072
+ <th scope='row'>
10073
+ <label for='ewww_image_optimizer_png_level'><?php esc_html_e( 'PNG Optimization Level', 'ewww-image-optimizer' ); ?></label>
10074
+ <?php ewwwio_help_link( 'https://docs.ewww.io/article/7-basic-configuration', '585373d5c697912ffd6c0bb2,5854531bc697912ffd6c1afa' ); ?>
10075
+ </th>
10076
+ <td>
10077
+ <select id='ewww_image_optimizer_png_level' name='ewww_image_optimizer_png_level'>
10078
+ <option value='0' <?php selected( ewww_image_optimizer_get_option( 'ewww_image_optimizer_png_level' ), 0 ); ?>>
10079
+ <?php esc_html_e( 'No Compression', 'ewww-image-optimizer' ); ?>
10080
+ </option>
10081
+ <?php if ( defined( 'EWWW_IMAGE_OPTIMIZER_TOOL_PATH' ) ) : ?>
10082
+ <option value='10' <?php selected( ewww_image_optimizer_get_option( 'ewww_image_optimizer_png_level' ), 10 ); ?>>
10083
+ <?php esc_html_e( 'Pixel Perfect', 'ewww-image-optimizer' ); ?>
10084
+ </option>
10085
+ <?php endif; ?>
10086
+ <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 ); ?>>
10087
+ <?php esc_html_e( 'Pixel Perfect Plus', 'ewww-image-optimizer' ); ?> *
10088
+ </option>
10089
+ <option value='40' <?php selected( ewww_image_optimizer_get_option( 'ewww_image_optimizer_png_level' ), 40 ); ?>>
10090
+ <?php esc_html_e( 'Premium', 'ewww-image-optimizer' ) . ' ' . $maybe_api_level; ?>
10091
+ </option>
10092
+ <option <?php disabled( $disable_level ); ?> value='50' <?php selected( ewww_image_optimizer_get_option( 'ewww_image_optimizer_png_level' ), 50 ); ?>>
10093
+ <?php esc_html_e( 'Premium Plus', 'ewww-image-optimizer' ); ?> *
10094
+ </option>
10095
+ </select>
10096
+ </td>
10097
+ </tr>
10098
+ <tr>
10099
+ <th scope='row'>
10100
+ <label for='ewww_image_optimizer_gif_level'><?php esc_html_e( 'GIF Optimization Level', 'ewww-image-optimizer' ); ?></label>
10101
+ <?php ewwwio_help_link( 'https://docs.ewww.io/article/7-basic-configuration', '585373d5c697912ffd6c0bb2' ); ?>
10102
+ </th>
10103
+ <td>
10104
+ <select id='ewww_image_optimizer_gif_level' name='ewww_image_optimizer_gif_level'>
10105
+ <option value='0' <?php selected( ewww_image_optimizer_get_option( 'ewww_image_optimizer_gif_level' ), 0 ); ?>>
10106
+ <?php esc_html_e( 'No Compression', 'ewww-image-optimizer' ); ?>
10107
+ </option>
10108
+ <option value='10' <?php selected( ewww_image_optimizer_get_option( 'ewww_image_optimizer_gif_level' ), 10 ); ?>>
10109
+ <?php esc_html_e( 'Pixel Perfect', 'ewww-image-optimizer' ) . ' ' . $maybe_api_level; ?>
10110
+ </option>
10111
+ </select>
10112
+ </td>
10113
+ </tr>
10114
+ <tr>
10115
+ <th scope='row'>
10116
+ <label for='ewww_image_optimizer_pdf_level'><?php esc_html_e( 'PDF Optimization Level', 'ewww-image-optimizer' ); ?></label>
10117
+ <?php ewwwio_help_link( 'https://docs.ewww.io/article/7-basic-configuration', '585373d5c697912ffd6c0bb2' ); ?>
10118
+ </th>
10119
+ <td>
10120
+ <select id='ewww_image_optimizer_pdf_level' name='ewww_image_optimizer_pdf_level'>
10121
+ <option value='0' <?php selected( ewww_image_optimizer_get_option( 'ewww_image_optimizer_pdf_level' ), 0 ); ?>>
10122
+ <?php esc_html_e( 'No Compression', 'ewww-image-optimizer' ); ?>
10123
+ </option>
10124
+ <option <?php disabled( $disable_level ); ?> value='10' <?php selected( ewww_image_optimizer_get_option( 'ewww_image_optimizer_pdf_level' ), 10 ); ?>>
10125
+ <?php esc_html_e( 'Pixel Perfect', 'ewww-image-optimizer' ); ?> *
10126
+ </option>
10127
+ <option <?php disabled( $disable_level ); ?> value='20' <?php selected( ewww_image_optimizer_get_option( 'ewww_image_optimizer_pdf_level' ), 20 ); ?>>
10128
+ <?php esc_html_e( 'High Compression', 'ewww-image-optimizer' ); ?> *
10129
+ </option>
10130
+ </select>
10131
+ </td>
10132
+ </tr>
10133
+ <tr>
10134
+ <th>&nbsp;</th>
10135
+ <td>
10136
+ <?php if ( ! ewww_image_optimizer_get_option( 'ewww_image_optimizer_cloud_key' ) ) : ?>
10137
+ <p>
10138
+ * <strong><a href='https://ewww.io/buy-credits/' target='_blank'>
10139
+ <?php esc_html_e( 'Purchase an API key to unlock these optimization levels and get priority support. Achieve up to 80% compression to speed up your site, save storage space, and reduce server load.', 'ewww-image-optimizer' ); ?>
10140
+ </a></strong><br>
10141
+ <a href='https://optimize.exactlywww.com/api_key/free-trial.php?TB_iframe=true&width=600&height=375' class='thickbox' target='_blank'>
10142
+ <?php esc_html_e( 'Or get a free trial key and take it for a test drive.', 'ewww-image-optimizer' ); ?>
10143
+ </a>
10144
+ </p>
10145
+ <?php else : ?>
10146
+ <p>
10147
+ * <?php esc_html_e( 'These levels use the compression API.', 'ewww-image-optimizer' ); ?>
10148
+ </p>
10149
+ <?php endif; ?>
10150
+ <p class='description'>
10151
+ <?php esc_html_e( 'All methods used by the EWWW Image Optimizer are intended to produce visually identical images.', 'ewww-image-optimizer' ); ?>
10152
+ </p>
10153
+ </td>
10154
+ </tr>
10155
+ <tr>
10156
+ <th scope='row'>
10157
+ <label for='ewww_image_optimizer_backup_files'><?php esc_html_e( 'Backup Originals', 'ewww-image-optimizer' ); ?></label>
10158
+ <?php ewwwio_help_link( 'https://docs.ewww.io/article/7-basic-configuration', '585373d5c697912ffd6c0bb2' ); ?>
10159
+ </th>
10160
+ <td>
10161
+ <input type='checkbox' id='ewww_image_optimizer_backup_files' name='ewww_image_optimizer_backup_files' value='true' <?php checked( ewww_image_optimizer_get_option( 'ewww_image_optimizer_backup_files' ) ); ?> <?php disabled( $disable_level ); ?>>
10162
+ <?php esc_html_e( 'Store a copy of your original images on our secure server for 30 days. *Requires an active API key.', 'ewww-image-optimizer' ); ?>
10163
+ </td>
10164
+ </tr>
10165
+ <?php if ( class_exists( 'Cloudinary' ) && Cloudinary::config_get( 'api_secret' ) ) : ?>
10166
+ <tr>
10167
+ <th scope='row'>
10168
+ <label for='ewww_image_optimizer_enable_cloudinary'><?php esc_html_e( 'Automatic Cloudinary Upload', 'ewww-image-optimizer' ); ?></label>
10169
+ </th>
10170
+ <td>
10171
+ <input type='checkbox' id='ewww_image_optimizer_enable_cloudinary' name='ewww_image_optimizer_enable_cloudinary' value='true' <?php checked( ewww_image_optimizer_get_option( 'ewww_image_optimizer_enable_cloudinary' ) ); ?> />
10172
+ <?php esc_html_e( 'When enabled, uploads to the Media Library will be transferred to Cloudinary after optimization. Cloudinary generates resizes, so only the full-size image is uploaded.', 'ewww-image-optimizer' ); ?>
10173
+ </td>
10174
+ </tr>
10175
+ <?php endif; ?>
10176
+ </table>
10177
+ <?php
10178
+ if ( $easymode ) {
10179
+ ob_end_clean();
10180
  } else {
10181
+ ob_end_flush();
10182
+ }
10183
+ ?>
10184
+ </div>
10185
+
10186
+ <?php
10187
+ $eio_base = new EIO_Base();
10188
+ $easyio_site_url = $eio_base->content_url();
10189
+ $exactdn_att_che = ewww_image_optimizer_get_option( 'exactdn_all_the_things' ) && ( ! is_object( $exactdn ) || 1 < $exactdn->get_plan_id() );
10190
+ $exactdn_att_id = ( ! $exactdn_enabled || 1 === $exactdn->get_plan_id() ? 'exactdn_all_the_things_disabled' : 'exactdn_all_the_things' );
10191
+ $exactdn_att_dis = ! $exactdn_enabled || 1 === $exactdn->get_plan_id();
10192
+ $exactdn_los_che = ewww_image_optimizer_get_option( 'exactdn_lossy' ) || ( is_object( $exactdn ) && 1 === $exactdn->get_plan_id() );
10193
+ $exactdn_los_id = ( ! $exactdn_enabled || 1 === $exactdn->get_plan_id() ? 'exactdn_lossy_disabled' : 'exactdn_lossy' );
10194
+ $exactdn_los_dis = ! $exactdn_enabled || 1 === $exactdn->get_plan_id();
10195
+ $eio_exclude_paths = ewww_image_optimizer_get_option( 'exactdn_exclude' ) ? implode( "\n", ewww_image_optimizer_get_option( 'exactdn_exclude' ) ) : '';
10196
+ $lqip_che = is_object( $exactdn ) && 1 < $exactdn->get_plan_id() && ewww_image_optimizer_get_option( 'ewww_image_optimizer_use_lqip' );
10197
+ $lqip_id = ( ! $exactdn_enabled || 1 === $exactdn->get_plan_id() ? 'ewww_image_optimizer_use_lqip_disabled' : 'ewww_image_optimizer_use_lqip' );
10198
+ $lqip_dis = ! $exactdn_enabled || 1 === $exactdn->get_plan_id();
10199
+ $ll_exclude_paths = ewww_image_optimizer_get_option( 'ewww_image_optimizer_ll_exclude' ) ? implode( "\n", ewww_image_optimizer_get_option( 'ewww_image_optimizer_ll_exclude' ) ) : '';
10200
+ ?>
10201
+
10202
+ <div id='ewww-exactdn-settings'>
10203
+ <noscript><h2><?php esc_html_e( 'Easy Mode', 'ewww-image-optimizer' ); ?></h2></noscript>
10204
+ <p>
10205
+ <?php esc_html_e( 'Having problems? Try disabling Lazy Load and Include All Resources. Finally, disable Easy IO if problems remain.', 'ewww-image-optimizer' ); ?><br>
10206
+ <a class='ewww-docs-root' href='https://ewww.io/contact-us/'>
10207
+ <?php esc_html_e( 'Then, let us know so we can find a fix for the problem.', 'ewww-image-optimizer' ); ?>
10208
+ </a>
10209
+ </p>
10210
+ <table class='form-table'>
10211
+ <tr>
10212
+ <th scope='row'>
10213
+ <label for='ewww_image_optimizer_exactdn'><?php esc_html_e( 'Easy IO', 'ewww-image-optimizer' ); ?></label>
10214
+ <?php ewwwio_help_link( 'https://docs.ewww.io/article/44-introduction-to-exactdn', '59bc5ad6042863033a1ce370,5c0042892c7d3a31944e88a4' ); ?>
10215
+ </th>
10216
+ <td>
10217
+ <input type='checkbox' id='ewww_image_optimizer_exactdn' name='ewww_image_optimizer_exactdn' value='true' <?php checked( $exactdn_enabled ); ?> />
10218
+ <?php esc_html_e( 'Comprehensive and automatic image optimization:', 'ewww-image-optimizer' ); ?>
10219
+ <p class="description">
10220
+ <?php esc_html_e( 'Premium Compression', 'ewww-image-optimizer' ); ?><br>
10221
+ <?php esc_html_e( 'Properly scale images to fit any device', 'ewww-image-optimizer' ); ?><br>
10222
+ <?php esc_html_e( 'Automatic WebP Conversion', 'ewww-image-optimizer' ); ?><br>
10223
+ <?php esc_html_e( 'Smart Image Conversion', 'ewww-image-optimizer' ); ?><br>
10224
+ <?php esc_html_e( 'JS/CSS Minification and Compression', 'ewww-image-optimizer' ); ?><br>
10225
+ <?php esc_html_e( 'CDN Included', 'ewww-image-optimizer' ); ?><br>
10226
+ <?php if ( ! $exactdn_enabled ) : ?>
10227
+ <strong>
10228
+ <a href="https://ewww.io/resize/" target="_blank">
10229
+ <?php esc_html_e( 'Purchase a subscription for your site.', 'ewww-image-optimizer' ); ?>
10230
+ </a>
10231
+ </strong><br>
10232
+ <a href="https://ewww.io/manage-sites/" target="_blank">
10233
+ <?php esc_html_e( 'Then, add your Site URL to your account:', 'easy-image-optimizer' ); ?>
10234
+ </a>
10235
+ <?php echo esc_url( $easyio_site_url ); ?><br>
10236
+ <?php endif; ?>
10237
+ <a href="https://docs.ewww.io/article/44-introduction-to-exactdn" target="_blank" data-beacon-article="59bc5ad6042863033a1ce370">
10238
+ <?php esc_html_e( 'Learn more about Easy IO', 'ewww-image-optimizer' ); ?>
10239
+ </a>
10240
+ </p>
10241
+ </td>
10242
+ </tr>
10243
+ <tr>
10244
+ <td>&nbsp;</td>
10245
+ <td>
10246
+ <input type='checkbox' name='exactdn_all_the_things' value='true' id='<?php echo esc_attr( $exactdn_att_id ); ?>' <?php disabled( $exactdn_att_dis ); ?> <?php checked( $exactdn_att_che ); ?> />
10247
+ <label for='exactdn_all_the_things'><strong><?php esc_html_e( 'Include All Resources', 'ewww-image-optimizer' ); ?></strong></label>
10248
+ <?php ewwwio_help_link( 'https://docs.ewww.io/article/47-getting-more-from-exactdn', '59de6631042863379ddc953c' ); ?>
10249
+ <p class='description'>
10250
+ <?php esc_html_e( 'Use Easy IO for all resources in wp-includes/ and wp-content/, including JavaScript, CSS, fonts, etc.', 'ewww-image-optimizer' ); ?>
10251
+ </p>
10252
+ </td>
10253
+ </tr>
10254
+ <tr>
10255
+ <td>&nbsp;</td>
10256
+ <td>
10257
+ <input type='checkbox' name='exactdn_lossy' value='true' id='<?php echo esc_attr( $exactdn_los_id ); ?>' <?php disabled( $exactdn_los_dis ); ?> <?php checked( $exactdn_los_che ); ?> />
10258
+ <label for='exactdn_lossy'><strong><?php esc_html_e( 'Premium Compression', 'ewww-image-optimizer' ); ?></strong></label>
10259
+ <?php ewwwio_help_link( 'https://docs.ewww.io/article/47-getting-more-from-exactdn', '59de6631042863379ddc953c' ); ?>
10260
+ <p class='description'>
10261
+ <?php esc_html_e( 'Enable high quality premium compression for all images. Disable to use Pixel Perfect mode instead.', 'ewww-image-optimizer' ); ?>
10262
+ </p>
10263
+ </td>
10264
+ </tr>
10265
+ <?php if ( ! $exactdn_enabled || 1 === $exactdn->get_plan_id() ) : ?>
10266
+ <input type='hidden' id='exactdn_all_the_things' name='exactdn_all_the_things' <?php echo ( ewww_image_optimizer_get_option( 'exactdn_all_the_things' ) ? "value='1'" : "value='0'" ); ?> />
10267
+ <input type='hidden' id='exactdn_lossy' name='exactdn_lossy' <?php echo ( ewww_image_optimizer_get_option( 'exactdn_lossy' ) ? "value='1'" : "value='0'" ); ?> />
10268
+ <input type='hidden' id='ewww_image_optimizer_use_lqip' name='ewww_image_optimizer_use_lqip' <?php echo ( ewww_image_optimizer_get_option( 'ewww_image_optimizer_use_lqip' ) ? "value='1'" : "value='0'" ); ?> />
10269
+ <?php endif; ?>
10270
+ <tr>
10271
+ <td>&nbsp;</td>
10272
+ <td>
10273
+ <label for='exactdn_exclude'><strong><?php esc_html_e( 'Exclusions', 'ewww-image-optimizer' ); ?></strong></label>
10274
+ <?php ewwwio_help_link( 'https://docs.ewww.io/article/68-exactdn-exclude', '5c0042892c7d3a31944e88a4' ); ?><br>
10275
+ <textarea id='exactdn_exclude' name='exactdn_exclude' rows='3' cols='60'><?php echo esc_html( $eio_exclude_paths ); ?></textarea>
10276
+ <p class='description'>
10277
+ <?php esc_html_e( 'One exclusion per line, no wildcards (*) needed. Any pattern or path provided will not be routed through Easy IO.', 'ewww-image-optimizer' ); ?>
10278
+ </p>
10279
+ </td>
10280
+ </tr>
10281
+ <tr>
10282
+ <th scope='row'>
10283
+ <label for='ewww_image_optimizer_lazy_load'><?php esc_html_e( 'Lazy Load', 'ewww-image-optimizer' ); ?></label>
10284
+ <?php ewwwio_help_link( 'https://docs.ewww.io/article/74-lazy-load', '5c6c36ed042863543ccd2d9b' ); ?>
10285
+ </th>
10286
+ <td>
10287
+ <input type='checkbox' id='ewww_image_optimizer_lazy_load' name='ewww_image_optimizer_lazy_load' value='true' <?php checked( ewww_image_optimizer_get_option( 'ewww_image_optimizer_lazy_load' ) ); ?> />
10288
+ <?php esc_html_e( 'Improves actual and perceived loading time as images will be loaded only as they enter (or are about to enter) the viewport.', 'ewww-image-optimizer' ); ?>
10289
+ <p class='description'>
10290
+ <?php esc_html_e( 'When used with Easy IO and/or JS WebP Rewriting, the plugin will load the best available image size and format for each device.', 'ewww-image-optimizer' ); ?></br>
10291
+ <?php esc_html_e( 'To disable auto-scaling for an image, add "skip-autoscale" to the HTML element via a class or attribute.', 'ewww-image-optimizer' ); ?>
10292
+ </p>
10293
+ </td>
10294
+ </tr>
10295
+ <tr>
10296
+ <td>&nbsp;</td>
10297
+ <td>
10298
+ <input type='checkbox' name='ewww_image_optimizer_use_lqip' value='true' id='<?php echo esc_attr( $lqip_id ); ?>' <?php disabled( $lqip_dis ); ?> <?php checked( $lqip_che ); ?> />
10299
+ <label for='ewww_image_optimizer_use_lqip'><strong>LQIP</strong></label>
10300
+ <?php ewwwio_help_link( 'https://docs.ewww.io/article/75-lazy-load-placeholders', '5c9a7a302c7d3a1544615e47' ); ?>
10301
+ <p class='description'>
10302
+ <?php esc_html_e( 'Use low-quality versions of your images as placeholders via Easy IO. Can improve user experience, but may be slower than blank placeholders.', 'ewww-image-optimizer' ); ?>
10303
+ </p>
10304
+ </td>
10305
+ </tr>
10306
+ <tr>
10307
+ <td>&nbsp;</td>
10308
+ <td>
10309
+ <label for='ewww_image_optimizer_ll_exclude'><strong><?php esc_html_e( 'Exclusions', 'ewww-image-optimizer' ); ?></strong></label>
10310
+ <?php ewwwio_help_link( 'https://docs.ewww.io/article/74-lazy-load', '5c6c36ed042863543ccd2d9b' ); ?><br>
10311
+ <textarea id='ewww_image_optimizer_ll_exclude' name='ewww_image_optimizer_ll_exclude' rows='3' cols='60'><?php echo esc_html( $ll_exclude_paths ); ?></textarea>
10312
+ <p class='description'>
10313
+ <?php esc_html_e( 'One exclusion per line, no wildcards (*) needed. Use any string that matches the desired element(s) or exclude entire element types like "div", "span", etc. The class "skip-lazy" and attribute "data-skip-lazy" are excluded by default.', 'ewww-image-optimizer' ); ?>
10314
+ </p>
10315
+ </td>
10316
+ </tr>
10317
+ </table>
10318
+ </div>
10319
+
10320
+ <?php
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
10321
  $media_include_disable = '';
10322
  if ( ewww_image_optimizer_get_option( 'ewww_image_optimizer_disable_resizes_opt', false, true ) ) {
10323
+ $media_include_disable = true;
10324
+ }
10325
+ $aux_paths = ewww_image_optimizer_get_option( 'ewww_image_optimizer_aux_paths' ) ? implode( "\n", ewww_image_optimizer_get_option( 'ewww_image_optimizer_aux_paths' ) ) : '';
10326
+ $exclude_paths = ewww_image_optimizer_get_option( 'ewww_image_optimizer_exclude_paths' ) ? implode( "\n", ewww_image_optimizer_get_option( 'ewww_image_optimizer_exclude_paths' ) ) : '';
10327
+ /* translators: %s: the folder where WordPress is installed */
10328
+ $aux_paths_desc = sprintf( __( 'One path per line, must be within %s. Use full paths, not relative paths.', 'ewww-image-optimizer' ), ABSPATH );
10329
+ ?>
10330
+
10331
+ <div id='ewww-optimization-settings'>
10332
+ <noscript><h2><?php esc_html_e( 'Advanced', 'ewww-image-optimizer' ); ?></h2></noscript>
10333
+ <table class='form-table'>
10334
+ <tr>
10335
+ <th scope='row'>
10336
+ <label for='ewww_image_optimizer_jpg_quality'><?php esc_html_e( 'JPG Quality Level', 'ewww-image-optimizer' ); ?></label>
10337
+ <?php ewwwio_help_link( 'https://docs.ewww.io/article/11-advanced-configuration', '58542afac697912ffd6c18c0,58543c69c697912ffd6c19a7' ); ?>
10338
+ </th>
10339
+ <td>
10340
+ <input type='text' id='ewww_image_optimizer_jpg_quality' name='ewww_image_optimizer_jpg_quality' class='small-text' value='<?php echo esc_attr( ewww_image_optimizer_jpg_quality() ); ?>' />
10341
+ <?php esc_html_e( 'Valid values are 1-100.', 'ewww-image-optimizer' ); ?>
10342
+ <p class='description'>
10343
+ <?php esc_html_e( 'Use this to override the default WordPress quality level of 82. Applies to image editing, resizing, PNG to JPG conversion, and JPG to WebP conversion. Does not affect the original uploaded image unless maximum dimensions are set and resizing occurs.', 'ewww-image-optimizer' ); ?>
10344
+ </p>
10345
+ </td>
10346
+ </tr>
10347
+ <tr>
10348
+ <th scope='row'>
10349
+ <label for='ewww_image_optimizer_parallel_optimization'><?php esc_html_e( 'Parallel Optimization', 'ewww-image-optimizer' ); ?></label>
10350
+ <?php ewwwio_help_link( 'https://docs.ewww.io/article/11-advanced-configuration', '58542afac697912ffd6c18c0,598cb8be2c7d3a73488be237' ); ?>
10351
+ </th>
10352
+ <td>
10353
+ <input type='checkbox' id='ewww_image_optimizer_parallel_optimization' name='ewww_image_optimizer_parallel_optimization' value='true' <?php checked( ewww_image_optimizer_get_option( 'ewww_image_optimizer_parallel_optimization' ) ); ?> />
10354
+ <?php esc_html_e( 'All resizes generated from a single upload are optimized in parallel for faster optimization. If this is causing performance issues, disable parallel optimization to reduce the load on your server.', 'ewww-image-optimizer' ); ?>
10355
+ </td>
10356
+ </tr>
10357
+ <tr>
10358
+ <th scope='row'>
10359
+ <label for='ewww_image_optimizer_auto'><?php esc_html_e( 'Scheduled Optimization', 'ewww-image-optimizer' ); ?></label>
10360
+ <?php ewwwio_help_link( 'https://docs.ewww.io/article/11-advanced-configuration', '58542afac697912ffd6c18c0,5853713bc697912ffd6c0b98' ); ?>
10361
+ </th>
10362
+ <td>
10363
+ <input type='checkbox' id='ewww_image_optimizer_auto' name='ewww_image_optimizer_auto' value='true' <?php checked( ewww_image_optimizer_get_option( 'ewww_image_optimizer_auto' ) ); ?> />
10364
+ <?php esc_html_e( 'This will enable scheduled optimization of unoptimized images for your theme, buddypress, and any additional folders you have configured below. Runs hourly: wp_cron only runs when your site is visited, so it may be even longer between optimizations.', 'ewww-image-optimizer' ); ?>
10365
+ </td>
10366
+ </tr>
10367
+ <?php if ( ewww_image_optimizer_get_option( 'ewww_image_optimizer_disable_resizes_opt', false, true ) ) : ?>
10368
+ <tr>
10369
+ <th>&nbsp;</th>
10370
+ <td>
10371
+ <p>
10372
+ <span style="color: #3eadc9"><?php esc_html_e( '*Include Media Library Folders has been disabled because it will cause the scanner to ignore the disabled resizes.', 'ewww-image-optimizer' ); ?></span>
10373
+ </p>
10374
+ </td>
10375
+ </tr>
10376
+ <?php endif; ?>
10377
+ <tr>
10378
+ <th scope='row'>
10379
+ <label for='ewww_image_optimizer_include_media_paths'><?php esc_html_e( 'Include Media Folders', 'ewww-image-optimizer' ); ?></label>
10380
+ <?php ewwwio_help_link( 'https://docs.ewww.io/article/11-advanced-configuration', '58542afac697912ffd6c18c0,5853713bc697912ffd6c0b98' ); ?>
10381
+ </th>
10382
+ <td>
10383
+ <input type='checkbox' id='ewww_image_optimizer_include_media_paths' name='ewww_image_optimizer_include_media_paths' <?php disabled( $media_include_disable ); ?> value='true' <?php checked( ewww_image_optimizer_get_option( 'ewww_image_optimizer_include_media_paths' ) && ! ewww_image_optimizer_get_option( 'ewww_image_optimizer_disable_resizes_opt', false, true ) ); ?> />
10384
+ <?php esc_html_e( 'Scan all images from the latest two folders of the Media Library during the Bulk Optimizer and Scheduled Optimization.', 'ewww-image-optimizer' ); ?>
10385
+ </td>
10386
+ </tr>
10387
+ <tr>
10388
+ <th scope='row'>
10389
+ <label for='ewww_image_optimizer_include_originals'><?php esc_html_e( 'Include Originals', 'ewww-image-optimizer' ); ?></label>
10390
+ <?php ewwwio_help_link( 'https://docs.ewww.io/article/11-advanced-configuration', '58542afac697912ffd6c18c0' ); ?>
10391
+ </th>
10392
+ <td>
10393
+ <input type='checkbox' id='ewww_image_optimizer_include_originals' name='ewww_image_optimizer_include_originals' value='true' <?php checked( ewww_image_optimizer_get_option( 'ewww_image_optimizer_include_originals' ) ); ?> />
10394
+ <?php esc_html_e( 'Optimize the original version of images that have been scaled down by WordPress.', 'ewww-image-optimizer' ); ?>
10395
+ </td>
10396
+ </tr>
10397
+ <tr>
10398
+ <th scope='row'>
10399
+ <label for='ewww_image_optimizer_aux_paths'><?php esc_html_e( 'Folders to Optimize', 'ewww-image-optimizer' ); ?></label>
10400
+ <?php ewwwio_help_link( 'https://docs.ewww.io/article/11-advanced-configuration', '58542afac697912ffd6c18c0,5853713bc697912ffd6c0b98' ); ?>
10401
+ </th>
10402
+ <td>
10403
+ <?php echo esc_html( $aux_paths_desc ); ?><br>
10404
+ <textarea id='ewww_image_optimizer_aux_paths' name='ewww_image_optimizer_aux_paths' rows='3' cols='60'><?php echo esc_html( $aux_paths ); ?></textarea>
10405
+ <p class='description'>
10406
+ <?php esc_html_e( 'Provide paths containing images to be optimized using the Bulk Optimizer and Scheduled Optimization.', 'ewww-image-optimizer' ); ?>
10407
+ </p>
10408
+ </td>
10409
+ </tr>
10410
+ <tr>
10411
+ <th scope='row'>
10412
+ <label for='ewww_image_optimizer_exclude_paths'><?php esc_html_e( 'Folders to Ignore', 'ewww-image-optimizer' ); ?></label>
10413
+ <?php ewwwio_help_link( 'https://docs.ewww.io/article/11-advanced-configuration', '58542afac697912ffd6c18c0,5853713bc697912ffd6c0b98' ); ?>
10414
+ </th>
10415
+ <td>
10416
+ <?php esc_html_e( 'One path per line, partial paths allowed, but no urls.', 'ewww-image-optimizer' ); ?><br>
10417
+ <textarea id='ewww_image_optimizer_exclude_paths' name='ewww_image_optimizer_exclude_paths' rows='3' cols='60'><?php echo esc_html( $exclude_paths ); ?></textarea>
10418
+ <p class='description'>
10419
+ <?php esc_html_e( 'A file that matches any pattern or path provided will not be optimized.', 'ewww-image-optimizer' ); ?>
10420
+ </p>
10421
+ </td>
10422
+ </tr>
10423
+ </table>
10424
+ </div>
10425
+
10426
+ <?php
10427
  $image_sizes = ewww_image_optimizer_get_image_sizes();
10428
  $disabled_sizes = ewww_image_optimizer_get_option( 'ewww_image_optimizer_disable_resizes', false, true );
10429
  $disabled_sizes_opt = ewww_image_optimizer_get_option( 'ewww_image_optimizer_disable_resizes_opt', false, true );
10430
+ ?>
10431
+
10432
+ <div id='ewww-resize-settings'>
10433
+ <noscript><h2><?php esc_html_e( 'Resize', 'ewww-image-optimizer' ); ?></h2></noscript>
10434
+ <table class='form-table'>
10435
+ <tr>
10436
+ <th scope='row'>
10437
+ <label for='ewww_image_optimizer_resize_detection'><?php esc_html_e( 'Resize Detection', 'ewww-image-optimizer' ); ?></label>
10438
+ <?php ewwwio_help_link( 'https://docs.ewww.io/article/41-resize-settings', '59849911042863033a1ba5f9' ); ?>
10439
+ </th>
10440
+ <td>
10441
+ <input type='checkbox' id='ewww_image_optimizer_resize_detection' name='ewww_image_optimizer_resize_detection' value='true' <?php checked( ewww_image_optimizer_get_option( 'ewww_image_optimizer_resize_detection' ) ); ?> />
10442
+ <?php esc_html_e( 'Highlight images that need to be resized because the browser is scaling them down. Only visible for Admin users and adds a button to the admin bar to detect scaled images that have been lazy loaded.', 'ewww-image-optimizer' ); ?>
10443
+ </td>
10444
+ </tr>
10445
+ <?php if ( function_exists( 'imsanity_get_max_width_height' ) ) : ?>
10446
+ <tr>
10447
+ <th>&nbsp;</th>
10448
+ <td>
10449
+ <p>
10450
+ <span style="color: #3eadc9"><?php esc_html_e( '*Imsanity settings override the EWWW resize dimensions.', 'ewww-image-optimizer' ); ?></span>
10451
+ </p>
10452
+ </td>
10453
+ </tr>
10454
+ <?php endif; ?>
10455
+ <tr>
10456
+ <th scope='row'>
10457
+ <?php esc_html_e( 'Resize Images', 'ewww-image-optimizer' ); ?>
10458
+ <?php ewwwio_help_link( 'https://docs.ewww.io/article/41-resize-settings', '59849911042863033a1ba5f9' ); ?>
10459
+ </th>
10460
+ <td>
10461
+ <label for='ewww_image_optimizer_maxmediawidth'><?php esc_html_e( 'Max Width', 'ewww-image-optimizer' ); ?></label>
10462
+ <input type='number' step='1' min='0' class='small-text' id='ewww_image_optimizer_maxmediawidth' name='ewww_image_optimizer_maxmediawidth' value='<?php echo (int) ewww_image_optimizer_get_option( 'ewww_image_optimizer_maxmediawidth' ); ?>' <?php disabled( function_exists( 'imsanity_get_max_width_height' ) ); ?> />
10463
+ <label for='ewww_image_optimizer_maxmediaheight'><?php esc_html_e( 'Max Height', 'ewww-image-optimizer' ); ?></label>
10464
+ <input type='number' step='1' min='0' class='small-text' id='ewww_image_optimizer_maxmediaheight' name='ewww_image_optimizer_maxmediaheight' value='<?php echo (int) ewww_image_optimizer_get_option( 'ewww_image_optimizer_maxmediaheight' ); ?>' <?php disabled( function_exists( 'imsanity_get_max_width_height' ) ); ?> />
10465
+ <?php esc_html_e( 'in pixels', 'ewww-image-optimizer' ); ?>
10466
+ <p class='description'>
10467
+ <?php esc_html_e( 'Resize uploaded images to these dimensions.', 'ewww-image-optimizer' ); ?>
10468
+ </p>
10469
+ </td>
10470
+ </tr>
10471
+ <?php if ( ! $easymode ) : ?>
10472
+ <tr>
10473
+ <th scope='row'>
10474
+ <label for='ewww_image_optimizer_resize_existing'><?php esc_html_e( 'Resize Existing Images', 'ewww-image-optimizer' ); ?></label>
10475
+ <?php ewwwio_help_link( 'https://docs.ewww.io/article/41-resize-settings', '59849911042863033a1ba5f9' ); ?>
10476
+ </th>
10477
+ <td>
10478
+ <input type='checkbox' id='ewww_image_optimizer_resize_existing' name='ewww_image_optimizer_resize_existing' value='true' <?php checked( ewww_image_optimizer_get_option( 'ewww_image_optimizer_resize_existing' ) ); ?> />
10479
+ <?php esc_html_e( 'Allow resizing of existing Media Library images.', 'ewww-image-optimizer' ); ?>
10480
+ </td>
10481
+ </tr>
10482
+ <tr>
10483
+ <th scope='row'>
10484
+ <label for='ewww_image_optimizer_resize_other_existing'><?php esc_html_e( 'Resize Other Images', 'ewww-image-optimizer' ); ?></label>
10485
+ <?php ewwwio_help_link( 'https://docs.ewww.io/article/41-resize-settings', '59849911042863033a1ba5f9' ); ?>
10486
+ </th>
10487
+ <td>
10488
+ <input type='checkbox' id='ewww_image_optimizer_resize_other_existing' name='ewww_image_optimizer_resize_other_existing' value='true' <?php checked( ewww_image_optimizer_get_option( 'ewww_image_optimizer_resize_other_existing' ) ); ?> />
10489
+ <?php esc_html_e( 'Allow resizing of existing images outside the Media Library. Use this to resize images specified under the Folders to Optimize setting when running Bulk or Scheduled Optimization.', 'ewww-image-optimizer' ); ?>
10490
+ </td>
10491
+ </tr>
10492
+ <?php endif; ?>
10493
+
10494
+ <?php if ( $easymode ) : ?>
10495
+ <?php elseif ( 'network-multisite' === $network ) : ?>
10496
+ <tr>
10497
+ <th scope="row">
10498
+ <?php esc_html_e( 'Disable Resizes', 'ewww-image-optimizer' ); ?>
10499
+ </th>
10500
+ <td>
10501
+ <p>
10502
+ <span style="color: #3eadc9"><?php esc_html_e( '*Settings to disable creation and optimization of individual sizes must be configured for each individual site.', 'ewww-image-optimizer' ); ?></span>
10503
+ </p>
10504
+ </td>
10505
+ </tr>
10506
+ <?php else : ?>
10507
+ <?php if ( 'network-singlesite' === $network ) : ?>
10508
+ <?php ob_end_clean(); ?>
10509
+ <div id='ewww-resize-settings'>
10510
+ <table class='form-table'>
10511
+ <?php endif; ?>
10512
+ <!-- RIGHT HERE is where we begin/clear buffer for network-singlesite (non-override version). -->
10513
+ <!-- Though the buffer will need to be started right the form begins. -->
10514
+ <tr>
10515
+ <th scope="row">
10516
+ <?php esc_html_e( 'Disable Resizes', 'ewww-image-optimizer' ); ?>
10517
+ <?php ewwwio_help_link( 'https://docs.ewww.io/article/41-resize-settings', '59849911042863033a1ba5f9,58598744c697912ffd6c3eb4' ); ?>
10518
+ </th>
10519
+ <td>
10520
+ <p>
10521
+ <?php esc_html_e( 'WordPress, your theme, and other plugins generate various image sizes for each image uploaded.', 'ewww-image-optimizer' ); ?><br>
10522
+ <?php if ( ewww_image_optimizer_get_option( 'ewww_image_optimizer_cloud_key' ) ) : ?>
10523
+ <i><?php esc_html_e( 'Remember that each image size will affect your API credits.', 'ewww-image-optimizer' ); ?></i>
10524
+ <?php endif; ?>
10525
+ </p>
10526
+ <table id="ewww-settings-disable-resizes">
10527
+ <tr>
10528
+ <th scope="col">
10529
+ <?php esc_html_e( 'Disable Optimization', 'ewww-image-optimizer' ); ?>
10530
+ </th>
10531
+ <th scope="col">
10532
+ <?php esc_html_e( 'Disable Creation', 'ewww-image-optimizer' ); ?>
10533
+ </th>
10534
+ </tr>
10535
+ <?php
10536
+ foreach ( $image_sizes as $size => $dimensions ) :
10537
+ if ( empty( $dimensions['width'] ) && empty( $dimensions['height'] ) ) :
10538
+ continue;
10539
+ endif;
10540
+ ?>
10541
+ <?php if ( 'thumbnail' === $size ) : ?>
10542
+ <tr>
10543
+ <td>
10544
+ <input type='checkbox' id='ewww_image_optimizer_disable_resizes_opt_<?php echo esc_attr( $size ); ?>' name='ewww_image_optimizer_disable_resizes_opt[<?php echo esc_attr( $size ); ?>]' value='true' <?php checked( ! empty( $disabled_sizes_opt[ $size ] ) ); ?> />
10545
+ </td>
10546
+ <td>
10547
+ <input type='checkbox' id='ewww_image_optimizer_disable_resizes_<?php echo esc_attr( $size ); ?>' name='ewww_image_optimizer_disable_resizes[<?php echo esc_attr( $size ); ?>]' value='true' disabled />
10548
+ </td>
10549
+ <td>
10550
+ <label for='ewww_image_optimizer_disable_resizes_<?php echo esc_attr( $size ); ?>'><?php echo esc_attr( $size ) . ' - ' . (int) $dimensions['width'] . ' x ' . (int) $dimensions['height']; ?></label>
10551
+ </td>
10552
+ </tr>
10553
+ <?php elseif ( 'pdf-full' === $size ) : ?>
10554
+ <tr>
10555
+ <td>
10556
+ <input type='checkbox' id='ewww_image_optimizer_disable_resizes_opt_<?php echo esc_attr( $size ); ?>' name='ewww_image_optimizer_disable_resizes_opt[<?php echo esc_attr( $size ); ?>]' value='true' <?php checked( ! empty( $disabled_sizes_opt[ $size ] ) ); ?> />
10557
+ </td>
10558
+ <td>
10559
+ <input type='checkbox' id='ewww_image_optimizer_disable_resizes_<?php echo esc_attr( $size ); ?>' name='ewww_image_optimizer_disable_resizes[<?php echo esc_attr( $size ); ?>]' value='true' <?php checked( ! empty( $disabled_sizes[ $size ] ) ); ?> />
10560
+ </td>
10561
+ <td>
10562
+ <label for='ewww_image_optimizer_disable_resizes_$size'>
10563
+ <?php echo esc_attr( $size ); ?> - <span class='description'><?php esc_html_e( 'Disabling creation of the full-size preview for PDF files will disable all PDF preview sizes', 'ewww-image-optimizer' ); ?></span>
10564
+ </label>
10565
+ </td>
10566
+ </tr>
10567
+ <?php else : ?>
10568
+ <tr>
10569
+ <td>
10570
+ <input type='checkbox' id='ewww_image_optimizer_disable_resizes_opt_<?php echo esc_attr( $size ); ?>' name='ewww_image_optimizer_disable_resizes_opt[<?php echo esc_attr( $size ); ?>]' value='true' <?php checked( ! empty( $disabled_sizes_opt[ $size ] ) ); ?> />
10571
+ </td>
10572
+ <td>
10573
+ <input type='checkbox' id='ewww_image_optimizer_disable_resizes_<?php echo esc_attr( $size ); ?>' name='ewww_image_optimizer_disable_resizes[<?php echo esc_attr( $size ); ?>]' value='true' <?php checked( ! empty( $disabled_sizes[ $size ] ) ); ?> />
10574
+ </td>
10575
+ <td>
10576
+ <label for='ewww_image_optimizer_disable_resizes_$size'><?php echo esc_attr( $size ) . ' - ' . (int) $dimensions['width'] . ' x ' . (int) $dimensions['height']; ?></label>
10577
+ </td>
10578
+ </tr>
10579
+ <?php endif; ?>
10580
+ <?php endforeach; ?>
10581
+ </table>
10582
+ </td>
10583
+ </tr>
10584
+ <?php endif; ?>
10585
+ </table>
10586
+ </div>
10587
+
10588
+ <?php if ( 'network-singlesite' === $network ) : ?>
10589
+ <p class='submit'><input type='submit' class='button-primary' value='<?php esc_attr_e( 'Save Changes', 'ewww-image-optimizer' ); ?>' /></p>
10590
+ </form>
10591
+ </div><!-- end container wrap -->
10592
+ <?php
10593
+ return;
10594
+ endif;
10595
+ /* translators: 1: JPG, GIF or PNG 2: JPG or PNG */
10596
+ $jpg2png = sprintf( __( '%1$s to %2$s Conversion', 'ewww-image-optimizer' ), 'JPG', 'PNG' );
10597
+ /* translators: 1: JPG, GIF or PNG 2: JPG or PNG */
10598
+ $png2jpg = sprintf( __( '%1$s to %2$s Conversion', 'ewww-image-optimizer' ), 'PNG', 'JPG' );
10599
+ /* translators: 1: JPG, GIF or PNG 2: JPG or PNG */
10600
+ $gif2png = sprintf( __( '%1$s to %2$s Conversion', 'ewww-image-optimizer' ), 'GIF', 'PNG' );
10601
+ ?>
10602
+
10603
+ <div id='ewww-conversion-settings'>
10604
+ <noscript><h2><?php esc_html_e( 'Convert', 'ewww-image-optimizer' ); ?></h2></noscript>
10605
+ <p>
10606
+ <?php esc_html_e( 'Conversion is only available for images in the Media Library (except WebP). By default, all images have a link available in the Media Library for one-time conversion. Turning on individual conversion operations below will enable conversion filters any time an image is uploaded or modified.', 'ewww-image-optimizer' ); ?><br />
10607
+ <strong><?php esc_html_e( 'NOTE:', 'ewww-image-optimizer' ); ?></strong> <?php esc_html_e( 'The plugin will attempt to update image locations for any posts that contain the images. You may still need to manually update locations/urls for converted images.', 'ewww-image-optimizer' ); ?>
10608
+ </p>
10609
+ <table class='form-table'>
10610
+ <?php if ( $toolkit_found ) : ?>
10611
+ <tr>
10612
+ <th scope='row'>
10613
+ <label for='ewww_image_optimizer_disable_convert_links'><?php esc_html_e( 'Hide Conversion Links', 'ewww-image-optimizer' ); ?></label>
10614
+ <span><?php ewwwio_help_link( 'https://docs.ewww.io/article/14-converting-images', '58545a86c697912ffd6c1b53' ); ?></span>
10615
+ </th>
10616
+ <td>
10617
+ <input type='checkbox' id='ewww_image_optimizer_disable_convert_links' name='ewww_image_optimizer_disable_convert_links' value='true' <?php checked( ewww_image_optimizer_get_option( 'ewww_image_optimizer_disable_convert_links' ) ); ?> />
10618
+ <span><?php esc_html_e( 'Site or Network admins can use this to prevent other users from using the conversion links in the Media Library which bypass the settings below.', 'ewww-image-optimizer' ); ?></span>
10619
+ </td>
10620
+ </tr>
10621
+ <tr>
10622
+ <th scope='row'>
10623
+ <label for='ewww_image_optimizer_delete_originals'><?php esc_html_e( 'Delete Originals', 'ewww-image-optimizer' ); ?></label>
10624
+ <span><?php ewwwio_help_link( 'https://docs.ewww.io/article/14-converting-images', '58545a86c697912ffd6c1b53' ); ?></span>
10625
+ </th>
10626
+ <td>
10627
+ <input type='checkbox' id='ewww_image_optimizer_delete_originals' name='ewww_image_optimizer_delete_originals' value='true' <?php checked( ewww_image_optimizer_get_option( 'ewww_image_optimizer_delete_originals' ) ); ?> />
10628
+ <span><?php esc_html_e( 'This will remove the original image from the server after a successful conversion.', 'ewww-image-optimizer' ); ?></span>
10629
+ </td>
10630
+ </tr>
10631
+ <tr>
10632
+ <th scope='row'>
10633
+ <label for='ewww_image_optimizer_jpg_to_png'><?php echo esc_html( $jpg2png ); ?></label>
10634
+ <span><?php ewwwio_help_link( 'https://docs.ewww.io/article/14-converting-images', '58545a86c697912ffd6c1b53' ); ?></span>
10635
+ </th>
10636
+ <td>
10637
+ <input type='checkbox' id='ewww_image_optimizer_jpg_to_png' name='ewww_image_optimizer_jpg_to_png' value='true' <?php checked( ewww_image_optimizer_get_option( 'ewww_image_optimizer_jpg_to_png' ) ); ?> />
10638
+ <span><b><?php esc_html_e( 'WARNING:', 'ewww-image-optimizer' ); ?></b> <?php esc_html_e( 'Removes metadata and increases cpu usage dramatically.', 'ewww-image-optimizer' ); ?></span>
10639
+ <p class='description'><?php esc_html_e( 'PNG is generally much better than JPG for logos and other images with a limited range of colors. Checking this option will slow down JPG processing significantly, and you may want to enable it only temporarily.', 'ewww-image-optimizer' ); ?></p>
10640
+ </td>
10641
+ </tr>
10642
+ <tr>
10643
+ <th scope='row'>
10644
+ <label for='ewww_image_optimizer_png_to_jpg'><?php echo esc_html( $png2jpg ); ?></label>
10645
+ <span><?php ewwwio_help_link( 'https://docs.ewww.io/article/14-converting-images', '58545a86c697912ffd6c1b53,58543c69c697912ffd6c19a7,58542afac697912ffd6c18c0' ); ?></span>
10646
+ </th>
10647
+ <td>
10648
+ <input type='checkbox' id='ewww_image_optimizer_png_to_jpg' name='ewww_image_optimizer_png_to_jpg' value='true' <?php checked( ewww_image_optimizer_get_option( 'ewww_image_optimizer_png_to_jpg' ) ); ?> />
10649
+ <span><b><?php esc_html_e( 'WARNING:', 'ewww-image-optimizer' ); ?></b> <?php esc_html_e( 'This is not a lossless conversion.', 'ewww-image-optimizer' ); ?></span>
10650
+ <p class='description'><?php esc_html_e( 'JPG is generally much better than PNG for photographic use because it compresses the image and discards data. PNGs with transparency are not converted by default.', 'ewww-image-optimizer' ); ?></p>
10651
+ <label for='ewww_image_optimizer_jpg_background'><strong><?php esc_html_e( 'JPG Background Color:', 'ewww-image-optimizer' ); ?></strong></label>
10652
+ #<input type='text' id='ewww_image_optimizer_jpg_background' name='ewww_image_optimizer_jpg_background' size='6' value='<?php echo esc_attr( ewww_image_optimizer_jpg_background() ); ?>' />
10653
+ <span style='padding-left: 12px; font-size: 12px; border: solid 1px #555555; background-color: #<?php echo esc_attr( ewww_image_optimizer_jpg_background() ); ?>'>&nbsp;</span> <?php esc_html_e( 'HEX format (#123def)', 'ewww-image-optimizer' ); ?></span>
10654
+ <p class='description'><?php esc_html_e( 'Background color is used only if the PNG has transparency. Leave this value blank to skip PNGs with transparency.', 'ewww-image-optimizer' ); ?></p>
10655
+ </td>
10656
+ </tr>
10657
+ <tr>
10658
+ <th scope='row'>
10659
+ <label for='ewww_image_optimizer_gif_to_png'><?php echo esc_html( $gif2png ); ?></label>
10660
+ <span><?php ewwwio_help_link( 'https://docs.ewww.io/article/14-converting-images', '58545a86c697912ffd6c1b53' ); ?></span>
10661
+ </th>
10662
+ <td>
10663
+ <input type='checkbox' id='ewww_image_optimizer_gif_to_png' name='ewww_image_optimizer_gif_to_png' value='true' <?php checked( ewww_image_optimizer_get_option( 'ewww_image_optimizer_gif_to_png' ) ); ?> />
10664
+ <span><?php esc_html_e( 'No warnings here, just do it.', 'ewww-image-optimizer' ); ?></span>
10665
+ <p class='description'><?php esc_html_e( 'PNG is generally better than GIF, but animated images cannot be converted.', 'ewww-image-optimizer' ); ?></p>
10666
+ </td>
10667
+ </tr>
10668
+ <?php else : ?>
10669
+ <tr>
10670
+ <th>&nbsp;</th>
10671
+ <td>
10672
+ <p>
10673
+ <span style="color: #3eadc9"><?php esc_html_e( 'Image conversion requires one of the following PHP libraries: GD, Imagick, or GMagick.', 'ewww-image-optimizer' ); ?></span>
10674
+ </p>
10675
+ </td>
10676
+ </tr>
10677
+ <?php endif; ?>
10678
+ </table>
10679
+ </div>
10680
+
10681
+ <?php
10682
+ $rewrite_notice = ( ewww_image_optimizer_get_option( 'ewww_image_optimizer_webp' ) && ! ewww_image_optimizer_get_option( 'ewww_image_optimizer_webp_for_cdn' ) && ! ewww_image_optimizer_get_option( 'ewww_image_optimizer_picture_webp' ) ? __( 'You can use the rewrite rules below to serve WebP images with Apache.', 'ewww-image-optimizer' ) : '' );
10683
+ $webp_exclude_paths = ewww_image_optimizer_get_option( 'ewww_image_optimizer_webp_rewrite_exclude' ) ? implode( "\n", ewww_image_optimizer_get_option( 'ewww_image_optimizer_webp_rewrite_exclude' ) ) : '';
10684
+ $webp_paths = ewww_image_optimizer_get_option( 'ewww_image_optimizer_webp_paths' ) ? implode( "\n", ewww_image_optimizer_get_option( 'ewww_image_optimizer_webp_paths' ) ) : '';
10685
+ $webp_url_example = sprintf(
10686
+ /* translators: 1: An image URL on a CDN 2: An image URL 3: An example folder URL */
10687
+ esc_html__( 'For example, with a CDN URL of %1$s and a local URL of %2$s you would enter %3$s.', 'ewww-image-optimizer' ),
10688
+ 'https://cdn.example.com/<strong>files/</strong>2038/01/image.jpg',
10689
+ 'https://example.com/<strong>wp-content/uploads/</strong>2038/01/image.jpg',
10690
+ 'https://cdn.example.com/<strong>files/</strong>'
10691
+ );
10692
+ ?>
10693
+
10694
+ <div id='ewww-webp-settings'>
10695
+ <noscript><h2><?php esc_html_e( 'WebP', 'ewww-image-optimizer' ); ?></h2></noscript>
10696
+ <?php if ( ! ewww_image_optimizer_get_option( 'ewww_image_optimizer_exactdn' ) && ! ewww_image_optimizer_easy_active() ) : ?>
10697
+ <p>
10698
+ <?php esc_html_e( 'Once JPG/PNG to WebP 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>
10699
+ <a href='https://ewww.io/easy/'><?php esc_html_e( 'Get Easy IO for automatic WebP conversion and delivery.', 'ewww-image-optimizer' ); ?></a>
10700
+ </p>
10701
+ <?php endif; ?>
10702
+ <table class='form-table'>
10703
+ <?php if ( ! ewww_image_optimizer_easy_active() || ewww_image_optimizer_get_option( 'ewww_image_optimizer_webp' ) ) : ?>
10704
+ <tr>
10705
+ <th scope='row'>
10706
+ <label for='ewww_image_optimizer_webp'><?php esc_html_e( 'JPG/PNG to WebP', 'ewww-image-optimizer' ); ?></label>
10707
+ <span><?php ewwwio_help_link( 'https://docs.ewww.io/article/16-ewww-io-and-webp-images', '5854745ac697912ffd6c1c89' ); ?></span>
10708
+ </th>
10709
+ <td>
10710
+ <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' ) ); ?> />
10711
+ <span><?php esc_html_e( 'JPG to WebP conversion is lossy, but quality loss is minimal. PNG to WebP conversion is lossless.', 'ewww-image-optimizer' ); ?></span>
10712
+ <p class='description'>
10713
+ <?php esc_html_e( 'Originals are never deleted, and WebP images should only be served to supported browsers.', 'ewww-image-optimizer' ); ?>
10714
+ <a href='#ewww-webp-rewrite'><?php echo esc_html( $rewrite_notice ); ?></a>
10715
+ </p>
10716
+ </td>
10717
+ </tr>
10718
+ <?php endif; ?>
10719
+
10720
+ <?php if ( ! ewww_image_optimizer_ce_webp_enabled() && ! ewww_image_optimizer_easy_active() ) : ?>
10721
+ <tr>
10722
+ <th scope='row'>
10723
+ <label for='ewww_image_optimizer_webp_for_cdn'><?php esc_html_e( 'JS WebP Rewriting', 'ewww-image-optimizer' ); ?></label>
10724
+ <span><?php ewwwio_help_link( 'https://docs.ewww.io/article/16-ewww-io-and-webp-images', '5854745ac697912ffd6c1c89,59443d162c7d3a0747cdf9f0' ); ?></span>
10725
+ </th>
10726
+ <td>
10727
+ <input type='checkbox' id='ewww_image_optimizer_webp_for_cdn' name='ewww_image_optimizer_webp_for_cdn' value='true' <?php checked( ewww_image_optimizer_get_option( 'ewww_image_optimizer_webp_for_cdn' ) ); ?> />
10728
+ <span><?php esc_html_e( 'Use this if the Apache rewrite rules do not work, or if your images are served from a CDN.', 'ewww-image-optimizer' ); ?></span>
10729
+ <p class='description'><?php esc_html_e( 'Supports CSS background images with Lazy Load option on the Easy Mode tab.', 'ewww-image-optimizer' ); ?></p>
10730
+ </td>
10731
+ </tr>
10732
+ <tr>
10733
+ <th scope='row'>
10734
+ <label for='ewww_image_optimizer_picture_webp'><?php esc_html_e( '<picture> WebP Rewriting', 'ewww-image-optimizer' ); ?></label>
10735
+ <span><?php ewwwio_help_link( 'https://docs.ewww.io/article/16-ewww-io-and-webp-images', '5854745ac697912ffd6c1c89,59443d162c7d3a0747cdf9f0' ); ?></span>
10736
+ </th>
10737
+ <td>
10738
+ <input type='checkbox' id='ewww_image_optimizer_picture_webp' name='ewww_image_optimizer_picture_webp' value='true' <?php checked( ewww_image_optimizer_get_option( 'ewww_image_optimizer_picture_webp' ) ); ?> />
10739
+ <span><?php esc_html_e( 'A JavaScript-free rewriting method using picture tags.', 'ewww-image-optimizer' ); ?></span>
10740
+ <p class='description'><?php esc_html_e( 'Use this if Apache rewrite rules do not work for your site. Some themes may not display <picture> tags properly, and does not support CSS background images.', 'ewww-image-optimizer' ); ?></p>
10741
+ </td>
10742
+ </tr>
10743
+ <tr>
10744
+ <td>&nbsp;</td>
10745
+ <td>
10746
+ <label for='ewww_image_optimizer_webp_rewrite_exclude'><?php esc_html_e( 'JS WebP and <picture> Web Exclusions', 'ewww-image-optimizer' ); ?></label><br>
10747
+ <textarea id='ewww_image_optimizer_webp_rewrite_exclude' name='ewww_image_optimizer_webp_rewrite_exclude' rows='3' cols='60'><?php echo esc_html( $webp_exclude_paths ); ?></textarea>
10748
+ <p class='description'><?php esc_html_e( 'One exclusion per line, no wildcards (*) needed. Use any string that matches the desired element(s) or exclude entire element types like "div", "span", etc.', 'ewww-image-optimizer' ); ?></p>
10749
+ </td>
10750
+ </tr>
10751
+ <tr>
10752
+ <th scope='row'>
10753
+ <label for='ewww_image_optimizer_webp_paths'><?php esc_html_e( 'WebP URLs', 'ewww-image-optimizer' ); ?></label>
10754
+ <span><?php ewwwio_help_link( 'https://docs.ewww.io/article/16-ewww-io-and-webp-images', '5854745ac697912ffd6c1c89' ); ?></span>
10755
+ </th>
10756
+ <td>
10757
+ <span><?php esc_html_e( 'Enter additional URL patterns, like a CDN URL, that should be permitted for JS WebP Rewriting. One URL per line, must include the domain name (cdn.example.com).', 'ewww-image-optimizer' ); ?></span>
10758
+ <p><?php esc_html_e( 'Optionally include a folder with the URL if your CDN path is different from your local path.', 'ewww-image-optimizer' ); ?></p>
10759
+ <textarea id='ewww_image_optimizer_webp_paths' name='ewww_image_optimizer_webp_paths' rows='3' cols='60'><?php echo esc_html( $webp_paths ); ?></textarea>
10760
+ <p class='description'><?php echo wp_kses_post( $webp_url_example ); ?></p>
10761
+ </td>
10762
+ </tr>
10763
+ <?php elseif ( ewww_image_optimizer_get_option( 'ewww_image_optimizer_exactdn' ) ) : ?>
10764
+ <tr>
10765
+ <th>&nbsp;</th>
10766
+ <td>
10767
+ <p class='description'><?php esc_html_e( 'WebP images are served automatically by Easy IO.', 'ewww-image-optimizer' ); ?></p>
10768
+ </td>
10769
+ </tr>
10770
+ <?php elseif ( get_option( 'easyio_exactdn' ) ) : ?>
10771
+ <tr>
10772
+ <th>&nbsp;</th>
10773
+ <td>
10774
+ <p class='description'><?php esc_html_e( 'WebP images are served automatically by Easy Image Optimizer.', 'ewww-image-optimizer' ); ?></p>
10775
+ </td>
10776
+ </tr>
10777
+ <?php endif; ?>
10778
+
10779
+ <?php if ( ! ewww_image_optimizer_easy_active() || ewww_image_optimizer_get_option( 'ewww_image_optimizer_webp' ) ) : ?>
10780
+ <tr>
10781
+ <th scope='row'>
10782
+ <label for='ewww_image_optimizer_webp_force'><?php esc_html_e( 'Force WebP', 'ewww-image-optimizer' ); ?></label>
10783
+ <span><?php ewwwio_help_link( 'https://docs.ewww.io/article/16-ewww-io-and-webp-images', '5854745ac697912ffd6c1c89' ); ?></span>
10784
+ </th>
10785
+ <td>
10786
+ <input type='checkbox' id='ewww_image_optimizer_webp_force' name='ewww_image_optimizer_webp_force' value='true' <?php checked( ewww_image_optimizer_get_option( 'ewww_image_optimizer_webp_force' ) ); ?> />
10787
+ <span><?php esc_html_e( 'WebP images will be generated and saved for all JPG/PNG images regardless of their size. The JS WebP Rewriting will not check if a file exists, only that the domain matches the home url, or one of the provided WebP URLs.', 'ewww-image-optimizer' ); ?></span>
10788
+ </td>
10789
+ </tr>
10790
+ <?php endif; ?>
10791
+ </table>
10792
+ </div>
10793
+
10794
+ <div id='ewww-support-settings'>
10795
+ <noscript><h2><?php esc_html_e( 'Support', 'ewww-image-optimizer' ); ?></h2></noscript>
10796
+ <p>
10797
+ <a class='ewww-docs-root' href='https://docs.ewww.io/'><?php esc_html_e( 'Documentation', 'ewww-image-optimizer' ); ?></a> |
10798
+ <a class='ewww-docs-root' href='https://ewww.io/contact-us/'><?php esc_html_e( 'Plugin Support', 'ewww-image-optimizer' ); ?></a> |
10799
+ <a href='https://feedback.ewww.io/'><?php esc_html_e( 'Submit Feedback', 'ewww-image-optimizer' ); ?></a> |
10800
+ <a href='https://ewww.io/chat/'><?php esc_html_e( 'Community Chat', 'ewww-image-optimizer' ); ?></a> |
10801
+ <a href='https://ewww.io/status/'><?php esc_html_e( 'Server Status', 'ewww-image-optimizer' ); ?></a>
10802
+ </p>
10803
+ <table class='form-table'>
10804
+ <tr>
10805
+ <th scope='row'>
10806
+ <label for='ewww_image_optimizer_enable_help'><?php esc_html_e( 'Enable Embedded Help', 'ewww-image-optimizer' ); ?></label>
10807
+ </th>
10808
+ <td>
10809
+ <input type='checkbox' id='ewww_image_optimizer_enable_help' name='ewww_image_optimizer_enable_help' value='true' <?php checked( ewww_image_optimizer_get_option( 'ewww_image_optimizer_enable_help' ) ); ?> />
10810
+ <span><?php esc_html_e( 'Enable the support beacon, which gives you access to documentation and our support team right from your WordPress dashboard. To assist you more efficiently, we may collect the current url, IP address, browser/device information, and debugging information.', 'ewww-image-optimizer' ); ?></span>
10811
+ </td>
10812
+ </tr>
10813
+ <tr>
10814
+ <th scope='row'>
10815
+ <label for='ewww_image_optimizer_debug'><?php esc_html_e( 'Debugging', 'ewww-image-optimizer' ); ?></label>
10816
+ <span><?php ewwwio_help_link( 'https://docs.ewww.io/article/7-basic-configuration', '585373d5c697912ffd6c0bb2' ); ?></span>
10817
+ </th>
10818
+ <td>
10819
+ <input type='checkbox' id='ewww_image_optimizer_debug' name='ewww_image_optimizer_debug' value='true' <?php checked( ewww_image_optimizer_get_option( 'ewww_image_optimizer_debug' ) ); ?> />
10820
+ <span><?php esc_html_e( 'Use this to provide information for support purposes, or if you feel comfortable digging around in the code to fix a problem you are experiencing.', 'ewww-image-optimizer' ); ?></span>
10821
+ </td>
10822
+ </tr>
10823
+ </table>
10824
+
10825
+ <?php if ( ! empty( $debug_info ) ) : ?>
10826
+ <p class="debug-actions">
10827
+ <strong><?php esc_html_e( 'Debugging Information', 'ewww-image-optimizer' ); ?>:</strong>
10828
+ <button id="ewww-copy-debug" class="button button-secondary" type="button"><?php esc_html_e( 'Copy', 'ewww-image-optimizer' ); ?></button>
10829
+ <?php if ( ewwwio_is_file( WP_CONTENT_DIR . '/ewww/debug.log' ) ) : ?>
10830
+ &emsp;<a href='<?php echo esc_url( admin_url( 'admin.php?action=ewww_image_optimizer_view_debug_log' ) ); ?>'><?php esc_html_e( 'View Debug Log', 'ewww-image-optimizer' ); ?></a> -
10831
+ <a href='<?php echo esc_url( admin_url( 'admin.php?action=ewww_image_optimizer_delete_debug_log' ) ); ?>'><?php esc_html_e( 'Remove Debug Log', 'ewww-image-optimizer' ); ?></a>
10832
+ <?php endif; ?>
10833
+ </p>
10834
+ <div id="ewww-debug-info" contenteditable="true">
10835
+ <?php echo wp_kses_post( $debug_info ); ?>
10836
+ </div>
10837
+ <?php endif; ?>
10838
+ </div>
10839
+
10840
+ <div id='ewww-contribute-settings'>
10841
+ <noscript><h2><?php esc_html_e( 'Contribute', 'ewww-image-optimizer' ); ?></h2></noscript>
10842
+ <p>
10843
+ <strong><?php esc_html_e( 'Here are some ways you can contribute to the development of this plugin:', 'ewww-image-optimizer' ); ?></strong>
10844
+ </p>
10845
+ <p>
10846
+ <a href='https://translate.wordpress.org/projects/wp-plugins/ewww-image-optimizer/'><?php esc_html_e( 'Translate EWWW I.O.', 'ewww-image-optimizer' ); ?></a> |
10847
+ <a href='https://wordpress.org/support/plugin/ewww-image-optimizer/reviews/#new-post'><?php esc_html_e( 'Write a review', 'ewww-image-optimizer' ); ?></a> |
10848
+ <a href='https://ewww.io/plans/'><?php esc_html_e( 'Upgrade to premium image optimization', 'ewww-image-optimizer' ); ?></a>
10849
+ </p>
10850
+ <table class='form-table'>
10851
+ <tr>
10852
+ <th scope='row'>
10853
+ <label for='ewww_image_optimizer_allow_tracking'><?php esc_html_e( 'Allow Usage Tracking?', 'ewww-image-optimizer' ); ?></label>
10854
+ <span><?php ewwwio_help_link( 'https://docs.ewww.io/article/23-usage-tracking', '591f3a8e2c7d3a057f893d91' ); ?></span>
10855
+ </th>
10856
+ <td>
10857
+ <input type='checkbox' id='ewww_image_optimizer_allow_tracking' name='ewww_image_optimizer_allow_tracking' value='true' <?php checked( ewww_image_optimizer_get_option( 'ewww_image_optimizer_allow_tracking' ) ); ?> />
10858
+ <span><?php esc_html_e( 'Allow EWWW Image Optimizer to anonymously track how this plugin is used and help us make the plugin better. Opt-in to tracking and receive 500 API image credits free. No sensitive data is tracked.', 'ewww-image-optimizer' ); ?></span>
10859
+ </td>
10860
+ </tr>
10861
+ </table>
10862
+ </div>
10863
+ <p class='submit'><input type='submit' class='button-primary' value='<?php esc_attr_e( 'Save Changes', 'ewww-image-optimizer' ); ?>' /></p>
10864
+ </form>
10865
+
10866
+ <?php
10867
  // Make sure .htaccess rules are terminated when ExactDN is enabled or if Cloudflare is detected.
10868
  $cf_host = ewwwio_is_cf_host();
10869
  if ( ewww_image_optimizer_easy_active() || $cf_host ) {
10870
  ewww_image_optimizer_webp_rewrite_verify();
10871
  }
10872
+ $test_webp_image = plugins_url( '/images/test.png.webp', __FILE__ );
10873
+ $test_png_image = plugins_url( '/images/test.png', __FILE__ );
 
10874
  if (
10875
  ! $cf_host &&
10876
  ewww_image_optimizer_get_option( 'ewww_image_optimizer_webp' ) &&
10879
  ! ewww_image_optimizer_ce_webp_enabled() && ! ewww_image_optimizer_easy_active()
10880
  ) {
10881
  if ( defined( 'PHP_SAPI' ) && false === strpos( PHP_SAPI, 'apache' ) && false === strpos( PHP_SAPI, 'litespeed' ) ) {
 
10882
  $false_positive_headers = esc_html( 'This may be a false positive. If so, the warning should go away once you implement the rewrite rules.' );
10883
  }
10884
  $header_error = '';
10885
  if ( ! apache_mod_loaded( 'mod_rewrite' ) ) {
 
10886
  /* translators: %s: mod_rewrite or mod_headers */
10887
+ $header_error = '<p><strong>' . sprintf( esc_html__( 'Your site appears to be missing %s, please contact your webhost or system administrator to enable this Apache module.', 'ewww-image-optimizer' ), 'mod_rewrite' ) . "</strong><br>$false_positive_headers</p>\n";
10888
  }
10889
  if ( ! apache_mod_loaded( 'mod_headers' ) ) {
10890
  /* translators: %s: mod_rewrite or mod_headers */
10891
+ $header_error = '<p><strong>' . sprintf( esc_html__( 'Your site appears to be missing %s, please contact your webhost or system administrator to enable this Apache module.', 'ewww-image-optimizer' ), 'mod_headers' ) . "</strong><br>$false_positive_headers</p>\n";
 
10892
  }
10893
 
10894
  $webp_verified = ewww_image_optimizer_test_webp_mime_verify();
10895
  if ( ! $webp_verified ) {
10896
+ echo wp_kses_post( $header_error );
10897
  }
10898
 
10899
  if ( $webp_verified || ! ewww_image_optimizer_webp_rewrite_verify() ) {
10900
+ ?>
10901
+ <form id='ewww-webp-rewrite'>
10902
+ <img id='webp-image' src='<?php echo esc_url( $test_png_image . '?m=' . time() ); ?>' style='float: right; padding: 0 1px 10px 10px;'>
10903
+ <p id='ewww-webp-rewrite-status'><strong><?php esc_html_e( 'Rules verified successfully', 'ewww-image-optimizer' ); ?></strong></p>
10904
+ <button type='button' id='ewww-webp-remove' class='button-secondary action'><?php esc_html_e( 'Remove Rewrite Rules', 'ewww-image-optimizer' ); ?></button>
10905
+ </form>
10906
+ <?php } else { ?>
10907
+ <p><?php esc_html_e( 'There are many ways to serve WebP images to visitors with supported browsers. You may choose any you wish, but it is recommended to serve them with an .htaccess file using mod_rewrite and mod_headers. The plugin can insert the rules for you if the file is writable, or you can edit .htaccess yourself.', 'ewww-image-optimizer' ); ?></p>
10908
+ <form id='ewww-webp-rewrite'>
10909
+ <pre id='webp-rewrite-rules' style='background: white; font-color: black; border: 1px solid black; clear: both; padding: 10px;'>
10910
+ &lt;IfModule mod_rewrite.c&gt;
10911
+ RewriteEngine On
10912
+ RewriteCond %{HTTP_ACCEPT} image/webp
10913
+ RewriteCond %{REQUEST_FILENAME} (.*)\.(jpe?g|png)$
10914
+ RewriteCond %{REQUEST_FILENAME}\.webp -f
10915
+ RewriteCond %{QUERY_STRING} !type=original
10916
+ RewriteRule (.+)\.(jpe?g|png)$ %{REQUEST_FILENAME}.webp [T=image/webp,E=accept:1,L]
10917
+ &lt;/IfModule&gt;
10918
+ &lt;IfModule mod_headers.c&gt;
10919
+ Header append Vary Accept env=REDIRECT_accept
10920
+ &lt;/IfModule&gt;
10921
+ AddType image/webp .webp</pre>
10922
+ <img id='webp-image' src='<?php echo esc_url( $test_png_image . '?m=' . time() ); ?>' style='float: right; padding-left: 10px;'>
10923
+ <p id='ewww-webp-rewrite-status'><?php esc_html_e( 'The image to the right will display a WebP image with WEBP in white text, if your site is serving WebP images and your browser supports WebP.', 'ewww-image-optimizer' ); ?></p>
10924
+ <button type='button' id='ewww-webp-insert' class='button-secondary action'><?php esc_html_e( 'Insert Rewrite Rules', 'ewww-image-optimizer' ); ?></button>
10925
+ <?php } ?>
10926
+ </form>
10927
+ <?php } elseif ( ewww_image_optimizer_get_option( 'ewww_image_optimizer_webp_for_cdn' ) && ! ewww_image_optimizer_ce_webp_enabled() ) { ?>
10928
+ <noscript data-img='<?php echo esc_url( $test_png_image ); ?>' data-webp='<?php echo esc_url( $test_webp_image ); ?>' data-style='padding: 0 0 10px 0;' class='ewww_webp'>
10929
+ <img src='<?php echo esc_url( $test_png_image ); ?>' style='float: right; padding: 0 0 10px 10px;'>
10930
+ </noscript>
10931
+ <?php } elseif ( ewww_image_optimizer_get_option( 'ewww_image_optimizer_picture_webp' ) && ! ewww_image_optimizer_ce_webp_enabled() ) { ?>
10932
+ <picture>
10933
+ <source srcset='<?php echo esc_url( $test_webp_image ); ?>' type='image/webp'>
10934
+ <img src='<?php echo esc_url( $test_webp_image ); ?>' style='padding: 0 0 10px 0;'>
10935
+ </picture>
10936
+ <?php } elseif ( $cf_host && ewww_image_optimizer_get_option( 'ewww_image_optimizer_webp' ) ) { ?>
10937
+ <p><?php esc_html_e( 'Your site is using Cloudflare, please use JS WebP or <picture> WebP rewriting.', 'ewww-image-optimizer' ); ?></p>
10938
+ <?php } ?>
10939
+
10940
+ <?php
 
 
 
 
 
 
 
 
 
10941
  if ( ewww_image_optimizer_get_option( 'ewww_image_optimizer_webp_for_cdn' ) && ! ewww_image_optimizer_ce_webp_enabled() && ! ewww_image_optimizer_easy_active() ) {
10942
+ if ( ! isset( $eio_alt_webp ) ) {
10943
+ require_once( EWWW_IMAGE_OPTIMIZER_PLUGIN_PATH . 'classes/class-eio-page-parser.php' );
10944
+ require_once( EWWW_IMAGE_OPTIMIZER_PLUGIN_PATH . 'classes/class-eio-alt-webp.php' );
10945
+ }
10946
  $eio_alt_webp->inline_script();
10947
  }
10948
 
10949
+ echo '<hr style="clear:both;"><div id="ewwwio-banner"><img src="' . esc_url( plugins_url( '/images/ewwwio-logo.png', __FILE__ ) ) . '">' .
10950
+ '<p>' . esc_html__( 'Get performance tips, exclusive discounts, and the latest news when you signup for our newsletter!', 'ewww-image-optimizer' ) . '</p>' .
10951
+ '<a href="https://eepurl.com/gKyU6L?TB_iframe=true&width=600&height=610" class="thickbox button-secondary">' . esc_html__( 'Subscribe now!', 'ewww-image-optimizer' ) . ' &rarr;</a></div>';
10952
+
10953
+ echo '<h2>' . esc_html__( "Shane's Recommendations", 'ewww-image-optimizer' ) . '</h2>';
10954
+ echo '<p>' . esc_html__( 'These are products I have personally used. An * indicates an affiliate link so you can support future development of EWWW IO.', 'ewww-image-optimizer' ) . '</p>';
10955
+ echo '<h3>' . esc_html__( 'Hosting', 'ewww-image-optimizer' ) . '</h3>' .
10956
+ '<p><a href="http://shareasale.com/r.cfm?b=917225&amp;u=1481701&amp;m=41388&amp;urllink=&amp;afftrack=">WP Engine</a>* - ' .
10957
+ esc_html__( 'ewww.io is powered by WP Engine, and their performance is worth every penny. This is "managed WordPress hosting" at it\'s finest. 20% discount off your first payment with our link.', 'ewww-image-optimizer' ) .
10958
+ '<br><a href="https://www.siteground.com/wordpress-hosting.htm?afcode=bd82f2335e9c794c1ba7ff4cc3a8b3fd">SiteGround</a>* - ' .
10959
+ esc_html__( 'With their SuperCacher system, the performance is amazing, and their support is pretty good also. I\'ve only used their GoGeek plan, so that\'s what I recommend.', 'ewww-image-optimizer' ) .
10960
+ '<br><a href="https://kinsta.com?kaid=OCKKBJARSDFR">Kinsta</a>* - ' .
10961
+ esc_html__( 'Their performance is the same blazing speed as WP Engine, and the support is top notch as well. In addition, they offer SSH access with WP-CLI. Very solid offering and highly recommended.', 'ewww-image-optimizer' ) .
10962
+ '<br><a href="http://www.a2hosting.com/?aid=b6322137">A2 Hosting</a>* - ' .
10963
+ esc_html__( 'I use them for several sites and this is pretty much the fastest shared hosting money can buy.', 'ewww-image-optimizer' ) .
10964
+ '<br><a href="https://vrlps.co/kXJu5yF/cp">Cloudways</a>* - ' .
10965
+ esc_html__( 'Simple, yet powerful, managed VPS hosting. I use their hosting for a few client sites and performance is crazy fast. Support has been great any time I\'ve needed their assistance.', 'ewww-image-optimizer' ) .
10966
+ '</p>' .
10967
+ '<h3>' . esc_html__( 'Plugins and Services', 'ewww-image-optimizer' ) . '</h3>' .
10968
+ '<p><a href="https://easydigitaldownloads.com/?ref=4735">Easy Digital Downloads</a>* - ' .
10969
+ esc_html__( 'Sell digital products with a huge number of extensions for amazing flexibility. Naturally, this is how we sell our services and plugins.', 'ewww-image-optimizer' ) .
10970
+ '<br><a href="https://tomasz-dobrzynski.com/wordpress-gonzales">Gonzales</a> - ' .
10971
+ esc_html__( 'Lets you customize the loading of JS and CSS resources so that every page has only what is needed to operate.', 'ewww-image-optimizer' ) .
10972
+ '<br><a href="https://www.helpscout.net/referral/?code=SVhaTmZDSSt2WG4xYS9FRmZrNllUa3RSR25VTStXcGhmaStQQ21QQjBDVmdZdz09OnoyVTFIUzBnbldtM21VMEM.">Helpscout</a>* - ' .
10973
+ esc_html__( 'Treat your customers like people, not numbers, and keep them satisfied. Personal favorite feature is Traffic Cop that keeps you from sending a message if you receive another message from the customer while you are typing.', 'ewww-image-optimizer' ) .
10974
+ '<br><a href="http://eepurl.com/cLPIeD">MailChimp</a>* - ' .
10975
+ esc_html__( 'Mailing lists that just work plus automation features that work even when you\'re not.', 'ewww-image-optimizer' ) .
10976
+ '<br><a href="https://malcare.com?src=C600E7">MalCare</a>* - ' .
10977
+ esc_html__( 'Secure your site with a firewall, advanced heuristic scanning, and brute force login protection. Securing your site is not an option, it\'s a necessity.', 'ewww-image-optimizer' ) .
10978
+ '<br><a href="https://nodeping.com?rid=201407082225W862K">NodePing</a>* - ' .
10979
+ esc_html__( 'Monitor all the things, and make sure they stay online. They have a fantastic array of monitors and notifications that you can setup, they are cheap, simple, and have great support.', 'ewww-image-optimizer' ) .
10980
+ '</p>';
10981
+
10982
+ echo "</div><!-- end container wrap -->\n";
10983
  if ( ewww_image_optimizer_get_option( 'ewww_image_optimizer_enable_help' ) ) {
10984
  $current_user = wp_get_current_user();
10985
  $help_email = $current_user->user_email;
10986
  $hs_debug = '';
10987
+ if ( ! empty( $debug_info ) ) {
10988
+ $hs_debug = str_replace( array( "'", '<br>', '<b>', '</b>', '=>' ), array( "\'", '\n', '**', '**', '=' ), $debug_info );
10989
  }
10990
  ?>
10991
  <script type="text/javascript">!function(e,t,n){function a(){var e=t.getElementsByTagName("script")[0],n=t.createElement("script");n.type="text/javascript",n.async=!0,n.src="https://beacon-v2.helpscout.net",e.parentNode.insertBefore(n,e)}if(e.Beacon=n=function(t,n,a){e.Beacon.readyQueue.push({method:t,options:n,data:a})},n.readyQueue=[],"complete"===t.readyState)return a();e.attachEvent?e.attachEvent("onload",a):e.addEventListener("load",a,!1)}(window,document,window.Beacon||function(){});</script>
10992
  <script type="text/javascript">
10993
  window.Beacon('init', 'aa9c3d3b-d4bc-4e9b-b6cb-f11c9f69da87');
10994
  Beacon( 'prefill', {
10995
+ email: '<?php echo esc_js( utf8_encode( $help_email ) ); ?>',
10996
+ text: '\n\n----------------------------------------\n<?php echo wp_kses_post( $hs_debug ); ?>',
10997
  });
10998
  </script>
10999
  <?php
11062
  }
11063
 
11064
  /**
11065
+ * Gets the HTML for a help icon linked to the docs.
11066
  *
11067
  * @param string $link A link to the documentation.
11068
  * @param string $hsid The HelpScout ID for the docs article. Optional.
11069
  * @return string An HTML hyperlink element with a help icon.
11070
  */
11071
+ function ewwwio_get_help_link( $link, $hsid = '' ) {
11072
+ ob_start();
11073
+ ewwwio_help_link( $link, $hsid );
11074
+ return ob_get_clean();
11075
+ }
11076
+
11077
+ /**
11078
+ * Displays a help icon linked to the docs.
11079
+ *
11080
+ * @param string $link A link to the documentation.
11081
+ * @param string $hsid The HelpScout ID for the docs article. Optional.
11082
+ */
11083
  function ewwwio_help_link( $link, $hsid = '' ) {
11084
  $help_icon = plugins_url( '/images/question-circle.png', __FILE__ );
11085
  $beacon_attr = '';
11086
  $link_class = 'ewww-help-icon';
11087
  if ( strpos( $hsid, ',' ) ) {
11088
+ $beacon_attr = 'data-beacon-articles';
11089
  $link_class = 'ewww-help-beacon-multi';
11090
  } elseif ( $hsid ) {
11091
+ $beacon_attr = 'data-beacon-article';
11092
  $link_class = 'ewww-help-beacon-single';
11093
  }
11094
+ echo '<a class="' . esc_attr( $link_class ) . '" href="' . esc_url( $link ) . '" target="_blank" ' . esc_attr( $beacon_attr ) . '="' . esc_attr( $hsid ) . '">' .
11095
+ '<img title="' . esc_attr__( 'Help', 'ewww-image-optimizer' ) . '" src="' . esc_url( $help_icon ) . '">' .
11096
+ '</a>';
11097
  }
11098
 
11099
  /**
11138
  ewww_image_optimizer_set_option( 'ewww_image_optimizer_backup_files', '' );
11139
  if ( 'none' !== $redirect ) {
11140
  $sendback = wp_get_referer();
11141
+ wp_safe_redirect( $sendback );
11142
  exit;
11143
  }
11144
  }
11147
  * Loads script to detect scaled images within the page, only enabled for admins.
11148
  */
11149
  function ewww_image_optimizer_resize_detection_script() {
11150
+ if (
11151
+ ! current_user_can( apply_filters( 'ewww_image_optimizer_admin_permissions', 'edit_others_posts' ) ) ||
11152
+ ( ! empty( $_SERVER['SCRIPT_NAME'] ) && 'wp-login.php' === basename( sanitize_text_field( wp_unslash( $_SERVER['SCRIPT_NAME'] ) ) ) )
11153
+ ) {
11154
  return;
11155
  }
11156
  if ( ewww_image_optimizer_is_amp() ) {
11164
  "\tmargin: -3px;\n" .
11165
  "}\n" .
11166
  "</style>\n";
11167
+ echo '<script type="text/javascript">' . $resize_detection_script . '</script>'; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
11168
  }
11169
  }
11170
 
11203
  * Checks if admin bar is visible, and then adds the admin_bar_menu action.
11204
  */
11205
  function ewww_image_optimizer_admin_bar_init() {
11206
+ if (
11207
+ ! current_user_can( apply_filters( 'ewww_image_optimizer_admin_permissions', 'edit_others_posts' ) ) ||
11208
+ ! is_admin_bar_showing() ||
11209
+ ( ! empty( $_SERVER['SCRIPT_NAME'] ) && 'wp-login.php' === basename( sanitize_text_field( wp_unslash( $_SERVER['SCRIPT_NAME'] ) ) ) ) ||
11210
+ is_admin()
11211
+ ) {
11212
  return;
11213
  }
11214
  if ( ewww_image_optimizer_get_option( 'ewww_image_optimizer_resize_detection' ) ) {
11329
  unlink( WP_CONTENT_DIR . '/ewww/debug.log' );
11330
  }
11331
  $sendback = wp_get_referer();
11332
+ wp_safe_redirect( $sendback );
11333
  exit;
11334
  }
11335
 
11383
  return maybe_serialize( $backtrace );
11384
  }
11385
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
11386
  /**
11387
  * Make sure to clear temp debug option on shutdown.
11388
  */
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.3.2
17
  Author URI: https://ewww.io/
18
  License: GPLv3
19
  */
@@ -71,7 +71,7 @@ if ( ! defined( 'PHP_VERSION_ID' ) || PHP_VERSION_ID < 50600 ) {
71
  require_once( plugin_dir_path( __FILE__ ) . 'classes/class-ewwwio-install-cloud.php' );
72
  // Loads the plugin translations.
73
  add_action( 'plugins_loaded', 'ewww_image_optimizer_false_init' );
74
- } elseif ( empty( $_GET['ewwwio_disable'] ) ) {
75
  /**
76
  * The full path of the plugin file (this file).
77
  *
@@ -157,7 +157,7 @@ if ( ! function_exists( 'ewww_image_optimizer_unsupported_php' ) ) {
157
  */
158
  function ewww_image_optimizer_notice_wpengine() {
159
  echo "<div id='ewww-image-optimizer-warning-wpengine' class='error'><p>" . esc_html__( 'The regular version of the EWWW Image Optimizer plugin is not permitted on WP Engine sites. However, the cloud version has been approved by WP Engine. Please deactivate EWWW Image Optimizer and install EWWW Image Optimizer Cloud to optimize your images.', 'ewww-image-optimizer' ) .
160
- ' <a href="' . admin_url( 'admin.php?action=ewwwio_install_cloud_plugin' ) . '">' . esc_html__( 'Install now.', 'ewww-image-optimizer' ) . '</a></p></div>';
161
  }
162
 
163
  /**
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.4.1
17
  Author URI: https://ewww.io/
18
  License: GPLv3
19
  */
71
  require_once( plugin_dir_path( __FILE__ ) . 'classes/class-ewwwio-install-cloud.php' );
72
  // Loads the plugin translations.
73
  add_action( 'plugins_loaded', 'ewww_image_optimizer_false_init' );
74
+ } elseif ( false === strpos( add_query_arg( null, null ), 'ewwwio_disable=1' ) ) {
75
  /**
76
  * The full path of the plugin file (this file).
77
  *
157
  */
158
  function ewww_image_optimizer_notice_wpengine() {
159
  echo "<div id='ewww-image-optimizer-warning-wpengine' class='error'><p>" . esc_html__( 'The regular version of the EWWW Image Optimizer plugin is not permitted on WP Engine sites. However, the cloud version has been approved by WP Engine. Please deactivate EWWW Image Optimizer and install EWWW Image Optimizer Cloud to optimize your images.', 'ewww-image-optimizer' ) .
160
+ ' <a href="' . esc_url( admin_url( 'admin.php?action=ewwwio_install_cloud_plugin' ) ) . '">' . esc_html__( 'Install now.', 'ewww-image-optimizer' ) . '</a></p></div>';
161
  }
162
 
163
  /**
images/ewwwio-logo.png ADDED
Binary file
includes/eio-tools.js CHANGED
@@ -1,6 +1,5 @@
1
  jQuery(document).ready(function($) {
2
  var ewww_table_action = 'bulk_aux_images_table';
3
- var ewww_table_count_action = 'bulk_aux_images_table_count';
4
  var ewww_total_pages = 0;
5
  var ewww_pointer = 0;
6
  var ewww_search_total = 0;
1
  jQuery(document).ready(function($) {
2
  var ewww_table_action = 'bulk_aux_images_table';
 
3
  var ewww_total_pages = 0;
4
  var ewww_pointer = 0;
5
  var ewww_search_total = 0;
includes/eio.js CHANGED
@@ -379,21 +379,19 @@ jQuery(document).ready(function($) {
379
  ewwwStartScan();
380
  } else if ( ewww_response.ready ) {
381
  ewww_attachments = ewww_response.ready;
382
- if (ewww_attachments == 0) {
383
- $('#ewww-scanning').hide();
384
- $('#ewww-nothing').show();
385
- if ( ewww_tiny_skip ) {
386
- $('#ewww-nothing').append( '<br><i>' + ewww_tiny_skip + '</i>' );
387
- console.log( 'done, skipped some tiny images' );
388
- }
389
- } else {
390
- $('#ewww-scanning').html(ewww_response.message);
391
- if ( ewww_tiny_skip ) {
392
- $('#ewww-scanning').append( '<br><i>' + ewww_tiny_skip + '</i>' );
393
- console.log( 'done, skipped some tiny images' );
394
- }
395
- $('#ewww-bulk-first').val(ewww_response.start_button);
396
- $('#ewww-bulk-start').show();
397
  }
398
  }
399
  })
@@ -604,6 +602,7 @@ jQuery(document).ready(function($) {
604
  clearInterval(ewww_countdown);
605
  var ewww_table_count_data = {
606
  action: ewww_table_count_action,
 
607
  ewww_inline: 1,
608
  };
609
  $.post(ajaxurl, ewww_table_count_data, function(response) {
379
  ewwwStartScan();
380
  } else if ( ewww_response.ready ) {
381
  ewww_attachments = ewww_response.ready;
382
+ $('#ewww-scanning').html(ewww_response.message);
383
+ if ( ewww_tiny_skip ) {
384
+ $('#ewww-scanning').append( '<br><i>' + ewww_tiny_skip + '</i>' );
385
+ console.log( 'done, skipped some tiny images' );
386
+ }
387
+ $('#ewww-bulk-first').val(ewww_response.start_button);
388
+ $('#ewww-bulk-start').show();
389
+ } else if ( ewww_response.ready === 0 ) {
390
+ $('#ewww-scanning').hide();
391
+ $('#ewww-nothing').show();
392
+ if ( ewww_tiny_skip ) {
393
+ $('#ewww-nothing').append( '<br><i>' + ewww_tiny_skip + '</i>' );
394
+ console.log( 'done, skipped some tiny images' );
 
 
395
  }
396
  }
397
  })
602
  clearInterval(ewww_countdown);
603
  var ewww_table_count_data = {
604
  action: ewww_table_count_action,
605
+ ewww_wpnonce: ewww_vars._wpnonce,
606
  ewww_inline: 1,
607
  };
608
  $.post(ajaxurl, ewww_table_count_data, function(response) {
includes/jquery-ui-1.10.1.custom.css CHANGED
@@ -391,6 +391,18 @@ a.removeimage, a.restoreimage {
391
  .ewww-attachment-detail {
392
  padding: 13px 0px 0px;
393
  }
 
 
 
 
 
 
 
 
 
 
 
 
394
  /* bulk and settings ui */
395
  h2.ewww-hndle {
396
  font-size: 14px;
@@ -458,7 +470,19 @@ button.ewww-handlediv {
458
  width: auto;
459
  }
460
  }
 
 
 
 
 
 
 
 
 
461
  /* optimization status section */
 
 
 
462
  #ewww-status .inside {
463
  margin: 0;
464
  padding: 0;
@@ -547,6 +571,10 @@ ul.ewww-blocks li:first-child {
547
  .ui-tooltip ul.ewww-tooltip li {
548
  margin-left: 1em;
549
  }
 
 
 
 
550
  #ewww-debug-info {
551
  border:1px solid #e5e5e5;
552
  background: #fff;
@@ -554,3 +582,80 @@ ul.ewww-blocks li:first-child {
554
  height: 300px;
555
  width: 800px;
556
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
391
  .ewww-attachment-detail {
392
  padding: 13px 0px 0px;
393
  }
394
+ .ewww-variant-icon {
395
+ color: white;
396
+ background-color: #f1900e;
397
+ border-radius: 50%;
398
+ font-size: 10px;
399
+ width: 16px;
400
+ height: 16px;
401
+ line-height: 16px;
402
+ text-align: center;
403
+ display: inline-block;
404
+ padding-bottom: 0px;
405
+ }
406
  /* bulk and settings ui */
407
  h2.ewww-hndle {
408
  font-size: 14px;
470
  width: auto;
471
  }
472
  }
473
+ /* settings tabs */
474
+ .ewww-tab span { font-size: 14px; font-weight: 600; color: #555; text-decoration: none; line-height: 36px; padding: 0 10px; }
475
+ .ewww-tab span:hover { color: #464646; }
476
+ .ewww-tab { margin: 0 0 0 5px; padding: 0px; border-width: 1px 1px 1px; border-style: solid solid none; border-image: none; border-color: #ccc; display: inline-block; background-color: #e4e4e4; cursor: pointer }
477
+ .ewww-tab:hover { background-color: #fff }
478
+ .ewww-selected { background-color: #f1f1f1; margin-bottom: -1px; border-bottom: 1px solid #f1f1f1 }
479
+ .ewww-selected span { color: #000; }
480
+ .ewww-selected:hover { background-color: #f1f1f1; }
481
+ .ewww-tab-nav { list-style: none; margin: 10px 0 0; padding-left: 5px; border-bottom: 1px solid #ccc; }
482
  /* optimization status section */
483
+ #ewww-widgets {
484
+ max-width: 1170px;
485
+ }
486
  #ewww-status .inside {
487
  margin: 0;
488
  padding: 0;
571
  .ui-tooltip ul.ewww-tooltip li {
572
  margin-left: 1em;
573
  }
574
+ /* other settings UI */
575
+ p.debug-actions {
576
+ clear: both;
577
+ }
578
  #ewww-debug-info {
579
  border:1px solid #e5e5e5;
580
  background: #fff;
582
  height: 300px;
583
  width: 800px;
584
  }
585
+ #ewwwio-banner {
586
+ margin-top: 10px;
587
+ min-height: 95px;
588
+ padding: 15px;
589
+ background-color: #3eadc9;
590
+ clear: both;
591
+ }
592
+ #ewwwio-banner img {
593
+ float: left;
594
+ margin-right: 10px;
595
+ }
596
+ #ewwwio-banner p {
597
+ color: #fff;
598
+ margin-bottom: 1.0em;
599
+ }
600
+ h3 a.ewww-upgrade {
601
+ font-weight:bold;
602
+ text-decoration: none;
603
+ color: #3eadc9;
604
+ }
605
+ .ewww-help-beacon-multi, .ewww-help-beacon-single {
606
+ margin: 3px;
607
+ }
608
+ /* iframe ewww.io */
609
+ .top-bar {
610
+ display: none;
611
+ }
612
+ /* mobile rules */
613
+ @media screen and (max-width: 782px) {
614
+ #wpbody-content #ewww-widgets {
615
+ float: right;
616
+ padding-top: 0px;
617
+ }
618
+ #ewww-widgets .postbox {
619
+ max-width: 215px;
620
+ min-width: 175px;
621
+ }
622
+ #ewww-widgets ul.ewww-blocks {
623
+ display: block;
624
+ }
625
+ .ewww-blocks li {
626
+ float: none;
627
+ }
628
+ .ewww-blocks li .ewww-status-detail {
629
+ margin: 1em;
630
+ }
631
+ #ewww-settings-form .form-table {
632
+ width: auto;
633
+ clear: none;
634
+ }
635
+ #ewww-settings-disable-resizes th, #ewww-settings-disable-resizes td {
636
+ display: table-cell;
637
+ }
638
+ .ewww-tab-nav {
639
+ border-style: none;
640
+ }
641
+ .ewww-tab {
642
+ margin: 0 0 3px 3px;
643
+ border-style: solid;
644
+ }
645
+ .ewww-selected {
646
+ border-color: #ccc;
647
+ }
648
+ .ewww-tab span {
649
+ font-size: 12px;
650
+ padding: 2px 3px;
651
+
652
+ }
653
+ p.debug-actions {
654
+ margin-top: 30px;
655
+ clear: none;
656
+ }
657
+ #ewww-debug-info {
658
+ width: auto;
659
+ margin-right: 225px;
660
+ }
661
+ }
includes/resize_detection.js CHANGED
@@ -21,7 +21,7 @@ function checkImageSizes() {
21
  }
22
  function checkImageScale(img) {
23
  if (img.naturalWidth) {
24
- if ((img.naturalWidth != 1) && (img.naturalHeight != 1)) {
25
  // For each image with a natural width which isn't
26
  // a 1x1 image, check its size.
27
  var dPR = (window.devicePixelRatio || 1);
21
  }
22
  function checkImageScale(img) {
23
  if (img.naturalWidth) {
24
+ if (img.naturalWidth > 25 && img.naturalHeight > 25 && img.clientWidth > 25 && img.clientHeight > 25) {
25
  // For each image with a natural width which isn't
26
  // a 1x1 image, check its size.
27
  var dPR = (window.devicePixelRatio || 1);
mwebp.php CHANGED
@@ -30,7 +30,7 @@ function ewww_image_optimizer_webp_migrate_preview() {
30
  <div id="webp-status"></div>
31
  <div id="bulk-forms">
32
  <form id="webp-start" class="webp-form" method="post" action="">
33
- <input id="webp-first" type="submit" class="button-secondary action" value="<?php echo $button_text; ?>" />
34
  </form>
35
  </div>
36
  <?php
@@ -107,7 +107,7 @@ function ewww_image_optimizer_webp_script( $hook ) {
107
  function ewww_image_optimizer_webp_initialize() {
108
  // Verify that an authorized user has started the migration.
109
  $permissions = apply_filters( 'ewww_image_optimizer_admin_permissions', '' );
110
- if ( ! wp_verify_nonce( $_REQUEST['ewww_wpnonce'], 'ewww-image-optimizer-webp' ) || ! current_user_can( $permissions ) ) {
111
  ewwwio_ob_clean();
112
  die( esc_html__( 'Access denied.', 'ewww-image-optimizer' ) );
113
  }
@@ -119,7 +119,7 @@ function ewww_image_optimizer_webp_initialize() {
119
  $loading_image = plugins_url( '/images/wpspin.gif', __FILE__ );
120
  // Let the user know that we are beginning.
121
  ewwwio_ob_clean();
122
- die( '<p>' . esc_html__( 'Scanning', 'ewww-image-optimizer' ) . "&nbsp;<img src='$loading_image' /></p>" );
123
  }
124
 
125
  /**
@@ -128,7 +128,7 @@ function ewww_image_optimizer_webp_initialize() {
128
  function ewww_image_optimizer_webp_loop() {
129
  ewwwio_debug_message( '<b>' . __FUNCTION__ . '()</b>' );
130
  $permissions = apply_filters( 'ewww_image_optimizer_admin_permissions', '' );
131
- if ( ! wp_verify_nonce( $_REQUEST['ewww_wpnonce'], 'ewww-image-optimizer-webp' ) || ! current_user_can( $permissions ) ) {
132
  ewwwio_ob_clean();
133
  die( esc_html__( 'Access token has expired, please reload the page.', 'ewww-image-optimizer' ) );
134
  }
@@ -223,7 +223,7 @@ function ewww_image_optimizer_webp_loop() {
223
  */
224
  function ewww_image_optimizer_webp_cleanup() {
225
  $permissions = apply_filters( 'ewww_image_optimizer_admin_permissions', '' );
226
- if ( ! wp_verify_nonce( $_REQUEST['ewww_wpnonce'], 'ewww-image-optimizer-webp' ) || ! current_user_can( $permissions ) ) {
227
  ewwwio_ob_clean();
228
  die( esc_html__( 'Access token has expired, please reload the page.', 'ewww-image-optimizer' ) );
229
  }
@@ -234,7 +234,7 @@ function ewww_image_optimizer_webp_cleanup() {
234
  ewwwio_ob_clean();
235
  if ( $skipped ) {
236
  echo '<p><b>' . esc_html__( 'Skipped:', 'ewww-image-optimizer' ) . '</b></p>';
237
- echo "<p>$skipped</p>";
238
  }
239
  // and let the user know we are done.
240
  die( '<p><b>' . esc_html__( 'Finished', 'ewww-image-optimizer' ) . '</b></p>' );
30
  <div id="webp-status"></div>
31
  <div id="bulk-forms">
32
  <form id="webp-start" class="webp-form" method="post" action="">
33
+ <input id="webp-first" type="submit" class="button-secondary action" value="<?php esc_attr_e( 'Start Migration', 'ewww-image-optimizer' ); ?>" />
34
  </form>
35
  </div>
36
  <?php
107
  function ewww_image_optimizer_webp_initialize() {
108
  // Verify that an authorized user has started the migration.
109
  $permissions = apply_filters( 'ewww_image_optimizer_admin_permissions', '' );
110
+ if ( empty( $_REQUEST['ewww_wpnonce'] ) || ! wp_verify_nonce( sanitize_key( $_REQUEST['ewww_wpnonce'] ), 'ewww-image-optimizer-webp' ) || ! current_user_can( $permissions ) ) {
111
  ewwwio_ob_clean();
112
  die( esc_html__( 'Access denied.', 'ewww-image-optimizer' ) );
113
  }
119
  $loading_image = plugins_url( '/images/wpspin.gif', __FILE__ );
120
  // Let the user know that we are beginning.
121
  ewwwio_ob_clean();
122
+ die( '<p>' . esc_html__( 'Scanning', 'ewww-image-optimizer' ) . '&nbsp;<img src="' . esc_url( $loading_image ) . '" /></p>' );
123
  }
124
 
125
  /**
128
  function ewww_image_optimizer_webp_loop() {
129
  ewwwio_debug_message( '<b>' . __FUNCTION__ . '()</b>' );
130
  $permissions = apply_filters( 'ewww_image_optimizer_admin_permissions', '' );
131
+ if ( empty( $_REQUEST['ewww_wpnonce'] ) || ! wp_verify_nonce( sanitize_key( $_REQUEST['ewww_wpnonce'] ), 'ewww-image-optimizer-webp' ) || ! current_user_can( $permissions ) ) {
132
  ewwwio_ob_clean();
133
  die( esc_html__( 'Access token has expired, please reload the page.', 'ewww-image-optimizer' ) );
134
  }
223
  */
224
  function ewww_image_optimizer_webp_cleanup() {
225
  $permissions = apply_filters( 'ewww_image_optimizer_admin_permissions', '' );
226
+ if ( empty( $_REQUEST['ewww_wpnonce'] ) || ! wp_verify_nonce( sanitize_key( $_REQUEST['ewww_wpnonce'] ), 'ewww-image-optimizer-webp' ) || ! current_user_can( $permissions ) ) {
227
  ewwwio_ob_clean();
228
  die( esc_html__( 'Access token has expired, please reload the page.', 'ewww-image-optimizer' ) );
229
  }
234
  ewwwio_ob_clean();
235
  if ( $skipped ) {
236
  echo '<p><b>' . esc_html__( 'Skipped:', 'ewww-image-optimizer' ) . '</b></p>';
237
+ echo wp_kses_post( "<p>$skipped</p>" );
238
  }
239
  // and let the user know we are done.
240
  die( '<p><b>' . esc_html__( 'Finished', 'ewww-image-optimizer' ) . '</b></p>' );
phpcs.ruleset.xml CHANGED
@@ -1,9 +1,13 @@
1
  <?xml version="1.0"?>
2
  <ruleset name="WordPress Coding Standards for Plugins">
3
  <description>Generally-applicable sniffs for WordPress plugins</description>
 
 
4
 
5
- <exclude-pattern>*/vendor/*</exclude-pattern>
6
- <exclude-pattern>*/tests/*</exclude-pattern>
 
 
7
 
8
  <rule ref="WordPress-Core" />
9
  <rule ref="WordPress-Docs" />
@@ -29,4 +33,16 @@
29
  <property name="customVariablesWhitelist" type="array" value="formatOutput,parentNode,nextSibling,documentElement" />
30
  </properties>
31
  </rule>
 
 
 
 
 
 
 
 
 
 
 
 
32
  </ruleset>
1
  <?xml version="1.0"?>
2
  <ruleset name="WordPress Coding Standards for Plugins">
3
  <description>Generally-applicable sniffs for WordPress plugins</description>
4
+ <!-- Only sniff PHP files -->
5
+ <arg name="extensions" value="php"/>
6
 
7
+ <arg value="s"/>
8
+
9
+ <exclude-pattern>/vendor/*</exclude-pattern>
10
+ <exclude-pattern>/tests/*</exclude-pattern>
11
 
12
  <rule ref="WordPress-Core" />
13
  <rule ref="WordPress-Docs" />
33
  <property name="customVariablesWhitelist" type="array" value="formatOutput,parentNode,nextSibling,documentElement" />
34
  </properties>
35
  </rule>
36
+
37
+ <rule ref="PHPCompatibilityWP">
38
+ <severity>10</severity>
39
+ </rule>
40
+
41
+ <rule ref="WordPress.Security">
42
+ <severity>10</severity>
43
+ </rule>
44
+
45
+ <rule ref="WordPress.DB.PreparedSQL">
46
+ <severity>10</severity>
47
+ </rule>
48
  </ruleset>
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.3.2
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,31 @@ https://developers.google.com/web/tools/lighthouse/audits/optimize-images
173
  * Feature requests can be viewed and submitted at https://github.com/nosilver4u/ewww-image-optimizer/labels/enhancement
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.3.2 =
177
  * added: defer jQuery also with EXACTDN_DEFER_JQUERY override
178
  * added: Lazy Load supports VC grid layouts retrieved via AJAX
5
  Requires at least: 5.0
6
  Tested up to: 5.4
7
  Requires PHP: 5.6
8
+ Stable tag: 5.4.1
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://github.com/nosilver4u/ewww-image-optimizer/labels/enhancement
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.4.1 =
177
+ * fixed: Bulk Optimizer sticks on stage 2 when there are no images to optimize
178
+ * fixed: transparency in PNG images with color type 0 or 2 not detected
179
+ * fixed: transparency false positives for PNG images with color types 4 and 6
180
+ * fixed: lazy load skips img elements with unquoted src attributes
181
+ * fixed: images converted by PNG to JPG (and friends) do not have restore links in library
182
+
183
+ = 5.4.0 =
184
+ * added: EXACTDN_DEFER_JQUERY_SAFE override for when inline scripts depend on jQuery
185
+ * changed: code rewrite to validate output escaping, input sanitization, and markup on settings page
186
+ * changed: use data-cfasync=false to prevent deferring inline JS WebP script
187
+ * changed: Easy IO uses better query-string fall-back for plugins
188
+ * changed: Easy IO enforces https if available rather than protocol-relative URLs
189
+ * changed: resize detection ignores images smaller than 25px
190
+ * changed: settings streamlined when using Easy IO
191
+ * fixed: parallel optimization on multisite fails due to missing db prefix
192
+ * fixed: error when saving JS WebP on network/multsite admin
193
+ * fixed: images not resized when Media File Renamer is active
194
+ * fixed: PHP warning while using <picture> WebP
195
+ * fixed: Lazy Load, JS WebP and <picture> WebP have nested fall-back img elements if an image is found multiple times in a page
196
+ * fixed: Easy IO mangles srcset URLs when src URL is relative instead of absolute
197
+ * fixed: Easy IO URLs leaking into block editor for new uploads
198
+ * fixed: WebP rewriting with WP Offload Media skips sub-domains of blog domain
199
+ * deprecated: support for Image Store plugin (abandoned)
200
+
201
  = 5.3.2 =
202
  * added: defer jQuery also with EXACTDN_DEFER_JQUERY override
203
  * added: Lazy Load supports VC grid layouts retrieved via AJAX
tests/test-convert.php CHANGED
@@ -86,7 +86,8 @@ class EWWWIO_Convert_Tests extends WP_UnitTestCase {
86
  if ( ! $original ) {
87
  $original = self::$test_jpg;
88
  }
89
- $_REQUEST['ewww_force'] = 1;
 
90
  $filename = $original . ".jpg";
91
  copy( $original, $filename );
92
  $results = ewww_image_optimizer( $filename, 1, false, false, true );
@@ -102,7 +103,8 @@ class EWWWIO_Convert_Tests extends WP_UnitTestCase {
102
  if ( ! $original ) {
103
  $original = self::$test_png;
104
  }
105
- $_REQUEST['ewww_force'] = 1;
 
106
  $filename = $original . ".png";
107
  copy( $original, $filename );
108
  $results = ewww_image_optimizer( $filename, 1, false, false, true );
@@ -118,7 +120,8 @@ class EWWWIO_Convert_Tests extends WP_UnitTestCase {
118
  if ( ! $original ) {
119
  $original = self::$test_gif;
120
  }
121
- $_REQUEST['ewww_force'] = 1;
 
122
  $filename = $original . ".gif";
123
  copy( $original, $filename );
124
  $results = ewww_image_optimizer( $filename, 1, false, false, true );
@@ -290,7 +293,7 @@ class EWWWIO_Convert_Tests extends WP_UnitTestCase {
290
 
291
  $base_dir = trailingslashit( dirname( $file_path ) );
292
  foreach ( $meta['sizes'] as $size => $data ) {
293
- $image_path = $base_dir . $data['file'];
294
  $this->assertEquals( 'image/jpeg', ewww_image_optimizer_mimetype( $image_path, 'i' ) );
295
  }
296
 
86
  if ( ! $original ) {
87
  $original = self::$test_jpg;
88
  }
89
+ global $ewww_force;
90
+ $ewww_force = 1;
91
  $filename = $original . ".jpg";
92
  copy( $original, $filename );
93
  $results = ewww_image_optimizer( $filename, 1, false, false, true );
103
  if ( ! $original ) {
104
  $original = self::$test_png;
105
  }
106
+ global $ewww_force;
107
+ $ewww_force = 1;
108
  $filename = $original . ".png";
109
  copy( $original, $filename );
110
  $results = ewww_image_optimizer( $filename, 1, false, false, true );
120
  if ( ! $original ) {
121
  $original = self::$test_gif;
122
  }
123
+ global $ewww_force;
124
+ $ewww_force = 1;
125
  $filename = $original . ".gif";
126
  copy( $original, $filename );
127
  $results = ewww_image_optimizer( $filename, 1, false, false, true );
293
 
294
  $base_dir = trailingslashit( dirname( $file_path ) );
295
  foreach ( $meta['sizes'] as $size => $data ) {
296
+ $image_path = $base_dir . wp_basename( $data['file'] );
297
  $this->assertEquals( 'image/jpeg', ewww_image_optimizer_mimetype( $image_path, 'i' ) );
298
  }
299
 
tests/test-optimize.php CHANGED
@@ -94,7 +94,8 @@ class EWWWIO_Optimize_Tests extends WP_UnitTestCase {
94
  * @return array The results of the ewww_image_optimizer() function.
95
  */
96
  protected function optimize_jpg() {
97
- $_REQUEST['ewww_force'] = 1;
 
98
  $filename = self::$test_jpg . ".jpg";
99
  copy( self::$test_jpg, $filename );
100
  $results = ewww_image_optimizer( $filename );
@@ -107,7 +108,8 @@ class EWWWIO_Optimize_Tests extends WP_UnitTestCase {
107
  * @return array The results of the ewww_image_optimizer() function.
108
  */
109
  protected function optimize_png() {
110
- $_REQUEST['ewww_force'] = 1;
 
111
  $filename = self::$test_png . ".png";
112
  copy( self::$test_png, $filename );
113
  $results = ewww_image_optimizer( $filename );
@@ -120,7 +122,8 @@ class EWWWIO_Optimize_Tests extends WP_UnitTestCase {
120
  * @return array The results of the ewww_image_optimizer() function.
121
  */
122
  protected function optimize_gif() {
123
- $_REQUEST['ewww_force'] = 1;
 
124
  $filename = self::$test_gif . ".gif";
125
  copy( self::$test_gif, $filename );
126
  $results = ewww_image_optimizer( $filename );
@@ -133,7 +136,8 @@ class EWWWIO_Optimize_Tests extends WP_UnitTestCase {
133
  * @return array The results of the ewww_image_optimizer() function.
134
  */
135
  protected function optimize_pdf() {
136
- $_REQUEST['ewww_force'] = 1;
 
137
  $filename = self::$test_pdf . ".pdf";
138
  copy( self::$test_pdf, $filename );
139
  $results = ewww_image_optimizer( $filename );
94
  * @return array The results of the ewww_image_optimizer() function.
95
  */
96
  protected function optimize_jpg() {
97
+ global $ewww_force;
98
+ $ewww_force = 1;
99
  $filename = self::$test_jpg . ".jpg";
100
  copy( self::$test_jpg, $filename );
101
  $results = ewww_image_optimizer( $filename );
108
  * @return array The results of the ewww_image_optimizer() function.
109
  */
110
  protected function optimize_png() {
111
+ global $ewww_force;
112
+ $ewww_force = 1;
113
  $filename = self::$test_png . ".png";
114
  copy( self::$test_png, $filename );
115
  $results = ewww_image_optimizer( $filename );
122
  * @return array The results of the ewww_image_optimizer() function.
123
  */
124
  protected function optimize_gif() {
125
+ global $ewww_force;
126
+ $ewww_force = 1;
127
  $filename = self::$test_gif . ".gif";
128
  copy( self::$test_gif, $filename );
129
  $results = ewww_image_optimizer( $filename );
136
  * @return array The results of the ewww_image_optimizer() function.
137
  */
138
  protected function optimize_pdf() {
139
+ global $ewww_force;
140
+ $ewww_force = 1;
141
  $filename = self::$test_pdf . ".pdf";
142
  copy( self::$test_pdf, $filename );
143
  $results = ewww_image_optimizer( $filename );
tests/test-tables.php CHANGED
@@ -55,7 +55,8 @@ class EWWWIO_Table_Tests extends WP_UnitTestCase {
55
  if ( ! $original ) {
56
  $original = self::$test_gif;
57
  }
58
- $_REQUEST['ewww_force'] = 1;
 
59
  $filename = $original . ".gif";
60
  copy( $original, $filename );
61
  $results = ewww_image_optimizer( $filename, 1 );
55
  if ( ! $original ) {
56
  $original = self::$test_gif;
57
  }
58
+ global $ewww_force;
59
+ $ewww_force = 1;
60
  $filename = $original . ".gif";
61
  copy( $original, $filename );
62
  $results = ewww_image_optimizer( $filename, 1 );
unique.php CHANGED
@@ -26,11 +26,6 @@ register_deactivation_hook( EWWW_IMAGE_OPTIMIZER_PLUGIN_FILE, 'ewww_image_optimi
26
  */
27
  function ewww_image_optimizer_cloud_init() {
28
  ewwwio_debug_message( '<b>' . __FUNCTION__ . '()</b>' );
29
- // Basically this happens on settings save, so we need to check if the settings are being saved with an empty key, and pre-emptively set the constant to false.
30
- if ( ! defined( 'EWWW_IMAGE_OPTIMIZER_CLOUD' ) && isset( $_POST['ewww_image_optimizer_cloud_key'] ) && ! $_POST['ewww_image_optimizer_cloud_key'] ) {
31
- define( 'EWWW_IMAGE_OPTIMIZER_CLOUD', false );
32
- return;
33
- }
34
  if (
35
  ! defined( 'EWWW_IMAGE_OPTIMIZER_CLOUD' ) &&
36
  ewww_image_optimizer_get_option( 'ewww_image_optimizer_cloud_key' ) &&
@@ -49,7 +44,8 @@ function ewww_image_optimizer_cloud_init() {
49
  */
50
  function ewww_image_optimizer_exec_init() {
51
  ewwwio_debug_message( '<b>' . __FUNCTION__ . '()</b>' );
52
- if ( defined( 'WPE_PLUGIN_VERSION' ) ) {
 
53
  add_action( 'network_admin_notices', 'ewww_image_optimizer_notice_wpengine' );
54
  add_action( 'admin_notices', 'ewww_image_optimizer_notice_wpengine' );
55
  if ( ! defined( 'EWWW_IMAGE_OPTIMIZER_NOEXEC' ) ) {
@@ -61,10 +57,9 @@ function ewww_image_optimizer_exec_init() {
61
  if ( EWWW_IMAGE_OPTIMIZER_CLOUD ) {
62
  ewwwio_debug_message( 'cloud options enabled, shutting off binaries' );
63
  ewww_image_optimizer_disable_tools();
64
- } elseif ( defined( 'WPCOMSH_VERSION' ) || ! empty( $_ENV['PANTHEON_ENVIRONMENT'] ) ) {
65
  if (
66
  ! ewww_image_optimizer_get_option( 'ewww_image_optimizer_cloud_key' ) &&
67
- empty( $_POST['ewww_image_optimizer_cloud_key'] ) &&
68
  ( ! is_object( $exactdn ) || ! $exactdn->get_exactdn_domain() )
69
  ) {
70
  add_action( 'network_admin_notices', 'ewww_image_optimizer_notice_hosting_requires_api' );
@@ -73,7 +68,7 @@ function ewww_image_optimizer_exec_init() {
73
  if ( ! defined( 'EWWW_IMAGE_OPTIMIZER_NOEXEC' ) ) {
74
  define( 'EWWW_IMAGE_OPTIMIZER_NOEXEC', true );
75
  }
76
- ewwwio_debug_message( 'wp.com/pantheon site, disabling tools' );
77
  ewww_image_optimizer_disable_tools();
78
  // Check if this is an unsupported OS (not Linux or Mac OSX or FreeBSD or Windows or SunOS).
79
  } elseif ( 'Linux' !== PHP_OS && 'Darwin' !== PHP_OS && 'FreeBSD' !== PHP_OS && 'WINNT' !== PHP_OS && 'SunOS' !== PHP_OS ) {
@@ -87,10 +82,9 @@ function ewww_image_optimizer_exec_init() {
87
  add_action( 'load-upload.php', 'ewww_image_optimizer_tool_init', 9 );
88
  add_action( 'load-media-new.php', 'ewww_image_optimizer_tool_init' );
89
  add_action( 'load-media_page_ewww-image-optimizer-bulk', 'ewww_image_optimizer_tool_init' );
90
- add_action( 'load-settings_page_ewww-image-optimizer', 'ewww_image_optimizer_tool_init' );
91
  add_action( 'load-plugins.php', 'ewww_image_optimizer_tool_init' );
92
  add_action( 'load-ims_gallery_page_ewww-ims-optimize', 'ewww_image_optimizer_tool_init' );
93
- add_action( 'load-media_page_ewww-image-optimizer-unoptimized', 'ewww_image_optimizer_tool_init' );
94
  }
95
  ewwwio_memory( __FUNCTION__ );
96
  }
@@ -171,14 +165,16 @@ function ewww_image_optimizer_notice_hosting_requires_api() {
171
  $webhost = 'WordPress.com';
172
  } elseif ( ! empty( $_ENV['PANTHEON_ENVIRONMENT'] ) ) {
173
  $webhost = 'Pantheon';
 
 
174
  } else {
175
  return;
176
  }
177
- echo "<div id='ewww-image-optimizer-cloud-key-required' class='notice notice-error'><p><strong>" .
178
  /* translators: %s: Name of a web host, like WordPress.com or Pantheon. */
179
- sprintf( esc_html__( 'The EWWW Image Optimizer requires an API key or an Easy IO subscription to optimize images on %s sites.', 'ewww-image-optimizer-cloud' ), $webhost ) .
180
- "</strong> <a href='https://ewww.io/plans/'>" . esc_html__( 'Purchase a subscription.', 'ewww-image-optimizer-cloud' ) .
181
- "</a> <a href='$settings_url'>" . esc_html__( 'Then, activate it on the settings page.', 'ewww-image-optimizer-cloud' ) . '</a></p></div>';
182
  }
183
 
184
  /**
@@ -186,7 +182,9 @@ function ewww_image_optimizer_notice_hosting_requires_api() {
186
  */
187
  function ewww_image_optimizer_notice_os() {
188
  ewwwio_debug_message( '<b>' . __FUNCTION__ . '()</b>' );
189
- echo "<div id='ewww-image-optimizer-warning-os' class='notice notice-error'><p><strong>" . esc_html__( 'The free mode of EWWW Image Optimizer is only supported on Linux, FreeBSD, Mac OSX, Solaris, and Windows.', 'ewww-image-optimizer' ) . '</strong></p></div>';
 
 
190
  }
191
 
192
  /**
@@ -301,25 +299,16 @@ function ewww_image_optimizer_check_permissions( $file, $minimum ) {
301
  * Alert the user when the tool folder could not be created.
302
  */
303
  function ewww_image_optimizer_tool_folder_notice() {
304
- echo "<div id='ewww-image-optimizer-warning-tool-folder-create' class='notice notice-error'><p><strong>" . esc_html__( 'EWWW Image Optimizer could not create the tool folder', 'ewww-image-optimizer' ) . ': ' . htmlentities( EWWW_IMAGE_OPTIMIZER_TOOL_PATH ) . '.</strong> ' . esc_html__( 'Please adjust permissions or create the folder', 'ewww-image-optimizer' ) . '.</p></div>';
305
  }
306
 
307
  /**
308
  * Alert the user when permissions on the tool folder are insufficient.
309
  */
310
  function ewww_image_optimizer_tool_folder_permissions_notice() {
311
- if ( ! function_exists( 'is_plugin_active_for_network' ) && is_multisite() ) {
312
- // Need to include the plugin library for the is_plugin_active function.
313
- require_once( ABSPATH . 'wp-admin/includes/plugin.php' );
314
- }
315
- if ( is_multisite() && is_plugin_active_for_network( EWWW_IMAGE_OPTIMIZER_PLUGIN_FILE_REL ) ) {
316
- $settings_page = network_admin_url( 'settings.php?page=ewww-image-optimizer-options' );
317
- } else {
318
- $settings_page = admin_url( 'options-general.php?page=ewww-image-optimizer-options' );
319
- }
320
  echo "<div id='ewww-image-optimizer-warning-tool-folder-permissions' class='notice notice-error'><p><strong>" .
321
  /* translators: %s: Folder location where executables should be installed */
322
- sprintf( esc_html__( 'EWWW Image Optimizer could not install tools in %s', 'ewww-image-optimizer' ), htmlentities( EWWW_IMAGE_OPTIMIZER_TOOL_PATH ) ) . '.</strong> ' .
323
  esc_html__( 'Please adjust permissions on the folder. If you have installed the tools elsewhere, use the override to skip the bundled tools.', 'ewww-image-optimizer' ) . ' ' .
324
  /* translators: s: Installation Instructions (link) */
325
  sprintf( esc_html__( 'For more details, see the %s.', 'ewww-image-optimizer' ), "<a href='https://docs.ewww.io/article/6-the-plugin-says-i-m-missing-something'>" . esc_html__( 'Installation Instructions', 'ewww-image-optimizer' ) . '</a>' ) . '</p></div>';
@@ -329,18 +318,9 @@ function ewww_image_optimizer_tool_folder_permissions_notice() {
329
  * Alert the user when tool installation fails.
330
  */
331
  function ewww_image_optimizer_tool_installation_failed_notice() {
332
- if ( ! function_exists( 'is_plugin_active_for_network' ) && is_multisite() ) {
333
- // Need to include the plugin library for the is_plugin_active function.
334
- require_once( ABSPATH . 'wp-admin/includes/plugin.php' );
335
- }
336
- if ( is_multisite() && is_plugin_active_for_network( EWWW_IMAGE_OPTIMIZER_PLUGIN_FILE_REL ) ) {
337
- $settings_page = network_admin_url( 'settings.php?page=ewww-image-optimizer-options' );
338
- } else {
339
- $settings_page = admin_url( 'options-general.php?page=ewww-image-optimizer-options' );
340
- }
341
  echo "<div id='ewww-image-optimizer-warning-tool-install' class='notice notice-error'><p><strong>" .
342
  /* translators: %s: Folder location where executables should be installed */
343
- sprintf( esc_html__( 'EWWW Image Optimizer could not install tools in %s', 'ewww-image-optimizer' ), htmlentities( EWWW_IMAGE_OPTIMIZER_TOOL_PATH ) ) . '.</strong> ' .
344
  /* translators: %s: Installation Instructions */
345
  sprintf( esc_html__( 'For more details, see the %s.', 'ewww-image-optimizer' ), "<a href='https://docs.ewww.io/article/6-the-plugin-says-i-m-missing-something'>" . esc_html__( 'Installation Instructions', 'ewww-image-optimizer' ) . '</a>' ) . '</p></div>';
346
  }
@@ -557,10 +537,17 @@ function ewww_image_optimizer_notice_utils( $quiet = null ) {
557
  // Need to be a little particular with the quiet parameter.
558
  if ( 'quiet' !== $quiet && ! $no_compression ) {
559
  $exactdn_dismiss = ewww_image_optimizer_get_option( 'ewww_image_optimizer_exactdn' ) ? true : false;
 
 
 
 
 
 
 
560
  // Display a warning if exec() is disabled, can't run local tools without it.
561
- echo "<div id='ewww-image-optimizer-warning-exec' " . ( $exactdn_dismiss ? "class='notice notice-warning is-dismissible'" : "class='notice notice-error'" ) . '><p>' . 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' ) .
562
- ( ! $exactdn_dismiss ? '<br>' . esc_html__( 'An API key or Easy IO subscription will allow you to offload the compression to our dedicated servers instead.', 'ewww-image-optimizer' )
563
- : '<br>' . 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' ) ) .
564
  '</p></div>';
565
  echo
566
  "<script>\n" .
@@ -575,6 +562,14 @@ function ewww_image_optimizer_notice_utils( $quiet = null ) {
575
  "\t});\n" .
576
  "});\n" .
577
  "</script>\n";
 
 
 
 
 
 
 
 
578
  }
579
  if ( ! defined( 'EWWW_IMAGE_OPTIMIZER_NOEXEC' ) ) {
580
  define( 'EWWW_IMAGE_OPTIMIZER_NOEXEC', true );
@@ -684,7 +679,7 @@ function ewww_image_optimizer_notice_utils( $quiet = null ) {
684
  sprintf(
685
  /* translators: 1: automatically (link) 2: manually (link) */
686
  esc_html__( 'You are missing pngout. Install %1$s or %2$s.', 'ewww-image-optimizer' ),
687
- "<a href='$pngout_install_url'>" . esc_html__( 'automatically', 'ewww-image-optimizer' ) . '</a>',
688
  '<a href="https://docs.ewww.io/article/13-installing-pngout" data-beacon-article="5854531bc697912ffd6c1afa">' . esc_html__( 'manually', 'ewww-image-optimizer' ) . '</a>'
689
  ) .
690
  '</p></div>';
@@ -699,8 +694,8 @@ function ewww_image_optimizer_notice_utils( $quiet = null ) {
699
  "<a href='http://pngquant.org/'>pngquant</a>",
700
  "<a href='http://www.lcdf.org/gifsicle/'>gifsicle</a>",
701
  "<a href='https://developers.google.com/speed/webp/'>cwebp</a>",
702
- $msg,
703
- "<a href='$settings_page'>" . esc_html__( 'Settings Page', 'ewww-image-optimizer' ) . '</a>',
704
  "<a href='https://docs.ewww.io/article/6-the-plugin-says-i-m-missing-something' data-beacon-article='585371e3c697912ffd6c0ba1' target='_blank'>" . esc_html__( 'Installation Instructions', 'ewww-image-optimizer' ) . '</a>'
705
  ) .
706
  '</p></div>';
@@ -1143,13 +1138,17 @@ function ewww_image_optimizer_mimetype( $path, $case ) {
1143
  }
1144
  $path = realpath( $path );
1145
  if ( ! ewwwio_is_file( $path ) ) {
 
1146
  return $type;
1147
  }
 
 
1148
  if ( 'i' === $case ) {
1149
- $fhandle = fopen( $path, 'rb' );
1150
- if ( $fhandle ) {
1151
  // Read first 12 bytes, which equates to 24 hex characters.
1152
- $magic = bin2hex( fread( $fhandle, 12 ) );
 
1153
  if ( 0 === strpos( $magic, '52494646' ) && 16 === strpos( $magic, '57454250' ) ) {
1154
  $type = 'image/webp';
1155
  ewwwio_debug_message( "ewwwio type: $type" );
@@ -1181,10 +1180,11 @@ function ewww_image_optimizer_mimetype( $path, $case ) {
1181
  }
1182
  }
1183
  if ( 'b' === $case ) {
1184
- $fhandle = fopen( $path, 'rb' );
1185
- if ( $fhandle ) {
1186
  // Read first 4 bytes, which equates to 8 hex characters.
1187
- $magic = bin2hex( fread( $fhandle, 4 ) );
 
1188
  // Mac (Mach-O) binary.
1189
  if ( 'cffaedfe' === $magic || 'feedface' === $magic || 'feedfacf' === $magic || 'cefaedfe' === $magic || 'cafebabe' === $magic ) {
1190
  $type = 'application/x-executable';
@@ -1748,6 +1748,10 @@ function ewww_image_optimizer( $file, $gallery_type = 4, $converted = false, $ne
1748
  return array( false, __( 'Optimization skipped', 'ewww-image-optimizer' ), $converted, $file );
1749
  }
1750
  global $ewww_image;
 
 
 
 
1751
  // Initialize the original filename.
1752
  $original = $file;
1753
  $result = '';
@@ -1856,8 +1860,8 @@ function ewww_image_optimizer( $file, $gallery_type = 4, $converted = false, $ne
1856
  if (
1857
  1 === (int) $gallery_type &&
1858
  $fullsize &&
1859
- ( ewww_image_optimizer_get_option( 'ewww_image_optimizer_jpg_to_png' ) || ! empty( $_REQUEST['ewww_convert'] ) ) &&
1860
- empty( $_REQUEST['ewww_webp_only'] )
1861
  ) {
1862
  // Generate the filename for a PNG:
1863
  // If this is a resize version.
@@ -1876,9 +1880,9 @@ function ewww_image_optimizer( $file, $gallery_type = 4, $converted = false, $ne
1876
  }
1877
  $compression_level = (int) ewww_image_optimizer_get_option( 'ewww_image_optimizer_jpg_level' );
1878
  // Check for previous optimization, so long as the force flag is not on and this isn't a new image that needs converting.
1879
- if ( empty( $_REQUEST['ewww_force'] ) && ! ( $new && $convert ) ) {
1880
  $results_msg = ewww_image_optimizer_check_table( $file, $orig_size );
1881
- $smart_reopt = ! empty( $_REQUEST['ewww_force_smart'] ) && ewww_image_optimizer_level_mismatch( $ewww_image->level, $compression_level ) ? true : false;
1882
  if ( $smart_reopt ) {
1883
  ewwwio_debug_message( "smart re-opt found level mismatch for $file, db says " . $ewww_image->level . " vs. current $compression_level" );
1884
  // If the current compression level is less than what was previously used, and the previous level was premium (or premium plus).
@@ -1891,7 +1895,7 @@ function ewww_image_optimizer( $file, $gallery_type = 4, $converted = false, $ne
1891
  }
1892
  }
1893
  $ewww_image->level = $compression_level;
1894
- if ( $compression_level > 10 && empty( $_REQUEST['ewww_webp_only'] ) ) {
1895
  list( $file, $converted, $result, $new_size, $backup_hash ) = ewww_image_optimizer_cloud_optimizer( $file, $type, $convert, $pngfile, 'image/png', $skip_lossy );
1896
  if ( $converted ) {
1897
  // Check to see if the user wants the originals deleted.
@@ -1929,7 +1933,7 @@ function ewww_image_optimizer( $file, $gallery_type = 4, $converted = false, $ne
1929
  ! $skip['webp']
1930
  );
1931
  }
1932
- if ( ! empty( $_REQUEST['ewww_webp_only'] ) ) {
1933
  $optimize = false;
1934
  } elseif ( ! ewww_image_optimizer_get_option( 'ewww_image_optimizer_jpg_level' ) ) {
1935
  // Store an appropriate message in $result.
@@ -2100,9 +2104,9 @@ function ewww_image_optimizer( $file, $gallery_type = 4, $converted = false, $ne
2100
  if (
2101
  1 === (int) $gallery_type &&
2102
  $fullsize &&
2103
- ( ewww_image_optimizer_get_option( 'ewww_image_optimizer_png_to_jpg' ) || ! empty( $_REQUEST['ewww_convert'] ) ) &&
2104
  ! $skip_lossy &&
2105
- empty( $_REQUEST['ewww_webp_only'] )
2106
  ) {
2107
  ewwwio_debug_message( 'PNG to JPG conversion turned on' );
2108
  $cloud_background = '';
@@ -2144,9 +2148,9 @@ function ewww_image_optimizer( $file, $gallery_type = 4, $converted = false, $ne
2144
  } // End if().
2145
  $compression_level = (int) ewww_image_optimizer_get_option( 'ewww_image_optimizer_png_level' );
2146
  // Check for previous optimization, so long as the force flag is on and this isn't a new image that needs converting.
2147
- if ( empty( $_REQUEST['ewww_force'] ) && ! ( $new && $convert ) ) {
2148
  $results_msg = ewww_image_optimizer_check_table( $file, $orig_size );
2149
- $smart_reopt = ! empty( $_REQUEST['ewww_force_smart'] ) && ewww_image_optimizer_level_mismatch( $ewww_image->level, $compression_level ) ? true : false;
2150
  if ( $smart_reopt ) {
2151
  ewwwio_debug_message( "smart re-opt found level mismatch for $file, db says " . $ewww_image->level . " vs. current $compression_level" );
2152
  // If the current compression level is less than what was previously used, and the previous level was premium (or premium plus).
@@ -2162,7 +2166,7 @@ function ewww_image_optimizer( $file, $gallery_type = 4, $converted = false, $ne
2162
  if (
2163
  $compression_level >= 20 &&
2164
  ewww_image_optimizer_get_option( 'ewww_image_optimizer_cloud_key' ) &&
2165
- empty( $_REQUEST['ewww_webp_only'] )
2166
  ) {
2167
  list( $file, $converted, $result, $new_size, $backup_hash ) = ewww_image_optimizer_cloud_optimizer(
2168
  $file,
@@ -2207,7 +2211,7 @@ function ewww_image_optimizer( $file, $gallery_type = 4, $converted = false, $ne
2207
  );
2208
  }
2209
  // If png optimization is disabled.
2210
- if ( ! empty( $_REQUEST['ewww_webp_only'] ) ) {
2211
  $optimize = false;
2212
  } elseif ( ! ewww_image_optimizer_get_option( 'ewww_image_optimizer_png_level' ) ) {
2213
  // Tell the user all PNG tools are disabled.
@@ -2425,14 +2429,14 @@ function ewww_image_optimizer( $file, $gallery_type = 4, $converted = false, $ne
2425
  $webp_result = ewww_image_optimizer_webp_create( $file, $new_size, $type, $tools['CWEBP'], $orig_size !== $new_size );
2426
  break;
2427
  case 'image/gif':
2428
- if ( ! empty( $_REQUEST['ewww_webp_only'] ) ) {
2429
  break;
2430
  }
2431
  // If gif2png is turned on, and the image is in the WordPress media library.
2432
  if (
2433
  1 === (int) $gallery_type &&
2434
  $fullsize &&
2435
- ( ewww_image_optimizer_get_option( 'ewww_image_optimizer_gif_to_png' ) || ! empty( $_REQUEST['ewww_convert'] ) ) &&
2436
  ! ewww_image_optimizer_is_animated( $file )
2437
  ) {
2438
  // Generate the filename for a PNG:
@@ -2452,9 +2456,9 @@ function ewww_image_optimizer( $file, $gallery_type = 4, $converted = false, $ne
2452
  }
2453
  $compression_level = (int) ewww_image_optimizer_get_option( 'ewww_image_optimizer_gif_level' );
2454
  // Check for previous optimization, so long as the force flag is on and this isn't a new image that needs converting.
2455
- if ( empty( $_REQUEST['ewww_force'] ) && ! ( $new && $convert ) ) {
2456
  $results_msg = ewww_image_optimizer_check_table( $file, $orig_size );
2457
- $smart_reopt = ! empty( $_REQUEST['ewww_force_smart'] ) && ewww_image_optimizer_level_mismatch( $ewww_image->level, $compression_level ) ? true : false;
2458
  if ( $smart_reopt ) {
2459
  ewwwio_debug_message( "smart re-opt found level mismatch for $file, db says " . $ewww_image->level . " vs. current $compression_level" );
2460
  // If the current compression level is less than what was previously used, and the previous level was premium (or premium plus).
@@ -2597,13 +2601,13 @@ function ewww_image_optimizer( $file, $gallery_type = 4, $converted = false, $ne
2597
  } // End if().
2598
  break;
2599
  case 'application/pdf':
2600
- if ( ! empty( $_REQUEST['ewww_webp_only'] ) ) {
2601
  break;
2602
  }
2603
  $compression_level = (int) ewww_image_optimizer_get_option( 'ewww_image_optimizer_pdf_level' );
2604
- if ( empty( $_REQUEST['ewww_force'] ) ) {
2605
  $results_msg = ewww_image_optimizer_check_table( $file, $orig_size );
2606
- $smart_reopt = ! empty( $_REQUEST['ewww_force_smart'] ) && ewww_image_optimizer_level_mismatch( $ewww_image->level, $compression_level ) ? true : false;
2607
  if ( $smart_reopt ) {
2608
  ewwwio_debug_message( "smart re-opt found level mismatch for $file, db says " . $ewww_image->level . " vs. current $compression_level" );
2609
  // If the current compression level is less than what was previously used, and the previous level was premium (or premium plus).
@@ -2648,7 +2652,7 @@ function ewww_image_optimizer( $file, $gallery_type = 4, $converted = false, $ne
2648
  }
2649
  ewwwio_memory( __FUNCTION__ );
2650
  // Otherwise, send back the filename, the results (some sort of error message), the $converted flag, and the name of the original image.
2651
- if ( ! empty( $webp_result ) && ! empty( $_REQUEST['ewww_webp_only'] ) ) {
2652
  $result = $webp_result;
2653
  return array( true, $result, $converted, $original );
2654
  }
@@ -2667,6 +2671,7 @@ function ewww_image_optimizer( $file, $gallery_type = 4, $converted = false, $ne
2667
  */
2668
  function ewww_image_optimizer_webp_create( $file, $orig_size, $type, $tool, $recreate = false ) {
2669
  ewwwio_debug_message( '<b>' . __FUNCTION__ . '()</b>' );
 
2670
  $webpfile = $file . '.webp';
2671
  if ( apply_filters( 'ewww_image_optimizer_bypass_webp', false, $file ) ) {
2672
  ewwwio_debug_message( "webp generation bypassed: $file" );
@@ -2677,7 +2682,7 @@ function ewww_image_optimizer_webp_create( $file, $orig_size, $type, $tool, $rec
2677
  return esc_html__( 'Could not find file.', 'ewww-image-optimizer' );
2678
  } elseif ( ! is_writable( $file ) ) {
2679
  return esc_html__( 'File is not writable.', 'ewww-image-optimizer' );
2680
- } elseif ( ewwwio_is_file( $webpfile ) && empty( $_REQUEST['ewww_force'] ) && ! $recreate ) {
2681
  ewwwio_debug_message( 'webp file exists, not forcing or recreating' );
2682
  return esc_html__( 'WebP image already exists.', 'ewww-image-optimizer' );
2683
  }
@@ -2744,7 +2749,7 @@ function ewww_image_optimizer_install_pngout_wrapper() {
2744
  wp_die( esc_html__( 'You do not have permission to install image optimizer utilities.', 'ewww-image-optimizer' ) );
2745
  }
2746
  $sendback = ewww_image_optimizer_install_pngout();
2747
- wp_redirect( esc_url_raw( $sendback ) );
2748
  ewwwio_memory( __FUNCTION__ );
2749
  exit( 0 );
2750
  }
26
  */
27
  function ewww_image_optimizer_cloud_init() {
28
  ewwwio_debug_message( '<b>' . __FUNCTION__ . '()</b>' );
 
 
 
 
 
29
  if (
30
  ! defined( 'EWWW_IMAGE_OPTIMIZER_CLOUD' ) &&
31
  ewww_image_optimizer_get_option( 'ewww_image_optimizer_cloud_key' ) &&
44
  */
45
  function ewww_image_optimizer_exec_init() {
46
  ewwwio_debug_message( '<b>' . __FUNCTION__ . '()</b>' );
47
+ // TODO: this one will need to go in favor of the next conditional.
48
+ if ( false && defined( 'WPE_PLUGIN_VERSION' ) ) {
49
  add_action( 'network_admin_notices', 'ewww_image_optimizer_notice_wpengine' );
50
  add_action( 'admin_notices', 'ewww_image_optimizer_notice_wpengine' );
51
  if ( ! defined( 'EWWW_IMAGE_OPTIMIZER_NOEXEC' ) ) {
57
  if ( EWWW_IMAGE_OPTIMIZER_CLOUD ) {
58
  ewwwio_debug_message( 'cloud options enabled, shutting off binaries' );
59
  ewww_image_optimizer_disable_tools();
60
+ } elseif ( defined( 'WPCOMSH_VERSION' ) || ! empty( $_ENV['PANTHEON_ENVIRONMENT'] ) || defined( 'WPE_PLUGIN_VERSION' ) ) {
61
  if (
62
  ! ewww_image_optimizer_get_option( 'ewww_image_optimizer_cloud_key' ) &&
 
63
  ( ! is_object( $exactdn ) || ! $exactdn->get_exactdn_domain() )
64
  ) {
65
  add_action( 'network_admin_notices', 'ewww_image_optimizer_notice_hosting_requires_api' );
68
  if ( ! defined( 'EWWW_IMAGE_OPTIMIZER_NOEXEC' ) ) {
69
  define( 'EWWW_IMAGE_OPTIMIZER_NOEXEC', true );
70
  }
71
+ ewwwio_debug_message( 'WPE/wp.com/pantheon site, disabling tools' );
72
  ewww_image_optimizer_disable_tools();
73
  // Check if this is an unsupported OS (not Linux or Mac OSX or FreeBSD or Windows or SunOS).
74
  } elseif ( 'Linux' !== PHP_OS && 'Darwin' !== PHP_OS && 'FreeBSD' !== PHP_OS && 'WINNT' !== PHP_OS && 'SunOS' !== PHP_OS ) {
82
  add_action( 'load-upload.php', 'ewww_image_optimizer_tool_init', 9 );
83
  add_action( 'load-media-new.php', 'ewww_image_optimizer_tool_init' );
84
  add_action( 'load-media_page_ewww-image-optimizer-bulk', 'ewww_image_optimizer_tool_init' );
85
+ add_action( 'load-settings_page_ewww-image-optimizer-options', 'ewww_image_optimizer_tool_init' );
86
  add_action( 'load-plugins.php', 'ewww_image_optimizer_tool_init' );
87
  add_action( 'load-ims_gallery_page_ewww-ims-optimize', 'ewww_image_optimizer_tool_init' );
 
88
  }
89
  ewwwio_memory( __FUNCTION__ );
90
  }
165
  $webhost = 'WordPress.com';
166
  } elseif ( ! empty( $_ENV['PANTHEON_ENVIRONMENT'] ) ) {
167
  $webhost = 'Pantheon';
168
+ } elseif ( defined( 'WPE_PLUGIN_VERSION' ) ) {
169
+ $webhost = 'WP Engine';
170
  } else {
171
  return;
172
  }
173
+ echo "<div id='ewww-image-optimizer-cloud-key-required' class='notice notice-warning'><p><strong>" .
174
  /* translators: %s: Name of a web host, like WordPress.com or Pantheon. */
175
+ 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 ) ) .
176
+ "</strong> <a href='https://ewww.io/plans/'>" . esc_html__( 'Start your trial.', 'ewww-image-optimizer-cloud' ) .
177
+ "</a> <a href='" . esc_url( $settings_url ) . "'>" . esc_html__( 'Then, activate it on the settings page.', 'ewww-image-optimizer-cloud' ) . '</a></p></div>';
178
  }
179
 
180
  /**
182
  */
183
  function ewww_image_optimizer_notice_os() {
184
  ewwwio_debug_message( '<b>' . __FUNCTION__ . '()</b>' );
185
+ echo "<div id='ewww-image-optimizer-warning-os' class='notice notice-error'><p><strong>" .
186
+ esc_html__( 'The free mode of EWWW Image Optimizer is only supported on Linux, FreeBSD, Mac OSX, Solaris, and Windows.', 'ewww-image-optimizer' ) .
187
+ '</strong></p></div>';
188
  }
189
 
190
  /**
299
  * Alert the user when the tool folder could not be created.
300
  */
301
  function ewww_image_optimizer_tool_folder_notice() {
302
+ echo "<div id='ewww-image-optimizer-warning-tool-folder-create' class='notice notice-error'><p><strong>" . esc_html__( 'EWWW Image Optimizer could not create the tool folder', 'ewww-image-optimizer' ) . ': ' . esc_html( EWWW_IMAGE_OPTIMIZER_TOOL_PATH ) . '.</strong> ' . esc_html__( 'Please adjust permissions or create the folder', 'ewww-image-optimizer' ) . '.</p></div>';
303
  }
304
 
305
  /**
306
  * Alert the user when permissions on the tool folder are insufficient.
307
  */
308
  function ewww_image_optimizer_tool_folder_permissions_notice() {
 
 
 
 
 
 
 
 
 
309
  echo "<div id='ewww-image-optimizer-warning-tool-folder-permissions' class='notice notice-error'><p><strong>" .
310
  /* translators: %s: Folder location where executables should be installed */
311
+ sprintf( esc_html__( 'EWWW Image Optimizer could not install tools in %s', 'ewww-image-optimizer' ), esc_html( EWWW_IMAGE_OPTIMIZER_TOOL_PATH ) ) . '.</strong> ' .
312
  esc_html__( 'Please adjust permissions on the folder. If you have installed the tools elsewhere, use the override to skip the bundled tools.', 'ewww-image-optimizer' ) . ' ' .
313
  /* translators: s: Installation Instructions (link) */
314
  sprintf( esc_html__( 'For more details, see the %s.', 'ewww-image-optimizer' ), "<a href='https://docs.ewww.io/article/6-the-plugin-says-i-m-missing-something'>" . esc_html__( 'Installation Instructions', 'ewww-image-optimizer' ) . '</a>' ) . '</p></div>';
318
  * Alert the user when tool installation fails.
319
  */
320
  function ewww_image_optimizer_tool_installation_failed_notice() {
 
 
 
 
 
 
 
 
 
321
  echo "<div id='ewww-image-optimizer-warning-tool-install' class='notice notice-error'><p><strong>" .
322
  /* translators: %s: Folder location where executables should be installed */
323
+ sprintf( esc_html__( 'EWWW Image Optimizer could not install tools in %s', 'ewww-image-optimizer' ), esc_html( EWWW_IMAGE_OPTIMIZER_TOOL_PATH ) ) . '.</strong> ' .
324
  /* translators: %s: Installation Instructions */
325
  sprintf( esc_html__( 'For more details, see the %s.', 'ewww-image-optimizer' ), "<a href='https://docs.ewww.io/article/6-the-plugin-says-i-m-missing-something'>" . esc_html__( 'Installation Instructions', 'ewww-image-optimizer' ) . '</a>' ) . '</p></div>';
326
  }
537
  // Need to be a little particular with the quiet parameter.
538
  if ( 'quiet' !== $quiet && ! $no_compression ) {
539
  $exactdn_dismiss = ewww_image_optimizer_get_option( 'ewww_image_optimizer_exactdn' ) ? true : false;
540
+ ob_start();
541
+ $notice_class = 'notice notice-error';
542
+ $notice_action = __( 'An API key or Easy IO subscription will allow you to offload the compression to our dedicated servers instead.', 'ewww-image-optimizer' );
543
+ if ( ewww_image_optimizer_get_option( 'ewww_image_optimizer_exactdn' ) ) {
544
+ $notice_class = 'notice notice-warning is-dismissible';
545
+ $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' );
546
+ }
547
  // Display a warning if exec() is disabled, can't run local tools without it.
548
+ echo "<div id='ewww-image-optimizer-warning-exec' class='" . esc_attr( $notice_class ) . "'><p>" .
549
+ 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>' .
550
+ esc_html( $notice_action ) .
551
  '</p></div>';
552
  echo
553
  "<script>\n" .
562
  "\t});\n" .
563
  "});\n" .
564
  "</script>\n";
565
+ if (
566
+ ewww_image_optimizer_get_option( 'ewww_image_optimizer_exactdn' ) &&
567
+ ! ewww_image_optimizer_get_option( 'ewww_image_optimizer_local_mode' )
568
+ ) {
569
+ ob_end_clean();
570
+ } else {
571
+ ob_end_flush();
572
+ }
573
  }
574
  if ( ! defined( 'EWWW_IMAGE_OPTIMIZER_NOEXEC' ) ) {
575
  define( 'EWWW_IMAGE_OPTIMIZER_NOEXEC', true );
679
  sprintf(
680
  /* translators: 1: automatically (link) 2: manually (link) */
681
  esc_html__( 'You are missing pngout. Install %1$s or %2$s.', 'ewww-image-optimizer' ),
682
+ "<a href='" . esc_url( $pngout_install_url ) . "'>" . esc_html__( 'automatically', 'ewww-image-optimizer' ) . '</a>',
683
  '<a href="https://docs.ewww.io/article/13-installing-pngout" data-beacon-article="5854531bc697912ffd6c1afa">' . esc_html__( 'manually', 'ewww-image-optimizer' ) . '</a>'
684
  ) .
685
  '</p></div>';
694
  "<a href='http://pngquant.org/'>pngquant</a>",
695
  "<a href='http://www.lcdf.org/gifsicle/'>gifsicle</a>",
696
  "<a href='https://developers.google.com/speed/webp/'>cwebp</a>",
697
+ esc_html( $msg ),
698
+ "<a href='" . esc_url( $settings_page ) . "'>" . esc_html__( 'Settings Page', 'ewww-image-optimizer' ) . '</a>',
699
  "<a href='https://docs.ewww.io/article/6-the-plugin-says-i-m-missing-something' data-beacon-article='585371e3c697912ffd6c0ba1' target='_blank'>" . esc_html__( 'Installation Instructions', 'ewww-image-optimizer' ) . '</a>'
700
  ) .
701
  '</p></div>';
1138
  }
1139
  $path = realpath( $path );
1140
  if ( ! ewwwio_is_file( $path ) ) {
1141
+ ewwwio_debug_message( "$path is not a file, or out of bounds" );
1142
  return $type;
1143
  }
1144
+ global $eio_filesystem;
1145
+ ewwwio_get_filesystem();
1146
  if ( 'i' === $case ) {
1147
+ $file_contents = $eio_filesystem->get_contents( $path );
1148
+ if ( $file_contents ) {
1149
  // Read first 12 bytes, which equates to 24 hex characters.
1150
+ $magic = bin2hex( substr( $file_contents, 0, 12 ) );
1151
+ ewwwio_debug_message( $magic );
1152
  if ( 0 === strpos( $magic, '52494646' ) && 16 === strpos( $magic, '57454250' ) ) {
1153
  $type = 'image/webp';
1154
  ewwwio_debug_message( "ewwwio type: $type" );
1180
  }
1181
  }
1182
  if ( 'b' === $case ) {
1183
+ $file_contents = $eio_filesystem->get_contents( $path );
1184
+ if ( $file_contents ) {
1185
  // Read first 4 bytes, which equates to 8 hex characters.
1186
+ $magic = bin2hex( substr( $file_contents, 0, 4 ) );
1187
+ ewwwio_debug_message( $magic );
1188
  // Mac (Mach-O) binary.
1189
  if ( 'cffaedfe' === $magic || 'feedface' === $magic || 'feedfacf' === $magic || 'cefaedfe' === $magic || 'cafebabe' === $magic ) {
1190
  $type = 'application/x-executable';
1748
  return array( false, __( 'Optimization skipped', 'ewww-image-optimizer' ), $converted, $file );
1749
  }
1750
  global $ewww_image;
1751
+ global $ewww_force;
1752
+ global $ewww_force_smart;
1753
+ global $ewww_convert;
1754
+ global $ewww_webp_only;
1755
  // Initialize the original filename.
1756
  $original = $file;
1757
  $result = '';
1860
  if (
1861
  1 === (int) $gallery_type &&
1862
  $fullsize &&
1863
+ ( ewww_image_optimizer_get_option( 'ewww_image_optimizer_jpg_to_png' ) || ! empty( $ewww_convert ) ) &&
1864
+ empty( $ewww_webp_only )
1865
  ) {
1866
  // Generate the filename for a PNG:
1867
  // If this is a resize version.
1880
  }
1881
  $compression_level = (int) ewww_image_optimizer_get_option( 'ewww_image_optimizer_jpg_level' );
1882
  // Check for previous optimization, so long as the force flag is not on and this isn't a new image that needs converting.
1883
+ if ( empty( $ewww_force ) && ! ( $new && $convert ) ) {
1884
  $results_msg = ewww_image_optimizer_check_table( $file, $orig_size );
1885
+ $smart_reopt = ! empty( $ewww_force_smart ) && ewww_image_optimizer_level_mismatch( $ewww_image->level, $compression_level ) ? true : false;
1886
  if ( $smart_reopt ) {
1887
  ewwwio_debug_message( "smart re-opt found level mismatch for $file, db says " . $ewww_image->level . " vs. current $compression_level" );
1888
  // If the current compression level is less than what was previously used, and the previous level was premium (or premium plus).
1895
  }
1896
  }
1897
  $ewww_image->level = $compression_level;
1898
+ if ( $compression_level > 10 && empty( $ewww_webp_only ) ) {
1899
  list( $file, $converted, $result, $new_size, $backup_hash ) = ewww_image_optimizer_cloud_optimizer( $file, $type, $convert, $pngfile, 'image/png', $skip_lossy );
1900
  if ( $converted ) {
1901
  // Check to see if the user wants the originals deleted.
1933
  ! $skip['webp']
1934
  );
1935
  }
1936
+ if ( ! empty( $ewww_webp_only ) ) {
1937
  $optimize = false;
1938
  } elseif ( ! ewww_image_optimizer_get_option( 'ewww_image_optimizer_jpg_level' ) ) {
1939
  // Store an appropriate message in $result.
2104
  if (
2105
  1 === (int) $gallery_type &&
2106
  $fullsize &&
2107
+ ( ewww_image_optimizer_get_option( 'ewww_image_optimizer_png_to_jpg' ) || ! empty( $ewww_convert ) ) &&
2108
  ! $skip_lossy &&
2109
+ empty( $ewww_webp_only )
2110
  ) {
2111
  ewwwio_debug_message( 'PNG to JPG conversion turned on' );
2112
  $cloud_background = '';
2148
  } // End if().
2149
  $compression_level = (int) ewww_image_optimizer_get_option( 'ewww_image_optimizer_png_level' );
2150
  // Check for previous optimization, so long as the force flag is on and this isn't a new image that needs converting.
2151
+ if ( empty( $ewww_force ) && ! ( $new && $convert ) ) {
2152
  $results_msg = ewww_image_optimizer_check_table( $file, $orig_size );
2153
+ $smart_reopt = ! empty( $ewww_force_smart ) && ewww_image_optimizer_level_mismatch( $ewww_image->level, $compression_level ) ? true : false;
2154
  if ( $smart_reopt ) {
2155
  ewwwio_debug_message( "smart re-opt found level mismatch for $file, db says " . $ewww_image->level . " vs. current $compression_level" );
2156
  // If the current compression level is less than what was previously used, and the previous level was premium (or premium plus).
2166
  if (
2167
  $compression_level >= 20 &&
2168
  ewww_image_optimizer_get_option( 'ewww_image_optimizer_cloud_key' ) &&
2169
+ empty( $ewww_webp_only )
2170
  ) {
2171
  list( $file, $converted, $result, $new_size, $backup_hash ) = ewww_image_optimizer_cloud_optimizer(
2172
  $file,
2211
  );
2212
  }
2213
  // If png optimization is disabled.
2214
+ if ( ! empty( $ewww_webp_only ) ) {
2215
  $optimize = false;
2216
  } elseif ( ! ewww_image_optimizer_get_option( 'ewww_image_optimizer_png_level' ) ) {
2217
  // Tell the user all PNG tools are disabled.
2429
  $webp_result = ewww_image_optimizer_webp_create( $file, $new_size, $type, $tools['CWEBP'], $orig_size !== $new_size );
2430
  break;
2431
  case 'image/gif':
2432
+ if ( ! empty( $ewww_webp_only ) ) {
2433
  break;
2434
  }
2435
  // If gif2png is turned on, and the image is in the WordPress media library.
2436
  if (
2437
  1 === (int) $gallery_type &&
2438
  $fullsize &&
2439
+ ( ewww_image_optimizer_get_option( 'ewww_image_optimizer_gif_to_png' ) || ! empty( $ewww_convert ) ) &&
2440
  ! ewww_image_optimizer_is_animated( $file )
2441
  ) {
2442
  // Generate the filename for a PNG:
2456
  }
2457
  $compression_level = (int) ewww_image_optimizer_get_option( 'ewww_image_optimizer_gif_level' );
2458
  // Check for previous optimization, so long as the force flag is on and this isn't a new image that needs converting.
2459
+ if ( empty( $ewww_force ) && ! ( $new && $convert ) ) {
2460
  $results_msg = ewww_image_optimizer_check_table( $file, $orig_size );
2461
+ $smart_reopt = ! empty( $ewww_force_smart ) && ewww_image_optimizer_level_mismatch( $ewww_image->level, $compression_level ) ? true : false;
2462
  if ( $smart_reopt ) {
2463
  ewwwio_debug_message( "smart re-opt found level mismatch for $file, db says " . $ewww_image->level . " vs. current $compression_level" );
2464
  // If the current compression level is less than what was previously used, and the previous level was premium (or premium plus).
2601
  } // End if().
2602
  break;
2603
  case 'application/pdf':
2604
+ if ( ! empty( $ewww_webp_only ) ) {
2605
  break;
2606
  }
2607
  $compression_level = (int) ewww_image_optimizer_get_option( 'ewww_image_optimizer_pdf_level' );
2608
+ if ( empty( $ewww_force ) ) {
2609
  $results_msg = ewww_image_optimizer_check_table( $file, $orig_size );
2610
+ $smart_reopt = ! empty( $ewww_force_smart ) && ewww_image_optimizer_level_mismatch( $ewww_image->level, $compression_level ) ? true : false;
2611
  if ( $smart_reopt ) {
2612
  ewwwio_debug_message( "smart re-opt found level mismatch for $file, db says " . $ewww_image->level . " vs. current $compression_level" );
2613
  // If the current compression level is less than what was previously used, and the previous level was premium (or premium plus).
2652
  }
2653
  ewwwio_memory( __FUNCTION__ );
2654
  // Otherwise, send back the filename, the results (some sort of error message), the $converted flag, and the name of the original image.
2655
+ if ( ! empty( $webp_result ) && ! empty( $ewww_webp_only ) ) {
2656
  $result = $webp_result;
2657
  return array( true, $result, $converted, $original );
2658
  }
2671
  */
2672
  function ewww_image_optimizer_webp_create( $file, $orig_size, $type, $tool, $recreate = false ) {
2673
  ewwwio_debug_message( '<b>' . __FUNCTION__ . '()</b>' );
2674
+ global $ewww_force;
2675
  $webpfile = $file . '.webp';
2676
  if ( apply_filters( 'ewww_image_optimizer_bypass_webp', false, $file ) ) {
2677
  ewwwio_debug_message( "webp generation bypassed: $file" );
2682
  return esc_html__( 'Could not find file.', 'ewww-image-optimizer' );
2683
  } elseif ( ! is_writable( $file ) ) {
2684
  return esc_html__( 'File is not writable.', 'ewww-image-optimizer' );
2685
+ } elseif ( ewwwio_is_file( $webpfile ) && empty( $ewww_force ) && ! $recreate ) {
2686
  ewwwio_debug_message( 'webp file exists, not forcing or recreating' );
2687
  return esc_html__( 'WebP image already exists.', 'ewww-image-optimizer' );
2688
  }
2749
  wp_die( esc_html__( 'You do not have permission to install image optimizer utilities.', 'ewww-image-optimizer' ) );
2750
  }
2751
  $sendback = ewww_image_optimizer_install_pngout();
2752
+ wp_safe_redirect( $sendback );
2753
  ewwwio_memory( __FUNCTION__ );
2754
  exit( 0 );
2755
  }