Version Description
Release date November 28, 2022
* New: added a filter to force a file check for WebP/AVIF if they were manually deleted from disk;
* Fix: if only small WebPs are available, include the JPG version in the picture
tag to avoid blurry images;
* Fix: the notification about unlisted thumbnails incorrectly reported WebP and AVIF files;
* Fix: improved integration with WP Offload Media by including Retina images in virtual/offload file checks;
* Fix: if the main file was optimized but some thumbnails did not have WebP/AVIF, it was not displayed correctly in the UI;
* Fix: added a % margin when generating WebPs/AVIF, so that files that are only a few bytes larger are also generated;
* Fix: when running WP-CLI, the percentage of finished items in the total was calculated incorrectly;
* Fix: the settings page crashed in certain cases for new accounts;
* Tweak: various CSS fixes and improvements on the Media Library, especially for cases with many thumbnails;
* Language: 2 new strings added, 2 updated, 0 fuzzed, and 0 deprecated.
Release Info
Developer | petredobrescu |
Plugin | ShortPixel Image Optimizer |
Version | 5.1.4 |
Comparing to | |
See all releases |
Code changes from version 5.1.3 to 5.1.4
- build/shortpixel/replacer/src/Replacer.php +10 -0
- class/Controller/ApiController.php +22 -2
- class/Controller/FileSystemController.php +1 -0
- class/Controller/OptimizeController.php +7 -2
- class/Controller/Queue/Queue.php +1 -1
- class/Controller/StatsController.php +8 -3
- class/Helper/UiHelper.php +51 -3
- class/Model/AdminNotices/AvifNotice.php +0 -4
- class/Model/Image/ImageModel.php +24 -35
- class/Model/Image/MediaLibraryModel.php +28 -25
- class/Model/Image/MediaLibraryThumbnailModel.php +15 -3
- class/external/uncode.php +0 -1
- class/external/wp-cli/wp-cli-base.php +2 -1
- class/front/img-to-picture-webp.php +7 -7
- class/view/bulk/part-selection.php +2 -1
- class/view/bulk/part-summary.php +8 -2
- readme.txt +33 -2
- res/css/shortpixel-admin.css +3 -0
- res/css/shortpixel-admin.css.map +1 -1
- res/scss/view/_list-item.scss +3 -0
- wp-shortpixel.php +2 -2
@@ -38,11 +38,21 @@ class Replacer
|
|
38 |
$this->source_url = $url;
|
39 |
}
|
40 |
|
|
|
|
|
|
|
|
|
|
|
41 |
public function setTarget($url)
|
42 |
{
|
43 |
$this->target_url = $url;
|
44 |
}
|
45 |
|
|
|
|
|
|
|
|
|
|
|
46 |
public function setSourceMeta($meta)
|
47 |
{
|
48 |
$this->source_metadata = $meta;
|
38 |
$this->source_url = $url;
|
39 |
}
|
40 |
|
41 |
+
public function getSource()
|
42 |
+
{
|
43 |
+
return $this->source_url;
|
44 |
+
}
|
45 |
+
|
46 |
public function setTarget($url)
|
47 |
{
|
48 |
$this->target_url = $url;
|
49 |
}
|
50 |
|
51 |
+
public function getTarget()
|
52 |
+
{
|
53 |
+
return $this->target_url;
|
54 |
+
}
|
55 |
+
|
56 |
public function setSourceMeta($meta)
|
57 |
{
|
58 |
$this->source_metadata = $meta;
|
@@ -585,7 +585,7 @@ class ApiController
|
|
585 |
$webpName = $originalFile->getFileBase() . '.webp';
|
586 |
$webpDownloadResult = false;
|
587 |
|
588 |
-
if ($fileData->$webpTypeSize
|
589 |
{
|
590 |
$results[$imageName]['webp'] = $this->returnOk(self::STATUS_OPTIMIZED_BIGGER, __('Special file type bigger than core file','shortpixel-image-optimiser'));
|
591 |
}
|
@@ -608,7 +608,7 @@ class ApiController
|
|
608 |
{
|
609 |
$avifName = $originalFile->getFileBase() . '.avif';
|
610 |
|
611 |
-
if ($fileData->$avifTypeSize
|
612 |
{
|
613 |
$results[$imageName]['avif'] = $this->returnOk(self::STATUS_OPTIMIZED_BIGGER, __('Special file type bigger than core file','shortpixel-image-optimiser'));
|
614 |
}
|
@@ -879,6 +879,26 @@ class ApiController
|
|
879 |
return $result;
|
880 |
}
|
881 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
882 |
|
883 |
|
884 |
} // class
|
585 |
$webpName = $originalFile->getFileBase() . '.webp';
|
586 |
$webpDownloadResult = false;
|
587 |
|
588 |
+
if (false === $this->checkFileSizeMargin($checkFileSize, $fileData->$webpTypeSize)) // if file is bigger.
|
589 |
{
|
590 |
$results[$imageName]['webp'] = $this->returnOk(self::STATUS_OPTIMIZED_BIGGER, __('Special file type bigger than core file','shortpixel-image-optimiser'));
|
591 |
}
|
608 |
{
|
609 |
$avifName = $originalFile->getFileBase() . '.avif';
|
610 |
|
611 |
+
if ($this->checkFileSizeMargin($checkFileSize, $fileData->$avifTypeSize)) // if file is bigger.
|
612 |
{
|
613 |
$results[$imageName]['avif'] = $this->returnOk(self::STATUS_OPTIMIZED_BIGGER, __('Special file type bigger than core file','shortpixel-image-optimiser'));
|
614 |
}
|
879 |
return $result;
|
880 |
}
|
881 |
|
882 |
+
private function checkFileSizeMargin($fileSize, $resultSize)
|
883 |
+
{
|
884 |
+
// This is ok.
|
885 |
+
if ($fileSize >= $resultSize)
|
886 |
+
return true;
|
887 |
+
|
888 |
+
$percentage = apply_filters('shortpixel/api/filesizeMargin', 5);
|
889 |
+
|
890 |
+
$increase = (($resultSize - $fileSize) / $fileSize) * 100;
|
891 |
+
|
892 |
+
if ($increase <= $percentage)
|
893 |
+
return true;
|
894 |
+
|
895 |
+
return false;
|
896 |
+
|
897 |
+
|
898 |
+
|
899 |
+
|
900 |
+
}
|
901 |
+
|
902 |
|
903 |
|
904 |
} // class
|
@@ -59,6 +59,7 @@ Class FileSystemController extends \ShortPixel\Controller
|
|
59 |
{
|
60 |
self::$mediaItems[$id] = $imageObj;
|
61 |
}
|
|
|
62 |
return $imageObj;
|
63 |
}
|
64 |
|
59 |
{
|
60 |
self::$mediaItems[$id] = $imageObj;
|
61 |
}
|
62 |
+
|
63 |
return $imageObj;
|
64 |
}
|
65 |
|
@@ -985,8 +985,13 @@ class OptimizeController
|
|
985 |
$perc = $object->stats->$key;
|
986 |
}
|
987 |
else
|
988 |
-
|
989 |
-
|
|
|
|
|
|
|
|
|
|
|
990 |
$object->stats->$key = $perc;
|
991 |
}
|
992 |
elseif (is_numeric($object->stats->$key)) // add only if number.
|
985 |
$perc = $object->stats->$key;
|
986 |
}
|
987 |
else
|
988 |
+
{
|
989 |
+
$total = $results->custom->stats->total + $results->media->stats->total;
|
990 |
+
$done = $results->custom->stats->done + $results->media->stats->done;
|
991 |
+
$fatal = $results->custom->stats->fatal_errors + $results->media->stats->fatal_errors;
|
992 |
+
$perc = round((100 / $total) * ($done + $fatal), 0, PHP_ROUND_HALF_DOWN);
|
993 |
+
// $perc = round(($object->stats->$key + $value) / 2); //exceptionnes.
|
994 |
+
}
|
995 |
$object->stats->$key = $perc;
|
996 |
}
|
997 |
elseif (is_numeric($object->stats->$key)) // add only if number.
|
@@ -352,7 +352,7 @@ abstract class Queue
|
|
352 |
$stats->total = $stats->in_queue + $stats->fatal_errors + $stats->errors + $stats->done + $stats->in_process;
|
353 |
if ($stats->total > 0)
|
354 |
{
|
355 |
-
$stats->percentage_done = round(
|
356 |
}
|
357 |
else
|
358 |
$stats->percentage_done = 100; // no items means all done.
|
352 |
$stats->total = $stats->in_queue + $stats->fatal_errors + $stats->errors + $stats->done + $stats->in_process;
|
353 |
if ($stats->total > 0)
|
354 |
{
|
355 |
+
$stats->percentage_done = round((100 / $stats->total) * ($stats->done + $stats->fatal_errors), 0, PHP_ROUND_HALF_DOWN);
|
356 |
}
|
357 |
else
|
358 |
$stats->percentage_done = 100; // no items means all done.
|
@@ -68,9 +68,14 @@ class StatsController extends \ShortPixel\Controller
|
|
68 |
$totalOptimized = $this->model->get('totalOptimized');
|
69 |
$totalOriginal = $this->model->get('totalOriginal');
|
70 |
|
71 |
-
|
72 |
-
|
73 |
-
|
|
|
|
|
|
|
|
|
|
|
74 |
}
|
75 |
|
76 |
// This is not functional @todo
|
68 |
$totalOptimized = $this->model->get('totalOptimized');
|
69 |
$totalOriginal = $this->model->get('totalOriginal');
|
70 |
|
71 |
+
$average = 0;
|
72 |
+
|
73 |
+
if ($totalOptimized > 0 && $totalOriginal > 0)
|
74 |
+
{
|
75 |
+
$average = round(( 1 - ( $totalOptimized / $totalOriginal ) ) * 100, 2);
|
76 |
+
}
|
77 |
+
|
78 |
+
return $average;
|
79 |
}
|
80 |
|
81 |
// This is not functional @todo
|
@@ -96,14 +96,32 @@ class UiHelper
|
|
96 |
|
97 |
if (isset($improvements['thumbnails']))
|
98 |
{
|
|
|
99 |
$output .= '<div class="thumbnails optimized">';
|
100 |
if ($thumbsTotal > $thumbsDone)
|
101 |
$output .= '<div class="totals">' . sprintf(__('+%s of %s thumbnails optimized','shortpixel-image-optimiser'), self::formatNumber($thumbsDone,0), self::formatNumber($thumbsTotal,0)) . '</div>';
|
102 |
elseif ($thumbsDone > 0)
|
103 |
$output .= '<div class="totals">' . sprintf(__('+%s thumbnails optimized','shortpixel-image-optimiser'), self::formatNumber($thumbsDone, 0)) . '</div>';
|
104 |
|
105 |
-
|
106 |
$improvs = array();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
107 |
// Quality Check
|
108 |
foreach($improvements['thumbnails'] as $thumbName => $thumbStat)
|
109 |
{
|
@@ -135,6 +153,10 @@ class UiHelper
|
|
135 |
</div>";
|
136 |
|
137 |
}
|
|
|
|
|
|
|
|
|
138 |
$output .= "</div> <!-- /thumb-wrapper -->";
|
139 |
}
|
140 |
$output .= "</div> <!-- /thumb optimized -->";
|
@@ -152,21 +174,44 @@ class UiHelper
|
|
152 |
{
|
153 |
$output .= '<div class="filetype avif">' . sprintf(__('+%s Avif images ','shortpixel-image-optimiser') , $avifsTotal) . '</div>';
|
154 |
}
|
|
|
155 |
if ($imageObj->isOptimized() && $imageObj->isProcessable())
|
156 |
{
|
157 |
list($urls, $optimizable) = $imageObj->getCountOptimizeData('thumbnails');
|
158 |
list($webpUrls, $webpCount) = $imageObj->getCountOptimizeData('webp');
|
159 |
list($avifUrls, $avifCount) = $imageObj->getCountOptimizeData('avif');
|
|
|
|
|
|
|
160 |
// Todo check if Webp / Acif is active, check for unoptimized items
|
161 |
// $processWebp = ($imageObj->isProcessableFileType('webp')) ? true : false;
|
162 |
// $processAvif = ($imageObj->isProcessableFileType('avif')) ? true : false;
|
163 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
164 |
if ($optimizable > 0)
|
165 |
{
|
166 |
-
$output .= '<div class="thumbs-todo"><h4>' . sprintf(__('%d to optimize', 'shortpixel-image-optimiser'), $optimizable) . '</h4>';
|
167 |
$output .= "<span>";
|
168 |
foreach($urls as $optObj)
|
169 |
{
|
|
|
|
|
|
|
170 |
$output .= substr($optObj, strrpos($optObj, '/')+1) . '<br>';
|
171 |
}
|
172 |
$output .= "</span>";
|
@@ -180,7 +225,10 @@ class UiHelper
|
|
180 |
$output .= "<span>";
|
181 |
foreach($webpUrls as $optObj)
|
182 |
{
|
183 |
-
|
|
|
|
|
|
|
184 |
}
|
185 |
$output .= "</span>";
|
186 |
$output .= '</div>';
|
96 |
|
97 |
if (isset($improvements['thumbnails']))
|
98 |
{
|
99 |
+
|
100 |
$output .= '<div class="thumbnails optimized">';
|
101 |
if ($thumbsTotal > $thumbsDone)
|
102 |
$output .= '<div class="totals">' . sprintf(__('+%s of %s thumbnails optimized','shortpixel-image-optimiser'), self::formatNumber($thumbsDone,0), self::formatNumber($thumbsTotal,0)) . '</div>';
|
103 |
elseif ($thumbsDone > 0)
|
104 |
$output .= '<div class="totals">' . sprintf(__('+%s thumbnails optimized','shortpixel-image-optimiser'), self::formatNumber($thumbsDone, 0)) . '</div>';
|
105 |
|
|
|
106 |
$improvs = array();
|
107 |
+
|
108 |
+
uasort($improvements['thumbnails'], function ($a, $b) {
|
109 |
+
//return $b[0] <=> $a[0]; // @todo Efficient code to use once PHP 5 support is done.
|
110 |
+
if ($a == $b) {
|
111 |
+
return 0;
|
112 |
+
}
|
113 |
+
return ($b < $a) ? -1 : 1;
|
114 |
+
});
|
115 |
+
|
116 |
+
$cutoff = false;
|
117 |
+
$thumbCount = count($improvements['thumbnails']);
|
118 |
+
if ($thumbCount > 20)
|
119 |
+
{
|
120 |
+
$improvements['thumbnails'] = array_slice($improvements['thumbnails'], 0, 15, true);
|
121 |
+
$cutoff = true;
|
122 |
+
}
|
123 |
+
|
124 |
+
|
125 |
// Quality Check
|
126 |
foreach($improvements['thumbnails'] as $thumbName => $thumbStat)
|
127 |
{
|
153 |
</div>";
|
154 |
|
155 |
}
|
156 |
+
if (true === $cutoff)
|
157 |
+
{
|
158 |
+
$output .= '<div class="thumb"><span class="cutoff">' . sprintf(__('+ %d more', 'shortpixel-image-optimiser'), ($thumbCount - 15)) . '</span></div>';
|
159 |
+
}
|
160 |
$output .= "</div> <!-- /thumb-wrapper -->";
|
161 |
}
|
162 |
$output .= "</div> <!-- /thumb optimized -->";
|
174 |
{
|
175 |
$output .= '<div class="filetype avif">' . sprintf(__('+%s Avif images ','shortpixel-image-optimiser') , $avifsTotal) . '</div>';
|
176 |
}
|
177 |
+
|
178 |
if ($imageObj->isOptimized() && $imageObj->isProcessable())
|
179 |
{
|
180 |
list($urls, $optimizable) = $imageObj->getCountOptimizeData('thumbnails');
|
181 |
list($webpUrls, $webpCount) = $imageObj->getCountOptimizeData('webp');
|
182 |
list($avifUrls, $avifCount) = $imageObj->getCountOptimizeData('avif');
|
183 |
+
|
184 |
+
|
185 |
+
$maxList = 10;
|
186 |
// Todo check if Webp / Acif is active, check for unoptimized items
|
187 |
// $processWebp = ($imageObj->isProcessableFileType('webp')) ? true : false;
|
188 |
// $processAvif = ($imageObj->isProcessableFileType('avif')) ? true : false;
|
189 |
|
190 |
+
if (count($urls) > $maxList)
|
191 |
+
{
|
192 |
+
$urls = array_slice($urls, 0, $maxList, true);
|
193 |
+
$urls[] = '...';
|
194 |
+
}
|
195 |
+
if (count($webpUrls) > $maxList)
|
196 |
+
{
|
197 |
+
$webpUrls = array_slice($webpUrls, 0, $maxList, true);
|
198 |
+
$webpUrls[] = '...';
|
199 |
+
}
|
200 |
+
if (count($avifUrls) > $maxList)
|
201 |
+
{
|
202 |
+
$avifUrls = array_slice($avifUrls, 0, $maxList, true);
|
203 |
+
$avifUrls[] = '...';
|
204 |
+
}
|
205 |
+
|
206 |
if ($optimizable > 0)
|
207 |
{
|
208 |
+
$output .= '<div class="thumbs-todo"><h4>' . sprintf(__('%d images to optimize', 'shortpixel-image-optimiser'), $optimizable) . '</h4>';
|
209 |
$output .= "<span>";
|
210 |
foreach($urls as $optObj)
|
211 |
{
|
212 |
+
if ($optObj === '...')
|
213 |
+
$output .= $optObj;
|
214 |
+
else
|
215 |
$output .= substr($optObj, strrpos($optObj, '/')+1) . '<br>';
|
216 |
}
|
217 |
$output .= "</span>";
|
225 |
$output .= "<span>";
|
226 |
foreach($webpUrls as $optObj)
|
227 |
{
|
228 |
+
if ($optObj === '...')
|
229 |
+
$output .= $optObj;
|
230 |
+
else
|
231 |
+
$output .= self::convertImageTypeName(substr($optObj, strrpos($optObj, '/')+1), 'webp') . '<br>';
|
232 |
}
|
233 |
$output .= "</span>";
|
234 |
$output .= '</div>';
|
@@ -25,7 +25,6 @@ class AvifNotice extends \ShortPixel\Model\AdminNoticeModel
|
|
25 |
if (apply_filters('shortpixel/avifcheck/override', false) === true)
|
26 |
{ return; }
|
27 |
|
28 |
-
Log::addTemp('Checking Avif');
|
29 |
|
30 |
if ($cache->getItem('avif_server_check')->exists() === false)
|
31 |
{
|
@@ -33,7 +32,6 @@ class AvifNotice extends \ShortPixel\Model\AdminNoticeModel
|
|
33 |
$headers = get_headers($url);
|
34 |
$is_error = true;
|
35 |
|
36 |
-
Log::addTemp('Avif check headers', $headers);
|
37 |
$this->addData('headers', $headers);
|
38 |
// Defaults.
|
39 |
$this->error_message = __('AVIF server test failed. Your server may not be configured to display AVIF files correctly. Serving AVIF might cause your images not to load. Check your images, disable the AVIF option, or update your web server configuration.', 'shortpixel-image-optimiser');
|
@@ -56,8 +54,6 @@ Log::addTemp('Avif check headers', $headers);
|
|
56 |
}
|
57 |
}
|
58 |
|
59 |
-
Log::addTemp('ContentType', $contentType);
|
60 |
-
|
61 |
// http not ok, redirect etc. Shouldn't happen.
|
62 |
if (is_null($response) || strpos($response, '200') === false)
|
63 |
{
|
25 |
if (apply_filters('shortpixel/avifcheck/override', false) === true)
|
26 |
{ return; }
|
27 |
|
|
|
28 |
|
29 |
if ($cache->getItem('avif_server_check')->exists() === false)
|
30 |
{
|
32 |
$headers = get_headers($url);
|
33 |
$is_error = true;
|
34 |
|
|
|
35 |
$this->addData('headers', $headers);
|
36 |
// Defaults.
|
37 |
$this->error_message = __('AVIF server test failed. Your server may not be configured to display AVIF files correctly. Serving AVIF might cause your images not to load. Check your images, disable the AVIF option, or update your web server configuration.', 'shortpixel-image-optimiser');
|
54 |
}
|
55 |
}
|
56 |
|
|
|
|
|
57 |
// http not ok, redirect etc. Shouldn't happen.
|
58 |
if (is_null($response) || strpos($response, '200') === false)
|
59 |
{
|
@@ -149,16 +149,16 @@ abstract class ImageModel extends \ShortPixel\Model\File\FileModel
|
|
149 |
return false;
|
150 |
}
|
151 |
|
152 |
-
|
153 |
-
if ($this->getExtension() == 'pdf')
|
154 |
-
return false;
|
155 |
-
|
156 |
-
if ($type == 'webp' && ! $settings->createWebp)
|
157 |
return false;
|
158 |
|
159 |
if ($type == 'avif' && ! $settings->createAvif)
|
160 |
return false;
|
161 |
|
|
|
|
|
|
|
|
|
162 |
$imgObj = $this->getImageType($type);
|
163 |
|
164 |
// if this image doesn't have webp / avif, it can be processed.
|
@@ -341,39 +341,22 @@ abstract class ImageModel extends \ShortPixel\Model\File\FileModel
|
|
341 |
$count = 0;
|
342 |
$urls = array();
|
343 |
$i = 0;
|
344 |
-
foreach($optimizeData['params'] as $sizeName => $data)
|
345 |
-
{
|
346 |
|
347 |
-
|
348 |
-
{
|
349 |
-
case 'thumbnails';
|
350 |
-
if (isset($data['image']) && $data['image'] === true)
|
351 |
-
{
|
352 |
-
$count++;
|
353 |
-
$urls[] = $optimizeData['paths'][$sizeName];
|
354 |
-
}
|
355 |
-
break;
|
356 |
-
case 'webp';
|
357 |
-
if (isset($data['webp']) && $data['webp'] === true)
|
358 |
-
{
|
359 |
-
$count++;
|
360 |
-
$urls[] = $optimizeData['paths'][$sizeName];
|
361 |
-
}
|
362 |
-
break;
|
363 |
-
case 'avif';
|
364 |
-
if (isset($data['avif']) && $data['avif'] === true)
|
365 |
-
{
|
366 |
-
$count++;
|
367 |
-
$urls[] = $optimizeData['paths'][$sizeName];
|
368 |
-
}
|
369 |
-
break;
|
370 |
|
371 |
-
|
372 |
-
|
373 |
-
}
|
374 |
|
|
|
|
|
375 |
|
|
|
|
|
|
|
|
|
|
|
376 |
return array($urls, $count);
|
|
|
377 |
}
|
378 |
|
379 |
protected function getImageType($type = 'webp')
|
@@ -384,9 +367,15 @@ abstract class ImageModel extends \ShortPixel\Model\File\FileModel
|
|
384 |
|
385 |
if (! is_null($this->getMeta($type)))
|
386 |
{
|
|
|
|
|
387 |
$filepath = $this->getFileDir() . $this->getMeta($type);
|
388 |
$file = $fs->getFile($filepath);
|
389 |
-
|
|
|
|
|
|
|
|
|
390 |
}
|
391 |
|
392 |
if ($type == 'webp')
|
@@ -407,7 +396,7 @@ abstract class ImageModel extends \ShortPixel\Model\File\FileModel
|
|
407 |
$file = $fs->getFile($filepath);
|
408 |
|
409 |
// If double extension is enabled, but no file, check the alternative.
|
410 |
-
if (! $file->
|
411 |
{
|
412 |
if ($is_double)
|
413 |
$file = $fs->getFile($filepath);
|
149 |
return false;
|
150 |
}
|
151 |
|
152 |
+
if ($type == 'webp' && ! $settings->createWebp)
|
|
|
|
|
|
|
|
|
153 |
return false;
|
154 |
|
155 |
if ($type == 'avif' && ! $settings->createAvif)
|
156 |
return false;
|
157 |
|
158 |
+
// Pdf, no special files.
|
159 |
+
if ($this->getExtension() == 'pdf')
|
160 |
+
return false;
|
161 |
+
|
162 |
$imgObj = $this->getImageType($type);
|
163 |
|
164 |
// if this image doesn't have webp / avif, it can be processed.
|
341 |
$count = 0;
|
342 |
$urls = array();
|
343 |
$i = 0;
|
|
|
|
|
344 |
|
345 |
+
$params = $optimizeData['params'];
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
346 |
|
347 |
+
if ($param == 'thumbnails')
|
348 |
+
$param = 'image';
|
|
|
349 |
|
350 |
+
// Take the optimizeData and take key - param column, then check if the param (image/webp/avif) is true (filter) .
|
351 |
+
$combinedArray = array_filter(array_combine(array_keys($params), array_column($params, $param)));
|
352 |
|
353 |
+
$count = count($combinedArray);
|
354 |
+
foreach($combinedArray as $sizeName => $unneeded)
|
355 |
+
{
|
356 |
+
$urls[] = $optimizeData['paths'][$sizeName];
|
357 |
+
}
|
358 |
return array($urls, $count);
|
359 |
+
|
360 |
}
|
361 |
|
362 |
protected function getImageType($type = 'webp')
|
367 |
|
368 |
if (! is_null($this->getMeta($type)))
|
369 |
{
|
370 |
+
// Filter to disable assumption(s) on the file basis of imageType. Active when something has manually been deleted.
|
371 |
+
$metaCheck = apply_filters('shortpixel/image/filecheck', false);
|
372 |
$filepath = $this->getFileDir() . $this->getMeta($type);
|
373 |
$file = $fs->getFile($filepath);
|
374 |
+
|
375 |
+
if ($metaCheck === false)
|
376 |
+
{
|
377 |
+
return $file;
|
378 |
+
}
|
379 |
}
|
380 |
|
381 |
if ($type == 'webp')
|
396 |
$file = $fs->getFile($filepath);
|
397 |
|
398 |
// If double extension is enabled, but no file, check the alternative.
|
399 |
+
if (! $file->is_virtual() && ! $file->exists())
|
400 |
{
|
401 |
if ($is_double)
|
402 |
$file = $fs->getFile($filepath);
|
@@ -316,7 +316,8 @@ class MediaLibraryModel extends \ShortPixel\Model\Image\MediaLibraryThumbnailMod
|
|
316 |
|
317 |
if ($main)
|
318 |
{
|
319 |
-
|
|
|
320 |
}
|
321 |
}
|
322 |
|
@@ -324,7 +325,10 @@ class MediaLibraryModel extends \ShortPixel\Model\Image\MediaLibraryThumbnailMod
|
|
324 |
{
|
325 |
$retscaled = $this->original_file->getRetina();
|
326 |
if ($retscaled)
|
|
|
|
|
327 |
$this->retinas[$this->originalImageKey] = $retscaled; //see main
|
|
|
328 |
}
|
329 |
|
330 |
foreach ($this->thumbnails as $thumbname => $thumbObj)
|
@@ -515,9 +519,6 @@ class MediaLibraryModel extends \ShortPixel\Model\Image\MediaLibraryThumbnailMod
|
|
515 |
$resultObj = $files[$sizeName];
|
516 |
$thumbnail = $thumbObjs[$sizeName];
|
517 |
|
518 |
-
//Log::addTemp('Handle Optimize thumbnail', $thumbnail);
|
519 |
-
//Log::add
|
520 |
-
|
521 |
$thumbnail->handleOptimizedFileType($resultObj); // check for webps /etc
|
522 |
|
523 |
if ($thumbnail->isOptimized())
|
@@ -1223,6 +1224,10 @@ class MediaLibraryModel extends \ShortPixel\Model\Image\MediaLibraryThumbnailMod
|
|
1223 |
|
1224 |
if ($bool === true) // Is Processable just needs one job
|
1225 |
return true;
|
|
|
|
|
|
|
|
|
1226 |
}
|
1227 |
|
1228 |
}
|
@@ -2058,7 +2063,7 @@ class MediaLibraryModel extends \ShortPixel\Model\Image\MediaLibraryThumbnailMod
|
|
2058 |
$adminNotices->invokeLegacyNotice();
|
2059 |
}
|
2060 |
|
2061 |
-
Log::addDebug("Conversion of legacy: ", array($metadata));
|
2062 |
|
2063 |
$type = isset($data['type']) ? $this->legacyConvertType($data['type']) : '';
|
2064 |
|
@@ -2463,7 +2468,6 @@ class MediaLibraryModel extends \ShortPixel\Model\Image\MediaLibraryThumbnailMod
|
|
2463 |
// Setting must be active.
|
2464 |
/*if (! \wpSPIO()->settings()->optimizeUnlisted )
|
2465 |
return; */
|
2466 |
-
|
2467 |
$searchUnlisted = \wpSPIO()->settings()->optimizeUnlisted;
|
2468 |
|
2469 |
// Don't check this more than once per run-time.
|
@@ -2576,13 +2580,7 @@ class MediaLibraryModel extends \ShortPixel\Model\Image\MediaLibraryThumbnailMod
|
|
2576 |
$thumbs = array_values(preg_grep($pattern, $all_files));
|
2577 |
if (count($thumbs) > 0)
|
2578 |
$unlisted = array_merge($unlisted, $thumbs);
|
2579 |
-
// $thumbs = array_merge($thumbs, self::getFilesByPattern($dirPath, $pattern));
|
2580 |
|
2581 |
-
/*foreach($thumbsCandidates as $th) {
|
2582 |
-
if(preg_match($pattern, $th)) {
|
2583 |
-
$thumbs[]= $th;
|
2584 |
-
}
|
2585 |
-
} */
|
2586 |
}
|
2587 |
}
|
2588 |
}
|
@@ -2592,10 +2590,7 @@ class MediaLibraryModel extends \ShortPixel\Model\Image\MediaLibraryThumbnailMod
|
|
2592 |
// Quality check on the thumbs. Must exist, must be same extension.
|
2593 |
$added = false;
|
2594 |
|
2595 |
-
|
2596 |
-
{
|
2597 |
-
return $unlisted;
|
2598 |
-
}
|
2599 |
|
2600 |
foreach($unlisted as $unName)
|
2601 |
{
|
@@ -2610,12 +2605,19 @@ class MediaLibraryModel extends \ShortPixel\Model\Image\MediaLibraryThumbnailMod
|
|
2610 |
}
|
2611 |
elseif ($thumbObj->is_readable()) // exclude webps
|
2612 |
{
|
2613 |
-
|
2614 |
-
|
2615 |
-
|
2616 |
-
|
2617 |
-
|
2618 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2619 |
}
|
2620 |
else
|
2621 |
{
|
@@ -2623,9 +2625,10 @@ class MediaLibraryModel extends \ShortPixel\Model\Image\MediaLibraryThumbnailMod
|
|
2623 |
}
|
2624 |
}
|
2625 |
|
2626 |
-
|
2627 |
-
|
2628 |
-
|
|
|
2629 |
self::$unlistedChecked[] = $this->get('id');
|
2630 |
}
|
2631 |
|
316 |
|
317 |
if ($main)
|
318 |
{
|
319 |
+
$main->setName($this->mainImageKey);
|
320 |
+
$this->retinas[$this->mainImageKey] = $main; // to prevent any custom image sizes to get overwritten.
|
321 |
}
|
322 |
}
|
323 |
|
325 |
{
|
326 |
$retscaled = $this->original_file->getRetina();
|
327 |
if ($retscaled)
|
328 |
+
{
|
329 |
+
$retscaled->setName($this->originalImageKey);
|
330 |
$this->retinas[$this->originalImageKey] = $retscaled; //see main
|
331 |
+
}
|
332 |
}
|
333 |
|
334 |
foreach ($this->thumbnails as $thumbname => $thumbObj)
|
519 |
$resultObj = $files[$sizeName];
|
520 |
$thumbnail = $thumbObjs[$sizeName];
|
521 |
|
|
|
|
|
|
|
522 |
$thumbnail->handleOptimizedFileType($resultObj); // check for webps /etc
|
523 |
|
524 |
if ($thumbnail->isOptimized())
|
1224 |
|
1225 |
if ($bool === true) // Is Processable just needs one job
|
1226 |
return true;
|
1227 |
+
|
1228 |
+
if ($thumbnail->isOptimized() && true === $thumbnail->isProcessableAnyFileType())
|
1229 |
+
return true;
|
1230 |
+
|
1231 |
}
|
1232 |
|
1233 |
}
|
2063 |
$adminNotices->invokeLegacyNotice();
|
2064 |
}
|
2065 |
|
2066 |
+
Log::addDebug("Conversion of legacy: " . $this->get('id'), array($metadata));
|
2067 |
|
2068 |
$type = isset($data['type']) ? $this->legacyConvertType($data['type']) : '';
|
2069 |
|
2468 |
// Setting must be active.
|
2469 |
/*if (! \wpSPIO()->settings()->optimizeUnlisted )
|
2470 |
return; */
|
|
|
2471 |
$searchUnlisted = \wpSPIO()->settings()->optimizeUnlisted;
|
2472 |
|
2473 |
// Don't check this more than once per run-time.
|
2580 |
$thumbs = array_values(preg_grep($pattern, $all_files));
|
2581 |
if (count($thumbs) > 0)
|
2582 |
$unlisted = array_merge($unlisted, $thumbs);
|
|
|
2583 |
|
|
|
|
|
|
|
|
|
|
|
2584 |
}
|
2585 |
}
|
2586 |
}
|
2590 |
// Quality check on the thumbs. Must exist, must be same extension.
|
2591 |
$added = false;
|
2592 |
|
2593 |
+
$foundUnlisted = array(); // found and ready. Used for notice / check only
|
|
|
|
|
|
|
2594 |
|
2595 |
foreach($unlisted as $unName)
|
2596 |
{
|
2605 |
}
|
2606 |
elseif ($thumbObj->is_readable()) // exclude webps
|
2607 |
{
|
2608 |
+
if (true === $check_only)
|
2609 |
+
{
|
2610 |
+
$foundUnlisted[] = $unName;
|
2611 |
+
}
|
2612 |
+
else {
|
2613 |
+
$thumbObj->setName($unName);
|
2614 |
+
$thumbObj->setMeta('originalWidth', $thumbObj->get('width'));
|
2615 |
+
$thumbObj->setMeta('originalHeight', $thumbObj->get('height'));
|
2616 |
+
$thumbObj->setMeta('file', $thumbObj->getFileName() );
|
2617 |
+
$this->thumbnails[$unName] = $thumbObj;
|
2618 |
+
$added = true;
|
2619 |
+
}
|
2620 |
+
|
2621 |
}
|
2622 |
else
|
2623 |
{
|
2625 |
}
|
2626 |
}
|
2627 |
|
2628 |
+
if (true === $check_only)
|
2629 |
+
{
|
2630 |
+
return $foundUnlisted;
|
2631 |
+
}
|
2632 |
self::$unlistedChecked[] = $this->get('id');
|
2633 |
}
|
2634 |
|
@@ -68,9 +68,21 @@ class MediaLibraryThumbnailModel extends \ShortPixel\Model\Image\ImageModel
|
|
68 |
|
69 |
public function getRetina()
|
70 |
{
|
71 |
-
|
72 |
-
|
73 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
74 |
|
75 |
$retina = new MediaLibraryThumbnailModel($filepath . $filebase . '@2x.' . $extension, $this->id, $this->size); // mind the dot in after 2x
|
76 |
$retina->setName($this->size);
|
68 |
|
69 |
public function getRetina()
|
70 |
{
|
71 |
+
if ($this->is_virtual())
|
72 |
+
{
|
73 |
+
$fs = \wpSPIO()->filesystem();
|
74 |
+
$filepath = apply_filters('shortpixel/file/virtual/translate', $this->getFullPath(), $this);
|
75 |
+
$virtualFile = $fs->getFile($filepath);
|
76 |
+
|
77 |
+
$filebase = $virtualFile->getFileBase();
|
78 |
+
$filepath = (string) $virtualFile->getFileDir();
|
79 |
+
$extension = $virtualFile->getExtension();
|
80 |
+
}
|
81 |
+
else {
|
82 |
+
$filebase = $this->getFileBase();
|
83 |
+
$filepath = (string) $this->getFileDir();
|
84 |
+
$extension = $this->getExtension();
|
85 |
+
}
|
86 |
|
87 |
$retina = new MediaLibraryThumbnailModel($filepath . $filebase . '@2x.' . $extension, $this->id, $this->size); // mind the dot in after 2x
|
88 |
$retina->setName($this->size);
|
@@ -29,7 +29,6 @@ class UncodeController
|
|
29 |
|
30 |
// Check Webp
|
31 |
$webpObj = $fs->getFile( (string) $fileObj->getFileDir() . $fileObj->getFileBase() . '.webp');
|
32 |
-
Log::addTemp('Webp file path ' . $webpObj->getFullPath(), $webpObj);
|
33 |
if ($webpObj->exists())
|
34 |
$webpObj->delete();
|
35 |
|
29 |
|
30 |
// Check Webp
|
31 |
$webpObj = $fs->getFile( (string) $fileObj->getFileDir() . $fileObj->getFileBase() . '.webp');
|
|
|
32 |
if ($webpObj->exists())
|
33 |
$webpObj->delete();
|
34 |
|
@@ -391,7 +391,7 @@ class SpioCommandBase
|
|
391 |
protected function displayStatsLine($name, $stats)
|
392 |
{
|
393 |
|
394 |
-
$line = sprintf('Current Status for %s : (%s\%s) Done (%s%%), %s awaiting %s errors --', $name, $stats->done, $stats->total, $stats->percentage_done, ( $stats->awaiting ), $stats->fatal_errors);
|
395 |
|
396 |
\WP_CLI::line($line);
|
397 |
}
|
@@ -445,6 +445,7 @@ class SpioCommandBase
|
|
445 |
|
446 |
\WP_CLI::Line("--- Current Status ---");
|
447 |
\WP_CLI\Utils\format_items('table', $items, $fields);
|
|
|
448 |
}
|
449 |
|
450 |
/**
|
391 |
protected function displayStatsLine($name, $stats)
|
392 |
{
|
393 |
|
394 |
+
$line = sprintf('Current Status for %s : (%s\%s) Done (%s%%), %s awaiting %s errors --', $name, ($stats->done + $stats->fatal_errors), $stats->total, $stats->percentage_done, ( $stats->awaiting ), $stats->fatal_errors);
|
395 |
|
396 |
\WP_CLI::line($line);
|
397 |
}
|
445 |
|
446 |
\WP_CLI::Line("--- Current Status ---");
|
447 |
\WP_CLI\Utils\format_items('table', $items, $fields);
|
448 |
+
\WP_CLI::Line($this->displayStatsLine('Total', $startupData->total->stats));
|
449 |
}
|
450 |
|
451 |
/**
|
@@ -18,6 +18,7 @@ class ShortPixelImgToPictureWebp
|
|
18 |
}
|
19 |
|
20 |
$new_content = $this->testPictures($content);
|
|
|
21 |
if ($new_content !== false)
|
22 |
{
|
23 |
$content = $new_content;
|
@@ -128,7 +129,6 @@ class ShortPixelImgToPictureWebp
|
|
128 |
protected function convertImage($match)
|
129 |
{
|
130 |
$fs = \wpSPIO()->filesystem();
|
131 |
-
|
132 |
// Do nothing with images that have the 'sp-no-webp' class.
|
133 |
if (strpos($match[0], 'sp-no-webp') || strpos($match[0], 'rev-sildebg')) {
|
134 |
Log::addInfo('SPDBG convertImage skipped, sp-no-webp found');
|
@@ -136,7 +136,6 @@ class ShortPixelImgToPictureWebp
|
|
136 |
}
|
137 |
|
138 |
$img = $this->get_attributes($match[0]);
|
139 |
-
|
140 |
if(isset($img['style']) && strpos($img['style'], 'background') !== false) {
|
141 |
//don't replace for <img>'s that have background
|
142 |
return $match[0];
|
@@ -162,7 +161,7 @@ class ShortPixelImgToPictureWebp
|
|
162 |
$imageBase = apply_filters( 'shortpixel_webp_image_base', $this->getImageBase($srcInfo['value']), $srcInfo['value']);
|
163 |
|
164 |
if($imageBase === false) {
|
165 |
-
Log::
|
166 |
return $match[0]; // . (isset($_GET['SHORTPIXEL_DEBUG']) ? '<!-- SPDBG baseurl doesn\'t match ' . $src . ' -->' : '');
|
167 |
}
|
168 |
|
@@ -204,7 +203,7 @@ class ShortPixelImgToPictureWebp
|
|
204 |
}
|
205 |
|
206 |
// $defs = explode(",", $srcset);
|
207 |
-
$mime = ''; //
|
208 |
|
209 |
foreach ($definitions as $item) {
|
210 |
$parts = preg_split('/\s+/', trim($item));
|
@@ -251,6 +250,9 @@ class ShortPixelImgToPictureWebp
|
|
251 |
$srcsetWebP[] = $fileurl_base . $thisfile->getFileName() . $condition;
|
252 |
break;
|
253 |
}
|
|
|
|
|
|
|
254 |
}
|
255 |
|
256 |
//@todo This will not work with offloaded avifs.
|
@@ -264,8 +266,8 @@ class ShortPixelImgToPictureWebp
|
|
264 |
|
265 |
|
266 |
if (count($srcsetWebP) == 0 && count($srcsetAvif) == 0) {
|
|
|
267 |
return $match[0]; //. (isset($_GET['SHORTPIXEL_DEBUG']) ? '<!-- SPDBG no srcsetWebP found (' . $srcsetWebP . ') -->' : '');
|
268 |
-
Log::addInfo(' SPDBG no srcsetWebP found (' . $srcsetWebP . ')');
|
269 |
}
|
270 |
|
271 |
//add the exclude class so if this content is processed again in other filter, the img is not converted again in picture
|
@@ -288,7 +290,6 @@ class ShortPixelImgToPictureWebp
|
|
288 |
|
289 |
// $srcsetWebP = implode(',', $srcsetWebP);
|
290 |
|
291 |
-
|
292 |
$output = '<picture ' . $this->create_attributes($imgpicture) . '>';
|
293 |
|
294 |
if (is_array($srcsetAvif) && count($srcsetAvif) > 0)
|
@@ -305,7 +306,6 @@ class ShortPixelImgToPictureWebp
|
|
305 |
.'<img ' . $srcPrefix . 'src="' . $src . '" ' . $this->create_attributes($img) . $idAttr . $altAttr . $heightAttr . $widthAttr
|
306 |
. (strlen($srcset) ? ' srcset="' . $srcset . '"': '') . (strlen($sizes) ? ' sizes="' . $sizes . '"': '') . '>'
|
307 |
.'</picture>';
|
308 |
-
|
309 |
return $output;
|
310 |
}
|
311 |
|
18 |
}
|
19 |
|
20 |
$new_content = $this->testPictures($content);
|
21 |
+
|
22 |
if ($new_content !== false)
|
23 |
{
|
24 |
$content = $new_content;
|
129 |
protected function convertImage($match)
|
130 |
{
|
131 |
$fs = \wpSPIO()->filesystem();
|
|
|
132 |
// Do nothing with images that have the 'sp-no-webp' class.
|
133 |
if (strpos($match[0], 'sp-no-webp') || strpos($match[0], 'rev-sildebg')) {
|
134 |
Log::addInfo('SPDBG convertImage skipped, sp-no-webp found');
|
136 |
}
|
137 |
|
138 |
$img = $this->get_attributes($match[0]);
|
|
|
139 |
if(isset($img['style']) && strpos($img['style'], 'background') !== false) {
|
140 |
//don't replace for <img>'s that have background
|
141 |
return $match[0];
|
161 |
$imageBase = apply_filters( 'shortpixel_webp_image_base', $this->getImageBase($srcInfo['value']), $srcInfo['value']);
|
162 |
|
163 |
if($imageBase === false) {
|
164 |
+
Log::addDebug('SPDBG baseurl doesn\'t match ' . $srcInfo['value'], array($imageBase) );
|
165 |
return $match[0]; // . (isset($_GET['SHORTPIXEL_DEBUG']) ? '<!-- SPDBG baseurl doesn\'t match ' . $src . ' -->' : '');
|
166 |
}
|
167 |
|
203 |
}
|
204 |
|
205 |
// $defs = explode(",", $srcset);
|
206 |
+
$mime = ''; // is_infinite
|
207 |
|
208 |
foreach ($definitions as $item) {
|
209 |
$parts = preg_split('/\s+/', trim($item));
|
250 |
$srcsetWebP[] = $fileurl_base . $thisfile->getFileName() . $condition;
|
251 |
break;
|
252 |
}
|
253 |
+
else {
|
254 |
+
$srcsetWebP[] = $fileurl . $condition;
|
255 |
+
}
|
256 |
}
|
257 |
|
258 |
//@todo This will not work with offloaded avifs.
|
266 |
|
267 |
|
268 |
if (count($srcsetWebP) == 0 && count($srcsetAvif) == 0) {
|
269 |
+
|
270 |
return $match[0]; //. (isset($_GET['SHORTPIXEL_DEBUG']) ? '<!-- SPDBG no srcsetWebP found (' . $srcsetWebP . ') -->' : '');
|
|
|
271 |
}
|
272 |
|
273 |
//add the exclude class so if this content is processed again in other filter, the img is not converted again in picture
|
290 |
|
291 |
// $srcsetWebP = implode(',', $srcsetWebP);
|
292 |
|
|
|
293 |
$output = '<picture ' . $this->create_attributes($imgpicture) . '>';
|
294 |
|
295 |
if (is_array($srcsetAvif) && count($srcsetAvif) > 0)
|
306 |
.'<img ' . $srcPrefix . 'src="' . $src . '" ' . $this->create_attributes($img) . $idAttr . $altAttr . $heightAttr . $widthAttr
|
307 |
. (strlen($srcset) ? ' srcset="' . $srcset . '"': '') . (strlen($sizes) ? ' sizes="' . $sizes . '"': '') . '>'
|
308 |
.'</picture>';
|
|
|
309 |
return $output;
|
310 |
}
|
311 |
|
@@ -141,7 +141,8 @@ $approx = $this->view->approx;
|
|
141 |
<div class="option"><?php esc_html_e('The total number of AVIF images will be calculated in the next step.','shortpixel-image-optimiser'); ?></div>
|
142 |
</div>
|
143 |
<?php else : ?>
|
144 |
-
<div class="option warning"><?php
|
|
|
145 |
|
146 |
</div>
|
147 |
</div>
|
141 |
<div class="option"><?php esc_html_e('The total number of AVIF images will be calculated in the next step.','shortpixel-image-optimiser'); ?></div>
|
142 |
</div>
|
143 |
<?php else : ?>
|
144 |
+
<div class="option warning"><?php printf(esc_html__('The creation of AVIF files is not possible with this license type. %s Read more %s ','shortpixel-image-optimiser'), '<a href="https://shortpixel.com/knowledge-base/article/555-how-does-the-unlimited-plan-work" target="_blank">', '</a>'); ?>
|
145 |
+
|
146 |
|
147 |
</div>
|
148 |
</div>
|
@@ -73,7 +73,12 @@ namespace ShortPixel;
|
|
73 |
</div>
|
74 |
|
75 |
</div>
|
76 |
-
<?php
|
|
|
|
|
|
|
|
|
|
|
77 |
<div class="credits">
|
78 |
<p class='heading'><span><?php esc_html_e('Your ShortPixel Credits Available', 'shortpixel-image-optimiser'); ?></span>
|
79 |
<span><?php echo esc_html($this->formatNumber($quotaData->total->remaining, 0)) ?></span>
|
@@ -110,7 +115,8 @@ namespace ShortPixel;
|
|
110 |
?></span>
|
111 |
</div>
|
112 |
<?php $this->loadView('snippets/part-upgrade-options'); ?>
|
113 |
-
|
|
|
114 |
|
115 |
<div class='no-images' data-check-visibility="false" data-control="data-check-total-total">
|
116 |
<?php esc_html_e('The current selection contains no images. The bulk process cannot start.', 'shortpixel-image-optimiser'); ?>
|
73 |
</div>
|
74 |
|
75 |
</div>
|
76 |
+
<?php
|
77 |
+
if(true === $quotaData->unlimited): ?>
|
78 |
+
<div class='credits'>
|
79 |
+
<p><span><?php _e('This site is currently on the ShortPixel Unlimited plan, so you do not have to worry about credits. Enjoy!', 'shortpixel-image-optimiser'); ?></span></p>
|
80 |
+
</div>
|
81 |
+
<?php else: ?>
|
82 |
<div class="credits">
|
83 |
<p class='heading'><span><?php esc_html_e('Your ShortPixel Credits Available', 'shortpixel-image-optimiser'); ?></span>
|
84 |
<span><?php echo esc_html($this->formatNumber($quotaData->total->remaining, 0)) ?></span>
|
115 |
?></span>
|
116 |
</div>
|
117 |
<?php $this->loadView('snippets/part-upgrade-options'); ?>
|
118 |
+
<?php endif;
|
119 |
+
?>
|
120 |
|
121 |
<div class='no-images' data-check-visibility="false" data-control="data-check-total-total">
|
122 |
<?php esc_html_e('The current selection contains no images. The bulk process cannot start.', 'shortpixel-image-optimiser'); ?>
|
@@ -4,7 +4,7 @@ Tags: convert webp, optimize images, image optimization, resize, compressor, ima
|
|
4 |
Requires at least: 4.8.0
|
5 |
Tested up to: 6.1
|
6 |
Requires PHP: 5.6
|
7 |
-
Stable tag: 5.1.
|
8 |
License: GPLv2 or later
|
9 |
License URI: http://www.gnu.org/licenses/gpl-2.0.html
|
10 |
|
@@ -12,7 +12,7 @@ Speed up your website & boost your SEO by compressing old & new images and PDFs.
|
|
12 |
|
13 |
== Description ==
|
14 |
|
15 |
-
**
|
16 |
|
17 |
Increase your website's SEO ranking, number of visitors, and ultimately your sales by optimising any image or PDF document on your website.
|
18 |
ShortPixel is an easy to use, lightweight, install-and-forget-about-it <a href="https://shortpixel.com" target="_blank">image optimization</a> plugin that can compress all your past images and PDF documents with a single click. New images are automatically resized/rescaled and optimized on the fly, in the background. It's also compatible with any gallery, slider or eCommerce plugin.
|
@@ -28,6 +28,12 @@ Optimized images mean better user experience, better PageSpeed Insights or GTmet
|
|
28 |
|
29 |
Make an instant <a href="https://shortpixel.com/image-compression-test" target="_blank">image compression test</a> of your site or <a href="https://shortpixel.com/online-image-compression" target="_blank">compress some images</a> to test our optimization algorithms.
|
30 |
|
|
|
|
|
|
|
|
|
|
|
|
|
31 |
**New! Smart Cropping**
|
32 |
|
33 |
With this new feature, all thumbnails used on your website are not only optimized, but also regenerated to fully display the subject of the image.
|
@@ -278,9 +284,18 @@ filters the URLs that will be sent to optimisation, `$URLs` is a plain array;
|
|
278 |
`apply_filters('shortpixel/db/chunk_size', $chunk);`
|
279 |
the `$chunk` is the value ShortPixel chooses to use as the number of selected records in one query (based on total table size), some hosts work better with a different value;
|
280 |
|
|
|
|
|
281 |
`apply_filters('shortpixel/backup/paths', $PATHs, $mainPath);`
|
282 |
filters the array of paths of the images sent for backup and can be used to exclude certain paths/images/thumbs from being backed up, based on the image path. `$mainPath` is the path of the main image, while `$PATHs` is an array with all files to be backed up (including thumbnails);
|
283 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
284 |
`apply_filters('shortpixel/settings/image_sizes', $sizes);`
|
285 |
filters the array (`$sizes`) of image sizes that can be excluded from processing (displayed in the plugin Advanced settings);
|
286 |
|
@@ -306,6 +321,9 @@ add_filter('shortpixel/init/optimize_on_screens', function ($screens) {
|
|
306 |
});
|
307 |
`
|
308 |
|
|
|
|
|
|
|
309 |
In order to define custom thumbnails to be picked up by the optimization you have two options, both comma separated defines:
|
310 |
|
311 |
`define('SHORTPIXEL_CUSTOM_THUMB_SUFFIXES', '_tl,_tr');`
|
@@ -348,6 +366,19 @@ Add HTTP basic authentication credentials by defining these constants in wp-conf
|
|
348 |
|
349 |
== Changelog ==
|
350 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
351 |
= 5.1.3 =
|
352 |
Release date November 9, 2022
|
353 |
* Fix: a typo related to Custom Media that caused an error when adding a new Custom Media folder;
|
4 |
Requires at least: 4.8.0
|
5 |
Tested up to: 6.1
|
6 |
Requires PHP: 5.6
|
7 |
+
Stable tag: 5.1.4
|
8 |
License: GPLv2 or later
|
9 |
License URI: http://www.gnu.org/licenses/gpl-2.0.html
|
10 |
|
12 |
|
13 |
== Description ==
|
14 |
|
15 |
+
**An easy-to-use, comprehensive, lightweight, stable and frequently updated freemium image compression plugin supported by the friendly team that created it.**
|
16 |
|
17 |
Increase your website's SEO ranking, number of visitors, and ultimately your sales by optimising any image or PDF document on your website.
|
18 |
ShortPixel is an easy to use, lightweight, install-and-forget-about-it <a href="https://shortpixel.com" target="_blank">image optimization</a> plugin that can compress all your past images and PDF documents with a single click. New images are automatically resized/rescaled and optimized on the fly, in the background. It's also compatible with any gallery, slider or eCommerce plugin.
|
28 |
|
29 |
Make an instant <a href="https://shortpixel.com/image-compression-test" target="_blank">image compression test</a> of your site or <a href="https://shortpixel.com/online-image-compression" target="_blank">compress some images</a> to test our optimization algorithms.
|
30 |
|
31 |
+
**<a href="https://shortpixel.com/spio-unlimited/" target="_blank">New Plan: ShortPixel Unlimited</a>**
|
32 |
+
|
33 |
+
This is the perfect monthly plan for single website owners.
|
34 |
+
It allows you to optimize an unlimited number of images with ShortPixel Image Optimizer on your website.
|
35 |
+
Read more details on our <a href="https://shortpixel.com/knowledge-base/article/555-how-does-the-unlimited-plan-work" target="_blank">dedicated page</a>.
|
36 |
+
|
37 |
**New! Smart Cropping**
|
38 |
|
39 |
With this new feature, all thumbnails used on your website are not only optimized, but also regenerated to fully display the subject of the image.
|
284 |
`apply_filters('shortpixel/db/chunk_size', $chunk);`
|
285 |
the `$chunk` is the value ShortPixel chooses to use as the number of selected records in one query (based on total table size), some hosts work better with a different value;
|
286 |
|
287 |
+
For version 4.22.10 and earlier:
|
288 |
+
|
289 |
`apply_filters('shortpixel/backup/paths', $PATHs, $mainPath);`
|
290 |
filters the array of paths of the images sent for backup and can be used to exclude certain paths/images/thumbs from being backed up, based on the image path. `$mainPath` is the path of the main image, while `$PATHs` is an array with all files to be backed up (including thumbnails);
|
291 |
|
292 |
+
For version 5.0.0 and later:
|
293 |
+
|
294 |
+
`apply_filters('shortpixel/image/skip_backup', false, $this->getFullPath(), $this->is_main_file)`
|
295 |
+
filters the images that are skipped or not from the backup. Return true for the type of images to be skipped in the backup. If you check if `is_main_file` is true and return false (do not skip backup), while while otherwise returning true, the backup will be kept only for the main image. We suggest using it in conjuction with this action that fires right after the restore from backup is done (to cleanup the meta data from the database, regenerate thumbnails after restoring the main file, etc.):
|
296 |
+
|
297 |
+
`do_action('shortpixel/image/after_restore', $this, $this->id, $cleanRestore);`
|
298 |
+
|
299 |
`apply_filters('shortpixel/settings/image_sizes', $sizes);`
|
300 |
filters the array (`$sizes`) of image sizes that can be excluded from processing (displayed in the plugin Advanced settings);
|
301 |
|
321 |
});
|
322 |
`
|
323 |
|
324 |
+
`add_filter('shortpixel/image/filecheck', function () { return true; });`
|
325 |
+
This filter forces a file check for WebP/AVIF in case they were manually removed from disk.
|
326 |
+
|
327 |
In order to define custom thumbnails to be picked up by the optimization you have two options, both comma separated defines:
|
328 |
|
329 |
`define('SHORTPIXEL_CUSTOM_THUMB_SUFFIXES', '_tl,_tr');`
|
366 |
|
367 |
== Changelog ==
|
368 |
|
369 |
+
= 5.1.4 =
|
370 |
+
Release date November 28, 2022
|
371 |
+
* New: added a filter to force a file check for WebP/AVIF if they were manually deleted from disk;
|
372 |
+
* Fix: if only small WebPs are available, include the JPG version in the `picture` tag to avoid blurry images;
|
373 |
+
* Fix: the notification about unlisted thumbnails incorrectly reported WebP and AVIF files;
|
374 |
+
* Fix: improved integration with WP Offload Media by including Retina images in virtual/offload file checks;
|
375 |
+
* Fix: if the main file was optimized but some thumbnails did not have WebP/AVIF, it was not displayed correctly in the UI;
|
376 |
+
* Fix: added a % margin when generating WebPs/AVIF, so that files that are only a few bytes larger are also generated;
|
377 |
+
* Fix: when running WP-CLI, the percentage of finished items in the total was calculated incorrectly;
|
378 |
+
* Fix: the settings page crashed in certain cases for new accounts;
|
379 |
+
* Tweak: various CSS fixes and improvements on the Media Library, especially for cases with many thumbnails;
|
380 |
+
* Language: 2 new strings added, 2 updated, 0 fuzzed, and 0 deprecated.
|
381 |
+
|
382 |
= 5.1.3 =
|
383 |
Release date November 9, 2022
|
384 |
* Fix: a typo related to Custom Media that caused an error when adding a new Custom Media folder;
|
@@ -168,6 +168,9 @@
|
|
168 |
.sp-column-info .thumbnails.optimized .thumb-wrapper .thumb .optimize-bar .point.checked {
|
169 |
background: #1abdca;
|
170 |
}
|
|
|
|
|
|
|
171 |
.sp-column-info .thumbnails.optimized:hover .thumb-wrapper {
|
172 |
display: block;
|
173 |
}
|
168 |
.sp-column-info .thumbnails.optimized .thumb-wrapper .thumb .optimize-bar .point.checked {
|
169 |
background: #1abdca;
|
170 |
}
|
171 |
+
.sp-column-info .thumbnails.optimized .thumb-wrapper .thumb .cutoff {
|
172 |
+
float: right;
|
173 |
+
}
|
174 |
.sp-column-info .thumbnails.optimized:hover .thumb-wrapper {
|
175 |
display: block;
|
176 |
}
|
@@ -1 +1 @@
|
|
1 |
-
{"version":3,"sourceRoot":"","sources":["../scss/view/_edit-media.scss","../scss/elements/_animation.scss","../scss/view/_other-media.scss","../scss/view/_list-item.scss","../scss/view/_modal.scss","../scss/view/_debug.scss","../scss/shortpixel-admin.scss"],"names":[],"mappings":"AAII;EAEG;EACA;;AAGH;EAEE;;AAEA;EAEE;EACA;;AAOA;EAEE;EACA;;AAIN;EAEE;EACA;;AAEA;EAGE;EACA;EACA;;;AAQP;EC/CC;EACI;EACA;EACA;EACA;ED6CH;;AC3CF;EACC;IAAM;IAA2B;;;AAGlC;EACC;IAAM;IAA8B;;;AAGrC;EACC;IAAM;IAA+B;;;AAGtC;EACC;IAAM;IAAmC;;;AAG1C;EACC;IAAM;IAAgC;;;;ADmCjC;EAEC;EACA;;AAEF;EACC;;AAUJ;EAAS;;AACT;EAAO;;;AEzEP;EAEG;EACA;EACA;;AAIL;EAEC;EACA;;AACA;EDdA;EACI;EACA;EACA;EACA;ECYF;;ADVH;EACC;IAAM;IAA2B;;;AAGlC;EACC;IAAM;IAA8B;;;AAGrC;EACC;IAAM;IAA+B;;;AAGtC;EACC;IAAM;IAAmC;;;AAG1C;EACC;IAAM;IAAgC;;;;AExBxC;EAEE;;AAEA;EAEE;;AAKA;EAEK;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACJ;;AACI;EAEI;EACA;;AAEL;EACC;EACA;EACA;EACA;;AAEI;EACK;EACA;EACA;EACA;EACA;EACA;;AAEC;EAEG;EACA;EAEA;EACA;;AAEA;EACE;;
|
1 |
+
{"version":3,"sourceRoot":"","sources":["../scss/view/_edit-media.scss","../scss/elements/_animation.scss","../scss/view/_other-media.scss","../scss/view/_list-item.scss","../scss/view/_modal.scss","../scss/view/_debug.scss","../scss/shortpixel-admin.scss"],"names":[],"mappings":"AAII;EAEG;EACA;;AAGH;EAEE;;AAEA;EAEE;EACA;;AAOA;EAEE;EACA;;AAIN;EAEE;EACA;;AAEA;EAGE;EACA;EACA;;;AAQP;EC/CC;EACI;EACA;EACA;EACA;ED6CH;;AC3CF;EACC;IAAM;IAA2B;;;AAGlC;EACC;IAAM;IAA8B;;;AAGrC;EACC;IAAM;IAA+B;;;AAGtC;EACC;IAAM;IAAmC;;;AAG1C;EACC;IAAM;IAAgC;;;;ADmCjC;EAEC;EACA;;AAEF;EACC;;AAUJ;EAAS;;AACT;EAAO;;;AEzEP;EAEG;EACA;EACA;;AAIL;EAEC;EACA;;AACA;EDdA;EACI;EACA;EACA;EACA;ECYF;;ADVH;EACC;IAAM;IAA2B;;;AAGlC;EACC;IAAM;IAA8B;;;AAGrC;EACC;IAAM;IAA+B;;;AAGtC;EACC;IAAM;IAAmC;;;AAG1C;EACC;IAAM;IAAgC;;;;AExBxC;EAEE;;AAEA;EAEE;;AAKA;EAEK;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACJ;;AACI;EAEI;EACA;;AAEL;EACC;EACA;EACA;EACA;;AAEI;EACK;EACA;EACA;EACA;EACA;EACA;;AAEC;EAEG;EACA;EAEA;EACA;;AAEA;EACE;;AAIjB;EACE;;AAKD;EACI;;AAKV;EAEG;EACA;EACA;;AAEH;EAEG;;AACA;EACI;;AAIJ;EAAkB;;AAGrB;EAAK;;AACL;EACI;EACA;EACA;EACA;EACA;EACA;;AAEA;EAEG;EACA;EACA;;;AASP;EAEG;EACA;EACF;;AACA;EF7GD;EACI;EACA;EACA;EACA;EE2GF;;AFzGH;EACC;IAAM;IAA2B;;;AAGlC;EACC;IAAM;IAA8B;;;AAGrC;EACC;IAAM;IAA+B;;;AAGtC;EACC;IAAM;IAAmC;;;AAG1C;EACC;IAAM;IAAgC;;;;AGzBxC;EACI;AAAe;EACf;AAAiB;EACjB;AAAgB;EAChB;EACA;EACA;AAAa;EACb;AAAc;EACd;AAAgB;EAChB;AAAwB;EACxB;AAA6B;EAC7B;;;AAEJ;EACI;AACA;EACA;EACA;EACA;AAAY;EACZ;AAAkB;EAClB;AAAiB;EACjB;EACA;EACA;EACA;EACA;;AACA;EAEE;EACA;EACA;EACA;EACA;EACA;EACA;;AAGF;EACI;EACA;EACA;;;AAKR;EACI;;;AAEJ;EACI;;;AC/CJ;EACE;;;AAGF;EAEC;;AACA;EACC;;AAED;EAEC;;;AAKF;EACC;EACA;EACA;EACA;EACA;EACA;EACC;EACA;EAED;EACA;EACA;EAEA;EAGA;EACA;;AAEA;EAEE;;AAGF;EACE;;AACA;EAAK;;AAGP;EACE;;AAIF;EACC;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACC;EACA;EACA;EACA;EACA;EACA;EACA;;AAGD;EACC;EACA;EACA;EACA;EACA;EACA;EACA;;AACA;EACC;EACA;;AAIH;EACC;EAIA;;;AAKF;EAEE;EACD;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AC/FD;EACI;;;AAIJ;EAEE;;;AAGF;EAGC;EACA;EACA;;AAEA;EACC;;AAEA;EACC;;AAGF;EAAQ;;AACP;EAA0B;;AAC1B;EACC;EACA;;AAED;EACC;EACA;;AAED;EAAiC;;AAElC;EACC;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACC;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EAGA;EACH;EACA;;AAEE;EAAiB;;AACjB;EACC","file":"shortpixel-admin.css"}
|
@@ -53,6 +53,9 @@
|
|
53 |
}
|
54 |
}
|
55 |
}
|
|
|
|
|
|
|
56 |
}
|
57 |
} // wrapper
|
58 |
&:hover {
|
53 |
}
|
54 |
}
|
55 |
}
|
56 |
+
.cutoff {
|
57 |
+
float:right;
|
58 |
+
}
|
59 |
}
|
60 |
} // wrapper
|
61 |
&:hover {
|
@@ -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="/wp-admin/options-general.php?page=wp-shortpixel-settings" target="_blank">Settings > ShortPixel</a> page on how to start optimizing your image library and make your website load faster.
|
6 |
-
* Version: 5.1.
|
7 |
* Author: ShortPixel
|
8 |
* Author URI: https://shortpixel.com
|
9 |
* GitHub Plugin URI: https://github.com/short-pixel-optimizer/shortpixel-image-optimiser
|
@@ -31,7 +31,7 @@ if (! defined('SHORTPIXEL_RESET_ON_ACTIVATE'))
|
|
31 |
define('SHORTPIXEL_PLUGIN_FILE', __FILE__);
|
32 |
define('SHORTPIXEL_PLUGIN_DIR', __DIR__);
|
33 |
|
34 |
-
define('SHORTPIXEL_IMAGE_OPTIMISER_VERSION', "5.1.
|
35 |
|
36 |
define('SHORTPIXEL_BACKUP', 'ShortpixelBackups');
|
37 |
define('SHORTPIXEL_MAX_FAIL_RETRIES', 3);
|
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="/wp-admin/options-general.php?page=wp-shortpixel-settings" target="_blank">Settings > ShortPixel</a> page on how to start optimizing your image library and make your website load faster.
|
6 |
+
* Version: 5.1.4
|
7 |
* Author: ShortPixel
|
8 |
* Author URI: https://shortpixel.com
|
9 |
* GitHub Plugin URI: https://github.com/short-pixel-optimizer/shortpixel-image-optimiser
|
31 |
define('SHORTPIXEL_PLUGIN_FILE', __FILE__);
|
32 |
define('SHORTPIXEL_PLUGIN_DIR', __DIR__);
|
33 |
|
34 |
+
define('SHORTPIXEL_IMAGE_OPTIMISER_VERSION', "5.1.4");
|
35 |
|
36 |
define('SHORTPIXEL_BACKUP', 'ShortpixelBackups');
|
37 |
define('SHORTPIXEL_MAX_FAIL_RETRIES', 3);
|