ShortPixel Image Optimizer - Version 3.1.0

Version Description

  • rescale images option
  • referral system
  • show how many thumbs are optimized for each image
  • fix the Visual Composer conflict - thanks to Andy Adams - www.certainlysoftware.com
Download this release

Release Info

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

Code changes from version 3.0.8 to 3.1.0

Files changed (6) hide show
  1. css/short-pixel.css +5 -0
  2. js/short-pixel.js +22 -4
  3. readme.txt +61 -13
  4. shortpixel_api.php +12 -3
  5. shortpixel_view.php +240 -12
  6. wp-shortpixel.php +144 -218
css/short-pixel.css CHANGED
@@ -127,3 +127,8 @@ li.shortpixel-hide {
127
  font-size: 48px;
128
  max-width: 150px;
129
  }
 
 
 
 
 
127
  font-size: 48px;
128
  max-width: 150px;
129
  }
130
+ p.settings-info {
131
+ padding-top: 0px;
132
+ color: #818181;
133
+ font-size:13px;
134
+ }
js/short-pixel.js CHANGED
@@ -96,7 +96,7 @@ function checkBulkProcessingCallApi(){
96
  if(isNaN(ShortPixel.retries)) ShortPixel.retries = 1;
97
  if(ShortPixel.retries < 6) {
98
  console.log("Invalid response from server. Retrying pass " + (ShortPixel.retries + 1) + "...");
99
- setTimeout(checkBulkProgress, 2000);
100
  } else {
101
  console.log("Invalid response from server 6 times. Giving up.");
102
  }
@@ -118,7 +118,7 @@ function checkBulkProcessingCallApi(){
118
  showToolBarAlert(ShortPixel.STATUS_FAIL, data["Message"]);
119
  }
120
  console.log(data["Message"]);
121
- setTimeout(checkBulkProgress, 2000);
122
  break;
123
  case ShortPixel.STATUS_EMPTY_QUEUE:
124
  console.log(data["Message"]);
@@ -137,7 +137,13 @@ function checkBulkProcessingCallApi(){
137
  break;
138
  case ShortPixel.STATUS_SUCCESS:
139
  var percent = data["PercentImprovement"];
140
- setCellMessage(id, "Reduced by <span class='percent'>" + percent + "%</span> | <a href=\"admin.php?action=shortpixel_restore_backup&attachment_ID=" + id + ")\">Restore backup</a>");
 
 
 
 
 
 
141
  var animator = new PercentageAnimator("#sp-msg-" + id + " span.percent", percent);
142
  animator.animate(percent);
143
  if(isBulkPage && typeof data["Thumb"] !== 'undefined' && data["PercentImprovement"] > 0) {
@@ -150,7 +156,7 @@ function checkBulkProcessingCallApi(){
150
  case ShortPixel.STATUS_ERROR: //for error and skip also we retry
151
  case ShortPixel.STATUS_SKIP:
152
  console.log('Server response: ' + response);
153
- setTimeout(checkBulkProgress, 2000);
154
  break;
155
  }
156
  }
@@ -186,6 +192,18 @@ function manualOptimization(id) {
186
  });
187
  }
188
 
 
 
 
 
 
 
 
 
 
 
 
 
189
  function PercentageAnimator(outputSelector, targetPercentage) {
190
  this.animationSpeed = 10;
191
  this.increment = 2;
96
  if(isNaN(ShortPixel.retries)) ShortPixel.retries = 1;
97
  if(ShortPixel.retries < 6) {
98
  console.log("Invalid response from server. Retrying pass " + (ShortPixel.retries + 1) + "...");
99
+ setTimeout(checkBulkProgress, 5000);
100
  } else {
101
  console.log("Invalid response from server 6 times. Giving up.");
102
  }
118
  showToolBarAlert(ShortPixel.STATUS_FAIL, data["Message"]);
119
  }
120
  console.log(data["Message"]);
121
+ setTimeout(checkBulkProgress, 5000);
122
  break;
123
  case ShortPixel.STATUS_EMPTY_QUEUE:
124
  console.log(data["Message"]);
137
  break;
138
  case ShortPixel.STATUS_SUCCESS:
139
  var percent = data["PercentImprovement"];
140
+ var cellMsg = "Reduced by <span class='percent'>" + percent
141
+ + "%</span> | <a href=\"admin.php?action=shortpixel_restore_backup&attachment_ID="
142
+ + id + ")\">Restore backup</a>";
143
+ if(0 + data['ThumbsCount'] > 0) {
144
+ cellMsg += "<br>+" + data['ThumbsCount'] + " thumbnails optimized";
145
+ }
146
+ setCellMessage(id, cellMsg);
147
  var animator = new PercentageAnimator("#sp-msg-" + id + " span.percent", percent);
148
  animator.animate(percent);
149
  if(isBulkPage && typeof data["Thumb"] !== 'undefined' && data["PercentImprovement"] > 0) {
156
  case ShortPixel.STATUS_ERROR: //for error and skip also we retry
157
  case ShortPixel.STATUS_SKIP:
158
  console.log('Server response: ' + response);
159
+ setTimeout(checkBulkProgress, 5000);
160
  break;
161
  }
162
  }
192
  });
193
  }
194
 
