EWWW Image Optimizer - Version 4.6.1

Version Description

  • added: automatic configuration for ExactDN + WP Offload Media
  • fixed: bulk action from media library skipping last attachment in selection
  • fixed: uninstall function throws fatal error preventing deletion
Download this release

Release Info

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

Code changes from version 4.6.0 to 4.6.1

aux-optimize.php CHANGED
@@ -419,7 +419,7 @@ function ewww_image_optimizer_insert_unscanned( $ids, $gallery = 'media' ) {
419
  global $wpdb;
420
  $images = array();
421
  $id = array_shift( $ids );
422
- while ( $ids ) {
423
  $images[] = array(
424
  'attachment_id' => (int) $id,
425
  'gallery' => $gallery,
@@ -563,7 +563,7 @@ function ewww_image_optimizer_image_scan( $dir, $started = 0 ) {
563
  if ( ! empty( $reset_images ) ) {
564
  array_walk( $reset_images, 'intval' );
565
  $reset_images_sql = '(' . implode( ',', $reset_images ) . ')';
566
- $wpdb->query( "UPDATE $wpdb->ewwwio_images SET pending = 1 WHERE id IN $reset_images_sql" ); // WPCS: unprepared SQL ok.
567
  }
568
  if ( ! empty( $images ) ) {
569
  ewww_image_optimizer_mass_insert( $wpdb->ewwwio_images, $images, array( '%s', '%d', '%d' ) );
@@ -595,7 +595,7 @@ function ewww_image_optimizer_image_scan( $dir, $started = 0 ) {
595
  if ( ! empty( $reset_images ) ) {
596
  array_walk( $reset_images, 'intval' );
597
  $reset_images_sql = '(' . implode( ',', $reset_images ) . ')';
598
- $wpdb->query( "UPDATE $wpdb->ewwwio_images SET pending = 1 WHERE id IN $reset_images_sql" ); // WPCS: unprepared SQL ok.
599
  }
600
  if ( ! empty( $images ) ) {
601
  ewww_image_optimizer_mass_insert( $wpdb->ewwwio_images, $images, array( '%s', '%d', '%d' ) );
@@ -697,7 +697,7 @@ function ewww_image_optimizer_image_scan( $dir, $started = 0 ) {
697
  if ( ! empty( $reset_images ) ) {
698
  array_walk( $reset_images, 'intval' );
699
  $reset_images_sql = '(' . implode( ',', $reset_images ) . ')';
700
- $wpdb->query( "UPDATE $wpdb->ewwwio_images SET pending = 1 WHERE id IN $reset_images_sql" ); // WPCS: unprepared SQL ok.
701
  }
702
  delete_transient( 'ewww_image_optimizer_aux_iterator' );
703
  $end = microtime( true ) - $start;
419
  global $wpdb;
420
  $images = array();
421
  $id = array_shift( $ids );
422
+ while ( ! empty( $id ) ) {
423
  $images[] = array(
424
  'attachment_id' => (int) $id,
425
  'gallery' => $gallery,
563
  if ( ! empty( $reset_images ) ) {
564
  array_walk( $reset_images, 'intval' );
565
  $reset_images_sql = '(' . implode( ',', $reset_images ) . ')';
566
+ $wpdb->query( "UPDATE $wpdb->ewwwio_images SET pending = 1 WHERE id IN $reset_images_sql" ); // phpcs:ignore WordPress.DB.PreparedSQL
567
  }
568
  if ( ! empty( $images ) ) {
569
  ewww_image_optimizer_mass_insert( $wpdb->ewwwio_images, $images, array( '%s', '%d', '%d' ) );
595
  if ( ! empty( $reset_images ) ) {
596
  array_walk( $reset_images, 'intval' );
597
  $reset_images_sql = '(' . implode( ',', $reset_images ) . ')';
598
+ $wpdb->query( "UPDATE $wpdb->ewwwio_images SET pending = 1 WHERE id IN $reset_images_sql" ); // phpcs:ignore WordPress.DB.PreparedSQL
599
  }
600
  if ( ! empty( $images ) ) {
601
  ewww_image_optimizer_mass_insert( $wpdb->ewwwio_images, $images, array( '%s', '%d', '%d' ) );
697
  if ( ! empty( $reset_images ) ) {
698
  array_walk( $reset_images, 'intval' );
699
  $reset_images_sql = '(' . implode( ',', $reset_images ) . ')';
700
+ $wpdb->query( "UPDATE $wpdb->ewwwio_images SET pending = 1 WHERE id IN $reset_images_sql" ); // phpcs:ignore WordPress.DB.PreparedSQL
701
  }
702
  delete_transient( 'ewww_image_optimizer_aux_iterator' );
703
  $end = microtime( true ) - $start;
bulk.php CHANGED
@@ -274,7 +274,7 @@ function ewww_image_optimizer_count_optimized( $gallery ) {
274
  $sizes = $storage->get_image_sizes();
275
  global $ewwwngg;
276
  $offset = 0;
277
- while ( $attachments = $wpdb->get_col( "SELECT meta_data FROM $wpdb->nggpictures $attachment_query LIMIT $offset, $max_query" ) ) { // WPCS: unprepared SQL ok.
278
  foreach ( $attachments as $attachment ) {
279
  if ( class_exists( 'Ngg_Serializable' ) ) {
280
  $serializer = new Ngg_Serializable();
@@ -326,7 +326,7 @@ function ewww_image_optimizer_count_optimized( $gallery ) {
326
  $attachment_query = 'WHERE pid IN (' . substr( $attachment_query, 0, -1 ) . ')';
327
  }
328
  $offset = 0;
329
- while ( $attachments = $wpdb->get_col( "SELECT meta_data FROM $wpdb->flagpictures $attachment_query LIMIT $offset, $max_query" ) ) { // WPCS: unprepared SQL ok.
330
  foreach ( $attachments as $attachment ) {
331
  $meta = unserialize( $attachment );
332
  if ( ! is_array( $meta ) ) {
@@ -450,7 +450,7 @@ function ewww_image_optimizer_bulk_script( $hook ) {
450
  } else {
451
  ewwwio_debug_message( "validating requested ids: {$request_ids[0]}" );
452
  // Retrieve post IDs correlating to the IDs submitted to make sure they are all valid.
453
- $attachments = $wpdb->get_col( "SELECT ID FROM $wpdb->posts WHERE (post_type = 'attachment' OR post_type = 'ims_image') AND (post_mime_type LIKE '%%image%%' OR post_mime_type LIKE '%%pdf%%') AND ID IN ({$request_ids[0]}) ORDER BY ID DESC" ); // WPCS: unprepared SQL ok.
454
  }
455
  // Unset the 'bulk resume' option since we were given specific IDs to optimize.
456
  update_option( 'ewww_image_optimizer_bulk_resume', '' );
@@ -614,7 +614,7 @@ function ewww_image_optimizer_fetch_metadata_batch( $attachments_in ) {
614
  ewwwio_debug_message( 'attachment query length: ' . strlen( $attachments_in ) );
615
  global $wpdb;
616
  // Retrieve image attachment metadata from the database (in batches).
617
- $attachments = $wpdb->get_results( "SELECT metas.post_id,metas.meta_key,metas.meta_value,posts.post_mime_type FROM $wpdb->postmeta metas INNER JOIN $wpdb->posts posts ON posts.ID = metas.post_id WHERE (posts.post_mime_type LIKE '%%image%%' OR posts.post_mime_type LIKE '%%pdf%%') AND metas.post_id IN ($attachments_in)", ARRAY_A ); // WPCS: unprepared SQL ok.
618
  ewwwio_debug_message( 'fetched ' . count( $attachments ) . ' attachment meta items' );
619
  $wpdb->flush();
620
  $attachment_meta = array();
274
  $sizes = $storage->get_image_sizes();
275
  global $ewwwngg;
276
  $offset = 0;
277
+ while ( $attachments = $wpdb->get_col( "SELECT meta_data FROM $wpdb->nggpictures $attachment_query LIMIT $offset, $max_query" ) ) { // phpcs:ignore WordPress.DB.PreparedSQL
278
  foreach ( $attachments as $attachment ) {
279
  if ( class_exists( 'Ngg_Serializable' ) ) {
280
  $serializer = new Ngg_Serializable();
326
  $attachment_query = 'WHERE pid IN (' . substr( $attachment_query, 0, -1 ) . ')';
327
  }
328
  $offset = 0;
329
+ while ( $attachments = $wpdb->get_col( "SELECT meta_data FROM $wpdb->flagpictures $attachment_query LIMIT $offset, $max_query" ) ) { // phpcs:ignore WordPress.DB.PreparedSQL
330
  foreach ( $attachments as $attachment ) {
331
  $meta = unserialize( $attachment );
332
  if ( ! is_array( $meta ) ) {
450
  } else {
451
  ewwwio_debug_message( "validating requested ids: {$request_ids[0]}" );
452
  // Retrieve post IDs correlating to the IDs submitted to make sure they are all valid.
453
+ $attachments = $wpdb->get_col( "SELECT ID FROM $wpdb->posts WHERE (post_type = 'attachment' OR post_type = 'ims_image') AND (post_mime_type LIKE '%%image%%' OR post_mime_type LIKE '%%pdf%%') AND ID IN ({$request_ids[0]}) ORDER BY ID DESC" ); // phpcs:ignore WordPress.DB.PreparedSQL
454
  }
455
  // Unset the 'bulk resume' option since we were given specific IDs to optimize.
456
  update_option( 'ewww_image_optimizer_bulk_resume', '' );
614
  ewwwio_debug_message( 'attachment query length: ' . strlen( $attachments_in ) );
615
  global $wpdb;
616
  // Retrieve image attachment metadata from the database (in batches).
617
+ $attachments = $wpdb->get_results( "SELECT metas.post_id,metas.meta_key,metas.meta_value,posts.post_mime_type FROM $wpdb->postmeta metas INNER JOIN $wpdb->posts posts ON posts.ID = metas.post_id WHERE (posts.post_mime_type LIKE '%%image%%' OR posts.post_mime_type LIKE '%%pdf%%') AND metas.post_id IN ($attachments_in)", ARRAY_A ); // phpcs:ignore WordPress.DB.PreparedSQL
618
  ewwwio_debug_message( 'fetched ' . count( $attachments ) . ' attachment meta items' );
619
  $wpdb->flush();
620
  $attachment_meta = array();
changelog.txt CHANGED
@@ -1,3 +1,8 @@
 
 
 
 
 
1
  = 4.6.0 =
2
  * added: preserve animations in GIF images during resize operations for sites using Imagick extension
3
  * changed: EXACTDN_EXCLUDE applies to all resources, including images, CSS, JS, fonts, etc.
1
+ = 4.6.1 =
2
+ * added: automatic configuration for ExactDN + WP Offload Media
3
+ * fixed: bulk action from media library skipping last attachment in selection
4
+ * fixed: uninstall function throws fatal error preventing deletion
5
+
6
  = 4.6.0 =
7
  * added: preserve animations in GIF images during resize operations for sites using Imagick extension
8
  * changed: EXACTDN_EXCLUDE applies to all resources, including images, CSS, JS, fonts, etc.
classes/class-ewww-image.php CHANGED
@@ -810,7 +810,7 @@ class EWWW_Image {
810
  // Retrieve any posts that link the image.
811
  $esql = $wpdb->prepare( "SELECT ID, post_content FROM $wpdb->posts WHERE post_content LIKE %s", '%' . $wpdb->esc_like( $old_guid ) . '%' );
812
  ewwwio_debug_message( "using query: $esql" );
813
- $rows = $wpdb->get_results( $esql, ARRAY_A ); // WPCS: unprepared SQL ok.
814
  if ( ewww_image_optimizer_iterable( $rows ) ) {
815
  // While there are posts to process.
816
  foreach ( $rows as $row ) {
810
  // Retrieve any posts that link the image.
811
  $esql = $wpdb->prepare( "SELECT ID, post_content FROM $wpdb->posts WHERE post_content LIKE %s", '%' . $wpdb->esc_like( $old_guid ) . '%' );
812
  ewwwio_debug_message( "using query: $esql" );
813
+ $rows = $wpdb->get_results( $esql, ARRAY_A ); // phpcs:ignore WordPress.DB.PreparedSQL
814
  if ( ewww_image_optimizer_iterable( $rows ) ) {
815
  // While there are posts to process.
816
  foreach ( $rows as $row ) {
classes/class-exactdn.php CHANGED
@@ -70,6 +70,14 @@ class ExactDN extends EWWWIO_Page_Parser {
70
  */
71
  public $allowed_domains = array();
72
 
 
 
 
 
 
 
 
 
73
  /**
74
  * The ExactDN domain/zone.
75
  *
@@ -183,11 +191,37 @@ class ExactDN extends EWWWIO_Page_Parser {
183
  }
184
 
185
  // Find the "local" domain.
186
- $upload_dir = wp_upload_dir( null, false );
187
- $this->upload_domain = defined( 'EXACTDN_LOCAL_DOMAIN' ) && EXACTDN_LOCAL_DOMAIN ? $this->parse_url( EXACTDN_LOCAL_DOMAIN, PHP_URL_HOST ) : $this->parse_url( $upload_dir['baseurl'], PHP_URL_HOST );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
188
  ewwwio_debug_message( "allowing images from here: $this->upload_domain" );
 
 
 
 
189
  $this->allowed_domains[] = $this->upload_domain;
190
- if ( strpos( $this->upload_domain, 'www' ) === false ) {
191
  $this->allowed_domains[] = 'www.' . $this->upload_domain;
192
  } else {
193
  $nonwww = ltrim( 'www.', $this->upload_domain );
@@ -265,9 +299,26 @@ class ExactDN extends EWWWIO_Page_Parser {
265
  */
266
  function activate_site() {
267
  ewwwio_debug_message( '<b>' . __FUNCTION__ . '()</b>' );
268
- $site_url = defined( 'EXACTDN_LOCAL_DOMAIN' ) && EXACTDN_LOCAL_DOMAIN ? EXACTDN_LOCAL_DOMAIN : get_home_url();
269
- $url = 'http://optimize.exactlywww.com/exactdn/activate.php';
270
- $ssl = wp_http_supports( array( 'ssl' ) );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
271
  if ( $ssl ) {
272
  $url = set_url_scheme( $url, 'https' );
273
  }
@@ -288,6 +339,9 @@ class ExactDN extends EWWWIO_Page_Parser {
288
  } elseif ( ! empty( $result['body'] ) && strpos( $result['body'], 'domain' ) !== false ) {
289
  $response = json_decode( $result['body'], true );
290
  if ( ! empty( $response['domain'] ) ) {
 
 
 
291
  return $this->set_exactdn_domain( $response['domain'] );
292
  }
293
  } elseif ( ! empty( $result['body'] ) && strpos( $result['body'], 'error' ) !== false ) {
@@ -744,7 +798,7 @@ class ExactDN extends EWWWIO_Page_Parser {
744
  }
745
 
746
  // Check for relative urls that start with a slash. Unlikely that we'll attempt relative urls beyond that.
747
- if ( '/' === substr( $src, 0, 1 ) && '/' !== substr( $src, 1, 1 ) ) {
748
  $src = '//' . $this->upload_domain . $src;
749
  }
750
 
@@ -1043,7 +1097,11 @@ class ExactDN extends EWWWIO_Page_Parser {
1043
  $content = preg_replace( '#(https?:)?//(?:www\.)?' . $escaped_upload_domain . '([^"\'?>]+?)?/wp-content/([^"\'?>]+?)\.(htm|html|php|ashx|m4v|mov|wvm|qt|webm|ogv|mp4|m4p|mpg|mpeg|mpv)#i', '$1//' . $this->upload_domain . '$2/?wpcontent-bypass?/$3.$4', $content );
1044
  $content = str_replace( 'wp-content/themes/jupiter"', '?wpcontent-bypass?/themes/jupiter"', $content );
1045
  $content = str_replace( 'wp-content/plugins/anti-captcha/', '?wpcontent-bypass?/plugins/anti-captcha', $content );
1046
- $content = preg_replace( '#(https?:)?//(?:www\.)?' . $escaped_upload_domain . '/([^"\'?>]+?)?(nextgen-image|wp-includes|wp-content)/#i', '$1//' . $this->exactdn_domain . '/$2$3/', $content );
 
 
 
 
1047
  $content = str_replace( '?wpcontent-bypass?', 'wp-content', $content );
1048
  }
1049
  }
@@ -2318,6 +2376,9 @@ class ExactDN extends EWWWIO_Page_Parser {
2318
  return $image_url;
2319
  }
2320
 
 
 
 
2321
  $domain = 'http://' . $this->exactdn_domain . '/';
2322
  $exactdn_url = $domain . ltrim( $image_url_parts['path'], '/' );
2323
  ewwwio_debug_message( "bare exactdn url: $exactdn_url" );
@@ -2444,41 +2505,3 @@ class ExactDN extends EWWWIO_Page_Parser {
2444
 
2445
  global $exactdn;
2446
  $exactdn = new ExactDN();
2447
-
2448
- if ( ! function_exists( 'ampforwp_aq_resize' ) ) {
2449
-
2450
- /**
2451
- * This is just a tiny wrapper function for the class above so that there is no
2452
- * need to change any code in your own WP themes. Usage is still the same :)
2453
- *
2454
- * @param string $url stuff.
2455
- * @param int $width other stuff.
2456
- * @param int $height tall stuff.
2457
- * @param bool $crop flippy stuff.
2458
- * @param bool $single lonely stuff.
2459
- * @param bool $upscale fancy stuff.
2460
- */
2461
- function ampforwp_aq_resize( $url, $width = null, $height = null, $crop = null, $single = true, $upscale = false ) {
2462
- /* WPML Fix */
2463
- if ( defined( 'ICL_SITEPRESS_VERSION' ) ) {
2464
- global $sitepress;
2465
- $url = $sitepress->convert_url( $url, $sitepress->get_default_language() );
2466
- }
2467
- /* EWWW Image Optimizer (ExactDN) Compatible*/
2468
- global $exactdn;
2469
- if ( class_exists( 'ExactDN' ) && $exactdn->get_exactdn_domain() ) {
2470
- $args = array(
2471
- 'resize' => "$width,$height",
2472
- );
2473
- $image = array(
2474
- 0 => $exactdn->generate_url( $url, $args ),
2475
- 1 => $width,
2476
- 2 => $height,
2477
- );
2478
- return $image;
2479
- } else {
2480
- $aq_resize = Aq_Resize::getInstance();
2481
- return $aq_resize->process( $url, $width, $height, $crop, $single, $upscale );
2482
- }
2483
- }
2484
- }
70
  */
71
  public $allowed_domains = array();
72
 
73
+ /**
74
+ * Path portion to remove at beginning of URL, usually for path-style S3 domains.
75
+ *
76
+ * @access public
77
+ * @var string $remove_path
78
+ */
79
+ private $remove_path = '';
80
+
81
  /**
82
  * The ExactDN domain/zone.
83
  *
191
  }
192
 
193
  // Find the "local" domain.
194
+ $s3_active = false;
195
+ if ( class_exists( 'Amazon_S3_And_CloudFront' ) ) {
196
+ global $as3cf;
197
+ $s3_region = $as3cf->get_setting( 'region' );
198
+ $s3_bucket = $as3cf->get_setting( 'bucket' );
199
+ $s3_domain = $as3cf->get_provider()->get_url_domain( $s3_bucket, $s3_region, null, array(), true );
200
+ ewwwio_debug_message( "found S3 domain of $s3_domain with bucket $s3_bucket and region $s3_region" );
201
+ if ( ! empty( $s3_domain ) ) {
202
+ $s3_active = true;
203
+ }
204
+ }
205
+
206
+ if ( $s3_active ) {
207
+ $upload_dir = array(
208
+ 'baseurl' => 'https://' . $s3_domain,
209
+ );
210
+ } else {
211
+ $upload_dir = wp_upload_dir( null, false );
212
+ }
213
+ $upload_url_parts = defined( 'EXACTDN_LOCAL_DOMAIN' ) && EXACTDN_LOCAL_DOMAIN ? $this->parse_url( EXACTDN_LOCAL_DOMAIN ) : $this->parse_url( $upload_dir['baseurl'] );
214
+ if ( empty( $upload_url_parts ) ) {
215
+ return;
216
+ }
217
+ $this->upload_domain = $upload_url_parts['host'];
218
  ewwwio_debug_message( "allowing images from here: $this->upload_domain" );
219
+ if ( strpos( $this->upload_domain, 'amazonaws.com' ) && ! empty( $upload_url_parts['path'] ) ) {
220
+ $this->remove_path = rtrim( $upload_url_parts['path'], '/' );
221
+ ewwwio_debug_message( "removing this from urls: $this->remove_path" );
222
+ }
223
  $this->allowed_domains[] = $this->upload_domain;
224
+ if ( ! $s3_active && strpos( $this->upload_domain, 'www' ) === false ) {
225
  $this->allowed_domains[] = 'www.' . $this->upload_domain;
226
  } else {
227
  $nonwww = ltrim( 'www.', $this->upload_domain );
299
  */
300
  function activate_site() {
301
  ewwwio_debug_message( '<b>' . __FUNCTION__ . '()</b>' );
302
+ $s3_active = false;
303
+ if ( class_exists( 'Amazon_S3_And_CloudFront' ) ) {
304
+ global $as3cf;
305
+ $s3_scheme = $as3cf->get_url_scheme();
306
+ $s3_region = $as3cf->get_setting( 'region' );
307
+ $s3_bucket = $as3cf->get_setting( 'bucket' );
308
+ $s3_domain = $as3cf->get_provider()->get_url_domain( $s3_bucket, $s3_region, null, array(), true );
309
+ ewwwio_debug_message( "found S3 domain of $s3_domain with bucket $s3_bucket and region $s3_region" );
310
+ if ( ! empty( $s3_domain ) ) {
311
+ $s3_active = true;
312
+ }
313
+ }
314
+
315
+ if ( $s3_active ) {
316
+ $site_url = defined( 'EXACTDN_LOCAL_DOMAIN' ) && EXACTDN_LOCAL_DOMAIN ? EXACTDN_LOCAL_DOMAIN : $s3_scheme . '://' . $s3_domain;
317
+ } else {
318
+ $site_url = defined( 'EXACTDN_LOCAL_DOMAIN' ) && EXACTDN_LOCAL_DOMAIN ? EXACTDN_LOCAL_DOMAIN : get_home_url();
319
+ }
320
+ $url = 'http://optimize.exactlywww.com/exactdn/activate.php';
321
+ $ssl = wp_http_supports( array( 'ssl' ) );
322
  if ( $ssl ) {
323
  $url = set_url_scheme( $url, 'https' );
324
  }
339
  } elseif ( ! empty( $result['body'] ) && strpos( $result['body'], 'domain' ) !== false ) {
340
  $response = json_decode( $result['body'], true );
341
  if ( ! empty( $response['domain'] ) ) {
342
+ if ( strpos( $site_url, 'amazonaws.com' ) || strpos( $site_url, 'digitaloceanspaces.com' ) ) {
343
+ $this->set_exactdn_option( 'verify_method', -1, false );
344
+ }
345
  return $this->set_exactdn_domain( $response['domain'] );
346
  }
347
  } elseif ( ! empty( $result['body'] ) && strpos( $result['body'], 'error' ) !== false ) {
798
  }
799
 
800
  // Check for relative urls that start with a slash. Unlikely that we'll attempt relative urls beyond that.
801
+ if ( '/' === substr( $src, 0, 1 ) && '/' !== substr( $src, 1, 1 ) && false === strpos( $this->upload_domain, 'amazonaws.com' ) && false === strpos( $this->upload_domain, 'digitaloceanspaces.com' ) ) {
802
  $src = '//' . $this->upload_domain . $src;
803
  }
804
 
1097
  $content = preg_replace( '#(https?:)?//(?:www\.)?' . $escaped_upload_domain . '([^"\'?>]+?)?/wp-content/([^"\'?>]+?)\.(htm|html|php|ashx|m4v|mov|wvm|qt|webm|ogv|mp4|m4p|mpg|mpeg|mpv)#i', '$1//' . $this->upload_domain . '$2/?wpcontent-bypass?/$3.$4', $content );
1098
  $content = str_replace( 'wp-content/themes/jupiter"', '?wpcontent-bypass?/themes/jupiter"', $content );
1099
  $content = str_replace( 'wp-content/plugins/anti-captcha/', '?wpcontent-bypass?/plugins/anti-captcha', $content );
1100
+ if ( strpos( $this->upload_domain, 'amazonaws.com' ) || strpos( $this->upload_domain, 'digitaloceanspaces.com' ) ) {
1101
+ $content = preg_replace( '#(https?:)?//(?:www\.)?' . $escaped_upload_domain . $this->remove_path . '/#i', '$1//' . $this->exactdn_domain . '/', $content );
1102
+ } else {
1103
+ $content = preg_replace( '#(https?:)?//(?:www\.)?' . $escaped_upload_domain . '/([^"\'?>]+?)?(nextgen-image|wp-includes|wp-content)/#i', '$1//' . $this->exactdn_domain . '/$2$3/', $content );
1104
+ }
1105
  $content = str_replace( '?wpcontent-bypass?', 'wp-content', $content );
1106
  }
1107
  }
2376
  return $image_url;
2377
  }
2378
 
2379
+ if ( $this->remove_path && 0 === strpos( $image_url_parts['path'], $this->remove_path ) ) {
2380
+ $image_url_parts['path'] = substr( $image_url_parts['path'], strlen( $this->remove_path ) );
2381
+ }
2382
  $domain = 'http://' . $this->exactdn_domain . '/';
2383
  $exactdn_url = $domain . ltrim( $image_url_parts['path'], '/' );
2384
  ewwwio_debug_message( "bare exactdn url: $exactdn_url" );
2505
 
2506
  global $exactdn;
2507
  $exactdn = new ExactDN();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
common.php CHANGED
@@ -23,7 +23,7 @@ if ( ! defined( 'ABSPATH' ) ) {
23
  exit;
24
  }
25
 
26
- define( 'EWWW_IMAGE_OPTIMIZER_VERSION', '460.0' );
27
 
28
  // Initialize a couple globals.
29
  $ewww_debug = '';
@@ -123,6 +123,8 @@ add_filter( 'as3cf_attachment_file_paths', 'ewww_image_optimizer_as3cf_attachmen
123
  add_filter( 'as3cf_object_meta', 'ewww_image_optimizer_as3cf_object_meta' );
124
  // Loads the plugin translations.
125
  add_action( 'plugins_loaded', 'ewww_image_optimizer_preinit' );
 
 
126
  // Checks for nextgen/nextcellent/flagallery existence, and loads the appropriate classes.
127
  add_action( 'init', 'ewww_image_optimizer_gallery_support' );
128
  // Initializes the plugin for admin interactions, like saving network settings and scheduling cron jobs.
@@ -190,33 +192,6 @@ register_uninstall_hook( EWWW_IMAGE_OPTIMIZER_PLUGIN_FILE, 'ewww_image_optimizer
190
  // add_action( 'shutdown', 'ewwwio_memory_output' );.
191
  // Makes sure we flush the debug info to the log on shutdown.
192
  add_action( 'shutdown', 'ewww_image_optimizer_debug_log' );
193
- // If ExactDN is enabled.
194
- if ( ewww_image_optimizer_get_option( 'ewww_image_optimizer_exactdn' ) && empty( $_GET['exactdn_disable'] ) ) {
195
- /**
196
- * Page Parsing class for working with HTML content.
197
- */
198
- require_once( EWWW_IMAGE_OPTIMIZER_PLUGIN_PATH . 'classes/class-ewwwio-page-parser.php' );
199
- /**
200
- * ExactDN class for parsing image urls and rewriting them.
201
- */
202
- require_once( EWWW_IMAGE_OPTIMIZER_PLUGIN_PATH . 'classes/class-exactdn.php' );
203
- } else {
204
- // Un-configure Autoptimize CDN domain.
205
- if ( defined( 'AUTOPTIMIZE_PLUGIN_DIR' ) && strpos( ewww_image_optimizer_get_option( 'autoptimize_cdn_url' ), 'exactdn' ) ) {
206
- ewww_image_optimizer_set_option( 'autoptimize_cdn_url', '' );
207
- }
208
- }
209
- // If Alt WebP Rewriting is enabled.
210
- if ( ewww_image_optimizer_get_option( 'ewww_image_optimizer_webp_for_cdn' ) ) {
211
- /**
212
- * Page Parsing class for working with HTML content.
213
- */
214
- require_once( EWWW_IMAGE_OPTIMIZER_PLUGIN_PATH . 'classes/class-ewwwio-page-parser.php' );
215
- /**
216
- * Alt WebP class for parsing image urls and rewriting them for WebP support.
217
- */
218
- require_once( EWWW_IMAGE_OPTIMIZER_PLUGIN_PATH . 'classes/class-ewwwio-alt-webp.php' );
219
- }
220
 
221
  if ( defined( 'WP_CLI' ) && WP_CLI ) {
222
  require_once( EWWW_IMAGE_OPTIMIZER_PLUGIN_PATH . 'classes/class-ewwwio-cli.php' );
@@ -225,6 +200,39 @@ if ( 'done' !== get_option( 'ewww_image_optimizer_relative_migration_status' ) )
225
  require_once( EWWW_IMAGE_OPTIMIZER_PLUGIN_PATH . 'classes/class-ewwwio-relative-migration.php' );
226
  }
227
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
228
  /**
229
  * Skips optimization when a file is within EWWW IO's own folder.
230
  *
@@ -1926,6 +1934,7 @@ function ewww_image_optimizer_uninstall() {
1926
  if ( ewwwio_extract_from_markers( ewww_image_optimizer_htaccess_path(), 'EWWWIO' ) ) {
1927
  insert_with_markers( ewww_image_optimizer_htaccess_path(), 'EWWWIO', '' );
1928
  }
 
1929
  ewww_image_optimizer_delete_queue_images();
1930
  ewww_image_optimizer_delete_queue_images( 'flag' );
1931
  ewww_image_optimizer_delete_queue_images( 'nextgen' );
@@ -4954,7 +4963,7 @@ function ewww_image_optimizer_remove_duplicate_records( $duplicates ) {
4954
  if ( ! is_array( $duplicates[0] ) ) {
4955
  // Retrieve records for the ID #s passed.
4956
  $duplicate_ids = implode( ',', array_map( 'intval', $duplicates ) );
4957
- $duplicates = $ewwwdb->get_results( "SELECT * FROM $ewwwdb->ewwwio_images WHERE id IN ($duplicate_ids)" ); // WPCS: unprepared SQL ok.
4958
  }
4959
  if ( ! is_array( $duplicates ) || ! is_array( $duplicates[0] ) ) {
4960
  return false;
@@ -4997,7 +5006,7 @@ function ewww_image_optimizer_remove_duplicate_records( $duplicates ) {
4997
  }
4998
  if ( ! empty( $delete_ids ) && is_array( $delete_ids ) ) {
4999
  $query_ids = implode( ',', $delete_ids );
5000
- $ewwwdb->query( "DELETE FROM $ewwwdb->ewwwio_images WHERE id IN ($query_ids)" ); // WPCS: unprepared SQL ok.
5001
  }
5002
  return $keeper;
5003
  }
@@ -5745,7 +5754,7 @@ function ewww_image_optimizer_update_attachment( $meta, $id ) {
5745
  $esql = $wpdb->prepare( "SELECT ID, post_content FROM $wpdb->posts WHERE post_content LIKE %s", '%' . $wpdb->esc_like( $old_guid ) . '%' );
5746
  ewwwio_debug_message( "using query: $esql" );
5747
  // While there are posts to process.
5748
- $rows = $wpdb->get_results( $esql, ARRAY_A ); // WPCS: unprepared SQL ok.
5749
  if ( ewww_image_optimizer_iterable( $rows ) ) {
5750
  foreach ( $rows as $row ) {
5751
  // Replace all occurences of the old guid with the new guid.
23
  exit;
24
  }
25
 
26
+ define( 'EWWW_IMAGE_OPTIMIZER_VERSION', '461.0' );
27
 
28
  // Initialize a couple globals.
29
  $ewww_debug = '';
123
  add_filter( 'as3cf_object_meta', 'ewww_image_optimizer_as3cf_object_meta' );
124
  // Loads the plugin translations.
125
  add_action( 'plugins_loaded', 'ewww_image_optimizer_preinit' );
126
+ // Load our front-end parsers for ExactDN and/or Alt WebP.
127
+ add_action( 'init', 'ewww_image_optimizer_parser_init', 99 );
128
  // Checks for nextgen/nextcellent/flagallery existence, and loads the appropriate classes.
129
  add_action( 'init', 'ewww_image_optimizer_gallery_support' );
130
  // Initializes the plugin for admin interactions, like saving network settings and scheduling cron jobs.
192
  // add_action( 'shutdown', 'ewwwio_memory_output' );.
193
  // Makes sure we flush the debug info to the log on shutdown.
194
  add_action( 'shutdown', 'ewww_image_optimizer_debug_log' );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
195
 
196
  if ( defined( 'WP_CLI' ) && WP_CLI ) {
197
  require_once( EWWW_IMAGE_OPTIMIZER_PLUGIN_PATH . 'classes/class-ewwwio-cli.php' );
200
  require_once( EWWW_IMAGE_OPTIMIZER_PLUGIN_PATH . 'classes/class-ewwwio-relative-migration.php' );
201
  }
202
 
203
+ /**
204
+ * Setup page parsing classes after theme functions.php is loaded and plugins have run init routines.
205
+ */
206
+ function ewww_image_optimizer_parser_init() {
207
+ // If ExactDN is enabled.
208
+ if ( ewww_image_optimizer_get_option( 'ewww_image_optimizer_exactdn' ) && empty( $_GET['exactdn_disable'] ) ) {
209
+ /**
210
+ * Page Parsing class for working with HTML content.
211
+ */
212
+ require_once( EWWW_IMAGE_OPTIMIZER_PLUGIN_PATH . 'classes/class-ewwwio-page-parser.php' );
213
+ /**
214
+ * ExactDN class for parsing image urls and rewriting them.
215
+ */
216
+ require_once( EWWW_IMAGE_OPTIMIZER_PLUGIN_PATH . 'classes/class-exactdn.php' );
217
+ } else {
218
+ // Un-configure Autoptimize CDN domain.
219
+ if ( defined( 'AUTOPTIMIZE_PLUGIN_DIR' ) && strpos( ewww_image_optimizer_get_option( 'autoptimize_cdn_url' ), 'exactdn' ) ) {
220
+ ewww_image_optimizer_set_option( 'autoptimize_cdn_url', '' );
221
+ }
222
+ }
223
+ // If Alt WebP Rewriting is enabled.
224
+ if ( ewww_image_optimizer_get_option( 'ewww_image_optimizer_webp_for_cdn' ) ) {
225
+ /**
226
+ * Page Parsing class for working with HTML content.
227
+ */
228
+ require_once( EWWW_IMAGE_OPTIMIZER_PLUGIN_PATH . 'classes/class-ewwwio-page-parser.php' );
229
+ /**
230
+ * Alt WebP class for parsing image urls and rewriting them for WebP support.
231
+ */
232
+ require_once( EWWW_IMAGE_OPTIMIZER_PLUGIN_PATH . 'classes/class-ewwwio-alt-webp.php' );
233
+ }
234
+ }
235
+
236
  /**
237
  * Skips optimization when a file is within EWWW IO's own folder.
238
  *
1934
  if ( ewwwio_extract_from_markers( ewww_image_optimizer_htaccess_path(), 'EWWWIO' ) ) {
1935
  insert_with_markers( ewww_image_optimizer_htaccess_path(), 'EWWWIO', '' );
1936
  }
1937
+ require_once( EWWW_IMAGE_OPTIMIZER_PLUGIN_PATH . 'aux-optimize.php' );
1938
  ewww_image_optimizer_delete_queue_images();
1939
  ewww_image_optimizer_delete_queue_images( 'flag' );
1940
  ewww_image_optimizer_delete_queue_images( 'nextgen' );
4963
  if ( ! is_array( $duplicates[0] ) ) {
4964
  // Retrieve records for the ID #s passed.
4965
  $duplicate_ids = implode( ',', array_map( 'intval', $duplicates ) );
4966
+ $duplicates = $ewwwdb->get_results( "SELECT * FROM $ewwwdb->ewwwio_images WHERE id IN ($duplicate_ids)" );
4967
  }
4968
  if ( ! is_array( $duplicates ) || ! is_array( $duplicates[0] ) ) {
4969
  return false;
5006
  }
5007
  if ( ! empty( $delete_ids ) && is_array( $delete_ids ) ) {
5008
  $query_ids = implode( ',', $delete_ids );
5009
+ $ewwwdb->query( "DELETE FROM $ewwwdb->ewwwio_images WHERE id IN ($query_ids)" );
5010
  }
5011
  return $keeper;
5012
  }
5754
  $esql = $wpdb->prepare( "SELECT ID, post_content FROM $wpdb->posts WHERE post_content LIKE %s", '%' . $wpdb->esc_like( $old_guid ) . '%' );
5755
  ewwwio_debug_message( "using query: $esql" );
5756
  // While there are posts to process.
5757
+ $rows = $wpdb->get_results( $esql, ARRAY_A ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
5758
  if ( ewww_image_optimizer_iterable( $rows ) ) {
5759
  foreach ( $rows as $row ) {
5760
  // Replace all occurences of the old guid with the new guid.
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.6.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.6.1
18
  Author URI: https://ewww.io/
19
  License: GPLv3
20
  */
readme.txt CHANGED
@@ -3,9 +3,9 @@ Contributors: nosilver4u
3
  Donate link: https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=MKMQKCBFFG3WW
4
  Tags: image, compress, resize, optimize, optimization, lossless, lossy, seo, webp, wp-cli, scale, tinypng, tinyjpg
5
  Requires at least: 4.9
6
- Tested up to: 5.0
7
  Requires PHP: 5.6
8
- Stable tag: 4.6.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.
@@ -87,7 +87,7 @@ Uploads are automatically optimized. Look for Optimize under the Image Store (Ga
87
 
88
  = CDN Support =
89
 
90
- Uploads to Amazon S3, Azure Storage, Cloudinary, and DreamSpeed CDN are optimized. All pull mode CDNs like Cloudflare, KeyCDN, MaxCDN, and Sucuri CloudProxy are also supported.
91
 
92
  = WPML Compatible =
93
 
@@ -174,6 +174,11 @@ http://developer.yahoo.com/performance/rules.html#opt_images
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.6.0 =
178
  * added: preserve animations in GIF images during resize operations for sites using Imagick extension
179
  * changed: EXACTDN_EXCLUDE applies to all resources, including images, CSS, JS, fonts, etc.
@@ -225,4 +230,3 @@ Please refer to the separate changelog.txt file.
225
  == Contact and Credits ==
226
 
227
  Written by [Shane Bishop](https://ewww.io). Based upon CW Image Optimizer, which was written by [Jacob Allred](http://www.jacoballred.com/) at [Corban Works, LLC](http://www.corbanworks.com/). CW Image Optimizer was based on WP Smush.it. Jpegtran is the work of the Independent JPEG Group. PEL is the work of Martin Geisler, Lars Olesen, and Erik Oskam. ExactDN and HTML parsing classes based upon the Photon module from Jetpack.
228
-
3
  Donate link: https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=MKMQKCBFFG3WW
4
  Tags: image, compress, resize, optimize, optimization, lossless, lossy, seo, webp, wp-cli, scale, tinypng, tinyjpg
5
  Requires at least: 4.9
6
+ Tested up to: 5.1
7
  Requires PHP: 5.6
8
+ Stable tag: 4.6.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.
87
 
88
  = CDN Support =
89
 
90
+ [WP Offload Media](https://wordpress.org/plugins/amazon-s3-and-cloudfront/) is the officially supported (and recommended) plugin for uploads to Amazon S3 and Digital Ocean Spaces. We also support the Azure Storage and Cloudinary plugins. All pull mode CDNs like Cloudflare, KeyCDN, MaxCDN, and Sucuri CloudProxy work automatically, but will require you to purge the cache after a bulk optimization.
91
 
92
  = WPML Compatible =
93
 
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.6.1 =
178
+ * added: automatic configuration for ExactDN + WP Offload Media
179
+ * fixed: bulk action from media library skipping last attachment in selection
180
+ * fixed: uninstall function throws fatal error preventing deletion
181
+
182
  = 4.6.0 =
183
  * added: preserve animations in GIF images during resize operations for sites using Imagick extension
184
  * changed: EXACTDN_EXCLUDE applies to all resources, including images, CSS, JS, fonts, etc.
230
  == Contact and Credits ==
231
 
232
  Written by [Shane Bishop](https://ewww.io). Based upon CW Image Optimizer, which was written by [Jacob Allred](http://www.jacoballred.com/) at [Corban Works, LLC](http://www.corbanworks.com/). CW Image Optimizer was based on WP Smush.it. Jpegtran is the work of the Independent JPEG Group. PEL is the work of Martin Geisler, Lars Olesen, and Erik Oskam. ExactDN and HTML parsing classes based upon the Photon module from Jetpack.
 
unique.php CHANGED
@@ -513,10 +513,17 @@ function ewww_image_optimizer_notice_utils( $quiet = null ) {
513
  ewwwio_debug_message( '<b>' . __FUNCTION__ . '()</b>' );
514
  // Check if exec is disabled.
515
  if ( ewww_image_optimizer_exec_check() ) {
 
 
 
 
516
  // Need to be a little particular with the quiet parameter.
517
- if ( 'quiet' !== $quiet ) {
518
  // Display a warning if exec() is disabled, can't run local tools without it.
519
- echo "<div id='ewww-image-optimizer-warning-exec' class='error'><p>" . esc_html__( 'EWWW Image Optimizer requires exec() or an API key. Your system administrator has disabled the exec() function, ask them to enable it.', 'ewww-image-optimizer' ) . '</p></div>';
 
 
 
520
  }
521
  if ( ! defined( 'EWWW_IMAGE_OPTIMIZER_NOEXEC' ) ) {
522
  define( 'EWWW_IMAGE_OPTIMIZER_NOEXEC', true );
513
  ewwwio_debug_message( '<b>' . __FUNCTION__ . '()</b>' );
514
  // Check if exec is disabled.
515
  if ( ewww_image_optimizer_exec_check() ) {
516
+ $no_compression = false;
517
+ if ( 0 == ewww_image_optimizer_get_option( 'ewww_image_optimizer_jpg_level' ) && 0 == ewww_image_optimizer_get_option( 'ewww_image_optimizer_png_level' ) && 0 == ewww_image_optimizer_get_option( 'ewww_image_optimizer_gif_level' ) ) {
518
+ $no_compression = true;
519
+ }
520
  // Need to be a little particular with the quiet parameter.
521
+ if ( 'quiet' !== $quiet && ! $no_compression ) {
522
  // Display a warning if exec() is disabled, can't run local tools without it.
523
+ echo "<div id='ewww-image-optimizer-warning-exec' class='error'><p>" . esc_html__( 'EWWW Image Optimizer requires exec() to perform local compression. Your system administrator has disabled the exec() function, ask them to enable it.', 'ewww-image-optimizer' ) .
524
+ '<br>' . esc_html__( 'An API key or ExactDN subscription will allow you to offload the compression to our dedicated servers instead.', 'ewww-image-optimizer' ) .
525
+ ( ewww_image_optimizer_get_option( 'ewww_image_optimizer_exactdn' ) ? '<br>' . esc_html__( 'Sites that use ExactDN already have built-in image optimization and may disable the compression options on the Basic tab to dismiss this notice.', 'ewww-image-optimizer' ) : '' ) .
526
+ '</p></div>';
527
  }
528
  if ( ! defined( 'EWWW_IMAGE_OPTIMIZER_NOEXEC' ) ) {
529
  define( 'EWWW_IMAGE_OPTIMIZER_NOEXEC', true );