Version Description
- speedier file download from API resource
- SQL changed to use less CPU intensive queries
- improved BULK processing logic, faster results
- different small fixes & improvements
- skip processed images when running bulk processing
Download this release
Release Info
Developer | ShortPixel |
Plugin | ShortPixel Image Optimizer |
Version | 2.1.0 |
Comparing to | |
See all releases |
Code changes from version 2.0.9 to 2.1.0
- readme.txt +8 -4
- shortpixel_api.php +81 -61
- wp-shortpixel.php +279 -182
readme.txt
CHANGED
@@ -4,7 +4,7 @@ Contributors: AlexSP
|
|
4 |
Tags: picture, optimization, image editor, pngout, upload speed, shortpixel, compression, jpegmini, webp, lossless, cwebp, media, tinypng, jpegtran,image, image optimisation, 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, optimise pdf, shrink pdf, jpg, jpeg, jpg optimisation, optimise jpg, shrink jpg, gif, animated gif, optimise gif
|
5 |
Requires at least: 3.0.0 or higher
|
6 |
Tested up to: 4.1.1
|
7 |
-
Stable tag: 2.0
|
8 |
License: GPLv2 or later
|
9 |
License URI: http://www.gnu.org/licenses/gpl-2.0.html
|
10 |
|
@@ -107,10 +107,14 @@ The ShortPixel team is here to help. <a href="https://shortpixel.com/contact">Co
|
|
107 |
|
108 |
== Changelog ==
|
109 |
|
110 |
-
= 2.0
|
|
|
|
|
|
|
|
|
|
|
|
|
111 |
|
112 |
-
* fixed some missing quotes
|
113 |
-
* fixed DB access in a function
|
114 |
|
115 |
= 2.0.8 =
|
116 |
|
4 |
Tags: picture, optimization, image editor, pngout, upload speed, shortpixel, compression, jpegmini, webp, lossless, cwebp, media, tinypng, jpegtran,image, image optimisation, 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, optimise pdf, shrink pdf, jpg, jpeg, jpg optimisation, optimise jpg, shrink jpg, gif, animated gif, optimise gif
|
5 |
Requires at least: 3.0.0 or higher
|
6 |
Tested up to: 4.1.1
|
7 |
+
Stable tag: 2.1.0
|
8 |
License: GPLv2 or later
|
9 |
License URI: http://www.gnu.org/licenses/gpl-2.0.html
|
10 |
|
107 |
|
108 |
== Changelog ==
|
109 |
|
110 |
+
= 2.1.0 =
|
111 |
+
|
112 |
+
* speedier file download from API resource
|
113 |
+
* SQL changed to use less CPU intensive queries
|
114 |
+
* improved BULK processing logic, faster results
|
115 |
+
* different small fixes & improvements
|
116 |
+
* skip processed images when running bulk processing
|
117 |
|
|
|
|
|
118 |
|
119 |
= 2.0.8 =
|
120 |
|
shortpixel_api.php
CHANGED
@@ -93,6 +93,9 @@ class shortpixel_api {
|
|
93 |
$meta['ShortPixelImprovement'] = 'Timed out while processing.';
|
94 |
unset($meta['ShortPixel']['WaitingProcessing']);
|
95 |
wp_update_attachment_metadata($ID, $meta);
|
|
|
|
|
|
|
96 |
}
|
97 |
else
|
98 |
{//we'll try again next time user visits a page on admin panel
|
@@ -100,8 +103,6 @@ class shortpixel_api {
|
|
100 |
update_option('wp-short-pixel-api-retries', $apiRetries);
|
101 |
exit('Timed out while processing. (pass '.$apiRetries.')');
|
102 |
}
|
103 |
-
|
104 |
-
|
105 |
}
|
106 |
|
107 |
$response = $this->doRequests($url, $filePaths, $ID);//send requests to API
|
@@ -112,27 +113,21 @@ class shortpixel_api {
|
|
112 |
return false;
|
113 |
}
|
114 |
|
115 |
-
$data = $this->parseResponse($response);//get the actual
|
116 |
|
117 |
-
if(
|
118 |
-
printf('Web service returned an error. Please try again later.');
|
119 |
-
return false;
|
120 |
-
}
|
121 |
-
|
122 |
-
$firstImage = $data[0];//extract as object first image
|
123 |
-
|
124 |
-
//this part makes sure that all the sizes were processed and ready to be downloaded
|
125 |
-
foreach ( $data as $imageObject )
|
126 |
{
|
127 |
-
|
128 |
-
|
129 |
-
|
130 |
-
|
131 |
-
|
132 |
-
|
133 |
-
|
134 |
-
|
135 |
-
|
|
|
|
|
136 |
case 1:
|
137 |
//handle image has been scheduled
|
138 |
sleep(1);
|
@@ -142,6 +137,15 @@ class shortpixel_api {
|
|
142 |
//handle image has been processed
|
143 |
$this->handleSuccess($data, $url, $filePaths, $ID);
|
144 |
break;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
145 |
case -403:
|
146 |
return 'Quota exceeded</br>';
|
147 |
break;
|
@@ -155,15 +159,16 @@ class shortpixel_api {
|
|
155 |
//handle error
|
156 |
if ( isset($data[0]->Status->Message) )
|
157 |
return $data[0]->Status->Message;
|
158 |
-
|
|
|
159 |
}
|
160 |
-
|
161 |
return $data;
|
162 |
}
|
163 |
|
164 |
|
165 |
public function handleSuccess($callData, $url, $filePath, $ID) {
|
166 |
-
|
167 |
$counter = 0;
|
168 |
if($this->_compressionType)
|
169 |
{
|
@@ -178,38 +183,43 @@ class shortpixel_api {
|
|
178 |
|
179 |
foreach ( $callData as $fileData )//download each file from array and process it
|
180 |
{
|
181 |
-
|
182 |
-
if ( $counter == 0 )//save percent improvement for main file
|
183 |
-
$percentImprovement = $fileData->PercentImprovement;
|
184 |
-
|
185 |
-
$correctFileSize = $fileData->$fileSize;
|
186 |
-
$tempFiles[$counter] = download_url(urldecode($fileData->$fileType));
|
187 |
-
|
188 |
-
if(is_wp_error( $tempFiles[$counter] )) //also tries with http instead of https
|
189 |
{
|
190 |
-
|
191 |
-
|
192 |
-
}
|
193 |
|
194 |
-
|
195 |
-
|
196 |
-
|
197 |
-
|
198 |
-
|
199 |
-
|
200 |
-
|
201 |
-
|
202 |
-
|
203 |
-
|
204 |
-
|
205 |
-
|
206 |
-
|
207 |
-
|
208 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
209 |
}
|
|
|
|
|
210 |
$counter++;
|
211 |
}
|
212 |
|
|
|
213 |
//if backup is enabled
|
214 |
if(get_option('wp-short-backup_images'))
|
215 |
{
|
@@ -220,9 +230,9 @@ class shortpixel_api {
|
|
220 |
return sprintf("Backup folder does not exist and it could not be created");
|
221 |
}
|
222 |
$meta = wp_get_attachment_metadata($ID);
|
|
|
223 |
$source = $filePath;
|
224 |
-
|
225 |
-
|
226 |
if ( empty($SubDir) ) //its a PDF?
|
227 |
{
|
228 |
$uploadFilePath = get_attached_file($ID);
|
@@ -286,16 +296,24 @@ class shortpixel_api {
|
|
286 |
$sourceFile = $tempFile;
|
287 |
$destinationFile = WP_CONTENT_DIR . DIRECTORY_SEPARATOR . 'uploads' . DIRECTORY_SEPARATOR . $SubDir . basename($url[$counter]);
|
288 |
|
289 |
-
|
290 |
-
|
291 |
-
|
292 |
-
|
293 |
-
|
294 |
-
|
|
|
|
|
|
|
295 |
}
|
296 |
-
|
|
|
|
|
|
|
|
|
|
|
297 |
//save data to counters
|
298 |
-
if($success || $copySuccess) {
|
299 |
//update statistics
|
300 |
$fileData = $callData[$counter];
|
301 |
$savedSpace = $fileData->OriginalSize - $fileData->LossySize;
|
@@ -317,12 +335,14 @@ class shortpixel_api {
|
|
317 |
//update metadata
|
318 |
if(isset($ID)) {
|
319 |
$meta = wp_get_attachment_metadata($ID);
|
320 |
-
$meta['ShortPixelImprovement'] = $percentImprovement;
|
321 |
wp_update_attachment_metadata($ID, $meta);
|
322 |
}
|
323 |
|
324 |
//we reset the retry counter in case of success
|
325 |
update_option('wp-short-pixel-api-retries', 0);
|
|
|
|
|
326 |
|
327 |
}//end handleSuccess
|
328 |
|
93 |
$meta['ShortPixelImprovement'] = 'Timed out while processing.';
|
94 |
unset($meta['ShortPixel']['WaitingProcessing']);
|
95 |
wp_update_attachment_metadata($ID, $meta);
|
96 |
+
//also decrement last ID for queries so bulk won't hang in such cases
|
97 |
+
$startQueryID = get_option("wp-short-pixel-query-id-start");
|
98 |
+
update_option("wp-short-pixel-query-id-start", $startQueryID - 1);
|
99 |
}
|
100 |
else
|
101 |
{//we'll try again next time user visits a page on admin panel
|
103 |
update_option('wp-short-pixel-api-retries', $apiRetries);
|
104 |
exit('Timed out while processing. (pass '.$apiRetries.')');
|
105 |
}
|
|
|
|
|
106 |
}
|
107 |
|
108 |
$response = $this->doRequests($url, $filePaths, $ID);//send requests to API
|
113 |
return false;
|
114 |
}
|
115 |
|
116 |
+
$data = (array)$this->parseResponse($response);//get the actual response from API, convert it to an array if it is an object
|
117 |
|
118 |
+
if ( isset($data[0]) )//API returned image details
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
119 |
{
|
120 |
+
$firstImage = $data[0];//extract as object first image
|
121 |
+
foreach ( $data as $imageObject )
|
122 |
+
{ //this part makes sure that all the sizes were processed and ready to be downloaded
|
123 |
+
if ( $imageObject->Status->Code == 0 || $imageObject->Status->Code == 1 )
|
124 |
+
{
|
125 |
+
sleep(2);
|
126 |
+
return $this->processImage($url, $filePaths, $ID, $startTime);
|
127 |
+
}
|
128 |
+
}
|
129 |
+
|
130 |
+
switch($firstImage->Status->Code) {
|
131 |
case 1:
|
132 |
//handle image has been scheduled
|
133 |
sleep(1);
|
137 |
//handle image has been processed
|
138 |
$this->handleSuccess($data, $url, $filePaths, $ID);
|
139 |
break;
|
140 |
+
default:
|
141 |
+
//handle error
|
142 |
+
if ( isset($data[0]->Status->Message) )
|
143 |
+
return $data[0]->Status->Message;
|
144 |
+
}
|
145 |
+
}
|
146 |
+
else//API returned an error
|
147 |
+
{
|
148 |
+
switch($data['Status']->Code) {
|
149 |
case -403:
|
150 |
return 'Quota exceeded</br>';
|
151 |
break;
|
159 |
//handle error
|
160 |
if ( isset($data[0]->Status->Message) )
|
161 |
return $data[0]->Status->Message;
|
162 |
+
}
|
163 |
+
|
164 |
}
|
165 |
+
|
166 |
return $data;
|
167 |
}
|
168 |
|
169 |
|
170 |
public function handleSuccess($callData, $url, $filePath, $ID) {
|
171 |
+
|
172 |
$counter = 0;
|
173 |
if($this->_compressionType)
|
174 |
{
|
183 |
|
184 |
foreach ( $callData as $fileData )//download each file from array and process it
|
185 |
{
|
186 |
+
if ( $fileData->Status->Code == 2 ) //file was processed OK
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
187 |
{
|
188 |
+
if ( $counter == 0 )//save percent improvement for main file
|
189 |
+
$percentImprovement = $fileData->PercentImprovement;
|
|
|
190 |
|
191 |
+
$correctFileSize = $fileData->$fileSize;
|
192 |
+
$tempFiles[$counter] = download_url(urldecode($fileData->$fileType));
|
193 |
+
|
194 |
+
if(is_wp_error( $tempFiles[$counter] )) //also tries with http instead of https
|
195 |
+
{
|
196 |
+
sleep(1);
|
197 |
+
$tempFiles[$counter] = download_url(str_replace('https://', 'http://', urldecode($fileData->$fileType)));
|
198 |
+
}
|
199 |
+
|
200 |
+
if ( is_wp_error( $tempFiles[$counter] ) ) {
|
201 |
+
@unlink($tempFiles[$counter]);
|
202 |
+
return sprintf("Error downloading file (%s)", $tempFiles[$counter]->get_error_message());
|
203 |
+
die;
|
204 |
+
}
|
205 |
+
|
206 |
+
//check response so that download is OK
|
207 |
+
if( filesize($tempFiles[$counter]) != $correctFileSize) {
|
208 |
+
return sprintf("Error downloading file - incorrect file size");
|
209 |
+
die;
|
210 |
+
}
|
211 |
+
|
212 |
+
if (!file_exists($tempFiles[$counter])) {
|
213 |
+
return sprintf("Unable to locate downloaded file (%s)", $tempFiles[$counter]);
|
214 |
+
die;
|
215 |
+
}
|
216 |
}
|
217 |
+
else //there was an error while trying to download a file
|
218 |
+
$tempFiles[$counter] = "";
|
219 |
$counter++;
|
220 |
}
|
221 |
|
222 |
+
|
223 |
//if backup is enabled
|
224 |
if(get_option('wp-short-backup_images'))
|
225 |
{
|
230 |
return sprintf("Backup folder does not exist and it could not be created");
|
231 |
}
|
232 |
$meta = wp_get_attachment_metadata($ID);
|
233 |
+
$SubDir = ( isset($meta['file']) ) ? trim(substr($meta['file'],0,strrpos($meta['file'],"/")+1)) : "";
|
234 |
$source = $filePath;
|
235 |
+
|
|
|
236 |
if ( empty($SubDir) ) //its a PDF?
|
237 |
{
|
238 |
$uploadFilePath = get_attached_file($ID);
|
296 |
$sourceFile = $tempFile;
|
297 |
$destinationFile = WP_CONTENT_DIR . DIRECTORY_SEPARATOR . 'uploads' . DIRECTORY_SEPARATOR . $SubDir . basename($url[$counter]);
|
298 |
|
299 |
+
if ( $sourceFile <> "" && file_exists($sourceFile) )//possibly there was an error and the file couldn't have been processed
|
300 |
+
{
|
301 |
+
@unlink( $destinationFile );
|
302 |
+
$success = @rename( $sourceFile, $destinationFile );
|
303 |
+
|
304 |
+
if (!$success) {
|
305 |
+
$copySuccess = copy($sourceFile, $destinationFile);
|
306 |
+
unlink($sourceFile);
|
307 |
+
}
|
308 |
}
|
309 |
+
else
|
310 |
+
{
|
311 |
+
$success = 0;
|
312 |
+
$copySuccess = 0;
|
313 |
+
}
|
314 |
+
|
315 |
//save data to counters
|
316 |
+
if( $success || $copySuccess) {
|
317 |
//update statistics
|
318 |
$fileData = $callData[$counter];
|
319 |
$savedSpace = $fileData->OriginalSize - $fileData->LossySize;
|
335 |
//update metadata
|
336 |
if(isset($ID)) {
|
337 |
$meta = wp_get_attachment_metadata($ID);
|
338 |
+
$meta['ShortPixelImprovement'] = round($percentImprovement,2);
|
339 |
wp_update_attachment_metadata($ID, $meta);
|
340 |
}
|
341 |
|
342 |
//we reset the retry counter in case of success
|
343 |
update_option('wp-short-pixel-api-retries', 0);
|
344 |
+
//set this file as processed -> we decrement the cursor
|
345 |
+
update_option("wp-short-pixel-query-id-start", $ID - 1);//update max ID
|
346 |
|
347 |
}//end handleSuccess
|
348 |
|
wp-shortpixel.php
CHANGED
@@ -3,7 +3,7 @@
|
|
3 |
* Plugin Name: ShortPixel Image Optimiser
|
4 |
* Plugin URI: https://shortpixel.com/
|
5 |
* Description: ShortPixel is an image compression tool that helps improve your website performance. The plugin optimises images automatically using both lossy and lossless compression. Resulting, smaller, images are no different in quality from the original. To install: 1) Click the "Activate" link to the left of this description. 2) <a href="https://shortpixel.com/wp-apikey" target="_blank">Free Sign up</a> for your unique API Key . 3) Check your email for your API key. 4) Use your API key to activate ShortPixel plugin in the 'Plugins' menu in WordPress. 5) Done!
|
6 |
-
* Version: 2.0
|
7 |
* Author: ShortPixel
|
8 |
* Author URI: https://shortpixel.com
|
9 |
*/
|
@@ -12,7 +12,7 @@ require_once('shortpixel_api.php');
|
|
12 |
require_once( ABSPATH . 'wp-admin/includes/image.php' );
|
13 |
require_once( ABSPATH . 'wp-includes/pluggable.php' );
|
14 |
|
15 |
-
define('PLUGIN_VERSION', "2.0
|
16 |
define('SP_DEBUG', false);
|
17 |
define('SP_LOG', false);
|
18 |
define('SP_MAX_TIMEOUT', 10);
|
@@ -21,7 +21,8 @@ define('MUST_HAVE_KEY', true);
|
|
21 |
define('MAX_API_RETRIES', 5);
|
22 |
$MAX_EXECUTION_TIME = ini_get('max_execution_time');
|
23 |
if ( is_numeric($MAX_EXECUTION_TIME) )
|
24 |
-
define('MAX_EXECUTION_TIME', $MAX_EXECUTION_TIME -
|
|
|
25 |
|
26 |
class WPShortPixel {
|
27 |
|
@@ -50,6 +51,10 @@ class WPShortPixel {
|
|
50 |
add_action( 'admin_menu', array( &$this, 'registerSettingsPage' ) );//display SP in Settings menu
|
51 |
add_action( 'admin_menu', array( &$this, 'registerAdminPage' ) );
|
52 |
add_action( 'delete_attachment', array( &$this, 'handleDeleteAttachmentInBackup' ) );
|
|
|
|
|
|
|
|
|
53 |
|
54 |
//automatic optimization
|
55 |
add_action( 'admin_footer', array( &$this, 'my_action_javascript') );
|
@@ -109,9 +114,31 @@ class WPShortPixel {
|
|
109 |
if(get_option('wp-short-pixel-api-retries') === false) {//sometimes we need to retry processing/downloading a file multiple times
|
110 |
add_option( 'wp-short-pixel-api-retries', 0, '', 'yes' );
|
111 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
112 |
|
|
|
|
|
|
|
|
|
|
|
113 |
}
|
114 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
115 |
//set default move as "list". only set once, it won't try to set the default mode again.
|
116 |
public function setDefaultViewModeList()
|
117 |
{
|
@@ -124,7 +151,6 @@ class WPShortPixel {
|
|
124 |
get_currentuserinfo();
|
125 |
$currentUserID = $current_user->ID;
|
126 |
update_user_meta($currentUserID, "wp_media_library_mode", "list");
|
127 |
-
echo "OK";
|
128 |
}
|
129 |
}
|
130 |
|
@@ -174,13 +200,30 @@ class WPShortPixel {
|
|
174 |
}
|
175 |
|
176 |
public function handleImageUpload($meta, $ID = null) {
|
|
|
177 |
if(MUST_HAVE_KEY && $this->_verifiedKey)
|
178 |
{
|
|
|
|
|
|
|
|
|
|
|
179 |
self::log("Processing image id {$ID}");
|
180 |
$url = wp_get_attachment_url($ID);
|
181 |
$path = get_attached_file($ID);
|
182 |
if(self::isProcesable($path) != false)
|
183 |
{
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
184 |
$urlList[] = $url;
|
185 |
$filePath[] = $path;
|
186 |
//send request for thumbs as well, if needed
|
@@ -202,16 +245,17 @@ class WPShortPixel {
|
|
202 |
$this->_apiInterface->doRequests($urlList, $filePath);//send a processing request right after a file was uploaded
|
203 |
}
|
204 |
}
|
|
|
|
|
|
|
|
|
205 |
}
|
206 |
else
|
207 |
{
|
208 |
-
$meta['ShortPixelImprovement'] = '
|
209 |
return $meta;
|
210 |
}
|
211 |
-
|
212 |
-
|
213 |
-
$meta['ShortPixel']['WaitingProcessing'] = true;
|
214 |
-
return $meta;
|
215 |
}
|
216 |
|
217 |
public function handleImageProcessing($ID = null) {
|
@@ -219,30 +263,97 @@ class WPShortPixel {
|
|
219 |
echo "Missing API Key";
|
220 |
die();
|
221 |
}
|
222 |
-
//query database for first found entry that needs processing
|
223 |
global $wpdb;
|
224 |
-
|
225 |
-
|
226 |
-
|
227 |
-
|
228 |
-
|
229 |
-
|
230 |
-
$
|
231 |
-
|
232 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
233 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
234 |
//send a couple of pre-process requests (if available/needed)
|
235 |
if ( isset($idList[1]) )
|
236 |
{
|
237 |
$itemDetails = $this->returnURLsAndPaths($idList[1]);
|
238 |
$this->_apiInterface->doRequests($itemDetails['imageURLs'], $itemDetails['imagePaths']);
|
239 |
}
|
|
|
240 |
if ( isset($idList[2]) )
|
241 |
{
|
242 |
$itemDetails = $this->returnURLsAndPaths($idList[1]);
|
243 |
$this->_apiInterface->doRequests($itemDetails['imageURLs'], $itemDetails['imagePaths']);
|
244 |
}
|
245 |
|
|
|
246 |
//send a request for the latest item
|
247 |
$itemDetails = $this->returnURLsAndPaths($idList[0]);
|
248 |
$meta = $itemDetails['meta'];
|
@@ -255,20 +366,29 @@ class WPShortPixel {
|
|
255 |
$meta['ShortPixelImprovement'] = $result;
|
256 |
wp_update_attachment_metadata($ID, $meta);
|
257 |
echo "Error processing image: " . $result;
|
|
|
|
|
|
|
258 |
die;
|
259 |
}
|
260 |
|
261 |
//$processThumbnails = get_option('wp-short-process_thumbnails');
|
|
|
|
|
262 |
|
263 |
-
|
264 |
-
|
265 |
-
if(isset($meta['ShortPixel']['BulkProcessing'])) {
|
266 |
unset($meta['ShortPixel']['BulkProcessing']);
|
267 |
-
}
|
268 |
|
269 |
-
$meta['ShortPixelImprovement'] = $result[0]->PercentImprovement;
|
270 |
wp_update_attachment_metadata($ID, $meta);
|
271 |
echo "\nProcessing done succesfully for image #{$ID}";
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
272 |
|
273 |
die();
|
274 |
}
|
@@ -278,13 +398,13 @@ class WPShortPixel {
|
|
278 |
public function returnURLsAndPaths($itemDetails)
|
279 |
{
|
280 |
global $wpdb;
|
281 |
-
|
282 |
$imageIndex=0;
|
283 |
$ID = $itemDetails->post_id;
|
284 |
$imageURL = wp_get_attachment_url($ID);
|
285 |
$imagePath = get_attached_file($ID);
|
286 |
-
$meta = wp_get_attachment_metadata($ID);
|
287 |
-
|
288 |
if ( !isset($meta['file']) )//this could be a PDF file
|
289 |
{
|
290 |
$qry = "SELECT * FROM " . $wpdb->prefix . "postmeta
|
@@ -293,21 +413,24 @@ class WPShortPixel {
|
|
293 |
meta_key = '_wp_attached_file'
|
294 |
)";
|
295 |
$idList = $wpdb->get_results($qry);
|
296 |
-
|
297 |
-
|
298 |
-
|
299 |
-
|
300 |
-
|
301 |
-
|
302 |
-
if
|
303 |
-
if(
|
304 |
-
|
305 |
-
|
306 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
307 |
}
|
308 |
-
|
309 |
-
$imageURLs[] = $uploadDir['url'] . DIRECTORY_SEPARATOR . basename($idList->meta_value);//URL to PDF file
|
310 |
-
$imagePaths[] = $filePath;
|
311 |
}
|
312 |
else
|
313 |
{//process images
|
@@ -342,8 +465,10 @@ class WPShortPixel {
|
|
342 |
}
|
343 |
}
|
344 |
|
345 |
-
|
346 |
-
|
|
|
|
|
347 |
}
|
348 |
|
349 |
|
@@ -369,6 +494,9 @@ class WPShortPixel {
|
|
369 |
|
370 |
$result = $this->_apiInterface->processImage($urlList, $filePath, $attachmentID);//request to process all the images
|
371 |
|
|
|
|
|
|
|
372 |
// store the referring webpage location
|
373 |
$sendback = wp_get_referer();
|
374 |
// sanitize the referring webpage location
|
@@ -377,6 +505,14 @@ class WPShortPixel {
|
|
377 |
wp_redirect($sendback);
|
378 |
// we are done,
|
379 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
380 |
|
381 |
public function handleRestoreBackup() {
|
382 |
$attachmentID = intval($_GET['attachment_ID']);
|
@@ -432,7 +568,11 @@ class WPShortPixel {
|
|
432 |
if(self::isProcesable($uploadFilePath) != false) {
|
433 |
try {
|
434 |
$uploadDir = wp_upload_dir();
|
435 |
-
|
|
|
|
|
|
|
|
|
436 |
if ( empty($SubDir) ) //its a PDF?
|
437 |
{
|
438 |
$uploadFilePath = get_attached_file($ID);
|
@@ -459,25 +599,6 @@ class WPShortPixel {
|
|
459 |
}
|
460 |
}
|
461 |
|
462 |
-
public function bulkOptimizeActionHandler($hook) {
|
463 |
-
if($hook == 'upload.php') {
|
464 |
-
if($_GET['action'] == 2) {
|
465 |
-
if(!empty($_GET['media'])) {
|
466 |
-
$imageLog = array();
|
467 |
-
//remove all ShortPixel data from metadata
|
468 |
-
foreach($_GET['media'] as $attachmentID) {
|
469 |
-
$meta = wp_get_attachment_metadata($attachmentID);
|
470 |
-
$meta['ShortPixel']['BulkProcessing'] = true;
|
471 |
-
unset($meta['ShortPixelImprovement']);
|
472 |
-
wp_update_attachment_metadata($attachmentID, $meta);
|
473 |
-
$imageLog[$attachmentID] = false;
|
474 |
-
}
|
475 |
-
update_option('bulkProcessingLog', $imageLog);
|
476 |
-
}
|
477 |
-
}
|
478 |
-
}
|
479 |
-
}
|
480 |
-
|
481 |
public function registerSettingsPage() {
|
482 |
add_options_page( 'ShortPixel Settings', 'ShortPixel', 'manage_options', 'wp-shortpixel', array($this, 'renderSettingsMenu'));
|
483 |
}
|
@@ -487,6 +608,8 @@ class WPShortPixel {
|
|
487 |
}
|
488 |
|
489 |
public function bulkProcess() {
|
|
|
|
|
490 |
echo '<h1>Bulk Image Optimisation by ShortPixel</h1>';
|
491 |
|
492 |
if(MUST_HAVE_KEY && $this->_verifiedKey == false) {//invalid API Key
|
@@ -495,133 +618,94 @@ class WPShortPixel {
|
|
495 |
return;
|
496 |
}
|
497 |
|
498 |
-
if($_GET['cancel'])
|
499 |
-
|
500 |
-
|
501 |
-
|
502 |
-
|
503 |
-
}
|
504 |
}
|
505 |
|
506 |
-
$
|
507 |
-
$attachments_images = get_posts( array(
|
508 |
-
'numberposts' => -1,
|
509 |
-
'post_type' => 'attachment',
|
510 |
-
'post_mime_type' => 'image'
|
511 |
-
));
|
512 |
-
$attachments_pdf = get_posts( array(
|
513 |
-
'numberposts' => -1,
|
514 |
-
'post_type' => 'attachment',
|
515 |
-
'post_mime_type' => 'application/pdf'
|
516 |
-
));
|
517 |
-
$attachments = array_merge($attachments_images, $attachments_pdf);
|
518 |
-
|
519 |
-
|
520 |
-
if($_POST["bulkProcess"])
|
521 |
{
|
522 |
-
$
|
523 |
-
$
|
524 |
-
|
525 |
-
|
526 |
-
|
527 |
-
|
528 |
-
|
529 |
-
|
530 |
-
if(self::isProcesable(get_attached_file($attachment->ID)) == false) continue;//skip this record
|
531 |
-
//apparently if the main image isn't on disk -> the result is false above
|
532 |
-
|
533 |
-
//prepare bulk call for processing
|
534 |
-
$imagePath = wp_get_attachment_url($attachment->ID);
|
535 |
-
$filePathOnDisk = get_attached_file($attachment->ID);
|
536 |
-
$imageDiskPath[] = $filePathOnDisk;
|
537 |
-
$imageList[] = $imagePath;
|
538 |
-
|
539 |
-
$meta = wp_get_attachment_metadata($attachment->ID);
|
540 |
-
$SubDirs = substr($meta['file'],0,strrpos($meta['file'],"/")+1);
|
541 |
-
|
542 |
-
if($processThumbnails && isset($meta['sizes'])) {
|
543 |
-
foreach($meta['sizes'] as $thumbnailData) {
|
544 |
-
$imageOnDisk = $uploadDir . DIRECTORY_SEPARATOR . $SubDirs . basename($thumbnailData["file"]);
|
545 |
-
|
546 |
-
if ( file_exists($imageOnDisk) )//make sure each version of the main file is on disk
|
547 |
-
{
|
548 |
-
$thumbPath = substr($imagePath, 0, strrpos($imagePath, '/')) . '/' . $thumbnailData["file"];
|
549 |
-
$imageList[] = $thumbPath;
|
550 |
-
$imageDiskPath[] = $imageOnDisk;
|
551 |
-
}
|
552 |
-
}
|
553 |
-
}
|
554 |
-
|
555 |
-
$meta['ShortPixel']['BulkProcessing'] = true;
|
556 |
-
wp_update_attachment_metadata($attachment->ID, $meta);
|
557 |
-
}
|
558 |
-
|
559 |
-
|
560 |
-
if(count($imageList) > 10) {
|
561 |
-
echo "<BR>Counter going";
|
562 |
-
$batchList = array();
|
563 |
-
foreach($imageList as $image) {
|
564 |
-
$batchList[] = $image;
|
565 |
|
566 |
-
|
567 |
-
|
568 |
-
|
569 |
-
|
570 |
-
|
571 |
-
|
572 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
573 |
|
574 |
-
|
575 |
-
|
576 |
-
}
|
577 |
|
|
|
578 |
|
579 |
-
|
580 |
-
|
|
|
|
|
581 |
|
582 |
-
|
583 |
-
|
584 |
-
WHERE meta_value LIKE '%\"BulkProcessing\";b:1;%'";
|
585 |
-
$idList = $wpdb->get_results($qry);
|
586 |
-
|
587 |
-
if(!empty($idList)) {
|
588 |
-
if(is_array($idList)) {
|
589 |
-
echo "<p>
|
590 |
-
Bulk optimisation has started. This process will take some time, depending on the number of images in your library. <BR>Do not worry about the slow speed, it is a necessary measure in order not to interfere with the normal functioning of your site.<BR><BR>
|
591 |
-
This is a brief estimation of the bulk processing times:<BR>
|
592 |
-
1 to 100 images < 20 min <BR>
|
593 |
-
100 to 500 images < 2 hour<BR>
|
594 |
-
500 to 1000 images < 4 hours<BR>
|
595 |
-
over 1000 images > 4 hours or more<BR><BR>
|
596 |
-
|
597 |
-
The latest status of the processing will be displayed here every 30 seconds.<BR>
|
598 |
-
In the meantime, you can continue using the admin as usual.<BR>
|
599 |
-
However, <b>you musn’t close the WordPress admin</b>, or the bulk processing will stop.
|
600 |
-
</p>";
|
601 |
-
echo '
|
602 |
-
<script type="text/javascript" >
|
603 |
-
var bulkProcessingRunning = true;
|
604 |
-
</script>
|
605 |
-
';
|
606 |
-
|
607 |
-
$imagesLeft = count($idList);
|
608 |
-
$totalImages = count($attachments);
|
609 |
-
|
610 |
-
echo "<p>{$imagesLeft} out of {$totalImages} images left to process.</p>";
|
611 |
-
|
612 |
-
echo '
|
613 |
-
<a class="button button-secondary" href="' . get_admin_url() . 'upload.php">Media Library</a>
|
614 |
-
<a class="button button-secondary" href="' . get_admin_url() . 'upload.php?page=wp-short-pixel-bulk&cancel=1">Cancel Processing</a>
|
615 |
-
';
|
616 |
-
}
|
617 |
-
} else {
|
618 |
$bulkProcessingStatus = get_option('bulkProcessingStatus');
|
619 |
-
if(isset($bulkProcessingStatus) && $bulkProcessingStatus == 'running')
|
|
|
620 |
echo "<p>Bulk optimisation was successful. ShortPixel has finished optimising all your images.</p>
|
621 |
<p>Go to the ShortPixel <a href='" . get_admin_url() . "options-general.php?page=wp-shortpixel#facts'>Stats</a> and see your website's optimised stats (in Settings > ShortPixel). </p>";
|
622 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
623 |
}
|
624 |
-
|
|
|
625 |
echo '
|
626 |
<script type="text/javascript" >
|
627 |
var bulkProcessingRunning = false;
|
@@ -661,6 +745,7 @@ class WPShortPixel {
|
|
661 |
$noticeHTML = "<br/><div style=\"background-color: #fff; border-left: 4px solid %s; box-shadow: 0 1px 1px 0 rgba(0, 0, 0, 0.1); padding: 1px 12px;\"><p>%s</p></div>";
|
662 |
|
663 |
if(isset($_POST['submit']) || isset($_POST['validate'])) {
|
|
|
664 |
//handle API Key - common for submit and validate
|
665 |
$_POST['key'] = trim($_POST['key']);
|
666 |
$validityData = $this->getQuotaInformation($_POST['key'], true);
|
@@ -949,8 +1034,20 @@ HTML;
|
|
949 |
$data = wp_get_attachment_metadata($id);
|
950 |
$file = get_attached_file($id);
|
951 |
$fileExtension = strtolower(substr($file,strrpos($file,".")+1));
|
952 |
-
|
953 |
-
if (
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
954 |
if(isset($meta['ShortPixel']['BulkProcessing'])) {
|
955 |
print 'Waiting for bulk processing';
|
956 |
return;
|
@@ -962,8 +1059,8 @@ HTML;
|
|
962 |
print " | <a href=\"admin.php?action=shortpixel_restore_backup&attachment_ID={$id}\">Restore backup</a>";
|
963 |
return;
|
964 |
}
|
965 |
-
|
966 |
-
print '';
|
967 |
} elseif(isset($data['ShortPixel']['WaitingProcessing'])) {
|
968 |
print 'Image waiting to be processed';
|
969 |
return;
|
3 |
* Plugin Name: ShortPixel Image Optimiser
|
4 |
* Plugin URI: https://shortpixel.com/
|
5 |
* Description: ShortPixel is an image compression tool that helps improve your website performance. The plugin optimises images automatically using both lossy and lossless compression. Resulting, smaller, images are no different in quality from the original. To install: 1) Click the "Activate" link to the left of this description. 2) <a href="https://shortpixel.com/wp-apikey" target="_blank">Free Sign up</a> for your unique API Key . 3) Check your email for your API key. 4) Use your API key to activate ShortPixel plugin in the 'Plugins' menu in WordPress. 5) Done!
|
6 |
+
* Version: 2.1.0
|
7 |
* Author: ShortPixel
|
8 |
* Author URI: https://shortpixel.com
|
9 |
*/
|
12 |
require_once( ABSPATH . 'wp-admin/includes/image.php' );
|
13 |
require_once( ABSPATH . 'wp-includes/pluggable.php' );
|
14 |
|
15 |
+
define('PLUGIN_VERSION', "2.1.0");
|
16 |
define('SP_DEBUG', false);
|
17 |
define('SP_LOG', false);
|
18 |
define('SP_MAX_TIMEOUT', 10);
|
21 |
define('MAX_API_RETRIES', 5);
|
22 |
$MAX_EXECUTION_TIME = ini_get('max_execution_time');
|
23 |
if ( is_numeric($MAX_EXECUTION_TIME) )
|
24 |
+
define('MAX_EXECUTION_TIME', $MAX_EXECUTION_TIME - 3 ); //in seconds
|
25 |
+
define("SP_MAX_RESULTS_QUERY", 6);
|
26 |
|
27 |
class WPShortPixel {
|
28 |
|
51 |
add_action( 'admin_menu', array( &$this, 'registerSettingsPage' ) );//display SP in Settings menu
|
52 |
add_action( 'admin_menu', array( &$this, 'registerAdminPage' ) );
|
53 |
add_action( 'delete_attachment', array( &$this, 'handleDeleteAttachmentInBackup' ) );
|
54 |
+
|
55 |
+
//when plugin is activated run this
|
56 |
+
register_activation_hook( __FILE__, array( &$this, 'shortPixelActivatePlugin' ) );
|
57 |
+
register_deactivation_hook( __FILE__, array( &$this, 'shortPixelDeactivatePlugin' ) );
|
58 |
|
59 |
//automatic optimization
|
60 |
add_action( 'admin_footer', array( &$this, 'my_action_javascript') );
|
114 |
if(get_option('wp-short-pixel-api-retries') === false) {//sometimes we need to retry processing/downloading a file multiple times
|
115 |
add_option( 'wp-short-pixel-api-retries', 0, '', 'yes' );
|
116 |
}
|
117 |
+
|
118 |
+
if(get_option('wp-short-pixel-query-id-start') === false) {//current query ID used for postmeta
|
119 |
+
add_option( 'wp-short-pixel-query-id-start', 0, '', 'yes' );
|
120 |
+
}
|
121 |
+
|
122 |
+
if(get_option('wp-short-pixel-query-id-stop') === false) {//current query ID used for postmeta
|
123 |
+
add_option( 'wp-short-pixel-query-id-stop', 0, '', 'yes' );
|
124 |
+
}
|
125 |
+
|
126 |
+
}
|
127 |
|
128 |
+
public function shortPixelActivatePlugin()//reset some params to avoid troubles for plugins that were activated/deactivated/activated
|
129 |
+
{
|
130 |
+
delete_option('bulkProcessingStatus');
|
131 |
+
update_option( 'wp-short-pixel-query-id-stop', 0 );
|
132 |
+
update_option( 'wp-short-pixel-query-id-start', 0 );
|
133 |
}
|
134 |
|
135 |
+
public function shortPixelDeactivatePlugin()//reset some params to avoid troubles for plugins that were activated/deactivated/activated
|
136 |
+
{
|
137 |
+
delete_option('bulkProcessingStatus');
|
138 |
+
update_option( 'wp-short-pixel-query-id-stop', 0 );
|
139 |
+
update_option( 'wp-short-pixel-query-id-start', 0 );
|
140 |
+
}
|
141 |
+
|
142 |
//set default move as "list". only set once, it won't try to set the default mode again.
|
143 |
public function setDefaultViewModeList()
|
144 |
{
|
151 |
get_currentuserinfo();
|
152 |
$currentUserID = $current_user->ID;
|
153 |
update_user_meta($currentUserID, "wp_media_library_mode", "list");
|
|
|
154 |
}
|
155 |
}
|
156 |
|
200 |
}
|
201 |
|
202 |
public function handleImageUpload($meta, $ID = null) {
|
203 |
+
|
204 |
if(MUST_HAVE_KEY && $this->_verifiedKey)
|
205 |
{
|
206 |
+
$bulkProcessingStatus = get_option('bulkProcessingStatus');
|
207 |
+
//update variable to keep track of this new attachment but only if bulk isn't running
|
208 |
+
if( $bulkProcessingStatus <> 'running' )
|
209 |
+
update_option("wp-short-pixel-query-id-start", $ID);
|
210 |
+
|
211 |
self::log("Processing image id {$ID}");
|
212 |
$url = wp_get_attachment_url($ID);
|
213 |
$path = get_attached_file($ID);
|
214 |
if(self::isProcesable($path) != false)
|
215 |
{
|
216 |
+
if ( empty($meta) && $bulkProcessingStatus <> 'running' )//here's a PDF file most likely, while bulk not running
|
217 |
+
{
|
218 |
+
$meta['ShortPixel']['WaitingProcessing'] = true;
|
219 |
+
return $meta;
|
220 |
+
}
|
221 |
+
elseif ( empty($meta) && $bulkProcessingStatus == 'running' )//while bulk running
|
222 |
+
{
|
223 |
+
return $meta;
|
224 |
+
}
|
225 |
+
|
226 |
+
|
227 |
$urlList[] = $url;
|
228 |
$filePath[] = $path;
|
229 |
//send request for thumbs as well, if needed
|
245 |
$this->_apiInterface->doRequests($urlList, $filePath);//send a processing request right after a file was uploaded
|
246 |
}
|
247 |
}
|
248 |
+
|
249 |
+
if ( $bulkProcessingStatus <> 'running' )
|
250 |
+
$meta['ShortPixel']['WaitingProcessing'] = true;
|
251 |
+
return $meta;
|
252 |
}
|
253 |
else
|
254 |
{
|
255 |
+
$meta['ShortPixelImprovement'] = 'Optimisation N/A';
|
256 |
return $meta;
|
257 |
}
|
258 |
+
}
|
|
|
|
|
|
|
259 |
}
|
260 |
|
261 |
public function handleImageProcessing($ID = null) {
|
263 |
echo "Missing API Key";
|
264 |
die();
|
265 |
}
|
266 |
+
//query database for first found entry that needs processing //
|
267 |
global $wpdb;
|
268 |
+
|
269 |
+
//////////////////
|
270 |
+
|
271 |
+
$startQueryID = get_option('wp-short-pixel-query-id-start');
|
272 |
+
$endQueryID = get_option('wp-short-pixel-query-id-stop');
|
273 |
+
sleep(1);
|
274 |
+
$queryPostMeta = "SELECT * FROM " . $wpdb->prefix . "postmeta
|
275 |
+
WHERE ( post_id <= $startQueryID AND post_id > $endQueryID ) AND (
|
276 |
+
meta_key = '_wp_attached_file'
|
277 |
+
OR meta_key = '_wp_attachment_metadata'
|
278 |
+
)
|
279 |
+
ORDER BY post_id DESC
|
280 |
+
LIMIT " . SP_MAX_RESULTS_QUERY;
|
281 |
+
$resultsPostMeta = $wpdb->get_results($queryPostMeta);
|
282 |
+
$idList = array();
|
283 |
+
foreach ( $resultsPostMeta as $itemMetaData )
|
284 |
+
{
|
285 |
+
$meta = wp_get_attachment_metadata($itemMetaData->post_id);
|
286 |
+
$meta['ShortPixelImprovement'] = ( isset($meta['ShortPixelImprovement']) ) ? $meta['ShortPixelImprovement'] : "";
|
287 |
+
$filePath = get_attached_file($itemMetaData->post_id);
|
288 |
+
$fileExtension = strtolower(substr($filePath,strrpos($filePath,".")+1));
|
289 |
+
|
290 |
+
if ( ( $itemMetaData->meta_key == "_wp_attachment_metadata" && $meta['ShortPixelImprovement'] <> "Optimisation N/A" && !is_numeric($meta['ShortPixelImprovement']) ) || $fileExtension == "pdf" )//Optimisation N/A = is an unsupported file format
|
291 |
+
{
|
292 |
+
$idList[] = $itemMetaData;
|
293 |
+
}
|
294 |
+
}
|
295 |
+
|
296 |
+
if ( isset($idList[0]) )
|
297 |
+
{
|
298 |
+
$meta = wp_get_attachment_metadata($idList[0]->post_id);
|
299 |
+
$filePath = get_attached_file($idList[0]->post_id);
|
300 |
+
$fileExtension = strtolower(substr($filePath,strrpos($filePath,".")+1));
|
301 |
+
|
302 |
+
if( !empty($meta) && !isset($meta['ShortPixel']['WaitingProcessing']) ) //possibly the file wasn't processed in the first pass so we'll wait for it to be completed
|
303 |
+
{
|
304 |
+
$startQueryID = ( $idList[0]->post_id );
|
305 |
+
update_option("wp-short-pixel-query-id-start", $startQueryID);//update max ID
|
306 |
+
}
|
307 |
+
elseif ( empty($meta) && $fileExtension <> "pdf" )//file is not an image or PDF so we just skip to the next batch
|
308 |
+
{
|
309 |
+
$startQueryID = $startQueryID - SP_MAX_RESULTS_QUERY;
|
310 |
+
update_option("wp-short-pixel-query-id-start", $startQueryID);//update max ID
|
311 |
+
die();
|
312 |
+
}
|
313 |
+
elseif ( !self::isProcesable($filePath) )//file has a non-supported extension, we skip it
|
314 |
+
{
|
315 |
+
$startQueryID = $idList[0]->post_id - 1;
|
316 |
+
update_option("wp-short-pixel-query-id-start", $startQueryID);//update max ID
|
317 |
+
die();
|
318 |
+
}
|
319 |
+
else //file was processed in the first pass
|
320 |
+
{
|
321 |
+
$startQueryID = $idList[0]->post_id;
|
322 |
+
update_option("wp-short-pixel-query-id-start", $startQueryID);//update max ID
|
323 |
+
}
|
324 |
+
}
|
325 |
+
elseif ( $startQueryID > $endQueryID )
|
326 |
+
{
|
327 |
+
$startQueryID = $startQueryID - 1;
|
328 |
+
update_option("wp-short-pixel-query-id-start", $startQueryID);//update max ID
|
329 |
+
die();
|
330 |
+
}
|
331 |
+
|
332 |
+
//////////////////////
|
333 |
|
334 |
+
if( empty($idList) && $startQueryID <= $endQueryID ) { //die but before set the $endQueryID so only new files will be processed
|
335 |
+
$queryMax = "SELECT max(post_id) as startQueryID FROM " . $wpdb->prefix . "postmeta";
|
336 |
+
$resultQuery = $wpdb->get_results($queryMax);
|
337 |
+
$endQueryID = $resultQuery[0]->startQueryID;
|
338 |
+
update_option('wp-short-pixel-query-id-stop', $endQueryID);
|
339 |
+
delete_option('bulkProcessingStatus');
|
340 |
+
echo 'Empty queue - '.$endQueryID; die;
|
341 |
+
}
|
342 |
+
|
343 |
//send a couple of pre-process requests (if available/needed)
|
344 |
if ( isset($idList[1]) )
|
345 |
{
|
346 |
$itemDetails = $this->returnURLsAndPaths($idList[1]);
|
347 |
$this->_apiInterface->doRequests($itemDetails['imageURLs'], $itemDetails['imagePaths']);
|
348 |
}
|
349 |
+
|
350 |
if ( isset($idList[2]) )
|
351 |
{
|
352 |
$itemDetails = $this->returnURLsAndPaths($idList[1]);
|
353 |
$this->_apiInterface->doRequests($itemDetails['imageURLs'], $itemDetails['imagePaths']);
|
354 |
}
|
355 |
|
356 |
+
|
357 |
//send a request for the latest item
|
358 |
$itemDetails = $this->returnURLsAndPaths($idList[0]);
|
359 |
$meta = $itemDetails['meta'];
|
366 |
$meta['ShortPixelImprovement'] = $result;
|
367 |
wp_update_attachment_metadata($ID, $meta);
|
368 |
echo "Error processing image: " . $result;
|
369 |
+
//also decrement last ID for queries so bulk won't hang in such cases
|
370 |
+
$startQueryID = get_option("wp-short-pixel-query-id-start");
|
371 |
+
update_option("wp-short-pixel-query-id-start", $startQueryID - 1);
|
372 |
die;
|
373 |
}
|
374 |
|
375 |
//$processThumbnails = get_option('wp-short-process_thumbnails');
|
376 |
+
if ( isset($meta['ShortPixel']['WaitingProcessing']) )
|
377 |
+
unset($meta['ShortPixel']['WaitingProcessing']);
|
378 |
|
379 |
+
if( isset($meta['ShortPixel']['BulkProcessing']) )
|
|
|
|
|
380 |
unset($meta['ShortPixel']['BulkProcessing']);
|
|
|
381 |
|
382 |
+
$meta['ShortPixelImprovement'] = round($result[0]->PercentImprovement,2);
|
383 |
wp_update_attachment_metadata($ID, $meta);
|
384 |
echo "\nProcessing done succesfully for image #{$ID}";
|
385 |
+
|
386 |
+
//set the next ID to be processed (skip to the next valid value)
|
387 |
+
if ( isset($isList[1]) )
|
388 |
+
{
|
389 |
+
$startQueryID = $idList[1]->post_id;
|
390 |
+
update_option("wp-short-pixel-query-id-start", $startQueryID);//update max ID
|
391 |
+
}
|
392 |
|
393 |
die();
|
394 |
}
|
398 |
public function returnURLsAndPaths($itemDetails)
|
399 |
{
|
400 |
global $wpdb;
|
401 |
+
|
402 |
$imageIndex=0;
|
403 |
$ID = $itemDetails->post_id;
|
404 |
$imageURL = wp_get_attachment_url($ID);
|
405 |
$imagePath = get_attached_file($ID);
|
406 |
+
$meta = wp_get_attachment_metadata($ID);
|
407 |
+
|
408 |
if ( !isset($meta['file']) )//this could be a PDF file
|
409 |
{
|
410 |
$qry = "SELECT * FROM " . $wpdb->prefix . "postmeta
|
413 |
meta_key = '_wp_attached_file'
|
414 |
)";
|
415 |
$idList = $wpdb->get_results($qry);
|
416 |
+
if ( isset($idList[0]) )
|
417 |
+
{
|
418 |
+
$idList = $idList[0];
|
419 |
+
$uploadDir = wp_upload_dir();
|
420 |
+
$filePath = $uploadDir['path'] . DIRECTORY_SEPARATOR . basename($idList->meta_value);
|
421 |
+
|
422 |
+
//check if the image file exists on disk, if not set the right params
|
423 |
+
if(!file_exists($filePath)) {
|
424 |
+
if(isset($meta['ShortPixel']['BulkProcessing'])) { unset($meta['ShortPixel']['BulkProcessing']); }
|
425 |
+
if(isset($meta['ShortPixel']['WaitingProcessing'])) { unset($meta['ShortPixel']['WaitingProcessing']); }
|
426 |
+
$meta['ShortPixel']['NoFileOnDisk'] = true;
|
427 |
+
wp_update_attachment_metadata($ID, $meta);
|
428 |
+
die;
|
429 |
+
}
|
430 |
+
|
431 |
+
$imageURLs[] = $uploadDir['url'] . DIRECTORY_SEPARATOR . basename($idList->meta_value);//URL to PDF file
|
432 |
+
$imagePaths[] = $filePath;
|
433 |
}
|
|
|
|
|
|
|
434 |
}
|
435 |
else
|
436 |
{//process images
|
465 |
}
|
466 |
}
|
467 |
|
468 |
+
if ( isset($imageURLs) )
|
469 |
+
return array("imageURLs" => $imageURLs, "imagePaths" => $imagePaths, "meta" => $meta, "ID" => $ID);
|
470 |
+
else
|
471 |
+
return false;
|
472 |
}
|
473 |
|
474 |
|
494 |
|
495 |
$result = $this->_apiInterface->processImage($urlList, $filePath, $attachmentID);//request to process all the images
|
496 |
|
497 |
+
if ( !is_array($result) )//there was an error, we save it in ShortPixelImprovement data
|
498 |
+
$this->handleError($attachmentID, $result);
|
499 |
+
|
500 |
// store the referring webpage location
|
501 |
$sendback = wp_get_referer();
|
502 |
// sanitize the referring webpage location
|
505 |
wp_redirect($sendback);
|
506 |
// we are done,
|
507 |
}
|
508 |
+
|
509 |
+
//save error in file's meta data
|
510 |
+
public function handleError($ID, $result)
|
511 |
+
{
|
512 |
+
$meta = wp_get_attachment_metadata($ID);
|
513 |
+
$meta['ShortPixelImprovement'] = $result;
|
514 |
+
wp_update_attachment_metadata($ID, $meta);
|
515 |
+
}
|
516 |
|
517 |
public function handleRestoreBackup() {
|
518 |
$attachmentID = intval($_GET['attachment_ID']);
|
568 |
if(self::isProcesable($uploadFilePath) != false) {
|
569 |
try {
|
570 |
$uploadDir = wp_upload_dir();
|
571 |
+
if ( isset($meta['file']) )
|
572 |
+
$SubDir = substr($meta['file'],0,strrpos($meta['file'],"/")+1);
|
573 |
+
else
|
574 |
+
$SubDir = "";
|
575 |
+
|
576 |
if ( empty($SubDir) ) //its a PDF?
|
577 |
{
|
578 |
$uploadFilePath = get_attached_file($ID);
|
599 |
}
|
600 |
}
|
601 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
602 |
public function registerSettingsPage() {
|
603 |
add_options_page( 'ShortPixel Settings', 'ShortPixel', 'manage_options', 'wp-shortpixel', array($this, 'renderSettingsMenu'));
|
604 |
}
|
608 |
}
|
609 |
|
610 |
public function bulkProcess() {
|
611 |
+
global $wpdb;
|
612 |
+
|
613 |
echo '<h1>Bulk Image Optimisation by ShortPixel</h1>';
|
614 |
|
615 |
if(MUST_HAVE_KEY && $this->_verifiedKey == false) {//invalid API Key
|
618 |
return;
|
619 |
}
|
620 |
|
621 |
+
if(isset($_GET['cancel']))
|
622 |
+
{//cancel an ongoing bulk processing, it might be needed sometimes
|
623 |
+
update_option("wp-short-pixel-query-id-start", 0);
|
624 |
+
update_option("wp-short-pixel-query-id-stop", 0);
|
625 |
+
delete_option('bulkProcessingStatus');
|
|
|
626 |
}
|
627 |
|
628 |
+
if(isset($_POST["bulkProcess"]))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
629 |
{
|
630 |
+
$queryMax = "SELECT max(post_id) as startQueryID FROM " . $wpdb->prefix . "postmeta";
|
631 |
+
$resultQuery = $wpdb->get_results($queryMax);
|
632 |
+
$startQueryID = $resultQuery[0]->startQueryID;
|
633 |
+
update_option("wp-short-pixel-query-id-start", $startQueryID);//start downwards from the biggest item ID
|
634 |
+
update_option("wp-short-pixel-query-id-stop", 0);
|
635 |
+
update_option("wp-short-pixel-flag-id", $startQueryID);//we use to detect new added files while bulk is running
|
636 |
+
add_option('bulkProcessingStatus', 'running');//set bulk flag
|
637 |
+
}//end bulk process was clicked
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
638 |
|
639 |
+
$bulkProcessingStatus = get_option('bulkProcessingStatus');
|
640 |
+
$startQueryID = get_option('wp-short-pixel-query-id-start');
|
641 |
+
|
642 |
+
//figure out all the files that could be processed
|
643 |
+
$qry = "SELECT count(*) FilesToBeProcessed FROM " . $wpdb->prefix . "postmeta
|
644 |
+
WHERE meta_key = '_wp_attached_file' ";
|
645 |
+
$allFiles = $wpdb->get_results($qry);
|
646 |
+
//figure out the files that are left to be processed
|
647 |
+
$qry_left = "SELECT count(*) FilesLeftToBeProcessed FROM " . $wpdb->prefix . "postmeta
|
648 |
+
WHERE meta_key = '_wp_attached_file' AND post_id <= $startQueryID";
|
649 |
+
$filesLeft = $wpdb->get_results($qry_left);
|
650 |
+
|
651 |
+
if( $filesLeft[0]->FilesLeftToBeProcessed > 0 && $bulkProcessingStatus == "running" )//bulk processing was started and wasn't yet ended
|
652 |
+
{
|
653 |
+
echo "<p>
|
654 |
+
Bulk optimisation has started. This process will take some time, depending on the number of images in your library. <BR>Do not worry about the slow speed, it is a necessary measure in order not to interfere with the normal functioning of your site.<BR><BR>
|
655 |
+
This is a brief estimation of the bulk processing times:<BR>
|
656 |
+
1 to 100 images < 20 min <BR>
|
657 |
+
100 to 500 images < 2 hour<BR>
|
658 |
+
500 to 1000 images < 4 hours<BR>
|
659 |
+
over 1000 images > 4 hours or more<BR><BR>
|
660 |
+
|
661 |
+
The latest status of the processing will be displayed here every 30 seconds.<BR>
|
662 |
+
In the meantime, you can continue using the admin as usual.<BR>
|
663 |
+
However, <b>you musn’t close the WordPress admin</b>, or the bulk processing will stop.
|
664 |
+
</p>";
|
665 |
+
echo '
|
666 |
+
<script type="text/javascript" >
|
667 |
+
var bulkProcessingRunning = true;
|
668 |
+
</script>
|
669 |
+
';
|
670 |
|
671 |
+
$imagesLeft = $filesLeft[0]->FilesLeftToBeProcessed;
|
672 |
+
$totalImages = $allFiles[0]->FilesToBeProcessed;
|
|
|
673 |
|
674 |
+
echo "<p>{$imagesLeft} out of {$totalImages} images left to process.</p>";
|
675 |
|
676 |
+
echo '
|
677 |
+
<a class="button button-secondary" href="' . get_admin_url() . 'upload.php">Media Library</a>
|
678 |
+
<a class="button button-secondary" href="' . get_admin_url() . 'upload.php?page=wp-short-pixel-bulk&cancel=1">Cancel Processing</a>
|
679 |
+
';
|
680 |
|
681 |
+
} else
|
682 |
+
{
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
683 |
$bulkProcessingStatus = get_option('bulkProcessingStatus');
|
684 |
+
if(isset($bulkProcessingStatus) && $bulkProcessingStatus == 'running')
|
685 |
+
{
|
686 |
echo "<p>Bulk optimisation was successful. ShortPixel has finished optimising all your images.</p>
|
687 |
<p>Go to the ShortPixel <a href='" . get_admin_url() . "options-general.php?page=wp-shortpixel#facts'>Stats</a> and see your website's optimised stats (in Settings > ShortPixel). </p>";
|
688 |
+
|
689 |
+
$queryMax = "SELECT max(post_id) as startQueryID FROM " . $wpdb->prefix . "postmeta";
|
690 |
+
$resultQuery = $wpdb->get_results($queryMax);
|
691 |
+
$startQueryID = $resultQuery[0]->startQueryID;
|
692 |
+
$maxIDbeforeBulk = get_option("wp-short-pixel-flag-id");//what was the max id before bulk was started?
|
693 |
+
|
694 |
+
if ( $startQueryID > $maxIDbeforeBulk )//basically we resume the processing for the files uploaded while bulk was running
|
695 |
+
{
|
696 |
+
update_option("wp-short-pixel-query-id-start", $startQueryID);
|
697 |
+
update_option("wp-short-pixel-query-id-stop", $maxIDbeforeBulk);
|
698 |
+
delete_option('bulkProcessingStatus');
|
699 |
+
}
|
700 |
+
else
|
701 |
+
{
|
702 |
+
update_option("wp-short-pixel-query-id-start", 0);
|
703 |
+
update_option("wp-short-pixel-query-id-stop", 0);
|
704 |
+
delete_option('bulkProcessingStatus');
|
705 |
+
}
|
706 |
}
|
707 |
+
|
708 |
+
echo $this->getBulkProcessingForm($allFiles[0]->FilesToBeProcessed);
|
709 |
echo '
|
710 |
<script type="text/javascript" >
|
711 |
var bulkProcessingRunning = false;
|
745 |
$noticeHTML = "<br/><div style=\"background-color: #fff; border-left: 4px solid %s; box-shadow: 0 1px 1px 0 rgba(0, 0, 0, 0.1); padding: 1px 12px;\"><p>%s</p></div>";
|
746 |
|
747 |
if(isset($_POST['submit']) || isset($_POST['validate'])) {
|
748 |
+
|
749 |
//handle API Key - common for submit and validate
|
750 |
$_POST['key'] = trim($_POST['key']);
|
751 |
$validityData = $this->getQuotaInformation($_POST['key'], true);
|
1034 |
$data = wp_get_attachment_metadata($id);
|
1035 |
$file = get_attached_file($id);
|
1036 |
$fileExtension = strtolower(substr($file,strrpos($file,".")+1));
|
1037 |
+
|
1038 |
+
if ( empty($data) )
|
1039 |
+
{
|
1040 |
+
if ( $fileExtension <> "pdf" )
|
1041 |
+
print 'Optimisation N/A';
|
1042 |
+
else
|
1043 |
+
{
|
1044 |
+
print 'PDF not processed';
|
1045 |
+
print " | <a href=\"admin.php?action=shortpixel_manual_optimize&attachment_ID={$id}\">Optimize now</a>";
|
1046 |
+
}
|
1047 |
+
return;
|
1048 |
+
}
|
1049 |
+
elseif ( isset( $data['ShortPixelImprovement'] ) )
|
1050 |
+
{
|
1051 |
if(isset($meta['ShortPixel']['BulkProcessing'])) {
|
1052 |
print 'Waiting for bulk processing';
|
1053 |
return;
|
1059 |
print " | <a href=\"admin.php?action=shortpixel_restore_backup&attachment_ID={$id}\">Restore backup</a>";
|
1060 |
return;
|
1061 |
}
|
1062 |
+
elseif ( $data['ShortPixelImprovement'] <> "Optimisation N/A" || is_numeric($data['ShortPixelImprovement']) )
|
1063 |
+
print '%';
|
1064 |
} elseif(isset($data['ShortPixel']['WaitingProcessing'])) {
|
1065 |
print 'Image waiting to be processed';
|
1066 |
return;
|