Version Description
- option to keep the EXIF data and ICC profile.
- more explanations on settings. *
Download this release
Release Info
Developer | ShortPixel |
Plugin | ShortPixel Image Optimizer |
Version | 3.1.9 |
Comparing to | |
See all releases |
Code changes from version 3.1.8 to 3.1.9
- js/short-pixel.js +2 -2
- readme.txt +8 -2
- shortpixel_api.php +421 -444
- shortpixel_queue.php +50 -48
- shortpixel_view.php +25 -13
- wp-shortpixel-settings.php +150 -0
- wp-shortpixel.php +124 -170
js/short-pixel.js
CHANGED
@@ -106,7 +106,7 @@ function checkQuotaExceededAlert() {
|
|
106 |
* calls itself until receives an Empty queue message
|
107 |
*/
|
108 |
function checkBulkProgress() {
|
109 |
-
if(window.location.href.search("wp-admin/upload.php") < 0
|
110 |
&& window.location.href.search("wp-admin/edit.php") < 0
|
111 |
&& window.location.href.search("wp-admin/edit-tags.php") < 0
|
112 |
&& window.location.href.search("wp-admin/post-new.php") < 0
|
@@ -201,7 +201,7 @@ function checkBulkProcessingCallApi(){
|
|
201 |
case ShortPixel.STATUS_SUCCESS:
|
202 |
var percent = data["PercentImprovement"];
|
203 |
var cellMsg = "Reduced by <span class='percent'>" + percent + "%</span> "
|
204 |
-
+ (data["BackupEnabled"] == 1 ? "
|
205 |
if(0 + data['ThumbsCount'] > 0) {
|
206 |
cellMsg += "<br>+" + data['ThumbsCount'] + " thumbnails optimized";
|
207 |
}
|
106 |
* calls itself until receives an Empty queue message
|
107 |
*/
|
108 |
function checkBulkProgress() {
|
109 |
+
if( window.location.href.search("wp-admin/upload.php") < 0
|
110 |
&& window.location.href.search("wp-admin/edit.php") < 0
|
111 |
&& window.location.href.search("wp-admin/edit-tags.php") < 0
|
112 |
&& window.location.href.search("wp-admin/post-new.php") < 0
|
201 |
case ShortPixel.STATUS_SUCCESS:
|
202 |
var percent = data["PercentImprovement"];
|
203 |
var cellMsg = "Reduced by <span class='percent'>" + percent + "%</span> "
|
204 |
+
+ (data["BackupEnabled"] == 1 ? "<a class='button button-smaller' href=\"admin.php?action=shortpixel_restore_backup&attachment_ID=" + id + ")\">Restore backup</a>" : "");
|
205 |
if(0 + data['ThumbsCount'] > 0) {
|
206 |
cellMsg += "<br>+" + data['ThumbsCount'] + " thumbnails optimized";
|
207 |
}
|
readme.txt
CHANGED
@@ -3,9 +3,9 @@
|
|
3 |
Contributors: AlexSP
|
4 |
Tags: picture, optimization, image editor, pngout, upload speed, shortpixel, compression, jpegmini, webp, lossless, cwebp, media, jpegtran, image, image optimisation, image optimization, shrink, picture, photo, optimize photos, compress, performance, tinypng, crunch, pngquant, attachment, optimize, pictures, fast, images, image files, image quality, lossy, upload, kraken, resize, seo, smushit, optipng, kraken image optimizer, ewww, photo optimization, gifsicle, image optimizer, images, krakenio, png, gmagick, image optimize, pdf, pdf optimisation, pdf optimization, optimize pdf, optimise pdf, shrink pdf, jpg, jpeg, jpg optimisation, jpg optimization, optimize jpg, optimise jpg, shrink jpg, gif, animated gif, optimize gif, optimise gif, optimizer, optimiser, compresion, optimization, cruncher, image cruncher, compress png, compress jpg, compress jpeg, compress pdf, faster loading times, image optimiser, improve pagerank, optimise, optimize animated gif, optimise jpeg, optimize jpeg, optimize png, optimise png, optimise pdf, optimize pdf, tinyjpg, short pixel, shortpixel, woocommerce compatible
|
5 |
|
6 |
-
Requires at least: 3.0
|
7 |
Tested up to: 4.4
|
8 |
-
Stable tag: 3.1.
|
9 |
License: GPLv2 or later
|
10 |
License URI: http://www.gnu.org/licenses/gpl-2.0.html
|
11 |
|
@@ -168,6 +168,12 @@ The ShortPixel team is here to help. <a href="https://shortpixel.com/contact">Co
|
|
168 |
|
169 |
== Changelog ==
|
170 |
|
|
|
|
|
|
|
|
|
|
|
|
|
171 |
= 3.1.8 =
|
172 |
|
173 |
* fix reloading bulk page on quota used up
|
3 |
Contributors: AlexSP
|
4 |
Tags: picture, optimization, image editor, pngout, upload speed, shortpixel, compression, jpegmini, webp, lossless, cwebp, media, jpegtran, image, image optimisation, image optimization, shrink, picture, photo, optimize photos, compress, performance, tinypng, crunch, pngquant, attachment, optimize, pictures, fast, images, image files, image quality, lossy, upload, kraken, resize, seo, smushit, optipng, kraken image optimizer, ewww, photo optimization, gifsicle, image optimizer, images, krakenio, png, gmagick, image optimize, pdf, pdf optimisation, pdf optimization, optimize pdf, optimise pdf, shrink pdf, jpg, jpeg, jpg optimisation, jpg optimization, optimize jpg, optimise jpg, shrink jpg, gif, animated gif, optimize gif, optimise gif, optimizer, optimiser, compresion, optimization, cruncher, image cruncher, compress png, compress jpg, compress jpeg, compress pdf, faster loading times, image optimiser, improve pagerank, optimise, optimize animated gif, optimise jpeg, optimize jpeg, optimize png, optimise png, optimise pdf, optimize pdf, tinyjpg, short pixel, shortpixel, woocommerce compatible
|
5 |
|
6 |
+
Requires at least: 3.2.0
|
7 |
Tested up to: 4.4
|
8 |
+
Stable tag: 3.1.9
|
9 |
License: GPLv2 or later
|
10 |
License URI: http://www.gnu.org/licenses/gpl-2.0.html
|
11 |
|
168 |
|
169 |
== Changelog ==
|
170 |
|
171 |
+
= 3.1.9 =
|
172 |
+
|
173 |
+
* option to keep the EXIF data and ICC profile.
|
174 |
+
* more explanations on settings.
|
175 |
+
*
|
176 |
+
|
177 |
= 3.1.8 =
|
178 |
|
179 |
* fix reloading bulk page on quota used up
|
shortpixel_api.php
CHANGED
@@ -1,444 +1,421 @@
|
|
1 |
-
<?php
|
2 |
-
if ( !function_exists( 'download_url' ) ) {
|
3 |
-
require_once( ABSPATH . 'wp-admin/includes/file.php' );
|
4 |
-
}
|
5 |
-
|
6 |
-
class ShortPixelAPI {
|
7 |
-
|
8 |
-
const STATUS_SUCCESS = 1;
|
9 |
-
const STATUS_UNCHANGED = 0;
|
10 |
-
const STATUS_ERROR = -1;
|
11 |
-
const STATUS_FAIL = -2;
|
12 |
-
const STATUS_QUOTA_EXCEEDED = -3;
|
13 |
-
const STATUS_SKIP = -4;
|
14 |
-
const STATUS_NOT_FOUND = -5;
|
15 |
-
const STATUS_NO_KEY = -6;
|
16 |
-
const STATUS_RETRY = -7;
|
17 |
-
|
18 |
-
private $
|
19 |
-
private $
|
20 |
-
private $
|
21 |
-
|
22 |
-
|
23 |
-
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
-
|
30 |
-
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
-
|
46 |
-
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
$this->
|
58 |
-
|
59 |
-
|
60 |
-
|
61 |
-
|
62 |
-
|
63 |
-
'
|
64 |
-
'
|
65 |
-
|
66 |
-
|
67 |
-
|
68 |
-
|
69 |
-
'
|
70 |
-
|
71 |
-
|
72 |
-
|
73 |
-
|
74 |
-
|
75 |
-
|
76 |
-
|
77 |
-
|
78 |
-
|
79 |
-
|
80 |
-
|
81 |
-
|
82 |
-
|
83 |
-
|
84 |
-
|
85 |
-
|
86 |
-
|
87 |
-
|
88 |
-
|
89 |
-
|
90 |
-
|
91 |
-
|
92 |
-
|
93 |
-
|
94 |
-
|
95 |
-
|
96 |
-
|
97 |
-
|
98 |
-
|
99 |
-
|
100 |
-
|
101 |
-
|
102 |
-
|
103 |
-
|
104 |
-
|
105 |
-
|
106 |
-
|
107 |
-
|
108 |
-
|
109 |
-
|
110 |
-
|
111 |
-
|
112 |
-
|
113 |
-
|
114 |
-
|
115 |
-
|
116 |
-
|
117 |
-
|
118 |
-
|
119 |
-
|
120 |
-
|
121 |
-
|
122 |
-
|
123 |
-
|
124 |
-
|
125 |
-
|
126 |
-
|
127 |
-
|
128 |
-
|
129 |
-
|
130 |
-
|
131 |
-
|
132 |
-
|
133 |
-
|
134 |
-
|
135 |
-
|
136 |
-
|
137 |
-
|
138 |
-
|
139 |
-
|
140 |
-
|
141 |
-
|
142 |
-
|
143 |
-
|
144 |
-
|
145 |
-
|
146 |
-
|
147 |
-
{
|
148 |
-
|
149 |
-
|
150 |
-
|
151 |
-
|
152 |
-
|
153 |
-
|
154 |
-
|
155 |
-
|
156 |
-
|
157 |
-
|
158 |
-
|
159 |
-
|
160 |
-
|
161 |
-
|
162 |
-
|
163 |
-
|
164 |
-
|
165 |
-
|
166 |
-
|
167 |
-
|
168 |
-
|
169 |
-
|
170 |
-
|
171 |
-
|
172 |
-
|
173 |
-
|
174 |
-
|
175 |
-
|
176 |
-
|
177 |
-
|
178 |
-
|
179 |
-
|
180 |
-
|
181 |
-
|
182 |
-
|
183 |
-
|
184 |
-
|
185 |
-
|
186 |
-
|
187 |
-
|
188 |
-
|
189 |
-
}
|
190 |
-
|
191 |
-
|
192 |
-
|
193 |
-
|
194 |
-
|
195 |
-
|
196 |
-
|
197 |
-
|
198 |
-
|
199 |
-
|
200 |
-
|
201 |
-
|
202 |
-
|
203 |
-
|
204 |
-
|
205 |
-
|
206 |
-
|
207 |
-
|
208 |
-
|
209 |
-
|
210 |
-
|
211 |
-
if($
|
212 |
-
|
213 |
-
$
|
214 |
-
|
215 |
-
|
216 |
-
|
217 |
-
|
218 |
-
|
219 |
-
$
|
220 |
-
|
221 |
-
|
222 |
-
|
223 |
-
|
224 |
-
|
225 |
-
|
226 |
-
|
227 |
-
|
228 |
-
|
229 |
-
|
230 |
-
|
231 |
-
|
232 |
-
|
233 |
-
|
234 |
-
//
|
235 |
-
|
236 |
-
|
237 |
-
|
238 |
-
|
239 |
-
|
240 |
-
|
241 |
-
|
242 |
-
|
243 |
-
|
244 |
-
|
245 |
-
|
246 |
-
|
247 |
-
|
248 |
-
|
249 |
-
|
250 |
-
|
251 |
-
|
252 |
-
|
253 |
-
|
254 |
-
|
255 |
-
|
256 |
-
|
257 |
-
|
258 |
-
$
|
259 |
-
|
260 |
-
//
|
261 |
-
|
262 |
-
{
|
263 |
-
|
264 |
-
|
265 |
-
|
266 |
-
|
267 |
-
|
268 |
-
|
269 |
-
|
270 |
-
|
271 |
-
|
272 |
-
|
273 |
-
|
274 |
-
|
275 |
-
|
276 |
-
|
277 |
-
|
278 |
-
|
279 |
-
|
280 |
-
|
281 |
-
|
282 |
-
|
283 |
-
|
284 |
-
|
285 |
-
|
286 |
-
|
287 |
-
|
288 |
-
|
289 |
-
|
290 |
-
|
291 |
-
|
292 |
-
|
293 |
-
return array("Status" => self::STATUS_FAIL, "Message" =>
|
294 |
-
}
|
295 |
-
|
296 |
-
|
297 |
-
|
298 |
-
|
299 |
-
|
300 |
-
|
301 |
-
|
302 |
-
|
303 |
-
//
|
304 |
-
|
305 |
-
{
|
306 |
-
|
307 |
-
|
308 |
-
|
309 |
-
|
310 |
-
|
311 |
-
|
312 |
-
|
313 |
-
|
314 |
-
|
315 |
-
|
316 |
-
|
317 |
-
|
318 |
-
|
319 |
-
|
320 |
-
|
321 |
-
|
322 |
-
|
323 |
-
|
324 |
-
|
325 |
-
|
326 |
-
|
327 |
-
|
328 |
-
|
329 |
-
|
330 |
-
|
331 |
-
|
332 |
-
|
333 |
-
|
334 |
-
|
335 |
-
|
336 |
-
|
337 |
-
|
338 |
-
|
339 |
-
|
340 |
-
|
341 |
-
|
342 |
-
|
343 |
-
|
344 |
-
|
345 |
-
|
346 |
-
|
347 |
-
|
348 |
-
|
349 |
-
|
350 |
-
|
351 |
-
|
352 |
-
|
353 |
-
|
354 |
-
|
355 |
-
|
356 |
-
|
357 |
-
|
358 |
-
|
359 |
-
|
360 |
-
|
361 |
-
|
362 |
-
|
363 |
-
|
364 |
-
|
365 |
-
|
366 |
-
|
367 |
-
|
368 |
-
|
369 |
-
|
370 |
-
|
371 |
-
|
372 |
-
|
373 |
-
|
374 |
-
|
375 |
-
|
376 |
-
|
377 |
-
|
378 |
-
|
379 |
-
|
380 |
-
|
381 |
-
|
382 |
-
$
|
383 |
-
|
384 |
-
|
385 |
-
|
386 |
-
|
387 |
-
|
388 |
-
|
389 |
-
|
390 |
-
|
391 |
-
|
392 |
-
|
393 |
-
|
394 |
-
|
395 |
-
|
396 |
-
|
397 |
-
|
398 |
-
|
399 |
-
|
400 |
-
|
401 |
-
|
402 |
-
|
403 |
-
|
404 |
-
|
405 |
-
|
406 |
-
|
407 |
-
|
408 |
-
|
409 |
-
|
410 |
-
|
411 |
-
|
412 |
-
|
413 |
-
|
414 |
-
|
415 |
-
|
416 |
-
|
417 |
-
|
418 |
-
|
419 |
-
|
420 |
-
|
421 |
-
|
422 |
-
|
423 |
-
}
|
424 |
-
|
425 |
-
|
426 |
-
static private function SaveMessageinMetadata($ID, $Message)
|
427 |
-
{
|
428 |
-
$meta = wp_get_attachment_metadata($ID);
|
429 |
-
$meta['ShortPixelImprovement'] = $Message;
|
430 |
-
unset($meta['ShortPixel']['WaitingProcessing']);
|
431 |
-
wp_update_attachment_metadata($ID, $meta);
|
432 |
-
}
|
433 |
-
|
434 |
-
public function parseJSON($data) {
|
435 |
-
if ( function_exists('json_decode') ) {
|
436 |
-
$data = json_decode( $data );
|
437 |
-
} else {
|
438 |
-
require_once( 'JSON/JSON.php' );
|
439 |
-
$json = new Services_JSON( );
|
440 |
-
$data = $json->decode( $data );
|
441 |
-
}
|
442 |
-
return $data;
|
443 |
-
}
|
444 |
-
}
|
1 |
+
<?php
|
2 |
+
if ( !function_exists( 'download_url' ) ) {
|
3 |
+
require_once( ABSPATH . 'wp-admin/includes/file.php' );
|
4 |
+
}
|
5 |
+
|
6 |
+
class ShortPixelAPI {
|
7 |
+
|
8 |
+
const STATUS_SUCCESS = 1;
|
9 |
+
const STATUS_UNCHANGED = 0;
|
10 |
+
const STATUS_ERROR = -1;
|
11 |
+
const STATUS_FAIL = -2;
|
12 |
+
const STATUS_QUOTA_EXCEEDED = -3;
|
13 |
+
const STATUS_SKIP = -4;
|
14 |
+
const STATUS_NOT_FOUND = -5;
|
15 |
+
const STATUS_NO_KEY = -6;
|
16 |
+
const STATUS_RETRY = -7;
|
17 |
+
|
18 |
+
private $_settings;
|
19 |
+
private $_maxAttempts = 10;
|
20 |
+
private $_apiEndPoint = 'https://api.shortpixel.com/v2/reducer_dev.php';
|
21 |
+
|
22 |
+
|
23 |
+
public function __construct($settings) {
|
24 |
+
$this->_settings = $settings;
|
25 |
+
add_action('processImageAction', array(&$this, 'processImageAction'), 10, 4);
|
26 |
+
}
|
27 |
+
|
28 |
+
public function processImageAction($url, $filePaths, $ID, $time) {
|
29 |
+
$this->processImage($URLs, $PATHs, $ID, $time);
|
30 |
+
}
|
31 |
+
|
32 |
+
public function doRequests($URLs, $Blocking, $ID) {
|
33 |
+
|
34 |
+
$requestParameters = array(
|
35 |
+
'plugin_version' => PLUGIN_VERSION,
|
36 |
+
'key' => $this->_settings->apiKey,
|
37 |
+
'lossy' => $this->_settings->compressionType,
|
38 |
+
'cmyk2rgb' => $this->_settings->CMYKtoRGBconversion,
|
39 |
+
'keep_exif' => ($this->_settings->keepExif ? "1" : "0"),
|
40 |
+
'resize' => $this->_settings->resizeImages,
|
41 |
+
'resize_width' => $this->_settings->resizeWidth,
|
42 |
+
'resize_height' => $this->_settings->resizeHeight,
|
43 |
+
'urllist' => $URLs
|
44 |
+
);
|
45 |
+
$arguments = array(
|
46 |
+
'method' => 'POST',
|
47 |
+
'timeout' => 45,
|
48 |
+
'redirection' => 3,
|
49 |
+
'sslverify' => false,
|
50 |
+
'httpversion' => '1.0',
|
51 |
+
'blocking' => $Blocking,
|
52 |
+
'headers' => array(),
|
53 |
+
'body' => json_encode($requestParameters),
|
54 |
+
'cookies' => array()
|
55 |
+
);
|
56 |
+
//echo("URL:".$this->_apiEndPoint."ARGUMENTS:");var_dump($arguments);
|
57 |
+
$response = wp_remote_post($this->_apiEndPoint, $arguments );
|
58 |
+
//echo("RESPONSE:"); var_dump($response);
|
59 |
+
|
60 |
+
//only if $Blocking is true analyze the response
|
61 |
+
if ( $Blocking )
|
62 |
+
{
|
63 |
+
//there was an error, save this error inside file's SP optimization field
|
64 |
+
if ( is_object($response) && get_class($response) == 'WP_Error' )
|
65 |
+
{
|
66 |
+
$errorMessage = $response->errors['http_request_failed'][0];
|
67 |
+
$errorCode = 503;
|
68 |
+
}
|
69 |
+
elseif ( isset($response['response']['code']) && $response['response']['code'] <> 200 )
|
70 |
+
{
|
71 |
+
$errorMessage = $response['response']['code'] . " - " . $response['response']['message'];
|
72 |
+
$errorCode = $response['response']['code'];
|
73 |
+
}
|
74 |
+
|
75 |
+
if ( isset($errorMessage) )
|
76 |
+
{//set details inside file so user can know what happened
|
77 |
+
$meta = wp_get_attachment_metadata($ID);
|
78 |
+
$meta['ShortPixelImprovement'] = 'Error: <i>' . $errorMessage . '</i>';
|
79 |
+
unset($meta['ShortPixel']['WaitingProcessing']);
|
80 |
+
wp_update_attachment_metadata($ID, $meta);
|
81 |
+
return array("response" => array("code" => $errorCode, "message" => $errorMessage ));
|
82 |
+
}
|
83 |
+
|
84 |
+
return $response;//this can be an error or a good response
|
85 |
+
}
|
86 |
+
|
87 |
+
return $response;
|
88 |
+
}
|
89 |
+
|
90 |
+
public function parseResponse($response) {
|
91 |
+
$data = $response['body'];
|
92 |
+
$data = $this->parseJSON($data);
|
93 |
+
return (array)$data;
|
94 |
+
}
|
95 |
+
|
96 |
+
//handles the processing of the image using the ShortPixel API
|
97 |
+
public function processImage($URLs, $PATHs, $ID = null, $startTime = 0)
|
98 |
+
{
|
99 |
+
|
100 |
+
$PATHs = self::CheckAndFixImagePaths($PATHs);//check for images to make sure they exist on disk
|
101 |
+
if ( $PATHs === false )
|
102 |
+
return array("Status" => self::STATUS_SKIP, "Message" => 'The file(s) do not exist on disk, Image ID: ' .$ID);
|
103 |
+
|
104 |
+
//tries multiple times (till timeout almost reached) to fetch images.
|
105 |
+
if($startTime == 0) {
|
106 |
+
$startTime = time();
|
107 |
+
}
|
108 |
+
$apiRetries = get_option('wp-short-pixel-api-retries');
|
109 |
+
if( time() - $startTime > MAX_EXECUTION_TIME)
|
110 |
+
{//keeps track of time
|
111 |
+
if ( $apiRetries > MAX_API_RETRIES )//we tried to process this time too many times, giving up...
|
112 |
+
{
|
113 |
+
$meta = wp_get_attachment_metadata($ID);
|
114 |
+
$meta['ShortPixelImprovement'] = 'Timed out while processing.';
|
115 |
+
unset($meta['ShortPixel']['WaitingProcessing']);
|
116 |
+
update_option('wp-short-pixel-api-retries', 0);//fai added to solve a bug?
|
117 |
+
wp_update_attachment_metadata($ID, $meta);
|
118 |
+
return array("Status" => self::STATUS_SKIP, "Message" => 'Skip this image, tries the next one.');
|
119 |
+
}
|
120 |
+
else
|
121 |
+
{//we'll try again next time user visits a page on admin panel
|
122 |
+
$apiRetries++;
|
123 |
+
update_option('wp-short-pixel-api-retries', $apiRetries);
|
124 |
+
return array("Status" => self::STATUS_RETRY, "Message" => 'Timed out while processing. (pass '.$apiRetries.')');
|
125 |
+
}
|
126 |
+
}
|
127 |
+
$response = $this->doRequests($URLs, true, $ID);//send requests to API
|
128 |
+
|
129 |
+
if($response['response']['code'] != 200)//response <> 200 -> there was an error apparently?
|
130 |
+
return array("Status" => self::STATUS_FAIL, "Message" => "There was an error and your request was not processed.");
|
131 |
+
|
132 |
+
$APIresponse = $this->parseResponse($response);//get the actual response from API, its an array
|
133 |
+
|
134 |
+
if ( isset($APIresponse[0]) )//API returned image details
|
135 |
+
{
|
136 |
+
foreach ( $APIresponse as $imageObject )//this part makes sure that all the sizes were processed and ready to be downloaded
|
137 |
+
{
|
138 |
+
if ( $imageObject->Status->Code == 0 || $imageObject->Status->Code == 1 )
|
139 |
+
{
|
140 |
+
sleep(1);
|
141 |
+
return $this->processImage($URLs, $PATHs, $ID, $startTime);
|
142 |
+
}
|
143 |
+
}
|
144 |
+
|
145 |
+
$firstImage = $APIresponse[0];//extract as object first image
|
146 |
+
switch($firstImage->Status->Code)
|
147 |
+
{
|
148 |
+
case 2:
|
149 |
+
//handle image has been processed
|
150 |
+
update_option( 'wp-short-pixel-quota-exceeded', 0);//reset the quota exceeded flag
|
151 |
+
return $this->handleSuccess($APIresponse, $URLs, $PATHs, $ID);
|
152 |
+
break;
|
153 |
+
default:
|
154 |
+
//handle error
|
155 |
+
if ( !file_exists($PATHs[0]) )
|
156 |
+
return array("Status" => self::STATUS_NOT_FOUND, "Message" => "File not found on disk.");
|
157 |
+
elseif ( isset($APIresponse[0]->Status->Message) )
|
158 |
+
return array("Status" => self::STATUS_FAIL, "Message" => "There was an error and your request was not processed (" . $APIresponse[0]->Status->Message . ").");
|
159 |
+
|
160 |
+
return array("Status" => self::STATUS_FAIL, "Message" => "There was an error and your request was not processed");
|
161 |
+
break;
|
162 |
+
}
|
163 |
+
}
|
164 |
+
|
165 |
+
switch($APIresponse['Status']->Code)
|
166 |
+
{
|
167 |
+
|
168 |
+
case -403:
|
169 |
+
@delete_option('bulkProcessingStatus');
|
170 |
+
update_option( 'wp-short-pixel-quota-exceeded', 1);
|
171 |
+
return array("Status" => self::STATUS_QUOTA_EXCEEDED, "Message" => "Quota exceeded.");
|
172 |
+
break;
|
173 |
+
}
|
174 |
+
|
175 |
+
//sometimes the response array can be different
|
176 |
+
if ( is_numeric($APIresponse['Status']->Code) )
|
177 |
+
return array("Status" => self::STATUS_FAIL, "Message" => $APIresponse['Status']->Message);
|
178 |
+
else
|
179 |
+
return array("Status" => self::STATUS_FAIL, "Message" => $APIresponse[0]->Status->Message);
|
180 |
+
|
181 |
+
}
|
182 |
+
|
183 |
+
public function handleDownload($fileData,$counter){
|
184 |
+
//var_dump($fileData);
|
185 |
+
if($this->_settings->compressionType)
|
186 |
+
{
|
187 |
+
$fileType = "LossyURL";
|
188 |
+
$fileSize = "LossySize";
|
189 |
+
}
|
190 |
+
else
|
191 |
+
{
|
192 |
+
$fileType = "LosslessURL";
|
193 |
+
$fileSize = "LoselessSize";
|
194 |
+
}
|
195 |
+
|
196 |
+
//if there is no improvement in size then we do not download this file
|
197 |
+
if ( $fileData->OriginalSize == $fileData->$fileSize )
|
198 |
+
return array("Status" => self::STATUS_UNCHANGED, "Message" => "File wasn't optimized so we do not download it.");
|
199 |
+
|
200 |
+
$correctFileSize = $fileData->$fileSize;
|
201 |
+
$tempFiles[$counter] = download_url(urldecode($fileData->$fileType));
|
202 |
+
//var_dump($tempFiles);
|
203 |
+
|
204 |
+
if(is_wp_error( $tempFiles[$counter] )) //also tries with http instead of https
|
205 |
+
{
|
206 |
+
$tempFiles[$counter] = download_url(str_replace('http://', 'https://', urldecode($fileData->$fileType)));
|
207 |
+
}
|
208 |
+
//on success we return this
|
209 |
+
$returnMessage = array("Status" => self::STATUS_SUCCESS, "Message" => $tempFiles[$counter]);
|
210 |
+
|
211 |
+
if ( is_wp_error( $tempFiles[$counter] ) ) {
|
212 |
+
@unlink($tempFiles[$counter]);
|
213 |
+
$returnMessage = array(
|
214 |
+
"Status" => self::STATUS_ERROR,
|
215 |
+
"Message" => "Error downloading file ({$fileData->$fileType}) " . $tempFiles[$counter]->get_error_message());
|
216 |
+
}
|
217 |
+
//check response so that download is OK
|
218 |
+
elseif( filesize($tempFiles[$counter]) != $correctFileSize) {
|
219 |
+
$size = filesize($tempFiles[$counter]);
|
220 |
+
@unlink($tempFiles[$counter]);
|
221 |
+
$returnMessage = array(
|
222 |
+
"Status" => self::STATUS_ERROR,
|
223 |
+
"Message" => "Error downloading file - incorrect file size (downloaded: {$size}, correct: {$correctFileSize} )");
|
224 |
+
}
|
225 |
+
elseif (!file_exists($tempFiles[$counter])) {
|
226 |
+
$returnMessage = array("Status" => self::STATUS_ERROR, "Message" => "Unable to locate downloaded file " . $tempFiles[$counter]);
|
227 |
+
}
|
228 |
+
return $returnMessage;
|
229 |
+
}
|
230 |
+
|
231 |
+
public function handleSuccess($APIresponse, $URLs, $PATHs, $ID) {
|
232 |
+
$counter = $savedSpace = $originalSpace = $optimizedSpace = $averageCompression = 0;
|
233 |
+
|
234 |
+
//download each file from array and process it
|
235 |
+
foreach ( $APIresponse as $fileData )
|
236 |
+
{
|
237 |
+
if ( $fileData->Status->Code == 2 ) //file was processed OK
|
238 |
+
{
|
239 |
+
if ( $counter == 0 )//save percent improvement for main file
|
240 |
+
$percentImprovement = $fileData->PercentImprovement;
|
241 |
+
else //count thumbnails only
|
242 |
+
update_option( 'wp-short-pixel-thumbnail-count', get_option('wp-short-pixel-thumbnail-count') + 1 );
|
243 |
+
$downloadResult = $this->handleDownload($fileData,$counter);
|
244 |
+
//when the status is STATUS_UNCHANGED we just skip the array line for that one
|
245 |
+
if ( $downloadResult['Status'] == self::STATUS_SUCCESS ) {
|
246 |
+
$tempFiles[$counter] = $downloadResult['Message'];
|
247 |
+
}
|
248 |
+
elseif ( $downloadResult['Status'] <> self::STATUS_UNCHANGED )
|
249 |
+
return array("Status" => $downloadResult['Status'], "Message" => $downloadResult['Message']);
|
250 |
+
}
|
251 |
+
else //there was an error while trying to download a file
|
252 |
+
$tempFiles[$counter] = "";
|
253 |
+
|
254 |
+
$counter++;
|
255 |
+
}
|
256 |
+
|
257 |
+
//figure out in what SubDir files should land
|
258 |
+
$SubDir = $this->returnSubDir(get_attached_file($ID));
|
259 |
+
|
260 |
+
//if backup is enabled - we try to save the images
|
261 |
+
if( get_option('wp-short-backup_images') )
|
262 |
+
{
|
263 |
+
$uploadDir = wp_upload_dir();
|
264 |
+
$source = $PATHs;//array with final paths for this files
|
265 |
+
|
266 |
+
if( !file_exists(SP_BACKUP_FOLDER) && !@mkdir(SP_BACKUP_FOLDER, 0777, true) ) {//creates backup folder if it doesn't exist
|
267 |
+
return array("Status" => self::STATUS_FAIL, "Message" => "Backup folder does not exist and it cannot be created");
|
268 |
+
}
|
269 |
+
//create subdir in backup folder if needed
|
270 |
+
@mkdir( SP_BACKUP_FOLDER . DIRECTORY_SEPARATOR . $SubDir, 0777, true);
|
271 |
+
|
272 |
+
foreach ( $source as $fileID => $filePATH )//create destination files array
|
273 |
+
{
|
274 |
+
$destination[$fileID] = SP_BACKUP_FOLDER . DIRECTORY_SEPARATOR . $SubDir . self::MB_basename($source[$fileID]);
|
275 |
+
}
|
276 |
+
|
277 |
+
//now that we have original files and where we should back them up we attempt to do just that
|
278 |
+
if(is_writable(SP_BACKUP_FOLDER))
|
279 |
+
{
|
280 |
+
foreach ( $destination as $fileID => $filePATH )
|
281 |
+
{
|
282 |
+
if ( !file_exists($filePATH) )
|
283 |
+
{
|
284 |
+
if ( !@copy($source[$fileID], $destination[$fileID]) )
|
285 |
+
{//file couldn't have been saved in backup folder
|
286 |
+
ShortPixelAPI::SaveMessageinMetadata($ID, 'Cannot save file <i>' . self::MB_basename($source[$fileID]) . '</i> in backup directory');
|
287 |
+
return array("Status" => self::STATUS_FAIL, "Message" => 'Cannot save file <i>' . self::MB_basename($source[$fileID]) . '</i> in backup directory');
|
288 |
+
}
|
289 |
+
}
|
290 |
+
}
|
291 |
+
} else {//cannot write to the backup dir, return with an error
|
292 |
+
ShortPixelAPI::SaveMessageinMetadata($ID, 'Cannot save file in backup directory');
|
293 |
+
return array("Status" => self::STATUS_FAIL, "Message" => 'Cannot save file in backup directory');
|
294 |
+
}
|
295 |
+
|
296 |
+
}//end backup section
|
297 |
+
|
298 |
+
|
299 |
+
$writeFailed = 0;
|
300 |
+
|
301 |
+
if ( !empty($tempFiles) )
|
302 |
+
{
|
303 |
+
//overwrite the original files with the optimized ones
|
304 |
+
foreach ( $tempFiles as $tempFileID => $tempFilePATH )
|
305 |
+
{
|
306 |
+
if ( file_exists($tempFilePATH) && file_exists($PATHs[$tempFileID]) && is_writable($PATHs[$tempFileID]) ) {
|
307 |
+
copy($tempFilePATH, $PATHs[$tempFileID]);
|
308 |
+
} else {
|
309 |
+
$writeFailed++;
|
310 |
+
}
|
311 |
+
@unlink($tempFilePATH);
|
312 |
+
|
313 |
+
if ( $writeFailed > 0 )//there was an error
|
314 |
+
{
|
315 |
+
ShortPixelAPI::SaveMessageinMetadata($ID, 'Error: optimized version of ' . $writeFailed . ' file(s) couldn\'t be updated.');
|
316 |
+
update_option('bulkProcessingStatus', "error");
|
317 |
+
return array("Status" => self::STATUS_FAIL, "Code" =>"write-fail", "Message" => 'Error: optimized version of ' . $writeFailed . ' file(s) couldn\'t be updated.');
|
318 |
+
}
|
319 |
+
else
|
320 |
+
{//all files were copied, optimization data regarding the savings locally in DB
|
321 |
+
$fileType = ( $this->_settings->compressionType ) ? "LossySize" : "LoselessSize";
|
322 |
+
$savedSpace += $APIresponse[$tempFileID]->OriginalSize - $APIresponse[$tempFileID]->$fileType;
|
323 |
+
$originalSpace += $APIresponse[$tempFileID]->OriginalSize;
|
324 |
+
$optimizedSpace += $APIresponse[$tempFileID]->$fileType;
|
325 |
+
$averageCompression += $fileData->PercentImprovement;
|
326 |
+
|
327 |
+
//add the number of files with < 5% optimization
|
328 |
+
if ( ( ( 1 - $APIresponse[$tempFileID]->$fileType/$APIresponse[$tempFileID]->OriginalSize ) * 100 ) < 5 )
|
329 |
+
$this->_settings->under5Percent++;
|
330 |
+
|
331 |
+
}
|
332 |
+
}
|
333 |
+
}
|
334 |
+
//old average counting
|
335 |
+
$this->_settings->savedSpace += $savedSpace;
|
336 |
+
$averageCompression = $this->_settings->averageCompression * $this->_settings->fileCount;
|
337 |
+
$averageCompression = $averageCompression / ($this->_settings->fileCount + count($APIresponse));
|
338 |
+
$this->_settings->averageCompression = $averageCompression;
|
339 |
+
$this->_settings->fileCount += count($APIresponse);
|
340 |
+
//new average counting
|
341 |
+
$this->_settings->totalOriginal += $originalSpace;
|
342 |
+
$this->_settings->totalOptimized += $optimizedSpace;
|
343 |
+
//update metadata for this file
|
344 |
+
$meta = wp_get_attachment_metadata($ID);
|
345 |
+
$meta['ShortPixelImprovement'] = round($percentImprovement,2);
|
346 |
+
$meta['ShortPixel']['type'] = $this->_settings->compressionType == 1 ? 'lossy' : 'lossless';
|
347 |
+
$meta['ShortPixel']['thumbsOpt'] = $this->_settings->processThumbnails && isset($meta['sizes']) ? count($meta['sizes']) : 0;
|
348 |
+
wp_update_attachment_metadata($ID, $meta);
|
349 |
+
//we reset the retry counter in case of success
|
350 |
+
update_option('wp-short-pixel-api-retries', 0);
|
351 |
+
|
352 |
+
return array("Status" => self::STATUS_SUCCESS, "Message" => 'Success: No pixels remained unsqueezed :-)', "PercentImprovement" => $percentImprovement);
|
353 |
+
}//end handleSuccess
|
354 |
+
|
355 |
+
static public function returnSubDir($file)//return subdir for that particular attached file
|
356 |
+
{
|
357 |
+
$Atoms = explode("/", $file);
|
358 |
+
$Counter = count($Atoms);
|
359 |
+
$SubDir = $Atoms[$Counter-3] . DIRECTORY_SEPARATOR . $Atoms[$Counter-2] . DIRECTORY_SEPARATOR;
|
360 |
+
|
361 |
+
return $SubDir;
|
362 |
+
}
|
363 |
+
|
364 |
+
//a basename alternative that deals OK with multibyte charsets (e.g. Arabic)
|
365 |
+
static public function MB_basename($Path){
|
366 |
+
$Separator = " qq ";
|
367 |
+
$Path = preg_replace("/[^ ]/u", $Separator."\$0".$Separator, $Path);
|
368 |
+
$Base = basename($Path);
|
369 |
+
$Base = str_replace($Separator, "", $Base);
|
370 |
+
return $Base;
|
371 |
+
}
|
372 |
+
|
373 |
+
//sometimes, the paths to the files as defined in metadata are wrong, we try to automatically correct them
|
374 |
+
static public function CheckAndFixImagePaths($PATHs){
|
375 |
+
|
376 |
+
$ErrorCount = 0;
|
377 |
+
$uploadDir = wp_upload_dir();
|
378 |
+
$Tmp = explode("/", $uploadDir['basedir']);
|
379 |
+
$TmpCount = count($Tmp);
|
380 |
+
$StichString = $Tmp[$TmpCount-2] . "/" . $Tmp[$TmpCount-1];
|
381 |
+
//files exist on disk?
|
382 |
+
foreach ( $PATHs as $Id => $File )
|
383 |
+
{
|
384 |
+
//we try again with a different path
|
385 |
+
if ( !file_exists($File) ){
|
386 |
+
//$NewFile = $uploadDir['basedir'] . "/" . substr($File,strpos($File, $StichString));//+strlen($StichString));
|
387 |
+
$NewFile = $uploadDir['basedir'] . substr($File,strpos($File, $StichString)+strlen($StichString));
|
388 |
+
if ( file_exists($NewFile) )
|
389 |
+
$PATHs[$Id] = $NewFile;
|
390 |
+
else
|
391 |
+
$ErrorCount++;
|
392 |
+
}
|
393 |
+
}
|
394 |
+
|
395 |
+
if ( $ErrorCount > 0 )
|
396 |
+
return false;
|
397 |
+
else
|
398 |
+
return $PATHs;
|
399 |
+
|
400 |
+
}
|
401 |
+
|
402 |
+
|
403 |
+
static private function SaveMessageinMetadata($ID, $Message)
|
404 |
+
{
|
405 |
+
$meta = wp_get_attachment_metadata($ID);
|
406 |
+
$meta['ShortPixelImprovement'] = $Message;
|
407 |
+
unset($meta['ShortPixel']['WaitingProcessing']);
|
408 |
+
wp_update_attachment_metadata($ID, $meta);
|
409 |
+
}
|
410 |
+
|
411 |
+
public function parseJSON($data) {
|
412 |
+
if ( function_exists('json_decode') ) {
|
413 |
+
$data = json_decode( $data );
|
414 |
+
} else {
|
415 |
+
require_once( 'JSON/JSON.php' );
|
416 |
+
$json = new Services_JSON( );
|
417 |
+
$data = $json->decode( $data );
|
418 |
+
}
|
419 |
+
return $data;
|
420 |
+
}
|
421 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
shortpixel_queue.php
CHANGED
@@ -2,7 +2,8 @@
|
|
2 |
|
3 |
class ShortPixelQueue {
|
4 |
|
5 |
-
private $ctrl;
|
|
|
6 |
private $startBulkId;
|
7 |
private $stopBulkId;
|
8 |
private $bulkCount;
|
@@ -18,17 +19,13 @@ class ShortPixelQueue {
|
|
18 |
const BULK_PAUSED = 2; //bulk is paused
|
19 |
const BULK_FINISHED = 3; //bulk finished
|
20 |
|
21 |
-
|
22 |
-
public function ShortPixelQueue($controller) {
|
23 |
-
$this->__construct($controller);
|
24 |
-
}
|
25 |
-
|
26 |
-
public function __construct($controller) {
|
27 |
$this->ctrl = $controller;
|
|
|
28 |
//init the option if needed
|
29 |
if(!isset($_SESSION["wp-short-pixel-priorityQueue"])) {
|
30 |
//take the priority list from the options (we persist there the priority IDs from the previous session)
|
31 |
-
$prioQueueOpt =
|
32 |
$_SESSION["wp-short-pixel-priorityQueue"] = array();
|
33 |
foreach($prioQueueOpt as $ID) {
|
34 |
$meta = wp_get_attachment_metadata($ID);
|
@@ -37,22 +34,27 @@ class ShortPixelQueue {
|
|
37 |
$this->push($ID);
|
38 |
}
|
39 |
}
|
40 |
-
|
41 |
WPShortPixel::log("INIT: Session queue not found, updated from Options with "
|
42 |
.json_encode($_SESSION["wp-short-pixel-priorityQueue"]));
|
43 |
}
|
44 |
|
45 |
-
$this->startBulkId =
|
46 |
-
$this->stopBulkId =
|
47 |
-
$this->bulkCount =
|
48 |
-
$this->bulkPreviousPercent =
|
49 |
-
$this->bulkCurrentlyProcessed =
|
50 |
-
$this->bulkAlreadyDoneCount =
|
51 |
-
$this->lastBulkStartTime =
|
52 |
-
$this->lastBulkSuccessTime =
|
53 |
-
$this->bulkRunningTime =
|
54 |
}
|
55 |
|
|
|
|
|
|
|
|
|
|
|
56 |
public function get() {
|
57 |
return $_SESSION["wp-short-pixel-priorityQueue"];//get_option("wp-short-pixel-priorityQueue");
|
58 |
}
|
@@ -65,7 +67,7 @@ class ShortPixelQueue {
|
|
65 |
$prioQ = array_unique($priorityQueue);
|
66 |
$_SESSION["wp-short-pixel-priorityQueue"] = $prioQ;
|
67 |
//push also to the options queue, in case the session gets killed retrieve frm there
|
68 |
-
|
69 |
|
70 |
WPShortPixel::log("PUSH: Updated: ".json_encode($_SESSION["wp-short-pixel-priorityQueue"]));//get_option("wp-short-pixel-priorityQueue")));
|
71 |
}
|
@@ -90,31 +92,31 @@ class ShortPixelQueue {
|
|
90 |
$found = true;
|
91 |
}
|
92 |
}
|
93 |
-
|
94 |
$_SESSION["wp-short-pixel-priorityQueue"] = $newPriorityQueue;
|
95 |
WPShortPixel::log("REM: " . ($found ? "Updated: " : "Not found") . json_encode($_SESSION["wp-short-pixel-priorityQueue"]));//get_option("wp-short-pixel-priorityQueue")));
|
96 |
return $found;
|
97 |
}
|
98 |
|
99 |
public function removeFromFailed($ID) {
|
100 |
-
$failed = explode(",",
|
101 |
$key = array_search($ID, $failed);
|
102 |
if($key !== false) {
|
103 |
unset($failed[$key]);
|
104 |
$failed = array_values($failed);
|
105 |
-
|
106 |
}
|
107 |
}
|
108 |
|
109 |
public function addToFailed($ID) {
|
110 |
-
$failed =
|
111 |
if(!in_array($ID, explode(",", $failed))) {
|
112 |
-
|
113 |
}
|
114 |
}
|
115 |
|
116 |
public function getFailed() {
|
117 |
-
$failed =
|
118 |
if(!strlen($failed)) return array();
|
119 |
return explode(",", $failed);
|
120 |
}
|
@@ -126,11 +128,11 @@ class ShortPixelQueue {
|
|
126 |
|
127 |
public function bulkPaused() {
|
128 |
WPShortPixel::log("Bulk Paused: " . get_option( 'wp-short-pixel-cancel-pointer'));
|
129 |
-
return
|
130 |
}
|
131 |
|
132 |
public function bulkRan() {
|
133 |
-
return
|
134 |
}
|
135 |
|
136 |
public function processing() {
|
@@ -139,7 +141,7 @@ class ShortPixelQueue {
|
|
139 |
}
|
140 |
|
141 |
public function getFlagBulkId() {
|
142 |
-
return
|
143 |
}
|
144 |
|
145 |
public function getStartBulkId() {
|
@@ -152,7 +154,7 @@ class ShortPixelQueue {
|
|
152 |
|
153 |
public function setStartBulkId($start){
|
154 |
$this->startBulkId = $start;
|
155 |
-
|
156 |
}
|
157 |
|
158 |
public function getStopBulkId() {
|
@@ -161,21 +163,21 @@ class ShortPixelQueue {
|
|
161 |
|
162 |
public function resetStopBulkId() {
|
163 |
$this->stopBulkId = $this->ctrl->getMinMediaId();
|
164 |
-
|
165 |
}
|
166 |
|
167 |
public function setBulkPreviousPercent() {
|
168 |
//processable
|
169 |
$res = $this->ctrl->countAllProcessableFiles($this->getFlagBulkId(), $this->stopBulkId);
|
170 |
$this->bulkCount = $res["mainFiles"];
|
171 |
-
|
172 |
//already processed
|
173 |
$res = $this->ctrl->countAllProcessedFiles($this->getFlagBulkId(), $this->stopBulkId);
|
174 |
$this->bulkAlreadyDoneCount = $res["mainFiles"];
|
175 |
-
|
176 |
//percent already done
|
177 |
$this->bulkPreviousPercent = round($this->bulkAlreadyDoneCount / $this->bulkCount *100);
|
178 |
-
|
179 |
}
|
180 |
|
181 |
public function getBulkToProcess() {
|
@@ -183,7 +185,7 @@ class ShortPixelQueue {
|
|
183 |
}
|
184 |
|
185 |
public function flagBulkStart() {
|
186 |
-
|
187 |
delete_option('bulkProcessingStatus');
|
188 |
add_option('bulkProcessingStatus', 'running');//set bulk flag
|
189 |
}
|
@@ -194,13 +196,13 @@ class ShortPixelQueue {
|
|
194 |
$this->flagBulkStart(); //we use this to detect new added files while bulk is running
|
195 |
$this->setBulkPreviousPercent();
|
196 |
$this->resetBulkCurrentlyProcessed();
|
197 |
-
|
198 |
}
|
199 |
|
200 |
public function pauseBulk() {
|
201 |
$cancelPointer = $this->startBulkId;
|
202 |
$bulkStartId = $this->getFlagBulkId();
|
203 |
-
|
204 |
WPShortPixel::log("PAUSE: Pointer = ".get_option( 'wp-short-pixel-cancel-pointer'));
|
205 |
//remove the bulk items from prio queue
|
206 |
foreach($this->get() as $qItem) {
|
@@ -214,18 +216,18 @@ class ShortPixelQueue {
|
|
214 |
public function stopBulk() {
|
215 |
$this->startBulkId = WPShortPixel::getMaxMediaId();
|
216 |
$this->stopBulkId = $this->startBulkId;
|
217 |
-
|
218 |
-
|
219 |
delete_option('bulkProcessingStatus');
|
220 |
-
return
|
221 |
}
|
222 |
|
223 |
public function resumeBulk() {
|
224 |
$this->startBulkId = get_option( 'wp-short-pixel-cancel-pointer');
|
225 |
-
|
226 |
$this->stopBulkId = $this->ctrl->getMinMediaId();
|
227 |
-
|
228 |
-
|
229 |
add_option('bulkProcessingStatus', 'running');//set bulk flag
|
230 |
delete_option( 'wp-short-pixel-cancel-pointer');
|
231 |
WPShortPixel::log("Resumed: (pause says: " . $this->bulkPaused() . ") Start from: " . $this->startBulkId . " to " . $this->stopBulkId);
|
@@ -233,12 +235,12 @@ class ShortPixelQueue {
|
|
233 |
|
234 |
public function resetBulkCurrentlyProcessed() {
|
235 |
$this->bulkCurrentlyProcessed = 0;
|
236 |
-
|
237 |
}
|
238 |
|
239 |
public function incrementBulkCurrentlyProcessed() {
|
240 |
$this->bulkCurrentlyProcessed++;
|
241 |
-
|
242 |
}
|
243 |
|
244 |
public function markBulkComplete() {
|
@@ -275,13 +277,13 @@ class ShortPixelQueue {
|
|
275 |
$this->incrementBulkCurrentlyProcessed();
|
276 |
if($t - $this->lastBulkSuccessTime > 120) { //if break longer than two minutes we mark a pause in the bulk
|
277 |
$this->bulkRunningTime += ($this->lastBulkSuccessTime - $this->lastBulkStartTime);
|
278 |
-
|
279 |
$this->lastBulkStartTime = $this->lastBulkSuccessTime = $t;
|
280 |
-
|
281 |
-
|
282 |
} else {
|
283 |
$this->lastBulkSuccessTime = $t;
|
284 |
-
|
285 |
}
|
286 |
}
|
287 |
|
2 |
|
3 |
class ShortPixelQueue {
|
4 |
|
5 |
+
private $ctrl;
|
6 |
+
private $settings;
|
7 |
private $startBulkId;
|
8 |
private $stopBulkId;
|
9 |
private $bulkCount;
|
19 |
const BULK_PAUSED = 2; //bulk is paused
|
20 |
const BULK_FINISHED = 3; //bulk finished
|
21 |
|
22 |
+
public function __construct($controller, $settings) {
|
|
|
|
|
|
|
|
|
|
|
23 |
$this->ctrl = $controller;
|
24 |
+
$this->settings = $settings;
|
25 |
//init the option if needed
|
26 |
if(!isset($_SESSION["wp-short-pixel-priorityQueue"])) {
|
27 |
//take the priority list from the options (we persist there the priority IDs from the previous session)
|
28 |
+
$prioQueueOpt = $this->settings->getOpt( 'wp-short-pixel-priorityQueue', array());//here we save the IDs for the files that need to be processed after an image upload for example
|
29 |
$_SESSION["wp-short-pixel-priorityQueue"] = array();
|
30 |
foreach($prioQueueOpt as $ID) {
|
31 |
$meta = wp_get_attachment_metadata($ID);
|
34 |
$this->push($ID);
|
35 |
}
|
36 |
}
|
37 |
+
$this->settings->setOpt('wp-short-pixel-priorityQueue', $_SESSION["wp-short-pixel-priorityQueue"]);
|
38 |
WPShortPixel::log("INIT: Session queue not found, updated from Options with "
|
39 |
.json_encode($_SESSION["wp-short-pixel-priorityQueue"]));
|
40 |
}
|
41 |
|
42 |
+
$this->startBulkId = $this->settings->getOpt( 'wp-short-pixel-query-id-start', 0);//current query ID used for postmeta queries
|
43 |
+
$this->stopBulkId = $this->settings->getOpt( 'wp-short-pixel-query-id-stop', 0);//min ID used for postmeta queries
|
44 |
+
$this->bulkCount = $this->settings->getOpt( "wp-short-pixel-bulk-count", 0);
|
45 |
+
$this->bulkPreviousPercent = $this->settings->getOpt( "wp-short-pixel-bulk-previous-percent", 0);
|
46 |
+
$this->bulkCurrentlyProcessed = $this->settings->getOpt( "wp-short-pixel-bulk-processed-items", 0);
|
47 |
+
$this->bulkAlreadyDoneCount = $this->settings->getOpt( "wp-short-pixel-bulk-done-count", 0);
|
48 |
+
$this->lastBulkStartTime = $this->settings->getOpt( 'wp-short-pixel-last-bulk-start-time', 0);//time of the last start of the bulk.
|
49 |
+
$this->lastBulkSuccessTime = $this->settings->getOpt( 'wp-short-pixel-last-bulk-success-time', 0);//time of the last start of the bulk.
|
50 |
+
$this->bulkRunningTime = $this->settings->getOpt( 'wp-short-pixel-bulk-running-time', 0);//how long the bulk ran that far.
|
51 |
}
|
52 |
|
53 |
+
//handling older
|
54 |
+
public function ShortPixelQueue($controller) {
|
55 |
+
$this->__construct($controller);
|
56 |
+
}
|
57 |
+
|
58 |
public function get() {
|
59 |
return $_SESSION["wp-short-pixel-priorityQueue"];//get_option("wp-short-pixel-priorityQueue");
|
60 |
}
|
67 |
$prioQ = array_unique($priorityQueue);
|
68 |
$_SESSION["wp-short-pixel-priorityQueue"] = $prioQ;
|
69 |
//push also to the options queue, in case the session gets killed retrieve frm there
|
70 |
+
$this->settings->setOpt('wp-short-pixel-priorityQueue', $prioQ);
|
71 |
|
72 |
WPShortPixel::log("PUSH: Updated: ".json_encode($_SESSION["wp-short-pixel-priorityQueue"]));//get_option("wp-short-pixel-priorityQueue")));
|
73 |
}
|
92 |
$found = true;
|
93 |
}
|
94 |
}
|
95 |
+
//$this->settings->setOpt("wp-short-pixel-priorityQueue", $newPriorityQueue);
|
96 |
$_SESSION["wp-short-pixel-priorityQueue"] = $newPriorityQueue;
|
97 |
WPShortPixel::log("REM: " . ($found ? "Updated: " : "Not found") . json_encode($_SESSION["wp-short-pixel-priorityQueue"]));//get_option("wp-short-pixel-priorityQueue")));
|
98 |
return $found;
|
99 |
}
|
100 |
|
101 |
public function removeFromFailed($ID) {
|
102 |
+
$failed = explode(",", $this->settings->getOpt('wp-short-pixel-failed-imgs',''));
|
103 |
$key = array_search($ID, $failed);
|
104 |
if($key !== false) {
|
105 |
unset($failed[$key]);
|
106 |
$failed = array_values($failed);
|
107 |
+
$this->settings->setOpt('wp-short-pixel-failed-imgs', implode(",", $failed) );
|
108 |
}
|
109 |
}
|
110 |
|
111 |
public function addToFailed($ID) {
|
112 |
+
$failed = $this->settings->getOpt('wp-short-pixel-failed-imgs','');
|
113 |
if(!in_array($ID, explode(",", $failed))) {
|
114 |
+
$this->settings->setOpt('wp-short-pixel-failed-imgs', (strlen($failed) ? $failed . "," : "") . $ID );
|
115 |
}
|
116 |
}
|
117 |
|
118 |
public function getFailed() {
|
119 |
+
$failed = $this->settings->getOpt('wp-short-pixel-failed-imgs','');
|
120 |
if(!strlen($failed)) return array();
|
121 |
return explode(",", $failed);
|
122 |
}
|
128 |
|
129 |
public function bulkPaused() {
|
130 |
WPShortPixel::log("Bulk Paused: " . get_option( 'wp-short-pixel-cancel-pointer'));
|
131 |
+
return $this->settings->getOpt( 'wp-short-pixel-cancel-pointer', 0);
|
132 |
}
|
133 |
|
134 |
public function bulkRan() {
|
135 |
+
return $this->settings->getOpt("wp-short-pixel-bulk-ever-ran", 0) != 0;
|
136 |
}
|
137 |
|
138 |
public function processing() {
|
141 |
}
|
142 |
|
143 |
public function getFlagBulkId() {
|
144 |
+
return $this->settings->getOpt("wp-short-pixel-flag-id",0);
|
145 |
}
|
146 |
|
147 |
public function getStartBulkId() {
|
154 |
|
155 |
public function setStartBulkId($start){
|
156 |
$this->startBulkId = $start;
|
157 |
+
$this->settings->setOpt("wp-short-pixel-query-id-start", $this->startBulkId);
|
158 |
}
|
159 |
|
160 |
public function getStopBulkId() {
|
163 |
|
164 |
public function resetStopBulkId() {
|
165 |
$this->stopBulkId = $this->ctrl->getMinMediaId();
|
166 |
+
$this->settings->setOpt("wp-short-pixel-query-id-stop", $this->stopBulkId);
|
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 |
//already processed
|
175 |
$res = $this->ctrl->countAllProcessedFiles($this->getFlagBulkId(), $this->stopBulkId);
|
176 |
$this->bulkAlreadyDoneCount = $res["mainFiles"];
|
177 |
+
$this->settings->setOpt("wp-short-pixel-bulk-done-count", $this->bulkAlreadyDoneCount);
|
178 |
//percent already done
|
179 |
$this->bulkPreviousPercent = round($this->bulkAlreadyDoneCount / $this->bulkCount *100);
|
180 |
+
$this->settings->setOpt("wp-short-pixel-bulk-previous-percent", $this->bulkPreviousPercent);
|
181 |
}
|
182 |
|
183 |
public function getBulkToProcess() {
|
185 |
}
|
186 |
|
187 |
public function flagBulkStart() {
|
188 |
+
$this->settings->setOpt("wp-short-pixel-flag-id", $this->startBulkId);
|
189 |
delete_option('bulkProcessingStatus');
|
190 |
add_option('bulkProcessingStatus', 'running');//set bulk flag
|
191 |
}
|
196 |
$this->flagBulkStart(); //we use this to detect new added files while bulk is running
|
197 |
$this->setBulkPreviousPercent();
|
198 |
$this->resetBulkCurrentlyProcessed();
|
199 |
+
$this->settings->setOpt( 'wp-short-pixel-bulk-ever-ran', 1);
|
200 |
}
|
201 |
|
202 |
public function pauseBulk() {
|
203 |
$cancelPointer = $this->startBulkId;
|
204 |
$bulkStartId = $this->getFlagBulkId();
|
205 |
+
$this->settings->setOpt( 'wp-short-pixel-cancel-pointer', $cancelPointer);//we save this so we can resume bulk processing
|
206 |
WPShortPixel::log("PAUSE: Pointer = ".get_option( 'wp-short-pixel-cancel-pointer'));
|
207 |
//remove the bulk items from prio queue
|
208 |
foreach($this->get() as $qItem) {
|
216 |
public function stopBulk() {
|
217 |
$this->startBulkId = WPShortPixel::getMaxMediaId();
|
218 |
$this->stopBulkId = $this->startBulkId;
|
219 |
+
$this->settings->setOpt("wp-short-pixel-query-id-start", $this->startBulkId);
|
220 |
+
$this->settings->setOpt("wp-short-pixel-query-id-stop", $this->stopBulkId);
|
221 |
delete_option('bulkProcessingStatus');
|
222 |
+
return $this->settings->getOpt('wp-short-pixel-bulk-ever-ran', 0);
|
223 |
}
|
224 |
|
225 |
public function resumeBulk() {
|
226 |
$this->startBulkId = get_option( 'wp-short-pixel-cancel-pointer');
|
227 |
+
$this->settings->setOpt("wp-short-pixel-query-id-start", $this->startBulkId);//start downwards from the biggest item ID
|
228 |
$this->stopBulkId = $this->ctrl->getMinMediaId();
|
229 |
+
$this->settings->setOpt("wp-short-pixel-query-id-stop", $this->stopBulkId);
|
230 |
+
//$this->settings->setOpt("wp-short-pixel-flag-id", $this->startBulkId);//we use to detect new added files while bulk is running
|
231 |
add_option('bulkProcessingStatus', 'running');//set bulk flag
|
232 |
delete_option( 'wp-short-pixel-cancel-pointer');
|
233 |
WPShortPixel::log("Resumed: (pause says: " . $this->bulkPaused() . ") Start from: " . $this->startBulkId . " to " . $this->stopBulkId);
|
235 |
|
236 |
public function resetBulkCurrentlyProcessed() {
|
237 |
$this->bulkCurrentlyProcessed = 0;
|
238 |
+
$this->settings->setOpt( "wp-short-pixel-bulk-processed-items", $this->bulkCurrentlyProcessed);
|
239 |
}
|
240 |
|
241 |
public function incrementBulkCurrentlyProcessed() {
|
242 |
$this->bulkCurrentlyProcessed++;
|
243 |
+
$this->settings->setOpt( "wp-short-pixel-bulk-processed-items", $this->bulkCurrentlyProcessed);
|
244 |
}
|
245 |
|
246 |
public function markBulkComplete() {
|
277 |
$this->incrementBulkCurrentlyProcessed();
|
278 |
if($t - $this->lastBulkSuccessTime > 120) { //if break longer than two minutes we mark a pause in the bulk
|
279 |
$this->bulkRunningTime += ($this->lastBulkSuccessTime - $this->lastBulkStartTime);
|
280 |
+
$this->settings->setOpt('wp-short-pixel-bulk-running-time', $this->bulkRunningTime);
|
281 |
$this->lastBulkStartTime = $this->lastBulkSuccessTime = $t;
|
282 |
+
$this->settings->setOpt('wp-short-pixel-last-bulk-start-time', $t);
|
283 |
+
$this->settings->setOpt('wp-short-pixel-last-bulk-success-time', $t);
|
284 |
} else {
|
285 |
$this->lastBulkSuccessTime = $t;
|
286 |
+
$this->settings->setOpt('wp-short-pixel-last-bulk-success-time', $t);
|
287 |
}
|
288 |
}
|
289 |
|
shortpixel_view.php
CHANGED
@@ -4,15 +4,15 @@ class ShortPixelView {
|
|
4 |
|
5 |
private $ctrl;
|
6 |
|
|
|
|
|
|
|
|
|
7 |
//handling older
|
8 |
public function ShortPixelView($controller) {
|
9 |
$this->__construct($controller);
|
10 |
}
|
11 |
|
12 |
-
public function __construct($controller) {
|
13 |
-
$this->ctrl = $controller;
|
14 |
-
}
|
15 |
-
|
16 |
public function displayQuotaExceededAlert($quotaData)
|
17 |
{ ?>
|
18 |
<br/>
|
@@ -327,9 +327,11 @@ class ShortPixelView {
|
|
327 |
}
|
328 |
|
329 |
public function displaySettingsForm($quotaData) {
|
|
|
330 |
$checked = ($this->ctrl->processThumbnails() ? 'checked' : '');
|
331 |
$checkedBackupImages = ($this->ctrl->backupImages() ? 'checked' : '');
|
332 |
$cmyk2rgb = ($this->ctrl->getCMYKtoRGBconversion() ? 'checked' : '');
|
|
|
333 |
$resize = ($this->ctrl->getResizeImages() ? 'checked' : '');
|
334 |
$resizeDisabled = ($this->ctrl->getResizeImages() ? '' : 'disabled');
|
335 |
$minSizes = $this->ctrl->getMaxIntermediateImageSize();
|
@@ -364,13 +366,13 @@ class ShortPixelView {
|
|
364 |
<label for="compressionType">Compression type:</label>
|
365 |
</th>
|
366 |
<td>
|
367 |
-
<input type="radio" name="compressionType" value="1" <?= $this->ctrl->getCompressionType() == 1 ? "checked" : "" ?>>Lossy</br>
|
368 |
-
<p class="settings-info"> <b>Lossy compression: </b>lossy has a better compression rate than lossless compression.</br>
|
369 |
-
is not 100% identical with the original
|
|
|
370 |
<input type="radio" name="compressionType" value="0" <?= $this->ctrl->getCompressionType() != 1 ? "checked" : "" ?>>Lossless
|
371 |
-
<p class="settings-info"><b>Lossless compression: </b> the shrunk image will be identical with the original and smaller in size.</br>
|
372 |
-
|
373 |
-
clip art and comics. </p>
|
374 |
</td>
|
375 |
</tr>
|
376 |
</tbody>
|
@@ -381,27 +383,37 @@ class ShortPixelView {
|
|
381 |
<th scope="row"><label for="thumbnails">Also include thumbnails:</label></th>
|
382 |
<td><input name="thumbnails" type="checkbox" id="thumbnails" <?= $checked ?>> Apply compression also to
|
383 |
<strong><?=$thumbnailsToProcess ? number_format($thumbnailsToProcess) : ""?> image thumbnails.</strong>
|
384 |
-
<p class="settings-info">
|
385 |
</td>
|
386 |
</tr>
|
387 |
<tr>
|
388 |
<th scope="row"><label for="backupImages">Image backup</label></th>
|
389 |
<td>
|
390 |
<input name="backupImages" type="checkbox" id="backupImages" <?= $checkedBackupImages ?>> Save and keep a backup of your original images in a separate folder.
|
|
|
391 |
</td>
|
392 |
</tr>
|
393 |
<tr>
|
394 |
-
<th scope="row"><label for="
|
395 |
<td>
|
396 |
<input name="cmyk2rgb" type="checkbox" id="cmyk2rgb" <?= $cmyk2rgb ?>>Adjust your images for computer and mobile screen display.
|
397 |
</td>
|
398 |
</tr>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
399 |
<tr>
|
400 |
<th scope="row"><label for="resize">Resize large images</label></th>
|
401 |
<td>
|
402 |
<input name="resize" type="checkbox" id="resize" <?= $resize ?>> to maximum
|
403 |
<input type="text" name="width" id="width" style="width:70px" value="<?= max($this->ctrl->getResizeWidth(), min(1024, $minSizes['width'])) ?>" <?= $resizeDisabled ?>/> pixels wide ×
|
404 |
-
<input type="text" name="height" id="height" style="width:70px" value="<?= max($this->ctrl->getResizeHeight(), min(1024, $minSizes['height'])) ?>" <?= $resizeDisabled ?>/> pixels high
|
405 |
<p class="settings-info"> Recommended for large photos, like the ones taken with your phone. Saved space can go up to 80% or more after resizing.<br/>
|
406 |
The new resolution should not be less than your largest thumbnail size, which is <?=$minSizes['width']?> × <?=$minSizes['height']?> pixels.</p>
|
407 |
</td>
|
4 |
|
5 |
private $ctrl;
|
6 |
|
7 |
+
public function __construct($controller) {
|
8 |
+
$this->ctrl = $controller;
|
9 |
+
}
|
10 |
+
|
11 |
//handling older
|
12 |
public function ShortPixelView($controller) {
|
13 |
$this->__construct($controller);
|
14 |
}
|
15 |
|
|
|
|
|
|
|
|
|
16 |
public function displayQuotaExceededAlert($quotaData)
|
17 |
{ ?>
|
18 |
<br/>
|
327 |
}
|
328 |
|
329 |
public function displaySettingsForm($quotaData) {
|
330 |
+
$settings = $this->ctrl->getSettings();
|
331 |
$checked = ($this->ctrl->processThumbnails() ? 'checked' : '');
|
332 |
$checkedBackupImages = ($this->ctrl->backupImages() ? 'checked' : '');
|
333 |
$cmyk2rgb = ($this->ctrl->getCMYKtoRGBconversion() ? 'checked' : '');
|
334 |
+
$removeExif = ($settings->keepExif ? '' : 'checked');
|
335 |
$resize = ($this->ctrl->getResizeImages() ? 'checked' : '');
|
336 |
$resizeDisabled = ($this->ctrl->getResizeImages() ? '' : 'disabled');
|
337 |
$minSizes = $this->ctrl->getMaxIntermediateImageSize();
|
366 |
<label for="compressionType">Compression type:</label>
|
367 |
</th>
|
368 |
<td>
|
369 |
+
<input type="radio" name="compressionType" value="1" <?= $this->ctrl->getCompressionType() == 1 ? "checked" : "" ?>>Lossy (recommended)</br>
|
370 |
+
<p class="settings-info"> <b>Lossy compression: </b>lossy has a better compression rate than lossless compression.</br>While the resulting image
|
371 |
+
is not 100% identical with the original, in the vast majority of cases the difference is not noticeable. You can
|
372 |
+
<a href="https://shortpixel.com/online-image-compression" target="_blank">freely test your images</a> for lossy optimization.</p></br>
|
373 |
<input type="radio" name="compressionType" value="0" <?= $this->ctrl->getCompressionType() != 1 ? "checked" : "" ?>>Lossless
|
374 |
+
<p class="settings-info"><b>Lossless compression: </b> the shrunk image will be identical with the original and smaller in size.</br>In some rare cases you will need to use
|
375 |
+
this type of compression. Some technical drawings or images from vector graphics are possible situations.</p>
|
|
|
376 |
</td>
|
377 |
</tr>
|
378 |
</tbody>
|
383 |
<th scope="row"><label for="thumbnails">Also include thumbnails:</label></th>
|
384 |
<td><input name="thumbnails" type="checkbox" id="thumbnails" <?= $checked ?>> Apply compression also to
|
385 |
<strong><?=$thumbnailsToProcess ? number_format($thumbnailsToProcess) : ""?> image thumbnails.</strong>
|
386 |
+
<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>
|
387 |
</td>
|
388 |
</tr>
|
389 |
<tr>
|
390 |
<th scope="row"><label for="backupImages">Image backup</label></th>
|
391 |
<td>
|
392 |
<input name="backupImages" type="checkbox" id="backupImages" <?= $checkedBackupImages ?>> Save and keep a backup of your original images in a separate folder.
|
393 |
+
<p class="settings-info">Usually recommended for safety.</p>
|
394 |
</td>
|
395 |
</tr>
|
396 |
<tr>
|
397 |
+
<th scope="row"><label for="cmyk2rgb">CMYK to RGB conversion</label></th>
|
398 |
<td>
|
399 |
<input name="cmyk2rgb" type="checkbox" id="cmyk2rgb" <?= $cmyk2rgb ?>>Adjust your images for computer and mobile screen display.
|
400 |
</td>
|
401 |
</tr>
|
402 |
+
<tr>
|
403 |
+
<th scope="row"><label for="removeExif">Remove EXIF</label></th>
|
404 |
+
<td>
|
405 |
+
<input name="removeExif" type="checkbox" id="removeExif" <?= $removeExif ?>>Remove the EXIF tag and ICC profile of the image (recommended).
|
406 |
+
<p class="settings-info"> EXIF is a set of various pieces of information that are automatically embedded into the image upon creation. This can include GPS position, camera manufacturer, date and time, etc.
|
407 |
+
ICC profile specifies the color profile that is used by the image.
|
408 |
+
Unless you really need that data to be kept we recommend you removing it as it can lead to <a href="http://blog.shortpixel.com/how-much-smaller-can-be-images-without-exif-icc" target="_blank">better compression rates</a>.</p></br>
|
409 |
+
</td>
|
410 |
+
</tr>
|
411 |
<tr>
|
412 |
<th scope="row"><label for="resize">Resize large images</label></th>
|
413 |
<td>
|
414 |
<input name="resize" type="checkbox" id="resize" <?= $resize ?>> to maximum
|
415 |
<input type="text" name="width" id="width" style="width:70px" value="<?= max($this->ctrl->getResizeWidth(), min(1024, $minSizes['width'])) ?>" <?= $resizeDisabled ?>/> pixels wide ×
|
416 |
+
<input type="text" name="height" id="height" style="width:70px" value="<?= max($this->ctrl->getResizeHeight(), min(1024, $minSizes['height'])) ?>" <?= $resizeDisabled ?>/> pixels high (original aspect ratio is preserved)
|
417 |
<p class="settings-info"> Recommended for large photos, like the ones taken with your phone. Saved space can go up to 80% or more after resizing.<br/>
|
418 |
The new resolution should not be less than your largest thumbnail size, which is <?=$minSizes['width']?> × <?=$minSizes['height']?> pixels.</p>
|
419 |
</td>
|
wp-shortpixel-settings.php
ADDED
@@ -0,0 +1,150 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
class WPShortPixelSettings {
|
4 |
+
private $_apiKey = '';
|
5 |
+
private $_compressionType = 1;
|
6 |
+
private $_keepExif = 0;
|
7 |
+
private $_processThumbnails = 1;
|
8 |
+
private $_CMYKtoRGBconversion = 1;
|
9 |
+
private $_backupImages = 1;
|
10 |
+
private $_verifiedKey = false;
|
11 |
+
|
12 |
+
private $_resizeImages = false;
|
13 |
+
private $_resizeWidth = 0;
|
14 |
+
private $_resizeHeight = 0;
|
15 |
+
|
16 |
+
private static $_optionsMap = array(
|
17 |
+
'apiKey' => 'wp-short-pixel-apiKey',
|
18 |
+
'verifiedKey' => 'wp-short-pixel-verifiedKey',
|
19 |
+
'compressionType' => 'wp-short-pixel-compression',
|
20 |
+
'processThumbnails' => 'wp-short-process_thumbnails',
|
21 |
+
'keepExif' => 'wp-short-pixel-keep-exif',
|
22 |
+
'CMYKtoRGBconversion' => 'wp-short-pixel_cmyk2rgb',
|
23 |
+
'backupImages' => 'wp-short-backup_images',
|
24 |
+
'fileCount' => 'wp-short-pixel-fileCount',
|
25 |
+
'thumbsCount' => 'wp-short-pixel-thumbnail-count',
|
26 |
+
'under5Percent' => 'wp-short-pixel-files-under-5-percent',
|
27 |
+
'savedSpace' => 'wp-short-pixel-savedSpace',
|
28 |
+
'averageCompression' => 'wp-short-pixel-averageCompression',
|
29 |
+
'apiRetries' => 'wp-short-pixel-api-retries',
|
30 |
+
'resizeImages' => 'wp-short-pixel-resize-images',
|
31 |
+
'resizeWidth' => 'wp-short-pixel-resize-width',
|
32 |
+
'resizeHeight' => 'wp-short-pixel-resize-height',
|
33 |
+
'totalOptimized' => 'wp-short-pixel-total-optimized',
|
34 |
+
'totalOriginal' => 'wp-short-pixel-total-original',
|
35 |
+
'quotaExceeded' => 'wp-short-pixel-quota-exceeded',
|
36 |
+
'' => '',
|
37 |
+
'' => '',
|
38 |
+
'' => '',
|
39 |
+
'' => '',
|
40 |
+
'' => '',
|
41 |
+
);
|
42 |
+
|
43 |
+
public function __construct() {
|
44 |
+
$this->populateOptions();
|
45 |
+
}
|
46 |
+
|
47 |
+
public function populateOptions() {
|
48 |
+
|
49 |
+
$this->_apiKey = self::getOpt('wp-short-pixel-apiKey', '');
|
50 |
+
$this->_verifiedKey = self::getOpt('wp-short-pixel-verifiedKey', $this->_verifiedKey);
|
51 |
+
$this->_compressionType = self::getOpt('wp-short-pixel-compression', $this->_compressionType);
|
52 |
+
$this->_processThumbnails = self::getOpt('wp-short-process_thumbnails', $this->_processThumbnails);
|
53 |
+
$this->_CMYKtoRGBconversion = self::getOpt('wp-short-pixel_cmyk2rgb', $this->_CMYKtoRGBconversion);
|
54 |
+
$this->_backupImages = self::getOpt('wp-short-backup_images', $this->_backupImages);
|
55 |
+
// the following practically set defaults for options if they're not set
|
56 |
+
self::getOpt( 'wp-short-pixel-fileCount', 0);
|
57 |
+
self::getOpt( 'wp-short-pixel-thumbnail-count', 0);//amount of optimized thumbnails
|
58 |
+
self::getOpt( 'wp-short-pixel-files-under-5-percent', 0);//amount of optimized thumbnails
|
59 |
+
self::getOpt( 'wp-short-pixel-savedSpace', 0);
|
60 |
+
self::getOpt( 'wp-short-pixel-api-retries', 0);//sometimes we need to retry processing/downloading a file multiple times
|
61 |
+
self::getOpt( 'wp-short-pixel-quota-exceeded', 0);
|
62 |
+
self::getOpt( 'wp-short-pixel-total-original', 0);//amount of original data
|
63 |
+
self::getOpt( 'wp-short-pixel-total-optimized', 0);//amount of optimized
|
64 |
+
self::getOpt( 'wp-short-pixel-protocol', 'https');
|
65 |
+
|
66 |
+
$this->_resizeImages = self::getOpt( 'wp-short-pixel-resize-images', 0);
|
67 |
+
$this->_resizeWidth = self::getOpt( 'wp-short-pixel-resize-width', 0);
|
68 |
+
$this->_resizeHeight = self::getOpt( 'wp-short-pixel-resize-height', 0);
|
69 |
+
}
|
70 |
+
|
71 |
+
public static function debugResetOptions() {
|
72 |
+
delete_option('wp-short-pixel-apiKey');
|
73 |
+
delete_option('wp-short-pixel-verifiedKey');
|
74 |
+
delete_option('wp-short-pixel-compression');
|
75 |
+
delete_option('wp-short-process_thumbnails');
|
76 |
+
delete_option('wp-short-pixel_cmyk2rgb');
|
77 |
+
delete_option('wp-short-pixel-keep-exif');
|
78 |
+
delete_option('wp-short-backup_images');
|
79 |
+
delete_option('wp-short-pixel-view-mode');
|
80 |
+
update_option( 'wp-short-pixel-thumbnail-count', 0);
|
81 |
+
update_option( 'wp-short-pixel-files-under-5-percent', 0);
|
82 |
+
update_option( 'wp-short-pixel-savedSpace', 0);
|
83 |
+
delete_option( 'wp-short-pixel-averageCompression');
|
84 |
+
delete_option( 'wp-short-pixel-fileCount');
|
85 |
+
delete_option( 'wp-short-pixel-total-original');
|
86 |
+
delete_option( 'wp-short-pixel-total-optimized');
|
87 |
+
update_option( 'wp-short-pixel-api-retries', 0);//sometimes we need to retry processing/downloading a file multiple times
|
88 |
+
update_option( 'wp-short-pixel-quota-exceeded', 0);
|
89 |
+
delete_option( 'wp-short-pixel-protocol');
|
90 |
+
update_option( 'wp-short-pixel-bulk-ever-ran', 0);
|
91 |
+
delete_option('wp-short-pixel-priorityQueue');
|
92 |
+
delete_option( 'wp-short-pixel-resize-images');
|
93 |
+
delete_option( 'wp-short-pixel-resize-width');
|
94 |
+
delete_option( 'wp-short-pixel-resize-height');
|
95 |
+
delete_option( 'wp-short-pixel-dismissed-notices');
|
96 |
+
if(isset($_SESSION["wp-short-pixel-priorityQueue"])) {
|
97 |
+
unset($_SESSION["wp-short-pixel-priorityQueue"]);
|
98 |
+
}
|
99 |
+
delete_option("wp-short-pixel-bulk-previous-percent");
|
100 |
+
}
|
101 |
+
|
102 |
+
public static function onActivate() {
|
103 |
+
if(!self::getOpt('wp-short-pixel-verifiedKey', false)) {
|
104 |
+
update_option('wp-short-pixel-activation-notice', true);
|
105 |
+
}
|
106 |
+
update_option( 'wp-short-pixel-activation-date', time());
|
107 |
+
delete_option( 'wp-short-pixel-bulk-last-status');
|
108 |
+
}
|
109 |
+
|
110 |
+
public static function onDeactivate() {
|
111 |
+
delete_option('wp-short-pixel-activation-notice');
|
112 |
+
}
|
113 |
+
|
114 |
+
|
115 |
+
|
116 |
+
|
117 |
+
|
118 |
+
|
119 |
+
|
120 |
+
public function __get($name)
|
121 |
+
{
|
122 |
+
if (array_key_exists($name, self::$_optionsMap)) {
|
123 |
+
return $this->getOpt(self::$_optionsMap[$name]);
|
124 |
+
}
|
125 |
+
$trace = debug_backtrace();
|
126 |
+
trigger_error(
|
127 |
+
'Undefined property via __get(): ' . $name .
|
128 |
+
' in ' . $trace[0]['file'] .
|
129 |
+
' on line ' . $trace[0]['line'],
|
130 |
+
E_USER_NOTICE);
|
131 |
+
return null;
|
132 |
+
}
|
133 |
+
|
134 |
+
public function __set($name, $value) {
|
135 |
+
if (array_key_exists($name, self::$_optionsMap)) {
|
136 |
+
$this->setOpt(self::$_optionsMap[$name], $value);
|
137 |
+
}
|
138 |
+
}
|
139 |
+
|
140 |
+
public function getOpt($key, $default = null) {
|
141 |
+
if(get_option($key) === false) {
|
142 |
+
add_option( $key, $default, '', 'yes' );
|
143 |
+
}
|
144 |
+
return get_option($key);
|
145 |
+
}
|
146 |
+
|
147 |
+
public function setOpt($key, $val) {
|
148 |
+
update_option($key, $val);
|
149 |
+
}
|
150 |
+
}
|
wp-shortpixel.php
CHANGED
@@ -3,11 +3,12 @@
|
|
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.1.
|
7 |
* Author: ShortPixel
|
8 |
* Author URI: https://shortpixel.com
|
9 |
*/
|
10 |
|
|
|
11 |
require_once('shortpixel_api.php');
|
12 |
require_once('shortpixel_queue.php');
|
13 |
require_once('shortpixel_view.php');
|
@@ -21,7 +22,7 @@ define('SP_RESET_ON_ACTIVATE', false); //if true TODO set false
|
|
21 |
|
22 |
define('SP_AFFILIATE_CODE', '');
|
23 |
|
24 |
-
define('PLUGIN_VERSION', "3.1.
|
25 |
define('SP_MAX_TIMEOUT', 10);
|
26 |
define('SP_VALIDATE_MAX_TIMEOUT', 60);
|
27 |
define('SP_BACKUP', 'ShortpixelBackups');
|
@@ -42,42 +43,27 @@ define("SP_MAX_RESULTS_QUERY", 6);
|
|
42 |
class WPShortPixel {
|
43 |
|
44 |
const BULK_EMPTY_QUEUE = 0;
|
45 |
-
|
46 |
-
private $_apiKey = '';
|
47 |
-
private $_affiliateSufix;
|
48 |
-
private $_compressionType = 1;
|
49 |
-
private $_processThumbnails = 1;
|
50 |
-
private $_CMYKtoRGBconversion = 1;
|
51 |
-
private $_backupImages = 1;
|
52 |
-
private $_verifiedKey = false;
|
53 |
|
54 |
-
private $
|
55 |
-
private $_resizeWidth = 0;
|
56 |
-
private $_resizeHeight = 0;
|
57 |
|
58 |
private $_apiInterface = null;
|
|
|
59 |
private $prioQ = null;
|
60 |
private $view = null;
|
61 |
|
62 |
-
//handling older
|
63 |
-
public function WPShortPixel() {
|
64 |
-
$this->__construct();
|
65 |
-
}
|
66 |
-
|
67 |
public function __construct() {
|
68 |
if (!session_id()) {
|
69 |
session_start();
|
70 |
}
|
71 |
-
$this->populateOptions();
|
72 |
|
73 |
$this->_affiliateSufix = (strlen(SP_AFFILIATE_CODE)) ? "/affiliate/" . SP_AFFILIATE_CODE : "";
|
74 |
-
$this->
|
75 |
-
|
76 |
-
$this->prioQ = new ShortPixelQueue($this);
|
77 |
$this->view = new ShortPixelView($this);
|
78 |
|
79 |
define('QUOTA_EXCEEDED', "Quota Exceeded. <a class='button button-smaller button-primary' href='https://shortpixel.com/login/"
|
80 |
-
.$this->
|
81 |
."<a class='button button-smaller' href='admin.php?action=shortpixel_check_quota' target='_blank'>Check Quota</a>");
|
82 |
|
83 |
$this->setDefaultViewModeList();//set default mode as list. only @ first run
|
@@ -104,7 +90,7 @@ class WPShortPixel {
|
|
104 |
add_action( 'wp_ajax_shortpixel_dismiss_notice', array(&$this, 'dismissAdminNotice'));
|
105 |
//backup restore
|
106 |
add_action('admin_action_shortpixel_restore_backup', array(&$this, 'handleRestoreBackup'));
|
107 |
-
//
|
108 |
add_action('admin_action_shortpixel_check_quota', array(&$this, 'handleCheckQuota'));
|
109 |
|
110 |
//This adds the constants used in PHP to be available also in JS
|
@@ -117,67 +103,18 @@ class WPShortPixel {
|
|
117 |
$this->migrateBackupFolder();
|
118 |
}
|
119 |
|
120 |
-
|
121 |
-
|
122 |
-
$this->
|
123 |
-
$this->_verifiedKey = self::getOpt('wp-short-pixel-verifiedKey', $this->_verifiedKey);
|
124 |
-
$this->_compressionType = self::getOpt('wp-short-pixel-compression', $this->_compressionType);
|
125 |
-
$this->_processThumbnails = self::getOpt('wp-short-process_thumbnails', $this->_processThumbnails);
|
126 |
-
$this->_CMYKtoRGBconversion = self::getOpt('wp-short-pixel_cmyk2rgb', $this->_CMYKtoRGBconversion);
|
127 |
-
$this->_backupImages = self::getOpt('wp-short-backup_images', $this->_backupImages);
|
128 |
-
// the following practically set defaults for options if they're not set
|
129 |
-
self::getOpt( 'wp-short-pixel-fileCount', 0);
|
130 |
-
self::getOpt( 'wp-short-pixel-thumbnail-count', 0);//amount of optimized thumbnails
|
131 |
-
self::getOpt( 'wp-short-pixel-files-under-5-percent', 0);//amount of optimized thumbnails
|
132 |
-
self::getOpt( 'wp-short-pixel-savedSpace', 0);
|
133 |
-
self::getOpt( 'wp-short-pixel-api-retries', 0);//sometimes we need to retry processing/downloading a file multiple times
|
134 |
-
self::getOpt( 'wp-short-pixel-quota-exceeded', 0);
|
135 |
-
self::getOpt( 'wp-short-pixel-total-original', 0);//amount of original data
|
136 |
-
self::getOpt( 'wp-short-pixel-total-optimized', 0);//amount of optimized
|
137 |
-
self::getOpt( 'wp-short-pixel-protocol', 'https');
|
138 |
-
|
139 |
-
$this->_resizeImages = self::getOpt( 'wp-short-pixel-resize-images', 0);
|
140 |
-
$this->_resizeWidth = self::getOpt( 'wp-short-pixel-resize-width', 0);
|
141 |
-
$this->_resizeHeight = self::getOpt( 'wp-short-pixel-resize-height', 0);
|
142 |
}
|
143 |
-
|
144 |
public static function shortPixelActivatePlugin()//reset some params to avoid trouble for plugins that were activated/deactivated/activated
|
145 |
{
|
146 |
self::shortPixelDeactivatePlugin();
|
147 |
if(SP_RESET_ON_ACTIVATE === true && WP_DEBUG === true) { //force reset plugin counters, only on specific occasions and on test environments
|
148 |
-
|
149 |
-
delete_option('wp-short-pixel-verifiedKey');
|
150 |
-
delete_option('wp-short-pixel-compression');
|
151 |
-
delete_option('wp-short-process_thumbnails');
|
152 |
-
delete_option('wp-short-pixel_cmyk2rgb');
|
153 |
-
delete_option('wp-short-backup_images');
|
154 |
-
delete_option('wp-short-pixel-view-mode');
|
155 |
-
update_option( 'wp-short-pixel-thumbnail-count', 0);
|
156 |
-
update_option( 'wp-short-pixel-files-under-5-percent', 0);
|
157 |
-
update_option( 'wp-short-pixel-savedSpace', 0);
|
158 |
-
delete_option( 'wp-short-pixel-averageCompression');
|
159 |
-
delete_option( 'wp-short-pixel-fileCount');
|
160 |
-
delete_option( 'wp-short-pixel-total-original');
|
161 |
-
delete_option( 'wp-short-pixel-total-optimized');
|
162 |
-
update_option( 'wp-short-pixel-api-retries', 0);//sometimes we need to retry processing/downloading a file multiple times
|
163 |
-
update_option( 'wp-short-pixel-quota-exceeded', 0);
|
164 |
-
delete_option( 'wp-short-pixel-protocol');
|
165 |
-
update_option( 'wp-short-pixel-bulk-ever-ran', 0);
|
166 |
-
delete_option('wp-short-pixel-priorityQueue');
|
167 |
-
delete_option( 'wp-short-pixel-resize-images');
|
168 |
-
delete_option( 'wp-short-pixel-resize-width');
|
169 |
-
delete_option( 'wp-short-pixel-resize-height');
|
170 |
-
delete_option( 'wp-short-pixel-dismissed-notices');
|
171 |
-
if(isset($_SESSION["wp-short-pixel-priorityQueue"])) {
|
172 |
-
unset($_SESSION["wp-short-pixel-priorityQueue"]);
|
173 |
-
}
|
174 |
-
delete_option("wp-short-pixel-bulk-previous-percent");
|
175 |
-
}
|
176 |
-
if(!self::getOpt('wp-short-pixel-verifiedKey', false)) {
|
177 |
-
update_option('wp-short-pixel-activation-notice', true);
|
178 |
}
|
179 |
-
|
180 |
-
delete_option( 'wp-short-pixel-bulk-last-status');
|
181 |
}
|
182 |
|
183 |
public static function shortPixelDeactivatePlugin()//reset some params to avoid trouble for plugins that were activated/deactivated/activated
|
@@ -185,15 +122,15 @@ class WPShortPixel {
|
|
185 |
include_once dirname( __FILE__ ) . '/shortpixel_queue.php';
|
186 |
ShortPixelQueue::resetBulk();
|
187 |
ShortPixelQueue::resetPrio();
|
188 |
-
|
189 |
}
|
190 |
|
191 |
public function displayAdminNotices() {
|
192 |
-
if(!$this->
|
193 |
-
$dismissed =
|
194 |
$now = time();
|
195 |
-
$act =
|
196 |
-
if(
|
197 |
ShortPixelView::displayActivationNotice();
|
198 |
delete_option('wp-short-pixel-activation-notice');
|
199 |
}
|
@@ -207,7 +144,7 @@ class WPShortPixel {
|
|
207 |
|
208 |
public function dismissAdminNotice() {
|
209 |
$noticeId = preg_replace('|[^a-z0-9]|i', '', $_GET['notice_id']);
|
210 |
-
$dismissed =
|
211 |
$dismissed[$noticeId] = true;
|
212 |
update_option( 'wp-short-pixel-dismissed-notices', $dismissed);
|
213 |
die(json_encode(array("Status" => 'success', "Message" => 'Notice ID: ' . $noticeId . ' dismissed')));
|
@@ -216,9 +153,9 @@ class WPShortPixel {
|
|
216 |
//set default move as "list". only set once, it won't try to set the default mode again.
|
217 |
public function setDefaultViewModeList()
|
218 |
{
|
219 |
-
if(
|
220 |
{
|
221 |
-
|
222 |
if ( function_exists('get_currentuserinfo') )
|
223 |
{
|
224 |
global $current_user;
|
@@ -254,7 +191,7 @@ class WPShortPixel {
|
|
254 |
STATUS_NO_KEY: <?= ShortPixelAPI::STATUS_NO_KEY ?>,
|
255 |
STATUS_RETRY: <?= ShortPixelAPI::STATUS_RETRY ?>,
|
256 |
WP_PLUGIN_URL: '<?= plugins_url( '', __FILE__ ) ?>',
|
257 |
-
API_KEY: "<?= $this->
|
258 |
});
|
259 |
}
|
260 |
});
|
@@ -273,16 +210,16 @@ class WPShortPixel {
|
|
273 |
if($this->prioQ->processing()) {
|
274 |
$extraClasses = " shortpixel-processing";
|
275 |
}
|
276 |
-
self::log("TOOLBAR: Quota exceeded: " .
|
277 |
-
if(
|
278 |
$extraClasses = " shortpixel-alert shortpixel-quota-exceeded";
|
279 |
$tooltip = "ShortPixel quota exceeded. Click for details.";
|
280 |
-
//$link = "http://shortpixel.com/login/" . $this->
|
281 |
$link = "options-general.php?page=wp-shortpixel";
|
282 |
//$blank = '_blank';
|
283 |
//$icon = "shortpixel-alert.png";
|
284 |
}
|
285 |
-
$lastStatus =
|
286 |
if($lastStatus['Status'] != ShortPixelAPI::STATUS_SUCCESS) {
|
287 |
$extraClasses = " shortpixel-alert shortpixel-processing";
|
288 |
$tooltip = $lastStatus['Message'];
|
@@ -300,13 +237,6 @@ class WPShortPixel {
|
|
300 |
$wp_admin_bar->add_node( $args );
|
301 |
}
|
302 |
|
303 |
-
public static function getOpt($key, $default) {
|
304 |
-
if(get_option($key) === false) {
|
305 |
-
add_option( $key, $default, '', 'yes' );
|
306 |
-
}
|
307 |
-
return get_option($key);
|
308 |
-
}
|
309 |
-
|
310 |
public function handleCustomBulk() {
|
311 |
// 1. get the action
|
312 |
$wp_list_table = _get_list_table('WP_Media_List_Table');
|
@@ -337,7 +267,7 @@ class WPShortPixel {
|
|
337 |
|
338 |
public function handleImageUpload($meta, $ID = null)
|
339 |
{
|
340 |
-
if( !$this->
|
341 |
return $meta;
|
342 |
}
|
343 |
//else
|
@@ -351,7 +281,7 @@ class WPShortPixel {
|
|
351 |
else
|
352 |
{//the kind of file we can process. goody.
|
353 |
$this->prioQ->push($ID);
|
354 |
-
$URLsAndPATHs = $this->getURLsAndPATHs($ID, $meta);
|
355 |
$this->_apiInterface->doRequests($URLsAndPATHs['URLs'], false, $ID);//send a processing request right after a file was uploaded, do NOT wait for response
|
356 |
self::log("IMG: sent: " . json_encode($URLsAndPATHs));
|
357 |
$meta['ShortPixel']['WaitingProcessing'] = true;
|
@@ -457,7 +387,7 @@ class WPShortPixel {
|
|
457 |
public function handleImageProcessing($ID = null) {
|
458 |
//die("stop");
|
459 |
//0: check key
|
460 |
-
if( $this->
|
461 |
if($ID == null){
|
462 |
$ids = $this->getFromPrioAndCheck();
|
463 |
$ID = (count($ids) > 0 ? $ids[0] : null);
|
@@ -523,7 +453,7 @@ class WPShortPixel {
|
|
523 |
$prio = $this->prioQ->removeFromFailed($ID);
|
524 |
$meta = wp_get_attachment_metadata($ID);
|
525 |
$result["ThumbsCount"] = isset($meta['sizes']) && is_array($meta['sizes']) ? count($meta['sizes']): 0;
|
526 |
-
$result["BackupEnabled"] = $this->
|
527 |
|
528 |
if(!$prio && $ID <= $this->prioQ->getStartBulkId()) {
|
529 |
$this->prioQ->setStartBulkId($ID - 1);
|
@@ -544,7 +474,7 @@ class WPShortPixel {
|
|
544 |
$urlPath = implode("/", array_slice($filePath, 0, count($filePath) - 1));
|
545 |
$urlBkPath = $this->_apiInterface->returnSubDir(get_attached_file($ID));
|
546 |
$thumb = (isset($meta["sizes"]["medium"]) ? $meta["sizes"]["medium"]["file"] : (isset($meta["sizes"]["thumbnail"]) ? $meta["sizes"]["thumbnail"]["file"]: ""));
|
547 |
-
if(strlen($thumb) && get_option('wp-short-backup_images') && $this->
|
548 |
$bkThumb = $uploadsUrl . SP_BACKUP . "/" . $urlBkPath . "/" . $thumb;
|
549 |
}
|
550 |
if(strlen($thumb)) {
|
@@ -724,13 +654,13 @@ class WPShortPixel {
|
|
724 |
public function bulkProcess() {
|
725 |
global $wpdb;
|
726 |
|
727 |
-
if( $this->
|
728 |
ShortPixelView::displayActivationNotice();
|
729 |
return;
|
730 |
}
|
731 |
|
732 |
$quotaData = $this->checkQuotaAndAlert();
|
733 |
-
if(
|
734 |
|
735 |
if(isset($_POST['bulkProcessPause']))
|
736 |
{//pause an ongoing bulk processing, it might be needed sometimes
|
@@ -783,8 +713,8 @@ class WPShortPixel {
|
|
783 |
//$imageCount = $this->countAllProcessableFiles();
|
784 |
//$imgProcessedCount = $this->countAllProcessedFiles();
|
785 |
$imageOnlyThumbs = $quotaData['totalFiles'] - $quotaData['mainFiles'];
|
786 |
-
$thumbsProcessedCount =
|
787 |
-
$under5PercentCount =
|
788 |
|
789 |
//average compression
|
790 |
$averageCompression = self::getAverageCompression();
|
@@ -872,9 +802,7 @@ class WPShortPixel {
|
|
872 |
{
|
873 |
$validityData = $this->getQuotaInformation($_POST['key'], true, isset($_POST['validate']) && $_POST['validate'] == "validate");
|
874 |
|
875 |
-
$this->
|
876 |
-
$this->_apiInterface->setApiKey($this->_apiKey);
|
877 |
-
update_option('wp-short-pixel-apiKey', $_POST['key']);
|
878 |
if($validityData['APIKeyValid']) {
|
879 |
if(isset($_POST['validate']) && $_POST['validate'] == "validate") {
|
880 |
// delete last status if it was no valid key
|
@@ -889,13 +817,12 @@ class WPShortPixel {
|
|
889 |
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.");
|
890 |
} else {
|
891 |
if ( function_exists("is_multisite") && is_multisite() )
|
892 |
-
$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->
|
893 |
else
|
894 |
$notice = array("status" => "success", "msg" => 'API Key valid!');
|
895 |
}
|
896 |
}
|
897 |
-
|
898 |
-
$this->_verifiedKey = true;
|
899 |
//test that the "uploads" have the right rights and also we can create the backup dir for ShortPixel
|
900 |
if ( !file_exists(SP_BACKUP_FOLDER) && !@mkdir(SP_BACKUP_FOLDER, 0777, true) )
|
901 |
$notice = array("status" => "error", "msg" => "There is something preventing us to create a new folder for backing up your original files.<BR>
|
@@ -905,29 +832,22 @@ class WPShortPixel {
|
|
905 |
//display notification
|
906 |
$notice = array("status" => "error", "msg" => $validityData["Message"]);
|
907 |
}
|
908 |
-
|
909 |
-
$this->_verifiedKey = false;
|
910 |
}
|
911 |
}
|
912 |
|
913 |
|
914 |
//if save button - we process the rest of the form elements
|
915 |
if(isset($_POST['save'])) {
|
916 |
-
|
917 |
-
$this->
|
918 |
-
$this->
|
919 |
-
if(isset($_POST['
|
920 |
-
|
921 |
-
|
922 |
-
|
923 |
-
|
924 |
-
|
925 |
-
$this->_resizeImages = (isset($_POST['resize']) ? 1: 0);
|
926 |
-
$this->_resizeWidth = (isset($_POST['width']) ? $_POST['width']: $this->_resizeWidth);
|
927 |
-
$this->_resizeHeight = (isset($_POST['height']) ? $_POST['height']: $this->_resizeHeight);
|
928 |
-
update_option( 'wp-short-pixel-resize-images', $this->_resizeImages);
|
929 |
-
update_option( 'wp-short-pixel-resize-width', 0 + $this->_resizeWidth);
|
930 |
-
update_option( 'wp-short-pixel-resize-height', 0 + $this->_resizeHeight);
|
931 |
|
932 |
if($_POST['save'] == "Save and Go to Bulk Process") {
|
933 |
wp_redirect("upload.php?page=wp-short-pixel-bulk");
|
@@ -947,11 +867,11 @@ class WPShortPixel {
|
|
947 |
|
948 |
$quotaData = $this->checkQuotaAndAlert();
|
949 |
|
950 |
-
if($this->
|
951 |
-
$fileCount = number_format(
|
952 |
-
$savedSpace = self::formatBytes(
|
953 |
$averageCompression = self::getAverageCompression();
|
954 |
-
$savedBandwidth = self::formatBytes(
|
955 |
if (is_numeric($quotaData['APICallsQuota'])) {
|
956 |
$quotaData['APICallsQuota'] .= "/month";
|
957 |
}
|
@@ -970,8 +890,8 @@ class WPShortPixel {
|
|
970 |
}
|
971 |
|
972 |
public function getAverageCompression(){
|
973 |
-
return
|
974 |
-
? round(( 1 - (
|
975 |
: 0;
|
976 |
}
|
977 |
|
@@ -984,7 +904,7 @@ class WPShortPixel {
|
|
984 |
*/
|
985 |
public function getQuotaInformation($apiKey = null, $appendUserAgent = false, $validate = false) {
|
986 |
|
987 |
-
if(is_null($apiKey)) { $apiKey = $this->
|
988 |
|
989 |
$requestURL = 'https://api.shortpixel.com/v2/api-status.php';
|
990 |
$args = array('timeout'=> SP_VALIDATE_MAX_TIMEOUT,
|
@@ -1049,12 +969,12 @@ class WPShortPixel {
|
|
1049 |
}
|
1050 |
|
1051 |
if ( ( $data->APICallsMade + $data->APICallsMadeOneTime ) < ( $data->APICallsQuota + $data->APICallsQuotaOneTime ) ) //reset quota exceeded flag -> user is allowed to process more images.
|
1052 |
-
|
1053 |
else
|
1054 |
-
|
1055 |
|
1056 |
//if a not valid status exists, delete it
|
1057 |
-
$lastStatus =
|
1058 |
if($lastStatus['Status'] == ShortPixelAPI::STATUS_NO_KEY) {
|
1059 |
delete_option('wp-short-pixel-bulk-last-status');
|
1060 |
}
|
@@ -1086,14 +1006,14 @@ class WPShortPixel {
|
|
1086 |
{
|
1087 |
if ( $fileExtension <> "pdf" )
|
1088 |
{
|
1089 |
-
if(!$this->
|
1090 |
print 'Invalid API Key. <a href="options-general.php?page=wp-shortpixel">Check your Settings</a>';
|
1091 |
else
|
1092 |
print 'Optimization N/A';
|
1093 |
}
|
1094 |
else
|
1095 |
{
|
1096 |
-
if (
|
1097 |
{
|
1098 |
print QUOTA_EXCEEDED;
|
1099 |
return;
|
@@ -1101,7 +1021,7 @@ class WPShortPixel {
|
|
1101 |
else
|
1102 |
{
|
1103 |
print 'PDF not processed';
|
1104 |
-
//if($this->
|
1105 |
print " <a class='button button-smaller button-primary' href=\"javascript:manualOptimization({$id})\">Optimize now</a>";
|
1106 |
//}
|
1107 |
return;
|
@@ -1112,7 +1032,7 @@ class WPShortPixel {
|
|
1112 |
{
|
1113 |
if(isset($meta['ShortPixel']['BulkProcessing']))
|
1114 |
{
|
1115 |
-
if (
|
1116 |
{
|
1117 |
print QUOTA_EXCEEDED;
|
1118 |
}
|
@@ -1130,12 +1050,14 @@ class WPShortPixel {
|
|
1130 |
print "Bonus processing";
|
1131 |
} else {
|
1132 |
print 'Reduced by ';
|
1133 |
-
print $data['ShortPixelImprovement'] . '%';
|
1134 |
}
|
1135 |
if ( get_option('wp-short-backup_images') && !isset($data['ShortPixel']['NoBackup'])) //display restore backup option only when backup is active
|
1136 |
print " <a class='button button-smaller' href=\"admin.php?action=shortpixel_restore_backup&attachment_ID={$id}\">Restore backup</a>";
|
1137 |
-
if (isset($data['sizes']) && count($data['sizes'])) {
|
1138 |
-
|
|
|
|
|
1139 |
}
|
1140 |
}
|
1141 |
elseif ( $data['ShortPixelImprovement'] <> "Optimization N/A" )
|
@@ -1143,7 +1065,7 @@ class WPShortPixel {
|
|
1143 |
if ( trim(strip_tags($data['ShortPixelImprovement'])) == "Quota exceeded" )
|
1144 |
{
|
1145 |
print QUOTA_EXCEEDED;
|
1146 |
-
if (
|
1147 |
print " <a class='button button-smaller button-primary' href=\"javascript:manualOptimization({$id})\">Try again</a>";
|
1148 |
}
|
1149 |
elseif ( trim(strip_tags($data['ShortPixelImprovement'])) == "Cannot write optimized file" )
|
@@ -1162,7 +1084,7 @@ class WPShortPixel {
|
|
1162 |
print "Optimization N/A";
|
1163 |
}
|
1164 |
} elseif(isset($data['ShortPixel']['WaitingProcessing'])) {
|
1165 |
-
if (
|
1166 |
{
|
1167 |
print QUOTA_EXCEEDED;
|
1168 |
}
|
@@ -1180,7 +1102,7 @@ class WPShortPixel {
|
|
1180 |
|
1181 |
if ( wp_attachment_is_image( $id ) )
|
1182 |
{
|
1183 |
-
if (
|
1184 |
{
|
1185 |
print QUOTA_EXCEEDED;
|
1186 |
}
|
@@ -1195,7 +1117,7 @@ class WPShortPixel {
|
|
1195 |
}
|
1196 |
elseif ( $fileExtension == "pdf" )
|
1197 |
{
|
1198 |
-
if (
|
1199 |
{
|
1200 |
print QUOTA_EXCEEDED;
|
1201 |
}
|
@@ -1279,7 +1201,7 @@ class WPShortPixel {
|
|
1279 |
|
1280 |
//it is NOT a PDF file and thumbs are processable
|
1281 |
if ( strtolower(substr($filePath[0],strrpos($filePath[0], ".")+1)) != "pdf"
|
1282 |
-
&& $this->
|
1283 |
&& isset($meta['sizes']) && is_array($meta['sizes']))
|
1284 |
{
|
1285 |
foreach( $meta['sizes'] as $thumbnailInfo )
|
@@ -1359,6 +1281,20 @@ class WPShortPixel {
|
|
1359 |
$limit = 500;
|
1360 |
$pointer = 0;
|
1361 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1362 |
//count all the files, main and thumbs
|
1363 |
while ( 1 )
|
1364 |
{
|
@@ -1369,28 +1305,31 @@ class WPShortPixel {
|
|
1369 |
if ( empty($filesList) ) //we parsed all the results
|
1370 |
break;
|
1371 |
|
|
|
1372 |
foreach ( $filesList as $file )
|
1373 |
{
|
1374 |
if ( $file->meta_key == "_wp_attached_file" )
|
1375 |
{//count pdf files only
|
1376 |
$extension = substr($file->meta_value, strrpos($file->meta_value,".") + 1 );
|
1377 |
-
if ( $extension == "pdf" )
|
1378 |
{
|
1379 |
$totalFiles++;
|
1380 |
$mainFiles++;
|
|
|
1381 |
}
|
1382 |
}
|
1383 |
else
|
1384 |
{
|
1385 |
$attachment = unserialize($file->meta_value);
|
1386 |
-
if(isset($attachment['file']) && self::isProcessablePath($attachment['file'])){
|
1387 |
-
if ( isset($attachment['sizes']) )
|
1388 |
$totalFiles += count($attachment['sizes']);
|
1389 |
-
|
1390 |
if ( isset($attachment['file']) )
|
1391 |
{
|
1392 |
$totalFiles++;
|
1393 |
$mainFiles++;
|
|
|
1394 |
}
|
1395 |
}
|
1396 |
}
|
@@ -1404,7 +1343,7 @@ class WPShortPixel {
|
|
1404 |
}
|
1405 |
|
1406 |
|
1407 |
-
//count all the
|
1408 |
public function countAllProcessedFiles($maxId = PHP_INT_MAX, $minId = 0){
|
1409 |
global $wpdb;
|
1410 |
|
@@ -1413,6 +1352,7 @@ class WPShortPixel {
|
|
1413 |
$pointer = 0;
|
1414 |
|
1415 |
//count all the files, main and thumbs
|
|
|
1416 |
while ( 1 )
|
1417 |
{
|
1418 |
$filesList= $wpdb->get_results("SELECT * FROM " . $wpdb->prefix . "postmeta
|
@@ -1425,12 +1365,20 @@ class WPShortPixel {
|
|
1425 |
foreach ( $filesList as $file )
|
1426 |
{
|
1427 |
$attachment = unserialize($file->meta_value);
|
1428 |
-
if (
|
|
|
|
|
|
|
1429 |
$processedMainFiles++;
|
1430 |
$processedTotalFiles++;
|
1431 |
-
if ( isset($attachment['
|
|
|
|
|
1432 |
$processedTotalFiles += count($attachment['sizes']);
|
1433 |
}
|
|
|
|
|
|
|
1434 |
}
|
1435 |
}
|
1436 |
unset($filesList);
|
@@ -1486,7 +1434,7 @@ class WPShortPixel {
|
|
1486 |
}
|
1487 |
|
1488 |
public function getApiKey() {
|
1489 |
-
return $this->
|
1490 |
}
|
1491 |
|
1492 |
public function getPrioQ() {
|
@@ -1494,35 +1442,41 @@ class WPShortPixel {
|
|
1494 |
}
|
1495 |
|
1496 |
public function backupImages() {
|
1497 |
-
return $this->
|
1498 |
}
|
1499 |
|
1500 |
public function processThumbnails() {
|
1501 |
-
return $this->
|
1502 |
}
|
|
|
1503 |
public function getCMYKtoRGBconversion() {
|
1504 |
-
return $this->
|
|
|
|
|
|
|
|
|
1505 |
}
|
1506 |
|
1507 |
-
|
1508 |
-
|
|
|
1509 |
}
|
1510 |
|
1511 |
public function getResizeWidth() {
|
1512 |
-
return $this->
|
1513 |
}
|
1514 |
|
1515 |
public function getResizeHeight() {
|
1516 |
-
return $this->
|
1517 |
}
|
1518 |
public function getAffiliateSufix() {
|
1519 |
return $this->_affiliateSufix;
|
1520 |
}
|
1521 |
public function getVerifiedKey() {
|
1522 |
-
return $this->
|
1523 |
}
|
1524 |
public function getCompressionType() {
|
1525 |
-
return $this->
|
1526 |
}
|
1527 |
|
1528 |
}
|
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.1.9
|
7 |
* Author: ShortPixel
|
8 |
* Author URI: https://shortpixel.com
|
9 |
*/
|
10 |
|
11 |
+
require_once('wp-shortpixel-settings.php');
|
12 |
require_once('shortpixel_api.php');
|
13 |
require_once('shortpixel_queue.php');
|
14 |
require_once('shortpixel_view.php');
|
22 |
|
23 |
define('SP_AFFILIATE_CODE', '');
|
24 |
|
25 |
+
define('PLUGIN_VERSION', "3.1.9");
|
26 |
define('SP_MAX_TIMEOUT', 10);
|
27 |
define('SP_VALIDATE_MAX_TIMEOUT', 60);
|
28 |
define('SP_BACKUP', 'ShortpixelBackups');
|
43 |
class WPShortPixel {
|
44 |
|
45 |
const BULK_EMPTY_QUEUE = 0;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
46 |
|
47 |
+
private $_affiliateSufix;
|
|
|
|
|
48 |
|
49 |
private $_apiInterface = null;
|
50 |
+
private $_settings = null;
|
51 |
private $prioQ = null;
|
52 |
private $view = null;
|
53 |
|
|
|
|
|
|
|
|
|
|
|
54 |
public function __construct() {
|
55 |
if (!session_id()) {
|
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', "Quota Exceeded. <a class='button button-smaller button-primary' href='https://shortpixel.com/login/"
|
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
|
90 |
add_action( 'wp_ajax_shortpixel_dismiss_notice', array(&$this, 'dismissAdminNotice'));
|
91 |
//backup restore
|
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 |
|
96 |
//This adds the constants used in PHP to be available also in JS
|
103 |
$this->migrateBackupFolder();
|
104 |
}
|
105 |
|
106 |
+
//handling older
|
107 |
+
public function 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();
|
114 |
if(SP_RESET_ON_ACTIVATE === true && WP_DEBUG === true) { //force reset plugin counters, only on specific occasions and on test environments
|
115 |
+
WPShortPixelSettings::debugResetOptions();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
116 |
}
|
117 |
+
WPShortPixelSettings::onActivate();
|
|
|
118 |
}
|
119 |
|
120 |
public static function shortPixelDeactivatePlugin()//reset some params to avoid trouble for plugins that were activated/deactivated/activated
|
122 |
include_once dirname( __FILE__ ) . '/shortpixel_queue.php';
|
123 |
ShortPixelQueue::resetBulk();
|
124 |
ShortPixelQueue::resetPrio();
|
125 |
+
WPShortPixelSettings::onDeactivate();
|
126 |
}
|
127 |
|
128 |
public function displayAdminNotices() {
|
129 |
+
if(!$this->_settings->verifiedKey) {
|
130 |
+
$dismissed = $this->_settings->getOpt( 'wp-short-pixel-dismissed-notices', array());
|
131 |
$now = time();
|
132 |
+
$act = $this->_settings->getOpt( 'wp-short-pixel-activation-date', $now);
|
133 |
+
if($this->_settings->getOpt( 'wp-short-pixel-activation-notice', false)) {
|
134 |
ShortPixelView::displayActivationNotice();
|
135 |
delete_option('wp-short-pixel-activation-notice');
|
136 |
}
|
144 |
|
145 |
public function dismissAdminNotice() {
|
146 |
$noticeId = preg_replace('|[^a-z0-9]|i', '', $_GET['notice_id']);
|
147 |
+
$dismissed = $this->_settings->getOpt( 'wp-short-pixel-dismissed-notices', array());
|
148 |
$dismissed[$noticeId] = true;
|
149 |
update_option( 'wp-short-pixel-dismissed-notices', $dismissed);
|
150 |
die(json_encode(array("Status" => 'success', "Message" => 'Notice ID: ' . $noticeId . ' dismissed')));
|
153 |
//set default move as "list". only set once, it won't try to set the default mode again.
|
154 |
public function setDefaultViewModeList()
|
155 |
{
|
156 |
+
if($this->_settings->getOpt('wp-short-pixel-view-mode') === false)
|
157 |
{
|
158 |
+
$this->_settings->setOpt('wp-short-pixel-view-mode', 1);
|
159 |
if ( function_exists('get_currentuserinfo') )
|
160 |
{
|
161 |
global $current_user;
|
191 |
STATUS_NO_KEY: <?= ShortPixelAPI::STATUS_NO_KEY ?>,
|
192 |
STATUS_RETRY: <?= ShortPixelAPI::STATUS_RETRY ?>,
|
193 |
WP_PLUGIN_URL: '<?= plugins_url( '', __FILE__ ) ?>',
|
194 |
+
API_KEY: "<?= $this->_settings->apiKey ?>"
|
195 |
});
|
196 |
}
|
197 |
});
|
210 |
if($this->prioQ->processing()) {
|
211 |
$extraClasses = " shortpixel-processing";
|
212 |
}
|
213 |
+
self::log("TOOLBAR: Quota exceeded: " . $this->_settings->quotaExceeded);
|
214 |
+
if($this->_settings->quotaExceeded) {
|
215 |
$extraClasses = " shortpixel-alert shortpixel-quota-exceeded";
|
216 |
$tooltip = "ShortPixel quota exceeded. Click for details.";
|
217 |
+
//$link = "http://shortpixel.com/login/" . $this->_settings->apiKey;
|
218 |
$link = "options-general.php?page=wp-shortpixel";
|
219 |
//$blank = '_blank';
|
220 |
//$icon = "shortpixel-alert.png";
|
221 |
}
|
222 |
+
$lastStatus = $this->_settings->getOpt( 'wp-short-pixel-bulk-last-status', array('Status' => ShortPixelAPI::STATUS_SUCCESS));
|
223 |
if($lastStatus['Status'] != ShortPixelAPI::STATUS_SUCCESS) {
|
224 |
$extraClasses = " shortpixel-alert shortpixel-processing";
|
225 |
$tooltip = $lastStatus['Message'];
|
237 |
$wp_admin_bar->add_node( $args );
|
238 |
}
|
239 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
240 |
public function handleCustomBulk() {
|
241 |
// 1. get the action
|
242 |
$wp_list_table = _get_list_table('WP_Media_List_Table');
|
267 |
|
268 |
public function handleImageUpload($meta, $ID = null)
|
269 |
{
|
270 |
+
if( !$this->_settings->verifiedKey) {// no API Key set/verified -> do nothing here, just return
|
271 |
return $meta;
|
272 |
}
|
273 |
//else
|
281 |
else
|
282 |
{//the kind of file we can process. goody.
|
283 |
$this->prioQ->push($ID);
|
284 |
+
$URLsAndPATHs = $this->getURLsAndPATHs($ID, $meta);
|
285 |
$this->_apiInterface->doRequests($URLsAndPATHs['URLs'], false, $ID);//send a processing request right after a file was uploaded, do NOT wait for response
|
286 |
self::log("IMG: sent: " . json_encode($URLsAndPATHs));
|
287 |
$meta['ShortPixel']['WaitingProcessing'] = true;
|
387 |
public function handleImageProcessing($ID = null) {
|
388 |
//die("stop");
|
389 |
//0: check key
|
390 |
+
if( $this->_settings->verifiedKey == false) {
|
391 |
if($ID == null){
|
392 |
$ids = $this->getFromPrioAndCheck();
|
393 |
$ID = (count($ids) > 0 ? $ids[0] : null);
|
453 |
$prio = $this->prioQ->removeFromFailed($ID);
|
454 |
$meta = wp_get_attachment_metadata($ID);
|
455 |
$result["ThumbsCount"] = isset($meta['sizes']) && is_array($meta['sizes']) ? count($meta['sizes']): 0;
|
456 |
+
$result["BackupEnabled"] = $this->_settings->backupImages;
|
457 |
|
458 |
if(!$prio && $ID <= $this->prioQ->getStartBulkId()) {
|
459 |
$this->prioQ->setStartBulkId($ID - 1);
|
474 |
$urlPath = implode("/", array_slice($filePath, 0, count($filePath) - 1));
|
475 |
$urlBkPath = $this->_apiInterface->returnSubDir(get_attached_file($ID));
|
476 |
$thumb = (isset($meta["sizes"]["medium"]) ? $meta["sizes"]["medium"]["file"] : (isset($meta["sizes"]["thumbnail"]) ? $meta["sizes"]["thumbnail"]["file"]: ""));
|
477 |
+
if(strlen($thumb) && get_option('wp-short-backup_images') && $this->_settings->processThumbnails) {
|
478 |
$bkThumb = $uploadsUrl . SP_BACKUP . "/" . $urlBkPath . "/" . $thumb;
|
479 |
}
|
480 |
if(strlen($thumb)) {
|
654 |
public function bulkProcess() {
|
655 |
global $wpdb;
|
656 |
|
657 |
+
if( $this->_settings->verifiedKey == false ) {//invalid API Key
|
658 |
ShortPixelView::displayActivationNotice();
|
659 |
return;
|
660 |
}
|
661 |
|
662 |
$quotaData = $this->checkQuotaAndAlert();
|
663 |
+
if($this->_settings->getOpt('wp-short-pixel-quota-exceeded', 0) != 0) return;
|
664 |
|
665 |
if(isset($_POST['bulkProcessPause']))
|
666 |
{//pause an ongoing bulk processing, it might be needed sometimes
|
713 |
//$imageCount = $this->countAllProcessableFiles();
|
714 |
//$imgProcessedCount = $this->countAllProcessedFiles();
|
715 |
$imageOnlyThumbs = $quotaData['totalFiles'] - $quotaData['mainFiles'];
|
716 |
+
$thumbsProcessedCount = $this->_settings->getOpt( 'wp-short-pixel-thumbnail-count', 0);//amount of optimized thumbnails
|
717 |
+
$under5PercentCount = $this->_settings->getOpt( 'wp-short-pixel-files-under-5-percent', 0);//amount of under 5% optimized imgs.
|
718 |
|
719 |
//average compression
|
720 |
$averageCompression = self::getAverageCompression();
|
802 |
{
|
803 |
$validityData = $this->getQuotaInformation($_POST['key'], true, isset($_POST['validate']) && $_POST['validate'] == "validate");
|
804 |
|
805 |
+
$this->_settings->apiKey = $_POST['key'];
|
|
|
|
|
806 |
if($validityData['APIKeyValid']) {
|
807 |
if(isset($_POST['validate']) && $_POST['validate'] == "validate") {
|
808 |
// delete last status if it was no valid key
|
817 |
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.");
|
818 |
} else {
|
819 |
if ( function_exists("is_multisite") && is_multisite() )
|
820 |
+
$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>");
|
821 |
else
|
822 |
$notice = array("status" => "success", "msg" => 'API Key valid!');
|
823 |
}
|
824 |
}
|
825 |
+
$this->_settings->verifiedKey = true;
|
|
|
826 |
//test that the "uploads" have the right rights and also we can create the backup dir for ShortPixel
|
827 |
if ( !file_exists(SP_BACKUP_FOLDER) && !@mkdir(SP_BACKUP_FOLDER, 0777, true) )
|
828 |
$notice = array("status" => "error", "msg" => "There is something preventing us to create a new folder for backing up your original files.<BR>
|
832 |
//display notification
|
833 |
$notice = array("status" => "error", "msg" => $validityData["Message"]);
|
834 |
}
|
835 |
+
$this->_settings->verifiedKey = false;
|
|
|
836 |
}
|
837 |
}
|
838 |
|
839 |
|
840 |
//if save button - we process the rest of the form elements
|
841 |
if(isset($_POST['save'])) {
|
842 |
+
$this->_settings->compressionType = $_POST['compressionType'];
|
843 |
+
if(isset($_POST['thumbnails'])) { $this->_settings->processThumbnails = 1; } else { $this->_settings->processThumbnails = 0; }
|
844 |
+
if(isset($_POST['backupImages'])) { $this->_settings->backupImages = 1; } else { $this->_settings->backupImages = 0; }
|
845 |
+
if(isset($_POST['cmyk2rgb'])) { $this->_settings->CMYKtoRGBconversion = 1; } else { $this->_settings->CMYKtoRGBconversion = 0; }
|
846 |
+
$this->_settings->keepExif = isset($_POST['removeExif']) ? 0 : 1;
|
847 |
+
//delete_option('wp-short-pixel-keep-exif');
|
848 |
+
$this->_settings->resizeImages = (isset($_POST['resize']) ? 1: 0);
|
849 |
+
$this->_settings->resizeWidth = (isset($_POST['width']) ? $_POST['width']: $this->_settings->resizeWidth);
|
850 |
+
$this->_settings->resizeHeight = (isset($_POST['height']) ? $_POST['height']: $this->_settings->resizeHeight);
|
|
|
|
|
|
|
|
|
|
|
|
|
851 |
|
852 |
if($_POST['save'] == "Save and Go to Bulk Process") {
|
853 |
wp_redirect("upload.php?page=wp-short-pixel-bulk");
|
867 |
|
868 |
$quotaData = $this->checkQuotaAndAlert();
|
869 |
|
870 |
+
if($this->_settings->verifiedKey) {
|
871 |
+
$fileCount = number_format($this->_settings->fileCount);
|
872 |
+
$savedSpace = self::formatBytes($this->_settings->savedSpace,2);
|
873 |
$averageCompression = self::getAverageCompression();
|
874 |
+
$savedBandwidth = self::formatBytes($this->_settings->savedSpace * 10000,2);
|
875 |
if (is_numeric($quotaData['APICallsQuota'])) {
|
876 |
$quotaData['APICallsQuota'] .= "/month";
|
877 |
}
|
890 |
}
|
891 |
|
892 |
public function getAverageCompression(){
|
893 |
+
return $this->_settings->totalOptimized > 0
|
894 |
+
? round(( 1 - ( $this->_settings->totalOptimized / $this->_settings->totalOriginal ) ) * 100, 2)
|
895 |
: 0;
|
896 |
}
|
897 |
|
904 |
*/
|
905 |
public function getQuotaInformation($apiKey = null, $appendUserAgent = false, $validate = false) {
|
906 |
|
907 |
+
if(is_null($apiKey)) { $apiKey = $this->_settings->apiKey; }
|
908 |
|
909 |
$requestURL = 'https://api.shortpixel.com/v2/api-status.php';
|
910 |
$args = array('timeout'=> SP_VALIDATE_MAX_TIMEOUT,
|
969 |
}
|
970 |
|
971 |
if ( ( $data->APICallsMade + $data->APICallsMadeOneTime ) < ( $data->APICallsQuota + $data->APICallsQuotaOneTime ) ) //reset quota exceeded flag -> user is allowed to process more images.
|
972 |
+
$this->_settings->quotaExceeded = 0;
|
973 |
else
|
974 |
+
$this->_settings->quotaExceeded = 1;//activate quota limiting
|
975 |
|
976 |
//if a not valid status exists, delete it
|
977 |
+
$lastStatus = $this->_settings->getOpt( 'wp-short-pixel-bulk-last-status', array('Status' => ShortPixelAPI::STATUS_SUCCESS));
|
978 |
if($lastStatus['Status'] == ShortPixelAPI::STATUS_NO_KEY) {
|
979 |
delete_option('wp-short-pixel-bulk-last-status');
|
980 |
}
|
1006 |
{
|
1007 |
if ( $fileExtension <> "pdf" )
|
1008 |
{
|
1009 |
+
if(!$this->_settings->verifiedKey)
|
1010 |
print 'Invalid API Key. <a href="options-general.php?page=wp-shortpixel">Check your Settings</a>';
|
1011 |
else
|
1012 |
print 'Optimization N/A';
|
1013 |
}
|
1014 |
else
|
1015 |
{
|
1016 |
+
if ( $this->_settings->quotaExceeded )
|
1017 |
{
|
1018 |
print QUOTA_EXCEEDED;
|
1019 |
return;
|
1021 |
else
|
1022 |
{
|
1023 |
print 'PDF not processed';
|
1024 |
+
//if($this->_settings->verifiedKey) {
|
1025 |
print " <a class='button button-smaller button-primary' href=\"javascript:manualOptimization({$id})\">Optimize now</a>";
|
1026 |
//}
|
1027 |
return;
|
1032 |
{
|
1033 |
if(isset($meta['ShortPixel']['BulkProcessing']))
|
1034 |
{
|
1035 |
+
if ( $this->_settings->quotaExceeded )
|
1036 |
{
|
1037 |
print QUOTA_EXCEEDED;
|
1038 |
}
|
1050 |
print "Bonus processing";
|
1051 |
} else {
|
1052 |
print 'Reduced by ';
|
1053 |
+
print $data['ShortPixelImprovement'] . '%' . (isset($data['ShortPixel']['type']) ? ' (' . $data['ShortPixel']['type'] . ')' : '' );
|
1054 |
}
|
1055 |
if ( get_option('wp-short-backup_images') && !isset($data['ShortPixel']['NoBackup'])) //display restore backup option only when backup is active
|
1056 |
print " <a class='button button-smaller' href=\"admin.php?action=shortpixel_restore_backup&attachment_ID={$id}\">Restore backup</a>";
|
1057 |
+
if (isset($data['ShortPixel']['thumbs']) || (isset($data['sizes']) && count($data['sizes']))) {
|
1058 |
+
$sizes = count($data['sizes']);
|
1059 |
+
$cnt = isset($data['ShortPixel']['thumbsOpt']) ? $data['ShortPixel']['thumbsOpt'] : $sizes;
|
1060 |
+
print "<br>+" . $cnt . ($sizes > $cnt ? " of ".$sizes : '') . " thumbnails optimized";
|
1061 |
}
|
1062 |
}
|
1063 |
elseif ( $data['ShortPixelImprovement'] <> "Optimization N/A" )
|
1065 |
if ( trim(strip_tags($data['ShortPixelImprovement'])) == "Quota exceeded" )
|
1066 |
{
|
1067 |
print QUOTA_EXCEEDED;
|
1068 |
+
if ( !$this->_settings->quotaExceeded )
|
1069 |
print " <a class='button button-smaller button-primary' href=\"javascript:manualOptimization({$id})\">Try again</a>";
|
1070 |
}
|
1071 |
elseif ( trim(strip_tags($data['ShortPixelImprovement'])) == "Cannot write optimized file" )
|
1084 |
print "Optimization N/A";
|
1085 |
}
|
1086 |
} elseif(isset($data['ShortPixel']['WaitingProcessing'])) {
|
1087 |
+
if ( $this->_settings->quotaExceeded )
|
1088 |
{
|
1089 |
print QUOTA_EXCEEDED;
|
1090 |
}
|
1102 |
|
1103 |
if ( wp_attachment_is_image( $id ) )
|
1104 |
{
|
1105 |
+
if ( $this->_settings->quotaExceeded )
|
1106 |
{
|
1107 |
print QUOTA_EXCEEDED;
|
1108 |
}
|
1117 |
}
|
1118 |
elseif ( $fileExtension == "pdf" )
|
1119 |
{
|
1120 |
+
if ( $this->_settings->quotaExceeded )
|
1121 |
{
|
1122 |
print QUOTA_EXCEEDED;
|
1123 |
}
|
1201 |
|
1202 |
//it is NOT a PDF file and thumbs are processable
|
1203 |
if ( strtolower(substr($filePath[0],strrpos($filePath[0], ".")+1)) != "pdf"
|
1204 |
+
&& $this->_settings->processThumbnails
|
1205 |
&& isset($meta['sizes']) && is_array($meta['sizes']))
|
1206 |
{
|
1207 |
foreach( $meta['sizes'] as $thumbnailInfo )
|
1281 |
$limit = 500;
|
1282 |
$pointer = 0;
|
1283 |
|
1284 |
+
//METODA DE A OBTINE LISTA DE IMAGINI CU API-UL WP
|
1285 |
+
$query_images_args = array(
|
1286 |
+
'post_type' => 'attachment',
|
1287 |
+
'post_mime_type' => array('image','application/pdf'),
|
1288 |
+
'post_status' => 'inherit',
|
1289 |
+
'posts_per_page' => - 1,
|
1290 |
+
);
|
1291 |
+
|
1292 |
+
$query_images = new WP_Query( $query_images_args );
|
1293 |
+
|
1294 |
+
//var_dump(count($query_images->posts));
|
1295 |
+
|
1296 |
+
|
1297 |
+
|
1298 |
//count all the files, main and thumbs
|
1299 |
while ( 1 )
|
1300 |
{
|
1305 |
if ( empty($filesList) ) //we parsed all the results
|
1306 |
break;
|
1307 |
|
1308 |
+
$filesMap = array();
|
1309 |
foreach ( $filesList as $file )
|
1310 |
{
|
1311 |
if ( $file->meta_key == "_wp_attached_file" )
|
1312 |
{//count pdf files only
|
1313 |
$extension = substr($file->meta_value, strrpos($file->meta_value,".") + 1 );
|
1314 |
+
if ( $extension == "pdf" && !isset($filesMap[$file->meta_value]))
|
1315 |
{
|
1316 |
$totalFiles++;
|
1317 |
$mainFiles++;
|
1318 |
+
$filesMap[$file->meta_value] = 1;
|
1319 |
}
|
1320 |
}
|
1321 |
else
|
1322 |
{
|
1323 |
$attachment = unserialize($file->meta_value);
|
1324 |
+
if(isset($attachment['file']) && !isset($filesMap[$attachment['file']]) && self::isProcessablePath($attachment['file'])){
|
1325 |
+
if ( isset($attachment['sizes']) ) {
|
1326 |
$totalFiles += count($attachment['sizes']);
|
1327 |
+
}
|
1328 |
if ( isset($attachment['file']) )
|
1329 |
{
|
1330 |
$totalFiles++;
|
1331 |
$mainFiles++;
|
1332 |
+
$filesMap[$attachment['file']] = 1;
|
1333 |
}
|
1334 |
}
|
1335 |
}
|
1343 |
}
|
1344 |
|
1345 |
|
1346 |
+
//count all the already processed files in media library (while limiting the results to max 10000)
|
1347 |
public function countAllProcessedFiles($maxId = PHP_INT_MAX, $minId = 0){
|
1348 |
global $wpdb;
|
1349 |
|
1352 |
$pointer = 0;
|
1353 |
|
1354 |
//count all the files, main and thumbs
|
1355 |
+
$filesMap = array();
|
1356 |
while ( 1 )
|
1357 |
{
|
1358 |
$filesList= $wpdb->get_results("SELECT * FROM " . $wpdb->prefix . "postmeta
|
1365 |
foreach ( $filesList as $file )
|
1366 |
{
|
1367 |
$attachment = unserialize($file->meta_value);
|
1368 |
+
if ( isset($attachment['ShortPixelImprovement'])
|
1369 |
+
&& ($attachment['ShortPixelImprovement'] > 0 || $attachment['ShortPixelImprovement'] === 0.0)
|
1370 |
+
//for PDFs there is no file field so just let it pass.
|
1371 |
+
&& (!isset($attachment['file']) || !isset($filesMap[$attachment['file']])) ) {
|
1372 |
$processedMainFiles++;
|
1373 |
$processedTotalFiles++;
|
1374 |
+
if ( isset($attachment['ShortPixel']['thumbsOpt']) ) {
|
1375 |
+
$processedTotalFiles += $attachment['ShortPixel']['thumbsOpt'];
|
1376 |
+
} elseif ( isset($attachment['sizes']) ) {
|
1377 |
$processedTotalFiles += count($attachment['sizes']);
|
1378 |
}
|
1379 |
+
if ( isset($attachment['file']) ) {
|
1380 |
+
$filesMap[$attachment['file']] = 1;
|
1381 |
+
}
|
1382 |
}
|
1383 |
}
|
1384 |
unset($filesList);
|
1434 |
}
|
1435 |
|
1436 |
public function getApiKey() {
|
1437 |
+
return $this->_settings->apiKey;
|
1438 |
}
|
1439 |
|
1440 |
public function getPrioQ() {
|
1442 |
}
|
1443 |
|
1444 |
public function backupImages() {
|
1445 |
+
return $this->_settings->backupImages;
|
1446 |
}
|
1447 |
|
1448 |
public function processThumbnails() {
|
1449 |
+
return $this->_settings->processThumbnails;
|
1450 |
}
|
1451 |
+
|
1452 |
public function getCMYKtoRGBconversion() {
|
1453 |
+
return $this->_settings->CMYKtoRGBconversion;
|
1454 |
+
}
|
1455 |
+
|
1456 |
+
public function getSettings() {
|
1457 |
+
return $this->_settings;
|
1458 |
}
|
1459 |
|
1460 |
+
|
1461 |
+
public function getResizeImages() {
|
1462 |
+
return $this->_settings->resizeImages;
|
1463 |
}
|
1464 |
|
1465 |
public function getResizeWidth() {
|
1466 |
+
return $this->_settings->resizeWidth;
|
1467 |
}
|
1468 |
|
1469 |
public function getResizeHeight() {
|
1470 |
+
return $this->_settings->resizeHeight;
|
1471 |
}
|
1472 |
public function getAffiliateSufix() {
|
1473 |
return $this->_affiliateSufix;
|
1474 |
}
|
1475 |
public function getVerifiedKey() {
|
1476 |
+
return $this->_settings->verifiedKey;
|
1477 |
}
|
1478 |
public function getCompressionType() {
|
1479 |
+
return $this->_settings->compressionType;
|
1480 |
}
|
1481 |
|
1482 |
}
|