195
+ function dismissShortPixelNotice(id) {
196
+ jQuery("#short-pixel-notice-" + id).hide();
197
+ var data = { action : 'shortpixel_dismiss_notice',
198
+ notice_id: id};
199
+ jQuery.get(ajaxurl, data, function(response) {
200
+ data = JSON.parse(response);
201
+ if(data["Status"] == ShortPixel.STATUS_SUCCESS) {
202
+ console.log("dismissed");
203
+ }
204
+ });
205
+ }
206
+
207
  function PercentageAnimator(outputSelector, targetPercentage) {
208
  this.animationSpeed = 10;
209
  this.increment = 2;
readme.txt CHANGED
@@ -1,32 +1,73 @@
1
  === ShortPixel Image Optimizer ===
2
 
3
  Contributors: AlexSP
4
- Tags: picture, optimization, image editor, pngout, upload speed, shortpixel, compression, jpegmini, webp, lossless, cwebp, media, jpegtran, image, image optimisation, image optimization, shrink, picture, photo, optimize photos, compress, performance, tinypng, crunch, pngquant, attachment, optimize, pictures, fast, images, image files, image quality, lossy, upload, kraken, resize, seo, smushit, optipng, kraken image optimizer, ewww, photo optimization, gifsicle, image optimizer, images, krakenio, png, gmagick, image optimize, pdf, pdf optimisation, pdf optimization, optimize pdf, optimise pdf, shrink pdf, jpg, jpeg, jpg optimisation, jpg optimization, optimize jpg, optimise jpg, shrink jpg, gif, animated gif, optimize gif, optimise gif, optimizer, optimiser, compresion, optimization, cruncher, image cruncher, compress png, compress jpg, compress jpeg, compress pdf, faster loading times, image optimiser, improve pagerank, optimise, optimize animated gif, optimise jpeg, optimize jpeg, optimize png, optimise png, optimise pdf, optimize pdf, tinyjpg, short pixel, shortpixel
5
 
6
  Requires at least: 3.0.1
7
  Tested up to: 4.3
8
- Stable tag: 3.0.8
9
  License: GPLv2 or later
10
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
11
 
12
- Fast, easy-to-use and lightweight plugin that optimizes images & PDFs. Preserve a high visual quality of images and make your website load faster!
13
 
14
  == Description ==
15
 
16
- ShortPixel is an image compression tool that helps improve your website performance. The plugin optimizes images automatically using both lossy and lossless compression. Resulting, smaller, images are no different in quality from the original.
17
 
18
- ShortPixel uses powerful algorithms that enable your website to load faster, use less bandwidth and rank better in search. The unique API key you receive for activating the plugin can be used for multiple websites.
19
 
20
- **The ShortPixel package includes:**
21
 
22
- * **Both lossy and lossless optimization:** you can choose between the two types of compression. Lossy for photographs. Lossless for technical drawings, clip art and comics.
23
- * **One API Key for multiple sites:** after registration, you receive an API key that you can further use on several websites or applications.
24
- * **Up to 90% compression rate:** with lossy compression images that were 3MB can crunch to 307Kb, with no before/after differences..
25
- * **Supported formats:** JPG, PNG, PDF, both static and animated GIFS. NEW UPDATE: we recently introduced optimization for PDFs.
26
- * **Backup and restore originals:** if you ever want to return to the original version, images are automatically stored in a backup folder on your hosting servers.
27
- * **Bulk image optimization:** Crunch your image gallery, and downsize your website. This feature may take up to several hours, depending on the number and size of existing images.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
28
 
29
- On the https://ShortPixel.com website, we offer free access to the ShortPixel API which you can use for further image optimization purposes.
30
 
31
  == Installation ==
32
 
@@ -119,6 +160,13 @@ The ShortPixel team is here to help. <a href="https://shortpixel.com/contact">Co
119
 
120
  == Changelog ==
121
 
 
 
 
 
 
 
 
122
  = 3.0.8 =
123
 
124
  * fix issue with files in /tmp dir that weren't deleted in certain cases, issue noted by Daniel - germangoogleguy.com
1
  === ShortPixel Image Optimizer ===
2
 
3
  Contributors: AlexSP
4
+ Tags: picture, optimization, image editor, pngout, upload speed, shortpixel, compression, jpegmini, webp, lossless, cwebp, media, jpegtran, image, image optimisation, image optimization, shrink, picture, photo, optimize photos, compress, performance, tinypng, crunch, pngquant, attachment, optimize, pictures, fast, images, image files, image quality, lossy, upload, kraken, resize, seo, smushit, optipng, kraken image optimizer, ewww, photo optimization, gifsicle, image optimizer, images, krakenio, png, gmagick, image optimize, pdf, pdf optimisation, pdf optimization, optimize pdf, optimise pdf, shrink pdf, jpg, jpeg, jpg optimisation, jpg optimization, optimize jpg, optimise jpg, shrink jpg, gif, animated gif, optimize gif, optimise gif, optimizer, optimiser, compresion, optimization, cruncher, image cruncher, compress png, compress jpg, compress jpeg, compress pdf, faster loading times, image optimiser, improve pagerank, optimise, optimize animated gif, optimise jpeg, optimize jpeg, optimize png, optimise png, optimise pdf, optimize pdf, tinyjpg, short pixel, shortpixel, woocommerce compatible
5
 
6
  Requires at least: 3.0.1
7
  Tested up to: 4.3
8
+ Stable tag: 3.1.0
9
  License: GPLv2 or later
10
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
11
 
12
+ Easy-to-use, lightweight plugin that optimizes images & PDFs. Make your website faster, keeping the images high quality. WooCommerce compatible.
13
 
14
  == Description ==
15
 
16
+ ShortPixel makes your website load faster by reducing the size of your images and helps you rank better in Google search. With both lossy and lossless <a rel="friend" href="https://shortpixel.com">image compression</a> available for all common image types (PNG, JPG, GIF), plus PDF files. The plugin is free to use for 100 images/month.
17
 
 
18
 
19
+ **How does it work?**
20
 
21
+ Both new and old images can be optimized with ShortPixel. Once activated, the plugin instantly processes new images uploaded to your website. Bulk optimization will automatically process all your past image gallery with one click. Images and thumbnails are processed in the cloud, and replaced back into your website. It’s simple to use, yet incredibly powerful.
22
+
23
+
24
+ **Plugin features. What you see is what you get:**
25
+
26
+ * all types of image formats PNG, JPG, GIF (still and animated) and PDF
27
+ * thumbnails and featured images are also optimized
28
+ * free 100 image credits/month. Images that are optimized less that 5% are bonus
29
+ * no file size limit
30
+ * originals are saved in a backup folder and can be manually restored
31
+ * 'Bulk' optimize past gallery with one click
32
+ * 40 days optimization report with all image details and overall statistics
33
+ * works great for eCommerce websites using WooCommerce plugin
34
+ * multisite support for a single API key
35
+ * compatible with WP Engine hosted websites
36
+ * 24h support from our fantastic team
37
+
38
+ ShortPixel free and paid plans offer the same features and deliver the same optimization quality. The difference is made by the available image quota. 100 images/month are for free, additional image quota requires a small fee ($4,99 for 5,000 image credits).
39
+
40
+ Both monthly subscriptions and one-time plans are available. The same plan can be used for multiple websites. Check our <a rel="friend" href="http://shortpixel.com/free-demo">free demo</a> and see the <a href="http://shortpixel.com/pricing">optimization plans</a> on our site.
41
+
42
+ We believe in a better society, so we support educational non-profits. <a href="http://shortpixel.com/contact">Contact us</a> and we’ll see how we can help!
43
+
44
+
45
+ **Why use ShortPixel to optimize you images?**
46
+
47
+ Image size is crucial to your website’s speed, and website speed affects search ranking. With ShortPixel plugin you will downsize your images and improve your web performance on the spot.
48
+
49
+ Read more about how <a href="http://googlewebmastercentral.blogspot.ro/2010/04/using-site-speed-in-web-search-ranking.html">Google ranks website speed</a>.
50
+
51
+ > ★★★★★ **Increased Page Speed and Optimizes Properly**
52
+ > "I noticed a huge difference on page speed after running the bulk compression. Does exactly as promised. An excellent plugin for those that care about page speed, SEO and optimizing their sites to the fullest potential." — [BrowCo](https://wordpress.org/support/topic/increased-page-speed-and-optimizes-properly#post-)
53
+ >
54
+
55
+
56
+ **New features coming soon:**
57
+
58
+ * Affiliate system
59
+ * support for NextGen Galley
60
+ * mass restore for backed-up images
61
+
62
+
63
+ **Get in touch!**
64
+
65
+ Website <a href="https://shortpixel.com">https://shortpixel.com</a>
66
+ Twitter <a href="https://twitter.com/shortpixel">https://twitter.com/shortpixel</a>
67
+ Google+ <a href="https://www.google.com/+Shortpixelpage">https://www.google.com/+Shortpixelpage</a>
68
+ Facebook <a href="https://www.facebook.com/ShortPixel">https://www.facebook.com/ShortPixel</a>
69
+ LinkedIn <a href="https://www.linkedin.com/company/shortpixel">https://www.linkedin.com/company/shortpixel</a>
70
 
 
71
 
72
  == Installation ==
73
 
160
 
161
  == Changelog ==
162
 
163
+ = 3.1.0 =
164
+
165
+ * rescale images option
166
+ * referral system
167
+ * show how many thumbs are optimized for each image
168
+ * fix the Visual Composer conflict - thanks to Andy Adams - www.certainlysoftware.com
169
+
170
  = 3.0.8 =
171
 
172
  * fix issue with files in /tmp dir that weren't deleted in certain cases, issue noted by Daniel - germangoogleguy.com
shortpixel_api.php CHANGED
@@ -18,6 +18,9 @@ class ShortPixelAPI {
18
  private $_CMYKtoRGBconversion = '';
19
  private $_maxAttempts = 10;
20
  private $_apiEndPoint = 'https://api.shortpixel.com/v2/reducer.php';
 
 
 
21
 
22
  public function setCompressionType($compressionType) {
23
  $this->_compressionType = $compressionType;
@@ -38,10 +41,13 @@ class ShortPixelAPI {
38
  return $this->_apiKey;
39
  }
40
 
41
- public function __construct($apiKey, $compressionType, $CMYK2RGB) {
42
  $this->_apiKey = $apiKey;
43
  $this->setCompressionType($compressionType);
44
  $this->setCMYKtoRGB($CMYK2RGB);
 
 
 
45
  add_action('processImageAction', array(&$this, 'processImageAction'), 10, 4);
46
  }
47
 
@@ -56,6 +62,9 @@ class ShortPixelAPI {
56
  'key' => $this->_apiKey,
57
  'lossy' => $this->_compressionType,
58
  'cmyk2rgb' => $this->_CMYKtoRGBconversion,
 
 
 
59
  'urllist' => $URLs
60
  );
61
  $arguments = array(
@@ -69,7 +78,7 @@ class ShortPixelAPI {
69
  'body' => json_encode($requestParameters),
70
  'cookies' => array()
71
  );
72
-
73
  $response = wp_remote_post($this->_apiEndPoint, $arguments );
74
 
75
  //only if $Blocking is true analyze the response
@@ -140,7 +149,7 @@ class ShortPixelAPI {
140
  }
141
  }
142
  $response = $this->doRequests($URLs, true, $ID);//send requests to API
143
-
144
  if($response['response']['code'] != 200)//response <> 200 -> there was an error apparently?
145
  return array("Status" => self::STATUS_FAIL, "Message" => "There was an error and your request was not processed.");
146
 
18
  private $_CMYKtoRGBconversion = '';
19
  private $_maxAttempts = 10;
20
  private $_apiEndPoint = 'https://api.shortpixel.com/v2/reducer.php';
21
+ private $_resizeImages;
22
+ private $_resizeWidth;
23
+ private $_resizeHeight;
24
 
25
  public function setCompressionType($compressionType) {
26
  $this->_compressionType = $compressionType;
41
  return $this->_apiKey;
42
  }
43
 
44
+ public function __construct($apiKey, $compressionType, $CMYK2RGB, $resize, $width, $height) {
45
  $this->_apiKey = $apiKey;
46
  $this->setCompressionType($compressionType);
47
  $this->setCMYKtoRGB($CMYK2RGB);
48
+ $this->_resizeImages = $resize;
49
+ $this->_resizeWidth = $width;
50
+ $this->_resizeHeight = $height;
51
  add_action('processImageAction', array(&$this, 'processImageAction'), 10, 4);
52
  }
53
 
62
  'key' => $this->_apiKey,
63
  'lossy' => $this->_compressionType,
64
  'cmyk2rgb' => $this->_CMYKtoRGBconversion,
65
+ 'resize' => $this->_resizeImages,
66
+ 'resize_width' => $this->_resizeWidth,
67
+ 'resize_height' => $this->_resizeHeight,
68
  'urllist' => $URLs
69
  );
70
  $arguments = array(
78
  'body' => json_encode($requestParameters),
79
  'cookies' => array()
80
  );
81
+
82
  $response = wp_remote_post($this->_apiEndPoint, $arguments );
83
 
84
  //only if $Blocking is true analyze the response
149
  }
150
  }
151
  $response = $this->doRequests($URLs, true, $ID);//send requests to API
152
+
153
  if($response['response']['code'] != 200)//response <> 200 -> there was an error apparently?
154
  return array("Status" => self::STATUS_FAIL, "Message" => "There was an error and your request was not processed.");
155
 
shortpixel_view.php CHANGED
@@ -18,9 +18,14 @@ class ShortPixelView {
18
  <br/>
19
  <div class="wrap" style="background-color: #fff; border-left: 4px solid #ff0000; box-shadow: 0 1px 1px 0 rgba(0, 0, 0, 0.1); padding: 1px 12px;">
20
  <h3>Quota Exceeded</h3>
21
- <p>The plugin has optimized <?=number_format($quotaData['APICallsMadeNumeric'] + $quotaData['APICallsMadeOneTimeNumeric'])?> images and stopped because it reached the available quota limit.</p>
22
- <p>It’s simple to upgrade, just <a href='https://shortpixel.com/login/<?=$this->ctrl->getApiKey()?>' target='_blank'>log into your account</a> and see the available options.</p>
23
- <p>You can immediately start processing 5,000 images/month for &#36;4,99, choose another plan that suits you or <a href='https://shortpixel.com/contact' target='_blank'>contact us</a> for larger compression needs.</p>
 
 
 
 
 
24
  <input type='button' name='checkQuota' class='button button-primary' value='Confirm New Quota' onclick="javascript:window.location.reload();" style="margin-bottom:12px;">
25
  </div> <?php
26
  }
@@ -33,15 +38,37 @@ class ShortPixelView {
33
  <?php
34
  }
35
 
36
- public function displayBulkProcessingForm($imageCount, $imgProcessedCount, $thumbsProcessedCount, $under5PercentCount, $bulkRan, $averageCompression, $filesOptimized, $savedSpace, $percent) {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
37
  ?>
38
  <div class="wrap short-pixel-bulk-page">
39
  <h1>Bulk Image Optimization by ShortPixel</h1>
40
  <?php
41
  if ( !$bulkRan ) { ?>
42
  <p>You have <?=number_format($imageCount['mainFiles'])?> images in your Media Library and <?=number_format($imageCount['totalFiles'] - $imageCount['mainFiles'])?> smaller thumbnails, associated to these images.</p>
43
- <?php if($imgProcessedCount["totalFiles"] > 0) { ?>
44
- <p>From these, <?=number_format($imgProcessedCount['mainFiles'])?> images and <?=number_format($imgProcessedCount['totalFiles'] - $imgProcessedCount['mainFiles'])?> thumbnails were already processed by ShorPixel</p>
45
  <?php } ?>
46
  <p>If the box below is checked, <b>ShortPixel will process a total of <?=number_format($imageCount['totalFiles'] - $imgProcessedCount['totalFiles'])?> images.</b> However, images with less than 5% optimization will not be counted out of your quota, so the final number of counted images could be smaller.</p>
47
  <p>Thumbnails are important because they are displayed on most of your website's pages and they may generate more traffic than the originals. Optimizing thumbnails will improve your overall website speed. However, if you don't want to optimize thumbnails, please uncheck the box below.</p>
@@ -59,18 +86,21 @@ class ShortPixelView {
59
  <?=$this->displayBulkProgressBar(false, $percent, "")?>
60
  <p>Please see below the optimization status so far:</p>
61
  <?=$this->displayBulkStats($filesOptimized, $thumbsProcessedCount, $under5PercentCount, $averageCompression, $savedSpace)?>
 
 
 
 
62
  <p>You can continue optimizing your Media Gallery from where you left, by clicking the Resume processing button. Already optimized images will not be reprocessed.</p>
63
  <?php
64
  } else { ?>
65
  <p>Congratulations, your media library has been successfully optimized!</p>
66
  <?=$this->displayBulkStats($filesOptimized, $thumbsProcessedCount, $under5PercentCount, $averageCompression, $savedSpace)?>
67
  <p>Go to the ShortPixel <a href='<?=get_admin_url()?>options-general.php?page=wp-shortpixel#facts'>Stats</a> and see all your websites' optimized stats. Download your detailed <a href="https://api.shortpixel.com/v2/report.php?key=<?=$this->ctrl->getApiKey()?>">Optimization Report</a> to check your image optimization statistics for the last 40 days</p>
68
- <?php if($imgProcessedCount['totalFiles'] < $imageCount['totalFiles']) { ?>
69
- <p><?=number_format($imageCount['mainFiles'] - $imgProcessedCount['mainFiles'])?> images and <?=number_format(($imageCount['totalFiles'] - $imageCount['mainFiles']) - ($imgProcessedCount['totalFiles'] - $imgProcessedCount['mainFiles']))?> thumbnails are not yet optimized by ShortPixel.</p>
70
- <?php } ?>
71
- <?php
72
  $failed = $this->ctrl->getPrioQ()->getFailed();
73
- //die(print_r($failed));
74
  if(count($failed)) { ?>
75
  <p>The following images are not writable so ShortPixel could not update the files. Please check the rights for these and then restart the optimization process.</p>
76
  <?=$this->displayFailed($failed)?>
@@ -127,7 +157,7 @@ class ShortPixelView {
127
  <div class="bulk-progress">
128
  <div id="bulk-progress" class="progress" >
129
  <div class="progress-img" style="left: <?=$percent?>%;">
130
- <img src="<?=WP_PLUGIN_URL?>/shortpixel-image-optimiser/img/slider.png">
131
  <span><?=$percentAfter?></span>
132
  </div>
133
  <div class="progress-left" style="width: <?=$percent?>%"><?=$percentBefore?></div>
@@ -173,5 +203,203 @@ class ShortPixelView {
173
  <?php
174
  }
175
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
176
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
177
  }
18
  <br/>
19
  <div class="wrap" style="background-color: #fff; border-left: 4px solid #ff0000; box-shadow: 0 1px 1px 0 rgba(0, 0, 0, 0.1); padding: 1px 12px;">
20
  <h3>Quota Exceeded</h3>
21
+ <p>The plugin has optimized <strong><?=number_format($quotaData['APICallsMadeNumeric'] + $quotaData['APICallsMadeOneTimeNumeric'])?> images</strong> and stopped because it reached the available quota limit.
22
+ <?php if($quotaData['totalProcessedFiles'] < $quotaData['totalFiles']) { ?>
23
+ <strong><?=number_format($quotaData['mainFiles'] - $quotaData['mainProcessedFiles'])?> images and
24
+ <?=number_format(($quotaData['totalFiles'] - $quotaData['mainFiles']) - ($quotaData['totalProcessedFiles'] - $quotaData['mainProcessedFiles']))?> thumbnails</strong> are not yet optimized by ShortPixel.
25
+ <?php } ?></p>
26
+ <p>It’s simple to upgrade, just <a href='https://shortpixel.com/login/<?=$this->ctrl->getApiKey()?>' target='_blank'>log into your account</a> and see the available options.
27
+ You can immediately start processing 5,000 images/month for &#36;4,99, choose another plan that suits you or <a href='https://shortpixel.com/contact' target='_blank'>contact us</a> for larger compression needs.</p>
28
+ <p>Get more image credits by referring ShortPixel to your friends! <a href="https://shortpixel.com/login/<?=$this->ctrl->getApiKey()?>/tell-a-friend" target="_blank">Check your account</a> for your unique referral link. For each user that joins, you will receive +100 additional image credits/month.</p>
29
  <input type='button' name='checkQuota' class='button button-primary' value='Confirm New Quota' onclick="javascript:window.location.reload();" style="margin-bottom:12px;">
30
  </div> <?php
31
  }
38
  <?php
39
  }
40
 
41
+ public function displayActivationNotice($when = 'activate') { ?>
42
+ <div class='notice notice-warning' id='short-pixel-notice-<?=$when?>'>
43
+ <?php if($when != 'activate') { ?>
44
+ <div style="float:right;"><a href="javascript:dismissShortPixelNotice('<?=$when?>')" class="button" style="margin-top:10px;">Dismiss</a></div>
45
+ <?php } ?>
46
+ <h3>ShortPixel Optimization</h3> <?php
47
+ switch($when) {
48
+ case '2h' :
49
+ echo "Action needed. Please <a href='https://shortpixel.com/wp-apikey' target='_blank'>get your API key</a> to activate your ShortPixel plugin.<BR><BR>";
50
+ break;
51
+ case '3d':
52
+ echo "Your image gallery is not optimized. It takes 2 minutes to <a href='https://shortpixel.com/wp-apikey' target='_blank'>get your API key</a> and activate your ShortPixel plugin.<BR><BR>";
53
+ break;
54
+ case 'activate':
55
+ $this->displayApiKeyAlert();
56
+ break;
57
+ }
58
+ ?>
59
+ </div>
60
+ <?php
61
+ }
62
+
63
+ public function displayBulkProcessingForm($quotaData, $thumbsProcessedCount, $under5PercentCount, $bulkRan, $averageCompression, $filesOptimized, $savedSpace, $percent) {
64
  ?>
65
  <div class="wrap short-pixel-bulk-page">
66
  <h1>Bulk Image Optimization by ShortPixel</h1>
67
  <?php
68
  if ( !$bulkRan ) { ?>
69
  <p>You have <?=number_format($imageCount['mainFiles'])?> images in your Media Library and <?=number_format($imageCount['totalFiles'] - $imageCount['mainFiles'])?> smaller thumbnails, associated to these images.</p>
70
+ <?php if($quotaData["totalProcessedFiles"] > 0) { ?>
71
+ <p>From these, <?=number_format($quotaData['mainProcessedFiles'])?> images and <?=number_format($quotaData['totalProcessedFiles'] - $quotaData['mainProcessedFiles'])?> thumbnails were already processed by ShorPixel</p>
72
  <?php } ?>
73
  <p>If the box below is checked, <b>ShortPixel will process a total of <?=number_format($imageCount['totalFiles'] - $imgProcessedCount['totalFiles'])?> images.</b> However, images with less than 5% optimization will not be counted out of your quota, so the final number of counted images could be smaller.</p>
74
  <p>Thumbnails are important because they are displayed on most of your website's pages and they may generate more traffic than the originals. Optimizing thumbnails will improve your overall website speed. However, if you don't want to optimize thumbnails, please uncheck the box below.</p>
86
  <?=$this->displayBulkProgressBar(false, $percent, "")?>
87
  <p>Please see below the optimization status so far:</p>
88
  <?=$this->displayBulkStats($filesOptimized, $thumbsProcessedCount, $under5PercentCount, $averageCompression, $savedSpace)?>
89
+ <?php if($quotaData['totalProcessedFiles'] < $quotaData['totalFiles']) { ?>
90
+ <p><?=number_format($quotaData['mainFiles'] - $quotaData['mainProcessedFiles'])?> images and
91
+ <?=number_format(($quotaData['totalFiles'] - $quotaData['mainFiles']) - ($quotaData['totalProcessedFiles'] - $quotaData['mainProcessedFiles']))?> thumbnails are not yet optimized by ShortPixel.</p>
92
+ <?php } ?>
93
  <p>You can continue optimizing your Media Gallery from where you left, by clicking the Resume processing button. Already optimized images will not be reprocessed.</p>
94
  <?php
95
  } else { ?>
96
  <p>Congratulations, your media library has been successfully optimized!</p>
97
  <?=$this->displayBulkStats($filesOptimized, $thumbsProcessedCount, $under5PercentCount, $averageCompression, $savedSpace)?>
98
  <p>Go to the ShortPixel <a href='<?=get_admin_url()?>options-general.php?page=wp-shortpixel#facts'>Stats</a> and see all your websites' optimized stats. Download your detailed <a href="https://api.shortpixel.com/v2/report.php?key=<?=$this->ctrl->getApiKey()?>">Optimization Report</a> to check your image optimization statistics for the last 40 days</p>
99
+ <?php if($quotaData['totalProcessedFiles'] < $quotaData['totalFiles']) { ?>
100
+ <p><?=number_format($quotaData['mainFiles'] - $quotaData['mainProcessedFiles'])?> images and
101
+ <?=number_format(($quotaData['totalFiles'] - $quotaData['mainFiles']) - ($quotaData['totalProcessedFiles'] - $quotaData['mainProcessedFiles']))?> thumbnails are not yet optimized by ShortPixel.</p>
102
+ <?php }
103
  $failed = $this->ctrl->getPrioQ()->getFailed();
 
104
  if(count($failed)) { ?>
105
  <p>The following images are not writable so ShortPixel could not update the files. Please check the rights for these and then restart the optimization process.</p>
106
  <?=$this->displayFailed($failed)?>
157
  <div class="bulk-progress">
158
  <div id="bulk-progress" class="progress" >
159
  <div class="progress-img" style="left: <?=$percent?>%;">
160
+ <img src="<?=plugins_url( 'img/slider.png', __FILE__ )?>">
161
  <span><?=$percentAfter?></span>
162
  </div>
163
  <div class="progress-left" style="width: <?=$percent?>%"><?=$percentBefore?></div>
203
  <?php
204
  }
205
 
206
+ public function displaySettingsForm($quotaData) {
207
+ $checked = ($this->ctrl->processThumbnails() ? 'checked' : '');
208
+ $checkedBackupImages = ($this->ctrl->backupImages() ? 'checked' : '');
209
+ $cmyk2rgb = ($this->ctrl->getCMYKtoRGBconversion() ? 'checked' : '');
210
+ $resize = ($this->ctrl->getResizeImages() ? 'checked' : '');
211
+ $resizeDisabled = ($this->ctrl->getResizeImages() ? '' : 'disabled');
212
+ $minSizes = $this->ctrl->getMaxIntermediateImageSize();
213
+ ?>
214
+ <form name='wp_shortpixel_options' action='' method='post' id='wp_shortpixel_options'>
215
+ <table class="form-table">
216
+ <tbody>
217
+ <tr>
218
+ <th scope="row"><label for="key">API Key:</label></th>
219
+ <td><input name="key" type="text" id="key" value="<?= $this->ctrl->getApiKey() ?>" class="regular-text">
220
+ <input type="hidden" name="validate" id="valid" value=""/>
221
+ <button type="button" id="validate" class="button button-primary" title="Validate the provided API key"
222
+ onclick="validateKey()">Validate</button>
223
+ </td>
224
+ </tr>
225
+ <?php if (!$this->ctrl->getVerifiedKey()) { //if invalid key we display the link to the API Key ?>
226
+ <tr>
227
+ <td style="padding-left: 0px;" colspan="2">Don’t have an API Key?
228
+ <a href="https://shortpixel.com/wp-apikey<?= $this->ctrl->getAffiliateSufix() ?>" target="_blank">Sign up, it’s free.</a>
229
+ </td>
230
+ </tr>
231
+ </tbody>
232
+ </table>
233
+ </form>
234
+ <?php } else { //if valid key we display the rest of the options ?>
235
+ <tr>
236
+ <th scope="row">
237
+ <label for="compressionType">Compression type:</label>
238
+ </th>
239
+ <td>
240
+ <input type="radio" name="compressionType" value="1" <?= $this->ctrl->getCompressionType() == 1 ? "checked" : "" ?>>Lossy</br></br>
241
+ <input type="radio" name="compressionType" value="0" <?= $this->ctrl->getCompressionType() != 1 ? "checked" : "" ?>>Lossless
242
+ </td>
243
+ </tr>
244
+ </tbody>
245
+ </table>
246
+ <p style="color: #818181;"> <b>Lossy compression: </b>lossy has a better compression rate than lossless compression.</br>The resulting image
247
+ is not 100% identical with the original. Works well for photos taken with your camera.</br></br>
248
+ <b>Lossless compression: </b> the shrunk image will be identical with the original and smaller in size.</br>Use this
249
+ when you do not want to lose any of the original image's details. Works best for technical drawings,
250
+ clip art and comics. </p>
251
+ <table class="form-table">
252
+ <tbody>
253
+ <tr>
254
+ <th scope="row"><label for="thumbnails">Also include thumbnails:</label></th>
255
+ <td><input name="thumbnails" type="checkbox" id="thumbnails" <?= $checked ?>> Apply compression also to
256
+ <strong><?=number_format(($quotaData['totalFiles'] - $quotaData['mainFiles']) - ($quotaData['totalProcessedFiles'] - $quotaData['mainProcessedFiles']))?>
257
+ image thumbnails.</strong>
258
+ <p class="settings-info">Thumbnails count up to your total quota, and should be optimized for best results of your website's speed.</p>
259
+ </td>
260
+ </tr>
261
+ <tr>
262
+ <th scope="row"><label for="backupImages">Image backup</label></th>
263
+ <td>
264
+ <input name="backupImages" type="checkbox" id="backupImages" <?= $checkedBackupImages ?>> Save and keep a backup of your original images in a separate folder.
265
+ </td>
266
+ </tr>
267
+ <tr>
268
+ <th scope="row"><label for="backupImages">CMYK to RGB conversion</label></th>
269
+ <td>
270
+ <input name="cmyk2rgb" type="checkbox" id="cmyk2rgb" <?= $cmyk2rgb ?>>Adjust your images for computer and mobile screen display.
271
+ </td>
272
+ </tr>
273
+ <tr>
274
+ <th scope="row"><label for="resize">Resize larger images</label></th>
275
+ <td>
276
+ <input name="resize" type="checkbox" id="resize" <?= $resize ?>> to maximum
277
+ <input type="text" name="width" id="width" style="width:70px" value="<?= max($this->ctrl->getResizeWidth(), $minSizes['width']) ?>" <?= $resizeDisabled ?>/> pixels wide &times;
278
+ <input type="text" name="height" id="height" style="width:70px" value="<?= max($this->ctrl->getResizeHeight(), $minSizes['height']) ?>" <?= $resizeDisabled ?>/> pixels high
279
+ <p class="settings-info"> Recommended for large photos, like the ones taken with your phone. Saved space can go up to 80% after resizing.<br/>
280
+ The new resolution cannot be less than your largest thumbnail size, which is <?=$minSizes['width']?> &times; <?=$minSizes['height']?> pixels.</p>
281
+ </td>
282
+ </tr>
283
+ </tbody>
284
+ </table>
285
+ <p class="submit">
286
+ <input type="submit" name="save" id="save" class="button button-primary" title="Save Changes" value="Save Changes"> &nbsp;and then&nbsp;
287
+ <a class="button button-primary" title="Process all the images in your Media Library" href="upload.php?page=wp-short-pixel-bulk">Bulk Process</a>
288
+ </p>
289
+ </form>
290
+ <script>
291
+ var rad = document.wp_shortpixel_options.compressionType;
292
+ var prev = null;
293
+ var minWidth = <?=$minSizes['width']?>,
294
+ minHeight = <?=$minSizes['height']?>;
295
+ for(var i = 0; i < rad.length; i++) {
296
+ rad[i].onclick = function() {
297
+
298
+ if(this !== prev) {
299
+ prev = this;
300
+ }
301
+ alert('This type of optimization will apply to new uploaded images.\\nImages that were already processed will not be re-optimized.');
302
+ };
303
+ }
304
+ function enableResize(elm) {
305
+ if(jQuery(elm).is(':checked')) {
306
+ jQuery("#width,#height").removeAttr("disabled");
307
+ } else {
308
+ jQuery("#width,#height").attr("disabled", "disabled");
309
+ }
310
+ }
311
+ enableResize("#resize");
312
+ jQuery("#resize").change(function(){ enableResize(this) });
313
+ jQuery("#width").blur(function(){
314
+ jQuery(this).val(jQuery(this).val() < minWidth ? minWidth : parseInt(jQuery(this).val()));
315
+ });
316
+ jQuery("#height").blur(function(){
317
+ jQuery(this).val(jQuery(this).val() < minHeight ? minHeight : parseInt(jQuery(this).val()));
318
+ });
319
+ </script>
320
+ <?php } ?>
321
+ <script>
322
+ function validateKey(){
323
+ jQuery('#valid').val('validate');
324
+ jQuery('#wp_shortpixel_options').submit();
325
+ }
326
+ jQuery("#key").keypress(function(e) {
327
+ if(e.which == 13) {
328
+ jQuery('#valid').val('validate');
329
+ }
330
+ });
331
+ </script>
332
+ <?php
333
+ }
334
 
335
+ function displaySettingsStats($averageCompression, $savedSpace, $savedBandwidth,
336
+ $quotaData, $remainingImages, $totalCallsMade, $fileCount, $backupFolderSize) { ?>
337
+ <a id="facts"></a>
338
+ <h3>Your ShortPixel Stats</h3>
339
+ <table class="form-table">
340
+ <tbody>
341
+ <tr>
342
+ <th scope="row"><label for="averagCompression">Average compression of your files:</label></th>
343
+ <td><?=$averageCompression?>%</td>
344
+ </tr>
345
+ <tr>
346
+ <th scope="row"><label for="savedSpace">Saved disk space by ShortPixel</label></th>
347
+ <td><?=$savedSpace?></td>
348
+ </tr>
349
+ <tr>
350
+ <th scope="row"><label for="savedBandwidth">Bandwith* saved with ShortPixel:</label></th>
351
+ <td><?=$savedBandwidth?></td>
352
+ </tr>
353
+ </tbody>
354
+ </table>
355
+
356
+ <p style="padding-top: 0px; color: #818181;" >* Saved bandwidth is calculated at 10,000 impressions/image</p>
357
+
358
+ <h3>Your ShortPixel Plan</h3>
359
+ <table class="form-table">
360
+ <tbody>
361
+ <tr>
362
+ <th scope="row" bgcolor="#ffffff"><label for="apiQuota">Your ShortPixel plan</label></th>
363
+ <td bgcolor="#ffffff">
364
+ <?=number_format($quotaData['APICallsQuota'])?>/month, renews in <?=floor(30 + (strtotime($quotaData['APILastRenewalDate']) - time()) / 86400)?> days, on <?=date('M d, Y', strtotime($quotaData['APILastRenewalDate']. ' + 30 days'))?> ( <a href="https://shortpixel.com/login/<?=$this->ctrl->getApiKey();?>" target="_blank">Need More? See the options available</a> )<br/>
365
+ <a href="https://shortpixel.com/login/<?=$this->ctrl->getApiKey()?>/tell-a-friend" target="_blank">Join our friend referral system</a> to win more credits. For each user that joins, you receive +100 images credits/month.
366
+ </td>
367
+ </tr>
368
+ <tr>
369
+ <th scope="row"><label for="usedQUota">One time credits:</label></th>
370
+ <td><?= number_format($quotaData['APICallsQuotaOneTimeNumeric'])?></td>
371
+ </tr>
372
+ <tr>
373
+ <th scope="row"><label for="usedQUota">Number of images processed this month:</label></th>
374
+ <td><?=$totalCallsMade?> (<a href="https://api.shortpixel.com/v2/report.php?key=<?=$this->ctrl->getApiKey()?>" target="_blank">see report</a>)</td>
375
+ </tr>
376
+ <tr>
377
+ <th scope="row"><label for="remainingImages">Remaining** images in your plan: </label></th>
378
+ <td><?=$remainingImages?> images</td>
379
+ </tr>
380
+ </tbody>
381
+ </table>
382
+
383
+ <p style="padding-top: 0px; color: #818181;" >** Increase your image quota by <a href="https://shortpixel.com/login/<?=$this->ctrl->getApiKey()?>" target="_blank">upgrading</a> your ShortPixel plan.</p>
384
+
385
+ <table class="form-table">
386
+ <tbody>
387
+ <tr>
388
+ <th scope="row"><label for="totalFiles">Total number of processed files:</label></th>
389
+ <td><?=$fileCount?></td>
390
+ </tr>
391
+ <?php if($this->ctrl->backupImages()) { ?>
392
+ <tr>
393
+ <th scope="row"><label for="sizeBackup">Original images are stored in a backup folder. Your backup folder size is now:</label></th>
394
+ <td>
395
+ <form action="" method="POST">
396
+ <?=$backupFolderSize?>
397
+ <input type="submit" style="margin-left: 15px; vertical-align: middle;" class="button button-secondary" name="emptyBackup" value="Empty backups"/>
398
+ </form>
399
+ </td>
400
+ </tr>
401
+ <?php } ?>
402
+ </tbody>
403
+ </table> <?php
404
+ }
405
  }
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: 3.0.8
7
  * Author: ShortPixel
8
  * Author URI: https://shortpixel.com
9
  */
@@ -21,16 +21,21 @@ define('SP_RESET_ON_ACTIVATE', false);
21
 
22
  define('SP_AFFILIATE_CODE', '');
23
 
24
- define('PLUGIN_VERSION', "3.0.8");
25
  define('SP_MAX_TIMEOUT', 10);
26
  define('SP_BACKUP', 'ShortpixelBackups');
27
  define('SP_BACKUP_FOLDER', WP_CONTENT_DIR . DIRECTORY_SEPARATOR . 'uploads' . DIRECTORY_SEPARATOR . SP_BACKUP);
28
- define('MAX_API_RETRIES', 5);
29
  $MAX_EXECUTION_TIME = ini_get('max_execution_time');
30
- if ( is_numeric($MAX_EXECUTION_TIME) && $MAX_EXECUTION_TIME > 10 )
 
 
31
  define('MAX_EXECUTION_TIME', $MAX_EXECUTION_TIME - 5 ); //in seconds
32
  else
33
  define('MAX_EXECUTION_TIME', 25 );
 
 
 
34
  define("SP_MAX_RESULTS_QUERY", 6);
35
 
36
  class WPShortPixel {
@@ -45,6 +50,10 @@ class WPShortPixel {
45
  private $_backupImages = 1;
46
  private $_verifiedKey = false;
47
 
 
 
 
 
48
  private $_apiInterface = null;
49
  private $prioQ = null;
50
  private $view = null;
@@ -61,7 +70,8 @@ class WPShortPixel {
61
  $this->populateOptions();
62
 
63
  $this->_affiliateSufix = (strlen(SP_AFFILIATE_CODE)) ? "/affiliate/" . SP_AFFILIATE_CODE : "";
64
- $this->_apiInterface = new ShortPixelAPI($this->_apiKey, $this->_compressionType, $this->_CMYKtoRGBconversion);
 
65
  $this->prioQ = new ShortPixelQueue($this);
66
  $this->view = new ShortPixelView($this);
67
 
@@ -91,14 +101,16 @@ class WPShortPixel {
91
  add_action( 'wp_ajax_shortpixel_image_processing', array( &$this, 'handleImageProcessing') );
92
  //manual optimization
93
  add_action( 'wp_ajax_shortpixel_manual_optimization', array(&$this, 'handleManualOptimization'));
 
 
94
  //backup restore
95
  add_action('admin_action_shortpixel_restore_backup', array(&$this, 'handleRestoreBackup'));
96
 
97
  //This adds the constants used in PHP to be available also in JS
98
  add_action( 'admin_footer', array( &$this, 'shortPixelJS') );
99
-
100
-
101
- //example toolbar by fai, to be configured
102
  add_action( 'admin_bar_menu', array( &$this, 'toolbar_shortpixel_processing'), 999 );
103
 
104
  $this->migrateBackupFolder();
@@ -122,6 +134,10 @@ class WPShortPixel {
122
  self::getOpt( 'wp-short-pixel-total-original', 0);//amount of original data
123
  self::getOpt( 'wp-short-pixel-total-optimized', 0);//amount of optimized
124
  self::getOpt( 'wp-short-pixel-protocol', 'https');
 
 
 
 
125
  }
126
 
127
  public function shortPixelActivatePlugin()//reset some params to avoid trouble for plugins that were activated/deactivated/activated
@@ -141,8 +157,35 @@ class WPShortPixel {
141
  unset($_SESSION["wp-short-pixel-priorityQueue"]);
142
  delete_option("wp-short-pixel-bulk-previous-percent");
143
  }
 
 
 
 
144
  }
145
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
146
  public function shortPixelDeactivatePlugin()//reset some params to avoid trouble for plugins that were activated/deactivated/activated
147
  {
148
  $this->prioQ->resetBulk();
@@ -439,6 +482,8 @@ class WPShortPixel {
439
  $prio = $this->prioQ->remove($ID);
440
  //remove also from the failed list if it failed in the past
441
  $prio = $this->prioQ->removeFromFailed($ID);
 
 
442
 
443
  if(!$prio && $ID <= $this->prioQ->getStartBulkId()) {
444
  $this->prioQ->setStartBulkId($ID - 1);
@@ -451,7 +496,6 @@ class WPShortPixel {
451
 
452
  $thumb = $bkThumb = "";
453
  $percent = 0;
454
- $meta = wp_get_attachment_metadata($ID);
455
  if(isset($meta["ShortPixelImprovement"]) && isset($meta["file"])){
456
  $percent = $meta["ShortPixelImprovement"];
457
 
@@ -630,6 +674,13 @@ class WPShortPixel {
630
  if ( !$quotaData['APIKeyValid']) {
631
  return $quotaData;
632
  }
 
 
 
 
 
 
 
633
  if($quotaData['APICallsQuotaNumeric'] + $quotaData['APICallsQuotaOneTimeNumeric'] > $quotaData['APICallsMadeNumeric'] + $quotaData['APICallsMadeOneTimeNumeric']) {
634
  update_option('wp-short-pixel-quota-exceeded','0');
635
  ?><script>var shortPixelQuotaExceeded = 0;</script><?php
@@ -700,16 +751,15 @@ class WPShortPixel {
700
  }
701
 
702
  //image count
703
- $imageCount = $this->countAllProcessableFiles();
704
- $imgProcessedCount = $this->countAllProcessedFiles();
705
- $imageOnlyThumbs = $imageCount['totalFiles'] - $imageCount['mainFiles'];
706
  $thumbsProcessedCount = self::getOpt( 'wp-short-pixel-thumbnail-count', 0);//amount of optimized thumbnails
707
  $under5PercentCount = self::getOpt( 'wp-short-pixel-files-under-5-percent', 0);//amount of under 5% optimized imgs.
708
 
709
  //average compression
710
  $averageCompression = self::getAverageCompression();
711
- // $this->view->displayBulkProcessingForm($imageCount, $imageOnlyThumbs, $this->prioQ->bulkRan(), $averageCompression,
712
- $this->view->displayBulkProcessingForm($imageCount, $imgProcessedCount, $thumbsProcessedCount, $under5PercentCount,
713
  $this->prioQ->bulkRan(), $averageCompression, get_option('wp-short-pixel-fileCount'),
714
  self::formatBytes(get_option('wp-short-pixel-savedSpace')), $this->prioQ->bulkPaused() ? $this->prioQ->getBulkPercent() : false);
715
  }
@@ -767,8 +817,6 @@ class WPShortPixel {
767
  wp_die('You do not have sufficient permissions to access this page.');
768
  }
769
 
770
- $quotaData = $this->checkQuotaAndAlert();
771
-
772
  echo '<h1>ShortPixel Plugin Settings</h1>';
773
  echo '<p>
774
  <a href="https://shortpixel.com" target="_blank">ShortPixel.com</a> |
@@ -783,16 +831,17 @@ class WPShortPixel {
783
 
784
  $noticeHTML = "<br/><div style=\"background-color: #fff; border-left: 4px solid %s; box-shadow: 0 1px 1px 0 rgba(0, 0, 0, 0.1); padding: 1px 12px;\"><p>%s</p></div>";
785
 
 
 
786
  //by default we try to fetch the API Key from wp-config.php (if defined)
787
- if ( !isset($_POST['submit']) && !get_option('wp-short-pixel-verifiedKey') && defined("SHORTPIXEL_API_KEY") && strlen(SHORTPIXEL_API_KEY) == 20 )
788
  {
789
  $_POST['validate'] = "validate";
790
  $_POST['key'] = SHORTPIXEL_API_KEY;
791
  }
792
 
793
- if(isset($_POST['submit']) || isset($_POST['validate'])) {
794
-
795
- //handle API Key - common for submit and validate
796
  $_POST['key'] = trim(str_replace("*","",$_POST['key']));
797
 
798
  if ( strlen($_POST['key']) <> 20 )
@@ -810,7 +859,7 @@ class WPShortPixel {
810
  $this->_apiInterface->setApiKey($this->_apiKey);
811
  update_option('wp-short-pixel-apiKey', $_POST['key']);
812
  if($validityData['APIKeyValid']) {
813
- if(isset($_POST['validate'])) {
814
  //display notification
815
  if(in_array($_SERVER["SERVER_ADDR"], array("127.0.0.1","::1"))) {
816
  printf($noticeHTML, '#FFC800', "API Key is valid but your server seems to have a local address.
@@ -842,7 +891,7 @@ class WPShortPixel {
842
 
843
 
844
  //if save button - we process the rest of the form elements
845
- if(isset($_POST['submit'])) {
846
  update_option('wp-short-pixel-compression', $_POST['compressionType']);
847
  $this->_compressionType = $_POST['compressionType'];
848
  $this->_apiInterface->setCompressionType($this->_compressionType);
@@ -852,6 +901,13 @@ class WPShortPixel {
852
  update_option('wp-short-process_thumbnails', $this->_processThumbnails);
853
  update_option('wp-short-backup_images', $this->_backupImages);
854
  update_option('wp-short-pixel_cmyk2rgb', $this->_CMYKtoRGBconversion);
 
 
 
 
 
 
 
855
  }
856
  }
857
 
@@ -861,101 +917,8 @@ class WPShortPixel {
861
  $this->emptyBackup();
862
  }
863
 
864
- $checked = '';
865
- if($this->_processThumbnails) { $checked = 'checked'; }
866
-
867
- $checkedBackupImages = '';
868
- if($this->_backupImages) { $checkedBackupImages = 'checked'; }
869
-
870
- $cmyk2rgb = '';
871
- if($this->_CMYKtoRGBconversion) { $cmyk2rgb = 'checked'; }
872
-
873
-
874
- $formHTML = <<< HTML
875
- <form name='wp_shortpixel_options' action='' method='post' id='wp_shortpixel_options'>
876
- <table class="form-table">
877
- <tbody><tr>
878
- <th scope="row"><label for="key">API Key:</label></th>
879
- <td><input name="key" type="text" id="key" value="{$this->_apiKey}" class="regular-text">
880
- <input type="submit" name="validate" id="validate" class="button button-primary" title="Validate the provided API key" value="Validate">
881
- </td>
882
- </tr>
883
- HTML;
884
-
885
- if(!$this->_verifiedKey) {
886
-
887
- //if invalid key we display the link to the API Key
888
- $formHTML .= '<tr><td style="padding-left: 0px;" colspan="2">Don’t have an API Key? <a href="https://shortpixel.com/wp-apikey'
889
- . $this->_affiliateSufix . '" target="_blank">Sign up, it’s free.</a></td></tr>';
890
- $formHTML .= '</form>';
891
- } else {
892
- //if valid key we display the rest of the options
893
- $formHTML .= <<< HTML
894
- <tr><th scope="row">
895
- <label for="compressionType">Compression type:</label>
896
- </th><td>
897
- HTML;
898
-
899
- if($this->_compressionType == 1) {
900
- $formHTML .= '<input type="radio" name="compressionType" value="1" checked>Lossy</br></br>';
901
- $formHTML .= '<input type="radio" name="compressionType" value="0" >Lossless';
902
- } else {
903
- $formHTML .= '<input type="radio" name="compressionType" value="1">Lossy</br></br>';
904
- $formHTML .= '<input type="radio" name="compressionType" value="0" checked>Lossless';
905
- }
906
-
907
- $formHTML .= <<<HTML
908
- </td>
909
- </tr>
910
- </tbody></table>
911
- <p style="color: #818181;">
912
- <b>Lossy compression: </b>lossy has a better compression rate than lossless compression.</br>The resulting image
913
- is not 100% identical with the original. Works well for photos taken with your camera.</br></br>
914
- <b>Lossless compression: </b> the shrunk image will be identical with the original and smaller in size.</br>Use this
915
- when you do not want to lose any of the original image's details. Works best for technical drawings,
916
- clip art and comics.
917
- </p>
918
- <table class="form-table">
919
- <tbody><tr>
920
- <th scope="row"><label for="thumbnails">Also include thumbnails:</label></th>
921
- <td><input name="thumbnails" type="checkbox" id="thumbnails" {$checked}> Apply compression also to image thumbnails.</td>
922
- </tr>
923
- <tr>
924
- <th scope="row"><label for="backupImages">Image backup</label></th>
925
- <td>
926
- <input name="backupImages" type="checkbox" id="backupImages" {$checkedBackupImages}> Save and keep a backup of your original images in a separate folder.
927
- </td>
928
- </tr>
929
- <tr>
930
- <th scope="row"><label for="backupImages">CMYK to RGB conversion</label></th>
931
- <td>
932
- <input name="cmyk2rgb" type="checkbox" id="cmyk2rgb" {$cmyk2rgb}>Adjust your images for computer and mobile screen display.
933
- </td>
934
- </tr>
935
- </tr>
936
- </tbody></table>
937
- <p class="submit">
938
- <input type="submit" name="submit" id="submit" class="button button-primary" title="Save Changes" value="Save Changes">
939
- <a class="button button-primary" title="Process all the images in your Media Library" href="upload.php?page=wp-short-pixel-bulk">Bulk Process</a>
940
- </p>
941
- </form>
942
- <script>
943
- var rad = document.wp_shortpixel_options.compressionType;
944
- var prev = null;
945
- for(var i = 0; i < rad.length; i++) {
946
- rad[i].onclick = function() {
947
-
948
- if(this !== prev) {
949
- prev = this;
950
- }
951
- alert('This type of optimization will apply to new uploaded images.\\nImages that were already processed will not be re-optimized.');
952
- };
953
- }
954
- </script>
955
- HTML;
956
- }
957
-
958
- echo $formHTML;
959
 
960
  if($this->_verifiedKey) {
961
  $fileCount = number_format(get_option('wp-short-pixel-fileCount'));
@@ -970,81 +933,8 @@ HTML;
970
  $remainingImages = ( $remainingImages < 0 ) ? 0 : number_format($remainingImages);
971
  $totalCallsMade = number_format($quotaData['APICallsMadeNumeric'] + $quotaData['APICallsMadeOneTimeNumeric']);
972
 
973
- $statHTML = <<< HTML
974
- <a id="facts"></a>
975
- <h3>Your ShortPixel Stats</h3>
976
- <table class="form-table">
977
- <tbody>
978
- <tr>
979
- <th scope="row"><label for="averagCompression">Average compression of your files:</label></th>
980
- <td>$averageCompression%</td>
981
- </tr>
982
- <tr>
983
- <th scope="row"><label for="savedSpace">Saved disk space by ShortPixel</label></th>
984
- <td>$savedSpace</td>
985
- </tr>
986
- <tr>
987
- <th scope="row"><label for="savedBandwidth">Bandwith* saved with ShortPixel:</label></th>
988
- <td>$savedBandwidth</td>
989
- </tr>
990
- </tbody></table>
991
-
992
- <p style="padding-top: 0px; color: #818181;" >* Saved bandwidth is calculated at 10,000 impressions/image</p>
993
-
994
- <h3>Your ShortPixel Plan</h3>
995
- <table class="form-table">
996
- <tbody>
997
- <tr>
998
- <th scope="row" bgcolor="#ffffff"><label for="apiQuota">Your ShortPixel plan</label></th>
999
- <td bgcolor="#ffffff">{$quotaData['APICallsQuota']}/month ( <a href="https://shortpixel.com/login/{$this->_apiKey}" target="_blank">Need More? See the options available</a> )
1000
- </tr>
1001
- <tr>
1002
- <th scope="row"><label for="usedQUota">One time credits:</label></th>
1003
- <td>{$quotaData['APICallsQuotaOneTimeNumeric']}</td>
1004
- </tr>
1005
- <tr>
1006
- <th scope="row"><label for="usedQUota">Number of images processed this month:</label></th>
1007
- <td>{$totalCallsMade} (<a href="https://api.shortpixel.com/v2/report.php?key={$this->_apiKey}" target="_blank">see report</a>)</td>
1008
- </tr>
1009
- <tr>
1010
- <th scope="row"><label for="remainingImages">Remaining** images in your plan: </label></th>
1011
- <td>{$remainingImages} images</td>
1012
- </tr>
1013
- </tbody></table>
1014
-
1015
- <p style="padding-top: 0px; color: #818181;" >** Increase your image quota by <a href="https://shortpixel.com/login/{$this->_apiKey}" target="_blank">upgrading</a> your ShortPixel plan.</p>
1016
-
1017
- <table class="form-table">
1018
- <tbody>
1019
- <tr>
1020
- <th scope="row"><label for="totalFiles">Total number of processed files:</label></th>
1021
- <td>{$fileCount}</td>
1022
- </tr>
1023
-
1024
-
1025
-
1026
- HTML;
1027
- if($this->_backupImages) {
1028
- $statHTML .= <<< HTML
1029
- <form action="" method="POST">
1030
- <tr>
1031
- <th scope="row"><label for="sizeBackup">Original images are stored in a backup folder. Your backup folder size is now:</label></th>
1032
- <td>
1033
- {$backupFolderSize}
1034
- <input type="submit" style="margin-left: 15px; vertical-align: middle;" class="button button-secondary" name="emptyBackup" value="Empty backups"/>
1035
- </td>
1036
- </tr>
1037
- </form>
1038
- HTML;
1039
- }
1040
-
1041
- $statHTML .= <<< HTML
1042
- </tbody></table>
1043
- HTML;
1044
-
1045
- echo $statHTML;
1046
-
1047
-
1048
  }
1049
 
1050
  }
@@ -1120,7 +1010,8 @@ HTML;
1120
  "APICallsMadeNumeric" => $data->APICallsMade,
1121
  "APICallsQuotaNumeric" => $data->APICallsQuota,
1122
  "APICallsMadeOneTimeNumeric" => $data->APICallsMadeOneTime,
1123
- "APICallsQuotaOneTimeNumeric" => $data->APICallsQuotaOneTime
 
1124
  );
1125
 
1126
 
@@ -1172,35 +1063,19 @@ HTML;
1172
  print " | <a href=\"javascript:manualOptimization({$id})\">Optimize now</a>";
1173
  }
1174
  }
1175
- elseif( is_numeric($data['ShortPixelImprovement']) && !isset($data['ShortPixel']['NoBackup']) ) {
1176
-
1177
- if ( $data['ShortPixelImprovement'] < 5 )
1178
- {
1179
  print $data['ShortPixelImprovement'] . '%';
1180
  print " optimized<BR> Bonus processing";
1181
-
1182
- }
1183
- else
1184
- {
1185
  print 'Reduced by ';
1186
  print $data['ShortPixelImprovement'] . '%';
1187
  }
1188
- if ( get_option('wp-short-backup_images') ) //display restore backup option only when backup is active
1189
  print " | <a href=\"admin.php?action=shortpixel_restore_backup&amp;attachment_ID={$id}\">Restore backup</a>";
1190
- }
1191
- elseif ( is_numeric($data['ShortPixelImprovement']) )
1192
- {
1193
- if ( $data['ShortPixelImprovement'] < 5 )
1194
- {
1195
- print $data['ShortPixelImprovement'] . '%';
1196
- print " optimized<BR> Bonus processing";
1197
-
1198
- }
1199
- else
1200
- {
1201
- print 'Reduced by ';
1202
- print $data['ShortPixelImprovement'] . '%';
1203
- }
1204
  }
1205
  elseif ( $data['ShortPixelImprovement'] <> "Optimization N/A" )
1206
  {
@@ -1232,7 +1107,7 @@ HTML;
1232
  }
1233
  else
1234
  {
1235
- print "<img src=\"" . plugins_url( 'img/loading.gif', __FILE__ ) . "\">Image waiting to be processed
1236
  | <a href=\"javascript:manualOptimization({$id})\">Retry</a></div>";
1237
  $this->prioQ->push($id); //should be there but just to make sure
1238
  }
@@ -1253,6 +1128,9 @@ HTML;
1253
  print 'Image not processed';
1254
  print " | <a href=\"javascript:manualOptimization({$id})\">Optimize now</a>";
1255
  }
 
 
 
1256
  }
1257
  elseif ( $fileExtension == "pdf" )
1258
  {
@@ -1517,6 +1395,28 @@ HTML;
1517
 
1518
  return;
1519
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1520
 
1521
  public function getApiKey() {
1522
  return $this->_apiKey;
@@ -1533,6 +1433,30 @@ HTML;
1533
  public function processThumbnails() {
1534
  return $this->_processThumbnails;
1535
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1536
 
1537
  }
1538
 
@@ -1544,7 +1468,9 @@ function onInit() {
1544
  global $pluginInstance;
1545
  }
1546
 
1547
- add_action( 'init', 'onInit');
 
 
1548
 
1549
  //$pluginInstance = new WPShortPixel();
1550
  //global $pluginInstance;
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: 3.1.0
7
  * Author: ShortPixel
8
  * Author URI: https://shortpixel.com
9
  */
21
 
22
  define('SP_AFFILIATE_CODE', '');
23
 
24
+ define('PLUGIN_VERSION', "3.1.0");
25
  define('SP_MAX_TIMEOUT', 10);
26
  define('SP_BACKUP', 'ShortpixelBackups');
27
  define('SP_BACKUP_FOLDER', WP_CONTENT_DIR . DIRECTORY_SEPARATOR . 'uploads' . DIRECTORY_SEPARATOR . SP_BACKUP);
28
+ define('MAX_API_RETRIES', 50);
29
  $MAX_EXECUTION_TIME = ini_get('max_execution_time');
30
+
31
+ /*
32
+ if ( is_numeric($MAX_EXECUTION_TIME) && $MAX_EXECUTION_TIME > 10 )
33
  define('MAX_EXECUTION_TIME', $MAX_EXECUTION_TIME - 5 ); //in seconds
34
  else
35
  define('MAX_EXECUTION_TIME', 25 );
36
+ */
37
+
38
+ define('MAX_EXECUTION_TIME', 2 );
39
  define("SP_MAX_RESULTS_QUERY", 6);
40
 
41
  class WPShortPixel {
50
  private $_backupImages = 1;
51
  private $_verifiedKey = false;
52
 
53
+ private $_resizeImages = false;
54
+ private $_resizeWidth = 0;
55
+ private $_resizeHeight = 0;
56
+
57
  private $_apiInterface = null;
58
  private $prioQ = null;
59
  private $view = null;
70
  $this->populateOptions();
71
 
72
  $this->_affiliateSufix = (strlen(SP_AFFILIATE_CODE)) ? "/affiliate/" . SP_AFFILIATE_CODE : "";
73
+ $this->_apiInterface = new ShortPixelAPI($this->_apiKey, $this->_compressionType, $this->_CMYKtoRGBconversion,
74
+ $this->_resizeImages, $this->_resizeWidth, $this->_resizeHeight);
75
  $this->prioQ = new ShortPixelQueue($this);
76
  $this->view = new ShortPixelView($this);
77
 
101
  add_action( 'wp_ajax_shortpixel_image_processing', array( &$this, 'handleImageProcessing') );
102
  //manual optimization
103
  add_action( 'wp_ajax_shortpixel_manual_optimization', array(&$this, 'handleManualOptimization'));
104
+ //manual optimization
105
+ add_action( 'wp_ajax_shortpixel_dismiss_notice', array(&$this, 'dismissAdminNotice'));
106
  //backup restore
107
  add_action('admin_action_shortpixel_restore_backup', array(&$this, 'handleRestoreBackup'));
108
 
109
  //This adds the constants used in PHP to be available also in JS
110
  add_action( 'admin_footer', array( &$this, 'shortPixelJS') );
111
+ //register a method to display admin notices if necessary
112
+ add_action('admin_notices', array( &$this, 'displayAdminNotices'));
113
+ //toolbar notifications
114
  add_action( 'admin_bar_menu', array( &$this, 'toolbar_shortpixel_processing'), 999 );
115
 
116
  $this->migrateBackupFolder();
134
  self::getOpt( 'wp-short-pixel-total-original', 0);//amount of original data
135
  self::getOpt( 'wp-short-pixel-total-optimized', 0);//amount of optimized
136
  self::getOpt( 'wp-short-pixel-protocol', 'https');
137
+
138
+ $this->_resizeImages = self::getOpt( 'wp-short-pixel-resize-images', 0);
139
+ $this->_resizeWidth = self::getOpt( 'wp-short-pixel-resize-width', 0);
140
+ $this->_resizeHeight = self::getOpt( 'wp-short-pixel-resize-height', 0);
141
  }
142
 
143
  public function shortPixelActivatePlugin()//reset some params to avoid trouble for plugins that were activated/deactivated/activated
157
  unset($_SESSION["wp-short-pixel-priorityQueue"]);
158
  delete_option("wp-short-pixel-bulk-previous-percent");
159
  }
160
+ if(!$this->_verifiedKey) {
161
+ $this->view->displayActivationNotice();
162
+ }
163
+ update_option( 'wp-short-pixel-activation-date', time());
164
  }
165
 
166
+ public function displayAdminNotices() {
167
+ update_option( 'wp-short-pixel-activation-date', time());
168
+ if(!$this->_verifiedKey) {
169
+ $dismissed = self::getOpt( 'wp-short-pixel-dismissed-notices', array());
170
+ $now = time();
171
+ $act = self::getOpt( 'wp-short-pixel-activation-date', $now);
172
+ if( ($now > $act + 7200) && !isset($dismissed['2h'])) {
173
+ $this->view->displayActivationNotice('2h');
174
+ } else if( ($now > $act + 72 * 3600) && !isset($dismissed['3d'])) {
175
+ $this->view->displayActivationNotice('3d');
176
+ }
177
+ }
178
+ }
179
+
180
+ public function dismissAdminNotice() {
181
+ $noticeId = preg_replace('|[^a-z0-9]|i', '', $_GET['notice_id']);
182
+ $dismissed = self::getOpt( 'wp-short-pixel-dismissed-notices', array());
183
+ $dismissed[$noticeId] = true;
184
+ update_option( 'wp-short-pixel-dismissed-notices', $dismissed);
185
+ die(json_encode(array("Status" => 'success', "Message" => 'Notice ID: ' . $noticeId . ' dismissed')));
186
+ }
187
+
188
+
189
  public function shortPixelDeactivatePlugin()//reset some params to avoid trouble for plugins that were activated/deactivated/activated
190
  {
191
  $this->prioQ->resetBulk();
482
  $prio = $this->prioQ->remove($ID);
483
  //remove also from the failed list if it failed in the past
484
  $prio = $this->prioQ->removeFromFailed($ID);
485
+ $meta = wp_get_attachment_metadata($ID);
486
+ $result["ThumbsCount"] = isset($meta['sizes']) && is_array($meta['sizes']) ? count($meta['sizes']): 0;
487
 
488
  if(!$prio && $ID <= $this->prioQ->getStartBulkId()) {
489
  $this->prioQ->setStartBulkId($ID - 1);
496
 
497
  $thumb = $bkThumb = "";
498
  $percent = 0;
 
499
  if(isset($meta["ShortPixelImprovement"]) && isset($meta["file"])){
500
  $percent = $meta["ShortPixelImprovement"];
501
 
674
  if ( !$quotaData['APIKeyValid']) {
675
  return $quotaData;
676
  }
677
+ $imageCount = $this->countAllProcessableFiles();
678
+ $imageProcessedCount = $this->countAllProcessedFiles();
679
+ $quotaData['totalFiles'] = $imageCount['totalFiles'];
680
+ $quotaData['totalProcessedFiles'] = $imageProcessedCount['totalFiles'];
681
+ $quotaData['mainFiles'] = $imageCount['mainFiles'];
682
+ $quotaData['mainProcessedFiles'] = $imageProcessedCount['mainFiles'];
683
+
684
  if($quotaData['APICallsQuotaNumeric'] + $quotaData['APICallsQuotaOneTimeNumeric'] > $quotaData['APICallsMadeNumeric'] + $quotaData['APICallsMadeOneTimeNumeric']) {
685
  update_option('wp-short-pixel-quota-exceeded','0');
686
  ?><script>var shortPixelQuotaExceeded = 0;</script><?php
751
  }
752
 
753
  //image count
754
+ //$imageCount = $this->countAllProcessableFiles();
755
+ //$imgProcessedCount = $this->countAllProcessedFiles();
756
+ $imageOnlyThumbs = $quotaData['totalFiles'] - $quotaData['mainFiles'];
757
  $thumbsProcessedCount = self::getOpt( 'wp-short-pixel-thumbnail-count', 0);//amount of optimized thumbnails
758
  $under5PercentCount = self::getOpt( 'wp-short-pixel-files-under-5-percent', 0);//amount of under 5% optimized imgs.
759
 
760
  //average compression
761
  $averageCompression = self::getAverageCompression();
762
+ $this->view->displayBulkProcessingForm($quotaData, $thumbsProcessedCount, $under5PercentCount,
 
763
  $this->prioQ->bulkRan(), $averageCompression, get_option('wp-short-pixel-fileCount'),
764
  self::formatBytes(get_option('wp-short-pixel-savedSpace')), $this->prioQ->bulkPaused() ? $this->prioQ->getBulkPercent() : false);
765
  }
817
  wp_die('You do not have sufficient permissions to access this page.');
818
  }
819
 
 
 
820
  echo '<h1>ShortPixel Plugin Settings</h1>';
821
  echo '<p>
822
  <a href="https://shortpixel.com" target="_blank">ShortPixel.com</a> |
831
 
832
  $noticeHTML = "<br/><div style=\"background-color: #fff; border-left: 4px solid %s; box-shadow: 0 1px 1px 0 rgba(0, 0, 0, 0.1); padding: 1px 12px;\"><p>%s</p></div>";
833
 
834
+ //die(var_dump($_POST));
835
+
836
  //by default we try to fetch the API Key from wp-config.php (if defined)
837
+ if ( !isset($_POST['save']) && !get_option('wp-short-pixel-verifiedKey') && defined("SHORTPIXEL_API_KEY") && strlen(SHORTPIXEL_API_KEY) == 20 )
838
  {
839
  $_POST['validate'] = "validate";
840
  $_POST['key'] = SHORTPIXEL_API_KEY;
841
  }
842
 
843
+ if(isset($_POST['save']) || (isset($_POST['validate']) && $_POST['validate'] == "validate")) {
844
+ //handle API Key - common for save and validate
 
845
  $_POST['key'] = trim(str_replace("*","",$_POST['key']));
846
 
847
  if ( strlen($_POST['key']) <> 20 )
859
  $this->_apiInterface->setApiKey($this->_apiKey);
860
  update_option('wp-short-pixel-apiKey', $_POST['key']);
861
  if($validityData['APIKeyValid']) {
862
+ if(isset($_POST['validate']) && $_POST['validate'] == "validate") {
863
  //display notification
864
  if(in_array($_SERVER["SERVER_ADDR"], array("127.0.0.1","::1"))) {
865
  printf($noticeHTML, '#FFC800', "API Key is valid but your server seems to have a local address.
891
 
892
 
893
  //if save button - we process the rest of the form elements
894
+ if(isset($_POST['save'])) {
895
  update_option('wp-short-pixel-compression', $_POST['compressionType']);
896
  $this->_compressionType = $_POST['compressionType'];
897
  $this->_apiInterface->setCompressionType($this->_compressionType);
901
  update_option('wp-short-process_thumbnails', $this->_processThumbnails);
902
  update_option('wp-short-backup_images', $this->_backupImages);
903
  update_option('wp-short-pixel_cmyk2rgb', $this->_CMYKtoRGBconversion);
904
+ $this->_resizeImages = (isset($_POST['resize']) ? 1: 0);
905
+ $this->_resizeWidth = (isset($_POST['width']) ? $_POST['width']: $this->_resizeWidth);
906
+ $this->_resizeHeight = (isset($_POST['height']) ? $_POST['height']: $this->_resizeHeight);
907
+ update_option( 'wp-short-pixel-resize-images', $this->_resizeImages);
908
+ update_option( 'wp-short-pixel-resize-width', 0 + $this->_resizeWidth);
909
+ update_option( 'wp-short-pixel-resize-height', 0 + $this->_resizeHeight);
910
+
911
  }
912
  }
913
 
917
  $this->emptyBackup();
918
  }
919
 
920
+ $quotaData = $this->checkQuotaAndAlert();
921
+ $this->view->displaySettingsForm($quotaData);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
922
 
923
  if($this->_verifiedKey) {
924
  $fileCount = number_format(get_option('wp-short-pixel-fileCount'));
933
  $remainingImages = ( $remainingImages < 0 ) ? 0 : number_format($remainingImages);
934
  $totalCallsMade = number_format($quotaData['APICallsMadeNumeric'] + $quotaData['APICallsMadeOneTimeNumeric']);
935
 
936
+ $this->view->displaySettingsStats($averageCompression, $savedSpace, $savedBandwidth,
937
+ $quotaData, $remainingImages, $totalCallsMade, $fileCount, $backupFolderSize);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
938
  }
939
 
940
  }
1010
  "APICallsMadeNumeric" => $data->APICallsMade,
1011
  "APICallsQuotaNumeric" => $data->APICallsQuota,
1012
  "APICallsMadeOneTimeNumeric" => $data->APICallsMadeOneTime,
1013
+ "APICallsQuotaOneTimeNumeric" => $data->APICallsQuotaOneTime,
1014
+ "APILastRenewalDate" => $data->DateSubscription
1015
  );
1016
 
1017
 
1063
  print " | <a href=\"javascript:manualOptimization({$id})\">Optimize now</a>";
1064
  }
1065
  }
1066
+ elseif( is_numeric($data['ShortPixelImprovement']) ) {
1067
+ if ( $data['ShortPixelImprovement'] < 5 ) {
 
 
1068
  print $data['ShortPixelImprovement'] . '%';
1069
  print " optimized<BR> Bonus processing";
1070
+ } else {
 
 
 
1071
  print 'Reduced by ';
1072
  print $data['ShortPixelImprovement'] . '%';
1073
  }
1074
+ if ( get_option('wp-short-backup_images') && !isset($data['ShortPixel']['NoBackup'])) //display restore backup option only when backup is active
1075
  print " | <a href=\"admin.php?action=shortpixel_restore_backup&amp;attachment_ID={$id}\">Restore backup</a>";
1076
+ if ($this->_backupImages && count($data['sizes'])) {
1077
+ print "<br>+" . count($data['sizes']) . " thumbnails optimized";
1078
+ }
 
 
 
 
 
 
 
 
 
 
 
1079
  }
1080
  elseif ( $data['ShortPixelImprovement'] <> "Optimization N/A" )
1081
  {
1107
  }
1108
  else
1109
  {
1110
+ print "<img src=\"" . plugins_url( 'img/loading.gif', __FILE__ ) . "\">&nbsp;Image waiting to be processed
1111
  | <a href=\"javascript:manualOptimization({$id})\">Retry</a></div>";
1112
  $this->prioQ->push($id); //should be there but just to make sure
1113
  }
1128
  print 'Image not processed';
1129
  print " | <a href=\"javascript:manualOptimization({$id})\">Optimize now</a>";
1130
  }
1131
+ if ($this->_backupImages && count($data['sizes'])) {
1132
+ print "<br>+" . count($data['sizes']) . " thumbnails";
1133
+ }
1134
  }
1135
  elseif ( $fileExtension == "pdf" )
1136
  {
1395
 
1396
  return;
1397
  }
1398
+
1399
+ function getMaxIntermediateImageSize() {
1400
+ global $_wp_additional_image_sizes;
1401
+
1402
+ $width = 0;
1403
+ $height = 0;
1404
+ $get_intermediate_image_sizes = get_intermediate_image_sizes();
1405
+
1406
+ // Create the full array with sizes and crop info
1407
+ foreach( $get_intermediate_image_sizes as $_size ) {
1408
+ if ( in_array( $_size, array( 'thumbnail', 'medium', 'large' ) ) ) {
1409
+ $width = max($width, get_option( $_size . '_size_w' ));
1410
+ $height = max($height, get_option( $_size . '_size_h' ));
1411
+ //$sizes[ $_size ]['crop'] = (bool) get_option( $_size . '_crop' );
1412
+ } elseif ( isset( $_wp_additional_image_sizes[ $_size ] ) ) {
1413
+ $width = max($width, $_wp_additional_image_sizes[ $_size ]['width']);
1414
+ $height = max($height, $_wp_additional_image_sizes[ $_size ]['height']);
1415
+ //'crop' => $_wp_additional_image_sizes[ $_size ]['crop']
1416
+ }
1417
+ }
1418
+ return array('width' => $width, 'height' => $height);
1419
+ }
1420
 
1421
  public function getApiKey() {
1422
  return $this->_apiKey;
1433
  public function processThumbnails() {
1434
  return $this->_processThumbnails;
1435
  }
1436
+ public function getCMYKtoRGBconversion() {
1437
+ return $this->_CMYKtoRGBconversion;
1438
+ }
1439
+
1440
+ public function getResizeImages() {
1441
+ return $this->_resizeImages;
1442
+ }
1443
+
1444
+ public function getResizeWidth() {
1445
+ return $this->_resizeWidth;
1446
+ }
1447
+
1448
+ public function getResizeHeight() {
1449
+ return $this->_resizeHeight;
1450
+ }
1451
+ public function getAffiliateSufix() {
1452
+ return $this->_affiliateSufix;
1453
+ }
1454
+ public function getVerifiedKey() {
1455
+ return $this->_verifiedKey;
1456
+ }
1457
+ public function getCompressionType() {
1458
+ return $this->_compressionType;
1459
+ }
1460
 
1461
  }
1462
 
1468
  global $pluginInstance;
1469
  }
1470
 
1471
+ if ( !function_exists( 'vc_action' ) || vc_action() !== 'vc_inline' ) { //handle incompatibility with Visual Composer
1472
+ add_action( 'init', 'onInit');
1473
+ }
1474
 
1475
  //$pluginInstance = new WPShortPixel();
1476
  //global $pluginInstance;