ShortPixel Image Optimizer - Version 4.8.4

Version Description

  • fix compatibility problem with WP 4.9 when editing source files with the new built-in editor
  • fix restore converted PNGs in some situations
  • fix some minor warnings
  • refactor png2jpg functions in another class
  • add compatibility with PHP 5.2
  • generate WebP urls - account for settings with different scheme (http - https)
Download this release

Release Info

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

Code changes from version 4.8.2 to 4.8.4

class/db/wp-shortpixel-media-library-adapter.php CHANGED
@@ -13,11 +13,22 @@ class WpShortPixelMediaLbraryAdapter {
13
  $pointer = 0;
14
  $filesWithErrors = array();
15
  $excludePatterns = WPShortPixelSettings::getOpt("excludePatterns");
16
-
17
- $month1 = new DateTime(); $month2 = new DateTime(); $month3 = new DateTime(); $month4 = new DateTime();
18
- $mi1 = new DateInterval('P1M'); $mi2 = new DateInterval('P2M'); $mi3 = new DateInterval('P3M'); $mi4 = new DateInterval('P4M');
19
- $month1->sub($mi1); $month2->sub($mi2); $month3->sub($mi3); $month4->sub($mi4);
20
-
 
 
 
 
 
 
 
 
 
 
 
21
  $counter = 0; $foundUnlistedThumbs = false;
22
 
23
  //count all the files, main and thumbs
@@ -173,17 +184,18 @@ class WpShortPixelMediaLbraryAdapter {
173
 
174
  }
175
 
176
- $dt = new DateTime($idInfo->idDates[$file->post_id]);
177
- if($dt > $month1) {
178
- $totalFilesM1 += $totalFilesThis;
179
- } else if($dt > $month2) {
180
- $totalFilesM2 += $totalFilesThis;
181
- } else if($dt > $month3) {
182
- $totalFilesM3 += $totalFilesThis;
183
- } else if($dt > $month4) {
184
- $totalFilesM4 += $totalFilesThis;
 
 
185
  }
186
-
187
  }
188
  unset($filesList);
189
  $pointer += $limit;
@@ -247,9 +259,11 @@ class WpShortPixelMediaLbraryAdapter {
247
  $pattern = '/' . preg_quote($base, '/') . '-\d+x\d+\.'. $ext .'/';
248
  $thumbsCandidates = @glob($base . "-*." . $ext);
249
  $thumbs = array();
250
- foreach($thumbsCandidates as $th) {
251
- if(preg_match($pattern, $th)) {
252
- $thumbs[]= $th;
 
 
253
  }
254
  }
255
  return $thumbs;
13
  $pointer = 0;
14
  $filesWithErrors = array();
15
  $excludePatterns = WPShortPixelSettings::getOpt("excludePatterns");
16
+
17
+ if (version_compare(PHP_VERSION, '5.3.0') >= 0) {
18
+ $month1 = new DateTime();
19
+ $month2 = new DateTime();
20
+ $month3 = new DateTime();
21
+ $month4 = new DateTime();
22
+ $mi1 = new DateInterval('P1M');
23
+ $mi2 = new DateInterval('P2M');
24
+ $mi3 = new DateInterval('P3M');
25
+ $mi4 = new DateInterval('P4M');
26
+ $month1->sub($mi1);
27
+ $month2->sub($mi2);
28
+ $month3->sub($mi3);
29
+ $month4->sub($mi4);
30
+ }
31
+
32
  $counter = 0; $foundUnlistedThumbs = false;
33
 
34
  //count all the files, main and thumbs
184
 
185
  }
186
 
187
+ if (version_compare(PHP_VERSION, '5.3.0') >= 0) {
188
+ $dt = new DateTime($idInfo->idDates[$file->post_id]);
189
+ if ($dt > $month1) {
190
+ $totalFilesM1 += $totalFilesThis;
191
+ } else if ($dt > $month2) {
192
+ $totalFilesM2 += $totalFilesThis;
193
+ } else if ($dt > $month3) {
194
+ $totalFilesM3 += $totalFilesThis;
195
+ } else if ($dt > $month4) {
196
+ $totalFilesM4 += $totalFilesThis;
197
+ }
198
  }
 
199
  }
200
  unset($filesList);
201
  $pointer += $limit;
259
  $pattern = '/' . preg_quote($base, '/') . '-\d+x\d+\.'. $ext .'/';
260
  $thumbsCandidates = @glob($base . "-*." . $ext);
261
  $thumbs = array();
262
+ if(is_array($thumbsCandidates)) {
263
+ foreach($thumbsCandidates as $th) {
264
+ if(preg_match($pattern, $th)) {
265
+ $thumbs[]= $th;
266
+ }
267
  }
268
  }
269
  return $thumbs;
class/front/img-to-picture-webp.php CHANGED
@@ -29,6 +29,12 @@ class ShortPixelImgToPictureWebp {
29
  $imageBase = dirname(get_attached_file($id)) . '/';
30
  */
31
  $updir = wp_upload_dir();
 
 
 
 
 
 
32
  $imageBase = str_replace($updir['baseurl'], $updir['basedir'], $src);
33
  if($imageBase == $src) {
34
  return $match[0];
@@ -67,6 +73,9 @@ class ShortPixelImgToPictureWebp {
67
  }
68
  }
69
  if(!strlen($srcsetWebP)) { return $match[0]; }
 
 
 
70
 
71
  return '<picture>'
72
  .'<source srcset="' . $srcsetWebP . '"' . ($sizes ? ' sizes="' . $sizes . '"' : '') . ' type="image/webp">'
29
  $imageBase = dirname(get_attached_file($id)) . '/';
30
  */
31
  $updir = wp_upload_dir();
32
+ $proto = explode("://", $src);
33
+ $proto = $proto[0];
34
+ if(strpos($updir['baseurl'], $proto."://") === false) {
35
+ $base = explode("://", $updir['baseurl']);
36
+ $updir['baseurl'] = $proto . "://" . $base[1];
37
+ }
38
  $imageBase = str_replace($updir['baseurl'], $updir['basedir'], $src);
39
  if($imageBase == $src) {
40
  return $match[0];
73
  }
74
  }
75
  if(!strlen($srcsetWebP)) { return $match[0]; }
76
+
77
+ //add the exclude class so if this content is processed again in other filter, the img is not converted again in picture
78
+ $img['class'] = (isset($img['class']) ? $img['class'] . " " : "") . "sp-no-webp";
79
 
80
  return '<picture>'
81
  .'<source srcset="' . $srcsetWebP . '"' . ($sizes ? ' sizes="' . $sizes . '"' : '') . ' type="image/webp">'
