ShortPixel Image Optimizer - Version 4.22.9

Version Description

Release date March 31st, 2022 * Fix: fixed the integration with the WP Media Offload plugin, which was broken in version 3.6.0; * Fix: added support for offloading AVIF files via WP Media Offload; * Fix: PDF files were not offloaded via WP Media Offload if the process PDF option wasn't enabled in SPIO; * Fix: added support for delivering animated gif files as WebP when using the .htaccess method; * Fix: the link for the plugin settings was leading to a 404 in the network admin of a multisite install; * Tweak: added 2 new constants for adding the HTTP basic authentication credentials directly in wp-config.php; * Tweak: added a notification in case of downgrading from the upcoming SPIO 5 version; * Compat: added integration with Pantheon cache, thanks to @TrilipuT & @LogicEveryWhere; * Language: 3 new strings added, 0 updated, 0 fuzzed, and 0 obsoleted.

Download this release

Release Info

Developer petredobrescu
Plugin Icon 128x128 ShortPixel Image Optimizer
Version 4.22.9
Comparing to
See all releases

Code changes from version 4.22.8 to 4.22.9

class/BuildAutoLoader.php CHANGED
@@ -57,6 +57,7 @@ class BuildAutoLoader
57
  'class/external/gravityforms.php',
58
  'class/external/helpscout.php',
59
  'class/external/nextgen.php',
 
60
  'class/external/securi.php',
61
  'class/external/shortpixel_queue_db.php',
62
  'class/external/visualcomposer.php',
57
  'class/external/gravityforms.php',
58
  'class/external/helpscout.php',
59
  'class/external/nextgen.php',
60
+ 'class/external/pantheon.php',
61
  'class/external/securi.php',
62
  'class/external/shortpixel_queue_db.php',
63
  'class/external/visualcomposer.php',
class/Controller/AdminNoticesController.php CHANGED
@@ -155,6 +155,9 @@ class AdminNoticesController extends \ShortPixel\Controller
155
  $this->doIntegrationNotices();
156
  $this->doHelpOptInNotices();
157
  $this->doRemoteNotices();
 
 
 
158
  }
159
 
160
 
@@ -417,6 +420,21 @@ class AdminNoticesController extends \ShortPixel\Controller
417
  }
418
  }
419
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
420
  // Callback to check if we are on the correct page.
421
  public function upgradeBulkCallback($notice)
422
  {
@@ -614,6 +632,15 @@ class AdminNoticesController extends \ShortPixel\Controller
614
  return $message;
615
  }
616
 
 
 
 
 
 
 
 
 
 
617
  protected function monthlyUpgradeNeeded($quotaData) {
618
  return isset($quotaData['APICallsQuotaNumeric']) && $this->getMonthAvg($quotaData) > $quotaData['APICallsQuotaNumeric'] + ($quotaData['APICallsQuotaOneTimeNumeric'] - $quotaData['APICallsMadeOneTimeNumeric'])/6 + 20;
619
  }
155
  $this->doIntegrationNotices();
156
  $this->doHelpOptInNotices();
157
  $this->doRemoteNotices();
158
+
159
+ // Check if we are legacy, or if SPIO 5 was ever installed.
160
+ $this->checkLegacyNotices();
161
  }
162
 
163
 
420
  }
421
  }
422
 
423
+ protected function checkLegacyNotices()
424
+ {
425
+ global $wpdb;
426
+
427
+ $table_name = $wpdb->prefix . 'shortpixel_postmeta';
428
+ if ($wpdb->get_var($wpdb->prepare("SHOW TABLES LIKE %s", $table_name) ) == $table_name)
429
+ {
430
+ $message = $this->getAlreadyUpgradedMessage();
431
+ Notices::addError($message);
432
+ }
433
+
434
+
435
+ }
436
+
437
+
438
  // Callback to check if we are on the correct page.
439
  public function upgradeBulkCallback($notice)
440
  {
632
  return $message;
633
  }
634
 
635
+ protected function getAlreadyUpgradedMessage()
636
+ {
637
+ $message = '<p>' . __('It seems you already upgraded to Shortpixel Image Optimizer version 5 and came back to version 4. We do not recommend using version 4 anymore because it might result in data loss. Please consult our support team if you have any issues with the new version.') . '</p>';
638
+
639
+ $message .= '<p>' . sprintf(__('If you are sure about what you\'re doing and you want to get rid of this message, remove the database table %s. All optimizations done with version 5 will be forgotten and they will be processed again with version 4, according to your settings. ', 'shortpixel_image_optimiser'), 'shortpixel_postmeta') . '<a class="shortpixel-help-link" href="https://shortpixel.com/knowledge-base/article/529-downgrading-shortpixel-image-optimizer-version-5-version-4" target="_blank"><span class="dashicons dashicons-editor-help"></span>' . __('Reaad more', 'shortpixel-image-optimiser') . '</a>' . '</p>';
640
+
641
+ return $message;
642
+ }
643
+
644
  protected function monthlyUpgradeNeeded($quotaData) {
645
  return isset($quotaData['APICallsQuotaNumeric']) && $this->getMonthAvg($quotaData) > $quotaData['APICallsQuotaNumeric'] + ($quotaData['APICallsQuotaOneTimeNumeric'] - $quotaData['APICallsMadeOneTimeNumeric'])/6 + 20;
646
  }
class/external/pantheon.php ADDED
@@ -0,0 +1,41 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ namespace ShortPixel;
2
+
3
+
4
+ class Pantheon {
5
+
6
+ public function __construct()
7
+ {
8
+ add_action( 'shortpixel_image_optimised', array( $this, 'flush_image_caches' ) );
9
+ }
10
+
11
+ public function flush_image_caches( $id )
12
+ {
13
+ $image_sizes = get_intermediate_image_sizes();
14
+ $image_paths = [];
15
+ $domain = get_site_url();
16
+ foreach ( $image_sizes as $size ) {
17
+ $image_array = wp_get_attachment_image_src( $id, $size );
18
+ if ( $image_array ) {
19
+ /**
20
+ * $0 Image source URL.
21
+ * We need absolute URI without domain
22
+ *
23
+ * @see wp_get_attachment_image_src
24
+ */
25
+ $image_paths[] = str_replace( $domain, '', $image_array[0] );
26
+ }
27
+ }
28
+
29
+ if ( ! empty( $image_paths ) ) {
30
+ $image_paths = array_unique( $image_paths );
31
+ if ( function_exists( 'pantheon_wp_clear_edge_paths' ) ) {
32
+ // Do the flush
33
+ pantheon_wp_clear_edge_paths( $image_paths );
34
+ }
35
+ }
36
+ }
37
+ }
38
+
39
+ if ( ! empty( $_ENV['PANTHEON_ENVIRONMENT'] ) ) {
40
+ $p = new Pantheon(); // monitor hook.
41
+ }
class/external/wp-offload-media.php CHANGED
@@ -3,17 +3,25 @@ namespace ShortPixel;
3
  use ShortPixel\ShortPixelLogger\ShortPixelLogger as Log;
