Version Description
- reoptimize lossless/lossy
- optimize thumbs for images already optimized
- compatibility with WPML
Download this release
Release Info
Developer | ShortPixel |
Plugin | ShortPixel Image Optimizer |
Version | 3.3.0 |
Comparing to | |
See all releases |
Code changes from version 3.2.1 to 3.3.0
- css/short-pixel.css +37 -0
- img/stars.png +0 -0
- js/short-pixel.js +100 -12
- readme.txt +9 -3
- shortpixel_api.php +120 -50
- shortpixel_queue.php +23 -5
- shortpixel_view.php +154 -22
- wp-shortpixel-settings.php +2 -0
- wp-shortpixel.php +496 -310
css/short-pixel.css
CHANGED
@@ -1,3 +1,34 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
li.shortpixel-toolbar-processing > a.ab-item > div,
|
2 |
#wpadminbar li.shortpixel-toolbar-processing > a.ab-item > div{
|
3 |
background-image: url("../img/loading-dark-big.gif");
|
@@ -107,9 +138,15 @@ li.shortpixel-hide {
|
|
107 |
width: 290px;
|
108 |
overflow: hidden;
|
109 |
}
|
|
|
|
|
|
|
|
|
|
|
110 |
.wp-core-ui .column-wp-shortPixel .button.button-smaller {
|
111 |
font-size: 13px;
|
112 |
padding:0px 5px;
|
|
|
113 |
height:20px;
|
114 |
line-height:16px;
|
115 |
float:right;
|
1 |
+
div.shortpixel-rate-us {
|
2 |
+
display:inline-block;
|
3 |
+
margin-left: 20px;
|
4 |
+
vertical-align: top;
|
5 |
+
font-weight: bold;
|
6 |
+
padding-top: 5px;
|
7 |
+
}
|
8 |
+
div.shortpixel-rate-us > a {
|
9 |
+
vertical-align: middle;
|
10 |
+
padding: 16px 5px 0;
|
11 |
+
}
|
12 |
+
div.shortpixel-rate-us > a > div {
|
13 |
+
display: inline-block;
|
14 |
+
vertical-align: top;
|
15 |
+
margin-top: 14px;
|
16 |
+
}
|
17 |
+
div.shortpixel-rate-us > a > img {
|
18 |
+
padding-top: 7px;
|
19 |
+
}
|
20 |
+
div.shortpixel-rate-us > a:active,
|
21 |
+
div.shortpixel-rate-us > a:hover,
|
22 |
+
div.shortpixel-rate-us > a:focus {
|
23 |
+
outline:0;
|
24 |
+
border-style: none;
|
25 |
+
}
|
26 |
+
.sp-loading-small {
|
27 |
+
margin-top: 2px;
|
28 |
+
float: left;
|
29 |
+
margin-right: 5px;
|
30 |
+
}
|
31 |
+
|
32 |
li.shortpixel-toolbar-processing > a.ab-item > div,
|
33 |
#wpadminbar li.shortpixel-toolbar-processing > a.ab-item > div{
|
34 |
background-image: url("../img/loading-dark-big.gif");
|
138 |
width: 290px;
|
139 |
overflow: hidden;
|
140 |
}
|
141 |
+
.wp-core-ui .column-wp-shortPixel .sp-column-actions {
|
142 |
+
max-width: 120px;
|
143 |
+
float:right;
|
144 |
+
text-align: right;
|
145 |
+
}
|
146 |
.wp-core-ui .column-wp-shortPixel .button.button-smaller {
|
147 |
font-size: 13px;
|
148 |
padding:0px 5px;
|
149 |
+
margin-bottom: 4px;
|
150 |
height:20px;
|
151 |
line-height:16px;
|
152 |
float:right;
|
img/stars.png
ADDED
Binary file
|
js/short-pixel.js
CHANGED
@@ -8,6 +8,10 @@ jQuery(document).ready(function($){
|
|
8 |
//register a bulk action
|
9 |
jQuery('select[name^="action"] option:last-child').before('<option value="short-pixel-bulk">Optimize with ShortPixel</option>');
|
10 |
}
|
|
|
|
|
|
|
|
|
11 |
//
|
12 |
jQuery(window).unload(function(){
|
13 |
if(ShortPixel.bulkProcessor == true) {
|
@@ -41,11 +45,34 @@ var ShortPixel = function() {
|
|
41 |
jQuery("section#" +target).addClass("sel-tab");
|
42 |
}
|
43 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
44 |
|
45 |
return {
|
46 |
-
setOptions
|
47 |
-
checkThumbsUpdTotal: checkThumbsUpdTotal,
|
48 |
-
switchSettingsTab
|
|
|
|
|
49 |
}
|
50 |
}();
|
51 |
|
@@ -66,6 +93,10 @@ function showToolBarAlert($status, $message) {
|
|
66 |
//jQuery("a div", robo).attr("title", "ShortPixel quota exceeded. Click to top-up");
|
67 |
jQuery("a div", robo).attr("title", "ShortPixel quota exceeded. Click for details.");
|
68 |
break;
|
|
|
|
|
|
|
|
|
69 |
case ShortPixel.STATUS_FAIL:
|
70 |
robo.addClass("shortpixel-alert shortpixel-processing");
|
71 |
jQuery("a div", robo).attr("title", $message);
|
@@ -200,11 +231,23 @@ function checkBulkProcessingCallApi(){
|
|
200 |
break;
|
201 |
case ShortPixel.STATUS_SUCCESS:
|
202 |
var percent = data["PercentImprovement"];
|
203 |
-
var
|
204 |
-
|
205 |
-
|
206 |
-
|
207 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
208 |
showToolBarAlert(ShortPixel.STATUS_SUCCESS, "");
|
209 |
setCellMessage(id, cellMsg);
|
210 |
var animator = new PercentageAnimator("#sp-msg-" + id + " span.percent", percent);
|
@@ -215,10 +258,20 @@ function checkBulkProcessingCallApi(){
|
|
215 |
sliderUpdate(id, data["Thumb"], data["BkThumb"], data["PercentImprovement"]);
|
216 |
}
|
217 |
}
|
218 |
-
|
219 |
-
|
|
|
|
|
|
|
|
|
|
|
220 |
case ShortPixel.STATUS_ERROR: //for error and skip also we retry
|
221 |
case ShortPixel.STATUS_SKIP:
|
|
|
|
|
|
|
|
|
|
|
222 |
console.log('Server response: ' + response);
|
223 |
if(isBulkPage && typeof data["BulkPercent"] !== 'undefined') {
|
224 |
progressUpdate(data["BulkPercent"], data["BulkMsg"]);
|
@@ -246,7 +299,7 @@ function setCellMessage(id, message){
|
|
246 |
}
|
247 |
|
248 |
function manualOptimization(id) {
|
249 |
-
setCellMessage(id, "<img src='" + ShortPixel.WP_PLUGIN_URL + "/img/loading.gif'>Image waiting to be processed");
|
250 |
jQuery("li.shortpixel-toolbar-processing").removeClass("shortpixel-hide");
|
251 |
jQuery("li.shortpixel-toolbar-processing").addClass("shortpixel-processing");
|
252 |
var data = { action : 'shortpixel_manual_optimization',
|
@@ -256,12 +309,47 @@ function manualOptimization(id) {
|
|
256 |
if(data["Status"] == ShortPixel.STATUS_SUCCESS) {
|
257 |
setTimeout(checkBulkProgress, 2000);
|
258 |
} else {
|
259 |
-
setCellMessage(id, "This content is not processable.");
|
260 |
}
|
261 |
//aici e aici
|
262 |
});
|
263 |
}
|
264 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
265 |
function dismissShortPixelNotice(id) {
|
266 |
jQuery("#short-pixel-notice-" + id).hide();
|
267 |
var data = { action : 'shortpixel_dismiss_notice',
|
8 |
//register a bulk action
|
9 |
jQuery('select[name^="action"] option:last-child').before('<option value="short-pixel-bulk">Optimize with ShortPixel</option>');
|
10 |
}
|
11 |
+
if( ShortPixel.MEDIA_ALERT == 'todo' && jQuery('div.media-frame.mode-grid').length > 0) {
|
12 |
+
//the media table is not in the list mode, alert the user
|
13 |
+
jQuery('div.media-frame.mode-grid').before('<div id="short-pixel-media-alert" class="notice notice-warning"><p>In order to access the ShortPixel Optimization actions and info, please change to <a href="/wp-admin/upload.php?mode=list" class="view-list"><span class="screen-reader-text">List View</span>List View</a><a class="alignright" href="javascript:ShortPixel.dismissMediaAlert();">Dismiss</a></p></div>');
|
14 |
+
}
|
15 |
//
|
16 |
jQuery(window).unload(function(){
|
17 |
if(ShortPixel.bulkProcessor == true) {
|
45 |
jQuery("section#" +target).addClass("sel-tab");
|
46 |
}
|
47 |
}
|
48 |
+
|
49 |
+
function dismissMediaAlert() {
|
50 |
+
var data = { action : 'shortpixel_dismiss_media_alert'};
|
51 |
+
jQuery.get(ajaxurl, data, function(response) {
|
52 |
+
data = JSON.parse(response);
|
53 |
+
if(data["Status"] == 'success') {
|
54 |
+
jQuery("#short-pixel-media-alert").hide();
|
55 |
+
console.log("dismissed");
|
56 |
+
}
|
57 |
+
});
|
58 |
+
}
|
59 |
+
|
60 |
+
function onBulkThumbsCheck(check) {
|
61 |
+
if(check.checked) {
|
62 |
+
jQuery("#with-thumbs").css('display', 'inherit');
|
63 |
+
jQuery("#without-thumbs").css('display', 'none');
|
64 |
+
} else {
|
65 |
+
jQuery("#without-thumbs").css('display', 'inherit');
|
66 |
+
jQuery("#with-thumbs").css('display', 'none');
|
67 |
+
}
|
68 |
+
}
|
69 |
|
70 |
return {
|
71 |
+
setOptions : setOptions,
|
72 |
+
checkThumbsUpdTotal : checkThumbsUpdTotal,
|
73 |
+
switchSettingsTab : switchSettingsTab,
|
74 |
+
onBulkThumbsCheck : onBulkThumbsCheck,
|
75 |
+
dismissMediaAlert : dismissMediaAlert
|
76 |
}
|
77 |
}();
|
78 |
|
93 |
//jQuery("a div", robo).attr("title", "ShortPixel quota exceeded. Click to top-up");
|
94 |
jQuery("a div", robo).attr("title", "ShortPixel quota exceeded. Click for details.");
|
95 |
break;
|
96 |
+
case ShortPixel.STATUS_SKIP:
|
97 |
+
robo.addClass("shortpixel-alert shortpixel-processing");
|
98 |
+
jQuery("a div", robo).attr("title", $message);
|
99 |
+
break;
|
100 |
case ShortPixel.STATUS_FAIL:
|
101 |
robo.addClass("shortpixel-alert shortpixel-processing");
|
102 |
jQuery("a div", robo).attr("title", $message);
|
231 |
break;
|
232 |
case ShortPixel.STATUS_SUCCESS:
|
233 |
var percent = data["PercentImprovement"];
|
234 |
+
var otherType = data["Type"].length > 0 ? (data["Type"] == "lossy" ? "lossless" : "lossy") : null;
|
235 |
+
|
236 |
+
var cellMsg = (percent > 0 ? "<div class='sp-column-info'>Reduced by <span class='percent'>" + percent + "%</span> " : "")
|
237 |
+
+ (percent > 0 && percent < 5 ? "<br>" : '')
|
238 |
+
+ (percent < 5 ? "Bonus processing" : '')
|
239 |
+
+ (data["Type"].length > 0 ? " ("+data["Type"]+")" : "")
|
240 |
+
+ (0 + data['ThumbsCount'] > 0 ? "<br>+" + data['ThumbsCount'] + " thumbnails optimized" :"")
|
241 |
+
+ "</div>";
|
242 |
+
|
243 |
+
if(data["BackupEnabled"] == 1) {
|
244 |
+
cellMsg = '<div class="sp-column-actions">'
|
245 |
+
+ (data["ThumbsTotal"] > data["ThumbsCount"] ? "<a class='button button-smaller button-primary' href=\"javascript:optimizeThumbs(" + id + ");\">Optimize " + (data["ThumbsTotal"] - data["ThumbsCount"]) + " thumbnails</a>" : "")
|
246 |
+
+ (otherType.length ? "<a class='button button-smaller' href=\"javascript:reoptimize(" + id + ", '" + otherType + "');\">Re-optimize " + otherType + "</a>" : "")
|
247 |
+
+ "<a class='button button-smaller' href=\"admin.php?action=shortpixel_restore_backup&attachment_ID=" + id + ")\">Restore backup</a>"
|
248 |
+
+ "</div>" + cellMsg;
|
249 |
+
}
|
250 |
+
|
251 |
showToolBarAlert(ShortPixel.STATUS_SUCCESS, "");
|
252 |
setCellMessage(id, cellMsg);
|
253 |
var animator = new PercentageAnimator("#sp-msg-" + id + " span.percent", percent);
|
258 |
sliderUpdate(id, data["Thumb"], data["BkThumb"], data["PercentImprovement"]);
|
259 |
}
|
260 |
}
|
261 |
+
console.log('Server response: ' + response);
|
262 |
+
if(isBulkPage && typeof data["BulkPercent"] !== 'undefined') {
|
263 |
+
progressUpdate(data["BulkPercent"], data["BulkMsg"]);
|
264 |
+
}
|
265 |
+
setTimeout(checkBulkProgress, 5000);
|
266 |
+
break;
|
267 |
+
|
268 |
case ShortPixel.STATUS_ERROR: //for error and skip also we retry
|
269 |
case ShortPixel.STATUS_SKIP:
|
270 |
+
if(typeof data["Message"] !== 'undefined') {
|
271 |
+
showToolBarAlert(ShortPixel.STATUS_SKIP, data["Message"] + ' Image ID: ' + id);
|
272 |
+
setCellMessage(id, data["Message"]);
|
273 |
+
}
|
274 |
+
case ShortPixel.STATUS_RETRY:
|
275 |
console.log('Server response: ' + response);
|
276 |
if(isBulkPage && typeof data["BulkPercent"] !== 'undefined') {
|
277 |
progressUpdate(data["BulkPercent"], data["BulkMsg"]);
|
299 |
}
|
300 |
|
301 |
function manualOptimization(id) {
|
302 |
+
setCellMessage(id, "<img src='" + ShortPixel.WP_PLUGIN_URL + "/img/loading.gif' class='sp-loading-small'>Image waiting to be processed");
|
303 |
jQuery("li.shortpixel-toolbar-processing").removeClass("shortpixel-hide");
|
304 |
jQuery("li.shortpixel-toolbar-processing").addClass("shortpixel-processing");
|
305 |
var data = { action : 'shortpixel_manual_optimization',
|
309 |
if(data["Status"] == ShortPixel.STATUS_SUCCESS) {
|
310 |
setTimeout(checkBulkProgress, 2000);
|
311 |
} else {
|
312 |
+
setCellMessage(id, typeof data["Message"] !== "undefined" ? data["Message"] : "This content is not processable.");
|
313 |
}
|
314 |
//aici e aici
|
315 |
});
|
316 |
}
|
317 |
|
318 |
+
function reoptimize(id, type) {
|
319 |
+
setCellMessage(id, "<img src='" + ShortPixel.WP_PLUGIN_URL + "/img/loading.gif' class='sp-loading-small'>Image waiting to be reprocessed");
|
320 |
+
jQuery("li.shortpixel-toolbar-processing").removeClass("shortpixel-hide");
|
321 |
+
jQuery("li.shortpixel-toolbar-processing").addClass("shortpixel-processing");
|
322 |
+
var data = { action : 'shortpixel_redo',
|
323 |
+
attachment_ID: id,
|
324 |
+
type: type};
|
325 |
+
jQuery.get(ajaxurl, data, function(response) {
|
326 |
+
data = JSON.parse(response);
|
327 |
+
if(data["Status"] == ShortPixel.STATUS_SUCCESS) {
|
328 |
+
setTimeout(checkBulkProgress, 2000);
|
329 |
+
} else {
|
330 |
+
$msg = typeof data["Message"] !== "undefined" ? data["Message"] : "This content is not processable.";
|
331 |
+
setCellMessage(id, $msg);
|
332 |
+
showToolBarAlert(ShortPixel.STATUS_FAIL, $msg);
|
333 |
+
}
|
334 |
+
});
|
335 |
+
}
|
336 |
+
|
337 |
+
function optimizeThumbs(id) {
|
338 |
+
setCellMessage(id, "<img src='" + ShortPixel.WP_PLUGIN_URL + "/img/loading.gif' class='sp-loading-small'>Image waiting to optimize thumbnails");
|
339 |
+
jQuery("li.shortpixel-toolbar-processing").removeClass("shortpixel-hide");
|
340 |
+
jQuery("li.shortpixel-toolbar-processing").addClass("shortpixel-processing");
|
341 |
+
var data = { action : 'shortpixel_optimize_thumbs',
|
342 |
+
attachment_ID: id};
|
343 |
+
jQuery.get(ajaxurl, data, function(response) {
|
344 |
+
data = JSON.parse(response);
|
345 |
+
if(data["Status"] == ShortPixel.STATUS_SUCCESS) {
|
346 |
+
setTimeout(checkBulkProgress, 2000);
|
347 |
+
} else {
|
348 |
+
setCellMessage(id, typeof data["Message"] !== "undefined" ? data["Message"] : "This content is not processable.");
|
349 |
+
}
|
350 |
+
});
|
351 |
+
}
|
352 |
+
|
353 |
function dismissShortPixelNotice(id) {
|
354 |
jQuery("#short-pixel-notice-" + id).hide();
|
355 |
var data = { action : 'shortpixel_dismiss_notice',
|
readme.txt
CHANGED
@@ -5,7 +5,7 @@ Tags: picture, optimization, image editor, pngout, upload speed, shortpixel, co
|
|
5 |
|
6 |
Requires at least: 3.2.0
|
7 |
Tested up to: 4.4
|
8 |
-
Stable tag: 3.
|
9 |
License: GPLv2 or later
|
10 |
License URI: http://www.gnu.org/licenses/gpl-2.0.html
|
11 |
|
@@ -38,14 +38,14 @@ Both new and old images can be optimized with ShortPixel. Once activated, the pl
|
|
38 |
|
39 |
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).
|
40 |
|
41 |
-
Both monthly subscriptions and one-time plans are available. The same plan can be used for multiple websites.
|
42 |
|
43 |
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!
|
44 |
|
45 |
Help us spread a the word by recommending ShortPixel to your friends and collect 100 additional image credits for each referred sign up.
|
46 |
Make money by promoting a great plugin with our <a href="https://shortpixel.com/free-sign-up-affiliate">50/50 affiliate program</a>.
|
47 |
|
48 |
-
**Why use ShortPixel to optimize
|
49 |
|
50 |
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.
|
51 |
|
@@ -170,6 +170,12 @@ The ShortPixel team is here to help. <a href="https://shortpixel.com/contact">Co
|
|
170 |
|
171 |
== Changelog ==
|
172 |
|
|
|
|
|
|
|
|
|
|
|
|
|
173 |
= 3.2.1 =
|
174 |
|
175 |
* old PHP compatibility fix
|
5 |
|
6 |
Requires at least: 3.2.0
|
7 |
Tested up to: 4.4
|
8 |
+
Stable tag: 3.3.0
|
9 |
License: GPLv2 or later
|
10 |
License URI: http://www.gnu.org/licenses/gpl-2.0.html
|
11 |
|
38 |
|
39 |
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).
|
40 |
|
41 |
+
Both monthly subscriptions and one-time plans are available. The same plan can be used for multiple websites. Make an instant <a rel="friend" href="http://shortpixel.com/image-compression-test">image compression test</a> on your site or <a rel="friend" href="http://shortpixel.com/online-image-compression">compress some images</a> to make sure they are to your liking.
|
42 |
|
43 |
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!
|
44 |
|
45 |
Help us spread a the word by recommending ShortPixel to your friends and collect 100 additional image credits for each referred sign up.
|
46 |
Make money by promoting a great plugin with our <a href="https://shortpixel.com/free-sign-up-affiliate">50/50 affiliate program</a>.
|
47 |
|
48 |
+
**Why use ShortPixel to optimize your images?**
|
49 |
|
50 |
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.
|
51 |
|
170 |
|
171 |
== Changelog ==
|
172 |
|
173 |
+
= 3.3.0 =
|
174 |
+
|
175 |
+
* reoptimize lossless/lossy
|
176 |
+
* optimize thumbs for images already optimized
|
177 |
+
* compatibility with WPML
|
178 |
+
|
179 |
= 3.2.1 =
|
180 |
|
181 |
* old PHP compatibility fix
|
shortpixel_api.php
CHANGED
@@ -22,7 +22,7 @@ class ShortPixelAPI {
|
|
22 |
|
23 |
public function __construct($settings) {
|
24 |
$this->_settings = $settings;
|
25 |
-
$this->_apiEndPoint = $this->_settings->httpProto . '://api.shortpixel.com/v2/
|
26 |
add_action('processImageAction', array(&$this, 'processImageAction'), 10, 4);
|
27 |
}
|
28 |
|
@@ -30,12 +30,12 @@ class ShortPixelAPI {
|
|
30 |
$this->processImage($URLs, $PATHs, $ID, $time);
|
31 |
}
|
32 |
|
33 |
-
public function doRequests($URLs, $Blocking, $ID) {
|
34 |
|
35 |
$requestParameters = array(
|
36 |
'plugin_version' => PLUGIN_VERSION,
|
37 |
'key' => $this->_settings->apiKey,
|
38 |
-
'lossy' => $this->_settings->compressionType,
|
39 |
'cmyk2rgb' => $this->_settings->CMYKtoRGBconversion,
|
40 |
'keep_exif' => ($this->_settings->keepExif ? "1" : "0"),
|
41 |
'resize' => $this->_settings->resizeImages,
|
@@ -45,7 +45,7 @@ class ShortPixelAPI {
|
|
45 |
);
|
46 |
$arguments = array(
|
47 |
'method' => 'POST',
|
48 |
-
'timeout' =>
|
49 |
'redirection' => 3,
|
50 |
'sslverify' => false,
|
51 |
'httpversion' => '1.0',
|
@@ -54,13 +54,16 @@ class ShortPixelAPI {
|
|
54 |
'body' => json_encode($requestParameters),
|
55 |
'cookies' => array()
|
56 |
);
|
57 |
-
//
|
|
|
|
|
|
|
58 |
$response = wp_remote_post($this->_apiEndPoint, $arguments );
|
59 |
-
//echo("RESPONSE:"); var_dump($response);
|
60 |
|
61 |
//only if $Blocking is true analyze the response
|
62 |
if ( $Blocking )
|
63 |
{
|
|
|
64 |
//there was an error, save this error inside file's SP optimization field
|
65 |
if ( is_object($response) && get_class($response) == 'WP_Error' )
|
66 |
{
|
@@ -81,7 +84,7 @@ class ShortPixelAPI {
|
|
81 |
wp_update_attachment_metadata($ID, $meta);
|
82 |
return array("response" => array("code" => $errorCode, "message" => $errorMessage ));
|
83 |
}
|
84 |
-
|
85 |
return $response;//this can be an error or a good response
|
86 |
}
|
87 |
|
@@ -98,25 +101,31 @@ class ShortPixelAPI {
|
|
98 |
public function processImage($URLs, $PATHs, $ID = null, $startTime = 0)
|
99 |
{
|
100 |
|
|
|
|
|
101 |
$PATHs = self::CheckAndFixImagePaths($PATHs);//check for images to make sure they exist on disk
|
102 |
-
if ( $PATHs === false )
|
103 |
-
|
|
|
|
|
|
|
|
|
104 |
|
105 |
//tries multiple times (till timeout almost reached) to fetch images.
|
106 |
if($startTime == 0) {
|
107 |
$startTime = time();
|
108 |
}
|
109 |
$apiRetries = get_option('wp-short-pixel-api-retries');
|
|
|
110 |
if( time() - $startTime > MAX_EXECUTION_TIME)
|
111 |
{//keeps track of time
|
112 |
if ( $apiRetries > MAX_API_RETRIES )//we tried to process this time too many times, giving up...
|
113 |
{
|
114 |
-
$meta = wp_get_attachment_metadata($ID);
|
115 |
$meta['ShortPixelImprovement'] = 'Timed out while processing.';
|
116 |
unset($meta['ShortPixel']['WaitingProcessing']);
|
117 |
update_option('wp-short-pixel-api-retries', 0);//fai added to solve a bug?
|
118 |
wp_update_attachment_metadata($ID, $meta);
|
119 |
-
return array("Status" => self::STATUS_SKIP, "Message" => 'Skip this image,
|
120 |
}
|
121 |
else
|
122 |
{//we'll try again next time user visits a page on admin panel
|
@@ -125,7 +134,9 @@ class ShortPixelAPI {
|
|
125 |
return array("Status" => self::STATUS_RETRY, "Message" => 'Timed out while processing. (pass '.$apiRetries.')');
|
126 |
}
|
127 |
}
|
128 |
-
|
|
|
|
|
129 |
|
130 |
if($response['response']['code'] != 200)//response <> 200 -> there was an error apparently?
|
131 |
return array("Status" => self::STATUS_FAIL, "Message" => "There was an error and your request was not processed.");
|
@@ -149,7 +160,7 @@ class ShortPixelAPI {
|
|
149 |
case 2:
|
150 |
//handle image has been processed
|
151 |
update_option( 'wp-short-pixel-quota-exceeded', 0);//reset the quota exceeded flag
|
152 |
-
return $this->handleSuccess($APIresponse, $URLs, $PATHs, $ID);
|
153 |
break;
|
154 |
default:
|
155 |
//handle error
|
@@ -183,9 +194,24 @@ class ShortPixelAPI {
|
|
183 |
|
184 |
}
|
185 |
|
186 |
-
public function
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
187 |
//var_dump($fileData);
|
188 |
-
if($
|
189 |
{
|
190 |
$fileType = "LossyURL";
|
191 |
$fileSize = "LossySize";
|
@@ -201,12 +227,16 @@ class ShortPixelAPI {
|
|
201 |
return array("Status" => self::STATUS_UNCHANGED, "Message" => "File wasn't optimized so we do not download it.");
|
202 |
|
203 |
$correctFileSize = $fileData->$fileSize;
|
204 |
-
$
|
|
|
|
|
|
|
205 |
//var_dump($tempFiles);
|
206 |
|
207 |
-
if(is_wp_error( $tempFiles[$counter] ))
|
208 |
-
{
|
209 |
-
$
|
|
|
210 |
}
|
211 |
//on success we return this
|
212 |
$returnMessage = array("Status" => self::STATUS_SUCCESS, "Message" => $tempFiles[$counter]);
|
@@ -231,8 +261,9 @@ class ShortPixelAPI {
|
|
231 |
return $returnMessage;
|
232 |
}
|
233 |
|
234 |
-
public function handleSuccess($APIresponse, $URLs, $PATHs, $ID) {
|
235 |
$counter = $savedSpace = $originalSpace = $optimizedSpace = $averageCompression = 0;
|
|
|
236 |
|
237 |
//download each file from array and process it
|
238 |
foreach ( $APIresponse as $fileData )
|
@@ -243,7 +274,7 @@ class ShortPixelAPI {
|
|
243 |
$percentImprovement = $fileData->PercentImprovement;
|
244 |
else //count thumbnails only
|
245 |
update_option( 'wp-short-pixel-thumbnail-count', get_option('wp-short-pixel-thumbnail-count') + 1 );
|
246 |
-
$downloadResult = $this->handleDownload($fileData,$counter);
|
247 |
//when the status is STATUS_UNCHANGED we just skip the array line for that one
|
248 |
if ( $downloadResult['Status'] == self::STATUS_SUCCESS ) {
|
249 |
$tempFiles[$counter] = $downloadResult['Message'];
|
@@ -261,10 +292,10 @@ class ShortPixelAPI {
|
|
261 |
$SubDir = $this->returnSubDir(get_attached_file($ID));
|
262 |
|
263 |
//if backup is enabled - we try to save the images
|
264 |
-
if(
|
265 |
{
|
266 |
$uploadDir = wp_upload_dir();
|
267 |
-
$source = $PATHs
|
268 |
|
269 |
if( !file_exists(SP_BACKUP_FOLDER) && !@mkdir(SP_BACKUP_FOLDER, 0777, true) ) {//creates backup folder if it doesn't exist
|
270 |
return array("Status" => self::STATUS_FAIL, "Message" => "Backup folder does not exist and it cannot be created");
|
@@ -285,12 +316,13 @@ class ShortPixelAPI {
|
|
285 |
if ( !file_exists($filePATH) )
|
286 |
{
|
287 |
if ( !@copy($source[$fileID], $destination[$fileID]) )
|
288 |
-
{//file couldn't
|
289 |
ShortPixelAPI::SaveMessageinMetadata($ID, 'Cannot save file <i>' . self::MB_basename($source[$fileID]) . '</i> in backup directory');
|
290 |
return array("Status" => self::STATUS_FAIL, "Message" => 'Cannot save file <i>' . self::MB_basename($source[$fileID]) . '</i> in backup directory');
|
291 |
}
|
292 |
}
|
293 |
}
|
|
|
294 |
} else {//cannot write to the backup dir, return with an error
|
295 |
ShortPixelAPI::SaveMessageinMetadata($ID, 'Cannot save file in backup directory');
|
296 |
return array("Status" => self::STATUS_FAIL, "Message" => 'Cannot save file in backup directory');
|
@@ -298,7 +330,6 @@ class ShortPixelAPI {
|
|
298 |
|
299 |
}//end backup section
|
300 |
|
301 |
-
|
302 |
$writeFailed = 0;
|
303 |
|
304 |
if ( !empty($tempFiles) )
|
@@ -312,27 +343,29 @@ class ShortPixelAPI {
|
|
312 |
$writeFailed++;
|
313 |
}
|
314 |
@unlink($tempFilePATH);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
315 |
|
316 |
-
|
317 |
-
{
|
318 |
-
|
319 |
-
update_option('bulkProcessingStatus', "error");
|
320 |
-
return array("Status" => self::STATUS_FAIL, "Code" =>"write-fail", "Message" => 'Error: optimized version of ' . $writeFailed . ' file(s) couldn\'t be updated.');
|
321 |
-
}
|
322 |
-
else
|
323 |
-
{//all files were copied, optimization data regarding the savings locally in DB
|
324 |
-
$fileType = ( $this->_settings->compressionType ) ? "LossySize" : "LoselessSize";
|
325 |
-
$savedSpace += $APIresponse[$tempFileID]->OriginalSize - $APIresponse[$tempFileID]->$fileType;
|
326 |
-
$originalSpace += $APIresponse[$tempFileID]->OriginalSize;
|
327 |
-
$optimizedSpace += $APIresponse[$tempFileID]->$fileType;
|
328 |
-
$averageCompression += $fileData->PercentImprovement;
|
329 |
-
|
330 |
-
//add the number of files with < 5% optimization
|
331 |
-
if ( ( ( 1 - $APIresponse[$tempFileID]->$fileType/$APIresponse[$tempFileID]->OriginalSize ) * 100 ) < 5 )
|
332 |
-
$this->_settings->under5Percent++;
|
333 |
-
|
334 |
}
|
335 |
-
}
|
|
|
|
|
336 |
}
|
337 |
//old average counting
|
338 |
$this->_settings->savedSpace += $savedSpace;
|
@@ -343,18 +376,52 @@ class ShortPixelAPI {
|
|
343 |
//new average counting
|
344 |
$this->_settings->totalOriginal += $originalSpace;
|
345 |
$this->_settings->totalOptimized += $optimizedSpace;
|
|
|
346 |
//update metadata for this file
|
347 |
-
$
|
348 |
-
$
|
349 |
-
|
350 |
-
|
351 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
352 |
//we reset the retry counter in case of success
|
353 |
update_option('wp-short-pixel-api-retries', 0);
|
354 |
|
355 |
return array("Status" => self::STATUS_SUCCESS, "Message" => 'Success: No pixels remained unsqueezed :-)', "PercentImprovement" => $percentImprovement);
|
356 |
}//end handleSuccess
|
357 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
358 |
static public function returnSubDir($file)//return subdir for that particular attached file
|
359 |
{
|
360 |
$Atoms = explode("/", $file);
|
@@ -401,7 +468,10 @@ class ShortPixelAPI {
|
|
401 |
return $PATHs;
|
402 |
|
403 |
}
|
404 |
-
|
|
|
|
|
|
|
405 |
|
406 |
static private function SaveMessageinMetadata($ID, $Message)
|
407 |
{
|
22 |
|
23 |
public function __construct($settings) {
|
24 |
$this->_settings = $settings;
|
25 |
+
$this->_apiEndPoint = $this->_settings->httpProto . '://api.shortpixel.com/v2/reducer.php';
|
26 |
add_action('processImageAction', array(&$this, 'processImageAction'), 10, 4);
|
27 |
}
|
28 |
|
30 |
$this->processImage($URLs, $PATHs, $ID, $time);
|
31 |
}
|
32 |
|
33 |
+
public function doRequests($URLs, $Blocking, $ID, $compressionType = false) {
|
34 |
|
35 |
$requestParameters = array(
|
36 |
'plugin_version' => PLUGIN_VERSION,
|
37 |
'key' => $this->_settings->apiKey,
|
38 |
+
'lossy' => $compressionType === false ? $this->_settings->compressionType : $compressionType,
|
39 |
'cmyk2rgb' => $this->_settings->CMYKtoRGBconversion,
|
40 |
'keep_exif' => ($this->_settings->keepExif ? "1" : "0"),
|
41 |
'resize' => $this->_settings->resizeImages,
|
45 |
);
|
46 |
$arguments = array(
|
47 |
'method' => 'POST',
|
48 |
+
'timeout' => 15,
|
49 |
'redirection' => 3,
|
50 |
'sslverify' => false,
|
51 |
'httpversion' => '1.0',
|
54 |
'body' => json_encode($requestParameters),
|
55 |
'cookies' => array()
|
56 |
);
|
57 |
+
//add this explicitely only for https, otherwise (for http) it slows the request
|
58 |
+
if($this->_settings->httpProto !== 'https') {
|
59 |
+
unset($arguments['sslverify']);
|
60 |
+
}
|
61 |
$response = wp_remote_post($this->_apiEndPoint, $arguments );
|
|
|
62 |
|
63 |
//only if $Blocking is true analyze the response
|
64 |
if ( $Blocking )
|
65 |
{
|
66 |
+
//die(var_dump(array('URL: ' => $this->_apiEndPoint, '<br><br>REQUEST:' => $arguments, '<br><br>RESPONSE: ' => $response )));
|
67 |
//there was an error, save this error inside file's SP optimization field
|
68 |
if ( is_object($response) && get_class($response) == 'WP_Error' )
|
69 |
{
|
84 |
wp_update_attachment_metadata($ID, $meta);
|
85 |
return array("response" => array("code" => $errorCode, "message" => $errorMessage ));
|
86 |
}
|
87 |
+
|
88 |
return $response;//this can be an error or a good response
|
89 |
}
|
90 |
|
101 |
public function processImage($URLs, $PATHs, $ID = null, $startTime = 0)
|
102 |
{
|
103 |
|
104 |
+
$meta = wp_get_attachment_metadata($ID);
|
105 |
+
|
106 |
$PATHs = self::CheckAndFixImagePaths($PATHs);//check for images to make sure they exist on disk
|
107 |
+
if ( $PATHs === false ) {
|
108 |
+
$msg = 'The file(s) do not exist on disk.';
|
109 |
+
$meta['ShortPixelImprovement'] = $msg;
|
110 |
+
wp_update_attachment_metadata($ID, $meta);
|
111 |
+
return array("Status" => self::STATUS_SKIP, "Message" => $msg);
|
112 |
+
}
|
113 |
|
114 |
//tries multiple times (till timeout almost reached) to fetch images.
|
115 |
if($startTime == 0) {
|
116 |
$startTime = time();
|
117 |
}
|
118 |
$apiRetries = get_option('wp-short-pixel-api-retries');
|
119 |
+
|
120 |
if( time() - $startTime > MAX_EXECUTION_TIME)
|
121 |
{//keeps track of time
|
122 |
if ( $apiRetries > MAX_API_RETRIES )//we tried to process this time too many times, giving up...
|
123 |
{
|
|
|
124 |
$meta['ShortPixelImprovement'] = 'Timed out while processing.';
|
125 |
unset($meta['ShortPixel']['WaitingProcessing']);
|
126 |
update_option('wp-short-pixel-api-retries', 0);//fai added to solve a bug?
|
127 |
wp_update_attachment_metadata($ID, $meta);
|
128 |
+
return array("Status" => self::STATUS_SKIP, "Message" => 'Image ID: ' . $ID .' Skip this image, try the next one.');
|
129 |
}
|
130 |
else
|
131 |
{//we'll try again next time user visits a page on admin panel
|
134 |
return array("Status" => self::STATUS_RETRY, "Message" => 'Timed out while processing. (pass '.$apiRetries.')');
|
135 |
}
|
136 |
}
|
137 |
+
|
138 |
+
$compressionType = isset($meta['ShortPixel']['type']) ? ($meta['ShortPixel']['type'] == 'lossy' ? 1 : 0) : $this->_settings->compressionType;
|
139 |
+
$response = $this->doRequests($URLs, true, $ID, $compressionType);//send requests to API
|
140 |
|
141 |
if($response['response']['code'] != 200)//response <> 200 -> there was an error apparently?
|
142 |
return array("Status" => self::STATUS_FAIL, "Message" => "There was an error and your request was not processed.");
|
160 |
case 2:
|
161 |
//handle image has been processed
|
162 |
update_option( 'wp-short-pixel-quota-exceeded', 0);//reset the quota exceeded flag
|
163 |
+
return $this->handleSuccess($APIresponse, $URLs, $PATHs, $ID, $compressionType);
|
164 |
break;
|
165 |
default:
|
166 |
//handle error
|
194 |
|
195 |
}
|
196 |
|
197 |
+
public function setPreferredProtocol($url, $reset = false) {
|
198 |
+
//switch protocol based on the formerly detected working protocol
|
199 |
+
if($this->_settings->downloadProto == '' || $reset) {
|
200 |
+
//make a test to see if the http is working
|
201 |
+
$testURL = 'http://api.shortpixel.com/img/connection-test-image.png';
|
202 |
+
$result = download_url($testURL, 10);
|
203 |
+
$this->_settings->downloadProto = is_wp_error( $result ) ? 'https' : 'http';
|
204 |
+
}
|
205 |
+
return $this->_settings->downloadProto == 'http' ?
|
206 |
+
str_replace('https://', 'http://', $url) :
|
207 |
+
str_replace('http://', 'https://', $url);
|
208 |
+
|
209 |
+
|
210 |
+
}
|
211 |
+
|
212 |
+
public function handleDownload($fileData,$counter, $compressionType){
|
213 |
//var_dump($fileData);
|
214 |
+
if($compressionType)
|
215 |
{
|
216 |
$fileType = "LossyURL";
|
217 |
$fileSize = "LossySize";
|
227 |
return array("Status" => self::STATUS_UNCHANGED, "Message" => "File wasn't optimized so we do not download it.");
|
228 |
|
229 |
$correctFileSize = $fileData->$fileSize;
|
230 |
+
$fileURL = $this->setPreferredProtocol(urldecode($fileData->$fileType));
|
231 |
+
|
232 |
+
$downloadTimeout = ini_get('max_execution_time') - 10;
|
233 |
+
$tempFiles[$counter] = download_url($fileURL, $downloadTimeout);
|
234 |
//var_dump($tempFiles);
|
235 |
|
236 |
+
if(is_wp_error( $tempFiles[$counter] ))
|
237 |
+
{ //try to switch the default protocol
|
238 |
+
$fileURL = $this->setPreferredProtocol(urldecode($fileData->$fileType), true); //force recheck of the protocol
|
239 |
+
$tempFiles[$counter] = download_url($fileURL, $downloadTimeout);
|
240 |
}
|
241 |
//on success we return this
|
242 |
$returnMessage = array("Status" => self::STATUS_SUCCESS, "Message" => $tempFiles[$counter]);
|
261 |
return $returnMessage;
|
262 |
}
|
263 |
|
264 |
+
public function handleSuccess($APIresponse, $URLs, $PATHs, $ID, $compressionType) {
|
265 |
$counter = $savedSpace = $originalSpace = $optimizedSpace = $averageCompression = 0;
|
266 |
+
$NoBackup = true;
|
267 |
|
268 |
//download each file from array and process it
|
269 |
foreach ( $APIresponse as $fileData )
|
274 |
$percentImprovement = $fileData->PercentImprovement;
|
275 |
else //count thumbnails only
|
276 |
update_option( 'wp-short-pixel-thumbnail-count', get_option('wp-short-pixel-thumbnail-count') + 1 );
|
277 |
+
$downloadResult = $this->handleDownload($fileData,$counter,$compressionType);
|
278 |
//when the status is STATUS_UNCHANGED we just skip the array line for that one
|
279 |
if ( $downloadResult['Status'] == self::STATUS_SUCCESS ) {
|
280 |
$tempFiles[$counter] = $downloadResult['Message'];
|
292 |
$SubDir = $this->returnSubDir(get_attached_file($ID));
|
293 |
|
294 |
//if backup is enabled - we try to save the images
|
295 |
+
if( $this->_settings->backupImages )
|
296 |
{
|
297 |
$uploadDir = wp_upload_dir();
|
298 |
+
$source = $PATHs; //array with final paths for these files
|
299 |
|
300 |
if( !file_exists(SP_BACKUP_FOLDER) && !@mkdir(SP_BACKUP_FOLDER, 0777, true) ) {//creates backup folder if it doesn't exist
|
301 |
return array("Status" => self::STATUS_FAIL, "Message" => "Backup folder does not exist and it cannot be created");
|
316 |
if ( !file_exists($filePATH) )
|
317 |
{
|
318 |
if ( !@copy($source[$fileID], $destination[$fileID]) )
|
319 |
+
{//file couldn't be saved in backup folder
|
320 |
ShortPixelAPI::SaveMessageinMetadata($ID, 'Cannot save file <i>' . self::MB_basename($source[$fileID]) . '</i> in backup directory');
|
321 |
return array("Status" => self::STATUS_FAIL, "Message" => 'Cannot save file <i>' . self::MB_basename($source[$fileID]) . '</i> in backup directory');
|
322 |
}
|
323 |
}
|
324 |
}
|
325 |
+
$NoBackup = true;
|
326 |
} else {//cannot write to the backup dir, return with an error
|
327 |
ShortPixelAPI::SaveMessageinMetadata($ID, 'Cannot save file in backup directory');
|
328 |
return array("Status" => self::STATUS_FAIL, "Message" => 'Cannot save file in backup directory');
|
330 |
|
331 |
}//end backup section
|
332 |
|
|
|
333 |
$writeFailed = 0;
|
334 |
|
335 |
if ( !empty($tempFiles) )
|
343 |
$writeFailed++;
|
344 |
}
|
345 |
@unlink($tempFilePATH);
|
346 |
+
}
|
347 |
+
|
348 |
+
if ( $writeFailed > 0 )//there was an error
|
349 |
+
{
|
350 |
+
ShortPixelAPI::SaveMessageinMetadata($ID, 'Error: optimized version of ' . $writeFailed . ' file(s) couldn\'t be updated.');
|
351 |
+
update_option('bulkProcessingStatus', "error");
|
352 |
+
return array("Status" => self::STATUS_FAIL, "Code" =>"write-fail", "Message" => 'Error: optimized version of ' . $writeFailed . ' file(s) couldn\'t be updated.');
|
353 |
+
}
|
354 |
+
else
|
355 |
+
{//all files were copied, optimization data regarding the savings locally in DB
|
356 |
+
$fileType = ( $this->_settings->compressionType ) ? "LossySize" : "LoselessSize";
|
357 |
+
$savedSpace += $APIresponse[$tempFileID]->OriginalSize - $APIresponse[$tempFileID]->$fileType;
|
358 |
+
$originalSpace += $APIresponse[$tempFileID]->OriginalSize;
|
359 |
+
$optimizedSpace += $APIresponse[$tempFileID]->$fileType;
|
360 |
+
$averageCompression += $fileData->PercentImprovement;
|
361 |
|
362 |
+
//add the number of files with < 5% optimization
|
363 |
+
if ( ( ( 1 - $APIresponse[$tempFileID]->$fileType/$APIresponse[$tempFileID]->OriginalSize ) * 100 ) < 5 ) {
|
364 |
+
$this->_settings->under5Percent++;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
365 |
}
|
366 |
+
}
|
367 |
+
} elseif( 0 + $fileData->PercentImprovement < 5) {
|
368 |
+
$this->_settings->under5Percent++;
|
369 |
}
|
370 |
//old average counting
|
371 |
$this->_settings->savedSpace += $savedSpace;
|
376 |
//new average counting
|
377 |
$this->_settings->totalOriginal += $originalSpace;
|
378 |
$this->_settings->totalOptimized += $optimizedSpace;
|
379 |
+
|
380 |
//update metadata for this file
|
381 |
+
$duplicates = self::getWPMLDuplicates($ID);
|
382 |
+
foreach($duplicates as $_ID) {
|
383 |
+
$meta = wp_get_attachment_metadata($_ID);
|
384 |
+
$meta['ShortPixel']['type'] = self::getCompressionTypeName($compressionType);
|
385 |
+
$meta['ShortPixel']['exifKept'] = $this->_settings->keepExif;
|
386 |
+
$meta['ShortPixel']['date'] = date("Y-m-d");
|
387 |
+
//thumbs were processed if settings or if they were explicitely requested
|
388 |
+
$meta['ShortPixel']['thumbsOpt'] = (isset($meta['ShortPixel']['thumbsTodo']) || $this->_settings->processThumbnails) && isset($meta['sizes']) ? count($meta['sizes']) : 0;
|
389 |
+
//if thumbsTodo - this means there was an explicit request to process thumbs for an image that was previously processed without
|
390 |
+
// don't update the ShortPixelImprovement ratio as this is only calculated based on main image
|
391 |
+
if(isset($meta['ShortPixel']['thumbsTodo'])) {
|
392 |
+
unset($meta['ShortPixel']['thumbsTodo']);
|
393 |
+
$percentImprovement = $meta['ShortPixelImprovement'];
|
394 |
+
} else {
|
395 |
+
$meta['ShortPixelImprovement'] = "".round($percentImprovement,2);
|
396 |
+
}
|
397 |
+
if($NoBackup) {
|
398 |
+
$meta['ShortPixel']['NoBackup'] = true;
|
399 |
+
}
|
400 |
+
wp_update_attachment_metadata($_ID, $meta);
|
401 |
+
}
|
402 |
//we reset the retry counter in case of success
|
403 |
update_option('wp-short-pixel-api-retries', 0);
|
404 |
|
405 |
return array("Status" => self::STATUS_SUCCESS, "Message" => 'Success: No pixels remained unsqueezed :-)', "PercentImprovement" => $percentImprovement);
|
406 |
}//end handleSuccess
|
407 |
|
408 |
+
static public function getWPMLDuplicates( $id ) {
|
409 |
+
global $wpdb;
|
410 |
+
|
411 |
+
$parentId = get_post_meta ($id, '_icl_lang_duplicate_of', true );
|
412 |
+
if($parentId) $id = $parentId;
|
413 |
+
|
414 |
+
$duplicates = $wpdb->get_col( $wpdb->prepare( "
|
415 |
+
SELECT pm.post_id FROM {$wpdb->postmeta} pm
|
416 |
+
WHERE pm.meta_value = %s AND pm.meta_key = '_icl_lang_duplicate_of'
|
417 |
+
", $id ) );
|
418 |
+
|
419 |
+
if(!in_array($id, $duplicates)) $duplicates[] = $id;
|
420 |
+
|
421 |
+
return $duplicates;
|
422 |
+
}
|
423 |
+
|
424 |
+
|
425 |
static public function returnSubDir($file)//return subdir for that particular attached file
|
426 |
{
|
427 |
$Atoms = explode("/", $file);
|
468 |
return $PATHs;
|
469 |
|
470 |
}
|
471 |
+
|
472 |
+
static public function getCompressionTypeName($compressionType) {
|
473 |
+
return $compressionType == 1 ? 'lossy' : 'lossless';
|
474 |
+
}
|
475 |
|
476 |
static private function SaveMessageinMetadata($ID, $Message)
|
477 |
{
|
shortpixel_queue.php
CHANGED
@@ -117,8 +117,19 @@ class ShortPixelQueue {
|
|
117 |
|
118 |
public function getFailed() {
|
119 |
$failed = $this->settings->getOpt('wp-short-pixel-failed-imgs','');
|
|
|
120 |
if(!strlen($failed)) return array();
|
121 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
122 |
}
|
123 |
|
124 |
public function bulkRunning() {
|
@@ -167,13 +178,20 @@ class ShortPixelQueue {
|
|
167 |
}
|
168 |
|
169 |
public function setBulkPreviousPercent() {
|
170 |
-
//processable
|
171 |
$res = $this->ctrl->countAllProcessableFiles($this->getFlagBulkId(), $this->stopBulkId);
|
172 |
$this->bulkCount = $res["mainFiles"];
|
173 |
$this->settings->setOpt("wp-short-pixel-bulk-count", $this->bulkCount);
|
174 |
-
|
175 |
-
|
176 |
-
$this->bulkAlreadyDoneCount = $res["
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
177 |
$this->settings->setOpt("wp-short-pixel-bulk-done-count", $this->bulkAlreadyDoneCount);
|
178 |
//percent already done
|
179 |
$this->bulkPreviousPercent = round($this->bulkAlreadyDoneCount / ($this->bulkCount ? $this->bulkCount : 1) * 100);
|
117 |
|
118 |
public function getFailed() {
|
119 |
$failed = $this->settings->getOpt('wp-short-pixel-failed-imgs','');
|
120 |
+
$failed = "83";
|
121 |
if(!strlen($failed)) return array();
|
122 |
+
$ret = explode(",", $failed);
|
123 |
+
$fails = array();
|
124 |
+
foreach($ret as $fail) {
|
125 |
+
$meta = wp_get_attachment_metadata($fail);
|
126 |
+
if(!$meta || (isset($meta["ShortPixelImprovement"]) && is_numeric($meta["ShortPixelImprovement"]))){
|
127 |
+
$this->removeFromFailed($fail);
|
128 |
+
} else {
|
129 |
+
$fails[] = $fail;
|
130 |
+
}
|
131 |
+
}
|
132 |
+
return $fails;
|
133 |
}
|
134 |
|
135 |
public function bulkRunning() {
|
178 |
}
|
179 |
|
180 |
public function setBulkPreviousPercent() {
|
181 |
+
//processable and already processed
|
182 |
$res = $this->ctrl->countAllProcessableFiles($this->getFlagBulkId(), $this->stopBulkId);
|
183 |
$this->bulkCount = $res["mainFiles"];
|
184 |
$this->settings->setOpt("wp-short-pixel-bulk-count", $this->bulkCount);
|
185 |
+
|
186 |
+
//if compression type changed, add also the images with the other compression type
|
187 |
+
$this->bulkAlreadyDoneCount = $res["mainProcessedFiles"] - $res["mainProc".((0 + $this->ctrl->getCompressionType() == 1) ? "Lossless" : "Lossy")."Files"];
|
188 |
+
// if the thumbnails are to be processed, add also the images that have thumbs not processed
|
189 |
+
if($this->settings->processThumbnails) {
|
190 |
+
$this->bulkAlreadyDoneCount -= $res["mainUnprocessedThumbs"];
|
191 |
+
}
|
192 |
+
|
193 |
+
//die(var_dump($res));
|
194 |
+
|
195 |
$this->settings->setOpt("wp-short-pixel-bulk-done-count", $this->bulkAlreadyDoneCount);
|
196 |
//percent already done
|
197 |
$this->bulkPreviousPercent = round($this->bulkAlreadyDoneCount / ($this->bulkCount ? $this->bulkCount : 1) * 100);
|
shortpixel_view.php
CHANGED
@@ -145,7 +145,8 @@ class ShortPixelView {
|
|
145 |
<?php $this->displayBulkStats($quotaData['totalProcessedFiles'], $quotaData['mainProcessedFiles'], $under5PercentCount, $averageCompression, $savedSpace);?>
|
146 |
<?php if($quotaData['totalProcessedFiles'] < $quotaData['totalFiles']) { ?>
|
147 |
<p><?php echo(number_format($quotaData['mainFiles'] - $quotaData['mainProcessedFiles']));?> images and
|
148 |
-
<?php echo(number_format(($quotaData['totalFiles'] - $quotaData['mainFiles']) - ($quotaData['totalProcessedFiles'] - $quotaData['mainProcessedFiles'])))
|
|
|
149 |
<?php } ?>
|
150 |
<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>
|
151 |
<?php
|
@@ -166,23 +167,90 @@ class ShortPixelView {
|
|
166 |
fjs.parentNode.insertBefore(js,fjs);}}(document, 'script', 'twitter-wjs');
|
167 |
</script>
|
168 |
</div>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
169 |
</div>
|
170 |
<?php $this->displayBulkStats($quotaData['totalProcessedFiles'], $quotaData['mainProcessedFiles'], $under5PercentCount, $averageCompression, $savedSpace);?>
|
171 |
-
<p>Go to the ShortPixel <a href='<?php echo(get_admin_url());?>options-general.php?page=wp-shortpixel#stats'>Stats</a> and see all your websites' optimized stats. Download your detailed <a href="https://api.shortpixel.com/v2/report.php?key=<?php echo($this->ctrl->getApiKey());?>">Optimization Report</a> to check your image optimization statistics for the last 40 days
|
172 |
-
<?php
|
173 |
-
<p><?php echo(number_format($quotaData['mainFiles'] - $quotaData['mainProcessedFiles']));?> images and
|
174 |
-
<?php echo(number_format(($quotaData['totalFiles'] - $quotaData['mainFiles']) - ($quotaData['totalProcessedFiles'] - $quotaData['mainProcessedFiles'])));?> thumbnails are not yet optimized by ShortPixel.</p>
|
175 |
-
<?php }
|
176 |
$failed = $this->ctrl->getPrioQ()->getFailed();
|
177 |
if(count($failed)) { ?>
|
178 |
-
<
|
179 |
-
|
|
|
|
|
|
|
|
|
180 |
<?php } ?>
|
181 |
-
<
|
182 |
-
|
183 |
-
|
184 |
-
|
185 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
186 |
<?php } ?>
|
187 |
</div>
|
188 |
<?php
|
@@ -266,12 +334,8 @@ class ShortPixelView {
|
|
266 |
<div class="bulk-progress bulk-stats">
|
267 |
<?php foreach($failed as $fail) {
|
268 |
$meta = wp_get_attachment_metadata($fail);
|
269 |
-
|
270 |
-
|
271 |
-
} else {
|
272 |
-
?> <div class="label"><a href="/wp-admin/post.php?post=<?php echo($fail);?>&action=edit"><?php echo(substr($meta["file"], 0, 80));?> - ID: <?php echo($fail);?></a></div><br/>
|
273 |
-
<?php }
|
274 |
-
}?>
|
275 |
</div>
|
276 |
<?php
|
277 |
}
|
@@ -285,7 +349,7 @@ class ShortPixelView {
|
|
285 |
<a href="https://shortpixel.com/<?php echo($this->ctrl->getVerifiedKey() ? "login/".$this->ctrl->getApiKey() : "pricing");?>" target="_blank" style="font-size:18px">
|
286 |
Upgrade now
|
287 |
</a> |
|
288 |
-
<a href="https://shortpixel.com/contact" target="_blank" style="font-size:18px">Support </a>
|
289 |
</p>
|
290 |
<?php if($notice !== null) { ?>
|
291 |
<br/>
|
@@ -393,7 +457,7 @@ class ShortPixelView {
|
|
393 |
<tr>
|
394 |
<th scope="row"><label for="thumbnails">Also include thumbnails:</label></th>
|
395 |
<td><input name="thumbnails" type="checkbox" id="thumbnails" <?php echo( $checked );?>> Apply compression also to
|
396 |
-
<strong
|
397 |
<p class="settings-info">It is highly recommended that you optimize the thumbnails as they are usually the images most viewed by end users and can generate most traffic.<br>Please note that thumbnails count up to your total quota.</p>
|
398 |
</td>
|
399 |
</tr>
|
@@ -446,7 +510,7 @@ class ShortPixelView {
|
|
446 |
if(this !== prev) {
|
447 |
prev = this;
|
448 |
}
|
449 |
-
alert('This type of optimization will apply to new uploaded images.\nImages that were already processed will not be re-optimized.');
|
450 |
};
|
451 |
}
|
452 |
function enableResize(elm) {
|
@@ -554,4 +618,72 @@ class ShortPixelView {
|
|
554 |
</div>
|
555 |
<?php
|
556 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
557 |
}
|
145 |
<?php $this->displayBulkStats($quotaData['totalProcessedFiles'], $quotaData['mainProcessedFiles'], $under5PercentCount, $averageCompression, $savedSpace);?>
|
146 |
<?php if($quotaData['totalProcessedFiles'] < $quotaData['totalFiles']) { ?>
|
147 |
<p><?php echo(number_format($quotaData['mainFiles'] - $quotaData['mainProcessedFiles']));?> images and
|
148 |
+
<?php echo(number_format(($quotaData['totalFiles'] - $quotaData['mainFiles']) - ($quotaData['totalProcessedFiles'] - $quotaData['mainProcessedFiles'])));
|
149 |
+
?> thumbnails are not yet optimized by ShortPixel.</p>
|
150 |
<?php } ?>
|
151 |
<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>
|
152 |
<?php
|
167 |
fjs.parentNode.insertBefore(js,fjs);}}(document, 'script', 'twitter-wjs');
|
168 |
</script>
|
169 |
</div>
|
170 |
+
<?php if(0+$averageCompression>30) {?>
|
171 |
+
<div class='shortpixel-rate-us'>
|
172 |
+
<a href="https://wordpress.org/support/view/plugin-reviews/shortpixel-image-optimiser?rate=5#postform" target="_blank">
|
173 |
+
<div>
|
174 |
+
Please rate us!
|
175 |
+
</div><img src="<?php echo(plugins_url( 'img/stars.png', __FILE__ ));?>">
|
176 |
+
</a>
|
177 |
+
</div>
|
178 |
+
<?php } ?>
|
179 |
</div>
|
180 |
<?php $this->displayBulkStats($quotaData['totalProcessedFiles'], $quotaData['mainProcessedFiles'], $under5PercentCount, $averageCompression, $savedSpace);?>
|
181 |
+
<p>Go to the ShortPixel <a href='<?php echo(get_admin_url());?>options-general.php?page=wp-shortpixel#stats'>Stats</a> and see all your websites' optimized stats. Download your detailed <a href="https://api.shortpixel.com/v2/report.php?key=<?php echo($this->ctrl->getApiKey());?>">Optimization Report</a> to check your image optimization statistics for the last 40 days.</p>
|
182 |
+
<?php
|
|
|
|
|
|
|
183 |
$failed = $this->ctrl->getPrioQ()->getFailed();
|
184 |
if(count($failed)) { ?>
|
185 |
+
<div class="bulk-progress" style="margin-bottom: 15px">
|
186 |
+
<p>
|
187 |
+
The following images could not be processed because of their limited write rights. This usually happens if you have changed your hosting provider. Please restart the optimization process after you granted write rights to all the files below.
|
188 |
+
</p>
|
189 |
+
<?php $this->displayFailed($failed); ?>
|
190 |
+
</div>
|
191 |
<?php } ?>
|
192 |
+
<div class="bulk-progress">
|
193 |
+
<?php
|
194 |
+
$todo = false;
|
195 |
+
if($quotaData['totalProcessedFiles'] < $quotaData['totalFiles']) {
|
196 |
+
$todo = true;
|
197 |
+
$mainNotProcessed = $quotaData['mainFiles'] - $quotaData['mainProcessedFiles'];
|
198 |
+
$thumbsNotProcessed = ($quotaData['totalFiles'] - $quotaData['mainFiles']) - ($quotaData['totalProcessedFiles'] - $quotaData['mainProcessedFiles']);
|
199 |
+
?>
|
200 |
+
<p>
|
201 |
+
<?php echo($mainNotProcessed ? number_format($mainNotProcessed) . " images" : "");?>
|
202 |
+
<?php echo($mainNotProcessed && $thumbsNotProcessed ? " and" : "");?>
|
203 |
+
<?php echo($thumbsNotProcessed ? number_format($thumbsNotProcessed) . " thumbnails" : "");?> are not yet optimized by ShortPixel.
|
204 |
+
<?php if (count($quotaData['filesWithErrors'])) { ?>
|
205 |
+
Some have errors:
|
206 |
+
<?php foreach($quotaData['filesWithErrors'] as $id => $data) {
|
207 |
+
echo('<a href="post.php?post='.$id.'&action=edit" title="'.$data['Message'].'">'.$data['Name'].'</a>, ');
|
208 |
+
} ?>
|
209 |
+
<?php } ?>
|
210 |
+
</p>
|
211 |
+
<?php }
|
212 |
+
$settings = $this->ctrl->getSettings();
|
213 |
+
$optType = $settings->compressionType == '1' ? 'lossy' : 'lossless';
|
214 |
+
$otherType = $settings->compressionType == '1' ? 'lossless' : 'lossy';
|
215 |
+
if( !$this->ctrl->backupFolderIsEmpty()
|
216 |
+
&& ( ($quotaData['totalProcLossyFiles'] > 0 && $settings->compressionType == 0)
|
217 |
+
|| ($quotaData['totalProcLosslessFiles'] > 0 && $settings->compressionType == 1)))
|
218 |
+
{
|
219 |
+
$todo = true;
|
220 |
+
$statType = $settings->compressionType == '1' ? 'Lossless' : 'Lossy';
|
221 |
+
$thumbsCount = $quotaData['totalProc'.$statType.'Files'] - $quotaData['mainProc'.$statType.'Files'];
|
222 |
+
?>
|
223 |
+
<p id="with-thumbs" <?php echo(!$settings->processThumbnails ? 'style="display:none;"' : "");?>>
|
224 |
+
<?php echo(number_format($quotaData['mainProc'.$statType.'Files']));?> images and
|
225 |
+
<?php echo(number_format($quotaData['totalProc'.$statType.'Files'] - $quotaData['mainProc'.$statType.'Files']));?> thumbnails were optimized
|
226 |
+
<strong>
|
227 |
+
<?php echo($otherType);?>
|
228 |
+
</strong>. You can re-optimize
|
229 |
+
<strong>
|
230 |
+
<?php echo($optType);?>
|
231 |
+
</strong> the ones that have backup.
|
232 |
+
</p>
|
233 |
+
<p id="without-thumbs" <?php echo($settings->processThumbnails ? 'style="display:none;"' : "");?>>
|
234 |
+
<?php echo(number_format($quotaData['mainProc'.$statType.'Files']));?> images are optimized
|
235 |
+
<strong>
|
236 |
+
<?php echo($otherType);?>
|
237 |
+
</strong>. You can re-optimize
|
238 |
+
<strong>
|
239 |
+
<?php echo($optType);?>
|
240 |
+
</strong> the ones that have backup.
|
241 |
+
<?php echo($thumbsCount ? number_format($thumbsCount) . ' thumbnails will be restored to originals.' : '');?>
|
242 |
+
</p>
|
243 |
+
<?php
|
244 |
+
} ?>
|
245 |
+
<p>Restart the optimization process for <?php echo($todo ? 'these images' : 'new images added to your library');?> by clicking the button below.
|
246 |
+
Already <strong><?php echo($todo ? ($optType) : '');?></strong> optimized images will not be reprocessed.
|
247 |
+
<br>Please note that reoptimizing images as <strong>lossy/lossless</strong> may use additional credits. <a href="http://blog.shortpixel.com/the-all-new-re-optimization-functions-in-shortpixel/" target="_blank">More info</a>
|
248 |
+
</p>
|
249 |
+
<form action='' method='POST' >
|
250 |
+
<input type='checkbox' id='bulk-thumbnails' name='thumbnails' <?php echo($this->ctrl->processThumbnails() ? "checked":"");?> onchange="ShortPixel.onBulkThumbsCheck(this)"> Include thumbnails<br><br>
|
251 |
+
<input type='submit' name='bulkProcess' id='bulkProcess' class='button button-primary' value='Restart Optimizing'>
|
252 |
+
</form>
|
253 |
+
</div>
|
254 |
<?php } ?>
|
255 |
</div>
|
256 |
<?php
|
334 |
<div class="bulk-progress bulk-stats">
|
335 |
<?php foreach($failed as $fail) {
|
336 |
$meta = wp_get_attachment_metadata($fail);
|
337 |
+
?> <div class="label"><a href="/wp-admin/post.php?post=<?php echo($fail);?>&action=edit"><?php echo(substr($meta["file"], 0, 80));?> - ID: <?php echo($fail);?></a></div><br/>
|
338 |
+
<?php }?>
|
|
|
|
|
|
|
|
|
339 |
</div>
|
340 |
<?php
|
341 |
}
|
349 |
<a href="https://shortpixel.com/<?php echo($this->ctrl->getVerifiedKey() ? "login/".$this->ctrl->getApiKey() : "pricing");?>" target="_blank" style="font-size:18px">
|
350 |
Upgrade now
|
351 |
</a> |
|
352 |
+
<a href="https://shortpixel.com/contact/<?php echo($this->ctrl->getEncryptedData());?>" target="_blank" style="font-size:18px">Support </a>
|
353 |
</p>
|
354 |
<?php if($notice !== null) { ?>
|
355 |
<br/>
|
457 |
<tr>
|
458 |
<th scope="row"><label for="thumbnails">Also include thumbnails:</label></th>
|
459 |
<td><input name="thumbnails" type="checkbox" id="thumbnails" <?php echo( $checked );?>> Apply compression also to
|
460 |
+
<strong>image thumbnails.</strong> (<?php echo($thumbnailsToProcess ? number_format($thumbnailsToProcess) : "");?> thumbnails to optimize)
|
461 |
<p class="settings-info">It is highly recommended that you optimize the thumbnails as they are usually the images most viewed by end users and can generate most traffic.<br>Please note that thumbnails count up to your total quota.</p>
|
462 |
</td>
|
463 |
</tr>
|
510 |
if(this !== prev) {
|
511 |
prev = this;
|
512 |
}
|
513 |
+
alert('This type of optimization will apply to new uploaded images.\nImages that were already processed will not be re-optimized unless you restart the bulk process.');
|
514 |
};
|
515 |
}
|
516 |
function enableResize(elm) {
|
618 |
</div>
|
619 |
<?php
|
620 |
}
|
621 |
+
|
622 |
+
public function renderCustomColumn($id, $data){ ?>
|
623 |
+
<div id='sp-msg-<?php echo($id);?>'>
|
624 |
+
<?php switch($data['status']) {
|
625 |
+
case 'n/a': ?>
|
626 |
+
Optimization N/A <?php
|
627 |
+
break;
|
628 |
+
case 'notFound': ?>
|
629 |
+
Image does not exist. <?php
|
630 |
+
break;
|
631 |
+
case 'invalidKey': ?>
|
632 |
+
Invalid API Key. <a href="options-general.php?page=wp-shortpixel">Check your Settings</a> <?php
|
633 |
+
break;
|
634 |
+
case 'quotaExceeded':
|
635 |
+
echo($this->getQuotaExceededHTML(isset($data['message']) ? $data['message'] : ''));
|
636 |
+
break;
|
637 |
+
case 'optimizeNow':
|
638 |
+
echo($data['message']) ?> <a class='button button-smaller button-primary' href="javascript:manualOptimization(<?php echo($id)?>)">Optimize now</a> <?php
|
639 |
+
if(isset($data['thumbsTotal']) && $data['thumbsTotal'] > 0) {
|
640 |
+
echo("<br>+" . $data['thumbsTotal'] . " thumbnails");
|
641 |
+
}
|
642 |
+
break;
|
643 |
+
case 'retry': ?>
|
644 |
+
<?php echo($data['message'])?> <a class='button button-smaller button-primary' href="javascript:manualOptimization(<?php echo($id)?>)">Retry</a> <?php
|
645 |
+
break;
|
646 |
+
case 'pdfOptimized':
|
647 |
+
case 'imgOptimized': ?>
|
648 |
+
<?php if($data['showActions']) { ?>
|
649 |
+
<div class='sp-column-actions'>
|
650 |
+
<?php if(!$data['thumbsOpt'] && $data['thumbsTotal']) { ?>
|
651 |
+
<a class='button button-smaller button-primary' href="javascript:optimizeThumbs(<?php echo($id)?>);">
|
652 |
+
Optimize <?php echo($data['thumbsTotal']);?> thumbnails
|
653 |
+
</a>
|
654 |
+
<?php }
|
655 |
+
if($data['backup']) {
|
656 |
+
if($data['type']) {
|
657 |
+
$type = $data['type'] == 'lossy' ? 'lossless' : 'lossy'; ?>
|
658 |
+
<a class='button button-smaller' href="javascript:reoptimize(<?php echo($id)?>, '<?php echo($type)?>');" title="Using the backed-up image">
|
659 |
+
Re-optimize <?php echo($type)?>
|
660 |
+
</a><?php
|
661 |
+
} ?>
|
662 |
+
<a class='button button-smaller' href="admin.php?action=shortpixel_restore_backup&attachment_ID=<?php echo($id)?>">
|
663 |
+
Restore backup
|
664 |
+
</a>
|
665 |
+
<?php } ?>
|
666 |
+
</div>
|
667 |
+
<?php } ?>
|
668 |
+
<div class='sp-column-info'>
|
669 |
+
<?php echo(($data['percent'] ? 'Reduced by ' . $data['percent'] . '% ' : '')
|
670 |
+
.($data['bonus'] && $data['percent'] ? '<br>' : '')
|
671 |
+
.($data['bonus'] ? 'Bonus processing' : '')
|
672 |
+
.($data['type'] ? ' ('.$data['type'].')':'') . '<br>');?>
|
673 |
+
<?php echo($data['thumbsOpt']
|
674 |
+
? "+" . $data['thumbsOpt'] . ($data['thumbsTotal'] > $data['thumbsOpt'] ? " of ".$data['thumbsTotal'] : '') . " thumbnails optimized" : '');?>
|
675 |
+
</div> <?php
|
676 |
+
break;
|
677 |
+
}
|
678 |
+
//die(var_dump($data));
|
679 |
+
?>
|
680 |
+
</div>
|
681 |
+
<?php
|
682 |
+
}
|
683 |
+
|
684 |
+
public function getQuotaExceededHTML($message = '') {
|
685 |
+
return $message . " Quota Exceeded.
|
686 |
+
<a class='button button-smaller button-primary' href='https://shortpixel.com/login/". $this->ctrl->getApiKey() . "' target='_blank'>Extend Quota</a>
|
687 |
+
<a class='button button-smaller' href='admin.php?action=shortpixel_check_quota' target='_blank'>Check Quota</a>";
|
688 |
+
}
|
689 |
}
|
wp-shortpixel-settings.php
CHANGED
@@ -34,6 +34,8 @@ class WPShortPixelSettings {
|
|
34 |
'totalOriginal' => 'wp-short-pixel-total-original',
|
35 |
'quotaExceeded' => 'wp-short-pixel-quota-exceeded',
|
36 |
'httpProto' => 'wp-short-pixel-protocol',
|
|
|
|
|
37 |
'' => '',
|
38 |
);
|
39 |
|
34 |
'totalOriginal' => 'wp-short-pixel-total-original',
|
35 |
'quotaExceeded' => 'wp-short-pixel-quota-exceeded',
|
36 |
'httpProto' => 'wp-short-pixel-protocol',
|
37 |
+
'downloadProto' => 'wp-short-pixel-download-protocol',
|
38 |
+
'mediaAlert' => 'wp-short-pixel-media-alert',
|
39 |
'' => '',
|
40 |
);
|
41 |
|
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 > ShortPixel</a> page on how to start optimizing your image library and make your website load faster.
|
6 |
-
* Version: 3.
|
7 |
* Author: ShortPixel
|
8 |
* Author URI: https://shortpixel.com
|
9 |
*/
|
@@ -22,12 +22,13 @@ define('SP_RESET_ON_ACTIVATE', false); //if true TODO set false
|
|
22 |
|
23 |
define('SP_AFFILIATE_CODE', '');
|
24 |
|
25 |
-
define('PLUGIN_VERSION', "3.
|
26 |
define('SP_MAX_TIMEOUT', 10);
|
27 |
define('SP_VALIDATE_MAX_TIMEOUT', 15);
|
28 |
define('SP_BACKUP', 'ShortpixelBackups');
|
29 |
define('SP_BACKUP_FOLDER', WP_CONTENT_DIR . DIRECTORY_SEPARATOR . 'uploads' . DIRECTORY_SEPARATOR . SP_BACKUP);
|
30 |
define('MAX_API_RETRIES', 50);
|
|
|
31 |
$MAX_EXECUTION_TIME = ini_get('max_execution_time');
|
32 |
|
33 |
/*
|
@@ -56,40 +57,54 @@ class WPShortPixel {
|
|
56 |
session_start();
|
57 |
}
|
58 |
|
|
|
|
|
59 |
$this->_affiliateSufix = (strlen(SP_AFFILIATE_CODE)) ? "/affiliate/" . SP_AFFILIATE_CODE : "";
|
60 |
$this->_settings = new WPShortPixelSettings();
|
61 |
$this->_apiInterface = new ShortPixelAPI($this->_settings);
|
62 |
$this->prioQ = new ShortPixelQueue($this, $this->_settings);
|
63 |
$this->view = new ShortPixelView($this);
|
64 |
|
65 |
-
define('QUOTA_EXCEEDED',
|
66 |
-
.$this->_settings->apiKey."' target='_blank'>Extend Quota</a>"
|
67 |
-
."<a class='button button-smaller' href='admin.php?action=shortpixel_check_quota' target='_blank'>Check Quota</a>");
|
68 |
|
69 |
$this->setDefaultViewModeList();//set default mode as list. only @ first run
|
70 |
|
71 |
//add hook for image upload processing
|
72 |
add_filter( 'wp_generate_attachment_metadata', array( &$this, 'handleImageUpload' ), 10, 2 );
|
73 |
-
add_filter( 'manage_media_columns', array( &$this, 'columns' ) );//add media library column header
|
74 |
add_filter( 'plugin_action_links_' . plugin_basename(__FILE__), array(&$this, 'generatePluginLinks'));//for plugin settings page
|
75 |
|
76 |
//add_action( 'admin_footer', array(&$this, 'handleImageProcessing'));
|
|
|
|
|
|
|
77 |
add_action( 'manage_media_custom_column', array( &$this, 'generateCustomColumn' ), 10, 2 );//generate the media library column
|
78 |
|
79 |
-
|
80 |
-
|
81 |
-
|
82 |
-
|
83 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
84 |
|
85 |
//automatic optimization
|
86 |
add_action( 'wp_ajax_shortpixel_image_processing', array( &$this, 'handleImageProcessing') );
|
87 |
//manual optimization
|
88 |
add_action( 'wp_ajax_shortpixel_manual_optimization', array(&$this, 'handleManualOptimization'));
|
89 |
-
//
|
90 |
add_action( 'wp_ajax_shortpixel_dismiss_notice', array(&$this, 'dismissAdminNotice'));
|
91 |
-
|
92 |
-
add_action('admin_action_shortpixel_restore_backup', array(&$this, 'handleRestoreBackup'));
|
93 |
//check quota
|
94 |
add_action('admin_action_shortpixel_check_quota', array(&$this, 'handleCheckQuota'));
|
95 |
|
@@ -97,8 +112,6 @@ class WPShortPixel {
|
|
97 |
add_action( 'admin_footer', array( &$this, 'shortPixelJS') );
|
98 |
//register a method to display admin notices if necessary
|
99 |
add_action('admin_notices', array( &$this, 'displayAdminNotices'));
|
100 |
-
//toolbar notifications
|
101 |
-
add_action( 'admin_bar_menu', array( &$this, 'toolbar_shortpixel_processing'), 999 );
|
102 |
|
103 |
$this->migrateBackupFolder();
|
104 |
}
|
@@ -108,6 +121,14 @@ class WPShortPixel {
|
|
108 |
$this->__construct();
|
109 |
}
|
110 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
111 |
public static function shortPixelActivatePlugin()//reset some params to avoid trouble for plugins that were activated/deactivated/activated
|
112 |
{
|
113 |
self::shortPixelDeactivatePlugin();
|
@@ -150,6 +171,11 @@ class WPShortPixel {
|
|
150 |
die(json_encode(array("Status" => 'success', "Message" => 'Notice ID: ' . $noticeId . ' dismissed')));
|
151 |
}
|
152 |
|
|
|
|
|
|
|
|
|
|
|
153 |
//set default move as "list". only set once, it won't try to set the default mode again.
|
154 |
public function setDefaultViewModeList()
|
155 |
{
|
@@ -192,16 +218,17 @@ class WPShortPixel {
|
|
192 |
STATUS_RETRY: <?php echo ShortPixelAPI::STATUS_RETRY; ?>,
|
193 |
WP_PLUGIN_URL: '<?php echo plugins_url( '', __FILE__ ); ?>',
|
194 |
WP_ADMIN_URL: '<?php echo admin_url(); ?>',
|
195 |
-
API_KEY: "<?php echo $this->_settings->apiKey; ?>"
|
|
|
196 |
});
|
197 |
}
|
198 |
});
|
199 |
</script> <?php
|
200 |
wp_enqueue_style('short-pixel.css', plugins_url('/css/short-pixel.css',__FILE__) );
|
|
|
201 |
}
|
202 |
|
203 |
function toolbar_shortpixel_processing( $wp_admin_bar ) {
|
204 |
-
wp_enqueue_script('short-pixel.js', plugins_url('/js/short-pixel.js',__FILE__) );
|
205 |
|
206 |
$extraClasses = " shortpixel-hide";
|
207 |
$tooltip = "ShortPixel optimizing...";
|
@@ -283,7 +310,8 @@ class WPShortPixel {
|
|
283 |
{//the kind of file we can process. goody.
|
284 |
$this->prioQ->push($ID);
|
285 |
$URLsAndPATHs = $this->getURLsAndPATHs($ID, $meta);
|
286 |
-
|
|
|
287 |
self::log("IMG: sent: " . json_encode($URLsAndPATHs));
|
288 |
$meta['ShortPixel']['WaitingProcessing'] = true;
|
289 |
return $meta;
|
@@ -340,9 +368,26 @@ class WPShortPixel {
|
|
340 |
$crtStartQueryID = $itemMetaData->post_id;
|
341 |
if(!in_array($crtStartQueryID, $idList) && self::isProcessable($crtStartQueryID)) {
|
342 |
$meta = wp_get_attachment_metadata($crtStartQueryID);
|
343 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
344 |
$idList[] = $crtStartQueryID;
|
345 |
-
}
|
|
|
346 |
$skippedAlreadyProcessed++;
|
347 |
}
|
348 |
}
|
@@ -351,8 +396,8 @@ class WPShortPixel {
|
|
351 |
//daca n-am adaugat niciuna pana acum, n-are sens sa mai selectez zona asta de id-uri in bulk-ul asta.
|
352 |
$leapStart = $this->prioQ->getStartBulkId();
|
353 |
$crtStartQueryID = $startQueryID = $itemMetaData->post_id - 1; //decrement it so we don't select it again
|
354 |
-
$res = self::
|
355 |
-
$skippedAlreadyProcessed += $res["
|
356 |
$this->prioQ->setStartBulkId($startQueryID);
|
357 |
} else {
|
358 |
$crtStartQueryID--;
|
@@ -431,14 +476,15 @@ class WPShortPixel {
|
|
431 |
//2: Send up to 3 files to the server for processing
|
432 |
for($i = 0; $i < min(3, count($ids)); $i++) {
|
433 |
$ID = $ids[$i];
|
434 |
-
$
|
|
|
|
|
435 |
if($i == 0) { //save for later use
|
436 |
$firstUrlAndPaths = $URLsAndPATHs;
|
437 |
}
|
438 |
}
|
439 |
|
440 |
self::log("HIP: 2 Prio Queue: ".json_encode($this->prioQ->get()));
|
441 |
-
|
442 |
//3: Retrieve the file for the first element of the list
|
443 |
$ID = $ids[0];
|
444 |
$result = $this->_apiInterface->processImage($firstUrlAndPaths['URLs'], $firstUrlAndPaths['PATHs'], $ID);
|
@@ -453,17 +499,17 @@ class WPShortPixel {
|
|
453 |
//remove also from the failed list if it failed in the past
|
454 |
$prio = $this->prioQ->removeFromFailed($ID);
|
455 |
$meta = wp_get_attachment_metadata($ID);
|
456 |
-
$result["
|
457 |
-
$result["
|
|
|
|
|
|
|
|
|
|
|
458 |
|
459 |
if(!$prio && $ID <= $this->prioQ->getStartBulkId()) {
|
460 |
-
$this->prioQ->setStartBulkId($ID - 1);
|
461 |
-
$this->prioQ->logBulkProgress();
|
462 |
|
463 |
-
$
|
464 |
-
$msg = $this->bulkProgressMessage($deltaBulkPercent, $this->prioQ->getTimeRemaining());
|
465 |
-
$result["BulkPercent"] = $this->prioQ->getBulkPercent();;
|
466 |
-
$result["BulkMsg"] = $msg;
|
467 |
|
468 |
$thumb = $bkThumb = "";
|
469 |
$percent = 0;
|
@@ -480,10 +526,10 @@ class WPShortPixel {
|
|
480 |
$thumb = count($sizes) ? $sizes[0]['file'] : '';
|
481 |
}
|
482 |
} else { //fallback to the image itself
|
483 |
-
$thumb = $
|
484 |
}
|
485 |
|
486 |
-
if(strlen($thumb) &&
|
487 |
$backupUrl = content_url() . "/uploads/" . SP_BACKUP . "/";
|
488 |
$urlBkPath = $this->_apiInterface->returnSubDir(get_attached_file($ID));
|
489 |
$bkThumb = $backupUrl . $urlBkPath . "/" . $thumb;
|
@@ -499,6 +545,23 @@ class WPShortPixel {
|
|
499 |
}
|
500 |
}
|
501 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
502 |
elseif ($result["Status"] == ShortPixelAPI::STATUS_SKIP
|
503 |
|| $result["Status"] == ShortPixelAPI::STATUS_FAIL) {
|
504 |
$prio = $this->prioQ->remove($ID);
|
@@ -506,14 +569,7 @@ class WPShortPixel {
|
|
506 |
//put this one in the failed images list - to show the user at the end
|
507 |
$prio = $this->prioQ->addToFailed($ID);
|
508 |
}
|
509 |
-
|
510 |
-
$this->prioQ->setStartBulkId($ID - 1);
|
511 |
-
$this->prioQ->logBulkProgress();
|
512 |
-
$deltaBulkPercent = $this->prioQ->getDeltaBulkPercent();
|
513 |
-
$msg = $this->bulkProgressMessage($deltaBulkPercent, $this->prioQ->getTimeRemaining());
|
514 |
-
$result["BulkPercent"] = $this->prioQ->getBulkPercent();
|
515 |
-
$result["BulkMsg"] = $msg;
|
516 |
-
}
|
517 |
}
|
518 |
if($result["Status"] !== ShortPixelAPI::STATUS_RETRY) {
|
519 |
update_option( 'wp-short-pixel-bulk-last-status', $result);
|
@@ -521,9 +577,20 @@ class WPShortPixel {
|
|
521 |
die(json_encode($result));
|
522 |
}
|
523 |
|
524 |
-
private function
|
525 |
-
$
|
526 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
527 |
$meta = wp_get_attachment_metadata($ID);
|
528 |
$meta['ShortPixel']['WaitingProcessing'] = true;
|
529 |
wp_update_attachment_metadata($ID, $meta);
|
@@ -531,6 +598,7 @@ class WPShortPixel {
|
|
531 |
}
|
532 |
|
533 |
public function handleManualOptimization() {
|
|
|
534 |
$imageId = intval($_GET['image_id']);
|
535 |
|
536 |
if(self::isProcessable($imageId)) {
|
@@ -551,41 +619,91 @@ class WPShortPixel {
|
|
551 |
wp_update_attachment_metadata($ID, $meta);
|
552 |
}
|
553 |
|
554 |
-
public function
|
555 |
-
$attachmentID = intval($_GET['attachment_ID']);
|
556 |
-
|
557 |
-
$file = get_attached_file($attachmentID);
|
558 |
-
$meta = wp_get_attachment_metadata($attachmentID);
|
559 |
-
$pathInfo = pathinfo($file);
|
560 |
-
|
561 |
$fileExtension = strtolower(substr($file,strrpos($file,".")+1));
|
562 |
$SubDir = $this->_apiInterface->returnSubDir($file);
|
563 |
|
564 |
//sometimes the month of original file and backup can differ
|
565 |
-
if ( !file_exists(SP_BACKUP_FOLDER . DIRECTORY_SEPARATOR . $SubDir . ShortPixelAPI::MB_basename($file)) )
|
566 |
$SubDir = date("Y") . "/" . date("m") . "/";
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
567 |
|
568 |
-
|
569 |
-
|
570 |
-
|
|
|
571 |
|
572 |
-
|
573 |
-
|
574 |
-
foreach($meta["sizes"] as $size => $imageData) {
|
575 |
-
$source = SP_BACKUP_FOLDER . DIRECTORY_SEPARATOR . $SubDir . $imageData['file'];
|
576 |
-
$destination = $pathInfo['dirname'] . DIRECTORY_SEPARATOR . $imageData['file'];
|
577 |
@rename($source, $destination);
|
578 |
}
|
579 |
-
|
580 |
-
|
581 |
-
|
582 |
-
|
583 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
584 |
|
585 |
-
|
586 |
-
|
|
|
|
|
|
|
|
|
587 |
}
|
588 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
589 |
$sendback = wp_get_referer();
|
590 |
// sanitize the referring webpage location
|
591 |
$sendback = preg_replace('|[^a-z0-9-~+_.?#=&;,/:]|i', '', $sendback);
|
@@ -594,6 +712,42 @@ class WPShortPixel {
|
|
594 |
// we are done
|
595 |
}
|
596 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
597 |
public function handleCheckQuota() {
|
598 |
$this->getQuotaInformation();
|
599 |
// store the referring webpage location
|
@@ -634,25 +788,23 @@ class WPShortPixel {
|
|
634 |
}
|
635 |
}
|
636 |
|
637 |
-
public function
|
638 |
-
|
639 |
-
|
640 |
-
|
641 |
-
function registerAdminPage( ) {
|
642 |
-
add_media_page( 'ShortPixel Bulk Process', 'Bulk ShortPixel', 'edit_others_posts', 'wp-short-pixel-bulk', array( &$this, 'bulkProcess' ) );
|
643 |
-
}
|
644 |
-
|
645 |
-
public function checkQuotaAndAlert() {
|
646 |
-
$quotaData = $this->getQuotaInformation();
|
647 |
if ( !$quotaData['APIKeyValid']) {
|
648 |
return $quotaData;
|
649 |
}
|
|
|
650 |
$imageCount = $this->countAllProcessableFiles();
|
651 |
-
|
652 |
-
$
|
653 |
-
|
654 |
-
|
655 |
-
|
|
|
|
|
|
|
656 |
|
657 |
if($quotaData['APICallsQuotaNumeric'] + $quotaData['APICallsQuotaOneTimeNumeric'] > $quotaData['APICallsMadeNumeric'] + $quotaData['APICallsMadeOneTimeNumeric']) {
|
658 |
update_option('wp-short-pixel-quota-exceeded','0');
|
@@ -725,7 +877,6 @@ class WPShortPixel {
|
|
725 |
|
726 |
//image count
|
727 |
//$imageCount = $this->countAllProcessableFiles();
|
728 |
-
//$imgProcessedCount = $this->countAllProcessedFiles();
|
729 |
$imageOnlyThumbs = $quotaData['totalFiles'] - $quotaData['mainFiles'];
|
730 |
$thumbsProcessedCount = $this->_settings->getOpt( 'wp-short-pixel-thumbnail-count', 0);//amount of optimized thumbnails
|
731 |
$under5PercentCount = $this->_settings->getOpt( 'wp-short-pixel-files-under-5-percent', 0);//amount of under 5% optimized imgs.
|
@@ -785,6 +936,10 @@ class WPShortPixel {
|
|
785 |
}
|
786 |
}
|
787 |
|
|
|
|
|
|
|
|
|
788 |
public function renderSettingsMenu() {
|
789 |
if ( !current_user_can( 'manage_options' ) ) {
|
790 |
wp_die('You do not have sufficient permissions to access this page.');
|
@@ -795,9 +950,11 @@ class WPShortPixel {
|
|
795 |
$notice = null;
|
796 |
|
797 |
//by default we try to fetch the API Key from wp-config.php (if defined)
|
798 |
-
if (
|
799 |
{
|
800 |
-
$_POST['
|
|
|
|
|
801 |
$_POST['key'] = SHORTPIXEL_API_KEY;
|
802 |
}
|
803 |
|
@@ -830,7 +987,7 @@ class WPShortPixel {
|
|
830 |
$notice = array("status" => "warn", "msg" => "API Key is valid but your site is not accessible from our servers.
|
831 |
Please make sure that your server is accessible from the Internet before using the API or otherwise we won't be able to optimize them.");
|
832 |
} else {
|
833 |
-
if ( function_exists("is_multisite") && is_multisite() )
|
834 |
$notice = array("status" => "success", "msg" => "API Key valid! <br>You seem to be running a multisite, please note that API Key can also be configured in wp-config.php like this:<BR> <b>define('SHORTPIXEL_API_KEY', '".$this->_settings->apiKey."');</b>");
|
835 |
else
|
836 |
$notice = array("status" => "success", "msg" => 'API Key valid!');
|
@@ -879,7 +1036,7 @@ class WPShortPixel {
|
|
879 |
$this->emptyBackup();
|
880 |
}
|
881 |
|
882 |
-
$quotaData = $this->checkQuotaAndAlert();
|
883 |
|
884 |
if($this->_settings->verifiedKey) {
|
885 |
$fileCount = number_format($this->_settings->fileCount);
|
@@ -893,8 +1050,11 @@ class WPShortPixel {
|
|
893 |
$remainingImages = $quotaData['APICallsQuotaNumeric'] + $quotaData['APICallsQuotaOneTimeNumeric'] - $quotaData['APICallsMadeNumeric'] - $quotaData['APICallsMadeOneTimeNumeric'];
|
894 |
$remainingImages = ( $remainingImages < 0 ) ? 0 : number_format($remainingImages);
|
895 |
$totalCallsMade = number_format($quotaData['APICallsMadeNumeric'] + $quotaData['APICallsMadeOneTimeNumeric']);
|
896 |
-
|
897 |
$resources = wp_remote_get($this->_settings->httpProto . "://shortpixel.com/resources-frag");
|
|
|
|
|
|
|
898 |
$this->view->displaySettings(is_main_site() || (is_multisite() && !defined("SHORTPIXEL_API_KEY")),
|
899 |
$quotaData, $notice, $resources, $averageCompression, $savedSpace, $savedBandwidth,
|
900 |
$remainingImages, $totalCallsMade, $fileCount, $backupFolderSize);
|
@@ -922,12 +1082,13 @@ class WPShortPixel {
|
|
922 |
|
923 |
if(is_null($apiKey)) { $apiKey = $this->_settings->apiKey; }
|
924 |
|
925 |
-
|
|
|
|
|
926 |
|
927 |
$requestURL = $this->_settings->httpProto . '://api.shortpixel.com/v2/api-status.php';
|
928 |
$args = array(
|
929 |
'timeout'=> SP_VALIDATE_MAX_TIMEOUT,
|
930 |
-
'sslverify' => false,
|
931 |
'body' => array('key' => $apiKey)
|
932 |
);
|
933 |
$argsStr = "?key=".$apiKey;
|
@@ -944,28 +1105,47 @@ class WPShortPixel {
|
|
944 |
$argsStr .= "&DomainCheck={$args['body']['DomainCheck']}&ImagesCount={$imageCount['mainFiles']}&ThumbsCount={$args['body']['ThumbsCount']}";
|
945 |
}
|
946 |
|
947 |
-
|
|
|
|
|
|
|
|
|
|
|
948 |
$response = wp_remote_post($requestURL, $args);
|
|
|
|
|
949 |
//some hosting providers won't allow https:// POST connections so we try http:// as well
|
950 |
if(is_wp_error( $response )) {
|
951 |
//echo("protocol " . $this->_settings->httpProto . " failed. switching...");
|
952 |
$requestURL = $this->_settings->httpProto == 'https' ?
|
953 |
str_replace('https://', 'http://', $requestURL) :
|
954 |
str_replace('http://', 'https://', $requestURL);
|
955 |
-
|
956 |
-
|
957 |
-
|
958 |
-
|
959 |
-
|
960 |
-
|
961 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
962 |
}
|
963 |
//Second fallback to HTTP get
|
964 |
if(is_wp_error( $response )){
|
965 |
$args['body'] = null;
|
966 |
$requestURL .= $argsStr;
|
967 |
$response = wp_remote_get($requestURL, $args);
|
|
|
968 |
}
|
|
|
|
|
|
|
969 |
$defaultData = array(
|
970 |
"APIKeyValid" => false,
|
971 |
"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 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. ',
|
@@ -977,9 +1157,9 @@ class WPShortPixel {
|
|
977 |
|
978 |
$urlElements = parse_url($requestURL);
|
979 |
$portConnect = @fsockopen($urlElements['host'],8,$errno,$errstr,15);
|
980 |
-
if(!$portConnect)
|
981 |
$defaultData['Message'] .= "<BR>Debug info: <i>$errstr</i>";
|
982 |
-
|
983 |
return $defaultData;
|
984 |
}
|
985 |
|
@@ -1029,141 +1209,87 @@ class WPShortPixel {
|
|
1029 |
$data = wp_get_attachment_metadata($id);
|
1030 |
$file = get_attached_file($id);
|
1031 |
$fileExtension = strtolower(substr($file,strrpos($file,".")+1));
|
|
|
|
|
|
|
1032 |
|
1033 |
-
|
1034 |
|
1035 |
-
|
1036 |
-
{
|
1037 |
-
|
1038 |
-
|
1039 |
-
|
1040 |
-
print 'Invalid API Key. <a href="options-general.php?page=wp-shortpixel">Check your Settings</a>';
|
1041 |
-
else
|
1042 |
-
print 'Optimization N/A';
|
1043 |
-
}
|
1044 |
-
else
|
1045 |
-
{
|
1046 |
-
if ( $this->_settings->quotaExceeded )
|
1047 |
-
{
|
1048 |
-
print QUOTA_EXCEEDED;
|
1049 |
-
return;
|
1050 |
-
}
|
1051 |
-
else
|
1052 |
-
{
|
1053 |
-
print 'PDF not processed';
|
1054 |
-
//if($this->_settings->verifiedKey) {
|
1055 |
-
print " <a class='button button-smaller button-primary' href=\"javascript:manualOptimization({$id})\">Optimize now</a>";
|
1056 |
-
//}
|
1057 |
-
return;
|
1058 |
-
}
|
1059 |
-
}
|
1060 |
}
|
1061 |
-
|
1062 |
-
|
1063 |
-
|
1064 |
-
{
|
1065 |
-
|
1066 |
-
|
1067 |
-
|
1068 |
-
|
1069 |
-
|
1070 |
-
{
|
1071 |
-
print 'Waiting for bulk processing';
|
1072 |
-
print " <a class='button button-smaller button-primary' href=\"javascript:manualOptimization({$id})\">Optimize now</a>";
|
1073 |
-
}
|
1074 |
-
}
|
1075 |
-
elseif( is_numeric($data['ShortPixelImprovement']) ) {
|
1076 |
-
if ( $data['ShortPixelImprovement'] < 5 ) {
|
1077 |
-
if($data['ShortPixelImprovement'] > 0 ) {
|
1078 |
-
print $data['ShortPixelImprovement'] . '% optimized<br>';
|
1079 |
-
}
|
1080 |
-
print "Bonus processing";
|
1081 |
-
} else {
|
1082 |
-
print 'Reduced by ';
|
1083 |
-
print $data['ShortPixelImprovement'] . '%' . (isset($data['ShortPixel']['type']) ? ' (' . $data['ShortPixel']['type'] . ')' : '' );
|
1084 |
-
}
|
1085 |
-
if ( get_option('wp-short-backup_images') && !isset($data['ShortPixel']['NoBackup'])) //display restore backup option only when backup is active
|
1086 |
-
print " <a class='button button-smaller' href=\"admin.php?action=shortpixel_restore_backup&attachment_ID={$id}\">Restore backup</a>";
|
1087 |
-
if (isset($data['ShortPixel']['thumbs']) || (isset($data['sizes']) && count($data['sizes']))) {
|
1088 |
-
$sizes = count($data['sizes']);
|
1089 |
-
$cnt = isset($data['ShortPixel']['thumbsOpt']) ? $data['ShortPixel']['thumbsOpt'] : $sizes;
|
1090 |
-
print "<br>+" . $cnt . ($sizes > $cnt ? " of ".$sizes : '') . " thumbnails optimized";
|
1091 |
-
}
|
1092 |
-
}
|
1093 |
-
elseif ( $data['ShortPixelImprovement'] <> "Optimization N/A" )
|
1094 |
-
{
|
1095 |
-
if ( trim(strip_tags($data['ShortPixelImprovement'])) == "Quota exceeded" )
|
1096 |
-
{
|
1097 |
-
print QUOTA_EXCEEDED;
|
1098 |
-
if ( !$this->_settings->quotaExceeded )
|
1099 |
-
print " <a class='button button-smaller button-primary' href=\"javascript:manualOptimization({$id})\">Try again</a>";
|
1100 |
-
}
|
1101 |
-
elseif ( trim(strip_tags($data['ShortPixelImprovement'])) == "Cannot write optimized file" )
|
1102 |
-
{
|
1103 |
-
print $data['ShortPixelImprovement'];
|
1104 |
-
print " - <a href='https://shortpixel.com/faq#cannot-write-optimized-file' target='_blank'>Why?</a>";
|
1105 |
-
}
|
1106 |
-
else
|
1107 |
-
{
|
1108 |
-
print $data['ShortPixelImprovement'];
|
1109 |
-
print " | <a href=\"javascript:manualOptimization({$id})\">Try again</a>";
|
1110 |
-
}
|
1111 |
-
}
|
1112 |
-
else
|
1113 |
-
{
|
1114 |
-
print "Optimization N/A";
|
1115 |
-
}
|
1116 |
-
} elseif(isset($data['ShortPixel']['WaitingProcessing'])) {
|
1117 |
-
if ( $this->_settings->quotaExceeded )
|
1118 |
-
{
|
1119 |
-
print QUOTA_EXCEEDED;
|
1120 |
}
|
1121 |
-
|
1122 |
-
|
1123 |
-
|
1124 |
-
| <a href=\"javascript:manualOptimization({$id})\">Retry</a></div>";
|
1125 |
-
if($id > $this->prioQ->getFlagBulkId()) $this->prioQ->push($id); //should be there but just to make sure
|
1126 |
-
}
|
1127 |
-
|
1128 |
-
} elseif(isset($data['ShortPixel']['NoFileOnDisk'])) {
|
1129 |
-
print 'Image does not exist';
|
1130 |
-
|
1131 |
-
} else {
|
1132 |
|
1133 |
-
|
1134 |
-
|
1135 |
-
|
1136 |
-
|
1137 |
-
|
1138 |
-
|
1139 |
-
|
1140 |
-
|
1141 |
-
|
1142 |
-
|
1143 |
-
|
1144 |
-
|
1145 |
-
|
1146 |
-
|
1147 |
-
|
1148 |
-
|
1149 |
-
|
1150 |
-
|
1151 |
-
|
1152 |
-
|
1153 |
-
|
1154 |
-
|
1155 |
-
|
1156 |
-
|
1157 |
-
|
1158 |
-
|
1159 |
-
|
|
|
|
|
1160 |
}
|
1161 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1162 |
}
|
1163 |
}
|
1164 |
|
1165 |
public function columns( $defaults ) {
|
1166 |
-
$defaults['wp-shortPixel'] = 'ShortPixel Compression
|
|
|
|
|
|
|
1167 |
return $defaults;
|
1168 |
}
|
1169 |
|
@@ -1213,25 +1339,25 @@ class WPShortPixel {
|
|
1213 |
|
1214 |
|
1215 |
//return an array with URL(s) and PATH(s) for this file
|
1216 |
-
public function getURLsAndPATHs($ID, $meta = NULL) {
|
1217 |
|
1218 |
-
if ( !parse_url(WP_CONTENT_URL, PHP_URL_SCHEME) )
|
1219 |
-
{//no absolute URLs used -> we implement a hack
|
1220 |
$url = get_site_url() . wp_get_attachment_url($ID);//get the file URL
|
1221 |
}
|
1222 |
-
else
|
1223 |
$url = wp_get_attachment_url($ID);//get the file URL
|
1224 |
-
|
1225 |
$urlList[] = $url;
|
1226 |
$path = get_attached_file($ID);//get the full file PATH
|
1227 |
$filePath[] = $path;
|
|
|
1228 |
if ( $meta == NULL ) {
|
1229 |
$meta = wp_get_attachment_metadata($ID);
|
1230 |
}
|
1231 |
|
1232 |
//it is NOT a PDF file and thumbs are processable
|
1233 |
if ( strtolower(substr($filePath[0],strrpos($filePath[0], ".")+1)) != "pdf"
|
1234 |
-
&& $this->_settings->processThumbnails
|
1235 |
&& isset($meta['sizes']) && is_array($meta['sizes']))
|
1236 |
{
|
1237 |
foreach( $meta['sizes'] as $thumbnailInfo )
|
@@ -1243,6 +1369,11 @@ class WPShortPixel {
|
|
1243 |
if(!isset($meta['sizes']) || !is_array($meta['sizes'])) {
|
1244 |
self::log("getURLsAndPATHs: no meta sizes for ID $ID : " . json_encode($meta));
|
1245 |
}
|
|
|
|
|
|
|
|
|
|
|
1246 |
return array("URLs" => $urlList, "PATHs" => $filePath);
|
1247 |
}
|
1248 |
|
@@ -1302,40 +1433,74 @@ class WPShortPixel {
|
|
1302 |
return $resultQuery[0]->QueryID;
|
1303 |
}
|
1304 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1305 |
//count all the processable files in media library (while limiting the results to max 10000)
|
1306 |
public function countAllProcessableFiles($maxId = PHP_INT_MAX, $minId = 0){
|
1307 |
global $wpdb;
|
1308 |
|
1309 |
-
$totalFiles =
|
1310 |
-
$
|
1311 |
-
$
|
|
|
1312 |
$pointer = 0;
|
1313 |
-
|
1314 |
-
|
1315 |
-
$query_images_args = array(
|
1316 |
-
'post_type' => 'attachment',
|
1317 |
-
'post_mime_type' => array('image','application/pdf'),
|
1318 |
-
'post_status' => 'inherit',
|
1319 |
-
'posts_per_page' => - 1,
|
1320 |
-
);
|
1321 |
-
|
1322 |
-
$query_images = new WP_Query( $query_images_args );
|
1323 |
-
|
1324 |
-
//var_dump(count($query_images->posts));
|
1325 |
-
|
1326 |
-
|
1327 |
-
|
1328 |
//count all the files, main and thumbs
|
1329 |
-
while ( 1 )
|
1330 |
-
|
1331 |
-
$filesList= $wpdb->get_results("SELECT
|
1332 |
-
|
1333 |
-
|
|
|
1334 |
LIMIT $pointer,$limit");
|
1335 |
if ( empty($filesList) ) //we parsed all the results
|
1336 |
break;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1337 |
|
1338 |
-
$filesMap = array();
|
1339 |
foreach ( $filesList as $file )
|
1340 |
{
|
1341 |
if ( $file->meta_key == "_wp_attached_file" )
|
@@ -1348,10 +1513,13 @@ class WPShortPixel {
|
|
1348 |
$filesMap[$file->meta_value] = 1;
|
1349 |
}
|
1350 |
}
|
1351 |
-
else
|
1352 |
{
|
1353 |
$attachment = unserialize($file->meta_value);
|
|
|
|
|
1354 |
if(isset($attachment['file']) && !isset($filesMap[$attachment['file']]) && self::isProcessablePath($attachment['file'])){
|
|
|
1355 |
if ( isset($attachment['sizes']) ) {
|
1356 |
$totalFiles += count($attachment['sizes']);
|
1357 |
}
|
@@ -1362,53 +1530,54 @@ class WPShortPixel {
|
|
1362 |
$filesMap[$attachment['file']] = 1;
|
1363 |
}
|
1364 |
}
|
1365 |
-
|
1366 |
-
|
1367 |
-
|
1368 |
-
|
1369 |
-
|
1370 |
-
|
1371 |
-
|
1372 |
-
|
1373 |
-
|
1374 |
-
|
1375 |
-
|
1376 |
-
|
1377 |
-
|
1378 |
-
|
1379 |
-
|
1380 |
-
|
1381 |
-
|
1382 |
-
|
1383 |
-
|
1384 |
-
|
1385 |
-
|
1386 |
-
|
1387 |
-
|
1388 |
-
|
1389 |
-
|
1390 |
-
|
1391 |
-
|
1392 |
-
|
1393 |
-
|
1394 |
-
|
1395 |
-
|
1396 |
-
|
1397 |
-
|
1398 |
-
|
1399 |
-
|
1400 |
-
|
1401 |
-
|
1402 |
-
|
1403 |
-
|
1404 |
-
|
1405 |
-
|
1406 |
-
} elseif ( isset($attachment['sizes']) ) {
|
1407 |
-
$processedTotalFiles += count($attachment['sizes']);
|
1408 |
}
|
1409 |
-
|
1410 |
-
$
|
|
|
|
|
1411 |
}
|
|
|
1412 |
}
|
1413 |
}
|
1414 |
unset($filesList);
|
@@ -1416,7 +1585,13 @@ class WPShortPixel {
|
|
1416 |
|
1417 |
}//end while
|
1418 |
|
1419 |
-
return array("totalFiles" => $
|
|
|
|
|
|
|
|
|
|
|
|
|
1420 |
}
|
1421 |
|
1422 |
public function migrateBackupFolder() {
|
@@ -1462,6 +1637,21 @@ class WPShortPixel {
|
|
1462 |
}
|
1463 |
return array('width' => $width, 'height' => $height);
|
1464 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1465 |
|
1466 |
public function getApiKey() {
|
1467 |
return $this->_settings->apiKey;
|
@@ -1512,7 +1702,7 @@ class WPShortPixel {
|
|
1512 |
}
|
1513 |
|
1514 |
function onInit() {
|
1515 |
-
if ( ! is_admin() || !is_user_logged_in() || ! current_user_can( 'manage_options' ) ) {
|
1516 |
return;
|
1517 |
}
|
1518 |
$pluginInstance = new WPShortPixel;
|
@@ -1526,8 +1716,4 @@ if ( !function_exists( 'vc_action' ) || vc_action() !== 'vc_inline' ) { //handle
|
|
1526 |
register_deactivation_hook( __FILE__, array( 'WPShortPixel', 'shortPixelDeactivatePlugin' ) );
|
1527 |
|
1528 |
}
|
1529 |
-
|
1530 |
-
//$pluginInstance = new WPShortPixel();
|
1531 |
-
//global $pluginInstance;
|
1532 |
-
|
1533 |
?>
|
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 > ShortPixel</a> page on how to start optimizing your image library and make your website load faster.
|
6 |
+
* Version: 3.3.0
|
7 |
* Author: ShortPixel
|
8 |
* Author URI: https://shortpixel.com
|
9 |
*/
|
22 |
|
23 |
define('SP_AFFILIATE_CODE', '');
|
24 |
|
25 |
+
define('PLUGIN_VERSION', "3.3.0");
|
26 |
define('SP_MAX_TIMEOUT', 10);
|
27 |
define('SP_VALIDATE_MAX_TIMEOUT', 15);
|
28 |
define('SP_BACKUP', 'ShortpixelBackups');
|
29 |
define('SP_BACKUP_FOLDER', WP_CONTENT_DIR . DIRECTORY_SEPARATOR . 'uploads' . DIRECTORY_SEPARATOR . SP_BACKUP);
|
30 |
define('MAX_API_RETRIES', 50);
|
31 |
+
define('MAX_ERR_RETRIES', 5);
|
32 |
$MAX_EXECUTION_TIME = ini_get('max_execution_time');
|
33 |
|
34 |
/*
|
57 |
session_start();
|
58 |
}
|
59 |
|
60 |
+
$isAdminUser = current_user_can( 'manage_options' );
|
61 |
+
|
62 |
$this->_affiliateSufix = (strlen(SP_AFFILIATE_CODE)) ? "/affiliate/" . SP_AFFILIATE_CODE : "";
|
63 |
$this->_settings = new WPShortPixelSettings();
|
64 |
$this->_apiInterface = new ShortPixelAPI($this->_settings);
|
65 |
$this->prioQ = new ShortPixelQueue($this, $this->_settings);
|
66 |
$this->view = new ShortPixelView($this);
|
67 |
|
68 |
+
define('QUOTA_EXCEEDED', $this->view->getQuotaExceededHTML());
|
|
|
|
|
69 |
|
70 |
$this->setDefaultViewModeList();//set default mode as list. only @ first run
|
71 |
|
72 |
//add hook for image upload processing
|
73 |
add_filter( 'wp_generate_attachment_metadata', array( &$this, 'handleImageUpload' ), 10, 2 );
|
|
|
74 |
add_filter( 'plugin_action_links_' . plugin_basename(__FILE__), array(&$this, 'generatePluginLinks'));//for plugin settings page
|
75 |
|
76 |
//add_action( 'admin_footer', array(&$this, 'handleImageProcessing'));
|
77 |
+
|
78 |
+
//Media custom column
|
79 |
+
add_filter( 'manage_media_columns', array( &$this, 'columns' ) );//add media library column header
|
80 |
add_action( 'manage_media_custom_column', array( &$this, 'generateCustomColumn' ), 10, 2 );//generate the media library column
|
81 |
|
82 |
+
if($isAdminUser) {
|
83 |
+
//add settings page
|
84 |
+
add_action( 'admin_menu', array( &$this, 'registerSettingsPage' ) );//display SP in Settings menu
|
85 |
+
add_action( 'admin_menu', array( &$this, 'registerAdminPage' ) );
|
86 |
+
|
87 |
+
add_action( 'delete_attachment', array( &$this, 'handleDeleteAttachmentInBackup' ) );
|
88 |
+
add_action( 'load-upload.php', array( &$this, 'handleCustomBulk'));
|
89 |
+
|
90 |
+
//backup restore
|
91 |
+
add_action('admin_action_shortpixel_restore_backup', array(&$this, 'handleRestoreBackup'));
|
92 |
+
//reoptimize with a different algorithm (losless/lossy)
|
93 |
+
add_action('wp_ajax_shortpixel_redo', array(&$this, 'handleRedo'));
|
94 |
+
//optimize thumbnails
|
95 |
+
add_action('wp_ajax_shortpixel_optimize_thumbs', array(&$this, 'handleOptimizeThumbs'));
|
96 |
+
|
97 |
+
//toolbar notifications
|
98 |
+
add_action( 'admin_bar_menu', array( &$this, 'toolbar_shortpixel_processing'), 999 );
|
99 |
+
}
|
100 |
|
101 |
//automatic optimization
|
102 |
add_action( 'wp_ajax_shortpixel_image_processing', array( &$this, 'handleImageProcessing') );
|
103 |
//manual optimization
|
104 |
add_action( 'wp_ajax_shortpixel_manual_optimization', array(&$this, 'handleManualOptimization'));
|
105 |
+
//dismiss notices
|
106 |
add_action( 'wp_ajax_shortpixel_dismiss_notice', array(&$this, 'dismissAdminNotice'));
|
107 |
+
add_action( 'wp_ajax_shortpixel_dismiss_media_alert', array(&$this, 'dismissMediaAlert'));
|
|
|
108 |
//check quota
|
109 |
add_action('admin_action_shortpixel_check_quota', array(&$this, 'handleCheckQuota'));
|
110 |
|
112 |
add_action( 'admin_footer', array( &$this, 'shortPixelJS') );
|
113 |
//register a method to display admin notices if necessary
|
114 |
add_action('admin_notices', array( &$this, 'displayAdminNotices'));
|
|
|
|
|
115 |
|
116 |
$this->migrateBackupFolder();
|
117 |
}
|
121 |
$this->__construct();
|
122 |
}
|
123 |
|
124 |
+
public function registerSettingsPage() {
|
125 |
+
add_options_page( 'ShortPixel Settings', 'ShortPixel', 'manage_options', 'wp-shortpixel', array($this, 'renderSettingsMenu'));
|
126 |
+
}
|
127 |
+
|
128 |
+
function registerAdminPage( ) {
|
129 |
+
add_media_page( 'ShortPixel Bulk Process', 'Bulk ShortPixel', 'edit_others_posts', 'wp-short-pixel-bulk', array( &$this, 'bulkProcess' ) );
|
130 |
+
}
|
131 |
+
|
132 |
public static function shortPixelActivatePlugin()//reset some params to avoid trouble for plugins that were activated/deactivated/activated
|
133 |
{
|
134 |
self::shortPixelDeactivatePlugin();
|
171 |
die(json_encode(array("Status" => 'success', "Message" => 'Notice ID: ' . $noticeId . ' dismissed')));
|
172 |
}
|
173 |
|
174 |
+
public function dismissMediaAlert() {
|
175 |
+
$this->_settings->mediaAlert = 1;
|
176 |
+
die(json_encode(array("Status" => 'success', "Message" => 'Media alert dismissed')));
|
177 |
+
}
|
178 |
+
|
179 |
//set default move as "list". only set once, it won't try to set the default mode again.
|
180 |
public function setDefaultViewModeList()
|
181 |
{
|
218 |
STATUS_RETRY: <?php echo ShortPixelAPI::STATUS_RETRY; ?>,
|
219 |
WP_PLUGIN_URL: '<?php echo plugins_url( '', __FILE__ ); ?>',
|
220 |
WP_ADMIN_URL: '<?php echo admin_url(); ?>',
|
221 |
+
API_KEY: "<?php echo $this->_settings->apiKey; ?>",
|
222 |
+
MEDIA_ALERT: '<?php echo $this->_settings->mediaAlert ? "done" : "todo"; ?>'
|
223 |
});
|
224 |
}
|
225 |
});
|
226 |
</script> <?php
|
227 |
wp_enqueue_style('short-pixel.css', plugins_url('/css/short-pixel.css',__FILE__) );
|
228 |
+
wp_enqueue_script('short-pixel.js', plugins_url('/js/short-pixel.js',__FILE__) );
|
229 |
}
|
230 |
|
231 |
function toolbar_shortpixel_processing( $wp_admin_bar ) {
|
|
|
232 |
|
233 |
$extraClasses = " shortpixel-hide";
|
234 |
$tooltip = "ShortPixel optimizing...";
|
310 |
{//the kind of file we can process. goody.
|
311 |
$this->prioQ->push($ID);
|
312 |
$URLsAndPATHs = $this->getURLsAndPATHs($ID, $meta);
|
313 |
+
//send a processing request right after a file was uploaded, do NOT wait for response
|
314 |
+
$this->_apiInterface->doRequests($URLsAndPATHs['URLs'], false, $ID);
|
315 |
self::log("IMG: sent: " . json_encode($URLsAndPATHs));
|
316 |
$meta['ShortPixel']['WaitingProcessing'] = true;
|
317 |
return $meta;
|
368 |
$crtStartQueryID = $itemMetaData->post_id;
|
369 |
if(!in_array($crtStartQueryID, $idList) && self::isProcessable($crtStartQueryID)) {
|
370 |
$meta = wp_get_attachment_metadata($crtStartQueryID);
|
371 |
+
$compression = ShortPixelAPI::getCompressionTypeName($this->_settings->compressionType);
|
372 |
+
|
373 |
+
if(! isset($meta["ShortPixelImprovement"]) || !is_numeric($meta["ShortPixelImprovement"])) {
|
374 |
+
$idList[] = $crtStartQueryID;
|
375 |
+
}
|
376 |
+
elseif(isset($meta["ShortPixel"]["type"]) && $meta["ShortPixel"]["type"] != $compression) {//a different type of compression was chosen in settings
|
377 |
+
if($this->doRestore($crtStartQueryID, $meta)) {
|
378 |
+
$idList[] = $crtStartQueryID;
|
379 |
+
} else {
|
380 |
+
$skippedAlreadyProcessed++;
|
381 |
+
}
|
382 |
+
}
|
383 |
+
elseif( $this->_settings->processThumbnails && isset($meta["ShortPixel"]["thumbsOpt"]) && $meta["ShortPixel"]["thumbsOpt"] == 0
|
384 |
+
&& isset($meta["sizes"]) && count($meta["sizes"]) > 0) { //thumbs were chosen in settings
|
385 |
+
//if($crtStartQueryID == 44 || $crtStartQueryID == 49) {echo("No THuMBS?");die(var_dump($meta));}
|
386 |
+
$meta["ShortPixel"]["thumbsTodo"] = true;
|
387 |
+
wp_update_attachment_metadata($crtStartQueryID, $meta);
|
388 |
$idList[] = $crtStartQueryID;
|
389 |
+
}
|
390 |
+
elseif($itemMetaData->meta_key == '_wp_attachment_metadata') { //count skipped
|
391 |
$skippedAlreadyProcessed++;
|
392 |
}
|
393 |
}
|
396 |
//daca n-am adaugat niciuna pana acum, n-are sens sa mai selectez zona asta de id-uri in bulk-ul asta.
|
397 |
$leapStart = $this->prioQ->getStartBulkId();
|
398 |
$crtStartQueryID = $startQueryID = $itemMetaData->post_id - 1; //decrement it so we don't select it again
|
399 |
+
$res = self::countAllProcessableFiles($leapStart, $crtStartQueryID);
|
400 |
+
$skippedAlreadyProcessed += $res["mainProcessedFiles"] - $res["mainProc".($this->getCompressionType() == 1 ? "Lossy" : "Lossless")."Files"];
|
401 |
$this->prioQ->setStartBulkId($startQueryID);
|
402 |
} else {
|
403 |
$crtStartQueryID--;
|
476 |
//2: Send up to 3 files to the server for processing
|
477 |
for($i = 0; $i < min(3, count($ids)); $i++) {
|
478 |
$ID = $ids[$i];
|
479 |
+
$tmpMeta = wp_get_attachment_metadata($ID);
|
480 |
+
$compType = (isset($tmpMeta['ShortPixel']['type']) ? ($tmpMeta['ShortPixel']['type'] == 'lossy' ? 1 : 0) : $this->_settings->compressionType);
|
481 |
+
$URLsAndPATHs = $this->sendToProcessing($ID, $compType, isset($tmpMeta['ShortPixel']['thumbsTodo']));
|
482 |
if($i == 0) { //save for later use
|
483 |
$firstUrlAndPaths = $URLsAndPATHs;
|
484 |
}
|
485 |
}
|
486 |
|
487 |
self::log("HIP: 2 Prio Queue: ".json_encode($this->prioQ->get()));
|
|
|
488 |
//3: Retrieve the file for the first element of the list
|
489 |
$ID = $ids[0];
|
490 |
$result = $this->_apiInterface->processImage($firstUrlAndPaths['URLs'], $firstUrlAndPaths['PATHs'], $ID);
|
499 |
//remove also from the failed list if it failed in the past
|
500 |
$prio = $this->prioQ->removeFromFailed($ID);
|
501 |
$meta = wp_get_attachment_metadata($ID);
|
502 |
+
$result["Type"] = isset($meta['ShortPixel']['type']) ? $meta['ShortPixel']['type'] : '';
|
503 |
+
$result["ThumbsTotal"] = isset($meta['sizes']) && is_array($meta['sizes']) ? count($meta['sizes']): 0;
|
504 |
+
$result["ThumbsCount"] = isset($meta['ShortPixel']['thumbsOpt'])
|
505 |
+
? $meta['ShortPixel']['thumbsOpt'] //below is the fallback for old optimized images that don't have thumbsOpt
|
506 |
+
: ($this->_settings->processThumbnails ? $result["ThumbsTotal"] : 0);
|
507 |
+
|
508 |
+
$result["BackupEnabled"] = ($this->getBackupFolder(get_attached_file($ID)) ? true : false);//$this->_settings->backupImages;
|
509 |
|
510 |
if(!$prio && $ID <= $this->prioQ->getStartBulkId()) {
|
|
|
|
|
511 |
|
512 |
+
$this->advanceBulk($ID, $result);
|
|
|
|
|
|
|
513 |
|
514 |
$thumb = $bkThumb = "";
|
515 |
$percent = 0;
|
526 |
$thumb = count($sizes) ? $sizes[0]['file'] : '';
|
527 |
}
|
528 |
} else { //fallback to the image itself
|
529 |
+
$thumb = is_array($filePath) ? $filePath[count($filePath) - 1] : $filePath;
|
530 |
}
|
531 |
|
532 |
+
if(strlen($thumb) && $this->_settings->backupImages && $this->_settings->processThumbnails) {
|
533 |
$backupUrl = content_url() . "/uploads/" . SP_BACKUP . "/";
|
534 |
$urlBkPath = $this->_apiInterface->returnSubDir(get_attached_file($ID));
|
535 |
$bkThumb = $backupUrl . $urlBkPath . "/" . $thumb;
|
545 |
}
|
546 |
}
|
547 |
}
|
548 |
+
elseif ($result["Status"] == ShortPixelAPI::STATUS_ERROR) {
|
549 |
+
$meta = wp_get_attachment_metadata($ID);
|
550 |
+
if(isset($meta['ShortPixel']['Retries']) && $meta['ShortPixel']['Retries'] > MAX_ERR_RETRIES) {
|
551 |
+
if(! $this->prioQ->remove($ID) ){
|
552 |
+
$this->advanceBulk($ID, $result);
|
553 |
+
}
|
554 |
+
unset($meta['ShortPixel']);
|
555 |
+
wp_update_attachment_metadata($ID, $meta);
|
556 |
+
$result["Status"] = ShortPixelAPI::STATUS_SKIP;
|
557 |
+
$result["Message"] .= " Retry limit reached. Skipping file ID " . $ID . ".";
|
558 |
+
}
|
559 |
+
else {
|
560 |
+
if(!isset($meta['ShortPixel'])) { $meta['ShortPixel'] = array(); }
|
561 |
+
$meta['ShortPixel']['Retries'] = isset($meta['ShortPixel']['Retries']) ? $meta['ShortPixel']['Retries'] + 1 : 1;
|
562 |
+
wp_update_attachment_metadata($ID, $meta);
|
563 |
+
}
|
564 |
+
}
|
565 |
elseif ($result["Status"] == ShortPixelAPI::STATUS_SKIP
|
566 |
|| $result["Status"] == ShortPixelAPI::STATUS_FAIL) {
|
567 |
$prio = $this->prioQ->remove($ID);
|
569 |
//put this one in the failed images list - to show the user at the end
|
570 |
$prio = $this->prioQ->addToFailed($ID);
|
571 |
}
|
572 |
+
$this->advanceBulk($ID, $result);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
573 |
}
|
574 |
if($result["Status"] !== ShortPixelAPI::STATUS_RETRY) {
|
575 |
update_option( 'wp-short-pixel-bulk-last-status', $result);
|
577 |
die(json_encode($result));
|
578 |
}
|
579 |
|
580 |
+
private function advanceBulk($processedID, &$result) {
|
581 |
+
if($processedID <= $this->prioQ->getStartBulkId()) {
|
582 |
+
$this->prioQ->setStartBulkId($processedID - 1);
|
583 |
+
$this->prioQ->logBulkProgress();
|
584 |
+
$deltaBulkPercent = $this->prioQ->getDeltaBulkPercent();
|
585 |
+
$msg = $this->bulkProgressMessage($deltaBulkPercent, $this->prioQ->getTimeRemaining());
|
586 |
+
$result["BulkPercent"] = $this->prioQ->getBulkPercent();
|
587 |
+
$result["BulkMsg"] = $msg;
|
588 |
+
}
|
589 |
+
}
|
590 |
+
|
591 |
+
private function sendToProcessing($ID, $compressionType = false, $onlyThumbs = false) {
|
592 |
+
$URLsAndPATHs = $this->getURLsAndPATHs($ID, NULL, $onlyThumbs);
|
593 |
+
$this->_apiInterface->doRequests($URLsAndPATHs['URLs'], false, $ID, $compressionType === false ? $this->_settings->compressionType : $compressionType);//send a request, do NOT wait for response
|
594 |
$meta = wp_get_attachment_metadata($ID);
|
595 |
$meta['ShortPixel']['WaitingProcessing'] = true;
|
596 |
wp_update_attachment_metadata($ID, $meta);
|
598 |
}
|
599 |
|
600 |
public function handleManualOptimization() {
|
601 |
+
|
602 |
$imageId = intval($_GET['image_id']);
|
603 |
|
604 |
if(self::isProcessable($imageId)) {
|
619 |
wp_update_attachment_metadata($ID, $meta);
|
620 |
}
|
621 |
|
622 |
+
public function getBackupFolder($file) {
|
|
|
|
|
|
|
|
|
|
|
|
|
623 |
$fileExtension = strtolower(substr($file,strrpos($file,".")+1));
|
624 |
$SubDir = $this->_apiInterface->returnSubDir($file);
|
625 |
|
626 |
//sometimes the month of original file and backup can differ
|
627 |
+
if ( !file_exists(SP_BACKUP_FOLDER . DIRECTORY_SEPARATOR . $SubDir . ShortPixelAPI::MB_basename($file)) ) {
|
628 |
$SubDir = date("Y") . "/" . date("m") . "/";
|
629 |
+
if( !file_exists(SP_BACKUP_FOLDER . DIRECTORY_SEPARATOR . $SubDir . ShortPixelAPI::MB_basename($file)) ) {
|
630 |
+
return false;
|
631 |
+
}
|
632 |
+
}
|
633 |
+
return SP_BACKUP_FOLDER . DIRECTORY_SEPARATOR . $SubDir;
|
634 |
+
}
|
635 |
+
|
636 |
+
protected function setFilePerms($file) {
|
637 |
+
//die(getenv('USERNAME') ? getenv('USERNAME') : getenv('USER'));
|
638 |
+
$perms = @fileperms($file);
|
639 |
+
if(!($perms & 0x0100) || !($perms & 0x0080)) {
|
640 |
+
if(!@chmod($file, $perms | 0x0100 | 0x0080)) {
|
641 |
+
return false;
|
642 |
+
}
|
643 |
+
}
|
644 |
+
return true;
|
645 |
+
}
|
646 |
+
|
647 |
+
protected function doRestore($attachmentID, $meta = null) {
|
648 |
+
$file = get_attached_file($attachmentID);
|
649 |
+
if(!$meta) {
|
650 |
+
$meta = wp_get_attachment_metadata($attachmentID);
|
651 |
+
}
|
652 |
+
$pathInfo = pathinfo($file);
|
653 |
+
|
654 |
+
$bkFolder = $this->getBackupFolder($file);
|
655 |
+
$bkFile = $bkFolder . ShortPixelAPI::MB_basename($file);
|
656 |
+
|
657 |
+
//first check if the file is readable by the current user - otherwise it will be unaccessible for the web browser
|
658 |
+
// - collect the thumbs paths in the process
|
659 |
+
if(! $this->setFilePerms($bkFile) ) return false;
|
660 |
+
$thumbsPaths = array();
|
661 |
+
if( !empty($meta['file']) ) {
|
662 |
+
foreach($meta["sizes"] as $size => $imageData) {
|
663 |
+
$source = $bkFolder . $imageData['file'];
|
664 |
+
$thumbsPaths[$source] = $pathInfo['dirname'] . DIRECTORY_SEPARATOR . $imageData['file'];
|
665 |
+
if(! $this->setFilePerms($source)) return false;
|
666 |
+
}
|
667 |
+
}
|
668 |
|
669 |
+
if($bkFolder) {
|
670 |
+
try {
|
671 |
+
//main file
|
672 |
+
@rename($bkFile, $file);
|
673 |
|
674 |
+
//overwriting thumbnails
|
675 |
+
foreach($thumbsPaths as $source => $destination) {
|
|
|
|
|
|
|
676 |
@rename($source, $destination);
|
677 |
}
|
678 |
+
|
679 |
+
$duplicates = ShortPixelAPI::getWPMLDuplicates($attachmentID);
|
680 |
+
foreach($duplicates as $ID) {
|
681 |
+
$crtMeta = $attachmentID == $ID ? $meta : wp_get_attachment_metadata($ID);
|
682 |
+
if(is_numeric($crtMeta["ShortPixelImprovement"]) && 0 + $crtMeta["ShortPixelImprovement"] < 5 && $this->_settings->under5Percent > 0) {
|
683 |
+
$this->_settings->under5Percent = $this->_settings->under5Percent - 1; // - (isset($crtMeta["ShortPixel"]["thumbsOpt"]) ? $crtMeta["ShortPixel"]["thumbsOpt"] : 0);
|
684 |
+
}
|
685 |
+
unset($crtMeta["ShortPixelImprovement"]);
|
686 |
+
unset($crtMeta['ShortPixel']);
|
687 |
+
wp_update_attachment_metadata($ID, $crtMeta);
|
688 |
+
}
|
689 |
|
690 |
+
} catch(Exception $e) {
|
691 |
+
//what to do, what to do?
|
692 |
+
return false;
|
693 |
+
}
|
694 |
+
} else {
|
695 |
+
return false;
|
696 |
}
|
697 |
+
|
698 |
+
return $meta;
|
699 |
+
}
|
700 |
+
|
701 |
+
public function handleRestoreBackup() {
|
702 |
+
$attachmentID = intval($_GET['attachment_ID']);
|
703 |
+
|
704 |
+
$this->doRestore($attachmentID);
|
705 |
+
|
706 |
+
// get the referring webpage location
|
707 |
$sendback = wp_get_referer();
|
708 |
// sanitize the referring webpage location
|
709 |
$sendback = preg_replace('|[^a-z0-9-~+_.?#=&;,/:]|i', '', $sendback);
|
712 |
// we are done
|
713 |
}
|
714 |
|
715 |
+
public function handleRedo() {
|
716 |
+
$ID = intval($_GET['attachment_ID']);
|
717 |
+
$type = ($_GET['type'] == 'lossless' ? 'lossless' : 'lossy'); //sanity check
|
718 |
+
|
719 |
+
$meta = $this->doRestore($ID);
|
720 |
+
//die(var_dump($meta));
|
721 |
+
if($meta) { //restore succeeded
|
722 |
+
$meta['ShortPixel'] = array("type" => $type);
|
723 |
+
wp_update_attachment_metadata($ID, $meta);
|
724 |
+
$this->prioQ->push($ID);
|
725 |
+
$this->sendToProcessing($ID, $type == 'lossy' ? 1 : 0);
|
726 |
+
$ret = array("Status" => ShortPixelAPI::STATUS_SUCCESS, "Message" => "");
|
727 |
+
} else {
|
728 |
+
$ret = array("Status" => ShortPixelAPI::STATUS_SKIP, "Message" => "Could not restore from backup: " . $ID);
|
729 |
+
}
|
730 |
+
die(json_encode($ret));
|
731 |
+
}
|
732 |
+
|
733 |
+
public function handleOptimizeThumbs() {
|
734 |
+
$ID = intval($_GET['attachment_ID']);
|
735 |
+
$meta = wp_get_attachment_metadata($ID);
|
736 |
+
//die(var_dump($meta));
|
737 |
+
if( isset($meta['ShortPixelImprovement'])
|
738 |
+
&& isset($meta['sizes']) && count($meta['sizes'])
|
739 |
+
&& ( !isset($meta['ShortPixel']['thumbsOpt']) || $meta['ShortPixel']['thumbsOpt'] == 0)) { //optimized without thumbs, thumbs exist
|
740 |
+
$meta['ShortPixel']['thumbsTodo'] = true;
|
741 |
+
wp_update_attachment_metadata($ID, $meta);
|
742 |
+
$this->prioQ->push($ID);
|
743 |
+
$this->sendToProcessing($ID);
|
744 |
+
$ret = array("Status" => ShortPixelAPI::STATUS_SUCCESS, "message" => "");
|
745 |
+
} else {
|
746 |
+
$ret = array("Status" => ShortPixelAPI::STATUS_SKIP, "message" => (isset($meta['ShortPixelImprovement']) ? "No thumbnails to optimize for ID: " : "Please optimize image for ID:") . $ID);
|
747 |
+
}
|
748 |
+
die(json_encode($ret));
|
749 |
+
}
|
750 |
+
|
751 |
public function handleCheckQuota() {
|
752 |
$this->getQuotaInformation();
|
753 |
// store the referring webpage location
|
788 |
}
|
789 |
}
|
790 |
|
791 |
+
public function checkQuotaAndAlert($quotaData = null) {
|
792 |
+
if(!$quotaData) {
|
793 |
+
$quotaData = $this->getQuotaInformation();
|
794 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
795 |
if ( !$quotaData['APIKeyValid']) {
|
796 |
return $quotaData;
|
797 |
}
|
798 |
+
//$tempus = microtime(true);
|
799 |
$imageCount = $this->countAllProcessableFiles();
|
800 |
+
//echo("Count took (seconds): " . (microtime(true) - $tempus));
|
801 |
+
foreach($imageCount as $key => $val) {
|
802 |
+
$quotaData[$key] = $val;
|
803 |
+
}
|
804 |
+
//$quotaData['totalFiles'] = $imageCount['totalFiles'];
|
805 |
+
//$quotaData['totalProcessedFiles'] = $imageCount['totalProcessedFiles'];
|
806 |
+
//$quotaData['mainFiles'] = $imageCount['mainFiles'];
|
807 |
+
//$quotaData['mainProcessedFiles'] = $imageCount['mainProcessedFiles'];
|
808 |
|
809 |
if($quotaData['APICallsQuotaNumeric'] + $quotaData['APICallsQuotaOneTimeNumeric'] > $quotaData['APICallsMadeNumeric'] + $quotaData['APICallsMadeOneTimeNumeric']) {
|
810 |
update_option('wp-short-pixel-quota-exceeded','0');
|
877 |
|
878 |
//image count
|
879 |
//$imageCount = $this->countAllProcessableFiles();
|
|
|
880 |
$imageOnlyThumbs = $quotaData['totalFiles'] - $quotaData['mainFiles'];
|
881 |
$thumbsProcessedCount = $this->_settings->getOpt( 'wp-short-pixel-thumbnail-count', 0);//amount of optimized thumbnails
|
882 |
$under5PercentCount = $this->_settings->getOpt( 'wp-short-pixel-files-under-5-percent', 0);//amount of under 5% optimized imgs.
|
936 |
}
|
937 |
}
|
938 |
|
939 |
+
public function backupFolderIsEmpty() {
|
940 |
+
return count(scandir(SP_BACKUP_FOLDER)) > 2 ? false : true;
|
941 |
+
}
|
942 |
+
|
943 |
public function renderSettingsMenu() {
|
944 |
if ( !current_user_can( 'manage_options' ) ) {
|
945 |
wp_die('You do not have sufficient permissions to access this page.');
|
950 |
$notice = null;
|
951 |
|
952 |
//by default we try to fetch the API Key from wp-config.php (if defined)
|
953 |
+
if ( defined("SHORTPIXEL_API_KEY") && strlen(SHORTPIXEL_API_KEY) == 20)
|
954 |
{
|
955 |
+
if(!isset($_POST['save']) && strlen($this->getApiKey()) == 0) {
|
956 |
+
$_POST['validate'] = "validate";
|
957 |
+
}
|
958 |
$_POST['key'] = SHORTPIXEL_API_KEY;
|
959 |
}
|
960 |
|
987 |
$notice = array("status" => "warn", "msg" => "API Key is valid but your site is not accessible from our servers.
|
988 |
Please make sure that your server is accessible from the Internet before using the API or otherwise we won't be able to optimize them.");
|
989 |
} else {
|
990 |
+
if ( function_exists("is_multisite") && is_multisite() && !defined("SHORTPIXEL_API_KEY"))
|
991 |
$notice = array("status" => "success", "msg" => "API Key valid! <br>You seem to be running a multisite, please note that API Key can also be configured in wp-config.php like this:<BR> <b>define('SHORTPIXEL_API_KEY', '".$this->_settings->apiKey."');</b>");
|
992 |
else
|
993 |
$notice = array("status" => "success", "msg" => 'API Key valid!');
|
1036 |
$this->emptyBackup();
|
1037 |
}
|
1038 |
|
1039 |
+
$quotaData = $this->checkQuotaAndAlert(isset($validityData) ? $validityData : null);
|
1040 |
|
1041 |
if($this->_settings->verifiedKey) {
|
1042 |
$fileCount = number_format($this->_settings->fileCount);
|
1050 |
$remainingImages = $quotaData['APICallsQuotaNumeric'] + $quotaData['APICallsQuotaOneTimeNumeric'] - $quotaData['APICallsMadeNumeric'] - $quotaData['APICallsMadeOneTimeNumeric'];
|
1051 |
$remainingImages = ( $remainingImages < 0 ) ? 0 : number_format($remainingImages);
|
1052 |
$totalCallsMade = number_format($quotaData['APICallsMadeNumeric'] + $quotaData['APICallsMadeOneTimeNumeric']);
|
1053 |
+
|
1054 |
$resources = wp_remote_get($this->_settings->httpProto . "://shortpixel.com/resources-frag");
|
1055 |
+
if(is_wp_error( $resources )) {
|
1056 |
+
$resources = array();
|
1057 |
+
}
|
1058 |
$this->view->displaySettings(is_main_site() || (is_multisite() && !defined("SHORTPIXEL_API_KEY")),
|
1059 |
$quotaData, $notice, $resources, $averageCompression, $savedSpace, $savedBandwidth,
|
1060 |
$remainingImages, $totalCallsMade, $fileCount, $backupFolderSize);
|
1082 |
|
1083 |
if(is_null($apiKey)) { $apiKey = $this->_settings->apiKey; }
|
1084 |
|
1085 |
+
if($this->_settings->httpProto != 'https' && $this->_settings->httpProto != 'http') {
|
1086 |
+
$this->_settings->httpProto = 'https';
|
1087 |
+
}
|
1088 |
|
1089 |
$requestURL = $this->_settings->httpProto . '://api.shortpixel.com/v2/api-status.php';
|
1090 |
$args = array(
|
1091 |
'timeout'=> SP_VALIDATE_MAX_TIMEOUT,
|
|
|
1092 |
'body' => array('key' => $apiKey)
|
1093 |
);
|
1094 |
$argsStr = "?key=".$apiKey;
|
1105 |
$argsStr .= "&DomainCheck={$args['body']['DomainCheck']}&ImagesCount={$imageCount['mainFiles']}&ThumbsCount={$args['body']['ThumbsCount']}";
|
1106 |
}
|
1107 |
|
1108 |
+
$comm = array();
|
1109 |
+
|
1110 |
+
//Try first HTTPS post. add the sslverify = false if https
|
1111 |
+
if($this->_settings->httpProto === 'https') {
|
1112 |
+
$args['sslverify'] = false;
|
1113 |
+
}
|
1114 |
$response = wp_remote_post($requestURL, $args);
|
1115 |
+
$comm[] = array("sent" => "POST: " . $requestURL, "args" => $args, "received" => $response);
|
1116 |
+
|
1117 |
//some hosting providers won't allow https:// POST connections so we try http:// as well
|
1118 |
if(is_wp_error( $response )) {
|
1119 |
//echo("protocol " . $this->_settings->httpProto . " failed. switching...");
|
1120 |
$requestURL = $this->_settings->httpProto == 'https' ?
|
1121 |
str_replace('https://', 'http://', $requestURL) :
|
1122 |
str_replace('http://', 'https://', $requestURL);
|
1123 |
+
// add or remove the sslverify
|
1124 |
+
if($this->_settings->httpProto === 'http') {
|
1125 |
+
$args['sslverify'] = false;
|
1126 |
+
} else {
|
1127 |
+
unset($args['sslverify']);
|
1128 |
+
}
|
1129 |
+
$response = wp_remote_post($requestURL, $args);
|
1130 |
+
$comm[] = array("sent" => "POST: " . $requestURL, "args" => $args, "received" => $response);
|
1131 |
+
|
1132 |
+
if(!is_wp_error( $response )){
|
1133 |
+
$this->_settings->httpProto = ($this->_settings->httpProto == 'https' ? 'http' : 'https');
|
1134 |
+
//echo("protocol " . $this->_settings->httpProto . " succeeded");
|
1135 |
+
} else {
|
1136 |
+
//echo("protocol " . $this->_settings->httpProto . " failed too");
|
1137 |
+
}
|
1138 |
}
|
1139 |
//Second fallback to HTTP get
|
1140 |
if(is_wp_error( $response )){
|
1141 |
$args['body'] = null;
|
1142 |
$requestURL .= $argsStr;
|
1143 |
$response = wp_remote_get($requestURL, $args);
|
1144 |
+
$comm[] = array("sent" => "POST: " . $requestURL, "args" => $args, "received" => $response);
|
1145 |
}
|
1146 |
+
|
1147 |
+
//die(var_dump($comm));
|
1148 |
+
|
1149 |
$defaultData = array(
|
1150 |
"APIKeyValid" => false,
|
1151 |
"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 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. ',
|
1157 |
|
1158 |
$urlElements = parse_url($requestURL);
|
1159 |
$portConnect = @fsockopen($urlElements['host'],8,$errno,$errstr,15);
|
1160 |
+
if(!$portConnect) {
|
1161 |
$defaultData['Message'] .= "<BR>Debug info: <i>$errstr</i>";
|
1162 |
+
}
|
1163 |
return $defaultData;
|
1164 |
}
|
1165 |
|
1209 |
$data = wp_get_attachment_metadata($id);
|
1210 |
$file = get_attached_file($id);
|
1211 |
$fileExtension = strtolower(substr($file,strrpos($file,".")+1));
|
1212 |
+
$invalidKey = !$this->_settings->verifiedKey;
|
1213 |
+
$quotaExceeded = $this->_settings->quotaExceeded;
|
1214 |
+
$renderData = array("id" => $id, "showActions" => current_user_can( 'manage_options' ));
|
1215 |
|
1216 |
+
$data2 = $data;
|
1217 |
|
1218 |
+
|
1219 |
+
if($invalidKey) { //invalid key - let the user first register and only then
|
1220 |
+
$renderData['status'] = 'invalidKey';
|
1221 |
+
$this->view->renderCustomColumn($id, $renderData);
|
1222 |
+
return;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1223 |
}
|
1224 |
+
|
1225 |
+
//empty data means document, we handle only PDF
|
1226 |
+
elseif (empty($data)) { //TODO asta devine if si decomentam returnurile
|
1227 |
+
if($fileExtension == "pdf") {
|
1228 |
+
$renderData['status'] = $quotaExceeded ? 'quotaExceeded' : 'optimizeNow';
|
1229 |
+
$renderData['message'] = 'PDF not processed';
|
1230 |
+
}
|
1231 |
+
else { //Optimization N/A
|
1232 |
+
$renderData['status'] = 'n/a';
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1233 |
}
|
1234 |
+
$this->view->renderCustomColumn($id, $renderData);
|
1235 |
+
return;
|
1236 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1237 |
|
1238 |
+
if(!isset($data['ShortPixelImprovement'])) { //new image
|
1239 |
+
$data['ShortPixelImprovement'] = '';
|
1240 |
+
}
|
1241 |
+
|
1242 |
+
if(is_numeric($data['ShortPixelImprovement'])) { //already optimized
|
1243 |
+
$renderData['status'] = $fileExtension == "pdf" ? 'pdfOptimized' : 'imgOptimized';
|
1244 |
+
$renderData['percent'] = $data['ShortPixelImprovement'];
|
1245 |
+
$renderData['bonus'] = ($data['ShortPixelImprovement'] < 5);
|
1246 |
+
$renderData['backup'] = $this->getBackupFolder(get_attached_file($id)) ;
|
1247 |
+
$renderData['type'] = isset($data['ShortPixel']['type']) ? $data['ShortPixel']['type'] : '';
|
1248 |
+
$sizes = isset($data['sizes']) ? count($data['sizes']) : 0;
|
1249 |
+
$renderData['thumbsTotal'] = $sizes;
|
1250 |
+
$renderData['thumbsOpt'] = isset($data['ShortPixel']['thumbsOpt']) ? $data['ShortPixel']['thumbsOpt'] : $sizes;
|
1251 |
+
$renderData['quotaExceeded'] = $quotaExceeded;
|
1252 |
+
}
|
1253 |
+
elseif($data['ShortPixelImprovement'] == "Optimization N/A") { //We don't optimize this
|
1254 |
+
$renderData['status'] = 'n/a';
|
1255 |
+
}
|
1256 |
+
elseif(isset($meta['ShortPixel']['BulkProcessing'])) { //Scheduled to bulk.
|
1257 |
+
$renderData['status'] = $quotaExceeded ? 'quotaExceeded' : 'optimizeNow';
|
1258 |
+
$renderData['message'] = 'Waiting for bulk processing.';
|
1259 |
+
}
|
1260 |
+
elseif( trim(strip_tags($data['ShortPixelImprovement'])) == "Cannot write optimized file" ) {
|
1261 |
+
$renderData['status'] = $quotaExceeded ? 'quotaExceeded' : 'retry';
|
1262 |
+
$renderData['message'] = "Cannot write optimized file - <a href='https://shortpixel.com/faq#cannot-write-optimized-file' target='_blank'>Why?</a>";
|
1263 |
+
}
|
1264 |
+
elseif( strlen(trim(strip_tags($data['ShortPixelImprovement']))) > 0 ) {
|
1265 |
+
$renderData['status'] = $quotaExceeded ? 'quotaExceeded' : 'retry';
|
1266 |
+
$renderData['message'] = $data['ShortPixelImprovement'];
|
1267 |
}
|
1268 |
+
elseif(isset($data['ShortPixel']['NoFileOnDisk'])) {
|
1269 |
+
$renderData['status'] = 'notFound';
|
1270 |
+
$renderData['message'] = 'Image does not exist';
|
1271 |
+
}
|
1272 |
+
elseif(isset($data['ShortPixel']['WaitingProcessing'])) {
|
1273 |
+
$renderData['status'] = $quotaExceeded ? 'quotaExceeded' : 'retry';
|
1274 |
+
$renderData['message'] = "<img src=\"" . plugins_url( 'img/loading.gif', __FILE__ ) . "\" class='sp-loading-small'> Image waiting to be processed";
|
1275 |
+
if($id > $this->prioQ->getFlagBulkId()) $this->prioQ->push($id); //should be there but just to make sure
|
1276 |
+
}
|
1277 |
+
else { //finally
|
1278 |
+
$renderData['status'] = $quotaExceeded ? 'quotaExceeded' : 'optimizeNow';
|
1279 |
+
$sizes = isset($data['sizes']) ? count($data['sizes']) : 0;
|
1280 |
+
$renderData['thumbsTotal'] = $sizes;
|
1281 |
+
$renderData['message'] = ($fileExtension == "pdf" ? 'PDF' : 'Image') . ' not processed';
|
1282 |
+
}
|
1283 |
+
|
1284 |
+
$this->view->renderCustomColumn($id, $renderData);
|
1285 |
}
|
1286 |
}
|
1287 |
|
1288 |
public function columns( $defaults ) {
|
1289 |
+
$defaults['wp-shortPixel'] = 'ShortPixel Compression';
|
1290 |
+
if(current_user_can( 'manage_options' )) {
|
1291 |
+
$defaults['wp-shortPixel'] .= ' <a href="options-general.php?page=wp-shortpixel#stats" title="ShortPixel Statistics"><span class="dashicons dashicons-dashboard"></span></a>';
|
1292 |
+
}
|
1293 |
return $defaults;
|
1294 |
}
|
1295 |
|
1339 |
|
1340 |
|
1341 |
//return an array with URL(s) and PATH(s) for this file
|
1342 |
+
public function getURLsAndPATHs($ID, $meta = NULL, $onlyThumbs = false) {
|
1343 |
|
1344 |
+
if ( !parse_url(WP_CONTENT_URL, PHP_URL_SCHEME) ) {//no absolute URLs used -> we implement a hack
|
|
|
1345 |
$url = get_site_url() . wp_get_attachment_url($ID);//get the file URL
|
1346 |
}
|
1347 |
+
else {
|
1348 |
$url = wp_get_attachment_url($ID);//get the file URL
|
1349 |
+
}
|
1350 |
$urlList[] = $url;
|
1351 |
$path = get_attached_file($ID);//get the full file PATH
|
1352 |
$filePath[] = $path;
|
1353 |
+
|
1354 |
if ( $meta == NULL ) {
|
1355 |
$meta = wp_get_attachment_metadata($ID);
|
1356 |
}
|
1357 |
|
1358 |
//it is NOT a PDF file and thumbs are processable
|
1359 |
if ( strtolower(substr($filePath[0],strrpos($filePath[0], ".")+1)) != "pdf"
|
1360 |
+
&& ($this->_settings->processThumbnails || $onlyThumbs)
|
1361 |
&& isset($meta['sizes']) && is_array($meta['sizes']))
|
1362 |
{
|
1363 |
foreach( $meta['sizes'] as $thumbnailInfo )
|
1369 |
if(!isset($meta['sizes']) || !is_array($meta['sizes'])) {
|
1370 |
self::log("getURLsAndPATHs: no meta sizes for ID $ID : " . json_encode($meta));
|
1371 |
}
|
1372 |
+
|
1373 |
+
if($onlyThumbs) { //remove the main image
|
1374 |
+
array_shift($urlList);
|
1375 |
+
array_shift($filePath);
|
1376 |
+
}
|
1377 |
return array("URLs" => $urlList, "PATHs" => $filePath);
|
1378 |
}
|
1379 |
|
1433 |
return $resultQuery[0]->QueryID;
|
1434 |
}
|
1435 |
|
1436 |
+
protected function getOptimalChunkSize() {
|
1437 |
+
global $wpdb;
|
1438 |
+
$cnt = $wpdb->get_results("SELECT count(*) posts FROM " . $wpdb->prefix . "posts");
|
1439 |
+
$posts = isset($cnt) && count($cnt) > 0 ? $cnt[0]->posts : 0;
|
1440 |
+
if($posts > 100000) {
|
1441 |
+
return 20000;
|
1442 |
+
} elseif ($posts > 50000) {
|
1443 |
+
return 5000;
|
1444 |
+
} elseif($posts > 10000) {
|
1445 |
+
return 2000;
|
1446 |
+
} else {
|
1447 |
+
return 500;
|
1448 |
+
}
|
1449 |
+
}
|
1450 |
+
|
1451 |
+
protected function getPostIdsChunk($minId, $maxId, $pointer, $limit) {
|
1452 |
+
global $wpdb;
|
1453 |
+
|
1454 |
+
$ids = array();
|
1455 |
+
$idList = $wpdb->get_results("SELECT ID, post_mime_type FROM " . $wpdb->prefix . "posts
|
1456 |
+
WHERE ( ID <= $maxId AND ID > $minId )
|
1457 |
+
LIMIT $pointer,$limit");
|
1458 |
+
if ( empty($idList) ) {
|
1459 |
+
return null;
|
1460 |
+
}
|
1461 |
+
foreach($idList as $item) {
|
1462 |
+
if($item->post_mime_type != '') {
|
1463 |
+
$ids[] = $item->ID;
|
1464 |
+
}
|
1465 |
+
}
|
1466 |
+
return $ids;
|
1467 |
+
}
|
1468 |
+
|
1469 |
//count all the processable files in media library (while limiting the results to max 10000)
|
1470 |
public function countAllProcessableFiles($maxId = PHP_INT_MAX, $minId = 0){
|
1471 |
global $wpdb;
|
1472 |
|
1473 |
+
$totalFiles = $mainFiles = $processedMainFiles = $processedTotalFiles =
|
1474 |
+
$procLossyMainFiles = $procLossyTotalFiles = $procLosslessMainFiles = $procLosslessTotalFiles = $mainUnprocessedThumbs = 0;
|
1475 |
+
$filesMap = $processedFilesMap = array();
|
1476 |
+
$limit = $this->getOptimalChunkSize();
|
1477 |
$pointer = 0;
|
1478 |
+
$filesWithErrors = array();
|
1479 |
+
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1480 |
//count all the files, main and thumbs
|
1481 |
+
while ( 1 ) {
|
1482 |
+
/* ALTERNATE CODE WITH JOIN - seems less efficient than select ids / select in
|
1483 |
+
$filesList= $wpdb->get_results("SELECT pm.* FROM " . $wpdb->prefix . "postmeta pm
|
1484 |
+
INNER JOIN " . $wpdb->prefix . "posts p on p.ID = pm.post_id
|
1485 |
+
WHERE ( p.ID <= $maxId AND p.ID > $minId ) and p.post_mime_type <> ''
|
1486 |
+
AND ( pm.meta_key = '_wp_attached_file' OR pm.meta_key = '_wp_attachment_metadata' )
|
1487 |
LIMIT $pointer,$limit");
|
1488 |
if ( empty($filesList) ) //we parsed all the results
|
1489 |
break;
|
1490 |
+
*/
|
1491 |
+
$ids = $this->getPostIdsChunk($minId, $maxId, $pointer, $limit);
|
1492 |
+
if($ids === null) {
|
1493 |
+
break; //we parsed all the results
|
1494 |
+
}
|
1495 |
+
elseif(count($ids) == 0) {
|
1496 |
+
$pointer += $limit;
|
1497 |
+
continue;
|
1498 |
+
}
|
1499 |
+
|
1500 |
+
$filesList= $wpdb->get_results("SELECT * FROM " . $wpdb->prefix . "postmeta
|
1501 |
+
WHERE post_id IN (" . implode(',', $ids) . ")
|
1502 |
+
AND ( meta_key = '_wp_attached_file' OR meta_key = '_wp_attachment_metadata' )");
|
1503 |
|
|
|
1504 |
foreach ( $filesList as $file )
|
1505 |
{
|
1506 |
if ( $file->meta_key == "_wp_attached_file" )
|
1513 |
$filesMap[$file->meta_value] = 1;
|
1514 |
}
|
1515 |
}
|
1516 |
+
else //_wp_attachment_metadata
|
1517 |
{
|
1518 |
$attachment = unserialize($file->meta_value);
|
1519 |
+
//processable
|
1520 |
+
$isProcessable = false;
|
1521 |
if(isset($attachment['file']) && !isset($filesMap[$attachment['file']]) && self::isProcessablePath($attachment['file'])){
|
1522 |
+
$isProcessable = true;
|
1523 |
if ( isset($attachment['sizes']) ) {
|
1524 |
$totalFiles += count($attachment['sizes']);
|
1525 |
}
|
1530 |
$filesMap[$attachment['file']] = 1;
|
1531 |
}
|
1532 |
}
|
1533 |
+
//processed
|
1534 |
+
if (isset($attachment['ShortPixelImprovement'])
|
1535 |
+
&& ($attachment['ShortPixelImprovement'] > 0 || $attachment['ShortPixelImprovement'] === 0.0 || $attachment['ShortPixelImprovement'] === "0")
|
1536 |
+
//for PDFs there is no file field so just let it pass.
|
1537 |
+
&& (!isset($attachment['file']) || !isset($processedFilesMap[$attachment['file']])) ) {
|
1538 |
+
|
1539 |
+
//add main file to counts
|
1540 |
+
$processedMainFiles++;
|
1541 |
+
$processedTotalFiles++;
|
1542 |
+
$type = isset($attachment['ShortPixel']['type']) ? $attachment['ShortPixel']['type'] : null;
|
1543 |
+
if($type == 'lossy') {
|
1544 |
+
$procLossyMainFiles++;
|
1545 |
+
$procLossyTotalFiles++;
|
1546 |
+
} else {
|
1547 |
+
$procLosslessMainFiles++;
|
1548 |
+
$procLosslessTotalFiles++;
|
1549 |
+
}
|
1550 |
+
|
1551 |
+
//get the thumbs processed for that attachment
|
1552 |
+
$thumbs = $allThumbs = 0;
|
1553 |
+
if ( isset($attachment['ShortPixel']['thumbsOpt']) ) {
|
1554 |
+
$thumbs = $attachment['ShortPixel']['thumbsOpt'];
|
1555 |
+
}
|
1556 |
+
elseif ( isset($attachment['sizes']) ) {
|
1557 |
+
$thumbs = count($attachment['sizes']);
|
1558 |
+
}
|
1559 |
+
if ( isset($attachment['sizes']) & count($attachment['sizes']) > $thumbs) {
|
1560 |
+
$mainUnprocessedThumbs++;
|
1561 |
+
}
|
1562 |
+
|
1563 |
+
//increment with thumbs processed
|
1564 |
+
$processedTotalFiles += $thumbs;
|
1565 |
+
if($type == 'lossy') {
|
1566 |
+
$procLossyTotalFiles += $thumbs;
|
1567 |
+
} else {
|
1568 |
+
$procLosslessTotalFiles += $thumbs;
|
1569 |
+
}
|
1570 |
+
|
1571 |
+
if ( isset($attachment['file']) ) {
|
1572 |
+
$processedFilesMap[$attachment['file']] = 1;
|
1573 |
+
}
|
|
|
|
|
1574 |
}
|
1575 |
+
elseif($isProcessable && isset($attachment['ShortPixelImprovement']) && count($filesWithErrors) < 50) {
|
1576 |
+
$filePath = explode("/", $attachment["file"]);
|
1577 |
+
$name = is_array($filePath)? $filePath[count($filePath) - 1] : $file->post_id;
|
1578 |
+
$filesWithErrors[$file->post_id] = array('Name' => $name, 'Message' => $attachment['ShortPixelImprovement']);
|
1579 |
}
|
1580 |
+
|
1581 |
}
|
1582 |
}
|
1583 |
unset($filesList);
|
1585 |
|
1586 |
}//end while
|
1587 |
|
1588 |
+
return array("totalFiles" => $totalFiles, "mainFiles" => $mainFiles,
|
1589 |
+
"totalProcessedFiles" => $processedTotalFiles, "mainProcessedFiles" => $processedMainFiles,
|
1590 |
+
"totalProcLossyFiles" => $procLossyTotalFiles, "mainProcLossyFiles" => $procLossyMainFiles,
|
1591 |
+
"totalProcLosslessFiles" => $procLosslessTotalFiles, "mainProcLosslessFiles" => $procLosslessMainFiles,
|
1592 |
+
"mainUnprocessedThumbs" => $mainUnprocessedThumbs,
|
1593 |
+
"filesWithErrors" => $filesWithErrors
|
1594 |
+
);
|
1595 |
}
|
1596 |
|
1597 |
public function migrateBackupFolder() {
|
1637 |
}
|
1638 |
return array('width' => $width, 'height' => $height);
|
1639 |
}
|
1640 |
+
|
1641 |
+
public function getEncryptedData() {
|
1642 |
+
return base64_encode(self::encrypt($this->getApiKey() . "|" . get_site_url(), "sh0r+Pix3l8im1N3r"));
|
1643 |
+
}
|
1644 |
+
/**
|
1645 |
+
* Returns an encrypted & utf8-encoded
|
1646 |
+
*/
|
1647 |
+
public static function encrypt($pure_string, $encryption_key)
|
1648 |
+
{
|
1649 |
+
$iv_size = \mcrypt_get_iv_size(MCRYPT_BLOWFISH, MCRYPT_MODE_ECB);
|
1650 |
+
$iv = \mcrypt_create_iv($iv_size, MCRYPT_RAND);
|
1651 |
+
$encrypted_string = \mcrypt_encrypt(MCRYPT_BLOWFISH, $encryption_key, utf8_encode($pure_string), MCRYPT_MODE_ECB, $iv);
|
1652 |
+
return $encrypted_string;
|
1653 |
+
}
|
1654 |
+
|
1655 |
|
1656 |
public function getApiKey() {
|
1657 |
return $this->_settings->apiKey;
|
1702 |
}
|
1703 |
|
1704 |
function onInit() {
|
1705 |
+
if ( ! is_admin() || !is_user_logged_in() || ! (current_user_can( 'manage_options' ) || current_user_can( 'upload_files' )) ) {
|
1706 |
return;
|
1707 |
}
|
1708 |
$pluginInstance = new WPShortPixel;
|
1716 |
register_deactivation_hook( __FILE__, array( 'WPShortPixel', 'shortPixelDeactivatePlugin' ) );
|
1717 |
|
1718 |
}
|
|
|
|
|
|
|
|
|
1719 |
?>
|