EWWW Image Optimizer - Version 4.5.1

Version Description

  • changed: optimization results are tracked by relative urls instead of absolute ones for better portability, migration tool coming soon
  • changed: ExactDN defaults to crop when explicit dimensions are given to image_downsize(), revert to scaling with EXACTDN_IMAGE_DOWNSIZE_SCALE
  • fixed: WooCommerce thumbnail regeneration triggers excessive admin-ajax requests within EWWW IO
  • fixed: ExactDN filtering REST API media endpoint for Gutenberg editor requests
  • fixed: ExactDN adding unneeded resize parameters to full-size image urls
  • fixed: Alt WebP skipping images with query strings
  • fixed: Alt WebP not working with Jetpack Lazy Load for images missing srcset
  • fixed: Show Optimized Images table does not display images saved to ewwwio_images table with relative path matching
  • fixed: Show Optimized Images table has broken thumbs when WP_CONTENT_DIR is outside of ABSPATH
Download this release

Release Info

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

Code changes from version 4.5.0 to 4.5.1

aux-optimize.php CHANGED
@@ -123,6 +123,7 @@ function ewww_image_optimizer_aux_images() {
123
  </script>
124
  <?php
125
  }
 
126
  ewwwio_memory( __FUNCTION__ );
127
  }
128
 