4
  use ShortPixel\Notices\NoticeController as Notice;
5
 
 
6
  class wpOffload
7
  {
8
  protected $as3cf;
9
  protected $active = false;
 
 
10
  private $itemClassName;
 
 
11
 
12
  protected $settings;
13
 
14
  protected $is_cname = false;
15
  protected $cname;
16
 
 
 
 
17
  public function __construct()
18
  {
19
  // This must be called before WordPress' init.
@@ -22,22 +30,27 @@ class wpOffload
22
 
23
  public function init($as3cf)
24
  {
 
25
  if (! class_exists('\DeliciousBrains\WP_Offload_Media\Items\Media_Library_Item'))
26
  {
27
  Notice::addWarning(__('Your S3-Offload plugin version doesn\'t seem to be compatible. Please upgrade the S3-Offload plugin', 'shortpixel-image-optimiser'), true);
 
28
  }
29
- else {
30
- $this->itemClassName = '\DeliciousBrains\WP_Offload_Media\Items\Media_Library_Item';
31
- }
 
 
 
 
32
 
33
  $this->as3cf = $as3cf;
34
  $this->active = true;
35
 
36
-
37
  // if setting to upload to bucket is off, don't hook or do anything really.
38
  if (! $this->as3cf->get_setting( 'copy-to-s3' ))
39
  {
40
- return;
41
  }
42
 
43
  if ('cloudfront' === $this->as3cf->get_setting( 'domain' ))
@@ -46,83 +59,44 @@ class wpOffload
46
  $this->cname = $this->as3cf->get_setting( 'cloudfront' );
47
  }
48
 
49
- $provider = $this->as3cf->get_provider();
50
- // $domain = $provider->get_bucket_location();
51
-
52
- // var_dump($domain);
53
-
54
  add_action('shortpixel_image_optimised', array($this, 'image_upload'));
55
- add_action('shortpixel_after_restore_image', array($this, 'image_restore')); // hit this when restoring.
56
- add_action('shortpixel/image/convertpng2jpg_after', array($this, 'image_converted'));
57
  add_action('shortpixel_restore_after_pathget', array($this, 'remove_remote')); // not optimal -> has to do w/ doRestore and when URL/PATH is available when not on server .
58
- add_action('shortpixel/image/convertpng2jpg_before', array($this, 'remove_remote'));
 
 
59
  add_filter('as3cf_attachment_file_paths', array($this, 'add_webp_paths'));
60
- add_filter('as3cf_remove_attachment_paths', array($this, 'remove_webp_paths'));
61
 
62
- add_filter('shortpixel/restore/targetfile', array($this, 'returnOriginalFile'),10,2);
 
 
 
63
 
 
 
 
 
 
 
 
64
  add_filter('as3cf_pre_update_attachment_metadata', array($this, 'preventInitialUpload'), 10,4);
65
 
66
- add_filter('shortpixel_get_attached_file', array($this, 'get_raw_attached_file'),10, 2);
67
- add_filter('shortpixel_get_original_image_path', array($this, 'get_raw_original_path'), 10, 2);
 
 
68
 
69
  // for webp picture paths rendered via output
70
  add_filter('shortpixel_webp_image_base', array($this, 'checkWebpRemotePath'), 10, 2);
71
  add_filter('shortpixel/front/webp_notfound', array($this, 'fixWebpRemotePath'), 10, 4);
72
- }
73
 
74
- public function get_raw_attached_file($file, $id)
75
- {
76
- $scheme = parse_url($file, PHP_URL_SCHEME);
77
 
78
- $item = $this->getItemById($id);
79
- if ($item !== false) // this is a offloaded thingie
80
- {
81
- return get_attached_file($id, true);
82
- }
83
- /*
84
- if ($scheme !== false && strpos($scheme, 's3') !== false)
85
- {
86
- return get_attached_file($id, true);
87
- }
88
- else
89
- {
90
-
91
- } */
92
- return $file;
93
  }
94
 
95
- // partial copy of the wp_get_original_image_path function. It doesn't support raw filter on get_attached_file
96
- public function get_raw_original_path($file, $id)
97
- {
98
-
99
- $scheme = parse_url($file, PHP_URL_SCHEME);
100
- $item = $this->getItemById($id);
101
-
102
- if ($item !== false)
103
- {
104
- $image_meta = wp_get_attachment_metadata( $id );
105
- $image_file = get_attached_file( $id, true );
106
-
107
- if ( empty( $image_meta['original_image'] ) ) {
108
- $original_image = $image_file;
109
- } else {
110
- $original_image = path_join( dirname( $image_file ), $image_meta['original_image'] );
111
- }
112
- $file = $original_image;
113
- }
114
-
115
- return $file;
116
- }
117
-
118
- public function addURLforDownload($bool, $url, $host)
119
- {
120
- $provider = $this->as3cf->get_provider();
121
- $provider->get_url_domain();
122
-
123
- //as3cf_aws_s3_client_args filter?
124
- return $url;
125
- }
126
 
127
  public function returnOriginalFile($file, $attach_id)
128
  {
@@ -130,44 +104,205 @@ class wpOffload
130
  return $file;
131
  }
132
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
133
  public function image_restore($id)
134
  {
135
  $this->remove_remote($id);
136
  $this->image_upload($id);
137
  }
138
 
 
 
139
  public function remove_remote($id)
140
  {
141
- $mediaItem = $this->getItemById($id);
142
- if ($mediaItem === false)
143
  {
144
  Log::addDebug('S3-Offload MediaItem not remote - ' . $id);
145
  return false;
146
  }
147
- // $provider_object = $this->as3cf->get_attachment_provider_info($id);
148
- $this->as3cf->remove_attachment_files_from_provider($id, $mediaItem);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
149
  }
150
 
 
151
  /** @return Returns S3Ofload MediaItem, or false when this does not exist */
152
  protected function getItemById($id)
153
  {
154
- $clazz = $this->itemClassName;
155
- $mediaItem = $clazz::get_by_source_id($id);
 
 
 
 
 
 
 
156
  return $mediaItem;
157
  }
158
 
159
- protected function getByURL($url)
 
160
  {
161
- $class = $this->itemClassName;
162
- $source_id = $class::get_source_id_by_remote_url($url);
163
 
164
  if ($source_id !== false)
165
- return $this->getItemById($source_id);
166
  else
167
  return false;
168
  }
169
 
170
- public function image_converted($id)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
171
  {
172
  $fs = \wpSPIO()->fileSystem();
173
 
@@ -221,8 +356,12 @@ class wpOffload
221
  $this->image_upload($id); // delete and reupload
222
  }
223
 
 
224
  public function image_upload($id)
225
  {
 
 
 
226
  $item = $this->getItemById($id);
227
 
228
  if ( $item === false && ! $this->as3cf->get_setting( 'copy-to-s3' ) ) {
@@ -231,8 +370,25 @@ class wpOffload
231
  return false;
232
  }
233
 
234
- Log::addDebug('Uploading New Attachment');
235
- $this->as3cf->upload_attachment($id);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
236
  }
237
 
238
  /** This function will cut out the initial upload to S3Offload and rely solely on the image_upload function provided here, after shortpixel optimize.
@@ -241,18 +397,25 @@ class wpOffload
241
  */
242
  public function preventInitialUpload($bool, $data, $post_id, $old_provider_object)
243
  {
244
- $settings = \wpSPIO()->settings();
245
-
246
- if ($settings->autoMediaLibrary)
247
- {
248
- // Don't prevent whaffever if shortpixel is already done. This can be caused by plugins doing a metadata update, we don't care then.
249
- if (! isset($data['ShortPixelImprovement']))
250
- {
251
- Log::addDebug('Preventing Initial Upload', $post_id);
252
- return true;
253
- }
254
- }
255
- return $bool;
 
 
 
 
 
 
 
256
  }
257
 
258
  private function getWebpPaths($paths, $check_exists = true)
@@ -269,6 +432,9 @@ class wpOffload
269
  $webpformat1 = $basepath . $file->getFileName() . '.webp';
270
  $webpformat2 = $basepath . $file->getFileBase() . '.webp';
271
 
 
 
 
272
  if ($check_exists)
273
  {
274
  if (file_exists($webpformat1))
@@ -287,6 +453,17 @@ class wpOffload
287
  $newPaths[$size . '_webp2'] = $webpformat2;
288
  }
289
 
 
 
 
 
 
 
 
 
 
 
 
290
  }