class/shortpixel-png2jpg.php ADDED
@@ -0,0 +1,297 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * User: simon
4
+ * Date: 17.11.2017
5
+ * Time: 13:44
6
+ */
7
+
8
+ class ShortPixelPng2Jpg {
9
+ private $_settings = null;
10
+
11
+ public function __construct($settings){
12
+ $this->_settings = $settings;
13
+ }
14
+
15
+ protected function canConvertPng2Jpg($image) {
16
+ $transparent = 0;
17
+ if (ord(file_get_contents($image, false, null, 25, 1)) & 4) {
18
+ $transparent = 1;
19
+ }
20
+ $contents = file_get_contents($image);
21
+ if (stripos($contents, 'PLTE') !== false && stripos($contents, 'tRNS') !== false) {
22
+ $transparent = 1;
23
+ }
24
+ $transparent_pixel = $img = $bg = false;
25
+ if (!$transparent) {
26
+ $img = imagecreatefrompng($image);
27
+ $w = imagesx($img); // Get the width of the image
28
+ $h = imagesy($img); // Get the height of the image
29
+ //run through pixels until transparent pixel is found:
30
+ for ($i = 0; $i < $w; $i++) {
31
+ for ($j = 0; $j < $h; $j++) {
32
+ $rgba = imagecolorat($img, $i, $j);
33
+ if (($rgba & 0x7F000000) >> 24) {
34
+ $transparent_pixel = true;
35
+ break;
36
+ }
37
+ }
38
+ }
39
+ }
40
+
41
+ //pass on the img too, if it was already loaded from PNG, matter of performance
42
+ return array('notTransparent' => !$transparent && !$transparent_pixel, 'img' => $img);
43
+ }
44
+
45
+ /**
46
+ *
47
+ * @param array $params
48
+ * @param string $backupPath
49
+ * @param string $suffixRegex for example [0-9]+x[0-9]+ - a thumbnail suffix - to add the counter of file name collisions files before that suffix (img-2-150x150.jpg).
50
+ * @param image $img
51
+ * @return string
52
+ */
53
+
54
+ protected function doConvertPng2Jpg($params, $backup, $suffixRegex = false, $img = false) {
55
+ $image = $params['file'];
56
+ if(!$img) {
57
+ $img = imagecreatefrompng($image);
58
+ }
59
+
60
+ $bg = imagecreatetruecolor(imagesx($img), imagesy($img));
61
+ if(!$bg) return $params;
62
+ imagefill($bg, 0, 0, imagecolorallocate($bg, 255, 255, 255));
63
+ imagealphablending($bg, 1);
64
+ imagecopy($bg, $img, 0, 0, 0, 0, imagesx($img), imagesy($img));
65
+ $newPath = preg_replace("/\.png$/i", ".jpg", $image);
66
+ $newUrl = preg_replace("/\.png$/i", ".jpg", $params['url']);
67
+ for ($i = 1; file_exists($newPath); $i++) {
68
+ if($suffixRegex) {
69
+ $newPath = preg_replace("/(" . $suffixRegex . ")\.png$/i", $i . '-$1.jpg', $image);
70
+ }else {
71
+ $newPath = preg_replace("/\.png$/i", "-" . $i . ".jpg", $image);
72
+ }
73
+ }
74
+ if (imagejpeg($bg, $newPath, 90)) {
75
+ $newSize = filesize($newPath);
76
+ $origSize = filesize($image);
77
+ if($newSize > $origSize * 0.95) {
78
+ //if the image is not 5% smaller, don't bother.
79
+ unlink($newPath);
80
+ return $params;
81
+ }
82
+ //backup?
83
+ if($backup) {
84
+ $imageForBk = trailingslashit(dirname($image)) . ShortPixelAPI::MB_basename($newPath, '.jpg') . '.png';
85
+ @rename($image, $imageForBk);
86
+ if(!file_exists($imageForBk)) {
87
+ unlink($newPath);
88
+ return $params;
89
+ }
90
+ $image = $imageForBk;
91
+ $ret = ShortPixelAPI::backupImage($image, array($image));
92
+ if($ret['Status'] !== ShortPixelAPI::STATUS_SUCCESS) {
93
+ unlink($newPath);
94
+ return $params;
95
+ }
96
+ }
97
+ unlink($image);
98
+ $params['file'] = $newPath;
99
+ $params['original_file'] = $image;
100
+ $params['url'] = $newUrl;
101
+ $params['type'] = 'image/jpeg';
102
+ $params['png_size'] = $origSize;
103
+ $params['jpg_size'] = $newSize;
104
+ }
105
+ return $params;
106
+ }
107
+
108
+ /**
109
+ * Convert an uploaded image from PNG to JPG
110
+ * @param type $params
111
+ * @return string
112
+ */
113
+ public function convertPng2Jpg($params) {
114
+
115
+ //echo("PARAMS : ");var_dump($params);
116
+ if(!$this->_settings->png2jpg || strtolower(substr($params['file'], -4)) !== '.png') {
117
+ return $params;
118
+ }
119
+
120
+ $image = $params['file'];
121
+ WPShortPixel::log("Convert Media PNG to JPG on upload: {$image}");
122
+
123
+ $ret = $this->canConvertPng2Jpg($image);
124
+ if ($ret['notTransparent']) {
125
+ $paramsC = $this->doConvertPng2Jpg($params, $this->_settings->backupImages, false, $ret['img']);
126
+ if($paramsC['type'] == 'image/jpeg') {
127
+ // we don't have metadata, so save the information in a temporary map
128
+ $conv = $this->_settings->convertedPng2Jpg;
129
+ //do a cleanup first
130
+ foreach($conv as $key => $val) {
131
+ if(time() - $val['timestamp'] > 3600) unset($conv[$key]);
132
+ }
133
+ $conv[$paramsC['file']] = array('pngFile' => $paramsC['original_file'], 'backup' => $this->_settings->backupImages,
134
+ 'optimizationPercent' => round(100.0 * (1.00 - $paramsC['jpg_size'] / $paramsC['png_size'])),
135
+ 'timestamp' => time());
136
+ $this->_settings->convertedPng2Jpg = $conv;
137
+ }
138
+ return $paramsC;
139
+ }
140
+ return $params;
141
+ }
142
+
143
+ /**
144
+ * convert PNG to JPEG if possible - already existing image in Media Library
145
+ *
146
+ * @param type $meta
147
+ * @param type $ID
148
+ * @return string
149
+ */
150
+ public function checkConvertMediaPng2Jpg($meta, $ID) {
151
+
152
+ if(!$this->_settings->png2jpg || strtolower(substr($meta['file'], -4)) !== '.png') {
153
+ return $meta;
154
+ }
155
+
156
+ WPShortPixel::log("Send to processing: Convert Media PNG to JPG #{$ID}");
157
+
158
+ $image = $meta['file'];
159
+ $imagePath = get_attached_file($ID);
160
+ $basePath = trailingslashit(str_replace($image, "", $imagePath));
161
+ $imageUrl = wp_get_attachment_url($ID);
162
+ $baseUrl = trailingslashit(str_replace($image, "", $imageUrl));
163
+
164
+ $ret = $this->canConvertPng2Jpg($imagePath);
165
+ if (!$ret['notTransparent']) {
166
+ return $meta; //cannot convert it
167
+ }
168
+
169
+ $ret = $this->doConvertPng2Jpg(array('file' => $imagePath, 'url' => false, 'type' => 'image/png'), $this->_settings->backupImages, false, $ret['img']);
170
+ //echo("CONVERT: " . $imagePath); var_dump($ret);
171
+
172
+ if ($ret['type'] == 'image/jpeg') {
173
+ //convert to the new URLs the urls in the existing posts.
174
+ $baseRelPath = trailingslashit(dirname($image));
175
+ $this->png2JpgUpdateUrls(array(), $imageUrl, $baseUrl . $baseRelPath . wp_basename($ret['file']));
176
+ $pngSize = $ret['png_size'];
177
+ $jpgSize = $ret['jpg_size'];
178
+ $imagePath = isset($ret['original_file']) ? $ret['original_file'] : $imagePath;
179
+
180
+ //conversion succeeded for the main image, update meta and proceed to thumbs. (It could also not succeed if the converted file is not smaller)
181
+ $meta['file'] = str_replace($basePath, '', $ret['file']);
182
+ $meta['type'] = 'image/jpeg';
183
+
184
+ $originalSizes = isset($meta['sizes']) ? $meta['sizes'] : array();
185
+ foreach($meta['sizes'] as $size => $info) {
186
+ $rett = $this->doConvertPng2Jpg(array('file' => $basePath . $baseRelPath . $info['file'], 'url' => false, 'type' => 'image/png'),
187
+ $this->_settings->backupImages, "[0-9]+x[0-9]+");
188
+ if ($rett['type'] == 'image/jpeg') {
189
+ $meta['sizes'][$size]['file'] = wp_basename($rett['file']);
190
+ $meta['sizes'][$size]['mime-type'] = 'image/jpeg';
191
+ $pngSize += $ret['png_size'];
192
+ $jpgSize += $ret['jpg_size'];
193
+ $originalSizes[$size]['file'] = wp_basename($rett['file'], '.jpg') . '.png';
194
+ $this->png2JpgUpdateUrls(array(), $baseUrl . $baseRelPath . $info['file'], $baseUrl . $baseRelPath . wp_basename($rett['file']));
195
+ }
196
+ }
197
+ $meta['ShortPixelPng2Jpg'] = array('originalFile' => $imagePath, 'originalSizes' => $originalSizes,
198
+ 'backup' => $this->_settings->backupImages,
199
+ 'optimizationPercent' => round(100.0 * (1.00 - $jpgSize / $pngSize)));
200
+ update_attached_file($ID, $meta['file']);
201
+ wp_update_attachment_metadata($ID, $meta);
202
+ }
203
+
204
+ return $meta;
205
+ }
206
+
207
+ /**
208
+ * taken from Velvet Blues Update URLs plugin
209
+ * @param $options
210
+ * @param $oldurl
211
+ * @param $newurl
212
+ * @return array
213
+ */
214
+ protected function png2JpgUpdateUrls($options,$oldurl,$newurl){
215
+ global $wpdb;
216
+ $results = array();
217
+ $queries = array(
218
+ 'content' => array("UPDATE $wpdb->posts SET post_content = replace(post_content, %s, %s)", __('Content Items (Posts, Pages, Custom Post Types, Revisions)','hortpixel-image-optimiser') ),
219
+ 'excerpts' => array("UPDATE $wpdb->posts SET post_excerpt = replace(post_excerpt, %s, %s)", __('Excerpts','hortpixel-image-optimiser') ),
220
+ 'attachments' => array("UPDATE $wpdb->posts SET guid = replace(guid, %s, %s) WHERE post_type = 'attachment'", __('Attachments','hortpixel-image-optimiser') ),
221
+ 'links' => array("UPDATE $wpdb->links SET link_url = replace(link_url, %s, %s)", __('Links','hortpixel-image-optimiser') ),
222
+ 'custom' => array("UPDATE $wpdb->postmeta SET meta_value = replace(meta_value, %s, %s)", __('Custom Fields','hortpixel-image-optimiser') ),
223
+ 'guids' => array("UPDATE $wpdb->posts SET guid = replace(guid, %s, %s)", __('GUIDs','hortpixel-image-optimiser') )
224
+ );
225
+ if(count($options) == 0) {
226
+ $options = array_keys($queries);
227
+ }
228
+ foreach($options as $option){
229
+ if( $option == 'custom' ){
230
+ $n = 0;
231
+ $row_count = $wpdb->get_var( "SELECT COUNT(*) FROM $wpdb->postmeta" );
232
+ $page_size = 10000;
233
+ $pages = ceil( $row_count / $page_size );
234
+
235
+ for( $page = 0; $page < $pages; $page++ ) {
236
+ $current_row = 0;
237
+ $start = $page * $page_size;
238
+ $end = $start + $page_size;
239
+ $pmquery = "SELECT * FROM $wpdb->postmeta WHERE meta_value <> ''";
240
+ $items = $wpdb->get_results( $pmquery );
241
+ foreach( $items as $item ){
242
+ $value = $item->meta_value;
243
+ if( trim($value) == '' )
244
+ continue;
245
+
246
+ $edited = $this->png2JpgUnserializeReplace( $oldurl, $newurl, $value );
247
+
248
+ if( $edited != $value ){
249
+ $fix = $wpdb->query("UPDATE $wpdb->postmeta SET meta_value = '".$edited."' WHERE meta_id = ".$item->meta_id );
250
+ if( $fix )
251
+ $n++;
252
+ }
253
+ }
254
+ }
255
+ $results[$option] = array($n, $queries[$option][1]);
256
+ }
257
+ else{
258
+ $result = $wpdb->query( $wpdb->prepare( $queries[$option][0], $oldurl, $newurl) );
259
+ $results[$option] = array($result, $queries[$option][1]);
260
+ }
261
+ }
262
+ return $results;
263
+ }
264
+
265
+ /**
266
+ * taken from Velvet Blues Update URLs plugin
267
+ * @param string $from
268
+ * @param string $to
269
+ * @param string $data
270
+ * @param bool|false $serialised
271
+ * @return array|mixed|string
272
+ */
273
+ function png2JpgUnserializeReplace( $from = '', $to = '', $data = '', $serialised = false ) {
274
+ try {
275
+ if ( false !== is_serialized( $data ) ) {
276
+ $unserialized = unserialize( $data );
277
+ $data = $this->png2JpgUnserializeReplace( $from, $to, $unserialized, true );
278
+ }
279
+ elseif ( is_array( $data ) ) {
280
+ $_tmp = array( );
281
+ foreach ( $data as $key => $value ) {
282
+ $_tmp[ $key ] = $this->png2JpgUnserializeReplace( $from, $to, $value, false );
283
+ }
284
+ $data = $_tmp;
285
+ unset( $_tmp );
286
+ }
287
+ else {
288
+ if ( is_string( $data ) )
289
+ $data = str_replace( $from, $to, $data );
290
+ }
291
+ if ( $serialised )
292
+ return serialize( $data );
293
+ } catch( Exception $error ) {
294
+ }
295
+ return $data;
296
+ }
297
+ }
class/shortpixel_queue.php CHANGED
@@ -61,6 +61,11 @@ class ShortPixelQueue {
61
  $this->settings->prioritySkip = array($id);
62
  }