@@ -155,14 +156,25 @@ function ewww_image_optimizer_aux_images_table() {
155
  echo '<br /><table class="wp-list-table widefat media" cellspacing="0"><thead><tr><th>&nbsp;</th><th>' . esc_html__( 'Filename', 'ewww-image-optimizer' ) . '</th><th>' . esc_html__( 'Image Type', 'ewww-image-optimizer' ) . '</th><th>' . esc_html__( 'Image Optimizer', 'ewww-image-optimizer' ) . '</th></tr></thead>';
156
  $alternate = true;
157
  foreach ( $already_optimized as $optimized_image ) {
158
- $image_name = str_replace( ABSPATH, '', ewww_image_optimizer_relative_path_replace( $optimized_image['path'] ) );
159
- $image_url = esc_url( trailingslashit( get_site_url() ) . $image_name );
 
 
 
 
 
 
 
 
 
 
 
160
  $savings = esc_html( ewww_image_optimizer_image_results( $optimized_image['orig_size'], $optimized_image['image_size'] ) );
161
  $updated_time = strtotime( $optimized_image['updated'] );
162
  if ( DAY_IN_SECONDS * 30 + $updated_time < time() ) {
163
  $optimized_image['backup'] = '';
164
  }
165
- if ( strpos( $optimized_image['path'], 's3' ) === 0 ) {
166
  // Retrieve the mimetype of the attachment.
167
  $type = esc_html__( 'Amazon S3 image', 'ewww-image-optimizer' );
168
  $file_size = ewww_image_optimizer_size_format( $optimized_image['image_size'] );
@@ -189,9 +201,9 @@ function ewww_image_optimizer_aux_images_table() {
189
  </tr>
190
  <?php
191
  $alternate = ! $alternate;
192
- } elseif ( file_exists( $optimized_image['path'] ) ) {
193
  // Retrieve the mimetype of the attachment.
194
- $type = ewww_image_optimizer_mimetype( $optimized_image['path'], 'i' );
195
  // Get a human readable filesize.
196
  $file_size = ewww_image_optimizer_size_format( $optimized_image['image_size'] );
197
  /* translators: %s: human-readable filesize */
@@ -217,6 +229,8 @@ function ewww_image_optimizer_aux_images_table() {
217
  </tr>
218
  <?php
219
  $alternate = ! $alternate;
 
 
220
  } // End if().
221
  } // End foreach().
222
  echo '</table>';
@@ -338,6 +352,7 @@ function ewww_image_optimizer_image_scan( $dir, $started = 0 ) {
338
  $folders_completed = array();
339
  }
340
  if ( in_array( $dir, $folders_completed ) ) {
 
341
  return;
342
  }
343
  global $wpdb;
@@ -345,6 +360,7 @@ function ewww_image_optimizer_image_scan( $dir, $started = 0 ) {
345
  $images = array();
346
  $reset_images = array();
347
  if ( ! is_dir( $dir ) ) {
 
348
  return;
349
  }
350
  ewwwio_debug_message( "scanning folder for images: $dir" );
123
  </script>
124
  <?php
125
  }
126
+ $ewww_debug = '';
127
  ewwwio_memory( __FUNCTION__ );
128
  }
129
 
156
  echo '<br /><table class="wp-list-table widefat media" cellspacing="0"><thead><tr><th>&nbsp;</th><th>' . esc_html__( 'Filename', 'ewww-image-optimizer' ) . '</th><th>' . esc_html__( 'Image Type', 'ewww-image-optimizer' ) . '</th><th>' . esc_html__( 'Image Optimizer', 'ewww-image-optimizer' ) . '</th></tr></thead>';
157
  $alternate = true;
158
  foreach ( $already_optimized as $optimized_image ) {
159
+ $file = ewww_image_optimizer_relative_path_replace( $optimized_image['path'] );
160
+ $image_name = str_replace( ABSPATH, '', $file );
161
+ $image_url = esc_url( site_url( 'wp-includes/images/media/default.png' ) );
162
+ ewwwio_debug_message( "name is $image_name after replacing ABSPATH" );
163
+ if ( $file != $image_name ) {
164
+ $image_url = esc_url( site_url( $image_name ) );
165
+ } else {
166
+ $image_name = str_replace( WP_CONTENT_DIR, '', $file );
167
+ ewwwio_debug_message( "name is $image_name after replacing WP_CONTENT_DIR" );
168
+ if ( $file != $image_name ) {
169
+ $image_url = esc_url( content_url( $image_name ) );
170
+ }
171
+ }
172
  $savings = esc_html( ewww_image_optimizer_image_results( $optimized_image['orig_size'], $optimized_image['image_size'] ) );
173
  $updated_time = strtotime( $optimized_image['updated'] );
174
  if ( DAY_IN_SECONDS * 30 + $updated_time < time() ) {
175
  $optimized_image['backup'] = '';
176
  }
177
+ if ( strpos( $file, 's3' ) === 0 ) {
178
  // Retrieve the mimetype of the attachment.
179
  $type = esc_html__( 'Amazon S3 image', 'ewww-image-optimizer' );
180
  $file_size = ewww_image_optimizer_size_format( $optimized_image['image_size'] );
201
  </tr>
202
  <?php
203
  $alternate = ! $alternate;
204
+ } elseif ( is_file( $file ) ) {
205
  // Retrieve the mimetype of the attachment.
206
+ $type = ewww_image_optimizer_quick_mimetype( $file, 'i' );
207
  // Get a human readable filesize.
208
  $file_size = ewww_image_optimizer_size_format( $optimized_image['image_size'] );
209
  /* translators: %s: human-readable filesize */
229
  </tr>
230
  <?php
231
  $alternate = ! $alternate;
232
+ } else {
233
+ ewwwio_debug_message( "could not find $file" );
234
  } // End if().
235
  } // End foreach().
236
  echo '</table>';
352
  $folders_completed = array();
353
  }
354
  if ( in_array( $dir, $folders_completed ) ) {
355
+ ewwwio_debug_message( "$dir already completed" );
356
  return;
357
  }
358
  global $wpdb;
360
  $images = array();
361
  $reset_images = array();
362
  if ( ! is_dir( $dir ) ) {
363
+ ewwwio_debug_message( "$dir is not a directory, or unreadable" );
364
  return;
365
  }
366
  ewwwio_debug_message( "scanning folder for images: $dir" );
bulk.php CHANGED
@@ -16,6 +16,7 @@ if ( ! defined( 'ABSPATH' ) ) {
16
  */
17
  function ewww_image_optimizer_bulk_preview() {
18
  ewwwio_debug_message( '<b>' . __FUNCTION__ . '()</b>' );
 
19
  // Retrieve the attachment IDs that were pre-loaded in the database.
20
  echo '<div class="wrap"><h1>' . esc_html__( 'Bulk Optimize', 'ewww-image-optimizer' ) . '</h1>';
21
  if ( ewww_image_optimizer_get_option( 'ewww_image_optimizer_auto' ) ) {
16
  */
17
  function ewww_image_optimizer_bulk_preview() {
18
  ewwwio_debug_message( '<b>' . __FUNCTION__ . '()</b>' );
19
+ ewwwio_debug_version_info();
20
  // Retrieve the attachment IDs that were pre-loaded in the database.
21
  echo '<div class="wrap"><h1>' . esc_html__( 'Bulk Optimize', 'ewww-image-optimizer' ) . '</h1>';
22
  if ( ewww_image_optimizer_get_option( 'ewww_image_optimizer_auto' ) ) {
changelog.txt CHANGED
@@ -1,3 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
1
  = 4.5.0 =
2
  * added: Alt WebP supports BJ Lazy Load, a3 Lazy Load, WP Rocket Lazy Load, Jetpack Lazy Load, and WP Retina Lazy Load
3
  * added: ExactDN rewrites relative image urls that start with a single slash
1
+ = 4.5.1 =
2
+ * changed: optimization results are tracked by relative urls instead of absolute ones for better portability, migration tool coming soon
3
+ * changed: ExactDN defaults to crop when explicit dimensions are given to image_downsize(), revert to scaling with EXACTDN_IMAGE_DOWNSIZE_SCALE
4
+ * fixed: WooCommerce thumbnail regeneration triggers excessive admin-ajax requests within EWWW IO
5
+ * fixed: ExactDN filtering REST API media endpoint for Gutenberg editor requests
6
+ * fixed: ExactDN adding unneeded resize parameters to full-size image urls
7
+ * fixed: Alt WebP skipping images with query strings
8
+ * fixed: Alt WebP not working with Jetpack Lazy Load for images missing srcset
9
+ * fixed: Show Optimized Images table does not display images saved to ewwwio_images table with relative path matching
10
+ * fixed: Show Optimized Images table has broken thumbs when WP_CONTENT_DIR is outside of ABSPATH
11
+
12
  = 4.5.0 =
13
  * added: Alt WebP supports BJ Lazy Load, a3 Lazy Load, WP Rocket Lazy Load, Jetpack Lazy Load, and WP Retina Lazy Load
14
  * added: ExactDN rewrites relative image urls that start with a single slash
classes/class-ewwwio-alt-webp.php CHANGED
@@ -16,12 +16,12 @@ if ( ! defined( 'ABSPATH' ) ) {
16
  class EWWWIO_Alt_Webp extends EWWWIO_Page_Parser {
17
 
18
  /**
19
- * The Alt WebP inline script contents. Current length 11804.
20
  *
21
  * @access private
22
  * @var string $inline_script
23
  */
24
- private $inline_script = 'var Arrive=function(w,e,c){"use strict";if(w.MutationObserver&&"undefined"!=typeof HTMLElement){var a,t,r=0,d=(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&&d.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!==w||(e=[e]),e}}),u=((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 u,s=this,o={fireOnAttributesModification:!1};return l.beforeAdding(function(t){var e,a=t.target;a!==w.document&&a!==w||(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=s}),l.beforeRemoving(function(e){e.observer.disconnect()}),this.bindEvent=function(e,t,a){t=d.mergeArrays(o,t);for(var r=d.toElementsArray(this),i=0;i<r.length;i++)l.addEvent(r[i],e,t,a)},this.unbindEvent=function(){var a=d.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=d.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=d.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 o={fireOnAttributesModification:!1,onceOnly:!1,existing:!1};function n(e,t,a){return!(!d.matchesSelector(e,t.selector)||(e._id===c&&(e._id=r++),-1!=t.firedElems.indexOf(e._id))||(t.firedElems.push(e._id),0))}var w=(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?d.checkChildNodesRecursively(t,i,n,r):"attributes"===e.type&&n(a,i)&&r.push({callback:i.callback,elem:a}),d.callCallbacks(r,i)})})).bindEvent;return i.bindEvent=function(e,t,a){void 0===a?(a=t,t=o):t=d.mergeArrays(o,t);var r=d.toElementsArray(this);if(t.existing){for(var i=[],n=0;n<r.length;n++)for(var l=r[n].querySelectorAll(e),s=0;s<l.length;s++)i.push({callback:a,elem:l[s]});if(t.onceOnly&&i.length)return a.call(i[0].elem,i[0].elem);setTimeout(d.callCallbacks,1,i)}w.call(this,e,t,a)},i},s=new function(){var r={};function i(e,t){return d.matchesSelector(e,t.selector)}var n=(s=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&&d.checkChildNodesRecursively(t,r,i,a),d.callCallbacks(a,r)})})).bindEvent;return s.bindEvent=function(e,t,a){void 0===a?(a=t,t=r):t=d.mergeArrays(r,t),n.call(this,e,t,a)},s};e&&h(e.fn),h(HTMLElement.prototype),h(NodeList.prototype),h(HTMLCollection.prototype),h(HTMLDocument.prototype),h(Window.prototype);var n={};return o(i,n,"unbindAllArrive"),o(s,n,"unbindAllLeave"),n}function o(e,t,a){d.addMethod(t,a,e.unbindEvent),d.addMethod(t,a,e.unbindEventWithSelectorOrCallback),d.addMethod(t,a,e.unbindEventWithSelectorAndCallback)}function h(e){e.arrive=i.bindEvent,o(i,e,"unbindArrive"),e.leave=s.bindEvent,o(s,e,"unbindLeave")}}(window,"undefined"==typeof jQuery?null:jQuery,void 0);function check_webp_feature(e,t){var a=new Image;a.onload=function(){ewww_webp_supported=0<a.width&&0<a.height,t(ewww_webp_supported)},a.onerror=function(){t(ewww_webp_supported=!1)},a.src="data:image/webp;base64,"+{alpha:"UklGRkoAAABXRUJQVlA4WAoAAAAQAAAAAAAAAAAAQUxQSAwAAAARBxAR/Q9ERP8DAABWUDggGAAAABQBAJ0BKgEAAQAAAP4AAA3AAP7mtQAAAA==",animation:"UklGRlIAAABXRUJQVlA4WAoAAAASAAAAAAAAAAAAQU5JTQYAAAD/////AABBTk1GJgAAAAAAAAAAAAAAAAAAAGQAAABWUDhMDQAAAC8AAAAQBxAREYiI/gcA"}[e]}function ewww_load_images(t){!function(n){n.fn.extend({ewwwattr:function(e,t){return void 0!==t&&!1!==t&&this.attr(e,t),this}});t&&(n(".batch-image img, .image-wrapper a, .ngg-pro-masonry-item a, .ngg-galleria-offscreen-seo-wrapper a").each(function(){n(this).ewwwattr("data-src",n(this).attr("data-webp")),n(this).ewwwattr("data-thumbnail",n(this).attr("data-webp-thumbnail"))}),n(".image-wrapper a, .ngg-pro-masonry-item a").each(function(){n(this).ewwwattr("href",n(this).attr("data-webp"))}),n(".rev_slider ul li").each(function(){n(this).ewwwattr("data-thumb",n(this).attr("data-webp-thumb"));for(var e=1;e<11;)n(this).ewwwattr("data-param"+e,n(this).attr("data-webp-param"+e)),e++}),n(".rev_slider img").each(function(){n(this).ewwwattr("data-lazyload",n(this).attr("data-webp-lazyload"))}),n("div.woocommerce-product-gallery__image").each(function(){n(this).ewwwattr("data-thumb",n(this).attr("data-webp-thumb"))})),n("img.ewww_webp_lazy_retina").each(function(){t&&n(this).ewwwattr("data-srcset",n(this).attr("data-srcset-webp")),n(this).removeClass("ewww_webp_lazy_retina")}),n("video").each(function(){t?n(this).ewwwattr("poster",n(this).attr("data-poster-webp")):n(this).ewwwattr("poster",n(this).attr("data-poster-image"))}),n("img.ewww_webp_lazy_load").each(function(){t&&(n(this).ewwwattr("data-lazy-srcset",n(this).attr("data-lazy-srcset-webp")),n(this).ewwwattr("data-srcset",n(this).attr("data-srcset-webp")),n(this).ewwwattr("data-lazy-src",n(this).attr("data-lazy-src-webp")),n(this).ewwwattr("data-src",n(this).attr("data-src-webp")),n(this).ewwwattr("data-orig-file",n(this).attr("data-webp-orig-file")),n(this).ewwwattr("data-medium-file",n(this).attr("data-webp-medium-file")),n(this).ewwwattr("data-large-file",n(this).attr("data-webp-large-file"))),n(this).removeClass("ewww_webp_lazy_load")}),n(".ewww_webp").each(function(){var e=document.createElement("img");t?(n(e).ewwwattr("src",n(this).attr("data-webp")),n(e).ewwwattr("srcset",n(this).attr("data-srcset-webp")),n(e).ewwwattr("data-orig-file",n(this).attr("data-orig-file")),n(e).ewwwattr("data-orig-file",n(this).attr("data-webp-orig-file")),n(e).ewwwattr("data-medium-file",n(this).attr("data-medium-file")),n(e).ewwwattr("data-medium-file",n(this).attr("data-webp-medium-file")),n(e).ewwwattr("data-large-file",n(this).attr("data-large-file")),n(e).ewwwattr("data-large-file",n(this).attr("data-webp-large-file")),n(e).ewwwattr("data-large_image",n(this).attr("data-large_image")),n(e).ewwwattr("data-large_image",n(this).attr("data-webp-large_image")),n(e).ewwwattr("data-src",n(this).attr("data-src")),n(e).ewwwattr("data-src",n(this).attr("data-webp-src"))):(n(e).ewwwattr("src",n(this).attr("data-img")),n(e).ewwwattr("srcset",n(this).attr("data-srcset-img")),n(e).ewwwattr("data-orig-file",n(this).attr("data-orig-file")),n(e).ewwwattr("data-medium-file",n(this).attr("data-medium-file")),n(e).ewwwattr("data-large-file",n(this).attr("data-large-file")),n(e).ewwwattr("data-large_image",n(this).attr("data-large_image")),n(e).ewwwattr("data-src",n(this).attr("data-src"))),e=function(e,t){for(var a=["align","alt","border","crossorigin","height","hspace","ismap","longdesc","usemap","vspace","width","accesskey","class","contenteditable","contextmenu","dir","draggable","dropzone","hidden","id","lang","spellcheck","style","tabindex","title","translate","sizes","data-caption","data-attachment-id","data-permalink","data-orig-size","data-comments-opened","data-image-meta","data-image-title","data-image-description","data-event-trigger","data-highlight-color","data-highlight-opacity","data-highlight-border-color","data-highlight-border-width","data-highlight-border-opacity","data-no-lazy","data-lazy","data-large_image_width","data-large_image_height"],r=0,i=a.length;r<i;r++)n(t).ewwwattr(a[r],n(e).attr("data-"+a[r]));return t}(this,e),n(this).after(e),n(this).removeClass("ewww_webp")})}(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()}))}var ewww_webp_supported=!1,ewww_jquery_waiting_timer=0;function ewww_ngg_plus_parse_galleries(e){e&&jQuery.each(galleries,function(e,t){galleries[e].images_list=ewww_ngg_plus_parse_image_list(t.images_list)})}function ewww_ngg_plus_load_galleries(e){var i;e&&((i=jQuery)(window).on("ngg.galleria.themeadded",function(e,t){window.ngg_galleria._create_backup=window.ngg_galleria.create,window.ngg_galleria.create=function(e,t){var a=i(e).data("id");return galleries["gallery_"+a].images_list=ewww_ngg_plus_parse_image_list(galleries["gallery_"+a].images_list),window.ngg_galleria._create_backup(e,t)}}),i(window).on("override_nplModal_methods",function(e,r){r._set_events_backup=r.set_events,r.set_events=function(){return i("#npl_content").bind("npl_images_ready",function(e,t){var a=r.fetch_images.gallery_image_cache[t];a=ewww_ngg_plus_parse_image_list(a)}),r._set_events_backup()}}))}function ewww_ngg_plus_parse_image_list(i){var e;return(e=jQuery).each(i,function(a,r){void 0!==r["image-webp"]&&(i[a].image=r["image-webp"],delete i[a]["image-webp"]),void 0!==r["thumb-webp"]&&(i[a].thumb=r["thumb-webp"],delete i[a]["thumb-webp"]),void 0!==r.full_image_webp&&(i[a].full_image=r.full_image_webp,delete i[a].full_image_webp),void 0!==r.srcsets&&e.each(r.srcsets,function(e,t){void 0!==r.srcsets[e+"-webp"]&&(i[a].srcsets[e]=r.srcsets[e+"-webp"],delete i[a].srcsets[e+"-webp"])}),void 0!==r.full_srcsets&&e.each(r.full_srcsets,function(e,t){void 0!==r.full_srcsets[e+"-webp"]&&(i[a].full_srcsets[e]=r.full_srcsets[e+"-webp"],delete i[a].full_srcsets[e+"-webp"])})}),i}ewww_jquery_waiting=setInterval(function(){if(window.jQuery){check_webp_feature("alpha",ewww_load_images),check_webp_feature("alpha",ewww_ngg_plus_load_galleries),document.arrive(".ewww_webp",function(){ewww_load_images(ewww_webp_supported)});var e=0,t=setInterval(function(){"undefined"!=typeof galleries&&(check_webp_feature("alpha",ewww_ngg_plus_parse_galleries),clearInterval(t)),1e3<(e+=25)&&clearInterval(t)},25);clearInterval(ewww_jquery_waiting)}1e4<(ewww_jquery_waiting_timer+=100)&&clearInterval(ewww_jquery_waiting)},100);';
25
 
26
  /**
27
  * Indicates if we are filtering ExactDN urls.
@@ -641,7 +641,8 @@ class EWWWIO_Alt_Webp extends EWWWIO_Page_Parser {
641
  ewwwio_debug_message( 'not a valid local image' );
642
  return false;
643
  }
644
- if ( is_file( $imagepath . '.webp' ) ) {
 
645
  ewwwio_debug_message( 'local .webp image found' );
646
  return true;
647
  }
@@ -660,7 +661,8 @@ class EWWWIO_Alt_Webp extends EWWWIO_Page_Parser {
660
  if ( $this->parsing_exactdn && false !== strpos( $url, $this->exactdn_domain ) ) {
661
  return add_query_arg( 'webp', 1, $url );
662
  } else {
663
- return $url . '.webp';
 
664
  }
665
  return $url;
666
  }
16
  class EWWWIO_Alt_Webp extends EWWWIO_Page_Parser {
17
 
18
  /**
19
+ * The Alt WebP inline script contents. Current length 11772.
20
  *
21
  * @access private
22
  * @var string $inline_script
23
  */
24
+ private $inline_script = 'var Arrive=function(w,e,c){"use strict";if(w.MutationObserver&&"undefined"!=typeof HTMLElement){var a,t,r=0,d=(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&&d.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!==w||(e=[e]),e}}),u=((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 u,s=this,o={fireOnAttributesModification:!1};return l.beforeAdding(function(t){var e,a=t.target;a!==w.document&&a!==w||(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=s}),l.beforeRemoving(function(e){e.observer.disconnect()}),this.bindEvent=function(e,t,a){t=d.mergeArrays(o,t);for(var r=d.toElementsArray(this),i=0;i<r.length;i++)l.addEvent(r[i],e,t,a)},this.unbindEvent=function(){var a=d.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=d.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=d.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 o={fireOnAttributesModification:!1,onceOnly:!1,existing:!1};function n(e,t,a){return!(!d.matchesSelector(e,t.selector)||(e._id===c&&(e._id=r++),-1!=t.firedElems.indexOf(e._id))||(t.firedElems.push(e._id),0))}var w=(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?d.checkChildNodesRecursively(t,i,n,r):"attributes"===e.type&&n(a,i)&&r.push({callback:i.callback,elem:a}),d.callCallbacks(r,i)})})).bindEvent;return i.bindEvent=function(e,t,a){void 0===a?(a=t,t=o):t=d.mergeArrays(o,t);var r=d.toElementsArray(this);if(t.existing){for(var i=[],n=0;n<r.length;n++)for(var l=r[n].querySelectorAll(e),s=0;s<l.length;s++)i.push({callback:a,elem:l[s]});if(t.onceOnly&&i.length)return a.call(i[0].elem,i[0].elem);setTimeout(d.callCallbacks,1,i)}w.call(this,e,t,a)},i},s=new function(){var r={};function i(e,t){return d.matchesSelector(e,t.selector)}var n=(s=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&&d.checkChildNodesRecursively(t,r,i,a),d.callCallbacks(a,r)})})).bindEvent;return s.bindEvent=function(e,t,a){void 0===a?(a=t,t=r):t=d.mergeArrays(r,t),n.call(this,e,t,a)},s};e&&h(e.fn),h(HTMLElement.prototype),h(NodeList.prototype),h(HTMLCollection.prototype),h(HTMLDocument.prototype),h(Window.prototype);var n={};return o(i,n,"unbindAllArrive"),o(s,n,"unbindAllLeave"),n}function o(e,t,a){d.addMethod(t,a,e.unbindEvent),d.addMethod(t,a,e.unbindEventWithSelectorOrCallback),d.addMethod(t,a,e.unbindEventWithSelectorAndCallback)}function h(e){e.arrive=i.bindEvent,o(i,e,"unbindArrive"),e.leave=s.bindEvent,o(s,e,"unbindLeave")}}(window,"undefined"==typeof jQuery?null:jQuery,void 0);function check_webp_feature(e,t){var a=new Image;a.onload=function(){ewww_webp_supported=0<a.width&&0<a.height,t(ewww_webp_supported)},a.onerror=function(){t(ewww_webp_supported=!1)},a.src="data:image/webp;base64,"+{alpha:"UklGRkoAAABXRUJQVlA4WAoAAAAQAAAAAAAAAAAAQUxQSAwAAAARBxAR/Q9ERP8DAABWUDggGAAAABQBAJ0BKgEAAQAAAP4AAA3AAP7mtQAAAA==",animation:"UklGRlIAAABXRUJQVlA4WAoAAAASAAAAAAAAAAAAQU5JTQYAAAD/////AABBTk1GJgAAAAAAAAAAAAAAAAAAAGQAAABWUDhMDQAAAC8AAAAQBxAREYiI/gcA"}[e]}function ewww_load_images(t){!function(n){n.fn.extend({ewwwattr:function(e,t){return void 0!==t&&!1!==t&&this.attr(e,t),this}});t&&(n(".batch-image img, .image-wrapper a, .ngg-pro-masonry-item a, .ngg-galleria-offscreen-seo-wrapper a").each(function(){n(this).ewwwattr("data-src",n(this).attr("data-webp")),n(this).ewwwattr("data-thumbnail",n(this).attr("data-webp-thumbnail"))}),n(".image-wrapper a, .ngg-pro-masonry-item a").each(function(){n(this).ewwwattr("href",n(this).attr("data-webp"))}),n(".rev_slider ul li").each(function(){n(this).ewwwattr("data-thumb",n(this).attr("data-webp-thumb"));for(var e=1;e<11;)n(this).ewwwattr("data-param"+e,n(this).attr("data-webp-param"+e)),e++}),n(".rev_slider img").each(function(){n(this).ewwwattr("data-lazyload",n(this).attr("data-webp-lazyload"))}),n("div.woocommerce-product-gallery__image").each(function(){n(this).ewwwattr("data-thumb",n(this).attr("data-webp-thumb"))})),n("video").each(function(){t?n(this).ewwwattr("poster",n(this).attr("data-poster-webp")):n(this).ewwwattr("poster",n(this).attr("data-poster-image"))}),n("img.ewww_webp_lazy_load").each(function(){if(t){n(this).ewwwattr("data-lazy-srcset",n(this).attr("data-lazy-srcset-webp")),n(this).ewwwattr("data-srcset",n(this).attr("data-srcset-webp")),n(this).ewwwattr("data-lazy-src",n(this).attr("data-lazy-src-webp")),n(this).ewwwattr("data-src",n(this).attr("data-src-webp")),n(this).ewwwattr("data-orig-file",n(this).attr("data-webp-orig-file")),n(this).ewwwattr("data-medium-file",n(this).attr("data-webp-medium-file")),n(this).ewwwattr("data-large-file",n(this).attr("data-webp-large-file"));var e=n(this).attr("srcset");void 0!==e&&!1!==e&&e.includes("R0lGOD")&&n(this).ewwwattr("src",n(this).attr("data-lazy-src-webp"))}n(this).removeClass("ewww_webp_lazy_load")}),n(".ewww_webp").each(function(){var e=document.createElement("img");t?(n(e).ewwwattr("src",n(this).attr("data-webp")),n(e).ewwwattr("srcset",n(this).attr("data-srcset-webp")),n(e).ewwwattr("data-orig-file",n(this).attr("data-orig-file")),n(e).ewwwattr("data-orig-file",n(this).attr("data-webp-orig-file")),n(e).ewwwattr("data-medium-file",n(this).attr("data-medium-file")),n(e).ewwwattr("data-medium-file",n(this).attr("data-webp-medium-file")),n(e).ewwwattr("data-large-file",n(this).attr("data-large-file")),n(e).ewwwattr("data-large-file",n(this).attr("data-webp-large-file")),n(e).ewwwattr("data-large_image",n(this).attr("data-large_image")),n(e).ewwwattr("data-large_image",n(this).attr("data-webp-large_image")),n(e).ewwwattr("data-src",n(this).attr("data-src")),n(e).ewwwattr("data-src",n(this).attr("data-webp-src"))):(n(e).ewwwattr("src",n(this).attr("data-img")),n(e).ewwwattr("srcset",n(this).attr("data-srcset-img")),n(e).ewwwattr("data-orig-file",n(this).attr("data-orig-file")),n(e).ewwwattr("data-medium-file",n(this).attr("data-medium-file")),n(e).ewwwattr("data-large-file",n(this).attr("data-large-file")),n(e).ewwwattr("data-large_image",n(this).attr("data-large_image")),n(e).ewwwattr("data-src",n(this).attr("data-src"))),e=function(e,t){for(var a=["align","alt","border","crossorigin","height","hspace","ismap","longdesc","usemap","vspace","width","accesskey","class","contenteditable","contextmenu","dir","draggable","dropzone","hidden","id","lang","spellcheck","style","tabindex","title","translate","sizes","data-caption","data-attachment-id","data-permalink","data-orig-size","data-comments-opened","data-image-meta","data-image-title","data-image-description","data-event-trigger","data-highlight-color","data-highlight-opacity","data-highlight-border-color","data-highlight-border-width","data-highlight-border-opacity","data-no-lazy","data-lazy","data-large_image_width","data-large_image_height"],r=0,i=a.length;r<i;r++)n(t).ewwwattr(a[r],n(e).attr("data-"+a[r]));return t}(this,e),n(this).after(e),n(this).removeClass("ewww_webp")})}(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()}))}var ewww_webp_supported=!1,ewww_jquery_waiting_timer=0;function ewww_ngg_plus_parse_galleries(e){e&&jQuery.each(galleries,function(e,t){galleries[e].images_list=ewww_ngg_plus_parse_image_list(t.images_list)})}function ewww_ngg_plus_load_galleries(e){var i;e&&((i=jQuery)(window).on("ngg.galleria.themeadded",function(e,t){window.ngg_galleria._create_backup=window.ngg_galleria.create,window.ngg_galleria.create=function(e,t){var a=i(e).data("id");return galleries["gallery_"+a].images_list=ewww_ngg_plus_parse_image_list(galleries["gallery_"+a].images_list),window.ngg_galleria._create_backup(e,t)}}),i(window).on("override_nplModal_methods",function(e,r){r._set_events_backup=r.set_events,r.set_events=function(){return i("#npl_content").bind("npl_images_ready",function(e,t){var a=r.fetch_images.gallery_image_cache[t];a=ewww_ngg_plus_parse_image_list(a)}),r._set_events_backup()}}))}function ewww_ngg_plus_parse_image_list(i){var e;return(e=jQuery).each(i,function(a,r){void 0!==r["image-webp"]&&(i[a].image=r["image-webp"],delete i[a]["image-webp"]),void 0!==r["thumb-webp"]&&(i[a].thumb=r["thumb-webp"],delete i[a]["thumb-webp"]),void 0!==r.full_image_webp&&(i[a].full_image=r.full_image_webp,delete i[a].full_image_webp),void 0!==r.srcsets&&e.each(r.srcsets,function(e,t){void 0!==r.srcsets[e+"-webp"]&&(i[a].srcsets[e]=r.srcsets[e+"-webp"],delete i[a].srcsets[e+"-webp"])}),void 0!==r.full_srcsets&&e.each(r.full_srcsets,function(e,t){void 0!==r.full_srcsets[e+"-webp"]&&(i[a].full_srcsets[e]=r.full_srcsets[e+"-webp"],delete i[a].full_srcsets[e+"-webp"])})}),i}ewww_jquery_waiting=setInterval(function(){if(window.jQuery){check_webp_feature("alpha",ewww_load_images),check_webp_feature("alpha",ewww_ngg_plus_load_galleries),document.arrive(".ewww_webp",function(){ewww_load_images(ewww_webp_supported)});var e=0,t=setInterval(function(){"undefined"!=typeof galleries&&(check_webp_feature("alpha",ewww_ngg_plus_parse_galleries),clearInterval(t)),1e3<(e+=25)&&clearInterval(t)},25);clearInterval(ewww_jquery_waiting)}1e4<(ewww_jquery_waiting_timer+=100)&&clearInterval(ewww_jquery_waiting)},100);';
25
 
26
  /**
27
  * Indicates if we are filtering ExactDN urls.
641
  ewwwio_debug_message( 'not a valid local image' );
642
  return false;
643
  }
644
+ $path_parts = explode( '?', $imagepath );
645
+ if ( is_file( $path_parts[0] . '.webp' ) || is_file( $imagepath . '.webp' ) ) {
646
  ewwwio_debug_message( 'local .webp image found' );
647
  return true;
648
  }
661
  if ( $this->parsing_exactdn && false !== strpos( $url, $this->exactdn_domain ) ) {
662
  return add_query_arg( 'webp', 1, $url );
663
  } else {
664
+ $path_parts = explode( '?', $url );
665
+ return $path_parts[0] . '.webp' . ( ! empty( $path_parts[1] ) && 'is-pending-load=1' !== $path_parts[1] ? '?' . $path_parts[1] : '' );
666
  }
667
  return $url;
668
  }
classes/class-ewwwio-background-process.php CHANGED
@@ -205,6 +205,36 @@ if ( ! class_exists( 'EWWWIO_Background_Process' ) ) {
205
  wp_die();
206
  }
207
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
208
  /**
209
  * Is queue empty
210
  *
205
  wp_die();
206
  }
207
 
208
+ /**
209
+ * Count items in queue.
210
+ *
211
+ * @return bool
212
+ */
213
+ public function count_queue() {
214
+ global $wpdb;
215
+
216
+ $key = $wpdb->esc_like( $this->identifier . '_batch_' ) . '%';
217
+
218
+ $queues = $wpdb->get_results(
219
+ $wpdb->prepare(
220
+ "SELECT option_value
221
+ FROM $wpdb->options
222
+ WHERE option_name LIKE %s AND option_value != ''",
223
+ $key
224
+ ),
225
+ ARRAY_A
226
+ );
227
+ if ( empty( $queues ) ) {
228
+ return 0;
229
+ }
230
+ $queued = array();
231
+ foreach ( $queues as $queue ) {
232
+ $queue = maybe_unserialize( $queue['option_value'] );
233
+ $queued = array_merge( $queued, $queue );
234
+ }
235
+ return count( $queued );
236
+ }
237
+
238
  /**
239
  * Is queue empty
240
  *
classes/class-exactdn.php CHANGED
@@ -139,6 +139,12 @@ class ExactDN extends EWWWIO_Page_Parser {
139
  }
140
  // Disable image_downsize filter during themify_get_image().
141
  add_action( 'themify_before_post_image', array( $this, 'disable_image_downsize' ) );
 
 
 
 
 
 
142
 
143
  // Overrides for admin-ajax images.
144
  add_filter( 'exactdn_admin_allow_image_downsize', array( $this, 'allow_admin_image_downsize' ), 10, 2 );
@@ -536,7 +542,7 @@ class ExactDN extends EWWWIO_Page_Parser {
536
  * @return bool|string The content width, if set. Default false.
537
  */
538
  function get_content_width() {
539
- $content_width = isset( $GLOBALS['content_width'] ) ? $GLOBALS['content_width'] : false;
540
  /**
541
  * Filter the Content Width value.
542
  *
@@ -1084,6 +1090,23 @@ class ExactDN extends EWWWIO_Page_Parser {
1084
  add_filter( 'image_downsize', array( $this, 'filter_image_downsize' ), 10, 3 );
1085
  }
1086
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1087
  /**
1088
  * Filter post thumbnail image retrieval, passing images through ExactDN.
1089
  *
@@ -1097,6 +1120,7 @@ class ExactDN extends EWWWIO_Page_Parser {
1097
  function filter_image_downsize( $image, $attachment_id, $size ) {
1098
  $started = microtime( true );
1099
  ewwwio_debug_message( '<b>' . __FUNCTION__ . '()</b>' );
 
1100
  // Don't foul up the admin side of things, unless a plugin wants to.
1101
  if ( is_admin() &&
1102
  /**
@@ -1104,7 +1128,7 @@ class ExactDN extends EWWWIO_Page_Parser {
1104
  *
1105
  * Note: enabling this will result in ExactDN URLs added to your post content, which could make migrations across domains (and off ExactDN) a bit more challenging.
1106
  *
1107
- * @param bool false Stop ExactDN from being run on the Dashboard. Default to false.
1108
  * @param array $args {
1109
  * Array of image details.
1110
  *
@@ -1203,7 +1227,6 @@ class ExactDN extends EWWWIO_Page_Parser {
1203
  $has_size_meta = true;
1204
  }
1205
 
1206
- // Expose determined arguments to a filter before passing to ExactDN.
1207
  $transform = $image_args['crop'] ? 'resize' : 'fit';
1208
 
1209
  // Check specified image dimensions and account for possible zero values; ExactDN fails to resize if a dimension is zero.
@@ -1214,25 +1237,34 @@ class ExactDN extends EWWWIO_Page_Parser {
1214
  $exactdn_args['w'] = $image_args['width'];
1215
  }
1216
  } else {
1217
- $image_meta = wp_get_attachment_metadata( $attachment_id );
1218
- if ( ( 'resize' === $transform ) && $image_meta ) {
1219
- if ( isset( $image_meta['width'], $image_meta['height'] ) ) {
1220
- // Lets make sure that we don't upscale images since wp never upscales them as well.
1221
- $smaller_width = ( ( $image_meta['width'] < $image_args['width'] ) ? $image_meta['width'] : $image_args['width'] );
1222
- $smaller_height = ( ( $image_meta['height'] < $image_args['height'] ) ? $image_meta['height'] : $image_args['height'] );
 
 
 
1223
 
1224
- $exactdn_args[ $transform ] = $smaller_width . ',' . $smaller_height;
1225
- }
1226
  } else {
1227
  $exactdn_args[ $transform ] = $image_args['width'] . ',' . $image_args['height'];
1228
  }
1229
  }
1230
 
 
 
 
1231
  if ( ! empty( $image_meta['sizes'] ) && 'full' !== $size && ! empty( $image_meta['sizes'][ $size ]['file'] ) ) {
1232
  $image_url_basename = wp_basename( $image_url );
1233
  $intermediate_url = str_replace( $image_url_basename, $image_meta['sizes'][ $size ]['file'], $image_url );
1234
 
1235
- list( $filename_width, $filename_height ) = $this->get_dimensions_from_filename( $intermediate_url );
 
 
 
 
1236
  if ( $filename_width && $filename_height && $image_args['width'] === $filename_width && $image_args['height'] === $filename_height ) {
1237
  $image_url = $intermediate_url;
1238
  } else {
@@ -1242,7 +1274,7 @@ class ExactDN extends EWWWIO_Page_Parser {
1242
  $resize_existing = true;
1243
  }
1244
 
1245
- $exactdn_args = $this->maybe_smart_crop( $exactdn_args, $attachment_id, $image_meta );
1246
 
1247
  /**
1248
  * Filter the ExactDN arguments added to an image, when that image size is a string.
@@ -1262,21 +1294,12 @@ class ExactDN extends EWWWIO_Page_Parser {
1262
  $exactdn_args = apply_filters( 'exactdn_image_downsize_string', $exactdn_args, compact( 'image_args', 'image_url', 'attachment_id', 'size', 'transform' ) );
1263
 
1264
  // Generate ExactDN URL.
1265
- if ( ! $resize_existing ) {
1266
- $image = array(
1267
- $this->generate_url( $image_url ),
1268
- $has_size_meta ? $image_args['width'] : false,
1269
- $has_size_meta ? $image_args['height'] : false,
1270
- $intermediate,
1271
- );
1272
- } else {
1273
- $image = array(
1274
- $this->generate_url( $image_url, $exactdn_args ),
1275
- $has_size_meta ? $image_args['width'] : false,
1276
- $has_size_meta ? $image_args['height'] : false,
1277
- $intermediate,
1278
- );
1279
- }
1280
  } elseif ( is_array( $size ) ) {
1281
  // Pull width and height values from the provided array, if possible.
1282
  $width = isset( $size[0] ) ? (int) $size[0] : false;
@@ -1309,7 +1332,7 @@ class ExactDN extends EWWWIO_Page_Parser {
1309
 
1310
  // Expose arguments to a filter before passing to ExactDN.
1311
  $exactdn_args = array(
1312
- 'fit' => $width . ',' . $height,
1313
  );
1314
 
1315
  $exactdn_args = $this->maybe_smart_crop( $exactdn_args, $attachment_id, $image_meta );
@@ -1380,14 +1403,14 @@ class ExactDN extends EWWWIO_Page_Parser {
1380
  ) {
1381
  return $sources;
1382
  }
 
1383
  if ( ! is_array( $sources ) ) {
1384
  return $sources;
1385
  }
 
1386
  $upload_dir = wp_get_upload_dir();
1387
  $resize_existing = defined( 'EXACTDN_RESIZE_EXISTING' ) && EXACTDN_RESIZE_EXISTING;
1388
 
1389
- ewwwio_debug_message( 'current list has ' . count( $sources ) . ' image(s)' );
1390
-
1391
  foreach ( $sources as $i => $source ) {
1392
  if ( ! $this->validate_image_url( $source['url'] ) ) {
1393
  continue;
@@ -1406,6 +1429,17 @@ class ExactDN extends EWWWIO_Page_Parser {
1406
  $sources[ $i ]['url'] = $this->generate_url( $source['url'] );
1407
  continue;
1408
  }
 
 
 
 
 
 
 
 
 
 
 
1409
  ewwwio_debug_message( 'continuing: ' . $width . ' vs. ' . $source['value'] );
1410
 
1411
  // It's quicker to get the full size with the data we have already, if available.
@@ -1471,7 +1505,7 @@ class ExactDN extends EWWWIO_Page_Parser {
1471
  if ( abs( $constrained_size[0] - $expected_size[0] ) <= 1 && abs( $constrained_size[1] - $expected_size[1] ) <= 1 ) {
1472
  ewwwio_debug_message( 'soft cropping' );
1473
  $crop = 'soft';
1474
- $base = $this->get_content_width() ? $this->get_content_width() : 1900; // Provide a default width if none set by the theme.
1475
  } else {
1476
  ewwwio_debug_message( 'hard cropping' );
1477
  $crop = 'hard';
@@ -1545,9 +1579,6 @@ class ExactDN extends EWWWIO_Page_Parser {
1545
  return $sizes;
1546
  }
1547
  $content_width = $this->get_content_width();
1548
- if ( ! $content_width ) {
1549
- $content_width = 1900;
1550
- }
1551
 
1552
  if ( ( is_array( $size ) && $size[0] < $content_width ) ) {
1553
  return $sizes;
@@ -1733,6 +1764,34 @@ class ExactDN extends EWWWIO_Page_Parser {
1733
  return $args;
1734
  }
1735
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1736
  /**
1737
  * Make sure the image domain is on the list of approved domains.
1738
  *
@@ -1858,7 +1917,7 @@ class ExactDN extends EWWWIO_Page_Parser {
1858
  // Extracts the file path to the image minus the base url.
1859
  $file_path = substr( $stripped_src, strlen( $upload_dir['baseurl'] ) );
1860
 
1861
- if ( file_exists( $upload_dir['basedir'] . $file_path ) ) {
1862
  $src = $stripped_src;
1863
  }
1864
  ewwwio_debug_message( 'stripped dims' );
139
  }
140
  // Disable image_downsize filter during themify_get_image().
141
  add_action( 'themify_before_post_image', array( $this, 'disable_image_downsize' ) );
142
+ if ( ewww_image_optimizer_get_option( 'exactdn_image_downsize_scale' ) ) {
143
+ add_action( 'exactdn_image_downsize_array', array( $this, 'image_downsize_scale' ) );
144
+ }
145
+
146
+ // Check REST API requests to see if ExactDN should be running.
147
+ add_filter( 'rest_request_before_callbacks', array( $this, 'parse_restapi_maybe' ), 10, 3 );
148
 
149
  // Overrides for admin-ajax images.
150
  add_filter( 'exactdn_admin_allow_image_downsize', array( $this, 'allow_admin_image_downsize' ), 10, 2 );
542
  * @return bool|string The content width, if set. Default false.
543
  */
544
  function get_content_width() {
545
+ $content_width = isset( $GLOBALS['content_width'] ) ? $GLOBALS['content_width'] : 1920;
546
  /**
547
  * Filter the Content Width value.
548
  *
1090
  add_filter( 'image_downsize', array( $this, 'filter_image_downsize' ), 10, 3 );
1091
  }
1092
 
1093
+ /**
1094
+ * Change the default for processing an array of dimensions to scaling instead of cropping.
1095
+ *
1096
+ * @param array $exactdn_args The ExactDN args generated by filter_image_downsize() when $size is an array.
1097
+ * @return array $exactdn_args The ExactDN args, with resize (crop) changed to fit (scale).
1098
+ */
1099
+ function image_downsize_scale( $exactdn_args ) {
1100
+ if ( ! is_array( $exactdn_args ) ) {
1101
+ return $exactdn_args;
1102
+ }
1103
+ if ( ! empty( $exactdn_args['resize'] ) ) {
1104
+ $exactdn_args['fit'] = $exactdn_args['resize'];
1105
+ unset( $exactdn_args['resize'] );
1106
+ }
1107
+ return $exactdn_args;
1108
+ }
1109
+
1110
  /**
1111
  * Filter post thumbnail image retrieval, passing images through ExactDN.
1112
  *
1120
  function filter_image_downsize( $image, $attachment_id, $size ) {
1121
  $started = microtime( true );
1122
  ewwwio_debug_message( '<b>' . __FUNCTION__ . '()</b>' );
1123
+
1124
  // Don't foul up the admin side of things, unless a plugin wants to.
1125
  if ( is_admin() &&
1126
  /**
1128
  *
1129
  * Note: enabling this will result in ExactDN URLs added to your post content, which could make migrations across domains (and off ExactDN) a bit more challenging.
1130
  *
1131
+ * @param bool false Allow ExactDN to run on the Dashboard. Default to false.
1132
  * @param array $args {
1133
  * Array of image details.
1134
  *
1227
  $has_size_meta = true;
1228
  }
1229
 
 
1230
  $transform = $image_args['crop'] ? 'resize' : 'fit';
1231
 
1232
  // Check specified image dimensions and account for possible zero values; ExactDN fails to resize if a dimension is zero.
1237
  $exactdn_args['w'] = $image_args['width'];
1238
  }
1239
  } else {
1240
+ if ( ! isset( $image_meta['sizes'] ) ) {
1241
+ $size_meta = $image_meta;
1242
+ // Because we don't have the "real" meta, just the height/width for the specific size.
1243
+ $image_meta = wp_get_attachment_metadata( $attachment_id );
1244
+ }
1245
+ if ( 'resize' === $transform && $image_meta && isset( $image_meta['width'], $image_meta['height'] ) ) {
1246
+ // Lets make sure that we don't upscale images since wp never upscales them as well.
1247
+ $smaller_width = ( ( $image_meta['width'] < $image_args['width'] ) ? $image_meta['width'] : $image_args['width'] );
1248
+ $smaller_height = ( ( $image_meta['height'] < $image_args['height'] ) ? $image_meta['height'] : $image_args['height'] );
1249
 
1250
+ $exactdn_args[ $transform ] = $smaller_width . ',' . $smaller_height;
 
1251
  } else {
1252
  $exactdn_args[ $transform ] = $image_args['width'] . ',' . $image_args['height'];
1253
  }
1254
  }
1255
 
1256
+ if ( empty( $image_meta['sizes'] ) && ! empty( $size_meta ) ) {
1257
+ $image_meta['sizes'][ $size ] = $size_meta;
1258
+ }
1259
  if ( ! empty( $image_meta['sizes'] ) && 'full' !== $size && ! empty( $image_meta['sizes'][ $size ]['file'] ) ) {
1260
  $image_url_basename = wp_basename( $image_url );
1261
  $intermediate_url = str_replace( $image_url_basename, $image_meta['sizes'][ $size ]['file'], $image_url );
1262
 
1263
+ if ( empty( $image_meta['width'] ) || empty( $image_meta['height'] ) ) {
1264
+ list( $filename_width, $filename_height ) = $this->get_dimensions_from_filename( $intermediate_url );
1265
+ }
1266
+ $filename_width = $image_meta['width'] ? $image_meta['width'] : $filename_width;
1267
+ $filename_height = $image_meta['height'] ? $image_meta['height'] : $filename_height;
1268
  if ( $filename_width && $filename_height && $image_args['width'] === $filename_width && $image_args['height'] === $filename_height ) {
1269
  $image_url = $intermediate_url;
1270
  } else {
1274
  $resize_existing = true;
1275
  }
1276
 
1277
+ $exactdn_args = $resize_existing && 'full' !== $size ? $this->maybe_smart_crop( $exactdn_args, $attachment_id, $image_meta ) : array();
1278
 
1279
  /**
1280
  * Filter the ExactDN arguments added to an image, when that image size is a string.
1294
  $exactdn_args = apply_filters( 'exactdn_image_downsize_string', $exactdn_args, compact( 'image_args', 'image_url', 'attachment_id', 'size', 'transform' ) );
1295
 
1296
  // Generate ExactDN URL.
1297
+ $image = array(
1298
+ $this->generate_url( $image_url, $exactdn_args ),
1299
+ $has_size_meta ? $image_args['width'] : false,
1300
+ $has_size_meta ? $image_args['height'] : false,
1301
+ $intermediate,
1302
+ );
 
 
 
 
 
 
 
 
 
1303
  } elseif ( is_array( $size ) ) {
1304
  // Pull width and height values from the provided array, if possible.
1305
  $width = isset( $size[0] ) ? (int) $size[0] : false;
1332
 
1333
  // Expose arguments to a filter before passing to ExactDN.
1334
  $exactdn_args = array(
1335
+ 'resize' => $width . ',' . $height,
1336
  );
1337
 
1338
  $exactdn_args = $this->maybe_smart_crop( $exactdn_args, $attachment_id, $image_meta );
1403
  ) {
1404
  return $sources;
1405
  }
1406
+
1407
  if ( ! is_array( $sources ) ) {
1408
  return $sources;
1409
  }
1410
+
1411
  $upload_dir = wp_get_upload_dir();
1412
  $resize_existing = defined( 'EXACTDN_RESIZE_EXISTING' ) && EXACTDN_RESIZE_EXISTING;
1413
 
 
 
1414
  foreach ( $sources as $i => $source ) {
1415
  if ( ! $this->validate_image_url( $source['url'] ) ) {
1416
  continue;
1429
  $sources[ $i ]['url'] = $this->generate_url( $source['url'] );
1430
  continue;
1431
  }
1432
+
1433
+ if ( $image_meta && ! empty( $image_meta['width'] ) ) {
1434
+ if ( ( $height && $image_meta['height'] == $height && $width && $image_meta['width'] == $width ) ||
1435
+ ( ! $height && ! $width && $image_meta['width'] == $source['value'] )
1436
+ ) {
1437
+ ewwwio_debug_message( "preventing further processing for (detected) full-size $url" );
1438
+ $sources[ $i ]['url'] = $this->generate_url( $source['url'] );
1439
+ continue;
1440
+ }
1441
+ }
1442
+
1443
  ewwwio_debug_message( 'continuing: ' . $width . ' vs. ' . $source['value'] );
1444
 
1445
  // It's quicker to get the full size with the data we have already, if available.
1505
  if ( abs( $constrained_size[0] - $expected_size[0] ) <= 1 && abs( $constrained_size[1] - $expected_size[1] ) <= 1 ) {
1506
  ewwwio_debug_message( 'soft cropping' );
1507
  $crop = 'soft';
1508
+ $base = $this->get_content_width(); // Provide a default width if none set by the theme.
1509
  } else {
1510
  ewwwio_debug_message( 'hard cropping' );
1511
  $crop = 'hard';
1579
  return $sizes;
1580
  }
1581
  $content_width = $this->get_content_width();
 
 
 
1582
 
1583
  if ( ( is_array( $size ) && $size[0] < $content_width ) ) {
1584
  return $sizes;
1764
  return $args;
1765
  }
1766
 
1767
+ /**
1768
+ * Check if this is a REST API request that we should handle (or not).
1769
+ *
1770
+ * @param WP_HTTP_Response $response Result to send to the client. Usually a WP_REST_Response.
1771
+ * @param WP_REST_Server $handler ResponseHandler instance (usually WP_REST_Server).
1772
+ * @param WP_REST_Request $request Request used to generate the response.
1773
+ * @return WP_HTTP_Response The result, unaltered.
1774
+ */
1775
+ function parse_restapi_maybe( $response, $handler, $request ) {
1776
+ ewwwio_debug_message( '<b>' . __FUNCTION__ . '()</b>' );
1777
+ if ( ! is_a( $request, 'WP_REST_Request' ) ) {
1778
+ ewwwio_debug_message( 'oddball REST request or handler' );
1779
+ return $response; // Something isn't right, bail.
1780
+ }
1781
+ $route = $request->get_route();
1782
+ if ( is_string( $route ) ) {
1783
+ ewwwio_debug_message( "current REST route is $route" );
1784
+ }
1785
+ if ( is_string( $route ) && false !== strpos( $route, 'wp/v2/media/' ) && ! empty( $request['context'] ) && 'edit' === $request['context'] ) {
1786
+ ewwwio_debug_message( 'REST API media endpoint from post editor' );
1787
+ // We don't want ExactDN urls anywhere near the editor, so disable everything we can.
1788
+ add_filter( 'exactdn_override_image_downsize', '__return_true', PHP_INT_MAX );
1789
+ add_filter( 'exactdn_skip_image', '__return_true', PHP_INT_MAX ); // This skips existing srcset indices.
1790
+ add_filter( 'exactdn_srcset_multipliers', '__return_false', PHP_INT_MAX ); // This one skips the additional multipliers.
1791
+ }
1792
+ return $response;
1793
+ }
1794
+
1795
  /**
1796
  * Make sure the image domain is on the list of approved domains.
1797
  *
1917
  // Extracts the file path to the image minus the base url.
1918
  $file_path = substr( $stripped_src, strlen( $upload_dir['baseurl'] ) );
1919
 
1920
+ if ( is_file( $upload_dir['basedir'] . $file_path ) ) {
1921
  $src = $stripped_src;
1922
  }
1923
  ewwwio_debug_message( 'stripped dims' );
common.php CHANGED
@@ -23,7 +23,7 @@ if ( ! defined( 'ABSPATH' ) ) {
23
  exit;
24
  }
25
 
26
- define( 'EWWW_IMAGE_OPTIMIZER_VERSION', '450.0' );
27
 
28
  // Initialize a couple globals.
29
  $ewww_debug = '';
@@ -39,11 +39,8 @@ if ( ! isset( $wpdb->ewwwio_images ) ) {
39
  $wpdb->ewwwio_images = $wpdb->prefix . 'ewwwio_images';
40
  }
41
 
42
- // Check for Pantheon environment, and turn on relative folder usage at level 3.
43
- if ( ! empty( $_ENV['PANTHEON_ENVIRONMENT'] ) && in_array( $_ENV['PANTHEON_ENVIRONMENT'], array( 'test', 'live', 'dev' ) ) ) {
44
- if ( ! defined( 'EWWW_IMAGE_OPTIMIZER_RELATIVE' ) ) {
45
- define( 'EWWW_IMAGE_OPTIMIZER_RELATIVE', 3 );
46
- }
47
  }
48
 
49
  // Used for manipulating exif info.
@@ -486,10 +483,6 @@ function ewww_image_optimizer_upgrade() {
486
  ewww_image_optimizer_enable_background_optimization();
487
  ewww_image_optimizer_install_table();
488
  ewww_image_optimizer_set_defaults();
489
- if ( ! ewww_image_optimizer_get_option( 'ewww_image_optimizer_cloud_key' ) || ewww_image_optimizer_get_option( 'ewww_image_optimizer_jpg_level' ) < 30 ) {
490
- add_site_option( 'exactdn_lossy', true );
491
- update_option( 'exactdn_lossy', true );
492
- }
493
  // This will get re-enabled if things are too slow.
494
  ewww_image_optimizer_set_option( 'exactdn_prevent_db_queries', false );
495
  delete_option( 'ewww_image_optimizer_exactdn_verify_method' );
@@ -515,8 +508,13 @@ function ewww_image_optimizer_upgrade() {
515
  if ( get_option( 'ewww_image_optimizer_version' ) > 0 && get_option( 'ewww_image_optimizer_version' ) < 434 && ! ewww_image_optimizer_get_option( 'ewww_image_optimizer_jpegtran_copy' ) ) {
516
  ewww_image_optimizer_set_option( 'ewww_image_optimizer_metadata_remove', false );
517
  }
 
 
 
 
518
  ewww_image_optimizer_remove_obsolete_settings();
519
  update_option( 'ewww_image_optimizer_version', EWWW_IMAGE_OPTIMIZER_VERSION );
 
520
  }
521
  ewwwio_memory( __FUNCTION__ );
522
  }
@@ -811,7 +809,8 @@ function ewww_image_optimizer_ajax_compat_check() {
811
  if ( ! empty( $_REQUEST['action'] ) ) {
812
  if ( 'regeneratethumbnail' == $_REQUEST['action'] ||
813
  'meauh_save_image' == $_REQUEST['action'] ||
814
- 'hotspot_save' == $_REQUEST['action']
 
815
  ) {
816
  ewwwio_debug_message( 'doing regeneratethumbnail' );
817
  ewww_image_optimizer_image_sizes( false );
@@ -1118,7 +1117,14 @@ function ewww_image_optimizer_install_table() {
1118
  // See if the path column exists, and what collation it uses to determine the column index size.
1119
  if ( $wpdb->get_var( "SHOW TABLES LIKE '$wpdb->ewwwio_images'" ) == $wpdb->ewwwio_images ) {
1120
  ewwwio_debug_message( 'upgrading table and checking collation for path, table exists' );
 
 
 
 
 
 
1121
  $wpdb->query( "UPDATE $wpdb->ewwwio_images SET updated = '1971-01-01 00:00:00' WHERE updated < '1001-01-01 00:00:01'" );
 
1122
  $column_collate = $wpdb->get_col_charset( $wpdb->ewwwio_images, 'path' );
1123
  if ( ! empty( $column_collate ) && ! is_wp_error( $column_collate ) && 'utf8mb4' !== $column_collate ) {
1124
  $path_index_size = 255;
@@ -1199,7 +1205,7 @@ function ewww_image_optimizer_install_table() {
1199
  updated timestamp DEFAULT '1971-01-01 00:00:00' ON UPDATE CURRENT_TIMESTAMP,
1200
  trace blob,
1201
  UNIQUE KEY id (id),
1202
- KEY path_image_size (path($path_index_size),image_size),
1203
  KEY attachment_info (gallery(3),attachment_id)
1204
  ) $db_collation;";
1205
 
@@ -5225,7 +5231,13 @@ function ewww_image_optimizer_resize_from_meta_data( $meta, $id = null, $log = t
5225
  'type' => $type,
5226
  )
5227
  );
5228
- $ewwwio_media_background->save()->dispatch();
 
 
 
 
 
 
5229
  set_transient( 'ewwwio-background-in-progress-' . $id, true, 24 * HOUR_IN_SECONDS );
5230
  if ( $log ) {
5231
  ewww_image_optimizer_debug_log();
@@ -7027,7 +7039,7 @@ function ewww_image_optimizer_htaccess_path() {
7027
  if ( get_option( 'siteurl' ) !== get_option( 'home' ) ) {
7028
  ewwwio_debug_message( 'WordPress Address and Site Address are different, possible subdir install' );
7029
  $path_diff = str_replace( get_option( 'home' ), '', get_option( 'siteurl' ) );
7030
- $newhtpath = trailingslashit( $htpath . $path_diff ) . '.htaccess';
7031
  if ( is_file( $newhtpath ) ) {
7032
  ewwwio_debug_message( 'subdir install confirmed' );
7033
  ewwwio_debug_message( "using $newhtpath" );
@@ -7280,6 +7292,7 @@ function ewww_image_optimizer_network_singlesite_options() {
7280
  */
7281
  function ewww_image_optimizer_options( $network = 'singlesite' ) {
7282
  ewwwio_debug_message( '<b>' . __FUNCTION__ . '()</b>' );
 
7283
  ewwwio_debug_message( 'ABSPATH: ' . ABSPATH );
7284
  ewwwio_debug_message( 'WP_CONTENT_DIR: ' . WP_CONTENT_DIR );
7285
  ewwwio_debug_message( 'home url: ' . get_home_url() );
@@ -8131,7 +8144,7 @@ function ewww_image_optimizer_options( $network = 'singlesite' ) {
8131
  <?php
8132
  }
8133
  ewwwio_memory( __FUNCTION__ );
8134
- ewww_image_optimizer_debug_log();
8135
  }
8136
 
8137
  /**
@@ -8322,11 +8335,6 @@ function ewwwio_debug_message( $message ) {
8322
  $memory_limit = ewwwio_memory_limit();
8323
  if ( strlen( $message ) + 4000000 + memory_get_usage( true ) <= $memory_limit ) {
8324
  global $ewww_debug;
8325
- global $ewww_version_dumped;
8326
- if ( empty( $ewww_debug ) && empty( $ewww_version_dumped ) ) {
8327
- ewwwio_debug_version_info();
8328
- $ewww_version_dumped = true;
8329
- }
8330
  $message = str_replace( "\n\n\n", '<br>', $message );
8331
  $message = str_replace( "\n\n", '<br>', $message );
8332
  $message = str_replace( "\n", '<br>', $message );
@@ -8499,16 +8507,16 @@ function ewww_image_optimizer_dynamic_image_debug() {
8499
  */
8500
  function ewww_image_optimizer_image_queue_debug() {
8501
  ewwwio_debug_message( '<b>' . __FUNCTION__ . '()</b>' );
 
 
 
 
 
 
 
8502
  // Let user clear a queue, or all queues.
8503
  if ( isset( $_POST['ewww_image_optimizer_clear_queue'] ) && current_user_can( 'manage_options' ) && wp_verify_nonce( $_POST['ewww_nonce'], 'ewww_image_optimizer_clear_queue' ) ) {
8504
  if ( is_numeric( $_POST['ewww_image_optimizer_clear_queue'] ) ) {
8505
- global $ewwwio_media_background;
8506
- if ( ! class_exists( 'WP_Background_Process' ) ) {
8507
- require_once( EWWW_IMAGE_OPTIMIZER_PLUGIN_PATH . 'background.php' );
8508
- }
8509
- if ( ! is_object( $ewwwio_media_background ) ) {
8510
- $ewwwio_media_background = new EWWWIO_Media_Background_Process();
8511
- }
8512
  $queues = (int) $_POST['ewww_image_optimizer_clear_queue'];
8513
  while ( $queues ) {
8514
  $ewwwio_media_background->cancel_process();
@@ -8551,6 +8559,8 @@ function ewww_image_optimizer_image_queue_debug() {
8551
  if ( empty( $queues ) ) {
8552
  esc_html_e( 'Nothing to see here, go upload some images!', 'ewww-image-optimizer' );
8553
  } else {
 
 
8554
  $all_ids = array();
8555
  foreach ( $queues as $queue ) {
8556
  $ids = array();
@@ -8561,6 +8571,8 @@ function ewww_image_optimizer_image_queue_debug() {
8561
  $all_ids[] = $item['id'];
8562
  $ids[] = $item['id'];
8563
  }
 
 
8564
  $ids = implode( ',', $ids );
8565
  ?>
8566
  <form id="ewww-queue-clear-<?php echo $queue['option_id']; ?>" method="post" style="margin-bottom: 1.5em;" action="">
23
  exit;
24
  }
25
 
26
+ define( 'EWWW_IMAGE_OPTIMIZER_VERSION', '451.0' );
27
 
28
  // Initialize a couple globals.
29
  $ewww_debug = '';
39
  $wpdb->ewwwio_images = $wpdb->prefix . 'ewwwio_images';
40
  }
41
 
42
+ if ( ! defined( 'EWWW_IMAGE_OPTIMIZER_RELATIVE' ) ) {
43
+ define( 'EWWW_IMAGE_OPTIMIZER_RELATIVE', true );
 
 
 
44
  }
45
 
46
  // Used for manipulating exif info.
483
  ewww_image_optimizer_enable_background_optimization();
484
  ewww_image_optimizer_install_table();
485
  ewww_image_optimizer_set_defaults();
 
 
 
 
486
  // This will get re-enabled if things are too slow.
487
  ewww_image_optimizer_set_option( 'exactdn_prevent_db_queries', false );
488
  delete_option( 'ewww_image_optimizer_exactdn_verify_method' );
508
  if ( get_option( 'ewww_image_optimizer_version' ) > 0 && get_option( 'ewww_image_optimizer_version' ) < 434 && ! ewww_image_optimizer_get_option( 'ewww_image_optimizer_jpegtran_copy' ) ) {
509
  ewww_image_optimizer_set_option( 'ewww_image_optimizer_metadata_remove', false );
510
  }
511
+ if ( get_option( 'ewww_image_optimizer_version' ) > 0 && get_option( 'ewww_image_optimizer_version' ) < 440 && ( ! ewww_image_optimizer_get_option( 'ewww_image_optimizer_cloud_key' ) || ewww_image_optimizer_get_option( 'ewww_image_optimizer_jpg_level' ) < 30 ) ) {
512
+ add_site_option( 'exactdn_lossy', true );
513
+ update_option( 'exactdn_lossy', true );
514
+ }
515
  ewww_image_optimizer_remove_obsolete_settings();
516
  update_option( 'ewww_image_optimizer_version', EWWW_IMAGE_OPTIMIZER_VERSION );
517
+ ewww_image_optimizer_debug_log();
518
  }
519
  ewwwio_memory( __FUNCTION__ );
520
  }
809
  if ( ! empty( $_REQUEST['action'] ) ) {
810
  if ( 'regeneratethumbnail' == $_REQUEST['action'] ||
811
  'meauh_save_image' == $_REQUEST['action'] ||
812
+ 'hotspot_save' == $_REQUEST['action'] ||
813
+ false !== strpos( $_REQUEST['action'], 'wc_regenerate_images' )
814
  ) {
815
  ewwwio_debug_message( 'doing regeneratethumbnail' );
816
  ewww_image_optimizer_image_sizes( false );
1117
  // See if the path column exists, and what collation it uses to determine the column index size.
1118
  if ( $wpdb->get_var( "SHOW TABLES LIKE '$wpdb->ewwwio_images'" ) == $wpdb->ewwwio_images ) {
1119
  ewwwio_debug_message( 'upgrading table and checking collation for path, table exists' );
1120
+ // Check if the old path_image_size index exists, and drop it.
1121
+ if ( $wpdb->get_results( "SHOW INDEX FROM $wpdb->ewwwio_images WHERE Key_name = 'path_image_size'", ARRAY_A ) ) {
1122
+ ewwwio_debug_message( 'getting rid of path_image_size index' );
1123
+ $wpdb->query( "ALTER TABLE $wpdb->ewwwio_images DROP INDEX path_image_size" );
1124
+ }
1125
+ // Make sure there are valid dates in updated column.
1126
  $wpdb->query( "UPDATE $wpdb->ewwwio_images SET updated = '1971-01-01 00:00:00' WHERE updated < '1001-01-01 00:00:01'" );
1127
+ // Check the current collation and adjust it if necessary.
1128
  $column_collate = $wpdb->get_col_charset( $wpdb->ewwwio_images, 'path' );
1129
  if ( ! empty( $column_collate ) && ! is_wp_error( $column_collate ) && 'utf8mb4' !== $column_collate ) {
1130
  $path_index_size = 255;
1205
  updated timestamp DEFAULT '1971-01-01 00:00:00' ON UPDATE CURRENT_TIMESTAMP,
1206
  trace blob,
1207
  UNIQUE KEY id (id),
1208
+ KEY path (path($path_index_size)),
1209
  KEY attachment_info (gallery(3),attachment_id)
1210
  ) $db_collation;";
1211
 
5231
  'type' => $type,
5232
  )
5233
  );
5234
+ if ( 5 > $ewwwio_media_background->count_queue() ) {
5235
+ $ewwwio_media_background->save()->dispatch();
5236
+ ewwwio_debug_message( 'small queue, dispatching post-haste' );
5237
+ } else {
5238
+ ewwwio_debug_message( 'detected queued items in progress, saving without dispatch' );
5239
+ $ewwwio_media_background->save();
5240
+ }
5241
  set_transient( 'ewwwio-background-in-progress-' . $id, true, 24 * HOUR_IN_SECONDS );
5242
  if ( $log ) {
5243
  ewww_image_optimizer_debug_log();
7039
  if ( get_option( 'siteurl' ) !== get_option( 'home' ) ) {
7040
  ewwwio_debug_message( 'WordPress Address and Site Address are different, possible subdir install' );
7041
  $path_diff = str_replace( get_option( 'home' ), '', get_option( 'siteurl' ) );
7042
+ $newhtpath = trailingslashit( rtrim( $htpath, '/' ) . '/' . ltrim( $path_diff, '/' ) ) . '.htaccess';
7043
  if ( is_file( $newhtpath ) ) {
7044
  ewwwio_debug_message( 'subdir install confirmed' );
7045
  ewwwio_debug_message( "using $newhtpath" );
7292
  */
7293
  function ewww_image_optimizer_options( $network = 'singlesite' ) {
7294
  ewwwio_debug_message( '<b>' . __FUNCTION__ . '()</b>' );
7295
+ ewwwio_debug_version_info();
7296
  ewwwio_debug_message( 'ABSPATH: ' . ABSPATH );
7297
  ewwwio_debug_message( 'WP_CONTENT_DIR: ' . WP_CONTENT_DIR );
7298
  ewwwio_debug_message( 'home url: ' . get_home_url() );
8144
  <?php
8145
  }
8146
  ewwwio_memory( __FUNCTION__ );
8147
+ $ewww_debug = '';
8148
  }
8149
 
8150
  /**
8335
  $memory_limit = ewwwio_memory_limit();
8336
  if ( strlen( $message ) + 4000000 + memory_get_usage( true ) <= $memory_limit ) {
8337
  global $ewww_debug;
 
 
 
 
 
8338
  $message = str_replace( "\n\n\n", '<br>', $message );
8339
  $message = str_replace( "\n\n", '<br>', $message );
8340
  $message = str_replace( "\n", '<br>', $message );
8507
  */
8508
  function ewww_image_optimizer_image_queue_debug() {
8509
  ewwwio_debug_message( '<b>' . __FUNCTION__ . '()</b>' );
8510
+ global $ewwwio_media_background;
8511
+ if ( ! class_exists( 'WP_Background_Process' ) ) {
8512
+ require_once( EWWW_IMAGE_OPTIMIZER_PLUGIN_PATH . 'background.php' );
8513
+ }
8514
+ if ( ! is_object( $ewwwio_media_background ) ) {
8515
+ $ewwwio_media_background = new EWWWIO_Media_Background_Process();
8516
+ }
8517
  // Let user clear a queue, or all queues.
8518
  if ( isset( $_POST['ewww_image_optimizer_clear_queue'] ) && current_user_can( 'manage_options' ) && wp_verify_nonce( $_POST['ewww_nonce'], 'ewww_image_optimizer_clear_queue' ) ) {
8519
  if ( is_numeric( $_POST['ewww_image_optimizer_clear_queue'] ) ) {
 
 
 
 
 
 
 
8520
  $queues = (int) $_POST['ewww_image_optimizer_clear_queue'];
8521
  while ( $queues ) {
8522
  $ewwwio_media_background->cancel_process();
8559
  if ( empty( $queues ) ) {
8560
  esc_html_e( 'Nothing to see here, go upload some images!', 'ewww-image-optimizer' );
8561
  } else {
8562
+ $queue_count = $ewwwio_media_background->count_queue();
8563
+ echo "<p><strong>$queue_count</strong> items in all queues</p>";
8564
  $all_ids = array();
8565
  foreach ( $queues as $queue ) {
8566
  $ids = array();
8571
  $all_ids[] = $item['id'];
8572
  $ids[] = $item['id'];
8573
  }
8574
+ $queue_count = count( $ids );
8575
+ echo "<strong>$queue_count</strong> items in queue<br>";
8576
  $ids = implode( ',', $ids );
8577
  ?>
8578
  <form id="ewww-queue-clear-<?php echo $queue['option_id']; ?>" method="post" style="margin-bottom: 1.5em;" action="">
ewww-image-optimizer.php CHANGED
@@ -14,7 +14,7 @@ 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
  Text Domain: ewww-image-optimizer
17
- Version: 4.5.0
18
  Author URI: https://ewww.io/
19
  License: GPLv3
20
  */
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
  Text Domain: ewww-image-optimizer
17
+ Version: 4.5.1
18
  Author URI: https://ewww.io/
19
  License: GPLv3
20
  */
includes/load_webp.js CHANGED
@@ -519,13 +519,6 @@ function ewww_load_images(ewww_webp_supported) {
519
  $(this).ewwwattr('data-thumb', $(this).attr('data-webp-thumb'));
520
  });
521
  }
522
- // we should not need this section, as it should be covered by ewww_webp_lazy_load
523
- $('img.ewww_webp_lazy_retina').each(function() {
524
- if (ewww_webp_supported) {
525
- $(this).ewwwattr('data-srcset', $(this).attr('data-srcset-webp'));
526
- }
527
- $(this).removeClass('ewww_webp_lazy_retina');
528
- });
529
  $('video').each(function() {
530
  if (ewww_webp_supported) {
531
  $(this).ewwwattr('poster', $(this).attr('data-poster-webp'));
@@ -542,6 +535,10 @@ function ewww_load_images(ewww_webp_supported) {
542
  $(this).ewwwattr('data-orig-file', $(this).attr('data-webp-orig-file'));
543
  $(this).ewwwattr('data-medium-file', $(this).attr('data-webp-medium-file'));
544
  $(this).ewwwattr('data-large-file', $(this).attr('data-webp-large-file'));
 
 
 
 
545
  }
546
  $(this).removeClass('ewww_webp_lazy_load');
547
  });
519
  $(this).ewwwattr('data-thumb', $(this).attr('data-webp-thumb'));
520
  });
521
  }
 
 
 
 
 
 
 
522
  $('video').each(function() {
523
  if (ewww_webp_supported) {
524
  $(this).ewwwattr('poster', $(this).attr('data-poster-webp'));
535
  $(this).ewwwattr('data-orig-file', $(this).attr('data-webp-orig-file'));
536
  $(this).ewwwattr('data-medium-file', $(this).attr('data-webp-medium-file'));
537
  $(this).ewwwattr('data-large-file', $(this).attr('data-webp-large-file'));
538
+ var jpsrcset = $(this).attr('srcset');
539
+ if (typeof jpsrcset !== typeof undefined && jpsrcset !== false && jpsrcset.includes('R0lGOD')) {
540
+ $(this).ewwwattr('src', $(this).attr('data-lazy-src-webp'));
541
+ }
542
  }
543
  $(this).removeClass('ewww_webp_lazy_load');
544
  });
includes/load_webp.min.js CHANGED
@@ -1 +1 @@
1
- var Arrive=function(w,e,c){"use strict";if(w.MutationObserver&&"undefined"!=typeof HTMLElement){var a,t,r=0,d=(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&&d.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!==w||(e=[e]),e}}),u=((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 u,s=this,o={fireOnAttributesModification:!1};return l.beforeAdding(function(t){var e,a=t.target;a!==w.document&&a!==w||(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=s}),l.beforeRemoving(function(e){e.observer.disconnect()}),this.bindEvent=function(e,t,a){t=d.mergeArrays(o,t);for(var r=d.toElementsArray(this),i=0;i<r.length;i++)l.addEvent(r[i],e,t,a)},this.unbindEvent=function(){var a=d.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=d.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=d.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 o={fireOnAttributesModification:!1,onceOnly:!1,existing:!1};function n(e,t,a){return!(!d.matchesSelector(e,t.selector)||(e._id===c&&(e._id=r++),-1!=t.firedElems.indexOf(e._id))||(t.firedElems.push(e._id),0))}var w=(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?d.checkChildNodesRecursively(t,i,n,r):"attributes"===e.type&&n(a,i)&&r.push({callback:i.callback,elem:a}),d.callCallbacks(r,i)})})).bindEvent;return i.bindEvent=function(e,t,a){void 0===a?(a=t,t=o):t=d.mergeArrays(o,t);var r=d.toElementsArray(this);if(t.existing){for(var i=[],n=0;n<r.length;n++)for(var l=r[n].querySelectorAll(e),s=0;s<l.length;s++)i.push({callback:a,elem:l[s]});if(t.onceOnly&&i.length)return a.call(i[0].elem,i[0].elem);setTimeout(d.callCallbacks,1,i)}w.call(this,e,t,a)},i},s=new function(){var r={};function i(e,t){return d.matchesSelector(e,t.selector)}var n=(s=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&&d.checkChildNodesRecursively(t,r,i,a),d.callCallbacks(a,r)})})).bindEvent;return s.bindEvent=function(e,t,a){void 0===a?(a=t,t=r):t=d.mergeArrays(r,t),n.call(this,e,t,a)},s};e&&h(e.fn),h(HTMLElement.prototype),h(NodeList.prototype),h(HTMLCollection.prototype),h(HTMLDocument.prototype),h(Window.prototype);var n={};return o(i,n,"unbindAllArrive"),o(s,n,"unbindAllLeave"),n}function o(e,t,a){d.addMethod(t,a,e.unbindEvent),d.addMethod(t,a,e.unbindEventWithSelectorOrCallback),d.addMethod(t,a,e.unbindEventWithSelectorAndCallback)}function h(e){e.arrive=i.bindEvent,o(i,e,"unbindArrive"),e.leave=s.bindEvent,o(s,e,"unbindLeave")}}(window,"undefined"==typeof jQuery?null:jQuery,void 0);function check_webp_feature(e,t){var a=new Image;a.onload=function(){ewww_webp_supported=0<a.width&&0<a.height,t(ewww_webp_supported)},a.onerror=function(){t(ewww_webp_supported=!1)},a.src="data:image/webp;base64,"+{alpha:"UklGRkoAAABXRUJQVlA4WAoAAAAQAAAAAAAAAAAAQUxQSAwAAAARBxAR/Q9ERP8DAABWUDggGAAAABQBAJ0BKgEAAQAAAP4AAA3AAP7mtQAAAA==",animation:"UklGRlIAAABXRUJQVlA4WAoAAAASAAAAAAAAAAAAQU5JTQYAAAD/////AABBTk1GJgAAAAAAAAAAAAAAAAAAAGQAAABWUDhMDQAAAC8AAAAQBxAREYiI/gcA"}[e]}function ewww_load_images(t){!function(n){n.fn.extend({ewwwattr:function(e,t){return void 0!==t&&!1!==t&&this.attr(e,t),this}});t&&(n(".batch-image img, .image-wrapper a, .ngg-pro-masonry-item a, .ngg-galleria-offscreen-seo-wrapper a").each(function(){n(this).ewwwattr("data-src",n(this).attr("data-webp")),n(this).ewwwattr("data-thumbnail",n(this).attr("data-webp-thumbnail"))}),n(".image-wrapper a, .ngg-pro-masonry-item a").each(function(){n(this).ewwwattr("href",n(this).attr("data-webp"))}),n(".rev_slider ul li").each(function(){n(this).ewwwattr("data-thumb",n(this).attr("data-webp-thumb"));for(var e=1;e<11;)n(this).ewwwattr("data-param"+e,n(this).attr("data-webp-param"+e)),e++}),n(".rev_slider img").each(function(){n(this).ewwwattr("data-lazyload",n(this).attr("data-webp-lazyload"))}),n("div.woocommerce-product-gallery__image").each(function(){n(this).ewwwattr("data-thumb",n(this).attr("data-webp-thumb"))})),n("img.ewww_webp_lazy_retina").each(function(){t&&n(this).ewwwattr("data-srcset",n(this).attr("data-srcset-webp")),n(this).removeClass("ewww_webp_lazy_retina")}),n("video").each(function(){t?n(this).ewwwattr("poster",n(this).attr("data-poster-webp")):n(this).ewwwattr("poster",n(this).attr("data-poster-image"))}),n("img.ewww_webp_lazy_load").each(function(){t&&(n(this).ewwwattr("data-lazy-srcset",n(this).attr("data-lazy-srcset-webp")),n(this).ewwwattr("data-srcset",n(this).attr("data-srcset-webp")),n(this).ewwwattr("data-lazy-src",n(this).attr("data-lazy-src-webp")),n(this).ewwwattr("data-src",n(this).attr("data-src-webp")),n(this).ewwwattr("data-orig-file",n(this).attr("data-webp-orig-file")),n(this).ewwwattr("data-medium-file",n(this).attr("data-webp-medium-file")),n(this).ewwwattr("data-large-file",n(this).attr("data-webp-large-file"))),n(this).removeClass("ewww_webp_lazy_load")}),n(".ewww_webp").each(function(){var e=document.createElement("img");t?(n(e).ewwwattr("src",n(this).attr("data-webp")),n(e).ewwwattr("srcset",n(this).attr("data-srcset-webp")),n(e).ewwwattr("data-orig-file",n(this).attr("data-orig-file")),n(e).ewwwattr("data-orig-file",n(this).attr("data-webp-orig-file")),n(e).ewwwattr("data-medium-file",n(this).attr("data-medium-file")),n(e).ewwwattr("data-medium-file",n(this).attr("data-webp-medium-file")),n(e).ewwwattr("data-large-file",n(this).attr("data-large-file")),n(e).ewwwattr("data-large-file",n(this).attr("data-webp-large-file")),n(e).ewwwattr("data-large_image",n(this).attr("data-large_image")),n(e).ewwwattr("data-large_image",n(this).attr("data-webp-large_image")),n(e).ewwwattr("data-src",n(this).attr("data-src")),n(e).ewwwattr("data-src",n(this).attr("data-webp-src"))):(n(e).ewwwattr("src",n(this).attr("data-img")),n(e).ewwwattr("srcset",n(this).attr("data-srcset-img")),n(e).ewwwattr("data-orig-file",n(this).attr("data-orig-file")),n(e).ewwwattr("data-medium-file",n(this).attr("data-medium-file")),n(e).ewwwattr("data-large-file",n(this).attr("data-large-file")),n(e).ewwwattr("data-large_image",n(this).attr("data-large_image")),n(e).ewwwattr("data-src",n(this).attr("data-src"))),e=function(e,t){for(var a=["align","alt","border","crossorigin","height","hspace","ismap","longdesc","usemap","vspace","width","accesskey","class","contenteditable","contextmenu","dir","draggable","dropzone","hidden","id","lang","spellcheck","style","tabindex","title","translate","sizes","data-caption","data-attachment-id","data-permalink","data-orig-size","data-comments-opened","data-image-meta","data-image-title","data-image-description","data-event-trigger","data-highlight-color","data-highlight-opacity","data-highlight-border-color","data-highlight-border-width","data-highlight-border-opacity","data-no-lazy","data-lazy","data-large_image_width","data-large_image_height"],r=0,i=a.length;r<i;r++)n(t).ewwwattr(a[r],n(e).attr("data-"+a[r]));return t}(this,e),n(this).after(e),n(this).removeClass("ewww_webp")})}(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()}))}var ewww_webp_supported=!1,ewww_jquery_waiting_timer=0;function ewww_ngg_plus_parse_galleries(e){e&&jQuery.each(galleries,function(e,t){galleries[e].images_list=ewww_ngg_plus_parse_image_list(t.images_list)})}function ewww_ngg_plus_load_galleries(e){var i;e&&((i=jQuery)(window).on("ngg.galleria.themeadded",function(e,t){window.ngg_galleria._create_backup=window.ngg_galleria.create,window.ngg_galleria.create=function(e,t){var a=i(e).data("id");return galleries["gallery_"+a].images_list=ewww_ngg_plus_parse_image_list(galleries["gallery_"+a].images_list),window.ngg_galleria._create_backup(e,t)}}),i(window).on("override_nplModal_methods",function(e,r){r._set_events_backup=r.set_events,r.set_events=function(){return i("#npl_content").bind("npl_images_ready",function(e,t){var a=r.fetch_images.gallery_image_cache[t];a=ewww_ngg_plus_parse_image_list(a)}),r._set_events_backup()}}))}function ewww_ngg_plus_parse_image_list(i){var e;return(e=jQuery).each(i,function(a,r){void 0!==r["image-webp"]&&(i[a].image=r["image-webp"],delete i[a]["image-webp"]),void 0!==r["thumb-webp"]&&(i[a].thumb=r["thumb-webp"],delete i[a]["thumb-webp"]),void 0!==r.full_image_webp&&(i[a].full_image=r.full_image_webp,delete i[a].full_image_webp),void 0!==r.srcsets&&e.each(r.srcsets,function(e,t){void 0!==r.srcsets[e+"-webp"]&&(i[a].srcsets[e]=r.srcsets[e+"-webp"],delete i[a].srcsets[e+"-webp"])}),void 0!==r.full_srcsets&&e.each(r.full_srcsets,function(e,t){void 0!==r.full_srcsets[e+"-webp"]&&(i[a].full_srcsets[e]=r.full_srcsets[e+"-webp"],delete i[a].full_srcsets[e+"-webp"])})}),i}ewww_jquery_waiting=setInterval(function(){if(window.jQuery){check_webp_feature("alpha",ewww_load_images),check_webp_feature("alpha",ewww_ngg_plus_load_galleries),document.arrive(".ewww_webp",function(){ewww_load_images(ewww_webp_supported)});var e=0,t=setInterval(function(){"undefined"!=typeof galleries&&(check_webp_feature("alpha",ewww_ngg_plus_parse_galleries),clearInterval(t)),1e3<(e+=25)&&clearInterval(t)},25);clearInterval(ewww_jquery_waiting)}1e4<(ewww_jquery_waiting_timer+=100)&&clearInterval(ewww_jquery_waiting)},100);
1
+ var Arrive=function(w,e,c){"use strict";if(w.MutationObserver&&"undefined"!=typeof HTMLElement){var a,t,r=0,d=(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&&d.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!==w||(e=[e]),e}}),u=((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 u,s=this,o={fireOnAttributesModification:!1};return l.beforeAdding(function(t){var e,a=t.target;a!==w.document&&a!==w||(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=s}),l.beforeRemoving(function(e){e.observer.disconnect()}),this.bindEvent=function(e,t,a){t=d.mergeArrays(o,t);for(var r=d.toElementsArray(this),i=0;i<r.length;i++)l.addEvent(r[i],e,t,a)},this.unbindEvent=function(){var a=d.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=d.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=d.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 o={fireOnAttributesModification:!1,onceOnly:!1,existing:!1};function n(e,t,a){return!(!d.matchesSelector(e,t.selector)||(e._id===c&&(e._id=r++),-1!=t.firedElems.indexOf(e._id))||(t.firedElems.push(e._id),0))}var w=(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?d.checkChildNodesRecursively(t,i,n,r):"attributes"===e.type&&n(a,i)&&r.push({callback:i.callback,elem:a}),d.callCallbacks(r,i)})})).bindEvent;return i.bindEvent=function(e,t,a){void 0===a?(a=t,t=o):t=d.mergeArrays(o,t);var r=d.toElementsArray(this);if(t.existing){for(var i=[],n=0;n<r.length;n++)for(var l=r[n].querySelectorAll(e),s=0;s<l.length;s++)i.push({callback:a,elem:l[s]});if(t.onceOnly&&i.length)return a.call(i[0].elem,i[0].elem);setTimeout(d.callCallbacks,1,i)}w.call(this,e,t,a)},i},s=new function(){var r={};function i(e,t){return d.matchesSelector(e,t.selector)}var n=(s=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&&d.checkChildNodesRecursively(t,r,i,a),d.callCallbacks(a,r)})})).bindEvent;return s.bindEvent=function(e,t,a){void 0===a?(a=t,t=r):t=d.mergeArrays(r,t),n.call(this,e,t,a)},s};e&&h(e.fn),h(HTMLElement.prototype),h(NodeList.prototype),h(HTMLCollection.prototype),h(HTMLDocument.prototype),h(Window.prototype);var n={};return o(i,n,"unbindAllArrive"),o(s,n,"unbindAllLeave"),n}function o(e,t,a){d.addMethod(t,a,e.unbindEvent),d.addMethod(t,a,e.unbindEventWithSelectorOrCallback),d.addMethod(t,a,e.unbindEventWithSelectorAndCallback)}function h(e){e.arrive=i.bindEvent,o(i,e,"unbindArrive"),e.leave=s.bindEvent,o(s,e,"unbindLeave")}}(window,"undefined"==typeof jQuery?null:jQuery,void 0);function check_webp_feature(e,t){var a=new Image;a.onload=function(){ewww_webp_supported=0<a.width&&0<a.height,t(ewww_webp_supported)},a.onerror=function(){t(ewww_webp_supported=!1)},a.src="data:image/webp;base64,"+{alpha:"UklGRkoAAABXRUJQVlA4WAoAAAAQAAAAAAAAAAAAQUxQSAwAAAARBxAR/Q9ERP8DAABWUDggGAAAABQBAJ0BKgEAAQAAAP4AAA3AAP7mtQAAAA==",animation:"UklGRlIAAABXRUJQVlA4WAoAAAASAAAAAAAAAAAAQU5JTQYAAAD/////AABBTk1GJgAAAAAAAAAAAAAAAAAAAGQAAABWUDhMDQAAAC8AAAAQBxAREYiI/gcA"}[e]}function ewww_load_images(t){!function(n){n.fn.extend({ewwwattr:function(e,t){return void 0!==t&&!1!==t&&this.attr(e,t),this}});t&&(n(".batch-image img, .image-wrapper a, .ngg-pro-masonry-item a, .ngg-galleria-offscreen-seo-wrapper a").each(function(){n(this).ewwwattr("data-src",n(this).attr("data-webp")),n(this).ewwwattr("data-thumbnail",n(this).attr("data-webp-thumbnail"))}),n(".image-wrapper a, .ngg-pro-masonry-item a").each(function(){n(this).ewwwattr("href",n(this).attr("data-webp"))}),n(".rev_slider ul li").each(function(){n(this).ewwwattr("data-thumb",n(this).attr("data-webp-thumb"));for(var e=1;e<11;)n(this).ewwwattr("data-param"+e,n(this).attr("data-webp-param"+e)),e++}),n(".rev_slider img").each(function(){n(this).ewwwattr("data-lazyload",n(this).attr("data-webp-lazyload"))}),n("div.woocommerce-product-gallery__image").each(function(){n(this).ewwwattr("data-thumb",n(this).attr("data-webp-thumb"))})),n("video").each(function(){t?n(this).ewwwattr("poster",n(this).attr("data-poster-webp")):n(this).ewwwattr("poster",n(this).attr("data-poster-image"))}),n("img.ewww_webp_lazy_load").each(function(){if(t){n(this).ewwwattr("data-lazy-srcset",n(this).attr("data-lazy-srcset-webp")),n(this).ewwwattr("data-srcset",n(this).attr("data-srcset-webp")),n(this).ewwwattr("data-lazy-src",n(this).attr("data-lazy-src-webp")),n(this).ewwwattr("data-src",n(this).attr("data-src-webp")),n(this).ewwwattr("data-orig-file",n(this).attr("data-webp-orig-file")),n(this).ewwwattr("data-medium-file",n(this).attr("data-webp-medium-file")),n(this).ewwwattr("data-large-file",n(this).attr("data-webp-large-file"));var e=n(this).attr("srcset");void 0!==e&&!1!==e&&e.includes("R0lGOD")&&n(this).ewwwattr("src",n(this).attr("data-lazy-src-webp"))}n(this).removeClass("ewww_webp_lazy_load")}),n(".ewww_webp").each(function(){var e=document.createElement("img");t?(n(e).ewwwattr("src",n(this).attr("data-webp")),n(e).ewwwattr("srcset",n(this).attr("data-srcset-webp")),n(e).ewwwattr("data-orig-file",n(this).attr("data-orig-file")),n(e).ewwwattr("data-orig-file",n(this).attr("data-webp-orig-file")),n(e).ewwwattr("data-medium-file",n(this).attr("data-medium-file")),n(e).ewwwattr("data-medium-file",n(this).attr("data-webp-medium-file")),n(e).ewwwattr("data-large-file",n(this).attr("data-large-file")),n(e).ewwwattr("data-large-file",n(this).attr("data-webp-large-file")),n(e).ewwwattr("data-large_image",n(this).attr("data-large_image")),n(e).ewwwattr("data-large_image",n(this).attr("data-webp-large_image")),n(e).ewwwattr("data-src",n(this).attr("data-src")),n(e).ewwwattr("data-src",n(this).attr("data-webp-src"))):(n(e).ewwwattr("src",n(this).attr("data-img")),n(e).ewwwattr("srcset",n(this).attr("data-srcset-img")),n(e).ewwwattr("data-orig-file",n(this).attr("data-orig-file")),n(e).ewwwattr("data-medium-file",n(this).attr("data-medium-file")),n(e).ewwwattr("data-large-file",n(this).attr("data-large-file")),n(e).ewwwattr("data-large_image",n(this).attr("data-large_image")),n(e).ewwwattr("data-src",n(this).attr("data-src"))),e=function(e,t){for(var a=["align","alt","border","crossorigin","height","hspace","ismap","longdesc","usemap","vspace","width","accesskey","class","contenteditable","contextmenu","dir","draggable","dropzone","hidden","id","lang","spellcheck","style","tabindex","title","translate","sizes","data-caption","data-attachment-id","data-permalink","data-orig-size","data-comments-opened","data-image-meta","data-image-title","data-image-description","data-event-trigger","data-highlight-color","data-highlight-opacity","data-highlight-border-color","data-highlight-border-width","data-highlight-border-opacity","data-no-lazy","data-lazy","data-large_image_width","data-large_image_height"],r=0,i=a.length;r<i;r++)n(t).ewwwattr(a[r],n(e).attr("data-"+a[r]));return t}(this,e),n(this).after(e),n(this).removeClass("ewww_webp")})}(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()}))}var ewww_webp_supported=!1,ewww_jquery_waiting_timer=0;function ewww_ngg_plus_parse_galleries(e){e&&jQuery.each(galleries,function(e,t){galleries[e].images_list=ewww_ngg_plus_parse_image_list(t.images_list)})}function ewww_ngg_plus_load_galleries(e){var i;e&&((i=jQuery)(window).on("ngg.galleria.themeadded",function(e,t){window.ngg_galleria._create_backup=window.ngg_galleria.create,window.ngg_galleria.create=function(e,t){var a=i(e).data("id");return galleries["gallery_"+a].images_list=ewww_ngg_plus_parse_image_list(galleries["gallery_"+a].images_list),window.ngg_galleria._create_backup(e,t)}}),i(window).on("override_nplModal_methods",function(e,r){r._set_events_backup=r.set_events,r.set_events=function(){return i("#npl_content").bind("npl_images_ready",function(e,t){var a=r.fetch_images.gallery_image_cache[t];a=ewww_ngg_plus_parse_image_list(a)}),r._set_events_backup()}}))}function ewww_ngg_plus_parse_image_list(i){var e;return(e=jQuery).each(i,function(a,r){void 0!==r["image-webp"]&&(i[a].image=r["image-webp"],delete i[a]["image-webp"]),void 0!==r["thumb-webp"]&&(i[a].thumb=r["thumb-webp"],delete i[a]["thumb-webp"]),void 0!==r.full_image_webp&&(i[a].full_image=r.full_image_webp,delete i[a].full_image_webp),void 0!==r.srcsets&&e.each(r.srcsets,function(e,t){void 0!==r.srcsets[e+"-webp"]&&(i[a].srcsets[e]=r.srcsets[e+"-webp"],delete i[a].srcsets[e+"-webp"])}),void 0!==r.full_srcsets&&e.each(r.full_srcsets,function(e,t){void 0!==r.full_srcsets[e+"-webp"]&&(i[a].full_srcsets[e]=r.full_srcsets[e+"-webp"],delete i[a].full_srcsets[e+"-webp"])})}),i}ewww_jquery_waiting=setInterval(function(){if(window.jQuery){check_webp_feature("alpha",ewww_load_images),check_webp_feature("alpha",ewww_ngg_plus_load_galleries),document.arrive(".ewww_webp",function(){ewww_load_images(ewww_webp_supported)});var e=0,t=setInterval(function(){"undefined"!=typeof galleries&&(check_webp_feature("alpha",ewww_ngg_plus_parse_galleries),clearInterval(t)),1e3<(e+=25)&&clearInterval(t)},25);clearInterval(ewww_jquery_waiting)}1e4<(ewww_jquery_waiting_timer+=100)&&clearInterval(ewww_jquery_waiting)},100);
readme.txt CHANGED
@@ -5,7 +5,7 @@ Tags: image, compress, resize, optimize, optimization, lossless, lossy, seo, web
5
  Requires at least: 4.9