291
 
292
  return $newPaths;
@@ -299,17 +476,20 @@ class wpOffload
299
  {
300
  // Log::addDebug('Received Paths', array($paths));
301
  $paths = $this->getWebpPaths($paths, true);
302
- // Log::addDebug('Webp Path Founder (S3)', array($paths));
303
  return $paths;
304
  }
305
 
 
306
  public function remove_webp_paths($paths)
307
  {
308
  $paths = $this->getWebpPaths($paths, false);
309
- // Log::addDebug('Remove S3 Paths', array($paths));
 
310
  return $paths;
311
  }
312
 
 
313
  public function checkWebpRemotePath($url, $original)
314
  {
315
  if ($url === false)
@@ -353,25 +533,12 @@ class wpOffload
353
  }
354
 
355
  // GetbyURL can't find thumbnails, only the main image. We are going to assume, if imagebase is ok, the webp might be there.
356
- // ImageBase is fileDir as String, not object!
357
  public function fixWebpRemotePath($bool, $file, $url, $imagebase)
358
  {
359
- if (strpos($url, $imagebase) !== false)
360
  return $file;
361
  else
362
  return $bool;
363
-
364
- /* $mediaItem = $this->getByURL($url);
365
- if ($mediaItem !== false)
366
- {
367
- return $file;
368
- }
369
- else
370
- {
371
- // Log::addDebug('Fixing Remote Path failed', array($file->getFullPath(), $url));
372
- }
373
- return false; */
374
-
375
  }
376
 
377
  }
3
  use ShortPixel\ShortPixelLogger\ShortPixelLogger as Log;
4
  use ShortPixel\Notices\NoticeController as Notice;
5
 
6
+ // @integration WP Offload Media Lite
7
  class wpOffload