63
  }
 
 
 
 
 
64
 
65
  public function allSkipped() {
66
  if( !is_array($this->settings->prioritySkip) ) return false;
61
  $this->settings->prioritySkip = array($id);
62
  }
63
  }
64
+
65
+ public function unskip($id) {
66
+ $prioSkip = $this->settings->prioritySkip;
67
+ $this->settings->prioritySkip = is_array($prioSkip) ? array_diff($prioSkip, array($id)) : array();
68
+ }
69
 
70
  public function allSkipped() {
71
  if( !is_array($this->settings->prioritySkip) ) return false;
class/view/shortpixel_view.php CHANGED
@@ -1355,12 +1355,12 @@ class ShortPixelView {
1355
  }
1356
 
1357
  public function renderListCell($id, $status, $showActions, $optimizeThumbs, $thumbsRemain, $backup, $type, $invType, $message, $extraClass = '') {
1358
- if($showActions) { ?>
1359
  <div class='sp-column-actions <?php echo($extraClass);?>'>
1360
  <div class="sp-dropdown">
1361
  <button onclick="ShortPixel.openImageMenu(event);" class="sp-dropbtn button <?php if($optimizeThumbs) { echo('button-primary'); } ?> dashicons dashicons-menu" title="ShortPixel Actions"></button>
1362
  <div id="sp-dd-<?php echo($id);?>" class="sp-dropdown-content">
1363
- <?php if($status == 'imgOptimized') { ?>
1364
  <a class="sp-action-compare" href="javascript:ShortPixel.loadComparer('<?php echo($id);?>')" title="Compare optimized image with the original">Compare</a>
1365
  <?php } ?>
1366
  <?php if($optimizeThumbs) { ?>
1355
  }
1356
 
1357
  public function renderListCell($id, $status, $showActions, $optimizeThumbs, $thumbsRemain, $backup, $type, $invType, $message, $extraClass = '') {
1358
+ if($showActions && ($backup || $optimizeThumbs)) { ?>
1359
  <div class='sp-column-actions <?php echo($extraClass);?>'>
1360
  <div class="sp-dropdown">
1361
  <button onclick="ShortPixel.openImageMenu(event);" class="sp-dropbtn button <?php if($optimizeThumbs) { echo('button-primary'); } ?> dashicons dashicons-menu" title="ShortPixel Actions"></button>
1362
  <div id="sp-dd-<?php echo($id);?>" class="sp-dropdown-content">
1363
+ <?php if($backup && $status == 'imgOptimized') { ?>
1364
  <a class="sp-action-compare" href="javascript:ShortPixel.loadComparer('<?php echo($id);?>')" title="Compare optimized image with the original">Compare</a>
1365
  <?php } ?>
1366
  <?php if($optimizeThumbs) { ?>
class/wp-short-pixel.php CHANGED
@@ -229,7 +229,7 @@ class WPShortPixel {
229
  $this->getQuotaInformation();
230
  }
231
  if($this->_settings->verifiedKey
232
- && (!isset($dismissed['upgmonth']) || !isset($dismissed['upgbulk']))
233
  && $this->_settings->currentStats['optimizePdfs'] == $this->_settings->optimizePdfs ) {
234
  $screen = get_current_screen();
235
  $stats = $this->countAllIfNeeded($this->_settings->currentStats, 300);
@@ -273,9 +273,8 @@ class WPShortPixel {
273
  return ($stats['totalM1'] + $stats['totalM2'] + $stats['totalM3'] + $stats['totalM4']) / max(1,$count);
274
  }
275
 
276
- protected function monthlyUpgradeNeeded($stats) {
277
- $quotaData = $stats;
278
- return $this->getMonthAvg($stats) > $quotaData['APICallsQuotaNumeric'] + ($quotaData['APICallsQuotaOneTimeNumeric'] - $quotaData['APICallsMadeOneTimeNumeric'])/6 + 20;
279
  }
280
 
281
  protected function bulkUpgradeNeeded($stats) {
@@ -537,286 +536,26 @@ class WPShortPixel {
537
  }
538
  }//end handleMediaLibraryImageUpload
539
 
540
- protected function canConvertPng2Jpg($image) {
541
- $transparent = 0;
542
- if (ord(file_get_contents($image, false, null, 25, 1)) & 4) {
543
- $transparent = 1;
544
- }
545
- $contents = file_get_contents($image);
546
- if (stripos($contents, 'PLTE') !== false && stripos($contents, 'tRNS') !== false) {
547
- $transparent = 1;
548
- }
549
- $transparent_pixel = $img = $bg = false;
550
- if (!$transparent) {
551
- $img = imagecreatefrompng($image);
552
- $w = imagesx($img); // Get the width of the image
553
- $h = imagesy($img); // Get the height of the image
554
- //run through pixels until transparent pixel is found:
555
- for ($i = 0; $i < $w; $i++) {
556
- for ($j = 0; $j < $h; $j++) {
557
- $rgba = imagecolorat($img, $i, $j);
558
- if (($rgba & 0x7F000000) >> 24) {
559
- $transparent_pixel = true;
560
- break;
561
- }
562
- }
563
- }
564
- }
565
-
566
- //pass on the img too, if it was already loaded from PNG, matter of performance
567
- return array('notTransparent' => !$transparent && !$transparent_pixel, 'img' => $img);
568
- }
569
-
570
- /**
571
- *
572
- * @param array $params
573
- * @param string $backupPath
574
- * @param string $suffixRegex for example [0-9]+x[0-9]+ - a thumbnail suffix - to add the counter of file name collisions files before that suffix (img-2-150x150.jpg).
575
- * @param image $img
576
- * @return string
577
- */
578
- protected function doConvertPng2Jpg($params, $backup, $suffixRegex = false, $img = false) {
579
- $image = $params['file'];
580
- if(!$img) {
581
- $img = imagecreatefrompng($image);
582
- }
583
-
584
- $bg = imagecreatetruecolor(imagesx($img), imagesy($img));
585
- if(!$bg) return $params;
586
- imagefill($bg, 0, 0, imagecolorallocate($bg, 255, 255, 255));
587
- imagealphablending($bg, 1);
588
- imagecopy($bg, $img, 0, 0, 0, 0, imagesx($img), imagesy($img));
589
- $newPath = preg_replace("/\.png$/i", ".jpg", $image);
590
- $newUrl = preg_replace("/\.png$/i", ".jpg", $params['url']);
591
- for ($i = 1; file_exists($newPath); $i++) {
592
- if($suffixRegex) {
593
- $newPath = preg_replace("/(" . $suffixRegex . ")\.png$/i", $i . '-$1.jpg', $image);
594
- }else {
595
- $newPath = preg_replace("/\.png$/i", "-" . $i . ".jpg", $image);
596
- }
597
- }
598
- if (imagejpeg($bg, $newPath, 90)) {
599
- $newSize = filesize($newPath);
600
- $origSize = filesize($image);
601
- if($newSize > $origSize * 0.95) {
602
- //if the image is not 5% smaller, don't bother.
603
- unlink($newPath);
604
- return $params;
605
- }
606
- //backup?
607
- if($backup) {
608
- $imageForBk = trailingslashit(dirname($image)) . ShortPixelAPI::MB_basename($newPath, '.jpg') . '.png';
609
- @rename($image, $imageForBk);
610
- if(!file_exists($imageForBk)) {
611
- unlink($newPath);
612
- return $params;
613
- }
614
- $image = $imageForBk;
615
- $ret = ShortPixelAPI::backupImage($image, array($image));
616
- if($ret['Status'] !== ShortPixelAPI::STATUS_SUCCESS) {
617
- unlink($newPath);
618
- return $params;
619
- }
620
- }
621
- unlink($image);
622
- $params['file'] = $newPath;
623
- $params['original_file'] = $image;
624
- $params['url'] = $newUrl;
625
- $params['type'] = 'image/jpeg';
626
- $params['png_size'] = $origSize;
627
- $params['jpg_size'] = $newSize;
628
- }
629
- return $params;
630
- }
631
-
632
  /**
633
  * Convert an uploaded image from PNG to JPG
634
  * @param type $params
635
  * @return string
636
  */
637
  public function convertPng2Jpg($params) {
638
-
639
- //echo("PARAMS : ");var_dump($params);
640
- if(!$this->_settings->png2jpg || strtolower(substr($params['file'], -4)) !== '.png') {
641
- return $params;
642
- }
643
-
644
- $image = $params['file'];
645
- self::log("Convert Media PNG to JPG on upload: {$image}");
646
-
647
- $ret = $this->canConvertPng2Jpg($image);
648
- if ($ret['notTransparent']) {
649
- $paramsC = $this->doConvertPng2Jpg($params, $this->_settings->backupImages, false, $ret['img']);
650
- if($paramsC['type'] == 'image/jpeg') {
651
- // we don't have metadata, so save the information in a temporary map
652
- $conv = $this->_settings->convertedPng2Jpg;
653
- //do a cleanup first
654
- foreach($conv as $key => $val) {
655
- if(time() - $val['timestamp'] > 3600) unset($conv[$key]);
656
- }
657
- $conv[$paramsC['file']] = array('pngFile' => $paramsC['original_file'], 'backup' => $this->_settings->backupImages,
658
- 'optimizationPercent' => round(100.0 * (1.00 - $paramsC['jpg_size'] / $paramsC['png_size'])),
659
- 'timestamp' => time());
660
- $this->_settings->convertedPng2Jpg = $conv;
661
- }
662
- return $paramsC;
663
- }
664
- return $params;
665
  }
666
-
667
  /**
668
  * convert PNG to JPEG if possible - already existing image in Media Library
669
- *
670
  * @param type $meta
671
  * @param type $ID
672
  * @return string
673
  */
674
  public function checkConvertMediaPng2Jpg($meta, $ID) {
675
-
676
- if(!$this->_settings->png2jpg || strtolower(substr($meta['file'], -4)) !== '.png') {
677
- return $meta;
678
- }
679
-
680
- self::log("Send to processing: Convert Media PNG to JPG #{$ID}");
681
-
682
- $image = $meta['file'];
683
- $imagePath = get_attached_file($ID);
684
- $basePath = trailingslashit(str_replace($image, "", $imagePath));
685
- $imageUrl = wp_get_attachment_url($ID);
686
- $baseUrl = trailingslashit(str_replace($image, "", $imageUrl));
687
-
688
- $ret = $this->canConvertPng2Jpg($imagePath);
689
- if (!$ret['notTransparent']) {
690
- return $meta; //cannot convert it
691
- }
692
-
693
- $ret = $this->doConvertPng2Jpg(array('file' => $imagePath, 'url' => false, 'type' => 'image/png'), $this->_settings->backupImages, false, $ret['img']);
694
- //echo("CONVERT: " . $imagePath); var_dump($ret);
695
-
696
- if ($ret['type'] == 'image/jpeg') {
697
- //convert to the new URLs the urls in the existing posts.
698
- $baseRelPath = trailingslashit(dirname($image));
699
- $this->png2JpgUpdateUrls(array(), $imageUrl, $baseUrl . $baseRelPath . wp_basename($ret['file']));
700
- $pngSize = $ret['png_size'];
701
- $jpgSize = $ret['jpg_size'];
702
- $imagePath = isset($ret['original_file']) ? $ret['original_file'] : $imagePath;
703
-
704
- //conversion succeeded for the main image, update meta and proceed to thumbs. (It could also not succeed if the converted file is not smaller)
705
- $meta['file'] = str_replace($basePath, '', $ret['file']);
706
- $meta['type'] = 'image/jpeg';
707
-
708
- $originalSizes = isset($meta['sizes']) ? $meta['sizes'] : array();
709
- foreach($meta['sizes'] as $size => $info) {
710
- $rett = $this->doConvertPng2Jpg(array('file' => $basePath . $baseRelPath . $info['file'], 'url' => false, 'type' => 'image/png'),
711
- $this->_settings->backupImages, "[0-9]+x[0-9]+");
712
- if ($rett['type'] == 'image/jpeg') {
713
- $meta['sizes'][$size]['file'] = wp_basename($rett['file']);
714
- $meta['sizes'][$size]['mime-type'] = 'image/jpeg';
715
- $pngSize += $ret['png_size'];
716
- $jpgSize += $ret['jpg_size'];
717
- $originalSizes[$size]['file'] = wp_basename($rett['file'], '.jpg') . '.png';
718
- $this->png2JpgUpdateUrls(array(), $baseUrl . $baseRelPath . $info['file'], $baseUrl . $baseRelPath . wp_basename($rett['file']));
719
- }
720
- }
721
- $meta['ShortPixelPng2Jpg'] = array('originalFile' => $imagePath, 'originalSizes' => $originalSizes,
722
- 'backup' => $this->_settings->backupImages,
723
- 'optimizationPercent' => round(100.0 * (1.00 - $jpgSize / $pngSize)));
724
- update_attached_file($ID, $meta['file']);
725
- wp_update_attachment_metadata($ID, $meta);
726
- }
727
-
728
- return $meta;
729
- }
730
-
731
- /**
732
- * taken from Velvet Blues Update URLs plugin
733
- * @param $options
734
- * @param $oldurl
735
- * @param $newurl
736
- * @return array
737
- */
738
- protected function png2JpgUpdateUrls($options,$oldurl,$newurl){
739
- global $wpdb;
740
- $results = array();
741
- $queries = array(
742
- 'content' => array("UPDATE $wpdb->posts SET post_content = replace(post_content, %s, %s)", __('Content Items (Posts, Pages, Custom Post Types, Revisions)','hortpixel-image-optimiser') ),
743
- 'excerpts' => array("UPDATE $wpdb->posts SET post_excerpt = replace(post_excerpt, %s, %s)", __('Excerpts','hortpixel-image-optimiser') ),
744
- 'attachments' => array("UPDATE $wpdb->posts SET guid = replace(guid, %s, %s) WHERE post_type = 'attachment'", __('Attachments','hortpixel-image-optimiser') ),
745
- 'links' => array("UPDATE $wpdb->links SET link_url = replace(link_url, %s, %s)", __('Links','hortpixel-image-optimiser') ),
746
- 'custom' => array("UPDATE $wpdb->postmeta SET meta_value = replace(meta_value, %s, %s)", __('Custom Fields','hortpixel-image-optimiser') ),
747
- 'guids' => array("UPDATE $wpdb->posts SET guid = replace(guid, %s, %s)", __('GUIDs','hortpixel-image-optimiser') )
748
- );
749
- if(count($options) == 0) {
750
- $options = array_keys($queries);
751
- }
752
- foreach($options as $option){
753
- if( $option == 'custom' ){
754
- $n = 0;
755
- $row_count = $wpdb->get_var( "SELECT COUNT(*) FROM $wpdb->postmeta" );
756
- $page_size = 10000;
757
- $pages = ceil( $row_count / $page_size );
758
-
759
- for( $page = 0; $page < $pages; $page++ ) {
760
- $current_row = 0;
761
- $start = $page * $page_size;
762
- $end = $start + $page_size;
763
- $pmquery = "SELECT * FROM $wpdb->postmeta WHERE meta_value <> ''";
764
- $items = $wpdb->get_results( $pmquery );
765
- foreach( $items as $item ){
766
- $value = $item->meta_value;
767
- if( trim($value) == '' )
768
- continue;
769
-
770
- $edited = $this->png2JpgUnserializeReplace( $oldurl, $newurl, $value );
771
-
772
- if( $edited != $value ){
773
- $fix = $wpdb->query("UPDATE $wpdb->postmeta SET meta_value = '".$edited."' WHERE meta_id = ".$item->meta_id );
774
- if( $fix )
775
- $n++;
776
- }
777
- }
778
- }
779
- $results[$option] = array($n, $queries[$option][1]);
780
- }
781
- else{
782
- $result = $wpdb->query( $wpdb->prepare( $queries[$option][0], $oldurl, $newurl) );
783
- $results[$option] = array($result, $queries[$option][1]);
784
- }
785
- }
786
- return $results;
787
- }
788
-
789
- /**
790
- * taken from Velvet Blues Update URLs plugin
791
- * @param string $from
792
- * @param string $to
793
- * @param string $data
794
- * @param bool|false $serialised
795
- * @return array|mixed|string
796
- */
797
- function png2JpgUnserializeReplace( $from = '', $to = '', $data = '', $serialised = false ) {
798
- try {
799
- if ( false !== is_serialized( $data ) ) {
800
- $unserialized = unserialize( $data );
801
- $data = $this->png2JpgUnserializeReplace( $from, $to, $unserialized, true );
802
- }
803
- elseif ( is_array( $data ) ) {
804
- $_tmp = array( );
805
- foreach ( $data as $key => $value ) {
806
- $_tmp[ $key ] = $this->png2JpgUnserializeReplace( $from, $to, $value, false );
807
- }
808
- $data = $_tmp;
809
- unset( $_tmp );
810
- }
811
- else {
812
- if ( is_string( $data ) )
813
- $data = str_replace( $from, $to, $data );
814
- }
815
- if ( $serialised )
816
- return serialize( $data );
817
- } catch( Exception $error ) {
818
- }
819
- return $data;
820
  }
821
 
822
  /**
@@ -1661,9 +1400,9 @@ class WPShortPixel {
1661
  $crtMeta['height'] = $height;
1662
  }
1663
  if($png2jpgMain) {
 
 
1664
  if($png2jpgSizes) {
1665
- $crtMeta['file'] = trailingslashit(dirname($crtMeta['file'])) . ShortPixelAPI::MB_basename($file);
1666
- update_attached_file($ID, $crtMeta['file']);
1667
  $crtMeta['sizes'] = $png2jpgSizes;
1668
  } else {
1669
  //this was an image converted on upload, regenerate the thumbs using the PNG main image BUT deactivate temporarily the filter!!
@@ -1881,7 +1620,7 @@ class WPShortPixel {
1881
  }
1882
  }
1883
 
1884
- public function checkQuotaAndAlert($quotaData = null, $recheck = false) {
1885
  if(!$quotaData) {
1886
  $quotaData = $this->getQuotaInformation();
1887
  }
@@ -1890,7 +1629,7 @@ class WPShortPixel {
1890
  return $quotaData;
1891
  }
1892
  //$tempus = microtime(true);
1893
- $quotaData = $this->countAllIfNeeded($quotaData, 300);
1894
  //echo("Count took (seconds): " . (microtime(true) - $tempus));
1895
 
1896
  if($quotaData['APICallsQuotaNumeric'] + $quotaData['APICallsQuotaOneTimeNumeric'] > $quotaData['APICallsMadeNumeric'] + $quotaData['APICallsMadeOneTimeNumeric']) {
@@ -1976,7 +1715,7 @@ class WPShortPixel {
1976
  return;
1977
  }
1978
 
1979
- $quotaData = $this->checkQuotaAndAlert(null, isset($_GET['checkquota']));
1980
  if($this->_settings->quotaExceeded != 0) {
1981
  return;
1982
  }
@@ -2751,6 +2490,7 @@ class WPShortPixel {
2751
  if( $this->_settings->quotaExceeded == 1) {
2752
  $dismissed = $this->_settings->dismissedNotices ? $this->_settings->dismissedNotices : array();
2753
  unset($dismissed['exceed']);
 
2754
  $this->_settings->dismissedNotices = $dismissed;
2755
  }
2756
  $this->_settings->quotaExceeded = 0;
@@ -2859,6 +2599,7 @@ class WPShortPixel {
2859
  $renderData['status'] = $quotaExceeded ? 'quotaExceeded' : 'retry';
2860
  $renderData['message'] = "<img src=\"" . plugins_url( 'res/img/loading.gif', SHORTPIXEL_PLUGIN_FILE ) . "\" class='sp-loading-small'>&nbsp;" . __("Image waiting to be processed.",'shortpixel-image-optimiser');
2861
  if($this->_settings->autoMediaLibrary && !$quotaExceeded && ($id > $this->prioQ->getFlagBulkId() || !$this->prioQ->bulkRunning())) {
 
2862
  $this->prioQ->push($id); //should be there but just to make sure
2863
  }
2864
  }
229
  $this->getQuotaInformation();
230
  }
231
  if($this->_settings->verifiedKey
232
+ && (!isset($dismissed['upgmonth']) || !isset($dismissed['upgbulk'])) && isset($this->_settings->currentStats['optimizePdfs'])
233
  && $this->_settings->currentStats['optimizePdfs'] == $this->_settings->optimizePdfs ) {
234
  $screen = get_current_screen();
235
  $stats = $this->countAllIfNeeded($this->_settings->currentStats, 300);
273
  return ($stats['totalM1'] + $stats['totalM2'] + $stats['totalM3'] + $stats['totalM4']) / max(1,$count);
274
  }
275
 
276
+ protected function monthlyUpgradeNeeded($quotaData) {
277
+ return isset($quotaData['APICallsQuotaNumeric']) && $this->getMonthAvg($quotaData) > $quotaData['APICallsQuotaNumeric'] + ($quotaData['APICallsQuotaOneTimeNumeric'] - $quotaData['APICallsMadeOneTimeNumeric'])/6 + 20;
 
278
  }
279
 
280
  protected function bulkUpgradeNeeded($stats) {
536
  }
537
  }//end handleMediaLibraryImageUpload
538
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
539
  /**
540
  * Convert an uploaded image from PNG to JPG
541
  * @param type $params
542
  * @return string
543
  */
544
  public function convertPng2Jpg($params) {
545
+ $converter = new ShortPixelPng2Jpg($this->_settings);
546
+ return $converter->convertPng2Jpg($params);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
547
  }
548
+
549
  /**
550
  * convert PNG to JPEG if possible - already existing image in Media Library
551
+ *
552
  * @param type $meta
553
  * @param type $ID
554
  * @return string
555
  */
556
  public function checkConvertMediaPng2Jpg($meta, $ID) {
557
+ $converter = new ShortPixelPng2Jpg($this->_settings);
558
+ return $converter->checkConvertMediaPng2Jpg($meta, $ID);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
559
  }
560
 
561
  /**
1400
  $crtMeta['height'] = $height;
1401
  }
1402
  if($png2jpgMain) {
1403
+ $crtMeta['file'] = trailingslashit(dirname($crtMeta['file'])) . ShortPixelAPI::MB_basename($file);
1404
+ update_attached_file($ID, $crtMeta['file']);
1405
  if($png2jpgSizes) {
 
 
1406
  $crtMeta['sizes'] = $png2jpgSizes;
1407
  } else {
1408
  //this was an image converted on upload, regenerate the thumbs using the PNG main image BUT deactivate temporarily the filter!!
1620
  }
1621
  }
1622
 
1623
+ public function checkQuotaAndAlert($quotaData = null, $recheck = false, $refreshFiles = 300) {
1624
  if(!$quotaData) {
1625
  $quotaData = $this->getQuotaInformation();
1626
  }
1629
  return $quotaData;
1630
  }
1631
  //$tempus = microtime(true);
1632
+ $quotaData = $this->countAllIfNeeded($quotaData, $refreshFiles);
1633
  //echo("Count took (seconds): " . (microtime(true) - $tempus));
1634
 
1635
  if($quotaData['APICallsQuotaNumeric'] + $quotaData['APICallsQuotaOneTimeNumeric'] > $quotaData['APICallsMadeNumeric'] + $quotaData['APICallsMadeOneTimeNumeric']) {
1715
  return;
1716
  }
1717
 
1718
+ $quotaData = $this->checkQuotaAndAlert(null, isset($_GET['checkquota']), 0);
1719
  if($this->_settings->quotaExceeded != 0) {
1720
  return;
1721
  }
2490
  if( $this->_settings->quotaExceeded == 1) {
2491
  $dismissed = $this->_settings->dismissedNotices ? $this->_settings->dismissedNotices : array();
2492
  unset($dismissed['exceed']);
2493
+ $this->_settings->prioritySkip = array();
2494
  $this->_settings->dismissedNotices = $dismissed;
2495
  }
2496
  $this->_settings->quotaExceeded = 0;
2599
  $renderData['status'] = $quotaExceeded ? 'quotaExceeded' : 'retry';
2600
  $renderData['message'] = "<img src=\"" . plugins_url( 'res/img/loading.gif', SHORTPIXEL_PLUGIN_FILE ) . "\" class='sp-loading-small'>&nbsp;" . __("Image waiting to be processed.",'shortpixel-image-optimiser');
2601
  if($this->_settings->autoMediaLibrary && !$quotaExceeded && ($id > $this->prioQ->getFlagBulkId() || !$this->prioQ->bulkRunning())) {
2602
+ $this->prioQ->unskip($id);
2603
  $this->prioQ->push($id); //should be there but just to make sure
2604
  }
2605
  }
readme.txt CHANGED
@@ -3,8 +3,8 @@ Contributors: ShortPixel
3
  Tags: compress, image, compression, optimize, image optimizer, image optimiser, image compression, resize, compress pdf, compress jpg, compress png, image compression
4
  Requires at least: 3.2.0
5
  Tested up to: 4.9
6
- Requires PHP: 5.3
7
- Stable tag: 4.8.2
8
  License: GPLv2 or later
9
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
10
 
@@ -12,7 +12,7 @@ Speed up your website and boost your SEO by compressing old & new images and PDF
12
 
13
  == Description ==
14
 
15
- **A freeemium easy to use, comprehensive, stable and frequently updated image compression plugin supported by the friendly team that created it. :)**
16
 
17
  Increase your website's SEO ranking, number of visitors and ultimately your sales by optimizing any image or PDF document on your website.
18
  ShortPixel is an easy to use, lightweight, install-and-forget-about-it <a rel="friend" href="https://shortpixel.com" target="_blank">image optimization</a> plugin that can compress all your past images and PDF documents with a single click. New images are automatically resized/rescaled and optimized on the fly, in the background.
@@ -228,6 +228,14 @@ The ShortPixel team is here to help. <a href="https://shortpixel.com/contact">Co
228
 
229
  == Changelog ==
230
 
 
 
 
 
 
 
 
 
231
  = 4.8.2 =
232
  * fix minified punycode.js not generated because of ECMA6 not supported by YUI...
233
 
3
  Tags: compress, image, compression, optimize, image optimizer, image optimiser, image compression, resize, compress pdf, compress jpg, compress png, image compression
4
  Requires at least: 3.2.0
5
  Tested up to: 4.9
6
+ Requires PHP: 5.2
7
+ Stable tag: 4.8.4
8
  License: GPLv2 or later
9
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
10
 
12
 
13
  == Description ==
14
 
15
+ **A freemium easy to use, comprehensive, stable and frequently updated image compression plugin supported by the friendly team that created it. :)**
16
 
17
  Increase your website's SEO ranking, number of visitors and ultimately your sales by optimizing any image or PDF document on your website.
18
  ShortPixel is an easy to use, lightweight, install-and-forget-about-it <a rel="friend" href="https://shortpixel.com" target="_blank">image optimization</a> plugin that can compress all your past images and PDF documents with a single click. New images are automatically resized/rescaled and optimized on the fly, in the background.
228
 
229
  == Changelog ==
230
 
231
+ = 4.8.4 =
232
+ * fix compatibility problem with WP 4.9 when editing source files with the new built-in editor
233
+ * fix restore converted PNGs in some situations
234
+ * fix some minor warnings
235
+ * refactor png2jpg functions in another class
236
+ * add compatibility with PHP 5.2
237
+ * generate WebP urls - account for settings with different scheme (http - https)
238
+
239
  = 4.8.2 =
240
  * fix minified punycode.js not generated because of ECMA6 not supported by YUI...
241
 
wp-shortpixel-req.php CHANGED
@@ -9,6 +9,7 @@ require_once('class/wp-short-pixel.php');
9
  require_once('class/wp-shortpixel-settings.php');
10
  require_once('shortpixel_api.php');
11
  require_once('class/shortpixel_queue.php');
 
12
  //entities
13
  require_once('class/model/shortpixel-entity.php');
14
  require_once('class/model/shortpixel-meta.php');
9
  require_once('class/wp-shortpixel-settings.php');
10
  require_once('shortpixel_api.php');
11
  require_once('class/shortpixel_queue.php');
12
+ require_once('class/shortpixel-png2jpg.php');
13
  //entities
14
  require_once('class/model/shortpixel-entity.php');
15
  require_once('class/model/shortpixel-meta.php');
wp-shortpixel.php CHANGED
@@ -3,7 +3,7 @@
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" target="_blank">Settings &gt; ShortPixel</a> page on how to start optimizing your image library and make your website load faster.
6
- * Version: 4.8.2
7
  * Author: ShortPixel
8
  * Author URI: https://shortpixel.com
9
  * Text Domain: shortpixel-image-optimiser
@@ -18,7 +18,7 @@ define('SHORTPIXEL_PLUGIN_FILE', __FILE__);
18
 
19
  define('SHORTPIXEL_AFFILIATE_CODE', '');
20
 
21
- define('SHORTPIXEL_IMAGE_OPTIMISER_VERSION', "4.8.2");
22
  define('SHORTPIXEL_MAX_TIMEOUT', 10);
23
  define('SHORTPIXEL_VALIDATE_MAX_TIMEOUT', 15);
24
  define('SHORTPIXEL_BACKUP', 'ShortpixelBackups');
@@ -54,11 +54,20 @@ define("SHORTPIXEL_MAX_RESULTS_QUERY", 6);
54
 
55
  function shortpixelInit() {
56
  global $pluginInstance;
 
 
 
 
 
 
 
 
57
  //is admin, is logged in - :) seems funny but it's not, ajax scripts are admin even if no admin is logged in.
58
  $prio = get_option('wp-short-pixel-priorityQueue');
 
59
  if (!isset($pluginInstance)
60
- && (($prio && is_array($prio) && count($prio) && get_option('wp-short-pixel-front-bootstrap'))
61
- || is_admin()
62
  && (function_exists("is_user_logged_in") && is_user_logged_in())
63
  && ( current_user_can( 'manage_options' )
64
  || current_user_can( 'upload_files' )
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" target="_blank">Settings &gt; ShortPixel</a> page on how to start optimizing your image library and make your website load faster.
6
+ * Version: 4.8.4
7
  * Author: ShortPixel
8
  * Author URI: https://shortpixel.com
9
  * Text Domain: shortpixel-image-optimiser
18
 
19
  define('SHORTPIXEL_AFFILIATE_CODE', '');
20
 
21
+ define('SHORTPIXEL_IMAGE_OPTIMISER_VERSION', "4.8.4");
22
  define('SHORTPIXEL_MAX_TIMEOUT', 10);
23
  define('SHORTPIXEL_VALIDATE_MAX_TIMEOUT', 15);
24
  define('SHORTPIXEL_BACKUP', 'ShortpixelBackups');
54
 
55
  function shortpixelInit() {
56
  global $pluginInstance;
57
+ //limit to certain admin pages if function available
58
+ $loadOnThisPage = !function_exists('get_current_screen');
59
+ if(!$loadOnThisPage) {
60
+ $screen = get_current_screen();
61
+ if(is_object($screen) && in_array($screen->id, array('upload', 'edit', 'edit-tags', 'post-new', 'post'))) {
62
+
63
+ }
64
+ }
65
  //is admin, is logged in - :) seems funny but it's not, ajax scripts are admin even if no admin is logged in.
66
  $prio = get_option('wp-short-pixel-priorityQueue');
67
+ $isAjaxButNotSP = defined( 'DOING_AJAX' ) && DOING_AJAX && !(isset($_REQUEST['action']) && (strpos($_REQUEST['action'], 'shortpixel_') === 0));
68
  if (!isset($pluginInstance)
69
+ && ( ($prio && is_array($prio) && count($prio) && get_option('wp-short-pixel-front-bootstrap'))
70
+ || is_admin() && !$isAjaxButNotSP
71
  && (function_exists("is_user_logged_in") && is_user_logged_in())
72
  && ( current_user_can( 'manage_options' )
73
  || current_user_can( 'upload_files' )