Version Description
- different bug fixes
Download this release
Release Info
Developer | ShortPixel |
Plugin | ShortPixel Image Optimizer |
Version | 3.0.5 |
Comparing to | |
See all releases |
Code changes from version 3.0.3 to 3.0.5
- js/short-pixel.js +6 -1
- readme.txt +7 -3
- shortpixel_view.php +4 -1
- wp-shortpixel.php +1526 -1530
js/short-pixel.js
CHANGED
@@ -230,7 +230,12 @@ function sliderUpdate(id, thumb, bkThumb, percent){
|
|
230 |
}
|
231 |
oldSlide.css("z-index", 1000);
|
232 |
jQuery(".bulk-img-opt", newSlide).attr("src", thumb);
|
233 |
-
|
|
|
|
|
|
|
|
|
|
|
234 |
jQuery(".bulk-opt-percent", newSlide).text(percent + "%");
|
235 |
|
236 |
jQuery(".bulk-slider").append(newSlide);
|
230 |
}
|
231 |
oldSlide.css("z-index", 1000);
|
232 |
jQuery(".bulk-img-opt", newSlide).attr("src", thumb);
|
233 |
+
if(bkThumb.length > 0) {
|
234 |
+
jQuery(".img-original", newSlide).show();
|
235 |
+
jQuery(".bulk-img-orig", newSlide).attr("src", bkThumb);
|
236 |
+
} else {
|
237 |
+
jQuery(".img-original", newSlide).hide();
|
238 |
+
}
|
239 |
jQuery(".bulk-opt-percent", newSlide).text(percent + "%");
|
240 |
|
241 |
jQuery(".bulk-slider").append(newSlide);
|
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, 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, faster loading times, image optimiser, improve pagerank, optimise, optimize animated gif, optimise jpeg, optimize jpeg, optimize png, optimise png, tinyjpg, short pixel, shortpixel
|
5 |
|
6 |
-
Requires at least: 3.0.1
|
7 |
Tested up to: 4.2
|
8 |
-
Stable tag: 3.0.
|
9 |
License: GPLv2 or later
|
10 |
License URI: http://www.gnu.org/licenses/gpl-2.0.html
|
11 |
|
@@ -119,7 +119,11 @@ The ShortPixel team is here to help. <a href="https://shortpixel.com/contact">Co
|
|
119 |
|
120 |
== Changelog ==
|
121 |
|
122 |
-
= 3.0.
|
|
|
|
|
|
|
|
|
123 |
|
124 |
* Progress bar improvements
|
125 |
|
3 |
Contributors: AlexSP
|
4 |
Tags: picture, optimization, image editor, pngout, upload speed, shortpixel, compression, jpegmini, webp, lossless, cwebp, media, 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, 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, faster loading times, image optimiser, improve pagerank, optimise, optimize animated gif, optimise jpeg, optimize jpeg, optimize png, optimise png, tinyjpg, short pixel, shortpixel
|
5 |
|
6 |
+
Requires at least: 3.0.1
|
7 |
Tested up to: 4.2
|
8 |
+
Stable tag: 3.0.5
|
9 |
License: GPLv2 or later
|
10 |
License URI: http://www.gnu.org/licenses/gpl-2.0.html
|
11 |
|
119 |
|
120 |
== Changelog ==
|
121 |
|
122 |
+
= 3.0.5 =
|
123 |
+
|
124 |
+
* different bug fixes
|
125 |
+
|
126 |
+
= 3.0.2 =
|
127 |
|
128 |
* Progress bar improvements
|
129 |
|
shortpixel_view.php
CHANGED
@@ -71,6 +71,9 @@ class ShortPixelView {
|
|
71 |
|
72 |
<?=$this->displayBulkStats($filesOptimized, $thumbsProcessedCount, $under5PercentCount, $averageCompression, $savedSpace)?>
|
73 |
<p>Download your detailed <a href="https://api.shortpixel.com/v2/report.php?key=<?=$this->ctrl->getApiKey()?>">Optimization Report</a> to check your image optimization statistics for the last 40 days</p>
|
|
|
|
|
|
|
74 |
<p>Restart the optimization process for new images added to your library:
|
75 |
<form action='' method='POST' >
|
76 |
<input type='checkbox' name='thumbnails' <?=$this->ctrl->processThumbnails() ? "checked":""?>> Include thumbnails<br><br>
|
@@ -151,4 +154,4 @@ class ShortPixelView {
|
|
151 |
<?php
|
152 |
}
|
153 |
|
154 |
-
}
|
71 |
|
72 |
<?=$this->displayBulkStats($filesOptimized, $thumbsProcessedCount, $under5PercentCount, $averageCompression, $savedSpace)?>
|
73 |
<p>Download your detailed <a href="https://api.shortpixel.com/v2/report.php?key=<?=$this->ctrl->getApiKey()?>">Optimization Report</a> to check your image optimization statistics for the last 40 days</p>
|
74 |
+
<?php if(false && $imgProcessedCount['totalFiles'] < $imageCount['totalFiles']) { ?>
|
75 |
+
<p>However, <?=number_format($imageCount['mainFiles'] - $imgProcessedCount['mainFiles'])?> images and <?=number_format(($imageCount['totalFiles'] - $imageCount['mainFiles']) - ($imgProcessedCount['totalFiles'] - $imgProcessedCount['mainFiles']))?> thumbnails are not yet optimized by ShorPixel.</p>
|
76 |
+
<?php } ?>
|
77 |
<p>Restart the optimization process for new images added to your library:
|
78 |
<form action='' method='POST' >
|
79 |
<input type='checkbox' name='thumbnails' <?=$this->ctrl->processThumbnails() ? "checked":""?>> Include thumbnails<br><br>
|
154 |
<?php
|
155 |
}
|
156 |
|
157 |
+
}
|
wp-shortpixel.php
CHANGED
@@ -1,1530 +1,1526 @@
|
|
1 |
-
<?php
|
2 |
-
/**
|
3 |
-
* Plugin Name: ShortPixel Image Optimizer
|
4 |
-
* Plugin URI: https://shortpixel.com/
|
5 |
-
* Description: ShortPixel optimizes images automatically, while guarding the quality of your images. Check your <a href="options-general.php?page=wp-shortpixel" target="_blank">Settings > ShortPixel</a> page on how to start optimizing your image library and make your website load faster.
|
6 |
-
* Version: 3.0.
|
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');
|
14 |
-
require_once( ABSPATH . 'wp-admin/includes/image.php' );
|
15 |
-
include_once( ABSPATH . 'wp-admin/includes/plugin.php' );
|
16 |
-
if ( !is_plugin_active( 'wpmandrill/wpmandrill.php' ) ) {
|
17 |
-
require_once( ABSPATH . 'wp-includes/pluggable.php' );//to avoid conflict with wpmandrill plugin
|
18 |
-
}
|
19 |
-
|
20 |
-
define('SP_RESET_ON_ACTIVATE', false);
|
21 |
-
|
22 |
-
define('PLUGIN_VERSION', "3.0.
|
23 |
-
define('SP_MAX_TIMEOUT', 10);
|
24 |
-
define('SP_BACKUP', 'ShortpixelBackups');
|
25 |
-
define('SP_BACKUP_FOLDER', WP_CONTENT_DIR . DIRECTORY_SEPARATOR . 'uploads' . DIRECTORY_SEPARATOR . SP_BACKUP);
|
26 |
-
define('MAX_API_RETRIES', 5);
|
27 |
-
$MAX_EXECUTION_TIME = ini_get('max_execution_time');
|
28 |
-
if ( is_numeric($MAX_EXECUTION_TIME) )
|
29 |
-
define('MAX_EXECUTION_TIME', $MAX_EXECUTION_TIME - 5 ); //in seconds
|
30 |
-
else
|
31 |
-
define('MAX_EXECUTION_TIME', 25 );
|
32 |
-
define("SP_MAX_RESULTS_QUERY", 6);
|
33 |
-
|
34 |
-
class WPShortPixel {
|
35 |
-
|
36 |
-
const BULK_EMPTY_QUEUE = 0;
|
37 |
-
|
38 |
-
private $_apiKey = '';
|
39 |
-
private $_compressionType = 1;
|
40 |
-
private $_processThumbnails = 1;
|
41 |
-
private $_CMYKtoRGBconversion = 1;
|
42 |
-
private $_backupImages = 1;
|
43 |
-
private $_verifiedKey = false;
|
44 |
-
|
45 |
-
private $_apiInterface = null;
|
46 |
-
private $prioQ = null;
|
47 |
-
private $view = null;
|
48 |
-
|
49 |
-
//handling older
|
50 |
-
public function WPShortPixel() {
|
51 |
-
$this->__construct();
|
52 |
-
}
|
53 |
-
|
54 |
-
public function __construct() {
|
55 |
-
session_start();
|
56 |
-
|
57 |
-
$this->populateOptions();
|
58 |
-
|
59 |
-
$this->_apiInterface = new ShortPixelAPI($this->_apiKey, $this->_compressionType, $this->_CMYKtoRGBconversion);
|
60 |
-
$this->prioQ = new ShortPixelQueue($this);
|
61 |
-
$this->view = new ShortPixelView($this);
|
62 |
-
|
63 |
-
define('QUOTA_EXCEEDED', "Quota Exceeded. <a href='https://shortpixel.com/login/".$this->_apiKey."' target='_blank'>Extend Quota</a>");
|
64 |
-
|
65 |
-
$this->setDefaultViewModeList();//set default mode as list. only @ first run
|
66 |
-
|
67 |
-
//add hook for image upload processing
|
68 |
-
add_filter( 'wp_generate_attachment_metadata', array( &$this, 'handleImageUpload' ), 10, 2 );
|
69 |
-
add_filter( 'manage_media_columns', array( &$this, 'columns' ) );//add media library column header
|
70 |
-
add_filter( 'plugin_action_links_' . plugin_basename(__FILE__), array(&$this, 'generatePluginLinks'));//for plugin settings page
|
71 |
-
|
72 |
-
//add_action( 'admin_footer', array(&$this, 'handleImageProcessing'));
|
73 |
-
add_action( 'manage_media_custom_column', array( &$this, 'generateCustomColumn' ), 10, 2 );//generate the media library column
|
74 |
-
|
75 |
-
//add settings page
|
76 |
-
add_action( 'admin_menu', array( &$this, 'registerSettingsPage' ) );//display SP in Settings menu
|
77 |
-
add_action( 'admin_menu', array( &$this, 'registerAdminPage' ) );
|
78 |
-
add_action( 'delete_attachment', array( &$this, 'handleDeleteAttachmentInBackup' ) );
|
79 |
-
add_action( 'load-upload.php', array( &$this, 'handleCustomBulk'));
|
80 |
-
|
81 |
-
//when plugin is activated run this
|
82 |
-
register_activation_hook( __FILE__, array( &$this, 'shortPixelActivatePlugin' ) );
|
83 |
-
register_deactivation_hook( __FILE__, array( &$this, 'shortPixelDeactivatePlugin' ) );
|
84 |
-
|
85 |
-
//automatic optimization
|
86 |
-
add_action( 'wp_ajax_shortpixel_image_processing', array( &$this, 'handleImageProcessing') );
|
87 |
-
//manual optimization
|
88 |
-
add_action( 'wp_ajax_shortpixel_manual_optimization', array(&$this, 'handleManualOptimization'));
|
89 |
-
//backup restore
|
90 |
-
add_action('admin_action_shortpixel_restore_backup', array(&$this, 'handleRestoreBackup'));
|
91 |
-
|
92 |
-
//This adds the constants used in PHP to be available also in JS
|
93 |
-
add_action( 'admin_footer', array( &$this, 'shortPixelJS') );
|
94 |
-
|
95 |
-
|
96 |
-
//example toolbar by fai, to be configured
|
97 |
-
add_action( 'admin_bar_menu', array( &$this, 'toolbar_shortpixel_processing'), 999 );
|
98 |
-
|
99 |
-
$this->migrateBackupFolder();
|
100 |
-
}
|
101 |
-
|
102 |
-
public function populateOptions() {
|
103 |
-
|
104 |
-
$this->_apiKey = self::getOpt('wp-short-pixel-apiKey', '');
|
105 |
-
$this->_verifiedKey = self::getOpt('wp-short-pixel-verifiedKey', $this->_verifiedKey);
|
106 |
-
$this->_compressionType = self::getOpt('wp-short-pixel-compression', $this->_compressionType);
|
107 |
-
$this->_processThumbnails = self::getOpt('wp-short-process_thumbnails', $this->_processThumbnails);
|
108 |
-
$this->_CMYKtoRGBconversion = self::getOpt('wp-short-pixel_cmyk2rgb', $this->_CMYKtoRGBconversion);
|
109 |
-
$this->_backupImages = self::getOpt('wp-short-backup_images', $this->_backupImages);
|
110 |
-
// the following practically set defaults for options if they're not set
|
111 |
-
self::getOpt( 'wp-short-pixel-fileCount', 0);
|
112 |
-
self::getOpt( 'wp-short-pixel-thumbnail-count', 0);//amount of optimized thumbnails
|
113 |
-
self::getOpt( 'wp-short-pixel-files-under-5-percent', 0);//amount of optimized thumbnails
|
114 |
-
self::getOpt( 'wp-short-pixel-savedSpace', 0);
|
115 |
-
self::getOpt( 'wp-short-pixel-api-retries', 0);//sometimes we need to retry processing/downloading a file multiple times
|
116 |
-
self::getOpt( 'wp-short-pixel-quota-exceeded', 0);
|
117 |
-
self::getOpt( 'wp-short-pixel-total-original', 0);//amount of original data
|
118 |
-
self::getOpt( 'wp-short-pixel-total-optimized', 0);//amount of optimized
|
119 |
-
self::getOpt( 'wp-short-pixel-protocol', 'https');
|
120 |
-
}
|
121 |
-
|
122 |
-
public function shortPixelActivatePlugin()//reset some params to avoid trouble for plugins that were activated/deactivated/activated
|
123 |
-
{
|
124 |
-
$this->prioQ->resetBulk();
|
125 |
-
if(SP_RESET_ON_ACTIVATE === true && WP_DEBUG === true) { //force reset plugin counters, only on specific occasions and on test environments
|
126 |
-
update_option( 'wp-short-pixel-fileCount', 0);
|
127 |
-
update_option( 'wp-short-pixel-thumbnail-count', 0);
|
128 |
-
update_option( 'wp-short-pixel-files-under-5-percent', 0);
|
129 |
-
update_option( 'wp-short-pixel-savedSpace', 0);
|
130 |
-
update_option( 'wp-short-pixel-api-retries', 0);//sometimes we need to retry processing/downloading a file multiple times
|
131 |
-
update_option( 'wp-short-pixel-quota-exceeded', 0);
|
132 |
-
update_option( 'wp-short-pixel-total-original', 0);//amount of original data
|
133 |
-
update_option( 'wp-short-pixel-total-optimized', 0);//amount of optimized
|
134 |
-
update_option( 'wp-short-pixel-bulk-ever-ran', 0);
|
135 |
-
delete_option('wp-short-pixel-priorityQueue');
|
136 |
-
unset($_SESSION["wp-short-pixel-priorityQueue"]);
|
137 |
-
delete_option("wp-short-pixel-bulk-previous-percent");
|
138 |
-
}
|
139 |
-
}
|
140 |
-
|
141 |
-
public function shortPixelDeactivatePlugin()//reset some params to avoid trouble for plugins that were activated/deactivated/activated
|
142 |
-
{
|
143 |
-
$this->prioQ->resetBulk();
|
144 |
-
}
|
145 |
-
|
146 |
-
//set default move as "list". only set once, it won't try to set the default mode again.
|
147 |
-
public function setDefaultViewModeList()
|
148 |
-
{
|
149 |
-
if(get_option('wp-short-pixel-view-mode') === false)
|
150 |
-
{
|
151 |
-
add_option('wp-short-pixel-view-mode', 1, '', 'yes' );
|
152 |
-
if ( function_exists('get_currentuserinfo') )
|
153 |
-
{
|
154 |
-
global $current_user;
|
155 |
-
get_currentuserinfo();
|
156 |
-
$currentUserID = $current_user->ID;
|
157 |
-
update_user_meta($currentUserID, "wp_media_library_mode", "list");
|
158 |
-
}
|
159 |
-
}
|
160 |
-
|
161 |
-
}
|
162 |
-
|
163 |
-
static function log($message) {
|
164 |
-
if (WP_DEBUG === true) {
|
165 |
-
if (is_array($message) || is_object($message)) {
|
166 |
-
error_log(print_r($message, true));
|
167 |
-
} else {
|
168 |
-
error_log($message);
|
169 |
-
}
|
170 |
-
}
|
171 |
-
}
|
172 |
-
|
173 |
-
function shortPixelJS() { ?>
|
174 |
-
<script type="text/javascript" >
|
175 |
-
jQuery(document).ready(function($){
|
176 |
-
ShortPixel.setOptions({
|
177 |
-
STATUS_SUCCESS: <?= ShortPixelAPI::STATUS_SUCCESS ?>,
|
178 |
-
STATUS_EMPTY_QUEUE: <?= self::BULK_EMPTY_QUEUE ?>,
|
179 |
-
STATUS_ERROR: <?= ShortPixelAPI::STATUS_ERROR ?>,
|
180 |
-
STATUS_FAIL: <?= ShortPixelAPI::STATUS_FAIL ?>,
|
181 |
-
STATUS_SKIP: <?= ShortPixelAPI::STATUS_SKIP ?>,
|
182 |
-
STATUS_QUOTA_EXCEEDED: <?= ShortPixelAPI::STATUS_QUOTA_EXCEEDED ?>,
|
183 |
-
WP_PLUGIN_URL: '<?= WP_PLUGIN_URL ?>',
|
184 |
-
API_KEY: "<?= $this->_apiKey ?>"
|
185 |
-
});
|
186 |
-
});
|
187 |
-
</script> <?php
|
188 |
-
wp_enqueue_style('short-pixel.css', plugins_url('/css/short-pixel.css',__FILE__) );
|
189 |
-
}
|
190 |
-
|
191 |
-
function toolbar_shortpixel_processing( $wp_admin_bar ) {
|
192 |
-
if ( !is_admin()) {
|
193 |
-
return;
|
194 |
-
}
|
195 |
-
|
196 |
-
|
197 |
-
|
198 |
-
$
|
199 |
-
$
|
200 |
-
$
|
201 |
-
$
|
202 |
-
$
|
203 |
-
|
204 |
-
|
205 |
-
|
206 |
-
|
207 |
-
|
208 |
-
$
|
209 |
-
$
|
210 |
-
$
|
211 |
-
|
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 |
-
$mediaIds
|
248 |
-
|
249 |
-
$meta
|
250 |
-
|
251 |
-
|
252 |
-
$
|
253 |
-
$meta
|
254 |
-
|
255 |
-
|
256 |
-
|
257 |
-
|
258 |
-
|
259 |
-
|
260 |
-
|
261 |
-
|
262 |
-
|
263 |
-
|
264 |
-
|
265 |
-
|
266 |
-
|
267 |
-
|
268 |
-
|
269 |
-
|
270 |
-
|
271 |
-
$meta
|
272 |
-
|
273 |
-
|
274 |
-
|
275 |
-
|
276 |
-
$this->
|
277 |
-
$
|
278 |
-
|
279 |
-
|
280 |
-
$meta
|
281 |
-
|
282 |
-
|
283 |
-
|
284 |
-
|
285 |
-
|
286 |
-
|
287 |
-
|
288 |
-
|
289 |
-
$
|
290 |
-
|
291 |
-
|
292 |
-
|
293 |
-
|
294 |
-
|
295 |
-
|
296 |
-
|
297 |
-
meta_key = '
|
298 |
-
|
299 |
-
$res
|
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 |
-
|
427 |
-
|
428 |
-
|
429 |
-
|
430 |
-
|
431 |
-
|
432 |
-
|
433 |
-
|
434 |
-
|
435 |
-
|
436 |
-
|
437 |
-
|
438 |
-
|
439 |
-
|
440 |
-
|
441 |
-
|
442 |
-
|
443 |
-
$this->prioQ->
|
444 |
-
$this->prioQ->
|
445 |
-
|
446 |
-
|
447 |
-
$
|
448 |
-
$
|
449 |
-
$
|
450 |
-
|
451 |
-
|
452 |
-
|
453 |
-
|
454 |
-
|
455 |
-
$
|
456 |
-
|
457 |
-
$
|
458 |
-
|
459 |
-
|
460 |
-
|
461 |
-
|
462 |
-
|
463 |
-
|
464 |
-
|
465 |
-
|
466 |
-
|
467 |
-
|
468 |
-
|
469 |
-
|
470 |
-
|
471 |
-
|
472 |
-
|
473 |
-
|
474 |
-
|
475 |
-
|
476 |
-
|
477 |
-
|
478 |
-
|
479 |
-
|
480 |
-
|
481 |
-
|
482 |
-
|
483 |
-
$
|
484 |
-
$
|
485 |
-
|
486 |
-
|
487 |
-
|
488 |
-
|
489 |
-
|
490 |
-
|
491 |
-
|
492 |
-
|
493 |
-
|
494 |
-
|
495 |
-
|
496 |
-
|
497 |
-
|
498 |
-
|
499 |
-
|
500 |
-
|
501 |
-
|
502 |
-
|
503 |
-
$
|
504 |
-
|
505 |
-
|
506 |
-
|
507 |
-
|
508 |
-
|
509 |
-
|
510 |
-
|
511 |
-
|
512 |
-
|
513 |
-
|
514 |
-
|
515 |
-
|
516 |
-
|
517 |
-
|
518 |
-
|
519 |
-
|
520 |
-
|
521 |
-
|
522 |
-
|
523 |
-
|
524 |
-
|
525 |
-
//
|
526 |
-
$sendback
|
527 |
-
//
|
528 |
-
|
529 |
-
|
530 |
-
|
531 |
-
|
532 |
-
|
533 |
-
|
534 |
-
|
535 |
-
|
536 |
-
|
537 |
-
|
538 |
-
|
539 |
-
|
540 |
-
|
541 |
-
|
542 |
-
|
543 |
-
$
|
544 |
-
|
545 |
-
$
|
546 |
-
$
|
547 |
-
|
548 |
-
|
549 |
-
|
550 |
-
|
551 |
-
|
552 |
-
|
553 |
-
|
554 |
-
|
555 |
-
|
556 |
-
|
557 |
-
|
558 |
-
|
559 |
-
|
560 |
-
|
561 |
-
|
562 |
-
|
563 |
-
|
564 |
-
|
565 |
-
|
566 |
-
|
567 |
-
|
568 |
-
|
569 |
-
|
570 |
-
|
571 |
-
|
572 |
-
|
573 |
-
|
574 |
-
|
575 |
-
//
|
576 |
-
$sendback
|
577 |
-
//
|
578 |
-
|
579 |
-
|
580 |
-
|
581 |
-
|
582 |
-
|
583 |
-
|
584 |
-
|
585 |
-
|
586 |
-
|
587 |
-
|
588 |
-
|
589 |
-
|
590 |
-
|
591 |
-
|
592 |
-
|
593 |
-
|
594 |
-
|
595 |
-
|
596 |
-
|
597 |
-
|
598 |
-
|
599 |
-
|
600 |
-
|
601 |
-
|
602 |
-
|
603 |
-
|
604 |
-
|
605 |
-
|
606 |
-
|
607 |
-
|
608 |
-
|
609 |
-
|
610 |
-
|
611 |
-
|
612 |
-
}
|
613 |
-
|
614 |
-
|
615 |
-
|
616 |
-
}
|
617 |
-
|
618 |
-
function
|
619 |
-
|
620 |
-
|
621 |
-
|
622 |
-
|
623 |
-
$quotaData
|
624 |
-
|
625 |
-
|
626 |
-
}
|
627 |
-
|
628 |
-
|
629 |
-
?><script>var shortPixelQuotaExceeded =
|
630 |
-
}
|
631 |
-
|
632 |
-
|
633 |
-
|
634 |
-
|
635 |
-
|
636 |
-
|
637 |
-
|
638 |
-
|
639 |
-
|
640 |
-
|
641 |
-
|
642 |
-
|
643 |
-
|
644 |
-
|
645 |
-
|
646 |
-
|
647 |
-
|
648 |
-
|
649 |
-
|
650 |
-
|
651 |
-
|
652 |
-
|
653 |
-
|
654 |
-
|
655 |
-
|
656 |
-
|
657 |
-
|
658 |
-
|
659 |
-
|
660 |
-
|
661 |
-
|
662 |
-
|
663 |
-
|
664 |
-
|
665 |
-
|
666 |
-
|
667 |
-
|
668 |
-
|
669 |
-
|
670 |
-
|
671 |
-
|
672 |
-
//figure out
|
673 |
-
$
|
674 |
-
WHERE meta_key = '_wp_attached_file' ";
|
675 |
-
$
|
676 |
-
|
677 |
-
$
|
678 |
-
|
679 |
-
|
680 |
-
|
681 |
-
|
682 |
-
|
683 |
-
$
|
684 |
-
$
|
685 |
-
|
686 |
-
|
687 |
-
|
688 |
-
|
689 |
-
|
690 |
-
|
691 |
-
|
692 |
-
|
693 |
-
|
694 |
-
|
695 |
-
|
696 |
-
|
697 |
-
$
|
698 |
-
|
699 |
-
|
700 |
-
$
|
701 |
-
$
|
702 |
-
|
703 |
-
|
704 |
-
|
705 |
-
|
706 |
-
|
707 |
-
|
708 |
-
|
709 |
-
|
710 |
-
|
711 |
-
|
712 |
-
|
713 |
-
|
714 |
-
$
|
715 |
-
|
716 |
-
|
717 |
-
$timeEst = "";
|
718 |
-
} elseif(
|
719 |
-
$timeEst = "~ " . round($minutes /
|
720 |
-
} elseif ($minutes >
|
721 |
-
$timeEst = "~ " . round($minutes /
|
722 |
-
}
|
723 |
-
$timeEst = "~ " .
|
724 |
-
}
|
725 |
-
|
726 |
-
|
727 |
-
|
728 |
-
|
729 |
-
|
730 |
-
|
731 |
-
|
732 |
-
|
733 |
-
|
734 |
-
|
735 |
-
|
736 |
-
|
737 |
-
|
738 |
-
|
739 |
-
|
740 |
-
|
741 |
-
)
|
742 |
-
|
743 |
-
|
744 |
-
|
745 |
-
|
746 |
-
|
747 |
-
|
748 |
-
|
749 |
-
|
750 |
-
|
751 |
-
|
752 |
-
|
753 |
-
|
754 |
-
|
755 |
-
|
756 |
-
|
757 |
-
|
758 |
-
|
759 |
-
|
760 |
-
|
761 |
-
|
762 |
-
|
763 |
-
|
764 |
-
|
765 |
-
|
766 |
-
|
767 |
-
|
768 |
-
|
769 |
-
|
770 |
-
|
771 |
-
|
772 |
-
|
773 |
-
|
774 |
-
|
775 |
-
|
776 |
-
|
777 |
-
|
778 |
-
|
779 |
-
|
780 |
-
|
781 |
-
|
782 |
-
|
783 |
-
|
784 |
-
|
785 |
-
|
786 |
-
|
787 |
-
|
788 |
-
|
789 |
-
|
790 |
-
|
791 |
-
|
792 |
-
|
793 |
-
|
794 |
-
|
795 |
-
|
796 |
-
|
797 |
-
|
798 |
-
|
799 |
-
|
800 |
-
|
801 |
-
|
802 |
-
|
803 |
-
|
804 |
-
|
805 |
-
|
806 |
-
|
807 |
-
|
808 |
-
|
809 |
-
|
810 |
-
|
811 |
-
|
812 |
-
|
813 |
-
|
814 |
-
|
815 |
-
|
816 |
-
|
817 |
-
|
818 |
-
|
819 |
-
|
820 |
-
|
821 |
-
|
822 |
-
|
823 |
-
|
824 |
-
|
825 |
-
|
826 |
-
|
827 |
-
|
828 |
-
|
829 |
-
|
830 |
-
|
831 |
-
|
832 |
-
|
833 |
-
|
834 |
-
|
835 |
-
|
836 |
-
|
837 |
-
$this->
|
838 |
-
|
839 |
-
|
840 |
-
|
841 |
-
|
842 |
-
|
843 |
-
|
844 |
-
|
845 |
-
|
846 |
-
|
847 |
-
|
848 |
-
|
849 |
-
|
850 |
-
|
851 |
-
|
852 |
-
|
853 |
-
|
854 |
-
$
|
855 |
-
|
856 |
-
|
857 |
-
$
|
858 |
-
|
859 |
-
|
860 |
-
$
|
861 |
-
|
862 |
-
|
863 |
-
|
864 |
-
|
865 |
-
<
|
866 |
-
<
|
867 |
-
|
868 |
-
|
869 |
-
|
870 |
-
|
871 |
-
|
872 |
-
|
873 |
-
|
874 |
-
|
875 |
-
|
876 |
-
|
877 |
-
//if
|
878 |
-
$formHTML .=
|
879 |
-
|
880 |
-
|
881 |
-
|
882 |
-
|
883 |
-
|
884 |
-
|
885 |
-
</
|
886 |
-
|
887 |
-
|
888 |
-
|
889 |
-
$formHTML .= '<input type="radio" name="compressionType" value="
|
890 |
-
|
891 |
-
|
892 |
-
|
893 |
-
|
894 |
-
|
895 |
-
|
896 |
-
|
897 |
-
</
|
898 |
-
|
899 |
-
</
|
900 |
-
|
901 |
-
|
902 |
-
|
903 |
-
<
|
904 |
-
|
905 |
-
|
906 |
-
|
907 |
-
|
908 |
-
<
|
909 |
-
<th scope="row"><label for="
|
910 |
-
<td
|
911 |
-
|
912 |
-
|
913 |
-
|
914 |
-
<
|
915 |
-
<
|
916 |
-
|
917 |
-
|
918 |
-
|
919 |
-
|
920 |
-
|
921 |
-
|
922 |
-
|
923 |
-
|
924 |
-
</
|
925 |
-
</
|
926 |
-
|
927 |
-
|
928 |
-
|
929 |
-
|
930 |
-
|
931 |
-
|
932 |
-
|
933 |
-
|
934 |
-
|
935 |
-
|
936 |
-
|
937 |
-
|
938 |
-
|
939 |
-
|
940 |
-
|
941 |
-
|
942 |
-
|
943 |
-
|
944 |
-
|
945 |
-
|
946 |
-
|
947 |
-
|
948 |
-
|
949 |
-
|
950 |
-
|
951 |
-
|
952 |
-
|
953 |
-
$
|
954 |
-
|
955 |
-
|
956 |
-
|
957 |
-
|
958 |
-
$
|
959 |
-
|
960 |
-
|
961 |
-
|
962 |
-
|
963 |
-
<
|
964 |
-
<
|
965 |
-
<
|
966 |
-
|
967 |
-
<tr>
|
968 |
-
<th scope="row"><label for="
|
969 |
-
<td>$
|
970 |
-
</tr>
|
971 |
-
<tr>
|
972 |
-
<th scope="row"><label for="
|
973 |
-
<td>$
|
974 |
-
</tr>
|
975 |
-
|
976 |
-
|
977 |
-
<
|
978 |
-
|
979 |
-
</
|
980 |
-
|
981 |
-
<
|
982 |
-
|
983 |
-
<
|
984 |
-
<
|
985 |
-
|
986 |
-
<tr>
|
987 |
-
<th scope="row"
|
988 |
-
<td
|
989 |
-
</tr>
|
990 |
-
<tr>
|
991 |
-
<th scope="row"><label for="usedQUota">
|
992 |
-
<td>{$
|
993 |
-
</tr>
|
994 |
-
<tr>
|
995 |
-
<th scope="row"><label for="
|
996 |
-
<td>{$
|
997 |
-
</tr>
|
998 |
-
|
999 |
-
|
1000 |
-
<
|
1001 |
-
|
1002 |
-
|
1003 |
-
|
1004 |
-
<
|
1005 |
-
|
1006 |
-
<
|
1007 |
-
|
1008 |
-
|
1009 |
-
|
1010 |
-
|
1011 |
-
|
1012 |
-
|
1013 |
-
|
1014 |
-
|
1015 |
-
|
1016 |
-
|
1017 |
-
|
1018 |
-
|
1019 |
-
<
|
1020 |
-
|
1021 |
-
|
1022 |
-
|
1023 |
-
|
1024 |
-
|
1025 |
-
|
1026 |
-
|
1027 |
-
|
1028 |
-
|
1029 |
-
|
1030 |
-
$statHTML
|
1031 |
-
|
1032 |
-
|
1033 |
-
|
1034 |
-
|
1035 |
-
|
1036 |
-
|
1037 |
-
|
1038 |
-
|
1039 |
-
|
1040 |
-
|
1041 |
-
|
1042 |
-
|
1043 |
-
|
1044 |
-
|
1045 |
-
|
1046 |
-
|
1047 |
-
|
1048 |
-
|
1049 |
-
|
1050 |
-
|
1051 |
-
|
1052 |
-
|
1053 |
-
|
1054 |
-
'body'
|
1055 |
-
|
1056 |
-
|
1057 |
-
|
1058 |
-
|
1059 |
-
|
1060 |
-
|
1061 |
-
|
1062 |
-
|
1063 |
-
|
1064 |
-
|
1065 |
-
|
1066 |
-
|
1067 |
-
|
1068 |
-
|
1069 |
-
|
1070 |
-
|
1071 |
-
|
1072 |
-
|
1073 |
-
|
1074 |
-
|
1075 |
-
|
1076 |
-
|
1077 |
-
|
1078 |
-
|
1079 |
-
|
1080 |
-
|
1081 |
-
return $defaultData;
|
1082 |
-
}
|
1083 |
-
|
1084 |
-
|
1085 |
-
|
1086 |
-
|
1087 |
-
|
1088 |
-
|
1089 |
-
$data
|
1090 |
-
|
1091 |
-
|
1092 |
-
|
1093 |
-
|
1094 |
-
|
1095 |
-
|
1096 |
-
|
1097 |
-
|
1098 |
-
|
1099 |
-
|
1100 |
-
|
1101 |
-
|
1102 |
-
|
1103 |
-
|
1104 |
-
"
|
1105 |
-
"
|
1106 |
-
"
|
1107 |
-
"
|
1108 |
-
"
|
1109 |
-
|
1110 |
-
|
1111 |
-
|
1112 |
-
|
1113 |
-
|
1114 |
-
|
1115 |
-
|
1116 |
-
|
1117 |
-
|
1118 |
-
|
1119 |
-
|
1120 |
-
|
1121 |
-
|
1122 |
-
|
1123 |
-
|
1124 |
-
|
1125 |
-
|
1126 |
-
|
1127 |
-
|
1128 |
-
|
1129 |
-
|
1130 |
-
|
1131 |
-
|
1132 |
-
|
1133 |
-
|
1134 |
-
|
1135 |
-
|
1136 |
-
|
1137 |
-
|
1138 |
-
|
1139 |
-
|
1140 |
-
|
1141 |
-
|
1142 |
-
|
1143 |
-
|
1144 |
-
|
1145 |
-
|
1146 |
-
|
1147 |
-
|
1148 |
-
|
1149 |
-
|
1150 |
-
|
1151 |
-
|
1152 |
-
|
1153 |
-
|
1154 |
-
|
1155 |
-
{
|
1156 |
-
print
|
1157 |
-
|
1158 |
-
|
1159 |
-
|
1160 |
-
|
1161 |
-
|
1162 |
-
|
1163 |
-
|
1164 |
-
|
1165 |
-
|
1166 |
-
|
1167 |
-
|
1168 |
-
|
1169 |
-
|
1170 |
-
|
1171 |
-
|
1172 |
-
|
1173 |
-
|
1174 |
-
|
1175 |
-
|
1176 |
-
|
1177 |
-
|
1178 |
-
|
1179 |
-
|
1180 |
-
|
1181 |
-
|
1182 |
-
|
1183 |
-
|
1184 |
-
|
1185 |
-
|
1186 |
-
|
1187 |
-
|
1188 |
-
|
1189 |
-
|
1190 |
-
|
1191 |
-
|
1192 |
-
|
1193 |
-
|
1194 |
-
|
1195 |
-
|
1196 |
-
|
1197 |
-
|
1198 |
-
|
1199 |
-
|
1200 |
-
|
1201 |
-
|
1202 |
-
|
1203 |
-
|
1204 |
-
|
1205 |
-
print
|
1206 |
-
|
1207 |
-
|
1208 |
-
|
1209 |
-
|
1210 |
-
|
1211 |
-
|
1212 |
-
}
|
1213 |
-
|
1214 |
-
|
1215 |
-
|
1216 |
-
|
1217 |
-
|
1218 |
-
|
1219 |
-
{
|
1220 |
-
print
|
1221 |
-
|
1222 |
-
|
1223 |
-
|
1224 |
-
|
1225 |
-
|
1226 |
-
|
1227 |
-
|
1228 |
-
|
1229 |
-
|
1230 |
-
|
1231 |
-
|
1232 |
-
|
1233 |
-
|
1234 |
-
|
1235 |
-
|
1236 |
-
|
1237 |
-
{
|
1238 |
-
print
|
1239 |
-
|
1240 |
-
|
1241 |
-
|
1242 |
-
|
1243 |
-
|
1244 |
-
|
1245 |
-
|
1246 |
-
|
1247 |
-
|
1248 |
-
|
1249 |
-
{
|
1250 |
-
print
|
1251 |
-
|
1252 |
-
|
1253 |
-
|
1254 |
-
|
1255 |
-
|
1256 |
-
|
1257 |
-
|
1258 |
-
|
1259 |
-
|
1260 |
-
|
1261 |
-
|
1262 |
-
|
1263 |
-
|
1264 |
-
|
1265 |
-
|
1266 |
-
|
1267 |
-
|
1268 |
-
|
1269 |
-
|
1270 |
-
|
1271 |
-
|
1272 |
-
|
1273 |
-
|
1274 |
-
|
1275 |
-
|
1276 |
-
$data =
|
1277 |
-
}
|
1278 |
-
|
1279 |
-
|
1280 |
-
|
1281 |
-
|
1282 |
-
|
1283 |
-
|
1284 |
-
|
1285 |
-
|
1286 |
-
|
1287 |
-
$
|
1288 |
-
|
1289 |
-
$bytes
|
1290 |
-
|
1291 |
-
|
1292 |
-
|
1293 |
-
|
1294 |
-
|
1295 |
-
|
1296 |
-
|
1297 |
-
|
1298 |
-
|
1299 |
-
|
1300 |
-
|
1301 |
-
|
1302 |
-
|
1303 |
-
|
1304 |
-
|
1305 |
-
|
1306 |
-
|
1307 |
-
|
1308 |
-
|
1309 |
-
|
1310 |
-
|
1311 |
-
|
1312 |
-
|
1313 |
-
|
1314 |
-
|
1315 |
-
|
1316 |
-
|
1317 |
-
|
1318 |
-
|
1319 |
-
|
1320 |
-
|
1321 |
-
|
1322 |
-
|
1323 |
-
|
1324 |
-
|
1325 |
-
|
1326 |
-
|
1327 |
-
|
1328 |
-
|
1329 |
-
|
1330 |
-
|
1331 |
-
|
1332 |
-
|
1333 |
-
|
1334 |
-
|
1335 |
-
|
1336 |
-
|
1337 |
-
|
1338 |
-
|
1339 |
-
|
1340 |
-
|
1341 |
-
|
1342 |
-
|
1343 |
-
|
1344 |
-
|
1345 |
-
|
1346 |
-
|
1347 |
-
$
|
1348 |
-
|
1349 |
-
|
1350 |
-
|
1351 |
-
|
1352 |
-
|
1353 |
-
|
1354 |
-
|
1355 |
-
|
1356 |
-
|
1357 |
-
|
1358 |
-
|
1359 |
-
|
1360 |
-
|
1361 |
-
|
1362 |
-
|
1363 |
-
|
1364 |
-
|
1365 |
-
|
1366 |
-
|
1367 |
-
|
1368 |
-
|
1369 |
-
|
1370 |
-
|
1371 |
-
|
1372 |
-
|
1373 |
-
$size =
|
1374 |
-
$total_size += $size;
|
1375 |
-
}
|
1376 |
-
|
1377 |
-
|
1378 |
-
|
1379 |
-
|
1380 |
-
|
1381 |
-
|
1382 |
-
|
1383 |
-
|
1384 |
-
|
1385 |
-
|
1386 |
-
|
1387 |
-
|
1388 |
-
|
1389 |
-
|
1390 |
-
|
1391 |
-
|
1392 |
-
|
1393 |
-
|
1394 |
-
|
1395 |
-
|
1396 |
-
|
1397 |
-
|
1398 |
-
|
1399 |
-
|
1400 |
-
|
1401 |
-
|
1402 |
-
|
1403 |
-
|
1404 |
-
|
1405 |
-
|
1406 |
-
|
1407 |
-
|
1408 |
-
|
1409 |
-
|
1410 |
-
|
1411 |
-
|
1412 |
-
|
1413 |
-
|
1414 |
-
|
1415 |
-
|
1416 |
-
|
1417 |
-
|
1418 |
-
|
1419 |
-
|
1420 |
-
|
1421 |
-
|
1422 |
-
|
1423 |
-
|
1424 |
-
|
1425 |
-
|
1426 |
-
|
1427 |
-
|
1428 |
-
|
1429 |
-
|
1430 |
-
|
1431 |
-
|
1432 |
-
|
1433 |
-
$totalFiles
|
1434 |
-
|
1435 |
-
|
1436 |
-
|
1437 |
-
|
1438 |
-
|
1439 |
-
|
1440 |
-
|
1441 |
-
|
1442 |
-
|
1443 |
-
|
1444 |
-
|
1445 |
-
|
1446 |
-
|
1447 |
-
|
1448 |
-
|
1449 |
-
|
1450 |
-
|
1451 |
-
|
1452 |
-
|
1453 |
-
|
1454 |
-
|
1455 |
-
|
1456 |
-
|
1457 |
-
|
1458 |
-
|
1459 |
-
|
1460 |
-
|
1461 |
-
|
1462 |
-
|
1463 |
-
|
1464 |
-
|
1465 |
-
|
1466 |
-
|
1467 |
-
|
1468 |
-
|
1469 |
-
|
1470 |
-
|
1471 |
-
if ( $
|
1472 |
-
|
1473 |
-
|
1474 |
-
|
1475 |
-
|
1476 |
-
|
1477 |
-
|
1478 |
-
|
1479 |
-
|
1480 |
-
|
1481 |
-
|
1482 |
-
|
1483 |
-
|
1484 |
-
|
1485 |
-
|
1486 |
-
|
1487 |
-
|
1488 |
-
|
1489 |
-
|
1490 |
-
|
1491 |
-
|
1492 |
-
|
1493 |
-
|
1494 |
-
|
1495 |
-
|
1496 |
-
|
1497 |
-
|
1498 |
-
|
1499 |
-
|
1500 |
-
|
1501 |
-
$scannedDirectory = array_diff(scandir($oldBackupFolder), array('..', '.'));
|
1502 |
-
|
1503 |
-
@
|
1504 |
-
}
|
1505 |
-
|
1506 |
-
|
1507 |
-
|
1508 |
-
|
1509 |
-
|
1510 |
-
return;
|
1511 |
-
}
|
1512 |
-
|
1513 |
-
public function
|
1514 |
-
return $this->
|
1515 |
-
}
|
1516 |
-
|
1517 |
-
public function
|
1518 |
-
return $this->
|
1519 |
-
}
|
1520 |
-
|
1521 |
-
|
1522 |
-
|
1523 |
-
|
1524 |
-
|
1525 |
-
|
1526 |
-
|
1527 |
-
$pluginInstance = new WPShortPixel();
|
1528 |
-
global $pluginInstance;
|
1529 |
-
|
1530 |
-
?>
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Plugin Name: ShortPixel Image Optimizer
|
4 |
+
* Plugin URI: https://shortpixel.com/
|
5 |
+
* Description: ShortPixel optimizes images automatically, while guarding the quality of your images. Check your <a href="options-general.php?page=wp-shortpixel" target="_blank">Settings > ShortPixel</a> page on how to start optimizing your image library and make your website load faster.
|
6 |
+
* Version: 3.0.5
|
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');
|
14 |
+
require_once( ABSPATH . 'wp-admin/includes/image.php' );
|
15 |
+
include_once( ABSPATH . 'wp-admin/includes/plugin.php' );
|
16 |
+
if ( !is_plugin_active( 'wpmandrill/wpmandrill.php' ) ) {
|
17 |
+
require_once( ABSPATH . 'wp-includes/pluggable.php' );//to avoid conflict with wpmandrill plugin
|
18 |
+
}
|
19 |
+
|
20 |
+
define('SP_RESET_ON_ACTIVATE', false);
|
21 |
+
|
22 |
+
define('PLUGIN_VERSION', "3.0.5");
|
23 |
+
define('SP_MAX_TIMEOUT', 10);
|
24 |
+
define('SP_BACKUP', 'ShortpixelBackups');
|
25 |
+
define('SP_BACKUP_FOLDER', WP_CONTENT_DIR . DIRECTORY_SEPARATOR . 'uploads' . DIRECTORY_SEPARATOR . SP_BACKUP);
|
26 |
+
define('MAX_API_RETRIES', 5);
|
27 |
+
$MAX_EXECUTION_TIME = ini_get('max_execution_time');
|
28 |
+
if ( is_numeric($MAX_EXECUTION_TIME) )
|
29 |
+
define('MAX_EXECUTION_TIME', $MAX_EXECUTION_TIME - 5 ); //in seconds
|
30 |
+
else
|
31 |
+
define('MAX_EXECUTION_TIME', 25 );
|
32 |
+
define("SP_MAX_RESULTS_QUERY", 6);
|
33 |
+
|
34 |
+
class WPShortPixel {
|
35 |
+
|
36 |
+
const BULK_EMPTY_QUEUE = 0;
|
37 |
+
|
38 |
+
private $_apiKey = '';
|
39 |
+
private $_compressionType = 1;
|
40 |
+
private $_processThumbnails = 1;
|
41 |
+
private $_CMYKtoRGBconversion = 1;
|
42 |
+
private $_backupImages = 1;
|
43 |
+
private $_verifiedKey = false;
|
44 |
+
|
45 |
+
private $_apiInterface = null;
|
46 |
+
private $prioQ = null;
|
47 |
+
private $view = null;
|
48 |
+
|
49 |
+
//handling older
|
50 |
+
public function WPShortPixel() {
|
51 |
+
$this->__construct();
|
52 |
+
}
|
53 |
+
|
54 |
+
public function __construct() {
|
55 |
+
session_start();
|
56 |
+
|
57 |
+
$this->populateOptions();
|
58 |
+
|
59 |
+
$this->_apiInterface = new ShortPixelAPI($this->_apiKey, $this->_compressionType, $this->_CMYKtoRGBconversion);
|
60 |
+
$this->prioQ = new ShortPixelQueue($this);
|
61 |
+
$this->view = new ShortPixelView($this);
|
62 |
+
|
63 |
+
define('QUOTA_EXCEEDED', "Quota Exceeded. <a href='https://shortpixel.com/login/".$this->_apiKey."' target='_blank'>Extend Quota</a>");
|
64 |
+
|
65 |
+
$this->setDefaultViewModeList();//set default mode as list. only @ first run
|
66 |
+
|
67 |
+
//add hook for image upload processing
|
68 |
+
add_filter( 'wp_generate_attachment_metadata', array( &$this, 'handleImageUpload' ), 10, 2 );
|
69 |
+
add_filter( 'manage_media_columns', array( &$this, 'columns' ) );//add media library column header
|
70 |
+
add_filter( 'plugin_action_links_' . plugin_basename(__FILE__), array(&$this, 'generatePluginLinks'));//for plugin settings page
|
71 |
+
|
72 |
+
//add_action( 'admin_footer', array(&$this, 'handleImageProcessing'));
|
73 |
+
add_action( 'manage_media_custom_column', array( &$this, 'generateCustomColumn' ), 10, 2 );//generate the media library column
|
74 |
+
|
75 |
+
//add settings page
|
76 |
+
add_action( 'admin_menu', array( &$this, 'registerSettingsPage' ) );//display SP in Settings menu
|
77 |
+
add_action( 'admin_menu', array( &$this, 'registerAdminPage' ) );
|
78 |
+
add_action( 'delete_attachment', array( &$this, 'handleDeleteAttachmentInBackup' ) );
|
79 |
+
add_action( 'load-upload.php', array( &$this, 'handleCustomBulk'));
|
80 |
+
|
81 |
+
//when plugin is activated run this
|
82 |
+
register_activation_hook( __FILE__, array( &$this, 'shortPixelActivatePlugin' ) );
|
83 |
+
register_deactivation_hook( __FILE__, array( &$this, 'shortPixelDeactivatePlugin' ) );
|
84 |
+
|
85 |
+
//automatic optimization
|
86 |
+
add_action( 'wp_ajax_shortpixel_image_processing', array( &$this, 'handleImageProcessing') );
|
87 |
+
//manual optimization
|
88 |
+
add_action( 'wp_ajax_shortpixel_manual_optimization', array(&$this, 'handleManualOptimization'));
|
89 |
+
//backup restore
|
90 |
+
add_action('admin_action_shortpixel_restore_backup', array(&$this, 'handleRestoreBackup'));
|
91 |
+
|
92 |
+
//This adds the constants used in PHP to be available also in JS
|
93 |
+
add_action( 'admin_footer', array( &$this, 'shortPixelJS') );
|
94 |
+
|
95 |
+
|
96 |
+
//example toolbar by fai, to be configured
|
97 |
+
add_action( 'admin_bar_menu', array( &$this, 'toolbar_shortpixel_processing'), 999 );
|
98 |
+
|
99 |
+
$this->migrateBackupFolder();
|
100 |
+
}
|
101 |
+
|
102 |
+
public function populateOptions() {
|
103 |
+
|
104 |
+
$this->_apiKey = self::getOpt('wp-short-pixel-apiKey', '');
|
105 |
+
$this->_verifiedKey = self::getOpt('wp-short-pixel-verifiedKey', $this->_verifiedKey);
|
106 |
+
$this->_compressionType = self::getOpt('wp-short-pixel-compression', $this->_compressionType);
|
107 |
+
$this->_processThumbnails = self::getOpt('wp-short-process_thumbnails', $this->_processThumbnails);
|
108 |
+
$this->_CMYKtoRGBconversion = self::getOpt('wp-short-pixel_cmyk2rgb', $this->_CMYKtoRGBconversion);
|
109 |
+
$this->_backupImages = self::getOpt('wp-short-backup_images', $this->_backupImages);
|
110 |
+
// the following practically set defaults for options if they're not set
|
111 |
+
self::getOpt( 'wp-short-pixel-fileCount', 0);
|
112 |
+
self::getOpt( 'wp-short-pixel-thumbnail-count', 0);//amount of optimized thumbnails
|
113 |
+
self::getOpt( 'wp-short-pixel-files-under-5-percent', 0);//amount of optimized thumbnails
|
114 |
+
self::getOpt( 'wp-short-pixel-savedSpace', 0);
|
115 |
+
self::getOpt( 'wp-short-pixel-api-retries', 0);//sometimes we need to retry processing/downloading a file multiple times
|
116 |
+
self::getOpt( 'wp-short-pixel-quota-exceeded', 0);
|
117 |
+
self::getOpt( 'wp-short-pixel-total-original', 0);//amount of original data
|
118 |
+
self::getOpt( 'wp-short-pixel-total-optimized', 0);//amount of optimized
|
119 |
+
self::getOpt( 'wp-short-pixel-protocol', 'https');
|
120 |
+
}
|
121 |
+
|
122 |
+
public function shortPixelActivatePlugin()//reset some params to avoid trouble for plugins that were activated/deactivated/activated
|
123 |
+
{
|
124 |
+
$this->prioQ->resetBulk();
|
125 |
+
if(SP_RESET_ON_ACTIVATE === true && WP_DEBUG === true) { //force reset plugin counters, only on specific occasions and on test environments
|
126 |
+
update_option( 'wp-short-pixel-fileCount', 0);
|
127 |
+
update_option( 'wp-short-pixel-thumbnail-count', 0);
|
128 |
+
update_option( 'wp-short-pixel-files-under-5-percent', 0);
|
129 |
+
update_option( 'wp-short-pixel-savedSpace', 0);
|
130 |
+
update_option( 'wp-short-pixel-api-retries', 0);//sometimes we need to retry processing/downloading a file multiple times
|
131 |
+
update_option( 'wp-short-pixel-quota-exceeded', 0);
|
132 |
+
update_option( 'wp-short-pixel-total-original', 0);//amount of original data
|
133 |
+
update_option( 'wp-short-pixel-total-optimized', 0);//amount of optimized
|
134 |
+
update_option( 'wp-short-pixel-bulk-ever-ran', 0);
|
135 |
+
delete_option('wp-short-pixel-priorityQueue');
|
136 |
+
unset($_SESSION["wp-short-pixel-priorityQueue"]);
|
137 |
+
delete_option("wp-short-pixel-bulk-previous-percent");
|
138 |
+
}
|
139 |
+
}
|
140 |
+
|
141 |
+
public function shortPixelDeactivatePlugin()//reset some params to avoid trouble for plugins that were activated/deactivated/activated
|
142 |
+
{
|
143 |
+
$this->prioQ->resetBulk();
|
144 |
+
}
|
145 |
+
|
146 |
+
//set default move as "list". only set once, it won't try to set the default mode again.
|
147 |
+
public function setDefaultViewModeList()
|
148 |
+
{
|
149 |
+
if(get_option('wp-short-pixel-view-mode') === false)
|
150 |
+
{
|
151 |
+
add_option('wp-short-pixel-view-mode', 1, '', 'yes' );
|
152 |
+
if ( function_exists('get_currentuserinfo') )
|
153 |
+
{
|
154 |
+
global $current_user;
|
155 |
+
get_currentuserinfo();
|
156 |
+
$currentUserID = $current_user->ID;
|
157 |
+
update_user_meta($currentUserID, "wp_media_library_mode", "list");
|
158 |
+
}
|
159 |
+
}
|
160 |
+
|
161 |
+
}
|
162 |
+
|
163 |
+
static function log($message) {
|
164 |
+
if (WP_DEBUG === true) {
|
165 |
+
if (is_array($message) || is_object($message)) {
|
166 |
+
error_log(print_r($message, true));
|
167 |
+
} else {
|
168 |
+
error_log($message);
|
169 |
+
}
|
170 |
+
}
|
171 |
+
}
|
172 |
+
|
173 |
+
function shortPixelJS() { ?>
|
174 |
+
<script type="text/javascript" >
|
175 |
+
jQuery(document).ready(function($){
|
176 |
+
ShortPixel.setOptions({
|
177 |
+
STATUS_SUCCESS: <?= ShortPixelAPI::STATUS_SUCCESS ?>,
|
178 |
+
STATUS_EMPTY_QUEUE: <?= self::BULK_EMPTY_QUEUE ?>,
|
179 |
+
STATUS_ERROR: <?= ShortPixelAPI::STATUS_ERROR ?>,
|
180 |
+
STATUS_FAIL: <?= ShortPixelAPI::STATUS_FAIL ?>,
|
181 |
+
STATUS_SKIP: <?= ShortPixelAPI::STATUS_SKIP ?>,
|
182 |
+
STATUS_QUOTA_EXCEEDED: <?= ShortPixelAPI::STATUS_QUOTA_EXCEEDED ?>,
|
183 |
+
WP_PLUGIN_URL: '<?= WP_PLUGIN_URL ?>',
|
184 |
+
API_KEY: "<?= $this->_apiKey ?>"
|
185 |
+
});
|
186 |
+
});
|
187 |
+
</script> <?php
|
188 |
+
wp_enqueue_style('short-pixel.css', plugins_url('/css/short-pixel.css',__FILE__) );
|
189 |
+
}
|
190 |
+
|
191 |
+
function toolbar_shortpixel_processing( $wp_admin_bar ) {
|
192 |
+
if ( !is_admin()) {
|
193 |
+
return;
|
194 |
+
}
|
195 |
+
wp_enqueue_script('short-pixel.js', plugins_url('/js/short-pixel.js',__FILE__) );
|
196 |
+
|
197 |
+
$extraClasses = " shortpixel-hide";
|
198 |
+
$tooltip = "ShortPixel optimizing...";
|
199 |
+
$icon = "shortpixel.png";
|
200 |
+
$link = current_user_can( 'edit_others_posts')? 'upload.php?page=wp-short-pixel-bulk' : 'upload.php';
|
201 |
+
$blank = "";
|
202 |
+
if($this->prioQ->processing()) {
|
203 |
+
$extraClasses = " shortpixel-processing";
|
204 |
+
}
|
205 |
+
self::log("TOOLBAR: Quota exceeded: " . self::getOpt( 'wp-short-pixel-quota-exceeded', 0));
|
206 |
+
if(self::getOpt( 'wp-short-pixel-quota-exceeded', 0)) {
|
207 |
+
$extraClasses = " shortpixel-alert shortpixel-quota-exceeded";
|
208 |
+
$tooltip = "ShortPixel quota exceeded. Click to top-up";
|
209 |
+
$link = "http://shortpixel.com/login/" . $this->_apiKey;
|
210 |
+
$blank = '_blank';
|
211 |
+
//$icon = "shortpixel-alert.png";
|
212 |
+
}
|
213 |
+
self::log("TB: Start: " . $this->prioQ->getStartBulkId() . ", stop: " . $this->prioQ->getStopBulkId() . " PrioQ: "
|
214 |
+
.json_encode($this->prioQ->get()));
|
215 |
+
|
216 |
+
$args = array(
|
217 |
+
'id' => 'shortpixel_processing',
|
218 |
+
'title' => '<div title="' . $tooltip . '" ><img src="'
|
219 |
+
. WP_PLUGIN_URL . '/shortpixel-image-optimiser/img/' . $icon . '"><span class="shp-alert">!</span></div>',
|
220 |
+
'href' => $link,
|
221 |
+
'meta' => array('target'=> $blank, 'class' => 'shortpixel-toolbar-processing' . $extraClasses)
|
222 |
+
);
|
223 |
+
$wp_admin_bar->add_node( $args );
|
224 |
+
}
|
225 |
+
|
226 |
+
public static function getOpt($key, $default) {
|
227 |
+
if(get_option($key) === false) {
|
228 |
+
add_option( $key, $default, '', 'yes' );
|
229 |
+
}
|
230 |
+
return get_option($key);
|
231 |
+
}
|
232 |
+
|
233 |
+
public function handleCustomBulk() {
|
234 |
+
// 1. get the action
|
235 |
+
$wp_list_table = _get_list_table('WP_Media_List_Table');
|
236 |
+
$action = $wp_list_table->current_action();
|
237 |
+
|
238 |
+
switch($action) {
|
239 |
+
// 2. Perform the action
|
240 |
+
case 'short-pixel-bulk':
|
241 |
+
// security check
|
242 |
+
check_admin_referer('bulk-media');
|
243 |
+
if(!is_array($_GET['media'])) {
|
244 |
+
break;
|
245 |
+
}
|
246 |
+
$mediaIds = array_reverse($_GET['media']);
|
247 |
+
foreach( $mediaIds as $ID ) {
|
248 |
+
$meta = wp_get_attachment_metadata($ID);
|
249 |
+
if( (!isset($meta['ShortPixel']) || !isset($meta['ShortPixel']['WaitingProcessing']) || $meta['ShortPixel']['WaitingProcessing'] != true)
|
250 |
+
&& (!isset($meta['ShortPixelImprovement']) || $meta['ShortPixelImprovement'] != 'Optimization N/A')) {
|
251 |
+
$this->prioQ->push($ID);
|
252 |
+
$meta['ShortPixel']['WaitingProcessing'] = true;
|
253 |
+
wp_update_attachment_metadata($ID, $meta);
|
254 |
+
}
|
255 |
+
}
|
256 |
+
break;
|
257 |
+
}
|
258 |
+
}
|
259 |
+
|
260 |
+
public function handleImageUpload($meta, $ID = null)
|
261 |
+
{
|
262 |
+
if( !$this->_verifiedKey) {// no API Key set/verified -> do nothing here, just return
|
263 |
+
return $meta;
|
264 |
+
}
|
265 |
+
//else
|
266 |
+
self::log("IMG: Auto-analyzing file ID #{$ID}");
|
267 |
+
|
268 |
+
if( self::isProcessable($ID) == false )
|
269 |
+
{//not a file that we can process
|
270 |
+
$meta['ShortPixelImprovement'] = 'Optimization N/A';
|
271 |
+
return $meta;
|
272 |
+
}
|
273 |
+
else
|
274 |
+
{//the kind of file we can process. goody.
|
275 |
+
$this->prioQ->push($ID);
|
276 |
+
$URLsAndPATHs = $this->getURLsAndPATHs($ID, $meta);
|
277 |
+
$this->_apiInterface->doRequests($URLsAndPATHs['URLs'], false, $ID);//send a processing request right after a file was uploaded, do NOT wait for response
|
278 |
+
self::log("IMG: sent: " . json_encode($URLsAndPATHs));
|
279 |
+
$meta['ShortPixel']['WaitingProcessing'] = true;
|
280 |
+
return $meta;
|
281 |
+
}
|
282 |
+
|
283 |
+
}//end handleImageUpload
|
284 |
+
|
285 |
+
public function getCurrentBulkItemsCount(){
|
286 |
+
global $wpdb;
|
287 |
+
|
288 |
+
$startQueryID = $this->prioQ->getFlagBulkId();
|
289 |
+
$endQueryID = $this->prioQ->getStopBulkId();
|
290 |
+
|
291 |
+
if ( $startQueryID <= $endQueryID ) {
|
292 |
+
return 0;
|
293 |
+
}
|
294 |
+
$queryPostMeta = "SELECT COUNT(DISTINCT post_id) items FROM " . $wpdb->prefix . "postmeta
|
295 |
+
WHERE ( post_id <= $startQueryID AND post_id > $endQueryID ) AND (
|
296 |
+
meta_key = '_wp_attached_file'
|
297 |
+
OR meta_key = '_wp_attachment_metadata' )";
|
298 |
+
$res = $wpdb->get_results($queryPostMeta);
|
299 |
+
return $res[0]->items;
|
300 |
+
}
|
301 |
+
|
302 |
+
public function getBulkItemsFromDb(){
|
303 |
+
global $wpdb;
|
304 |
+
|
305 |
+
$startQueryID = $this->prioQ->getStartBulkId();
|
306 |
+
$endQueryID = $this->prioQ->getStopBulkId();
|
307 |
+
$skippedAlreadyProcessed = 0;
|
308 |
+
|
309 |
+
if ( $startQueryID <= $endQueryID ) {
|
310 |
+
return false;
|
311 |
+
}
|
312 |
+
$idList = array();
|
313 |
+
for ($sanityCheck = 0, $crtStartQueryID = $startQueryID;
|
314 |
+
$crtStartQueryID > $endQueryID && count($idList) < 3; $sanityCheck++) {
|
315 |
+
|
316 |
+
self::log("GETDB: current StartID: " . $crtStartQueryID);
|
317 |
+
|
318 |
+
$queryPostMeta = "SELECT * FROM " . $wpdb->prefix . "postmeta
|
319 |
+
WHERE ( post_id <= $crtStartQueryID AND post_id > $endQueryID )
|
320 |
+
AND ( meta_key = '_wp_attached_file' OR meta_key = '_wp_attachment_metadata' )
|
321 |
+
ORDER BY post_id DESC
|
322 |
+
LIMIT " . SP_MAX_RESULTS_QUERY;
|
323 |
+
$resultsPostMeta = $wpdb->get_results($queryPostMeta);
|
324 |
+
|
325 |
+
if ( empty($resultsPostMeta) ) {
|
326 |
+
$crtStartQueryID -= SP_MAX_RESULTS_QUERY;
|
327 |
+
continue;
|
328 |
+
}
|
329 |
+
|
330 |
+
foreach ( $resultsPostMeta as $itemMetaData ) {
|
331 |
+
$crtStartQueryID = $itemMetaData->post_id;
|
332 |
+
if(!in_array($crtStartQueryID, $idList) && self::isProcessable($crtStartQueryID)) {
|
333 |
+
$meta = wp_get_attachment_metadata($crtStartQueryID);
|
334 |
+
if(!isset($meta["ShortPixelImprovement"]) || !is_numeric($meta["ShortPixelImprovement"])) {
|
335 |
+
$idList[] = $crtStartQueryID;
|
336 |
+
} elseif($itemMetaData->meta_key == '_wp_attachment_metadata') { //count skipped
|
337 |
+
$skippedAlreadyProcessed++;
|
338 |
+
}
|
339 |
+
}
|
340 |
+
}
|
341 |
+
if(!count($idList) && $crtStartQueryID <= $startQueryID) {
|
342 |
+
//daca n-am adaugat niciuna pana acum, n-are sens sa mai selectez zona asta de id-uri in bulk-ul asta.
|
343 |
+
$leapStart = $this->prioQ->getStartBulkId();
|
344 |
+
$crtStartQueryID = $startQueryID = $itemMetaData->post_id - 1; //decrement it so we don't select it again
|
345 |
+
$res = self::countAllProcessedFiles($leapStart, $crtStartQueryID);
|
346 |
+
$skippedAlreadyProcessed += $res["mainFiles"];
|
347 |
+
$this->prioQ->setStartBulkId($startQueryID);
|
348 |
+
} else {
|
349 |
+
$crtStartQueryID--;
|
350 |
+
}
|
351 |
+
}
|
352 |
+
return array("ids" => $idList, "skipped" => $skippedAlreadyProcessed);
|
353 |
+
}
|
354 |
+
|
355 |
+
/**
|
356 |
+
* Get last added items from priority
|
357 |
+
* @return type
|
358 |
+
*/
|
359 |
+
public function getFromPrioAndCheck() {
|
360 |
+
$ids = array();
|
361 |
+
$removeIds = array();
|
362 |
+
|
363 |
+
$idsPrio = $this->prioQ->get();
|
364 |
+
for($i = count($idsPrio) - 1, $cnt = 0; $i>=0 && $cnt < 3; $i--) {
|
365 |
+
$id = $idsPrio[$i];
|
366 |
+
if(wp_get_attachment_url($id)) {
|
367 |
+
$ids[] = $id; //valid ID
|
368 |
+
} else {
|
369 |
+
$removeIds[] = $id;//absent, to remove
|
370 |
+
}
|
371 |
+
}
|
372 |
+
foreach($removeIds as $rId){
|
373 |
+
self::log("HIP: Unfound ID $rID Remove from Priority Queue: ".json_encode(get_option($this->prioQ->get())));
|
374 |
+
$this->prioQ->remove($rId);
|
375 |
+
}
|
376 |
+
return $ids;
|
377 |
+
}
|
378 |
+
|
379 |
+
public function handleImageProcessing($ID = null) {
|
380 |
+
//die("bau");
|
381 |
+
//0: check key
|
382 |
+
if( $this->_verifiedKey == false) {
|
383 |
+
echo "Missing API Key";
|
384 |
+
die();
|
385 |
+
}
|
386 |
+
|
387 |
+
self::log("HIP: 0 Priority Queue: ".json_encode($this->prioQ->get()));
|
388 |
+
|
389 |
+
//1: get 3 ids to process. Take them with priority from the queue
|
390 |
+
$ids = $this->getFromPrioAndCheck();
|
391 |
+
if(count($ids) < 3 ) { //take from bulk if bulk processing active
|
392 |
+
$bulkStatus = $this->prioQ->bulkRunning();
|
393 |
+
if($bulkStatus =='running') {
|
394 |
+
$res = $this->getBulkItemsFromDb();
|
395 |
+
$bulkItems = $res['ids'];
|
396 |
+
if($bulkItems){
|
397 |
+
$ids = array_merge ($ids, $bulkItems);
|
398 |
+
}
|
399 |
+
}
|
400 |
+
}
|
401 |
+
if ($ids === false || count( $ids ) == 0 ){
|
402 |
+
$bulkEverRan = $this->prioQ->stopBulk();
|
403 |
+
$avg = self::getAverageCompression();
|
404 |
+
$fileCount = get_option('wp-short-pixel-fileCount');
|
405 |
+
die(json_encode(array("Status" => self::BULK_EMPTY_QUEUE,
|
406 |
+
"Message" => 'Empty queue ' . $this->prioQ->getStartBulkId() . '->' . $this->prioQ->getStopBulkId(),
|
407 |
+
"BulkStatus" => ($this->prioQ->bulkRunning()
|
408 |
+
? "1" : ($this->prioQ->bulkPaused() ? "2" : "0")),
|
409 |
+
"AverageCompression" => $avg,
|
410 |
+
"FileCount" => $fileCount,
|
411 |
+
"BulkPercent" => $this->prioQ->getBulkPercent())));
|
412 |
+
}
|
413 |
+
|
414 |
+
self::log("HIP: 1 Prio Queue: ".json_encode($this->prioQ->get()));
|
415 |
+
|
416 |
+
//2: Send up to 3 files to the server for processing
|
417 |
+
for($i = 0; $i < min(3, count($ids)); $i++) {
|
418 |
+
$ID = $ids[$i];
|
419 |
+
$URLsAndPATHs = $this->sendToProcessing($ID);
|
420 |
+
if($i == 0) { //save for later use
|
421 |
+
$firstUrlAndPaths = $URLsAndPATHs;
|
422 |
+
}
|
423 |
+
}
|
424 |
+
|
425 |
+
self::log("HIP: 2 Prio Queue: ".json_encode($this->prioQ->get()));
|
426 |
+
|
427 |
+
//3: Retrieve the file for the first element of the list
|
428 |
+
$ID = $ids[0];
|
429 |
+
$result = $this->_apiInterface->processImage($firstUrlAndPaths['URLs'], $firstUrlAndPaths['PATHs'], $ID);
|
430 |
+
$result["ImageID"] = $ID;
|
431 |
+
|
432 |
+
self::log("HIP: 3 Prio Queue: ".json_encode($this->prioQ->get()));
|
433 |
+
|
434 |
+
//4: update counters and priority list
|
435 |
+
if( $result["Status"] == ShortPixelAPI::STATUS_SUCCESS) {
|
436 |
+
self::log("HIP: Image ID $ID optimized successfully: ".json_encode($result));
|
437 |
+
$prio = $this->prioQ->remove($ID);
|
438 |
+
if(!$prio && $ID <= $this->prioQ->getStartBulkId()) {
|
439 |
+
$this->prioQ->setStartBulkId($ID - 1);
|
440 |
+
$this->prioQ->logBulkProgress();
|
441 |
+
|
442 |
+
$deltaBulkPercent = $this->prioQ->getDeltaBulkPercent();
|
443 |
+
$msg = $this->bulkProgressMessage($deltaBulkPercent, $this->prioQ->getTimeRemaining());
|
444 |
+
$result["BulkPercent"] = $this->prioQ->getBulkPercent();;
|
445 |
+
$result["BulkMsg"] = $msg;
|
446 |
+
|
447 |
+
$thumb = $bkThumb = "";
|
448 |
+
$percent = 0;
|
449 |
+
$meta = wp_get_attachment_metadata($ID);
|
450 |
+
if(isset($meta["ShortPixelImprovement"]) && isset($meta["file"])){
|
451 |
+
$percent = $meta["ShortPixelImprovement"];
|
452 |
+
|
453 |
+
$filePath = explode("/", $meta["file"]);
|
454 |
+
$uploadsUrl = content_url() . "/uploads/";
|
455 |
+
$urlPath = implode("/", array_slice($filePath, 0, count($filePath) - 1));
|
456 |
+
$thumb = (isset($meta["sizes"]["medium"]) ? $meta["sizes"]["medium"]["file"] : (isset($meta["sizes"]["thumbnail"]) ? $meta["sizes"]["thumbnail"]["file"]: ""));
|
457 |
+
if(strlen($thumb) && get_option('wp-short-backup_images')) {
|
458 |
+
$bkThumb = $uploadsUrl . SP_BACKUP . "/" . $urlPath . "/" . $thumb;
|
459 |
+
}
|
460 |
+
if(strlen($thumb)) {
|
461 |
+
$thumb = $uploadsUrl . $urlPath . "/" . $thumb;
|
462 |
+
}
|
463 |
+
$result["Thumb"] = $thumb;
|
464 |
+
$result["BkThumb"] = $bkThumb;
|
465 |
+
}
|
466 |
+
}
|
467 |
+
}
|
468 |
+
elseif ($result["Status"] == ShortPixelAPI::STATUS_SKIP
|
469 |
+
|| $result["Status"] == ShortPixelAPI::STATUS_FAIL) {
|
470 |
+
$prio = $this->prioQ->remove($ID);
|
471 |
+
if(!$prio && $ID <= $this->prioQ->getStartBulkId()) {
|
472 |
+
$this->prioQ->setStartBulkId($ID - 1);
|
473 |
+
}
|
474 |
+
}
|
475 |
+
die(json_encode($result));
|
476 |
+
}
|
477 |
+
|
478 |
+
private function sendToProcessing($ID) {
|
479 |
+
$URLsAndPATHs = $this->getURLsAndPATHs($ID);
|
480 |
+
$this->_apiInterface->doRequests($URLsAndPATHs['URLs'], false, $ID);//send a request, do NOT wait for response
|
481 |
+
$meta = wp_get_attachment_metadata($ID);
|
482 |
+
$meta['ShortPixel']['WaitingProcessing'] = true;
|
483 |
+
wp_update_attachment_metadata($ID, $meta);
|
484 |
+
return $URLsAndPATHs;
|
485 |
+
}
|
486 |
+
|
487 |
+
public function handleManualOptimization() {
|
488 |
+
$imageId = intval($_GET['image_id']);
|
489 |
+
|
490 |
+
if(self::isProcessable($imageId)) {
|
491 |
+
$this->prioQ->push($imageId);
|
492 |
+
$this->sendToProcessing($imageId);
|
493 |
+
$ret = array("Status" => ShortPixelAPI::STATUS_SUCCESS, "message" => "");
|
494 |
+
} else {
|
495 |
+
die(var_dump($pathParts));
|
496 |
+
}
|
497 |
+
die(json_encode($ret));
|
498 |
+
|
499 |
+
$urlList[] = wp_get_attachment_url($attachmentID);
|
500 |
+
$filePath[] = get_attached_file($attachmentID);
|
501 |
+
$meta = wp_get_attachment_metadata($attachmentID);
|
502 |
+
|
503 |
+
$processThumbnails = get_option('wp-short-process_thumbnails');
|
504 |
+
|
505 |
+
//process all files (including thumbs)
|
506 |
+
if($processThumbnails && !empty($meta['sizes'])) {
|
507 |
+
//we generate an array with the URLs that need to be handled
|
508 |
+
$SubDir = $this->_apiInterface->returnSubDir($meta['file']);
|
509 |
+
foreach($meta['sizes'] as $thumbnailInfo)
|
510 |
+
{
|
511 |
+
$urlList[]= str_replace(ShortPixelAPI::MB_basename($filePath[0]), $thumbnailInfo['file'], $urlList[0]);
|
512 |
+
$filePath[] = str_replace(ShortPixelAPI::MB_basename($filePath[0]), $thumbnailInfo['file'], $filePath[0]);
|
513 |
+
}
|
514 |
+
}
|
515 |
+
|
516 |
+
$result = $this->_apiInterface->processImage($urlList, $filePath, $attachmentID);//request to process all the images
|
517 |
+
|
518 |
+
if ( !is_array($result) )//there was an error, we save it in ShortPixelImprovement data
|
519 |
+
$this->handleError($attachmentID, $result);
|
520 |
+
|
521 |
+
// store the referring webpage location
|
522 |
+
$sendback = wp_get_referer();
|
523 |
+
// sanitize the referring webpage location
|
524 |
+
$sendback = preg_replace('|[^a-z0-9-~+_.?#=&;,/:]|i', '', $sendback);
|
525 |
+
// send the user back where they came from
|
526 |
+
wp_redirect($sendback);
|
527 |
+
// we are done,
|
528 |
+
}
|
529 |
+
|
530 |
+
//save error in file's meta data
|
531 |
+
public function handleError($ID, $result)
|
532 |
+
{
|
533 |
+
$meta = wp_get_attachment_metadata($ID);
|
534 |
+
$meta['ShortPixelImprovement'] = $result;
|
535 |
+
wp_update_attachment_metadata($ID, $meta);
|
536 |
+
}
|
537 |
+
|
538 |
+
public function handleRestoreBackup() {
|
539 |
+
$attachmentID = intval($_GET['attachment_ID']);
|
540 |
+
|
541 |
+
$file = get_attached_file($attachmentID);
|
542 |
+
$meta = wp_get_attachment_metadata($attachmentID);
|
543 |
+
$pathInfo = pathinfo($file);
|
544 |
+
|
545 |
+
$fileExtension = strtolower(substr($file,strrpos($file,".")+1));
|
546 |
+
$SubDir = $this->_apiInterface->returnSubDir($file);
|
547 |
+
|
548 |
+
//sometimes the month of original file and backup can differ
|
549 |
+
if ( !file_exists(SP_BACKUP_FOLDER . DIRECTORY_SEPARATOR . $SubDir . ShortPixelAPI::MB_basename($file)) )
|
550 |
+
$SubDir = date("Y") . "/" . date("m") . "/";
|
551 |
+
|
552 |
+
try {
|
553 |
+
//main file
|
554 |
+
@rename(SP_BACKUP_FOLDER . DIRECTORY_SEPARATOR . $SubDir . ShortPixelAPI::MB_basename($file), $file);
|
555 |
+
|
556 |
+
//overwriting thumbnails
|
557 |
+
if( !empty($meta['file']) ) {
|
558 |
+
foreach($meta["sizes"] as $size => $imageData) {
|
559 |
+
$source = SP_BACKUP_FOLDER . DIRECTORY_SEPARATOR . $SubDir . $imageData['file'];
|
560 |
+
$destination = $pathInfo['dirname'] . DIRECTORY_SEPARATOR . $imageData['file'];
|
561 |
+
@rename($source, $destination);
|
562 |
+
}
|
563 |
+
}
|
564 |
+
unset($meta["ShortPixelImprovement"]);
|
565 |
+
unset($meta['ShortPixel']['WaitingProcessing']);
|
566 |
+
wp_update_attachment_metadata($attachmentID, $meta);
|
567 |
+
|
568 |
+
} catch(Exception $e) {
|
569 |
+
//what to do, what to do?
|
570 |
+
}
|
571 |
+
// store the referring webpage location
|
572 |
+
$sendback = wp_get_referer();
|
573 |
+
// sanitize the referring webpage location
|
574 |
+
$sendback = preg_replace('|[^a-z0-9-~+_.?#=&;,/:]|i', '', $sendback);
|
575 |
+
// send the user back where they came from
|
576 |
+
wp_redirect($sendback);
|
577 |
+
// we are done
|
578 |
+
}
|
579 |
+
|
580 |
+
|
581 |
+
public function handleDeleteAttachmentInBackup($ID) {
|
582 |
+
$file = get_attached_file($ID);
|
583 |
+
$meta = wp_get_attachment_metadata($ID);
|
584 |
+
|
585 |
+
if(self::isProcessable($ID) != false)
|
586 |
+
{
|
587 |
+
$SubDir = $this->_apiInterface->returnSubDir($file);
|
588 |
+
try {
|
589 |
+
$SubDir = $this->_apiInterface->returnSubDir($file);
|
590 |
+
|
591 |
+
@unlink(SP_BACKUP_FOLDER . DIRECTORY_SEPARATOR . $SubDir . ShortPixelAPI::MB_basename($file));
|
592 |
+
|
593 |
+
if ( !empty($meta['file']) )
|
594 |
+
{
|
595 |
+
$filesPath = SP_BACKUP_FOLDER . DIRECTORY_SEPARATOR . $SubDir;//base BACKUP path
|
596 |
+
//remove thumbs thumbnails
|
597 |
+
if(isset($meta["sizes"])) {
|
598 |
+
foreach($meta["sizes"] as $size => $imageData) {
|
599 |
+
@unlink($filesPath . ShortPixelAPI::MB_basename($imageData['file']));//remove thumbs
|
600 |
+
}
|
601 |
+
}
|
602 |
+
}
|
603 |
+
|
604 |
+
} catch(Exception $e) {
|
605 |
+
//what to do, what to do?
|
606 |
+
}
|
607 |
+
}
|
608 |
+
}
|
609 |
+
|
610 |
+
public function registerSettingsPage() {
|
611 |
+
add_options_page( 'ShortPixel Settings', 'ShortPixel', 'manage_options', 'wp-shortpixel', array($this, 'renderSettingsMenu'));
|
612 |
+
}
|
613 |
+
|
614 |
+
function registerAdminPage( ) {
|
615 |
+
add_media_page( 'ShortPixel Bulk Process', 'Bulk ShortPixel', 'edit_others_posts', 'wp-short-pixel-bulk', array( &$this, 'bulkProcess' ) );
|
616 |
+
}
|
617 |
+
|
618 |
+
public function checkQuotaAndAlert() {
|
619 |
+
$quotaData = $this->getQuotaInformation();
|
620 |
+
if ( !$quotaData['APIKeyValid']) {
|
621 |
+
return $quotaData;
|
622 |
+
}
|
623 |
+
if($quotaData['APICallsQuotaNumeric'] + $quotaData['APICallsQuotaOneTimeNumeric'] > $quotaData['APICallsMadeNumeric'] + $quotaData['APICallsMadeOneTimeNumeric']) {
|
624 |
+
update_option('wp-short-pixel-quota-exceeded','0');
|
625 |
+
?><script>var shortPixelQuotaExceeded = 0;</script><?php
|
626 |
+
}
|
627 |
+
else {
|
628 |
+
$this->view->displayQuotaExceededAlert($quotaData);
|
629 |
+
?><script>var shortPixelQuotaExceeded = 1;</script><?php
|
630 |
+
}
|
631 |
+
return $quotaData;
|
632 |
+
}
|
633 |
+
|
634 |
+
public function bulkProcess() {
|
635 |
+
global $wpdb;
|
636 |
+
|
637 |
+
if( $this->_verifiedKey == false ) {//invalid API Key
|
638 |
+
$this->view->displayApiKeyAlert();
|
639 |
+
return;
|
640 |
+
}
|
641 |
+
|
642 |
+
$quotaData = $this->checkQuotaAndAlert();
|
643 |
+
if(self::getOpt('wp-short-pixel-quota-exceeded', 0) != 0) return;
|
644 |
+
|
645 |
+
if(isset($_POST['bulkProcessPause']))
|
646 |
+
{//pause an ongoing bulk processing, it might be needed sometimes
|
647 |
+
$this->prioQ->pauseBulk();
|
648 |
+
}
|
649 |
+
|
650 |
+
if(isset($_POST["bulkProcess"]))
|
651 |
+
{
|
652 |
+
//set the thumbnails option
|
653 |
+
if ( isset($_POST['thumbnails']) ) {
|
654 |
+
update_option('wp-short-process_thumbnails', 1);
|
655 |
+
} else {
|
656 |
+
update_option('wp-short-process_thumbnails', 0);
|
657 |
+
}
|
658 |
+
$this->prioQ->startBulk();
|
659 |
+
self::log("BULK: Start: " . $this->prioQ->getStartBulkId() . ", stop: " . $this->prioQ->getStopBulkId() . " PrioQ: "
|
660 |
+
.json_encode($this->prioQ->get()));
|
661 |
+
}//end bulk process was clicked
|
662 |
+
|
663 |
+
if(isset($_POST["bulkProcessResume"]))
|
664 |
+
{
|
665 |
+
$this->prioQ->resumeBulk();
|
666 |
+
}//resume was clicked
|
667 |
+
|
668 |
+
//figure out all the files that could be processed
|
669 |
+
$qry = "SELECT count(*) FilesToBeProcessed FROM " . $wpdb->prefix . "postmeta
|
670 |
+
WHERE meta_key = '_wp_attached_file' ";
|
671 |
+
$allFiles = $wpdb->get_results($qry);
|
672 |
+
//figure out the files that are left to be processed
|
673 |
+
$qry_left = "SELECT count(*) FilesLeftToBeProcessed FROM " . $wpdb->prefix . "postmeta
|
674 |
+
WHERE meta_key = '_wp_attached_file' AND post_id <= " . $this->prioQ->getStartBulkId();
|
675 |
+
$filesLeft = $wpdb->get_results($qry_left);
|
676 |
+
|
677 |
+
if ( $filesLeft[0]->FilesLeftToBeProcessed > 0 && $this->prioQ->bulkRunning() )//bulk processing was started and is still running
|
678 |
+
{
|
679 |
+
$msg = $this->bulkProgressMessage($this->prioQ->getDeltaBulkPercent(), $this->prioQ->getTimeRemaining());
|
680 |
+
$this->view->displayBulkProcessingRunning($this->prioQ->getBulkPercent(), $msg);
|
681 |
+
|
682 |
+
// $imagesLeft = $filesLeft[0]->FilesLeftToBeProcessed;
|
683 |
+
// $totalImages = $allFiles[0]->FilesToBeProcessed;
|
684 |
+
// echo "<p>{$imagesLeft} out of {$totalImages} images left to process.</p>";
|
685 |
+
// echo ' <a class="button button-secondary" href="' . get_admin_url() . 'upload.php">Media Library</a> ';
|
686 |
+
} else
|
687 |
+
{
|
688 |
+
if($this->prioQ->bulkRan() && !$this->prioQ->bulkPaused()) {
|
689 |
+
$this->prioQ->markBulkComplete();
|
690 |
+
}
|
691 |
+
|
692 |
+
//image count
|
693 |
+
$imageCount = $this->countAllProcessableFiles();
|
694 |
+
$imgProcessedCount = $this->countAllProcessedFiles();
|
695 |
+
$imageOnlyThumbs = $imageCount['totalFiles'] - $imageCount['mainFiles'];
|
696 |
+
$thumbsProcessedCount = self::getOpt( 'wp-short-pixel-thumbnail-count', 0);//amount of optimized thumbnails
|
697 |
+
$under5PercentCount = self::getOpt( 'wp-short-pixel-files-under-5-percent', 0);//amount of under 5% optimized imgs.
|
698 |
+
|
699 |
+
//average compression
|
700 |
+
$averageCompression = self::getAverageCompression();
|
701 |
+
// $this->view->displayBulkProcessingForm($imageCount, $imageOnlyThumbs, $this->prioQ->bulkRan(), $averageCompression,
|
702 |
+
$this->view->displayBulkProcessingForm($imageCount, $imgProcessedCount, $thumbsProcessedCount, $under5PercentCount,
|
703 |
+
$this->prioQ->bulkRan(), $averageCompression, get_option('wp-short-pixel-fileCount'),
|
704 |
+
self::formatBytes(get_option('wp-short-pixel-savedSpace')), $this->prioQ->bulkPaused() ? $this->prioQ->getBulkPercent() : false);
|
705 |
+
}
|
706 |
+
}
|
707 |
+
//end bulk processing
|
708 |
+
|
709 |
+
public function bulkProgressMessage($percent, $minutes) {
|
710 |
+
$timeEst = "";
|
711 |
+
self::log("bulkProgressMessage(): percent: " . $percent);
|
712 |
+
if($percent < 1 || $minutes == 0) {
|
713 |
+
$timeEst = "";
|
714 |
+
} elseif( $minutes > 2880) {
|
715 |
+
$timeEst = "~ " . round($minutes / 1440) . " days left";
|
716 |
+
} elseif ($minutes > 240) {
|
717 |
+
$timeEst = "~ " . round($minutes / 60) . " hours left";
|
718 |
+
} elseif ($minutes > 60) {
|
719 |
+
$timeEst = "~ " . round($minutes / 60) . " hours " . round($minutes%60/10) * 10 . " min. left";
|
720 |
+
} elseif ($minutes > 20) {
|
721 |
+
$timeEst = "~ " . round($minutes / 10) * 10 . " minutes left";
|
722 |
+
} else {
|
723 |
+
$timeEst = "~ " . $minutes . " minutes left";
|
724 |
+
}
|
725 |
+
return $timeEst;
|
726 |
+
}
|
727 |
+
|
728 |
+
public function emptyBackup(){
|
729 |
+
if(file_exists(SP_BACKUP_FOLDER)) {
|
730 |
+
|
731 |
+
//extract all images from DB in an array. of course
|
732 |
+
$attachments = null;
|
733 |
+
$attachments = get_posts( array(
|
734 |
+
'numberposts' => -1,
|
735 |
+
'post_type' => 'attachment',
|
736 |
+
'post_mime_type' => 'image'
|
737 |
+
));
|
738 |
+
|
739 |
+
|
740 |
+
//parse all images and set the right flag that the image has no backup
|
741 |
+
foreach($attachments as $attachment)
|
742 |
+
{
|
743 |
+
if(self::isProcessable(get_attached_file($attachment->ID)) == false) continue;
|
744 |
+
|
745 |
+
$meta = wp_get_attachment_metadata($attachment->ID);
|
746 |
+
$meta['ShortPixel']['NoBackup'] = true;
|
747 |
+
wp_update_attachment_metadata($attachment->ID, $meta);
|
748 |
+
}
|
749 |
+
|
750 |
+
//delete the actual files on disk
|
751 |
+
$this->deleteDir(SP_BACKUP_FOLDER);//call a recursive function to empty files and sub-dirs in backup dir
|
752 |
+
}
|
753 |
+
}
|
754 |
+
|
755 |
+
public function renderSettingsMenu() {
|
756 |
+
if ( !current_user_can( 'manage_options' ) ) {
|
757 |
+
wp_die('You do not have sufficient permissions to access this page.');
|
758 |
+
}
|
759 |
+
|
760 |
+
$quotaData = $this->checkQuotaAndAlert();
|
761 |
+
|
762 |
+
echo '<h1>ShortPixel Plugin Settings</h1>';
|
763 |
+
echo '<p>
|
764 |
+
<a href="https://shortpixel.com" target="_blank">ShortPixel.com</a> |
|
765 |
+
<a href="https://wordpress.org/plugins/shortpixel-image-optimiser/installation/" target="_blank">Installation </a> |
|
766 |
+
<a href="https://shortpixel.com/contact" target="_blank">Support </a>
|
767 |
+
</p>';
|
768 |
+
echo '<p>New images uploaded to the Media Library will be optimized automatically.<br/>If you have existing images you would like to optimize, you can use the <a href="' . get_admin_url() . 'upload.php?page=wp-short-pixel-bulk">Bulk Optimization Tool</a>.</p>';
|
769 |
+
|
770 |
+
$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>";
|
771 |
+
|
772 |
+
//by default we try to fetch the API Key from wp-config.php (if defined)
|
773 |
+
if ( !isset($_POST['submit']) && !get_option('wp-short-pixel-verifiedKey') && defined("SHORTPIXEL_API_KEY") && strlen(SHORTPIXEL_API_KEY) == 20 )
|
774 |
+
{
|
775 |
+
$_POST['validate'] = "validate";
|
776 |
+
$_POST['key'] = SHORTPIXEL_API_KEY;
|
777 |
+
}
|
778 |
+
|
779 |
+
if(isset($_POST['submit']) || isset($_POST['validate'])) {
|
780 |
+
|
781 |
+
//handle API Key - common for submit and validate
|
782 |
+
$_POST['key'] = trim(str_replace("*","",$_POST['key']));
|
783 |
+
|
784 |
+
if ( strlen($_POST['key']) <> 20 )
|
785 |
+
{
|
786 |
+
$KeyLength = strlen($_POST['key']);
|
787 |
+
|
788 |
+
printf($noticeHTML, '#ff0000', "The key you provided has " . $KeyLength . " characters. The API key should have 20 characters, letters and numbers only.<BR> <b>Please check that the API key is the same as the one you received in your confirmation email.</b><BR>
|
789 |
+
If this problem persists, please contact us at <a href='mailto:support@shortpixel.com?Subject=API Key issues' target='_top'>support@shortpixel.com</a> or <a href='https://shortpixel.com/contact' target='_blank'>here</a>.");
|
790 |
+
}
|
791 |
+
else
|
792 |
+
{
|
793 |
+
$validityData = $this->getQuotaInformation($_POST['key'], true);
|
794 |
+
|
795 |
+
$this->_apiKey = $_POST['key'];
|
796 |
+
$this->_apiInterface->setApiKey($this->_apiKey);
|
797 |
+
update_option('wp-short-pixel-apiKey', $_POST['key']);
|
798 |
+
if($validityData['APIKeyValid']) {
|
799 |
+
if(isset($_POST['validate'])) {
|
800 |
+
//display notification
|
801 |
+
if(in_array($_SERVER["SERVER_ADDR"], array("127.0.0.1","::1"))) {
|
802 |
+
printf($noticeHTML, '#FFC800', "API Key is valid but your server seems to have a local address.
|
803 |
+
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.");
|
804 |
+
} else {
|
805 |
+
|
806 |
+
if ( function_exists("is_multisite") && is_multisite() )
|
807 |
+
printf($noticeHTML, '#7ad03a', "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->_apiKey."');</b>");
|
808 |
+
else
|
809 |
+
printf($noticeHTML, '#7ad03a', 'API Key valid!');
|
810 |
+
}
|
811 |
+
}
|
812 |
+
update_option('wp-short-pixel-verifiedKey', true);
|
813 |
+
$this->_verifiedKey = true;
|
814 |
+
//test that the "uploads" have the right rights and also we can create the backup dir for ShortPixel
|
815 |
+
if ( !file_exists(SP_BACKUP_FOLDER) && !@mkdir(SP_BACKUP_FOLDER, 0777, true) )
|
816 |
+
printf($noticeHTML, '#ff0000', "There is something preventing us to create a new folder for backing up your original files.<BR>
|
817 |
+
Please make sure that folder <b>" .
|
818 |
+
WP_CONTENT_DIR . DIRECTORY_SEPARATOR . "uploads</b> has the necessary write and read rights." );
|
819 |
+
} else {
|
820 |
+
if(isset($_POST['validate'])) {
|
821 |
+
//display notification
|
822 |
+
printf($noticeHTML, '#ff0000', $validityData["Message"]);
|
823 |
+
}
|
824 |
+
update_option('wp-short-pixel-verifiedKey', false);
|
825 |
+
$this->_verifiedKey = false;
|
826 |
+
}
|
827 |
+
}
|
828 |
+
|
829 |
+
|
830 |
+
//if save button - we process the rest of the form elements
|
831 |
+
if(isset($_POST['submit'])) {
|
832 |
+
update_option('wp-short-pixel-compression', $_POST['compressionType']);
|
833 |
+
$this->_compressionType = $_POST['compressionType'];
|
834 |
+
$this->_apiInterface->setCompressionType($this->_compressionType);
|
835 |
+
if(isset($_POST['thumbnails'])) { $this->_processThumbnails = 1; } else { $this->_processThumbnails = 0; }
|
836 |
+
if(isset($_POST['backupImages'])) { $this->_backupImages = 1; } else { $this->_backupImages = 0; }
|
837 |
+
if(isset($_POST['cmyk2rgb'])) { $this->_CMYKtoRGBconversion = 1; } else { $this->_CMYKtoRGBconversion = 0; }
|
838 |
+
update_option('wp-short-process_thumbnails', $this->_processThumbnails);
|
839 |
+
update_option('wp-short-backup_images', $this->_backupImages);
|
840 |
+
update_option('wp-short-pixel_cmyk2rgb', $this->_CMYKtoRGBconversion);
|
841 |
+
}
|
842 |
+
}
|
843 |
+
|
844 |
+
|
845 |
+
//empty backup
|
846 |
+
if(isset($_POST['emptyBackup'])) {
|
847 |
+
$this->emptyBackup();
|
848 |
+
}
|
849 |
+
|
850 |
+
$checked = '';
|
851 |
+
if($this->_processThumbnails) { $checked = 'checked'; }
|
852 |
+
|
853 |
+
$checkedBackupImages = '';
|
854 |
+
if($this->_backupImages) { $checkedBackupImages = 'checked'; }
|
855 |
+
|
856 |
+
$cmyk2rgb = '';
|
857 |
+
if($this->_CMYKtoRGBconversion) { $cmyk2rgb = 'checked'; }
|
858 |
+
|
859 |
+
|
860 |
+
$formHTML = <<< HTML
|
861 |
+
<form name='wp_shortpixel_options' action='' method='post' id='wp_shortpixel_options'>
|
862 |
+
<table class="form-table">
|
863 |
+
<tbody><tr>
|
864 |
+
<th scope="row"><label for="key">API Key:</label></th>
|
865 |
+
<td><input name="key" type="text" id="key" value="{$this->_apiKey}" class="regular-text">
|
866 |
+
<input type="submit" name="validate" id="validate" class="button button-primary" title="Validate the provided API key" value="Validate">
|
867 |
+
</td>
|
868 |
+
</tr>
|
869 |
+
HTML;
|
870 |
+
|
871 |
+
if(!$this->_verifiedKey) {
|
872 |
+
|
873 |
+
//if invalid key we display the link to the API Key
|
874 |
+
$formHTML .= '<tr><td style="padding-left: 0px;" colspan="2">Don’t have an API Key? <a href="https://shortpixel.com/wp-apikey" target="_blank">Sign up, it’s free.</a></td></tr>';
|
875 |
+
$formHTML .= '</form>';
|
876 |
+
} else {
|
877 |
+
//if valid key we display the rest of the options
|
878 |
+
$formHTML .= <<< HTML
|
879 |
+
<tr><th scope="row">
|
880 |
+
<label for="compressionType">Compression type:</label>
|
881 |
+
</th><td>
|
882 |
+
HTML;
|
883 |
+
|
884 |
+
if($this->_compressionType == 1) {
|
885 |
+
$formHTML .= '<input type="radio" name="compressionType" value="1" checked>Lossy</br></br>';
|
886 |
+
$formHTML .= '<input type="radio" name="compressionType" value="0" >Lossless';
|
887 |
+
} else {
|
888 |
+
$formHTML .= '<input type="radio" name="compressionType" value="1">Lossy</br></br>';
|
889 |
+
$formHTML .= '<input type="radio" name="compressionType" value="0" checked>Lossless';
|
890 |
+
}
|
891 |
+
|
892 |
+
$formHTML .= <<<HTML
|
893 |
+
</td>
|
894 |
+
</tr>
|
895 |
+
</tbody></table>
|
896 |
+
<p style="color: #818181;">
|
897 |
+
<b>Lossy compression: </b>lossy has a better compression rate than lossless compression.</br>The resulting image
|
898 |
+
is not 100% identical with the original. Works well for photos taken with your camera.</br></br>
|
899 |
+
<b>Lossless compression: </b> the shrunk image will be identical with the original and smaller in size.</br>Use this
|
900 |
+
when you do not want to lose any of the original image's details. Works best for technical drawings,
|
901 |
+
clip art and comics.
|
902 |
+
</p>
|
903 |
+
<table class="form-table">
|
904 |
+
<tbody><tr>
|
905 |
+
<th scope="row"><label for="thumbnails">Image thumbnails:</label></th>
|
906 |
+
<td><input name="thumbnails" type="checkbox" id="thumbnails" {$checked}> Apply compression also to image thumbnails.</td>
|
907 |
+
</tr>
|
908 |
+
<tr>
|
909 |
+
<th scope="row"><label for="backupImages">Image backup</label></th>
|
910 |
+
<td>
|
911 |
+
<input name="backupImages" type="checkbox" id="backupImages" {$checkedBackupImages}> Save and keep a backup of your original images in a separate folder.
|
912 |
+
</td>
|
913 |
+
</tr>
|
914 |
+
<tr>
|
915 |
+
<th scope="row"><label for="backupImages">CMYK to RGB conversion</label></th>
|
916 |
+
<td>
|
917 |
+
<input name="cmyk2rgb" type="checkbox" id="cmyk2rgb" {$cmyk2rgb}>Adjust your images for computer and mobile screen display.
|
918 |
+
</td>
|
919 |
+
</tr>
|
920 |
+
</tr>
|
921 |
+
</tbody></table>
|
922 |
+
<p class="submit">
|
923 |
+
<input type="submit" name="submit" id="submit" class="button button-primary" title="Save Changes" value="Save Changes">
|
924 |
+
<a class="button button-primary" title="Process all the images in your Media Library" href="upload.php?page=wp-short-pixel-bulk">Bulk Process</a>
|
925 |
+
</p>
|
926 |
+
</form>
|
927 |
+
<script>
|
928 |
+
var rad = document.wp_shortpixel_options.compressionType;
|
929 |
+
var prev = null;
|
930 |
+
for(var i = 0; i < rad.length; i++) {
|
931 |
+
rad[i].onclick = function() {
|
932 |
+
|
933 |
+
if(this !== prev) {
|
934 |
+
prev = this;
|
935 |
+
}
|
936 |
+
alert('This type of optimization will apply to new uploaded images. <BR>Images that were already processed will not be re-optimized.');
|
937 |
+
};
|
938 |
+
}
|
939 |
+
</script>
|
940 |
+
HTML;
|
941 |
+
}
|
942 |
+
|
943 |
+
echo $formHTML;
|
944 |
+
|
945 |
+
if($this->_verifiedKey) {
|
946 |
+
$fileCount = number_format(get_option('wp-short-pixel-fileCount'));
|
947 |
+
$savedSpace = self::formatBytes(get_option('wp-short-pixel-savedSpace'),2);
|
948 |
+
$averageCompression = self::getAverageCompression();
|
949 |
+
$savedBandwidth = self::formatBytes(get_option('wp-short-pixel-savedSpace') * 10000,2);
|
950 |
+
if (is_numeric($quotaData['APICallsQuota'])) {
|
951 |
+
$quotaData['APICallsQuota'] .= "/month";
|
952 |
+
}
|
953 |
+
$backupFolderSize = self::formatBytes(self::folderSize(SP_BACKUP_FOLDER));
|
954 |
+
$remainingImages = $quotaData['APICallsQuotaNumeric'] + $quotaData['APICallsQuotaOneTimeNumeric'] - $quotaData['APICallsMadeNumeric'] - $quotaData['APICallsMadeOneTimeNumeric'];
|
955 |
+
$remainingImages = ( $remainingImages < 0 ) ? 0 : number_format($remainingImages);
|
956 |
+
$totalCallsMade = number_format($quotaData['APICallsMadeNumeric'] + $quotaData['APICallsMadeOneTimeNumeric']);
|
957 |
+
|
958 |
+
$statHTML = <<< HTML
|
959 |
+
<a id="facts"></a>
|
960 |
+
<h3>Your ShortPixel Stats</h3>
|
961 |
+
<table class="form-table">
|
962 |
+
<tbody>
|
963 |
+
<tr>
|
964 |
+
<th scope="row"><label for="averagCompression">Average compression of your files:</label></th>
|
965 |
+
<td>$averageCompression%</td>
|
966 |
+
</tr>
|
967 |
+
<tr>
|
968 |
+
<th scope="row"><label for="savedSpace">Saved disk space by ShortPixel</label></th>
|
969 |
+
<td>$savedSpace</td>
|
970 |
+
</tr>
|
971 |
+
<tr>
|
972 |
+
<th scope="row"><label for="savedBandwidth">Bandwith* saved with ShortPixel:</label></th>
|
973 |
+
<td>$savedBandwidth</td>
|
974 |
+
</tr>
|
975 |
+
</tbody></table>
|
976 |
+
|
977 |
+
<p style="padding-top: 0px; color: #818181;" >* Saved bandwidth is calculated at 10,000 impressions/image</p>
|
978 |
+
|
979 |
+
<h3>Your ShortPixel Plan</h3>
|
980 |
+
<table class="form-table">
|
981 |
+
<tbody>
|
982 |
+
<tr>
|
983 |
+
<th scope="row" bgcolor="#ffffff"><label for="apiQuota">Your ShortPixel plan</label></th>
|
984 |
+
<td bgcolor="#ffffff">{$quotaData['APICallsQuota']}/month ( <a href="https://shortpixel.com/login/{$this->_apiKey}" target="_blank">Need More? See the options available</a> )
|
985 |
+
</tr>
|
986 |
+
<tr>
|
987 |
+
<th scope="row"><label for="usedQUota">One time credits:</label></th>
|
988 |
+
<td>{$quotaData['APICallsQuotaOneTimeNumeric']}</td>
|
989 |
+
</tr>
|
990 |
+
<tr>
|
991 |
+
<th scope="row"><label for="usedQUota">Number of images processed this month:</label></th>
|
992 |
+
<td>{$totalCallsMade} (<a href="https://api.shortpixel.com/v2/report.php?key={$this->_apiKey}" target="_blank">see report</a>)</td>
|
993 |
+
</tr>
|
994 |
+
<tr>
|
995 |
+
<th scope="row"><label for="remainingImages">Remaining** images in your plan: </label></th>
|
996 |
+
<td>{$remainingImages} images</td>
|
997 |
+
</tr>
|
998 |
+
</tbody></table>
|
999 |
+
|
1000 |
+
<p style="padding-top: 0px; color: #818181;" >** Increase your image quota by <a href="https://shortpixel.com/login/{$this->_apiKey}" target="_blank">upgrading</a> your ShortPixel plan.</p>
|
1001 |
+
|
1002 |
+
<table class="form-table">
|
1003 |
+
<tbody>
|
1004 |
+
<tr>
|
1005 |
+
<th scope="row"><label for="totalFiles">Total number of processed files:</label></th>
|
1006 |
+
<td>{$fileCount}</td>
|
1007 |
+
</tr>
|
1008 |
+
|
1009 |
+
|
1010 |
+
|
1011 |
+
HTML;
|
1012 |
+
if($this->_backupImages) {
|
1013 |
+
$statHTML .= <<< HTML
|
1014 |
+
<form action="" method="POST">
|
1015 |
+
<tr>
|
1016 |
+
<th scope="row"><label for="sizeBackup">Original images are stored in a backup folder. Your backup folder size is now:</label></th>
|
1017 |
+
<td>
|
1018 |
+
{$backupFolderSize}
|
1019 |
+
<input type="submit" style="margin-left: 15px; vertical-align: middle;" class="button button-secondary" name="emptyBackup" value="Empty backups"/>
|
1020 |
+
</td>
|
1021 |
+
</tr>
|
1022 |
+
</form>
|
1023 |
+
HTML;
|
1024 |
+
}
|
1025 |
+
|
1026 |
+
$statHTML .= <<< HTML
|
1027 |
+
</tbody></table>
|
1028 |
+
HTML;
|
1029 |
+
|
1030 |
+
echo $statHTML;
|
1031 |
+
|
1032 |
+
|
1033 |
+
}
|
1034 |
+
|
1035 |
+
}
|
1036 |
+
|
1037 |
+
public function getAverageCompression(){
|
1038 |
+
return get_option('wp-short-pixel-total-optimized') > 0
|
1039 |
+
? round(( 1 - ( get_option('wp-short-pixel-total-optimized') / get_option('wp-short-pixel-total-original') ) ) * 100, 2)
|
1040 |
+
: 0;
|
1041 |
+
}
|
1042 |
+
|
1043 |
+
public function getQuotaInformation($apiKey = null, $appendUserAgent = false) {
|
1044 |
+
|
1045 |
+
if(is_null($apiKey)) { $apiKey = $this->_apiKey; }
|
1046 |
+
|
1047 |
+
$requestURL = 'https://api.shortpixel.com/v2/api-status.php';
|
1048 |
+
$args = array('timeout'=> SP_MAX_TIMEOUT,
|
1049 |
+
'sslverify' => false,
|
1050 |
+
'body' => array('key' => $apiKey)
|
1051 |
+
);
|
1052 |
+
|
1053 |
+
if($appendUserAgent) {
|
1054 |
+
$args['body']['useragent'] = "Agent" . urlencode($_SERVER['HTTP_USER_AGENT']);
|
1055 |
+
}
|
1056 |
+
$response = wp_remote_post($requestURL, $args);
|
1057 |
+
|
1058 |
+
if(is_wp_error( $response )) //some hosting providers won't allow https:// POST connections so we try http:// as well
|
1059 |
+
$response = wp_remote_post(str_replace('https://', 'http://', $requestURL), $args);
|
1060 |
+
|
1061 |
+
if(is_wp_error( $response ))
|
1062 |
+
$response = wp_remote_get(str_replace('https://', 'http://', $requestURL), $args);
|
1063 |
+
|
1064 |
+
$defaultData = array(
|
1065 |
+
"APIKeyValid" => false,
|
1066 |
+
"Message" => 'API Key could not be validated due to a connectivity error.<BR>Your firewall may be blocking us. Please contact your hosting provider and ask them to allow connections from your site to IP 176.9.106.46.<BR> If you still cannot validate your API Key after this, please <a href="https://shortpixel.com/contact" target="_blank">contact us</a> and we will try to help. ',
|
1067 |
+
"APICallsMade" => 'Information unavailable. Please check your API key.',
|
1068 |
+
"APICallsQuota" => 'Information unavailable. Please check your API key.');
|
1069 |
+
|
1070 |
+
if(is_object($response) && get_class($response) == 'WP_Error') {
|
1071 |
+
|
1072 |
+
$urlElements = parse_url($requestURL);
|
1073 |
+
$portConnect = @fsockopen($urlElements['host'],8,$errno,$errstr,15);
|
1074 |
+
if(!$portConnect)
|
1075 |
+
$defaultData['Message'] .= "<BR>Debug info: <i>$errstr</i>";
|
1076 |
+
|
1077 |
+
return $defaultData;
|
1078 |
+
}
|
1079 |
+
|
1080 |
+
if($response['response']['code'] != 200) {
|
1081 |
+
return $defaultData;
|
1082 |
+
}
|
1083 |
+
|
1084 |
+
$data = $response['body'];
|
1085 |
+
$data = $this->parseJSON($data);
|
1086 |
+
|
1087 |
+
if(empty($data)) { return $defaultData; }
|
1088 |
+
|
1089 |
+
if($data->Status->Code != 2) {
|
1090 |
+
$defaultData['Message'] = $data->Status->Message;
|
1091 |
+
return $defaultData;
|
1092 |
+
}
|
1093 |
+
|
1094 |
+
if ( ( $data->APICallsMade + $data->APICallsMadeOneTime ) < ( $data->APICallsQuota + $data->APICallsQuotaOneTime ) ) //reset quota exceeded flag -> user is allowed to process more images.
|
1095 |
+
update_option('wp-short-pixel-quota-exceeded',0);
|
1096 |
+
else
|
1097 |
+
update_option('wp-short-pixel-quota-exceeded',1);//activate quota limiting
|
1098 |
+
|
1099 |
+
return array(
|
1100 |
+
"APIKeyValid" => true,
|
1101 |
+
"APICallsMade" => number_format($data->APICallsMade) . ' images',
|
1102 |
+
"APICallsQuota" => number_format($data->APICallsQuota) . ' images',
|
1103 |
+
"APICallsMadeOneTime" => number_format($data->APICallsMadeOneTime) . ' images',
|
1104 |
+
"APICallsQuotaOneTime" => number_format($data->APICallsQuotaOneTime) . ' images',
|
1105 |
+
"APICallsMadeNumeric" => $data->APICallsMade,
|
1106 |
+
"APICallsQuotaNumeric" => $data->APICallsQuota,
|
1107 |
+
"APICallsMadeOneTimeNumeric" => $data->APICallsMadeOneTime,
|
1108 |
+
"APICallsQuotaOneTimeNumeric" => $data->APICallsQuotaOneTime
|
1109 |
+
);
|
1110 |
+
|
1111 |
+
|
1112 |
+
}
|
1113 |
+
|
1114 |
+
public function generateCustomColumn( $column_name, $id ) {
|
1115 |
+
if( 'wp-shortPixel' == $column_name ) {
|
1116 |
+
$data = wp_get_attachment_metadata($id);
|
1117 |
+
$file = get_attached_file($id);
|
1118 |
+
$fileExtension = strtolower(substr($file,strrpos($file,".")+1));
|
1119 |
+
|
1120 |
+
print "<div id='sp-msg-{$id}'>";
|
1121 |
+
|
1122 |
+
if ( empty($data) )
|
1123 |
+
{
|
1124 |
+
if ( $fileExtension <> "pdf" )
|
1125 |
+
{
|
1126 |
+
if(!$this->_verifiedKey)
|
1127 |
+
print 'Invalid API Key. <a href="options-general.php?page=wp-shortpixel">Check your Settings</a>';
|
1128 |
+
else
|
1129 |
+
print 'Optimization N/A';
|
1130 |
+
}
|
1131 |
+
else
|
1132 |
+
{
|
1133 |
+
if ( get_option('wp-short-pixel-quota-exceeded') )
|
1134 |
+
{
|
1135 |
+
print QUOTA_EXCEEDED;
|
1136 |
+
return;
|
1137 |
+
}
|
1138 |
+
else
|
1139 |
+
{
|
1140 |
+
print 'PDF not processed';
|
1141 |
+
print " | <a href=\"javascript:manualOptimization({$id})\">Optimize now</a>";
|
1142 |
+
return;
|
1143 |
+
}
|
1144 |
+
}
|
1145 |
+
}
|
1146 |
+
elseif ( isset( $data['ShortPixelImprovement'] ) )
|
1147 |
+
{
|
1148 |
+
if(isset($meta['ShortPixel']['BulkProcessing']))
|
1149 |
+
{
|
1150 |
+
if ( get_option('wp-short-pixel-quota-exceeded') )
|
1151 |
+
{
|
1152 |
+
print QUOTA_EXCEEDED;
|
1153 |
+
}
|
1154 |
+
else
|
1155 |
+
{
|
1156 |
+
print 'Waiting for bulk processing';
|
1157 |
+
print " | <a href=\"javascript:manualOptimization({$id})\">Optimize now</a>";
|
1158 |
+
}
|
1159 |
+
}
|
1160 |
+
elseif( is_numeric($data['ShortPixelImprovement']) && !isset($data['ShortPixel']['NoBackup']) ) {
|
1161 |
+
|
1162 |
+
if ( $data['ShortPixelImprovement'] < 5 )
|
1163 |
+
{
|
1164 |
+
print $data['ShortPixelImprovement'] . '%';
|
1165 |
+
print " optimized<BR> Bonus processing";
|
1166 |
+
|
1167 |
+
}
|
1168 |
+
else
|
1169 |
+
{
|
1170 |
+
print 'Reduced by ';
|
1171 |
+
print $data['ShortPixelImprovement'] . '%';
|
1172 |
+
}
|
1173 |
+
if ( get_option('wp-short-backup_images') ) //display restore backup option only when backup is active
|
1174 |
+
print " | <a href=\"admin.php?action=shortpixel_restore_backup&attachment_ID={$id}\">Restore backup</a>";
|
1175 |
+
}
|
1176 |
+
elseif ( is_numeric($data['ShortPixelImprovement']) )
|
1177 |
+
{
|
1178 |
+
if ( $data['ShortPixelImprovement'] < 5 )
|
1179 |
+
{
|
1180 |
+
print $data['ShortPixelImprovement'] . '%';
|
1181 |
+
print " optimized<BR> Bonus processing";
|
1182 |
+
|
1183 |
+
}
|
1184 |
+
else
|
1185 |
+
{
|
1186 |
+
print 'Reduced by ';
|
1187 |
+
print $data['ShortPixelImprovement'] . '%';
|
1188 |
+
}
|
1189 |
+
}
|
1190 |
+
elseif ( $data['ShortPixelImprovement'] <> "Optimization N/A" )
|
1191 |
+
{
|
1192 |
+
if ( trim(strip_tags($data['ShortPixelImprovement'])) == "Quota exceeded" )
|
1193 |
+
{
|
1194 |
+
print QUOTA_EXCEEDED;
|
1195 |
+
if ( !get_option('wp-short-pixel-quota-exceeded') )
|
1196 |
+
print " | <a href=\"javascript:manualOptimization({$id})\">Try again</a>";
|
1197 |
+
}
|
1198 |
+
elseif ( trim(strip_tags($data['ShortPixelImprovement'])) == "Cannot write optimized file" )
|
1199 |
+
{
|
1200 |
+
print $data['ShortPixelImprovement'];
|
1201 |
+
print " - <a href='https://shortpixel.com/faq#cannot-write-optimized-file' target='_blank'>Why?</a>";
|
1202 |
+
}
|
1203 |
+
else
|
1204 |
+
{
|
1205 |
+
print $data['ShortPixelImprovement'];
|
1206 |
+
print " | <a href=\"javascript:manualOptimization({$id})\">Try again</a>";
|
1207 |
+
}
|
1208 |
+
}
|
1209 |
+
else
|
1210 |
+
{
|
1211 |
+
print "Optimization N/A";
|
1212 |
+
}
|
1213 |
+
} elseif(isset($data['ShortPixel']['WaitingProcessing'])) {
|
1214 |
+
if ( get_option('wp-short-pixel-quota-exceeded') )
|
1215 |
+
{
|
1216 |
+
print QUOTA_EXCEEDED;
|
1217 |
+
}
|
1218 |
+
else
|
1219 |
+
{
|
1220 |
+
print "<img src=\"" . WP_PLUGIN_URL . "/shortpixel-image-optimiser/img/loading.gif\">Image waiting to be processed
|
1221 |
+
| <a href=\"javascript:manualOptimization({$id})\">Retry</a></div>";
|
1222 |
+
$this->prioQ->push($id); //should be there but just to make sure
|
1223 |
+
}
|
1224 |
+
|
1225 |
+
} elseif(isset($data['ShortPixel']['NoFileOnDisk'])) {
|
1226 |
+
print 'Image does not exist';
|
1227 |
+
|
1228 |
+
} else {
|
1229 |
+
|
1230 |
+
if ( wp_attachment_is_image( $id ) )
|
1231 |
+
{
|
1232 |
+
if ( get_option('wp-short-pixel-quota-exceeded') )
|
1233 |
+
{
|
1234 |
+
print QUOTA_EXCEEDED;
|
1235 |
+
}
|
1236 |
+
else
|
1237 |
+
{
|
1238 |
+
print 'Image not processed';
|
1239 |
+
print " | <a href=\"javascript:manualOptimization({$id})\">Optimize now</a>";
|
1240 |
+
}
|
1241 |
+
}
|
1242 |
+
elseif ( $fileExtension == "pdf" )
|
1243 |
+
{
|
1244 |
+
if ( get_option('wp-short-pixel-quota-exceeded') )
|
1245 |
+
{
|
1246 |
+
print QUOTA_EXCEEDED;
|
1247 |
+
}
|
1248 |
+
else
|
1249 |
+
{
|
1250 |
+
print 'PDF not processed';
|
1251 |
+
print " | <a href=\"javascript:manualOptimization({$id})\">Optimize now</a>";
|
1252 |
+
}
|
1253 |
+
}
|
1254 |
+
}
|
1255 |
+
print "</div>";
|
1256 |
+
}
|
1257 |
+
}
|
1258 |
+
|
1259 |
+
public function columns( $defaults ) {
|
1260 |
+
$defaults['wp-shortPixel'] = 'ShortPixel Compression';
|
1261 |
+
return $defaults;
|
1262 |
+
}
|
1263 |
+
|
1264 |
+
public function generatePluginLinks($links) {
|
1265 |
+
$in = '<a href="options-general.php?page=wp-shortpixel">Settings</a>';
|
1266 |
+
array_unshift($links, $in);
|
1267 |
+
return $links;
|
1268 |
+
}
|
1269 |
+
|
1270 |
+
public function parseJSON($data) {
|
1271 |
+
if ( function_exists('json_decode') ) {
|
1272 |
+
$data = json_decode( $data );
|
1273 |
+
} else {
|
1274 |
+
require_once( 'JSON/JSON.php' );
|
1275 |
+
$json = new Services_JSON( );
|
1276 |
+
$data = $json->decode( $data );
|
1277 |
+
}
|
1278 |
+
return $data;
|
1279 |
+
}
|
1280 |
+
|
1281 |
+
|
1282 |
+
static public function formatBytes($bytes, $precision = 2) {
|
1283 |
+
$units = array('B', 'KB', 'MB', 'GB', 'TB');
|
1284 |
+
|
1285 |
+
$bytes = max($bytes, 0);
|
1286 |
+
$pow = floor(($bytes ? log($bytes) : 0) / log(1024));
|
1287 |
+
$pow = min($pow, count($units) - 1);
|
1288 |
+
|
1289 |
+
$bytes /= pow(1024, $pow);
|
1290 |
+
|
1291 |
+
return round($bytes, $precision) . ' ' . $units[$pow];
|
1292 |
+
}
|
1293 |
+
|
1294 |
+
static public function isProcessable($ID) {
|
1295 |
+
$path = get_attached_file($ID);//get the full file PATH
|
1296 |
+
$pathParts = pathinfo($path);
|
1297 |
+
if( isset($pathParts['extension']) && in_array(strtolower($pathParts['extension']), array('jpg', 'jpeg', 'gif', 'png', 'pdf'))) {
|
1298 |
+
return true;
|
1299 |
+
} else {
|
1300 |
+
return false;
|
1301 |
+
}
|
1302 |
+
}
|
1303 |
+
|
1304 |
+
|
1305 |
+
//return an array with URL(s) and PATH(s) for this file
|
1306 |
+
public function getURLsAndPATHs($ID, $meta = NULL) {
|
1307 |
+
|
1308 |
+
if ( !parse_url(WP_CONTENT_URL, PHP_URL_SCHEME) )
|
1309 |
+
{//no absolute URLs used -> we implement a hack
|
1310 |
+
$url = get_site_url() . wp_get_attachment_url($ID);//get the file URL
|
1311 |
+
}
|
1312 |
+
else
|
1313 |
+
$url = wp_get_attachment_url($ID);//get the file URL
|
1314 |
+
|
1315 |
+
$urlList[] = $url;
|
1316 |
+
$path = get_attached_file($ID);//get the full file PATH
|
1317 |
+
$filePath[] = $path;
|
1318 |
+
if ( $meta == NULL ) {
|
1319 |
+
$meta = wp_get_attachment_metadata($ID);
|
1320 |
+
}
|
1321 |
+
|
1322 |
+
//it is NOT a PDF file and thumbs are processable
|
1323 |
+
if ( strtolower(substr($filePath[0],strrpos($filePath[0], ".")+1)) != "pdf"
|
1324 |
+
&& $this->_processThumbnails
|
1325 |
+
&& isset($meta['sizes']) && is_array($meta['sizes']))
|
1326 |
+
{
|
1327 |
+
foreach( $meta['sizes'] as $thumbnailInfo )
|
1328 |
+
{
|
1329 |
+
$urlList[] = str_replace(ShortPixelAPI::MB_basename($urlList[0]), $thumbnailInfo['file'], $url);
|
1330 |
+
$filePath[] = str_replace(ShortPixelAPI::MB_basename($filePath[0]), $thumbnailInfo['file'], $path);
|
1331 |
+
}
|
1332 |
+
}
|
1333 |
+
if(!isset($meta['sizes']) || !is_array($meta['sizes'])) {
|
1334 |
+
self::log("getURLsAndPATHs: no meta sizes for ID $ID : " . json_encode($meta));
|
1335 |
+
}
|
1336 |
+
return array("URLs" => $urlList, "PATHs" => $filePath);
|
1337 |
+
}
|
1338 |
+
|
1339 |
+
|
1340 |
+
public static function deleteDir($dirPath) {
|
1341 |
+
if (substr($dirPath, strlen($dirPath) - 1, 1) !=
|
1342 |
+
'/') {
|
1343 |
+
$dirPath .= '/';
|
1344 |
+
}
|
1345 |
+
$files = glob($dirPath . '*', GLOB_MARK);
|
1346 |
+
foreach ($files as $file) {
|
1347 |
+
if (is_dir($file)) {
|
1348 |
+
self::deleteDir($file);
|
1349 |
+
@rmdir($file);//remove empty dir
|
1350 |
+
} else {
|
1351 |
+
@unlink($file);//remove file
|
1352 |
+
}
|
1353 |
+
}
|
1354 |
+
}
|
1355 |
+
|
1356 |
+
static public function folderSize($path) {
|
1357 |
+
$total_size = 0;
|
1358 |
+
if(file_exists($path)) {
|
1359 |
+
$files = scandir($path);
|
1360 |
+
} else {
|
1361 |
+
return $total_size;
|
1362 |
+
}
|
1363 |
+
$cleanPath = rtrim($path, '/'). '/';
|
1364 |
+
foreach($files as $t) {
|
1365 |
+
if ($t<>"." && $t<>"..")
|
1366 |
+
{
|
1367 |
+
$currentFile = $cleanPath . $t;
|
1368 |
+
if (is_dir($currentFile)) {
|
1369 |
+
$size = self::folderSize($currentFile);
|
1370 |
+
$total_size += $size;
|
1371 |
+
}
|
1372 |
+
else {
|
1373 |
+
$size = filesize($currentFile);
|
1374 |
+
$total_size += $size;
|
1375 |
+
}
|
1376 |
+
}
|
1377 |
+
}
|
1378 |
+
return $total_size;
|
1379 |
+
}
|
1380 |
+
|
1381 |
+
public function getMaxMediaId() {
|
1382 |
+
global $wpdb;
|
1383 |
+
$queryMax = "SELECT max(post_id) as QueryID FROM " . $wpdb->prefix . "postmeta";
|
1384 |
+
$resultQuery = $wpdb->get_results($queryMax);
|
1385 |
+
return $resultQuery[0]->QueryID;
|
1386 |
+
}
|
1387 |
+
|
1388 |
+
public function getMinMediaId() {
|
1389 |
+
global $wpdb;
|
1390 |
+
$queryMax = "SELECT min(post_id) as QueryID FROM " . $wpdb->prefix . "postmeta";
|
1391 |
+
$resultQuery = $wpdb->get_results($queryMax);
|
1392 |
+
return $resultQuery[0]->QueryID;
|
1393 |
+
}
|
1394 |
+
|
1395 |
+
//count all the processable files in media library (while limiting the results to max 10000)
|
1396 |
+
public function countAllProcessableFiles($maxId = PHP_INT_MAX, $minId = 0){
|
1397 |
+
global $wpdb;
|
1398 |
+
|
1399 |
+
$totalFiles = 0;
|
1400 |
+
$mainFiles = 0;
|
1401 |
+
$limit = 500;
|
1402 |
+
$pointer = 0;
|
1403 |
+
|
1404 |
+
//count all the files, main and thumbs
|
1405 |
+
while ( 1 )
|
1406 |
+
{
|
1407 |
+
$filesList= $wpdb->get_results("SELECT * FROM " . $wpdb->prefix . "postmeta
|
1408 |
+
WHERE ( post_id <= $maxId AND post_id > $minId )
|
1409 |
+
AND ( meta_key = '_wp_attached_file' OR meta_key = '_wp_attachment_metadata' )
|
1410 |
+
LIMIT $pointer,$limit");
|
1411 |
+
if ( empty($filesList) ) //we parsed all the results
|
1412 |
+
break;
|
1413 |
+
|
1414 |
+
foreach ( $filesList as $file )
|
1415 |
+
{
|
1416 |
+
if ( $file->meta_key == "_wp_attached_file" )
|
1417 |
+
{//count pdf files only
|
1418 |
+
$extension = substr($file->meta_value, strrpos($file->meta_value,".") + 1 );
|
1419 |
+
if ( $extension == "pdf" )
|
1420 |
+
{
|
1421 |
+
$totalFiles++;
|
1422 |
+
$mainFiles++;
|
1423 |
+
}
|
1424 |
+
}
|
1425 |
+
else
|
1426 |
+
{
|
1427 |
+
$attachment = unserialize($file->meta_value);
|
1428 |
+
if ( isset($attachment['sizes']) )
|
1429 |
+
$totalFiles += count($attachment['sizes']);
|
1430 |
+
|
1431 |
+
if ( isset($attachment['file']) )
|
1432 |
+
{
|
1433 |
+
$totalFiles++;
|
1434 |
+
$mainFiles++;
|
1435 |
+
}
|
1436 |
+
}
|
1437 |
+
}
|
1438 |
+
unset($filesList);
|
1439 |
+
$pointer += $limit;
|
1440 |
+
|
1441 |
+
}//end while
|
1442 |
+
|
1443 |
+
return array("totalFiles" => $totalFiles, "mainFiles" => $mainFiles);
|
1444 |
+
}
|
1445 |
+
|
1446 |
+
|
1447 |
+
//count all the processable files in media library (while limiting the results to max 10000)
|
1448 |
+
public function countAllProcessedFiles($maxId = PHP_INT_MAX, $minId = 0){
|
1449 |
+
global $wpdb;
|
1450 |
+
|
1451 |
+
$processedMainFiles = $processedTotalFiles = 0;
|
1452 |
+
$limit = 500;
|
1453 |
+
$pointer = 0;
|
1454 |
+
|
1455 |
+
//count all the files, main and thumbs
|
1456 |
+
while ( 1 )
|
1457 |
+
{
|
1458 |
+
$filesList= $wpdb->get_results("SELECT * FROM " . $wpdb->prefix . "postmeta
|
1459 |
+
WHERE ( post_id <= $maxId AND post_id > $minId )
|
1460 |
+
AND ( meta_key = '_wp_attached_file' OR meta_key = '_wp_attachment_metadata' )
|
1461 |
+
LIMIT $pointer,$limit");
|
1462 |
+
if ( empty($filesList) ) {//we parsed all the results
|
1463 |
+
break;
|
1464 |
+
}
|
1465 |
+
foreach ( $filesList as $file )
|
1466 |
+
{
|
1467 |
+
if ( $file->meta_key == "_wp_attached_file" ) {
|
1468 |
+
continue;
|
1469 |
+
}
|
1470 |
+
$attachment = unserialize($file->meta_value);
|
1471 |
+
if ( isset($attachment['ShortPixelImprovement']) && $attachment['ShortPixelImprovement'] > 0 ) {
|
1472 |
+
$processedMainFiles++;
|
1473 |
+
$processedTotalFiles++;
|
1474 |
+
if ( isset($attachment['sizes']) ) {
|
1475 |
+
$processedTotalFiles += count($attachment['sizes']);
|
1476 |
+
}
|
1477 |
+
}
|
1478 |
+
}
|
1479 |
+
unset($filesList);
|
1480 |
+
$pointer += $limit;
|
1481 |
+
|
1482 |
+
}//end while
|
1483 |
+
|
1484 |
+
return array("totalFiles" => $processedTotalFiles, "mainFiles" => $processedMainFiles);
|
1485 |
+
}
|
1486 |
+
|
1487 |
+
public function migrateBackupFolder() {
|
1488 |
+
$oldBackupFolder = WP_CONTENT_DIR . DIRECTORY_SEPARATOR . 'ShortpixelBackups';
|
1489 |
+
|
1490 |
+
if(!file_exists($oldBackupFolder)) return; //if old backup folder does not exist then there is nothing to do
|
1491 |
+
|
1492 |
+
if(!file_exists(SP_BACKUP_FOLDER)) {
|
1493 |
+
//we check that the backup folder exists, if not we create it so we can copy into it
|
1494 |
+
if(!mkdir(SP_BACKUP_FOLDER, 0777, true)) return;
|
1495 |
+
}
|
1496 |
+
|
1497 |
+
$scannedDirectory = array_diff(scandir($oldBackupFolder), array('..', '.'));
|
1498 |
+
foreach($scannedDirectory as $file) {
|
1499 |
+
@rename($oldBackupFolder.DIRECTORY_SEPARATOR.$file, SP_BACKUP_FOLDER.DIRECTORY_SEPARATOR.$file);
|
1500 |
+
}
|
1501 |
+
$scannedDirectory = array_diff(scandir($oldBackupFolder), array('..', '.'));
|
1502 |
+
if(empty($scannedDirectory)) {
|
1503 |
+
@rmdir($oldBackupFolder);
|
1504 |
+
}
|
1505 |
+
|
1506 |
+
return;
|
1507 |
+
}
|
1508 |
+
|
1509 |
+
public function getApiKey() {
|
1510 |
+
return $this->_apiKey;
|
1511 |
+
}
|
1512 |
+
|
1513 |
+
public function backupImages() {
|
1514 |
+
return $this->_backupImages;
|
1515 |
+
}
|
1516 |
+
|
1517 |
+
public function processThumbnails() {
|
1518 |
+
return $this->_processThumbnails;
|
1519 |
+
}
|
1520 |
+
|
1521 |
+
}
|
1522 |
+
|
1523 |
+
$pluginInstance = new WPShortPixel();
|
1524 |
+
global $pluginInstance;
|
1525 |
+
|
1526 |
+
?>
|
|
|
|
|
|
|
|