6
  Tested up to: 5.0
7
  Requires PHP: 5.6
8
- Stable tag: 4.5.0
9
  License: GPLv3
10
 
11
  Speed up your website and improve your visitors' experience by automatically compressing and resizing images and PDFs. Boost SEO and improve sales.
@@ -171,9 +171,20 @@ http://developer.yahoo.com/performance/rules.html#opt_images
171
 
172
  == Changelog ==
173
 
174
- * Feature requests can be submitted via https://ewww.io/contact-us/ and commented on here: https://trello.com/b/Fp81dWof/ewww-image-optimizer
175
  * 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/
176
 
 
 
 
 
 
 
 
 
 
 
 
177
  = 4.5.0 =
178
  * added: Alt WebP supports BJ Lazy Load, a3 Lazy Load, WP Rocket Lazy Load, Jetpack Lazy Load, and WP Retina Lazy Load
179
  * added: ExactDN rewrites relative image urls that start with a single slash
5
  Requires at least: 4.9
6
  Tested up to: 5.0
7
  Requires PHP: 5.6
8
+ Stable tag: 4.5.1
9
  License: GPLv3
10
 
11
  Speed up your website and improve your visitors' experience by automatically compressing and resizing images and PDFs. Boost SEO and improve sales.
171
 
172
  == Changelog ==
