EWWW Image Optimizer - Version 5.7.1

Version Description

  • added: alert on domain change for Easy IO, like if you clone from a production environment to staging
  • changed: Easy IO domain and plan_id refresh automatically when visiting settings page
  • changed: better JS WebP and WPBakery Page Builder compatibility
  • changed: restore savings gauge for network settings page
  • fixed: resize detection visible for editors, should be admin-only
  • fixed: (force) re-optimize not working with parallel mode
  • fixed: upload error when WP cannot load image editor
Download this release

Release Info

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

Code changes from version 5.6.2 to 5.7.1

.travis.yml CHANGED
@@ -20,7 +20,8 @@ services:
20
 
21
  env:
22
  - WP_VERSION=latest WP_MULTISITE=0
23
- - WP_VERSION=5.1 WP_MULTISITE=0
 
24
 
25
  jobs:
26
  include:
@@ -40,8 +41,6 @@ before_script:
40
  - |
41
  if [[ ${TRAVIS_PHP_VERSION:0:2} == "5." ]]; then
42
  composer global require phpunit/phpunit ^5
43
- elif [[ ${WP_VERSION:0:3} == "5.0" ]]; then
44
- composer global require phpunit/phpunit ^6
45
  else
46
  composer global require phpunit/phpunit ^7
47
  fi
20
 
21
  env:
22
  - WP_VERSION=latest WP_MULTISITE=0
23
+ - WP_VERSION=5.4 WP_MULTISITE=0
24
+ - WP_VERSION=5.2 WP_MULTISITE=0
25
 
26
  jobs:
27
  include:
41
  - |
42
  if [[ ${TRAVIS_PHP_VERSION:0:2} == "5." ]]; then
43
  composer global require phpunit/phpunit ^5
 
 
44
  else
45
  composer global require phpunit/phpunit ^7
46
  fi