8
  {
9
  protected $as3cf;
10
  protected $active = false;
11
+ protected $offloading = true;
12
+
13
  private $itemClassName;
14
+ private $useHandlers = false; // Check for newer ItemHandlers or Compat mode.
15
+ protected $shouldPrevent = true; // if offload should be prevented. This is turned off when SPIO want to tell S3 to offload. Better than removing filter.
16
 
17
  protected $settings;
18
 
19
  protected $is_cname = false;
20
  protected $cname;
21
 
22
+ // if might have to do these checks many times for each thumbnails, keep it fastish.
23
+ //protected $retrievedCache = array();
24
+
25
  public function __construct()
26
  {
27
  // This must be called before WordPress' init.
30
 
31
  public function init($as3cf)
32
  {
33
+
34
  if (! class_exists('\DeliciousBrains\WP_Offload_Media\Items\Media_Library_Item'))
35
  {
36
  Notice::addWarning(__('Your S3-Offload plugin version doesn\'t seem to be compatible. Please upgrade the S3-Offload plugin', 'shortpixel-image-optimiser'), true);
37
+ return false;
38
  }
39
+
40
+ $this->itemClassName = '\DeliciousBrains\WP_Offload_Media\Items\Media_Library_Item';
41
+
42
+ if (method_exists($as3cf, 'get_item_handler'))
43
+ {
44
+ $this->useHandlers = true; // we have a new version
45
+ }
46
 
47
  $this->as3cf = $as3cf;
48
  $this->active = true;
49
 
 
50
  // if setting to upload to bucket is off, don't hook or do anything really.
51
  if (! $this->as3cf->get_setting( 'copy-to-s3' ))
52
  {
53
+ $this->offloading = false;
54
  }
55
 
56
  if ('cloudfront' === $this->as3cf->get_setting( 'domain' ))
59
  $this->cname = $this->as3cf->get_setting( 'cloudfront' );
60
  }
61
 
62
+ // $provider = $this->as3cf->get_provider();
 
 
 
 
63
  add_action('shortpixel_image_optimised', array($this, 'image_upload'));
64
+ add_action('shortpixel_after_restore_image', array($this, 'image_restore'), 10, 3); // hit this when restoring.
65
+
66
  add_action('shortpixel_restore_after_pathget', array($this, 'remove_remote')); // not optimal -> has to do w/ doRestore and when URL/PATH is available when not on server .
67
+
68
+ // Seems this better served by _after? If it fails, it's removed from remote w/o filechange.
69
+ // add_action('shortpixel/image/convertpng2jpg_before', array($this, 'remove_remote'));
70
  add_filter('as3cf_attachment_file_paths', array($this, 'add_webp_paths'));
 
71
 
72
+ if ($this->useHandlers)
73
+ {
74
+ // add_filter('as3cf_remove_source_files_from_provider', array($this, 'remove_webp_paths'), 10);
75
+ add_action('shortpixel/image/convertpng2jpg_success', array($this, 'image_converted'), 10);
76
 
77
+ }
78
+ else {
79
+ add_filter('as3cf_remove_attachment_paths', array($this, 'remove_webp_paths'));
80
+ add_action('shortpixel/image/convertpng2jpg_after', array($this, 'image_converted_legacy'), 10, 2);
81
+ }
82
+
83
+ add_filter('shortpixel/restore/targetfile', array($this, 'returnOriginalFile'),10,2);
84
  add_filter('as3cf_pre_update_attachment_metadata', array($this, 'preventInitialUpload'), 10,4);
85
 
86
+ // add_filter('shortpixel_get_attached_file', array($this, 'get_raw_attached_file'),10, 2);
87
+ // add_filter('shortpixel_get_original_image_path', array($this, 'get_raw_original_path'), 10, 2);
88
+ add_filter('shortpixel/image/urltopath', array($this, 'checkIfOffloaded'), 10,2);
89
+ add_filter('shortpixel/file/virtual/translate', array($this, 'getLocalPathByURL'));
90
 
91
  // for webp picture paths rendered via output
92
  add_filter('shortpixel_webp_image_base', array($this, 'checkWebpRemotePath'), 10, 2);
93
  add_filter('shortpixel/front/webp_notfound', array($this, 'fixWebpRemotePath'), 10, 4);
 
94
 
95
+ //add_filter('as3cf_remove_source_files_from_provider', function ($paths){ Log::addTemp("removing these paths", $paths); return $paths;
96
+ //}, 20);
 
97
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
98
  }
99
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
100
 
101
  public function returnOriginalFile($file, $attach_id)
102
  {
104
  return $file;
105
  }
106
 
107
+ private function getMediaClass()
108
+ {
109
+ if ($this->useHandlers)
110
+ {
111
+ $class = $this->as3cf->get_source_type_class('media-library');
112
+ }
113
+ else
114
+ {
115
+ $class = $this->itemClassName; //backward compat.
116
+ }
117
+
118
+ return $class;
119
+ }
120
+
121
+ /**
122
+ * @param $id attachment id (WP)
123
+ * @param $mediaItem MediaLibraryModel SPIO
124
+ * @param $clean - boolean - if restore did all files (clean) or partial (not clean)
125
+ */
126
  public function image_restore($id)
127
  {
128
  $this->remove_remote($id);
129
  $this->image_upload($id);
130
  }
131
 
132
+
133
+
134
  public function remove_remote($id)
135
  {
136
+ $item = $this->getItemById($id); // MediaItem is AS3CF Object
137
+ if ($item === false)
138
  {
139
  Log::addDebug('S3-Offload MediaItem not remote - ' . $id);
140
  return false;
141
  }
142
+
143
+ // Backwards compat.
144
+ if ($this->useHandlers)
145
+ {
146
+ $remove = \DeliciousBrains\WP_Offload_Media\Items\Remove_Provider_Handler::get_item_handler_key_name();
147
+ $itemHandler = $this->as3cf->get_item_handler($remove);
148
+ // $files = $a3cfItem->offloaded_files();
149
+ $result = $itemHandler->handle($item, array( 'verify_exists_on_local' => false)); //handle it then.
150
+ // $result = $itemHandler->handle($item, array( 'verify_exists_on_local' => false, 'offloaded_files' => $files )); //handle it then.
151
+
152
+ }
153
+ else // compat.
154
+ {
155
+ $this->as3cf->remove_attachment_files_from_provider($id, $item);
156
+ }
157
+
158
  }
159
 
160
+
161
  /** @return Returns S3Ofload MediaItem, or false when this does not exist */
162
  protected function getItemById($id)
163
  {
164
+ $class = $this->getMediaClass();
165
+ $mediaItem = $class::get_by_source_id($id);
166
+
167
+ if ($this->useHandlers && $mediaItem === false)
168
+ {
169
+ Log::addWarn('Important. Creating S3 Item New ' . $id);
170
+ $mediaItem = $class::create_from_source_id($id);
171
+ }
172
+
173
  return $mediaItem;
174
  }
175
 
176
+
177
+ public function checkIfOffloaded($bool, $url)
178
  {
179
+ $source_id = $this->getSourceIDByURL($url);
 
180
 
181
  if ($source_id !== false)
182
+ return true;
183
  else
184
  return false;
185
  }
186
 
187
+ protected function getSourceIDByURL($url)
188
+ {
189
+ $class = $this->getMediaClass();
190
+ $source = $class::get_item_source_by_remote_url($url);
191
+
192
+ /// Function can return false
193
+ if ($source === false)
194
+ return false;
195
+
196
+ $source_id = isset($source['id']) ? intval($source['id']) : false;
197
+
198
+ if ($source_id !== false)
199
+ return $source_id;
200
+ else
201
+ {
202
+ $source_id = $this->checkIfThumbnail($url); // can be item or false.
203
+ return $source_id;
204
+ }
205
+
206
+ return false;
207
+ }
208
+
209
+ //** The thumbnails are not recorded by offload, but still offloaded.
210
+ private function checkIfThumbnail($original_url)
211
+ {
212
+ //$result = \attachment_url_to_postid($url);
213
+ $pattern = '/(.*)-\d+[xX]\d+(\.\w+)/m';
214
+ $url = preg_replace($pattern, '$1$2', $original_url);
215
+
216
+ $class = $this->getMediaClass();
217
+ $source = $class::get_item_source_by_remote_url($url);
218
+
219
+ $source_id = isset($source['id']) ? intval($source['id']) : false;
220
+
221
+ if ($source_id !== false)
222
+ return $source_id;
223
+ else
224
+ return false;
225
+
226
+ }
227
+
228
+ public function getLocalPathByURL($url)
229
+ {
230
+ $source_id = $this->getSourceIDByURL($url);
231
+ if ($source_id == false)
232
+ {
233
+ return false;
234
+ }
235
+ $item = $this->getItemById($source_id);
236
+
237
+ $original_path = $item->original_source_path(); // $values['original_source_path'];
238
+
239
+ if (wp_basename($url) !== wp_basename($original_path)) // thumbnails translate to main file.
240
+ {
241
+ $original_path = str_replace(wp_basename($original_path), wp_basename($url), $original_path);
242
+ }
243
+
244
+ $fs = \wpSPIO()->filesystem();
245
+ $base = $fs->getWPUploadBase();
246
+
247
+ $file = $fs->getFile($base . $original_path);
248
+ return $file;
249
+ }
250
+
251
+
252
+ /** Converted after png2jpg
253
+ *
254
+ * @param MediaItem Object SPIO
255
+ */
256
+ public function image_converted($mediaItem)
257
+ {
258
+ $fs = \wpSPIO()->fileSystem();
259
+
260
+ // Do nothing if not successfull
261
+ if ($params['success'] === false)
262
+ return;
263
+
264
+ Log::addTemp('S3Off Converting ');
265
+ $id = $mediaItem->get('id');
266
+ $this->remove_remote($id);
267
+
268
+ $item = $this->getItemById($id);
269
+ $item->delete();
270
+
271
+ $this->image_upload($id);
272
+ return;
273
+ // delete the old file
274
+ // $item = $this->getItemById($id);
275
+ // if ($mediaItem === false) // mediaItem seems not present. Probably not a remote file
276
+ // return;
277
+
278
+ //$providerFile = $fs->getFile($providerSourcePath);
279
+ //$newFile = $fs->getFile($this->returnOriginalFile(null, $id));
280
+
281
+
282
+ // convert
283
+ if ($providerFile->getExtension() !== $newFile->getExtension())
284
+ {
285
+ $data = $mediaItem->key_values(true);
286
+ $record_id = $data['id'];
287
+
288
+ $data['path'] = str_replace($providerFile->getFileName(), $newFile->getFileName(), $data['path']);
289
+
290
+
291
+ //$provider, $region, $bucket, $path, $is_private, $source_id, $source_path, $original_filename = null, $private_sizes = array(), $id = null
292
+ $class = $this->getMediaClass();
293
+ $newItem = new $class($data['provider'], $data['region'], $data['bucket'], $data['path'], $data['is_private'], $data['source_id'], $data['source_path'], $newFile->getFileName(), $data['extra_info'], $record_id );
294
+
295
+ $newItem->save();
296
+
297
+ Log::addDebug('S3Offload - Uploading converted file ');
298
+ }
299
+
300
+ // upload
301
+ $this->image_upload($id); // delete and reupload
302
+ }
303
+
304
+
305
+ public function image_converted_legacy($id)
306
  {
307
  $fs = \wpSPIO()->fileSystem();
308
 
356
  $this->image_upload($id); // delete and reupload
357
  }
358
 
359
+
360
  public function image_upload($id)
361
  {
362
+ if (! $this->offloading)
363
+ return false;
364
+
365
  $item = $this->getItemById($id);
366
 
367
  if ( $item === false && ! $this->as3cf->get_setting( 'copy-to-s3' ) ) {
370
  return false;
371
  }
372
 
373
+ $this->shouldPrevent = false;
374
+ $data = wp_get_attachment_metadata($id);
375
+ $data = apply_filters('wp_update_attachment_metadata', $data, $id);
376
+ $this->shouldPrevent = true;
377
+
378
+ // Log::addTemp('Image Upload', $item->objects() );
379
+ return;
380
+
381
+ if ($this->useHandlers)
382
+ {
383
+ // This should load the A3cf UploadHandler
384
+ $upload = \DeliciousBrains\WP_Offload_Media\Items\Upload_Handler::get_item_handler_key_name();
385
+ $itemHandler = $this->as3cf->get_item_handler($upload);
386
+ $result = $itemHandler->handle($item); //handle it then.
387
+ Log::addTemp('S3Offload Upload Result', $result);
388
+ }
389
+ else {
390
+ $this->as3cf->upload_attachment($id);
391
+ }
392
  }
393
 
394
  /** This function will cut out the initial upload to S3Offload and rely solely on the image_upload function provided here, after shortpixel optimize.
397
  */
398
  public function preventInitialUpload($bool, $data, $post_id, $old_provider_object)
399
  {
400
+ $settings = \wpSPIO()->settings();
401
+
402
+ if ($settings->autoMediaLibrary)
403
+ {
404
+ // Don't prevent whaffever if shortpixel is already done. This can be caused by plugins doing a metadata update, we don't care then.
405
+ if (! isset($data['ShortPixelImprovement']) && $this->shouldPrevent === true)
406
+ {
407
+ $file = get_attached_file($post_id);
408
+ if (strpos($file, '.pdf') !== false && ! $settings->optimizePdfs )
409
+ {
410
+ Log::addDebug('S3 Prevent Initial Upload detected PDF, which will not be optimized', $post_id);
411
+ return false;
412
+ }
413
+
414
+ Log::addDebug('Preventing Initial Upload', $post_id);
415
+ return true;
416
+ }
417
+ }
418
+ return $bool;
419
  }
420
 
421
  private function getWebpPaths($paths, $check_exists = true)
432
  $webpformat1 = $basepath . $file->getFileName() . '.webp';
433
  $webpformat2 = $basepath . $file->getFileBase() . '.webp';
434
 
435
+ $avifformat = $basepath . $file->getFileBase() . '.avif';
436
+
437
+
438
  if ($check_exists)
439
  {
440
  if (file_exists($webpformat1))
453
  $newPaths[$size . '_webp2'] = $webpformat2;
454
  }
455
 
456
+ if ($check_exists)
457
+ {
458
+ if (file_exists($avifformat))
459
+ {
460
+ $newPaths[$size . '_avif'] = $avifformat;
461
+ }
462
+ }
463
+ else {
464
+ $newPaths[$size . '_avif'] = $avifformat;
465
+ }
466
+
467
  }
