Version Description
- convert PNG images to JPG option
- action called upon optimizing an image: do_action('shortpixel_image_optimized', $post_id);
- monitor Other Media folders for changes every hour
- button to delete all ShortPixel metadata making ShortPixel forget it optimized the images in Media Library
- plugin images at @2x
- cleanup Other Media tables
- fix wp-options that would not save in some circumstances
- fix generate webp
- fix problem with AMP pages when generating the
Download this release
Release Info
Developer | ShortPixel |
Plugin | ShortPixel Image Optimizer |
Version | 4.7.0 |
Comparing to | |
See all releases |
Code changes from version 4.6.0 to 4.7.0
- class/db/shortpixel-custom-meta-dao.php +5 -1
- class/db/shortpixel-meta-facade.php +24 -0
- class/db/wp-shortpixel-media-library-adapter.php +35 -13
- class/front/img-to-picture-webp.php +17 -3
- class/shortpixel_queue.php +5 -5
- class/view/shortpixel_view.php +60 -8
- class/wp-short-pixel.php +347 -61
- class/wp-shortpixel-settings.php +8 -2
- readme.txt +20 -4
- res/css/short-pixel.css +2 -1
- res/img/slider.png +0 -0
- res/img/slider@2x.png +0 -0
- res/js/short-pixel.js +39 -3
- shortpixel_api.php +2 -0
- wp-shortpixel.php +24 -4
class/db/shortpixel-custom-meta-dao.php
CHANGED
@@ -286,7 +286,11 @@ class ShortPixelCustomMetaDao {
|
|
286 |
|
287 |
public function batchInsertImages($pathsFile, $folderId) {
|
288 |
$pathsFileHandle = fopen($pathsFile, 'r');
|
289 |
-
|
|
|
|
|
|
|
|
|
290 |
$values = ''; $inserted = 0;
|
291 |
$sql = "INSERT IGNORE INTO {$this->db->getPrefix()}shortpixel_meta(folder_id, path, name, path_md5, status) VALUES ";
|
292 |
for ($i = 0; ($path = fgets($pathsFileHandle)) !== false; $i++) {
|
286 |
|
287 |
public function batchInsertImages($pathsFile, $folderId) {
|
288 |
$pathsFileHandle = fopen($pathsFile, 'r');
|
289 |
+
|
290 |
+
//facem un delete pe cele care nu au shortpixel_folder, pentru curatenie - am mai intalnit situatii in care stergerea s-a agatat (stop monitoring)
|
291 |
+
$sqlCleanup = "DELETE FROM {$this->db->getPrefix()}shortpixel_meta WHERE folder_id NOT IN (SELECT id FROM {$this->db->getPrefix()}shortpixel_folders)";
|
292 |
+
$this->db->query($sqlCleanup);
|
293 |
+
|
294 |
$values = ''; $inserted = 0;
|
295 |
$sql = "INSERT IGNORE INTO {$this->db->getPrefix()}shortpixel_meta(folder_id, path, name, path_md5, status) VALUES ";
|
296 |
for ($i = 0; ($path = fgets($pathsFileHandle)) !== false; $i++) {
|
class/db/shortpixel-meta-facade.php
CHANGED
@@ -187,6 +187,23 @@ class ShortPixelMetaFacade {
|
|
187 |
}
|
188 |
}
|
189 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
190 |
|
191 |
function deleteMeta() {
|
192 |
if($this->type == self::CUSTOM_TYPE) {
|
@@ -583,4 +600,11 @@ class ShortPixelMetaFacade {
|
|
583 |
}
|
584 |
return false;
|
585 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
586 |
}
|
187 |
}
|
188 |
}
|
189 |
}
|
190 |
+
|
191 |
+
function cleanupMeta() {
|
192 |
+
if($this->type == ShortPixelMetaFacade::MEDIA_LIBRARY_TYPE) {
|
193 |
+
if(!isset($this->rawMeta)) {
|
194 |
+
$rawMeta = $this->sanitizeMeta(wp_get_attachment_metadata($_ID));
|
195 |
+
} else {
|
196 |
+
$rawMeta = $this->rawMeta;
|
197 |
+
}
|
198 |
+
unset($rawMeta["ShortPixelImprovement"]);
|
199 |
+
unset($rawMeta['ShortPixel']);
|
200 |
+
unset($this->meta);
|
201 |
+
wp_update_attachment_metadata($this->ID, $rawMeta);
|
202 |
+
$this->rawMeta = $rawMeta;
|
203 |
+
} else {
|
204 |
+
throw new Exception("Not implemented 1");
|
205 |
+
}
|
206 |
+
}
|
207 |
|
208 |
function deleteMeta() {
|
209 |
if($this->type == self::CUSTOM_TYPE) {
|
600 |
}
|
601 |
return false;
|
602 |
}
|
603 |
+
|
604 |
+
public function doActions() {
|
605 |
+
if($this->getType() == self::MEDIA_LIBRARY_TYPE) {
|
606 |
+
do_action( 'shortpixel_image_optimised', $this->getId() );
|
607 |
+
}
|
608 |
+
|
609 |
+
}
|
610 |
}
|
class/db/wp-shortpixel-media-library-adapter.php
CHANGED
@@ -6,7 +6,7 @@ class WpShortPixelMediaLbraryAdapter {
|
|
6 |
public static function countAllProcessableFiles($includePdfs = true, $maxId = PHP_INT_MAX, $minId = 0){
|
7 |
global $wpdb;
|
8 |
|
9 |
-
$totalFiles = $mainFiles = $processedMainFiles = $processedTotalFiles =
|
10 |
$procGlossyMainFiles = $procGlossyTotalFiles = $procLossyMainFiles = $procLossyTotalFiles = $procLosslessMainFiles = $procLosslessTotalFiles = $procUndefMainFiles = $procUndefTotalFiles = $mainUnprocessedThumbs = 0;
|
11 |
$filesMap = $processedFilesMap = array();
|
12 |
$limit = self::getOptimalChunkSize();
|
@@ -14,31 +14,38 @@ class WpShortPixelMediaLbraryAdapter {
|
|
14 |
$filesWithErrors = array();
|
15 |
$excludePatterns = WPShortPixelSettings::getOpt("excludePatterns");
|
16 |
|
|
|
|
|
|
|
|
|
17 |
//count all the files, main and thumbs
|
18 |
while ( 1 ) {
|
19 |
-
$
|
20 |
-
if($
|
21 |
break; //we parsed all the results
|
22 |
}
|
23 |
-
elseif(count($ids) == 0) {
|
24 |
$pointer += $limit;
|
25 |
continue;
|
26 |
}
|
27 |
|
28 |
$filesList= $wpdb->get_results("SELECT * FROM " . $wpdb->prefix . "postmeta
|
29 |
-
WHERE post_id IN (" . implode(',', $ids) . ")
|
30 |
AND ( meta_key = '_wp_attached_file' OR meta_key = '_wp_attachment_metadata' )");
|
31 |
|
32 |
foreach ( $filesList as $file )
|
33 |
-
{
|
|
|
|
|
34 |
if ( $file->meta_key == "_wp_attached_file" )
|
35 |
{//count pdf files only
|
36 |
$extension = substr($file->meta_value, strrpos($file->meta_value,".") + 1 );
|
37 |
if ( $extension == "pdf" && !isset($filesMap[$file->meta_value]))
|
38 |
{
|
39 |
$totalFiles++;
|
|
|
40 |
$mainFiles++;
|
41 |
-
$filesMap[$file->meta_value] = 1;
|
42 |
}
|
43 |
}
|
44 |
else //_wp_attachment_metadata
|
@@ -51,11 +58,13 @@ class WpShortPixelMediaLbraryAdapter {
|
|
51 |
&& WPShortPixel::_isProcessablePath($attachment['file'], array(), $excludePatterns)){
|
52 |
$isProcessable = true;
|
53 |
if ( isset($attachment['sizes']) ) {
|
54 |
-
$totalFiles += $sizesCount;
|
|
|
55 |
}
|
56 |
if ( isset($attachment['file']) )
|
57 |
{
|
58 |
$totalFiles++;
|
|
|
59 |
$mainFiles++;
|
60 |
$filesMap[$attachment['file']] = 1;
|
61 |
}
|
@@ -123,6 +132,18 @@ class WpShortPixelMediaLbraryAdapter {
|
|
123 |
}
|
124 |
|
125 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
126 |
}
|
127 |
unset($filesList);
|
128 |
$pointer += $limit;
|
@@ -140,8 +161,8 @@ class WpShortPixelMediaLbraryAdapter {
|
|
140 |
"totalProcGlossyMlFiles" => $procGlossyTotalFiles, "mainProcGlossyMlFiles" => $procGlossyMainFiles,
|
141 |
"totalProcLosslessMlFiles" => $procLosslessTotalFiles, "mainProcLosslessMlFiles" => $procLosslessMainFiles,
|
142 |
"totalProcUndefMlFiles" => $procUndefTotalFiles, "mainProcUndefMlFiles" => $procUndefMainFiles,
|
143 |
-
"mainUnprocessedThumbs" => $mainUnprocessedThumbs,
|
144 |
-
"filesWithErrors" => $filesWithErrors
|
145 |
);
|
146 |
}
|
147 |
|
@@ -211,8 +232,8 @@ class WpShortPixelMediaLbraryAdapter {
|
|
211 |
protected static function getPostIdsChunk($minId, $maxId, $pointer, $limit) {
|
212 |
global $wpdb;
|
213 |
|
214 |
-
$ids = array();
|
215 |
-
$idList = $wpdb->get_results("SELECT ID, post_mime_type FROM " . $wpdb->prefix . "posts
|
216 |
WHERE ( ID <= $maxId AND ID > $minId )
|
217 |
LIMIT $pointer,$limit");
|
218 |
if ( empty($idList) ) {
|
@@ -221,9 +242,10 @@ class WpShortPixelMediaLbraryAdapter {
|
|
221 |
foreach($idList as $item) {
|
222 |
if($item->post_mime_type != '') {
|
223 |
$ids[] = $item->ID;
|
|
|
224 |
}
|
225 |
}
|
226 |
-
return $ids;
|
227 |
}
|
228 |
|
229 |
}
|
6 |
public static function countAllProcessableFiles($includePdfs = true, $maxId = PHP_INT_MAX, $minId = 0){
|
7 |
global $wpdb;
|
8 |
|
9 |
+
$totalFiles = $mainFiles = $processedMainFiles = $processedTotalFiles = $totalFilesM1 = $totalFilesM2 = $totalFilesM3 = $totalFilesM4 =
|
10 |
$procGlossyMainFiles = $procGlossyTotalFiles = $procLossyMainFiles = $procLossyTotalFiles = $procLosslessMainFiles = $procLosslessTotalFiles = $procUndefMainFiles = $procUndefTotalFiles = $mainUnprocessedThumbs = 0;
|
11 |
$filesMap = $processedFilesMap = array();
|
12 |
$limit = self::getOptimalChunkSize();
|
14 |
$filesWithErrors = array();
|
15 |
$excludePatterns = WPShortPixelSettings::getOpt("excludePatterns");
|
16 |
|
17 |
+
$month1 = new DateTime(); $month2 = new DateTime(); $month3 = new DateTime(); $month4 = new DateTime();
|
18 |
+
$mi1 = new DateInterval('P1M'); $mi2 = new DateInterval('P2M'); $mi3 = new DateInterval('P3M'); $mi4 = new DateInterval('P4M');
|
19 |
+
$month1->sub($mi1); $month2->sub($mi2); $month3->sub($mi3); $month4->sub($mi4);
|
20 |
+
|
21 |
//count all the files, main and thumbs
|
22 |
while ( 1 ) {
|
23 |
+
$idInfo = self::getPostIdsChunk($minId, $maxId, $pointer, $limit);
|
24 |
+
if($idInfo === null) {
|
25 |
break; //we parsed all the results
|
26 |
}
|
27 |
+
elseif(count($idInfo->ids) == 0) {
|
28 |
$pointer += $limit;
|
29 |
continue;
|
30 |
}
|
31 |
|
32 |
$filesList= $wpdb->get_results("SELECT * FROM " . $wpdb->prefix . "postmeta
|
33 |
+
WHERE post_id IN (" . implode(',', $idInfo->ids) . ")
|
34 |
AND ( meta_key = '_wp_attached_file' OR meta_key = '_wp_attachment_metadata' )");
|
35 |
|
36 |
foreach ( $filesList as $file )
|
37 |
+
{
|
38 |
+
$totalFilesThis = 0;
|
39 |
+
|
40 |
if ( $file->meta_key == "_wp_attached_file" )
|
41 |
{//count pdf files only
|
42 |
$extension = substr($file->meta_value, strrpos($file->meta_value,".") + 1 );
|
43 |
if ( $extension == "pdf" && !isset($filesMap[$file->meta_value]))
|
44 |
{
|
45 |
$totalFiles++;
|
46 |
+
$totalFilesThis++;
|
47 |
$mainFiles++;
|
48 |
+
$filesMap[$file->meta_value] = 1;
|
49 |
}
|
50 |
}
|
51 |
else //_wp_attachment_metadata
|
58 |
&& WPShortPixel::_isProcessablePath($attachment['file'], array(), $excludePatterns)){
|
59 |
$isProcessable = true;
|
60 |
if ( isset($attachment['sizes']) ) {
|
61 |
+
$totalFiles += $sizesCount;
|
62 |
+
$totalFilesThis += $sizesCount;
|
63 |
}
|
64 |
if ( isset($attachment['file']) )
|
65 |
{
|
66 |
$totalFiles++;
|
67 |
+
$totalFilesThis++;
|
68 |
$mainFiles++;
|
69 |
$filesMap[$attachment['file']] = 1;
|
70 |
}
|
132 |
}
|
133 |
|
134 |
}
|
135 |
+
|
136 |
+
$dt = new DateTime($idInfo->idDates[$file->post_id]);
|
137 |
+
if($dt > $month1) {
|
138 |
+
$totalFilesM1 += $totalFilesThis;
|
139 |
+
} else if($dt > $month2) {
|
140 |
+
$totalFilesM2 += $totalFilesThis;
|
141 |
+
} else if($dt > $month3) {
|
142 |
+
$totalFilesM3 += $totalFilesThis;
|
143 |
+
} else if($dt > $month4) {
|
144 |
+
$totalFilesM4 += $totalFilesThis;
|
145 |
+
}
|
146 |
+
|
147 |
}
|
148 |
unset($filesList);
|
149 |
$pointer += $limit;
|
161 |
"totalProcGlossyMlFiles" => $procGlossyTotalFiles, "mainProcGlossyMlFiles" => $procGlossyMainFiles,
|
162 |
"totalProcLosslessMlFiles" => $procLosslessTotalFiles, "mainProcLosslessMlFiles" => $procLosslessMainFiles,
|
163 |
"totalProcUndefMlFiles" => $procUndefTotalFiles, "mainProcUndefMlFiles" => $procUndefMainFiles,
|
164 |
+
"mainUnprocessedThumbs" => $mainUnprocessedThumbs, "totalM1" => $totalFilesM1, "totalM2" => $totalFilesM2, "totalM3" => $totalFilesM3, "totalM4" => $totalFilesM4,
|
165 |
+
"filesWithErrors" => $filesWithErrors,
|
166 |
);
|
167 |
}
|
168 |
|
232 |
protected static function getPostIdsChunk($minId, $maxId, $pointer, $limit) {
|
233 |
global $wpdb;
|
234 |
|
235 |
+
$ids = $idDates = array();
|
236 |
+
$idList = $wpdb->get_results("SELECT ID, post_mime_type, post_date FROM " . $wpdb->prefix . "posts
|
237 |
WHERE ( ID <= $maxId AND ID > $minId )
|
238 |
LIMIT $pointer,$limit");
|
239 |
if ( empty($idList) ) {
|
242 |
foreach($idList as $item) {
|
243 |
if($item->post_mime_type != '') {
|
244 |
$ids[] = $item->ID;
|
245 |
+
$idDates[$item->ID] = $item->post_date;
|
246 |
}
|
247 |
}
|
248 |
+
return (object)array('ids' => $ids, 'idDates' => $idDates);
|
249 |
}
|
250 |
|
251 |
}
|
class/front/img-to-picture-webp.php
CHANGED
@@ -109,9 +109,23 @@ class ShortPixelImgToPictureWebp {
|
|
109 |
$image_url = preg_replace('/^(.+?)(-\d+x\d+)?\.(jpg|jpeg|png|gif)((?:\?|#).+)?$/i', '$1.$3', $image_url);
|
110 |
$prefix = $wpdb->prefix;
|
111 |
$attachment_id = $wpdb->get_col($wpdb->prepare("SELECT ID FROM " . $prefix . "posts" . " WHERE guid='%s';", $image_url ));
|
112 |
-
|
113 |
-
|
114 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
115 |
$attachment_id = $wpdb->get_col($wpdb->prepare("SELECT ID FROM " . $prefix . "posts" . " WHERE guid='%s';", $original_image_url ));
|
116 |
}
|
117 |
return !empty($attachment_id) ? $attachment_id[0] : false;
|
109 |
$image_url = preg_replace('/^(.+?)(-\d+x\d+)?\.(jpg|jpeg|png|gif)((?:\?|#).+)?$/i', '$1.$3', $image_url);
|
110 |
$prefix = $wpdb->prefix;
|
111 |
$attachment_id = $wpdb->get_col($wpdb->prepare("SELECT ID FROM " . $prefix . "posts" . " WHERE guid='%s';", $image_url ));
|
112 |
+
|
113 |
+
//try the other proto (https - http) if full urls are used
|
114 |
+
if ( empty($attachment_id) && strpos($image_url, 'http://') === 0 ) {
|
115 |
+
$image_url_other_proto = strpos($image_url, 'https') === 0 ?
|
116 |
+
str_replace('https://', 'http://', $image_url) :
|
117 |
+
str_replace('http://', 'https://', $image_url);
|
118 |
+
$attachment_id = $wpdb->get_col($wpdb->prepare("SELECT ID FROM " . $prefix . "posts" . " WHERE guid='%s';", $image_url_other_proto ));
|
119 |
+
}
|
120 |
+
|
121 |
+
//try using only path
|
122 |
+
if (empty($attachment_id) ) {
|
123 |
+
$image_path = parse_url($image_url, PHP_URL_PATH); //some sites have different domains in posts guid (site changes, etc.)
|
124 |
+
$attachment_id = $wpdb->get_col($wpdb->prepare("SELECT ID FROM " . $prefix . "posts" . " WHERE guid like'%%%s';", $image_path ));
|
125 |
+
}
|
126 |
+
|
127 |
+
//try using the initial URL
|
128 |
+
if ( empty($attachment_id) ) {
|
129 |
$attachment_id = $wpdb->get_col($wpdb->prepare("SELECT ID FROM " . $prefix . "posts" . " WHERE guid='%s';", $original_image_url ));
|
130 |
}
|
131 |
return !empty($attachment_id) ? $attachment_id[0] : false;
|
class/shortpixel_queue.php
CHANGED
@@ -208,7 +208,7 @@ class ShortPixelQueue {
|
|
208 |
}
|
209 |
|
210 |
public function bulkPaused() {
|
211 |
-
WPShortPixel::log("Bulk Paused: " . $this->settings->cancelPointer);
|
212 |
return $this->settings->cancelPointer;
|
213 |
}
|
214 |
|
@@ -217,7 +217,7 @@ class ShortPixelQueue {
|
|
217 |
}
|
218 |
|
219 |
public function processing() {
|
220 |
-
WPShortPixel::log("QUEUE: processing(): get:" . json_encode($this->get()));
|
221 |
return $this->bulkRunning() || count($this->get());
|
222 |
}
|
223 |
|
@@ -391,15 +391,15 @@ class ShortPixelQueue {
|
|
391 |
|
392 |
public function getBulkPercent() {
|
393 |
$previousPercent = $this->settings->bulkPreviousPercent;
|
394 |
-
WPShortPixel::log("QUEUE - BulkPrevPercent: " . $previousPercent . " BulkCurrentlyProcessing: "
|
395 |
-
|
396 |
|
397 |
if($this->getBulkToProcess() <= 0) return ($this->processing () ? 99: 100);
|
398 |
// return maximum 99%
|
399 |
$percent = $previousPercent + round($this->settings->bulkCurrentlyProcessed / $this->getBulkToProcess()
|
400 |
* (100 - $previousPercent));
|
401 |
|
402 |
-
WPShortPixel::log("QUEUE - Calculated Percent: " . $percent);
|
403 |
|
404 |
return min(99, $percent);
|
405 |
}
|
208 |
}
|
209 |
|
210 |
public function bulkPaused() {
|
211 |
+
//WPShortPixel::log("Bulk Paused: " . $this->settings->cancelPointer);
|
212 |
return $this->settings->cancelPointer;
|
213 |
}
|
214 |
|
217 |
}
|
218 |
|
219 |
public function processing() {
|
220 |
+
//WPShortPixel::log("QUEUE: processing(): get:" . json_encode($this->get()));
|
221 |
return $this->bulkRunning() || count($this->get());
|
222 |
}
|
223 |
|
391 |
|
392 |
public function getBulkPercent() {
|
393 |
$previousPercent = $this->settings->bulkPreviousPercent;
|
394 |
+
//WPShortPixel::log("QUEUE - BulkPrevPercent: " . $previousPercent . " BulkCurrentlyProcessing: "
|
395 |
+
// . $this->settings->bulkCurrentlyProcessed . " out of " . $this->getBulkToProcess());
|
396 |
|
397 |
if($this->getBulkToProcess() <= 0) return ($this->processing () ? 99: 100);
|
398 |
// return maximum 99%
|
399 |
$percent = $previousPercent + round($this->settings->bulkCurrentlyProcessed / $this->getBulkToProcess()
|
400 |
* (100 - $previousPercent));
|
401 |
|
402 |
+
//WPShortPixel::log("QUEUE - Calculated Percent: " . $percent);
|
403 |
|
404 |
return min(99, $percent);
|
405 |
}
|
class/view/shortpixel_view.php
CHANGED
@@ -98,6 +98,31 @@ class ShortPixelView {
|
|
98 |
}
|
99 |
echo("</ul>");
|
100 |
break;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
101 |
case 'generic' :
|
102 |
echo("<p>$extra</p>");
|
103 |
break;
|
@@ -166,7 +191,14 @@ class ShortPixelView {
|
|
166 |
</div>
|
167 |
</a>
|
168 |
</div>
|
169 |
-
<?php
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
170 |
<div class="bulk-play bulk-nothing-optimize">
|
171 |
<?php _e('Nothing to optimize! The images that you add to Media Gallery will be automatically optimized after upload.','shortpixel-image-optimiser');?>
|
172 |
</div>
|
@@ -212,7 +244,10 @@ class ShortPixelView {
|
|
212 |
} else { ?>
|
213 |
<div class="sp-container">
|
214 |
<div class='sp-notice sp-notice-success sp-floating-block sp-single-width' style="height: 80px;overflow:hidden;">
|
215 |
-
<div style='float:left;margin:5px 20px 5px 0'
|
|
|
|
|
|
|
216 |
<div class="sp-bulk-summary">
|
217 |
<input type="text" value="<?php echo("" . round($averageCompression))?>" id="sp-total-optimization-dial" class="dial">
|
218 |
</div>
|
@@ -390,7 +425,8 @@ class ShortPixelView {
|
|
390 |
<input type='checkbox' id='bulk-thumbnails' name='thumbnails' <?php echo($this->ctrl->processThumbnails() ? "checked":"");?>
|
391 |
onchange="ShortPixel.onBulkThumbsCheck(this)"> <?php _e('Include thumbnails','shortpixel-image-optimiser');?><br><br>
|
392 |
<input type='submit' name='bulkProcess' id='bulkProcess' class='button button-primary' value='<?php _e('Restart Optimizing','shortpixel-image-optimiser');?>'>
|
393 |
-
<input type='submit' name='bulkRestore' id='bulkRestore' class='button' value='<?php _e('Bulk Restore Media Library','shortpixel-image-optimiser');?>' style="float: right;">
|
|
|
394 |
</form>
|
395 |
</div>
|
396 |
<?php } ?>
|
@@ -495,7 +531,7 @@ class ShortPixelView {
|
|
495 |
</div>
|
496 |
</div>
|
497 |
<?php if($running) {
|
498 |
-
if($type) { ?>
|
499 |
<div class="sp-h2"><?php
|
500 |
echo($type & 1 ? __('Media Library','shortpixel-image-optimiser') . " " : "");
|
501 |
echo($type & 3 == 3 ? __('and','shortpixel-image-optimiser') . " " : "");
|
@@ -503,11 +539,16 @@ class ShortPixelView {
|
|
503 |
_e('optimization in progress ...','shortpixel-image-optimiser');?></div>
|
504 |
<p style="margin: 0 0 18px;"><?php _e('Bulk optimization has started.','shortpixel-image-optimiser');?><br>
|
505 |
<?php
|
506 |
-
}
|
507 |
<div class="sp-h2"><?php
|
508 |
_e('Media Library restore in progress ...','shortpixel-image-optimiser');?></div>
|
509 |
<p style="margin: 0 0 18px;"><?php _e('Bulk restore has started.','shortpixel-image-optimiser');?><br>
|
510 |
<?php }
|
|
|
|
|
|
|
|
|
|
|
511 |
printf(__('This process will take some time, depending on the number of images in your library. In the meantime, you can continue using
|
512 |
the admin as usual, <a href="%s" target="_blank">in a different browser window or tab</a>.<br>
|
513 |
However, <strong>if you close this window, the bulk processing will pause</strong> until you open the media gallery or the ShortPixel bulk page again.','shortpixel-image-optimiser'), get_admin_url());?>
|
@@ -518,7 +559,8 @@ class ShortPixelView {
|
|
518 |
<?php }?>
|
519 |
<div id="bulk-progress" class="progress" >
|
520 |
<div class="progress-img" style="left: <?php echo($percent);?>%;">
|
521 |
-
<img src="<?php echo(plugins_url( 'shortpixel-image-optimiser/res/img/slider.png' ));?>"
|
|
|
522 |
<span><?php echo($percentAfter);?></span>
|
523 |
</div>
|
524 |
<div class="progress-left" style="width: <?php echo($percent);?>%"><?php echo($percentBefore);?></div>
|
@@ -835,6 +877,7 @@ class ShortPixelView {
|
|
835 |
}
|
836 |
$excludePatterns = substr($excludePatterns, 0, -2);
|
837 |
}
|
|
|
838 |
?>
|
839 |
<div class="wp-shortpixel-options">
|
840 |
<?php if(!$this->ctrl->getVerifiedKey()) { ?>
|
@@ -912,7 +955,7 @@ class ShortPixelView {
|
|
912 |
<p class="settings-info">
|
913 |
<?php _e('Use the Select... button to select site folders. ShortPixel will optimize images and PDFs from the specified folders and their subfolders. The optimization status for each image or PDF in these folders can be seen in the <a href="upload.php?page=wp-short-pixel-custom">Other Media list</a>, under the Media menu.','shortpixel-image-optimiser');?>
|
914 |
</p>
|
915 |
-
<div class="sp-modal-shade">
|
916 |
<div class="shortpixel-modal">
|
917 |
<div class="sp-modal-title"><?php _e('Select the images folder','shortpixel-image-optimiser');?></div>
|
918 |
<div class="sp-folder-picker"></div>
|
@@ -938,6 +981,15 @@ class ShortPixelView {
|
|
938 |
</td>
|
939 |
</tr>
|
940 |
<?php } ?>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
941 |
<tr>
|
942 |
<th scope="row"><label for="createWebp"><?php _e('WebP versions','shortpixel-image-optimiser');?></label></th>
|
943 |
<td>
|
@@ -1262,7 +1314,7 @@ class ShortPixelView {
|
|
1262 |
<div id="spUploadCompare" class="shortpixel-modal shortpixel-hide">
|
1263 |
<div class="sp-modal-title">
|
1264 |
<button type="button" class="sp-close-button">×</button>
|
1265 |
-
Compare Images
|
1266 |
</div>
|
1267 |
<div class="sp-modal-body sptw-modal-spinner" style="height:400px;padding:0;">
|
1268 |
<div class="shortpixel-slider" style="z-index:2000;">
|
98 |
}
|
99 |
echo("</ul>");
|
100 |
break;
|
101 |
+
case 'upgmonth' :
|
102 |
+
case 'upgbulk' : ?>
|
103 |
+
<p> <?php
|
104 |
+
if($when == 'upgmonth') {
|
105 |
+
printf(__("You are adding an average of <strong>%d images and thumbnails every month</strong> to your Media Library and you have <strong>a plan of %d images/month</strong>."
|
106 |
+
. " You might need to upgrade you plan in order to have all your images optimized.", 'shortpixel_image_optimiser'), $extra['monthAvg'], $extra['monthlyQuota']);
|
107 |
+
} else {
|
108 |
+
printf(__("You currently have <strong>%d images and thumbnails to optimize</strong> in your Media Library but you only you have <strong>%d images</strong> available in your current plan."
|
109 |
+
. " You might need to upgrade you plan in order to have all your images optimized.", 'shortpixel_image_optimiser'), $extra['filesTodo'], $extra['quotaAvailable']);
|
110 |
+
}?>
|
111 |
+
<br><br>
|
112 |
+
<button class="button button-primary" id="shortpixel-upgrade-advice" onclick="ShortPixel.proposeUpgrade()"><strong>
|
113 |
+
<?php _e('Show me the best available options', 'shortpixel_image_optimiser'); ?></strong></button>
|
114 |
+
</p>
|
115 |
+
<div id="shortPixelProposeUpgradeShade" class="sp-modal-shade" style="display:none;">
|
116 |
+
<div id="shortPixelProposeUpgrade" class="shortpixel-modal shortpixel-hide">
|
117 |
+
<div class="sp-modal-title">
|
118 |
+
<button type="button" class="sp-close-upgrade-button" onclick="ShortPixel.closeProposeUpgrade()">×</button>
|
119 |
+
<?php _e('Upgrade your ShortPixel account', 'shortpixel-image-optimiser');?>
|
120 |
+
</div>
|
121 |
+
<div class="sp-modal-body sptw-modal-spinner" style="height:400px;padding:0;">
|
122 |
+
</div>
|
123 |
+
</div>
|
124 |
+
</div>
|
125 |
+
<?php break;
|
126 |
case 'generic' :
|
127 |
echo("<p>$extra</p>");
|
128 |
break;
|
191 |
</div>
|
192 |
</a>
|
193 |
</div>
|
194 |
+
<?php if($quotaData['mainProcessedMlFiles'] > 0) {?>
|
195 |
+
<div style="position: absolute;bottom: 10px;right: 10px;">
|
196 |
+
<input type='submit' name='bulkRestore' id='bulkRestore' class='button' value='<?php _e('Bulk Restore Media Library','shortpixel-image-optimiser');?>' onclick="ShortPixel.confirmBulkAction('Restore', event)" style="margin-bottom:10px;"><br>
|
197 |
+
<input type='submit' name='bulkCleanup' id='bulkRestore' class='button' value='<?php _e('Bulk Delete Metadata','shortpixel-image-optimiser');?>' onclick="ShortPixel.confirmBulkAction('Cleanup', event)" style="width:100%">
|
198 |
+
</div>
|
199 |
+
|
200 |
+
<?php }
|
201 |
+
} else {?>
|
202 |
<div class="bulk-play bulk-nothing-optimize">
|
203 |
<?php _e('Nothing to optimize! The images that you add to Media Gallery will be automatically optimized after upload.','shortpixel-image-optimiser');?>
|
204 |
</div>
|
244 |
} else { ?>
|
245 |
<div class="sp-container">
|
246 |
<div class='sp-notice sp-notice-success sp-floating-block sp-single-width' style="height: 80px;overflow:hidden;">
|
247 |
+
<div style='float:left;margin:5px 20px 5px 0'>
|
248 |
+
<img src="<?php echo(plugins_url( 'shortpixel-image-optimiser/res/img/slider.png' ));?>"
|
249 |
+
srcset='<?php echo(plugins_url( 'shortpixel-image-optimiser/res/img/slider.png' ));?> 1x, <?php echo(plugins_url( 'shortpixel-image-optimiser/res/img/slider@2x.png' ));?> 2x'>
|
250 |
+
</div>
|
251 |
<div class="sp-bulk-summary">
|
252 |
<input type="text" value="<?php echo("" . round($averageCompression))?>" id="sp-total-optimization-dial" class="dial">
|
253 |
</div>
|
425 |
<input type='checkbox' id='bulk-thumbnails' name='thumbnails' <?php echo($this->ctrl->processThumbnails() ? "checked":"");?>
|
426 |
onchange="ShortPixel.onBulkThumbsCheck(this)"> <?php _e('Include thumbnails','shortpixel-image-optimiser');?><br><br>
|
427 |
<input type='submit' name='bulkProcess' id='bulkProcess' class='button button-primary' value='<?php _e('Restart Optimizing','shortpixel-image-optimiser');?>'>
|
428 |
+
<input type='submit' name='bulkRestore' id='bulkRestore' class='button' value='<?php _e('Bulk Restore Media Library','shortpixel-image-optimiser');?>' onclick="ShortPixel.confirmBulkAction('Restore',event)" style="float: right;">
|
429 |
+
<input type='submit' name='bulkCleanup' id='bulkRestore' class='button' value='<?php _e('Bulk Delete Metadata','shortpixel-image-optimiser');?>' onclick="ShortPixel.confirmBulkAction('Cleanup',event)" style="float: right;margin-right:10px;">
|
430 |
</form>
|
431 |
</div>
|
432 |
<?php } ?>
|
531 |
</div>
|
532 |
</div>
|
533 |
<?php if($running) {
|
534 |
+
if($type > 0) { ?>
|
535 |
<div class="sp-h2"><?php
|
536 |
echo($type & 1 ? __('Media Library','shortpixel-image-optimiser') . " " : "");
|
537 |
echo($type & 3 == 3 ? __('and','shortpixel-image-optimiser') . " " : "");
|
539 |
_e('optimization in progress ...','shortpixel-image-optimiser');?></div>
|
540 |
<p style="margin: 0 0 18px;"><?php _e('Bulk optimization has started.','shortpixel-image-optimiser');?><br>
|
541 |
<?php
|
542 |
+
} elseif($type == 0) { // restore ?>
|
543 |
<div class="sp-h2"><?php
|
544 |
_e('Media Library restore in progress ...','shortpixel-image-optimiser');?></div>
|
545 |
<p style="margin: 0 0 18px;"><?php _e('Bulk restore has started.','shortpixel-image-optimiser');?><br>
|
546 |
<?php }
|
547 |
+
elseif($type == -1) { // cleanup ?>
|
548 |
+
<div class="sp-h2"><?php
|
549 |
+
_e('Media Library cleanup in progress ...','shortpixel-image-optimiser');?></div>
|
550 |
+
<p style="margin: 0 0 18px;"><?php _e('Bulk cleanup has started.','shortpixel-image-optimiser');?><br>
|
551 |
+
<?php }
|
552 |
printf(__('This process will take some time, depending on the number of images in your library. In the meantime, you can continue using
|
553 |
the admin as usual, <a href="%s" target="_blank">in a different browser window or tab</a>.<br>
|
554 |
However, <strong>if you close this window, the bulk processing will pause</strong> until you open the media gallery or the ShortPixel bulk page again.','shortpixel-image-optimiser'), get_admin_url());?>
|
559 |
<?php }?>
|
560 |
<div id="bulk-progress" class="progress" >
|
561 |
<div class="progress-img" style="left: <?php echo($percent);?>%;">
|
562 |
+
<img src="<?php echo(plugins_url( 'shortpixel-image-optimiser/res/img/slider.png' ));?>"
|
563 |
+
srcset='<?php echo(plugins_url( 'shortpixel-image-optimiser/res/img/slider.png' ));?> 1x, <?php echo(plugins_url( 'shortpixel-image-optimiser/res/img/slider@2x.png' ));?> 2x'>
|
564 |
<span><?php echo($percentAfter);?></span>
|
565 |
</div>
|
566 |
<div class="progress-left" style="width: <?php echo($percent);?>%"><?php echo($percentBefore);?></div>
|
877 |
}
|
878 |
$excludePatterns = substr($excludePatterns, 0, -2);
|
879 |
}
|
880 |
+
$convertPng2Jpg = ($settings->png2jpg ? 'checked' : '');
|
881 |
?>
|
882 |
<div class="wp-shortpixel-options">
|
883 |
<?php if(!$this->ctrl->getVerifiedKey()) { ?>
|
955 |
<p class="settings-info">
|
956 |
<?php _e('Use the Select... button to select site folders. ShortPixel will optimize images and PDFs from the specified folders and their subfolders. The optimization status for each image or PDF in these folders can be seen in the <a href="upload.php?page=wp-short-pixel-custom">Other Media list</a>, under the Media menu.','shortpixel-image-optimiser');?>
|
957 |
</p>
|
958 |
+
<div class="sp-modal-shade sp-folder-picker-shade">
|
959 |
<div class="shortpixel-modal">
|
960 |
<div class="sp-modal-title"><?php _e('Select the images folder','shortpixel-image-optimiser');?></div>
|
961 |
<div class="sp-folder-picker"></div>
|
981 |
</td>
|
982 |
</tr>
|
983 |
<?php } ?>
|
984 |
+
<tr>
|
985 |
+
<th scope="row"><label for="png2jpg"><?php _e('Convert PNG images to JPEG','shortpixel-image-optimiser');?></label></th>
|
986 |
+
<td>
|
987 |
+
<input name="png2jpg" type="checkbox" id="resize" <?php echo( $convertPng2Jpg );?>> <?php _e('Automatically convert the PNG images to JPEG if possible.','shortpixel-image-optimiser');?>
|
988 |
+
<p class="settings-info">
|
989 |
+
<?php _e('Converts all PNGs that don\'t have transparent pixels to JPEG. This can dramatically reduce the file size, especially if you have pictures that are saved in PNG format.','shortpixel-image-optimiser');?>
|
990 |
+
</p>
|
991 |
+
</td>
|
992 |
+
</tr>
|
993 |
<tr>
|
994 |
<th scope="row"><label for="createWebp"><?php _e('WebP versions','shortpixel-image-optimiser');?></label></th>
|
995 |
<td>
|
1314 |
<div id="spUploadCompare" class="shortpixel-modal shortpixel-hide">
|
1315 |
<div class="sp-modal-title">
|
1316 |
<button type="button" class="sp-close-button">×</button>
|
1317 |
+
<?php _('Compare Images', 'shortpixel-image-optimiser');?>
|
1318 |
</div>
|
1319 |
<div class="sp-modal-body sptw-modal-spinner" style="height:400px;padding:0;">
|
1320 |
<div class="shortpixel-slider" style="z-index:2000;">
|
class/wp-short-pixel.php
CHANGED
@@ -75,7 +75,9 @@ class WPShortPixel {
|
|
75 |
add_action('wp_ajax_shortpixel_browse_content', array(&$this, 'browseContent'));
|
76 |
add_action('wp_ajax_shortpixel_get_backup_size', array(&$this, 'getBackupSize'));
|
77 |
add_action('wp_ajax_shortpixel_get_comparer_data', array(&$this, 'getComparerData'));
|
78 |
-
|
|
|
|
|
79 |
add_action( 'delete_attachment', array( &$this, 'handleDeleteAttachmentInBackup' ) );
|
80 |
add_action( 'load-upload.php', array( &$this, 'handleCustomBulk'));
|
81 |
|
@@ -205,6 +207,26 @@ class WPShortPixel {
|
|
205 |
ShortPixelView::displayActivationNotice('compat', $conflictPlugins);
|
206 |
}
|
207 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
208 |
}
|
209 |
|
210 |
public function dismissAdminNotice() {
|
@@ -218,7 +240,25 @@ class WPShortPixel {
|
|
218 |
public function dismissMediaAlert() {
|
219 |
$this->_settings->mediaAlert = 1;
|
220 |
die(json_encode(array("Status" => 'success', "Message" => __('Media alert dismissed','shortpixel-image-optimiser'))));
|
221 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
222 |
|
223 |
//set default move as "list". only set once, it won't try to set the default mode again.
|
224 |
public function setDefaultViewModeList()
|
@@ -239,12 +279,20 @@ class WPShortPixel {
|
|
239 |
static function log($message) {
|
240 |
if (SHORTPIXEL_DEBUG === true) {
|
241 |
if (is_array($message) || is_object($message)) {
|
242 |
-
|
243 |
} else {
|
244 |
-
|
245 |
}
|
246 |
}
|
247 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
248 |
|
249 |
function shortPixelJS() {
|
250 |
require_once(ABSPATH . 'wp-admin/includes/screen.php');
|
@@ -300,7 +348,9 @@ class WPShortPixel {
|
|
300 |
'thisContentNotProcessable' => __( 'This content is not processable.', 'shortpixel-image-optimiser' ),
|
301 |
'imageWaitOptThumbs' => __( 'Image waiting to optimize thumbnails', 'shortpixel-image-optimiser' ),
|
302 |
'pleaseDoNotSetLesserSize' => __( "Please do not set a {0} less than the {1} of the largest thumbnail which is {2}, to be able to still regenerate all your thumbnails in case you'll ever need this.", 'shortpixel-image-optimiser' ),
|
303 |
-
'pleaseDoNotSetLesser1024' => __( "Please do not set a {0} less than 1024, to be able to still regenerate all your thumbnails in case you'll ever need this.", 'shortpixel-image-optimiser' )
|
|
|
|
|
304 |
);
|
305 |
wp_localize_script( 'short-pixel.js', '_spTr', $jsTranslation );
|
306 |
wp_enqueue_script('short-pixel.js');
|
@@ -401,46 +451,183 @@ class WPShortPixel {
|
|
401 |
*/
|
402 |
public function handleMediaLibraryImageUpload($meta, $ID = null)
|
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 |
}//end handleMediaLibraryImageUpload
|
443 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
444 |
/**
|
445 |
* this is hooked onto the NextGen upload
|
446 |
* @param type $image
|
@@ -523,6 +710,8 @@ class WPShortPixel {
|
|
523 |
if ( $startQueryID <= $endQueryID ) {
|
524 |
return false;
|
525 |
}
|
|
|
|
|
526 |
|
527 |
$startTime = time();
|
528 |
$maxTime = (is_numeric(SHORTPIXEL_MAX_EXECUTION_TIME) && SHORTPIXEL_MAX_EXECUTION_TIME > 10 ? SHORTPIXEL_MAX_EXECUTION_TIME - 5 : 25);
|
@@ -546,8 +735,14 @@ class WPShortPixel {
|
|
546 |
$item = new ShortPixelMetaFacade($crtStartQueryID);
|
547 |
$meta = $item->getMeta();//wp_get_attachment_metadata($crtStartQueryID);
|
548 |
|
549 |
-
if($meta->getStatus() == 2) {
|
550 |
-
$
|
|
|
|
|
|
|
|
|
|
|
|
|
551 |
$restored[] = array('id' => $crtStartQueryID, 'status' => $res ? 'success' : 'fail');
|
552 |
}
|
553 |
}
|
@@ -586,7 +781,10 @@ class WPShortPixel {
|
|
586 |
if ( empty($resultsPostMeta) ) {
|
587 |
$crtStartQueryID -= SHORTPIXEL_MAX_RESULTS_QUERY;
|
588 |
$startQueryID = $crtStartQueryID;
|
589 |
-
|
|
|
|
|
|
|
590 |
continue;
|
591 |
}
|
592 |
|
@@ -688,11 +886,13 @@ class WPShortPixel {
|
|
688 |
$this->_settings->lastBackAction = time();
|
689 |
}
|
690 |
|
691 |
-
|
|
|
692 |
//self::log("HIP: 0 Bulk running? " . $this->prioQ->bulkRunning() . " START " . $this->_settings->startBulkId . " STOP " . $this->_settings->stopBulkId);
|
693 |
|
694 |
//handle the bulk restore and cleanup first - these are fast operations taking precedece over optimization
|
695 |
-
if($this->prioQ->bulkRunning()
|
|
|
696 |
$res = $this->bulkRestore();
|
697 |
if($res === false) {
|
698 |
$this->sendEmptyQueue();
|
@@ -726,12 +926,17 @@ class WPShortPixel {
|
|
726 |
}
|
727 |
}
|
728 |
|
729 |
-
self::log("HIP: 0 Bulk ran: " . $this->prioQ->bulkRan());
|
730 |
$customIds = false;
|
731 |
if(count($ids) < 3 && $this->prioQ->bulkRan() && $this->_settings->hasCustomFolders
|
732 |
&& (!$this->_settings->cancelPointer || $this->_settings->skipToCustom)
|
733 |
&& !$this->_settings->customBulkPaused)
|
734 |
{ //take from custom images if any left to optimize - only if bulk was ever started
|
|
|
|
|
|
|
|
|
|
|
735 |
$customIds = $this->spMetaDao->getPendingMetas( 3 - count($ids));
|
736 |
if(is_array($customIds)) {
|
737 |
$ids = array_merge($ids, array_map(array('ShortPixelMetaFacade', 'getNewFromRow'), $customIds));
|
@@ -740,8 +945,8 @@ class WPShortPixel {
|
|
740 |
//var_dump($ids);
|
741 |
//die("za stop 2");
|
742 |
|
743 |
-
self::log("HIP: 1 Prio Queue: ".json_encode($this->prioQ->get()));
|
744 |
-
self::log("HIP: 1 Selected IDs
|
745 |
|
746 |
//2: Send up to 3 files to the server for processing
|
747 |
for($i = 0, $itemHandler = false; $ids !== false && $i < min(3, count($ids)); $i++) {
|
@@ -771,7 +976,7 @@ class WPShortPixel {
|
|
771 |
"Message" => __('Searching images to optimize... ','shortpixel-image-optimiser') . $this->prioQ->getStartBulkId() . '->' . $this->prioQ->getStopBulkId() )));
|
772 |
}
|
773 |
//in this case the queue is really empty
|
774 |
-
self::log("HIP: 1 STOP BULK");
|
775 |
$bulkEverRan = $this->prioQ->stopBulk();
|
776 |
$this->sendEmptyQueue();
|
777 |
}
|
@@ -951,7 +1156,8 @@ class WPShortPixel {
|
|
951 |
$percent = $this->prioQ->getBulkPercent();
|
952 |
if(0 + $pendingMeta > 0) {
|
953 |
$customMeta = $this->spMetaDao->getCustomMetaCount();
|
954 |
-
$
|
|
|
955 |
$minutesRemaining = round($minutesRemaining * (100 - $totalPercent) / max(1, 100 - $percent));
|
956 |
$percent = $totalPercent;
|
957 |
}
|
@@ -960,6 +1166,15 @@ class WPShortPixel {
|
|
960 |
}
|
961 |
|
962 |
private function sendToProcessing($itemHandler, $compressionType = false, $onlyThumbs = false) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
963 |
//WpShortPixelMediaLbraryAdapter::cleanupFoundThumbs($itemHandler);
|
964 |
$URLsAndPATHs = $this->getURLsAndPATHs($itemHandler, NULL, $onlyThumbs);
|
965 |
|
@@ -1031,6 +1246,9 @@ class WPShortPixel {
|
|
1031 |
public function handleManualOptimization() {
|
1032 |
$imageId = $_GET['image_id'];
|
1033 |
$cleanup = $_GET['cleanup'];
|
|
|
|
|
|
|
1034 |
switch(substr($imageId, 0, 2)) {
|
1035 |
case "N-":
|
1036 |
return "Add the gallery to the custom folders list in ShortPixel settings.";
|
@@ -1102,8 +1320,14 @@ class WPShortPixel {
|
|
1102 |
|
1103 |
public function getBackupFolder($file) {
|
1104 |
if(realpath($file)) {
|
1105 |
-
$
|
|
|
1106 |
}
|
|
|
|
|
|
|
|
|
|
|
1107 |
$fileExtension = strtolower(substr($file,strrpos($file,".")+1));
|
1108 |
$SubDir = ShortPixelMetaFacade::returnSubDir($file, ShortPixelMetaFacade::MEDIA_LIBRARY_TYPE);
|
1109 |
$SubDirOld = ShortPixelMetaFacade::returnSubDirOld($file, ShortPixelMetaFacade::MEDIA_LIBRARY_TYPE);
|
@@ -1267,6 +1491,7 @@ class WPShortPixel {
|
|
1267 |
public function handleRestoreBackup() {
|
1268 |
$attachmentID = intval($_GET['attachment_ID']);
|
1269 |
|
|
|
1270 |
$this->doRestore($attachmentID);
|
1271 |
|
1272 |
// get the referring webpage location
|
@@ -1279,6 +1504,8 @@ class WPShortPixel {
|
|
1279 |
}
|
1280 |
|
1281 |
public function handleRedo() {
|
|
|
|
|
1282 |
die(json_encode($this->redo($_GET['attachment_ID'], $_GET['type'])));
|
1283 |
}
|
1284 |
|
@@ -1401,13 +1628,23 @@ class WPShortPixel {
|
|
1401 |
$quotaData = $this->getQuotaInformation();
|
1402 |
}
|
1403 |
if ( !$quotaData['APIKeyValid']) {
|
1404 |
-
$this->view->displayActivationNotice('generic', $quotaData['Message']);
|
1405 |
return $quotaData;
|
1406 |
}
|
1407 |
//$tempus = microtime(true);
|
1408 |
-
$imageCount = WpShortPixelMediaLbraryAdapter::countAllProcessableFiles($this->_settings->optimizePdfs);
|
1409 |
|
1410 |
-
$this->_settings->
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1411 |
|
1412 |
//echo("Count took (seconds): " . (microtime(true) - $tempus));
|
1413 |
foreach($imageCount as $key => $val) {
|
@@ -1483,7 +1720,7 @@ class WPShortPixel {
|
|
1483 |
$customMediaListTable->display();
|
1484 |
//push to the processing list the pending ones, just in case
|
1485 |
//$count = $this->spMetaDao->getCustomMetaCount();
|
1486 |
-
foreach ($items as $item) {
|
1487 |
if($item->status == 1){
|
1488 |
$this->prioQ->push(ShortPixelMetaFacade::queuedId(ShortPixelMetaFacade::CUSTOM_TYPE, $item->id));
|
1489 |
}
|
@@ -1552,6 +1789,12 @@ class WPShortPixel {
|
|
1552 |
$this->_settings->customBulkPaused = 0;
|
1553 |
}//end bulk restore was clicked
|
1554 |
|
|
|
|
|
|
|
|
|
|
|
|
|
1555 |
if(isset($_POST["bulkProcessResume"]))
|
1556 |
{
|
1557 |
$this->prioQ->resumeBulk();
|
@@ -1578,7 +1821,8 @@ class WPShortPixel {
|
|
1578 |
$msg = $this->bulkProgressMessage($this->prioQ->getDeltaBulkPercent(), $this->prioQ->getTimeRemaining());
|
1579 |
|
1580 |
$this->view->displayBulkProcessingRunning($this->getPercent($quotaData), $msg, $quotaData['APICallsRemaining'], $this->getAverageCompression(),
|
1581 |
-
|
|
|
1582 |
|
1583 |
} else
|
1584 |
{
|
@@ -1723,6 +1967,47 @@ class WPShortPixel {
|
|
1723 |
die(json_encode((object)$ret));
|
1724 |
}
|
1725 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1726 |
public static function getCustomFolderBase() {
|
1727 |
if(is_main_site()) {
|
1728 |
$base = get_home_path();
|
@@ -1907,13 +2192,14 @@ class WPShortPixel {
|
|
1907 |
$notice = array("status" => "success", "msg" => __('Folder added successfully.','shortpixel-image-optimiser'));
|
1908 |
}
|
1909 |
$customFolders = $this->spMetaDao->getFolders();
|
1910 |
-
$this->_settings->hasCustomFolders =
|
1911 |
}
|
1912 |
|
1913 |
$this->_settings->createWebp = (isset($_POST['createWebp']) ? 1: 0);
|
1914 |
$this->_settings->createWebpMarkup = (isset($_POST['createWebpMarkup']) ? 1: 0);
|
1915 |
$this->_settings->optimizeRetina = (isset($_POST['optimizeRetina']) ? 1: 0);
|
1916 |
$this->_settings->optimizePdfs = (isset($_POST['optimizePdfs']) ? 1: 0);
|
|
|
1917 |
|
1918 |
//die(var_dump($_POST['excludePatterns']));
|
1919 |
|
@@ -2012,7 +2298,7 @@ class WPShortPixel {
|
|
2012 |
$ngGalleries = ShortPixelNextGenAdapter::getGalleries();
|
2013 |
foreach($ngGalleries as $gallery) {
|
2014 |
$folderMsg = $this->spMetaDao->newFolderFromPath($gallery, get_home_path(), self::getCustomFolderBase());
|
2015 |
-
$this->_settings->hasCustomFolders =
|
2016 |
}
|
2017 |
$customFolders = $this->spMetaDao->getFolders();
|
2018 |
}
|
@@ -2274,7 +2560,7 @@ class WPShortPixel {
|
|
2274 |
elseif(isset($data['ShortPixel']['WaitingProcessing'])) {
|
2275 |
$renderData['status'] = $quotaExceeded ? 'quotaExceeded' : 'retry';
|
2276 |
$renderData['message'] = "<img src=\"" . plugins_url( 'res/img/loading.gif', SHORTPIXEL_PLUGIN_FILE ) . "\" class='sp-loading-small'> " . __("Image waiting to be processed.",'shortpixel-image-optimiser');
|
2277 |
-
if(!$quotaExceeded && ($id > $this->prioQ->getFlagBulkId() || !$this->prioQ->bulkRunning())) {
|
2278 |
$this->prioQ->push($id); //should be there but just to make sure
|
2279 |
}
|
2280 |
}
|
75 |
add_action('wp_ajax_shortpixel_browse_content', array(&$this, 'browseContent'));
|
76 |
add_action('wp_ajax_shortpixel_get_backup_size', array(&$this, 'getBackupSize'));
|
77 |
add_action('wp_ajax_shortpixel_get_comparer_data', array(&$this, 'getComparerData'));
|
78 |
+
|
79 |
+
add_action('wp_ajax_shortpixel_propose_upgrade', array(&$this, 'proposeUpgrade'));
|
80 |
+
|
81 |
add_action( 'delete_attachment', array( &$this, 'handleDeleteAttachmentInBackup' ) );
|
82 |
add_action( 'load-upload.php', array( &$this, 'handleCustomBulk'));
|
83 |
|
207 |
ShortPixelView::displayActivationNotice('compat', $conflictPlugins);
|
208 |
}
|
209 |
}
|
210 |
+
if(false)
|
211 |
+
if($this->_settings->verifiedKey
|
212 |
+
&& (!isset($dismissed['upgmonth']) || !isset($dismissed['upgbulk'])) && is_array($this->_settings->currentStats)
|
213 |
+
&& $this->_settings->currentStats['optimizePdfs'] == $this->_settings->optimizePdfs ) {
|
214 |
+
$screen = get_current_screen();
|
215 |
+
$stats = $this->_settings->currentStats;
|
216 |
+
$quotaData = $stats['quotaData'];
|
217 |
+
|
218 |
+
//this is for bulk page - alert on the total credits for total images
|
219 |
+
if( $screen && $screen->id == 'media_page_wp-short-pixel-bulk' && $this->bulkUpgradeNeeded($stats)) {
|
220 |
+
//looks like the user hasn't got enough credits to bulk process all media library
|
221 |
+
ShortPixelView::displayActivationNotice('upgbulk', array('filesTodo' => $stats['totalFiles'] - $stats['totalProcessedFiles'],
|
222 |
+
'quotaAvailable' => $quotaData['APICallsQuotaNumeric'] + $quotaData['APICallsQuotaOneTimeNumeric'] - $quotaData['APICallsMadeNumeric'] - $quotaData['APICallsMadeOneTimeNumeric']));
|
223 |
+
}
|
224 |
+
//consider the monthly plus 1/6 of the available one-time credits.
|
225 |
+
elseif($this->monthlyUpgradeNeeded($stats)) {
|
226 |
+
//looks like the user hasn't got enough credits to process the monthly images, display a notice telling this
|
227 |
+
ShortPixelView::displayActivationNotice('upgmonth', array('monthAvg' => $this->getMonthAvg($stats), 'monthlyQuota' => $quotaData['APICallsQuotaNumeric']));
|
228 |
+
}
|
229 |
+
}
|
230 |
}
|
231 |
|
232 |
public function dismissAdminNotice() {
|
240 |
public function dismissMediaAlert() {
|
241 |
$this->_settings->mediaAlert = 1;
|
242 |
die(json_encode(array("Status" => 'success', "Message" => __('Media alert dismissed','shortpixel-image-optimiser'))));
|
243 |
+
}
|
244 |
+
|
245 |
+
protected function getMonthAvg($stats) {
|
246 |
+
for($i = 4, $count = 0; $i>=1; $i--) {
|
247 |
+
if($count == 0 && $stats['totalM' . $i] == 0) continue;
|
248 |
+
$count++;
|
249 |
+
}
|
250 |
+
return ($stats['totalM1'] + $stats['totalM2'] + $stats['totalM3'] + $stats['totalM4']) / max(1,$count);
|
251 |
+
}
|
252 |
+
|
253 |
+
protected function monthlyUpgradeNeeded($stats) {
|
254 |
+
$quotaData = $stats['quotaData'];
|
255 |
+
return $this->getMonthAvg($stats) > $quotaData['APICallsQuotaNumeric'] + ($quotaData['APICallsQuotaOneTimeNumeric'] - $quotaData['APICallsMadeOneTimeNumeric'])/6 + 20;
|
256 |
+
}
|
257 |
+
|
258 |
+
protected function bulkUpgradeNeeded($stats) {
|
259 |
+
$quotaData = $stats['quotaData'];
|
260 |
+
return $stats['totalFiles'] - $stats['totalProcessedFiles'] > $quotaData['APICallsQuotaNumeric'] + $quotaData['APICallsQuotaOneTimeNumeric'] - $quotaData['APICallsMadeNumeric'] - $quotaData['APICallsMadeOneTimeNumeric'];
|
261 |
+
}
|
262 |
|
263 |
//set default move as "list". only set once, it won't try to set the default mode again.
|
264 |
public function setDefaultViewModeList()
|
279 |
static function log($message) {
|
280 |
if (SHORTPIXEL_DEBUG === true) {
|
281 |
if (is_array($message) || is_object($message)) {
|
282 |
+
self::doLog(print_r($message, true));
|
283 |
} else {
|
284 |
+
self::doLog($message);
|
285 |
}
|
286 |
}
|
287 |
}
|
288 |
+
|
289 |
+
static protected function doLog($message) {
|
290 |
+
if(defined('SHORTPIXEL_DEBUG_TARGET')) {
|
291 |
+
file_put_contents(SHORTPIXEL_BACKUP_FOLDER . "/shortpixel_log", '[' . date('Y-m-d H:i:s') . "] $message\n", FILE_APPEND);
|
292 |
+
} else {
|
293 |
+
error_log($message);
|
294 |
+
}
|
295 |
+
}
|
296 |
|
297 |
function shortPixelJS() {
|
298 |
require_once(ABSPATH . 'wp-admin/includes/screen.php');
|
348 |
'thisContentNotProcessable' => __( 'This content is not processable.', 'shortpixel-image-optimiser' ),
|
349 |
'imageWaitOptThumbs' => __( 'Image waiting to optimize thumbnails', 'shortpixel-image-optimiser' ),
|
350 |
'pleaseDoNotSetLesserSize' => __( "Please do not set a {0} less than the {1} of the largest thumbnail which is {2}, to be able to still regenerate all your thumbnails in case you'll ever need this.", 'shortpixel-image-optimiser' ),
|
351 |
+
'pleaseDoNotSetLesser1024' => __( "Please do not set a {0} less than 1024, to be able to still regenerate all your thumbnails in case you'll ever need this.", 'shortpixel-image-optimiser' ),
|
352 |
+
'confirmBulkRestore' => __( "Are you sure you want to restore from backup all the images in your Media Library optimized with ShortPixel?", 'shortpixel-image-optimiser' ),
|
353 |
+
'confirmBulkCleanup' => __( "Are you sure you want to cleanup the ShortPixel metadata info for the images in your Media Library optimized with ShortPixel? This will make ShortPixel 'forget' that it optimized them and will optimize them again if you re-run the Bulk Optimization process.", 'shortpixel-image-optimiser' )
|
354 |
);
|
355 |
wp_localize_script( 'short-pixel.js', '_spTr', $jsTranslation );
|
356 |
wp_enqueue_script('short-pixel.js');
|
451 |
*/
|
452 |
public function handleMediaLibraryImageUpload($meta, $ID = null)
|
453 |
{
|
454 |
+
if( !$this->_settings->verifiedKey) {// no API Key set/verified -> do nothing here, just return
|
455 |
+
return $meta;
|
456 |
+
}
|
457 |
+
//else
|
458 |
+
//self::log("IMG: Auto-analyzing file ID #{$ID}");
|
459 |
+
|
460 |
+
self::log("Handle Media Library Image Upload #{$ID}");
|
461 |
+
|
462 |
+
if(!$this->_settings->optimizePdfs && 'pdf' === pathinfo(get_attached_file($ID), PATHINFO_EXTENSION)) {
|
463 |
+
//pdf is not optimized automatically as per the option, but can be optimized by button. Nothing to do.
|
464 |
+
return $meta;
|
465 |
+
}
|
466 |
+
elseif( self::_isProcessable($ID, array(), $this->_settings->excludePatterns, $meta) == false )
|
467 |
+
{//not a file that we can process
|
468 |
+
$meta['ShortPixelImprovement'] = __('Optimization N/A','shortpixel-image-optimiser');
|
469 |
+
return $meta;
|
470 |
+
}
|
471 |
+
else
|
472 |
+
{//the kind of file we can process. goody.
|
473 |
+
|
474 |
+
$this->prioQ->push($ID);
|
475 |
+
//that's a hack for watermarking plugins, don't send the image right away to processing, only add it in the queue
|
476 |
+
include_once( ABSPATH . 'wp-admin/includes/plugin.php' );
|
477 |
+
if( !is_plugin_active('image-watermark/image-watermark.php')
|
478 |
+
&& !is_plugin_active('easy-watermark/index.php')) {
|
479 |
+
$itemHandler = new ShortPixelMetaFacade($ID);
|
480 |
+
$itemHandler->setRawMeta($meta);
|
481 |
+
try {
|
482 |
+
$URLsAndPATHs = $this->getURLsAndPATHs($itemHandler);
|
483 |
+
//send a processing request right after a file was uploaded, do NOT wait for response
|
484 |
+
$this->_apiInterface->doRequests($URLsAndPATHs['URLs'], false, $ID);
|
485 |
+
} catch(Exception $e) {
|
486 |
+
$meta['ShortPixelImprovement'] = $e->getMessage();
|
487 |
+
return $meta;
|
488 |
}
|
489 |
+
//self::log("IMG: sent: " . json_encode($URLsAndPATHs));
|
490 |
+
}
|
491 |
+
$meta['ShortPixel']['WaitingProcessing'] = true;
|
492 |
+
return $meta;
|
493 |
+
}
|
494 |
}//end handleMediaLibraryImageUpload
|
495 |
|
496 |
+
protected function canConvertPng2Jpg($image) {
|
497 |
+
$transparent = 0;
|
498 |
+
$contents = file_get_contents($image);
|
499 |
+
if (ord(file_get_contents($image, false, null, 25, 1)) & 4) {
|
500 |
+
$transparent = 1;
|
501 |
+
}
|
502 |
+
if (stripos($contents, 'PLTE') !== false && stripos($contents, 'tRNS') !== false) {
|
503 |
+
$transparent = 1;
|
504 |
+
}
|
505 |
+
$transparent_pixel = $img = $bg = false;
|
506 |
+
if ($transparent) {
|
507 |
+
$img = imagecreatefrompng($image);
|
508 |
+
$w = imagesx($img); // Get the width of the image
|
509 |
+
$h = imagesy($img); // Get the height of the image
|
510 |
+
//run through pixels until transparent pixel is found:
|
511 |
+
for ($i = 0; $i < $w; $i++) {
|
512 |
+
for ($j = 0; $j < $h; $j++) {
|
513 |
+
$rgba = imagecolorat($img, $i, $j);
|
514 |
+
if (($rgba & 0x7F000000) >> 24) {
|
515 |
+
$transparent_pixel = true;
|
516 |
+
break;
|
517 |
+
}
|
518 |
+
}
|
519 |
+
}
|
520 |
+
}
|
521 |
+
|
522 |
+
return !$transparent || !$transparent_pixel;
|
523 |
+
}
|
524 |
+
|
525 |
+
/**
|
526 |
+
*
|
527 |
+
* @param type $params
|
528 |
+
* @param type $suffixRegex for example [0-9]+x[0-9]+ - a thumbnail suffix - to have the counter of file name collisions files before it.
|
529 |
+
* @param type $img
|
530 |
+
* @return string
|
531 |
+
*/
|
532 |
+
protected function doConvertPng2Jpg($params, $suffixRegex = false, $img = false) {
|
533 |
+
if(!$img) {
|
534 |
+
$img = imagecreatefrompng($params['file']);
|
535 |
+
}
|
536 |
+
|
537 |
+
$bg = imagecreatetruecolor(imagesx($img), imagesy($img));
|
538 |
+
imagefill($bg, 0, 0, imagecolorallocate($bg, 255, 255, 255));
|
539 |
+
imagealphablending($bg, 1);
|
540 |
+
imagecopy($bg, $img, 0, 0, 0, 0, imagesx($img), imagesy($img));
|
541 |
+
$newPath = preg_replace("/\.png$/", ".jpg", $params['file']);
|
542 |
+
$newUrl = preg_replace("/\.png$/", ".jpg", $params['url']);
|
543 |
+
for ($i = 1; file_exists($newPath); $i++) {
|
544 |
+
if($suffixRegex) {
|
545 |
+
$newPath = preg_replace("/(" . $suffixRegex . ")\.png$/", $i . '-$1.jpg', $params['file']);
|
546 |
+
}else {
|
547 |
+
$newPath = preg_replace("/\.png$/", "-" . $i . ".jpg", $params['file']);
|
548 |
+
}
|
549 |
+
}
|
550 |
+
if (imagejpeg($bg, $newPath, 90)) {
|
551 |
+
$newSize = filesize($newPath);
|
552 |
+
$origSize = filesize($params['file']);
|
553 |
+
if($newSize > $origSize * 0.95) {
|
554 |
+
//if the image is not 5% smaller, don't bother.
|
555 |
+
unlink($newPath);
|
556 |
+
return $params;
|
557 |
+
}
|
558 |
+
unlink($params['file']);
|
559 |
+
$params['file'] = $newPath;
|
560 |
+
$params['url'] = $newUrl;
|
561 |
+
$params['type'] = 'image/jpeg';
|
562 |
+
}
|
563 |
+
return $params;
|
564 |
+
}
|
565 |
+
|
566 |
+
/**
|
567 |
+
* Convert an uploaded image from PNG to JPG
|
568 |
+
* @param type $params
|
569 |
+
* @return string
|
570 |
+
*/
|
571 |
+
public function convertPng2Jpg($params) {
|
572 |
+
|
573 |
+
//echo("PARAMS : ");var_dump($params);
|
574 |
+
if(!$this->_settings->png2jpg || strtolower(substr($params['file'], -4)) !== '.png') {
|
575 |
+
return $params;
|
576 |
+
}
|
577 |
+
|
578 |
+
$image = $params['file'];
|
579 |
+
self::log("Convert Media PNG to JPG on upload: {$image}");
|
580 |
+
|
581 |
+
if ($this->canConvertPng2Jpg($image)) {
|
582 |
+
return $this->doConvertPng2Jpg($params);
|
583 |
+
}
|
584 |
+
return $params;
|
585 |
+
}
|
586 |
+
|
587 |
+
/**
|
588 |
+
* convert PNG to JPEG if possible
|
589 |
+
*
|
590 |
+
* @param type $meta
|
591 |
+
* @param type $ID
|
592 |
+
* @return string
|
593 |
+
*/
|
594 |
+
public function checkConvertMediaPng2Jpg($meta, $ID) {
|
595 |
+
|
596 |
+
if(!$this->_settings->png2jpg || strtolower(substr($meta['file'], -4)) !== '.png') {
|
597 |
+
return $meta;
|
598 |
+
}
|
599 |
+
|
600 |
+
self::log("Send to processing: Convert Media PNG to JPG #{$ID}");
|
601 |
+
|
602 |
+
$image = $meta['file'];
|
603 |
+
$imagePath = get_attached_file($ID);
|
604 |
+
$basePath = trailingslashit(str_replace($image, "", $imagePath));
|
605 |
+
|
606 |
+
if(!$this->canConvertPng2Jpg($imagePath)) return $meta; //cannot convert it
|
607 |
+
|
608 |
+
$ret = $this->doConvertPng2Jpg(array('file' => $imagePath, 'url' => false, 'type' => 'image/png'));
|
609 |
+
//echo("CONVERT: " . $imagePath); var_dump($ret);
|
610 |
+
|
611 |
+
if ($ret['type'] == 'image/jpeg') {
|
612 |
+
//conversion succeeded for the main image, update meta and proceed to thumbs. (It could also not succeed if the converted file is not smaller)
|
613 |
+
$meta['file'] = str_replace($basePath, '', $ret['file']);
|
614 |
+
|
615 |
+
$baseRelPath = trailingslashit(dirname($image));
|
616 |
+
if(isset($meta['sizes'])) foreach($meta['sizes'] as $size => $info) {
|
617 |
+
$rett = $this->doConvertPng2Jpg(array('file' => $basePath . $baseRelPath . $info['file'], 'url' => false, 'type' => 'image/png'), "[0-9]+x[0-9]+");
|
618 |
+
//echo("CONVERT: " . $basePath . $baseRelPath . $info['file']); var_dump($rett);
|
619 |
+
if ($rett['type'] == 'image/jpeg') {
|
620 |
+
$meta['sizes'][$size]['file'] = wp_basename($rett['file']);
|
621 |
+
$meta['sizes'][$size]['mime-type'] = 'image/jpeg';
|
622 |
+
}
|
623 |
+
}
|
624 |
+
update_attached_file($ID, $meta['file']);
|
625 |
+
wp_update_attachment_metadata($ID, $meta);
|
626 |
+
}
|
627 |
+
|
628 |
+
return $meta;
|
629 |
+
}
|
630 |
+
|
631 |
/**
|
632 |
* this is hooked onto the NextGen upload
|
633 |
* @param type $image
|
710 |
if ( $startQueryID <= $endQueryID ) {
|
711 |
return false;
|
712 |
}
|
713 |
+
|
714 |
+
$this->prioQ->resetPrio();
|
715 |
|
716 |
$startTime = time();
|
717 |
$maxTime = (is_numeric(SHORTPIXEL_MAX_EXECUTION_TIME) && SHORTPIXEL_MAX_EXECUTION_TIME > 10 ? SHORTPIXEL_MAX_EXECUTION_TIME - 5 : 25);
|
735 |
$item = new ShortPixelMetaFacade($crtStartQueryID);
|
736 |
$meta = $item->getMeta();//wp_get_attachment_metadata($crtStartQueryID);
|
737 |
|
738 |
+
if($meta->getStatus() == 2 || $meta->getStatus() == 1) {
|
739 |
+
if($meta->getStatus() == 2 && $this->prioQ->getBulkType() == ShortPixelQueue::BULK_TYPE_RESTORE) {
|
740 |
+
$res = $this->doRestore($crtStartQueryID); //this is restore, the real
|
741 |
+
} else {
|
742 |
+
//this is only meta cleanup, no files are replaced (BACKUP REMAINS IN PLACE TOO)
|
743 |
+
$item->cleanupMeta();
|
744 |
+
$res = true;
|
745 |
+
}
|
746 |
$restored[] = array('id' => $crtStartQueryID, 'status' => $res ? 'success' : 'fail');
|
747 |
}
|
748 |
}
|
781 |
if ( empty($resultsPostMeta) ) {
|
782 |
$crtStartQueryID -= SHORTPIXEL_MAX_RESULTS_QUERY;
|
783 |
$startQueryID = $crtStartQueryID;
|
784 |
+
if(!count($idList)) { //none found so far, so decrease the start ID
|
785 |
+
//self::log("GETDB: empty slice. setStartBulkID to $startQueryID");
|
786 |
+
$this->prioQ->setStartBulkId($startQueryID);
|
787 |
+
}
|
788 |
continue;
|
789 |
}
|
790 |
|
886 |
$this->_settings->lastBackAction = time();
|
887 |
}
|
888 |
|
889 |
+
$rawPrioQ = $this->prioQ->get();
|
890 |
+
if(count($rawPrioQ)) { self::log("HIP: 0 Priority Queue: ".json_encode($rawPrioQ)); }
|
891 |
//self::log("HIP: 0 Bulk running? " . $this->prioQ->bulkRunning() . " START " . $this->_settings->startBulkId . " STOP " . $this->_settings->stopBulkId);
|
892 |
|
893 |
//handle the bulk restore and cleanup first - these are fast operations taking precedece over optimization
|
894 |
+
if( $this->prioQ->bulkRunning()
|
895 |
+
&& ($this->prioQ->getBulkType() == ShortPixelQueue::BULK_TYPE_RESTORE || $this->prioQ->getBulkType() == ShortPixelQueue::BULK_TYPE_CLEANUP)) {
|
896 |
$res = $this->bulkRestore();
|
897 |
if($res === false) {
|
898 |
$this->sendEmptyQueue();
|
926 |
}
|
927 |
}
|
928 |
|
929 |
+
//self::log("HIP: 0 Bulk ran: " . $this->prioQ->bulkRan());
|
930 |
$customIds = false;
|
931 |
if(count($ids) < 3 && $this->prioQ->bulkRan() && $this->_settings->hasCustomFolders
|
932 |
&& (!$this->_settings->cancelPointer || $this->_settings->skipToCustom)
|
933 |
&& !$this->_settings->customBulkPaused)
|
934 |
{ //take from custom images if any left to optimize - only if bulk was ever started
|
935 |
+
//but first refresh if it wasn't refreshed in the last hour
|
936 |
+
if(time() - $this->_settings->hasCustomFolders > 3600) {
|
937 |
+
$notice = null; $this->refreshCustomFolders($notice);
|
938 |
+
$this->_settings->hasCustomFolders = time();
|
939 |
+
}
|
940 |
$customIds = $this->spMetaDao->getPendingMetas( 3 - count($ids));
|
941 |
if(is_array($customIds)) {
|
942 |
$ids = array_merge($ids, array_map(array('ShortPixelMetaFacade', 'getNewFromRow'), $customIds));
|
945 |
//var_dump($ids);
|
946 |
//die("za stop 2");
|
947 |
|
948 |
+
//self::log("HIP: 1 Prio Queue: ".json_encode($this->prioQ->get()));
|
949 |
+
if(count($ids)) { self::log("HIP: 1 Selected IDs: ".json_encode($ids));}
|
950 |
|
951 |
//2: Send up to 3 files to the server for processing
|
952 |
for($i = 0, $itemHandler = false; $ids !== false && $i < min(3, count($ids)); $i++) {
|
976 |
"Message" => __('Searching images to optimize... ','shortpixel-image-optimiser') . $this->prioQ->getStartBulkId() . '->' . $this->prioQ->getStopBulkId() )));
|
977 |
}
|
978 |
//in this case the queue is really empty
|
979 |
+
//self::log("HIP: 1 STOP BULK");
|
980 |
$bulkEverRan = $this->prioQ->stopBulk();
|
981 |
$this->sendEmptyQueue();
|
982 |
}
|
1156 |
$percent = $this->prioQ->getBulkPercent();
|
1157 |
if(0 + $pendingMeta > 0) {
|
1158 |
$customMeta = $this->spMetaDao->getCustomMetaCount();
|
1159 |
+
$crtTotalFiles = is_array($this->_settings->currentStats) ? $this->_settings->currentStats['totalFiles'] : $this->_settings->currentStats;
|
1160 |
+
$totalPercent = round(($percent * $crtTotalFiles + ($customMeta - $pendingMeta) * 100) / ($crtTotalFiles + $customMeta));
|
1161 |
$minutesRemaining = round($minutesRemaining * (100 - $totalPercent) / max(1, 100 - $percent));
|
1162 |
$percent = $totalPercent;
|
1163 |
}
|
1166 |
}
|
1167 |
|
1168 |
private function sendToProcessing($itemHandler, $compressionType = false, $onlyThumbs = false) {
|
1169 |
+
|
1170 |
+
if($itemHandler->getType() == ShortPixelMetaFacade::MEDIA_LIBRARY_TYPE) { //currently only for ML
|
1171 |
+
$rawMeta = $this->checkConvertMediaPng2Jpg($itemHandler->getRawMeta(), $itemHandler->getId());
|
1172 |
+
|
1173 |
+
if(isset($rawMeta['type']) && $rawMeta['type'] == 'image/jpeg') {
|
1174 |
+
$itemHandler->setRawMeta($rawMeta);
|
1175 |
+
}
|
1176 |
+
}
|
1177 |
+
|
1178 |
//WpShortPixelMediaLbraryAdapter::cleanupFoundThumbs($itemHandler);
|
1179 |
$URLsAndPATHs = $this->getURLsAndPATHs($itemHandler, NULL, $onlyThumbs);
|
1180 |
|
1246 |
public function handleManualOptimization() {
|
1247 |
$imageId = $_GET['image_id'];
|
1248 |
$cleanup = $_GET['cleanup'];
|
1249 |
+
|
1250 |
+
self::log("Handle Manual Optimization #{$imageId}");
|
1251 |
+
|
1252 |
switch(substr($imageId, 0, 2)) {
|
1253 |
case "N-":
|
1254 |
return "Add the gallery to the custom folders list in ShortPixel settings.";
|
1320 |
|
1321 |
public function getBackupFolder($file) {
|
1322 |
if(realpath($file)) {
|
1323 |
+
$ret = $this->getBackupFolderInternal(realpath($file)); //found cases when $file contains for example /wp/../wp-content - clean it up
|
1324 |
+
if($ret) return $ret;
|
1325 |
}
|
1326 |
+
//another chance at glory, maybe cleanup was too much? (we tried first the cleaned up version for historical reason, don't disturb the sleeping dragon, right? :))
|
1327 |
+
return $this->getBackupFolderInternal($file);
|
1328 |
+
}
|
1329 |
+
|
1330 |
+
private function getBackupFolderInternal($file) {
|
1331 |
$fileExtension = strtolower(substr($file,strrpos($file,".")+1));
|
1332 |
$SubDir = ShortPixelMetaFacade::returnSubDir($file, ShortPixelMetaFacade::MEDIA_LIBRARY_TYPE);
|
1333 |
$SubDirOld = ShortPixelMetaFacade::returnSubDirOld($file, ShortPixelMetaFacade::MEDIA_LIBRARY_TYPE);
|
1491 |
public function handleRestoreBackup() {
|
1492 |
$attachmentID = intval($_GET['attachment_ID']);
|
1493 |
|
1494 |
+
self::log("Handle Restore Backup #{$attachmentID}");
|
1495 |
$this->doRestore($attachmentID);
|
1496 |
|
1497 |
// get the referring webpage location
|
1504 |
}
|
1505 |
|
1506 |
public function handleRedo() {
|
1507 |
+
self::log("Handle Redo #{$_GET['attachment_ID']} type {$_GET['type']}");
|
1508 |
+
|
1509 |
die(json_encode($this->redo($_GET['attachment_ID'], $_GET['type'])));
|
1510 |
}
|
1511 |
|
1628 |
$quotaData = $this->getQuotaInformation();
|
1629 |
}
|
1630 |
if ( !$quotaData['APIKeyValid']) {
|
1631 |
+
if(strlen($this->_settings->apiKey)) $this->view->displayActivationNotice('generic', $quotaData['Message']);
|
1632 |
return $quotaData;
|
1633 |
}
|
1634 |
//$tempus = microtime(true);
|
|
|
1635 |
|
1636 |
+
if( is_array($this->_settings->currentStats)
|
1637 |
+
&& $this->_settings->currentStats['optimizePdfs'] == $this->_settings->optimizePdfs
|
1638 |
+
&& (time() - $this->_settings->currentStats['time'] < 300))
|
1639 |
+
{
|
1640 |
+
$imageCount = $this->_settings->currentStats;
|
1641 |
+
} else {
|
1642 |
+
$imageCount = WpShortPixelMediaLbraryAdapter::countAllProcessableFiles($this->_settings->optimizePdfs);
|
1643 |
+
$imageCount['time'] = time();
|
1644 |
+
$imageCount['optimizePdfs'] = $this->_settings->optimizePdfs;
|
1645 |
+
$imageCount['quotaData'] = $quotaData;
|
1646 |
+
$this->_settings->currentStats = $imageCount;
|
1647 |
+
}
|
1648 |
|
1649 |
//echo("Count took (seconds): " . (microtime(true) - $tempus));
|
1650 |
foreach($imageCount as $key => $val) {
|
1720 |
$customMediaListTable->display();
|
1721 |
//push to the processing list the pending ones, just in case
|
1722 |
//$count = $this->spMetaDao->getCustomMetaCount();
|
1723 |
+
if($this->_settings->autoMediaLibrary) foreach ($items as $item) {
|
1724 |
if($item->status == 1){
|
1725 |
$this->prioQ->push(ShortPixelMetaFacade::queuedId(ShortPixelMetaFacade::CUSTOM_TYPE, $item->id));
|
1726 |
}
|
1789 |
$this->_settings->customBulkPaused = 0;
|
1790 |
}//end bulk restore was clicked
|
1791 |
|
1792 |
+
if(isset($_POST["bulkCleanup"]))
|
1793 |
+
{
|
1794 |
+
$this->prioQ->startBulk(ShortPixelQueue::BULK_TYPE_CLEANUP);
|
1795 |
+
$this->_settings->customBulkPaused = 0;
|
1796 |
+
}//end bulk restore was clicked
|
1797 |
+
|
1798 |
if(isset($_POST["bulkProcessResume"]))
|
1799 |
{
|
1800 |
$this->prioQ->resumeBulk();
|
1821 |
$msg = $this->bulkProgressMessage($this->prioQ->getDeltaBulkPercent(), $this->prioQ->getTimeRemaining());
|
1822 |
|
1823 |
$this->view->displayBulkProcessingRunning($this->getPercent($quotaData), $msg, $quotaData['APICallsRemaining'], $this->getAverageCompression(),
|
1824 |
+
$this->prioQ->getBulkType() == ShortPixelQueue::BULK_TYPE_RESTORE ? 0 :
|
1825 |
+
($this->prioQ->getBulkType() == ShortPixelQueue::BULK_TYPE_CLEANUP ? -1 : ($pendingMeta !== null ? ($this->prioQ->bulkRunning() ? 3 : 2) : 1)));
|
1826 |
|
1827 |
} else
|
1828 |
{
|
1967 |
die(json_encode((object)$ret));
|
1968 |
}
|
1969 |
|
1970 |
+
public function proposeUpgrade() {
|
1971 |
+
if ( !current_user_can( 'manage_options' ) ) {
|
1972 |
+
wp_die(__('You do not have sufficient permissions to access this page.','shortpixel-image-optimiser'));
|
1973 |
+
}
|
1974 |
+
|
1975 |
+
if( is_array($this->_settings->currentStats)
|
1976 |
+
&& $this->_settings->currentStats['optimizePdfs'] == $this->_settings->optimizePdfs
|
1977 |
+
&& (time() - $this->_settings->currentStats['time'] < 300))
|
1978 |
+
{
|
1979 |
+
$stats = $this->_settings->currentStats;
|
1980 |
+
} else {
|
1981 |
+
$stats = WpShortPixelMediaLbraryAdapter::countAllProcessableFiles($this->_settings->optimizePdfs);
|
1982 |
+
}
|
1983 |
+
|
1984 |
+
//$proposal = wp_remote_post($this->_settings->httpProto . "://shortpixel.com/propose-upgrade-frag", array(
|
1985 |
+
echo("<div style='color: #f50a0a; position: relative; top: -59px; right: -255px; height: 0px; font-weight: bold; font-size: 1.2em;'>atentie de trecut pe live propose-upgrade</div>");
|
1986 |
+
$proposal = wp_remote_post("http://dev.shortpixel.com/propose-upgrade-frag", array(
|
1987 |
+
'method' => 'POST',
|
1988 |
+
'timeout' => 10,
|
1989 |
+
'redirection' => 5,
|
1990 |
+
'httpversion' => '1.0',
|
1991 |
+
'blocking' => true,
|
1992 |
+
'headers' => array(),
|
1993 |
+
'body' => json_encode(array(
|
1994 |
+
'plugin_version' => SHORTPIXEL_IMAGE_OPTIMISER_VERSION,
|
1995 |
+
'key' => $this->_settings->apiKey,
|
1996 |
+
'm1' => $stats['totalM1'],
|
1997 |
+
'm2' => $stats['totalM2'],
|
1998 |
+
'm3' => $stats['totalM3'],
|
1999 |
+
'm3' => $stats['totalM4'],
|
2000 |
+
'filesTodo' => $stats['totalFiles'] - $stats['totalProcessedFiles']
|
2001 |
+
)),
|
2002 |
+
'cookies' => array()
|
2003 |
+
));
|
2004 |
+
if(is_wp_error( $proposal )) {
|
2005 |
+
$proposal = array('body' => '');
|
2006 |
+
}
|
2007 |
+
die($proposal['body']);
|
2008 |
+
|
2009 |
+
}
|
2010 |
+
|
2011 |
public static function getCustomFolderBase() {
|
2012 |
if(is_main_site()) {
|
2013 |
$base = get_home_path();
|
2192 |
$notice = array("status" => "success", "msg" => __('Folder added successfully.','shortpixel-image-optimiser'));
|
2193 |
}
|
2194 |
$customFolders = $this->spMetaDao->getFolders();
|
2195 |
+
$this->_settings->hasCustomFolders = time();
|
2196 |
}
|
2197 |
|
2198 |
$this->_settings->createWebp = (isset($_POST['createWebp']) ? 1: 0);
|
2199 |
$this->_settings->createWebpMarkup = (isset($_POST['createWebpMarkup']) ? 1: 0);
|
2200 |
$this->_settings->optimizeRetina = (isset($_POST['optimizeRetina']) ? 1: 0);
|
2201 |
$this->_settings->optimizePdfs = (isset($_POST['optimizePdfs']) ? 1: 0);
|
2202 |
+
$this->_settings->png2jpg = (isset($_POST['png2jpg']) ? 1: 0);
|
2203 |
|
2204 |
//die(var_dump($_POST['excludePatterns']));
|
2205 |
|
2298 |
$ngGalleries = ShortPixelNextGenAdapter::getGalleries();
|
2299 |
foreach($ngGalleries as $gallery) {
|
2300 |
$folderMsg = $this->spMetaDao->newFolderFromPath($gallery, get_home_path(), self::getCustomFolderBase());
|
2301 |
+
$this->_settings->hasCustomFolders = time();
|
2302 |
}
|
2303 |
$customFolders = $this->spMetaDao->getFolders();
|
2304 |
}
|
2560 |
elseif(isset($data['ShortPixel']['WaitingProcessing'])) {
|
2561 |
$renderData['status'] = $quotaExceeded ? 'quotaExceeded' : 'retry';
|
2562 |
$renderData['message'] = "<img src=\"" . plugins_url( 'res/img/loading.gif', SHORTPIXEL_PLUGIN_FILE ) . "\" class='sp-loading-small'> " . __("Image waiting to be processed.",'shortpixel-image-optimiser');
|
2563 |
+
if($this->_settings->autoMediaLibrary && !$quotaExceeded && ($id > $this->prioQ->getFlagBulkId() || !$this->prioQ->bulkRunning())) {
|
2564 |
$this->prioQ->push($id); //should be there but just to make sure
|
2565 |
}
|
2566 |
}
|
class/wp-shortpixel-settings.php
CHANGED
@@ -38,6 +38,7 @@ class WPShortPixelSettings {
|
|
38 |
'autoMediaLibrary' => array('key' => 'wp-short-pixel-auto-media-library', 'default' => 1),
|
39 |
'optimizePdfs' => array('key' => 'wp-short-pixel-optimize-pdfs', 'default' => 1),
|
40 |
'excludePatterns' => array('key' => 'wp-short-pixel-exclude-patterns', 'default' => array()),
|
|
|
41 |
|
42 |
//optimize other images than the ones in Media Library
|
43 |
'includeNextGen' => array('key' => 'wp-short-pixel-include-next-gen', 'default' => null),
|
@@ -45,7 +46,7 @@ class WPShortPixelSettings {
|
|
45 |
'customBulkPaused' => array('key' => 'wp-short-pixel-custom-bulk-paused', 'default' => false),
|
46 |
|
47 |
//stats, notices, etc.
|
48 |
-
'
|
49 |
'fileCount' => array('key' => 'wp-short-pixel-fileCount', 'default' => 0),
|
50 |
'thumbsCount' => array('key' => 'wp-short-pixel-thumbnail-count', 'default' => 0),
|
51 |
'under5Percent' => array('key' => 'wp-short-pixel-files-under-5-percent', 'default' => 0),
|
@@ -175,6 +176,11 @@ class WPShortPixelSettings {
|
|
175 |
}
|
176 |
|
177 |
public function setOpt($key, $val) {
|
178 |
-
update_option($key, $val);
|
|
|
|
|
|
|
|
|
|
|
179 |
}
|
180 |
}
|
38 |
'autoMediaLibrary' => array('key' => 'wp-short-pixel-auto-media-library', 'default' => 1),
|
39 |
'optimizePdfs' => array('key' => 'wp-short-pixel-optimize-pdfs', 'default' => 1),
|
40 |
'excludePatterns' => array('key' => 'wp-short-pixel-exclude-patterns', 'default' => array()),
|
41 |
+
'png2jpg' => array('key' => 'wp-short-pixel-png2jpg', 'default' => 0),
|
42 |
|
43 |
//optimize other images than the ones in Media Library
|
44 |
'includeNextGen' => array('key' => 'wp-short-pixel-include-next-gen', 'default' => null),
|
46 |
'customBulkPaused' => array('key' => 'wp-short-pixel-custom-bulk-paused', 'default' => false),
|
47 |
|
48 |
//stats, notices, etc.
|
49 |
+
'currentStats' => array('key' => 'wp-short-pixel-current-total-files', 'default' => null),
|
50 |
'fileCount' => array('key' => 'wp-short-pixel-fileCount', 'default' => 0),
|
51 |
'thumbsCount' => array('key' => 'wp-short-pixel-thumbnail-count', 'default' => 0),
|
52 |
'under5Percent' => array('key' => 'wp-short-pixel-files-under-5-percent', 'default' => 0),
|
176 |
}
|
177 |
|
178 |
public function setOpt($key, $val) {
|
179 |
+
$ret = update_option($key, $val);
|
180 |
+
//hack for the situation when the option would just not update....
|
181 |
+
if($ret === false && $val != get_option($key)) {
|
182 |
+
delete_option($key);
|
183 |
+
update_option($key, $val);
|
184 |
+
}
|
185 |
}
|
186 |
}
|
readme.txt
CHANGED
@@ -1,9 +1,9 @@
|
|
1 |
=== ShortPixel Image Optimizer ===
|
2 |
Contributors: ShortPixel
|
3 |
-
Tags: compress, image, compression, optimize, image optimizer, image compression, resize,
|
4 |
Requires at least: 3.2.0
|
5 |
Tested up to: 4.8
|
6 |
-
Stable tag: 4.
|
7 |
License: GPLv2 or later
|
8 |
License URI: http://www.gnu.org/licenses/gpl-2.0.html
|
9 |
|
@@ -28,8 +28,9 @@ Make an instant <a rel="friend" href="http://shortpixel.com/image-compression-te
|
|
28 |
|
29 |
**Why is ShortPixel the best choice when it comes to image optimization or PDF compression?**
|
30 |
|
31 |
-
* popular plugin with over
|
32 |
* compress JPG, PNG, GIF (still or animated) images and also PDF documents
|
|
|
33 |
* no file size limit
|
34 |
* option to freely convert any JPEG, PNG or GIF (even animated ones!) to **WebP** for more Google love. <a rel="friend" href="http://blog.shortpixel.com/how-webp-images-can-speed-up-your-site/" target="_blank">How to enable WebP?</a>
|
35 |
* option to include the generated WebP images into the front-end pages by using the <picture> tag instead of <img>
|
@@ -53,7 +54,7 @@ Make an instant <a rel="friend" href="http://shortpixel.com/image-compression-te
|
|
53 |
* compatible with watermarking plugins
|
54 |
* option to deactivate auto-optimizing images on upload
|
55 |
* images that are optimized less that 5% are bonus
|
56 |
-
* WooCommerce compatible
|
57 |
* 40 days optimization report with all image details and overall statistics
|
58 |
* **free optimization credits for non-profits**, <a href="https://shortpixel.com/contact" target="_blank">contact us</a> for details
|
59 |
|
@@ -96,6 +97,10 @@ Let's get ShortPixel plugin running on your WordPress website:
|
|
96 |
|
97 |
== Frequently Asked Questions ==
|
98 |
|
|
|
|
|
|
|
|
|
99 |
= Can I use the same API Key on multiple web sites? =
|
100 |
Yes, you can.
|
101 |
As long as you have available credits you can use a single API Key on as many websites as you wish!
|
@@ -222,6 +227,17 @@ The ShortPixel team is here to help. <a href="https://shortpixel.com/contact">Co
|
|
222 |
|
223 |
== Changelog ==
|
224 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
225 |
= 4.6.0 =
|
226 |
* add a filter option to the Other Media table
|
227 |
* fixes in order to comply with WP plugin guidelines
|
1 |
=== ShortPixel Image Optimizer ===
|
2 |
Contributors: ShortPixel
|
3 |
+
Tags: compress, image, compression, optimize, image optimizer, image optimiser, image compression, resize, compress pdf, compress jpg, compress png, image compression
|
4 |
Requires at least: 3.2.0
|
5 |
Tested up to: 4.8
|
6 |
+
Stable tag: 4.7.0
|
7 |
License: GPLv2 or later
|
8 |
License URI: http://www.gnu.org/licenses/gpl-2.0.html
|
9 |
|
28 |
|
29 |
**Why is ShortPixel the best choice when it comes to image optimization or PDF compression?**
|
30 |
|
31 |
+
* popular plugin with over 50,000 active installations according to WordPress
|
32 |
* compress JPG, PNG, GIF (still or animated) images and also PDF documents
|
33 |
+
* option to automatically convert PNG to JPG if that will result in smaller images. Ideal for large images in PNG format.
|
34 |
* no file size limit
|
35 |
* option to freely convert any JPEG, PNG or GIF (even animated ones!) to **WebP** for more Google love. <a rel="friend" href="http://blog.shortpixel.com/how-webp-images-can-speed-up-your-site/" target="_blank">How to enable WebP?</a>
|
36 |
* option to include the generated WebP images into the front-end pages by using the <picture> tag instead of <img>
|
54 |
* compatible with watermarking plugins
|
55 |
* option to deactivate auto-optimizing images on upload
|
56 |
* images that are optimized less that 5% are bonus
|
57 |
+
* WooCommerce, WP offload S3 compatible
|
58 |
* 40 days optimization report with all image details and overall statistics
|
59 |
* **free optimization credits for non-profits**, <a href="https://shortpixel.com/contact" target="_blank">contact us</a> for details
|
60 |
|
97 |
|
98 |
== Frequently Asked Questions ==
|
99 |
|
100 |
+
= How does ShortPixel compare to other image optimisation plugins (e.g Smush, Imagify, TinyPNG, Kraken, EWWW)? =
|
101 |
+
ShortPixel has better compression rates, more features, supports backups and has very affordable one-time plans.
|
102 |
+
If you are serious about making an informed decision please take 10 minutes and read this <a rel="friend" href="https://blog.shortpixel.com/wp-image-optimization-wordpress-plugins/">article</a>.
|
103 |
+
|
104 |
= Can I use the same API Key on multiple web sites? =
|
105 |
Yes, you can.
|
106 |
As long as you have available credits you can use a single API Key on as many websites as you wish!
|
227 |
|
228 |
== Changelog ==
|
229 |
|
230 |
+
= 4.7.0 =
|
231 |
+
* convert PNG images to JPG option
|
232 |
+
* action called upon optimizing an image: do_action('shortpixel_image_optimized', $post_id);
|
233 |
+
* monitor Other Media folders for changes every hour
|
234 |
+
* button to delete all ShortPixel metadata making ShortPixel forget it optimized the images in Media Library
|
235 |
+
* plugin images at @2x
|
236 |
+
* cleanup Other Media tables
|
237 |
+
* fix wp-options that would not save in some circumstances
|
238 |
+
* fix generate webp <picture> tags when post guids are absolute URLs and image URLs are changed, or when site has HTTP/HTTPS versions
|
239 |
+
* fix problem with AMP pages when generating the <picture> tags - when using AMP for WP plugin AMP pages are not changed.
|
240 |
+
|
241 |
= 4.6.0 =
|
242 |
* add a filter option to the Other Media table
|
243 |
* fixes in order to comply with WP plugin guidelines
|
res/css/short-pixel.css
CHANGED
@@ -284,7 +284,7 @@ div.shortpixel-modal {
|
|
284 |
width: 30%; /* Could be more or less, depending on screen size */
|
285 |
min-width: 300px; /* Could be more or less, depending on screen size */
|
286 |
}
|
287 |
-
div.shortpixel-modal .sp-close-button {
|
288 |
float: right;
|
289 |
margin-top: 0px;
|
290 |
background: transparent;
|
@@ -317,6 +317,7 @@ div.shortpixel-modal .sptw-modal-spinner {
|
|
317 |
width:98%;
|
318 |
background-color:white;
|
319 |
padding:10px 10px 0;
|
|
|
320 |
/*margin-top: 2em;*/
|
321 |
}
|
322 |
|
284 |
width: 30%; /* Could be more or less, depending on screen size */
|
285 |
min-width: 300px; /* Could be more or less, depending on screen size */
|
286 |
}
|
287 |
+
div.shortpixel-modal .sp-close-button, div.shortpixel-modal .sp-close-upgrade-button {
|
288 |
float: right;
|
289 |
margin-top: 0px;
|
290 |
background: transparent;
|
317 |
width:98%;
|
318 |
background-color:white;
|
319 |
padding:10px 10px 0;
|
320 |
+
position:relative;
|
321 |
/*margin-top: 2em;*/
|
322 |
}
|
323 |
|
res/img/slider.png
CHANGED
Binary file
|
res/img/slider@2x.png
ADDED
Binary file
|
res/js/short-pixel.js
CHANGED
@@ -274,10 +274,34 @@ var ShortPixel = function() {
|
|
274 |
});
|
275 |
return browseResponse;
|
276 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
277 |
|
278 |
function initFolderSelector() {
|
279 |
jQuery(".select-folder-button").click(function(){
|
280 |
-
jQuery(".sp-
|
281 |
jQuery(".sp-folder-picker").fileTree({
|
282 |
script: ShortPixel.browseContent,
|
283 |
//folderEvent: 'dblclick',
|
@@ -286,7 +310,7 @@ var ShortPixel = function() {
|
|
286 |
});
|
287 |
});
|
288 |
jQuery(".shortpixel-modal input.select-folder-cancel").click(function(){
|
289 |
-
jQuery(".sp-
|
290 |
});
|
291 |
jQuery(".shortpixel-modal input.select-folder").click(function(){
|
292 |
var subPath = jQuery("UL.jqueryFileTree LI.directory.selected A").attr("rel").trim();
|
@@ -295,7 +319,7 @@ var ShortPixel = function() {
|
|
295 |
if(fullPath.slice(-1) == '/') fullPath = fullPath.slice(0, -1);
|
296 |
jQuery("#addCustomFolder").val(fullPath);
|
297 |
jQuery("#addCustomFolderView").val(fullPath);
|
298 |
-
jQuery(".sp-
|
299 |
} else {
|
300 |
alert("Please select a folder from the list.");
|
301 |
}
|
@@ -353,6 +377,15 @@ var ShortPixel = function() {
|
|
353 |
noticeTpl.after(notice);
|
354 |
notice.css("display", "block");
|
355 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
356 |
|
357 |
function removeBulkMsg(me) {
|
358 |
jQuery(me).parent().parent().remove();
|
@@ -485,11 +518,14 @@ var ShortPixel = function() {
|
|
485 |
initFolderSelector : initFolderSelector,
|
486 |
browseContent : browseContent,
|
487 |
getBackupSize : getBackupSize,
|
|
|
|
|
488 |
bulkShowLengthyMsg : bulkShowLengthyMsg,
|
489 |
bulkHideLengthyMsg : bulkHideLengthyMsg,
|
490 |
bulkShowMaintenanceMsg : bulkShowMaintenanceMsg,
|
491 |
bulkHideMaintenanceMsg : bulkHideMaintenanceMsg,
|
492 |
bulkShowError : bulkShowError,
|
|
|
493 |
removeBulkMsg : removeBulkMsg,
|
494 |
isCustomImageId : isCustomImageId,
|
495 |
recheckQuota : recheckQuota,
|
274 |
});
|
275 |
return browseResponse;
|
276 |
}
|
277 |
+
|
278 |
+
function proposeUpgrade() {
|
279 |
+
//first open the popup window with the spinner
|
280 |
+
jQuery("#shortPixelProposeUpgrade .sp-modal-body").addClass('sptw-modal-spinner');
|
281 |
+
jQuery("#shortPixelProposeUpgrade .sp-modal-body").html("");
|
282 |
+
jQuery("#shortPixelProposeUpgradeShade").css("display", "block");
|
283 |
+
jQuery("#shortPixelProposeUpgrade").removeClass('shortpixel-hide');
|
284 |
+
//get proposal from server
|
285 |
+
var browseData = { 'action': 'shortpixel_propose_upgrade'};
|
286 |
+
jQuery.ajax({
|
287 |
+
type: "POST",
|
288 |
+
url: ShortPixel.AJAX_URL,
|
289 |
+
data: browseData,
|
290 |
+
success: function(response) {
|
291 |
+
jQuery("#shortPixelProposeUpgrade .sp-modal-body").removeClass('sptw-modal-spinner');
|
292 |
+
jQuery("#shortPixelProposeUpgrade .sp-modal-body").html(response);
|
293 |
+
}
|
294 |
+
});
|
295 |
+
}
|
296 |
+
|
297 |
+
function closeProposeUpgrade() {
|
298 |
+
jQuery("#shortPixelProposeUpgradeShade").css("display", "none");
|
299 |
+
jQuery("#shortPixelProposeUpgrade").addClass('shortpixel-hide');
|
300 |
+
}
|
301 |
|
302 |
function initFolderSelector() {
|
303 |
jQuery(".select-folder-button").click(function(){
|
304 |
+
jQuery(".sp-folder-picker-shade").css("display", "block");
|
305 |
jQuery(".sp-folder-picker").fileTree({
|
306 |
script: ShortPixel.browseContent,
|
307 |
//folderEvent: 'dblclick',
|
310 |
});
|
311 |
});
|
312 |
jQuery(".shortpixel-modal input.select-folder-cancel").click(function(){
|
313 |
+
jQuery(".sp-folder-picker-shade").css("display", "none");
|
314 |
});
|
315 |
jQuery(".shortpixel-modal input.select-folder").click(function(){
|
316 |
var subPath = jQuery("UL.jqueryFileTree LI.directory.selected A").attr("rel").trim();
|
319 |
if(fullPath.slice(-1) == '/') fullPath = fullPath.slice(0, -1);
|
320 |
jQuery("#addCustomFolder").val(fullPath);
|
321 |
jQuery("#addCustomFolderView").val(fullPath);
|
322 |
+
jQuery(".sp-folder-picker-shade").css("display", "none");
|
323 |
} else {
|
324 |
alert("Please select a folder from the list.");
|
325 |
}
|
377 |
noticeTpl.after(notice);
|
378 |
notice.css("display", "block");
|
379 |
}
|
380 |
+
|
381 |
+
function confirmBulkAction(type, e) {
|
382 |
+
if(!confirm(_spTr['confirmBulk' + type])) {
|
383 |
+
e.stopPropagation();
|
384 |
+
e.preventDefault();
|
385 |
+
return false;
|
386 |
+
}
|
387 |
+
return true;
|
388 |
+
}
|
389 |
|
390 |
function removeBulkMsg(me) {
|
391 |
jQuery(me).parent().parent().remove();
|
518 |
initFolderSelector : initFolderSelector,
|
519 |
browseContent : browseContent,
|
520 |
getBackupSize : getBackupSize,
|
521 |
+
proposeUpgrade : proposeUpgrade,
|
522 |
+
closeProposeUpgrade : closeProposeUpgrade,
|
523 |
bulkShowLengthyMsg : bulkShowLengthyMsg,
|
524 |
bulkHideLengthyMsg : bulkHideLengthyMsg,
|
525 |
bulkShowMaintenanceMsg : bulkShowMaintenanceMsg,
|
526 |
bulkHideMaintenanceMsg : bulkHideMaintenanceMsg,
|
527 |
bulkShowError : bulkShowError,
|
528 |
+
confirmBulkAction : confirmBulkAction,
|
529 |
removeBulkMsg : removeBulkMsg,
|
530 |
isCustomImageId : isCustomImageId,
|
531 |
recheckQuota : recheckQuota,
|
shortpixel_api.php
CHANGED
@@ -580,6 +580,8 @@ class ShortPixelAPI {
|
|
580 |
$meta->setStatus(2);
|
581 |
|
582 |
$itemHandler->updateMeta($meta);
|
|
|
|
|
583 |
if(!$originalSpace) { //das kann nicht sein, alles klar?!
|
584 |
throw new Exception("OriginalSpace = 0. APIResponse" . json_encode($APIresponse));
|
585 |
}
|
580 |
$meta->setStatus(2);
|
581 |
|
582 |
$itemHandler->updateMeta($meta);
|
583 |
+
$itemHandler->doActions();
|
584 |
+
|
585 |
if(!$originalSpace) { //das kann nicht sein, alles klar?!
|
586 |
throw new Exception("OriginalSpace = 0. APIResponse" . json_encode($APIresponse));
|
587 |
}
|
wp-shortpixel.php
CHANGED
@@ -3,7 +3,7 @@
|
|
3 |
* Plugin Name: ShortPixel Image Optimizer
|
4 |
* Plugin URI: https://shortpixel.com/
|
5 |
* Description: ShortPixel optimizes images automatically, while guarding the quality of your images. Check your <a href="options-general.php?page=wp-shortpixel" target="_blank">Settings > ShortPixel</a> page on how to start optimizing your image library and make your website load faster.
|
6 |
-
* Version: 4.
|
7 |
* Author: ShortPixel
|
8 |
* Author URI: https://shortpixel.com
|
9 |
* Text Domain: shortpixel-image-optimiser
|
@@ -12,19 +12,22 @@
|
|
12 |
|
13 |
define('SHORTPIXEL_RESET_ON_ACTIVATE', false); //if true TODO set false
|
14 |
//define('SHORTPIXEL_DEBUG', true);
|
|
|
15 |
|
16 |
define('SHORTPIXEL_PLUGIN_FILE', __FILE__);
|
17 |
|
18 |
define('SHORTPIXEL_AFFILIATE_CODE', '');
|
19 |
|
20 |
-
define('SHORTPIXEL_IMAGE_OPTIMISER_VERSION', "4.
|
21 |
define('SHORTPIXEL_MAX_TIMEOUT', 10);
|
22 |
define('SHORTPIXEL_VALIDATE_MAX_TIMEOUT', 15);
|
23 |
define('SHORTPIXEL_BACKUP', 'ShortpixelBackups');
|
24 |
define('SHORTPIXEL_MAX_API_RETRIES', 50);
|
25 |
define('SHORTPIXEL_MAX_ERR_RETRIES', 5);
|
26 |
define('SHORTPIXEL_MAX_FAIL_RETRIES', 3);
|
27 |
-
|
|
|
|
|
28 |
|
29 |
define('SHORTPIXEL_MAX_EXECUTION_TIME', ini_get('max_execution_time'));
|
30 |
|
@@ -75,6 +78,15 @@ function shortPixelHandleImageUploadHook($meta, $ID = null) {
|
|
75 |
return $pluginInstance->handleMediaLibraryImageUpload($meta, $ID);
|
76 |
}
|
77 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
78 |
function shortPixelNggAdd($image) {
|
79 |
global $pluginInstance;
|
80 |
if(!isset($pluginInstance)) {
|
@@ -96,8 +108,12 @@ function shortPixelDeactivatePlugin () {
|
|
96 |
|
97 |
//Picture generation, hooked on the_content filter
|
98 |
function shortPixelConvertImgToPictureAddWebp($content) {
|
|
|
|
|
|
|
|
|
99 |
require_once('class/front/img-to-picture-webp.php');
|
100 |
-
return ShortPixelImgToPictureWebp::convert($content) . "<!-- PICTURE TAGS BY SHORTPIXEL -->";
|
101 |
}
|
102 |
function shortPixelAddPictureJs() {
|
103 |
// Don't do anything with the RSS feed.
|
@@ -127,6 +143,10 @@ if ( !function_exists( 'vc_action' ) || vc_action() !== 'vc_inline' ) { //handle
|
|
127 |
add_action( 'init', 'shortpixelInit');
|
128 |
add_action('ngg_added_new_image', 'shortPixelNggAdd');
|
129 |
|
|
|
|
|
|
|
|
|
130 |
$autoMediaLibrary = get_option('wp-short-pixel-auto-media-library');
|
131 |
if($autoMediaLibrary) {
|
132 |
add_filter( 'wp_generate_attachment_metadata', 'shortPixelHandleImageUploadHook', 10, 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: 4.7.0
|
7 |
* Author: ShortPixel
|
8 |
* Author URI: https://shortpixel.com
|
9 |
* Text Domain: shortpixel-image-optimiser
|
12 |
|
13 |
define('SHORTPIXEL_RESET_ON_ACTIVATE', false); //if true TODO set false
|
14 |
//define('SHORTPIXEL_DEBUG', true);
|
15 |
+
//define('SHORTPIXEL_DEBUG_TARGET', true);
|
16 |
|
17 |
define('SHORTPIXEL_PLUGIN_FILE', __FILE__);
|
18 |
|
19 |
define('SHORTPIXEL_AFFILIATE_CODE', '');
|
20 |
|
21 |
+
define('SHORTPIXEL_IMAGE_OPTIMISER_VERSION', "4.7.0");
|
22 |
define('SHORTPIXEL_MAX_TIMEOUT', 10);
|
23 |
define('SHORTPIXEL_VALIDATE_MAX_TIMEOUT', 15);
|
24 |
define('SHORTPIXEL_BACKUP', 'ShortpixelBackups');
|
25 |
define('SHORTPIXEL_MAX_API_RETRIES', 50);
|
26 |
define('SHORTPIXEL_MAX_ERR_RETRIES', 5);
|
27 |
define('SHORTPIXEL_MAX_FAIL_RETRIES', 3);
|
28 |
+
if(!defined('SHORTPIXEL_MAX_THUMBS')) { //can be defined in wp-config.php
|
29 |
+
define('SHORTPIXEL_MAX_THUMBS', 100);
|
30 |
+
}
|
31 |
|
32 |
define('SHORTPIXEL_MAX_EXECUTION_TIME', ini_get('max_execution_time'));
|
33 |
|
78 |
return $pluginInstance->handleMediaLibraryImageUpload($meta, $ID);
|
79 |
}
|
80 |
|
81 |
+
function shortPixelPng2JpgHook($params) {
|
82 |
+
global $pluginInstance;
|
83 |
+
if(!isset($pluginInstance)) {
|
84 |
+
require_once('wp-shortpixel-req.php');
|
85 |
+
$pluginInstance = new WPShortPixel;
|
86 |
+
}
|
87 |
+
return $pluginInstance->convertPng2Jpg($params);
|
88 |
+
}
|
89 |
+
|
90 |
function shortPixelNggAdd($image) {
|
91 |
global $pluginInstance;
|
92 |
if(!isset($pluginInstance)) {
|
108 |
|
109 |
//Picture generation, hooked on the_content filter
|
110 |
function shortPixelConvertImgToPictureAddWebp($content) {
|
111 |
+
if(function_exists('is_amp_endpoint') && is_amp_endpoint()) {
|
112 |
+
//for AMP pages the <picture> tag is not allowed
|
113 |
+
return $content;
|
114 |
+
}
|
115 |
require_once('class/front/img-to-picture-webp.php');
|
116 |
+
return ShortPixelImgToPictureWebp::convert($content);// . "<!-- PICTURE TAGS BY SHORTPIXEL -->";
|
117 |
}
|
118 |
function shortPixelAddPictureJs() {
|
119 |
// Don't do anything with the RSS feed.
|
143 |
add_action( 'init', 'shortpixelInit');
|
144 |
add_action('ngg_added_new_image', 'shortPixelNggAdd');
|
145 |
|
146 |
+
$autoPng2Jpg = get_option('wp-short-pixel-png2jpg');
|
147 |
+
if($autoPng2Jpg) {
|
148 |
+
add_action( 'wp_handle_upload', 'shortPixelPng2JpgHook');
|
149 |
+
}
|
150 |
$autoMediaLibrary = get_option('wp-short-pixel-auto-media-library');
|
151 |
if($autoMediaLibrary) {
|
152 |
add_filter( 'wp_generate_attachment_metadata', 'shortPixelHandleImageUploadHook', 10, 2 );
|