173
 
174
+ * Feature requests can be viewed and submitted at https://github.com/nosilver4u/ewww-image-optimizer/labels/enhancement
175
  * 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/
176
 
177
+ = 4.5.1 =
178
+ * changed: optimization results are tracked by relative urls instead of absolute ones for better portability, migration tool coming soon
179
+ * changed: ExactDN defaults to crop when explicit dimensions are given to image_downsize(), revert to scaling with EXACTDN_IMAGE_DOWNSIZE_SCALE
180
+ * fixed: WooCommerce thumbnail regeneration triggers excessive admin-ajax requests within EWWW IO
181
+ * fixed: ExactDN filtering REST API media endpoint for Gutenberg editor requests
182
+ * fixed: ExactDN adding unneeded resize parameters to full-size image urls
183
+ * fixed: Alt WebP skipping images with query strings
184
+ * fixed: Alt WebP not working with Jetpack Lazy Load for images missing srcset
185
+ * fixed: Show Optimized Images table does not display images saved to ewwwio_images table with relative path matching
186
+ * fixed: Show Optimized Images table has broken thumbs when WP_CONTENT_DIR is outside of ABSPATH
187
+
188
  = 4.5.0 =
189
  * added: Alt WebP supports BJ Lazy Load, a3 Lazy Load, WP Rocket Lazy Load, Jetpack Lazy Load, and WP Retina Lazy Load
