ShortPixel Image Optimizer - Version 4.9.0

Version Description

  • inline help beacon
  • fix exclude patterns not working after last update
  • handle situations when not enough memory to convert from PNG to JPG.
  • fix particular situations where there was no 'file' property in the metadata.
  • fix slider optimized percent over the bulk warning box.
  • display the x close link for the bulk warning box.
Download this release

Release Info

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

Code changes from version 4.8.9 to 4.9.0

class/db/shortpixel-meta-facade.php CHANGED
@@ -294,7 +294,7 @@ class ShortPixelMetaFacade {
294
  public static function safeGetAttachmentUrl($id) {
295
  $attURL = wp_get_attachment_url($id);
296
  if(!$attURL || !strlen($attURL)) {
297
- throw new Exception("Post metadata is corrupt (No attachment URL)");
298
  }
299
  if ( !parse_url($attURL, PHP_URL_SCHEME) ) {//no absolute URLs used -> we implement a hack
300
  return self::getHomeUrl() . $attURL;//get the file URL
@@ -344,7 +344,11 @@ class ShortPixelMetaFacade {
344
 
345
  $count = 0;
346
  foreach( $sizes as $thumbnailName => $thumbnailInfo ) {
347
-
 
 
 
 
348
  if(strpos($thumbnailName, ShortPixelMeta::WEBP_THUMB_PREFIX) === 0) {
349
  continue;
350
  }
294
  public static function safeGetAttachmentUrl($id) {
295
  $attURL = wp_get_attachment_url($id);
296
  if(!$attURL || !strlen($attURL)) {
297
+ throw new Exception("Post metadata is corrupt (No attachment URL)", ShortPixelAPI::ERR_POSTMETA_CORRUPT);
298
  }
299
  if ( !parse_url($attURL, PHP_URL_SCHEME) ) {//no absolute URLs used -> we implement a hack
300
  return self::getHomeUrl() . $attURL;//get the file URL
344
 
345
  $count = 0;
346
  foreach( $sizes as $thumbnailName => $thumbnailInfo ) {
347
+
348
+ if(!isset($thumbnailInfo['file'])) { //cases when $thumbnailInfo is NULL
349
+ continue;
350
+ }
351
+
352
  if(strpos($thumbnailName, ShortPixelMeta::WEBP_THUMB_PREFIX) === 0) {
353
  continue;
354
  }
class/db/wp-shortpixel-media-library-adapter.php CHANGED
@@ -3,10 +3,10 @@
3
  class WpShortPixelMediaLbraryAdapter {
4
 
5
  //count all the processable files in media library (while limiting the results to max 10000)
6
- public static function countAllProcessableFiles($includePdfs = true, $maxId = PHP_INT_MAX, $minId = 0){
7
  global $wpdb;
8
 
9
- $totalFiles = $mainFiles = $processedMainFiles = $processedTotalFiles = $totalFilesM1 = $totalFilesM2 = $totalFilesM3 = $totalFilesM4 =
10
  $procGlossyMainFiles = $procGlossyTotalFiles = $procLossyMainFiles = $procLossyTotalFiles = $procLosslessMainFiles = $procLosslessTotalFiles = $procUndefMainFiles = $procUndefTotalFiles = $mainUnprocessedThumbs = 0;
11
  $filesMap = $processedFilesMap = array();
12
  $limit = self::getOptimalChunkSize();
@@ -68,8 +68,10 @@ class WpShortPixelMediaLbraryAdapter {
68
  $sizesCount = isset($attachment['sizes']) ? WpShortPixelMediaLbraryAdapter::countNonWebpSizes($attachment['sizes']) : 0;
69
 
70
  // LA FIECARE 100 de imagini facem un test si daca findThumbs da diferit, sa dam o avertizare si eventual optiune
71
- if( $foundUnlistedThumbs === false && $maxId == PHP_INT_MAX && (in_array($counter, array(2,4,6,8)) || floor($counter/100) == 0 && $counter%10 == 0
72
- || floor($counter/1000) == 0 && $counter%100 == 0 || floor($counter/10000) == 0 && $counter%1000 == 0))
 
 
73
  {
74
  $filePath = isset($attachment['file']) ? trailingslashit(SHORTPIXEL_UPLOADS_BASE).$attachment['file'] : false;
75
  if ($filePath && file_exists($filePath) && isset($attachment['sizes']) &&
@@ -271,6 +273,18 @@ class WpShortPixelMediaLbraryAdapter {
271
  }
272
  }
273
  }
 
 
 
 
 
 
 
 
 
 
 
 
274
  return $thumbs;
275
  }
276
 
3
  class WpShortPixelMediaLbraryAdapter {
4
 
5
  //count all the processable files in media library (while limiting the results to max 10000)
6
+ public static function countAllProcessableFiles($settings = array(), $maxId = PHP_INT_MAX, $minId = 0){
7
  global $wpdb;
8
 
9
+ $totalFiles = $mainFiles = $processedMainFiles = $processedTotalFiles = $totalFilesM1 = $totalFilesM2 = $totalFilesM3 = $totalFilesM4 =
10
  $procGlossyMainFiles = $procGlossyTotalFiles = $procLossyMainFiles = $procLossyTotalFiles = $procLosslessMainFiles = $procLosslessTotalFiles = $procUndefMainFiles = $procUndefTotalFiles = $mainUnprocessedThumbs = 0;
11
  $filesMap = $processedFilesMap = array();
12
  $limit = self::getOptimalChunkSize();
68
  $sizesCount = isset($attachment['sizes']) ? WpShortPixelMediaLbraryAdapter::countNonWebpSizes($attachment['sizes']) : 0;
69
 
70
  // LA FIECARE 100 de imagini facem un test si daca findThumbs da diferit, sa dam o avertizare si eventual optiune
71
+ $dismissed = $settings->dismissedNotices ? $settings->dismissedNotices : array();
72
+ if( $foundUnlistedThumbs === false && $maxId == PHP_INT_MAX && !isset($dismissed['unlisted'])
73
+ && ( in_array($counter, array(2,4,6,8)) || floor($counter/100) == 0 && $counter%10 == 0
74
+ || floor($counter/1000) == 0 && $counter%100 == 0 || floor($counter/10000) == 0 && $counter%1000 == 0))
75
  {
76
  $filePath = isset($attachment['file']) ? trailingslashit(SHORTPIXEL_UPLOADS_BASE).$attachment['file'] : false;
77
  if ($filePath && file_exists($filePath) && isset($attachment['sizes']) &&
273
  }
274
  }
275
  }
276
+ if(defined('SHORTPIXEL_CUSTOM_THUMB_SUFFIX')) {
277
+ $pattern = '/' . preg_quote($base, '/') . '-\d+x\d+'. SHORTPIXEL_CUSTOM_THUMB_SUFFIX . '\.'. $ext .'/';
278
+ $thumbsCandidates = @glob($base . "-*." . $ext);
279
+ $thumbs = array();
280
+ if(is_array($thumbsCandidates)) {
281
+ foreach($thumbsCandidates as $th) {
282
+ if(preg_match($pattern, $th)) {
283
+ $thumbs[]= $th;
284
+ }
285
+ }
286
+ }
287
+ }
288
  return $thumbs;
289
  }
290
 
class/shortpixel-png2jpg.php CHANGED
@@ -5,10 +5,12 @@
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
 
@@ -23,6 +25,9 @@ class ShortPixelPng2Jpg {
23
  }
24
  $transparent_pixel = $img = $bg = false;
25
  if (!$transparent) {
 
 
 
26
  $img = @imagecreatefrompng($image);
27
  if(!$img) {
28
  $transparent = true; //it's not a PNG, can't convert it
@@ -51,7 +56,7 @@ class ShortPixelPng2Jpg {
51
  * @param array $params
52
  * @param string $backupPath
53
  * @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).
54
- * @param image $img
55
  * @return string
56
  */
57
 
@@ -64,11 +69,14 @@ class ShortPixelPng2Jpg {
64
  }
65
  }
66
 
67
- $bg = imagecreatetruecolor(imagesx($img), imagesy($img));
 
 
68
  if(!$bg) return $params;
69
  imagefill($bg, 0, 0, imagecolorallocate($bg, 255, 255, 255));
70
  imagealphablending($bg, 1);
71
- imagecopy($bg, $img, 0, 0, 0, 0, imagesx($img), imagesy($img));
 
72
  $newPath = preg_replace("/\.png$/i", ".jpg", $image);
73
  $newUrl = preg_replace("/\.png$/i", ".jpg", $params['url']);
74
  for ($i = 1; file_exists($newPath); $i++) {
@@ -160,7 +168,7 @@ class ShortPixelPng2Jpg {
160
  return $meta;
161
  }
162
 
163
- WPShortPixel::log("Send to processing: Convert Media PNG to JPG #{$ID}");
164
 
165
  $image = $meta['file'];
166
  $imagePath = get_attached_file($ID);
@@ -168,13 +176,32 @@ class ShortPixelPng2Jpg {
168
  $imageUrl = wp_get_attachment_url($ID);
169
  $baseUrl = trailingslashit(str_replace($image, "", $imageUrl));
170
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
171
  $ret = $this->canConvertPng2Jpg($imagePath);
172
  if (!$ret['notTransparent']) {
173
  return $meta; //cannot convert it
174
  }
175
 
176
  $ret = $this->doConvertPng2Jpg(array('file' => $imagePath, 'url' => false, 'type' => 'image/png'), $this->_settings->backupImages, false, $ret['img']);
177
- //echo("CONVERT: " . $imagePath); var_dump($ret);
 
 
 
 
 
178
 
179
  if ($ret['type'] == 'image/jpeg') {
180
  //convert to the new URLs the urls in the existing posts.
5
  * Time: 13:44
6
  */
7
 
8
+ //TODO decouple from directly using WP metadata, in order to be able to use it for custom images
9
  class ShortPixelPng2Jpg {
10
  private $_settings = null;
11
 
12
  public function __construct($settings){
13
+ wp_raise_memory_limit( 'image' );
14
  $this->_settings = $settings;
15
  }
16
 
25
  }
26
  $transparent_pixel = $img = $bg = false;
27
  if (!$transparent) {
28
+ $is = getimagesize($image);
29
+ WPShortPixel::log("PNG2JPG Image size: " . round($is[0]*$is[1]*5/1024/1024) . "M memory limit: " . ini_get('memory_limit') . " USED: " . memory_get_usage());
30
+ WPShortPixel::log("PNG2JPG create from png $image");
31
  $img = @imagecreatefrompng($image);
32
  if(!$img) {
33
  $transparent = true; //it's not a PNG, can't convert it
56
  * @param array $params
57
  * @param string $backupPath
58
  * @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).
59
+ * @param image $img - the image if it was already created from png. It will be destroyed at the end.
60
  * @return string
61
  */
62
 
69
  }
70
  }
71
 
72
+ $x = imagesx($img);
73
+ $y = imagesy($img);
74
+ $bg = imagecreatetruecolor($x, $y);
75
  if(!$bg) return $params;
76
  imagefill($bg, 0, 0, imagecolorallocate($bg, 255, 255, 255));
77
  imagealphablending($bg, 1);
78
+ imagecopy($bg, $img, 0, 0, 0, 0, $x, $y);
79
+ imagedestroy($img);
80
  $newPath = preg_replace("/\.png$/i", ".jpg", $image);
81
  $newUrl = preg_replace("/\.png$/i", ".jpg", $params['url']);
82
  for ($i = 1; file_exists($newPath); $i++) {
168
  return $meta;
169
  }
170
 
171
+ WPShortPixel::log("Send to processing: Convert Media PNG to JPG #{$ID} META: " . json_encode($meta));
172
 
173
  $image = $meta['file'];
174
  $imagePath = get_attached_file($ID);
176
  $imageUrl = wp_get_attachment_url($ID);
177
  $baseUrl = trailingslashit(str_replace($image, "", $imageUrl));
178
 
179
+ // set a temporary error in order to make sure user gets something if the image failed from memory limit.
180
+ if( isset($meta['ShortPixel']['Retries']) && $meta['ShortPixel']['Retries'] > 3
181
+ && isset($meta['ShortPixel']['ErrCode']) && $meta['ShortPixel']['ErrCode'] == ShortPixelAPI::ERR_PNG2JPG_MEMORY) {
182
+ WPShortPixel::log("PNG2JPG too many memory failures!");
183
+ throw new Exception('Not enough memory to convert from PNG to JPG.', ShortPixelAPI::ERR_PNG2JPG_MEMORY);
184
+ }
185
+ $meta['ShortPixelImprovement'] = 'Error: <i>Not enough memory to convert from PNG to JPG.</i>';
186
+ if(!isset($meta['ShortPixel']) || !is_array($meta['ShortPixel'])) {
187
+ $meta['ShortPixel'] = array();
188
+ }
189
+ $meta['ShortPixel']['Retries'] = isset($meta['ShortPixel']['Retries']) ? $meta['ShortPixel']['Retries'] + 1 : 1;
190
+ $meta['ShortPixel']['ErrCode'] = ShortPixelAPI::ERR_PNG2JPG_MEMORY;
191
+ wp_update_attachment_metadata($ID, $meta);
192
+
193
  $ret = $this->canConvertPng2Jpg($imagePath);
194
  if (!$ret['notTransparent']) {
195
  return $meta; //cannot convert it
196
  }
197
 
198
  $ret = $this->doConvertPng2Jpg(array('file' => $imagePath, 'url' => false, 'type' => 'image/png'), $this->_settings->backupImages, false, $ret['img']);
199
+
200
+ //unset the temporary error
201
+ unset($meta['ShortPixelImprovement']);
202
+ unset($meta['ShortPixel']['ErrCode']);
203
+ $meta['ShortPixel']['Retries'] -= 1;
204
+ wp_update_attachment_metadata($ID, $meta);
205
 
206
  if ($ret['type'] == 'image/jpeg') {
207
  //convert to the new URLs the urls in the existing posts.
class/shortpixel_queue.php CHANGED
@@ -128,27 +128,31 @@ class ShortPixelQueue {
128
  //$this->settings->priorityQueue = $_SESSION["wp-short-pixel-priorityQueue"] = array_reverse($_SESSION["wp-short-pixel-priorityQueue"]);
129
 
130
  }
131
-
 
 
 
 
 
 
 
 
132
  public function push($ID)//add an ID to priority queue
133
  {
134
- $this->apply(function($priorityQueue, $ID) {
135
- WPShortPixel::log("PUSH: Push ID $ID into queue " . json_encode($priorityQueue));
136
- array_push($priorityQueue, $ID);
137
- $prioQ = array_unique($priorityQueue);
138
- WPShortPixel::log("PUSH: Updated: " . json_encode($prioQ));//get_option("wp-short-pixel-priorityQueue")));
139
- return $prioQ;
140
- }, $ID);
 
 
141
  }
142
 
143
  public function enqueue($ID)//add an ID to priority queue as LAST
144
  {
145
- $this->apply(function($priorityQueue, $ID) {
146
- WPShortPixel::log("ENQUEUE: Enqueue ID $ID into queue " . json_encode($priorityQueue));
147
- array_unshift($priorityQueue, $ID);
148
- $prioQ = array_unique($priorityQueue);
149
- WPShortPixel::log("ENQUEUE: Updated: " . json_encode($prioQ));//get_option("wp-short-pixel-priorityQueue")));
150
- return $prioQ;
151
- }, $ID);
152
  }
153
 
154
  public function getFirst($count = 1)//return the first values added to priority queue
@@ -291,7 +295,7 @@ class ShortPixelQueue {
291
 
292
  public function setBulkPreviousPercent() {
293
  //processable and already processed
294
- $res = WpShortPixelMediaLbraryAdapter::countAllProcessableFiles($this->settings->optimizePdfs, $this->getFlagBulkId(), $this->settings->stopBulkId);
295
  $this->settings->bulkCount = $res["mainFiles"];
296
 
297
  //if compression type changed, add also the images with the other compression type
128
  //$this->settings->priorityQueue = $_SESSION["wp-short-pixel-priorityQueue"] = array_reverse($_SESSION["wp-short-pixel-priorityQueue"]);
129
 
130
  }
131
+
132
+ protected function pushCallback($priorityQueue, $ID) {
133
+ WPShortPixel::log("PUSH: Push ID $ID into queue " . json_encode($priorityQueue));
134
+ array_push($priorityQueue, $ID);
135
+ $prioQ = array_unique($priorityQueue);
136
+ WPShortPixel::log("PUSH: Updated: " . json_encode($prioQ));//get_option("wp-short-pixel-priorityQueue")));
137
+ return $prioQ;
138
+ }
139
+
140
  public function push($ID)//add an ID to priority queue
141
  {
142
+ $this->apply(array(&$this, 'pushCallback'), $ID);
143
+ }
144
+
145
+ protected function enqueueCallback($priorityQueue, $ID) {
146
+ WPShortPixel::log("ENQUEUE: Enqueue ID $ID into queue " . json_encode($priorityQueue));
147
+ array_unshift($priorityQueue, $ID);
148
+ $prioQ = array_unique($priorityQueue);
149
+ WPShortPixel::log("ENQUEUE: Updated: " . json_encode($prioQ));//get_option("wp-short-pixel-priorityQueue")));
150
+ return $prioQ;
151
  }
152
 
153
  public function enqueue($ID)//add an ID to priority queue as LAST
154
  {
155
+ $this->apply(array(&$this, 'enqueueCallback'), $ID);
 
 
 
 
 
 
156
  }
157
 
158
  public function getFirst($count = 1)//return the first values added to priority queue
295
 
296
  public function setBulkPreviousPercent() {
297
  //processable and already processed
298
+ $res = WpShortPixelMediaLbraryAdapter::countAllProcessableFiles($this->settings, $this->getFlagBulkId(), $this->settings->stopBulkId);
299
  $this->settings->bulkCount = $res["mainFiles"];
300
 
301
  //if compression type changed, add also the images with the other compression type
class/view/shortpixel_view.php CHANGED
@@ -188,6 +188,7 @@ class ShortPixelView {
188
  public function displayBulkProcessingForm($quotaData, $thumbsProcessedCount, $under5PercentCount, $bulkRan,
189
  $averageCompression, $filesOptimized, $savedSpace, $percent, $customCount) {
190
  $settings = $this->ctrl->getSettings();
 
191
  ?>
192
  <div class="wrap short-pixel-bulk-page">
193
  <h1>Bulk Image Optimization by ShortPixel</h1>
@@ -540,8 +541,8 @@ class ShortPixelView {
540
  <?php _e("Too many images processing simultaneously for your site, automatically retrying in 1 min. Please don't close this window.",'shortpixel-image-optimiser');?>
541
  </div>
542
  <div class="bulk-notice-msg bulk-error" id="bulk-error-template">
543
- <div style="float: right; margin-top: -4px; margin-right: -8px;">
544
- <a href="javascript:void(0);" onclick="ShortPixel.removeBulkMsg(this)" style='color: #c32525;'>&#10006;</a>
545
  </div>
546
  <img src="<?php echo(plugins_url( 'shortpixel-image-optimiser/res/img/exclamation-big.png' ));?>">
547
  <span class="sp-err-title"><?php _e('Error processing file:','shortpixel-image-optimiser');?><br></span>
@@ -687,11 +688,12 @@ class ShortPixelView {
687
  <?php
688
  }
689
 
690
- function displaySettings($showApiKey, $editApiKey, $quotaData, $notice, $resources = null, $averageCompression = null, $savedSpace = null, $savedBandwidth = null,
691
  $remainingImages = null, $totalCallsMade = null, $fileCount = null, $backupFolderSize = null,
692
  $customFolders = null, $folderMsg = false, $addedFolder = false, $showAdvanced = false) {
693
  //wp_enqueue_script('jquery.idTabs.js', plugins_url('/js/jquery.idTabs.js',__FILE__) );
694
- ?>
 
695
  <h1><?php _e('ShortPixel Plugin Settings','shortpixel-image-optimiser');?></h1>
696
  <p style="font-size:18px">
697
  <a href="https://shortpixel.com/<?php
@@ -777,7 +779,7 @@ class ShortPixelView {
777
  <p><?php printf(__('New images uploaded to the Media Library will be optimized automatically.<br/>If you have existing images you would like to optimize, you can use the <a href="%supload.php?page=wp-short-pixel-bulk">Bulk Optimization Tool</a>.','shortpixel-image-optimiser'),get_admin_url());?></p>
778
  <?php } else {
779
  if($showApiKey) {?>
780
- <h3><?php _e('Step 1:','shortpixel-image-optimiser');?></h3>
781
  <p style='font-size: 14px'><?php _e('If you don\'t have an API Key, you can request one for free. Just press the "Request Key" button after checking that the e-mail is correct.','shortpixel-image-optimiser');?></p>
782
  <table class="form-table">
783
  <tbody>
@@ -801,17 +803,19 @@ class ShortPixelView {
801
  printf(__('<b>%s</b> is the e-mail address in your WordPress Settings. You can use it, or change it to any valid e-mail address that you own.','shortpixel-image-optimiser'), $adminEmail);
802
  } else {
803
  _e('Please input your e-mail address and press the Request Key button.','shortpixel-image-optimiser');
804
- }?>
 
 
805
  </p>
806
  </td>
807
  </tr>
808
  </tbody>
809
  </table>
810
  <h3>
811
- <?php _e('Step 2:','shortpixel-image-optimiser');?>
812
  </h3>
813
  <p style='font-size: 14px'>
814
- <?php _e('Please enter here the API Key and press Validate.','shortpixel-image-optimiser');?>
815
  </p>
816
  <?php }
817
  }?>
@@ -930,6 +934,9 @@ class ShortPixelView {
930
  <img src="<?php echo(plugins_url( 'shortpixel-image-optimiser/res/img/resize-inner.png' ));?>"
931
  srcset='<?php echo(plugins_url( 'shortpixel-image-optimiser/res/img/resize-inner.png' ));?> 1x, <?php echo(plugins_url( 'shortpixel-image-optimiser/res/img/resize-inner@2x.png' ));?> 2x'
932
  title="<?php _e('Sizes will be smaller or equal to the corresponding value. For example, if you set the resize dimensions at 1000x1200, an image of 2000x3000px will be resized to 800x1200px while an image of 3000x2000px will be resized to 1000x667px','shortpixel-image-optimiser');?>">
 
 
 
933
  </div>
934
  </td>
935
  </tr>
@@ -1287,7 +1294,9 @@ class ShortPixelView {
1287
  <?php if ($backupFolderSize === null) { ?>
1288
  <span id='backup-folder-size'>Calculating...</span>
1289
  <?php } else { echo($backupFolderSize); }?>
1290
- <input type="submit" style="margin-left: 15px; vertical-align: middle;" class="button button-secondary" name="emptyBackup" value="<?php _e('Empty backups','shortpixel-image-optimiser');?>"/>
 
 
1291
  </form>
1292
  </td>
1293
  </tr>
@@ -1331,16 +1340,23 @@ class ShortPixelView {
1331
  echo("<br>+" . $data['thumbsTotal'] . " thumbnails");
1332
  }
1333
  break;
 
1334
  case 'retry':
1335
  echo($data['message']);
1336
  if(isset($data['cleanup'])) {?> <a class='button button-smaller button-primary' href="javascript:manualOptimization('<?php echo($id)?>', true)">
1337
  <?php _e('Cleanup&Retry','shortpixel-image-optimiser');?>
1338
  </a> <?php
1339
  } else {
1340
- ?>
 
 
 
 
 
1341
  <a class='button button-smaller button-primary' href="javascript:manualOptimization('<?php echo($id)?>', false)">
1342
  <?php _e('Retry','shortpixel-image-optimiser');?>
1343
- </a> <?php
 
1344
  }
1345
  break;
1346
  case 'pdfOptimized':
188
  public function displayBulkProcessingForm($quotaData, $thumbsProcessedCount, $under5PercentCount, $bulkRan,
189
  $averageCompression, $filesOptimized, $savedSpace, $percent, $customCount) {
190
  $settings = $this->ctrl->getSettings();
191
+ $this->ctrl->outputHSBeacon();
192
  ?>
193
  <div class="wrap short-pixel-bulk-page">
194
  <h1>Bulk Image Optimization by ShortPixel</h1>
541
  <?php _e("Too many images processing simultaneously for your site, automatically retrying in 1 min. Please don't close this window.",'shortpixel-image-optimiser');?>
542
  </div>
543
  <div class="bulk-notice-msg bulk-error" id="bulk-error-template">
544
+ <div style="float: right; margin-top: -4px; margin-right: -3px;">
545
+ <a href="javascript:void(0);" onclick="ShortPixel.removeBulkMsg(this)" style='color: #c32525;font-size: 20px;text-decoration: none;'>&times;</a>
546
  </div>
547
  <img src="<?php echo(plugins_url( 'shortpixel-image-optimiser/res/img/exclamation-big.png' ));?>">
548
  <span class="sp-err-title"><?php _e('Error processing file:','shortpixel-image-optimiser');?><br></span>
688
  <?php
689
  }
690
 
691
+ function displaySettings($showApiKey, $editApiKey, $quotaData, $notice, $resources = null, $averageCompression = null, $savedSpace = null, $savedBandwidth = null,
692
  $remainingImages = null, $totalCallsMade = null, $fileCount = null, $backupFolderSize = null,
693
  $customFolders = null, $folderMsg = false, $addedFolder = false, $showAdvanced = false) {
694
  //wp_enqueue_script('jquery.idTabs.js', plugins_url('/js/jquery.idTabs.js',__FILE__) );
695
+ $this->ctrl->outputHSBeacon();
696
+ ?>
697
  <h1><?php _e('ShortPixel Plugin Settings','shortpixel-image-optimiser');?></h1>
698
  <p style="font-size:18px">
699
  <a href="https://shortpixel.com/<?php
779
  <p><?php printf(__('New images uploaded to the Media Library will be optimized automatically.<br/>If you have existing images you would like to optimize, you can use the <a href="%supload.php?page=wp-short-pixel-bulk">Bulk Optimization Tool</a>.','shortpixel-image-optimiser'),get_admin_url());?></p>
780
  <?php } else {
781
  if($showApiKey) {?>
782
+ <h3><?php _e('Request an API Key:','shortpixel-image-optimiser');?></h3>
783
  <p style='font-size: 14px'><?php _e('If you don\'t have an API Key, you can request one for free. Just press the "Request Key" button after checking that the e-mail is correct.','shortpixel-image-optimiser');?></p>
784
  <table class="form-table">
785
  <tbody>
803
  printf(__('<b>%s</b> is the e-mail address in your WordPress Settings. You can use it, or change it to any valid e-mail address that you own.','shortpixel-image-optimiser'), $adminEmail);
804
  } else {
805
  _e('Please input your e-mail address and press the Request Key button.','shortpixel-image-optimiser');
806
+ }
807
+ echo(' ');_e('By signing up or validating your API Key, you agree to our <a href="https://shortpixel.com/tos" target="_blank">Terms of Service</a>.','shortpixel-image-optimiser');
808
+ ?>
809
  </p>
810
  </td>
811
  </tr>
812
  </tbody>
813
  </table>
814
  <h3>
815
+ <?php _e('Already have an API Key:','shortpixel-image-optimiser');?>
816
  </h3>
817
  <p style='font-size: 14px'>
818
+ <?php _e('If you already have an API Key please input it below and press Validate.','shortpixel-image-optimiser');?>
819
  </p>
820
  <?php }
821
  }?>
934
  <img src="<?php echo(plugins_url( 'shortpixel-image-optimiser/res/img/resize-inner.png' ));?>"
935
  srcset='<?php echo(plugins_url( 'shortpixel-image-optimiser/res/img/resize-inner.png' ));?> 1x, <?php echo(plugins_url( 'shortpixel-image-optimiser/res/img/resize-inner@2x.png' ));?> 2x'
936
  title="<?php _e('Sizes will be smaller or equal to the corresponding value. For example, if you set the resize dimensions at 1000x1200, an image of 2000x3000px will be resized to 800x1200px while an image of 3000x2000px will be resized to 1000x667px','shortpixel-image-optimiser');?>">
937
+ <div style="display:inline-block;margin-left: 20px;"><a href="https://blog.shortpixel.com/resize-images/" class="shortpixel-help-link" target="_blank">
938
+ <span class="dashicons dashicons-editor-help"></span>What is this?</a>
939
+ </div>
940
  </div>
941
  </td>
942
  </tr>
1294
  <?php if ($backupFolderSize === null) { ?>
1295
  <span id='backup-folder-size'>Calculating...</span>
1296
  <?php } else { echo($backupFolderSize); }?>
1297
+ <input type="submit" style="margin-left: 15px; vertical-align: middle;" class="button button-secondary shortpixel-confirm"
1298
+ name="emptyBackup" value="<?php _e('Empty backups','shortpixel-image-optimiser');?>"
1299
+ data-confirm="<?php _e('Are you sure you want to delete all the backup images? You won\'t be able to restore from backup or to reoptimize with different settings if you delete the backups.','shortpixel-image-optimiser'); ?>"/>
1300
  </form>
1301
  </td>
1302
  </tr>
1340
  echo("<br>+" . $data['thumbsTotal'] . " thumbnails");
1341
  }
1342
  break;
1343
+ case 'waiting':
1344
  case 'retry':
1345
  echo($data['message']);
1346
  if(isset($data['cleanup'])) {?> <a class='button button-smaller button-primary' href="javascript:manualOptimization('<?php echo($id)?>', true)">
1347
  <?php _e('Cleanup&Retry','shortpixel-image-optimiser');?>
1348
  </a> <?php
1349
  } else {
1350
+ if($data['status'] == 'retry') { ?>
1351
+ <a class="button button-smaller sp-action-restore" href="admin.php?action=shortpixel_restore_backup&attachment_ID=<?php echo($id)?>" style="margin-left:5px;"
1352
+ title="Cleanup the metadata and return the image to the status before the error.">
1353
+ <?php _e('Cleanup','shortpixel-image-optimiser');?>
1354
+ </a>
1355
+ <?php } ?>
1356
  <a class='button button-smaller button-primary' href="javascript:manualOptimization('<?php echo($id)?>', false)">
1357
  <?php _e('Retry','shortpixel-image-optimiser');?>
1358
+ </a>
1359
+ <?php
1360
  }
1361
  break;
1362
  case 'pdfOptimized':
class/wp-short-pixel.php CHANGED
@@ -39,7 +39,11 @@ class WPShortPixel {
39
  $this->prioQ = new ShortPixelQueue($this, $this->_settings);
40
  $this->view = new ShortPixelView($this);
41
 
42
- define('QUOTA_EXCEEDED', $this->view->getQuotaExceededHTML());
 
 
 
 
43
 
44
  $this->setDefaultViewModeList();//set default mode as list. only @ first run
45
 
@@ -105,6 +109,8 @@ class WPShortPixel {
105
  add_action( 'wp_ajax_shortpixel_image_processing', array( &$this, 'handleImageProcessing') );
106
  //manual optimization
107
  add_action( 'wp_ajax_shortpixel_manual_optimization', array(&$this, 'handleManualOptimization'));
 
 
108
  //dismiss notices
109
  add_action( 'wp_ajax_shortpixel_dismiss_notice', array(&$this, 'dismissAdminNotice'));
110
  add_action( 'wp_ajax_shortpixel_dismiss_media_alert', array(&$this, 'dismissMediaAlert'));
@@ -113,6 +119,7 @@ class WPShortPixel {
113
  add_action('admin_action_shortpixel_check_quota', array(&$this, 'handleCheckQuota'));
114
  //This adds the constants used in PHP to be available also in JS
115
  add_action( 'admin_footer', array( &$this, 'shortPixelJS') );
 
116
 
117
  if($this->_settings->frontBootstrap) {
118
  //also need to have it in the front footer then
@@ -319,6 +326,10 @@ class WPShortPixel {
319
  error_log($message);
320
  }
321
  }
 
 
 
 
322
 
323
  function shortPixelJS() {
324
  //require_once(ABSPATH . 'wp-admin/includes/screen.php');
@@ -353,6 +364,10 @@ class WPShortPixel {
353
  FRONT_BOOTSTRAP: <?php echo $this->_settings->frontBootstrap && (!isset($this->_settings->lastBackAction) || (time() - $this->_settings->lastBackAction > 600)) ? 1 : 0; ?>,
354
  AJAX_URL: '<?php echo admin_url('admin-ajax.php'); ?>'
355
  };
 
 
 
 
356
  </script> <?php
357
  wp_enqueue_style('short-pixel.min.css', plugins_url('/res/css/short-pixel.min.css',SHORTPIXEL_PLUGIN_FILE), array(), SHORTPIXEL_IMAGE_OPTIMISER_VERSION);
358
 
@@ -416,6 +431,7 @@ class WPShortPixel {
416
  if($lastStatus && $lastStatus['Status'] != ShortPixelAPI::STATUS_SUCCESS) {
417
  $extraClasses = " shortpixel-alert shortpixel-processing";
418
  $tooltip = $lastStatus['Message'];
 
419
  }
420
 
421
  $args = array(
@@ -483,11 +499,11 @@ class WPShortPixel {
483
  if( !$this->_settings->verifiedKey) {// no API Key set/verified -> do nothing here, just return
484
  return $meta;
485
  }
486
- //else
487
- //self::log("IMG: Auto-analyzing file ID #{$ID}");
488
-
489
- if(isset($meta['ShortPixelImprovement'])) {
490
- return $meta;// some plugins (e.g. WP e-Commerce) call the wp_attachment_metadata on just editing the image...
491
  }
492
 
493
  self::log("Handle Media Library Image Upload #{$ID}");
@@ -496,9 +512,16 @@ class WPShortPixel {
496
  //pdf is not optimized automatically as per the option, but can be optimized by button. Nothing to do.
497
  return $meta;
498
  }
 
 
 
 
 
 
499
  elseif( self::_isProcessable($ID, array(), $this->_settings->excludePatterns, $meta) == false )
500
- {//not a file that we can process
501
- $meta['ShortPixelImprovement'] = __('Optimization N/A','shortpixel-image-optimiser');
 
502
  return $meta;
503
  }
504
  else
@@ -509,8 +532,9 @@ class WPShortPixel {
509
  $itemHandler->setRawMeta($meta);
510
  //that's a hack for watermarking plugins, don't send the image right away to processing, only add it in the queue
511
  include_once( ABSPATH . 'wp-admin/includes/plugin.php' );
512
- if( !is_plugin_active('image-watermark/image-watermark.php')
513
  && !is_plugin_active('amazon-s3-and-cloudfront/wordpress-s3.php')
 
514
  && !is_plugin_active('easy-watermark/index.php')) {
515
  try {
516
  $URLsAndPATHs = $this->getURLsAndPATHs($itemHandler);
@@ -683,6 +707,9 @@ class WPShortPixel {
683
  }
684
  $restored[] = array('id' => $crtStartQueryID, 'status' => $res ? 'success' : 'fail');
685
  }
 
 
 
686
  }
687
  }
688
  $this->advanceBulk($crtStartQueryID);
@@ -766,7 +793,7 @@ class WPShortPixel {
766
  //daca n-am adaugat niciuna pana acum, n-are sens sa mai selectez zona asta de id-uri in bulk-ul asta.
767
  $leapStart = $this->prioQ->getStartBulkId();
768
  $crtStartQueryID = $startQueryID = $itemMetaData->post_id - 1; //decrement it so we don't select it again
769
- $res = WpShortPixelMediaLbraryAdapter::countAllProcessableFiles($this->_settings->optimizePdfs, $leapStart, $crtStartQueryID);
770
  $skippedAlreadyProcessed += $res["mainProcessedFiles"] - $res["mainProc".($this->getCompressionType() == 1 ? "Lossy" : "Lossless")."Files"];
771
  self::log("GETDB: empty list. setStartBulkID to $startQueryID");
772
  $this->prioQ->setStartBulkId($startQueryID);
@@ -909,7 +936,7 @@ class WPShortPixel {
909
  $firstUrlAndPaths = $URLsAndPATHs;
910
  }
911
  } catch(Exception $e) { // Exception("Post metadata is corrupt (No attachment URL)") or Exception("Image files are missing.")
912
- $crtItemHandler->incrementRetries(1, ShortPixelAPI::ERR_FILE_NOT_FOUND, $e->getMessage());
913
  if(! $this->prioQ->remove($crtItemHandler->getQueuedId()) ){
914
  $this->advanceBulk($crtItemHandler->getId());
915
  $res['searching'] = true;
@@ -1225,8 +1252,14 @@ class WPShortPixel {
1225
  //do_action('shortpixel-optimize-now', $imageId);
1226
 
1227
  }
1228
-
1229
- //custom hook
 
 
 
 
 
 
1230
  public function optimizeNowHook($imageId, $manual = false) {
1231
  if($this->isProcessable($imageId)) {
1232
  $this->prioQ->push($imageId);
@@ -1240,7 +1273,8 @@ class WPShortPixel {
1240
  $ret = array("Status" => ShortPixelAPI::STATUS_SUCCESS, "Message" => "");
1241
  } catch(Exception $e) { // Exception("Post metadata is corrupt (No attachment URL)")
1242
  $itemHandler->getMeta();
1243
- $itemHandler->setError(ShortPixelAPI::ERR_FILE_NOT_FOUND, $e->getMessage());
 
1244
  $ret = array("Status" => ShortPixelAPI::STATUS_FAIL, "Message" => $e->getMessage());
1245
  }
1246
  }
@@ -1305,7 +1339,8 @@ class WPShortPixel {
1305
 
1306
  public function getBackupFolderAny($file, $thumbs) {
1307
  $ret = $this->getBackupFolder($file);
1308
- if(!$ret && !file_exists($file) && isset($thumbs)) {
 
1309
  //try with the thumbnails
1310
  foreach($thumbs as $size) {
1311
  $backup = $this->getBackupFolder(trailingslashit(dirname($file)) . $size['file']);
@@ -1333,6 +1368,7 @@ class WPShortPixel {
1333
  return true;
1334
  }
1335
 
 
1336
  protected function doRestore($attachmentID, $meta = null) {
1337
  $file = $origFile = get_attached_file($attachmentID);
1338
  if(!$meta) {
@@ -1356,39 +1392,46 @@ class WPShortPixel {
1356
 
1357
  //first check if the file is readable by the current user - otherwise it will be unaccessible for the web browser
1358
  // - collect the thumbs paths in the process
1359
- $bkCount = 0; $main = false;
1360
- if(file_exists($bkFile)) {
1361
- if(!$this->setFilePerms($bkFile) || (file_exists($file) && !$this->setFilePerms($file)) ) {
1362
- return false;
1363
- }
1364
- $bkCount++;
1365
- $main = true;
1366
- }
1367
- $thumbsPaths = array();
1368
- if( !empty($meta['file']) && count($sizes) ) {
1369
- foreach($sizes as $size => $imageData) {
1370
- $dest = $pathInfo['dirname'] . '/' . $imageData['file'];
1371
- $source = trailingslashit($bkFolder) . $imageData['file'];
1372
- if(!file_exists($source)) continue; // if thumbs were not optimized, then the backups will not be there.
1373
- if(!$this->setFilePerms($source) || (file_exists($dest) && !$this->setFilePerms($dest))) {
1374
  return false;
1375
  }
1376
  $bkCount++;
1377
- $thumbsPaths[$source] = $dest;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1378
  }
1379
  }
1380
- if(!$bkCount) {
1381
- return false;
1382
- }
1383
-
1384
- if($bkFolder) {
1385
- try {
1386
- //main file
1387
  if($main) {
1388
  $this->renameWithRetina($bkFile, $file);
1389
  }
1390
  //getSize to update meta if image was resized by ShortPixel
1391
- $width = false;
1392
  if(file_exists($file)) {
1393
  $size = getimagesize($file);
1394
  $width = $size[0];
@@ -1399,46 +1442,44 @@ class WPShortPixel {
1399
  foreach($thumbsPaths as $source => $destination) {
1400
  $this->renameWithRetina($source, $destination);
1401
  }
1402
- $duplicates = ShortPixelMetaFacade::getWPMLDuplicates($attachmentID);
1403
- foreach($duplicates as $ID) {
1404
- $crtMeta = $attachmentID == $ID ? $meta : wp_get_attachment_metadata($ID);
1405
- if( isset($crtMeta["ShortPixelImprovement"]) && is_numeric($crtMeta["ShortPixelImprovement"])
1406
- && 0 + $crtMeta["ShortPixelImprovement"] < 5 && $this->_settings->under5Percent > 0) {
1407
- $this->_settings->under5Percent = $this->_settings->under5Percent - 1; // - (isset($crtMeta["ShortPixel"]["thumbsOpt"]) ? $crtMeta["ShortPixel"]["thumbsOpt"] : 0);
1408
- }
1409
- unset($crtMeta["ShortPixelImprovement"]);
1410
- unset($crtMeta['ShortPixel']);
1411
- unset($crtMeta['ShortPixelPng2Jpg']);
1412
- if($width && $height) {
1413
- $crtMeta['width'] = $width;
1414
- $crtMeta['height'] = $height;
1415
- }
1416
- if($png2jpgMain) {
1417
- $crtMeta['file'] = trailingslashit(dirname($crtMeta['file'])) . ShortPixelAPI::MB_basename($file);
1418
- update_attached_file($ID, $crtMeta['file']);
1419
- if($png2jpgSizes) {
1420
- $crtMeta['sizes'] = $png2jpgSizes;
1421
- } else {
1422
- //this was an image converted on upload, regenerate the thumbs using the PNG main image BUT deactivate temporarily the filter!!
1423
- remove_filter( 'wp_generate_attachment_metadata', 'shortPixelHandleImageUploadHook');
1424
- $crtMeta = wp_generate_attachment_metadata($ID, $png2jpgMain);
1425
- add_filter( 'wp_generate_attachment_metadata', 'shortPixelHandleImageUploadHook', 10, 2 );
1426
- }
 
1427
  }
1428
- wp_update_attachment_metadata($ID, $crtMeta);
1429
  }
1430
- unset($meta["ShortPixelImprovement"]);
1431
- unset($meta['ShortPixel']);
1432
- unset($meta['ShortPixelPng2Jpg']);
1433
-
1434
- } catch(Exception $e) {
1435
- //what to do, what to do?
1436
- return false;
1437
  }
1438
- } else {
 
 
 
 
 
1439
  return false;
1440
  }
1441
-
1442
  return $meta;
1443
  }
1444
 
@@ -1514,7 +1555,7 @@ class WPShortPixel {
1514
  $ret = array("Status" => ShortPixelAPI::STATUS_SUCCESS, "Message" => "");
1515
  } catch(Exception $e) { // Exception("Post metadata is corrupt (No attachment URL)") or Exception("Image files are missing.")
1516
  $meta['ShortPixelImprovement'] = $e->getMessage();
1517
- $meta['ShortPixel']['ErrCode'] = ShortPixelAPI::STATUS_FAIL;
1518
  unset($meta['ShortPixel']['WaitingProcessing']);
1519
  wp_update_attachment_metadata($ID, $meta);
1520
  $ret = array("Status" => ShortPixelAPI::STATUS_FAIL, "Message" => $e->getMessage());
@@ -1542,7 +1583,7 @@ class WPShortPixel {
1542
  $ret = array("Status" => ShortPixelAPI::STATUS_SUCCESS, "message" => "");
1543
  } catch(Exception $e) { // Exception("Post metadata is corrupt (No attachment URL)") or Exception("Image files are missing.")
1544
  $meta['ShortPixelImprovement'] = $e->getMessage();
1545
- $meta['ShortPixel']['ErrCode'] = ShortPixelAPI::STATUS_FAIL;
1546
  unset($meta['ShortPixel']['WaitingProcessing']);
1547
  wp_update_attachment_metadata($ID, $meta);
1548
  $ret = array("Status" => ShortPixelAPI::STATUS_FAIL, "Message" => $e->getMessage());
@@ -1613,7 +1654,7 @@ class WPShortPixel {
1613
  {
1614
  return $this->_settings->currentStats;
1615
  } else {
1616
- $imageCount = WpShortPixelMediaLbraryAdapter::countAllProcessableFiles($this->_settings->optimizePdfs);
1617
  $quotaData['time'] = time();
1618
  $quotaData['optimizePdfs'] = $this->_settings->optimizePdfs;
1619
  //$quotaData['quotaData'] = $quotaData;
@@ -1685,9 +1726,9 @@ class WPShortPixel {
1685
  if ( isset($_GET['noheader']) ) {
1686
  require_once(ABSPATH . 'wp-admin/admin-header.php');
1687
  }
1688
-
1689
  ?>
1690
- <div class="wrap shortpixel-other-media">
1691
  <h2>
1692
  <div style="float:right;">
1693
  <a href="upload.php?page=wp-short-pixel-custom&refresh=1" id="refresh" class="button button-primary" title="<?php _e('Refresh custom folders content','shortpixel-image-optimiser');?>">
@@ -1860,7 +1901,9 @@ class WPShortPixel {
1860
  } elseif ($minutes > 240) {
1861
  $timeEst = "~ " . round($minutes / 60) . " hours left";
1862
  } elseif ($minutes > 60) {
1863
- $timeEst = "~ " . round($minutes / 60) . " hours " . round($minutes % 60 / 10) * 10 . " min. left";
 
 
1864
  } elseif ($minutes > 20) {
1865
  $timeEst = "~ " . round($minutes / 10) * 10 . " minutes left";
1866
  } else {
@@ -2035,6 +2078,7 @@ class WPShortPixel {
2035
  //'m1' => 4625, 'm2' => 4592, 'm3' => 4711, 'm4' => 4121, 'filesTodo' => 51143, 'estimated' => 'true'
2036
  //'m1' => 4625, 'm2' => 4592, 'm3' => 4711, 'm4' => 4121, 'filesTodo' => 41143, 'estimated' => 'true'
2037
  //'m1' => 7625, 'm2' => 6592, 'm3' => 6711, 'm4' => 5121, 'filesTodo' => 41143, 'estimated' => 'true'
 
2038
  'm1' => $stats['totalM1'],
2039
  'm2' => $stats['totalM2'],
2040
  'm3' => $stats['totalM3'],
@@ -2390,7 +2434,7 @@ class WPShortPixel {
2390
  if($validate) {
2391
  $args['body']['DomainCheck'] = get_site_url();
2392
  $args['body']['Info'] = get_bloginfo('version') . '|' . phpversion();
2393
- $imageCount = WpShortPixelMediaLbraryAdapter::countAllProcessableFiles($this->_settings->optimizePdfs);
2394
  $args['body']['ImagesCount'] = $imageCount['mainFiles'];
2395
  $args['body']['ThumbsCount'] = $imageCount['totalFiles'] - $imageCount['mainFiles'];
2396
  $argsStr .= "&DomainCheck={$args['body']['DomainCheck']}&Info={$args['body']['Info']}&ImagesCount={$imageCount['mainFiles']}&ThumbsCount={$args['body']['ThumbsCount']}";
@@ -2529,7 +2573,7 @@ class WPShortPixel {
2529
  if( 'wp-shortPixel' == $column_name ) {
2530
 
2531
  if(!$this->isProcessable($id)) {
2532
- $renderData['status'] = 'n/a';
2533
  $this->view->renderCustomColumn($id, $renderData, $extended);
2534
  return;
2535
  }
@@ -2625,7 +2669,7 @@ class WPShortPixel {
2625
  $renderData['message'] = __('Image does not exist','shortpixel-image-optimiser');
2626
  }
2627
  elseif(isset($data['ShortPixel']['WaitingProcessing'])) {
2628
- $renderData['status'] = $quotaExceeded ? 'quotaExceeded' : 'retry';
2629
  $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');
2630
  if($this->_settings->autoMediaLibrary && !$quotaExceeded && ($id > $this->prioQ->getFlagBulkId() || !$this->prioQ->bulkRunning())) {
2631
  $this->prioQ->unskip($id);
@@ -2938,12 +2982,42 @@ class WPShortPixel {
2938
 
2939
  public function getOtherCompressionTypes($compressionType = false) {
2940
  return array_values(array_diff(array(0, 1, 2), array(0 + $compressionType)));
2941
- }
2942
-
2943
- /* public function getEncryptedData() {
2944
- return base64_encode(self::encrypt($this->getApiKey() . "|" . get_site_url(), "sh0r+Pix3l8im1N3r"));
2945
  }
2946
- */
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2947
 
2948
  /**
2949
  * Returns an encrypted & utf8-encoded
39
  $this->prioQ = new ShortPixelQueue($this, $this->_settings);
40
  $this->view = new ShortPixelView($this);
41
 
42
+ define('QUOTA_EXCEEDED', $this->view->getQuotaExceededHTML());
43
+
44
+ if(is_plugin_active('envira-gallery/envira-gallery.php')) {
45
+ define('SHORTPIXEL_CUSTOM_THUMB_SUFFIX', '_c');
46
+ }
47
 
48
  $this->setDefaultViewModeList();//set default mode as list. only @ first run
49
 
109
  add_action( 'wp_ajax_shortpixel_image_processing', array( &$this, 'handleImageProcessing') );
110
  //manual optimization
111
  add_action( 'wp_ajax_shortpixel_manual_optimization', array(&$this, 'handleManualOptimization'));
112
+ //check status
113
+ add_action( 'wp_ajax_shortpixel_check_status', array(&$this, 'checkStatus'));
114
  //dismiss notices
115
  add_action( 'wp_ajax_shortpixel_dismiss_notice', array(&$this, 'dismissAdminNotice'));
116
  add_action( 'wp_ajax_shortpixel_dismiss_media_alert', array(&$this, 'dismissMediaAlert'));
119
  add_action('admin_action_shortpixel_check_quota', array(&$this, 'handleCheckQuota'));
120
  //This adds the constants used in PHP to be available also in JS
121
  add_action( 'admin_footer', array( &$this, 'shortPixelJS') );
122
+ add_action( 'admin_head', array( &$this, 'headCSS') );
123
 
124
  if($this->_settings->frontBootstrap) {
125
  //also need to have it in the front footer then
326
  error_log($message);
327
  }
328
  }
329
+
330
+ function headCSS() {
331
+ echo('<style>.shortpixel-hide {display:none;}</style>');
332
+ }
333
 
334
  function shortPixelJS() {
335
  //require_once(ABSPATH . 'wp-admin/includes/screen.php');
364
  FRONT_BOOTSTRAP: <?php echo $this->_settings->frontBootstrap && (!isset($this->_settings->lastBackAction) || (time() - $this->_settings->lastBackAction > 600)) ? 1 : 0; ?>,
365
  AJAX_URL: '<?php echo admin_url('admin-ajax.php'); ?>'
366
  };
367
+ //check after 10 seconds if ShortPixel initialized OK, if not, force the init (could happen if a JS error somewhere else stopped the JS execution).
368
+ setTimeout(function($) {
369
+ ShortPixel.init();
370
+ }, 10000);
371
  </script> <?php
372
  wp_enqueue_style('short-pixel.min.css', plugins_url('/res/css/short-pixel.min.css',SHORTPIXEL_PLUGIN_FILE), array(), SHORTPIXEL_IMAGE_OPTIMISER_VERSION);
373
 
431
  if($lastStatus && $lastStatus['Status'] != ShortPixelAPI::STATUS_SUCCESS) {
432
  $extraClasses = " shortpixel-alert shortpixel-processing";
433
  $tooltip = $lastStatus['Message'];
434
+ $successLink = $link = admin_url(current_user_can( 'edit_others_posts')? 'post.php?post=' . $lastStatus['ImageID'] . '&action=edit' : 'upload.php');
435
  }
436
 
437
  $args = array(
499
  if( !$this->_settings->verifiedKey) {// no API Key set/verified -> do nothing here, just return
500
  return $meta;
501
  }
502
+
503
+ // some plugins (e.g. WP e-Commerce) call the wp_attachment_metadata on just editing the image...
504
+ $dbMeta = wp_get_attachment_metadata($ID);
505
+ if(isset($dbMeta['ShortPixelImprovement'])) {
506
+ return $meta;
507
  }
508
 
509
  self::log("Handle Media Library Image Upload #{$ID}");
512
  //pdf is not optimized automatically as per the option, but can be optimized by button. Nothing to do.
513
  return $meta;
514
  }
515
+ elseif(!get_attached_file($ID) && isset($meta['file']) && in_array(strtolower(pathinfo($meta['file'], PATHINFO_EXTENSION)), self::$PROCESSABLE_EXTENSIONS)) {
516
+ //in some rare cases (images added from the front-end) it's an image but get_attached_file returns null (the record is not yet saved in the DB)
517
+ //in this case add it to the queue nevertheless
518
+ $this->prioQ->push($ID);
519
+ $meta['ShortPixel'] = array('WaitingProcessing' => true);
520
+ }
521
  elseif( self::_isProcessable($ID, array(), $this->_settings->excludePatterns, $meta) == false )
522
+ {
523
+ //not a file that we can process
524
+ $meta['ShortPixelImprovement'] = __('Optimization N/A', 'shortpixel-image-optimiser');
525
  return $meta;
526
  }
527
  else
532
  $itemHandler->setRawMeta($meta);
533
  //that's a hack for watermarking plugins, don't send the image right away to processing, only add it in the queue
534
  include_once( ABSPATH . 'wp-admin/includes/plugin.php' );
535
+ if( !is_plugin_active('image-watermark/image-watermark.php')
536
  && !is_plugin_active('amazon-s3-and-cloudfront/wordpress-s3.php')
537
+ && !is_plugin_active('amazon-s3-and-cloudfront-pro/amazon-s3-and-cloudfront-pro.php')
538
  && !is_plugin_active('easy-watermark/index.php')) {
539
  try {
540
  $URLsAndPATHs = $this->getURLsAndPATHs($itemHandler);
707
  }
708
  $restored[] = array('id' => $crtStartQueryID, 'status' => $res ? 'success' : 'fail');
709
  }
710
+ if($meta->getStatus() < 0) {//also cleanup errors either for restore or cleanup
711
+ $item->cleanupMeta();
712
+ }
713
  }
714
  }
715
  $this->advanceBulk($crtStartQueryID);
793
  //daca n-am adaugat niciuna pana acum, n-are sens sa mai selectez zona asta de id-uri in bulk-ul asta.
794
  $leapStart = $this->prioQ->getStartBulkId();
795
  $crtStartQueryID = $startQueryID = $itemMetaData->post_id - 1; //decrement it so we don't select it again
796
+ $res = WpShortPixelMediaLbraryAdapter::countAllProcessableFiles($this->_settings, $leapStart, $crtStartQueryID);
797
  $skippedAlreadyProcessed += $res["mainProcessedFiles"] - $res["mainProc".($this->getCompressionType() == 1 ? "Lossy" : "Lossless")."Files"];
798
  self::log("GETDB: empty list. setStartBulkID to $startQueryID");
799
  $this->prioQ->setStartBulkId($startQueryID);
936
  $firstUrlAndPaths = $URLsAndPATHs;
937
  }
938
  } catch(Exception $e) { // Exception("Post metadata is corrupt (No attachment URL)") or Exception("Image files are missing.")
939
+ $crtItemHandler->incrementRetries(1, ($e->getCode() < 0 ? $e->getCode() : ShortPixelAPI::ERR_FILE_NOT_FOUND), $e->getMessage());
940
  if(! $this->prioQ->remove($crtItemHandler->getQueuedId()) ){
941
  $this->advanceBulk($crtItemHandler->getId());
942
  $res['searching'] = true;
1252
  //do_action('shortpixel-optimize-now', $imageId);
1253
 
1254
  }
1255
+
1256
+ public function checkStatus() {
1257
+ $itemHandler = new ShortPixelMetaFacade($_GET['image_id']);
1258
+ $meta = $itemHandler->getMeta();
1259
+ die(json_encode(array("Status" => $meta->getStatus(), "Message" => $meta->getMessage())));
1260
+ }
1261
+
1262
+ //custom hook
1263
  public function optimizeNowHook($imageId, $manual = false) {
1264
  if($this->isProcessable($imageId)) {
1265
  $this->prioQ->push($imageId);
1273
  $ret = array("Status" => ShortPixelAPI::STATUS_SUCCESS, "Message" => "");
1274
  } catch(Exception $e) { // Exception("Post metadata is corrupt (No attachment URL)")
1275
  $itemHandler->getMeta();
1276
+ $errCode = $e->getCode() < 0 ? $e->getCode() : ShortPixelAPI::ERR_FILE_NOT_FOUND;
1277
+ $itemHandler->setError($errCode, $e->getMessage());
1278
  $ret = array("Status" => ShortPixelAPI::STATUS_FAIL, "Message" => $e->getMessage());
1279
  }
1280
  }
1339
 
1340
  public function getBackupFolderAny($file, $thumbs) {
1341
  $ret = $this->getBackupFolder($file);
1342
+ //if(!$ret && !file_exists($file) && isset($thumbs)) {
1343
+ if(!$ret && isset($thumbs)) {
1344
  //try with the thumbnails
1345
  foreach($thumbs as $size) {
1346
  $backup = $this->getBackupFolder(trailingslashit(dirname($file)) . $size['file']);
1368
  return true;
1369
  }
1370
 
1371
+ //TODO specific to Media Lib., move accordingly
1372
  protected function doRestore($attachmentID, $meta = null) {
1373
  $file = $origFile = get_attached_file($attachmentID);
1374
  if(!$meta) {
1392
 
1393
  //first check if the file is readable by the current user - otherwise it will be unaccessible for the web browser
1394
  // - collect the thumbs paths in the process
1395
+ $bkCount = 0;
1396
+ if(isset($meta["ShortPixel"]['ErrCode'])) {
1397
+ $lastStatus = $this->_settings->bulkLastStatus;
1398
+ if($lastStatus['ImageID'] == $attachmentID) {
1399
+ $this->_settings->bulkLastStatus = null;
1400
+ }
1401
+ } else {
1402
+ if(file_exists($bkFile)) {
1403
+ if(!$this->setFilePerms($bkFile) || (file_exists($file) && !$this->setFilePerms($file)) ) {
 
 
 
 
 
 
1404
  return false;
1405
  }
1406
  $bkCount++;
1407
+ $main = true;
1408
+ }
1409
+ $thumbsPaths = array();
1410
+ if($bkFolder && !empty($meta['file']) && count($sizes) ) {
1411
+ foreach($sizes as $size => $imageData) {
1412
+ $dest = $pathInfo['dirname'] . '/' . $imageData['file'];
1413
+ $source = trailingslashit($bkFolder) . $imageData['file'];
1414
+ if(!file_exists($source)) continue; // if thumbs were not optimized, then the backups will not be there.
1415
+ if(!$this->setFilePerms($source) || (file_exists($dest) && !$this->setFilePerms($dest))) {
1416
+ return false;
1417
+ }
1418
+ $bkCount++;
1419
+ $thumbsPaths[$source] = $dest;
1420
+ }
1421
+ }
1422
+ if(!$bkCount) {
1423
+ return false;
1424
  }
1425
  }
1426
+ //either backups exist, or it was error so it's normal no backup is present
1427
+ try {
1428
+ $width = false;
1429
+ if($bkCount) { // backups, if exist
1430
+ //main file
 
 
1431
  if($main) {
1432
  $this->renameWithRetina($bkFile, $file);
1433
  }
1434
  //getSize to update meta if image was resized by ShortPixel
 
1435
  if(file_exists($file)) {
1436
  $size = getimagesize($file);
1437
  $width = $size[0];
1442
  foreach($thumbsPaths as $source => $destination) {
1443
  $this->renameWithRetina($source, $destination);
1444
  }
1445
+ }
1446
+
1447
+ $duplicates = ShortPixelMetaFacade::getWPMLDuplicates($attachmentID);
1448
+ foreach($duplicates as $ID) {
1449
+ $crtMeta = $attachmentID == $ID ? $meta : wp_get_attachment_metadata($ID);
1450
+ if( isset($crtMeta["ShortPixelImprovement"]) && is_numeric($crtMeta["ShortPixelImprovement"])
1451
+ && 0 + $crtMeta["ShortPixelImprovement"] < 5 && $this->_settings->under5Percent > 0) {
1452
+ $this->_settings->under5Percent = $this->_settings->under5Percent - 1; // - (isset($crtMeta["ShortPixel"]["thumbsOpt"]) ? $crtMeta["ShortPixel"]["thumbsOpt"] : 0);
1453
+ }
1454
+ unset($crtMeta["ShortPixelImprovement"]);
1455
+ unset($crtMeta['ShortPixel']);
1456
+ unset($crtMeta['ShortPixelPng2Jpg']);
1457
+ if($width && $height) {
1458
+ $crtMeta['width'] = $width;
1459
+ $crtMeta['height'] = $height;
1460
+ }
1461
+ if($png2jpgMain) {
1462
+ $crtMeta['file'] = trailingslashit(dirname($crtMeta['file'])) . ShortPixelAPI::MB_basename($file);
1463
+ update_attached_file($ID, $crtMeta['file']);
1464
+ if($png2jpgSizes) {
1465
+ $crtMeta['sizes'] = $png2jpgSizes;
1466
+ } else {
1467
+ //this was an image converted on upload, regenerate the thumbs using the PNG main image BUT deactivate temporarily the filter!!
1468
+ remove_filter( 'wp_generate_attachment_metadata', 'shortPixelHandleImageUploadHook');
1469
+ $crtMeta = wp_generate_attachment_metadata($ID, $png2jpgMain);
1470
+ add_filter( 'wp_generate_attachment_metadata', 'shortPixelHandleImageUploadHook', 10, 2 );
1471
  }
 
1472
  }
1473
+ wp_update_attachment_metadata($ID, $crtMeta);
 
 
 
 
 
 
1474
  }
1475
+ unset($meta["ShortPixelImprovement"]);
1476
+ unset($meta['ShortPixel']);
1477
+ unset($meta['ShortPixelPng2Jpg']);
1478
+
1479
+ } catch(Exception $e) {
1480
+ //what to do, what to do?
1481
  return false;
1482
  }
 
1483
  return $meta;
1484
  }
1485
 
1555
  $ret = array("Status" => ShortPixelAPI::STATUS_SUCCESS, "Message" => "");
1556
  } catch(Exception $e) { // Exception("Post metadata is corrupt (No attachment URL)") or Exception("Image files are missing.")
1557
  $meta['ShortPixelImprovement'] = $e->getMessage();
1558
+ $meta['ShortPixel']['ErrCode'] = $e->getCode() < 0 ? $e->getCode() : ShortPixelAPI::STATUS_FAIL;
1559
  unset($meta['ShortPixel']['WaitingProcessing']);
1560
  wp_update_attachment_metadata($ID, $meta);
1561
  $ret = array("Status" => ShortPixelAPI::STATUS_FAIL, "Message" => $e->getMessage());
1583
  $ret = array("Status" => ShortPixelAPI::STATUS_SUCCESS, "message" => "");
1584
  } catch(Exception $e) { // Exception("Post metadata is corrupt (No attachment URL)") or Exception("Image files are missing.")
1585
  $meta['ShortPixelImprovement'] = $e->getMessage();
1586
+ $meta['ShortPixel']['ErrCode'] = $e->getCode() < 0 ? $e->getCode() : ShortPixelAPI::STATUS_FAIL;
1587
  unset($meta['ShortPixel']['WaitingProcessing']);
1588
  wp_update_attachment_metadata($ID, $meta);
1589
  $ret = array("Status" => ShortPixelAPI::STATUS_FAIL, "Message" => $e->getMessage());
1654
  {
1655
  return $this->_settings->currentStats;
1656
  } else {
1657
+ $imageCount = WpShortPixelMediaLbraryAdapter::countAllProcessableFiles($this->_settings);
1658
  $quotaData['time'] = time();
1659
  $quotaData['optimizePdfs'] = $this->_settings->optimizePdfs;
1660
  //$quotaData['quotaData'] = $quotaData;
1726
  if ( isset($_GET['noheader']) ) {
1727
  require_once(ABSPATH . 'wp-admin/admin-header.php');
1728
  }
1729
+ $this->outputHSBeacon();
1730
  ?>
1731
+ <div class="wrap shortpixel-other-media">
1732
  <h2>
1733
  <div style="float:right;">
1734
  <a href="upload.php?page=wp-short-pixel-custom&refresh=1" id="refresh" class="button button-primary" title="<?php _e('Refresh custom folders content','shortpixel-image-optimiser');?>">
1901
  } elseif ($minutes > 240) {
1902
  $timeEst = "~ " . round($minutes / 60) . " hours left";
1903
  } elseif ($minutes > 60) {
1904
+ $hours = round($minutes / 60);
1905
+ $minutes = round(max(0, $minutes - $hours * 60) / 10) * 10;
1906
+ $timeEst = "~ " . $hours . " hours " . ($minutes > 0 ? $minutes . " min." : "") . " left";
1907
  } elseif ($minutes > 20) {
1908
  $timeEst = "~ " . round($minutes / 10) * 10 . " minutes left";
1909
  } else {
2078
  //'m1' => 4625, 'm2' => 4592, 'm3' => 4711, 'm4' => 4121, 'filesTodo' => 51143, 'estimated' => 'true'
2079
  //'m1' => 4625, 'm2' => 4592, 'm3' => 4711, 'm4' => 4121, 'filesTodo' => 41143, 'estimated' => 'true'
2080
  //'m1' => 7625, 'm2' => 6592, 'm3' => 6711, 'm4' => 5121, 'filesTodo' => 41143, 'estimated' => 'true'
2081
+ //'m1' => 1010, 'm2' => 4875, 'm3' => 2863, 'm4' => 1026, 'filesTodo' => 239595, 'estimated' => 'true',
2082
  'm1' => $stats['totalM1'],
2083
  'm2' => $stats['totalM2'],
2084
  'm3' => $stats['totalM3'],
2434
  if($validate) {
2435
  $args['body']['DomainCheck'] = get_site_url();
2436
  $args['body']['Info'] = get_bloginfo('version') . '|' . phpversion();
2437
+ $imageCount = WpShortPixelMediaLbraryAdapter::countAllProcessableFiles($this->_settings);
2438
  $args['body']['ImagesCount'] = $imageCount['mainFiles'];
2439
  $args['body']['ThumbsCount'] = $imageCount['totalFiles'] - $imageCount['mainFiles'];
2440
  $argsStr .= "&DomainCheck={$args['body']['DomainCheck']}&Info={$args['body']['Info']}&ImagesCount={$imageCount['mainFiles']}&ThumbsCount={$args['body']['ThumbsCount']}";
2573
  if( 'wp-shortPixel' == $column_name ) {
2574
 
2575
  if(!$this->isProcessable($id)) {
2576
+ $renderData['status'] = 'n/a';
2577
  $this->view->renderCustomColumn($id, $renderData, $extended);
2578
  return;
2579
  }
2669
  $renderData['message'] = __('Image does not exist','shortpixel-image-optimiser');
2670
  }
2671
  elseif(isset($data['ShortPixel']['WaitingProcessing'])) {
2672
+ $renderData['status'] = $quotaExceeded ? 'quotaExceeded' : 'waiting';
2673
  $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');
2674
  if($this->_settings->autoMediaLibrary && !$quotaExceeded && ($id > $this->prioQ->getFlagBulkId() || !$this->prioQ->bulkRunning())) {
2675
  $this->prioQ->unskip($id);
2982
 
2983
  public function getOtherCompressionTypes($compressionType = false) {
2984
  return array_values(array_diff(array(0, 1, 2), array(0 + $compressionType)));
 
 
 
 
2985
  }
2986
+
2987
+ function outputHSBeacon() {
2988
+ ?><script>
2989
+ !function(e,o,n){ window.HSCW=o,window.HS=n,n.beacon=n.beacon||{};var t=n.beacon;t.userConfig={
2990
+ color: "#1CBECB",
2991
+ icon: "question",
2992
+ instructions: "Send ShortPixel a message",
2993
+ topArticles: true,
2994
+ poweredBy: false,
2995
+ showContactFields: true,
2996
+ showName: false,
2997
+ showSubject: true,
2998
+ translation: {
2999
+ searchLabel: "What can ShortPixel help you with?",
3000
+ contactSuccessDescription: "Thanks for reaching out! Someone from our team will get back to you in 24h max."
3001
+ }
3002
+
3003
+ },t.readyQueue=[],t.config=function(e){this.userConfig=e},t.ready=function(e){this.readyQueue.push(e)},o.config={docs:{enabled:!0,baseUrl:"//shortpixel.helpscoutdocs.com/"},contact:{enabled:!0,formId:"278a7825-fce0-11e7-b466-0ec85169275a"}};var r=e.getElementsByTagName("script")[0],c=e.createElement("script");
3004
+ c.type="text/javascript",c.async=!0,c.src="https://djtflbt20bdde.cloudfront.net/",r.parentNode.insertBefore(c,r);
3005
+ }(document,window.HSCW||{},window.HS||{});
3006
+
3007
+ window.HS.beacon.ready(function(){
3008
+ HS.beacon.identify({
3009
+ email: "<?php $u = wp_get_current_user(); echo($u->user_email); ?>",
3010
+ apiKey: "<?php echo($this->getApiKey());?>"
3011
+ });
3012
+ });
3013
+ </script><?php
3014
+ }
3015
+
3016
+
3017
+ /* public function getEncryptedData() {
3018
+ return base64_encode(self::encrypt($this->getApiKey() . "|" . get_site_url(), "sh0r+Pix3l8im1N3r"));
3019
+ }
3020
+ */
3021
 
3022
  /**
3023
  * Returns an encrypted & utf8-encoded
class/wp-shortpixel-settings.php CHANGED
@@ -15,79 +15,79 @@ class WPShortPixelSettings {
15
 
16
  private static $_optionsMap = array(
17
  //This one is accessed also directly via get_option
18
- 'frontBootstrap' => array('key' => 'wp-short-pixel-front-bootstrap', 'default' => null), //set to 1 when need the plugin active for logged in user in the front-end
19
- 'lastBackAction' => array('key' => 'wp-short-pixel-last-back-action', 'default' => null), //when less than 10 min. passed from this timestamp, the front-bootstrap is ineffective.
20
 
21
  //optimization options
22
- 'apiKey' => array('key' => 'wp-short-pixel-apiKey', 'default' => ''),
23
- 'verifiedKey' => array('key' => 'wp-short-pixel-verifiedKey', 'default' => false),
24
- 'compressionType' => array('key' => 'wp-short-pixel-compression', 'default' => 1),
25
- 'processThumbnails' => array('key' => 'wp-short-process_thumbnails', 'default' => null),
26
- 'keepExif' => array('key' => 'wp-short-pixel-keep-exif', 'default' => 0),
27
- 'CMYKtoRGBconversion' => array('key' => 'wp-short-pixel_cmyk2rgb', 'default' => 1),
28
- 'createWebp' => array('key' => 'wp-short-create-webp', 'default' => null),
29
- 'createWebpMarkup' => array('key' => 'wp-short-pixel-create-webp-markup', 'default' => null),
30
- 'optimizeRetina' => array('key' => 'wp-short-pixel-optimize-retina', 'default' => 1),
31
- 'optimizeUnlisted' => array('key' => 'wp-short-pixel-optimize-unlisted', 'default' => 0),
32
- 'backupImages' => array('key' => 'wp-short-backup_images', 'default' => 1),
33
- 'resizeImages' => array('key' => 'wp-short-pixel-resize-images', 'default' => false),
34
- 'resizeType' => array('key' => 'wp-short-pixel-resize-type', 'default' => null),
35
- 'resizeWidth' => array('key' => 'wp-short-pixel-resize-width', 'default' => 0),
36
- 'resizeHeight' => array('key' => 'wp-short-pixel-resize-height', 'default' => 0),
37
- 'siteAuthUser' => array('key' => 'wp-short-pixel-site-auth-user', 'default' => null),
38
- 'siteAuthPass' => array('key' => 'wp-short-pixel-site-auth-pass', 'default' => null),
39
- 'autoMediaLibrary' => array('key' => 'wp-short-pixel-auto-media-library', 'default' => 1),
40
- 'optimizePdfs' => array('key' => 'wp-short-pixel-optimize-pdfs', 'default' => 1),
41
- 'excludePatterns' => array('key' => 'wp-short-pixel-exclude-patterns', 'default' => array()),
42
- 'png2jpg' => array('key' => 'wp-short-pixel-png2jpg', 'default' => 0),
43
 
44
  //optimize other images than the ones in Media Library
45
- 'includeNextGen' => array('key' => 'wp-short-pixel-include-next-gen', 'default' => null),
46
- 'hasCustomFolders' => array('key' => 'wp-short-pixel-has-custom-folders', 'default' => false),
47
- 'customBulkPaused' => array('key' => 'wp-short-pixel-custom-bulk-paused', 'default' => false),
48
 
49
  //stats, notices, etc.
50
- 'currentStats' => array('key' => 'wp-short-pixel-current-total-files', 'default' => null),
51
- 'fileCount' => array('key' => 'wp-short-pixel-fileCount', 'default' => 0),
52
- 'thumbsCount' => array('key' => 'wp-short-pixel-thumbnail-count', 'default' => 0),
53
- 'under5Percent' => array('key' => 'wp-short-pixel-files-under-5-percent', 'default' => 0),
54
- 'savedSpace' => array('key' => 'wp-short-pixel-savedSpace', 'default' => 0),
55
- 'averageCompression' => array('key' => 'wp-short-pixel-averageCompression', 'default' => null),
56
- 'apiRetries' => array('key' => 'wp-short-pixel-api-retries', 'default' => 0),
57
- 'totalOptimized' => array('key' => 'wp-short-pixel-total-optimized', 'default' => 0),
58
- 'totalOriginal' => array('key' => 'wp-short-pixel-total-original', 'default' => 0),
59
- 'quotaExceeded' => array('key' => 'wp-short-pixel-quota-exceeded', 'default' => 0),
60
- 'httpProto' => array('key' => 'wp-short-pixel-protocol', 'default' => 'https'),
61
- 'downloadProto' => array('key' => 'wp-short-pixel-download-protocol', 'default' => null),
62
- 'mediaAlert' => array('key' => 'wp-short-pixel-media-alert', 'default' => null),
63
- 'dismissedNotices' => array('key' => 'wp-short-pixel-dismissed-notices', 'default' => array()),
64
- 'activationDate' => array('key' => 'wp-short-pixel-activation-date', 'default' => null),
65
- 'activationNotice' => array('key' => 'wp-short-pixel-activation-notice', 'default' => null),
66
- 'mediaLibraryViewMode' => array('key' => 'wp-short-pixel-view-mode', 'default' => null),
67
- 'redirectedSettings' => array('key' => 'wp-short-pixel-redirected-settings', 'default' => null),
68
- 'convertedPng2Jpg' => array('key' => 'wp-short-pixel-converted-png2jpg', 'default' => array()),
69
 
70
  //bulk state machine
71
- 'bulkType' => array('key' => 'wp-short-pixel-bulk-type', 'default' => null),
72
- 'bulkLastStatus' => array('key' => 'wp-short-pixel-bulk-last-status', 'default' => null),
73
- 'startBulkId' => array('key' => 'wp-short-pixel-query-id-start', 'default' => 0),
74
- 'stopBulkId' => array('key' => 'wp-short-pixel-query-id-stop', 'default' => 0),
75
- 'bulkCount' => array('key' => 'wp-short-pixel-bulk-count', 'default' => 0),
76
- 'bulkPreviousPercent' => array('key' => 'wp-short-pixel-bulk-previous-percent', 'default' => 0),
77
- 'bulkCurrentlyProcessed' => array('key' => 'wp-short-pixel-bulk-processed-items', 'default' => 0),
78
- 'bulkAlreadyDoneCount' => array('key' => 'wp-short-pixel-bulk-done-count', 'default' => 0),
79
- 'lastBulkStartTime' => array('key' => 'wp-short-pixel-last-bulk-start-time', 'default' => 0),
80
- 'lastBulkSuccessTime' => array('key' => 'wp-short-pixel-last-bulk-success-time', 'default' => 0),
81
- 'bulkRunningTime' => array('key' => 'wp-short-pixel-bulk-running-time', 'default' => 0),
82
- 'cancelPointer' => array('key' => 'wp-short-pixel-cancel-pointer', 'default' => 0),
83
- 'skipToCustom' => array('key' => 'wp-short-pixel-skip-to-custom', 'default' => null),
84
- 'bulkEverRan' => array('key' => 'wp-short-pixel-bulk-ever-ran', 'default' => false),
85
- 'flagId' => array('key' => 'wp-short-pixel-flag-id', 'default' => 0),
86
- 'failedImages' => array('key' => 'wp-short-pixel-failed-imgs', 'default' => 0),
87
- 'bulkProcessingStatus' => array('key' => 'bulkProcessingStatus', 'default' => null),
88
 
89
  //'priorityQueue' => array('key' => 'wp-short-pixel-priorityQueue', 'default' => array()),
90
- 'prioritySkip' => array('key' => 'wp-short-pixel-prioritySkip', 'default' => array()),
91
 
92
  //'' => array('key' => 'wp-short-pixel-', 'default' => null),
93
  );
@@ -191,6 +191,7 @@ class WPShortPixelSettings {
191
  } else {
192
  wp_cache_delete( $key, 'options' );
193
  }
 
194
  add_option($key, $val, '', 'no');
195
 
196
  // still not? try the DB way...
@@ -213,6 +214,7 @@ class WPShortPixelSettings {
213
  if($val != get_option($key)) {
214
  //tough luck, gonna use the bomb...
215
  wp_cache_flush();
 
216
  add_option($key, $val, '', 'no');
217
  }
218
  }
15
 
16
  private static $_optionsMap = array(
17
  //This one is accessed also directly via get_option
18
+ 'frontBootstrap' => array('key' => 'wp-short-pixel-front-bootstrap', 'default' => null, 'group' => 'options'), //set to 1 when need the plugin active for logged in user in the front-end
19
+ 'lastBackAction' => array('key' => 'wp-short-pixel-last-back-action', 'default' => null, 'group' => 'state'), //when less than 10 min. passed from this timestamp, the front-bootstrap is ineffective.
20
 
21
  //optimization options
22
+ 'apiKey' => array('key' => 'wp-short-pixel-apiKey', 'default' => '', 'group' => 'options'),
23
+ 'verifiedKey' => array('key' => 'wp-short-pixel-verifiedKey', 'default' => false, 'group' => 'options'),
24
+ 'compressionType' => array('key' => 'wp-short-pixel-compression', 'default' => 1, 'group' => 'options'),
25
+ 'processThumbnails' => array('key' => 'wp-short-process_thumbnails', 'default' => null, 'group' => 'options'),
26
+ 'keepExif' => array('key' => 'wp-short-pixel-keep-exif', 'default' => 0, 'group' => 'options'),
27
+ 'CMYKtoRGBconversion' => array('key' => 'wp-short-pixel_cmyk2rgb', 'default' => 1, 'group' => 'options'),
28
+ 'createWebp' => array('key' => 'wp-short-create-webp', 'default' => null, 'group' => 'options'),
29
+ 'createWebpMarkup' => array('key' => 'wp-short-pixel-create-webp-markup', 'default' => null, 'group' => 'options'),
30
+ 'optimizeRetina' => array('key' => 'wp-short-pixel-optimize-retina', 'default' => 1, 'group' => 'options'),
31
+ 'optimizeUnlisted' => array('key' => 'wp-short-pixel-optimize-unlisted', 'default' => 0, 'group' => 'options'),
32
+ 'backupImages' => array('key' => 'wp-short-backup_images', 'default' => 1, 'group' => 'options'),
33
+ 'resizeImages' => array('key' => 'wp-short-pixel-resize-images', 'default' => false, 'group' => 'options'),
34
+ 'resizeType' => array('key' => 'wp-short-pixel-resize-type', 'default' => null, 'group' => 'options'),
35
+ 'resizeWidth' => array('key' => 'wp-short-pixel-resize-width', 'default' => 0, 'group' => 'options'),
36
+ 'resizeHeight' => array('key' => 'wp-short-pixel-resize-height', 'default' => 0, 'group' => 'options'),
37
+ 'siteAuthUser' => array('key' => 'wp-short-pixel-site-auth-user', 'default' => null, 'group' => 'options'),
38
+ 'siteAuthPass' => array('key' => 'wp-short-pixel-site-auth-pass', 'default' => null, 'group' => 'options'),
39
+ 'autoMediaLibrary' => array('key' => 'wp-short-pixel-auto-media-library', 'default' => 1, 'group' => 'options'),
40
+ 'optimizePdfs' => array('key' => 'wp-short-pixel-optimize-pdfs', 'default' => 1, 'group' => 'options'),
41
+ 'excludePatterns' => array('key' => 'wp-short-pixel-exclude-patterns', 'default' => array(), 'group' => 'options'),
42
+ 'png2jpg' => array('key' => 'wp-short-pixel-png2jpg', 'default' => 0, 'group' => 'options'),
43
 
44
  //optimize other images than the ones in Media Library
45
+ 'includeNextGen' => array('key' => 'wp-short-pixel-include-next-gen', 'default' => null, 'group' => 'options'),
46
+ 'hasCustomFolders' => array('key' => 'wp-short-pixel-has-custom-folders', 'default' => false, 'group' => 'options'),
47
+ 'customBulkPaused' => array('key' => 'wp-short-pixel-custom-bulk-paused', 'default' => false, 'group' => 'options'),
48
 
49
  //stats, notices, etc.
50
+ 'currentStats' => array('key' => 'wp-short-pixel-current-total-files', 'default' => null, 'group' => 'state'),
51
+ 'fileCount' => array('key' => 'wp-short-pixel-fileCount', 'default' => 0, 'group' => 'state'),
52
+ 'thumbsCount' => array('key' => 'wp-short-pixel-thumbnail-count', 'default' => 0, 'group' => 'state'),
53
+ 'under5Percent' => array('key' => 'wp-short-pixel-files-under-5-percent', 'default' => 0, 'group' => 'state'),
54
+ 'savedSpace' => array('key' => 'wp-short-pixel-savedSpace', 'default' => 0, 'group' => 'state'),
55
+ 'averageCompression' => array('key' => 'wp-short-pixel-averageCompression', 'default' => null, 'group' => 'state'),
56
+ 'apiRetries' => array('key' => 'wp-short-pixel-api-retries', 'default' => 0, 'group' => 'state'),
57
+ 'totalOptimized' => array('key' => 'wp-short-pixel-total-optimized', 'default' => 0, 'group' => 'state'),
58
+ 'totalOriginal' => array('key' => 'wp-short-pixel-total-original', 'default' => 0, 'group' => 'state'),
59
+ 'quotaExceeded' => array('key' => 'wp-short-pixel-quota-exceeded', 'default' => 0, 'group' => 'state'),
60
+ 'httpProto' => array('key' => 'wp-short-pixel-protocol', 'default' => 'https', 'group' => 'state'),
61
+ 'downloadProto' => array('key' => 'wp-short-pixel-download-protocol', 'default' => null, 'group' => 'state'),
62
+ 'mediaAlert' => array('key' => 'wp-short-pixel-media-alert', 'default' => null, 'group' => 'state'),
63
+ 'dismissedNotices' => array('key' => 'wp-short-pixel-dismissed-notices', 'default' => array(), 'group' => 'state'),
64
+ 'activationDate' => array('key' => 'wp-short-pixel-activation-date', 'default' => null, 'group' => 'state'),
65
+ 'activationNotice' => array('key' => 'wp-short-pixel-activation-notice', 'default' => null, 'group' => 'state'),
66
+ 'mediaLibraryViewMode' => array('key' => 'wp-short-pixel-view-mode', 'default' => null, 'group' => 'state'),
67
+ 'redirectedSettings' => array('key' => 'wp-short-pixel-redirected-settings', 'default' => null, 'group' => 'state'),
68
+ 'convertedPng2Jpg' => array('key' => 'wp-short-pixel-converted-png2jpg', 'default' => array(), 'group' => 'state'),
69
 
70
  //bulk state machine
71
+ 'bulkType' => array('key' => 'wp-short-pixel-bulk-type', 'default' => null, 'group' => 'bulk'),
72
+ 'bulkLastStatus' => array('key' => 'wp-short-pixel-bulk-last-status', 'default' => null, 'group' => 'bulk'),
73
+ 'startBulkId' => array('key' => 'wp-short-pixel-query-id-start', 'default' => 0, 'group' => 'bulk'),
74
+ 'stopBulkId' => array('key' => 'wp-short-pixel-query-id-stop', 'default' => 0, 'group' => 'bulk'),
75
+ 'bulkCount' => array('key' => 'wp-short-pixel-bulk-count', 'default' => 0, 'group' => 'bulk'),
76
+ 'bulkPreviousPercent' => array('key' => 'wp-short-pixel-bulk-previous-percent', 'default' => 0, 'group' => 'bulk'),
77
+ 'bulkCurrentlyProcessed' => array('key' => 'wp-short-pixel-bulk-processed-items', 'default' => 0, 'group' => 'bulk'),
78
+ 'bulkAlreadyDoneCount' => array('key' => 'wp-short-pixel-bulk-done-count', 'default' => 0, 'group' => 'bulk'),
79
+ 'lastBulkStartTime' => array('key' => 'wp-short-pixel-last-bulk-start-time', 'default' => 0, 'group' => 'bulk'),
80
+ 'lastBulkSuccessTime' => array('key' => 'wp-short-pixel-last-bulk-success-time', 'default' => 0, 'group' => 'bulk'),
81
+ 'bulkRunningTime' => array('key' => 'wp-short-pixel-bulk-running-time', 'default' => 0, 'group' => 'bulk'),
82
+ 'cancelPointer' => array('key' => 'wp-short-pixel-cancel-pointer', 'default' => 0, 'group' => 'bulk'),
83
+ 'skipToCustom' => array('key' => 'wp-short-pixel-skip-to-custom', 'default' => null, 'group' => 'bulk'),
84
+ 'bulkEverRan' => array('key' => 'wp-short-pixel-bulk-ever-ran', 'default' => false, 'group' => 'bulk'),
85
+ 'flagId' => array('key' => 'wp-short-pixel-flag-id', 'default' => 0, 'group' => 'bulk'),
86
+ 'failedImages' => array('key' => 'wp-short-pixel-failed-imgs', 'default' => 0, 'group' => 'bulk'),
87
+ 'bulkProcessingStatus' => array('key' => 'bulkProcessingStatus', 'default' => null, 'group' => 'bulk'),
88
 
89
  //'priorityQueue' => array('key' => 'wp-short-pixel-priorityQueue', 'default' => array()),
90
+ 'prioritySkip' => array('key' => 'wp-short-pixel-prioritySkip', 'default' => array(), 'group' => 'state'),
91
 
92
  //'' => array('key' => 'wp-short-pixel-', 'default' => null),
93
  );
191
  } else {
192
  wp_cache_delete( $key, 'options' );
193
  }
194
+ delete_option($key);
195
  add_option($key, $val, '', 'no');
196
 
197
  // still not? try the DB way...
214
  if($val != get_option($key)) {
215
  //tough luck, gonna use the bomb...
216
  wp_cache_flush();
217
+ delete_option($key);
218
  add_option($key, $val, '', 'no');
219
  }
220
  }
readme.txt CHANGED
@@ -4,7 +4,7 @@ Tags: compress, image, compression, optimize, image optimizer, image optimiser,
4
  Requires at least: 3.2.0
5
  Tested up to: 4.9
6
  Requires PHP: 5.2
7
- Stable tag: 4.8.9
8
  License: GPLv2 or later
9
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
10
 
@@ -15,17 +15,17 @@ Speed up your website and boost your SEO by compressing old & new images and PDF
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.
19
 
20
  **Ready for a quick DEMO? <a href="https://addendio.com/try-plugin/?slug=shortpixel-image-optimiser" target="_blank">Test here.</a>**
21
 
22
- This plugin uses minimal resources and works well with any shared, cloud, VPS or dedicated web hosting. It can optimize any image you have on your website even the images that aren't listed in Media Library like those in galleries like <a href="https://wordpress.org/plugins/nextgen-gallery/" target="_blank">NextGEN</a>, <a href="https://wordpress.org/plugins/modula-best-grid-gallery/" target="_blank">Modula</a> or added directly via FTP!
23
 
24
  Both lossy and lossless image compression is available for the most common image types (JPG, PNG, GIF and WebP) plus PDF files.
25
  We also offer **glossy** JPEG compression which is a very high quality lossy optimization algorithm. Specially designed for photographers!
26
  Optimized images mean better user experience, better PageSpeed Insights or GTmetrix results, better Google PageRank and more visitors.
27
 
28
- Make an instant <a rel="friend" href="http://shortpixel.com/image-compression-test" target="_blank">image compression test</a> on your site or <a rel="friend" href="http://shortpixel.com/online-image-compression" target="_blank">compress some images</a> to make sure they are to your liking.
29
 
30
  **Why is ShortPixel the best choice when it comes to image optimization or PDF compression?**
31
 
@@ -33,16 +33,16 @@ Make an instant <a rel="friend" href="http://shortpixel.com/image-compression-te
33
  * compress JPG, PNG, GIF (still or animated) images and also PDF documents
34
  * option to automatically convert PNG to JPG if that will result in smaller images. Ideal for large images in PNG format.
35
  * no file size limit
36
- * option to freely convert any JPEG, PNG or GIF (even animated ones!) to **WebP** for more Google love. <a rel="friend" href="http://blog.shortpixel.com/how-webp-images-can-speed-up-your-site/" target="_blank">How to enable WebP?</a>
37
  * option to include the generated WebP images into the front-end pages by using the &lt;picture&gt; tag instead of &lt;img&gt;
38
- * compatible with WP Retina 2x - all **retina images** are automatically compressed. <a rel="friend" href="http://blog.shortpixel.com/how-to-use-optimized-retina-images-on-your-wordpress-site-for-best-user-experience-on-apple-devices/" target="_blank">How to benefit from Retina displays?</a>
39
  * optimize thumbnails as well as featured images
40
  * ability to optimize any image on your site including images in **NextGEN Gallery** and any other image gallery or slider
41
  * featured images can be automatically resized before being optimized with 2 different options. No need for additional plugins like Imsanity
42
  * CMYK to RGB conversion
43
  * **24h <a href="https://wordpress.org/support/plugin/shortpixel-image-optimiser/reviews/?filter=5" target="_blank">stellar support</a>** (24/7) directly from developers.
44
  * easily **test lossy/lossless** versions of the images with a single click in your Media Library
45
- * **great for photographers**: <a rel="friend" href="http://blog.shortpixel.com/how-much-smaller-can-be-images-without-exif-icc/" target="_blank">keep or remove EXIF</a> data from your images, compress images with lossless option
46
  * works well with both HTTPS and HTTP websites
47
  * you can run ShortPixel plugin on **multiple websites** or on a **multisite** with a **single API Key**
48
  * it is **safe to test** and use the plugin: all the original images can be restored with a click, either one by one or in bulk
@@ -61,7 +61,7 @@ Make an instant <a rel="friend" href="http://shortpixel.com/image-compression-te
61
 
62
  **How much it costs?**
63
  ShortPixel comes with 100 free credits/month and additional credits can be bought with as little as $4.99 for 5,000 image credits.
64
- Check out <a rel="friend" href="https://shortpixel.com/pricing" target="_blank">our prices</a>.
65
 
66
  > **Testimonials:**
67
  > ★★★★★ **A Super Plugin works very well 62% reduction overall.** [robertvarns](https://wordpress.org/support/topic/a-super-plugin-works-very-well-62-reduction-overall/)
@@ -100,7 +100,7 @@ Let's get ShortPixel plugin running on your WordPress website:
100
 
101
  = How does ShortPixel compare to other image optimisation plugins (e.g Smush, Imagify, TinyPNG, Kraken, EWWW)? =
102
  ShortPixel has better compression rates, more features, supports backups and has very affordable one-time plans.
103
- If you are serious about making an informed decision please take 10 minutes and read this <a rel="friend" href="https://blog.shortpixel.com/wp-image-optimization-wordpress-plugins/">article</a>.
104
 
105
  = Can I use the same API Key on multiple web sites? =
106
  Yes, you can.
@@ -131,7 +131,7 @@ Let's get ShortPixel plugin running on your WordPress website:
131
 
132
  = Do you have one-time plans? =
133
  Yes we do.
134
- The credits that come with our <a href="https://shortpixel.com/plans" rel="friend">one-time plans</a> never expire. Yummy! :-)
135
 
136
  = What happens to my existing images? =
137
  Your existing images are replaced with the optimized ones.
@@ -175,7 +175,7 @@ Let's get ShortPixel plugin running on your WordPress website:
175
 
176
  = Do I have to pay monthly or one time? =
177
  We have both options available.
178
- One-time credits never expire are a bit more expensive. Check out our prices <a href="https://shortpixel.com/pricing" rel="friend">here</a>
179
 
180
  = When can I cancel a monthly plan? =
181
  Whenever you want.
@@ -228,6 +228,24 @@ The ShortPixel team is here to help. <a href="https://shortpixel.com/contact">Co
228
 
229
  == Changelog ==
230
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
231
  = 4.8.9 =
232
  * On some multisites installed in a subdirectory, the get_home_path() doesn't return the subdirectory, fallback to ABSPATH
233
  * Sometimes images are not PNG even if they have .png extension. Don't try to convert them if imagecreatefrompng returns false.
4
  Requires at least: 3.2.0
5
  Tested up to: 4.9
6
  Requires PHP: 5.2
7
+ Stable tag: 4.8.10
8
  License: GPLv2 or later
9
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
10
 
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 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.
19
 
20
  **Ready for a quick DEMO? <a href="https://addendio.com/try-plugin/?slug=shortpixel-image-optimiser" target="_blank">Test here.</a>**
21
 
22
+ Short Pixel uses minimal resources and works well with any shared, cloud, VPS or dedicated web hosting. It can optimize any image you have on your website even the images that aren't listed in Media Library like those in galleries like <a href="https://wordpress.org/plugins/nextgen-gallery/" target="_blank">NextGEN</a>, <a href="https://wordpress.org/plugins/modula-best-grid-gallery/" target="_blank">Modula</a> or added directly via FTP!
23
 
24
  Both lossy and lossless image compression is available for the most common image types (JPG, PNG, GIF and WebP) plus PDF files.
25
  We also offer **glossy** JPEG compression which is a very high quality lossy optimization algorithm. Specially designed for photographers!
26
  Optimized images mean better user experience, better PageSpeed Insights or GTmetrix results, better Google PageRank and more visitors.
27
 
28
+ Make an instant <a href="http://shortpixel.com/image-compression-test" target="_blank">image compression test</a> on your site or <a href="http://shortpixel.com/online-image-compression" target="_blank">compress some images</a> to make sure they are to your liking.
29
 
30
  **Why is ShortPixel the best choice when it comes to image optimization or PDF compression?**
31
 
33
  * compress JPG, PNG, GIF (still or animated) images and also PDF documents
34
  * option to automatically convert PNG to JPG if that will result in smaller images. Ideal for large images in PNG format.
35
  * no file size limit
36
+ * option to freely convert any JPEG, PNG or GIF (even animated ones!) to **WebP** for more Google love. <a href="http://blog.shortpixel.com/how-webp-images-can-speed-up-your-site/" target="_blank">How to enable WebP?</a>
37
  * option to include the generated WebP images into the front-end pages by using the &lt;picture&gt; tag instead of &lt;img&gt;
38
+ * compatible with WP Retina 2x - all **retina images** are automatically compressed. <a href="http://blog.shortpixel.com/how-to-use-optimized-retina-images-on-your-wordpress-site-for-best-user-experience-on-apple-devices/" target="_blank">How to benefit from Retina displays?</a>
39
  * optimize thumbnails as well as featured images
40
  * ability to optimize any image on your site including images in **NextGEN Gallery** and any other image gallery or slider
41
  * featured images can be automatically resized before being optimized with 2 different options. No need for additional plugins like Imsanity
42
  * CMYK to RGB conversion
43
  * **24h <a href="https://wordpress.org/support/plugin/shortpixel-image-optimiser/reviews/?filter=5" target="_blank">stellar support</a>** (24/7) directly from developers.
44
  * easily **test lossy/lossless** versions of the images with a single click in your Media Library
45
+ * **great for photographers**: <a href="http://blog.shortpixel.com/how-much-smaller-can-be-images-without-exif-icc/" target="_blank">keep or remove EXIF</a> data from your images, compress images with lossless option
46
  * works well with both HTTPS and HTTP websites
47
  * you can run ShortPixel plugin on **multiple websites** or on a **multisite** with a **single API Key**
48
  * it is **safe to test** and use the plugin: all the original images can be restored with a click, either one by one or in bulk
61
 
62
  **How much it costs?**
63
  ShortPixel comes with 100 free credits/month and additional credits can be bought with as little as $4.99 for 5,000 image credits.
64
+ Check out <a href="https://shortpixel.com/pricing" target="_blank">our prices</a>.
65
 
66
  > **Testimonials:**
67
  > ★★★★★ **A Super Plugin works very well 62% reduction overall.** [robertvarns](https://wordpress.org/support/topic/a-super-plugin-works-very-well-62-reduction-overall/)
100
 
101
  = How does ShortPixel compare to other image optimisation plugins (e.g Smush, Imagify, TinyPNG, Kraken, EWWW)? =
102
  ShortPixel has better compression rates, more features, supports backups and has very affordable one-time plans.
103
+ If you are serious about making an informed decision please take 10 minutes and read this <a href="https://blog.shortpixel.com/wp-image-optimization-wordpress-plugins/">article</a>.
104
 
105
  = Can I use the same API Key on multiple web sites? =
106
  Yes, you can.
131
 
132
  = Do you have one-time plans? =
133
  Yes we do.
134
+ The credits that come with our <a href="https://shortpixel.com/plans" >one-time plans</a> never expire. Yummy! :-)
135
 
136
  = What happens to my existing images? =
137
  Your existing images are replaced with the optimized ones.
175
 
176
  = Do I have to pay monthly or one time? =
177
  We have both options available.
178
+ One-time credits never expire are a bit more expensive. Check out our prices <a href="https://shortpixel.com/pricing" >here</a>
179
 
180
  = When can I cancel a monthly plan? =
181
  Whenever you want.
228
 
229
  == Changelog ==
230
 
231
+ = 4.9.0 =
232
+ * inline help beacon
233
+ * fix exclude patterns not working after last update
234
+ * handle situations when not enough memory to convert from PNG to JPG.
235
+ * fix particular situations where there was no 'file' property in the metadata.
236
+ * fix slider optimized percent over the bulk warning box.
237
+ * display the x close link for the bulk warning box.
238
+
239
+ = 4.8.10 =
240
+ * restore compatibility with PHP 5.2.x
241
+ * finding unlisted thumbnails - don't bother if dialog dismissed.
242
+ * force JS initialization after 10 sec. if external error on the document.load thread prevented it.
243
+ * onboarding - small text changes
244
+ * images added from the front-end sometimes have get_attached_file() null when hook called, delay the check and processing in this case, instead of marking as Optimization N/A.
245
+ * compatibility with s3-offload pro plugin
246
+ * fix to time estimate at bulk, which sometimes was displaying x hours and 60 minutes left.
247
+ * confirm popup when deleting backups.
248
+
249
  = 4.8.9 =
250
  * On some multisites installed in a subdirectory, the get_home_path() doesn't return the subdirectory, fallback to ABSPATH
251
  * Sometimes images are not PNG even if they have .png extension. Don't try to convert them if imagecreatefrompng returns false.
res/css/short-pixel.css CHANGED
@@ -145,6 +145,8 @@ div.wrap.short-pixel-bulk-page .bulk-notice-container .bulk-notice-msg.bulk-erro
145
  border: 1px solid #b5914d;
146
  background-color: #ffe996;
147
  margin-right:20px;
 
 
148
  }
149
  div.wrap.short-pixel-bulk-page .bulk-notice-container .bulk-notice-msg.bulk-error.bulk-error-fatal {
150
  border: 1px solid #c32525;
@@ -257,9 +259,6 @@ li.shortpixel-toolbar-processing.shortpixel-alert > a.ab-item > div,
257
  box-shadow: 0 1px 1px 0 rgba(0, 0, 0, 0.1);
258
  padding: 1px 12px;
259
  }
260
- .shortpixel-hide {
261
- display:none;
262
- }
263
  .shortpixel-clearfix {
264
  width:100%;
265
  float:left;
@@ -713,7 +712,8 @@ section#tab-resources p {
713
  top: 0px;
714
  left: -1px;
715
  }
716
- #wpadminbar .shortpixel-toolbar-processing.shortpixel-quota-exceeded .cssload-container{
 
717
  display: none;
718
  }
719
 
145
  border: 1px solid #b5914d;
146
  background-color: #ffe996;
147
  margin-right:20px;
148
+ position: relative;
149
+ z-index: 10;
150
  }
151
  div.wrap.short-pixel-bulk-page .bulk-notice-container .bulk-notice-msg.bulk-error.bulk-error-fatal {
152
  border: 1px solid #c32525;
259
  box-shadow: 0 1px 1px 0 rgba(0, 0, 0, 0.1);
260
  padding: 1px 12px;
261
  }
 
 
 
262
  .shortpixel-clearfix {
263
  width:100%;
264
  float:left;
712
  top: 0px;
713
  left: -1px;
714
  }
715
+ #wpadminbar .shortpixel-toolbar-processing.shortpixel-quota-exceeded .cssload-container,
716
+ #wpadminbar .shortpixel-toolbar-processing.shortpixel-alert .cssload-container{
717
  display: none;
718
  }
719
 
res/css/short-pixel.min.css CHANGED
@@ -1 +1 @@
1
- .sp-dropbtn.button{padding:1px 24px 20px 5px;font-size:20px;cursor:pointer}.sp-dropdown{position:relative;display:inline-block}.sp-dropdown-content{display:none;right:0;position:absolute;background-color:#f9f9f9;min-width:190px;box-shadow:0 8px 16px 0 rgba(0,0,0,0.2);z-index:1}.sp-dropdown-content a{color:black;padding:12px 16px;text-decoration:none;display:block}.sp-dropdown-content a:hover{background-color:#f1f1f1}.sp-dropdown.sp-show .sp-dropdown-content{display:block}div.fb-like{transform:scale(1.3);-ms-transform:scale(1.3);-webkit-transform:scale(1.3);-o-transform:scale(1.3);-moz-transform:scale(1.3);transform-origin:bottom left;-ms-transform-origin:bottom left;-webkit-transform-origin:bottom left;-moz-transform-origin:bottom left;-webkit-transform-origin:bottom left}.wp-core-ui .button.button-alert,.wp-core-ui .button.button-alert:hover{background:#f79797}.wp-core-ui .button.remove-folder-button{min-width:120px}.sp-notice{background:#fff;border-left:4px solid #fff;-webkit-box-shadow:0 1px 1px 0 rgba(0,0,0,.1);box-shadow:0 1px 1px 0 rgba(0,0,0,.1);padding:1px 12px}@media(max-width:1249px){.sp-notice{margin:5px 15px 2px}}.sp-notice-info{border-left-color:#00a0d2}.sp-notice-success{border-left-color:#46b450}li.sp-conflict-plugins-list{line-height:28px;list-style:disc;margin-left:80px}li.sp-conflict-plugins-list a.button{margin-left:10px}div.short-pixel-bulk-page input.dial{font-size:16px!important}div.short-pixel-bulk-page h1{margin-bottom:20px}div.bulk-progress div.sp-h2{margin-top:0;margin-bottom:10px;font-size:23px;font-weight:400;padding:9px 15px 4px 0;line-height:29px}div.bulk-progress-partners{margin-top:20px}div.bulk-progress.bulk-progress-partners a div{display:inline-block;vertical-align:top;line-height:50px;margin-left:30px;font-size:1.2em}div.bulk-progress .bulk-progress-indicator,div.sp-quota-exceeded-alert .bulk-progress-indicator{display:inline-block;text-align:center;padding:0 10px;margin-left:10px;float:left;height:90px;overflow:hidden;border:1px solid #1caecb}div.wrap.short-pixel-bulk-page .bulk-notice-container{margin-top:15px;position:absolute;width:500px}div.wrap.short-pixel-bulk-page .bulk-notice-container .bulk-notice-msg{text-align:center;margin:10px 0 0 32px;overflow:hidden;border:1px solid #1caecb;background-color:#9ddbe0;border-radius:5px;padding:7px 10px 10px;display:none;max-width:600px;margin-right:20px}div.wrap.short-pixel-bulk-page .bulk-notice-container .bulk-notice-msg.bulk-error{border:1px solid #b5914d;background-color:#ffe996;margin-right:20px}div.wrap.short-pixel-bulk-page .bulk-notice-container .bulk-notice-msg.bulk-error.bulk-error-fatal{border:1px solid #c32525;background-color:#ff969d}div.wrap.short-pixel-bulk-page .bulk-notice-msg img{float:left;margin-top:3px;margin-right:5px}div.sp-bulk-summary{float:right;margin:8px 5px 3px 20px}input.dial{box-shadow:none}.shortpixel-table .column-filename{max-width:32em;width:40%}.shortpixel-table .column-folder{max-width:20em;width:20%}.shortpixel-table .column-media_type{max-width:8em;width:10%}.shortpixel-table .column-status{max-width:16em;width:15%}.shortpixel-table .column-options{max-width:16em;width:15%}.form-table table.shortpixel-folders-list tr{background-color:#eee}.form-table table.shortpixel-folders-list td{padding:5px 10px}div.shortpixel-rate-us{display:inline-block;margin-left:10px;vertical-align:top;font-weight:bold}div.shortpixel-rate-us>a{vertical-align:middle;padding:1px 5px 0;text-align:center;display:inline-block}div.shortpixel-rate-us>a>span{display:inline-block;vertical-align:top;margin-top:5px}div.shortpixel-rate-us>a>img{padding-top:7px}div.shortpixel-rate-us>a:active,div.shortpixel-rate-us>a:hover,div.shortpixel-rate-us>a:focus{outline:0;border-style:none}.sp-loading-small{margin-top:2px;float:left;margin-right:5px}li.shortpixel-toolbar-processing>a.ab-item>div,#wpadminbar li.shortpixel-toolbar-processing>a.ab-item>div{height:33px;margin-top:-1px;padding:0 3px}li.shortpixel-toolbar-processing>a.ab-item>div>img,#wpadminbar li.shortpixel-toolbar-processing>a.ab-item>div>img{margin-right:2px;margin-top:6px}li.shortpixel-toolbar-processing>a.ab-item>div>span.shp-alert,#wpadminbar li.shortpixel-toolbar-processing>a.ab-item>div>span.shp-alert{display:none}li.shortpixel-toolbar-processing.shortpixel-alert>a.ab-item>div>span.shp-alert,#wpadminbar li.shortpixel-toolbar-processing.shortpixel-alert>a.ab-item>div>span.shp-alert{display:inline;font-size:26px;color:red;font-weight:bold;vertical-align:top}li.shortpixel-toolbar-processing.shortpixel-alert>a.ab-item>div,#wpadminbar li.shortpixel-toolbar-processing.shortpixel-alert>a.ab-item>div{background-image:none}.sp-quota-exceeded-alert{background-color:#fff;border-left:4px solid #f00;box-shadow:0 1px 1px 0 rgba(0,0,0,0.1);padding:1px 12px}.shortpixel-hide{display:none}.shortpixel-clearfix{width:100%;float:left}div.sp-modal-shade{display:none;position:fixed;z-index:10;left:0;top:0;width:100%;height:100%;overflow:auto;background-color:#000;background-color:rgba(0,0,0,0.4)}div.shortpixel-modal{background-color:#fefefe;margin:8% auto;padding:20px;border:1px solid #888;width:30%;min-width:300px}div.shortpixel-modal .sp-close-button,div.shortpixel-modal .sp-close-upgrade-button{float:right;margin-top:0;background:transparent;border:0;font-size:22px;line-height:10px;cursor:pointer}.twentytwenty-horizontal .twentytwenty-before-label:before,.twentytwenty-horizontal .twentytwenty-after-label:before{font-family:inherit;font-size:16px}div.sp-modal-title{font-size:22px}div.sp-modal-body{margin-top:20px}.short-pixel-bulk-page p{margin:.6em 0}div.shortpixel-modal .sptw-modal-spinner{background-image:url("../img/spinner2.gif");background-repeat:no-repeat;background-position:center}.short-pixel-bulk-page form.start{display:table;content:" ";width:98%;background-color:white;padding:10px 10px 0;position:relative}.bulk-stats-container{display:inline-block;min-width:450px;width:45%;float:left;padding-right:50px;font-size:1.1em;line-height:1.5em}.bulk-text-container{display:inline-block;min-width:440px;width:45%;float:left;padding-right:50px}.bulk-text-container h3{border-bottom:1px solid #a8a8a8;margin-bottom:.5em;padding-bottom:.5em}.bulk-wide{display:inline-block;width:90%;float:left;margin-top:25px}.bulk-stats-container .bulk-label{width:220px;display:inline-block}.bulk-stats-container .bulk-val{width:50px;display:inline-block;text-align:right}.bulk-stats-container .bulk-total{font-weight:bold;margin-top:10px;margin-bottom:10px}.wp-core-ui .bulk-play{display:inline;width:310px;float:left;margin-bottom:20px}.wp-core-ui .bulk-play.bulk-nothing-optimize{font-weight:bold;color:#0080b2;border:1px solid;border-radius:5px;margin-top:60px;padding:5px 12px}.wp-core-ui .bulk-play a.button{height:60px;margin-top:27px;width:290px;overflow:hidden}.wp-core-ui .column-wp-shortPixel .sp-column-actions{max-width:140px;float:right;text-align:right}.wp-core-ui .column-wp-shortPixel .sp-column-actions .button.button-smaller{margin-right:0}.wp-core-ui .column-wp-shortPixel .button.button-smaller{font-size:13px;padding:0 5px;margin-bottom:4px;height:20px;line-height:16px;float:right}.wp-core-ui .bulk-play a.button .bulk-btn-img{float:left;display:inline-block;padding-top:6px}.wp-core-ui .bulk-play a.button .bulk-btn-txt{float:left;display:inline-block;text-align:right;line-height:1.3em;margin:11px 10px}.wp-core-ui .bulk-play a.button .bulk-btn-txt span.label{font-size:1.6em}.wp-core-ui .bulk-play a.button .bulk-btn-txt span.total{font-size:1.4em}.short-pixel-notice-icon{float:left;margin:10px 10px 10px 0}.bulk-progress{padding:20px 32px 17px;background-color:#fff}.bulk-progress.bulk-stats>div{display:inline-block}.bulk-progress.bulk-stats>div.label{width:320px}.bulk-progress.bulk-stats>div.stat-value{width:80px;text-align:right}.progress{background-color:#ecedee;height:30px;position:relative;width:60%;display:inline-block;margin-right:28px}.progress .progress-img{position:absolute;top:-10px;z-index:2;margin-left:-35px;line-height:48px;font-size:22px;font-weight:bold}.progress .progress-img span{vertical-align:top;margin-left:-7px}.progress .progress-left{background-color:#1cbecb;bottom:0;left:0;position:absolute;top:0;z-index:1;font-size:22px;font-weight:bold;line-height:28px;text-align:center;color:#fff}.bulk-estimate{font-size:20px;line-height:30px;vertical-align:top;display:inline-block}.wp-core-ui .button-primary.bulk-cancel{float:right;height:30px}.short-pixel-block-title{font-size:22px;font-weight:bold;margin-bottom:15px;text-align:center;margin-bottom:30px}.sp-floating-block.bulk-slider-container{display:none}.sp-floating-block.sp-notice.bulk-notices-parent{padding:0;margin:0;float:right;margin-right:500px!important}.bulk-slider-container{margin-top:20px;min-height:300px;overflow:hidden}.bulk-slider-container h2{margin-bottom:15px}.bulk-slider-container span.filename{font-weight:normal}.bulk-slider{display:table;margin:0 auto}.bulk-slider .bulk-slide{margin:0 auto;padding-left:120px;display:inline-block;font-weight:bold}.bulk-slider .img-original,.bulk-slider .img-optimized{display:inline-block;margin-right:20px;text-align:center}.bulk-slider .img-original div,.bulk-slider .img-optimized div{max-height:450px;overflow:hidden}.bulk-slider .img-original img,.bulk-slider .img-optimized img{max-width:300px}.bulk-slider .img-info{display:inline-block;vertical-align:top;font-size:48px;max-width:150px;padding:10px 0 0 20px}.bulk-slide-images{display:inline-block;border:1px solid #1caecb;padding:15px 0 0 20px}p.settings-info{padding-top:0;color:#818181;font-size:13px!important}p.settings-info.shortpixel-settings-error{color:#c32525}article.sp-tabs{position:relative;display:block;width:100%;height:1100px;margin:2em auto}article.sp-tabs section{position:absolute;display:block;top:1.8em;left:0;height:1100px;width:94%;padding:10px 20px;background-color:#ddd;box-shadow:0 3px 3px rgba(0,0,0,0.1);z-index:0}article.sp-tabs section:first-child{z-index:1}article.sp-tabs section h2{position:absolute;font-size:1.3em;font-weight:normal;width:180px;height:1.8em;top:-1.8em;left:10px;padding:0;margin:0;color:#999;background-color:#ddd}article.sp-tabs section:nth-child(2) h2{left:192px}article.sp-tabs section:nth-child(3) h2{left:374px}article.sp-tabs section:nth-child(4) h2{left:556px}article.sp-tabs section h2 a{display:block;width:100%;line-height:1.8em;text-align:center;text-decoration:none;color:#23282d;outline:0 none}article.sp-tabs section h2 a:focus,article.sp-tabs section#tab-resources a:focus{box-shadow:none;outline:0}article.sp-tabs section.sel-tab,article.sp-tabs section.sel-tab h2{color:#333;background-color:#fff;z-index:2}.shortpixel-help-link span.dashicons{text-decoration:none;margin-top:-1px}@media(min-width:1000px){section#tab-resources .col-md-6{display:inline-block;width:45%}}@media(max-width:999px){section#tab-resources .col-sm-12{display:inline-block;width:100%}}section#tab-resources .text-center{text-align:center}section#tab-resources p{font-size:16px}.wrap.short-pixel-bulk-page{margin-right:0}.sp-container{overflow:hidden;display:block;width:100%}.sp-floating-block{overflow:hidden;display:inline-block;float:left;margin-right:1.1%!important}.sp-full-width{width:98.8%;box-sizing:border-box}.sp-double-width{width:65.52%;box-sizing:border-box}.sp-single-width{width:32.23%;box-sizing:border-box}@media(max-width:1759px){.sp-floating-block{margin-right:1.3%!important}.sp-double-width,.sp-full-width{width:98.65%}.sp-single-width{width:48.7%}}@media(max-width:1249px){.sp-floating-block{margin-right:2%!important}.sp-double-width,.sp-full-width,.sp-single-width{width:97%}}.sp-tabs h2:before{content:none}#wpadminbar .shortpixel-toolbar-processing .cssload-container{width:100%;height:24px;text-align:center;position:absolute;top:0;left:-1px}#wpadminbar .shortpixel-toolbar-processing.shortpixel-quota-exceeded .cssload-container{display:none}#wpadminbar .shortpixel-toolbar-processing .cssload-speeding-wheel{width:24px;height:24px;opacity:.7;margin:0 auto;border:4px solid #1cbfcb;border-radius:50%;border-left-color:transparent;animation:cssload-spin 2000ms infinite linear;-o-animation:cssload-spin 2000ms infinite linear;-ms-animation:cssload-spin 2000ms infinite linear;-webkit-animation:cssload-spin 2000ms infinite linear;-moz-animation:cssload-spin 2000ms infinite linear}@keyframes cssload-spin{100%{transform:rotate(360deg);transform:rotate(360deg)}}@-o-keyframes cssload-spin{100%{-o-transform:rotate(360deg);transform:rotate(360deg)}}@-ms-keyframes cssload-spin{100%{-ms-transform:rotate(360deg);transform:rotate(360deg)}}@-webkit-keyframes cssload-spin{100%{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}@-moz-keyframes cssload-spin{100%{-moz-transform:rotate(360deg);transform:rotate(360deg)}}
1
+ .sp-dropbtn.button{padding:1px 24px 20px 5px;font-size:20px;cursor:pointer}.sp-dropdown{position:relative;display:inline-block}.sp-dropdown-content{display:none;right:0;position:absolute;background-color:#f9f9f9;min-width:190px;box-shadow:0 8px 16px 0 rgba(0,0,0,0.2);z-index:1}.sp-dropdown-content a{color:black;padding:12px 16px;text-decoration:none;display:block}.sp-dropdown-content a:hover{background-color:#f1f1f1}.sp-dropdown.sp-show .sp-dropdown-content{display:block}div.fb-like{transform:scale(1.3);-ms-transform:scale(1.3);-webkit-transform:scale(1.3);-o-transform:scale(1.3);-moz-transform:scale(1.3);transform-origin:bottom left;-ms-transform-origin:bottom left;-webkit-transform-origin:bottom left;-moz-transform-origin:bottom left;-webkit-transform-origin:bottom left}.wp-core-ui .button.button-alert,.wp-core-ui .button.button-alert:hover{background:#f79797}.wp-core-ui .button.remove-folder-button{min-width:120px}.sp-notice{background:#fff;border-left:4px solid #fff;-webkit-box-shadow:0 1px 1px 0 rgba(0,0,0,.1);box-shadow:0 1px 1px 0 rgba(0,0,0,.1);padding:1px 12px}@media(max-width:1249px){.sp-notice{margin:5px 15px 2px}}.sp-notice-info{border-left-color:#00a0d2}.sp-notice-success{border-left-color:#46b450}li.sp-conflict-plugins-list{line-height:28px;list-style:disc;margin-left:80px}li.sp-conflict-plugins-list a.button{margin-left:10px}div.short-pixel-bulk-page input.dial{font-size:16px!important}div.short-pixel-bulk-page h1{margin-bottom:20px}div.bulk-progress div.sp-h2{margin-top:0;margin-bottom:10px;font-size:23px;font-weight:400;padding:9px 15px 4px 0;line-height:29px}div.bulk-progress-partners{margin-top:20px}div.bulk-progress.bulk-progress-partners a div{display:inline-block;vertical-align:top;line-height:50px;margin-left:30px;font-size:1.2em}div.bulk-progress .bulk-progress-indicator,div.sp-quota-exceeded-alert .bulk-progress-indicator{display:inline-block;text-align:center;padding:0 10px;margin-left:10px;float:left;height:90px;overflow:hidden;border:1px solid #1caecb}div.wrap.short-pixel-bulk-page .bulk-notice-container{margin-top:15px;position:absolute;width:500px}div.wrap.short-pixel-bulk-page .bulk-notice-container .bulk-notice-msg{text-align:center;margin:10px 0 0 32px;overflow:hidden;border:1px solid #1caecb;background-color:#9ddbe0;border-radius:5px;padding:7px 10px 10px;display:none;max-width:600px;margin-right:20px}div.wrap.short-pixel-bulk-page .bulk-notice-container .bulk-notice-msg.bulk-error{border:1px solid #b5914d;background-color:#ffe996;margin-right:20px;position: relative;z-index:10}div.wrap.short-pixel-bulk-page .bulk-notice-container .bulk-notice-msg.bulk-error.bulk-error-fatal{border:1px solid #c32525;background-color:#ff969d}div.wrap.short-pixel-bulk-page .bulk-notice-msg img{float:left;margin-top:3px;margin-right:5px}div.sp-bulk-summary{float:right;margin:8px 5px 3px 20px}input.dial{box-shadow:none}.shortpixel-table .column-filename{max-width:32em;width:40%}.shortpixel-table .column-folder{max-width:20em;width:20%}.shortpixel-table .column-media_type{max-width:8em;width:10%}.shortpixel-table .column-status{max-width:16em;width:15%}.shortpixel-table .column-options{max-width:16em;width:15%}.form-table table.shortpixel-folders-list tr{background-color:#eee}.form-table table.shortpixel-folders-list td{padding:5px 10px}div.shortpixel-rate-us{display:inline-block;margin-left:10px;vertical-align:top;font-weight:bold}div.shortpixel-rate-us>a{vertical-align:middle;padding:1px 5px 0;text-align:center;display:inline-block}div.shortpixel-rate-us>a>span{display:inline-block;vertical-align:top;margin-top:5px}div.shortpixel-rate-us>a>img{padding-top:7px}div.shortpixel-rate-us>a:active,div.shortpixel-rate-us>a:hover,div.shortpixel-rate-us>a:focus{outline:0;border-style:none}.sp-loading-small{margin-top:2px;float:left;margin-right:5px}li.shortpixel-toolbar-processing>a.ab-item>div,#wpadminbar li.shortpixel-toolbar-processing>a.ab-item>div{height:33px;margin-top:-1px;padding:0 3px}li.shortpixel-toolbar-processing>a.ab-item>div>img,#wpadminbar li.shortpixel-toolbar-processing>a.ab-item>div>img{margin-right:2px;margin-top:6px}li.shortpixel-toolbar-processing>a.ab-item>div>span.shp-alert,#wpadminbar li.shortpixel-toolbar-processing>a.ab-item>div>span.shp-alert{display:none}li.shortpixel-toolbar-processing.shortpixel-alert>a.ab-item>div>span.shp-alert,#wpadminbar li.shortpixel-toolbar-processing.shortpixel-alert>a.ab-item>div>span.shp-alert{display:inline;font-size:26px;color:red;font-weight:bold;vertical-align:top}li.shortpixel-toolbar-processing.shortpixel-alert>a.ab-item>div,#wpadminbar li.shortpixel-toolbar-processing.shortpixel-alert>a.ab-item>div{background-image:none}.sp-quota-exceeded-alert{background-color:#fff;border-left:4px solid #f00;box-shadow:0 1px 1px 0 rgba(0,0,0,0.1);padding:1px 12px}.shortpixel-hide{display:none}.shortpixel-clearfix{width:100%;float:left}div.sp-modal-shade{display:none;position:fixed;z-index:10;left:0;top:0;width:100%;height:100%;overflow:auto;background-color:#000;background-color:rgba(0,0,0,0.4)}div.shortpixel-modal{background-color:#fefefe;margin:8% auto;padding:20px;border:1px solid #888;width:30%;min-width:300px}div.shortpixel-modal .sp-close-button,div.shortpixel-modal .sp-close-upgrade-button{float:right;margin-top:0;background:transparent;border:0;font-size:22px;line-height:10px;cursor:pointer}.twentytwenty-horizontal .twentytwenty-before-label:before,.twentytwenty-horizontal .twentytwenty-after-label:before{font-family:inherit;font-size:16px}div.sp-modal-title{font-size:22px}div.sp-modal-body{margin-top:20px}.short-pixel-bulk-page p{margin:.6em 0}div.shortpixel-modal .sptw-modal-spinner{background-image:url("../img/spinner2.gif");background-repeat:no-repeat;background-position:center}.short-pixel-bulk-page form.start{display:table;content:" ";width:98%;background-color:white;padding:10px 10px 0;position:relative}.bulk-stats-container{display:inline-block;min-width:450px;width:45%;float:left;padding-right:50px;font-size:1.1em;line-height:1.5em}.bulk-text-container{display:inline-block;min-width:440px;width:45%;float:left;padding-right:50px}.bulk-text-container h3{border-bottom:1px solid #a8a8a8;margin-bottom:.5em;padding-bottom:.5em}.bulk-wide{display:inline-block;width:90%;float:left;margin-top:25px}.bulk-stats-container .bulk-label{width:220px;display:inline-block}.bulk-stats-container .bulk-val{width:50px;display:inline-block;text-align:right}.bulk-stats-container .bulk-total{font-weight:bold;margin-top:10px;margin-bottom:10px}.wp-core-ui .bulk-play{display:inline;width:310px;float:left;margin-bottom:20px}.wp-core-ui .bulk-play.bulk-nothing-optimize{font-weight:bold;color:#0080b2;border:1px solid;border-radius:5px;margin-top:60px;padding:5px 12px}.wp-core-ui .bulk-play a.button{height:60px;margin-top:27px;width:290px;overflow:hidden}.wp-core-ui .column-wp-shortPixel .sp-column-actions{max-width:140px;float:right;text-align:right}.wp-core-ui .column-wp-shortPixel .sp-column-actions .button.button-smaller{margin-right:0}.wp-core-ui .column-wp-shortPixel .button.button-smaller{font-size:13px;padding:0 5px;margin-bottom:4px;height:20px;line-height:16px;float:right}.wp-core-ui .bulk-play a.button .bulk-btn-img{float:left;display:inline-block;padding-top:6px}.wp-core-ui .bulk-play a.button .bulk-btn-txt{float:left;display:inline-block;text-align:right;line-height:1.3em;margin:11px 10px}.wp-core-ui .bulk-play a.button .bulk-btn-txt span.label{font-size:1.6em}.wp-core-ui .bulk-play a.button .bulk-btn-txt span.total{font-size:1.4em}.short-pixel-notice-icon{float:left;margin:10px 10px 10px 0}.bulk-progress{padding:20px 32px 17px;background-color:#fff}.bulk-progress.bulk-stats>div{display:inline-block}.bulk-progress.bulk-stats>div.label{width:320px}.bulk-progress.bulk-stats>div.stat-value{width:80px;text-align:right}.progress{background-color:#ecedee;height:30px;position:relative;width:60%;display:inline-block;margin-right:28px}.progress .progress-img{position:absolute;top:-10px;z-index:2;margin-left:-35px;line-height:48px;font-size:22px;font-weight:bold}.progress .progress-img span{vertical-align:top;margin-left:-7px}.progress .progress-left{background-color:#1cbecb;bottom:0;left:0;position:absolute;top:0;z-index:1;font-size:22px;font-weight:bold;line-height:28px;text-align:center;color:#fff}.bulk-estimate{font-size:20px;line-height:30px;vertical-align:top;display:inline-block}.wp-core-ui .button-primary.bulk-cancel{float:right;height:30px}.short-pixel-block-title{font-size:22px;font-weight:bold;margin-bottom:15px;text-align:center;margin-bottom:30px}.sp-floating-block.bulk-slider-container{display:none}.sp-floating-block.sp-notice.bulk-notices-parent{padding:0;margin:0;float:right;margin-right:500px!important}.bulk-slider-container{margin-top:20px;min-height:300px;overflow:hidden}.bulk-slider-container h2{margin-bottom:15px}.bulk-slider-container span.filename{font-weight:normal}.bulk-slider{display:table;margin:0 auto}.bulk-slider .bulk-slide{margin:0 auto;padding-left:120px;display:inline-block;font-weight:bold}.bulk-slider .img-original,.bulk-slider .img-optimized{display:inline-block;margin-right:20px;text-align:center}.bulk-slider .img-original div,.bulk-slider .img-optimized div{max-height:450px;overflow:hidden}.bulk-slider .img-original img,.bulk-slider .img-optimized img{max-width:300px}.bulk-slider .img-info{display:inline-block;vertical-align:top;font-size:48px;max-width:150px;padding:10px 0 0 20px}.bulk-slide-images{display:inline-block;border:1px solid #1caecb;padding:15px 0 0 20px}p.settings-info{padding-top:0;color:#818181;font-size:13px!important}p.settings-info.shortpixel-settings-error{color:#c32525}article.sp-tabs{position:relative;display:block;width:100%;height:1100px;margin:2em auto}article.sp-tabs section{position:absolute;display:block;top:1.8em;left:0;height:1100px;width:94%;padding:10px 20px;background-color:#ddd;box-shadow:0 3px 3px rgba(0,0,0,0.1);z-index:0}article.sp-tabs section:first-child{z-index:1}article.sp-tabs section h2{position:absolute;font-size:1.3em;font-weight:normal;width:180px;height:1.8em;top:-1.8em;left:10px;padding:0;margin:0;color:#999;background-color:#ddd}article.sp-tabs section:nth-child(2) h2{left:192px}article.sp-tabs section:nth-child(3) h2{left:374px}article.sp-tabs section:nth-child(4) h2{left:556px}article.sp-tabs section h2 a{display:block;width:100%;line-height:1.8em;text-align:center;text-decoration:none;color:#23282d;outline:0 none}article.sp-tabs section h2 a:focus,article.sp-tabs section#tab-resources a:focus{box-shadow:none;outline:0}article.sp-tabs section.sel-tab,article.sp-tabs section.sel-tab h2{color:#333;background-color:#fff;z-index:2}.shortpixel-help-link span.dashicons{text-decoration:none;margin-top:-1px}@media(min-width:1000px){section#tab-resources .col-md-6{display:inline-block;width:45%}}@media(max-width:999px){section#tab-resources .col-sm-12{display:inline-block;width:100%}}section#tab-resources .text-center{text-align:center}section#tab-resources p{font-size:16px}.wrap.short-pixel-bulk-page{margin-right:0}.sp-container{overflow:hidden;display:block;width:100%}.sp-floating-block{overflow:hidden;display:inline-block;float:left;margin-right:1.1%!important}.sp-full-width{width:98.8%;box-sizing:border-box}.sp-double-width{width:65.52%;box-sizing:border-box}.sp-single-width{width:32.23%;box-sizing:border-box}@media(max-width:1759px){.sp-floating-block{margin-right:1.3%!important}.sp-double-width,.sp-full-width{width:98.65%}.sp-single-width{width:48.7%}}@media(max-width:1249px){.sp-floating-block{margin-right:2%!important}.sp-double-width,.sp-full-width,.sp-single-width{width:97%}}.sp-tabs h2:before{content:none}#wpadminbar .shortpixel-toolbar-processing .cssload-container{width:100%;height:24px;text-align:center;position:absolute;top:0;left:-1px}#wpadminbar .shortpixel-toolbar-processing.shortpixel-quota-exceeded .cssload-container,#wpadminbar .shortpixel-toolbar-processing.shortpixel-alert .cssload-container{display:none}#wpadminbar .shortpixel-toolbar-processing .cssload-speeding-wheel{width:24px;height:24px;opacity:.7;margin:0 auto;border:4px solid #1cbfcb;border-radius:50%;border-left-color:transparent;animation:cssload-spin 2000ms infinite linear;-o-animation:cssload-spin 2000ms infinite linear;-ms-animation:cssload-spin 2000ms infinite linear;-webkit-animation:cssload-spin 2000ms infinite linear;-moz-animation:cssload-spin 2000ms infinite linear}@keyframes cssload-spin{100%{transform:rotate(360deg);transform:rotate(360deg)}}@-o-keyframes cssload-spin{100%{-o-transform:rotate(360deg);transform:rotate(360deg)}}@-ms-keyframes cssload-spin{100%{-ms-transform:rotate(360deg);transform:rotate(360deg)}}@-webkit-keyframes cssload-spin{100%{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}@-moz-keyframes cssload-spin{100%{-moz-transform:rotate(360deg);transform:rotate(360deg)}}
res/js/short-pixel.js CHANGED
@@ -2,39 +2,42 @@
2
  * Short Pixel WordPress Plugin javascript
3
  */
4
 
5
- jQuery(document).ready(function($){
6
- //are we on media list?
7
- if( jQuery('table.wp-list-table.media').length > 0) {
8
- //register a bulk action
9
- jQuery('select[name^="action"] option:last-child').before('<option value="short-pixel-bulk">' + _spTr.optimizeWithSP + '</option>');
10
- }
11
-
12
- ShortPixel.setOptions(ShortPixelConstants);
13
 
14
- if(jQuery('#backup-folder-size').length) {
15
- jQuery('#backup-folder-size').html(ShortPixel.getBackupSize());
16
- }
17
-
18
- if( ShortPixel.MEDIA_ALERT == 'todo' && jQuery('div.media-frame.mode-grid').length > 0) {
19
- //the media table is not in the list mode, alert the user
20
- jQuery('div.media-frame.mode-grid').before('<div id="short-pixel-media-alert" class="notice notice-warning"><p>'
21
- + _spTr.changeMLToListMode.format('<a href="upload.php?mode=list" class="view-list"><span class="screen-reader-text">',' </span>',
22
- '</a><a class="alignright" href="javascript:ShortPixel.dismissMediaAlert();">','</a>')
23
- + '</p></div>');
24
- }
25
- //
26
- jQuery(window).on('beforeunload', function(){
27
- if(ShortPixel.bulkProcessor == true) {
28
- clearBulkProcessor();
29
  }
30
- });
31
- //check if bulk processing
32
- checkQuotaExceededAlert();
33
- checkBulkProgress();
34
- });
35
 
 
36
 
37
- var ShortPixel = function() {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
38
 
39
  function setOptions(options) {
40
  for(var opt in options) {
@@ -112,6 +115,14 @@ var ShortPixel = function() {
112
  jQuery(this).val(Math.max(minHeight, parseInt(jQuery(this).val())));
113
  });
114
  */
 
 
 
 
 
 
 
 
115
  }
116
 
117
  function setupAdvancedTab() {
@@ -570,6 +581,7 @@ var ShortPixel = function() {
570
  }
571
 
572
  return {
 
573
  setOptions : setOptions,
574
  isEmailValid : isEmailValid,
575
  updateSignupEmail : updateSignupEmail,
@@ -622,7 +634,7 @@ var ShortPixel = function() {
622
  }
623
  }();
624
 
625
- function showToolBarAlert($status, $message) {
626
  var robo = jQuery("li.shortpixel-toolbar-processing");
627
  switch($status) {
628
  case ShortPixel.STATUS_QUOTA_EXCEEDED:
@@ -639,12 +651,12 @@ function showToolBarAlert($status, $message) {
639
  jQuery("a div", robo).attr("title", "ShortPixel quota exceeded. Click for details.");
640
  break;
641
  case ShortPixel.STATUS_SKIP:
642
- robo.addClass("shortpixel-alert shortpixel-processing");
643
- jQuery("a div", robo).attr("title", $message);
644
- break;
645
- case ShortPixel.STATUS_FAIL:
646
- robo.addClass("shortpixel-alert shortpixel-processing");
647
  jQuery("a div", robo).attr("title", $message);
 
 
 
648
  break;
649
  case ShortPixel.STATUS_NO_KEY:
650
  robo.addClass("shortpixel-alert");
@@ -785,9 +797,9 @@ function checkBulkProcessingCallApi(){
785
  case ShortPixel.STATUS_FAIL:
786
  setCellMessage(id, data["Message"], "<a class='button button-smaller button-primary' href=\"javascript:manualOptimization('" + id + "', false)\">"
787
  + _spTr.retry + "</a>");
 
788
  if(isBulkPage) {
789
  ShortPixel.bulkShowError(id, data["Message"], data["Filename"], data["CustomImageLink"]);
790
- showToolBarAlert(ShortPixel.STATUS_FAIL, data["Message"]);
791
  if(data["BulkPercent"]) {
792
  progressUpdate(data["BulkPercent"], data["BulkMsg"]);
793
  }
@@ -915,17 +927,39 @@ function setCellMessage(id, message, actions){
915
  function manualOptimization(id, cleanup) {
916
  setCellMessage(id, "<img src='" + ShortPixel.WP_PLUGIN_URL + "/res/img/loading.gif' class='sp-loading-small'>Image waiting to be processed", "");
917
  jQuery("li.shortpixel-toolbar-processing").removeClass("shortpixel-hide");
 
918
  jQuery("li.shortpixel-toolbar-processing").addClass("shortpixel-processing");
919
  var data = { action : 'shortpixel_manual_optimization',
920
  image_id: id, cleanup: cleanup};
921
- jQuery.get(ShortPixel.AJAX_URL, data, function(response) {
922
- data = JSON.parse(response);
923
- if(data["Status"] == ShortPixel.STATUS_SUCCESS) {
 
 
 
 
924
  setTimeout(checkBulkProgress, 2000);
925
  } else {
926
- setCellMessage(id, typeof data["Message"] !== "undefined" ? data["Message"] : _spTr.thisContentNotProcessable, "");
927
  }
928
  //aici e aici
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
929
  });
930
  }
931
 
2
  * Short Pixel WordPress Plugin javascript
3
  */
4
 
5
+ jQuery(document).ready(function($){ShortPixel.init();});
 
 
 
 
 
 
 
6
 
7
+
8
+ var ShortPixel = function() {
9
+
10
+ function init() {
11
+ if (typeof ShortPixel.API_KEY !== 'undefined') return; //was initialized by the 10 sec. setTimeout, rare but who knows, might happen on very slow connections...
12
+ //are we on media list?
13
+ if( jQuery('table.wp-list-table.media').length > 0) {
14
+ //register a bulk action
15
+ jQuery('select[name^="action"] option:last-child').before('<option value="short-pixel-bulk">' + _spTr.optimizeWithSP + '</option>');
 
 
 
 
 
 
16
  }
 
 
 
 
 
17
 
18
+ ShortPixel.setOptions(ShortPixelConstants);
19
 
20
+ if(jQuery('#backup-folder-size').length) {
21
+ jQuery('#backup-folder-size').html(ShortPixel.getBackupSize());
22
+ }
23
+
24
+ if( ShortPixel.MEDIA_ALERT == 'todo' && jQuery('div.media-frame.mode-grid').length > 0) {
25
+ //the media table is not in the list mode, alert the user
26
+ jQuery('div.media-frame.mode-grid').before('<div id="short-pixel-media-alert" class="notice notice-warning"><p>'
27
+ + _spTr.changeMLToListMode.format('<a href="upload.php?mode=list" class="view-list"><span class="screen-reader-text">',' </span>',
28
+ '</a><a class="alignright" href="javascript:ShortPixel.dismissMediaAlert();">','</a>')
29
+ + '</p></div>');
30
+ }
31
+ //
32
+ jQuery(window).on('beforeunload', function(){
33
+ if(ShortPixel.bulkProcessor == true) {
34
+ clearBulkProcessor();
35
+ }
36
+ });
37
+ //check if bulk processing
38
+ checkQuotaExceededAlert();
39
+ checkBulkProgress();
40
+ }
41
 
42
  function setOptions(options) {
43
  for(var opt in options) {
115
  jQuery(this).val(Math.max(minHeight, parseInt(jQuery(this).val())));
116
  });
117
  */
118
+ jQuery('.shortpixel-confirm').click(function(event){
119
+ var choice = confirm(event.target.getAttribute('data-confirm'));
120
+ if (!choice) {
121
+ event.preventDefault();
122
+ return false;
123
+ }
124
+ return true;
125
+ });
126
  }
127
 
128
  function setupAdvancedTab() {
581
  }
582
 
583
  return {
584
+ init : init,
585
  setOptions : setOptions,
586
  isEmailValid : isEmailValid,
587
  updateSignupEmail : updateSignupEmail,
634
  }
635
  }();
636
 
637
+ function showToolBarAlert($status, $message, id) {
638
  var robo = jQuery("li.shortpixel-toolbar-processing");
639
  switch($status) {
640
  case ShortPixel.STATUS_QUOTA_EXCEEDED:
651
  jQuery("a div", robo).attr("title", "ShortPixel quota exceeded. Click for details.");
652
  break;
653
  case ShortPixel.STATUS_SKIP:
654
+ case ShortPixel.STATUS_FAIL:
655
+ robo.addClass("shortpixel-alert shortpixel-processing");
 
 
 
656
  jQuery("a div", robo).attr("title", $message);
657
+ if(typeof id !== 'undefined') {
658
+ jQuery("a", robo).attr("href", "post.php?post=" + id + "&action=edit");
659
+ }
660
  break;
661
  case ShortPixel.STATUS_NO_KEY:
662
  robo.addClass("shortpixel-alert");
797
  case ShortPixel.STATUS_FAIL:
798
  setCellMessage(id, data["Message"], "<a class='button button-smaller button-primary' href=\"javascript:manualOptimization('" + id + "', false)\">"
799
  + _spTr.retry + "</a>");
800
+ showToolBarAlert(ShortPixel.STATUS_FAIL, data["Message"], id);
801
  if(isBulkPage) {
802
  ShortPixel.bulkShowError(id, data["Message"], data["Filename"], data["CustomImageLink"]);
 
803
  if(data["BulkPercent"]) {
804
  progressUpdate(data["BulkPercent"], data["BulkMsg"]);
805
  }
927
  function manualOptimization(id, cleanup) {
928
  setCellMessage(id, "<img src='" + ShortPixel.WP_PLUGIN_URL + "/res/img/loading.gif' class='sp-loading-small'>Image waiting to be processed", "");
929
  jQuery("li.shortpixel-toolbar-processing").removeClass("shortpixel-hide");
930
+ jQuery("li.shortpixel-toolbar-processing").removeClass("shortpixel-alert");
931
  jQuery("li.shortpixel-toolbar-processing").addClass("shortpixel-processing");
932
  var data = { action : 'shortpixel_manual_optimization',
933
  image_id: id, cleanup: cleanup};
934
+ jQuery.ajax({
935
+ type: "GET",
936
+ url: ShortPixel.AJAX_URL, //formerly ajaxurl , but changed it because it's not available in the front-end and now we have an option to run in the front-end
937
+ data: data,
938
+ success: function(response) {
939
+ var resp = JSON.parse(response);
940
+ if(resp["Status"] == ShortPixel.STATUS_SUCCESS) {
941
  setTimeout(checkBulkProgress, 2000);
942
  } else {
943
+ setCellMessage(id, typeof resp["Message"] !== "undefined" ? resp["Message"] : _spTr.thisContentNotProcessable, "");
944
  }
945
  //aici e aici
946
+ },
947
+ error: function(response){
948
+ //if error, give the ajax processor a chance to maybe find out why.
949
+ data.action = 'shortpixel_check_status'
950
+ jQuery.ajax({
951
+ type: "GET",
952
+ url: ShortPixel.AJAX_URL, //formerly ajaxurl , but changed it because it's not available in the front-end and now we have an option to run in the front-end
953
+ data: data,
954
+ success: function (response) {
955
+ var resp = JSON.parse(response);
956
+ if (resp["Status"] !== ShortPixel.STATUS_SUCCESS) {
957
+ setCellMessage(id, typeof resp["Message"] !== "undefined" ? resp["Message"] : _spTr.thisContentNotProcessable, "");
958
+ }
959
+ //aici e aici
960
+ }
961
+ });
962
+ }
963
  });
964
  }
965
 
res/js/short-pixel.min.js CHANGED
@@ -1 +1 @@
1
- jQuery(document).ready(function(a){if(jQuery("table.wp-list-table.media").length>0){jQuery('select[name^="action"] option:last-child').before('<option value="short-pixel-bulk">'+_spTr.optimizeWithSP+"</option>")}ShortPixel.setOptions(ShortPixelConstants);if(jQuery("#backup-folder-size").length){jQuery("#backup-folder-size").html(ShortPixel.getBackupSize())}if(ShortPixel.MEDIA_ALERT=="todo"&&jQuery("div.media-frame.mode-grid").length>0){jQuery("div.media-frame.mode-grid").before('<div id="short-pixel-media-alert" class="notice notice-warning"><p>'+_spTr.changeMLToListMode.format('<a href="upload.php?mode=list" class="view-list"><span class="screen-reader-text">'," </span>",'</a><a class="alignright" href="javascript:ShortPixel.dismissMediaAlert();">',"</a>")+"</p></div>")}jQuery(window).on("beforeunload",function(){if(ShortPixel.bulkProcessor==true){clearBulkProcessor()}});checkQuotaExceededAlert();checkBulkProgress()});var ShortPixel=function(){function l(M){for(var N in M){ShortPixel[N]=M[N]}}function s(M){return/^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{1,63})+$/.test(M)}function m(){var M=jQuery("#pluginemail").val();if(ShortPixel.isEmailValid(M)){jQuery("#request_key").removeClass("disabled")}jQuery("#request_key").attr("href",jQuery("#request_key").attr("href").split("?")[0]+"?pluginemail="+M)}function a(){jQuery("#valid").val("validate");jQuery("#wp_shortpixel_options").submit()}jQuery("#key").keypress(function(M){if(M.which==13){jQuery("#valid").val("validate")}});function H(M){if(jQuery(M).is(":checked")){jQuery("#width,#height").removeAttr("disabled")}else{jQuery("#width,#height").attr("disabled","disabled")}}function e(M,O,Q){for(var N=0,P=null;N<M.length;N++){M[N].onclick=function(){if(this!==P){P=this}alert(_spTr.alertOnlyAppliesToNewImages)}}ShortPixel.enableResize("#resize");jQuery("#resize").change(function(){H(this)});jQuery(".resize-sizes").blur(function(S){var T=jQuery(this);if(ShortPixel.resizeSizesAlert==T.val()){return}ShortPixel.resizeSizesAlert=T.val();var R=jQuery("#min-"+T.attr("name")).val();if(T.val()<Math.min(R,1024)){if(R>1024){alert(_spTr.pleaseDoNotSetLesser1024.format(T.attr("name")))}else{alert(_spTr.pleaseDoNotSetLesserSize.format(T.attr("name"),T.attr("name"),R))}S.preventDefault();T.focus()}else{this.defaultValue=T.val()}})}function t(){jQuery("input.remove-folder-button").click(function(){var N=jQuery(this).data("value");var M=confirm(_spTr.areYouSureStopOptimizing.format(N));if(M==true){jQuery("#removeFolder").val(N);jQuery("#wp_shortpixel_options").submit()}});jQuery("input.recheck-folder-button").click(function(){var N=jQuery(this).data("value");var M=confirm(_spTr.areYouSureStopOptimizing.format(N));if(M==true){jQuery("#recheckFolder").val(N);jQuery("#wp_shortpixel_options").submit()}})}function G(M){var N=jQuery("#"+(M.checked?"total":"main")+"ToProcess").val();jQuery("div.bulk-play span.total").text(N);jQuery("#displayTotal").text(N)}function w(N){var M=jQuery("section#"+N);if(M.length>0){jQuery("section").removeClass("sel-tab");jQuery("section#"+N).addClass("sel-tab")}}function x(){var M=jQuery("section#tab-settings .wp-shortpixel-options").height()+90;M=Math.max(M,jQuery("section#tab-adv-settings .wp-shortpixel-options").height()+20);M=Math.max(M,jQuery("section#tab-resources .area1").height()+60);jQuery("#shortpixel-settings-tabs").css("height",M);jQuery("#shortpixel-settings-tabs section").css("height",M)}function I(){var M={action:"shortpixel_dismiss_media_alert"};jQuery.get(ShortPixel.AJAX_URL,M,function(N){M=JSON.parse(N);if(M.Status=="success"){jQuery("#short-pixel-media-alert").hide();console.log("dismissed")}})}function j(){var M={action:"shortpixel_check_quota"};jQuery.get(ShortPixel.AJAX_URL,M,function(){console.log("quota refreshed")})}function z(M){if(M.checked){jQuery("#with-thumbs").css("display","inherit");jQuery("#without-thumbs").css("display","none")}else{jQuery("#without-thumbs").css("display","inherit");jQuery("#with-thumbs").css("display","none")}}function b(Q,O,N,P,M){return(O>0?"<div class='sp-column-info'>"+_spTr.reducedBy+" <strong><span class='percent'>"+O+"%</span></strong> ":"")+(O>0&&O<5?"<br>":"")+(O<5?_spTr.bonusProcessing:"")+(N.length>0?" ("+N+")":"")+(0+P>0?"<br>"+_spTr.plusXthumbsOpt.format(P):"")+(0+M>0?"<br>"+_spTr.plusXretinasOpt.format(M):"")+"</div>"}function o(N,M){jQuery(N).knob({readOnly:true,width:M,height:M,fgColor:"#1CAECB",format:function(O){return O+"%"}})}function c(T,O,R,Q,N,S){if(N==1){var P=jQuery(".sp-column-actions-template").clone();if(!P.length){return false}var M;if(O.length==0){M=["lossy","lossless"]}else{M=["lossy","glossy","lossless"].filter(function(U){return !(U==O)})}P.html(P.html().replace(/__SP_ID__/g,T));if(S.substr(S.lastIndexOf(".")+1).toLowerCase()=="pdf"){jQuery(".sp-action-compare",P).remove()}if(R==0&&Q>0){P.html(P.html().replace("__SP_THUMBS_TOTAL__",Q))}else{jQuery(".sp-action-optimize-thumbs",P).remove();jQuery(".sp-dropbtn",P).removeClass("button-primary")}P.html(P.html().replace(/__SP_FIRST_TYPE__/g,M[0]));P.html(P.html().replace(/__SP_SECOND_TYPE__/g,M[1]));return P.html()}return""}function h(Q,P){Q=Q.substring(2);if(jQuery(".shortpixel-other-media").length){var O=["optimize","retry","restore","redo","quota","view"];for(var N=0,M=O.length;N<M;N++){jQuery("#"+O[N]+"_"+Q).css("display","none")}for(var N=0,M=P.length;N<M;N++){jQuery("#"+P[N]+"_"+Q).css("display","")}}}function i(M){ShortPixel.retries++;if(isNaN(ShortPixel.retries)){ShortPixel.retries=1}if(ShortPixel.retries<6){console.log("Invalid response from server (Error: "+M+"). Retrying pass "+(ShortPixel.retries+1)+"...");setTimeout(checkBulkProgress,5000)}else{ShortPixel.bulkShowError(-1,"Invalid response from server received 6 times. Please retry later by reloading this page, or <a href='https://shortpixel.com/contact' target='_blank'>contact support</a>. (Error: "+M+")","");console.log("Invalid response from server 6 times. Giving up.")}}function k(M){M.action="shortpixel_browse_content";var N="";jQuery.ajax({type:"POST",url:ShortPixel.AJAX_URL,data:M,success:function(O){N=O},async:false});return N}function d(){var M={action:"shortpixel_get_backup_size"};var N="";jQuery.ajax({type:"POST",url:ShortPixel.AJAX_URL,data:M,success:function(O){N=O},async:false});return N}function f(N){jQuery("#request_key").addClass("disabled");jQuery("#pluginemail_spinner").addClass("is-active");ShortPixel.updateSignupEmail();if(ShortPixel.isEmailValid(jQuery("#pluginemail").val())){jQuery("#pluginemail-error").css("display","none");var M={action:"shortpixel_new_api_key",email:jQuery("#pluginemail").val()};jQuery.ajax({type:"POST",async:false,url:ShortPixel.AJAX_URL,data:M,success:function(O){data=JSON.parse(O);if(data.Status=="success"){N.preventDefault();window.location.reload()}else{if(data.Status=="invalid"){jQuery("#pluginemail-error").html("<b>"+data.Details+"</b>");jQuery("#pluginemail-error").css("display","");jQuery("#pluginemail-info").css("display","none");N.preventDefault()}else{}}}});jQuery("#request_key").removeAttr("onclick")}else{jQuery("#pluginemail-error").css("display","");jQuery("#pluginemail-info").css("display","none");N.preventDefault()}jQuery("#request_key").removeClass("disabled");jQuery("#pluginemail_spinner").removeClass("is-active")}function J(){jQuery("#shortPixelProposeUpgrade .sp-modal-body").addClass("sptw-modal-spinner");jQuery("#shortPixelProposeUpgrade .sp-modal-body").html("");jQuery("#shortPixelProposeUpgradeShade").css("display","block");jQuery("#shortPixelProposeUpgrade").removeClass("shortpixel-hide");var M={action:"shortpixel_propose_upgrade"};jQuery.ajax({type:"POST",url:ShortPixel.AJAX_URL,data:M,success:function(N){jQuery("#shortPixelProposeUpgrade .sp-modal-body").removeClass("sptw-modal-spinner");jQuery("#shortPixelProposeUpgrade .sp-modal-body").html(N)}})}function D(){jQuery("#shortPixelProposeUpgradeShade").css("display","none");jQuery("#shortPixelProposeUpgrade").addClass("shortpixel-hide");if(ShortPixel.toRefresh){ShortPixel.recheckQuota()}}function u(){jQuery("#short-pixel-notice-unlisted").hide();jQuery("#optimizeUnlisted").prop("checked",true);var M={action:"shortpixel_dismiss_notice",notice_id:"unlisted",notice_data:"true"};jQuery.get(ShortPixel.AJAX_URL,M,function(N){M=JSON.parse(N);if(M.Status==ShortPixel.STATUS_SUCCESS){console.log("dismissed")}})}function n(){jQuery(".select-folder-button").click(function(){jQuery(".sp-folder-picker-shade").css("display","block");jQuery(".sp-folder-picker").fileTree({script:ShortPixel.browseContent,multiFolder:false})});jQuery(".shortpixel-modal input.select-folder-cancel").click(function(){jQuery(".sp-folder-picker-shade").css("display","none")});jQuery(".shortpixel-modal input.select-folder").click(function(){var M=jQuery("UL.jqueryFileTree LI.directory.selected A").attr("rel").trim();if(M){var N=jQuery("#customFolderBase").val()+M;if(N.slice(-1)=="/"){N=N.slice(0,-1)}jQuery("#addCustomFolder").val(N);jQuery("#addCustomFolderView").val(N);jQuery(".sp-folder-picker-shade").css("display","none")}else{alert("Please select a folder from the list.")}})}function C(Q,P,O){var N=jQuery(".bulk-notice-msg.bulk-lengthy");if(N.length==0){return}var M=jQuery("a",N);M.text(P);if(O){M.attr("href",O)}else{M.attr("href",M.data("href").replace("__ID__",Q))}N.css("display","block")}function y(){jQuery(".bulk-notice-msg.bulk-lengthy").css("display","none")}function v(M){var N=jQuery(".bulk-notice-msg.bulk-"+M);if(N.length==0){return}N.css("display","block")}function K(M){jQuery(".bulk-notice-msg.bulk-"+M).css("display","none")}function r(S,Q,R,P){var M=jQuery("#bulk-error-template");if(M.length==0){return}var O=M.clone();O.attr("id","bulk-error-"+S);if(S==-1){jQuery("span.sp-err-title",O).remove();O.addClass("bulk-error-fatal")}else{jQuery("img",O).remove();jQuery("#bulk-error-".id).remove()}jQuery("span.sp-err-content",O).html(Q);var N=jQuery("a.sp-post-link",O);if(P){N.attr("href",P)}else{N.attr("href",N.attr("href").replace("__ID__",S))}N.text(R);M.after(O);O.css("display","block")}function A(M,N){if(!confirm(_spTr["confirmBulk"+M])){N.stopPropagation();N.preventDefault();return false}return true}function q(M){jQuery(M).parent().parent().remove()}function E(M){return M.substring(0,2)=="C-"}function F(){window.location.href=window.location.href+(window.location.href.indexOf("?")>0?"&":"?")+"checkquota=1"}function g(N){N.preventDefault();if(!this.menuCloseEvent){jQuery(window).click(function(O){if(!O.target.matches(".sp-dropbtn")){jQuery(".sp-dropdown.sp-show").removeClass("sp-show")}});this.menuCloseEvent=true}var M=N.target.parentElement.classList.contains("sp-show");jQuery(".sp-dropdown.sp-show").removeClass("sp-show");if(!M){N.target.parentElement.classList.add("sp-show")}}function L(M){this.comparerData.origUrl=false;if(this.comparerData.cssLoaded===false){jQuery("<link>").appendTo("head").attr({type:"text/css",rel:"stylesheet",href:this.WP_PLUGIN_URL+"/res/css/twentytwenty.min.css"});this.comparerData.cssLoaded=2}if(this.comparerData.jsLoaded===false){jQuery.getScript(this.WP_PLUGIN_URL+"/res/js/jquery.twentytwenty.min.js",function(){ShortPixel.comparerData.jsLoaded=2;if(ShortPixel.comparerData.origUrl.length>0){ShortPixel.displayComparerPopup(ShortPixel.comparerData.width,ShortPixel.comparerData.height,ShortPixel.comparerData.origUrl,ShortPixel.comparerData.optUrl)}});this.comparerData.jsLoaded=1;jQuery(".sp-close-button").click(ShortPixel.closeComparerPopup)}if(this.comparerData.origUrl===false){jQuery.ajax({type:"POST",url:ShortPixel.AJAX_URL,data:{action:"shortpixel_get_comparer_data",id:M},success:function(N){data=JSON.parse(N);jQuery.extend(ShortPixel.comparerData,data);if(ShortPixel.comparerData.jsLoaded==2){ShortPixel.displayComparerPopup(ShortPixel.comparerData.width,ShortPixel.comparerData.height,ShortPixel.comparerData.origUrl,ShortPixel.comparerData.optUrl)}}});this.comparerData.origUrl=""}}function B(Q,O,N,P){var T=Q;var S=(O<150||Q<350);var R=jQuery(S?"#spUploadCompareSideBySide":"#spUploadCompare");if(!S){jQuery("#spCompareSlider").html('<img class="spUploadCompareOriginal"/><img class="spUploadCompareOptimized"/>')}Q=Math.max(350,Math.min(800,(Q<350?(Q+25)*2:(O<150?Q+25:Q))));O=Math.max(150,(S?(T>350?2*(O+45):O+45):O*Q/T));jQuery(".sp-modal-body",R).css("width",Q);jQuery(".shortpixel-slider",R).css("width",Q);R.css("width",Q);jQuery(".sp-modal-body",R).css("height",O);R.css("display","block");R.parent().css("display","block");if(!S){jQuery("#spCompareSlider").twentytwenty({slider_move:"mousemove"})}jQuery(document).on("keyup.sp_modal_active",ShortPixel.closeComparerPopup);var M=jQuery(".spUploadCompareOptimized",R);jQuery(".spUploadCompareOriginal",R).attr("src",N);setTimeout(function(){jQuery(window).trigger("resize")},1000);M.load(function(){jQuery(window).trigger("resize")});M.attr("src",P)}function p(M){jQuery("#spUploadCompareSideBySide").parent().css("display","none");jQuery("#spUploadCompareSideBySide").css("display","none");jQuery("#spUploadCompare").css("display","none");jQuery(document).unbind("keyup.sp_modal_active")}return{setOptions:l,isEmailValid:s,updateSignupEmail:m,validateKey:a,enableResize:H,setupGeneralTab:e,setupAdvancedTab:t,checkThumbsUpdTotal:G,switchSettingsTab:w,adjustSettingsTabs:x,onBulkThumbsCheck:z,dismissMediaAlert:I,checkQuota:j,percentDial:o,successMsg:b,successActions:c,otherMediaUpdateActions:h,retry:i,initFolderSelector:n,browseContent:k,getBackupSize:d,newApiKey:f,proposeUpgrade:J,closeProposeUpgrade:D,includeUnlisted:u,bulkShowLengthyMsg:C,bulkHideLengthyMsg:y,bulkShowMaintenanceMsg:v,bulkHideMaintenanceMsg:K,bulkShowError:r,confirmBulkAction:A,removeBulkMsg:q,isCustomImageId:E,recheckQuota:F,openImageMenu:g,menuCloseEvent:false,loadComparer:L,displayComparerPopup:B,closeComparerPopup:p,comparerData:{cssLoaded:false,jsLoaded:false,origUrl:false,optUrl:false,width:0,height:0},toRefresh:false,resizeSizesAlert:false}}();function showToolBarAlert(c,b){var a=jQuery("li.shortpixel-toolbar-processing");switch(c){case ShortPixel.STATUS_QUOTA_EXCEEDED:if(window.location.href.search("wp-short-pixel-bulk")>0&&jQuery(".sp-quota-exceeded-alert").length==0){location.reload();return}a.addClass("shortpixel-alert");a.addClass("shortpixel-quota-exceeded");jQuery("a",a).attr("href","options-general.php?page=wp-shortpixel");jQuery("a div",a).attr("title","ShortPixel quota exceeded. Click for details.");break;case ShortPixel.STATUS_SKIP:a.addClass("shortpixel-alert shortpixel-processing");jQuery("a div",a).attr("title",b);break;case ShortPixel.STATUS_FAIL:a.addClass("shortpixel-alert shortpixel-processing");jQuery("a div",a).attr("title",b);break;case ShortPixel.STATUS_NO_KEY:a.addClass("shortpixel-alert");a.addClass("shortpixel-quota-exceeded");jQuery("a",a).attr("href","options-general.php?page=wp-shortpixel");jQuery("a div",a).attr("title","Get API Key");break;case ShortPixel.STATUS_SUCCESS:case ShortPixel.STATUS_RETRY:a.addClass("shortpixel-processing");a.removeClass("shortpixel-alert");jQuery("a",a).removeAttr("target");jQuery("a",a).attr("href",jQuery("a img",a).attr("success-url"))}a.removeClass("shortpixel-hide")}function hideToolBarAlert(){jQuery("li.shortpixel-toolbar-processing.shortpixel-processing").addClass("shortpixel-hide")}function hideQuotaExceededToolBarAlert(){jQuery("li.shortpixel-toolbar-processing.shortpixel-quota-exceeded").addClass("shortpixel-hide")}function checkQuotaExceededAlert(){if(typeof shortPixelQuotaExceeded!="undefined"){if(shortPixelQuotaExceeded==1){showToolBarAlert(ShortPixel.STATUS_QUOTA_EXCEEDED)}else{hideQuotaExceededToolBarAlert()}}}function checkBulkProgress(){var b=function(f){if(!d){d=true;return f}return"/"};var d=false;var a=window.location.href.toLowerCase().replace(/\/\//g,b);d=false;var c=ShortPixel.WP_ADMIN_URL.toLowerCase().replace(/\/\//g,b);if(a.search(c)<0){var e=document.createElement("a");e.href=a;a=a.replace(e.protocol+"//"+e.hostname,e.protocol+"//"+e.hostname.split(".").map(function(f){return sp_punycode.toASCII(f)}).join("."))}if(a.search(c+"upload.php")<0&&a.search(c+"edit.php")<0&&a.search(c+"edit-tags.php")<0&&a.search(c+"post-new.php")<0&&a.search(c+"post.php")<0&&a.search("page=nggallery-manage-gallery")<0&&(ShortPixel.FRONT_BOOTSTRAP==0||a.search(c)==0)){hideToolBarAlert();return}if(ShortPixel.bulkProcessor==true&&window.location.href.search("wp-short-pixel-bulk")<0&&typeof localStorage.bulkPage!=="undefined"&&localStorage.bulkPage>0){ShortPixel.bulkProcessor=false}if(window.location.href.search("wp-short-pixel-bulk")>=0){ShortPixel.bulkProcessor=true;localStorage.bulkTime=Math.floor(Date.now()/1000);localStorage.bulkPage=1}if(ShortPixel.bulkProcessor==true||typeof localStorage.bulkTime=="undefined"||Math.floor(Date.now()/1000)-localStorage.bulkTime>90){ShortPixel.bulkProcessor=true;localStorage.bulkPage=(window.location.href.search("wp-short-pixel-bulk")>=0?1:0);localStorage.bulkTime=Math.floor(Date.now()/1000);console.log(localStorage.bulkTime);checkBulkProcessingCallApi()}else{setTimeout(checkBulkProgress,5000)}}function checkBulkProcessingCallApi(){var a={action:"shortpixel_image_processing"};jQuery.ajax({type:"POST",url:ShortPixel.AJAX_URL,data:a,success:function(g){if(g.length>0){var i=null;try{var i=JSON.parse(g)}catch(k){ShortPixel.retry(k.message);return}ShortPixel.retries=0;var d=i.ImageID;var j=(jQuery("div.short-pixel-bulk-page").length>0);switch(i.Status){case ShortPixel.STATUS_NO_KEY:setCellMessage(d,i.Message,'<a class=\'button button-smaller button-primary\' href="https://shortpixel.com/wp-apikey" target="_blank">'+_spTr.getApiKey+"</a>");showToolBarAlert(ShortPixel.STATUS_NO_KEY);break;case ShortPixel.STATUS_QUOTA_EXCEEDED:setCellMessage(d,i.Message,"<a class='button button-smaller button-primary' href=\"https://shortpixel.com/login/"+ShortPixel.API_KEY+'" target="_blank">'+_spTr.extendQuota+"</a><a class='button button-smaller' href='admin.php?action=shortpixel_check_quota'>"+_spTr.check__Quota+"</a>");showToolBarAlert(ShortPixel.STATUS_QUOTA_EXCEEDED);if(i.Stop==false){setTimeout(checkBulkProgress,5000)}ShortPixel.otherMediaUpdateActions(d,["quota","view"]);break;case ShortPixel.STATUS_FAIL:setCellMessage(d,i.Message,"<a class='button button-smaller button-primary' href=\"javascript:manualOptimization('"+d+"', false)\">"+_spTr.retry+"</a>");if(j){ShortPixel.bulkShowError(d,i.Message,i.Filename,i.CustomImageLink);showToolBarAlert(ShortPixel.STATUS_FAIL,i.Message);if(i.BulkPercent){progressUpdate(i.BulkPercent,i.BulkMsg)}ShortPixel.otherMediaUpdateActions(d,["retry","view"])}console.log(i.Message);setTimeout(checkBulkProgress,5000);break;case ShortPixel.STATUS_EMPTY_QUEUE:console.log(i.Message);clearBulkProcessor();hideToolBarAlert();var c=jQuery("#bulk-progress");if(j&&c.length&&i.BulkStatus!="2"){progressUpdate(100,"Bulk finished!");jQuery("a.bulk-cancel").attr("disabled","disabled");hideSlider();setTimeout(function(){window.location.reload()},3000)}break;case ShortPixel.STATUS_SUCCESS:if(j){ShortPixel.bulkHideLengthyMsg();ShortPixel.bulkHideMaintenanceMsg()}var l=i.PercentImprovement;showToolBarAlert(ShortPixel.STATUS_SUCCESS,"");var b=ShortPixel.isCustomImageId(d)?"":ShortPixel.successActions(d,i.Type,i.ThumbsCount,i.ThumbsTotal,i.BackupEnabled,i.Filename);setCellMessage(d,ShortPixel.successMsg(d,l,i.Type,i.ThumbsCount,i.RetinasCount),b);var h=jQuery(["restore","view","redolossy","redoglossy","redolossless"]).not(["redo"+i.Type]).get();ShortPixel.otherMediaUpdateActions(d,h);var f=new PercentageAnimator("#sp-msg-"+d+" span.percent",l);f.animate(l);if(j&&typeof i.Thumb!=="undefined"){if(i.BulkPercent){progressUpdate(i.BulkPercent,i.BulkMsg)}if(i.Thumb.length>0){sliderUpdate(d,i.Thumb,i.BkThumb,i.PercentImprovement,i.Filename);if(typeof i.AverageCompression!=="undefined"&&0+i.AverageCompression>0){jQuery("#sp-avg-optimization").html('<input type="text" class="dial" value="'+Math.round(i.AverageCompression)+'"/>');ShortPixel.percentDial("#sp-avg-optimization .dial",60)}}}console.log("Server response: "+g);if(j&&typeof i.BulkPercent!=="undefined"){progressUpdate(i.BulkPercent,i.BulkMsg)}setTimeout(checkBulkProgress,5000);break;case ShortPixel.STATUS_SKIP:if(i.Silent!==1){ShortPixel.bulkShowError(d,i.Message,i.Filename,i.CustomImageLink)}case ShortPixel.STATUS_ERROR:if(typeof i.Message!=="undefined"){showToolBarAlert(ShortPixel.STATUS_SKIP,i.Message+" Image ID: "+d);setCellMessage(d,i.Message,"")}ShortPixel.otherMediaUpdateActions(d,["retry","view"]);case ShortPixel.STATUS_RETRY:console.log("Server response: "+g);showToolBarAlert(ShortPixel.STATUS_RETRY,"");if(j&&typeof i.BulkPercent!=="undefined"){progressUpdate(i.BulkPercent,i.BulkMsg)}if(j&&i.Count>3){ShortPixel.bulkShowLengthyMsg(d,i.Filename,i.CustomImageLink)}setTimeout(checkBulkProgress,5000);break;case ShortPixel.STATUS_MAINTENANCE:ShortPixel.bulkShowMaintenanceMsg("maintenance");setTimeout(checkBulkProgress,60000);break;case ShortPixel.STATUS_QUEUE_FULL:ShortPixel.bulkShowMaintenanceMsg("queue-full");setTimeout(checkBulkProgress,60000);break;default:ShortPixel.retry("Unknown status "+i.Status+". Retrying...");break}}},error:function(b){ShortPixel.retry(b.statusText)}})}function clearBulkProcessor(){ShortPixel.bulkProcessor=false;localStorage.bulkTime=0;if(window.location.href.search("wp-short-pixel-bulk")>=0){localStorage.bulkPage=0}}function setCellMessage(d,a,c){var b=jQuery("#sp-msg-"+d);if(b.length>0){b.html("<div class='sp-column-actions'>"+c+"</div><div class='sp-column-info'>"+a+"</div>");b.css("color","")}b=jQuery("#sp-cust-msg-"+d);if(b.length>0){b.html("<div class='sp-column-info'>"+a+"</div>")}}function manualOptimization(c,a){setCellMessage(c,"<img src='"+ShortPixel.WP_PLUGIN_URL+"/res/img/loading.gif' class='sp-loading-small'>Image waiting to be processed","");jQuery("li.shortpixel-toolbar-processing").removeClass("shortpixel-hide");jQuery("li.shortpixel-toolbar-processing").addClass("shortpixel-processing");var b={action:"shortpixel_manual_optimization",image_id:c,cleanup:a};jQuery.get(ShortPixel.AJAX_URL,b,function(d){b=JSON.parse(d);if(b.Status==ShortPixel.STATUS_SUCCESS){setTimeout(checkBulkProgress,2000)}else{setCellMessage(c,typeof b.Message!=="undefined"?b.Message:_spTr.thisContentNotProcessable,"")}})}function reoptimize(c,a){setCellMessage(c,"<img src='"+ShortPixel.WP_PLUGIN_URL+"/res/img/loading.gif' class='sp-loading-small'>Image waiting to be reprocessed","");jQuery("li.shortpixel-toolbar-processing").removeClass("shortpixel-hide");jQuery("li.shortpixel-toolbar-processing").addClass("shortpixel-processing");var b={action:"shortpixel_redo",attachment_ID:c,type:a};jQuery.get(ShortPixel.AJAX_URL,b,function(d){b=JSON.parse(d);if(b.Status==ShortPixel.STATUS_SUCCESS){setTimeout(checkBulkProgress,2000)}else{$msg=typeof b.Message!=="undefined"?b.Message:_spTr.thisContentNotProcessable;setCellMessage(c,$msg,"");showToolBarAlert(ShortPixel.STATUS_FAIL,$msg)}})}function optimizeThumbs(b){setCellMessage(b,"<img src='"+ShortPixel.WP_PLUGIN_URL+"/res/img/loading.gif' class='sp-loading-small'>"+_spTr.imageWaitOptThumbs,"");jQuery("li.shortpixel-toolbar-processing").removeClass("shortpixel-hide");jQuery("li.shortpixel-toolbar-processing").addClass("shortpixel-processing");var a={action:"shortpixel_optimize_thumbs",attachment_ID:b};jQuery.get(ShortPixel.AJAX_URL,a,function(c){a=JSON.parse(c);if(a.Status==ShortPixel.STATUS_SUCCESS){setTimeout(checkBulkProgress,2000)}else{setCellMessage(b,typeof a.Message!=="undefined"?a.Message:_spTr.thisContentNotProcessable,"")}})}function dismissShortPixelNoticeExceed(b){jQuery("#wp-admin-bar-shortpixel_processing").hide();var a={action:"shortpixel_dismiss_notice",notice_id:"exceed"};jQuery.get(ShortPixel.AJAX_URL,a,function(c){a=JSON.parse(c);if(a.Status==ShortPixel.STATUS_SUCCESS){console.log("dismissed")}});b.preventDefault()}function dismissShortPixelNotice(b){jQuery("#short-pixel-notice-"+b).hide();var a={action:"shortpixel_dismiss_notice",notice_id:b};jQuery.get(ShortPixel.AJAX_URL,a,function(c){a=JSON.parse(c);if(a.Status==ShortPixel.STATUS_SUCCESS){console.log("dismissed")}})}function PercentageAnimator(b,a){this.animationSpeed=10;this.increment=2;this.curPercentage=0;this.targetPercentage=a;this.outputSelector=b;this.animate=function(c){this.targetPercentage=c;setTimeout(PercentageTimer.bind(null,this),this.animationSpeed)}}function PercentageTimer(a){if(a.curPercentage-a.targetPercentage<-a.increment){a.curPercentage+=a.increment}else{if(a.curPercentage-a.targetPercentage>a.increment){a.curPercentage-=a.increment}else{a.curPercentage=a.targetPercentage}}jQuery(a.outputSelector).text(a.curPercentage+"%");if(a.curPercentage!=a.targetPercentage){setTimeout(PercentageTimer.bind(null,a),a.animationSpeed)}}function progressUpdate(c,b){var a=jQuery("#bulk-progress");if(a.length){jQuery(".progress-left",a).css("width",c+"%");jQuery(".progress-img",a).css("left",c+"%");if(c>24){jQuery(".progress-img span",a).html("");jQuery(".progress-left",a).html(c+"%")}else{jQuery(".progress-img span",a).html(c+"%");jQuery(".progress-left",a).html("")}jQuery(".bulk-estimate").html(b)}}function sliderUpdate(g,c,d,e,b){var f=jQuery(".bulk-slider div.bulk-slide:first-child");if(f.length===0){return}if(f.attr("id")!="empty-slide"){f.hide()}f.css("z-index",1000);jQuery(".bulk-img-opt",f).attr("src","");if(typeof d==="undefined"){d=""}if(d.length>0){jQuery(".bulk-img-orig",f).attr("src","")}var a=f.clone();a.attr("id","slide-"+g);jQuery(".bulk-img-opt",a).attr("src",c);if(d.length>0){jQuery(".img-original",a).css("display","inline-block");jQuery(".bulk-img-orig",a).attr("src",d)}else{jQuery(".img-original",a).css("display","none")}jQuery(".bulk-opt-percent",a).html('<input type="text" class="dial" value="'+e+'"/>');jQuery(".bulk-slider").append(a);ShortPixel.percentDial("#"+a.attr("id")+" .dial",100);jQuery(".bulk-slider-container span.filename").html("&nbsp;&nbsp;"+b);if(f.attr("id")=="empty-slide"){f.remove();jQuery(".bulk-slider-container").css("display","block")}else{f.animate({left:f.width()+f.position().left},"slow","swing",function(){f.remove();a.fadeIn("slow")})}}function hideSlider(){jQuery(".bulk-slider-container").css("display","none")}function showStats(){var a=jQuery(".bulk-stats");if(a.length>0){}}if(!(typeof String.prototype.format=="function")){String.prototype.format=function(){var b=this,a=arguments.length;while(a--){b=b.replace(new RegExp("\\{"+a+"\\}","gm"),arguments[a])}return b}};
1
+ jQuery(document).ready(function(a){ShortPixel.init()});var ShortPixel=function(){function F(){if(typeof ShortPixel.API_KEY!=="undefined"){return}if(jQuery("table.wp-list-table.media").length>0){jQuery('select[name^="action"] option:last-child').before('<option value="short-pixel-bulk">'+_spTr.optimizeWithSP+"</option>")}ShortPixel.setOptions(ShortPixelConstants);if(jQuery("#backup-folder-size").length){jQuery("#backup-folder-size").html(ShortPixel.getBackupSize())}if(ShortPixel.MEDIA_ALERT=="todo"&&jQuery("div.media-frame.mode-grid").length>0){jQuery("div.media-frame.mode-grid").before('<div id="short-pixel-media-alert" class="notice notice-warning"><p>'+_spTr.changeMLToListMode.format('<a href="upload.php?mode=list" class="view-list"><span class="screen-reader-text">'," </span>",'</a><a class="alignright" href="javascript:ShortPixel.dismissMediaAlert();">',"</a>")+"</p></div>")}jQuery(window).on("beforeunload",function(){if(ShortPixel.bulkProcessor==true){clearBulkProcessor()}});checkQuotaExceededAlert();checkBulkProgress()}function l(N){for(var O in N){ShortPixel[O]=N[O]}}function s(N){return/^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{1,63})+$/.test(N)}function m(){var N=jQuery("#pluginemail").val();if(ShortPixel.isEmailValid(N)){jQuery("#request_key").removeClass("disabled")}jQuery("#request_key").attr("href",jQuery("#request_key").attr("href").split("?")[0]+"?pluginemail="+N)}function a(){jQuery("#valid").val("validate");jQuery("#wp_shortpixel_options").submit()}jQuery("#key").keypress(function(N){if(N.which==13){jQuery("#valid").val("validate")}});function I(N){if(jQuery(N).is(":checked")){jQuery("#width,#height").removeAttr("disabled")}else{jQuery("#width,#height").attr("disabled","disabled")}}function e(N,P,R){for(var O=0,Q=null;O<N.length;O++){N[O].onclick=function(){if(this!==Q){Q=this}alert(_spTr.alertOnlyAppliesToNewImages)}}ShortPixel.enableResize("#resize");jQuery("#resize").change(function(){I(this)});jQuery(".resize-sizes").blur(function(T){var U=jQuery(this);if(ShortPixel.resizeSizesAlert==U.val()){return}ShortPixel.resizeSizesAlert=U.val();var S=jQuery("#min-"+U.attr("name")).val();if(U.val()<Math.min(S,1024)){if(S>1024){alert(_spTr.pleaseDoNotSetLesser1024.format(U.attr("name")))}else{alert(_spTr.pleaseDoNotSetLesserSize.format(U.attr("name"),U.attr("name"),S))}T.preventDefault();U.focus()}else{this.defaultValue=U.val()}});jQuery(".shortpixel-confirm").click(function(T){var S=confirm(T.target.getAttribute("data-confirm"));if(!S){T.preventDefault();return false}return true})}function t(){jQuery("input.remove-folder-button").click(function(){var O=jQuery(this).data("value");var N=confirm(_spTr.areYouSureStopOptimizing.format(O));if(N==true){jQuery("#removeFolder").val(O);jQuery("#wp_shortpixel_options").submit()}});jQuery("input.recheck-folder-button").click(function(){var O=jQuery(this).data("value");var N=confirm(_spTr.areYouSureStopOptimizing.format(O));if(N==true){jQuery("#recheckFolder").val(O);jQuery("#wp_shortpixel_options").submit()}})}function H(N){var O=jQuery("#"+(N.checked?"total":"main")+"ToProcess").val();jQuery("div.bulk-play span.total").text(O);jQuery("#displayTotal").text(O)}function w(O){var N=jQuery("section#"+O);if(N.length>0){jQuery("section").removeClass("sel-tab");jQuery("section#"+O).addClass("sel-tab")}}function x(){var N=jQuery("section#tab-settings .wp-shortpixel-options").height()+90;N=Math.max(N,jQuery("section#tab-adv-settings .wp-shortpixel-options").height()+20);N=Math.max(N,jQuery("section#tab-resources .area1").height()+60);jQuery("#shortpixel-settings-tabs").css("height",N);jQuery("#shortpixel-settings-tabs section").css("height",N)}function J(){var N={action:"shortpixel_dismiss_media_alert"};jQuery.get(ShortPixel.AJAX_URL,N,function(O){N=JSON.parse(O);if(N.Status=="success"){jQuery("#short-pixel-media-alert").hide();console.log("dismissed")}})}function j(){var N={action:"shortpixel_check_quota"};jQuery.get(ShortPixel.AJAX_URL,N,function(){console.log("quota refreshed")})}function z(N){if(N.checked){jQuery("#with-thumbs").css("display","inherit");jQuery("#without-thumbs").css("display","none")}else{jQuery("#without-thumbs").css("display","inherit");jQuery("#with-thumbs").css("display","none")}}function b(R,P,O,Q,N){return(P>0?"<div class='sp-column-info'>"+_spTr.reducedBy+" <strong><span class='percent'>"+P+"%</span></strong> ":"")+(P>0&&P<5?"<br>":"")+(P<5?_spTr.bonusProcessing:"")+(O.length>0?" ("+O+")":"")+(0+Q>0?"<br>"+_spTr.plusXthumbsOpt.format(Q):"")+(0+N>0?"<br>"+_spTr.plusXretinasOpt.format(N):"")+"</div>"}function o(O,N){jQuery(O).knob({readOnly:true,width:N,height:N,fgColor:"#1CAECB",format:function(P){return P+"%"}})}function c(U,P,S,R,O,T){if(O==1){var Q=jQuery(".sp-column-actions-template").clone();if(!Q.length){return false}var N;if(P.length==0){N=["lossy","lossless"]}else{N=["lossy","glossy","lossless"].filter(function(V){return !(V==P)})}Q.html(Q.html().replace(/__SP_ID__/g,U));if(T.substr(T.lastIndexOf(".")+1).toLowerCase()=="pdf"){jQuery(".sp-action-compare",Q).remove()}if(S==0&&R>0){Q.html(Q.html().replace("__SP_THUMBS_TOTAL__",R))}else{jQuery(".sp-action-optimize-thumbs",Q).remove();jQuery(".sp-dropbtn",Q).removeClass("button-primary")}Q.html(Q.html().replace(/__SP_FIRST_TYPE__/g,N[0]));Q.html(Q.html().replace(/__SP_SECOND_TYPE__/g,N[1]));return Q.html()}return""}function h(R,Q){R=R.substring(2);if(jQuery(".shortpixel-other-media").length){var P=["optimize","retry","restore","redo","quota","view"];for(var O=0,N=P.length;O<N;O++){jQuery("#"+P[O]+"_"+R).css("display","none")}for(var O=0,N=Q.length;O<N;O++){jQuery("#"+Q[O]+"_"+R).css("display","")}}}function i(N){ShortPixel.retries++;if(isNaN(ShortPixel.retries)){ShortPixel.retries=1}if(ShortPixel.retries<6){console.log("Invalid response from server (Error: "+N+"). Retrying pass "+(ShortPixel.retries+1)+"...");setTimeout(checkBulkProgress,5000)}else{ShortPixel.bulkShowError(-1,"Invalid response from server received 6 times. Please retry later by reloading this page, or <a href='https://shortpixel.com/contact' target='_blank'>contact support</a>. (Error: "+N+")","");console.log("Invalid response from server 6 times. Giving up.")}}function k(N){N.action="shortpixel_browse_content";var O="";jQuery.ajax({type:"POST",url:ShortPixel.AJAX_URL,data:N,success:function(P){O=P},async:false});return O}function d(){var N={action:"shortpixel_get_backup_size"};var O="";jQuery.ajax({type:"POST",url:ShortPixel.AJAX_URL,data:N,success:function(P){O=P},async:false});return O}function f(O){jQuery("#request_key").addClass("disabled");jQuery("#pluginemail_spinner").addClass("is-active");ShortPixel.updateSignupEmail();if(ShortPixel.isEmailValid(jQuery("#pluginemail").val())){jQuery("#pluginemail-error").css("display","none");var N={action:"shortpixel_new_api_key",email:jQuery("#pluginemail").val()};jQuery.ajax({type:"POST",async:false,url:ShortPixel.AJAX_URL,data:N,success:function(P){data=JSON.parse(P);if(data.Status=="success"){O.preventDefault();window.location.reload()}else{if(data.Status=="invalid"){jQuery("#pluginemail-error").html("<b>"+data.Details+"</b>");jQuery("#pluginemail-error").css("display","");jQuery("#pluginemail-info").css("display","none");O.preventDefault()}else{}}}});jQuery("#request_key").removeAttr("onclick")}else{jQuery("#pluginemail-error").css("display","");jQuery("#pluginemail-info").css("display","none");O.preventDefault()}jQuery("#request_key").removeClass("disabled");jQuery("#pluginemail_spinner").removeClass("is-active")}function K(){jQuery("#shortPixelProposeUpgrade .sp-modal-body").addClass("sptw-modal-spinner");jQuery("#shortPixelProposeUpgrade .sp-modal-body").html("");jQuery("#shortPixelProposeUpgradeShade").css("display","block");jQuery("#shortPixelProposeUpgrade").removeClass("shortpixel-hide");var N={action:"shortpixel_propose_upgrade"};jQuery.ajax({type:"POST",url:ShortPixel.AJAX_URL,data:N,success:function(O){jQuery("#shortPixelProposeUpgrade .sp-modal-body").removeClass("sptw-modal-spinner");jQuery("#shortPixelProposeUpgrade .sp-modal-body").html(O)}})}function D(){jQuery("#shortPixelProposeUpgradeShade").css("display","none");jQuery("#shortPixelProposeUpgrade").addClass("shortpixel-hide");if(ShortPixel.toRefresh){ShortPixel.recheckQuota()}}function u(){jQuery("#short-pixel-notice-unlisted").hide();jQuery("#optimizeUnlisted").prop("checked",true);var N={action:"shortpixel_dismiss_notice",notice_id:"unlisted",notice_data:"true"};jQuery.get(ShortPixel.AJAX_URL,N,function(O){N=JSON.parse(O);if(N.Status==ShortPixel.STATUS_SUCCESS){console.log("dismissed")}})}function n(){jQuery(".select-folder-button").click(function(){jQuery(".sp-folder-picker-shade").css("display","block");jQuery(".sp-folder-picker").fileTree({script:ShortPixel.browseContent,multiFolder:false})});jQuery(".shortpixel-modal input.select-folder-cancel").click(function(){jQuery(".sp-folder-picker-shade").css("display","none")});jQuery(".shortpixel-modal input.select-folder").click(function(){var N=jQuery("UL.jqueryFileTree LI.directory.selected A").attr("rel").trim();if(N){var O=jQuery("#customFolderBase").val()+N;if(O.slice(-1)=="/"){O=O.slice(0,-1)}jQuery("#addCustomFolder").val(O);jQuery("#addCustomFolderView").val(O);jQuery(".sp-folder-picker-shade").css("display","none")}else{alert("Please select a folder from the list.")}})}function C(R,Q,P){var O=jQuery(".bulk-notice-msg.bulk-lengthy");if(O.length==0){return}var N=jQuery("a",O);N.text(Q);if(P){N.attr("href",P)}else{N.attr("href",N.data("href").replace("__ID__",R))}O.css("display","block")}function y(){jQuery(".bulk-notice-msg.bulk-lengthy").css("display","none")}function v(N){var O=jQuery(".bulk-notice-msg.bulk-"+N);if(O.length==0){return}O.css("display","block")}function L(N){jQuery(".bulk-notice-msg.bulk-"+N).css("display","none")}function r(T,R,S,Q){var N=jQuery("#bulk-error-template");if(N.length==0){return}var P=N.clone();P.attr("id","bulk-error-"+T);if(T==-1){jQuery("span.sp-err-title",P).remove();P.addClass("bulk-error-fatal")}else{jQuery("img",P).remove();jQuery("#bulk-error-".id).remove()}jQuery("span.sp-err-content",P).html(R);var O=jQuery("a.sp-post-link",P);if(Q){O.attr("href",Q)}else{O.attr("href",O.attr("href").replace("__ID__",T))}O.text(S);N.after(P);P.css("display","block")}function A(N,O){if(!confirm(_spTr["confirmBulk"+N])){O.stopPropagation();O.preventDefault();return false}return true}function q(N){jQuery(N).parent().parent().remove()}function E(N){return N.substring(0,2)=="C-"}function G(){window.location.href=window.location.href+(window.location.href.indexOf("?")>0?"&":"?")+"checkquota=1"}function g(O){O.preventDefault();if(!this.menuCloseEvent){jQuery(window).click(function(P){if(!P.target.matches(".sp-dropbtn")){jQuery(".sp-dropdown.sp-show").removeClass("sp-show")}});this.menuCloseEvent=true}var N=O.target.parentElement.classList.contains("sp-show");jQuery(".sp-dropdown.sp-show").removeClass("sp-show");if(!N){O.target.parentElement.classList.add("sp-show")}}function M(N){this.comparerData.origUrl=false;if(this.comparerData.cssLoaded===false){jQuery("<link>").appendTo("head").attr({type:"text/css",rel:"stylesheet",href:this.WP_PLUGIN_URL+"/res/css/twentytwenty.min.css"});this.comparerData.cssLoaded=2}if(this.comparerData.jsLoaded===false){jQuery.getScript(this.WP_PLUGIN_URL+"/res/js/jquery.twentytwenty.min.js",function(){ShortPixel.comparerData.jsLoaded=2;if(ShortPixel.comparerData.origUrl.length>0){ShortPixel.displayComparerPopup(ShortPixel.comparerData.width,ShortPixel.comparerData.height,ShortPixel.comparerData.origUrl,ShortPixel.comparerData.optUrl)}});this.comparerData.jsLoaded=1;jQuery(".sp-close-button").click(ShortPixel.closeComparerPopup)}if(this.comparerData.origUrl===false){jQuery.ajax({type:"POST",url:ShortPixel.AJAX_URL,data:{action:"shortpixel_get_comparer_data",id:N},success:function(O){data=JSON.parse(O);jQuery.extend(ShortPixel.comparerData,data);if(ShortPixel.comparerData.jsLoaded==2){ShortPixel.displayComparerPopup(ShortPixel.comparerData.width,ShortPixel.comparerData.height,ShortPixel.comparerData.origUrl,ShortPixel.comparerData.optUrl)}}});this.comparerData.origUrl=""}}function B(R,P,O,Q){var U=R;var T=(P<150||R<350);var S=jQuery(T?"#spUploadCompareSideBySide":"#spUploadCompare");if(!T){jQuery("#spCompareSlider").html('<img class="spUploadCompareOriginal"/><img class="spUploadCompareOptimized"/>')}R=Math.max(350,Math.min(800,(R<350?(R+25)*2:(P<150?R+25:R))));P=Math.max(150,(T?(U>350?2*(P+45):P+45):P*R/U));jQuery(".sp-modal-body",S).css("width",R);jQuery(".shortpixel-slider",S).css("width",R);S.css("width",R);jQuery(".sp-modal-body",S).css("height",P);S.css("display","block");S.parent().css("display","block");if(!T){jQuery("#spCompareSlider").twentytwenty({slider_move:"mousemove"})}jQuery(document).on("keyup.sp_modal_active",ShortPixel.closeComparerPopup);var N=jQuery(".spUploadCompareOptimized",S);jQuery(".spUploadCompareOriginal",S).attr("src",O);setTimeout(function(){jQuery(window).trigger("resize")},1000);N.load(function(){jQuery(window).trigger("resize")});N.attr("src",Q)}function p(N){jQuery("#spUploadCompareSideBySide").parent().css("display","none");jQuery("#spUploadCompareSideBySide").css("display","none");jQuery("#spUploadCompare").css("display","none");jQuery(document).unbind("keyup.sp_modal_active")}return{init:F,setOptions:l,isEmailValid:s,updateSignupEmail:m,validateKey:a,enableResize:I,setupGeneralTab:e,setupAdvancedTab:t,checkThumbsUpdTotal:H,switchSettingsTab:w,adjustSettingsTabs:x,onBulkThumbsCheck:z,dismissMediaAlert:J,checkQuota:j,percentDial:o,successMsg:b,successActions:c,otherMediaUpdateActions:h,retry:i,initFolderSelector:n,browseContent:k,getBackupSize:d,newApiKey:f,proposeUpgrade:K,closeProposeUpgrade:D,includeUnlisted:u,bulkShowLengthyMsg:C,bulkHideLengthyMsg:y,bulkShowMaintenanceMsg:v,bulkHideMaintenanceMsg:L,bulkShowError:r,confirmBulkAction:A,removeBulkMsg:q,isCustomImageId:E,recheckQuota:G,openImageMenu:g,menuCloseEvent:false,loadComparer:M,displayComparerPopup:B,closeComparerPopup:p,comparerData:{cssLoaded:false,jsLoaded:false,origUrl:false,optUrl:false,width:0,height:0},toRefresh:false,resizeSizesAlert:false}}();function showToolBarAlert(c,b,d){var a=jQuery("li.shortpixel-toolbar-processing");switch(c){case ShortPixel.STATUS_QUOTA_EXCEEDED:if(window.location.href.search("wp-short-pixel-bulk")>0&&jQuery(".sp-quota-exceeded-alert").length==0){location.reload();return}a.addClass("shortpixel-alert");a.addClass("shortpixel-quota-exceeded");jQuery("a",a).attr("href","options-general.php?page=wp-shortpixel");jQuery("a div",a).attr("title","ShortPixel quota exceeded. Click for details.");break;case ShortPixel.STATUS_SKIP:case ShortPixel.STATUS_FAIL:a.addClass("shortpixel-alert shortpixel-processing");jQuery("a div",a).attr("title",b);if(typeof d!=="undefined"){jQuery("a",a).attr("href","post.php?post="+d+"&action=edit")}break;case ShortPixel.STATUS_NO_KEY:a.addClass("shortpixel-alert");a.addClass("shortpixel-quota-exceeded");jQuery("a",a).attr("href","options-general.php?page=wp-shortpixel");jQuery("a div",a).attr("title","Get API Key");break;case ShortPixel.STATUS_SUCCESS:case ShortPixel.STATUS_RETRY:a.addClass("shortpixel-processing");a.removeClass("shortpixel-alert");jQuery("a",a).removeAttr("target");jQuery("a",a).attr("href",jQuery("a img",a).attr("success-url"))}a.removeClass("shortpixel-hide")}function hideToolBarAlert(){jQuery("li.shortpixel-toolbar-processing.shortpixel-processing").addClass("shortpixel-hide")}function hideQuotaExceededToolBarAlert(){jQuery("li.shortpixel-toolbar-processing.shortpixel-quota-exceeded").addClass("shortpixel-hide")}function checkQuotaExceededAlert(){if(typeof shortPixelQuotaExceeded!="undefined"){if(shortPixelQuotaExceeded==1){showToolBarAlert(ShortPixel.STATUS_QUOTA_EXCEEDED)}else{hideQuotaExceededToolBarAlert()}}}function checkBulkProgress(){var b=function(f){if(!d){d=true;return f}return"/"};var d=false;var a=window.location.href.toLowerCase().replace(/\/\//g,b);d=false;var c=ShortPixel.WP_ADMIN_URL.toLowerCase().replace(/\/\//g,b);if(a.search(c)<0){var e=document.createElement("a");e.href=a;a=a.replace(e.protocol+"//"+e.hostname,e.protocol+"//"+e.hostname.split(".").map(function(f){return sp_punycode.toASCII(f)}).join("."))}if(a.search(c+"upload.php")<0&&a.search(c+"edit.php")<0&&a.search(c+"edit-tags.php")<0&&a.search(c+"post-new.php")<0&&a.search(c+"post.php")<0&&a.search("page=nggallery-manage-gallery")<0&&(ShortPixel.FRONT_BOOTSTRAP==0||a.search(c)==0)){hideToolBarAlert();return}if(ShortPixel.bulkProcessor==true&&window.location.href.search("wp-short-pixel-bulk")<0&&typeof localStorage.bulkPage!=="undefined"&&localStorage.bulkPage>0){ShortPixel.bulkProcessor=false}if(window.location.href.search("wp-short-pixel-bulk")>=0){ShortPixel.bulkProcessor=true;localStorage.bulkTime=Math.floor(Date.now()/1000);localStorage.bulkPage=1}if(ShortPixel.bulkProcessor==true||typeof localStorage.bulkTime=="undefined"||Math.floor(Date.now()/1000)-localStorage.bulkTime>90){ShortPixel.bulkProcessor=true;localStorage.bulkPage=(window.location.href.search("wp-short-pixel-bulk")>=0?1:0);localStorage.bulkTime=Math.floor(Date.now()/1000);console.log(localStorage.bulkTime);checkBulkProcessingCallApi()}else{setTimeout(checkBulkProgress,5000)}}function checkBulkProcessingCallApi(){var a={action:"shortpixel_image_processing"};jQuery.ajax({type:"POST",url:ShortPixel.AJAX_URL,data:a,success:function(g){if(g.length>0){var i=null;try{var i=JSON.parse(g)}catch(k){ShortPixel.retry(k.message);return}ShortPixel.retries=0;var d=i.ImageID;var j=(jQuery("div.short-pixel-bulk-page").length>0);switch(i.Status){case ShortPixel.STATUS_NO_KEY:setCellMessage(d,i.Message,'<a class=\'button button-smaller button-primary\' href="https://shortpixel.com/wp-apikey" target="_blank">'+_spTr.getApiKey+"</a>");showToolBarAlert(ShortPixel.STATUS_NO_KEY);break;case ShortPixel.STATUS_QUOTA_EXCEEDED:setCellMessage(d,i.Message,"<a class='button button-smaller button-primary' href=\"https://shortpixel.com/login/"+ShortPixel.API_KEY+'" target="_blank">'+_spTr.extendQuota+"</a><a class='button button-smaller' href='admin.php?action=shortpixel_check_quota'>"+_spTr.check__Quota+"</a>");showToolBarAlert(ShortPixel.STATUS_QUOTA_EXCEEDED);if(i.Stop==false){setTimeout(checkBulkProgress,5000)}ShortPixel.otherMediaUpdateActions(d,["quota","view"]);break;case ShortPixel.STATUS_FAIL:setCellMessage(d,i.Message,"<a class='button button-smaller button-primary' href=\"javascript:manualOptimization('"+d+"', false)\">"+_spTr.retry+"</a>");showToolBarAlert(ShortPixel.STATUS_FAIL,i.Message,d);if(j){ShortPixel.bulkShowError(d,i.Message,i.Filename,i.CustomImageLink);if(i.BulkPercent){progressUpdate(i.BulkPercent,i.BulkMsg)}ShortPixel.otherMediaUpdateActions(d,["retry","view"])}console.log(i.Message);setTimeout(checkBulkProgress,5000);break;case ShortPixel.STATUS_EMPTY_QUEUE:console.log(i.Message);clearBulkProcessor();hideToolBarAlert();var c=jQuery("#bulk-progress");if(j&&c.length&&i.BulkStatus!="2"){progressUpdate(100,"Bulk finished!");jQuery("a.bulk-cancel").attr("disabled","disabled");hideSlider();setTimeout(function(){window.location.reload()},3000)}break;case ShortPixel.STATUS_SUCCESS:if(j){ShortPixel.bulkHideLengthyMsg();ShortPixel.bulkHideMaintenanceMsg()}var l=i.PercentImprovement;showToolBarAlert(ShortPixel.STATUS_SUCCESS,"");var b=ShortPixel.isCustomImageId(d)?"":ShortPixel.successActions(d,i.Type,i.ThumbsCount,i.ThumbsTotal,i.BackupEnabled,i.Filename);setCellMessage(d,ShortPixel.successMsg(d,l,i.Type,i.ThumbsCount,i.RetinasCount),b);var h=jQuery(["restore","view","redolossy","redoglossy","redolossless"]).not(["redo"+i.Type]).get();ShortPixel.otherMediaUpdateActions(d,h);var f=new PercentageAnimator("#sp-msg-"+d+" span.percent",l);f.animate(l);if(j&&typeof i.Thumb!=="undefined"){if(i.BulkPercent){progressUpdate(i.BulkPercent,i.BulkMsg)}if(i.Thumb.length>0){sliderUpdate(d,i.Thumb,i.BkThumb,i.PercentImprovement,i.Filename);if(typeof i.AverageCompression!=="undefined"&&0+i.AverageCompression>0){jQuery("#sp-avg-optimization").html('<input type="text" class="dial" value="'+Math.round(i.AverageCompression)+'"/>');ShortPixel.percentDial("#sp-avg-optimization .dial",60)}}}console.log("Server response: "+g);if(j&&typeof i.BulkPercent!=="undefined"){progressUpdate(i.BulkPercent,i.BulkMsg)}setTimeout(checkBulkProgress,5000);break;case ShortPixel.STATUS_SKIP:if(i.Silent!==1){ShortPixel.bulkShowError(d,i.Message,i.Filename,i.CustomImageLink)}case ShortPixel.STATUS_ERROR:if(typeof i.Message!=="undefined"){showToolBarAlert(ShortPixel.STATUS_SKIP,i.Message+" Image ID: "+d);setCellMessage(d,i.Message,"")}ShortPixel.otherMediaUpdateActions(d,["retry","view"]);case ShortPixel.STATUS_RETRY:console.log("Server response: "+g);showToolBarAlert(ShortPixel.STATUS_RETRY,"");if(j&&typeof i.BulkPercent!=="undefined"){progressUpdate(i.BulkPercent,i.BulkMsg)}if(j&&i.Count>3){ShortPixel.bulkShowLengthyMsg(d,i.Filename,i.CustomImageLink)}setTimeout(checkBulkProgress,5000);break;case ShortPixel.STATUS_MAINTENANCE:ShortPixel.bulkShowMaintenanceMsg("maintenance");setTimeout(checkBulkProgress,60000);break;case ShortPixel.STATUS_QUEUE_FULL:ShortPixel.bulkShowMaintenanceMsg("queue-full");setTimeout(checkBulkProgress,60000);break;default:ShortPixel.retry("Unknown status "+i.Status+". Retrying...");break}}},error:function(b){ShortPixel.retry(b.statusText)}})}function clearBulkProcessor(){ShortPixel.bulkProcessor=false;localStorage.bulkTime=0;if(window.location.href.search("wp-short-pixel-bulk")>=0){localStorage.bulkPage=0}}function setCellMessage(d,a,c){var b=jQuery("#sp-msg-"+d);if(b.length>0){b.html("<div class='sp-column-actions'>"+c+"</div><div class='sp-column-info'>"+a+"</div>");b.css("color","")}b=jQuery("#sp-cust-msg-"+d);if(b.length>0){b.html("<div class='sp-column-info'>"+a+"</div>")}}function manualOptimization(c,a){setCellMessage(c,"<img src='"+ShortPixel.WP_PLUGIN_URL+"/res/img/loading.gif' class='sp-loading-small'>Image waiting to be processed","");jQuery("li.shortpixel-toolbar-processing").removeClass("shortpixel-hide");jQuery("li.shortpixel-toolbar-processing").removeClass("shortpixel-alert");jQuery("li.shortpixel-toolbar-processing").addClass("shortpixel-processing");var b={action:"shortpixel_manual_optimization",image_id:c,cleanup:a};jQuery.ajax({type:"GET",url:ShortPixel.AJAX_URL,data:b,success:function(d){var e=JSON.parse(d);if(e.Status==ShortPixel.STATUS_SUCCESS){setTimeout(checkBulkProgress,2000)}else{setCellMessage(c,typeof e.Message!=="undefined"?e.Message:_spTr.thisContentNotProcessable,"")}},error:function(d){b.action="shortpixel_check_status";jQuery.ajax({type:"GET",url:ShortPixel.AJAX_URL,data:b,success:function(e){var f=JSON.parse(e);if(f.Status!==ShortPixel.STATUS_SUCCESS){setCellMessage(c,typeof f.Message!=="undefined"?f.Message:_spTr.thisContentNotProcessable,"")}}})}})}function reoptimize(c,a){setCellMessage(c,"<img src='"+ShortPixel.WP_PLUGIN_URL+"/res/img/loading.gif' class='sp-loading-small'>Image waiting to be reprocessed","");jQuery("li.shortpixel-toolbar-processing").removeClass("shortpixel-hide");jQuery("li.shortpixel-toolbar-processing").addClass("shortpixel-processing");var b={action:"shortpixel_redo",attachment_ID:c,type:a};jQuery.get(ShortPixel.AJAX_URL,b,function(d){b=JSON.parse(d);if(b.Status==ShortPixel.STATUS_SUCCESS){setTimeout(checkBulkProgress,2000)}else{$msg=typeof b.Message!=="undefined"?b.Message:_spTr.thisContentNotProcessable;setCellMessage(c,$msg,"");showToolBarAlert(ShortPixel.STATUS_FAIL,$msg)}})}function optimizeThumbs(b){setCellMessage(b,"<img src='"+ShortPixel.WP_PLUGIN_URL+"/res/img/loading.gif' class='sp-loading-small'>"+_spTr.imageWaitOptThumbs,"");jQuery("li.shortpixel-toolbar-processing").removeClass("shortpixel-hide");jQuery("li.shortpixel-toolbar-processing").addClass("shortpixel-processing");var a={action:"shortpixel_optimize_thumbs",attachment_ID:b};jQuery.get(ShortPixel.AJAX_URL,a,function(c){a=JSON.parse(c);if(a.Status==ShortPixel.STATUS_SUCCESS){setTimeout(checkBulkProgress,2000)}else{setCellMessage(b,typeof a.Message!=="undefined"?a.Message:_spTr.thisContentNotProcessable,"")}})}function dismissShortPixelNoticeExceed(b){jQuery("#wp-admin-bar-shortpixel_processing").hide();var a={action:"shortpixel_dismiss_notice",notice_id:"exceed"};jQuery.get(ShortPixel.AJAX_URL,a,function(c){a=JSON.parse(c);if(a.Status==ShortPixel.STATUS_SUCCESS){console.log("dismissed")}});b.preventDefault()}function dismissShortPixelNotice(b){jQuery("#short-pixel-notice-"+b).hide();var a={action:"shortpixel_dismiss_notice",notice_id:b};jQuery.get(ShortPixel.AJAX_URL,a,function(c){a=JSON.parse(c);if(a.Status==ShortPixel.STATUS_SUCCESS){console.log("dismissed")}})}function PercentageAnimator(b,a){this.animationSpeed=10;this.increment=2;this.curPercentage=0;this.targetPercentage=a;this.outputSelector=b;this.animate=function(c){this.targetPercentage=c;setTimeout(PercentageTimer.bind(null,this),this.animationSpeed)}}function PercentageTimer(a){if(a.curPercentage-a.targetPercentage<-a.increment){a.curPercentage+=a.increment}else{if(a.curPercentage-a.targetPercentage>a.increment){a.curPercentage-=a.increment}else{a.curPercentage=a.targetPercentage}}jQuery(a.outputSelector).text(a.curPercentage+"%");if(a.curPercentage!=a.targetPercentage){setTimeout(PercentageTimer.bind(null,a),a.animationSpeed)}}function progressUpdate(c,b){var a=jQuery("#bulk-progress");if(a.length){jQuery(".progress-left",a).css("width",c+"%");jQuery(".progress-img",a).css("left",c+"%");if(c>24){jQuery(".progress-img span",a).html("");jQuery(".progress-left",a).html(c+"%")}else{jQuery(".progress-img span",a).html(c+"%");jQuery(".progress-left",a).html("")}jQuery(".bulk-estimate").html(b)}}function sliderUpdate(g,c,d,e,b){var f=jQuery(".bulk-slider div.bulk-slide:first-child");if(f.length===0){return}if(f.attr("id")!="empty-slide"){f.hide()}f.css("z-index",1000);jQuery(".bulk-img-opt",f).attr("src","");if(typeof d==="undefined"){d=""}if(d.length>0){jQuery(".bulk-img-orig",f).attr("src","")}var a=f.clone();a.attr("id","slide-"+g);jQuery(".bulk-img-opt",a).attr("src",c);if(d.length>0){jQuery(".img-original",a).css("display","inline-block");jQuery(".bulk-img-orig",a).attr("src",d)}else{jQuery(".img-original",a).css("display","none")}jQuery(".bulk-opt-percent",a).html('<input type="text" class="dial" value="'+e+'"/>');jQuery(".bulk-slider").append(a);ShortPixel.percentDial("#"+a.attr("id")+" .dial",100);jQuery(".bulk-slider-container span.filename").html("&nbsp;&nbsp;"+b);if(f.attr("id")=="empty-slide"){f.remove();jQuery(".bulk-slider-container").css("display","block")}else{f.animate({left:f.width()+f.position().left},"slow","swing",function(){f.remove();a.fadeIn("slow")})}}function hideSlider(){jQuery(".bulk-slider-container").css("display","none")}function showStats(){var a=jQuery(".bulk-stats");if(a.length>0){}}if(!(typeof String.prototype.format=="function")){String.prototype.format=function(){var b=this,a=arguments.length;while(a--){b=b.replace(new RegExp("\\{"+a+"\\}","gm"),arguments[a])}return b}};
shortpixel_api.php CHANGED
@@ -23,6 +23,8 @@ class ShortPixelAPI {
23
  const ERR_SAVE_BKP = -5;
24
  const ERR_INCORRECT_FILE_SIZE = -6;
25
  const ERR_DOWNLOAD = -7;
 
 
26
  const ERR_UNKNOWN = -999;
27
 
28
  private $_settings;
@@ -531,21 +533,13 @@ class ShortPixelAPI {
531
  if(file_exists($tempWebpFilePATH)) {
532
  $targetWebPFile = dirname($targetFile) . '/' . self::MB_basename($targetFile, '.' . pathinfo($targetFile, PATHINFO_EXTENSION)) . ".webp";
533
  copy($tempWebpFilePATH, $targetWebPFile);
534
-
535
- /* the webp thumbnails in metadata sizes is not working so deactivate for now
536
- $webpSize = $itemHandler->getWebpSizeMeta($targetFile);
537
- if($webpSize) {
538
- $webpSizes[$webpSize['key']] = $webpSize['val'];
539
- }
540
- */
541
  }
542
- @unlink($tempWebpFilePATH);
543
- }
544
 
545
  if ( $writeFailed > 0 )//there was an error
546
  {
547
  $msg = sprintf(__('Optimized version of %s file(s) couldn\'t be updated.','shortpixel-image-optimiser'),$writeFailed);
548
- //#ShortPixelAPI::SaveMessageinMetadata($ID, 'Error: optimized version of ' . $writeFailed . ' file(s) couldn\'t be updated.');
549
  $itemHandler->incrementRetries(1, self::ERR_SAVE, $msg);
550
  $this->_settings->bulkProcessingStatus = "error";
551
  return array("Status" => self::STATUS_FAIL, "Code" =>"write-fail", "Message" => $msg);
@@ -680,12 +674,4 @@ class ShortPixelAPI {
680
  static public function getCompressionTypeCode($compressionName) {
681
  return $compressionName == 'glossy' ? 2 : ($compressionName == 'lossy' ? 1 : 0);
682
  }
683
-
684
- static private function SaveMessageinMetadata($ID, $Message)
685
- {
686
- $meta = wp_get_attachment_metadata($ID);
687
- $meta['ShortPixelImprovement'] = $Message;
688
- unset($meta['ShortPixel']['WaitingProcessing']);
689
- wp_update_attachment_metadata($ID, $meta);
690
- }
691
  }
23
  const ERR_SAVE_BKP = -5;
24
  const ERR_INCORRECT_FILE_SIZE = -6;
25
  const ERR_DOWNLOAD = -7;
26
+ const ERR_PNG2JPG_MEMORY = -8;
27
+ const ERR_POSTMETA_CORRUPT = -9;
28
  const ERR_UNKNOWN = -999;
29
 
30
  private $_settings;
533
  if(file_exists($tempWebpFilePATH)) {
534
  $targetWebPFile = dirname($targetFile) . '/' . self::MB_basename($targetFile, '.' . pathinfo($targetFile, PATHINFO_EXTENSION)) . ".webp";
535
  copy($tempWebpFilePATH, $targetWebPFile);
536
+ @unlink($tempWebpFilePATH);
 
 
 
 
 
 
537
  }
538
+ }
 
539
 
540
  if ( $writeFailed > 0 )//there was an error
541
  {
542
  $msg = sprintf(__('Optimized version of %s file(s) couldn\'t be updated.','shortpixel-image-optimiser'),$writeFailed);
 
543
  $itemHandler->incrementRetries(1, self::ERR_SAVE, $msg);
544
  $this->_settings->bulkProcessingStatus = "error";
545
  return array("Status" => self::STATUS_FAIL, "Code" =>"write-fail", "Message" => $msg);
674
  static public function getCompressionTypeCode($compressionName) {
675
  return $compressionName == 'glossy' ? 2 : ($compressionName == 'lossy' ? 1 : 0);
676
  }
 
 
 
 
 
 
 
 
677
  }
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.9
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.9");
22
  define('SHORTPIXEL_MAX_TIMEOUT', 10);
23
  define('SHORTPIXEL_VALIDATE_MAX_TIMEOUT', 15);
24
  define('SHORTPIXEL_BACKUP', 'ShortpixelBackups');
@@ -37,7 +37,7 @@ require_once(ABSPATH . 'wp-admin/includes/file.php');
37
 
38
  $sp__uploads = wp_upload_dir();
39
  define('SHORTPIXEL_UPLOADS_BASE', $sp__uploads['basedir']);
40
- define('SHORTPIXEL_UPLOADS_URL', $sp__uploads['baseurl']);
41
  define('SHORTPIXEL_UPLOADS_NAME', basename(is_main_site() ? SHORTPIXEL_UPLOADS_BASE : dirname(dirname(SHORTPIXEL_UPLOADS_BASE))));
42
  $sp__backupBase = is_main_site() ? SHORTPIXEL_UPLOADS_BASE : dirname(dirname(SHORTPIXEL_UPLOADS_BASE));
43
  define('SHORTPIXEL_BACKUP_FOLDER', $sp__backupBase . '/' . SHORTPIXEL_BACKUP);
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.9.0
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.9.0");
22
  define('SHORTPIXEL_MAX_TIMEOUT', 10);
23
  define('SHORTPIXEL_VALIDATE_MAX_TIMEOUT', 15);
24
  define('SHORTPIXEL_BACKUP', 'ShortpixelBackups');
37
 
38
  $sp__uploads = wp_upload_dir();
39
  define('SHORTPIXEL_UPLOADS_BASE', $sp__uploads['basedir']);
40
+ define('SHORTPIXEL_UPLOADS_URL', is_main_site() ? $sp__uploads['baseurl'] : dirname(dirname($sp__uploads['baseurl'])));
41
  define('SHORTPIXEL_UPLOADS_NAME', basename(is_main_site() ? SHORTPIXEL_UPLOADS_BASE : dirname(dirname(SHORTPIXEL_UPLOADS_BASE))));
42
  $sp__backupBase = is_main_site() ? SHORTPIXEL_UPLOADS_BASE : dirname(dirname(SHORTPIXEL_UPLOADS_BASE));
43
  define('SHORTPIXEL_BACKUP_FOLDER', $sp__backupBase . '/' . SHORTPIXEL_BACKUP);