ShortPixel Image Optimizer - Version 4.10.0

Version Description

  • option to exclude thumbnails from optimization
  • options to delete Cloudflare cache for optimized images
  • method to define affilate codes for themes
  • error message when restore could not be performed
  • better handling of situations with files with different owner but with write permissions for all
  • fix bug for inner resize when setting and unsetting the resize parameter
  • fix bug for third-party WebP thumbnails registered in the 'sizes' metadata array which were sent to optimization.
  • check if function mb_convert_encoding exists before using it
Download this release

Release Info

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

Code changes from version 4.9.1 to 4.10.0

class/db/shortpixel-custom-meta-dao.php CHANGED
@@ -326,7 +326,7 @@ class ShortPixelCustomMetaDao {
326
  . "FROM {$this->db->getPrefix()}shortpixel_meta sm "
327
  . "INNER JOIN {$this->db->getPrefix()}shortpixel_folders sf on sm.folder_id = sf.id "
328
  . ($hasNextGen ? "LEFT JOIN {$this->db->getPrefix()}ngg_gallery ng on sf.path = ng.path " : " ")
329
- . "WHERE sf.status <> -1 ";
330
  foreach($filters as $field => $value) {
331
  $sql .= " AND sm.$field " . $value->operator . " ". $value->value . " ";
332
  }
326
  . "FROM {$this->db->getPrefix()}shortpixel_meta sm "
327
  . "INNER JOIN {$this->db->getPrefix()}shortpixel_folders sf on sm.folder_id = sf.id "
328
  . ($hasNextGen ? "LEFT JOIN {$this->db->getPrefix()}ngg_gallery ng on sf.path = ng.path " : " ")
329
+ . "WHERE sf.status <> -1 AND sm.status <> 3";
330
  foreach($filters as $field => $value) {
331
  $sql .= " AND sm.$field " . $value->operator . " ". $value->value . " ";
332
  }
class/db/shortpixel-meta-facade.php CHANGED
@@ -60,9 +60,11 @@ class ShortPixelMetaFacade {
60
  : null),
61
  "thumbsOpt" =>(isset($rawMeta["ShortPixel"]["thumbsOpt"]) ? $rawMeta["ShortPixel"]["thumbsOpt"] : null),
62
  "thumbsOptList" =>(isset($rawMeta["ShortPixel"]["thumbsOptList"]) ? $rawMeta["ShortPixel"]["thumbsOptList"] : array()),
 
63
  "thumbsMissing" =>(isset($rawMeta["ShortPixel"]["thumbsMissing"]) ? $rawMeta["ShortPixel"]["thumbsMissing"] : null),
64
  "retinasOpt" =>(isset($rawMeta["ShortPixel"]["retinasOpt"]) ? $rawMeta["ShortPixel"]["retinasOpt"] : null),
65
  "thumbsTodo" =>(isset($rawMeta["ShortPixel"]["thumbsTodo"]) ? $rawMeta["ShortPixel"]["thumbsTodo"] : false),
 
66
  "backup" => !isset($rawMeta['ShortPixel']['NoBackup']),
67
  "status" => (!isset($rawMeta["ShortPixel"]) ? 0
68
  : (isset($rawMeta["ShortPixelImprovement"]) && is_numeric($rawMeta["ShortPixelImprovement"])
@@ -135,7 +137,7 @@ class ShortPixelMetaFacade {
135
  if(null === $this->meta->getTsOptimized()) {
136
  unset($rawMeta['ShortPixel']['date']);
137
  } else {
138
- $rawMeta['ShortPixel']['date'] = date("Y-m-d", strtotime($this->meta->getTsOptimized()));
139
  }
140
 
141
  //thumbs were processed if settings or if they were explicitely requested
@@ -146,7 +148,14 @@ class ShortPixelMetaFacade {
146
  $rawMeta['ShortPixel']['thumbsOpt'] = $this->meta->getThumbsOpt();
147
  $rawMeta['ShortPixel']['thumbsOptList'] = $this->meta->getThumbsOptList();
148
  }
149
-
 
 
 
 
 
 
 
150
  $thumbsMissing = $this->meta->getThumbsMissing();
151
  if(is_array($thumbsMissing) && count($thumbsMissing)) {
152
  $rawMeta['ShortPixel']['thumbsMissing'] = $this->meta->getThumbsMissing();
@@ -223,7 +232,19 @@ class ShortPixelMetaFacade {
223
  wp_update_attachment_metadata($this->ID, $this->rawMeta);
224
  }
225
  }
226
-
 
 
 
 
 
 
 
 
 
 
 
 
227
  function incrementRetries($count = 1, $errorCode = ShortPixelAPI::ERR_UNKNOWN, $errorMessage = '') {
228
  if($this->type == self::CUSTOM_TYPE) {
229
  $this->meta->setRetries($this->meta->getRetries() + $count);
@@ -304,7 +325,7 @@ class ShortPixelMetaFacade {
304
  }
305
  }
306
 
307
- public function getURLsAndPATHs($processThumbnails, $onlyThumbs = false, $addRetina = true) {
308
  $sizesMissing = array();
309
 
310
  if($this->type == self::CUSTOM_TYPE) {
@@ -349,11 +370,19 @@ class ShortPixelMetaFacade {
349
  continue;
350
  }
351
 
 
 
 
 
 
 
 
 
352
  if(strpos($thumbnailName, ShortPixelMeta::WEBP_THUMB_PREFIX) === 0) {
353
  continue;
354
  }
355
 
356
- if(in_array($thumbnailInfo['file'], $meta->getThumbsOptList())) {
357
  continue;
358
  }
359
 
60
  : null),
61
  "thumbsOpt" =>(isset($rawMeta["ShortPixel"]["thumbsOpt"]) ? $rawMeta["ShortPixel"]["thumbsOpt"] : null),
62
  "thumbsOptList" =>(isset($rawMeta["ShortPixel"]["thumbsOptList"]) ? $rawMeta["ShortPixel"]["thumbsOptList"] : array()),
63
+ 'excludeSizes' =>(isset($rawMeta["ShortPixel"]["excludeSizes"]) ? $rawMeta["ShortPixel"]["excludeSizes"] : null),
64
  "thumbsMissing" =>(isset($rawMeta["ShortPixel"]["thumbsMissing"]) ? $rawMeta["ShortPixel"]["thumbsMissing"] : null),
65
  "retinasOpt" =>(isset($rawMeta["ShortPixel"]["retinasOpt"]) ? $rawMeta["ShortPixel"]["retinasOpt"] : null),
66
  "thumbsTodo" =>(isset($rawMeta["ShortPixel"]["thumbsTodo"]) ? $rawMeta["ShortPixel"]["thumbsTodo"] : false),
67
+ "tsOptimized" => (isset($rawMeta["ShortPixel"]["date"]) ? $rawMeta["ShortPixel"]["date"] : false),
68
  "backup" => !isset($rawMeta['ShortPixel']['NoBackup']),
69
  "status" => (!isset($rawMeta["ShortPixel"]) ? 0
70
  : (isset($rawMeta["ShortPixelImprovement"]) && is_numeric($rawMeta["ShortPixelImprovement"])
137
  if(null === $this->meta->getTsOptimized()) {
138
  unset($rawMeta['ShortPixel']['date']);
139
  } else {
140
+ $rawMeta['ShortPixel']['date'] = date("Y-m-d H:i:s", strtotime($this->meta->getTsOptimized()));
141
  }
142
 
143
  //thumbs were processed if settings or if they were explicitely requested
148
  $rawMeta['ShortPixel']['thumbsOpt'] = $this->meta->getThumbsOpt();
149
  $rawMeta['ShortPixel']['thumbsOptList'] = $this->meta->getThumbsOptList();
150
  }
151
+
152
+ //thumbs that were explicitely excluded from settings
153
+ if(null === $this->meta->getExcludeSizes()) {
154
+ unset($rawMeta['ShortPixel']['excludeSizes']);
155
+ } else {
156
+ $rawMeta['ShortPixel']['excludeSizes'] = $this->meta->getExcludeSizes();
157
+ }
158
+
159
  $thumbsMissing = $this->meta->getThumbsMissing();
160
  if(is_array($thumbsMissing) && count($thumbsMissing)) {
161
  $rawMeta['ShortPixel']['thumbsMissing'] = $this->meta->getThumbsMissing();
232
  wp_update_attachment_metadata($this->ID, $this->rawMeta);
233
  }
234
  }
235
+
236
+ function deleteAllSPMeta() {
237
+ if($this->type == self::CUSTOM_TYPE) {
238
+ throw new Exception("Not implemented 1");
239
+ } else {
240
+ unset($this->rawMeta["ShortPixelImprovement"]);
241
+ unset($this->rawMeta['ShortPixel']);
242
+ unset($this->rawMeta['ShortPixelPng2Jpg']);
243
+ unset($this->meta);
244
+ wp_update_attachment_metadata($this->ID, $this->rawMeta);
245
+ }
246
+ }
247
+
248
  function incrementRetries($count = 1, $errorCode = ShortPixelAPI::ERR_UNKNOWN, $errorMessage = '') {
249
  if($this->type == self::CUSTOM_TYPE) {
250
  $this->meta->setRetries($this->meta->getRetries() + $count);
325
  }
326
  }
327
 
328
+ public function getURLsAndPATHs($processThumbnails, $onlyThumbs = false, $addRetina = true, $excludeSizes = array(), $includeOptimized = false) {
329
  $sizesMissing = array();
330
 
331
  if($this->type == self::CUSTOM_TYPE) {
370
  continue;
371
  }
372
 
373
+ if(isset($thumbnailInfo['mime-type']) && $thumbnailInfo['mime-type'] == "image/webp") {
374
+ continue; // found a case when there were .jpg.webp thumbnails registered in sizes
375
+ }
376
+
377
+ if(in_array($thumbnailName, $excludeSizes)) {
378
+ continue;
379
+ }
380
+
381
  if(strpos($thumbnailName, ShortPixelMeta::WEBP_THUMB_PREFIX) === 0) {
382
  continue;
383
  }
384
 
385
+ if(!$includeOptimized && in_array($thumbnailInfo['file'], $meta->getThumbsOptList())) {
386
  continue;
387
  }
388
 
class/db/wp-shortpixel-media-library-adapter.php CHANGED
@@ -65,7 +65,7 @@ class WpShortPixelMediaLbraryAdapter {
65
  elseif ( $file->meta_key == "_wp_attachment_metadata" ) //_wp_attachment_metadata
66
  {
67
  $attachment = @unserialize($file->meta_value);
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();
@@ -236,15 +236,18 @@ class WpShortPixelMediaLbraryAdapter {
236
  return $wpdb->get_results($queryPostMeta);
237
  }
238
 
239
- public static function countNonWebpSizes($sizes) {
240
  $uniq = array();
 
241
  foreach($sizes as $key => $val) {
242
  if (strpos($key, ShortPixelMeta::WEBP_THUMB_PREFIX) === 0) continue;
 
 
243
  $uniq[$val['file']] = $key;
244
  }
245
  return count($uniq);
246
  }
247
-
248
  public static function cleanupFoundThumbs($itemHandler) {
249
  $meta = $itemHandler->getMeta();
250
  $sizesAll = $meta->getThumbs();
65
  elseif ( $file->meta_key == "_wp_attachment_metadata" ) //_wp_attachment_metadata
66
  {
67
  $attachment = @unserialize($file->meta_value);
68
+ $sizesCount = isset($attachment['sizes']) ? self::countSizesNotExcluded($attachment['sizes'], $settings->excludeSizes) : 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();
236
  return $wpdb->get_results($queryPostMeta);
237
  }
238
 
239
+ public static function countSizesNotExcluded($sizes, $exclude = false) {
240
  $uniq = array();
241
+ $exclude = is_array($exclude) ? $exclude : array(); //this is because it sometimes receives directly the setting which could be false
242
  foreach($sizes as $key => $val) {
243
  if (strpos($key, ShortPixelMeta::WEBP_THUMB_PREFIX) === 0) continue;
244
+ if (isset($val['mime-type']) && $val['mime-type'] == "image/webp") continue;
245
+ if (in_array($key, $exclude)) continue;
246
  $uniq[$val['file']] = $key;
247
  }
248
  return count($uniq);
249
  }
250
+
251
  public static function cleanupFoundThumbs($itemHandler) {
252
  $meta = $itemHandler->getMeta();
253
  $sizesAll = $meta->getThumbs();
class/front/img-to-picture-webp.php CHANGED
@@ -12,7 +12,7 @@ class ShortPixelImgToPictureWebp {
12
 
13
  $thisClass = __CLASS__; // hack for PHP 5.3 which doesn't accept self:: in closures
14
  return preg_replace_callback('/<img[^>]*>/', function ($match) use ($thisClass) {
15
- // Do nothing with images that has the 'rwp-not-responsive' class.
16
  if ( strpos($match[0], 'sp-no-webp') ) { return $match[0]; }
17
 
18
  $img = $thisClass::get_attributes($match[0]);
@@ -87,7 +87,9 @@ class ShortPixelImgToPictureWebp {
87
 
88
  public static function get_attributes( $image_node )
89
  {
90
- $image_node = mb_convert_encoding($image_node, 'HTML-ENTITIES', 'UTF-8');
 
 
91
  $dom = new DOMDocument();
92
  @$dom->loadHTML($image_node);
93
  $image = $dom->getElementsByTagName('img')->item(0);
12
 
13
  $thisClass = __CLASS__; // hack for PHP 5.3 which doesn't accept self:: in closures
14
  return preg_replace_callback('/<img[^>]*>/', function ($match) use ($thisClass) {
15
+ // Do nothing with images that have the 'sp-no-webp' class.
16
  if ( strpos($match[0], 'sp-no-webp') ) { return $match[0]; }
17
 
18
  $img = $thisClass::get_attributes($match[0]);
87
 
88
  public static function get_attributes( $image_node )
89
  {
90
+ if(function_exists("mb_convert_encoding")) {
91
+ $image_node = mb_convert_encoding($image_node, 'HTML-ENTITIES', 'UTF-8');
92
+ }
93
  $dom = new DOMDocument();
94
  @$dom->loadHTML($image_node);
95
  $image = $dom->getElementsByTagName('img')->item(0);
class/model/shortpixel-meta.php CHANGED
@@ -14,6 +14,7 @@ class ShortPixelMeta extends ShortPixelEntity{
14
  protected $png2Jpg;
15
  protected $thumbsOpt;
16
  protected $thumbsOptList;
 
17
  protected $thumbsMissing;
18
  protected $retinasOpt;
19
  protected $thumbsTodo;
@@ -158,6 +159,22 @@ class ShortPixelMeta extends ShortPixelEntity{
158
  $this->thumbsOptList = $thumbsOptList;
159
  }
160
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
161
  function getThumbsMissing() {
162
  return $this->thumbsMissing;
163
  }
14
  protected $png2Jpg;
15
  protected $thumbsOpt;
16
  protected $thumbsOptList;
17
+ protected $excludeSizes;
18
  protected $thumbsMissing;
19
  protected $retinasOpt;
20
  protected $thumbsTodo;
159
  $this->thumbsOptList = $thumbsOptList;
160
  }
161
 
162
+ /**
163
+ * @return mixed
164
+ */
165
+ public function getExcludeSizes()
166
+ {
167
+ return $this->excludeSizes;
168
+ }
169
+
170
+ /**
171
+ * @param mixed $excludeSizes
172
+ */
173
+ public function setExcludeSizes($excludeSizes)
174
+ {
175
+ $this->excludeSizes = $excludeSizes;
176
+ }
177
+
178
  function getThumbsMissing() {
179
  return $this->thumbsMissing;
180
  }
class/shortpixel-png2jpg.php CHANGED
@@ -330,4 +330,4 @@ class ShortPixelPng2Jpg {
330
  }
331
  return $data;
332
  }
333
- }
330
  }
331
  return $data;
332
  }
333
+ }
class/view/shortpixel_view.php CHANGED
@@ -71,21 +71,21 @@ class ShortPixelView {
71
  . '<a href="options-general.php?page=wp-shortpixel">ShortPixel Settings</a> page in your WordPress Admin.','shortpixel-image-optimiser');?>
72
  </p>
73
  <p><?php _e('If you don’t have an API Key, you can get one delivered to your inbox, for free.','shortpixel-image-optimiser');?></p>
74
- <p><?php _e('Please <a href="https://shortpixel.com/wp-apikey" target="_blank">sign up to get your API key.</a>','shortpixel-image-optimiser');?>
75
  </p>
76
  <?php
77
  }
78
 
79
- public static function displayActivationNotice($when = 'activate', $extra = '') {
80
- $extraStyle = $when == 'compat' || $when == 'fileperms' ? "style='border-left: 4px solid #ff0000;background-color: #ff9999;margin: 5px 20px 15px 0;'" :
81
- ($when == 'upgmonth' || $when == 'upgbulk' ? "style='border-left: 4px solid #46b450;'" : '');
82
- $icon = false; $extraClass = '';
83
  switch($when) {
84
- case 'compat': $extraClass = 'below-h2';
85
- case 'fileperms': $icon = 'scared'; break;
86
  case 'unlisted': $icon = 'magnifier'; break;
87
  case 'upgmonth':
88
- case 'upgbulk': $icon = 'notes'; break;
 
89
  }
90
  ?>
91
  <div class='notice <?php echo($extraClass);?> notice-warning' id='short-pixel-notice-<?php echo($when);?>' <?php echo($extraStyle);?>>
@@ -99,14 +99,18 @@ class ShortPixelView {
99
  <a href="javascript:ShortPixel.includeUnlisted()" class="button button-primary" style="margin-top:10px;margin-left:10px;">
100
  <strong><?php _e('Yes, include these thumbnails','shortpixel-image-optimiser');?></strong></a>
101
  <?php }
102
- if($when !== 'fileperms' && $when !== 'compat') { ?>
103
  <a href="javascript:dismissShortPixelNotice('<?php echo($when);?>')" class="button" style="margin-top:10px;"><?php _e('Dismiss','shortpixel-image-optimiser');?></a>
104
  <?php }
105
  if($when == 'compat') { ?>
106
  <a href="javascript:dismissShortPixelNotice('<?php echo($when);?>')" class="button" style="margin-top:10px;"><?php _e('I know what I\'m doing','shortpixel-image-optimiser');?></a>
107
  <?php } ?>
108
  </div>
109
- <?php if($icon){ ?>
 
 
 
 
110
  <img src="<?php echo(plugins_url('/shortpixel-image-optimiser/res/img/robo-' . $icon . '.png'));?>"
111
  srcset='<?php echo(plugins_url( 'shortpixel-image-optimiser/res/img/robo-' . $icon . '.png' ));?> 1x, <?php echo(plugins_url( 'shortpixel-image-optimiser/res/img/robo-' . $icon . '@2x.png' ));?> 2x'
112
  class='short-pixel-notice-icon'>
@@ -164,6 +168,7 @@ class ShortPixelView {
164
  </p><?php
165
  break;
166
  case 'generic' :
 
167
  echo("<p>$extra</p>");
168
  break;
169
  }
@@ -252,7 +257,7 @@ class ShortPixelView {
252
  <?php if($quotaData['mainProcessedMlFiles'] > 0) {?>
253
  <div style="position: absolute;bottom: 10px;right: 10px;">
254
  <input type='submit' name='bulkRestore' id='bulkRestore' class='button' value='<?php _e('Bulk Restore Media Library','shortpixel-image-optimiser');?>' onclick="ShortPixel.confirmBulkAction('Restore', event)" style="margin-bottom:10px;"><br>
255
- <input type='submit' name='bulkCleanup' id='bulkCleanup' class='button' value='<?php _e('Bulk Delete Metadata','shortpixel-image-optimiser');?>' onclick="ShortPixel.confirmBulkAction('Cleanup', event)" style="width:100%">
256
  <input type='submit' name='bulkCleanupPending' id='bulkCleanupPending' class='button' value='<?php _e('Bulk Delete Pending Metadata','shortpixel-image-optimiser');?>' onclick="ShortPixel.confirmBulkAction('CleanupPending', event)" style="display:none">
257
  </div>
258
 
@@ -382,8 +387,9 @@ class ShortPixelView {
382
  </div>
383
  </div>
384
  <p><?php printf(__('Go to the ShortPixel <a href="%soptions-general.php?page=wp-shortpixel#stats">Stats</a> '
385
- . 'and see all your websites\' optimized stats. Download your detailed <a href="https://api.shortpixel.com/v2/report.php?key=%s">Optimization Report</a> '
386
- . 'to check your image optimization statistics for the last 40 days.','shortpixel-image-optimiser'),
 
387
  get_admin_url(), (defined("SHORTPIXEL_HIDE_API_KEY") ? '' : $this->ctrl->getApiKey()) );?></p>
388
  <?php
389
  $failed = $this->ctrl->getPrioQ()->getFailed();
@@ -497,7 +503,7 @@ class ShortPixelView {
497
  <input type='submit' name='bulkProcess' id='bulkProcess' class='button button-primary' value='<?php _e('Restart Optimizing','shortpixel-image-optimiser');?>'
498
  <?php echo($settings->quotaExceeded? "disabled title=\"" . __("Top-up your account to optimize more images.",'shortpixel-image-optimiser')."\"" : ""); ?>>
499
  <input type='submit' name='bulkRestore' id='bulkRestore' class='button' value='<?php _e('Bulk Restore Media Library','shortpixel-image-optimiser');?>' onclick="ShortPixel.confirmBulkAction('Restore',event)" style="float: right;">
500
- <input type='submit' name='bulkCleanup' id='bulkCleanup' class='button' value='<?php _e('Bulk Delete Metadata','shortpixel-image-optimiser');?>' onclick="ShortPixel.confirmBulkAction('Cleanup',event)" style="float: right;margin-right:10px;">
501
  <input type='submit' name='bulkCleanupPending' id='bulkCleanupPending' class='button' value='<?php _e('Bulk Delete Pending Metadata','shortpixel-image-optimiser');?>' onclick="ShortPixel.confirmBulkAction('CleanupPending', event)" style="display:none">
502
  </form>
503
  </div>
@@ -688,20 +694,20 @@ class ShortPixelView {
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
700
- echo($this->ctrl->getVerifiedKey() ? "login/".(defined("SHORTPIXEL_HIDE_API_KEY") ? '' : $this->ctrl->getApiKey()) : "pricing");
701
  ?>" target="_blank" style="font-size:18px">
702
  <?php _e('Upgrade now','shortpixel-image-optimiser');?>
703
- </a> | <a href="https://shortpixel.com/pricing#faq" target="_blank" style="font-size:18px"><?php _e('FAQ','shortpixel-image-optimiser');?> </a> |
704
- <a href="https://shortpixel.com/contact/<?php //echo($this->ctrl->getEncryptedData());?>" target="_blank" style="font-size:18px"><?php _e('Support','shortpixel-image-optimiser');?> </a>
705
  </p>
706
  <?php if($notice !== null) { ?>
707
  <br/>
@@ -731,6 +737,16 @@ class ShortPixelView {
731
  </section>
732
  <?php } ?>
733
  </form><span style="display:none">&nbsp;</span><?php //the span is a trick to keep the sections ordered as nth-child in styles: 1,2,3,4 (otherwise the third section would be nth-child(2) too, because of the form)
 
 
 
 
 
 
 
 
 
 
734
  if($averageCompression !== null) {?>
735
  <section id="tab-stats">
736
  <h2><a class='tab-link' href='javascript:void(0);' data-id="tab-stats"><?php _e('Statistics','shortpixel-image-optimiser');?></a></h2>
@@ -790,7 +806,7 @@ class ShortPixelView {
790
  onchange="ShortPixel.updateSignupEmail();" class="regular-text">
791
  <span class="spinner" id="pluginemail_spinner" style="float:none;"></span>
792
  <a type="button" id="request_key" class="button button-primary" title="<?php _e('Request a new API key','shortpixel-image-optimiser');?>"
793
- href="https://shortpixel.com/free-sign-up?pluginemail=<?php echo( $adminEmail );?>"
794
  onclick="ShortPixel.newApiKey(event);"
795
  onmouseenter="ShortPixel.updateSignupEmail();">
796
  <?php _e('Request Key','shortpixel-image-optimiser');?>
@@ -982,6 +998,8 @@ class ShortPixelView {
982
  $settings->png2jpg = 0;
983
  }
984
  $convertPng2Jpg = ($settings->png2jpg ? 'checked' : '');
 
 
985
  ?>
986
  <div class="wp-shortpixel-options">
987
  <?php if(!$this->ctrl->getVerifiedKey()) { ?>
@@ -1204,6 +1222,20 @@ class ShortPixelView {
1204
  </p>
1205
  </td>
1206
  </tr>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1207
  </tbody>
1208
  </table>
1209
  <p class="submit">
@@ -1217,7 +1249,67 @@ class ShortPixelView {
1217
  <?php }
1218
  }
1219
 
1220
- function displaySettingsStats($quotaData, $averageCompression, $savedSpace, $savedBandwidth,
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1221
  $remainingImages, $totalCallsMade, $fileCount, $backupFolderSize) { ?>
1222
  <a id="facts"></a>
1223
  <h3><?php _e('Your ShortPixel Stats','shortpixel-image-optimiser');?></h3>
@@ -1263,7 +1355,7 @@ class ShortPixelView {
1263
  </tr>
1264
  <tr>
1265
  <th scope="row"><label for="usedQUota"><?php _e('Number of images processed this month:','shortpixel-image-optimiser');?></label></th>
1266
- <td><?php echo($totalCallsMade);?> (<a href="https://api.shortpixel.com/v2/report.php?key=<?php echo(defined("SHORTPIXEL_HIDE_API_KEY") ? '' : $this->ctrl->getApiKey());?>" target="_blank">
1267
  <?php _e('see report','shortpixel-image-optimiser');?>
1268
  </a>)
1269
  </td>
@@ -1360,12 +1452,21 @@ class ShortPixelView {
1360
  }
1361
  break;
1362
  case 'pdfOptimized':
1363
- case 'imgOptimized':
1364
- $successText = $this->getSuccessText($data['percent'],$data['bonus'],$data['type'],$data['thumbsOpt'],$data['thumbsTotal'], $data['retinasOpt']);
 
1365
  if($extended) {
 
 
 
 
 
 
 
 
1366
  $missingThumbs = '';
1367
  if(count($data['thumbsMissing'])) {
1368
- $missingThumbs .= "<br><span style='font-weight: bold;'>" . __("Missing thumbs:", 'shortpixel-image-optimiser');
1369
  foreach($data['thumbsMissing'] as $miss) {
1370
  $missingThumbs .= "<br> &#8226; " . $miss;
1371
  }
@@ -1375,11 +1476,12 @@ class ShortPixelView {
1375
  . "<br>EXIF: " . ($data['exifKept'] ? __('kept','shortpixel-image-optimiser') : __('removed','shortpixel-image-optimiser'))
1376
  . ($data['png2jpg'] ? '<br>' . __('Converted from PNG','shortpixel-image-optimiser'): '')
1377
  . "<br>" . __("Optimized on", 'shortpixel-image-optimiser') . ": " . $data['date']
1378
- . $missingThumbs;
1379
  }
 
1380
  $this->renderListCell($id, $data['status'], $data['showActions'],
1381
  (!$data['thumbsOpt'] && $data['thumbsTotal']) //no thumb was optimized
1382
- || (count($data['thumbsOptList']) && ($data['thumbsTotal'] - $data['thumbsOpt'] > 0)), $data['thumbsTotal'] - $data['thumbsOpt'],
1383
  $data['backup'], $data['type'], $data['invType'], $successText);
1384
 
1385
  break;
@@ -1392,7 +1494,7 @@ class ShortPixelView {
1392
  <?php
1393
  }
1394
 
1395
- public function getSuccessText($percent, $bonus, $type, $thumbsOpt = 0, $thumbsTotal = 0, $retinasOpt = 0) {
1396
  if($percent == 999) return __("Reduced by X%(unknown)");
1397
  return ($percent && $percent > 0 ? __('Reduced by','shortpixel-image-optimiser') . ' <strong>' . $percent . '%</strong> ' : '')
1398
  .(!$bonus ? ' ('.$type.')':'')
@@ -1402,7 +1504,7 @@ class ShortPixelView {
1402
  .($thumbsOpt ? ( $thumbsTotal > $thumbsOpt
1403
  ? sprintf(__('+%s of %s thumbnails optimized','shortpixel-image-optimiser'),$thumbsOpt,$thumbsTotal)
1404
  : sprintf(__('+%s thumbnails optimized','shortpixel-image-optimiser'),$thumbsOpt)) : '')
1405
- .($retinasOpt ? '<br>' . sprintf(__('+%s Retina images optimized','shortpixel-image-optimiser') , $retinasOpt) : '' ) ;
1406
  }
1407
 
1408
  public function renderListCell($id, $status, $showActions, $optimizeThumbs, $thumbsRemain, $backup, $type, $invType, $message, $extraClass = '') {
71
  . '<a href="options-general.php?page=wp-shortpixel">ShortPixel Settings</a> page in your WordPress Admin.','shortpixel-image-optimiser');?>
72
  </p>
73
  <p><?php _e('If you don’t have an API Key, you can get one delivered to your inbox, for free.','shortpixel-image-optimiser');?></p>
74
+ <p><?php _e('Please <a href="https://shortpixel.com/wp-apikey' . WPShortPixel::getAffiliateSufix() . '" target="_blank">sign up to get your API key.</a>','shortpixel-image-optimiser');?>
75
  </p>
76
  <?php
77
  }
78
 
79
+ public static function displayActivationNotice($when = 'activate', $extra = '') {
80
+ $extraStyle = ($when == 'compat' || $when == 'fileperms' ? "background-color: #ff9999;margin: 5px 20px 15px 0;'" : '');
81
+ $icon = false; $extraClass = 'notice-warning';
 
82
  switch($when) {
83
+ case 'compat': $extraClass = 'notice-error below-h2';
84
+ case 'fileperms': $icon = 'scared'; $extraClass = 'notice-error'; break;
85
  case 'unlisted': $icon = 'magnifier'; break;
86
  case 'upgmonth':
87
+ case 'upgbulk': $icon = 'notes'; $extraClass = 'notice-success'; break;
88
+ case 'generic-err': $extraClass = 'notice-error is-dismissible'; break;
89
  }
90
  ?>
91
  <div class='notice <?php echo($extraClass);?> notice-warning' id='short-pixel-notice-<?php echo($when);?>' <?php echo($extraStyle);?>>
99
  <a href="javascript:ShortPixel.includeUnlisted()" class="button button-primary" style="margin-top:10px;margin-left:10px;">
100
  <strong><?php _e('Yes, include these thumbnails','shortpixel-image-optimiser');?></strong></a>
101
  <?php }
102
+ if($when !== 'fileperms' && $when !== 'compat' && $when !== 'generic-err') { ?>
103
  <a href="javascript:dismissShortPixelNotice('<?php echo($when);?>')" class="button" style="margin-top:10px;"><?php _e('Dismiss','shortpixel-image-optimiser');?></a>
104
  <?php }
105
  if($when == 'compat') { ?>
106
  <a href="javascript:dismissShortPixelNotice('<?php echo($when);?>')" class="button" style="margin-top:10px;"><?php _e('I know what I\'m doing','shortpixel-image-optimiser');?></a>
107
  <?php } ?>
108
  </div>
109
+ <?php
110
+ if($when == 'generic-err') {?>
111
+ <button type="button" class="notice-dismiss"><span class="screen-reader-text">Dismiss this notice.</span></button>
112
+ <?php }
113
+ if($icon){ ?>
114
  <img src="<?php echo(plugins_url('/shortpixel-image-optimiser/res/img/robo-' . $icon . '.png'));?>"
115
  srcset='<?php echo(plugins_url( 'shortpixel-image-optimiser/res/img/robo-' . $icon . '.png' ));?> 1x, <?php echo(plugins_url( 'shortpixel-image-optimiser/res/img/robo-' . $icon . '@2x.png' ));?> 2x'
116
  class='short-pixel-notice-icon'>
168
  </p><?php
169
  break;
170
  case 'generic' :
171
+ case 'generic-err' :
172
  echo("<p>$extra</p>");
173
  break;
174
  }
257
  <?php if($quotaData['mainProcessedMlFiles'] > 0) {?>
258
  <div style="position: absolute;bottom: 10px;right: 10px;">
259
  <input type='submit' name='bulkRestore' id='bulkRestore' class='button' value='<?php _e('Bulk Restore Media Library','shortpixel-image-optimiser');?>' onclick="ShortPixel.confirmBulkAction('Restore', event)" style="margin-bottom:10px;"><br>
260
+ <input type='submit' name='bulkCleanup' id='bulkCleanup' class='button' value='<?php _e('Bulk Delete SP Metadata','shortpixel-image-optimiser');?>' onclick="ShortPixel.confirmBulkAction('Cleanup', event)" style="width:100%">
261
  <input type='submit' name='bulkCleanupPending' id='bulkCleanupPending' class='button' value='<?php _e('Bulk Delete Pending Metadata','shortpixel-image-optimiser');?>' onclick="ShortPixel.confirmBulkAction('CleanupPending', event)" style="display:none">
262
  </div>
263
 
387
  </div>
388
  </div>
389
  <p><?php printf(__('Go to the ShortPixel <a href="%soptions-general.php?page=wp-shortpixel#stats">Stats</a> '
390
+ . 'and see all your websites\' optimized stats. Download your detailed <a href="https://%s/v2/report.php?key=%s">Optimization Report</a> '
391
+ . 'to check your image optimization statistics for the last 40 days.','shortpixel-image-optimiser'),
392
+ SHORTPIXEL_API,
393
  get_admin_url(), (defined("SHORTPIXEL_HIDE_API_KEY") ? '' : $this->ctrl->getApiKey()) );?></p>
394
  <?php
395
  $failed = $this->ctrl->getPrioQ()->getFailed();
503
  <input type='submit' name='bulkProcess' id='bulkProcess' class='button button-primary' value='<?php _e('Restart Optimizing','shortpixel-image-optimiser');?>'
504
  <?php echo($settings->quotaExceeded? "disabled title=\"" . __("Top-up your account to optimize more images.",'shortpixel-image-optimiser')."\"" : ""); ?>>
505
  <input type='submit' name='bulkRestore' id='bulkRestore' class='button' value='<?php _e('Bulk Restore Media Library','shortpixel-image-optimiser');?>' onclick="ShortPixel.confirmBulkAction('Restore',event)" style="float: right;">
506
+ <input type='submit' name='bulkCleanup' id='bulkCleanup' class='button' value='<?php _e('Bulk Delete SP Metadata','shortpixel-image-optimiser');?>' onclick="ShortPixel.confirmBulkAction('Cleanup',event)" style="float: right;margin-right:10px;">
507
  <input type='submit' name='bulkCleanupPending' id='bulkCleanupPending' class='button' value='<?php _e('Bulk Delete Pending Metadata','shortpixel-image-optimiser');?>' onclick="ShortPixel.confirmBulkAction('CleanupPending', event)" style="display:none">
508
  </form>
509
  </div>
694
  <?php
695
  }
696
 
697
+ function displaySettings($showApiKey, $editApiKey, $quotaData, $notice, $resources = null, $averageCompression = null, $savedSpace = null, $savedBandwidth = null,
698
  $remainingImages = null, $totalCallsMade = null, $fileCount = null, $backupFolderSize = null,
699
+ $customFolders = null, $folderMsg = false, $addedFolder = false, $showAdvanced = false, $cloudflareAPI = false) {
700
  //wp_enqueue_script('jquery.idTabs.js', plugins_url('/js/jquery.idTabs.js',__FILE__) );
701
  $this->ctrl->outputHSBeacon();
702
  ?>
703
  <h1><?php _e('ShortPixel Plugin Settings','shortpixel-image-optimiser');?></h1>
704
  <p style="font-size:18px">
705
  <a href="https://shortpixel.com/<?php
706
+ echo($this->ctrl->getVerifiedKey() ? "login/".(defined("SHORTPIXEL_HIDE_API_KEY") ? '' : $this->ctrl->getApiKey()) : "pricing" . WPShortPixel::getAffiliateSufix());
707
  ?>" target="_blank" style="font-size:18px">
708
  <?php _e('Upgrade now','shortpixel-image-optimiser');?>
709
+ </a> | <a href="https://shortpixel.com/pricing<?php echo(WPShortPixel::getAffiliateSufix()); ?>#faq" target="_blank" style="font-size:18px"><?php _e('FAQ','shortpixel-image-optimiser');?> </a> |
710
+ <a href="https://shortpixel.com/contact<?php echo(WPShortPixel::getAffiliateSufix());?>" target="_blank" style="font-size:18px"><?php _e('Support','shortpixel-image-optimiser');?> </a>
711
  </p>
712
  <?php if($notice !== null) { ?>
713
  <br/>
737
  </section>
738
  <?php } ?>
739
  </form><span style="display:none">&nbsp;</span><?php //the span is a trick to keep the sections ordered as nth-child in styles: 1,2,3,4 (otherwise the third section would be nth-child(2) too, because of the form)
740
+
741
+ if($cloudflareAPI){
742
+ ?>
743
+ <section id="tab-cloudflare">
744
+ <h2><a class='tab-link' href='javascript:void(0);'
745
+ data-id="tab-cloudflare"><?php _e('Cloudflare API', 'shortpixel-image-optimiser'); ?></a>
746
+ </h2>
747
+ <?php $this->display_cloudflare_settings_form(); ?>
748
+ </section>
749
+ <?php }
750
  if($averageCompression !== null) {?>
751
  <section id="tab-stats">
752
  <h2><a class='tab-link' href='javascript:void(0);' data-id="tab-stats"><?php _e('Statistics','shortpixel-image-optimiser');?></a></h2>
806
  onchange="ShortPixel.updateSignupEmail();" class="regular-text">
807
  <span class="spinner" id="pluginemail_spinner" style="float:none;"></span>
808
  <a type="button" id="request_key" class="button button-primary" title="<?php _e('Request a new API key','shortpixel-image-optimiser');?>"
809
+ href="https://shortpixel.com/free-sign-up<?php echo($this->ctrl->getAffiliateSufix()); ?>?pluginemail=<?php echo( $adminEmail );?>"
810
  onclick="ShortPixel.newApiKey(event);"
811
  onmouseenter="ShortPixel.updateSignupEmail();">
812
  <?php _e('Request Key','shortpixel-image-optimiser');?>
998
  $settings->png2jpg = 0;
999
  }
1000
  $convertPng2Jpg = ($settings->png2jpg ? 'checked' : '');
1001
+ $allSizes = $this->ctrl->getAllThumbnailSizes();
1002
+ $excludeSizes = $settings->excludeSizes;
1003
  ?>
1004
  <div class="wp-shortpixel-options">
1005
  <?php if(!$this->ctrl->getVerifiedKey()) { ?>
1222
  </p>
1223
  </td>
1224
  </tr>
1225
+ <tr>
1226
+ <th scope="row"><label for="excludeSizes"><?php _e('Exclude thumbnail sizes','shortpixel-image-optimiser');?></label></th>
1227
+ <td>
1228
+ <?php foreach($allSizes as $sizeKey => $sizeVal) {?>
1229
+ <span style="margin-right: 20px;white-space:nowrap">
1230
+ <input name="excludeSizes[]" type="checkbox" id="excludeSizes_<?php echo($sizeKey);?>" <?php echo((in_array($sizeKey, $excludeSizes) ? 'checked' : ''));?>
1231
+ value="<?php echo($sizeKey);?>">&nbsp;<?php $w=$sizeVal['width']?$sizeVal['width'].'px':'*';$h=$sizeVal['height']?$sizeVal['height'].'px':'*';echo("$sizeKey ({$w} &times; {$h})");?>&nbsp;&nbsp;
1232
+ </span><br>
1233
+ <?php } ?>
1234
+ <p class="settings-info">
1235
+ <?php _e('Please check the thumbnail sizes you would like to <strong>exclude</strong> from optimization. There might be sizes created by themes or plugins which do not appear here, because they were not properly registered with WordPress. If you want to ignore them too, please uncheck the option <strong>Optimize other thumbs</strong> above.','shortpixel-image-optimiser');?>
1236
+ </p>
1237
+ </td>
1238
+ </tr>
1239
  </tbody>
1240
  </table>
1241
  <p class="submit">
1249
  <?php }
1250
  }
1251
 
1252
+ /**
1253
+ * @desc This form is used in WP back-end to allow users that use CloudFlare to save their settings
1254
+ *
1255
+ * @link wp-admin/options-general.php?page=wp-shortpixel
1256
+ */
1257
+ function display_cloudflare_settings_form()
1258
+ {
1259
+ ?>
1260
+ <p><?php _e("If you're using Cloudflare on your site then we advise you to fill in the details below. This will allow ShortPixel to work seamlessly with Cloudflare so that any image optimized/restored by ShortPixel will be automatically updated on Cloudflare as well.",'shortpixel-image-optimiser');?></p>
1261
+ <form name='wp_shortpixel_cloudflareAPI' action='options-general.php?page=wp-shortpixel&noheader=true'
1262
+ method='post' id='wp_shortpixel_cloudflareAPI'>
1263
+ <table class="form-table">
1264
+ <tbody>
1265
+ <tr>
1266
+ <th scope="row">
1267
+ <label for="cloudflare-email"><?php _e('Cloudflare E-mail:', 'shortpixel-image-optimiser'); ?></label>
1268
+ </th>
1269
+ <td>
1270
+ <input name="cloudflare-email" type="text" id="cloudflare-email"
1271
+ value="<?php echo($this->ctrl->fetch_cloudflare_api_email()); ?>" class="regular-text">
1272
+ <p class="settings-info">
1273
+ <?php _e('The e-mail address you use to login to CloudFlare.','shortpixel-image-optimiser');?>
1274
+ </p>
1275
+ </td>
1276
+ </tr>
1277
+ <tr>
1278
+ <th scope="row"><label
1279
+ for="cloudflare-auth-key"><?php _e('Global API Key:', 'shortpixel-image-optimiser'); ?></label>
1280
+ </th>
1281
+ <td>
1282
+ <input name="cloudflare-auth-key" type="text" id="cloudflare-auth-key"
1283
+ value="<?php echo($this->ctrl->fetch_cloudflare_api_key()); ?>" class="regular-text">
1284
+ <p class="settings-info">
1285
+ <?php _e("This can be found when you're logged into your account, on the My Profile page:",'shortpixel-image-optimiser');?> <a href='https://www.cloudflare.com/a/profile' target='_blank'>https://www.cloudflare.com/a/profile</a>
1286
+ </p>
1287
+ </td>
1288
+ </tr>
1289
+ <tr>
1290
+ <th scope="row"><label
1291
+ for="cloudflare-zone-id"><?php _e('Zone ID:', 'shortpixel-image-optimiser'); ?></label>
1292
+ </th>
1293
+ <td>
1294
+ <input name="cloudflare-zone-id" type="text" id="cloudflare-zone-id"
1295
+ value="<?php echo($this->ctrl->fetch_cloudflare_api_zoneid()); ?>" class="regular-text">
1296
+ <p class="settings-info">
1297
+ <?php _e('This can be found in your Cloudflare account in the "Overview" section for your domain.','shortpixel-image-optimiser');?>
1298
+ </p>
1299
+ </td>
1300
+ </tr>
1301
+ </tbody>
1302
+ </table>
1303
+ <p class="submit">
1304
+ <input type="submit" name="saveCloudflare" id="saveCloudflare" class="button button-primary"
1305
+ title="<?php _e('Save Changes', 'shortpixel-image-optimiser'); ?>"
1306
+ value="<?php _e('Save Changes', 'shortpixel-image-optimiser'); ?>"> &nbsp;
1307
+ </p>
1308
+ </form>
1309
+
1310
+ <?php }
1311
+
1312
+ function displaySettingsStats($quotaData, $averageCompression, $savedSpace, $savedBandwidth,
1313
  $remainingImages, $totalCallsMade, $fileCount, $backupFolderSize) { ?>
1314
  <a id="facts"></a>
1315
  <h3><?php _e('Your ShortPixel Stats','shortpixel-image-optimiser');?></h3>
1355
  </tr>
1356
  <tr>
1357
  <th scope="row"><label for="usedQUota"><?php _e('Number of images processed this month:','shortpixel-image-optimiser');?></label></th>
1358
+ <td><?php echo($totalCallsMade);?> (<a href="https://<?php echo(SHORTPIXEL_API);?>/v2/report.php?key=<?php echo(defined("SHORTPIXEL_HIDE_API_KEY") ? '' : $this->ctrl->getApiKey());?>" target="_blank">
1359
  <?php _e('see report','shortpixel-image-optimiser');?>
1360
  </a>)
1361
  </td>
1452
  }
1453
  break;
1454
  case 'pdfOptimized':
1455
+ case 'imgOptimized':
1456
+ $excluded = (isset($data['excludeSizes']) ? count($data['excludeSizes']) : 0);
1457
+ $successText = $this->getSuccessText($data['percent'],$data['bonus'],$data['type'],$data['thumbsOpt'],$data['thumbsTotal'], $data['retinasOpt'], $data['excludeSizes']);
1458
  if($extended) {
1459
+ $excludeSizes = '';
1460
+ if(isset($data['excludeSizes'])) {
1461
+ $excludeSizes .= "<br><span> <span style='font-weight: bold;'>" . __("Excluded thumbnails:", 'shortpixel-image-optimiser') . "</span>";
1462
+ foreach($data['excludeSizes'] as $excluded) {
1463
+ $excludeSizes .= "<br> &#8226; " . $excluded;
1464
+ }
1465
+ $excludeSizes .= '</span>';
1466
+ }
1467
  $missingThumbs = '';
1468
  if(count($data['thumbsMissing'])) {
1469
+ $missingThumbs .= "<br><span> <span style='font-weight: bold;'>" . __("Missing thumbnails:", 'shortpixel-image-optimiser') . "</span>";
1470
  foreach($data['thumbsMissing'] as $miss) {
1471
  $missingThumbs .= "<br> &#8226; " . $miss;
1472
  }
1476
  . "<br>EXIF: " . ($data['exifKept'] ? __('kept','shortpixel-image-optimiser') : __('removed','shortpixel-image-optimiser'))
1477
  . ($data['png2jpg'] ? '<br>' . __('Converted from PNG','shortpixel-image-optimiser'): '')
1478
  . "<br>" . __("Optimized on", 'shortpixel-image-optimiser') . ": " . $data['date']
1479
+ . $excludeSizes . $missingThumbs;
1480
  }
1481
+
1482
  $this->renderListCell($id, $data['status'], $data['showActions'],
1483
  (!$data['thumbsOpt'] && $data['thumbsTotal']) //no thumb was optimized
1484
+ || (count($data['thumbsOptList']) && ($data['thumbsTotal'] - $data['thumbsOpt'] - $excluded > 0)), $data['thumbsTotal'] - $data['thumbsOpt'],
1485
  $data['backup'], $data['type'], $data['invType'], $successText);
1486
 
1487
  break;
1494
  <?php
1495
  }
1496
 
1497
+ public function getSuccessText($percent, $bonus, $type, $thumbsOpt = 0, $thumbsTotal = 0, $retinasOpt = 0, $excluded = 0) {
1498
  if($percent == 999) return __("Reduced by X%(unknown)");
1499
  return ($percent && $percent > 0 ? __('Reduced by','shortpixel-image-optimiser') . ' <strong>' . $percent . '%</strong> ' : '')
1500
  .(!$bonus ? ' ('.$type.')':'')
1504
  .($thumbsOpt ? ( $thumbsTotal > $thumbsOpt
1505
  ? sprintf(__('+%s of %s thumbnails optimized','shortpixel-image-optimiser'),$thumbsOpt,$thumbsTotal)
1506
  : sprintf(__('+%s thumbnails optimized','shortpixel-image-optimiser'),$thumbsOpt)) : '')
1507
+ .($retinasOpt ? '<br>' . sprintf(__('+%s Retina images optimized','shortpixel-image-optimiser') , $retinasOpt) : '' );
1508
  }
1509
 
1510
  public function renderListCell($id, $status, $showActions, $optimizeThumbs, $thumbsRemain, $backup, $type, $invType, $message, $extraClass = '') {
class/wp-short-pixel.php CHANGED
@@ -4,8 +4,6 @@ class WPShortPixel {
4
 
5
  const BULK_EMPTY_QUEUE = 0;
6
 
7
- private $_affiliateSufix;
8
-
9
  private $_apiInterface = null;
10
  private $_settings = null;
11
  private $prioQ = null;
@@ -31,9 +29,9 @@ class WPShortPixel {
31
 
32
  $isAdminUser = current_user_can( 'manage_options' );
33
 
34
- $this->_affiliateSufix = (strlen(SHORTPIXEL_AFFILIATE_CODE)) ? "/affiliate/" . SHORTPIXEL_AFFILIATE_CODE : "";
35
  $this->_settings = new WPShortPixelSettings();
36
  $this->_apiInterface = new ShortPixelAPI($this->_settings);
 
37
  $this->hasNextGen = ShortPixelNextGenAdapter::hasNextGen();
38
  $this->spMetaDao = new ShortPixelCustomMetaDao(new WpShortPixelDb(), $this->_settings->excludePatterns);
39
  $this->prioQ = new ShortPixelQueue($this, $this->_settings);
@@ -178,7 +176,7 @@ class WPShortPixel {
178
  WPShortPixelSettings::onDeactivate();
179
  }
180
 
181
- public static function getConflictingPlugins() {
182
  $conflictPlugins = array(
183
  'WP Smush - Image Optimization' => 'wp-smushit/wp-smush.php',
184
  'Imagify Image Optimizer' => 'imagify/imagify.php',
@@ -190,9 +188,14 @@ class WPShortPixel {
190
  'CheetahO Image Optimizer' => 'cheetaho-image-optimizer/cheetaho.php',
191
  'Zara 4 Image Compression' => 'zara-4/zara-4.php',
192
  'Prizm Image' => 'prizm-image/wp-prizmimage.php',
193
- 'CW Image Optimizer' => 'cw-image-optimizer/cw-image-optimizer.php',
194
- 'Regenerate Thumbnails: recreating image files may require re-optimization of the resulting thumbnails, even if they were previously optimized.' => 'regenerate-thumbnails/regenerate-thumbnails.php'
195
  );
 
 
 
 
 
 
196
  $found = array();
197
  foreach($conflictPlugins as $name => $path) {
198
  if(is_plugin_active($path)) {
@@ -206,6 +209,9 @@ class WPShortPixel {
206
  if(!ShortPixelQueue::testQ()) {
207
  ShortPixelView::displayActivationNotice('fileperms');
208
  }
 
 
 
209
  $dismissed = $this->_settings->dismissedNotices ? $this->_settings->dismissedNotices : array();
210
  $this->_settings->dismissedNotices = $dismissed;
211
 
@@ -223,7 +229,7 @@ class WPShortPixel {
223
  }
224
  }
225
  if(!isset($dismissed['compat'])) {
226
- $conflictPlugins = self::getConflictingPlugins();
227
  if(count($conflictPlugins)) {
228
  ShortPixelView::displayActivationNotice('compat', $conflictPlugins);
229
  return;
@@ -243,7 +249,7 @@ class WPShortPixel {
243
  && (!isset($dismissed['upgmonth']) || !isset($dismissed['upgbulk'])) && isset($this->_settings->currentStats['optimizePdfs'])
244
  && $this->_settings->currentStats['optimizePdfs'] == $this->_settings->optimizePdfs ) {
245
  $screen = get_current_screen();
246
- $stats = $this->countAllIfNeeded($this->_settings->currentStats, 300);
247
  $quotaData = $stats;
248
 
249
  //this is for bulk page - alert on the total credits for total images
@@ -257,6 +263,7 @@ class WPShortPixel {
257
  //looks like the user hasn't got enough credits to process the monthly images, display a notice telling this
258
  ShortPixelView::displayActivationNotice('upgmonth', array('monthAvg' => $this->getMonthAvg($stats), 'monthlyQuota' => $quotaData['APICallsQuotaNumeric']));
259
  }
 
260
  }
261
  }
262
 
@@ -362,7 +369,8 @@ class WPShortPixel {
362
  DEFAULT_COMPRESSION: <?php echo $this->_settings->compressionType; ?>,
363
  MEDIA_ALERT: '<?php echo $this->_settings->mediaAlert ? "done" : "todo"; ?>',
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($) {
@@ -409,7 +417,7 @@ class WPShortPixel {
409
  $extraClasses = " shortpixel-hide";
410
  /*translators: toolbar icon tooltip*/
411
  $id = 'short-pixel-notice-toolbar';
412
- $tooltip = __('ShortPixel optimizing...','shortpixel-image-optimiser');
413
  $icon = "shortpixel.png";
414
  $successLink = $link = admin_url(current_user_can( 'edit_others_posts')? 'upload.php?page=wp-short-pixel-bulk' : 'upload.php');
415
  $blank = "";
@@ -502,6 +510,8 @@ class WPShortPixel {
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
  }
@@ -539,7 +549,7 @@ class WPShortPixel {
539
  try {
540
  $URLsAndPATHs = $this->getURLsAndPATHs($itemHandler);
541
  //send a processing request right after a file was uploaded, do NOT wait for response
542
- $this->_apiInterface->doRequests($URLsAndPATHs['URLs'], false, $ID);
543
  } catch(Exception $e) {
544
  $meta['ShortPixelImprovement'] = $e->getMessage();
545
  return $meta;
@@ -565,6 +575,21 @@ class WPShortPixel {
565
  }
566
  }//end handleMediaLibraryImageUpload
567
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
568
  /**
569
  * Convert an uploaded image from PNG to JPG
570
  * @param type $params
@@ -776,7 +801,7 @@ class WPShortPixel {
776
  }
777
  elseif( $this->_settings->processThumbnails && $meta->getThumbsOpt() !== null
778
  && ($meta->getThumbsOpt() == 0 && count($meta->getThumbs()) > 0
779
- || $meta->getThumbsOpt() < WpShortPixelMediaLbraryAdapter::countNonWebpSizes($meta->getThumbs()) && is_array($meta->getThumbsOptList()))) { //thumbs were chosen in settings
780
  //if($crtStartQueryID == 44 || $crtStartQueryID == 49) {echo("No THuMBS?");die(var_dump($meta));}
781
  $meta->setThumbsTodo(true);
782
  $item->updateMeta($meta);//wp_update_attachment_metadata($crtStartQueryID, $meta);
@@ -975,8 +1000,9 @@ class WPShortPixel {
975
  //remove also from the failed list if it failed in the past
976
  $prio = $this->prioQ->removeFromFailed($itemId);
977
  $result["Type"] = $meta->getCompressionType() !== null ? ShortPixelAPI::getCompressionTypeName($meta->getCompressionType()) : '';
978
- $result["ThumbsTotal"] = $meta->getThumbs() && is_array($meta->getThumbs()) ? WpShortPixelMediaLbraryAdapter::countNonWebpSizes($meta->getThumbs()): 0;
979
- $result["ThumbsTotal"] -= count($meta->getThumbsMissing());
 
980
  $result["ThumbsCount"] = $meta->getThumbsOpt()
981
  ? $meta->getThumbsOpt() //below is the fallback for old optimized images that don't have thumbsOpt
982
  : ($this->_settings->processThumbnails ? $result["ThumbsTotal"] : 0);
@@ -1007,12 +1033,22 @@ class WPShortPixel {
1007
  $bkThumb = '';
1008
  } else {
1009
  if(count($sizes)) {
1010
- $thumb = (isset($sizes["medium"]) ? $sizes["medium"]["file"] : (isset($sizes["thumbnail"]) ? $sizes["thumbnail"]["file"]: ""));
1011
- if(!strlen($thumb)) { //fallback to the first in the list
1012
- $sizeVals = array_values($sizes);
1013
- $thumb = count($sizeVals) ? $sizeVals[0]['file'] : '';
 
 
 
 
 
 
 
 
 
1014
  }
1015
- } else { //fallback to the image itself
 
1016
  $thumb = is_array($filePath) ? $filePath[count($filePath) - 1] : $filePath;
1017
  }
1018
 
@@ -1349,9 +1385,15 @@ class WPShortPixel {
1349
  }
1350
  return $ret;
1351
  }
1352
-
1353
  protected function setFilePerms($file) {
1354
  //die(getenv('USERNAME') ? getenv('USERNAME') : getenv('USER'));
 
 
 
 
 
 
1355
  if(strtoupper(substr(PHP_OS, 0, 3)) !== 'WIN') {
1356
  //on *nix platforms check also the owner
1357
  $owner = fileowner($file);
@@ -1359,11 +1401,9 @@ class WPShortPixel {
1359
  return false;
1360
  }
1361
  }
1362
- $perms = @fileperms($file);
1363
- if(!($perms & 0x0100) || !($perms & 0x0080)) {
1364
- if(!@chmod($file, $perms | 0x0100 | 0x0080)) {
1365
- return false;
1366
- }
1367
  }
1368
  return true;
1369
  }
@@ -1400,7 +1440,10 @@ class WPShortPixel {
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++;
@@ -1413,6 +1456,10 @@ class WPShortPixel {
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++;
@@ -1420,6 +1467,7 @@ class WPShortPixel {
1420
  }
1421
  }
1422
  if(!$bkCount) {
 
1423
  return false;
1424
  }
1425
  }
@@ -1477,11 +1525,30 @@ class WPShortPixel {
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
 
1486
  protected function renameWithRetina($bkFile, $file) {
1487
  @rename($bkFile, $file);
@@ -1571,10 +1638,11 @@ class WPShortPixel {
1571
  $ID = intval($_GET['attachment_ID']);
1572
  $meta = wp_get_attachment_metadata($ID);
1573
  //die(var_dump($meta));
 
1574
  if( isset($meta['ShortPixelImprovement'])
1575
- && isset($meta['sizes']) && WpShortPixelMediaLbraryAdapter::countNonWebpSizes($meta['sizes'])
1576
  && ( !isset($meta['ShortPixel']['thumbsOpt']) || $meta['ShortPixel']['thumbsOpt'] == 0
1577
- || (isset($meta['sizes']) && isset($meta['ShortPixel']['thumbsOptList']) && $meta['ShortPixel']['thumbsOpt'] < WpShortPixelMediaLbraryAdapter::countNonWebpSizes($meta['sizes'])))) { //optimized without thumbs, thumbs exist
1578
  $meta['ShortPixel']['thumbsTodo'] = true;
1579
  wp_update_attachment_metadata($ID, $meta);
1580
  $this->prioQ->push($ID);
@@ -2014,39 +2082,40 @@ class WPShortPixel {
2014
  if( $this->_settings->verifiedKey ) {
2015
  die(json_encode((object)array('Status' => 'success', 'Details' => $this->_settings->apiKey)));
2016
  }
2017
-
2018
- $newKey = wp_remote_post("https://shortpixel.com/free-sign-up-plugin", array(
2019
  'method' => 'POST',
2020
  'timeout' => 10,
2021
  'redirection' => 5,
2022
  'httpversion' => '1.0',
2023
  'blocking' => true,
 
2024
  'headers' => array(),
2025
  'body' => array(
2026
  'plugin_version' => SHORTPIXEL_IMAGE_OPTIMISER_VERSION,
2027
  'email' => isset($_POST['email']) ? trim($_POST['email']) : null,
2028
  'ip' => isset($_SERVER["HTTP_X_FORWARDED_FOR"]) ? $_SERVER["HTTP_X_FORWARDED_FOR"]: $_SERVER['REMOTE_ADDR'],
2029
  //'XDEBUG_SESSION_START' => 'session_name'
2030
- )));
2031
-
2032
-
2033
-
2034
- if ( is_object($newKey) && get_class($newKey) == 'WP_Error' ) {
 
2035
  die(json_encode((object)array('Status' => 'fail', 'Details' => '503')));
2036
  }
2037
- elseif ( isset($response['response']['code']) && $response['response']['code'] <> 200 ) {
2038
- die(json_encode((object)array('Status' => 'fail', 'Details' => $response['response']['code'])));
2039
  }
2040
- $response = (object)$this->_apiInterface->parseResponse($newKey);
2041
- if($response->Status == 'success') {
2042
- $key = trim($response->Details);
2043
  $validityData = $this->getQuotaInformation($key, true, true);
2044
  if($validityData['APIKeyValid']) {
2045
  $this->_settings->apiKey = $key;
2046
  $this->_settings->verifiedKey = true;
2047
  }
2048
  }
2049
- die(json_encode($response));
2050
 
2051
  }
2052
 
@@ -2186,7 +2255,14 @@ class WPShortPixel {
2186
  . "<a href='https://shortpixel.com/contact' target='_blank'>" . __('here','shortpixel-image-optimiser') . "</a>.");
2187
  }
2188
  }
2189
-
 
 
 
 
 
 
 
2190
  if( isset($_POST['save']) || isset($_POST['saveAdv'])
2191
  || (isset($_POST['validate']) && $_POST['validate'] == "validate")
2192
  || isset($_POST['removeFolder']) || isset($_POST['recheckFolder'])) {
@@ -2310,6 +2386,7 @@ class WPShortPixel {
2310
  }
2311
  $this->_settings->frontBootstrap = (isset($_POST['frontBootstrap']) ? 1: 0);
2312
  $this->_settings->autoMediaLibrary = (isset($_POST['autoMediaLibrary']) ? 1: 0);
 
2313
 
2314
  //Redirect to bulk processing if requested
2315
  if( isset($_POST['save']) && $_POST['save'] == __("Save and Go to Bulk Process",'shortpixel-image-optimiser')
@@ -2370,10 +2447,12 @@ class WPShortPixel {
2370
  if(is_wp_error( $resources )) {
2371
  $resources = array();
2372
  }
 
 
2373
  $this->view->displaySettings($showApiKey, $editApiKey,
2374
  $quotaData, $notice, $resources, $averageCompression, $savedSpace, $savedBandwidth, $remainingImages,
2375
  $totalCallsMade, $fileCount, null /*folder size now on AJAX*/, $customFolders,
2376
- $folderMsg, $folderMsg ? $addedFolder : false, isset($_POST['saveAdv']));
2377
  } else {
2378
  $this->view->displaySettings($showApiKey, $editApiKey, $quotaData, $notice);
2379
  }
@@ -2420,7 +2499,7 @@ class WPShortPixel {
2420
  $this->_settings->httpProto = 'https';
2421
  }
2422
 
2423
- $requestURL = $this->_settings->httpProto . '://api.shortpixel.com/v2/api-status.php';
2424
  $args = array(
2425
  'timeout'=> SHORTPIXEL_VALIDATE_MAX_TIMEOUT,
2426
  'body' => array('key' => $apiKey)
@@ -2453,6 +2532,7 @@ class WPShortPixel {
2453
  $args['sslverify'] = false;
2454
  }
2455
  $response = wp_remote_post($requestURL, $args);
 
2456
  $comm[] = array("sent" => "POST: " . $requestURL, "args" => $args, "received" => $response);
2457
 
2458
  //some hosting providers won't allow https:// POST connections so we try http:// as well
@@ -2484,10 +2564,10 @@ class WPShortPixel {
2484
  $response = wp_remote_get($requestURL, $args);
2485
  $comm[] = array("sent" => "POST: " . $requestURL, "args" => $args, "received" => $response);
2486
  }
2487
-
2488
  $defaultData = array(
2489
  "APIKeyValid" => false,
2490
- "Message" => __('API Key could not be validated due to a connectivity error.<BR>Your firewall may be blocking us. Please contact your hosting provider and ask them to allow connections from your site to api.shortpixel.com (IP 176.9.106.46).<BR> If you still cannot validate your API Key after this, please <a href="https://shortpixel.com/contact" target="_blank">contact us</a> and we will try to help. ','shortpixel-image-optimiser'),
2491
  "APICallsMade" => __('Information unavailable. Please check your API key.','shortpixel-image-optimiser'),
2492
  "APICallsQuota" => __('Information unavailable. Please check your API key.','shortpixel-image-optimiser'),
2493
  "APICallsMadeOneTime" => 0,
@@ -2580,6 +2660,7 @@ class WPShortPixel {
2580
 
2581
  $file = get_attached_file($id);
2582
  $data = wp_get_attachment_metadata($id);
 
2583
  $fileExtension = strtolower(pathinfo($file, PATHINFO_EXTENSION));
2584
  $invalidKey = !$this->_settings->verifiedKey;
2585
  $quotaExceeded = $this->_settings->quotaExceeded;
@@ -2611,7 +2692,7 @@ class WPShortPixel {
2611
  if( is_numeric($data['ShortPixelImprovement'])
2612
  && !($data['ShortPixelImprovement'] == 0 && isset($data['ShortPixel']['WaitingProcessing'])) //for images that erroneously have ShortPixelImprovement = 0 when WaitingProcessing
2613
  ) { //already optimized
2614
- $sizesCount = isset($data['sizes']) ? WpShortPixelMediaLbraryAdapter::countNonWebpSizes($data['sizes']) : 0;
2615
 
2616
  $renderData['status'] = $fileExtension == "pdf" ? 'pdfOptimized' : 'imgOptimized';
2617
  $renderData['percent'] = $this->optimizationPercentIfPng2Jpg($data);
@@ -2622,6 +2703,7 @@ class WPShortPixel {
2622
  $renderData['thumbsTotal'] = $sizesCount;
2623
  $renderData['thumbsOpt'] = isset($data['ShortPixel']['thumbsOpt']) ? $data['ShortPixel']['thumbsOpt'] : $sizesCount;
2624
  $renderData['thumbsOptList'] = isset($data['ShortPixel']['thumbsOptList']) ? $data['ShortPixel']['thumbsOptList'] : array();
 
2625
  $renderData['thumbsMissing'] = isset($data['ShortPixel']['thumbsMissing']) ? $data['ShortPixel']['thumbsMissing'] : array();
2626
  $renderData['retinasOpt'] = isset($data['ShortPixel']['retinasOpt']) ? $data['ShortPixel']['retinasOpt'] : null;
2627
  $renderData['exifKept'] = isset($data['ShortPixel']['exifKept']) ? $data['ShortPixel']['exifKept'] : null;
@@ -2678,7 +2760,7 @@ class WPShortPixel {
2678
  }
2679
  else { //finally
2680
  $renderData['status'] = $quotaExceeded ? 'quotaExceeded' : 'optimizeNow';
2681
- $sizes = isset($data['sizes']) ? WpShortPixelMediaLbraryAdapter::countNonWebpSizes($data['sizes']) : 0;
2682
  $renderData['thumbsTotal'] = $sizes;
2683
  $renderData['message'] = ($fileExtension == "pdf" ? 'PDF' : __('Image','shortpixel-image-optimiser'))
2684
  . __(' not processed.','shortpixel-image-optimiser')
@@ -2712,10 +2794,19 @@ class WPShortPixel {
2712
  $this->generateCustomColumn( 'wp-shortPixel', $post->ID, true );
2713
  }
2714
 
2715
- function onDeleteImage($post_id) {
2716
  $itemHandler = new ShortPixelMetaFacade($post_id);
2717
- $urlsPaths = $itemHandler->getURLsAndPATHs(true, false, false);
2718
- foreach($urlsPaths['PATHs'] as $path) {
 
 
 
 
 
 
 
 
 
2719
  $pos = strrpos($path, ".");
2720
  if ($pos !== false) {
2721
  //$webpPath = substr($path, 0, $pos) . ".webp";
@@ -2723,6 +2814,11 @@ class WPShortPixel {
2723
  @unlink(substr($path, 0, $pos) . ".webp");
2724
  @unlink(substr($path, 0, $pos) . "@2x.webp");
2725
  }
 
 
 
 
 
2726
  }
2727
  }
2728
 
@@ -2873,7 +2969,7 @@ class WPShortPixel {
2873
 
2874
  //return an array with URL(s) and PATH(s) for this file
2875
  public function getURLsAndPATHs($itemHandler, $meta = NULL, $onlyThumbs = false) {
2876
- return $itemHandler->getURLsAndPATHs($this->_settings->processThumbnails, $onlyThumbs, $this->_settings->optimizeRetina);
2877
  }
2878
 
2879
 
@@ -2957,6 +3053,24 @@ class WPShortPixel {
2957
  }
2958
  return;
2959
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2960
 
2961
  function getMaxIntermediateImageSize() {
2962
  global $_wp_additional_image_sizes;
@@ -3069,8 +3183,10 @@ class WPShortPixel {
3069
  public function getResizeHeight() {
3070
  return $this->_settings->resizeHeight;
3071
  }
3072
- public function getAffiliateSufix() {
3073
- return $this->_affiliateSufix;
 
 
3074
  }
3075
  public function getVerifiedKey() {
3076
  return $this->_settings->verifiedKey;
@@ -3086,4 +3202,31 @@ class WPShortPixel {
3086
  return $this->spMetaDao;
3087
  }
3088
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3089
  }
4
 
5
  const BULK_EMPTY_QUEUE = 0;
6
 
 
 
7
  private $_apiInterface = null;
8
  private $_settings = null;
9
  private $prioQ = null;
29
 
30
  $isAdminUser = current_user_can( 'manage_options' );
31
 
 
32
  $this->_settings = new WPShortPixelSettings();
33
  $this->_apiInterface = new ShortPixelAPI($this->_settings);
34
+ $this->cloudflareApi = new ShortPixelCloudFlareApi($this->_settings->cloudflareEmail, $this->_settings->cloudflareAuthKey, $this->_settings->cloudflareZoneID);
35
  $this->hasNextGen = ShortPixelNextGenAdapter::hasNextGen();
36
  $this->spMetaDao = new ShortPixelCustomMetaDao(new WpShortPixelDb(), $this->_settings->excludePatterns);
37
  $this->prioQ = new ShortPixelQueue($this, $this->_settings);
176
  WPShortPixelSettings::onDeactivate();
177
  }
178
 
179
+ public function getConflictingPlugins() {
180
  $conflictPlugins = array(
181
  'WP Smush - Image Optimization' => 'wp-smushit/wp-smush.php',
182
  'Imagify Image Optimizer' => 'imagify/imagify.php',
188
  'CheetahO Image Optimizer' => 'cheetaho-image-optimizer/cheetaho.php',
189
  'Zara 4 Image Compression' => 'zara-4/zara-4.php',
190
  'Prizm Image' => 'prizm-image/wp-prizmimage.php',
191
+ 'CW Image Optimizer' => 'cw-image-optimizer/cw-image-optimizer.php'
 
192
  );
193
+ if($this->_settings->processThumbnails) {
194
+ $conflictPlugins = array_merge($conflictPlugins, array(
195
+ 'Regenerate Thumbnails: recreating image files may require re-optimization of the resulting thumbnails, even if they were previously optimized.' => 'regenerate-thumbnails/regenerate-thumbnails.php',
196
+ 'Force Regenerate Thumbnails: recreating image files may require re-optimization of the resulting thumbnails, even if they were previously optimized.' => 'force-regenerate-thumbnails/force-regenerate-thumbnails.php'
197
+ ));
198
+ }
199
  $found = array();
200
  foreach($conflictPlugins as $name => $path) {
201
  if(is_plugin_active($path)) {
209
  if(!ShortPixelQueue::testQ()) {
210
  ShortPixelView::displayActivationNotice('fileperms');
211
  }
212
+ if($this->catchNotice()) { //notices for errors like for example a failed restore notice - these are one time so display them with priority.
213
+ return;
214
+ }
215
  $dismissed = $this->_settings->dismissedNotices ? $this->_settings->dismissedNotices : array();
216
  $this->_settings->dismissedNotices = $dismissed;
217
 
229
  }
230
  }
231
  if(!isset($dismissed['compat'])) {
232
+ $conflictPlugins = $this->getConflictingPlugins();
233
  if(count($conflictPlugins)) {
234
  ShortPixelView::displayActivationNotice('compat', $conflictPlugins);
235
  return;
249
  && (!isset($dismissed['upgmonth']) || !isset($dismissed['upgbulk'])) && isset($this->_settings->currentStats['optimizePdfs'])
250
  && $this->_settings->currentStats['optimizePdfs'] == $this->_settings->optimizePdfs ) {
251
  $screen = get_current_screen();
252
+ $stats = $this->countAllIfNeeded($this->_settings->currentStats, 86400);
253
  $quotaData = $stats;
254
 
255
  //this is for bulk page - alert on the total credits for total images
263
  //looks like the user hasn't got enough credits to process the monthly images, display a notice telling this
264
  ShortPixelView::displayActivationNotice('upgmonth', array('monthAvg' => $this->getMonthAvg($stats), 'monthlyQuota' => $quotaData['APICallsQuotaNumeric']));
265
  }
266
+
267
  }
268
  }
269
 
369
  DEFAULT_COMPRESSION: <?php echo $this->_settings->compressionType; ?>,
370
  MEDIA_ALERT: '<?php echo $this->_settings->mediaAlert ? "done" : "todo"; ?>',
371
  FRONT_BOOTSTRAP: <?php echo $this->_settings->frontBootstrap && (!isset($this->_settings->lastBackAction) || (time() - $this->_settings->lastBackAction > 600)) ? 1 : 0; ?>,
372
+ AJAX_URL: '<?php echo admin_url('admin-ajax.php'); ?>',
373
+ AFFILIATE: '<?php echo(self::getAffiliateSufix());?>'
374
  };
375
  //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).
376
  setTimeout(function($) {
417
  $extraClasses = " shortpixel-hide";
418
  /*translators: toolbar icon tooltip*/
419
  $id = 'short-pixel-notice-toolbar';
420
+ $tooltip = __('ShortPixel optimizing...','shortpixel-image-optimiser') . " " . __('Please do not close this admin page.','shortpixel-image-optimiser');
421
  $icon = "shortpixel.png";
422
  $successLink = $link = admin_url(current_user_can( 'edit_others_posts')? 'upload.php?page=wp-short-pixel-bulk' : 'upload.php');
423
  $blank = "";
510
 
511
  // some plugins (e.g. WP e-Commerce) call the wp_attachment_metadata on just editing the image...
512
  $dbMeta = wp_get_attachment_metadata($ID);
513
+ $refresh = false;
514
+
515
  if(isset($dbMeta['ShortPixelImprovement'])) {
516
  return $meta;
517
  }
549
  try {
550
  $URLsAndPATHs = $this->getURLsAndPATHs($itemHandler);
551
  //send a processing request right after a file was uploaded, do NOT wait for response
552
+ $this->_apiInterface->doRequests($URLsAndPATHs['URLs'], false, $itemHandler, false, $refresh);
553
  } catch(Exception $e) {
554
  $meta['ShortPixelImprovement'] = $e->getMessage();
555
  return $meta;
575
  }
576
  }//end handleMediaLibraryImageUpload
577
 
578
+ /**
579
+ * if the image was optimized in the last hour, send a request to delete from picQueue
580
+ * @param $itemHandler
581
+ * @param bool $urlsAndPaths
582
+ */
583
+ public function maybeDumpFromProcessedOnServer($itemHandler, $urlsAndPaths) {
584
+ $meta = $itemHandler->getMeta();
585
+
586
+ //die(var_dump($itemHandler->getURLsAndPATHs(true, false, true, array())));
587
+
588
+ if(time() - strtotime($meta->getTsOptimized()) < 3600) {
589
+ $this->_apiInterface->doDumpRequests($urlsAndPaths["URLs"]);
590
+ }
591
+ }
592
+
593
  /**
594
  * Convert an uploaded image from PNG to JPG
595
  * @param type $params
801
  }
802
  elseif( $this->_settings->processThumbnails && $meta->getThumbsOpt() !== null
803
  && ($meta->getThumbsOpt() == 0 && count($meta->getThumbs()) > 0
804
+ || $meta->getThumbsOpt() < WpShortPixelMediaLbraryAdapter::countSizesNotExcluded($meta->getThumbs(), $this->_settings->excludeSizes) && is_array($meta->getThumbsOptList()))) { //thumbs were chosen in settings
805
  //if($crtStartQueryID == 44 || $crtStartQueryID == 49) {echo("No THuMBS?");die(var_dump($meta));}
806
  $meta->setThumbsTodo(true);
807
  $item->updateMeta($meta);//wp_update_attachment_metadata($crtStartQueryID, $meta);
1000
  //remove also from the failed list if it failed in the past
1001
  $prio = $this->prioQ->removeFromFailed($itemId);
1002
  $result["Type"] = $meta->getCompressionType() !== null ? ShortPixelAPI::getCompressionTypeName($meta->getCompressionType()) : '';
1003
+ $result["ThumbsTotal"] = $meta->getThumbs() && is_array($meta->getThumbs()) ? WpShortPixelMediaLbraryAdapter::countSizesNotExcluded($meta->getThumbs()): 0;
1004
+ $miss = $meta->getThumbsMissing();
1005
+ $result["ThumbsTotal"] -= is_array($miss) ? count($miss) : 0;
1006
  $result["ThumbsCount"] = $meta->getThumbsOpt()
1007
  ? $meta->getThumbsOpt() //below is the fallback for old optimized images that don't have thumbsOpt
1008
  : ($this->_settings->processThumbnails ? $result["ThumbsTotal"] : 0);
1033
  $bkThumb = '';
1034
  } else {
1035
  if(count($sizes)) {
1036
+ $exclude = $this->_settings->excludeSizes;
1037
+ $exclude = is_array($exclude) ? $exclude : array();
1038
+ $thumb = (isset($sizes["medium"]) && !in_array("medium", $exclude)
1039
+ ? $sizes["medium"]["file"]
1040
+ : (isset($sizes["thumbnail"]) && !in_array("thumbnail", $exclude) ? $sizes["thumbnail"]["file"] : ""));
1041
+ if (!strlen($thumb)) { //fallback to the first in the list
1042
+ foreach($sizes as $sizeName => $sizeVal) {
1043
+ $exclude = $this->_settings->excludeSizes;
1044
+ if(!in_array($sizeName, $exclude)) {
1045
+ $thumb = isset($sizeVal['file']) ? $sizeVal['file'] : '';
1046
+ break;
1047
+ }
1048
+ }
1049
  }
1050
+ }
1051
+ if(!strlen($thumb)) { //fallback to the image itself
1052
  $thumb = is_array($filePath) ? $filePath[count($filePath) - 1] : $filePath;
1053
  }
1054
 
1385
  }
1386
  return $ret;
1387
  }
1388
+
1389
  protected function setFilePerms($file) {
1390
  //die(getenv('USERNAME') ? getenv('USERNAME') : getenv('USER'));
1391
+
1392
+ $perms = @fileperms($file);
1393
+ if(($perms & 0x0100) && ($perms & 0x0080)) {
1394
+ return true;
1395
+ }
1396
+
1397
  if(strtoupper(substr(PHP_OS, 0, 3)) !== 'WIN') {
1398
  //on *nix platforms check also the owner
1399
  $owner = fileowner($file);
1401
  return false;
1402
  }
1403
  }
1404
+
1405
+ if(!@chmod($file, $perms | 0x0100 | 0x0080)) {
1406
+ return false;
 
 
1407
  }
1408
  return true;
1409
  }
1440
  }
1441
  } else {
1442
  if(file_exists($bkFile)) {
1443
+ if(!is_readable($bkFile) || (file_exists($file) && !$this->setFilePerms($file)) ) {
1444
+ $this->throwNotice('generic-err',
1445
+ sprintf(__("File %s cannot be restored due to lack of permissions, please contact your hosting provider to assist you in fixing this.",'shortpixel-image-optimiser'),
1446
+ (is_readable($bkFile) ? "" : "$bkFile and ") . "$file"));
1447
  return false;
1448
  }
1449
  $bkCount++;
1456
  $source = trailingslashit($bkFolder) . $imageData['file'];
1457
  if(!file_exists($source)) continue; // if thumbs were not optimized, then the backups will not be there.
1458
  if(!$this->setFilePerms($source) || (file_exists($dest) && !$this->setFilePerms($dest))) {
1459
+ $failedFile = ($this->setFilePerms($bkFile) ? $file : $bkFile);
1460
+ $this->throwNotice('generic-err',
1461
+ sprintf(__("File %s cannot be restored due to lack of permissions, please contact your hosting provider to assist you in fixing this.",'shortpixel-image-optimiser'),
1462
+ "$failedFile (current permissions: " . sprintf("%o", fileperms($failedFile)) . ")"));
1463
  return false;
1464
  }
1465
  $bkCount++;
1467
  }
1468
  }
1469
  if(!$bkCount) {
1470
+ $this->throwNotice('generic-err', __("No backup files found. Restore not performed.",'shortpixel-image-optimiser'));
1471
  return false;
1472
  }
1473
  }
1525
  unset($meta['ShortPixelPng2Jpg']);
1526
 
1527
  } catch(Exception $e) {
1528
+ $this->throwNotice('generic-err', $e->getMessage());
1529
  return false;
1530
  }
1531
  return $meta;
1532
  }
1533
+
1534
+ /**
1535
+ * used to store a notice to be displayed after the redirect, for ex. when having an error restoring.
1536
+ * @param string $when
1537
+ * @param string $extra
1538
+ */
1539
+ protected function throwNotice($when = 'activate', $extra = '') {
1540
+ set_transient("shortpixel_thrown_notice", array('when' => $when, 'extra' => $extra), 120);
1541
+ }
1542
+
1543
+ protected function catchNotice() {
1544
+ $notice = get_transient("shortpixel_thrown_notice");
1545
+ if(isset($notice['when'])) {
1546
+ ShortPixelView::displayActivationNotice($notice['when'], $notice['extra']);
1547
+ delete_transient("shortpixel_thrown_notice");
1548
+ return true;
1549
+ }
1550
+ return false;
1551
+ }
1552
 
1553
  protected function renameWithRetina($bkFile, $file) {
1554
  @rename($bkFile, $file);
1638
  $ID = intval($_GET['attachment_ID']);
1639
  $meta = wp_get_attachment_metadata($ID);
1640
  //die(var_dump($meta));
1641
+ $thumbsCount = WpShortPixelMediaLbraryAdapter::countSizesNotExcluded($meta['sizes'], $this->_settings->excludeSizes);
1642
  if( isset($meta['ShortPixelImprovement'])
1643
+ && isset($meta['sizes']) && $thumbsCount
1644
  && ( !isset($meta['ShortPixel']['thumbsOpt']) || $meta['ShortPixel']['thumbsOpt'] == 0
1645
+ || (isset($meta['sizes']) && isset($meta['ShortPixel']['thumbsOptList']) && $meta['ShortPixel']['thumbsOpt'] < $thumbsCount))) { //optimized without thumbs, thumbs exist
1646
  $meta['ShortPixel']['thumbsTodo'] = true;
1647
  wp_update_attachment_metadata($ID, $meta);
1648
  $this->prioQ->push($ID);
2082
  if( $this->_settings->verifiedKey ) {
2083
  die(json_encode((object)array('Status' => 'success', 'Details' => $this->_settings->apiKey)));
2084
  }
2085
+ $params = array(
 
2086
  'method' => 'POST',
2087
  'timeout' => 10,
2088
  'redirection' => 5,
2089
  'httpversion' => '1.0',
2090
  'blocking' => true,
2091
+ 'sslverify' => false,
2092
  'headers' => array(),
2093
  'body' => array(
2094
  'plugin_version' => SHORTPIXEL_IMAGE_OPTIMISER_VERSION,
2095
  'email' => isset($_POST['email']) ? trim($_POST['email']) : null,
2096
  'ip' => isset($_SERVER["HTTP_X_FORWARDED_FOR"]) ? $_SERVER["HTTP_X_FORWARDED_FOR"]: $_SERVER['REMOTE_ADDR'],
2097
  //'XDEBUG_SESSION_START' => 'session_name'
2098
+ )
2099
+ );
2100
+
2101
+ $newKeyResponse = wp_remote_post("https://shortpixel.com/free-sign-up-plugin" . $this->getAffiliateSufix(), $params);
2102
+
2103
+ if ( is_object($newKeyResponse) && get_class($newKeyResponse) == 'WP_Error' ) {
2104
  die(json_encode((object)array('Status' => 'fail', 'Details' => '503')));
2105
  }
2106
+ elseif ( isset($newKeyResponse['response']['code']) && $newKeyResponse['response']['code'] <> 200 ) {
2107
+ die(json_encode((object)array('Status' => 'fail', 'Details' => $newKeyResponse['response']['code'])));
2108
  }
2109
+ $body = (object)$this->_apiInterface->parseResponse($newKeyResponse);
2110
+ if($body->Status == 'success') {
2111
+ $key = trim($body->Details);
2112
  $validityData = $this->getQuotaInformation($key, true, true);
2113
  if($validityData['APIKeyValid']) {
2114
  $this->_settings->apiKey = $key;
2115
  $this->_settings->verifiedKey = true;
2116
  }
2117
  }
2118
+ die(json_encode($body));
2119
 
2120
  }
2121
 
2255
  . "<a href='https://shortpixel.com/contact' target='_blank'>" . __('here','shortpixel-image-optimiser') . "</a>.");
2256
  }
2257
  }
2258
+
2259
+ if ( isset( $_POST["saveCloudflare"] ) ) {
2260
+ $cfApi = $this->_settings->cloudflareEmail = sanitize_text_field( $_POST['cloudflare-email'] );
2261
+ $cfAuth = $this->_settings->cloudflareAuthKey = sanitize_text_field( $_POST['cloudflare-auth-key'] );
2262
+ $cfZone = $this->_settings->cloudflareZoneID = sanitize_text_field( $_POST['cloudflare-zone-id'] );
2263
+ $this->cloudflareApi->set_up($cfApi, $cfAuth, $cfZone);
2264
+ }
2265
+
2266
  if( isset($_POST['save']) || isset($_POST['saveAdv'])
2267
  || (isset($_POST['validate']) && $_POST['validate'] == "validate")
2268
  || isset($_POST['removeFolder']) || isset($_POST['recheckFolder'])) {
2386
  }
2387
  $this->_settings->frontBootstrap = (isset($_POST['frontBootstrap']) ? 1: 0);
2388
  $this->_settings->autoMediaLibrary = (isset($_POST['autoMediaLibrary']) ? 1: 0);
2389
+ $this->_settings->excludeSizes = (isset($_POST['excludeSizes']) ? $_POST['excludeSizes']: array());
2390
 
2391
  //Redirect to bulk processing if requested
2392
  if( isset($_POST['save']) && $_POST['save'] == __("Save and Go to Bulk Process",'shortpixel-image-optimiser')
2447
  if(is_wp_error( $resources )) {
2448
  $resources = array();
2449
  }
2450
+
2451
+ $cloudflareAPI = true;
2452
  $this->view->displaySettings($showApiKey, $editApiKey,
2453
  $quotaData, $notice, $resources, $averageCompression, $savedSpace, $savedBandwidth, $remainingImages,
2454
  $totalCallsMade, $fileCount, null /*folder size now on AJAX*/, $customFolders,
2455
+ $folderMsg, $folderMsg ? $addedFolder : false, isset($_POST['saveAdv']), $cloudflareAPI);
2456
  } else {
2457
  $this->view->displaySettings($showApiKey, $editApiKey, $quotaData, $notice);
2458
  }
2499
  $this->_settings->httpProto = 'https';
2500
  }
2501
 
2502
+ $requestURL = $this->_settings->httpProto . '://' . SHORTPIXEL_API . '/v2/api-status.php';
2503
  $args = array(
2504
  'timeout'=> SHORTPIXEL_VALIDATE_MAX_TIMEOUT,
2505
  'body' => array('key' => $apiKey)
2532
  $args['sslverify'] = false;
2533
  }
2534
  $response = wp_remote_post($requestURL, $args);
2535
+
2536
  $comm[] = array("sent" => "POST: " . $requestURL, "args" => $args, "received" => $response);
2537
 
2538
  //some hosting providers won't allow https:// POST connections so we try http:// as well
2564
  $response = wp_remote_get($requestURL, $args);
2565
  $comm[] = array("sent" => "POST: " . $requestURL, "args" => $args, "received" => $response);
2566
  }
2567
+
2568
  $defaultData = array(
2569
  "APIKeyValid" => false,
2570
+ "Message" => __('API Key could not be validated due to a connectivity error.<BR>Your firewall may be blocking us. Please contact your hosting provider and ask them to allow connections from your site to api.shortpixel.com (IP 176.9.21.94).<BR> If you still cannot validate your API Key after this, please <a href="https://shortpixel.com/contact" target="_blank">contact us</a> and we will try to help. ','shortpixel-image-optimiser'),
2571
  "APICallsMade" => __('Information unavailable. Please check your API key.','shortpixel-image-optimiser'),
2572
  "APICallsQuota" => __('Information unavailable. Please check your API key.','shortpixel-image-optimiser'),
2573
  "APICallsMadeOneTime" => 0,
2660
 
2661
  $file = get_attached_file($id);
2662
  $data = wp_get_attachment_metadata($id);
2663
+ //if($extended) var_dump($data);
2664
  $fileExtension = strtolower(pathinfo($file, PATHINFO_EXTENSION));
2665
  $invalidKey = !$this->_settings->verifiedKey;
2666
  $quotaExceeded = $this->_settings->quotaExceeded;
2692
  if( is_numeric($data['ShortPixelImprovement'])
2693
  && !($data['ShortPixelImprovement'] == 0 && isset($data['ShortPixel']['WaitingProcessing'])) //for images that erroneously have ShortPixelImprovement = 0 when WaitingProcessing
2694
  ) { //already optimized
2695
+ $sizesCount = isset($data['sizes']) ? WpShortPixelMediaLbraryAdapter::countSizesNotExcluded($data['sizes']) : 0;
2696
 
2697
  $renderData['status'] = $fileExtension == "pdf" ? 'pdfOptimized' : 'imgOptimized';
2698
  $renderData['percent'] = $this->optimizationPercentIfPng2Jpg($data);
2703
  $renderData['thumbsTotal'] = $sizesCount;
2704
  $renderData['thumbsOpt'] = isset($data['ShortPixel']['thumbsOpt']) ? $data['ShortPixel']['thumbsOpt'] : $sizesCount;
2705
  $renderData['thumbsOptList'] = isset($data['ShortPixel']['thumbsOptList']) ? $data['ShortPixel']['thumbsOptList'] : array();
2706
+ $renderData['excludeSizes'] = isset($data['ShortPixel']['excludeSizes']) ? $data['ShortPixel']['excludeSizes'] : null;
2707
  $renderData['thumbsMissing'] = isset($data['ShortPixel']['thumbsMissing']) ? $data['ShortPixel']['thumbsMissing'] : array();
2708
  $renderData['retinasOpt'] = isset($data['ShortPixel']['retinasOpt']) ? $data['ShortPixel']['retinasOpt'] : null;
2709
  $renderData['exifKept'] = isset($data['ShortPixel']['exifKept']) ? $data['ShortPixel']['exifKept'] : null;
2760
  }
2761
  else { //finally
2762
  $renderData['status'] = $quotaExceeded ? 'quotaExceeded' : 'optimizeNow';
2763
+ $sizes = isset($data['sizes']) ? WpShortPixelMediaLbraryAdapter::countSizesNotExcluded($data['sizes']) : 0;
2764
  $renderData['thumbsTotal'] = $sizes;
2765
  $renderData['message'] = ($fileExtension == "pdf" ? 'PDF' : __('Image','shortpixel-image-optimiser'))
2766
  . __(' not processed.','shortpixel-image-optimiser')
2794
  $this->generateCustomColumn( 'wp-shortPixel', $post->ID, true );
2795
  }
2796
 
2797
+ public function onDeleteImage($post_id) {
2798
  $itemHandler = new ShortPixelMetaFacade($post_id);
2799
+ $urlsPaths = $itemHandler->getURLsAndPATHs(true, false, true, array(), true);
2800
+ if(count($urlsPaths['PATHs'])) {
2801
+ $this->maybeDumpFromProcessedOnServer($itemHandler, $urlsPaths);
2802
+ $this->deleteBackupsAndWebPs($urlsPaths['PATHs']);
2803
+ }
2804
+ return $itemHandler; //return it because we call it also on replace and on replace we need to follow this by deleting SP metadata, on delete it
2805
+ }
2806
+
2807
+ public function deleteBackupsAndWebPs($paths) {
2808
+ $backupFolder = trailingslashit($this->getBackupFolder($paths[0]));
2809
+ foreach($paths as $path) {
2810
  $pos = strrpos($path, ".");
2811
  if ($pos !== false) {
2812
  //$webpPath = substr($path, 0, $pos) . ".webp";
2814
  @unlink(substr($path, 0, $pos) . ".webp");
2815
  @unlink(substr($path, 0, $pos) . "@2x.webp");
2816
  }
2817
+ //delte also the backups for image and retina correspondent
2818
+ $fileName = wp_basename($path);
2819
+ $extension = pathinfo($fileName, PATHINFO_EXTENSION);
2820
+ @unlink($backupFolder . $fileName);
2821
+ @unlink($backupFolder . preg_replace("/\." . $extension . "$/i", '@2x.' . $extension, $fileName));
2822
  }
2823
  }
2824
 
2969
 
2970
  //return an array with URL(s) and PATH(s) for this file
2971
  public function getURLsAndPATHs($itemHandler, $meta = NULL, $onlyThumbs = false) {
2972
+ return $itemHandler->getURLsAndPATHs($this->_settings->processThumbnails, $onlyThumbs, $this->_settings->optimizeRetina, $this->_settings->excludeSizes);
2973
  }
2974
 
2975
 
3053
  }
3054
  return;
3055
  }
3056
+
3057
+ function getAllThumbnailSizes() {
3058
+ global $_wp_additional_image_sizes;
3059
+
3060
+ $sizes_names = get_intermediate_image_sizes();
3061
+ $sizes = array();
3062
+ foreach ( $sizes_names as $size ) {
3063
+ $sizes[ $size ][ 'width' ] = intval( get_option( "{$size}_size_w" ) );
3064
+ $sizes[ $size ][ 'height' ] = intval( get_option( "{$size}_size_h" ) );
3065
+ $sizes[ $size ][ 'crop' ] = get_option( "{$size}_crop" ) ? get_option( "{$size}_crop" ) : false;
3066
+ }
3067
+ if(function_exists('wp_get_additional_image_sizes')) {
3068
+ $sizes = array_merge($sizes, wp_get_additional_image_sizes());
3069
+ } elseif(is_array($_wp_additional_image_sizes)) {
3070
+ $sizes = array_merge($sizes, $_wp_additional_image_sizes);
3071
+ }
3072
+ return $sizes;
3073
+ }
3074
 
3075
  function getMaxIntermediateImageSize() {
3076
  global $_wp_additional_image_sizes;
3183
  public function getResizeHeight() {
3184
  return $this->_settings->resizeHeight;
3185
  }
3186
+ public static function getAffiliateSufix() {
3187
+ return isset($_COOKIE["AffiliateShortPixel"])
3188
+ ? "/affiliate/" . $_COOKIE["AffiliateShortPixel"]
3189
+ : (defined("SHORTPIXEL_AFFILIATE_CODE") && strlen(SHORTPIXEL_AFFILIATE_CODE) ? "/affiliate/" . SHORTPIXEL_AFFILIATE_CODE : "");
3190
  }
3191
  public function getVerifiedKey() {
3192
  return $this->_settings->verifiedKey;
3202
  return $this->spMetaDao;
3203
  }
3204
 
3205
+ /**
3206
+ * @desc Return CloudFlare API E-mail
3207
+ *
3208
+ * @return mixed|null
3209
+ */
3210
+ public function fetch_cloudflare_api_email() {
3211
+ return $this->_settings->cloudflareEmail;
3212
+ }
3213
+
3214
+ /**
3215
+ * @desc Return CloudFlare API key
3216
+ *
3217
+ * @return mixed|null
3218
+ */
3219
+ public function fetch_cloudflare_api_key() {
3220
+ return $this->_settings->cloudflareAuthKey;
3221
+ }
3222
+
3223
+ /**
3224
+ * @desc Return CloudFlare API Zone ID
3225
+ *
3226
+ * @return mixed|null
3227
+ */
3228
+ public function fetch_cloudflare_api_zoneid() {
3229
+ return $this->_settings->cloudflareZoneID;
3230
+ }
3231
+
3232
  }
class/wp-shortpixel-cloudflare-api.php ADDED
@@ -0,0 +1,159 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class ShortPixelCloudFlareApi {
4
+ private $_cloudflareEmail = ''; // $_cloudflareEmail
5
+ private $_cloudflareAuthKey = ''; // $_cloudflareAuthKey
6
+ private $_cloudflareZoneID = ''; // $_cloudflareZoneID
7
+
8
+ public function __construct($cloudflareEmail, $cloudflareAuthKey, $cloudflareZoneID) {
9
+ $this->set_up($cloudflareEmail, $cloudflareAuthKey, $cloudflareZoneID);
10
+ $this->set_up_required_hooks();
11
+ }
12
+
13
+ public function set_up($cloudflareEmail, $cloudflareAuthKey, $cloudflareZoneID) {
14
+ $this->_cloudflareEmail = $cloudflareEmail;
15
+ $this->_cloudflareAuthKey = $cloudflareAuthKey;
16
+ $this->_cloudflareZoneID = $cloudflareZoneID;
17
+ }
18
+
19
+ /**
20
+ * @desc A list of hooks needed for actions towards CloudFlare
21
+ */
22
+ private function set_up_required_hooks() {
23
+ // After the image is optimized we apply the code that will purge cached URL(img) from CloudFlare
24
+ add_action( 'shortpixel_image_optimised', array( $this, 'start_cloudflare_cache_purge_process' ) );
25
+ }
26
+
27
+ /**
28
+ * Method taken from @class WPShortPixelSettings
29
+ *
30
+ * @param string $key
31
+ * @param string|array $val
32
+ */
33
+ public function save_to_wp_options( $key = '', $val = '' ) {
34
+ $ret = update_option( $key, $val, 'no' );
35
+
36
+ //hack for the situation when the option would just not update....
37
+ if ( $ret === false && ! is_array( $val ) && $val != get_option( $key ) ) {
38
+ delete_option( $key );
39
+ $alloptions = wp_load_alloptions();
40
+ if ( isset( $alloptions[ $key ] ) ) {
41
+ wp_cache_delete( 'alloptions', 'options' );
42
+ } else {
43
+ wp_cache_delete( $key, 'options' );
44
+ }
45
+ add_option( $key, $val, '', 'no' );
46
+
47
+ // still not? try the DB way...
48
+ if ( $ret === false && $val != get_option( $key ) ) {
49
+ global $wpdb;
50
+ $sql = "SELECT * FROM {$wpdb->prefix}options WHERE option_name = '" . $key . "'";
51
+ $rows = $wpdb->get_results( $sql );
52
+ if ( count( $rows ) === 0 ) {
53
+ $wpdb->insert( $wpdb->prefix . 'options',
54
+ array( "option_name" => $key, "option_value" => ( is_array( $val ) ? serialize( $val ) : $val ), "autoload" => "no" ),
55
+ array( "option_name" => "%s", "option_value" => ( is_numeric( $val ) ? "%d" : "%s" ) ) );
56
+ } else { //update
57
+ $sql = "update {$wpdb->prefix}options SET option_value=" .
58
+ ( is_array( $val )
59
+ ? "'" . serialize( $val ) . "'"
60
+ : ( is_numeric( $val ) ? $val : "'" . $val . "'" ) ) . " WHERE option_name = '" . $key . "'";
61
+ $rows = $wpdb->get_results( $sql );
62
+ }
63
+
64
+ if ( $val != get_option( $key ) ) {
65
+ //tough luck, gonna use the bomb...
66
+ wp_cache_flush();
67
+ add_option( $key, $val, '', 'no' );
68
+ }
69
+ }
70
+ }
71
+ }
72
+
73
+ /**
74
+ * @desc Start the process of purging all cache for image URL (includes all the image sizes/thumbnails)f1
75
+ *
76
+ * @param $image_id - WordPress image media ID
77
+ */
78
+ function start_cloudflare_cache_purge_process( $image_id ) {
79
+
80
+ // Fetch CloudFlare API credentials
81
+ $cloudflare_auth_email = $this->_cloudflareEmail;
82
+ $cloudflare_auth_key = $this->_cloudflareAuthKey;
83
+ $cloudflare_zone_id = $this->_cloudflareZoneID;
84
+
85
+ if ( ! empty( $cloudflare_auth_email ) && ! empty( $cloudflare_auth_key ) && ! empty( $cloudflare_zone_id ) ) {
86
+
87
+ // Fetch all WordPress install possible thumbnail sizes ( this will not return the full size option )
88
+ $fetch_images_sizes = get_intermediate_image_sizes();
89
+ $image_url_for_purge = array();
90
+ $prepare_request_info = array();
91
+
92
+ // if full image size tag is missing, we need to add it
93
+ if ( ! in_array( 'full', $fetch_images_sizes ) ) {
94
+ $fetch_images_sizes[] = 'full';
95
+ }
96
+
97
+ // Fetch the URL for each image size
98
+ foreach ( $fetch_images_sizes as $size ) {
99
+ // 0 - url; 1 - width; 2 - height
100
+ $image_attributes = wp_get_attachment_image_src( $image_id, $size );
101
+ // Append to the list
102
+ array_push( $image_url_for_purge, $image_attributes[0] );
103
+ }
104
+
105
+ if ( ! empty( $image_url_for_purge ) ) {
106
+ $prepare_request_info['files'] = $image_url_for_purge;
107
+ // Encode the data into JSON before send
108
+ $dispatch_purge_info = wp_json_encode( $prepare_request_info );
109
+ // Set headers for remote API to authenticate for the request
110
+ $dispatch_header = array(
111
+ 'X-Auth-Email: ' . $cloudflare_auth_email,
112
+ 'X-Auth-Key: ' . $cloudflare_auth_key,
113
+ 'Content-Type: application/json'
114
+ );
115
+
116
+ // Start the process of cache purge
117
+ $request_response = $this->delete_url_cache_request_action( "https://api.cloudflare.com/client/v4/zones/" . $cloudflare_zone_id . "/purge_cache", $dispatch_purge_info, $dispatch_header );
118
+
119
+ if ( ! is_array( $request_response ) ) {
120
+ WPShortPixel::log( 'Shortpixel - CloudFlare: The CloudFlare API is not responding correctly' );
121
+ } elseif ( isset( $request_response['success'] ) && isset( $request_response['errors'] ) && false === (bool) $request_response['success'] ) {
122
+ WPShortPixel::log( 'Shortpixel - CloudFlare, Error messages: '
123
+ . (isset($request_response['errors']['message']) ? $request_response['errors']['message'] : json_encode($request_response['errors'])) );
124
+ } else {
125
+ WPShortPixel::log('Shortpixel - CloudFlare successfully requested clear cache for: ' . json_encode($image_url_for_purge));
126
+ }
127
+ } else {
128
+ // No use in running the process
129
+ }
130
+ } else {
131
+ // CloudFlare credentials do not exist
132
+ }
133
+ }
134
+
135
+ /**
136
+ * @desc Send a delete cache request to CloudFlare for specified URL(s)
137
+ *
138
+ * @param string $request_url - The url to which we need to send the DELETE request
139
+ * @param string $parameters_as_json - This JSON will contain the required parameters for DELETE request
140
+ * @param array $request_headers - Authentication information and type of request
141
+ *
142
+ * @return array|mixed|object - Request response as decoded JSON
143
+ */
144
+ private function delete_url_cache_request_action( $request_url = '', $parameters_as_json = '', $request_headers = array() ) {
145
+ $curl_connection = curl_init();
146
+ curl_setopt( $curl_connection, CURLOPT_URL, $request_url );
147
+ curl_setopt( $curl_connection, CURLOPT_CUSTOMREQUEST, "DELETE" );
148
+ curl_setopt( $curl_connection, CURLOPT_POSTFIELDS, $parameters_as_json );
149
+ curl_setopt( $curl_connection, CURLOPT_RETURNTRANSFER, true );
150
+ curl_setopt( $curl_connection, CURLOPT_HTTPHEADER, $request_headers );
151
+ curl_setopt( $curl_connection, CURLOPT_USERAGENT, '"User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.87 Safari/537.36"' );
152
+
153
+ $request_response = curl_exec( $curl_connection );
154
+ $result = json_decode( $request_response, true );
155
+ curl_close( $curl_connection );
156
+
157
+ return $result;
158
+ }
159
+ }
class/wp-shortpixel-settings.php CHANGED
@@ -40,7 +40,13 @@ class WPShortPixelSettings {
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'),
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
+ 'excludeSizes' => array('key' => 'wp-short-pixel-excludeSizes', 'default' => array(), 'group' => 'options'),
44
+
45
+ //CloudFlare
46
+ 'cloudflareEmail' => array( 'key' => 'wp-short-pixel-cloudflareAPIEmail', 'default' => '', 'group' => 'options'),
47
+ 'cloudflareAuthKey' => array( 'key' => 'wp-short-pixel-cloudflareAuthKey', 'default' => '', 'group' => 'options'),
48
+ 'cloudflareZoneID' => array( 'key' => 'wp-short-pixel-cloudflareAPIZoneID', 'default' => '', 'group' => 'options'),
49
+
50
  //optimize other images than the ones in Media Library
51
  'includeNextGen' => array('key' => 'wp-short-pixel-include-next-gen', 'default' => null, 'group' => 'options'),
52
  'hasCustomFolders' => array('key' => 'wp-short-pixel-has-custom-folders', 'default' => false, 'group' => 'options'),
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.9.1
8
  License: GPLv2 or later
9
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
10
 
@@ -36,7 +36,7 @@ Make an instant <a href="http://shortpixel.com/image-compression-test" target="_
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
@@ -228,6 +228,16 @@ The ShortPixel team is here to help. <a href="https://shortpixel.com/contact">Co
228
 
229
  == Changelog ==
230
 
 
 
 
 
 
 
 
 
 
 
231
  = 4.9.1 =
232
  * fix error for older WP versions which don't have wp_raise_memory_limit
233
 
4
  Requires at least: 3.2.0
5
  Tested up to: 4.9
6
  Requires PHP: 5.2
7
+ Stable tag: 4.10.0
8
  License: GPLv2 or later
9
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
10
 
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. You can also **select individual thumbnails to exclude** from optimization.
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
228
 
229
  == Changelog ==
230
 
231
+ = 4.10.0 =
232
+ * option to exclude thumbnails from optimization
233
+ * options to delete Cloudflare cache for optimized images
234
+ * method to define affilate codes for themes
235
+ * error message when restore could not be performed
236
+ * better handling of situations with files with different owner but with write permissions for all
237
+ * fix bug for inner resize when setting and unsetting the resize parameter
238
+ * fix bug for third-party WebP thumbnails registered in the 'sizes' metadata array which were sent to optimization.
239
+ * check if function mb_convert_encoding exists before using it
240
+
241
  = 4.9.1 =
242
  * fix error for older WP versions which don't have wp_raise_memory_limit
243
 
res/css/short-pixel.css CHANGED
@@ -599,6 +599,9 @@ article.sp-tabs section:nth-child(3) h2 {
599
  article.sp-tabs section:nth-child(4) h2 {
600
  left: 556px;
601
  }
 
 
 
602
  article.sp-tabs section h2 a {
603
  display: block;
604
  width: 100%;
599
  article.sp-tabs section:nth-child(4) h2 {
600
  left: 556px;
601
  }
602
+ article.sp-tabs section:nth-child(5) h2 {
603
+ left: 738px;
604
+ }
605
  article.sp-tabs section h2 a {
606
  display: block;
607
  width: 100%;
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;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)}}
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:nth-child(5) h2{left: 738px}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
@@ -781,7 +781,8 @@ function checkBulkProcessingCallApi(){
781
 
782
  switch (data["Status"]) {
783
  case ShortPixel.STATUS_NO_KEY:
784
- setCellMessage(id, data["Message"], "<a class='button button-smaller button-primary' href=\"https://shortpixel.com/wp-apikey\" target=\"_blank\">" + _spTr.getApiKey + "</a>");
 
785
  showToolBarAlert(ShortPixel.STATUS_NO_KEY);
786
  break;
787
  case ShortPixel.STATUS_QUOTA_EXCEEDED:
781
 
782
  switch (data["Status"]) {
783
  case ShortPixel.STATUS_NO_KEY:
784
+ setCellMessage(id, data["Message"], "<a class='button button-smaller button-primary' href=\"https://shortpixel.com/wp-apikey"
785
+ + ShortPixel.AFFILIATE + "\" target=\"_blank\">" + _spTr.getApiKey + "</a>");
786
  showToolBarAlert(ShortPixel.STATUS_NO_KEY);
787
  break;
788
  case ShortPixel.STATUS_QUOTA_EXCEEDED:
res/js/short-pixel.min.js CHANGED
@@ -1 +1 @@
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}};
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"+ShortPixel.AFFILIATE+'" 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
@@ -30,11 +30,45 @@ class ShortPixelAPI {
30
  private $_settings;
31
  private $_maxAttempts = 10;
32
  private $_apiEndPoint;
 
33
 
34
 
35
  public function __construct($settings) {
36
  $this->_settings = $settings;
37
- $this->_apiEndPoint = $this->_settings->httpProto . '://api.shortpixel.com/v2/reducer.php';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
38
  }
39
 
40
  /**
@@ -58,7 +92,7 @@ class ShortPixelAPI {
58
  'cmyk2rgb' => $this->_settings->CMYKtoRGBconversion,
59
  'keep_exif' => ($this->_settings->keepExif ? "1" : "0"),
60
  'convertto' => ($this->_settings->createWebp ? urlencode("+webp") : ""),
61
- 'resize' => $this->_settings->resizeImages + 2 * ($this->_settings->resizeType == 'inner' ? 1 : 0),
62
  'resize_width' => $this->_settings->resizeWidth,
63
  'resize_height' => $this->_settings->resizeHeight,
64
  'urllist' => $URLs
@@ -66,32 +100,15 @@ class ShortPixelAPI {
66
  if($refresh) {
67
  $requestParameters['refresh'] = 1;
68
  }
69
- $arguments = array(
70
- 'method' => 'POST',
71
- 'timeout' => 15,
72
- 'redirection' => 3,
73
- 'sslverify' => false,
74
- 'httpversion' => '1.0',
75
- 'blocking' => $Blocking,
76
- 'headers' => array(),
77
- 'body' => json_encode($requestParameters),
78
- 'cookies' => array()
79
- );
80
- //die(var_dump($requestParameters));
81
- //add this explicitely only for https, otherwise (for http) it slows down the request
82
- if($this->_settings->httpProto !== 'https') {
83
- unset($arguments['sslverify']);
84
- }
85
- //WpShortPixel::log("Calling API with params : " . json_encode($arguments));
86
 
87
- $response = wp_remote_post($this->_apiEndPoint, $arguments );
88
 
89
  //only if $Blocking is true analyze the response
90
  if ( $Blocking )
91
  {
92
  //WpShortPixel::log("API response : " . json_encode($response));
93
 
94
- //die(var_dump(array('URL: ' => $this->_apiEndPoint, '<br><br>REQUEST:' => $arguments, '<br><br>RESPONSE: ' => $response )));
95
  //there was an error, save this error inside file's SP optimization field
96
  if ( is_object($response) && get_class($response) == 'WP_Error' )
97
  {
@@ -289,7 +306,7 @@ class ShortPixelAPI {
289
  //switch protocol based on the formerly detected working protocol
290
  if($this->_settings->downloadProto == '' || $reset) {
291
  //make a test to see if the http is working
292
- $testURL = 'http://api.shortpixel.com/img/connection-test-image.png';
293
  $result = download_url($testURL, 10);
294
  $this->_settings->downloadProto = is_wp_error( $result ) ? 'https' : 'http';
295
  }
@@ -357,20 +374,20 @@ class ShortPixelAPI {
357
  "Message" => __('Error downloading file','shortpixel-image-optimiser') . " ({$fileData->$fileType}) " . $tempFile->get_error_message());
358
  }
359
  //check response so that download is OK
 
 
 
 
 
360
  elseif( filesize($tempFile) != $correctFileSize) {
361
  $size = filesize($tempFile);
362
  @unlink($tempFile);
363
  $returnMessage = array(
364
- "Status" => self::STATUS_ERROR,
365
  "Code" => self::ERR_INCORRECT_FILE_SIZE,
366
  "Message" => sprintf(__('Error downloading file - incorrect file size (downloaded: %s, correct: %s )','shortpixel-image-optimiser'),$size, $correctFileSize));
367
  }
368
- elseif (!file_exists($tempFile)) {
369
- $returnMessage = array("Status" => self::STATUS_ERROR,
370
- "Code" => self::ERR_FILE_NOT_FOUND,
371
- "Message" => __('Unable to locate downloaded file','shortpixel-image-optimiser') . " " . $tempFile);
372
- }
373
- return $returnMessage;
374
  }
375
 
376
  public static function backupImage($mainPath, $PATHs) {
@@ -575,6 +592,9 @@ class ShortPixelAPI {
575
  $meta->setThumbsOptList(is_array($meta->getThumbsOptList()) ? array_unique(array_merge($meta->getThumbsOptList(), $thumbsOptList)) : $thumbsOptList);
576
  $meta->setThumbsOpt(($meta->getThumbsTodo() || $this->_settings->processThumbnails) ? count($meta->getThumbsOptList()) : 0);
577
  $meta->setRetinasOpt($retinas);
 
 
 
578
  $meta->setThumbsTodo(false);
579
  //* Not yet as it doesn't seem to work... */$meta->addThumbs($webpSizes);
580
  if($width && $height) {
30
  private $_settings;
31
  private $_maxAttempts = 10;
32
  private $_apiEndPoint;
33
+ private $_apiDumpEndPoint;
34
 
35
 
36
  public function __construct($settings) {
37
  $this->_settings = $settings;
38
+ $this->_apiEndPoint = $this->_settings->httpProto . '://' . SHORTPIXEL_API . '/v2/reducer.php';
39
+ $this->_apiDumpEndPoint = $this->_settings->httpProto . '://' . SHORTPIXEL_API . '/v2/cleanup.php';
40
+ }
41
+
42
+ protected function prepareRequest($requestParameters, $Blocking = false) {
43
+ $arguments = array(
44
+ 'method' => 'POST',
45
+ 'timeout' => 15,
46
+ 'redirection' => 3,
47
+ 'sslverify' => false,
48
+ 'httpversion' => '1.0',
49
+ 'blocking' => $Blocking,
50
+ 'headers' => array(),
51
+ 'body' => json_encode($requestParameters),
52
+ 'cookies' => array()
53
+ );
54
+ //die(var_dump($requestParameters));
55
+ //add this explicitely only for https, otherwise (for http) it slows down the request
56
+ if($this->_settings->httpProto !== 'https') {
57
+ unset($arguments['sslverify']);
58
+ }
59
+
60
+ return $arguments;
61
+ }
62
+
63
+ public function doDumpRequests($URLs) {
64
+ if(!count($URLs)) {
65
+ return false;
66
+ }
67
+ return wp_remote_post($this->_apiDumpEndPoint, $this->prepareRequest(array(
68
+ 'plugin_version' => SHORTPIXEL_IMAGE_OPTIMISER_VERSION,
69
+ 'key' => $this->_settings->apiKey,
70
+ 'urllist' => $URLs
71
+ ) ) );
72
  }
73
 
74
  /**
92
  'cmyk2rgb' => $this->_settings->CMYKtoRGBconversion,
93
  'keep_exif' => ($this->_settings->keepExif ? "1" : "0"),
94
  'convertto' => ($this->_settings->createWebp ? urlencode("+webp") : ""),
95
+ 'resize' => $this->_settings->resizeImages ? 1 + 2 * ($this->_settings->resizeType == 'inner' ? 1 : 0) : 0,
96
  'resize_width' => $this->_settings->resizeWidth,
97
  'resize_height' => $this->_settings->resizeHeight,
98
  'urllist' => $URLs
100
  if($refresh) {
101
  $requestParameters['refresh'] = 1;
102
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
103
 
104
+ $response = wp_remote_post($this->_apiEndPoint, $this->prepareRequest($requestParameters, $Blocking) );
105
 
106
  //only if $Blocking is true analyze the response
107
  if ( $Blocking )
108
  {
109
  //WpShortPixel::log("API response : " . json_encode($response));
110
 
111
+ //die(var_dump(array('URL: ' => $this->_apiEndPoint, '<br><br>REQUEST:' => $this->prepareRequest($requestParameters), '<br><br>RESPONSE: ' => $response )));
112
  //there was an error, save this error inside file's SP optimization field
113
  if ( is_object($response) && get_class($response) == 'WP_Error' )
114
  {
306
  //switch protocol based on the formerly detected working protocol
307
  if($this->_settings->downloadProto == '' || $reset) {
308
  //make a test to see if the http is working
309
+ $testURL = 'http://' . SHORTPIXEL_API . '/img/connection-test-image.png';
310
  $result = download_url($testURL, 10);
311
  $this->_settings->downloadProto = is_wp_error( $result ) ? 'https' : 'http';
312
  }
374
  "Message" => __('Error downloading file','shortpixel-image-optimiser') . " ({$fileData->$fileType}) " . $tempFile->get_error_message());
375
  }
376
  //check response so that download is OK
377
+ elseif (!file_exists($tempFile)) {
378
+ $returnMessage = array("Status" => self::STATUS_ERROR,
379
+ "Code" => self::ERR_FILE_NOT_FOUND,
380
+ "Message" => __('Unable to locate downloaded file','shortpixel-image-optimiser') . " " . $tempFile);
381
+ }
382
  elseif( filesize($tempFile) != $correctFileSize) {
383
  $size = filesize($tempFile);
384
  @unlink($tempFile);
385
  $returnMessage = array(
386
+ "Status" => self::STATUS_ERROR,
387
  "Code" => self::ERR_INCORRECT_FILE_SIZE,
388
  "Message" => sprintf(__('Error downloading file - incorrect file size (downloaded: %s, correct: %s )','shortpixel-image-optimiser'),$size, $correctFileSize));
389
  }
390
+ return $returnMessage;
 
 
 
 
 
391
  }
392
 
393
  public static function backupImage($mainPath, $PATHs) {
592
  $meta->setThumbsOptList(is_array($meta->getThumbsOptList()) ? array_unique(array_merge($meta->getThumbsOptList(), $thumbsOptList)) : $thumbsOptList);
593
  $meta->setThumbsOpt(($meta->getThumbsTodo() || $this->_settings->processThumbnails) ? count($meta->getThumbsOptList()) : 0);
594
  $meta->setRetinasOpt($retinas);
595
+ if(null !== $this->_settings->excludeSizes) {
596
+ $meta->setExcludeSizes($this->_settings->excludeSizes);
597
+ }
598
  $meta->setThumbsTodo(false);
599
  //* Not yet as it doesn't seem to work... */$meta->addThumbs($webpSizes);
600
  if($width && $height) {
wp-shortpixel-req.php CHANGED
@@ -7,6 +7,7 @@ if(defined('SHORTPIXEL_DEBUG') && SHORTPIXEL_DEBUG === true) {
7
 
8
  require_once('class/wp-short-pixel.php');
9
  require_once('class/wp-shortpixel-settings.php');
 
10
  require_once('shortpixel_api.php');
11
  require_once('class/shortpixel_queue.php');
12
  require_once('class/shortpixel-png2jpg.php');
7
 
8
  require_once('class/wp-short-pixel.php');
9
  require_once('class/wp-shortpixel-settings.php');
10
+ require_once('class/wp-shortpixel-cloudflare-api.php');
11
  require_once('shortpixel_api.php');
12
  require_once('class/shortpixel_queue.php');
13
  require_once('class/shortpixel-png2jpg.php');
wp-shortpixel.php CHANGED
@@ -3,7 +3,7 @@
3
  * Plugin Name: ShortPixel Image Optimizer
4
  * Plugin URI: https://shortpixel.com/
5
  * Description: ShortPixel optimizes images automatically, while guarding the quality of your images. Check your <a href="options-general.php?page=wp-shortpixel" target="_blank">Settings &gt; ShortPixel</a> page on how to start optimizing your image library and make your website load faster.
6
- * Version: 4.9.1
7
  * Author: ShortPixel
8
  * Author URI: https://shortpixel.com
9
  * Text Domain: shortpixel-image-optimiser
@@ -16,9 +16,9 @@ define('SHORTPIXEL_RESET_ON_ACTIVATE', false); //if true TODO set false
16
 
17
  define('SHORTPIXEL_PLUGIN_FILE', __FILE__);
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');
@@ -30,6 +30,7 @@ if(!defined('SHORTPIXEL_MAX_THUMBS')) { //can be defined in wp-config.php
30
  }
31
 
32
  define('SHORTPIXEL_PRESEND_ITEMS', 3);
 
33
 
34
  define('SHORTPIXEL_MAX_EXECUTION_TIME', ini_get('max_execution_time'));
35
 
@@ -90,6 +91,18 @@ function shortPixelHandleImageUploadHook($meta, $ID = null) {
90
  return $pluginInstance->handleMediaLibraryImageUpload($meta, $ID);
91
  }
92
 
 
 
 
 
 
 
 
 
 
 
 
 
93
  function shortPixelPng2JpgHook($params) {
94
  global $pluginInstance;
95
  if(!isset($pluginInstance)) {
@@ -159,6 +172,7 @@ if ( !function_exists( 'vc_action' ) || vc_action() !== 'vc_inline' ) { //handle
159
  if($autoPng2Jpg) {
160
  add_action( 'wp_handle_upload', 'shortPixelPng2JpgHook');
161
  }
 
162
  $autoMediaLibrary = get_option('wp-short-pixel-auto-media-library');
163
  if($autoMediaLibrary) {
164
  add_filter( 'wp_generate_attachment_metadata', 'shortPixelHandleImageUploadHook', 10, 2 );
3
  * Plugin Name: ShortPixel Image Optimizer
4
  * Plugin URI: https://shortpixel.com/
5
  * Description: ShortPixel optimizes images automatically, while guarding the quality of your images. Check your <a href="options-general.php?page=wp-shortpixel" target="_blank">Settings &gt; ShortPixel</a> page on how to start optimizing your image library and make your website load faster.
6
+ * Version: 4.10.0
7
  * Author: ShortPixel
8
  * Author URI: https://shortpixel.com
9
  * Text Domain: shortpixel-image-optimiser
16
 
17
  define('SHORTPIXEL_PLUGIN_FILE', __FILE__);
18
 
19
+ //define('SHORTPIXEL_AFFILIATE_CODE', '');
20
 
21
+ define('SHORTPIXEL_IMAGE_OPTIMISER_VERSION', "4.10.0");
22
  define('SHORTPIXEL_MAX_TIMEOUT', 10);
23
  define('SHORTPIXEL_VALIDATE_MAX_TIMEOUT', 15);
24
  define('SHORTPIXEL_BACKUP', 'ShortpixelBackups');
30
  }
31
 
32
  define('SHORTPIXEL_PRESEND_ITEMS', 3);
33
+ define('SHORTPIXEL_API', 'api.shortpixel.com');
34
 
35
  define('SHORTPIXEL_MAX_EXECUTION_TIME', ini_get('max_execution_time'));
36
 
91
  return $pluginInstance->handleMediaLibraryImageUpload($meta, $ID);
92
  }
93
 
94
+ function shortPixelReplaceHook($params) {
95
+ if(isset($params['post_id'])) { //integration with EnableMediaReplace - that's an upload for replacing an existing ID
96
+ global $pluginInstance;
97
+ if (!isset($pluginInstance)) {
98
+ require_once('wp-shortpixel-req.php');
99
+ $pluginInstance = new WPShortPixel;
100
+ }
101
+ $itemHandler = $pluginInstance->onDeleteImage($params['post_id']);
102
+ $itemHandler->deleteAllSPMeta();
103
+ }
104
+ }
105
+
106
  function shortPixelPng2JpgHook($params) {
107
  global $pluginInstance;
108
  if(!isset($pluginInstance)) {
172
  if($autoPng2Jpg) {
173
  add_action( 'wp_handle_upload', 'shortPixelPng2JpgHook');
174
  }
175
+ add_action('wp_handle_replace', 'shortPixelReplaceHook');
176
  $autoMediaLibrary = get_option('wp-short-pixel-auto-media-library');
177
  if($autoMediaLibrary) {
178
  add_filter( 'wp_generate_attachment_metadata', 'shortPixelHandleImageUploadHook', 10, 2 );