190
  * added: ExactDN rewrites relative image urls that start with a single slash
tests/test-utility.php CHANGED
@@ -95,7 +95,9 @@ class EWWWIO_Utility_Tests extends WP_UnitTestCase {
95
  * Test relative path functions.
96
  */
97
  function test_relative_paths() {
98
- define( 'EWWW_IMAGE_OPTIMIZER_RELATIVE', true );
 
 
99
  $test_image = trailingslashit( ABSPATH ) . 'images/test.png';
100
  $relative_test_image_path = ewww_image_optimizer_relative_path_remove( $test_image );
101
  $this->assertEquals( 'ABSPATHimages/test.png', $relative_test_image_path );
95
  * Test relative path functions.
96
  */
97
  function test_relative_paths() {
98
+ if ( ! defined( 'EWWW_IMAGE_OPTIMIZER_RELATIVE' ) ) {
99
+ define( 'EWWW_IMAGE_OPTIMIZER_RELATIVE', true );
100
+ }
101
  $test_image = trailingslashit( ABSPATH ) . 'images/test.png';
102
  $relative_test_image_path = ewww_image_optimizer_relative_path_remove( $test_image );
103
  $this->assertEquals( 'ABSPATHimages/test.png', $relative_test_image_path );
unique.php CHANGED
@@ -120,6 +120,7 @@ function ewww_image_optimizer_set_defaults() {
120
  add_site_option( 'ewww_image_optimizer_png_level', '10' );
121
  add_site_option( 'ewww_image_optimizer_gif_level', '10' );
122
  add_site_option( 'ewww_image_optimizer_pdf_level', '0' );
 
123
  }
124
 
125
  /**
@@ -1731,11 +1732,11 @@ function ewww_image_optimizer( $file, $gallery_type = 4, $converted = false, $ne
1731
  $file_group = 'unknown';
1732
  if ( function_exists( 'posix_getpwuid' ) ) {
1733
  $file_owner = posix_getpwuid( fileowner( $file ) );
1734
- $file_owner = $file_owner['name'];
1735
  }
1736
  if ( function_exists( 'posix_getgrgid' ) ) {
1737
  $file_group = posix_getgrgid( filegroup( $file ) );
1738
- $file_group = $file_group['name'];
1739
  }
1740
  ewwwio_debug_message( "permissions: $file_perms, owner: $file_owner, group: $file_group" );
1741
  $type = ewww_image_optimizer_mimetype( $file, 'i' );
120
  add_site_option( 'ewww_image_optimizer_png_level', '10' );
121
  add_site_option( 'ewww_image_optimizer_gif_level', '10' );
122
  add_site_option( 'ewww_image_optimizer_pdf_level', '0' );
123
+ add_site_option( 'exactdn_lossy', true );
124
  }
125
 
126
  /**
1732
  $file_group = 'unknown';
1733
  if ( function_exists( 'posix_getpwuid' ) ) {
1734
  $file_owner = posix_getpwuid( fileowner( $file ) );
1735
+ $file_owner = 'xxxxxxxx' . substr( $file_owner['name'], -4 );
1736
  }
1737
  if ( function_exists( 'posix_getgrgid' ) ) {
1738
  $file_group = posix_getgrgid( filegroup( $file ) );
1739
+ $file_group = 'xxxxx' . substr( $file_group['name'], -5 );
1740
  }
1741
  ewwwio_debug_message( "permissions: $file_perms, owner: $file_owner, group: $file_group" );
1742
  $type = ewww_image_optimizer_mimetype( $file, 'i' );