468
 
469
  return $newPaths;
476
  {
477
  // Log::addDebug('Received Paths', array($paths));
478
  $paths = $this->getWebpPaths($paths, true);
479
+ Log::addDebug('Webp Path Founder (S3)', array($paths));
480
  return $paths;
481
  }
482
 
483
+
484
  public function remove_webp_paths($paths)
485
  {
486
  $paths = $this->getWebpPaths($paths, false);
487
+ //Log::addDebug('Remove S3 Paths', array($paths));
488
+
489
  return $paths;
490
  }
491
 
492
+
493
  public function checkWebpRemotePath($url, $original)
494
  {
495
  if ($url === false)
533
  }
534
 
535
  // GetbyURL can't find thumbnails, only the main image. We are going to assume, if imagebase is ok, the webp might be there.
 
536
  public function fixWebpRemotePath($bool, $file, $url, $imagebase)
537
  {
538
+ if (strpos($url, $imagebase ) !== false)
539
  return $file;
540
  else
541
  return $bool;
 
 
 
 
 
 
 
 
 
 
 
 
542
  }
543
 
544
  }
class/view/settings/part-advanced.php CHANGED
@@ -340,16 +340,24 @@ namespace ShortPixel;
340
  </p>
341
  </td>
342
  </tr>
 
 
343
  <tr>
344
  <th scope="row"><label for="authentication"><?php _e('HTTP AUTH credentials','shortpixel-image-optimiser');?></label></th>
345
  <td>
346
- <input name="siteAuthUser" type="text" id="siteAuthUser" value="<?php echo( stripslashes(esc_html($view->data->siteAuthUser )));?>" class="regular-text" placeholder="<?php _e('User','shortpixel-image-optimiser');?>"><br>
 