aux-optimize.php CHANGED
@@ -82,6 +82,7 @@ function ewww_image_optimizer_aux_images() {
82
  * @global object $wpdb
83
  */
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 ) ) {
@@ -102,7 +103,9 @@ function ewww_image_optimizer_aux_images_table() {
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 );
 
 
106
  $search_count = $ewwwdb->get_var( $ewwwdb->prepare( "SELECT COUNT(*) FROM $ewwwdb->ewwwio_images WHERE pending=0 AND image_size > 0 AND updates > %d AND path LIKE %s", $debug_query, '%' . $ewwwdb->esc_like( $search ) . '%' ) );
107
  if ( $search_count < $per_page ) {
108
  /* translators: %d: number of image records found */
@@ -113,13 +116,21 @@ function ewww_image_optimizer_aux_images_table() {
113
  }
114
  $total = ceil( $search_count / $per_page );
115
  } else {
116
- $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 ORDER BY " . ( $debug_query ? 'updates,id' : 'id' ) . ' DESC LIMIT %d,%d', $debug_query, $offset, $per_page ), ARRAY_A );
 
117
  if ( $debug_query ) {
 
118
  $search_count = $ewwwdb->get_var( $ewwwdb->prepare( "SELECT COUNT(*) FROM $ewwwdb->ewwwio_images WHERE pending=0 AND image_size > 0 AND updates > %d", $debug_query ) );
119
  $total = ceil( $search_count / $per_page );
 
 
 
 
 
 
 
 
120
  }
121
- /* translators: %d: number of image records found */
122
- $output['search_result'] = sprintf( esc_html__( '%d items displayed', 'ewww-image-optimizer' ), count( $already_optimized ) );
123
  }
124
  /* translators: 1: current page in list of images 2: total pages for list of images */
125
  $output['pagination'] = sprintf( esc_html__( 'page %1$d of %2$d', 'ewww-image-optimizer' ), (int) $_POST['ewww_offset'] + 1, $total );
@@ -403,7 +414,7 @@ function ewww_image_optimizer_aux_images_converted_clean() {
403
  die( wp_json_encode( array( 'finished' => 1 ) ) );
404
  }
405
 
406
- // Because some plugins might have loose filters (looking at your WPML).
407
  remove_all_filters( 'wp_delete_file' );
408
 
409
  foreach ( $converted_images as $optimized_image ) {
@@ -432,6 +443,212 @@ function ewww_image_optimizer_aux_images_converted_clean() {
432
  die( wp_json_encode( array( 'completed' => $completed ) ) );
433
  }
434
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
435
  /**
436
  * Cleanup duplicate and unreferenced records from the images table.
437
  *
@@ -487,7 +704,7 @@ function ewww_image_optimizer_aux_images_clean() {
487
  function ewww_image_optimizer_aux_meta_clean() {
488
  ewwwio_debug_message( '<b>' . __FUNCTION__ . '()</b>' );
489
  // Verify that an authorized user has called function.
490
- $permissions = apply_filters( 'ewww_image_optimizer_bulk_permissions', '' );
491
  if ( empty( $_REQUEST['ewww_wpnonce'] ) || ! wp_verify_nonce( sanitize_key( $_REQUEST['ewww_wpnonce'] ), 'ewww-image-optimizer-tools' ) || ! current_user_can( $permissions ) ) {
492
  ewwwio_ob_clean();
493
  die( wp_json_encode( array( 'error' => esc_html__( 'Access token has expired, please reload the page.', 'ewww-image-optimizer' ) ) ) );
@@ -534,7 +751,7 @@ function ewww_image_optimizer_aux_meta_clean() {
534
  */
535
  function ewww_image_optimizer_aux_images_table_count() {
536
  global $wpdb;
537
- $count = $wpdb->get_var( "SELECT COUNT(*) FROM $wpdb->ewwwio_images WHERE pending=0 AND image_size > 0" );
538
  // Verify that an authorized user has called function.
539
  $permissions = apply_filters( 'ewww_image_optimizer_bulk_permissions', '' );
540
  if ( ! empty( $_REQUEST['ewww_inline'] ) &&
@@ -678,6 +895,27 @@ function ewww_image_optimizer_image_is_pending( $id, $gallery = 'media' ) {
678
  return $wpdb->get_var( $wpdb->prepare( "SELECT attachment_id FROM $wpdb->ewwwio_queue WHERE attachment_id = %d AND gallery = %s", $id, $gallery ) );
679
  }
680
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
681
  /**
682
  * Retrieve an image ID from the ewwwio_queue table.
683
  *
@@ -1296,9 +1534,12 @@ function ewww_image_optimizer_aux_images_cleanup( $auto = false ) {
1296
  add_action( 'wp_ajax_bulk_aux_images_table', 'ewww_image_optimizer_aux_images_table' );
1297
  add_action( 'wp_ajax_bulk_aux_images_table_count', 'ewww_image_optimizer_aux_images_table_count' );
1298
  add_action( 'wp_ajax_bulk_aux_images_table_clear', 'ewww_image_optimizer_aux_images_clear_all' );
 
1299
  add_action( 'wp_ajax_bulk_aux_images_count_converted', 'ewww_image_optimizer_aux_images_count_converted' );
1300
  add_action( 'wp_ajax_bulk_aux_images_converted_clean', 'ewww_image_optimizer_aux_images_converted_clean' );
1301
  add_action( 'wp_ajax_bulk_aux_images_table_clean', 'ewww_image_optimizer_aux_images_clean' );
1302
  add_action( 'wp_ajax_bulk_aux_images_meta_clean', 'ewww_image_optimizer_aux_meta_clean' );
1303
- add_action( 'wp_ajax_bulk_aux_images_remove', 'ewww_image_optimizer_aux_images_remove' );
 
 
1304
  ?>
82
  * @global object $wpdb
83
  */
84
  function ewww_image_optimizer_aux_images_table() {
85
+ ewwwio_debug_message( '<b>' . __FUNCTION__ . '()</b>' );
86
  // Verify that an authorized user has called function.
87
  $permissions = apply_filters( 'ewww_image_optimizer_bulk_permissions', '' );
88
  if ( empty( $_REQUEST['ewww_wpnonce'] ) || ! wp_verify_nonce( sanitize_key( $_REQUEST['ewww_wpnonce'] ), 'ewww-image-optimizer-tools' ) || ! current_user_can( $permissions ) ) {
103
  $total = empty( $_POST['ewww_total_pages'] ) ? 0 : (int) $_POST['ewww_total_pages'];
104
  $output = array();
105
  if ( ! empty( $search ) ) {
106
+ ewwwio_debug_message( $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 DESC,id' : 'id' ) . ' DESC LIMIT %d,%d', $debug_query, '%' . $ewwwdb->esc_like( $search ) . '%', $offset, $per_page ) );
107
+ ewwwio_debug_message( $ewwwdb->prepare( "SELECT COUNT(*) FROM $ewwwdb->ewwwio_images WHERE pending=0 AND image_size > 0 AND updates > %d AND path LIKE %s", $debug_query, '%' . $ewwwdb->esc_like( $search ) . '%' ) );
108
+ $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 DESC,id' : 'id' ) . ' DESC LIMIT %d,%d', $debug_query, '%' . $ewwwdb->esc_like( $search ) . '%', $offset, $per_page ), ARRAY_A );
109
  $search_count = $ewwwdb->get_var( $ewwwdb->prepare( "SELECT COUNT(*) FROM $ewwwdb->ewwwio_images WHERE pending=0 AND image_size > 0 AND updates > %d AND path LIKE %s", $debug_query, '%' . $ewwwdb->esc_like( $search ) . '%' ) );
110
  if ( $search_count < $per_page ) {
111
  /* translators: %d: number of image records found */
116
  }
117
  $total = ceil( $search_count / $per_page );
118
  } else {
119
+ ewwwio_debug_message( $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 ORDER BY " . ( $debug_query ? 'updates DESC,id' : 'id' ) . ' DESC LIMIT %d,%d', $debug_query, $offset, $per_page ) );
120
+ $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 ORDER BY " . ( $debug_query ? 'updates DESC,id' : 'id' ) . ' DESC LIMIT %d,%d', $debug_query, $offset, $per_page ), ARRAY_A );
121
  if ( $debug_query ) {
122
+ ewwwio_debug_message( $ewwwdb->prepare( "SELECT COUNT(*) FROM $ewwwdb->ewwwio_images WHERE pending=0 AND image_size > 0 AND updates > %d", $debug_query ) );
123
  $search_count = $ewwwdb->get_var( $ewwwdb->prepare( "SELECT COUNT(*) FROM $ewwwdb->ewwwio_images WHERE pending=0 AND image_size > 0 AND updates > %d", $debug_query ) );
124
  $total = ceil( $search_count / $per_page );
125
+ if ( $search_count > $per_page ) {
126
+ /* translators: 1: number of image records displayed, 2: number of total records found */
127
+ $output['search_result'] = sprintf( esc_html__( '%1$d items displayed of %2$d records found', 'ewww-image-optimizer' ), count( $already_optimized ), $search_count );
128
+ }
129
+ }
130
+ if ( empty( $output['search_result'] ) ) {
131
+ /* translators: %d: number of image records found */
132
+ $output['search_result'] = sprintf( esc_html__( '%d items displayed', 'ewww-image-optimizer' ), count( $already_optimized ) );
133
  }
 
 
134
  }
135
  /* translators: 1: current page in list of images 2: total pages for list of images */
136
  $output['pagination'] = sprintf( esc_html__( 'page %1$d of %2$d', 'ewww-image-optimizer' ), (int) $_POST['ewww_offset'] + 1, $total );
414
  die( wp_json_encode( array( 'finished' => 1 ) ) );
415
  }
416
 
417
+ // Because some plugins might have loose filters (looking at you WPML).
418
  remove_all_filters( 'wp_delete_file' );
419
 
420
  foreach ( $converted_images as $optimized_image ) {
443
  die( wp_json_encode( array( 'completed' => $completed ) ) );
444
  }
445
 
446
+ /**
447
+ * Cleanup WebP images using records from the ewwwio_images table.
448
+ *
449
+ * @global object $wpdb
450
+ */
451
+ function ewww_image_optimizer_aux_images_webp_clean() {
452
+ ewwwio_debug_message( '<b>' . __FUNCTION__ . '()</b>' );
453
+ // Verify that an authorized user has called function.
454
+ $permissions = apply_filters( 'ewww_image_optimizer_admin_permissions', '' );
455
+ if ( empty( $_REQUEST['ewww_wpnonce'] ) || ! wp_verify_nonce( sanitize_key( $_REQUEST['ewww_wpnonce'] ), 'ewww-image-optimizer-tools' ) || ! current_user_can( $permissions ) ) {
456
+ ewwwio_ob_clean();
457
+ die( wp_json_encode( array( 'error' => esc_html__( 'Access token has expired, please reload the page.', 'ewww-image-optimizer' ) ) ) );
458
+ }
459
+ global $wpdb;
460
+ if ( strpos( $wpdb->charset, 'utf8' ) === false ) {
461
+ ewww_image_optimizer_db_init();
462
+ global $ewwwdb;
463
+ } else {
464
+ $ewwwdb = $wpdb;
465
+ }
466
+ $completed = 0;
467
+ $per_page = 50;
468
+ $offset = empty( $_POST['ewww_offset'] ) ? 0 : (int) $_POST['ewww_offset'];
469
+
470
+ ewwwio_debug_message( "searching for $per_page records starting at $offset" );
471
+ $optimized_images = $wpdb->get_results( $wpdb->prepare( "SELECT path,converted,id FROM $wpdb->ewwwio_images WHERE pending = 0 AND image_size > 0 AND updates > 0 ORDER BY id DESC LIMIT %d,%d", $offset, $per_page ), ARRAY_A );
472
+
473
+ if ( empty( $optimized_images ) || ! is_countable( $optimized_images ) || 0 === count( $optimized_images ) ) {
474
+ die( wp_json_encode( array( 'finished' => 1 ) ) );
475
+ }
476
+
477
+ // Because some plugins might have loose filters (looking at you WPML).
478
+ remove_all_filters( 'wp_delete_file' );
479
+
480
+ foreach ( $optimized_images as $optimized_image ) {
481
+ $completed++;
482
+ $file = ewww_image_optimizer_absolutize_path( $optimized_image['path'] );
483
+ ewwwio_debug_message( "looking for $file.webp" );
484
+ if ( ! ewww_image_optimizer_stream_wrapped( $file ) && ewwwio_is_file( $file . '.webp' ) ) {
485
+ ewwwio_debug_message( "removing: $file.webp" );
486
+ if ( ewwwio_delete_file( $file . '.webp' ) ) {
487
+ ewwwio_debug_message( "removed $file.webp" );
488
+ } else {
489
+ /* translators: %s: file name */
490
+ die( wp_json_encode( array( 'error' => sprintf( esc_html__( 'Could not delete %s, please remove manually or fix permissions and try again.', 'ewww-image-optimizer' ), esc_html( $file . '.webp' ) ) ) ) );
491
+ }
492
+ }
493
+ if ( ! empty( $optimized_image['converted'] ) ) {
494
+ $file = ewww_image_optimizer_absolutize_path( $optimized_image['converted'] );
495
+ ewwwio_debug_message( "$file was converted, checking if webp version exists" );
496
+ if ( ! ewww_image_optimizer_stream_wrapped( $file ) && ewwwio_is_file( $file . '.webp' ) ) {
497
+ ewwwio_debug_message( "removing: $file.webp" );
498
+ if ( ewwwio_delete_file( $file . '.webp' ) ) {
499
+ ewwwio_debug_message( "removed $file.webp" );
500
+ } else {
501
+ /* translators: %s: file name */
502
+ die( wp_json_encode( array( 'error' => sprintf( esc_html__( 'Could not delete %s, please remove manually or fix permissions and try again.', 'ewww-image-optimizer' ), esc_html( $file . '.webp' ) ) ) ) );
503
+ }
504
+ }
505
+ }
506
+ } // End foreach().
507
+ die( wp_json_encode( array( 'completed' => $completed ) ) );
508
+ }
509
+
510
+ /**
511
+ * Cleans up WebP images via AJAX for a particular attachment.
512
+ *
513
+ * @global object $wpdb
514
+ * @global object $ewwwdb A clone of $wpdb unless it is lacking utf8 connectivity.
515
+ */
516
+ function ewww_image_optimizer_delete_webp() {
517
+ ewwwio_debug_message( '<b>' . __FUNCTION__ . '()</b>' );
518
+ // Verify that an authorized user has called function.
519
+ $permissions = apply_filters( 'ewww_image_optimizer_admin_permissions', '' );
520
+ if ( empty( $_REQUEST['ewww_wpnonce'] ) || ! wp_verify_nonce( sanitize_key( $_REQUEST['ewww_wpnonce'] ), 'ewww-image-optimizer-tools' ) || ! current_user_can( $permissions ) ) {
521
+ ewwwio_ob_clean();
522
+ die( wp_json_encode( array( 'error' => esc_html__( 'Access token has expired, please reload the page.', 'ewww-image-optimizer' ) ) ) );
523
+ }
524
+ global $wpdb;
525
+ if ( strpos( $wpdb->charset, 'utf8' ) === false ) {
526
+ ewww_image_optimizer_db_init();
527
+ global $ewwwdb;
528
+ } else {
529
+ $ewwwdb = $wpdb;
530
+ }
531
+ if ( empty( $_POST['attachment_id'] ) ) {
532
+ die;
533
+ }
534
+
535
+ // Because some plugins might have loose filters (looking at you WPML).
536
+ remove_all_filters( 'wp_delete_file' );
537
+
538
+ $id = (int) $_POST['attachment_id'];
539
+ // Finds non-meta images to remove from disk, and from db, as well as converted originals.
540
+ $optimized_images = $ewwwdb->get_results( "SELECT path,converted FROM $ewwwdb->ewwwio_images WHERE attachment_id = $id AND gallery = 'media'", ARRAY_A );
541
+ if ( $optimized_images ) {
542
+ if ( ewww_image_optimizer_iterable( $optimized_images ) ) {
543
+ foreach ( $optimized_images as $image ) {
544
+ if ( ! empty( $image['path'] ) ) {
545
+ $image['path'] = ewww_image_optimizer_absolutize_path( $image['path'] );
546
+ }
547
+ if ( ! empty( $image['path'] ) ) {
548
+ if ( ewwwio_is_file( $image['path'] . '.webp' ) ) {
549
+ ewwwio_debug_message( 'removing: ' . $image['path'] . '.webp' );
550
+ ewwwio_delete_file( $image['path'] . '.webp' );
551
+ }
552
+ $webpfileold = preg_replace( '/\.\w+$/', '.webp', $image['path'] );
553
+ if ( ewwwio_is_file( $webpfileold ) ) {
554
+ ewwwio_debug_message( 'removing: ' . $webpfileold );
555
+ ewwwio_delete_file( $webpfileold );
556
+ }
557
+ }
558
+ if ( ! empty( $image['converted'] ) && ewwwio_is_file( $image['converted'] . '.webp' ) ) {
559
+ ewwwio_debug_message( 'removing: ' . $image['converted'] . '.webp' );
560
+ ewwwio_delete_file( $image['converted'] . '.webp' );
561
+ }
562
+ }
563
+ }
564
+ }
565
+ $s3_path = false;
566
+ $s3_dir = false;
567
+ if ( class_exists( 'S3_Uploads' ) ) {
568
+ $s3_path = get_attached_file( $id );
569
+ if ( 0 === strpos( $s3_path, 's3://' ) ) {
570
+ ewwwio_debug_message( 'removing: ' . $s3_path . '.webp' );
571
+ unlink( $s3_path . '.webp' );
572
+ }
573
+ $s3_dir = trailingslashit( dirname( $s3_path ) );
574
+ }
575
+ // Retrieve the image metadata.
576
+ $meta = wp_get_attachment_metadata( $id );
577
+ // If the attachment has an original file set.
578
+ if ( ! empty( $meta['orig_file'] ) ) {
579
+ // Get the filepath from the metadata.
580
+ $file_path = $meta['orig_file'];
581
+ // Get the base filename.
582
+ $filename = wp_basename( $file_path );
583
+ // Delete any residual webp versions.
584
+ $webpfile = $file_path . '.webp';
585
+ $webpfileold = preg_replace( '/\.\w+$/', '.webp', $file_path );
586
+ if ( ewwwio_is_file( $webpfile ) ) {
587
+ ewwwio_debug_message( 'removing: ' . $webpfile );
588
+ ewwwio_delete_file( $webpfile );
589
+ }
590
+ if ( ewwwio_is_file( $webpfileold ) ) {
591
+ ewwwio_debug_message( 'removing: ' . $webpfileold );
592
+ ewwwio_delete_file( $webpfileold );
593
+ }
594
+ }
595
+ $file_path = get_attached_file( $id );
596
+ // If the attachment has an original file set.
597
+ if ( ! empty( $meta['original_image'] ) ) {
598
+ // One way or another, $file_path is now set, and we can get the base folder name.
599
+ $base_dir = dirname( $file_path ) . '/';
600
+ // Get the original filename from the metadata.
601
+ $orig_path = $base_dir . wp_basename( $meta['original_image'] );
602
+ // Delete any residual webp versions.
603
+ $webpfile = $orig_path . '.webp';
604
+ if ( ewwwio_is_file( $webpfile ) ) {
605
+ ewwwio_debug_message( 'removing: ' . $webpfile );
606
+ ewwwio_delete_file( $webpfile );
607
+ }
608
+ if ( $s3_path && $s3_dir && wp_basename( $meta['original_image'] ) ) {
609
+ ewwwio_debug_message( 'removing: ' . $s3_dir . wp_basename( $meta['original_image'] ) . '.webp' );
610
+ unlink( $s3_dir . wp_basename( $meta['original_image'] ) . '.webp' );
611
+ }
612
+ }
613
+ // Resized versions, so we can continue.
614
+ if ( isset( $meta['sizes'] ) && ewww_image_optimizer_iterable( $meta['sizes'] ) ) {
615
+ // One way or another, $file_path is now set, and we can get the base folder name.
616
+ $base_dir = dirname( $file_path ) . '/';
617
+ foreach ( $meta['sizes'] as $size => $data ) {
618
+ // Delete any residual webp versions.
619
+ $webpfile = $base_dir . wp_basename( $data['file'] ) . '.webp';
620
+ $webpfileold = preg_replace( '/\.\w+$/', '.webp', $base_dir . wp_basename( $data['file'] ) );
621
+ if ( ewwwio_is_file( $webpfile ) ) {
622
+ ewwwio_debug_message( 'removing: ' . $webpfile );
623
+ ewwwio_delete_file( $webpfile );
624
+ }
625
+ if ( ewwwio_is_file( $webpfileold ) ) {
626
+ ewwwio_debug_message( 'removing: ' . $webpfileold );
627
+ ewwwio_delete_file( $webpfileold );
628
+ }
629
+ if ( $s3_path && $s3_dir && wp_basename( $data['file'] ) ) {
630
+ ewwwio_debug_message( 'removing: ' . $s3_dir . wp_basename( $data['file'] ) . '.webp' );
631
+ unlink( $s3_dir . wp_basename( $data['file'] ) . '.webp' );
632
+ }
633
+ // If the original resize is set, and still exists.
634
+ if ( ! empty( $data['orig_file'] ) && ewwwio_is_file( $base_dir . $data['orig_file'] ) . '.webp' ) {
635
+ ewwwio_debug_message( 'removing: ' . $base_dir . $data['orig_file'] . '.webp' );
636
+ ewwwio_delete_file( $base_dir . $data['orig_file'] . '.webp' );
637
+ }
638
+ }
639
+ }
640
+ if ( ewwwio_is_file( $file_path . '.webp' ) ) {
641
+ ewwwio_debug_message( 'removing: ' . $file_path . '.webp' );
642
+ ewwwio_delete_file( $image['path'] . '.webp' );
643
+ }
644
+ $webpfileold = preg_replace( '/\.\w+$/', '.webp', $file_path );
645
+ if ( ewwwio_is_file( $webpfileold ) ) {
646
+ ewwwio_debug_message( 'removing: ' . $webpfileold );
647
+ ewwwio_delete_file( $webpfileold );
648
+ }
649
+ die( wp_json_encode( array( 'completed' => 1 ) ) );
650
+ }
651
+
652
  /**
653
  * Cleanup duplicate and unreferenced records from the images table.
654
  *
704
  function ewww_image_optimizer_aux_meta_clean() {
705
  ewwwio_debug_message( '<b>' . __FUNCTION__ . '()</b>' );
706
  // Verify that an authorized user has called function.
707
+ $permissions = apply_filters( 'ewww_image_optimizer_admin_permissions', '' );
708
  if ( empty( $_REQUEST['ewww_wpnonce'] ) || ! wp_verify_nonce( sanitize_key( $_REQUEST['ewww_wpnonce'] ), 'ewww-image-optimizer-tools' ) || ! current_user_can( $permissions ) ) {
709
  ewwwio_ob_clean();
710
  die( wp_json_encode( array( 'error' => esc_html__( 'Access token has expired, please reload the page.', 'ewww-image-optimizer' ) ) ) );
751
  */
752
  function ewww_image_optimizer_aux_images_table_count() {
753
  global $wpdb;
754
+ $count = $wpdb->get_var( "SELECT COUNT(*) FROM $wpdb->ewwwio_images WHERE pending=0 AND image_size > 0 AND updates > 0" );
755
  // Verify that an authorized user has called function.
756
  $permissions = apply_filters( 'ewww_image_optimizer_bulk_permissions', '' );
757
  if ( ! empty( $_REQUEST['ewww_inline'] ) &&
895
  return $wpdb->get_var( $wpdb->prepare( "SELECT attachment_id FROM $wpdb->ewwwio_queue WHERE attachment_id = %d AND gallery = %s", $id, $gallery ) );
896
  }
897
 
898
+ /**
899
+ * Retrieve all the images (and PDFs) from the wp_posts table.
900
+ *
901
+ * @global object $wpdb
902
+ */
903
+ function ewww_image_optimizer_get_all_attachments() {
904
+ ewwwio_debug_message( '<b>' . __FUNCTION__ . '()</b>' );
905
+ $permissions = apply_filters( 'ewww_image_optimizer_admin_permissions', '' );
906
+ if ( empty( $_REQUEST['ewww_wpnonce'] ) || ! wp_verify_nonce( sanitize_key( $_REQUEST['ewww_wpnonce'] ), 'ewww-image-optimizer-tools' ) || ! current_user_can( $permissions ) ) {
907
+ ewwwio_ob_clean();
908
+ die( wp_json_encode( array( 'error' => esc_html__( 'Access token has expired, please reload the page.', 'ewww-image-optimizer' ) ) ) );
909
+ }
910
+ global $wpdb;
911
+ $attachments = $wpdb->get_col( "SELECT ID FROM $wpdb->posts WHERE (post_type = 'attachment' OR post_type = 'ims_image') AND (post_mime_type LIKE '%%image%%' OR post_mime_type LIKE '%%pdf%%') ORDER BY ID DESC" );
912
+ if ( empty( $attachments ) || ! is_countable( $attachments ) || 0 === count( $attachments ) ) {
913
+ die( wp_json_encode( array( 'error' => esc_html__( 'No media uploads found.', 'ewww-image-optimizer' ) ) ) );
914
+ }
915
+ ewwwio_debug_message( gettype( $attachments ) );
916
+ die( wp_json_encode( $attachments ) );
917
+ }
918
+
919
  /**
920
  * Retrieve an image ID from the ewwwio_queue table.
921
  *
1534
  add_action( 'wp_ajax_bulk_aux_images_table', 'ewww_image_optimizer_aux_images_table' );
1535
  add_action( 'wp_ajax_bulk_aux_images_table_count', 'ewww_image_optimizer_aux_images_table_count' );
1536
  add_action( 'wp_ajax_bulk_aux_images_table_clear', 'ewww_image_optimizer_aux_images_clear_all' );
1537
+ add_action( 'wp_ajax_bulk_aux_images_remove', 'ewww_image_optimizer_aux_images_remove' );
1538
  add_action( 'wp_ajax_bulk_aux_images_count_converted', 'ewww_image_optimizer_aux_images_count_converted' );
1539
  add_action( 'wp_ajax_bulk_aux_images_converted_clean', 'ewww_image_optimizer_aux_images_converted_clean' );
1540
  add_action( 'wp_ajax_bulk_aux_images_table_clean', 'ewww_image_optimizer_aux_images_clean' );
1541
  add_action( 'wp_ajax_bulk_aux_images_meta_clean', 'ewww_image_optimizer_aux_meta_clean' );
1542
+ add_action( 'wp_ajax_bulk_aux_images_webp_clean', 'ewww_image_optimizer_aux_images_webp_clean' );
1543
+ add_action( 'wp_ajax_bulk_aux_images_delete_webp', 'ewww_image_optimizer_delete_webp' );
1544
+ add_action( 'wp_ajax_ewwwio_get_all_attachments', 'ewww_image_optimizer_get_all_attachments' );
1545
  ?>
bulk.php CHANGED
@@ -100,6 +100,15 @@ function ewww_image_optimizer_display_tools() {
100
  echo "<div id='ewww-clean-converted-progressbar' style='display:none;'></div>";
101
  echo "<div id='ewww-clean-converted-progress' style='display:none;'></div>";
102
 
 
 
 
 
 
 
 
 
 
103
  $as3cf_remove = false;
104
  if ( class_exists( 'Amazon_S3_And_CloudFront' ) ) {
105
  global $as3cf;
@@ -202,6 +211,8 @@ function ewww_image_optimizer_tool_script( $hook ) {
202
  'original_restored' => esc_html__( 'Original Restored', 'ewww-image-optimizer' ),
203
  'restoring' => '<p>' . esc_html__( 'Restoring', 'ewww-image-optimizer' ) . "&nbsp;<img src='$loading_image' /></p>",
204
  'finished' => '<p><b>' . esc_html__( 'Finished', 'ewww-image-optimizer' ) . '</b></p>',
 
 
205
  /* translators: used for Table Cleanup progress bar, like so: batch 32/346 */
206
  'batch' => esc_html__( 'batch', 'ewww-image-optimizer' ),
207
  'erase_warning' => $erase_warning,
@@ -856,7 +867,7 @@ function ewww_image_optimizer_should_resize( $file, $media = false ) {
856
  ewwwio_debug_message( '<b>' . __FUNCTION__ . '()</b>' );
857
  if (
858
  ! ewwwio_is_file( $file ) ||
859
- ! ewww_image_optimizer_get_option( 'ewww_image_optimizer_resize_existing' ) ||
860
  function_exists( 'imsanity_get_max_width_height' )
861
  ) {
862
  return false;
@@ -1763,6 +1774,7 @@ function ewww_image_optimizer_bulk_loop( $hook = '', $delay = 0 ) {
1763
  global $ewww_force_smart;
1764
  global $ewww_webp_only;
1765
  global $ewww_defer;
 
1766
  $ewww_defer = false;
1767
  $output = array();
1768
  $time_adjustment = 0;
@@ -1927,6 +1939,9 @@ function ewww_image_optimizer_bulk_loop( $hook = '', $delay = 0 ) {
1927
  WP_CLI::line( str_replace( '&nbsp;', '', $msg ) );
1928
  }
1929
  $output['results'] .= sprintf( '<p>' . esc_html__( 'Optimized', 'ewww-image-optimizer' ) . ' <strong>%s</strong><br>', esc_html( $image->file ) );
 
 
 
1930
  $output['results'] .= "$msg</p>";
1931
 
1932
  // Do metadata update after full-size is processed, usually because of conversion or resizing.
100
  echo "<div id='ewww-clean-converted-progressbar' style='display:none;'></div>";
101
  echo "<div id='ewww-clean-converted-progress' style='display:none;'></div>";
102
 
103
+ echo '<hr class="ewww-tool-divider">';
104
+ echo "<div>\n<p id='ewww-clean-webp-info' class='ewww-tool-info'>" .
105
+ esc_html__( 'You may remove all the WebP images from your site if you no longer need them. For example, sites that use Easy IO do not need local WebP images.', 'ewww-image-optimizer' ) . "</p>\n";
106
+ echo "<form id='ewww-clean-webp' class='ewww-tool-form' method='post' action=''>\n" .
107
+ "<input type='submit' class='button-secondary action' value='" . esc_attr__( 'Remove WebP Images', 'ewww-image-optimizer' ) . "' />\n" .
108
+ "</form>\n</div>\n";
109
+ echo "<div id='ewww-clean-webp-progressbar' style='display:none;'></div>";
110
+ echo "<div id='ewww-clean-webp-progress' style='display:none;'></div>";
111
+
112
  $as3cf_remove = false;
113
  if ( class_exists( 'Amazon_S3_And_CloudFront' ) ) {
114
  global $as3cf;
211
  'original_restored' => esc_html__( 'Original Restored', 'ewww-image-optimizer' ),
212
  'restoring' => '<p>' . esc_html__( 'Restoring', 'ewww-image-optimizer' ) . "&nbsp;<img src='$loading_image' /></p>",
213
  'finished' => '<p><b>' . esc_html__( 'Finished', 'ewww-image-optimizer' ) . '</b></p>',
214
+ 'stage1' => esc_html__( 'Stage 1:', 'ewww-image-optimizer' ),
215
+ 'stage2' => esc_html__( 'Stage 2:', 'ewww-image-optimizer' ),
216
  /* translators: used for Table Cleanup progress bar, like so: batch 32/346 */
217
  'batch' => esc_html__( 'batch', 'ewww-image-optimizer' ),
218
  'erase_warning' => $erase_warning,
867
  ewwwio_debug_message( '<b>' . __FUNCTION__ . '()</b>' );
868
  if (
869
  ! ewwwio_is_file( $file ) ||
870
+ ( $media && ! ewww_image_optimizer_get_option( 'ewww_image_optimizer_resize_existing' ) ) ||
871
  function_exists( 'imsanity_get_max_width_height' )
872
  ) {
873
  return false;
1774
  global $ewww_force_smart;
1775
  global $ewww_webp_only;
1776
  global $ewww_defer;
1777
+ global $ewwwio_resize_status;
1778
  $ewww_defer = false;
1779
  $output = array();
1780
  $time_adjustment = 0;
1939
  WP_CLI::line( str_replace( '&nbsp;', '', $msg ) );
1940
  }
1941
  $output['results'] .= sprintf( '<p>' . esc_html__( 'Optimized', 'ewww-image-optimizer' ) . ' <strong>%s</strong><br>', esc_html( $image->file ) );
1942
+ if ( ! empty( $ewwwio_resize_status ) ) {
1943
+ $output['results'] .= esc_html( $ewwwio_resize_status ) . '<br>';
1944
+ }
1945
  $output['results'] .= "$msg</p>";
1946
 
1947
  // Do metadata update after full-size is processed, usually because of conversion or resizing.
changelog.txt CHANGED
@@ -1,3 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  = 5.6.2 =
2
  * fixed: fatal error for undefined add_query_var
3
 
1
+ = 5.7.1 =
2
+ * added: alert on domain change for Easy IO, like if you clone from a production environment to staging
3
+ * changed: Easy IO domain and plan_id refresh automatically when visiting settings page
4
+ * changed: better JS WebP and WPBakery Page Builder compatibility
5
+ * changed: restore savings gauge for network settings page
6
+ * fixed: resize detection visible for editors, should be admin-only
7
+ * fixed: (force) re-optimize not working with parallel mode
8
+ * fixed: upload error when WP cannot load image editor
9
+
10
+ = 5.7.0 =
11
+ * added: cleanup tool if you no longer need local WebP copies of images
12
+ * added: resizing results displayed in bulk & single optimization report
13
+ * changed: The browser-native portion of the Lazy Load feature obeys the wp_lazy_loading_enabled filter
14
+ * fixed: plugin tables do not have PRIMARY indexes
15
+ * fixed: Third-party plugins sometimes set erroneous WebP quality values
16
+ * fixed: Show Re-optimized Images lists images in reverse order
17
+ * fixed: cannot skip to last page of re-optimized images
18
+ * fixed: Scheduled Optimizer skips files that need scaling/resizing if they have already been compressed
19
+ * fixed: Lazy Load placeholders not rewritten for CDN usage by Autoptimize and WP Offload Media Assets Add-on
20
+
21
  = 5.6.2 =
22
  * fixed: fatal error for undefined add_query_var
23
 
classes/class-eio-alt-webp.php CHANGED
@@ -124,6 +124,9 @@ class EIO_Alt_Webp extends EIO_Page_Parser {
124
  }
125
  }
126
 
 
 
 
127
  foreach ( $this->webp_paths as $webp_path ) {
128
  $webp_domain = $this->parse_url( $webp_path, PHP_URL_HOST );
129
  if ( $webp_domain ) {
@@ -202,11 +205,16 @@ class EIO_Alt_Webp extends EIO_Page_Parser {
202
  'usemap',
203
  'vspace',
204
  'width',
 
205
  'data-attachment-id',
 
206
  'data-caption',
207
  'data-comments-opened',
 
208
  'data-event-trigger',
 
209
  'data-height',
 
210
  'data-highlight-color',
211
  'data-highlight-border-color',
212
  'data-highlight-border-opacity',
@@ -215,18 +223,32 @@ class EIO_Alt_Webp extends EIO_Page_Parser {
215
  'data-image-meta',
216
  'data-image-title',
217
  'data-image-description',
 
218
  'data-large_image_width',
219
  'data-large_image_height',
220
  'data-lazy',
221
  'data-lazy-type',
 
 
222
  'data-no-lazy',
223
  'data-orig-size',
 
 
224
  'data-permalink',
225
  'data-pin-description',
226
  'data-pin-id',
227
  'data-pin-media',
228
  'data-pin-url',
 
 
 
 
 
 
 
 
229
  'data-width',
 
230
  );
231
  foreach ( $attributes as $attribute ) {
232
  $attr_value = $this->get_attribute( $image, $attribute );
124
  }
125
  }
126
 
127
+ if ( function_exists( 'swis' ) && swis()->settings->get_option( 'cdn_domain' ) ) {
128
+ $this->webp_paths[] = swis()->settings->get_option( 'cdn_domain' );
129
+ }
130
  foreach ( $this->webp_paths as $webp_path ) {
131
  $webp_domain = $this->parse_url( $webp_path, PHP_URL_HOST );
132
  if ( $webp_domain ) {
205
  'usemap',
206
  'vspace',
207
  'width',
208
+ 'data-animation',
209
  'data-attachment-id',
210
+ 'data-auto-height',
211
  'data-caption',
212
  'data-comments-opened',
213
+ 'data-delay',
214
  'data-event-trigger',
215
+ 'data-flex_fx',
216
  'data-height',
217
+ 'data-hide-on-end',
218
  'data-highlight-color',
219
  'data-highlight-border-color',
220
  'data-highlight-border-opacity',
223
  'data-image-meta',
224
  'data-image-title',
225
  'data-image-description',
226
+ 'data-interval',
227
  'data-large_image_width',
228
  'data-large_image_height',
229
  'data-lazy',
230
  'data-lazy-type',
231
+ 'data-mode',
232
+ 'data-name',
233
  'data-no-lazy',
234
  'data-orig-size',
235
+ 'data-partial',
236
+ 'data-per-view',
237
  'data-permalink',
238
  'data-pin-description',
239
  'data-pin-id',
240
  'data-pin-media',
241
  'data-pin-url',
242
+ 'data-rel',
243
+ 'data-ride',
244
+ 'data-shadow',
245
+ 'data-shadow-direction',
246
+ 'data-slide',
247
+ 'data-slide-to',
248
+ 'data-target',
249
+ 'data-vc-zoom',
250
  'data-width',
251
+ 'data-wrap',
252
  );
253
  foreach ( $attributes as $attribute ) {
254
  $attr_value = $this->get_attribute( $image, $attribute );
classes/class-eio-base.php CHANGED
@@ -319,6 +319,40 @@ if ( ! class_exists( 'EIO_Base' ) ) {
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
  *
319
  }
320
  return false;
321
  }
322
+
323
+ /**
324
+ * Make sure this is really and truly a "front-end request", excluding page builders and such.
325
+ *
326
+ * @return bool True for front-end requests, false for admin/builder requests.
327
+ */
328
+ function is_frontend() {
329
+ if ( is_admin() ) {
330
+ return false;
331
+ }
332
+ $uri = add_query_arg( null, null );
333
+ if (
334
+ strpos( $uri, 'cornerstone=' ) !== false ||
335
+ strpos( $uri, 'cornerstone-endpoint' ) !== false ||
336
+ strpos( $uri, 'ct_builder=' ) !== false ||
337
+ did_action( 'cornerstone_boot_app' ) || did_action( 'cs_before_preview_frame' ) ||
338
+ '/print/' === substr( $uri, -7 ) ||
339
+ strpos( $uri, 'elementor-preview=' ) !== false ||
340
+ strpos( $uri, 'et_fb=' ) !== false ||
341
+ strpos( $uri, 'vc_editable=' ) !== false ||
342
+ strpos( $uri, 'tatsu=' ) !== false ||
343
+ ( ! empty( $_POST['action'] ) && 'tatsu_get_concepts' === sanitize_text_field( wp_unslash( $_POST['action'] ) ) ) || // phpcs:ignore WordPress.Security.NonceVerification
344
+ strpos( $uri, 'wp-login.php' ) !== false ||
345
+ is_embed() ||
346
+ is_feed() ||
347
+ is_preview() ||
348
+ is_customize_preview() ||
349
+ ( defined( 'REST_REQUEST' ) && REST_REQUEST )
350
+ ) {
351
+ return false;
352
+ }
353
+ return true;
354
+ }
355
+
356
  /**
357
  * Check if file exists, and that it is local rather than using a protocol like http:// or phar://
358
  *
classes/class-eio-lazy-load.php CHANGED
@@ -79,7 +79,12 @@ if ( ! class_exists( 'EIO_Lazy_Load' ) ) {
79
 
80
  add_action( 'wp_head', array( $this, 'no_js_css' ) );
81
 
82
- add_filter( $this->prefix . 'filter_page_output', array( $this, 'filter_page_output' ), 15 );
 
 
 
 
 
83
  add_filter( 'vc_get_vc_grid_data_response', array( $this, 'filter_page_output' ) );
84
 
85
  if ( class_exists( 'ExactDN' ) && $this->get_option( $this->prefix . 'exactdn' ) ) {
@@ -103,6 +108,11 @@ if ( ! class_exists( 'EIO_Lazy_Load' ) ) {
103
  $this->allow_piip = is_writable( $this->piip_folder ) && $this->gd_support();
104
  }
105
 
 
 
 
 
 
106
  // Filter early, so that others at the default priority take precendence.
107
  add_filter( 'eio_use_piip', array( $this, 'maybe_piip' ), 9 );
108
  add_filter( 'eio_use_siip', array( $this, 'maybe_siip' ), 9 );
@@ -225,7 +235,7 @@ if ( ! class_exists( 'EIO_Lazy_Load' ) ) {
225
  $this->debug_message( 'AMP page processing' );
226
  }
227
  if ( $this->is_amp() ) {
228
- ewwwio_debug_message( 'AMP page processing (is_amp)' );
229
  }
230
  return $buffer;
231
  }
@@ -444,6 +454,7 @@ if ( ! class_exists( 'EIO_Lazy_Load' ) ) {
444
  $this->set_attribute( $image, 'srcset', $placeholder_src, true );
445
  $this->remove_attribute( $image, 'src' );
446
  } else {
 
447
  $this->set_attribute( $image, 'src', $placeholder_src, true );
448
  $this->remove_attribute( $image, 'srcset' );
449
  }
@@ -604,6 +615,7 @@ if ( ! class_exists( 'EIO_Lazy_Load' ) ) {
604
  'lazy-slider-img=',
605
  'mgl-lazy',
606
  'owl-lazy',
 
607
  'skip-lazy',
608
  'timthumb.php?',
609
  'wpcf7_captcha/',
@@ -824,7 +836,4 @@ if ( ! class_exists( 'EIO_Lazy_Load' ) ) {
824
  );
825
  }
826
  }
827
-
828
- global $eio_lazy_load;
829
- $eio_lazy_load = new EIO_Lazy_Load();
830
  }
79
 
80
  add_action( 'wp_head', array( $this, 'no_js_css' ) );
81
 
82
+ if ( method_exists( 'autoptimizeImages', 'imgopt_active' ) && autoptimizeImages::imgopt_active() ) {
83
+ add_filter( 'autoptimize_filter_html_before_minify', array( $this, 'filter_page_output' ) );
84
+ } else {
85
+ add_filter( $this->prefix . 'filter_page_output', array( $this, 'filter_page_output' ), 15 );
86
+ }
87
+
88
  add_filter( 'vc_get_vc_grid_data_response', array( $this, 'filter_page_output' ) );
89
 
90
  if ( class_exists( 'ExactDN' ) && $this->get_option( $this->prefix . 'exactdn' ) ) {
108
  $this->allow_piip = is_writable( $this->piip_folder ) && $this->gd_support();
109
  }
110
 
111
+ if ( ! apply_filters( 'wp_lazy_loading_enabled', true ) ) {
112
+ define( 'EWWWIO_DISABLE_NATIVE_LAZY', true );
113
+ }
114
+ add_filter( 'wp_lazy_loading_enabled', '__return_false' );
115
+
116
  // Filter early, so that others at the default priority take precendence.
117
  add_filter( 'eio_use_piip', array( $this, 'maybe_piip' ), 9 );
118
  add_filter( 'eio_use_siip', array( $this, 'maybe_siip' ), 9 );
235
  $this->debug_message( 'AMP page processing' );
236
  }
237
  if ( $this->is_amp() ) {
238
+ $this->debug_message( 'AMP page processing (is_amp)' );
239
  }
240
  return $buffer;
241
  }
454
  $this->set_attribute( $image, 'srcset', $placeholder_src, true );
455
  $this->remove_attribute( $image, 'src' );
456
  } else {
457
+ $placeholder_src = apply_filters( 'as3cf_get_asset', $placeholder_src );
458
  $this->set_attribute( $image, 'src', $placeholder_src, true );
459
  $this->remove_attribute( $image, 'srcset' );
460
  }
615
  'lazy-slider-img=',
616
  'mgl-lazy',
617
  'owl-lazy',
618
+ 'preload-me',
619
  'skip-lazy',
620
  'timthumb.php?',
621
  'wpcf7_captcha/',
836
  );
837
  }
838
  }
 
 
 
839
  }
classes/class-eio-picture-webp.php CHANGED
@@ -61,8 +61,12 @@ class EIO_Picture_Webp extends EIO_Page_Parser {
61
 
62
  // Make sure gallery block images crop properly.
63
  add_action( 'wp_head', array( $this, 'gallery_block_css' ) );
64
- // Start an output buffer before any output starts.
65
- add_filter( 'ewww_image_optimizer_filter_page_output', array( $this, 'filter_page_output' ), 10 );
 
 
 
 
66
 
67
  $this->home_url = trailingslashit( get_site_url() );
68
  ewwwio_debug_message( "home url: $this->home_url" );
@@ -108,6 +112,9 @@ class EIO_Picture_Webp extends EIO_Page_Parser {
108
  }
109
  }
110
 
 
 
 
111
  foreach ( $this->webp_paths as $webp_path ) {
112
  $webp_domain = $this->parse_url( $webp_path, PHP_URL_HOST );
113
  if ( $webp_domain ) {
61
 
62
  // Make sure gallery block images crop properly.
63
  add_action( 'wp_head', array( $this, 'gallery_block_css' ) );
64
+ // Hook onto the output buffer function.
65
+ if ( function_exists( 'swis' ) && swis()->settings->get_option( 'lazy_load' ) ) {
66
+ add_filter( 'swis_filter_page_output', array( $this, 'filter_page_output' ) );
67
+ } else {
68
+ add_filter( 'ewww_image_optimizer_filter_page_output', array( $this, 'filter_page_output' ), 10 );
69
+ }
70
 
71
  $this->home_url = trailingslashit( get_site_url() );
72
  ewwwio_debug_message( "home url: $this->home_url" );
112
  }
113
  }
114
 
115
+ if ( function_exists( 'swis' ) && swis()->settings->get_option( 'cdn_domain' ) ) {
116
+ $this->webp_paths[] = swis()->settings->get_option( 'cdn_domain' );
117
+ }
118
  foreach ( $this->webp_paths as $webp_path ) {
119
  $webp_domain = $this->parse_url( $webp_path, PHP_URL_HOST );
120
  if ( $webp_domain ) {
classes/class-ewwwio-media-background-process.php CHANGED
@@ -517,6 +517,7 @@ class EWWWIO_Async_Request extends WP_Async_Request {
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 {
@@ -530,7 +531,8 @@ class EWWWIO_Async_Request extends WP_Async_Request {
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 ) {
517
  session_write_close();
518
  ewwwio_debug_message( '<b>' . __METHOD__ . '()</b>' );
519
  check_ajax_referer( $this->identifier, 'nonce' );
520
+ global $ewww_force;
521
  if ( empty( $_POST['ewwwio_size'] ) ) {
522
  $size = '';
523
  } else {
531
  if ( empty( $_POST['ewwwio_id'] ) ) {
532
  return;
533
  }
534
+ $ewww_force = ! empty( $_REQUEST['ewww_force'] ) ? true : false;
535
+ $ewwwio_id = (int) $_POST['ewwwio_id'];
536
  global $ewww_image;
537
  $file_path = ewww_image_optimizer_find_file_by_id( $ewwwio_id );
538
  if ( $file_path && 'full' === $size ) {
classes/class-exactdn.php CHANGED
@@ -112,7 +112,8 @@ if ( ! class_exists( 'ExactDN' ) ) {
112
  $this->debug_message( '<b>' . __METHOD__ . '()</b>' );
113
  global $exactdn;
114
  if ( is_object( $exactdn ) ) {
115
- return 'you are doing it wrong';
 
116
  }
117
 
118
  // Bail out on customizer.
@@ -220,6 +221,12 @@ if ( ! class_exists( 'ExactDN' ) ) {
220
  return;
221
  }
222
  $this->upload_domain = $upload_url_parts['host'];
 
 
 
 
 
 
223
  $this->debug_message( "allowing images from here: $this->upload_domain" );
224
  if (
225
  ( false !== strpos( $this->upload_domain, 'amazonaws.com' ) || false !== strpos( $this->upload_domain, 'storage.googleapis.com' ) ) &&
@@ -461,7 +468,7 @@ if ( ! class_exists( 'ExactDN' ) ) {
461
  $exactdn_activate_error = $error_message;
462
  add_action( 'admin_notices', $this->prefix . 'notice_exactdn_activation_error' );
463
  return false;
464
- } elseif ( ! empty( $result['body'] ) && strpos( $result['body'], 'error' ) === false ) {
465
  $response = json_decode( $result['body'], true );
466
  if ( ! empty( $response['success'] ) ) {
467
  if ( 2 === (int) $response['success'] ) {
@@ -486,6 +493,10 @@ if ( ! class_exists( 'ExactDN' ) ) {
486
  $error_message = $response['error'];
487
  $this->debug_message( "exactdn verification request failed: $error_message" );
488
  $exactdn_activate_error = $error_message;
 
 
 
 
489
  add_action( 'admin_notices', $this->prefix . 'notice_exactdn_activation_error' );
490
  return false;
491
  }
@@ -2941,7 +2952,7 @@ if ( ! class_exists( 'ExactDN' ) ) {
2941
  }
2942
 
2943
  /**
2944
- * Adds link to header which enables DNS prefetching for faster speed.
2945
  *
2946
  * @param array $hints A list of hints for a particular relationship type.
2947
  * @param string $relationship_type The type of hint being filtered: dns-prefetch, preconnect, etc.
@@ -2951,6 +2962,9 @@ if ( ! class_exists( 'ExactDN' ) ) {
2951
  if ( 'dns-prefetch' === $relationship_type && $this->exactdn_domain ) {
2952
  $hints[] = '//' . $this->exactdn_domain;
2953
  }
 
 
 
2954
  return $hints;
2955
  }
2956
 
112
  $this->debug_message( '<b>' . __METHOD__ . '()</b>' );
113
  global $exactdn;
114
  if ( is_object( $exactdn ) ) {
115
+ $this->debug_message( 'you are doing it wrong' );
116
+ return;
117
  }
118
 
119
  // Bail out on customizer.
221
  return;
222
  }
223
  $this->upload_domain = $upload_url_parts['host'];
224
+ if ( ! $this->get_option( $this->prefix . 'exactdn_local_domain' ) ) {
225
+ $this->set_option( $this->prefix . 'exactdn_local_domain', $this->upload_domain );
226
+ }
227
+ if ( $this->get_option( $this->prefix . 'exactdn_local_domain' ) !== $this->upload_domain && is_admin() ) {
228
+ add_action( 'admin_notices', $this->prefix . 'notice_exactdn_domain_mismatch' );
229
+ }
230
  $this->debug_message( "allowing images from here: $this->upload_domain" );
231
  if (
232
  ( false !== strpos( $this->upload_domain, 'amazonaws.com' ) || false !== strpos( $this->upload_domain, 'storage.googleapis.com' ) ) &&
468
  $exactdn_activate_error = $error_message;
469
  add_action( 'admin_notices', $this->prefix . 'notice_exactdn_activation_error' );
470
  return false;
471
+ } elseif ( ! empty( $result['body'] ) && false === strpos( $result['body'], 'error' ) ) {
472
  $response = json_decode( $result['body'], true );
473
  if ( ! empty( $response['success'] ) ) {
474
  if ( 2 === (int) $response['success'] ) {
493
  $error_message = $response['error'];
494
  $this->debug_message( "exactdn verification request failed: $error_message" );
495
  $exactdn_activate_error = $error_message;
496
+ if ( false !== strpos( $error_message, 'not found' ) ) {
497
+ delete_option( $this->prefix . 'exactdn_domain' );
498
+ delete_site_option( $this->prefix . 'exactdn_domain' );
499
+ }
500
  add_action( 'admin_notices', $this->prefix . 'notice_exactdn_activation_error' );
501
  return false;
502
  }
2952
  }
2953
 
2954
  /**
2955
+ * Adds link to header which enables DNS prefetching and preconnect for faster speed.
2956
  *
2957
  * @param array $hints A list of hints for a particular relationship type.
2958
  * @param string $relationship_type The type of hint being filtered: dns-prefetch, preconnect, etc.
2962
  if ( 'dns-prefetch' === $relationship_type && $this->exactdn_domain ) {
2963
  $hints[] = '//' . $this->exactdn_domain;
2964
  }
2965
+ if ( 'preconnect' === $relationship_type && $this->exactdn_domain ) {
2966
+ $hints[] = '//' . $this->exactdn_domain;
2967
+ }
2968
  return $hints;
2969
  }
2970
 
common.php CHANGED
@@ -14,7 +14,7 @@ if ( ! defined( 'ABSPATH' ) ) {
14
  exit;
15
  }
16
 
17
- define( 'EWWW_IMAGE_OPTIMIZER_VERSION', '562.0' );
18
 
19
  // Initialize a couple globals.
20
  $eio_debug = '';
@@ -244,6 +244,9 @@ function ewww_image_optimizer_parser_init() {
244
  * Lazy Load class for parsing image urls and rewriting them to defer off-screen images.
245
  */
246
  require_once( EWWW_IMAGE_OPTIMIZER_PLUGIN_PATH . 'classes/class-eio-lazy-load.php' );
 
 
 
247
  }
248
  // If Alt WebP Rewriting is enabled.
249
  if ( ewww_image_optimizer_get_option( 'ewww_image_optimizer_webp_for_cdn' ) && ! ewww_image_optimizer_get_option( 'ewww_image_optimizer_exactdn' ) ) {
@@ -693,8 +696,7 @@ function ewww_image_optimizer_enable_background_optimization() {
693
  * Re-tests background optimization at a user's request.
694
  */
695
  function ewww_image_optimizer_retest_background_optimization() {
696
- $permissions = apply_filters( 'ewww_image_optimizer_admin_permissions', 'manage_options' );
697
- if ( false === current_user_can( $permissions ) ) {
698
  wp_die( esc_html__( 'Access denied.', 'ewww-image-optimizer' ) );
699
  }
700
  ewww_image_optimizer_enable_background_optimization();
@@ -1253,6 +1255,15 @@ function ewww_image_optimizer_restapi_compat_check() {
1253
  add_filter( 'ewww_image_optimizer_allowed_reopt', '__return_true' );
1254
  return;
1255
  }
 
 
 
 
 
 
 
 
 
1256
  }
1257
 
1258
  /**
@@ -1398,6 +1409,13 @@ function ewww_image_optimizer_install_table() {
1398
  // See if the path column exists, and what collation it uses to determine the column index size.
1399
  if ( $wpdb->get_var( "SHOW TABLES LIKE '$wpdb->ewwwio_images'" ) === $wpdb->ewwwio_images ) {
1400
  ewwwio_debug_message( 'upgrading table and checking collation for path, table exists' );
 
 
 
 
 
 
 
1401
  // Check if the old path_image_size index exists, and drop it.
1402
  if ( $wpdb->get_results( "SHOW INDEX FROM $wpdb->ewwwio_images WHERE Key_name = 'path_image_size'", ARRAY_A ) ) {
1403
  ewwwio_debug_message( 'getting rid of path_image_size index' );
@@ -1470,7 +1488,7 @@ function ewww_image_optimizer_install_table() {
1470
  * trace: tracelog from the last optimization if debugging was enabled.
1471
  */
1472
  $sql = "CREATE TABLE $wpdb->ewwwio_images (
1473
- id int(14) unsigned NOT NULL AUTO_INCREMENT,
1474
  attachment_id bigint(20) unsigned,
1475
  gallery varchar(10),
1476
  resize varchar(75),
@@ -1485,7 +1503,6 @@ function ewww_image_optimizer_install_table() {
1485
  updates int(5) unsigned,
1486
  updated timestamp DEFAULT '1971-01-01 00:00:00' ON UPDATE CURRENT_TIMESTAMP,
1487
  trace blob,
1488
- UNIQUE KEY id (id),
1489
  KEY path (path($path_index_size)),
1490
  KEY attachment_info (gallery(3),attachment_id)
1491
  ) $db_collation;";
@@ -1502,6 +1519,7 @@ function ewww_image_optimizer_install_table() {
1502
  * scanned: 1 if the image is queued for optimization, 0 if it still needs scanning.
1503
  */
1504
  $sql = "CREATE TABLE $wpdb->ewwwio_queue (
 
1505
  attachment_id bigint(20) unsigned,
1506
  gallery varchar(20),
1507
  scanned tinyint(3) NOT NULL DEFAULT 0,
@@ -1768,10 +1786,35 @@ function ewww_image_optimizer_notice_exactdn_activation_success() {
1768
  }
1769
 
1770
  /**
1771
- * Display a notice that PHP version 5.5 support is going away.
1772
  */
1773
- function ewww_image_optimizer_php55_warning() {
1774
- echo '<div id="ewww-image-optimizer-notice-php55" class="notice notice-info"><p><a href="https://docs.ewww.io/article/55-upgrading-php" target="_blank" data-beacon-article="5ab2baa6042863478ea7c2ae">' . esc_html__( 'The next major release of EWWW Image Optimizer will require PHP 5.6 or greater. Newer versions of PHP, like 7.1 and 7.2, are significantly faster and much more secure. If you are unsure how to upgrade to a supported version, ask your webhost for instructions.', 'ewww-image-optimizer' ) . '</a></p></div>';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1775
  }
1776
 
1777
  /**
@@ -1781,6 +1824,13 @@ function ewww_image_optimizer_notice_exactdn_sp_conflict() {
1781
  echo "<div id='ewww-image-optimizer-exactdn-sp' class='notice notice-warning'><p>" . esc_html__( 'ShortPixel image optimization has been disabled to prevent conflicts with Easy IO (EWWW Image Optimizer).', 'ewww-image-optimizer' ) . '</p></div>';
1782
  }
1783
 
 
 
 
 
 
 
 
1784
  /**
1785
  * Lets the user know their network settings have been saved.
1786
  */
@@ -3577,12 +3627,17 @@ function ewww_image_optimizer_delete( $id ) {
3577
  ewwwio_debug_message( 'removing: ' . $image['path'] . '.webp' );
3578
  ewwwio_delete_file( $image['path'] . '.webp' );
3579
  }
 
 
 
 
 
3580
  }
3581
  if ( ! empty( $image['converted'] ) ) {
3582
  $image['converted'] = ewww_image_optimizer_absolutize_path( $image['converted'] );
3583
  }
3584
  if ( ! empty( $image['converted'] ) && ewwwio_is_file( $image['converted'] ) ) {
3585
- ewwwio_debug_message( 'removing: ' . $image['converted'] . '.webp' );
3586
  ewwwio_delete_file( $image['converted'] );
3587
  if ( ewwwio_is_file( $image['converted'] . '.webp' ) ) {
3588
  ewwwio_debug_message( 'removing: ' . $image['converted'] . '.webp' );
@@ -3691,7 +3746,15 @@ function ewww_image_optimizer_delete( $id ) {
3691
  }
3692
  }
3693
  }
3694
- ewwwio_memory( __FUNCTION__ );
 
 
 
 
 
 
 
 
3695
  }
3696
 
3697
  /**
@@ -3951,7 +4014,7 @@ function ewww_image_optimizer_cloud_verify( $cache = true, $api_key = '' ) {
3951
  return false;
3952
  }
3953
  if ( ewww_image_optimizer_get_option( 'ewww_image_optimizer_cloud_exceeded' ) > time() ) {
3954
- set_transient( 'ewww_image_optimizer_cloud_status', 'exceeded', 3600 );
3955
  ewwwio_debug_message( 'license exceeded notice has not expired' );
3956
  return 'exceeded';
3957
  }
@@ -4008,7 +4071,7 @@ function ewww_image_optimizer_cloud_verify( $cache = true, $api_key = '' ) {
4008
  ewwwio_memory( __FUNCTION__ );
4009
  return false;
4010
  } else {
4011
- set_transient( 'ewww_image_optimizer_cloud_status', $verified, 3600 );
4012
  if ( ewww_image_optimizer_get_option( 'ewww_image_optimizer_jpg_level' ) < 20 && ewww_image_optimizer_get_option( 'ewww_image_optimizer_png_level' ) < 20 && ewww_image_optimizer_get_option( 'ewww_image_optimizer_gif_level' ) < 20 && ! ewww_image_optimizer_get_option( 'ewww_image_optimizer_pdf_level' ) ) {
4013
  ewww_image_optimizer_cloud_enable();
4014
  }
@@ -4226,6 +4289,9 @@ function ewww_image_optimizer_cloud_optimizer( $file, $type, $convert = false, $
4226
  } else {
4227
  $webp = 0;
4228
  }
 
 
 
4229
  if ( 30 === (int) ewww_image_optimizer_get_option( 'ewww_image_optimizer_png_level' ) ) {
4230
  $png_compress = 1;
4231
  } else {
@@ -4347,7 +4413,7 @@ function ewww_image_optimizer_cloud_optimizer( $file, $type, $convert = false, $
4347
  ewww_image_optimizer_remove_cloud_key( 'none' );
4348
  } elseif ( 100 > strlen( $response['body'] ) && strpos( $response['body'], 'exceeded' ) ) {
4349
  ewwwio_debug_message( 'License Exceeded' );
4350
- set_transient( 'ewww_image_optimizer_cloud_status', 'exceeded', 3600 );
4351
  $msg = 'exceeded';
4352
  ewwwio_delete_file( $tempfile );
4353
  } elseif ( ewww_image_optimizer_mimetype( $tempfile, 'i' ) === $type ) {
@@ -4479,7 +4545,7 @@ function ewww_image_optimizer_cloud_autorotate( $file, $type ) {
4479
  $newsize = $orig_size;
4480
  if ( preg_match( '/exceeded/', $response['body'] ) ) {
4481
  ewwwio_debug_message( 'License Exceeded' );
4482
- set_transient( 'ewww_image_optimizer_cloud_status', 'exceeded', 3600 );
4483
  ewwwio_delete_file( $tempfile );
4484
  } elseif ( ewww_image_optimizer_mimetype( $tempfile, 'i' ) === $type ) {
4485
  $newsize = filesize( $tempfile );
@@ -5002,6 +5068,41 @@ function ewww_image_optimizer_check_table( $file, $orig_size ) {
5002
  return '';
5003
  }
5004
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5005
  /**
5006
  * Inserts or updates an image record in the database.
5007
  *
@@ -5024,6 +5125,7 @@ function ewww_image_optimizer_update_table( $attachment, $opt_size, $orig_size,
5024
  } else {
5025
  $ewwwdb = $wpdb;
5026
  }
 
5027
  global $ewww_image;
5028
  // First check if the image was converted, so we don't orphan records.
5029
  if ( $original && $original !== $attachment ) {
@@ -6086,6 +6188,9 @@ function ewww_image_optimizer_noresize( $dimensions, $filename ) {
6086
  /**
6087
  * Check non-Media Library filenames to see if the image is eligible for resizing.
6088
  *
 
 
 
6089
  * @param string $file The image filename.
6090
  * @return bool True to allow resizing, false otherwise.
6091
  */
@@ -6133,6 +6238,8 @@ function ewww_image_optimizer_resize_upload( $file ) {
6133
  // Parts adapted from Imsanity (THANKS Jason!).
6134
  ewwwio_debug_message( '<b>' . __FUNCTION__ . '()</b>' );
6135
  global $ewww_webp_only;
 
 
6136
  if ( ! $file ) {
6137
  return false;
6138
  }
@@ -6203,6 +6310,8 @@ function ewww_image_optimizer_resize_upload( $file ) {
6203
  list( $oldwidth, $oldheight ) = getimagesize( $file );
6204
  if ( $oldwidth <= $maxwidth && $oldheight <= $maxheight ) {
6205
  ewwwio_debug_message( 'image too small for resizing' );
 
 
6206
  if ( $oldwidth && $oldheight ) {
6207
  return array( $oldwidth, $oldheight );
6208
  }
@@ -6227,6 +6336,7 @@ function ewww_image_optimizer_resize_upload( $file ) {
6227
  }
6228
  if ( ! function_exists( 'wp_get_image_editor' ) ) {
6229
  ewwwio_debug_message( 'no image editor function' );
 
6230
  return false;
6231
  }
6232
 
@@ -6236,7 +6346,10 @@ function ewww_image_optimizer_resize_upload( $file ) {
6236
 
6237
  $editor = wp_get_image_editor( $file );
6238
  if ( is_wp_error( $editor ) ) {
6239
- ewwwio_debug_message( 'could not get image editor' );
 
 
 
6240
  return false;
6241
  }
6242
  // Rotation only happens on existing media here, so we need to swap dimension when we rotate by 90.
@@ -6266,6 +6379,8 @@ function ewww_image_optimizer_resize_upload( $file ) {
6266
  if ( is_wp_error( $resized_image ) ) {
6267
  $error_message = $resized_image->get_error_message();
6268
  ewwwio_debug_message( "error during resizing: $error_message" );
 
 
6269
  return false;
6270
  }
6271
  $new_file = $editor->generate_filename( 'tmp' );
@@ -6275,6 +6390,8 @@ function ewww_image_optimizer_resize_upload( $file ) {
6275
  if ( is_wp_error( $saved ) ) {
6276
  $error_message = $saved->get_error_message();
6277
  ewwwio_debug_message( "error saving resized image: $error_message" );
 
 
6278
  }
6279
  if ( ! ewww_image_optimizer_get_option( 'ewww_image_optimizer_noauto' ) && ( ! defined( 'EWWW_IMAGE_OPTIMIZER_DISABLE_EDITOR' ) || ! EWWW_IMAGE_OPTIMIZER_DISABLE_EDITOR ) ) {
6280
  $ewww_preempt_editor = false;
@@ -6322,6 +6439,8 @@ function ewww_image_optimizer_resize_upload( $file ) {
6322
  ewwwio_rename( $new_file, $file );
6323
  } else {
6324
  ewwwio_debug_message( "resizing did not create a valid image: $new_type" );
 
 
6325
  unlink( $new_file );
6326
  return false;
6327
  }
@@ -6371,10 +6490,13 @@ function ewww_image_optimizer_resize_upload( $file ) {
6371
  );
6372
  }
6373
  }
 
 
6374
  return array( $newwidth, $newheight );
6375
  } // End if().
6376
  if ( ewwwio_is_file( $new_file ) ) {
6377
  ewwwio_debug_message( "resizing did not create a smaller image: $new_size" );
 
6378
  unlink( $new_file );
6379
  }
6380
  return false;
@@ -8389,6 +8511,7 @@ function ewww_image_optimizer_custom_column_results( $id, $optimized_images ) {
8389
  return array( '', false, false );
8390
  }
8391
  ewwwio_debug_message( '<b>' . __FUNCTION__ . '()</b>' );
 
8392
  $orig_size = 0;
8393
  $opt_size = 0;
8394
  $converted = false;
@@ -8421,6 +8544,9 @@ function ewww_image_optimizer_custom_column_results( $id, $optimized_images ) {
8421
  }
8422
  $detail_output .= '</table>';
8423
 
 
 
 
8424
  $output .= '<div>' . sprintf(
8425
  esc_html(
8426
  /* translators: %d: number of resizes/thumbnails compressed */
@@ -8707,7 +8833,7 @@ function ewww_image_optimizer_dismiss_wc_regen() {
8707
  ewwwio_ob_clean();
8708
  ewwwio_debug_message( '<b>' . __FUNCTION__ . '()</b>' );
8709
  // Verify that the user is properly authorized.
8710
- if ( ! current_user_can( apply_filters( 'ewww_image_optimizer_admin_permissions', 'manage_options' ) ) ) {
8711
  wp_die( esc_html__( 'Access denied.', 'ewww-image-optimizer' ) );
8712
  }
8713
  delete_option( 'ewww_image_optimizer_wc_regen' );
@@ -8721,7 +8847,7 @@ function ewww_image_optimizer_dismiss_lr_sync() {
8721
  ewwwio_ob_clean();
8722
  ewwwio_debug_message( '<b>' . __FUNCTION__ . '()</b>' );
8723
  // Verify that the user is properly authorized.
8724
- if ( ! current_user_can( apply_filters( 'ewww_image_optimizer_admin_permissions', 'manage_options' ) ) ) {
8725
  wp_die( esc_html__( 'Access denied.', 'ewww-image-optimizer' ) );
8726
  }
8727
  delete_option( 'ewww_image_optimizer_lr_sync' );
@@ -8735,7 +8861,7 @@ function ewww_image_optimizer_dismiss_media_notice() {
8735
  ewwwio_ob_clean();
8736
  ewwwio_debug_message( '<b>' . __FUNCTION__ . '()</b>' );
8737
  // Verify that the user is properly authorized.
8738
- if ( ! current_user_can( apply_filters( 'ewww_image_optimizer_admin_permissions', 'manage_options' ) ) ) {
8739
  wp_die( esc_html__( 'Access denied.', 'ewww-image-optimizer' ) );
8740
  }
8741
  update_option( 'ewww_image_optimizer_dismiss_media_notice', true, false );
@@ -8750,7 +8876,7 @@ function ewww_image_optimizer_dismiss_review_notice() {
8750
  ewwwio_ob_clean();
8751
  ewwwio_debug_message( '<b>' . __FUNCTION__ . '()</b>' );
8752
  // Verify that the user is properly authorized.
8753
- if ( ! current_user_can( apply_filters( 'ewww_image_optimizer_admin_permissions', 'manage_options' ) ) ) {
8754
  wp_die( esc_html__( 'Access denied.', 'ewww-image-optimizer' ) );
8755
  }
8756
  update_option( 'ewww_image_optimizer_dismiss_review_notice', true, false );
@@ -8962,6 +9088,17 @@ function ewww_image_optimizer_settings_script( $hook ) {
8962
  if ( 'settings_page_ewww-image-optimizer-options' !== $hook ) {
8963
  return;
8964
  }
 
 
 
 
 
 
 
 
 
 
 
8965
  add_thickbox();
8966
  wp_enqueue_script( 'jquery-ui-tooltip' );
8967
  wp_enqueue_script( 'ewwwbulkscript', plugins_url( '/includes/eio.js', __FILE__ ), array( 'jquery' ), EWWW_IMAGE_OPTIMIZER_VERSION );
@@ -8975,42 +9112,38 @@ function ewww_image_optimizer_settings_script( $hook ) {
8975
  /**
8976
  * Get a total of how much space we have saved so far.
8977
  *
 
8978
  * @global object $wpdb
8979
  *
8980
  * @return int The total savings found, in bytes.
8981
  */
8982
- function ewww_image_optimizer_savings() {
8983
  ewwwio_debug_message( '<b>' . __FUNCTION__ . '()</b>' );
8984
  global $wpdb;
8985
- if ( ! function_exists( 'is_plugin_active_for_network' ) && is_multisite() ) {
8986
- // Need to include the plugin library for the is_plugin_active function.
8987
- require_once( ABSPATH . 'wp-admin/includes/plugin.php' );
8988
- }
8989
  $total_orig = 0;
8990
  $total_opt = 0;
8991
  $total_savings = 0;
8992
- if ( is_multisite() && is_plugin_active_for_network( EWWW_IMAGE_OPTIMIZER_PLUGIN_FILE_REL ) ) {
 
 
 
 
 
 
8993
  ewwwio_debug_message( 'querying savings for multi-site' );
8994
 
8995
  if ( get_blog_count() > 1000 ) {
8996
  return 0;
8997
  }
8998
  if ( function_exists( 'get_sites' ) ) {
8999
- ewwwio_debug_message( 'retrieving list of sites the easy way (4.6+)' );
9000
  $blogs = get_sites(
9001
  array(
9002
  'fields' => 'ids',
9003
  'number' => 1000,
9004
  )
9005
  );
9006
- } elseif ( function_exists( 'wp_get_sites' ) ) {
9007
- ewwwio_debug_message( 'retrieving list of sites the easy way (pre 4.6)' );
9008
- $blogs = wp_get_sites(
9009
- array(
9010
- 'network_id' => $wpdb->siteid,
9011
- 'limit' => 1000,
9012
- )
9013
- );
9014
  }
9015
  if ( ewww_image_optimizer_iterable( $blogs ) ) {
9016
  foreach ( $blogs as $blog ) {
@@ -9038,7 +9171,13 @@ function ewww_image_optimizer_savings() {
9038
  restore_current_blog();
9039
  }
9040
  }
 
9041
  } else {
 
 
 
 
 
9042
  ewwwio_debug_message( 'querying savings for single site' );
9043
  $table_name = $wpdb->ewwwio_images;
9044
  ewwwio_debug_message( "table name is $table_name" );
@@ -9051,7 +9190,10 @@ function ewww_image_optimizer_savings() {
9051
  $total_opt += $opt_size;
9052
 
9053
  $total_savings = $orig_size - $opt_size;
 
9054
  } // End if().
 
 
9055
  ewwwio_debug_message( "total original size: $total_orig" );
9056
  ewwwio_debug_message( "total current(opt) size: $total_opt" );
9057
  ewwwio_debug_message( "savings found: $total_savings" );
@@ -9122,7 +9264,7 @@ function ewww_image_optimizer_webp_rewrite() {
9122
  if ( empty( $_REQUEST['ewww_wpnonce'] ) || ! wp_verify_nonce( sanitize_key( $_REQUEST['ewww_wpnonce'] ), 'ewww-image-optimizer-settings' ) ) {
9123
  wp_die( esc_html__( 'Access denied.', 'ewww-image-optimizer' ) );
9124
  }
9125
- if ( ! current_user_can( apply_filters( 'ewww_image_optimizer_admin_permissions', 'manage_options' ) ) ) {
9126
  wp_die( esc_html__( 'Access denied.', 'ewww-image-optimizer' ) );
9127
  }
9128
  $ewww_rules = ewww_image_optimizer_webp_rewrite_verify();
@@ -9146,7 +9288,7 @@ function ewww_image_optimizer_webp_unwrite() {
9146
  if ( empty( $_REQUEST['ewww_wpnonce'] ) || ! wp_verify_nonce( sanitize_key( $_REQUEST['ewww_wpnonce'] ), 'ewww-image-optimizer-settings' ) ) {
9147
  wp_die( esc_html__( 'Access denied.', 'ewww-image-optimizer' ) );
9148
  }
9149
- if ( ! current_user_can( apply_filters( 'ewww_image_optimizer_admin_permissions', 'manage_options' ) ) ) {
9150
  wp_die( esc_html__( 'Access denied.', 'ewww-image-optimizer' ) );
9151
  }
9152
  if ( insert_with_markers( ewww_image_optimizer_htaccess_path(), 'EWWWIO', '' ) ) {
@@ -9611,7 +9753,10 @@ function ewww_image_optimizer_options( $network = 'singlesite' ) {
9611
  global $exactdn;
9612
  global $eio_alt_webp;
9613
  $total_savings = 0;
9614
- if ( false === strpos( $network, 'network-multisite' ) ) {
 
 
 
9615
  $total_sizes = ewww_image_optimizer_savings();
9616
  $total_savings = $total_sizes[1] - $total_sizes[0];
9617
  }
@@ -9993,7 +10138,7 @@ function ewww_image_optimizer_options( $network = 'singlesite' ) {
9993
  <p><i><?php esc_html_e( 'Priority Support included with any purchase.', 'ewww-image-optimizer' ); ?></i></p>
9994
  <?php endif; ?>
9995
  <?php if ( ewww_image_optimizer_get_option( 'ewww_image_optimizer_cloud_key' ) ) : ?>
9996
- <p><strong><?php esc_html_e( 'Cloud optimization API Key', 'ewww-image-optimizer' ); ?></strong>
9997
  <?php if ( false !== strpos( $verify_cloud, 'great' ) ) : ?>
9998
  <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() ); ?>
9999
  <?php elseif ( false !== strpos( $verify_cloud, 'exceeded' ) ) : ?>
@@ -10023,6 +10168,7 @@ function ewww_image_optimizer_options( $network = 'singlesite' ) {
10023
  <p><b>Easy IO:</b>
10024
  <?php if ( $exactdn->get_exactdn_domain() && $exactdn->verify_domain( $exactdn->get_exactdn_domain() ) ) : ?>
10025
  <span style="color: #3eadc9; font-weight: bolder"><?php esc_html_e( 'Verified', 'ewww-image-optimizer' ); ?></span>
 
10026
  <?php elseif ( $exactdn->get_exactdn_domain() && $exactdn->get_exactdn_option( 'verified' ) ) : ?>
10027
  <span style="color: orange; font-weight: bolder"><?php esc_html_e( 'Temporarily disabled.', 'ewww-image-optimizer' ); ?></span>
10028
  <?php elseif ( $exactdn->get_exactdn_domain() && $exactdn->get_exactdn_option( 'suspended' ) ) : ?>
@@ -10035,7 +10181,10 @@ function ewww_image_optimizer_options( $network = 'singlesite' ) {
10035
  <?php endif; ?>
10036
  </p>
10037
  <?php elseif ( ! ewww_image_optimizer_get_option( 'ewww_image_optimizer_exactdn' ) && ! get_option( 'easyio_exactdn' ) ) : ?>
10038
- <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>
 
 
 
10039
  <?php endif; ?>
10040
  <p>
10041
  <strong><?php esc_html_e( 'Background optimization (faster uploads):', 'ewww-image-optimizer' ); ?></strong><br>
@@ -10184,7 +10333,7 @@ function ewww_image_optimizer_options( $network = 'singlesite' ) {
10184
  <?php if ( ewww_image_optimizer_get_option( 'ewww_image_optimizer_cloud_key' ) ) : ?>
10185
  <tr>
10186
  <th scope='row'>
10187
- <label for='ewww_image_optimizer_cloud_notkey'><?php esc_html_e( 'Optimization API Key', 'ewww-image-optimizer' ); ?></label>
10188
  </th>
10189
  <td>
10190
  <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' />
@@ -10197,7 +10346,7 @@ function ewww_image_optimizer_options( $network = 'singlesite' ) {
10197
  <?php else : ?>
10198
  <tr>
10199
  <th scope='row'>
10200
- <label for='ewww_image_optimizer_cloud_key'><?php esc_html_e( 'Optimization API Key', 'ewww-image-optimizer' ); ?></label>
10201
  <?php ewwwio_help_link( 'https://docs.ewww.io/article/7-basic-configuration', '585373d5c697912ffd6c0bb2,5ad0c8e7042863075092650b,5a9efec62c7d3a7549516550' ); ?>
10202
  </th>
10203
  <td>
@@ -10944,7 +11093,7 @@ function ewww_image_optimizer_options( $network = 'singlesite' ) {
10944
  <span><?php ewwwio_help_link( 'https://docs.ewww.io/article/16-ewww-io-and-webp-images', '5854745ac697912ffd6c1c89' ); ?></span>
10945
  </th>
10946
  <td>
10947
- <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>
10948
  <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>
10949
  <textarea id='ewww_image_optimizer_webp_paths' name='ewww_image_optimizer_webp_paths' rows='3' cols='60'><?php echo esc_html( $webp_paths ); ?></textarea>
10950
  <p class='description'><?php echo wp_kses_post( $webp_url_example ); ?></p>
@@ -11158,20 +11307,14 @@ AddType image/webp .webp</pre>
11158
  echo '<h3>' . esc_html__( 'Hosting', 'ewww-image-optimizer' ) . '</h3>' .
11159
  '<p><a href="http://shareasale.com/r.cfm?b=917225&amp;u=1481701&amp;m=41388&amp;urllink=&amp;afftrack=">WP Engine</a>* - ' .
11160
  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' ) .
11161
- '<br><a href="https://www.siteground.com/wordpress-hosting.htm?afcode=bd82f2335e9c794c1ba7ff4cc3a8b3fd">SiteGround</a>* - ' .
11162
- 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' ) .
11163
  '<br><a href="https://kinsta.com?kaid=OCKKBJARSDFR">Kinsta</a>* - ' .
11164
  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' ) .
11165
- '<br><a href="http://www.a2hosting.com/?aid=b6322137">A2 Hosting</a>* - ' .
11166
- esc_html__( 'I use them for several sites and this is pretty much the fastest shared hosting money can buy.', 'ewww-image-optimizer' ) .
11167
  '<br><a href="https://vrlps.co/kXJu5yF/cp">Cloudways</a>* - ' .
11168
  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' ) .
11169
  '</p>' .
11170
  '<h3>' . esc_html__( 'Plugins and Services', 'ewww-image-optimizer' ) . '</h3>' .
11171
  '<p><a href="https://easydigitaldownloads.com/?ref=4735">Easy Digital Downloads</a>* - ' .
11172
  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' ) .
11173
- '<br><a href="https://tomasz-dobrzynski.com/wordpress-gonzales">Gonzales</a> - ' .
11174
- 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' ) .
11175
  '<br><a href="https://www.helpscout.net/referral/?code=SVhaTmZDSSt2WG4xYS9FRmZrNllUa3RSR25VTStXcGhmaStQQ21QQjBDVmdZdz09OnoyVTFIUzBnbldtM21VMEM.">Helpscout</a>* - ' .
11176
  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' ) .
11177
  '<br><a href="http://eepurl.com/cLPIeD">MailChimp</a>* - ' .
@@ -11321,7 +11464,7 @@ function ewww_image_optimizer_easy_active() {
11321
  * @param boolean|string $redirect Should the plugin do a silent redirect back to the referring page? Default true.
11322
  */
11323
  function ewww_image_optimizer_remove_cloud_key( $redirect = true ) {
11324
- $permissions = apply_filters( 'ewww_image_optimizer_admin_permissions', 'manage_options' );
11325
  if ( 'none' !== $redirect && false === current_user_can( $permissions ) ) {
11326
  wp_die( esc_html__( 'Access denied.', 'ewww-image-optimizer' ) );
11327
  }
@@ -11356,8 +11499,7 @@ function ewww_image_optimizer_remove_cloud_key( $redirect = true ) {
11356
  * Enables Forced WebP for GIF images once the site is ready.
11357
  */
11358
  function ewww_image_optimizer_enable_force_gif2webp() {
11359
- $permissions = apply_filters( 'ewww_image_optimizer_admin_permissions', 'manage_options' );
11360
- if ( ! current_user_can( $permissions ) ) {
11361
  wp_die( esc_html__( 'Access denied.', 'ewww-image-optimizer' ) );
11362
  }
11363
  ewww_image_optimizer_set_option( 'ewww_image_optimizer_force_gif2webp', true );
@@ -11370,7 +11512,7 @@ function ewww_image_optimizer_enable_force_gif2webp() {
11370
  */
11371
  function ewww_image_optimizer_resize_detection_script() {
11372
  if (
11373
- ! current_user_can( apply_filters( 'ewww_image_optimizer_admin_permissions', 'edit_others_posts' ) ) ||
11374
  ( ! empty( $_SERVER['SCRIPT_NAME'] ) && 'wp-login.php' === basename( sanitize_text_field( wp_unslash( $_SERVER['SCRIPT_NAME'] ) ) ) )
11375
  ) {
11376
  return;
@@ -11426,7 +11568,7 @@ function ewww_image_optimizer_is_amp() {
11426
  */
11427
  function ewww_image_optimizer_admin_bar_init() {
11428
  if (
11429
- ! current_user_can( apply_filters( 'ewww_image_optimizer_admin_permissions', 'edit_others_posts' ) ) ||
11430
  ! is_admin_bar_showing() ||
11431
  ( ! empty( $_SERVER['SCRIPT_NAME'] ) && 'wp-login.php' === basename( sanitize_text_field( wp_unslash( $_SERVER['SCRIPT_NAME'] ) ) ) ) ||
11432
  is_admin()
@@ -11440,9 +11582,10 @@ function ewww_image_optimizer_admin_bar_init() {
11440
 
11441
  /**
11442
  * Adds a resize detection button to the wp admin bar.
 
 
11443
  */
11444
- function ewww_image_optimizer_admin_bar_menu() {
11445
- global $wp_admin_bar;
11446
  $wp_admin_bar->add_menu(
11447
  array(
11448
  'id' => 'resize-detection',
@@ -11526,8 +11669,7 @@ function ewww_image_optimizer_debug_log() {
11526
  * View the debug.log file from the wp-admin.
11527
  */
11528
  function ewww_image_optimizer_view_debug_log() {
11529
- $permissions = apply_filters( 'ewww_image_optimizer_admin_permissions', 'manage_options' );
11530
- if ( false === current_user_can( $permissions ) ) {
11531
  wp_die( esc_html__( 'Access denied.', 'ewww-image-optimizer' ) );
11532
  }
11533
  if ( ewwwio_is_file( WP_CONTENT_DIR . '/ewww/debug.log' ) ) {
@@ -11543,8 +11685,7 @@ function ewww_image_optimizer_view_debug_log() {
11543
  * Removes the debug.log file from the plugin folder.
11544
  */
11545
  function ewww_image_optimizer_delete_debug_log() {
11546
- $permissions = apply_filters( 'ewww_image_optimizer_admin_permissions', 'manage_options' );
11547
- if ( false === current_user_can( $permissions ) ) {
11548
  wp_die( esc_html__( 'Access denied.', 'ewww-image-optimizer' ) );
11549
  }
11550
  if ( ewwwio_is_file( WP_CONTENT_DIR . '/ewww/debug.log' ) ) {
14
  exit;
15
  }
16
 
17
+ define( 'EWWW_IMAGE_OPTIMIZER_VERSION', '571.0' );
18
 
19
  // Initialize a couple globals.
20
  $eio_debug = '';
244
  * Lazy Load class for parsing image urls and rewriting them to defer off-screen images.
245
  */
246
  require_once( EWWW_IMAGE_OPTIMIZER_PLUGIN_PATH . 'classes/class-eio-lazy-load.php' );
247
+
248
+ global $eio_lazy_load;
249
+ $eio_lazy_load = new EIO_Lazy_Load();
250
  }
251
  // If Alt WebP Rewriting is enabled.
252
  if ( ewww_image_optimizer_get_option( 'ewww_image_optimizer_webp_for_cdn' ) && ! ewww_image_optimizer_get_option( 'ewww_image_optimizer_exactdn' ) ) {
696
  * Re-tests background optimization at a user's request.
697
  */
698
  function ewww_image_optimizer_retest_background_optimization() {
699
+ if ( ! current_user_can( apply_filters( 'ewww_image_optimizer_admin_permissions', '' ) ) ) {
 
700
  wp_die( esc_html__( 'Access denied.', 'ewww-image-optimizer' ) );
701
  }
702
  ewww_image_optimizer_enable_background_optimization();
1255
  add_filter( 'ewww_image_optimizer_allowed_reopt', '__return_true' );
1256
  return;
1257
  }
1258
+ if (
1259
+ ! empty( $GLOBALS['wp']->query_vars['rest_route'] ) &&
1260
+ strpos( $GLOBALS['wp']->query_vars['rest_route'], '/media/' ) &&
1261
+ preg_match( '/media\/\d+\/edit$/', $GLOBALS['wp']->query_vars['rest_route'] )
1262
+ ) {
1263
+ ewwwio_debug_message( 'image edited via REST' );
1264
+ global $ewww_preempt_editor;
1265
+ $ewww_preempt_editor = true;
1266
+ }
1267
  }
1268
 
1269
  /**
1409
  // See if the path column exists, and what collation it uses to determine the column index size.
1410
  if ( $wpdb->get_var( "SHOW TABLES LIKE '$wpdb->ewwwio_images'" ) === $wpdb->ewwwio_images ) {
1411
  ewwwio_debug_message( 'upgrading table and checking collation for path, table exists' );
1412
+ if ( $wpdb->get_results( "SHOW INDEX FROM $wpdb->ewwwio_images WHERE Key_name = 'id'", ARRAY_A ) ) {
1413
+ $id_key = $wpdb->get_results( "SHOW INDEX FROM $wpdb->ewwwio_images WHERE Key_name = 'id'", ARRAY_A );
1414
+ // Possibly use AND NOT Non_unique (double-negativity fun).
1415
+ if ( $wpdb->query( "ALTER TABLE $wpdb->ewwwio_images ADD PRIMARY KEY(id)" ) ) {
1416
+ $wpdb->query( "ALTER TABLE $wpdb->ewwwio_images DROP INDEX id" );
1417
+ }
1418
+ }
1419
  // Check if the old path_image_size index exists, and drop it.
1420
  if ( $wpdb->get_results( "SHOW INDEX FROM $wpdb->ewwwio_images WHERE Key_name = 'path_image_size'", ARRAY_A ) ) {
1421
  ewwwio_debug_message( 'getting rid of path_image_size index' );
1488
  * trace: tracelog from the last optimization if debugging was enabled.
1489
  */
1490
  $sql = "CREATE TABLE $wpdb->ewwwio_images (
1491
+ id int(14) unsigned NOT NULL AUTO_INCREMENT PRIMARY KEY,
1492
  attachment_id bigint(20) unsigned,
1493
  gallery varchar(10),
1494
  resize varchar(75),
1503
  updates int(5) unsigned,
1504
  updated timestamp DEFAULT '1971-01-01 00:00:00' ON UPDATE CURRENT_TIMESTAMP,
1505
  trace blob,
 
1506
  KEY path (path($path_index_size)),
1507
  KEY attachment_info (gallery(3),attachment_id)
1508
  ) $db_collation;";
1519
  * scanned: 1 if the image is queued for optimization, 0 if it still needs scanning.
1520
  */
1521
  $sql = "CREATE TABLE $wpdb->ewwwio_queue (
1522
+ id int(14) unsigned NOT NULL AUTO_INCREMENT PRIMARY KEY,
1523
  attachment_id bigint(20) unsigned,
1524
  gallery varchar(20),
1525
  scanned tinyint(3) NOT NULL DEFAULT 0,
1786
  }
1787
 
1788
  /**
1789
+ * Let the user know the local domain appears to have changed from what Easy IO has recorded in the db.
1790
  */
1791
+ function ewww_image_optimizer_notice_exactdn_domain_mismatch() {
1792
+ global $exactdn;
1793
+ if ( ! isset( $exactdn->upload_domain ) ) {
1794
+ return;
1795
+ }
1796
+ ?>
1797
+ <div id="ewww-image-optimizer-notice-exactdn-domain-mismatch" class="notice notice-warning">
1798
+ <p>
1799
+ <?php
1800
+ printf(
1801
+ /* translators: 1: old domain name, 2: current domain name */
1802
+ esc_html__( 'Easy IO detected that the Site URL has changed since the initial activation (previously %1$s, currently %2$s).', 'ewww-image-optimizer' ),
1803
+ '<strong>' . esc_html( ewww_image_optimizer_get_option( 'ewww_image_optimizer_exactdn_local_domain' ) ) . '</strong>',
1804
+ '<strong>' . esc_html( $exactdn->upload_domain ) . '</strong>'
1805
+ );
1806
+ ?>
1807
+ <br>
1808
+ <?php
1809
+ printf(
1810
+ /* translators: %s: settings page */
1811
+ esc_html__( 'Please visit the %s to refresh the Easy IO settings and verify activation status.', 'ewww-image-optimizer' ),
1812
+ '<a href="' . esc_url( admin_url( 'options-general.php?page=ewww-image-optimizer-options' ) ) . '">' . esc_html__( 'settings page', 'ewww-image-optimizer' ) . '</a>'
1813
+ );
1814
+ ?>
1815
+ </p>
1816
+ </div>
1817
+ <?php
1818
  }
1819
 
1820
  /**
1824
  echo "<div id='ewww-image-optimizer-exactdn-sp' class='notice notice-warning'><p>" . esc_html__( 'ShortPixel image optimization has been disabled to prevent conflicts with Easy IO (EWWW Image Optimizer).', 'ewww-image-optimizer' ) . '</p></div>';
1825
  }
1826
 
1827
+ /**
1828
+ * Display a notice that PHP version 5.5 support is going away.
1829
+ */
1830
+ function ewww_image_optimizer_php55_warning() {
1831
+ echo '<div id="ewww-image-optimizer-notice-php55" class="notice notice-info"><p><a href="https://docs.ewww.io/article/55-upgrading-php" target="_blank" data-beacon-article="5ab2baa6042863478ea7c2ae">' . esc_html__( 'The next major release of EWWW Image Optimizer will require PHP 5.6 or greater. Newer versions of PHP, like 7.1 and 7.2, are significantly faster and much more secure. If you are unsure how to upgrade to a supported version, ask your webhost for instructions.', 'ewww-image-optimizer' ) . '</a></p></div>';
1832
+ }
1833
+
1834
  /**
1835
  * Lets the user know their network settings have been saved.
1836
  */
3627
  ewwwio_debug_message( 'removing: ' . $image['path'] . '.webp' );
3628
  ewwwio_delete_file( $image['path'] . '.webp' );
3629
  }
3630
+ $webpfileold = preg_replace( '/\.\w+$/', '.webp', $image['path'] );
3631
+ if ( ewwwio_is_file( $webpfileold ) ) {
3632
+ ewwwio_debug_message( 'removing: ' . $webpfileold );
3633
+ ewwwio_delete_file( $webpfileold );
3634
+ }
3635
  }
3636
  if ( ! empty( $image['converted'] ) ) {
3637
  $image['converted'] = ewww_image_optimizer_absolutize_path( $image['converted'] );
3638
  }
3639
  if ( ! empty( $image['converted'] ) && ewwwio_is_file( $image['converted'] ) ) {
3640
+ ewwwio_debug_message( 'removing: ' . $image['converted'] );
3641
  ewwwio_delete_file( $image['converted'] );
3642
  if ( ewwwio_is_file( $image['converted'] . '.webp' ) ) {
3643
  ewwwio_debug_message( 'removing: ' . $image['converted'] . '.webp' );
3746
  }
3747
  }
3748
  }
3749
+ if ( ewwwio_is_file( $file_path . '.webp' ) ) {
3750
+ ewwwio_debug_message( 'removing: ' . $file_path . '.webp' );
3751
+ ewwwio_delete_file( $image['path'] . '.webp' );
3752
+ }
3753
+ $webpfileold = preg_replace( '/\.\w+$/', '.webp', $file_path );
3754
+ if ( ewwwio_is_file( $webpfileold ) ) {
3755
+ ewwwio_debug_message( 'removing: ' . $webpfileold );
3756
+ ewwwio_delete_file( $webpfileold );
3757
+ }
3758
  }
3759
 
3760
  /**
4014
  return false;
4015
  }
4016
  if ( ewww_image_optimizer_get_option( 'ewww_image_optimizer_cloud_exceeded' ) > time() ) {
4017
+ set_transient( 'ewww_image_optimizer_cloud_status', 'exceeded', HOUR_IN_SECONDS );
4018
  ewwwio_debug_message( 'license exceeded notice has not expired' );
4019
  return 'exceeded';
4020
  }
4071
  ewwwio_memory( __FUNCTION__ );
4072
  return false;
4073
  } else {
4074
+ set_transient( 'ewww_image_optimizer_cloud_status', $verified, HOUR_IN_SECONDS );
4075
  if ( ewww_image_optimizer_get_option( 'ewww_image_optimizer_jpg_level' ) < 20 && ewww_image_optimizer_get_option( 'ewww_image_optimizer_png_level' ) < 20 && ewww_image_optimizer_get_option( 'ewww_image_optimizer_gif_level' ) < 20 && ! ewww_image_optimizer_get_option( 'ewww_image_optimizer_pdf_level' ) ) {
4076
  ewww_image_optimizer_cloud_enable();
4077
  }
4289
  } else {
4290
  $webp = 0;
4291
  }
4292
+ if ( $jpg_quality < 50 ) {
4293
+ $jpg_quality = 82;
4294
+ }
4295
  if ( 30 === (int) ewww_image_optimizer_get_option( 'ewww_image_optimizer_png_level' ) ) {
4296
  $png_compress = 1;
4297
  } else {
4413
  ewww_image_optimizer_remove_cloud_key( 'none' );
4414
  } elseif ( 100 > strlen( $response['body'] ) && strpos( $response['body'], 'exceeded' ) ) {
4415
  ewwwio_debug_message( 'License Exceeded' );
4416
+ set_transient( 'ewww_image_optimizer_cloud_status', 'exceeded', HOUR_IN_SECONDS );
4417
  $msg = 'exceeded';
4418
  ewwwio_delete_file( $tempfile );
4419
  } elseif ( ewww_image_optimizer_mimetype( $tempfile, 'i' ) === $type ) {
4545
  $newsize = $orig_size;
4546
  if ( preg_match( '/exceeded/', $response['body'] ) ) {
4547
  ewwwio_debug_message( 'License Exceeded' );
4548
+ set_transient( 'ewww_image_optimizer_cloud_status', 'exceeded', HOUR_IN_SECONDS );
4549
  ewwwio_delete_file( $tempfile );
4550
  } elseif ( ewww_image_optimizer_mimetype( $tempfile, 'i' ) === $type ) {
4551
  $newsize = filesize( $tempfile );
5068
  return '';
5069
  }
5070
 
5071
+ /**
5072
+ * Updates the savings statistics cache.
5073
+ *
5074
+ * @param int $opt_size The new size of the image.
5075
+ * @param int $orig_size The original size of the image.
5076
+ */
5077
+ function ewww_image_optimizer_update_savings( $opt_size, $orig_size ) {
5078
+ ewwwio_debug_message( '<b>' . __FUNCTION__ . '()</b>' );
5079
+ if ( ! $opt_size || ! $orig_size ) {
5080
+ return;
5081
+ }
5082
+ $cache_savings = get_transient( 'ewww_image_optimizer_savings' );
5083
+ if ( ! empty( $cache_savings ) && is_array( $cache_savings ) && 2 === count( $cache_savings ) ) {
5084
+ $total_opt = (int) $cache_savings[0];
5085
+ $total_orig = (int) $cache_savings[1];
5086
+ ewwwio_debug_message( "increasing $total_opt by $opt_size" );
5087
+ $total_opt += (int) $opt_size;
5088
+ ewwwio_debug_message( "increasing $total_orig by $orig_size" );
5089
+ $total_orig += (int) $orig_size;
5090
+ set_transient( 'ewww_image_optimizer_savings', array( $total_opt, $total_orig ), DAY_IN_SECONDS );
5091
+ }
5092
+ if ( is_multisite() ) {
5093
+ $cache_savings = get_site_transient( 'ewww_image_optimizer_savings' );
5094
+ if ( ! empty( $cache_savings ) && is_array( $cache_savings ) && 2 === count( $cache_savings ) ) {
5095
+ $total_opt = (int) $cache_savings[0];
5096
+ $total_orig = (int) $cache_savings[1];
5097
+ ewwwio_debug_message( "increasing $total_opt by $opt_size" );
5098
+ $total_opt += (int) $opt_size;
5099
+ ewwwio_debug_message( "increasing $total_orig by $orig_size" );
5100
+ $total_orig += (int) $orig_size;
5101
+ set_site_transient( 'ewww_image_optimizer_savings', array( $total_opt, $total_orig ), DAY_IN_SECONDS );
5102
+ }
5103
+ }
5104
+ }
5105
+
5106
  /**
5107
  * Inserts or updates an image record in the database.
5108
  *
5125
  } else {
5126
  $ewwwdb = $wpdb;
5127
  }
5128
+ ewww_image_optimizer_update_savings( $opt_size, $orig_size );
5129
  global $ewww_image;
5130
  // First check if the image was converted, so we don't orphan records.
5131
  if ( $original && $original !== $attachment ) {
6188
  /**
6189
  * Check non-Media Library filenames to see if the image is eligible for resizing.
6190
  *
6191
+ * This function specifically checks to be sure the filename does not preclude an image.
6192
+ * It does not check the dimensions, that is done by ewww_image_optimizer_should_resize().
6193
+ *
6194
  * @param string $file The image filename.
6195
  * @return bool True to allow resizing, false otherwise.
6196
  */
6238
  // Parts adapted from Imsanity (THANKS Jason!).
6239
  ewwwio_debug_message( '<b>' . __FUNCTION__ . '()</b>' );
6240
  global $ewww_webp_only;
6241
+ global $ewwwio_resize_status;
6242
+ $ewwwio_resize_status = '';
6243
  if ( ! $file ) {
6244
  return false;
6245
  }
6310
  list( $oldwidth, $oldheight ) = getimagesize( $file );
6311
  if ( $oldwidth <= $maxwidth && $oldheight <= $maxheight ) {
6312
  ewwwio_debug_message( 'image too small for resizing' );
6313
+ /* translators: 1: width in pixels 2: height in pixels */
6314
+ $ewwwio_resize_status = sprintf( __( 'Resize not required, image smaller than %1$s x %2$s', 'ewww-image-optimizer' ), $maxwidth . 'w', $maxheight . 'h' );
6315
  if ( $oldwidth && $oldheight ) {
6316
  return array( $oldwidth, $oldheight );
6317
  }
6336
  }
6337
  if ( ! function_exists( 'wp_get_image_editor' ) ) {
6338
  ewwwio_debug_message( 'no image editor function' );
6339
+ $ewwwio_resize_status = __( 'wp_get_image_editor function is missing', 'ewww-image-optimizer' );
6340
  return false;
6341
  }
6342
 
6346
 
6347
  $editor = wp_get_image_editor( $file );
6348
  if ( is_wp_error( $editor ) ) {
6349
+ $error_message = $editor->get_error_message();
6350
+ ewwwio_debug_message( "could not get image editor: $error_message" );
6351
+ /* translators: %s: a WP error message, translated elsewhere */
6352
+ $ewwwio_resize_status = sprintf( __( 'Unable to load resize function: %s', 'ewww-image-optimizer' ), $error_message );
6353
  return false;
6354
  }
6355
  // Rotation only happens on existing media here, so we need to swap dimension when we rotate by 90.
6379
  if ( is_wp_error( $resized_image ) ) {
6380
  $error_message = $resized_image->get_error_message();
6381
  ewwwio_debug_message( "error during resizing: $error_message" );
6382
+ /* translators: %s: a WP error message, translated elsewhere */
6383
+ $ewwwio_resize_status = sprintf( __( 'Resizing error: %s', 'ewww-image-optimizer' ), $error_message );
6384
  return false;
6385
  }
6386
  $new_file = $editor->generate_filename( 'tmp' );
6390
  if ( is_wp_error( $saved ) ) {
6391
  $error_message = $saved->get_error_message();
6392
  ewwwio_debug_message( "error saving resized image: $error_message" );
6393
+ /* translators: %s: a WP error message, translated elsewhere */
6394
+ $ewwwio_resize_status = sprintf( __( 'Could not save resized image: %s', 'ewww-image-optimizer' ), $error_message );
6395
  }
6396
  if ( ! ewww_image_optimizer_get_option( 'ewww_image_optimizer_noauto' ) && ( ! defined( 'EWWW_IMAGE_OPTIMIZER_DISABLE_EDITOR' ) || ! EWWW_IMAGE_OPTIMIZER_DISABLE_EDITOR ) ) {
6397
  $ewww_preempt_editor = false;
6439
  ewwwio_rename( $new_file, $file );
6440
  } else {
6441
  ewwwio_debug_message( "resizing did not create a valid image: $new_type" );
6442
+ /* translators: %s: the mime type of the new file */
6443
+ $ewwwio_resize_status = sprintf( __( 'Resizing resulted in an invalid file type: %s', 'ewww-image-optimizer' ), $new_type );
6444
  unlink( $new_file );
6445
  return false;
6446
  }
6490
  );
6491
  }
6492
  }
6493
+ /* translators: 1: width in pixels 2: height in pixels */
6494
+ $ewwwio_resize_status = sprintf( __( 'Resized to %1$s x %2$s', 'ewww-image-optimizer' ), $newwidth . 'w', $newheight . 'h' );
6495
  return array( $newwidth, $newheight );
6496
  } // End if().
6497
  if ( ewwwio_is_file( $new_file ) ) {
6498
  ewwwio_debug_message( "resizing did not create a smaller image: $new_size" );
6499
+ $ewwwio_resize_status = __( 'Resizing did not reduce the file size, result discarded', 'ewww-image-optimizer' );
6500
  unlink( $new_file );
6501
  }
6502
  return false;
8511
  return array( '', false, false );
8512
  }
8513
  ewwwio_debug_message( '<b>' . __FUNCTION__ . '()</b>' );
8514
+ global $ewwwio_resize_status;
8515
  $orig_size = 0;
8516
  $opt_size = 0;
8517
  $converted = false;
8544
  }
8545
  $detail_output .= '</table>';
8546
 
8547
+ if ( ! empty( $ewwwio_resize_status ) ) {
8548
+ $output .= '<div>' . esc_html( $ewwwio_resize_status ) . '</div>';
8549
+ }
8550
  $output .= '<div>' . sprintf(
8551
  esc_html(
8552
  /* translators: %d: number of resizes/thumbnails compressed */
8833
  ewwwio_ob_clean();
8834
  ewwwio_debug_message( '<b>' . __FUNCTION__ . '()</b>' );
8835
  // Verify that the user is properly authorized.
8836
+ if ( ! current_user_can( apply_filters( 'ewww_image_optimizer_admin_permissions', '' ) ) ) {
8837
  wp_die( esc_html__( 'Access denied.', 'ewww-image-optimizer' ) );
8838
  }
8839
  delete_option( 'ewww_image_optimizer_wc_regen' );
8847
  ewwwio_ob_clean();
8848
  ewwwio_debug_message( '<b>' . __FUNCTION__ . '()</b>' );
8849
  // Verify that the user is properly authorized.
8850
+ if ( ! current_user_can( apply_filters( 'ewww_image_optimizer_admin_permissions', '' ) ) ) {
8851
  wp_die( esc_html__( 'Access denied.', 'ewww-image-optimizer' ) );
8852
  }
8853
  delete_option( 'ewww_image_optimizer_lr_sync' );
8861
  ewwwio_ob_clean();
8862
  ewwwio_debug_message( '<b>' . __FUNCTION__ . '()</b>' );
8863
  // Verify that the user is properly authorized.
8864
+ if ( ! current_user_can( apply_filters( 'ewww_image_optimizer_admin_permissions', '' ) ) ) {
8865
  wp_die( esc_html__( 'Access denied.', 'ewww-image-optimizer' ) );
8866
  }
8867
  update_option( 'ewww_image_optimizer_dismiss_media_notice', true, false );
8876
  ewwwio_ob_clean();
8877
  ewwwio_debug_message( '<b>' . __FUNCTION__ . '()</b>' );
8878
  // Verify that the user is properly authorized.
8879
+ if ( ! current_user_can( apply_filters( 'ewww_image_optimizer_admin_permissions', '' ) ) ) {
8880
  wp_die( esc_html__( 'Access denied.', 'ewww-image-optimizer' ) );
8881
  }
8882
  update_option( 'ewww_image_optimizer_dismiss_review_notice', true, false );
9088
  if ( 'settings_page_ewww-image-optimizer-options' !== $hook ) {
9089
  return;
9090
  }
9091
+ delete_option( 'ewww_image_optimizer_exactdn_checkin' );
9092
+ global $exactdn;
9093
+ if ( has_action( 'admin_notices', 'ewww_image_optimizer_notice_exactdn_domain_mismatch' ) ) {
9094
+ delete_option( 'ewww_image_optimizer_exactdn_domain' );
9095
+ delete_option( 'ewww_image_optimizer_exactdn_local_domain' );
9096
+ delete_option( 'ewww_image_optimizer_exactdn_plan_id' );
9097
+ delete_option( 'ewww_image_optimizer_exactdn_failures' );
9098
+ delete_option( 'ewww_image_optimizer_exactdn_verified' );
9099
+ remove_action( 'admin_notices', 'ewww_image_optimizer_notice_exactdn_domain_mismatch' );
9100
+ $exactdn->setup();
9101
+ }
9102
  add_thickbox();
9103
  wp_enqueue_script( 'jquery-ui-tooltip' );
9104
  wp_enqueue_script( 'ewwwbulkscript', plugins_url( '/includes/eio.js', __FILE__ ), array( 'jquery' ), EWWW_IMAGE_OPTIMIZER_VERSION );
9112
  /**
9113
  * Get a total of how much space we have saved so far.
9114
  *
9115
+ * @param bool $network_admin True if this is called from the network admin dashboard, false otherwise.
9116
  * @global object $wpdb
9117
  *
9118
  * @return int The total savings found, in bytes.
9119
  */
9120
+ function ewww_image_optimizer_savings( $network_admin = false ) {
9121
  ewwwio_debug_message( '<b>' . __FUNCTION__ . '()</b>' );
9122
  global $wpdb;
 
 
 
 
9123
  $total_orig = 0;
9124
  $total_opt = 0;
9125
  $total_savings = 0;
9126
+ $started = microtime( true );
9127
+ if ( is_multisite() && $network_admin ) {
9128
+ $cache_savings = get_site_transient( 'ewww_image_optimizer_savings' );
9129
+ if ( ! empty( $cache_savings ) && is_array( $cache_savings ) && 2 === count( $cache_savings ) ) {
9130
+ ewwwio_debug_message( 'savings query avoided via (multi-site) cache' );
9131
+ return $cache_savings;
9132
+ }
9133
  ewwwio_debug_message( 'querying savings for multi-site' );
9134
 
9135
  if ( get_blog_count() > 1000 ) {
9136
  return 0;
9137
  }
9138
  if ( function_exists( 'get_sites' ) ) {
 
9139
  $blogs = get_sites(
9140
  array(
9141
  'fields' => 'ids',
9142
  'number' => 1000,
9143
  )
9144
  );
9145
+ } else {
9146
+ return 0;
 
 
 
 
 
 
9147
  }
9148
  if ( ewww_image_optimizer_iterable( $blogs ) ) {
9149
  foreach ( $blogs as $blog ) {
9171
  restore_current_blog();
9172
  }
9173
  }
9174
+ set_site_transient( 'ewww_image_optimizer_savings', array( $total_opt, $total_orig ), DAY_IN_SECONDS );
9175
  } else {
9176
+ $cache_savings = get_transient( 'ewww_image_optimizer_savings' );
9177
+ if ( ! empty( $cache_savings ) && is_array( $cache_savings ) && 2 === count( $cache_savings ) ) {
9178
+ ewwwio_debug_message( 'savings query avoided via (single-site) cache' );
9179
+ return $cache_savings;
9180
+ }
9181
  ewwwio_debug_message( 'querying savings for single site' );
9182
  $table_name = $wpdb->ewwwio_images;
9183
  ewwwio_debug_message( "table name is $table_name" );
9190
  $total_opt += $opt_size;
9191
 
9192
  $total_savings = $orig_size - $opt_size;
9193
+ set_transient( 'ewww_image_optimizer_savings', array( $total_opt, $total_orig ), DAY_IN_SECONDS );
9194
  } // End if().
9195
+ $elapsed = microtime( true ) - $started;
9196
+ ewwwio_debug_message( "savings query took $elapsed seconds" );
9197
  ewwwio_debug_message( "total original size: $total_orig" );
9198
  ewwwio_debug_message( "total current(opt) size: $total_opt" );
9199
  ewwwio_debug_message( "savings found: $total_savings" );
9264
  if ( empty( $_REQUEST['ewww_wpnonce'] ) || ! wp_verify_nonce( sanitize_key( $_REQUEST['ewww_wpnonce'] ), 'ewww-image-optimizer-settings' ) ) {
9265
  wp_die( esc_html__( 'Access denied.', 'ewww-image-optimizer' ) );
9266
  }
9267
+ if ( ! current_user_can( apply_filters( 'ewww_image_optimizer_admin_permissions', '' ) ) ) {
9268
  wp_die( esc_html__( 'Access denied.', 'ewww-image-optimizer' ) );
9269
  }
9270
  $ewww_rules = ewww_image_optimizer_webp_rewrite_verify();
9288
  if ( empty( $_REQUEST['ewww_wpnonce'] ) || ! wp_verify_nonce( sanitize_key( $_REQUEST['ewww_wpnonce'] ), 'ewww-image-optimizer-settings' ) ) {
9289
  wp_die( esc_html__( 'Access denied.', 'ewww-image-optimizer' ) );
9290
  }
9291
+ if ( ! current_user_can( apply_filters( 'ewww_image_optimizer_admin_permissions', '' ) ) ) {
9292
  wp_die( esc_html__( 'Access denied.', 'ewww-image-optimizer' ) );
9293
  }
9294
  if ( insert_with_markers( ewww_image_optimizer_htaccess_path(), 'EWWWIO', '' ) ) {
9753
  global $exactdn;
9754
  global $eio_alt_webp;
9755
  $total_savings = 0;
9756
+ if ( 'network-multisite' === $network ) {
9757
+ $total_sizes = ewww_image_optimizer_savings( true );
9758
+ $total_savings = $total_sizes[1] - $total_sizes[0];
9759
+ } else {
9760
  $total_sizes = ewww_image_optimizer_savings();
9761
  $total_savings = $total_sizes[1] - $total_sizes[0];
9762
  }
10138
  <p><i><?php esc_html_e( 'Priority Support included with any purchase.', 'ewww-image-optimizer' ); ?></i></p>
10139
  <?php endif; ?>
10140
  <?php if ( ewww_image_optimizer_get_option( 'ewww_image_optimizer_cloud_key' ) ) : ?>
10141
+ <p><strong><?php esc_html_e( 'Compress API Key', 'ewww-image-optimizer' ); ?></strong>
10142
  <?php if ( false !== strpos( $verify_cloud, 'great' ) ) : ?>
10143
  <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() ); ?>
10144
  <?php elseif ( false !== strpos( $verify_cloud, 'exceeded' ) ) : ?>
10168
  <p><b>Easy IO:</b>
10169
  <?php if ( $exactdn->get_exactdn_domain() && $exactdn->verify_domain( $exactdn->get_exactdn_domain() ) ) : ?>
10170
  <span style="color: #3eadc9; font-weight: bolder"><?php esc_html_e( 'Verified', 'ewww-image-optimizer' ); ?></span>
10171
+ <br><?php echo esc_html( $exactdn->get_exactdn_domain() ); ?>
10172
  <?php elseif ( $exactdn->get_exactdn_domain() && $exactdn->get_exactdn_option( 'verified' ) ) : ?>
10173
  <span style="color: orange; font-weight: bolder"><?php esc_html_e( 'Temporarily disabled.', 'ewww-image-optimizer' ); ?></span>
10174
  <?php elseif ( $exactdn->get_exactdn_domain() && $exactdn->get_exactdn_option( 'suspended' ) ) : ?>
10181
  <?php endif; ?>
10182
  </p>
10183
  <?php elseif ( ! ewww_image_optimizer_get_option( 'ewww_image_optimizer_exactdn' ) && ! get_option( 'easyio_exactdn' ) ) : ?>
10184
+ <p><span style="font-weight:bold;color:#3eadc9;">Easy IO:</span> <a href="https://ewww.io/easy/" target="_blank"><?php esc_html_e( 'Comprehensive image optimization with automatic compression, auto-sizing, WebP conversion, and lazy load.', 'ewww-image-optimizer' ); ?></a></p>
10185
+ <?php endif; ?>
10186
+ <?php if ( ! function_exists( 'swis' ) ) : ?>
10187
+ <p><span style="font-weight:bold;color:#3eadc9;">SWIS Performance:</span> <a href="https://ewww.io/swis/" target="_blank"><?php esc_html_e( 'Go beyond image optimization with this collection of tools that I use for improving site speed.', 'ewww-image-optimizer' ); ?></a></p>
10188
  <?php endif; ?>
10189
  <p>
10190
  <strong><?php esc_html_e( 'Background optimization (faster uploads):', 'ewww-image-optimizer' ); ?></strong><br>
10333
  <?php if ( ewww_image_optimizer_get_option( 'ewww_image_optimizer_cloud_key' ) ) : ?>
10334
  <tr>
10335
  <th scope='row'>
10336
+ <label for='ewww_image_optimizer_cloud_notkey'><?php esc_html_e( 'Compress API Key', 'ewww-image-optimizer' ); ?></label>
10337
  </th>
10338
  <td>
10339
  <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' />
10346
  <?php else : ?>
10347
  <tr>
10348
  <th scope='row'>
10349
+ <label for='ewww_image_optimizer_cloud_key'><?php esc_html_e( 'Compress API Key', 'ewww-image-optimizer' ); ?></label>
10350
  <?php ewwwio_help_link( 'https://docs.ewww.io/article/7-basic-configuration', '585373d5c697912ffd6c0bb2,5ad0c8e7042863075092650b,5a9efec62c7d3a7549516550' ); ?>
10351
  </th>
10352
  <td>
11093
  <span><?php ewwwio_help_link( 'https://docs.ewww.io/article/16-ewww-io-and-webp-images', '5854745ac697912ffd6c1c89' ); ?></span>
11094
  </th>
11095
  <td>
11096
+ <span><?php esc_html_e( 'Enter additional URL patterns, like a CDN URL, that should be permitted for WebP Rewriting. One URL per line, must include the domain name (cdn.example.com).', 'ewww-image-optimizer' ); ?></span>
11097
  <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>
11098
  <textarea id='ewww_image_optimizer_webp_paths' name='ewww_image_optimizer_webp_paths' rows='3' cols='60'><?php echo esc_html( $webp_paths ); ?></textarea>
11099
  <p class='description'><?php echo wp_kses_post( $webp_url_example ); ?></p>
11307
  echo '<h3>' . esc_html__( 'Hosting', 'ewww-image-optimizer' ) . '</h3>' .
11308
  '<p><a href="http://shareasale.com/r.cfm?b=917225&amp;u=1481701&amp;m=41388&amp;urllink=&amp;afftrack=">WP Engine</a>* - ' .
11309
  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' ) .
 
 
11310
  '<br><a href="https://kinsta.com?kaid=OCKKBJARSDFR">Kinsta</a>* - ' .
11311
  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' ) .
 
 
11312
  '<br><a href="https://vrlps.co/kXJu5yF/cp">Cloudways</a>* - ' .
11313
  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' ) .
11314
  '</p>' .
11315
  '<h3>' . esc_html__( 'Plugins and Services', 'ewww-image-optimizer' ) . '</h3>' .
11316
  '<p><a href="https://easydigitaldownloads.com/?ref=4735">Easy Digital Downloads</a>* - ' .
11317
  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' ) .
 
 
11318
  '<br><a href="https://www.helpscout.net/referral/?code=SVhaTmZDSSt2WG4xYS9FRmZrNllUa3RSR25VTStXcGhmaStQQ21QQjBDVmdZdz09OnoyVTFIUzBnbldtM21VMEM.">Helpscout</a>* - ' .
11319
  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' ) .
11320
  '<br><a href="http://eepurl.com/cLPIeD">MailChimp</a>* - ' .
11464
  * @param boolean|string $redirect Should the plugin do a silent redirect back to the referring page? Default true.
11465
  */
11466
  function ewww_image_optimizer_remove_cloud_key( $redirect = true ) {
11467
+ $permissions = apply_filters( 'ewww_image_optimizer_admin_permissions', '' );
11468
  if ( 'none' !== $redirect && false === current_user_can( $permissions ) ) {
11469
  wp_die( esc_html__( 'Access denied.', 'ewww-image-optimizer' ) );
11470
  }
11499
  * Enables Forced WebP for GIF images once the site is ready.
11500
  */
11501
  function ewww_image_optimizer_enable_force_gif2webp() {
11502
+ if ( ! current_user_can( apply_filters( 'ewww_image_optimizer_admin_permissions', '' ) ) ) {
 
11503
  wp_die( esc_html__( 'Access denied.', 'ewww-image-optimizer' ) );
11504
  }
11505
  ewww_image_optimizer_set_option( 'ewww_image_optimizer_force_gif2webp', true );
11512
  */
11513
  function ewww_image_optimizer_resize_detection_script() {
11514
  if (
11515
+ ! current_user_can( apply_filters( 'ewww_image_optimizer_admin_permissions', '' ) ) ||
11516
  ( ! empty( $_SERVER['SCRIPT_NAME'] ) && 'wp-login.php' === basename( sanitize_text_field( wp_unslash( $_SERVER['SCRIPT_NAME'] ) ) ) )
11517
  ) {
11518
  return;
11568
  */
11569
  function ewww_image_optimizer_admin_bar_init() {
11570
  if (
11571
+ ! current_user_can( apply_filters( 'ewww_image_optimizer_admin_permissions', '' ) ) ||
11572
  ! is_admin_bar_showing() ||
11573
  ( ! empty( $_SERVER['SCRIPT_NAME'] ) && 'wp-login.php' === basename( sanitize_text_field( wp_unslash( $_SERVER['SCRIPT_NAME'] ) ) ) ) ||
11574
  is_admin()
11582
 
11583
  /**
11584
  * Adds a resize detection button to the wp admin bar.
11585
+ *
11586
+ * @param object $wp_admin_bar The WP Admin Bar object, passed by reference.
11587
  */
11588
+ function ewww_image_optimizer_admin_bar_menu( $wp_admin_bar ) {
 
11589
  $wp_admin_bar->add_menu(
11590
  array(
11591
  'id' => 'resize-detection',
11669
  * View the debug.log file from the wp-admin.
11670
  */
11671
  function ewww_image_optimizer_view_debug_log() {
11672
+ if ( ! current_user_can( apply_filters( 'ewww_image_optimizer_admin_permissions', '' ) ) ) {
 
11673
  wp_die( esc_html__( 'Access denied.', 'ewww-image-optimizer' ) );
11674
  }
11675
  if ( ewwwio_is_file( WP_CONTENT_DIR . '/ewww/debug.log' ) ) {
11685
  * Removes the debug.log file from the plugin folder.
11686
  */
11687
  function ewww_image_optimizer_delete_debug_log() {
11688
+ if ( ! current_user_can( apply_filters( 'ewww_image_optimizer_admin_permissions', '' ) ) ) {
 
11689
  wp_die( esc_html__( 'Access denied.', 'ewww-image-optimizer' ) );
11690
  }
11691
  if ( ewwwio_is_file( WP_CONTENT_DIR . '/ewww/debug.log' ) ) {
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.6.2
17
  Author URI: https://ewww.io/
18
  License: GPLv3
19
  */
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.7.1
17
  Author URI: https://ewww.io/
18
  License: GPLv3
19
  */
includes/eio-tools.js CHANGED
@@ -36,6 +36,18 @@ jQuery(document).ready(function($) {
36
  $('.ewww-aux-table').show();
37
  $('.ewww-search-count').text(ewww_response.search_result);
38
  $('.current-page').text(ewww_response.pagination);
 
 
 
 
 
 
 
 
 
 
 
 
39
  if (ewww_vars.image_count >= 50) {
40
  $('.tablenav').show();
41
  $('.next-page').show();
@@ -167,7 +179,7 @@ jQuery(document).ready(function($) {
167
  $('.last-page').click(function() {
168
  var ewww_search = $('.ewww-search-input').val();
169
  ewww_pointer = ewww_total_pages - 1;
170
- if (ewww_search) {
171
  ewww_pointer = ewww_search_total - 1;
172
  }
173
  var ewww_table_data = {
@@ -286,11 +298,12 @@ jQuery(document).ready(function($) {
286
  };
287
  $.post(ajaxurl, ewww_converted_data, function(response) {
288
  try {
289
- var ewww_response = $.parseJSON(response);
290
  } catch (err) {
291
  $('#ewww-clean-converted-progressbar').hide();
292
  $('#ewww-clean-converted-progress').html('<span style="color: red"><b>' + ewww_vars.invalid_response + '</b></span>');
293
- console.log( response );
 
294
  return false;
295
  }
296
  if ( ewww_response.error ) {
@@ -308,6 +321,102 @@ jQuery(document).ready(function($) {
308
  ewwwRemoveOriginals(converted_offset);
309
  });
310
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
311
  $('#ewww-clean-table').submit(function() {
312
  ewww_total_pages = Math.ceil(ewww_vars.image_count / 500);
313
  $('.ewww-tool-info').hide();
36
  $('.ewww-aux-table').show();
37
  $('.ewww-search-count').text(ewww_response.search_result);
38
  $('.current-page').text(ewww_response.pagination);
39
+ // from here
40
+ if ( ewww_response.search_total > 0 ) {
41
+ ewww_search_total = ewww_response.search_total;
42
+ }
43
+ if (ewww_response.search_count < 50) {
44
+ $('.next-page').hide();
45
+ $('.last-page').hide();
46
+ }
47
+ if (ewww_table_debug) {
48
+ $('.displaying-num').hide();
49
+ }
50
+ // to here
51
  if (ewww_vars.image_count >= 50) {
52
  $('.tablenav').show();
53
  $('.next-page').show();
179
  $('.last-page').click(function() {
180
  var ewww_search = $('.ewww-search-input').val();
181
  ewww_pointer = ewww_total_pages - 1;
182
+ if (ewww_search || ewww_table_debug) {
183
  ewww_pointer = ewww_search_total - 1;
184
  }
185
  var ewww_table_data = {
298
  };
299
  $.post(ajaxurl, ewww_converted_data, function(response) {
300
  try {
301
+ var ewww_response = JSON.parse(response);
302
  } catch (err) {
303
  $('#ewww-clean-converted-progressbar').hide();
304
  $('#ewww-clean-converted-progress').html('<span style="color: red"><b>' + ewww_vars.invalid_response + '</b></span>');
305
+ console.log(err);
306
+ console.log(response);
307
  return false;
308
  }
309
  if ( ewww_response.error ) {
321
  ewwwRemoveOriginals(converted_offset);
322
  });
323
  }
324
+ var ewww_total_webp = 0;
325
+ var ewww_webp_attachments = false;
326
+ $('#ewww-clean-webp').submit(function() {
327
+ var ewww_webp_data = {
328
+ action: 'ewwwio_get_all_attachments',
329
+ ewww_wpnonce: ewww_vars._wpnonce,
330
+ };
331
+ $.post(ajaxurl, ewww_webp_data, function(response) {
332
+ try {
333
+ ewww_webp_attachments = JSON.parse(response);
334
+ } catch (err) {
335
+ $('#ewww-clean-webp-progress').html('<span style="color: red"><b>' + ewww_vars.invalid_response + '</b></span>');
336
+ console.log(err);
337
+ console.log(response);
338
+ return false;
339
+ }
340
+ ewww_total_webp = ewww_webp_attachments.length;
341
+ $('.ewww-tool-info').hide();
342
+ $('.ewww-tool-form').hide();
343
+ $('.ewww-tool-divider').hide();
344
+ $('#ewww-clean-webp-progressbar').progressbar({ max: ewww_total_webp });
345
+ $('#ewww-clean-webp-progress').html('<p>' + ewww_vars.stage1 + ' 0/' + ewww_total_webp + '</p>');
346
+ $('#ewww-clean-webp-progressbar').show();
347
+ $('#ewww-clean-webp-progress').show();
348
+ ewwwRemoveWebPByID();
349
+ });
350
+ return false;
351
+ });
352
+ function ewwwRemoveWebPByID(){
353
+ var attachment_id = ewww_webp_attachments.pop();
354
+ console.log('removing webp for attachment: ' + attachment_id);
355
+ var ewww_webp_data = {
356
+ action: 'bulk_aux_images_delete_webp',
357
+ ewww_wpnonce: ewww_vars._wpnonce,
358
+ attachment_id: attachment_id,
359
+ };
360
+ $.post(ajaxurl, ewww_webp_data, function(response) {
361
+ try {
362
+ var ewww_response = JSON.parse(response);
363
+ } catch (err) {
364
+ $('#ewww-clean-webp-progressbar').hide();
365
+ $('#ewww-clean-webp-progress').html('<span style="color: red"><b>' + ewww_vars.invalid_response + '</b></span>');
366
+ console.log(err);
367
+ console.log(response);
368
+ return false;
369
+ }
370
+ if ( ewww_response.error ) {
371
+ $('#ewww-clean-webp-progressbar').hide();
372
+ $('#ewww-clean-webp-progress').html('<span style="color: red"><b>' + ewww_response.error + '</b></span>');
373
+ return false;
374
+ }
375
+ if(!ewww_webp_attachments.length) {
376
+ ewww_total_webp = ewww_vars.image_count;
377
+ $('#ewww-clean-webp-progressbar').progressbar({ max: ewww_total_webp });
378
+ $('#ewww-clean-webp-progressbar').progressbar("option", "value", 0);
379
+ $('#ewww-clean-webp-progress').html('<p>' + ewww_vars.stage2 + ' 0/' + ewww_total_webp + '</p>');
380
+ ewwwRemoveWebP(0);
381
+ return false;
382
+ }
383
+ var completed = ewww_total_webp - ewww_webp_attachments.length;
384
+ $('#ewww-clean-webp-progressbar').progressbar("option", "value", completed);
385
+ $('#ewww-clean-webp-progress').html('<p>' + ewww_vars.stage1 + ' ' + completed + '/' + ewww_total_webp + '</p>');
386
+ ewwwRemoveWebPByID();
387
+ });
388
+ }
389
+ function ewwwRemoveWebP(webp_offset){
390
+ var ewww_webp_data = {
391
+ action: 'bulk_aux_images_webp_clean',
392
+ ewww_wpnonce: ewww_vars._wpnonce,
393
+ ewww_offset: webp_offset,
394
+ };
395
+ $.post(ajaxurl, ewww_webp_data, function(response) {
396
+ try {
397
+ var ewww_response = JSON.parse(response);
398
+ } catch (err) {
399
+ $('#ewww-clean-webp-progressbar').hide();
400
+ $('#ewww-clean-webp-progress').html('<span style="color: red"><b>' + ewww_vars.invalid_response + '</b></span>');
401
+ console.log(err);
402
+ console.log(response);
403
+ return false;
404
+ }
405
+ if ( ewww_response.error ) {
406
+ $('#ewww-clean-webp-progressbar').hide();
407
+ $('#ewww-clean-webp-progress').html('<span style="color: red"><b>' + ewww_response.error + '</b></span>');
408
+ return false;
409
+ }
410
+ if(ewww_response.finished) {
411
+ $('#ewww-clean-webp-progress').html(ewww_vars.finished);
412
+ return false;
413
+ }
414
+ webp_offset += ewww_response.completed;
415
+ $('#ewww-clean-webp-progressbar').progressbar("option", "value", webp_offset);
416
+ $('#ewww-clean-webp-progress').html('<p>' + ewww_vars.stage2 + ' ' + webp_offset + '/' + ewww_total_webp + '</p>');
417
+ ewwwRemoveWebP(webp_offset);
418
+ });
419
+ }
420
  $('#ewww-clean-table').submit(function() {
421
  ewww_total_pages = Math.ceil(ewww_vars.image_count / 500);
422
  $('.ewww-tool-info').hide();
includes/eio.js CHANGED
@@ -248,13 +248,15 @@ jQuery(document).ready(function($) {
248
  });
249
  });
250
  var ewwwdelayinput = document.getElementById("ewww-delay");
251
- ewwwdelayinput.onblur = function() {
252
- if (isNaN(this.value)) {
253
- this.value = 0;
254
- } else {
255
- this.value = Math.ceil(this.value);
256
- }
257
- };
 
 
258
  var ewww_attachments = ewww_vars.attachments;
259
  var ewww_i = 0;
260
  var ewww_k = 0;
248
  });
249
  });
250
  var ewwwdelayinput = document.getElementById("ewww-delay");
251
+ if (ewwwdelayinput) {
252
+ ewwwdelayinput.onblur = function() {
253
+ if (isNaN(this.value)) {
254
+ this.value = 0;
255
+ } else {
256
+ this.value = Math.ceil(this.value);
257
+ }
258
+ };
259
+ }
260
  var ewww_attachments = ewww_vars.attachments;
261
  var ewww_i = 0;
262
  var ewww_k = 0;
includes/load_webp.js CHANGED
@@ -508,11 +508,16 @@ function ewwwLoadImages(ewww_webp_supported) {
508
  'usemap',
509
  'vspace',
510
  'width',
 
511
  'data-attachment-id',
 
512
  'data-caption',
513
  'data-comments-opened',
 
514
  'data-event-trigger',
 
515
  'data-height',
 
516
  'data-highlight-color',
517
  'data-highlight-border-color',
518
  'data-highlight-border-opacity',
@@ -521,18 +526,32 @@ function ewwwLoadImages(ewww_webp_supported) {
521
  'data-image-meta',
522
  'data-image-title',
523
  'data-image-description',
 
524
  'data-large_image_width',
525
  'data-large_image_height',
526
  'data-lazy',
527
  'data-lazy-type',
 
 
528
  'data-no-lazy',
529
  'data-orig-size',
 
 
530
  'data-permalink',
531
  'data-pin-description',
532
  'data-pin-id',
533
  'data-pin-media',
534
  'data-pin-url',
 
 
 
 
 
 
 
 
535
  'data-width',
 
536
  ];
537
  for (var i = 0, len = attrs.length; i < len; i++) {
538
  ewwwAttr(ewww_img, attrs[i], ewww_nscript.getAttribute(attr_prefix + attrs[i]));
508
  'usemap',
509
  'vspace',
510
  'width',
511
+ 'data-animation',
512
  'data-attachment-id',
513
+ 'data-auto-height',
514
  'data-caption',
515
  'data-comments-opened',
516
+ 'data-delay',
517
  'data-event-trigger',
518
+ 'data-flex_fx',
519
  'data-height',
520
+ 'data-hide-on-end',
521
  'data-highlight-color',
522
  'data-highlight-border-color',
523
  'data-highlight-border-opacity',
526
  'data-image-meta',
527
  'data-image-title',
528
  'data-image-description',
529
+ 'data-interval',
530
  'data-large_image_width',
531
  'data-large_image_height',
532
  'data-lazy',
533
  'data-lazy-type',
534
+ 'data-mode',
535
+ 'data-name',
536
  'data-no-lazy',
537
  'data-orig-size',
538
+ 'data-partial',
539
+ 'data-per-view',
540
  'data-permalink',
541
  'data-pin-description',
542
  'data-pin-id',
543
  'data-pin-media',
544
  'data-pin-url',
545
+ 'data-rel',
546
+ 'data-ride',
547
+ 'data-shadow',
548
+ 'data-shadow-direction',
549
+ 'data-slide',
550
+ 'data-slide-to',
551
+ 'data-target',
552
+ 'data-vc-zoom',
553
  'data-width',
554
+ 'data-wrap',
555
  ];
556
  for (var i = 0, len = attrs.length; i < len; i++) {
557
  ewwwAttr(ewww_img, attrs[i], ewww_nscript.getAttribute(attr_prefix + attrs[i]));
includes/load_webp.min.js CHANGED
@@ -1 +1 @@
1
- var Arrive=function(d,e,c){"use strict";if(d.MutationObserver&&"undefined"!=typeof HTMLElement){var a,t,r=0,u=(a=HTMLElement.prototype.matches||HTMLElement.prototype.webkitMatchesSelector||HTMLElement.prototype.mozMatchesSelector||HTMLElement.prototype.msMatchesSelector,{matchesSelector:function(e,t){return e instanceof HTMLElement&&a.call(e,t)},addMethod:function(e,t,a){var r=e[t];e[t]=function(){return a.length==arguments.length?a.apply(this,arguments):"function"==typeof r?r.apply(this,arguments):void 0}},callCallbacks:function(e,t){t&&t.options.onceOnly&&1==t.firedElems.length&&(e=[e[0]]);for(var a,r=0;a=e[r];r++)a&&a.callback&&a.callback.call(a.elem,a.elem);t&&t.options.onceOnly&&1==t.firedElems.length&&t.me.unbindEventWithSelectorAndCallback.call(t.target,t.selector,t.callback)},checkChildNodesRecursively:function(e,t,a,r){for(var i,n=0;i=e[n];n++)a(i,t,r)&&r.push({callback:t.callback,elem:i}),0<i.childNodes.length&&u.checkChildNodesRecursively(i.childNodes,t,a,r)},mergeArrays:function(e,t){var a,r={};for(a in e)e.hasOwnProperty(a)&&(r[a]=e[a]);for(a in t)t.hasOwnProperty(a)&&(r[a]=t[a]);return r},toElementsArray:function(e){return void 0===e||"number"==typeof e.length&&e!==d||(e=[e]),e}}),w=((t=function(){this._eventsBucket=[],this._beforeAdding=null,this._beforeRemoving=null}).prototype.addEvent=function(e,t,a,r){var i={target:e,selector:t,options:a,callback:r,firedElems:[]};return this._beforeAdding&&this._beforeAdding(i),this._eventsBucket.push(i),i},t.prototype.removeEvent=function(e){for(var t,a=this._eventsBucket.length-1;t=this._eventsBucket[a];a--)if(e(t)){this._beforeRemoving&&this._beforeRemoving(t);var r=this._eventsBucket.splice(a,1);r&&r.length&&(r[0].callback=null)}},t.prototype.beforeAdding=function(e){this._beforeAdding=e},t.prototype.beforeRemoving=function(e){this._beforeRemoving=e},t),l=function(i,n){var l=new w,o=this,s={fireOnAttributesModification:!1};return l.beforeAdding(function(t){var e,a=t.target;a!==d.document&&a!==d||(a=document.getElementsByTagName("html")[0]),e=new MutationObserver(function(e){n.call(this,e,t)});var r=i(t.options);e.observe(a,r),t.observer=e,t.me=o}),l.beforeRemoving(function(e){e.observer.disconnect()}),this.bindEvent=function(e,t,a){t=u.mergeArrays(s,t);for(var r=u.toElementsArray(this),i=0;i<r.length;i++)l.addEvent(r[i],e,t,a)},this.unbindEvent=function(){var a=u.toElementsArray(this);l.removeEvent(function(e){for(var t=0;t<a.length;t++)if(this===c||e.target===a[t])return!0;return!1})},this.unbindEventWithSelectorOrCallback=function(a){var e,r=u.toElementsArray(this),i=a;e="function"==typeof a?function(e){for(var t=0;t<r.length;t++)if((this===c||e.target===r[t])&&e.callback===i)return!0;return!1}:function(e){for(var t=0;t<r.length;t++)if((this===c||e.target===r[t])&&e.selector===a)return!0;return!1},l.removeEvent(e)},this.unbindEventWithSelectorAndCallback=function(a,r){var i=u.toElementsArray(this);l.removeEvent(function(e){for(var t=0;t<i.length;t++)if((this===c||e.target===i[t])&&e.selector===a&&e.callback===r)return!0;return!1})},this},i=new function(){var s={fireOnAttributesModification:!1,onceOnly:!1,existing:!1};function n(e,t,a){return!(!u.matchesSelector(e,t.selector)||(e._id===c&&(e._id=r++),-1!=t.firedElems.indexOf(e._id))||(t.firedElems.push(e._id),0))}var d=(i=new l(function(e){var t={attributes:!1,childList:!0,subtree:!0};return e.fireOnAttributesModification&&(t.attributes=!0),t},function(e,i){e.forEach(function(e){var t=e.addedNodes,a=e.target,r=[];null!==t&&0<t.length?u.checkChildNodesRecursively(t,i,n,r):"attributes"===e.type&&n(a,i)&&r.push({callback:i.callback,elem:a}),u.callCallbacks(r,i)})})).bindEvent;return i.bindEvent=function(e,t,a){t=void 0===a?(a=t,s):u.mergeArrays(s,t);var r=u.toElementsArray(this);if(t.existing){for(var i=[],n=0;n<r.length;n++)for(var l=r[n].querySelectorAll(e),o=0;o<l.length;o++)i.push({callback:a,elem:l[o]});if(t.onceOnly&&i.length)return a.call(i[0].elem,i[0].elem);setTimeout(u.callCallbacks,1,i)}d.call(this,e,t,a)},i},o=new function(){var r={};function i(e,t){return u.matchesSelector(e,t.selector)}var n=(o=new l(function(){return{childList:!0,subtree:!0}},function(e,r){e.forEach(function(e){var t=e.removedNodes,a=[];null!==t&&0<t.length&&u.checkChildNodesRecursively(t,r,i,a),u.callCallbacks(a,r)})})).bindEvent;return o.bindEvent=function(e,t,a){t=void 0===a?(a=t,r):u.mergeArrays(r,t),n.call(this,e,t,a)},o};e&&g(e.fn),g(HTMLElement.prototype),g(NodeList.prototype),g(HTMLCollection.prototype),g(HTMLDocument.prototype),g(Window.prototype);var n={};return s(i,n,"unbindAllArrive"),s(o,n,"unbindAllLeave"),n}function s(e,t,a){u.addMethod(t,a,e.unbindEvent),u.addMethod(t,a,e.unbindEventWithSelectorOrCallback),u.addMethod(t,a,e.unbindEventWithSelectorAndCallback)}function g(e){e.arrive=i.bindEvent,s(i,e,"unbindArrive"),e.leave=o.bindEvent,s(o,e,"unbindLeave")}}(window,"undefined"==typeof jQuery?null:jQuery,void 0);function check_webp_feature(e,t){var a=new Image;a.onload=function(){var e=0<a.width&&0<a.height;t(e)},a.onerror=function(){t(!1)},a.src="data:image/webp;base64,"+{alpha:"UklGRkoAAABXRUJQVlA4WAoAAAAQAAAAAAAAAAAAQUxQSAwAAAARBxAR/Q9ERP8DAABWUDggGAAAABQBAJ0BKgEAAQAAAP4AAA3AAP7mtQAAAA==",animation:"UklGRlIAAABXRUJQVlA4WAoAAAASAAAAAAAAAAAAQU5JTQYAAAD/////AABBTk1GJgAAAAAAAAAAAAAAAAAAAGQAAABWUDhMDQAAAC8AAAAQBxAREYiI/gcA"}[e]}function ewwwLoadImages(e){var n="data-";function t(e,t){for(var a=["accesskey","align","alt","border","class","contenteditable","contextmenu","crossorigin","dir","draggable","dropzone","height","hidden","hspace","id","ismap","lang","longdesc","sizes","spellcheck","style","tabindex","title","translate","usemap","vspace","width","data-attachment-id","data-caption","data-comments-opened","data-event-trigger","data-height","data-highlight-color","data-highlight-border-color","data-highlight-border-opacity","data-highlight-border-width","data-highlight-opacity","data-image-meta","data-image-title","data-image-description","data-large_image_width","data-large_image_height","data-lazy","data-lazy-type","data-no-lazy","data-orig-size","data-permalink","data-pin-description","data-pin-id","data-pin-media","data-pin-url","data-width"],r=0,i=a.length;r<i;r++)ewwwAttr(t,a[r],e.getAttribute(n+a[r]));return t}if(e){for(var a=document.querySelectorAll(".batch-image img, .image-wrapper a, .ngg-pro-masonry-item a, .ngg-galleria-offscreen-seo-wrapper a"),r=0,i=a.length;r<i;r++)ewwwAttr(a[r],"data-src",a[r].getAttribute("data-webp")),ewwwAttr(a[r],"data-thumbnail",a[r].getAttribute("data-webp-thumbnail"));for(r=0,i=(o=document.querySelectorAll(".rev_slider ul li")).length;r<i;r++){ewwwAttr(o[r],"data-thumb",o[r].getAttribute("data-webp-thumb"));for(var l=1;l<11;)ewwwAttr(o[r],"data-param"+l,o[r].getAttribute("data-webp-param"+l)),l++}var o;for(r=0,i=(o=document.querySelectorAll(".rev_slider img")).length;r<i;r++)ewwwAttr(o[r],"data-lazyload",o[r].getAttribute("data-webp-lazyload"));var s=document.querySelectorAll("div.woocommerce-product-gallery__image");for(r=0,i=s.length;r<i;r++)ewwwAttr(s[r],"data-thumb",s[r].getAttribute("data-webp-thumb"))}var d=document.querySelectorAll("video");for(r=0,i=d.length;r<i;r++)ewwwAttr(d[r],"poster",e?d[r].getAttribute("data-poster-webp"):d[r].getAttribute("data-poster-image"));var c=document.querySelectorAll("img.ewww_webp_lazy_load");for(r=0,i=c.length;r<i;r++){if(e){ewwwAttr(c[r],"data-lazy-srcset",c[r].getAttribute("data-lazy-srcset-webp")),ewwwAttr(c[r],"data-srcset",c[r].getAttribute("data-srcset-webp")),ewwwAttr(c[r],"data-lazy-src",c[r].getAttribute("data-lazy-src-webp")),ewwwAttr(c[r],"data-src",c[r].getAttribute("data-src-webp")),ewwwAttr(c[r],"data-orig-file",c[r].getAttribute("data-webp-orig-file")),ewwwAttr(c[r],"data-medium-file",c[r].getAttribute("data-webp-medium-file")),ewwwAttr(c[r],"data-large-file",c[r].getAttribute("data-webp-large-file"));var u=c[r].getAttribute("srcset");null!=u&&!1!==u&&u.includes("R0lGOD")&&ewwwAttr(c[r],"src",c[r].getAttribute("data-lazy-src-webp"))}c[r].className=c[r].className.replace(/\bewww_webp_lazy_load\b/,"")}var w=document.querySelectorAll(".ewww_webp");for(r=0,i=w.length;r<i;r++){var g=document.createElement("img");e?(ewwwAttr(g,"src",w[r].getAttribute("data-webp")),ewwwAttr(g,"srcset",w[r].getAttribute("data-srcset-webp")),ewwwAttr(g,"data-orig-file",w[r].getAttribute("data-orig-file")),ewwwAttr(g,"data-orig-file",w[r].getAttribute("data-webp-orig-file")),ewwwAttr(g,"data-medium-file",w[r].getAttribute("data-medium-file")),ewwwAttr(g,"data-medium-file",w[r].getAttribute("data-webp-medium-file")),ewwwAttr(g,"data-large-file",w[r].getAttribute("data-large-file")),ewwwAttr(g,"data-large-file",w[r].getAttribute("data-webp-large-file")),ewwwAttr(g,"data-large_image",w[r].getAttribute("data-large_image")),ewwwAttr(g,"data-large_image",w[r].getAttribute("data-webp-large_image")),ewwwAttr(g,"data-src",w[r].getAttribute("data-src")),ewwwAttr(g,"data-src",w[r].getAttribute("data-webp-src"))):(ewwwAttr(g,"src",w[r].getAttribute("data-img")),ewwwAttr(g,"srcset",w[r].getAttribute("data-srcset-img")),ewwwAttr(g,"data-orig-file",w[r].getAttribute("data-orig-file")),ewwwAttr(g,"data-medium-file",w[r].getAttribute("data-medium-file")),ewwwAttr(g,"data-large-file",w[r].getAttribute("data-large-file")),ewwwAttr(g,"data-large_image",w[r].getAttribute("data-large_image")),ewwwAttr(g,"data-src",w[r].getAttribute("data-src"))),g=t(w[r],g),w[r].parentNode.insertBefore(g,w[r].nextSibling),w[r].className=w[r].className.replace(/\bewww_webp\b/,"")}window.jQuery&&jQuery.fn.isotope&&jQuery.fn.imagesLoaded&&(jQuery(".fusion-posts-container-infinite").imagesLoaded(function(){jQuery(".fusion-posts-container-infinite").hasClass("isotope")&&jQuery(".fusion-posts-container-infinite").isotope()}),jQuery(".fusion-portfolio:not(.fusion-recent-works) .fusion-portfolio-wrapper").imagesLoaded(function(){jQuery(".fusion-portfolio:not(.fusion-recent-works) .fusion-portfolio-wrapper").isotope()}))}function ewwwWebPInit(e){ewwwLoadImages(e),ewwwNggLoadGalleries(e),document.arrive(".ewww_webp",function(){ewwwLoadImages(e)}),document.arrive(".ewww_webp_lazy_load",function(){ewwwLoadImages(e)});var t=0,a=setInterval(function(){"undefined"!=typeof galleries&&(ewwwNggParseGalleries(e),clearInterval(a)),1e3<(t+=25)&&clearInterval(a)},25)}function ewwwAttr(e,t,a){null!=a&&!1!==a&&e.setAttribute(t,a)}function ewwwNggParseGalleries(e){if(e)for(var t in galleries){var a=galleries[t];galleries[t].images_list=ewwwNggParseImageList(a.images_list)}}function ewwwNggLoadGalleries(e){e&&document.addEventListener("ngg.galleria.themeadded",function(e,t){window.ngg_galleria._create_backup=window.ngg_galleria.create,window.ngg_galleria.create=function(e,t){var a=$(e).data("id");return galleries["gallery_"+a].images_list=ewwwNggParseImageList(galleries["gallery_"+a].images_list),window.ngg_galleria._create_backup(e,t)}})}function ewwwNggParseImageList(e){for(var t in e){var a=e[t];if(void 0!==a["image-webp"]&&(e[t].image=a["image-webp"],delete e[t]["image-webp"]),void 0!==a["thumb-webp"]&&(e[t].thumb=a["thumb-webp"],delete e[t]["thumb-webp"]),void 0!==a.full_image_webp&&(e[t].full_image=a.full_image_webp,delete e[t].full_image_webp),void 0!==a.srcsets)for(var r in a.srcsets)nggSrcset=a.srcsets[r],void 0!==a.srcsets[r+"-webp"]&&(e[t].srcsets[r]=a.srcsets[r+"-webp"],delete e[t].srcsets[r+"-webp"]);if(void 0!==a.full_srcsets)for(var i in a.full_srcsets)nggFSrcset=a.full_srcsets[i],void 0!==a.full_srcsets[i+"-webp"]&&(e[t].full_srcsets[i]=a.full_srcsets[i+"-webp"],delete e[t].full_srcsets[i+"-webp"])}return e}check_webp_feature("alpha",ewwwWebPInit);
1
+ var Arrive=function(s,e,c){"use strict";if(s.MutationObserver&&"undefined"!=typeof HTMLElement){var a,t,r=0,u=(a=HTMLElement.prototype.matches||HTMLElement.prototype.webkitMatchesSelector||HTMLElement.prototype.mozMatchesSelector||HTMLElement.prototype.msMatchesSelector,{matchesSelector:function(e,t){return e instanceof HTMLElement&&a.call(e,t)},addMethod:function(e,t,a){var r=e[t];e[t]=function(){return a.length==arguments.length?a.apply(this,arguments):"function"==typeof r?r.apply(this,arguments):void 0}},callCallbacks:function(e,t){t&&t.options.onceOnly&&1==t.firedElems.length&&(e=[e[0]]);for(var a,r=0;a=e[r];r++)a&&a.callback&&a.callback.call(a.elem,a.elem);t&&t.options.onceOnly&&1==t.firedElems.length&&t.me.unbindEventWithSelectorAndCallback.call(t.target,t.selector,t.callback)},checkChildNodesRecursively:function(e,t,a,r){for(var i,n=0;i=e[n];n++)a(i,t,r)&&r.push({callback:t.callback,elem:i}),0<i.childNodes.length&&u.checkChildNodesRecursively(i.childNodes,t,a,r)},mergeArrays:function(e,t){var a,r={};for(a in e)e.hasOwnProperty(a)&&(r[a]=e[a]);for(a in t)t.hasOwnProperty(a)&&(r[a]=t[a]);return r},toElementsArray:function(e){return void 0===e||"number"==typeof e.length&&e!==s||(e=[e]),e}}),w=((t=function(){this._eventsBucket=[],this._beforeAdding=null,this._beforeRemoving=null}).prototype.addEvent=function(e,t,a,r){var i={target:e,selector:t,options:a,callback:r,firedElems:[]};return this._beforeAdding&&this._beforeAdding(i),this._eventsBucket.push(i),i},t.prototype.removeEvent=function(e){for(var t,a=this._eventsBucket.length-1;t=this._eventsBucket[a];a--)if(e(t)){this._beforeRemoving&&this._beforeRemoving(t);var r=this._eventsBucket.splice(a,1);r&&r.length&&(r[0].callback=null)}},t.prototype.beforeAdding=function(e){this._beforeAdding=e},t.prototype.beforeRemoving=function(e){this._beforeRemoving=e},t),l=function(i,n){var l=new w,o=this,d={fireOnAttributesModification:!1};return l.beforeAdding(function(t){var e,a=t.target;a!==s.document&&a!==s||(a=document.getElementsByTagName("html")[0]),e=new MutationObserver(function(e){n.call(this,e,t)});var r=i(t.options);e.observe(a,r),t.observer=e,t.me=o}),l.beforeRemoving(function(e){e.observer.disconnect()}),this.bindEvent=function(e,t,a){t=u.mergeArrays(d,t);for(var r=u.toElementsArray(this),i=0;i<r.length;i++)l.addEvent(r[i],e,t,a)},this.unbindEvent=function(){var a=u.toElementsArray(this);l.removeEvent(function(e){for(var t=0;t<a.length;t++)if(this===c||e.target===a[t])return!0;return!1})},this.unbindEventWithSelectorOrCallback=function(a){var e,r=u.toElementsArray(this),i=a;e="function"==typeof a?function(e){for(var t=0;t<r.length;t++)if((this===c||e.target===r[t])&&e.callback===i)return!0;return!1}:function(e){for(var t=0;t<r.length;t++)if((this===c||e.target===r[t])&&e.selector===a)return!0;return!1},l.removeEvent(e)},this.unbindEventWithSelectorAndCallback=function(a,r){var i=u.toElementsArray(this);l.removeEvent(function(e){for(var t=0;t<i.length;t++)if((this===c||e.target===i[t])&&e.selector===a&&e.callback===r)return!0;return!1})},this},i=new function(){var d={fireOnAttributesModification:!1,onceOnly:!1,existing:!1};function n(e,t,a){return!(!u.matchesSelector(e,t.selector)||(e._id===c&&(e._id=r++),-1!=t.firedElems.indexOf(e._id))||(t.firedElems.push(e._id),0))}var s=(i=new l(function(e){var t={attributes:!1,childList:!0,subtree:!0};return e.fireOnAttributesModification&&(t.attributes=!0),t},function(e,i){e.forEach(function(e){var t=e.addedNodes,a=e.target,r=[];null!==t&&0<t.length?u.checkChildNodesRecursively(t,i,n,r):"attributes"===e.type&&n(a,i)&&r.push({callback:i.callback,elem:a}),u.callCallbacks(r,i)})})).bindEvent;return i.bindEvent=function(e,t,a){t=void 0===a?(a=t,d):u.mergeArrays(d,t);var r=u.toElementsArray(this);if(t.existing){for(var i=[],n=0;n<r.length;n++)for(var l=r[n].querySelectorAll(e),o=0;o<l.length;o++)i.push({callback:a,elem:l[o]});if(t.onceOnly&&i.length)return a.call(i[0].elem,i[0].elem);setTimeout(u.callCallbacks,1,i)}s.call(this,e,t,a)},i},o=new function(){var r={};function i(e,t){return u.matchesSelector(e,t.selector)}var n=(o=new l(function(){return{childList:!0,subtree:!0}},function(e,r){e.forEach(function(e){var t=e.removedNodes,a=[];null!==t&&0<t.length&&u.checkChildNodesRecursively(t,r,i,a),u.callCallbacks(a,r)})})).bindEvent;return o.bindEvent=function(e,t,a){t=void 0===a?(a=t,r):u.mergeArrays(r,t),n.call(this,e,t,a)},o};e&&g(e.fn),g(HTMLElement.prototype),g(NodeList.prototype),g(HTMLCollection.prototype),g(HTMLDocument.prototype),g(Window.prototype);var n={};return d(i,n,"unbindAllArrive"),d(o,n,"unbindAllLeave"),n}function d(e,t,a){u.addMethod(t,a,e.unbindEvent),u.addMethod(t,a,e.unbindEventWithSelectorOrCallback),u.addMethod(t,a,e.unbindEventWithSelectorAndCallback)}function g(e){e.arrive=i.bindEvent,d(i,e,"unbindArrive"),e.leave=o.bindEvent,d(o,e,"unbindLeave")}}(window,"undefined"==typeof jQuery?null:jQuery,void 0);function check_webp_feature(e,t){var a=new Image;a.onload=function(){var e=0<a.width&&0<a.height;t(e)},a.onerror=function(){t(!1)},a.src="data:image/webp;base64,"+{alpha:"UklGRkoAAABXRUJQVlA4WAoAAAAQAAAAAAAAAAAAQUxQSAwAAAARBxAR/Q9ERP8DAABWUDggGAAAABQBAJ0BKgEAAQAAAP4AAA3AAP7mtQAAAA==",animation:"UklGRlIAAABXRUJQVlA4WAoAAAASAAAAAAAAAAAAQU5JTQYAAAD/////AABBTk1GJgAAAAAAAAAAAAAAAAAAAGQAAABWUDhMDQAAAC8AAAAQBxAREYiI/gcA"}[e]}function ewwwLoadImages(e){var n="data-";function t(e,t){for(var a=["accesskey","align","alt","border","class","contenteditable","contextmenu","crossorigin","dir","draggable","dropzone","height","hidden","hspace","id","ismap","lang","longdesc","sizes","spellcheck","style","tabindex","title","translate","usemap","vspace","width","data-animation","data-attachment-id","data-auto-height","data-caption","data-comments-opened","data-delay","data-event-trigger","data-flex_fx","data-height","data-hide-on-end","data-highlight-color","data-highlight-border-color","data-highlight-border-opacity","data-highlight-border-width","data-highlight-opacity","data-image-meta","data-image-title","data-image-description","data-interval","data-large_image_width","data-large_image_height","data-lazy","data-lazy-type","data-mode","data-name","data-no-lazy","data-orig-size","data-partial","data-per-view","data-permalink","data-pin-description","data-pin-id","data-pin-media","data-pin-url","data-rel","data-ride","data-shadow","data-shadow-direction","data-slide","data-slide-to","data-target","data-vc-zoom","data-width","data-wrap"],r=0,i=a.length;r<i;r++)ewwwAttr(t,a[r],e.getAttribute(n+a[r]));return t}if(e){for(var a=document.querySelectorAll(".batch-image img, .image-wrapper a, .ngg-pro-masonry-item a, .ngg-galleria-offscreen-seo-wrapper a"),r=0,i=a.length;r<i;r++)ewwwAttr(a[r],"data-src",a[r].getAttribute("data-webp")),ewwwAttr(a[r],"data-thumbnail",a[r].getAttribute("data-webp-thumbnail"));for(r=0,i=(o=document.querySelectorAll(".rev_slider ul li")).length;r<i;r++){ewwwAttr(o[r],"data-thumb",o[r].getAttribute("data-webp-thumb"));for(var l=1;l<11;)ewwwAttr(o[r],"data-param"+l,o[r].getAttribute("data-webp-param"+l)),l++}var o;for(r=0,i=(o=document.querySelectorAll(".rev_slider img")).length;r<i;r++)ewwwAttr(o[r],"data-lazyload",o[r].getAttribute("data-webp-lazyload"));var d=document.querySelectorAll("div.woocommerce-product-gallery__image");for(r=0,i=d.length;r<i;r++)ewwwAttr(d[r],"data-thumb",d[r].getAttribute("data-webp-thumb"))}var s=document.querySelectorAll("video");for(r=0,i=s.length;r<i;r++)ewwwAttr(s[r],"poster",e?s[r].getAttribute("data-poster-webp"):s[r].getAttribute("data-poster-image"));var c=document.querySelectorAll("img.ewww_webp_lazy_load");for(r=0,i=c.length;r<i;r++){if(e){ewwwAttr(c[r],"data-lazy-srcset",c[r].getAttribute("data-lazy-srcset-webp")),ewwwAttr(c[r],"data-srcset",c[r].getAttribute("data-srcset-webp")),ewwwAttr(c[r],"data-lazy-src",c[r].getAttribute("data-lazy-src-webp")),ewwwAttr(c[r],"data-src",c[r].getAttribute("data-src-webp")),ewwwAttr(c[r],"data-orig-file",c[r].getAttribute("data-webp-orig-file")),ewwwAttr(c[r],"data-medium-file",c[r].getAttribute("data-webp-medium-file")),ewwwAttr(c[r],"data-large-file",c[r].getAttribute("data-webp-large-file"));var u=c[r].getAttribute("srcset");null!=u&&!1!==u&&u.includes("R0lGOD")&&ewwwAttr(c[r],"src",c[r].getAttribute("data-lazy-src-webp"))}c[r].className=c[r].className.replace(/\bewww_webp_lazy_load\b/,"")}var w=document.querySelectorAll(".ewww_webp");for(r=0,i=w.length;r<i;r++){var g=document.createElement("img");e?(ewwwAttr(g,"src",w[r].getAttribute("data-webp")),ewwwAttr(g,"srcset",w[r].getAttribute("data-srcset-webp")),ewwwAttr(g,"data-orig-file",w[r].getAttribute("data-orig-file")),ewwwAttr(g,"data-orig-file",w[r].getAttribute("data-webp-orig-file")),ewwwAttr(g,"data-medium-file",w[r].getAttribute("data-medium-file")),ewwwAttr(g,"data-medium-file",w[r].getAttribute("data-webp-medium-file")),ewwwAttr(g,"data-large-file",w[r].getAttribute("data-large-file")),ewwwAttr(g,"data-large-file",w[r].getAttribute("data-webp-large-file")),ewwwAttr(g,"data-large_image",w[r].getAttribute("data-large_image")),ewwwAttr(g,"data-large_image",w[r].getAttribute("data-webp-large_image")),ewwwAttr(g,"data-src",w[r].getAttribute("data-src")),ewwwAttr(g,"data-src",w[r].getAttribute("data-webp-src"))):(ewwwAttr(g,"src",w[r].getAttribute("data-img")),ewwwAttr(g,"srcset",w[r].getAttribute("data-srcset-img")),ewwwAttr(g,"data-orig-file",w[r].getAttribute("data-orig-file")),ewwwAttr(g,"data-medium-file",w[r].getAttribute("data-medium-file")),ewwwAttr(g,"data-large-file",w[r].getAttribute("data-large-file")),ewwwAttr(g,"data-large_image",w[r].getAttribute("data-large_image")),ewwwAttr(g,"data-src",w[r].getAttribute("data-src"))),g=t(w[r],g),w[r].parentNode.insertBefore(g,w[r].nextSibling),w[r].className=w[r].className.replace(/\bewww_webp\b/,"")}window.jQuery&&jQuery.fn.isotope&&jQuery.fn.imagesLoaded&&(jQuery(".fusion-posts-container-infinite").imagesLoaded(function(){jQuery(".fusion-posts-container-infinite").hasClass("isotope")&&jQuery(".fusion-posts-container-infinite").isotope()}),jQuery(".fusion-portfolio:not(.fusion-recent-works) .fusion-portfolio-wrapper").imagesLoaded(function(){jQuery(".fusion-portfolio:not(.fusion-recent-works) .fusion-portfolio-wrapper").isotope()}))}function ewwwWebPInit(e){ewwwLoadImages(e),ewwwNggLoadGalleries(e),document.arrive(".ewww_webp",function(){ewwwLoadImages(e)}),document.arrive(".ewww_webp_lazy_load",function(){ewwwLoadImages(e)});var t=0,a=setInterval(function(){"undefined"!=typeof galleries&&(ewwwNggParseGalleries(e),clearInterval(a)),1e3<(t+=25)&&clearInterval(a)},25)}function ewwwAttr(e,t,a){null!=a&&!1!==a&&e.setAttribute(t,a)}function ewwwNggParseGalleries(e){if(e)for(var t in galleries){var a=galleries[t];galleries[t].images_list=ewwwNggParseImageList(a.images_list)}}function ewwwNggLoadGalleries(e){e&&document.addEventListener("ngg.galleria.themeadded",function(e,t){window.ngg_galleria._create_backup=window.ngg_galleria.create,window.ngg_galleria.create=function(e,t){var a=$(e).data("id");return galleries["gallery_"+a].images_list=ewwwNggParseImageList(galleries["gallery_"+a].images_list),window.ngg_galleria._create_backup(e,t)}})}function ewwwNggParseImageList(e){for(var t in e){var a=e[t];if(void 0!==a["image-webp"]&&(e[t].image=a["image-webp"],delete e[t]["image-webp"]),void 0!==a["thumb-webp"]&&(e[t].thumb=a["thumb-webp"],delete e[t]["thumb-webp"]),void 0!==a.full_image_webp&&(e[t].full_image=a.full_image_webp,delete e[t].full_image_webp),void 0!==a.srcsets)for(var r in a.srcsets)nggSrcset=a.srcsets[r],void 0!==a.srcsets[r+"-webp"]&&(e[t].srcsets[r]=a.srcsets[r+"-webp"],delete e[t].srcsets[r+"-webp"]);if(void 0!==a.full_srcsets)for(var i in a.full_srcsets)nggFSrcset=a.full_srcsets[i],void 0!==a.full_srcsets[i+"-webp"]&&(e[t].full_srcsets[i]=a.full_srcsets[i+"-webp"],delete e[t].full_srcsets[i+"-webp"])}return e}check_webp_feature("alpha",ewwwWebPInit);
readme.txt CHANGED
@@ -2,33 +2,33 @@
2
  Contributors: nosilver4u
3
  Donate link: https://ewww.io/donate/
4
  Tags: optimize, image, convert, webp, resize, compress, lazy load, optimization, lossless, lossy, seo, scale
5
- Requires at least: 5.1
6
  Tested up to: 5.5
7
  Requires PHP: 5.6
8
- Stable tag: 5.6.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.
12
 
13
  == Description ==
14
 
15
- The EWWW Image Optimizer will increase your page speeds by way of image optimization. Increased page speeds can result in better search engine rankings, and will also improve conversion rates (increased sales and signups). It will also save you storage space and bandwidth. While EWWW I.O. will automatically optimize new images that you upload, it can also optimize all the images that you have already uploaded, and optionally convert your images to the best file format. You can choose pixel perfect compression or high compression options that are visually lossless.
16
 
17
- EWWW I.O. will optimize images uploaded and created by any plugin, and features special integrations with many popular plugins, detailed below.
18
 
19
  **Why use EWWW Image Optimizer?**
20
 
21
  1. **No Speed Limits** and [unlimited file size](https://ewww.io/unlimited-file-size/).
22
  1. **Smooth Handling** with pixel-perfect optimization using industry-leading tools and progressive rendering.
23
- 1. **High Torque** as we bring you the best compression/quality ratio available with our lossy options for JPG, PNG, and PDF files.
24
- 1. **Adaptive Steering** with intelligent conversion options to get the right image format for the job (JPG, PNG, or GIF).
25
  1. **Free Parking** The core plugin is free and always will be. However, our paid services offer up to 80% compression, and a [host of other features](https://ewww.io/plans/)!
26
- 1. **Comprehensive Coverage:** no image gets left behind, optimize everything on your site, beyond just the WordPress Media Library.
27
  1. **Safety First:** all communications are secured with top SSL encryption.
28
  1. **Roadside Assistance:** top-notch support is in our DNA. While API customers get top priority, we answer [every single support question with care](https://ewww.io/contact-us/).
29
  1. **Pack a Spare:** free image backups store your original images for 30 days.
30
 
31
- Images can be optimized using tools on your own server for free (jpegtran, optipng, pngout, pngquant, gifsicle, cwebp), or can be optimized via specialized servers that utilize the best tools available in lossless or lossy mode. Our lossy compression uses unique algorithms to gain maximum compression while remaining visually lossless. Your images can even be converted to the most suitable file format using the appropriate options. Using the EWWW I.O. API will allow the plugin to work on any hosting platform, and can also be desirable if you cannot, or do not want to use the exec() function on your server, or prefer to offload the resource demands of optimization.
32
 
33
  = Automatic Everything =
34
 
@@ -36,78 +36,51 @@ With Easy IO, images are automatically compressed, scaled to fit the page and de
36
 
37
  = Support =
38
 
39
- If you need assistance using the plugin, please visit our [Support Page](https://ewww.io/contact-us/).
40
- The EWWW Image Optimizer is developed at https://github.com/nosilver4u/ewww-image-optimizer
 
41
 
42
  = Bulk Optimize =
43
 
44
- Optimize all your images from a single page using the Bulk Scanner. This includes the Media Library, your theme, and a handful of pre-configured folders (see Optimize Everything Else below). Officially supported galleries (GRAND FlaGallery, NextCellent and NextGEN) have their own Bulk Optimize pages.
45
 
46
  = Optimize Everything Else =
47
 
48
- Configure any folder within your WordPress folder to be optimized. The Bulk Scan under Media->Bulk Optimize will optimize theme images, BuddyPress avatars, BuddyPress Activity Plus images, Meta Slider slides, WP Symposium Pro avatars, GD bbPress attachments, Grand Media Galleries, and any user-specified folders. Additionally, this tool can run on an hourly basis via wp_cron to keep newly uploaded images optimized. Scheduled optimization should not be used for any plugin that uses the built-in Wordpress image functions.
49
 
50
- = Skips Previously Optimized Images =
51
 
52
- All optimized images are stored in the database so that the plugin does not attempt to re-optimize them unless they are modified. On the Bulk Optimize page you can view a list of already optimized images. You may also remove individual images from the list, or use the Force optimize option to override the default behavior. The re-optimize links on the Media Library page also force the plugin to ignore the previous optimization status of images.
53
-
54
- = WP Image Editor =
55
-
56
- All images created by the built-in WP_Image_Editor class will be automatically optimized. Current implementations are GD, Imagick, and Gmagick. Images optimized via this class include Animated GIF Resize, BuddyPress Activity Plus (thumbs), Easy Watermark, Hammy, Imsanity, MediaPress, Meta Slider, MyArcadePlugin, OTF Regenerate Thumbnails, Regenerate Thumbnails, Simple Image Sizes, WP Retina 2x, WP RSS Aggregator and probably countless others. If you are not sure if a plugin uses WP_Image_Editor, [just ask](https://ewww.io/contact-us/).
57
 
58
  = WebP Images =
59
 
60
- Automatic WebP conversion with Easy IO, no additional configuration. Otherwise, can generate WebP versions of your images, and enables you to serve even smaller images to supported browsers. Several methods are available for serving WebP images, including Apache-compatible rewrite rules and our JS WebP Rewriting option compatible with caches and CDNs. Also works with the WebP option in the Cache Enabler plugin from KeyCDN.
61
 
62
  = WP-CLI =
63
 
64
  Allows you to run all Bulk Optimization processes from your command line, instead of the web interface. It is much faster, and allows you to do things like run it in 'screen' or via regular cron (instead of wp-cron, which can be unpredictable on low-traffic sites). Install WP-CLI from wp-cli.org, and run 'wp-cli.phar help ewwwio optimize' for more information or see the [Docs](https://docs.ewww.io/article/25-optimizing-with-wp-cli).
65
 
66
- = FooGallery =
67
-
68
- All images uploaded and cached by FooGallery are automatically optimized. Previous uploads can be optimized by running the Media Library Bulk Optimize. Previously cached images can be optimized by entering the wp-content/uploads/cache/ folder under Folders to Optimize and running a Scan & Optimize from the Bulk Optimize page.
69
-
70
- = NextGEN Gallery =
71
-
72
- Features optimization on upload capability, re-optimization, and bulk optimizing. The NextGEN Bulk Optimize function is located near the bottom of the NextGEN menu, and will optimize all images in all galleries. It is also possible to optimize groups of images in a gallery, or multiple galleries at once.
73
-
74
- = NextCellent Gallery =
75
-
76
- Features all the same capability as NextGEN, and is the continuation of legacy (1.9.x) NextGEN support.
77
-
78
- = GRAND Flash Album Gallery =
79
-
80
- Features optimization on upload capability, re-optimization, and bulk optimizing. The Bulk Optimize function is located near the bottom of the FlAGallery menu, and will optimize all images in all galleries. It is also possible to optimize groups of images in a gallery, or multiple galleries at once.
81
-
82
- = Image Store =
83
-
84
- Uploads are automatically optimized. Look for Optimize under the Image Store (Galleries) menu to see status of optimization and for re-optimization and bulk-optimization options. Using the Bulk Optimization tool under Media Library automatically includes all Image Store uploads.
85
-
86
  = CDN Support =
87
 
88
- [WP Offload Media](https://wordpress.org/plugins/amazon-s3-and-cloudfront/) is the officially supported (and recommended) plugin for uploads to Amazon S3 and Digital Ocean Spaces. We also support the Azure Storage and Cloudinary plugins. All pull mode CDNs like Cloudflare, KeyCDN, MaxCDN, and Sucuri CloudProxy work automatically, but will require you to purge the cache after a bulk optimization.
89
-
90
- = WPML Compatible =
91
-
92
- Tested regularly to ensure compatibility with multilingual sites. Learn more at https://wpml.org/plugin/ewww-image-optimizer/
93
 
94
  = Translations =
95
 
96
- Huge thanks to all our translators! See the full list here: https://translate.wordpress.org/projects/wp-plugins/ewww-image-optimizer/contributors
97
 
98
- If you would like to help translate this plugin (new or existing translations), you can do so here: https://translate.wordpress.org/projects/wp-plugins/ewww-image-optimizer
99
- To receive updates when new strings are available for translation, you can signup here: https://ewww.io/register/
100
 
101
  == Installation ==
102
 
103
  1. Upload the "ewww-image-optimizer" plugin to your /wp-content/plugins/ directory.
104
  1. Activate the plugin through the 'Plugins' menu in WordPress.
105
  1. The plugin will attempt to install jpegtran, optipng, and gifsicle automatically for you. This requires that the wp-content folder is writable by the user running the web server.
106
- 1. If the binaries don't run locally, you can sign up for the EWWW IO cloud service to run them via our optimization servers: https://ewww.io/plans/
107
  1. *Recommended* Visit the settings page to enable/disable specific tools and turn on advanced optimization features.
108
  1. Done!
109
 
110
- If these steps do not work, additional documentation is available at https://docs.ewww.io/article/6-the-plugin-says-i-m-missing-something. If you need further assistance using the plugin, please visit our [Support Page](https://ewww.io/contact-us/).
111
 
112
  = Webhosts =
113
 
@@ -117,11 +90,11 @@ To find out if your webhost works with the EWWW Image Optimizer, you can check t
117
 
118
  = Google Pagespeed says my images need compressing or resizing, but I already optimized all my images. What do I do? =
119
 
120
- Try this for starters: https://docs.ewww.io/article/5-pagespeed-says-my-images-need-more-work
121
 
122
  = The plugin complains that I'm missing something, what do I do? =
123
 
124
- This article will walk you through installing the required tools (and the alternatives if installation does not work): https://docs.ewww.io/article/6-the-plugin-says-i-m-missing-something
125
 
126
  = Does the plugin replace existing images? =
127
 
@@ -133,32 +106,20 @@ Yes, you can, set it up on the Resize tab.
133
 
134
  = Can I lower the compression setting for JPGs to save more space? =
135
 
136
- The lossy JPG optimization using the API will determine the ideal quality setting and give you the best results, but you can also adjust the default quality for conversion and resizing. More information: https://docs.ewww.io/article/12-jpq-quality-and-wordpress
137
 
138
  = The bulk optimizer doesn't seem to be working, what can I do? =
139
 
140
- See https://docs.ewww.io/article/39-bulk-optimizer-failure for full troubleshooting instructions.
141
 
142
  = What are the supported operating systems? =
143
 
144
- I've tested it on Windows (with Apache), Linux, Mac OSX, FreeBSD 9, and Solaris (v10). The cloud API will work on any OS.
145
-
146
- = How are JPGs optimized? =
147
-
148
- Lossless optimization is done with the command *jpegtran -copy all -optimize -progressive -outfile optimized-file original-file*. Optionally, the -copy switch gets the 'none' parameter if you choose to strip metadata from your JPGs on the options page.
149
-
150
- = How are PNGs optimized? =
151
-
152
- There are three parts (and all are optional). First, using the command *pngquant original-file*, then using the commands *pngout-static -s2 original-file* and *optipng -o2 original-file*. You can adjust the optimization levels for both tools using the [Overrides](https://docs.ewww.io/article/40-override-options). Optipng is an automated derivative of pngcrush, which is another widely used png optimization utility.
153
-
154
- = How are GIFs optimized? =
155
-
156
- Using the command *gifsicle -b -O3 --careful original file*. This is particularly useful for animated GIFs, and can also streamline your color palette. That said, if your GIF is not animated, you should strongly consider converting it to a PNG. PNG files are almost always smaller, they just don't do animations. The following command would do this for you on a Linux system with imagemagick: *convert somefile.gif somefile.png*
157
 
158
  = I want to know more about image optimization, and why you chose these options/tools. =
159
 
160
  That's not a question, but since I made it up, I'll answer it. See this resource:
161
- https://developers.google.com/web/tools/lighthouse/audits/optimize-images
162
 
163
  == Screenshots ==
164
 
@@ -168,29 +129,28 @@ https://developers.google.com/web/tools/lighthouse/audits/optimize-images
168
 
169
  == Changelog ==
170
 
171
- * Feature requests can be viewed and submitted at https://feedback.ewww.io
172
- * 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/
173
-
174
- = 5.6.2 =
175
- * fixed: fatal error for undefined add_query_var
176
-
177
- = 5.6.1 =
178
- * changed: prevent unintentional image re-optimization from plugins with a threshold of 5x, indicate intential regen with ewww_image_optimizer_allowed_reopt filter
179
- * changed: include lazy load and WebP in optimization score
180
- * fixed: query paramaters added to videos via image_downsize filter
181
- * fixed: WP-CLI command triggers async queueing
182
- * fixed: WPML check skips too many images during bulk scanner
183
- * fixed: WP-CLI command options for FlAGallery and NextGEN using outdated code
184
- * fixed: re-optimization tracker not tracking
185
-
186
- = 5.6.0 =
187
- * added: if exec() is disabled, free cloud-based JPG compression will be enabled
188
- * added: tool to remove originals for converted images
189
- * changed: improved handling of WPML replicas in media library list mode and bulk optimizer
190
- * fixed: JS WebP, picture WebP, and Easy IO errors with WP Offload Media 2.4
191
- * fixed: JS WebP cannot find local paths when WP_CONTENT_DIR is outside ABSPATH
192
- * fixed: Easy IO hard crops images when requested height/width is 9999
193
- * fixed: Lazy Load and WebP parsers running on customizer preview pane
194
 
195
  = Earlier versions =
196
  Please refer to the separate changelog.txt file.
2
  Contributors: nosilver4u
3
  Donate link: https://ewww.io/donate/
4
  Tags: optimize, image, convert, webp, resize, compress, lazy load, optimization, lossless, lossy, seo, scale
5
+ Requires at least: 5.2
6
  Tested up to: 5.5
7
  Requires PHP: 5.6
8
+ Stable tag: 5.7.1
9
  License: GPLv3
10
 
11
+ Smaller Images, Faster Sites, Happier Visitors. Comprehensive image optimization that doesn't require a degree in rocket science.
12
 
13
  == Description ==
14
 
15
+ Are you frustrated by a slow website? Do over-sized images make you say "ewww"... Let EWWW Image Optimizer help you make your site faster, improve your bounce rate, and boost your SEO. But most importantly, make your visitors happier so they keep coming back for more.
16
 
17
+ With EWWW IO you can optimize all your existing images, [from any plugin](https://docs.ewww.io/article/84-plugin-compatibility), and then let EWWW IO take care of new image uploads automatically.
18
 
19
  **Why use EWWW Image Optimizer?**
20
 
21
  1. **No Speed Limits** and [unlimited file size](https://ewww.io/unlimited-file-size/).
22
  1. **Smooth Handling** with pixel-perfect optimization using industry-leading tools and progressive rendering.
23
+ 1. **High Torque** as we bring you the best compression/quality ratio available with our Premium compression for JPG, PNG, and PDF files.
24
+ 1. **Adaptive Steering** with intelligent conversion options to get the right image format for the job (JPG, PNG, GIF, or WebP).
25
  1. **Free Parking** The core plugin is free and always will be. However, our paid services offer up to 80% compression, and a [host of other features](https://ewww.io/plans/)!
26
+ 1. **Comprehensive Coverage:** no image gets left behind, optimize everything on your site, not just the WordPress Media Library.
27
  1. **Safety First:** all communications are secured with top SSL encryption.
28
  1. **Roadside Assistance:** top-notch support is in our DNA. While API customers get top priority, we answer [every single support question with care](https://ewww.io/contact-us/).
29
  1. **Pack a Spare:** free image backups store your original images for 30 days.
30
 
31
+ EWWW IO is the only plugin that lets you optimize images using tools on your own server (jpegtran, optipng, pngout, pngquant, gifsicle, cwebp). If you feel the need for more speed, get more compression and offload the CPU-intensive process of optimization to [our specialized servers](https://ewww.io/plans/).
32
 
33
  = Automatic Everything =
34
 
36
 
37
  = Support =
38
 
39
+ Stuck? Feeling like maybe you DO need that rocket science degree? [We provide free one-on-one email support to everyone](https://ewww.io/contact-us/).
40
+ Do you have an idea to make EWWW IO even better? [Share it and vote on future features](https://feedback.ewww.io/)!
41
+ Found a bug? Report the issue on [GitHub](https://github.com/nosilver4u/ewww-image-optimizer), and we'll get it fixed!
42
 
43
  = Bulk Optimize =
44
 
45
+ Optimize all your images from a single page. This includes the Media Library, your theme, and a handful of pre-configured folders (see Optimize Everything Else below). GRAND FlaGallery, NextCellent and NextGEN have their own Bulk Optimize pages.
46
 
47
  = Optimize Everything Else =
48
 
49
+ Configure any folder within your WordPress install to be optimized. The Bulk Optimizer will compress theme images, BuddyPress avatars, BuddyPress Activity Plus images, Meta Slider slides, WP Symposium Pro avatars, GD bbPress attachments, Grand Media Galleries, and any user-specified folders. You can also use Scheduled optimization or run the optimizer from WP-CLI if that's more your thing.
50
 
51
+ = Plugin Compatibility =
52
 
53
+ EWWW IO has been tested with hundreds (if not thousands) of [plugins and themes](https://docs.ewww.io/article/84-plugin-compatibility), here are just a few of the most common ones: BuddyPress (Activity Plus add-on too), Cloudinary, Easy Watermark, FooGallery, GD bbPress Attachments, GRAND FlAGallery, Gmedia Photo Gallery, MediaPress, Meta Slider, Microsoft Azure Storage, MyArcadePlugin, NextGEN Gallery, Regenerate Thumbnails, WP Offload Media, [WPML](https://wpml.org/plugin/ewww-image-optimizer/), WP Retina 2x, WP RSS Aggregator, WP Symposium. [Read more...](https://docs.ewww.io/article/84-plugin-compatibility)
 
 
 
 
54
 
55
  = WebP Images =
56
 
57
+ If you want simple, get automatic WebP conversion with Easy IO, and be done with it! Otherwise, you can generate WebP versions of your images with the Bulk Optimizer, and deliver them to supported browsers. Take your pick between Apache-style rewrite rules, JS WebP Rewriting, and <picture> WebP Rewriting. EWWW IO even works with the WebP option in the Cache Enabler plugin from KeyCDN.
58
 
59
  = WP-CLI =
60
 
61
  Allows you to run all Bulk Optimization processes from your command line, instead of the web interface. It is much faster, and allows you to do things like run it in 'screen' or via regular cron (instead of wp-cron, which can be unpredictable on low-traffic sites). Install WP-CLI from wp-cli.org, and run 'wp-cli.phar help ewwwio optimize' for more information or see the [Docs](https://docs.ewww.io/article/25-optimizing-with-wp-cli).
62
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
63
  = CDN Support =
64
 
65
+ [WP Offload Media](https://wordpress.org/plugins/amazon-s3-and-cloudfront/) is the officially supported (and recommended) plugin for uploads to Amazon S3, Digital Ocean Spaces, and Google Cloud Storage. [Check our compatibility list for details on other plugins](https://docs.ewww.io/article/84-plugin-compatibility). All pull mode CDNs like Cloudflare, KeyCDN, MaxCDN, and Sucuri CloudProxy work automatically, but will require you to purge the cache after a bulk optimization.
 
 
 
 
66
 
67
  = Translations =
68
 
69
+ Huge thanks to all our translators, [see the full list](https://translate.wordpress.org/projects/wp-plugins/ewww-image-optimizer/contributors)!
70
 
71
+ If you would like to help translate this plugin, [join the team](https://translate.wordpress.org/projects/wp-plugins/ewww-image-optimizer).
72
+ [Signup to receive updates when new strings are available for translation](https://ewww.io/register/).
73
 
74
  == Installation ==
75
 
76
  1. Upload the "ewww-image-optimizer" plugin to your /wp-content/plugins/ directory.
77
  1. Activate the plugin through the 'Plugins' menu in WordPress.
78
  1. The plugin will attempt to install jpegtran, optipng, and gifsicle automatically for you. This requires that the wp-content folder is writable by the user running the web server.
79
+ 1. If the binaries don't run locally, you may sign up for cloud-based optimization: https://ewww.io/plans/
80
  1. *Recommended* Visit the settings page to enable/disable specific tools and turn on advanced optimization features.
81
  1. Done!
82
 
83
+ If these steps do not work, [see the additional documentation](https://docs.ewww.io/article/6-the-plugin-says-i-m-missing-something). If you need further assistance using the plugin, please visit our [Support Page](https://ewww.io/contact-us/).
84
 
85
  = Webhosts =
86
 
90
 
91
  = Google Pagespeed says my images need compressing or resizing, but I already optimized all my images. What do I do? =
92
 
93
+ Try this for starters: [https://docs.ewww.io/article/5-pagespeed-says-my-images-need-more-work](https://docs.ewww.io/article/5-pagespeed-says-my-images-need-more-work)
94
 
95
  = The plugin complains that I'm missing something, what do I do? =
96
 
97
+ This article will walk you through installing the required tools (and the alternatives if installation does not work): [https://docs.ewww.io/article/6-the-plugin-says-i-m-missing-something](https://docs.ewww.io/article/6-the-plugin-says-i-m-missing-something)
98
 
99
  = Does the plugin replace existing images? =
100
 
106
 
107
  = Can I lower the compression setting for JPGs to save more space? =
108
 
109
+ Our premium compression can determine the ideal quality setting and give you the best results, but you may also adjust the default quality for conversion and resizing. [Read more...](https://docs.ewww.io/article/12-jpq-quality-and-wordpress)
110
 
111
  = The bulk optimizer doesn't seem to be working, what can I do? =
112
 
113
+ See [https://docs.ewww.io/article/39-bulk-optimizer-failure](https://docs.ewww.io/article/39-bulk-optimizer-failure) for full troubleshooting instructions.
114
 
115
  = What are the supported operating systems? =
116
 
117
+ I've tested it on Windows (with Apache), Linux, Mac OSX, FreeBSD, and Solaris. The cloud API will work on any OS.
 
 
 
 
 
 
 
 
 
 
 
 
118
 
119
  = I want to know more about image optimization, and why you chose these options/tools. =
120
 
121
  That's not a question, but since I made it up, I'll answer it. See this resource:
122
+ [https://developers.google.com/web/tools/lighthouse/audits/optimize-images](https://developers.google.com/web/tools/lighthouse/audits/optimize-images)
123
 
124
  == Screenshots ==
125
 
129
 
130
  == Changelog ==
131
 
132
+ * Feature requests can be viewed and submitted on our [feedback portal](https://feedback.ewww.io)
133
+ * If you would like to help translate this plugin in your language, [join the team](https://translate.wordpress.org/projects/wp-plugins/ewww-image-optimizer/)
134
+
135
+ = 5.7.1 =
136
+ * added: alert on domain change for Easy IO, like if you clone from a production environment to staging
137
+ * changed: Easy IO domain and plan_id refresh automatically when visiting settings page
138
+ * changed: better JS WebP and WPBakery Page Builder compatibility
139
+ * changed: restore savings gauge for network settings page
140
+ * fixed: resize detection visible for editors, should be admin-only
141
+ * fixed: (force) re-optimize not working with parallel mode
142
+ * fixed: upload error when WP cannot load image editor
143
+
144
+ = 5.7.0 =
145
+ * added: cleanup tool if you no longer need local WebP copies of images
146
+ * added: resizing results displayed in bulk & single optimization report
147
+ * changed: The browser-native portion of the Lazy Load feature obeys the wp_lazy_loading_enabled filter
148
+ * fixed: plugin tables do not have PRIMARY indexes
149
+ * fixed: Third-party plugins sometimes set erroneous WebP quality values
150
+ * fixed: Show Re-optimized Images lists images in reverse order
151
+ * fixed: cannot skip to last page of re-optimized images
152
+ * fixed: Scheduled Optimizer skips files that need scaling/resizing if they have already been compressed
153
+ * fixed: Lazy Load placeholders not rewritten for CDN usage by Autoptimize and WP Offload Media Assets Add-on
 
154
 
155
  = Earlier versions =
156
  Please refer to the separate changelog.txt file.
unique.php CHANGED
@@ -54,7 +54,8 @@ function ewww_image_optimizer_exec_init() {
54
  ! empty( $_ENV['PANTHEON_ENVIRONMENT'] ) ||
55
  defined( 'WPE_PLUGIN_VERSION' ) ||
56
  defined( 'FLYWHEEL_CONFIG_DIR' ) ||
57
- defined( 'KINSTAMU_VERSION' )
 
58
  ) {
59
  if (
60
  ! ewww_image_optimizer_get_option( 'ewww_image_optimizer_cloud_key' ) &&
@@ -170,6 +171,8 @@ function ewww_image_optimizer_notice_hosting_requires_api() {
170
  $webhost = 'Flywheel';
171
  } elseif ( defined( 'KINSTAMU_VERSION' ) ) {
172
  $webhost = 'Kinsta';
 
 
173
  } else {
174
  return;
175
  }
@@ -532,7 +535,7 @@ function ewww_image_optimizer_dismiss_exec_notice() {
532
  ewwwio_ob_clean();
533
  ewwwio_debug_message( '<b>' . __FUNCTION__ . '()</b>' );
534
  // Verify that the user is properly authorized.
535
- if ( ! current_user_can( apply_filters( 'ewww_image_optimizer_admin_permissions', 'manage_options' ) ) ) {
536
  wp_die( esc_html__( 'Access denied.', 'ewww-image-optimizer' ) );
537
  }
538
  update_option( 'ewww_image_optimizer_jpg_level', 10 );
@@ -2741,6 +2744,9 @@ function ewww_image_optimizer_webp_create( $file, $orig_size, $type, $tool, $rec
2741
  $copy_opt = 'all';
2742
  }
2743
  $quality = (int) apply_filters( 'jpeg_quality', 82, 'image/webp' );
 
 
 
2744
  if ( defined( 'EWWW_IMAGE_OPTIMIZER_LOSSY_PNG2WEBP' ) && EWWW_IMAGE_OPTIMIZER_LOSSY_PNG2WEBP ) {
2745
  $lossless = "-q $quality";
2746
  } else {
@@ -2748,9 +2754,11 @@ function ewww_image_optimizer_webp_create( $file, $orig_size, $type, $tool, $rec
2748
  }
2749
  switch ( $type ) {
2750
  case 'image/jpeg':
 
2751
  exec( "$nice " . $tool . " -q $quality -metadata $copy_opt -quiet " . ewww_image_optimizer_escapeshellarg( $file ) . ' -o ' . ewww_image_optimizer_escapeshellarg( $webpfile ) . ' 2>&1', $cli_output );
2752
  break;
2753
  case 'image/png':
 
2754
  exec( "$nice " . $tool . " $lossless -metadata $copy_opt -quiet " . ewww_image_optimizer_escapeshellarg( $file ) . ' -o ' . ewww_image_optimizer_escapeshellarg( $webpfile ) . ' 2>&1', $cli_output );
2755
  break;
2756
  }
@@ -2779,8 +2787,7 @@ function ewww_image_optimizer_webp_create( $file, $orig_size, $type, $tool, $rec
2779
  */
2780
  function ewww_image_optimizer_install_pngout_wrapper() {
2781
  ewwwio_debug_message( '<b>' . __FUNCTION__ . '()</b>' );
2782
- $permissions = apply_filters( 'ewww_image_optimizer_admin_permissions', '' );
2783
- if ( false === current_user_can( $permissions ) ) {
2784
  wp_die( esc_html__( 'You do not have permission to install image optimizer utilities.', 'ewww-image-optimizer' ) );
2785
  }
2786
  $sendback = ewww_image_optimizer_install_pngout();
54
  ! empty( $_ENV['PANTHEON_ENVIRONMENT'] ) ||
55
  defined( 'WPE_PLUGIN_VERSION' ) ||
56
  defined( 'FLYWHEEL_CONFIG_DIR' ) ||
57
+ defined( 'KINSTAMU_VERSION' ) ||
58
+ defined( 'WPNET_INIT_PLUGIN_VERSION' )
59
  ) {
60
  if (
61
  ! ewww_image_optimizer_get_option( 'ewww_image_optimizer_cloud_key' ) &&
171
  $webhost = 'Flywheel';
172
  } elseif ( defined( 'KINSTAMU_VERSION' ) ) {
173
  $webhost = 'Kinsta';
174
+ } elseif ( defined( 'WPNET_INIT_PLUGIN_VERSION' ) ) {
175
+ $webhost = 'WPNET';
176
  } else {
177
  return;
178
  }
535
  ewwwio_ob_clean();
536
  ewwwio_debug_message( '<b>' . __FUNCTION__ . '()</b>' );
537
  // Verify that the user is properly authorized.
538
+ if ( ! current_user_can( apply_filters( 'ewww_image_optimizer_admin_permissions', '' ) ) ) {
539
  wp_die( esc_html__( 'Access denied.', 'ewww-image-optimizer' ) );
540
  }
541
  update_option( 'ewww_image_optimizer_jpg_level', 10 );
2744
  $copy_opt = 'all';
2745
  }
2746
  $quality = (int) apply_filters( 'jpeg_quality', 82, 'image/webp' );
2747
+ if ( $quality < 50 ) {
2748
+ $quality = 82;
2749
+ }
2750
  if ( defined( 'EWWW_IMAGE_OPTIMIZER_LOSSY_PNG2WEBP' ) && EWWW_IMAGE_OPTIMIZER_LOSSY_PNG2WEBP ) {
2751
  $lossless = "-q $quality";
2752
  } else {
2754
  }
2755
  switch ( $type ) {
2756
  case 'image/jpeg':
2757
+ ewwwio_debug_message( "$nice " . $tool . " -q $quality -metadata $copy_opt -quiet " . ewww_image_optimizer_escapeshellarg( $file ) . ' -o ' . ewww_image_optimizer_escapeshellarg( $webpfile ) . ' 2>&1' );
2758
  exec( "$nice " . $tool . " -q $quality -metadata $copy_opt -quiet " . ewww_image_optimizer_escapeshellarg( $file ) . ' -o ' . ewww_image_optimizer_escapeshellarg( $webpfile ) . ' 2>&1', $cli_output );
2759
  break;
2760
  case 'image/png':
2761
+ ewwwio_debug_message( "$nice " . $tool . " $lossless -metadata $copy_opt -quiet " . ewww_image_optimizer_escapeshellarg( $file ) . ' -o ' . ewww_image_optimizer_escapeshellarg( $webpfile ) . ' 2>&1' );
2762
  exec( "$nice " . $tool . " $lossless -metadata $copy_opt -quiet " . ewww_image_optimizer_escapeshellarg( $file ) . ' -o ' . ewww_image_optimizer_escapeshellarg( $webpfile ) . ' 2>&1', $cli_output );
2763
  break;
2764
  }
2787
  */
2788
  function ewww_image_optimizer_install_pngout_wrapper() {
2789
  ewwwio_debug_message( '<b>' . __FUNCTION__ . '()</b>' );
2790
+ if ( ! current_user_can( apply_filters( 'ewww_image_optimizer_admin_permissions', '' ) ) ) {
 
2791
  wp_die( esc_html__( 'You do not have permission to install image optimizer utilities.', 'ewww-image-optimizer' ) );
2792
  }
2793
  $sendback = ewww_image_optimizer_install_pngout();