347
  <input name="siteAuthPass" type="text" id="siteAuthPass" value="<?php echo( stripslashes(esc_html($view->data->siteAuthPass )));?>" class="regular-text" placeholder="<?php _e('Password','shortpixel-image-optimiser');?>">
348
  <p class="settings-info">
349
  <?php _e('Only fill in these fields if your site (front-end) is not publicly accessible and visitors need a user/pass to connect to it. If you don\'t know what is this then just <strong>leave the fields empty</strong>.','shortpixel-image-optimiser');?>
350
  </p>
 
 
 
 
351
  </td>
352
  </tr>
 
353
  <tr>
354
  <th scope="row"><?php _e('Optimize media on upload','shortpixel-image-optimiser');?></th>
355
  <td>
340
  </p>
341
  </td>
342
  </tr>
343
+
344
+
345
  <tr>
346
  <th scope="row"><label for="authentication"><?php _e('HTTP AUTH credentials','shortpixel-image-optimiser');?></label></th>
347
  <td>
348
+ <?php if (! defined('SHORTPIXEL_HTTP_AUTH_USER')): ?>
349
+ <input name="siteAuthUser" type="text" id="siteAuthUser" value="<?php echo( stripslashes(esc_html($view->data->siteAuthUser )));?>" class="regular-text" placeholder="<?php _e('User','shortpixel-image-optimiser');?>"><br>
350
  <input name="siteAuthPass" type="text" id="siteAuthPass" value="<?php echo( stripslashes(esc_html($view->data->siteAuthPass )));?>" class="regular-text" placeholder="<?php _e('Password','shortpixel-image-optimiser');?>">
351
  <p class="settings-info">
352
  <?php _e('Only fill in these fields if your site (front-end) is not publicly accessible and visitors need a user/pass to connect to it. If you don\'t know what is this then just <strong>leave the fields empty</strong>.','shortpixel-image-optimiser');?>
353
  </p>
354
+ <?php else: ?>
355
+ <p><?php _e('The HTTP AUth credentials have been defined in the wp-config file', 'shortpixel-image-optimiser'); ?></p>
356
+ <?php endif; ?>
357
+
358
  </td>
359
  </tr>
360
+
361
  <tr>
362
  <th scope="row"><?php _e('Optimize media on upload','shortpixel-image-optimiser');?></th>
363
  <td>
class/wp-short-pixel.php CHANGED
@@ -3060,12 +3060,12 @@ class WPShortPixel {
3060
  RewriteCond %{REQUEST_URI} ^(.+)\.(?:jpe?g|png)$
3061
  # AND does a .avif image exist?
3062
  RewriteCond %{DOCUMENT_ROOT}/%1.avif -f
3063
- # THEN send the webp image and set the env var avif
3064
  RewriteRule (.+)\.(?:jpe?g|png)$ $1.avif [NC,T=image/avif,E=avif,L]
3065
 
3066
  </IfModule>
3067
  <IfModule mod_headers.c>
3068
- # If REDIRECT_webp env var exists, append Accept to the Vary header
3069
  Header append Vary Accept env=REDIRECT_avif
3070
  </IfModule>
3071
 
@@ -3087,8 +3087,8 @@ class WPShortPixel {
3087
  RewriteCond %{HTTP_ACCEPT} image/webp
3088
  # AND NOT MS EDGE 42/17 - doesnt work.
3089
  RewriteCond %{HTTP_USER_AGENT} !Edge/17
3090
- # AND is the request a jpg or png?
3091
- RewriteCond %{REQUEST_URI} ^(.+)\.(?:jpe?g|png)$
3092
  # AND does a .ext.webp image exist?
3093
  RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI}.webp -f
3094
  # THEN send the webp image and set the env var webp
@@ -3099,12 +3099,12 @@ class WPShortPixel {
3099
  RewriteCond %{HTTP_USER_AGENT} "Google Page Speed Insights" [OR]
3100
  RewriteCond %{HTTP_ACCEPT} image/webp
3101
  RewriteCond %{HTTP_USER_AGENT} !Edge/17
3102
- # AND is the request a jpg or png? (also grab the basepath %1 to match in the next rule)
3103
- RewriteCond %{REQUEST_URI} ^(.+)\.(?:jpe?g|png)$
3104
  # AND does a .ext.webp image exist?
3105
  RewriteCond %{DOCUMENT_ROOT}/%1.webp -f
3106
  # THEN send the webp image and set the env var webp
3107
- RewriteRule (.+)\.(?:jpe?g|png)$ $1.webp [NC,T=image/webp,E=webp,L]
3108
 
3109
  </IfModule>
3110
  <IfModule mod_headers.c>
@@ -3164,7 +3164,7 @@ class WPShortPixel {
3164
  if ($this->_settings->createAvif)
3165
  {
3166
  if (! isset($mimes['avif']))
3167
- $mimes['webp'] = 'image/avif';
3168
  }
3169
  return $mimes;
3170
  }
@@ -3205,7 +3205,14 @@ class WPShortPixel {
3205
  }
3206
  $args['body']['host'] = parse_url(get_site_url(),PHP_URL_HOST);
3207
  $argsStr .= "&host={$args['body']['host']}";
3208
- if(strlen($this->_settings->siteAuthUser)) {
 
 
 
 
 
 
 
3209
 
3210
  $args['body']['user'] = stripslashes($this->_settings->siteAuthUser);
3211
  $args['body']['pass'] = stripslashes($this->_settings->siteAuthPass);
3060
  RewriteCond %{REQUEST_URI} ^(.+)\.(?:jpe?g|png)$
3061
  # AND does a .avif image exist?
3062
  RewriteCond %{DOCUMENT_ROOT}/%1.avif -f
3063
+ # THEN send the avif image and set the env var avif
3064
  RewriteRule (.+)\.(?:jpe?g|png)$ $1.avif [NC,T=image/avif,E=avif,L]
3065
 
3066
  </IfModule>
3067
  <IfModule mod_headers.c>
3068
+ # If REDIRECT_avif env var exists, append Accept to the Vary header
3069
  Header append Vary Accept env=REDIRECT_avif
3070
  </IfModule>
3071
 
3087
  RewriteCond %{HTTP_ACCEPT} image/webp
3088
  # AND NOT MS EDGE 42/17 - doesnt work.
3089
  RewriteCond %{HTTP_USER_AGENT} !Edge/17
3090
+ # AND is the request a jpg, png or gif?
3091
+ RewriteCond %{REQUEST_URI} ^(.+)\.(?:jpe?g|png|gif)$
3092
  # AND does a .ext.webp image exist?
3093
  RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI}.webp -f
3094
  # THEN send the webp image and set the env var webp
3099
  RewriteCond %{HTTP_USER_AGENT} "Google Page Speed Insights" [OR]
3100
  RewriteCond %{HTTP_ACCEPT} image/webp
3101
  RewriteCond %{HTTP_USER_AGENT} !Edge/17
3102
+ # AND is the request a jpg, png or gif? (also grab the basepath %1 to match in the next rule)
3103
+ RewriteCond %{REQUEST_URI} ^(.+)\.(?:jpe?g|png|gif)$
3104
  # AND does a .ext.webp image exist?
3105
  RewriteCond %{DOCUMENT_ROOT}/%1.webp -f
3106
  # THEN send the webp image and set the env var webp
3107
+ RewriteRule (.+)\.(?:jpe?g|png|gif)$ $1.webp [NC,T=image/webp,E=webp,L]
3108
 
3109
  </IfModule>
3110
  <IfModule mod_headers.c>
3164
  if ($this->_settings->createAvif)
3165
  {
3166
  if (! isset($mimes['avif']))
3167
+ $mimes['avif'] = 'image/avif';
3168
  }
3169
  return $mimes;
3170
  }
3205
  }
3206
  $args['body']['host'] = parse_url(get_site_url(),PHP_URL_HOST);
3207
  $argsStr .= "&host={$args['body']['host']}";
3208
+
3209
+ if (defined('SHORTPIXEL_HTTP_AUTH_USER') && defined('SHORTPIXEL_HTTP_AUTH_PASSWORD'))
3210
+ {
3211
+ $args['body']['user'] = stripslashes(SHORTPIXEL_HTTP_AUTH_USER);
3212
+ $args['body']['pass'] = stripslashes(SHORTPIXEL_HTTP_AUTH_PASSWORD);
3213
+ $argsStr .= '&user=' . urlencode($args['body']['user']) . '&pass=' . urlencode($args['body']['pass']);
3214
+ }
3215
+ elseif(strlen($this->_settings->siteAuthUser)) {
3216
 
3217
  $args['body']['user'] = stripslashes($this->_settings->siteAuthUser);
3218
  $args['body']['pass'] = stripslashes($this->_settings->siteAuthPass);
readme.txt CHANGED
@@ -2,9 +2,9 @@
2
  Contributors: ShortPixel
3
  Tags: convert webp, optimize images, image optimization, resize, compressor, image, avif, compression, optimize, image optimiser, image compression, compress pdf, compress jpg, compress png, performance, photography, smush, scale, pictures
4
  Requires at least: 4.2.0
5
- Tested up to: 5.9
6
  Requires PHP: 5.6
7
- Stable tag: 4.22.8
8
  License: GPLv2 or later
9
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
10
 
@@ -81,11 +81,11 @@ Help us spread the word by recommending ShortPixel to your friends and collect *
81
 
82
  **Other plugins by ShortPixel**
83
 
84
- * Image optimization & CDN on the fly - <a href="https://wordpress.org/plugins/shortpixel-adaptive-images/" target="_blank">ShortPixel Adaptive Images</a>
85
- * Easily replace images or files in Media Library - <a href="https://wordpress.org/plugins/enable-media-replace/" target="_blank">Enable Media Replace</a>
86
- * Regenerate thumbnails plugin compatible with the other ShortPixel plugins - <a href="https://wordpress.org/plugins/regenerate-thumbnails-advanced/" target="_blank">reGenerate Thumbnails Advanced</a>
87
- * Make sure you don't have huge images in your Media Library - <a href="https://wordpress.org/plugins/resize-image-after-upload/" target="_blank">Resize Image After Upload</a>
88
-
89
 
90
  **Get in touch!**
91
 
@@ -284,6 +284,11 @@ Hide the Cloudflare settings by defining these constants in wp-config.php:
284
  `define('SHORTPIXEL_CFTOKEN', 'the Cloudflare API token that has Purge Cache right');`
285
  `define('SHORTPIXEL_CFZONE', 'The Zone ID from the domain settings in Cloudflare');`
286
 
 
 
 
 
 
287
  Hide the WSO banner in the settings by defining this constant in wp-config.php:
288
 
289
  `define('SHORTPIXEL_NO_BANNER', true);`
@@ -314,6 +319,18 @@ Alternatively, you can use this filter in your theme's functions.php file:
314
 
315
  == Changelog ==
316
 
 
 
 
 
 
 
 
 
 
 
 
 
317
  = 4.22.8 =
318
  Release date February 8th, 2022
319
  * Fix: an error was occurring on new installs when using PHP8;
@@ -547,3 +564,9 @@ Release date: 2nd April 2020
547
 
548
  = EARLIER VERSIONS =
549
  * please refer to the <a href="https://github.com/short-pixel-optimizer/shortpixel-image-optimiser/blob/master/changelog.txt" target="_blank">changelog.txt</a> file inside the plugin archive.
 
 
 
 
 
 
2
  Contributors: ShortPixel
3
  Tags: convert webp, optimize images, image optimization, resize, compressor, image, avif, compression, optimize, image optimiser, image compression, compress pdf, compress jpg, compress png, performance, photography, smush, scale, pictures
4
  Requires at least: 4.2.0
5
+ Tested up to: 6.0
6
  Requires PHP: 5.6
7
+ Stable tag: 4.22.9
8
  License: GPLv2 or later
9
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
10
 
81
 
82
  **Other plugins by ShortPixel**
83
 
84
+ * [ShortPixel Adaptive Images](https://wordpress.org/plugins/shortpixel-adaptive-images/) - On-the-fly image optimization & CDN delivery
85
+ * [Enable Media Replace](https://wordpress.org/plugins/enable-media-replace/) - Easily replace images or files in Media Library
86
+ * [reGenerate Thumbnails Advanced](https://wordpress.org/plugins/regenerate-thumbnails-advanced/) - Easily regenerate thumbnails
87
+ * [Resize Image After Upload](https://wordpress.org/plugins/resize-image-after-upload/) - Automatically resize each uploaded image
88
+ * [WP SVG Images](https://wordpress.org/plugins/wp-svg-images/) - Secure upload of SVG files to Media Library
89
 
90
  **Get in touch!**
91
 
284
  `define('SHORTPIXEL_CFTOKEN', 'the Cloudflare API token that has Purge Cache right');`
285
  `define('SHORTPIXEL_CFZONE', 'The Zone ID from the domain settings in Cloudflare');`
286
 
287
+ Add HTTP basic authentication credentials by defining these constants in wp-config.php
288
+
289
+ `define('SHORTPIXEL_HTTP_AUTH_USER', 'user');`
290
+ `define('SHORTPIXEL_HTTP_AUTH_PASSWORD', 'pass');`
291
+
292
  Hide the WSO banner in the settings by defining this constant in wp-config.php:
293
 
294
  `define('SHORTPIXEL_NO_BANNER', true);`
319
 
320
  == Changelog ==
321
 
322
+ = 4.22.9 =
323
+ Release date March 31st, 2022
324
+ * Fix: fixed the integration with the WP Media Offload plugin, which was broken in version 3.6.0;
325
+ * Fix: added support for offloading AVIF files via WP Media Offload;
326
+ * Fix: PDF files were not offloaded via WP Media Offload if the process PDF option wasn't enabled in SPIO;
327
+ * Fix: added support for delivering animated gif files as WebP when using the .htaccess method;
328
+ * Fix: the link for the plugin settings was leading to a 404 in the network admin of a multisite install;
329
+ * Tweak: added 2 new constants for adding the HTTP basic authentication credentials directly in wp-config.php;
330
+ * Tweak: added a notification in case of downgrading from the upcoming SPIO 5 version;
331
+ * Compat: added integration with Pantheon cache, thanks to @TrilipuT & @LogicEveryWhere;
332
+ * Language: 3 new strings added, 0 updated, 0 fuzzed, and 0 obsoleted.
333
+
334
  = 4.22.8 =
335
  Release date February 8th, 2022
336
  * Fix: an error was occurring on new installs when using PHP8;
564
 
565
  = EARLIER VERSIONS =
566
  * please refer to the <a href="https://github.com/short-pixel-optimizer/shortpixel-image-optimiser/blob/master/changelog.txt" target="_blank">changelog.txt</a> file inside the plugin archive.
567
+
568
+ == Upgrade Notice ==
569
+
570
+ = 4.22.9 =
571
+
572
+ * This version contains a fix for the WP Offload Media plugin version 2.6.0 and above. Please ensure you're running the latest WP Offload Media plugin and check that everything works correctly after upgrading.
res/img/.htaccess CHANGED
@@ -8,8 +8,8 @@
8
  RewriteCond %{HTTP_USER_AGENT} "Google Page Speed Insights" [OR]
9
  # OR does this browser explicitly support webp
10
  RewriteCond %{HTTP_ACCEPT} image/webp
11
- # AND is the request a jpg or png?
12
- RewriteCond %{REQUEST_URI} ^(.+)\.(?:jpe?g|png)$
13
  # AND does a .ext.webp image exist?
14
  RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI}.webp -f
15
  # THEN send the webp image and set the env var webp
@@ -19,12 +19,12 @@
19
  RewriteCond %{HTTP_USER_AGENT} Chrome [OR]
20
  RewriteCond %{HTTP_USER_AGENT} "Google Page Speed Insights" [OR]
21
  RewriteCond %{HTTP_ACCEPT} image/webp
22
- # AND is the request a jpg or png? (also grab the basepath %1 to match in the next rule)
23
- RewriteCond %{REQUEST_URI} ^(.+)\.(?:jpe?g|png)$
24
  # AND does a .ext.webp image exist?
25
  RewriteCond %{DOCUMENT_ROOT}/%1.webp -f
26
  # THEN send the webp image and set the env var webp
27
- RewriteRule (.+)\.(?:jpe?g|png)$ $1.webp [NC,T=image/webp,E=webp,L]
28
 
29
  </IfModule>
30
  <IfModule mod_headers.c>
8
  RewriteCond %{HTTP_USER_AGENT} "Google Page Speed Insights" [OR]
9
  # OR does this browser explicitly support webp
10
  RewriteCond %{HTTP_ACCEPT} image/webp
11
+ # AND is the request a jpg, png or gif?
12
+ RewriteCond %{REQUEST_URI} ^(.+)\.(?:jpe?g|png|gif)$
13
  # AND does a .ext.webp image exist?
14
  RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI}.webp -f
15
  # THEN send the webp image and set the env var webp
19
  RewriteCond %{HTTP_USER_AGENT} Chrome [OR]
20
  RewriteCond %{HTTP_USER_AGENT} "Google Page Speed Insights" [OR]
21
  RewriteCond %{HTTP_ACCEPT} image/webp
22
+ # AND is the request a jpg, png or gif? (also grab the basepath %1 to match in the next rule)
23
+ RewriteCond %{REQUEST_URI} ^(.+)\.(?:jpe?g|png|gif)$
24
  # AND does a .ext.webp image exist?
25
  RewriteCond %{DOCUMENT_ROOT}/%1.webp -f
26
  # THEN send the webp image and set the env var webp
27
+ RewriteRule (.+)\.(?:jpe?g|png|gif)$ $1.webp [NC,T=image/webp,E=webp,L]
28
 
29
  </IfModule>
30
  <IfModule mod_headers.c>
wp-shortpixel.php CHANGED
@@ -2,8 +2,8 @@
2
  /**
3
  * Plugin Name: ShortPixel Image Optimizer
4
  * Plugin URI: https://shortpixel.com/
5
- * Description: ShortPixel optimizes images automatically, while guarding the quality of your images. Check your <a href="options-general.php?page=wp-shortpixel-settings" target="_blank">Settings &gt; ShortPixel</a> page on how to start optimizing your image library and make your website load faster.
6
- * Version: 4.22.8
7
  * Author: ShortPixel
8
  * Author URI: https://shortpixel.com
9
  * GitHub Plugin URI: https://github.com/short-pixel-optimizer/shortpixel-image-optimiser
@@ -33,7 +33,7 @@ define('SHORTPIXEL_PLUGIN_DIR', __DIR__);
33
 
34
  //define('SHORTPIXEL_AFFILIATE_CODE', '');
35
 
36
- define('SHORTPIXEL_IMAGE_OPTIMISER_VERSION', "4.22.8");
37
  define('SHORTPIXEL_MAX_TIMEOUT', 10);
38
  define('SHORTPIXEL_VALIDATE_MAX_TIMEOUT', 15);
39
  define('SHORTPIXEL_BACKUP', 'ShortpixelBackups');
2
  /**
3
  * Plugin Name: ShortPixel Image Optimizer
4
  * Plugin URI: https://shortpixel.com/
5
+ * Description: ShortPixel optimizes images automatically, while guarding the quality of your images. Check your <a href="/wp-admin/options-general.php?page=wp-shortpixel-settings" target="_blank">Settings &gt; ShortPixel</a> page on how to start optimizing your image library and make your website load faster.
6
+ * Version: 4.22.9
7
  * Author: ShortPixel
8
  * Author URI: https://shortpixel.com
9
  * GitHub Plugin URI: https://github.com/short-pixel-optimizer/shortpixel-image-optimiser
33
 
34
  //define('SHORTPIXEL_AFFILIATE_CODE', '');
35
 
36
+ define('SHORTPIXEL_IMAGE_OPTIMISER_VERSION', "4.22.9");
37
  define('SHORTPIXEL_MAX_TIMEOUT', 10);
38
  define('SHORTPIXEL_VALIDATE_MAX_TIMEOUT', 15);
39
  define('SHORTPIXEL_BACKUP', 'ShortpixelBackups');