Version Description
- improvements to context help beacon
- performance improvements to PNG to JPG conversion
Download this release
Release Info
Developer | ShortPixel |
Plugin | ShortPixel Image Optimizer |
Version | 4.10.3 |
Comparing to | |
See all releases |
Code changes from version 4.10.2 to 4.10.3
- class/db/wp-shortpixel-media-library-adapter.php +1 -1
- class/shortpixel-png2jpg.php +147 -67
- class/view/shortpixel_view.php +18 -19
- class/wp-short-pixel.php +21 -0
- readme.txt +5 -1
- wp-shortpixel.php +2 -2
class/db/wp-shortpixel-media-library-adapter.php
CHANGED
@@ -54,7 +54,7 @@ class WpShortPixelMediaLbraryAdapter {
|
|
54 |
if ( $file->meta_key == "_wp_attached_file" )
|
55 |
{//count pdf files only
|
56 |
$extension = substr($file->meta_value, strrpos($file->meta_value,".") + 1 );
|
57 |
-
if ( $extension == "pdf" && !isset($filesMap[$file->meta_value]))
|
58 |
{
|
59 |
$totalFiles++;
|
60 |
$totalFilesThis++;
|
54 |
if ( $file->meta_key == "_wp_attached_file" )
|
55 |
{//count pdf files only
|
56 |
$extension = substr($file->meta_value, strrpos($file->meta_value,".") + 1 );
|
57 |
+
if ( $extension == "pdf" && $settings->optimizePdfs && !isset($filesMap[$file->meta_value]))
|
58 |
{
|
59 |
$totalFiles++;
|
60 |
$totalFilesThis++;
|
class/shortpixel-png2jpg.php
CHANGED
@@ -18,37 +18,44 @@ class ShortPixelPng2Jpg {
|
|
18 |
|
19 |
protected function canConvertPng2Jpg($image) {
|
20 |
$transparent = 0;
|
21 |
-
if (ord(file_get_contents($image, false, null, 25, 1)) & 4) {
|
22 |
-
$transparent = 1;
|
23 |
-
}
|
24 |
-
$contents = file_get_contents($image);
|
25 |
-
if (stripos($contents, 'PLTE') !== false && stripos($contents, 'tRNS') !== false) {
|
26 |
-
$transparent = 1;
|
27 |
-
}
|
28 |
$transparent_pixel = $img = $bg = false;
|
29 |
-
|
30 |
-
|
31 |
-
|
32 |
-
|
33 |
-
$
|
34 |
-
if(
|
35 |
-
$transparent =
|
36 |
-
}
|
37 |
-
|
38 |
-
$
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
46 |
}
|
47 |
}
|
48 |
}
|
49 |
}
|
50 |
}
|
51 |
|
|
|
52 |
//pass on the img too, if it was already loaded from PNG, matter of performance
|
53 |
return array('notTransparent' => !$transparent && !$transparent_pixel, 'img' => $img);
|
54 |
}
|
@@ -64,17 +71,23 @@ class ShortPixelPng2Jpg {
|
|
64 |
|
65 |
protected function doConvertPng2Jpg($params, $backup, $suffixRegex = false, $img = false) {
|
66 |
$image = $params['file'];
|
|
|
67 |
if(!$img) {
|
68 |
-
|
|
|
69 |
if(!$img) {
|
70 |
-
|
|
|
71 |
}
|
72 |
}
|
73 |
|
|
|
74 |
$x = imagesx($img);
|
75 |
$y = imagesy($img);
|
|
|
76 |
$bg = imagecreatetruecolor($x, $y);
|
77 |
-
|
|
|
78 |
imagefill($bg, 0, 0, imagecolorallocate($bg, 255, 255, 255));
|
79 |
imagealphablending($bg, 1);
|
80 |
imagecopy($bg, $img, 0, 0, 0, 0, $x, $y);
|
@@ -89,29 +102,33 @@ class ShortPixelPng2Jpg {
|
|
89 |
}
|
90 |
}
|
91 |
if (imagejpeg($bg, $newPath, 90)) {
|
|
|
92 |
$newSize = filesize($newPath);
|
93 |
$origSize = filesize($image);
|
94 |
if($newSize > $origSize * 0.95) {
|
95 |
//if the image is not 5% smaller, don't bother.
|
96 |
unlink($newPath);
|
97 |
-
return $params;
|
98 |
}
|
99 |
//backup?
|
100 |
if($backup) {
|
101 |
$imageForBk = trailingslashit(dirname($image)) . ShortPixelAPI::MB_basename($newPath, '.jpg') . '.png';
|
102 |
-
|
|
|
|
|
|
|
103 |
if(!file_exists($imageForBk)) {
|
104 |
unlink($newPath);
|
105 |
-
return $params;
|
106 |
}
|
107 |
$image = $imageForBk;
|
108 |
$ret = ShortPixelAPI::backupImage($image, array($image));
|
109 |
if($ret['Status'] !== ShortPixelAPI::STATUS_SUCCESS) {
|
110 |
unlink($newPath);
|
111 |
-
return $params;
|
112 |
}
|
113 |
}
|
114 |
-
unlink($image);
|
115 |
$params['file'] = $newPath;
|
116 |
$params['original_file'] = $image;
|
117 |
$params['url'] = $newUrl;
|
@@ -119,7 +136,7 @@ class ShortPixelPng2Jpg {
|
|
119 |
$params['png_size'] = $origSize;
|
120 |
$params['jpg_size'] = $newSize;
|
121 |
}
|
122 |
-
return $params;
|
123 |
}
|
124 |
|
125 |
/**
|
@@ -139,7 +156,9 @@ class ShortPixelPng2Jpg {
|
|
139 |
|
140 |
$ret = $this->canConvertPng2Jpg($image);
|
141 |
if ($ret['notTransparent']) {
|
142 |
-
$
|
|
|
|
|
143 |
if($paramsC['type'] == 'image/jpeg') {
|
144 |
// we don't have metadata, so save the information in a temporary map
|
145 |
$conv = $this->_settings->convertedPng2Jpg;
|
@@ -192,12 +211,17 @@ class ShortPixelPng2Jpg {
|
|
192 |
$meta['ShortPixel']['ErrCode'] = ShortPixelAPI::ERR_PNG2JPG_MEMORY;
|
193 |
wp_update_attachment_metadata($ID, $meta);
|
194 |
|
195 |
-
$
|
196 |
-
if (!$
|
|
|
197 |
return $meta; //cannot convert it
|
198 |
}
|
199 |
|
200 |
-
$
|
|
|
|
|
|
|
|
|
201 |
|
202 |
//unset the temporary error
|
203 |
unset($meta['ShortPixelImprovement']);
|
@@ -206,9 +230,11 @@ class ShortPixelPng2Jpg {
|
|
206 |
wp_update_attachment_metadata($ID, $meta);
|
207 |
|
208 |
if ($ret['type'] == 'image/jpeg') {
|
|
|
209 |
//convert to the new URLs the urls in the existing posts.
|
210 |
$baseRelPath = trailingslashit(dirname($image));
|
211 |
-
$
|
|
|
212 |
$pngSize = $ret['png_size'];
|
213 |
$jpgSize = $ret['jpg_size'];
|
214 |
$imagePath = isset($ret['original_file']) ? $ret['original_file'] : $imagePath;
|
@@ -216,27 +242,45 @@ class ShortPixelPng2Jpg {
|
|
216 |
//conversion succeeded for the main image, update meta and proceed to thumbs. (It could also not succeed if the converted file is not smaller)
|
217 |
$meta['file'] = str_replace($basePath, '', $ret['file']);
|
218 |
$meta['type'] = 'image/jpeg';
|
|
|
|
|
219 |
|
220 |
$originalSizes = isset($meta['sizes']) ? $meta['sizes'] : array();
|
221 |
foreach($meta['sizes'] as $size => $info) {
|
222 |
-
$
|
223 |
$this->_settings->backupImages, "[0-9]+x[0-9]+");
|
|
|
|
|
|
|
224 |
if ($rett['type'] == 'image/jpeg') {
|
|
|
|
|
225 |
$meta['sizes'][$size]['file'] = wp_basename($rett['file']);
|
226 |
$meta['sizes'][$size]['mime-type'] = 'image/jpeg';
|
227 |
-
$pngSize += $
|
228 |
-
$jpgSize += $
|
|
|
229 |
$originalSizes[$size]['file'] = wp_basename($rett['file'], '.jpg') . '.png';
|
230 |
-
$
|
|
|
|
|
231 |
}
|
232 |
}
|
233 |
$meta['ShortPixelPng2Jpg'] = array('originalFile' => $imagePath, 'originalSizes' => $originalSizes,
|
234 |
'backup' => $this->_settings->backupImages,
|
235 |
'optimizationPercent' => round(100.0 * (1.00 - $jpgSize / $pngSize)));
|
236 |
-
update_attached_file($ID, $meta['file']);
|
237 |
wp_update_attachment_metadata($ID, $meta);
|
238 |
}
|
239 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
240 |
return $meta;
|
241 |
}
|
242 |
|
@@ -247,21 +291,23 @@ class ShortPixelPng2Jpg {
|
|
247 |
* @param $newurl
|
248 |
* @return array
|
249 |
*/
|
250 |
-
protected function png2JpgUpdateUrls($options
|
251 |
global $wpdb;
|
|
|
252 |
$results = array();
|
253 |
$queries = array(
|
254 |
-
'content' => array("UPDATE $wpdb->posts SET post_content = replace(post_content, %s, %s)", __('Content Items (Posts, Pages, Custom Post Types, Revisions)','
|
255 |
-
'excerpts' => array("UPDATE $wpdb->posts SET post_excerpt = replace(post_excerpt, %s, %s)", __('Excerpts','
|
256 |
-
'attachments' => array("UPDATE $wpdb->posts SET guid = replace(guid, %s, %s) WHERE post_type = 'attachment'", __('Attachments','
|
257 |
-
'links' => array("UPDATE $wpdb->links SET link_url = replace(link_url, %s, %s)", __('Links','
|
258 |
-
'custom' => array("UPDATE $wpdb->postmeta SET meta_value = replace(meta_value, %s, %s)", __('Custom Fields','
|
259 |
-
'guids' => array("UPDATE $wpdb->posts SET guid = replace(guid, %s, %s)", __('GUIDs','
|
260 |
);
|
261 |
if(count($options) == 0) {
|
262 |
$options = array_keys($queries);
|
263 |
}
|
264 |
foreach($options as $option){
|
|
|
265 |
if( $option == 'custom' ){
|
266 |
$n = 0;
|
267 |
$row_count = $wpdb->get_var( "SELECT COUNT(*) FROM $wpdb->postmeta" );
|
@@ -269,20 +315,24 @@ class ShortPixelPng2Jpg {
|
|
269 |
$pages = ceil( $row_count / $page_size );
|
270 |
|
271 |
for( $page = 0; $page < $pages; $page++ ) {
|
272 |
-
$current_row = 0;
|
273 |
$start = $page * $page_size;
|
274 |
-
$
|
275 |
-
$pmquery = "SELECT * FROM $wpdb->postmeta WHERE meta_value <> ''";
|
276 |
$items = $wpdb->get_results( $pmquery );
|
277 |
foreach( $items as $item ){
|
278 |
$value = $item->meta_value;
|
279 |
if( trim($value) == '' )
|
280 |
continue;
|
281 |
|
282 |
-
$edited =
|
283 |
-
|
284 |
-
|
285 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
286 |
if( $fix )
|
287 |
$n++;
|
288 |
}
|
@@ -290,9 +340,13 @@ class ShortPixelPng2Jpg {
|
|
290 |
}
|
291 |
$results[$option] = array($n, $queries[$option][1]);
|
292 |
}
|
293 |
-
else{
|
294 |
-
|
295 |
-
|
|
|
|
|
|
|
|
|
296 |
}
|
297 |
}
|
298 |
return $results;
|
@@ -307,27 +361,53 @@ class ShortPixelPng2Jpg {
|
|
307 |
* @return array|mixed|string
|
308 |
*/
|
309 |
function png2JpgUnserializeReplace( $from = '', $to = '', $data = '', $serialised = false ) {
|
|
|
310 |
try {
|
311 |
if ( false !== is_serialized( $data ) ) {
|
|
|
|
|
|
|
|
|
|
|
312 |
$unserialized = unserialize( $data );
|
313 |
-
$
|
|
|
|
|
314 |
}
|
315 |
elseif ( is_array( $data ) ) {
|
316 |
$_tmp = array( );
|
317 |
foreach ( $data as $key => $value ) {
|
318 |
-
$
|
|
|
|
|
319 |
}
|
320 |
$data = $_tmp;
|
321 |
unset( $_tmp );
|
322 |
}
|
323 |
-
|
324 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
325 |
$data = str_replace( $from, $to, $data );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
326 |
}
|
327 |
-
if ( $serialised )
|
328 |
-
return serialize( $data );
|
329 |
} catch( Exception $error ) {
|
330 |
}
|
331 |
-
return $data;
|
332 |
}
|
333 |
}
|
18 |
|
19 |
protected function canConvertPng2Jpg($image) {
|
20 |
$transparent = 0;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
21 |
$transparent_pixel = $img = $bg = false;
|
22 |
+
|
23 |
+
if (!file_exists($image) || ord(file_get_contents($image, false, null, 25, 1)) & 4) {
|
24 |
+
$transparent = 1;
|
25 |
+
} else {
|
26 |
+
$contents = file_get_contents($image);
|
27 |
+
if (stripos($contents, 'PLTE') !== false && stripos($contents, 'tRNS') !== false) {
|
28 |
+
$transparent = 1;
|
29 |
+
}
|
30 |
+
if (!$transparent) {
|
31 |
+
$is = getimagesize($image);
|
32 |
+
WPShortPixel::log("PNG2JPG Image width: " . $is[0] . " height: " . $is[1] . " aprox. size: " . round($is[0]*$is[1]*5/1024/1024) . "M memory limit: " . ini_get('memory_limit') . " USED: " . memory_get_usage());
|
33 |
+
WPShortPixel::log("PNG2JPG create from png $image");
|
34 |
+
$img = @imagecreatefrompng($image);
|
35 |
+
WPShortPixel::log("PNG2JPG created from png");
|
36 |
+
if(!$img) {
|
37 |
+
WPShortPixel::log("PNG2JPG not a PNG");
|
38 |
+
$transparent = true; //it's not a PNG, can't convert it
|
39 |
+
} else {
|
40 |
+
WPShortPixel::log("PNG2JPG is PNG");
|
41 |
+
$w = imagesx($img); // Get the width of the image
|
42 |
+
$h = imagesy($img); // Get the height of the image
|
43 |
+
WPShortPixel::log("PNG2JPG width $w height $h. Now checking pixels.");
|
44 |
+
//run through pixels until transparent pixel is found:
|
45 |
+
for ($i = 0; $i < $w; $i++) {
|
46 |
+
for ($j = 0; $j < $h; $j++) {
|
47 |
+
$rgba = imagecolorat($img, $i, $j);
|
48 |
+
if (($rgba & 0x7F000000) >> 24) {
|
49 |
+
$transparent_pixel = true;
|
50 |
+
break;
|
51 |
+
}
|
52 |
}
|
53 |
}
|
54 |
}
|
55 |
}
|
56 |
}
|
57 |
|
58 |
+
WPShortPixel::log("PNG2JPG is " . (!$transparent && !$transparent_pixel ? " not" : "") . " transparent");
|
59 |
//pass on the img too, if it was already loaded from PNG, matter of performance
|
60 |
return array('notTransparent' => !$transparent && !$transparent_pixel, 'img' => $img);
|
61 |
}
|
71 |
|
72 |
protected function doConvertPng2Jpg($params, $backup, $suffixRegex = false, $img = false) {
|
73 |
$image = $params['file'];
|
74 |
+
WPShortPixel::log("PNG2JPG doConvert $image");
|
75 |
if(!$img) {
|
76 |
+
WPShortPixel::log("PNG2JPG doConvert create from PNG");
|
77 |
+
$img = (file_exists($image) ? imagecreatefrompng($image) : false);
|
78 |
if(!$img) {
|
79 |
+
WPShortPixel::log("PNG2JPG doConvert image cannot be created.");
|
80 |
+
return (object)array("params" => $params, "unlink" => false); //actually not a PNG.
|
81 |
}
|
82 |
}
|
83 |
|
84 |
+
WPShortPixel::log("PNG2JPG doConvert img ready");
|
85 |
$x = imagesx($img);
|
86 |
$y = imagesy($img);
|
87 |
+
WPShortPixel::log("PNG2JPG doConvert width $x height $y");
|
88 |
$bg = imagecreatetruecolor($x, $y);
|
89 |
+
WPShortPixel::log("PNG2JPG doConvert img created truecolor");
|
90 |
+
if(!$bg) return (object)array("params" => $params, "unlink" => false);
|
91 |
imagefill($bg, 0, 0, imagecolorallocate($bg, 255, 255, 255));
|
92 |
imagealphablending($bg, 1);
|
93 |
imagecopy($bg, $img, 0, 0, 0, 0, $x, $y);
|
102 |
}
|
103 |
}
|
104 |
if (imagejpeg($bg, $newPath, 90)) {
|
105 |
+
WPShortPixel::log("PNG2JPG doConvert created JPEG at $newPath");
|
106 |
$newSize = filesize($newPath);
|
107 |
$origSize = filesize($image);
|
108 |
if($newSize > $origSize * 0.95) {
|
109 |
//if the image is not 5% smaller, don't bother.
|
110 |
unlink($newPath);
|
111 |
+
return (object)array("params" => $params, "unlink" => false);
|
112 |
}
|
113 |
//backup?
|
114 |
if($backup) {
|
115 |
$imageForBk = trailingslashit(dirname($image)) . ShortPixelAPI::MB_basename($newPath, '.jpg') . '.png';
|
116 |
+
if($image != $imageForBk) {
|
117 |
+
WPShortPixel::log("PNG2JPG doConvert rename $image to $imageForBk");
|
118 |
+
@rename($image, $imageForBk);
|
119 |
+
}
|
120 |
if(!file_exists($imageForBk)) {
|
121 |
unlink($newPath);
|
122 |
+
return (object)array("params" => $params, "unlink" => false);
|
123 |
}
|
124 |
$image = $imageForBk;
|
125 |
$ret = ShortPixelAPI::backupImage($image, array($image));
|
126 |
if($ret['Status'] !== ShortPixelAPI::STATUS_SUCCESS) {
|
127 |
unlink($newPath);
|
128 |
+
return (object)array("params" => $params, "unlink" => false);
|
129 |
}
|
130 |
}
|
131 |
+
//unlink($image);
|
132 |
$params['file'] = $newPath;
|
133 |
$params['original_file'] = $image;
|
134 |
$params['url'] = $newUrl;
|
136 |
$params['png_size'] = $origSize;
|
137 |
$params['jpg_size'] = $newSize;
|
138 |
}
|
139 |
+
return (object)array("params" => $params, "unlink" => $image);
|
140 |
}
|
141 |
|
142 |
/**
|
156 |
|
157 |
$ret = $this->canConvertPng2Jpg($image);
|
158 |
if ($ret['notTransparent']) {
|
159 |
+
$ret = $this->doConvertPng2Jpg($params, $this->_settings->backupImages, false, $ret['img']);
|
160 |
+
if($ret->unlink) @unlink($ret->unlink);
|
161 |
+
$paramsC = $ret->params;
|
162 |
if($paramsC['type'] == 'image/jpeg') {
|
163 |
// we don't have metadata, so save the information in a temporary map
|
164 |
$conv = $this->_settings->convertedPng2Jpg;
|
211 |
$meta['ShortPixel']['ErrCode'] = ShortPixelAPI::ERR_PNG2JPG_MEMORY;
|
212 |
wp_update_attachment_metadata($ID, $meta);
|
213 |
|
214 |
+
$retC = $this->canConvertPng2Jpg($imagePath);
|
215 |
+
if (!$retC['notTransparent']) {
|
216 |
+
WPShortPixel::log("PNG2JPG not a PNG");
|
217 |
return $meta; //cannot convert it
|
218 |
}
|
219 |
|
220 |
+
$retMain = $this->doConvertPng2Jpg(array('file' => $imagePath, 'url' => false, 'type' => 'image/png'), $this->_settings->backupImages, false, $retC['img']);
|
221 |
+
WPShortPixel::log("PNG2JPG doConvert Main RETURNED " . json_encode($retMain));
|
222 |
+
$ret = $retMain->params;
|
223 |
+
$toUnlink = array();
|
224 |
+
$toReplace = array();
|
225 |
|
226 |
//unset the temporary error
|
227 |
unset($meta['ShortPixelImprovement']);
|
230 |
wp_update_attachment_metadata($ID, $meta);
|
231 |
|
232 |
if ($ret['type'] == 'image/jpeg') {
|
233 |
+
$toUnlink[] = $retMain->unlink;
|
234 |
//convert to the new URLs the urls in the existing posts.
|
235 |
$baseRelPath = trailingslashit(dirname($image));
|
236 |
+
$toReplace[$imageUrl] = $baseUrl . $baseRelPath . wp_basename($ret['file']);
|
237 |
+
//$this->png2JpgUpdateUrls(array(), $imageUrl, $baseUrl . $baseRelPath . wp_basename($ret['file']));
|
238 |
$pngSize = $ret['png_size'];
|
239 |
$jpgSize = $ret['jpg_size'];
|
240 |
$imagePath = isset($ret['original_file']) ? $ret['original_file'] : $imagePath;
|
242 |
//conversion succeeded for the main image, update meta and proceed to thumbs. (It could also not succeed if the converted file is not smaller)
|
243 |
$meta['file'] = str_replace($basePath, '', $ret['file']);
|
244 |
$meta['type'] = 'image/jpeg';
|
245 |
+
update_attached_file($ID, $meta['file']);
|
246 |
+
wp_update_attachment_metadata($ID, $meta);
|
247 |
|
248 |
$originalSizes = isset($meta['sizes']) ? $meta['sizes'] : array();
|
249 |
foreach($meta['sizes'] as $size => $info) {
|
250 |
+
$retThumb = $this->doConvertPng2Jpg(array('file' => $basePath . $baseRelPath . $info['file'], 'url' => false, 'type' => 'image/png'),
|
251 |
$this->_settings->backupImages, "[0-9]+x[0-9]+");
|
252 |
+
$rett = $retThumb->params;
|
253 |
+
|
254 |
+
WPShortPixel::log("PNG2JPG doConvert thumb RETURNED " . json_encode($rett));
|
255 |
if ($rett['type'] == 'image/jpeg') {
|
256 |
+
$toUnlink[] = $retThumb->unlink;
|
257 |
+
WPShortPixel::log("PNG2JPG thumb is jpg");
|
258 |
$meta['sizes'][$size]['file'] = wp_basename($rett['file']);
|
259 |
$meta['sizes'][$size]['mime-type'] = 'image/jpeg';
|
260 |
+
$pngSize += $rett['png_size'];
|
261 |
+
$jpgSize += $rett['jpg_size'];
|
262 |
+
WPShortPixel::log("PNG2JPG total PNG size: $pngSize total JPG size: $jpgSize");
|
263 |
$originalSizes[$size]['file'] = wp_basename($rett['file'], '.jpg') . '.png';
|
264 |
+
$toReplace[$baseUrl . $baseRelPath . $info['file']] = $baseUrl . $baseRelPath . wp_basename($rett['file']);
|
265 |
+
//$this->png2JpgUpdateUrls(array(), $baseUrl . $baseRelPath . $info['file'], $baseUrl . $baseRelPath . wp_basename($rett['file']));
|
266 |
+
wp_update_attachment_metadata($ID, $meta);
|
267 |
}
|
268 |
}
|
269 |
$meta['ShortPixelPng2Jpg'] = array('originalFile' => $imagePath, 'originalSizes' => $originalSizes,
|
270 |
'backup' => $this->_settings->backupImages,
|
271 |
'optimizationPercent' => round(100.0 * (1.00 - $jpgSize / $pngSize)));
|
|
|
272 |
wp_update_attachment_metadata($ID, $meta);
|
273 |
}
|
274 |
|
275 |
+
$this->png2JpgUpdateUrls(array(), $toReplace);
|
276 |
+
foreach($toUnlink as $unlink) {
|
277 |
+
if($unlink) {
|
278 |
+
WPShortPixel::log("PNG2JPG unlink $unlink");
|
279 |
+
@unlink($unlink);
|
280 |
+
}
|
281 |
+
}
|
282 |
+
WPShortPixel::log("PNG2JPG done. Return: " . json_encode($meta));
|
283 |
+
|
284 |
return $meta;
|
285 |
}
|
286 |
|
291 |
* @param $newurl
|
292 |
* @return array
|
293 |
*/
|
294 |
+
protected function png2JpgUpdateUrls($options, $map){
|
295 |
global $wpdb;
|
296 |
+
WPShortPixel::log("PNG2JPG update URLS " . json_encode($map));
|
297 |
$results = array();
|
298 |
$queries = array(
|
299 |
+
'content' => array("UPDATE $wpdb->posts SET post_content = replace(post_content, %s, %s)", __('Content Items (Posts, Pages, Custom Post Types, Revisions)','shortpixel-image-optimiser') ),
|
300 |
+
'excerpts' => array("UPDATE $wpdb->posts SET post_excerpt = replace(post_excerpt, %s, %s)", __('Excerpts','shortpixel-image-optimiser') ),
|
301 |
+
'attachments' => array("UPDATE $wpdb->posts SET guid = replace(guid, %s, %s) WHERE post_type = 'attachment'", __('Attachments','shortpixel-image-optimiser') ),
|
302 |
+
'links' => array("UPDATE $wpdb->links SET link_url = replace(link_url, %s, %s)", __('Links','shortpixel-image-optimiser') ),
|
303 |
+
'custom' => array("UPDATE $wpdb->postmeta SET meta_value = replace(meta_value, %s, %s)", __('Custom Fields','shortpixel-image-optimiser') ),
|
304 |
+
'guids' => array("UPDATE $wpdb->posts SET guid = replace(guid, %s, %s)", __('GUIDs','shortpixel-image-optimiser') )
|
305 |
);
|
306 |
if(count($options) == 0) {
|
307 |
$options = array_keys($queries);
|
308 |
}
|
309 |
foreach($options as $option){
|
310 |
+
WPShortPixel::log("PNG2JPG update URLS on $option ");
|
311 |
if( $option == 'custom' ){
|
312 |
$n = 0;
|
313 |
$row_count = $wpdb->get_var( "SELECT COUNT(*) FROM $wpdb->postmeta" );
|
315 |
$pages = ceil( $row_count / $page_size );
|
316 |
|
317 |
for( $page = 0; $page < $pages; $page++ ) {
|
|
|
318 |
$start = $page * $page_size;
|
319 |
+
$pmquery = "SELECT * FROM $wpdb->postmeta WHERE meta_value <> '' AND meta_value <> '_wp_attachment_metadata' AND meta_value <> '_wp_attached_file' LIMIT $start, $page_size";
|
|
|
320 |
$items = $wpdb->get_results( $pmquery );
|
321 |
foreach( $items as $item ){
|
322 |
$value = $item->meta_value;
|
323 |
if( trim($value) == '' )
|
324 |
continue;
|
325 |
|
326 |
+
$edited = (object)array('data' => $value, 'replaced' => false);
|
327 |
+
foreach($map as $oldurl => $newurl) {
|
328 |
+
if (strlen($newurl)) {
|
329 |
+
$editedOne = $this->png2JpgUnserializeReplace($oldurl, $newurl, $edited->data);
|
330 |
+
$edited->data = $editedOne->data;
|
331 |
+
$edited->replaced = $edited->replaced || $editedOne->replaced;
|
332 |
+
}
|
333 |
+
}
|
334 |
+
if( $edited->replaced ){
|
335 |
+
$fix = $wpdb->query("UPDATE $wpdb->postmeta SET meta_value = '".$edited->data."' WHERE meta_id = ".$item->meta_id );
|
336 |
if( $fix )
|
337 |
$n++;
|
338 |
}
|
340 |
}
|
341 |
$results[$option] = array($n, $queries[$option][1]);
|
342 |
}
|
343 |
+
else {
|
344 |
+
foreach($map as $oldurl => $newurl) {
|
345 |
+
if(strlen($newurl)) {
|
346 |
+
$result = $wpdb->query( $wpdb->prepare( $queries[$option][0], $oldurl, $newurl) );
|
347 |
+
$results[$option] = array($result, $queries[$option][1]);
|
348 |
+
}
|
349 |
+
}
|
350 |
}
|
351 |
}
|
352 |
return $results;
|
361 |
* @return array|mixed|string
|
362 |
*/
|
363 |
function png2JpgUnserializeReplace( $from = '', $to = '', $data = '', $serialised = false ) {
|
364 |
+
$replaced = false;
|
365 |
try {
|
366 |
if ( false !== is_serialized( $data ) ) {
|
367 |
+
|
368 |
+
if(false === strpos($data, wp_basename($from))) {
|
369 |
+
return (object)array('data' => $data, 'replaced' => false); //quick pre-screening
|
370 |
+
}
|
371 |
+
|
372 |
$unserialized = unserialize( $data );
|
373 |
+
$ret = $this->png2JpgUnserializeReplace( $from, $to, $unserialized, true );
|
374 |
+
$data = $ret->data;
|
375 |
+
$replaced = $replaced || $ret->replaced;
|
376 |
}
|
377 |
elseif ( is_array( $data ) ) {
|
378 |
$_tmp = array( );
|
379 |
foreach ( $data as $key => $value ) {
|
380 |
+
$ret = $this->png2JpgUnserializeReplace( $from, $to, $value, false );
|
381 |
+
$_tmp[ $key ] = $ret->data;
|
382 |
+
$replaced = $replaced || $ret->replaced;
|
383 |
}
|
384 |
$data = $_tmp;
|
385 |
unset( $_tmp );
|
386 |
}
|
387 |
+
elseif(is_object( $data )) {
|
388 |
+
foreach(get_object_vars($data) as $key => $value) {
|
389 |
+
$ret = $this->png2JpgUnserializeReplace( $from, $to, $value, false );
|
390 |
+
$_tmp[ $key ] = $ret->data;
|
391 |
+
$replaced = $replaced || $ret->replaced;
|
392 |
+
}
|
393 |
+
$data = (object)$_tmp;
|
394 |
+
}
|
395 |
+
elseif ( is_string( $data )) {
|
396 |
+
if(false !== strpos($data, $from)) {
|
397 |
+
$replaced = true;
|
398 |
$data = str_replace( $from, $to, $data );
|
399 |
+
} elseif( strlen($from) > strlen($data) //data is shorter than the url to be replaced - could be a relative path?
|
400 |
+
&& strlen($data) >= strlen(wp_basename($from)) //but should at least contain the file name
|
401 |
+
&& strpos($from, $data) == strlen($from) - strlen($data)) {
|
402 |
+
$replaced = true;
|
403 |
+
$data = substr($to, strlen($from) - strlen($data));
|
404 |
+
}
|
405 |
+
}
|
406 |
+
if ( $serialised ) {
|
407 |
+
return (object)array('data' => serialize($data), 'replaced' => $replaced);
|
408 |
}
|
|
|
|
|
409 |
} catch( Exception $error ) {
|
410 |
}
|
411 |
+
return (object)array('data' => $data, 'replaced' => $replaced);
|
412 |
}
|
413 |
}
|
class/view/shortpixel_view.php
CHANGED
@@ -386,9 +386,9 @@ class ShortPixelView {
|
|
386 |
<?php $this->displayBulkStats($quotaData['totalProcessedFiles'], $quotaData['mainProcessedFiles'], $under5PercentCount, $averageCompression, $savedSpace);?>
|
387 |
</div>
|
388 |
</div>
|
389 |
-
<p><?php printf(__('Go to the ShortPixel <a href="%soptions-general.php?page=wp-shortpixel#stats">Stats</a>
|
390 |
-
|
391 |
-
|
392 |
SHORTPIXEL_API,
|
393 |
get_admin_url(), (defined("SHORTPIXEL_HIDE_API_KEY") ? '' : $this->ctrl->getApiKey()) );?></p>
|
394 |
<?php
|
@@ -703,7 +703,7 @@ class ShortPixelView {
|
|
703 |
<h1><?php _e('ShortPixel Plugin Settings','shortpixel-image-optimiser');?></h1>
|
704 |
<p style="font-size:18px">
|
705 |
<a href="https://shortpixel.com/<?php
|
706 |
-
echo($this->ctrl->getVerifiedKey() ? "login/".(defined("SHORTPIXEL_HIDE_API_KEY") ? '' : $this->ctrl->getApiKey()) : "pricing" . WPShortPixel::getAffiliateSufix());
|
707 |
?>" target="_blank" style="font-size:18px">
|
708 |
<?php _e('Upgrade now','shortpixel-image-optimiser');?>
|
709 |
</a> | <a href="https://shortpixel.com/pricing<?php echo(WPShortPixel::getAffiliateSufix()); ?>#faq" target="_blank" style="font-size:18px"><?php _e('FAQ','shortpixel-image-optimiser');?> </a> |
|
@@ -902,7 +902,7 @@ class ShortPixelView {
|
|
902 |
<th scope="row"><label for="thumbnails"><?php _e('Also include thumbnails:','shortpixel-image-optimiser');?></label></th>
|
903 |
<td><input name="thumbnails" type="checkbox" id="thumbnails" <?php echo( $checked );?>> <?php
|
904 |
_e('Apply compression also to <strong>image thumbnails.</strong> ','shortpixel-image-optimiser');?>
|
905 |
-
<?php echo($thumbnailsToProcess ? "(" . number_format($thumbnailsToProcess) . " " . __('thumbnails to optimize','shortpixel-image-optimiser') . ")" : "");?>
|
906 |
<p class="settings-info">
|
907 |
<?php _e('It is highly recommended that you optimize the thumbnails as they are usually the images most viewed by end users and can generate most traffic.<br>Please note that thumbnails count up to your total quota.','shortpixel-image-optimiser');?>
|
908 |
</p>
|
@@ -1181,16 +1181,16 @@ class ShortPixelView {
|
|
1181 |
_e('name:keepbig, path:/ignore_regex/i, size:1000x2000','shortpixel-image-optimiser');?>">
|
1182 |
<?php _e('Exclude certain images from being optimized, based on patterns.','shortpixel-image-optimiser');?>
|
1183 |
<p class="settings-info">
|
1184 |
-
<?php _e('Add patterns separated by comma. A pattern
|
1185 |
-
|
1186 |
-
|
1187 |
-
|
1188 |
-
|
1189 |
-
|
1190 |
-
|
1191 |
-
|
1192 |
-
|
1193 |
-
|
1194 |
</p>
|
1195 |
</td>
|
1196 |
</tr>
|
@@ -1455,16 +1455,15 @@ class ShortPixelView {
|
|
1455 |
case 'imgOptimized':
|
1456 |
$excluded = (isset($data['excludeSizes']) ? count($data['excludeSizes']) : 0);
|
1457 |
$successText = $this->getSuccessText($data['percent'],$data['bonus'],$data['type'],$data['thumbsOpt'],$data['thumbsTotal'], $data['retinasOpt'], $data['excludeSizes']);
|
|
|
1458 |
if($extended) {
|
1459 |
-
$excludeSizes = '';
|
1460 |
if(isset($data['excludeSizes'])) {
|
1461 |
$excludeSizes .= "<br><span> <span style='font-weight: bold;'>" . __("Excluded thumbnails:", 'shortpixel-image-optimiser') . "</span>";
|
1462 |
-
foreach($data['excludeSizes'] as $
|
1463 |
-
$excludeSizes .= "<br> • " . $
|
1464 |
}
|
1465 |
$excludeSizes .= '</span>';
|
1466 |
}
|
1467 |
-
$missingThumbs = '';
|
1468 |
if(count($data['thumbsMissing'])) {
|
1469 |
$missingThumbs .= "<br><span> <span style='font-weight: bold;'>" . __("Missing thumbnails:", 'shortpixel-image-optimiser') . "</span>";
|
1470 |
foreach($data['thumbsMissing'] as $miss) {
|
386 |
<?php $this->displayBulkStats($quotaData['totalProcessedFiles'], $quotaData['mainProcessedFiles'], $under5PercentCount, $averageCompression, $savedSpace);?>
|
387 |
</div>
|
388 |
</div>
|
389 |
+
<p><?php printf(__('Go to the ShortPixel <a href="%soptions-general.php?page=wp-shortpixel#stats">Stats</a>
|
390 |
+
and see all your websites\' optimized stats. Download your detailed <a href="https://%s/v2/report.php?key=%s">Optimization Report</a>
|
391 |
+
to check your image optimization statistics for the last 40 days.','shortpixel-image-optimiser'),
|
392 |
SHORTPIXEL_API,
|
393 |
get_admin_url(), (defined("SHORTPIXEL_HIDE_API_KEY") ? '' : $this->ctrl->getApiKey()) );?></p>
|
394 |
<?php
|
703 |
<h1><?php _e('ShortPixel Plugin Settings','shortpixel-image-optimiser');?></h1>
|
704 |
<p style="font-size:18px">
|
705 |
<a href="https://shortpixel.com/<?php
|
706 |
+
echo(($this->ctrl->getVerifiedKey() ? "login/".(defined("SHORTPIXEL_HIDE_API_KEY") ? '' : $this->ctrl->getApiKey()) : "pricing") . WPShortPixel::getAffiliateSufix());
|
707 |
?>" target="_blank" style="font-size:18px">
|
708 |
<?php _e('Upgrade now','shortpixel-image-optimiser');?>
|
709 |
</a> | <a href="https://shortpixel.com/pricing<?php echo(WPShortPixel::getAffiliateSufix()); ?>#faq" target="_blank" style="font-size:18px"><?php _e('FAQ','shortpixel-image-optimiser');?> </a> |
|
902 |
<th scope="row"><label for="thumbnails"><?php _e('Also include thumbnails:','shortpixel-image-optimiser');?></label></th>
|
903 |
<td><input name="thumbnails" type="checkbox" id="thumbnails" <?php echo( $checked );?>> <?php
|
904 |
_e('Apply compression also to <strong>image thumbnails.</strong> ','shortpixel-image-optimiser');?>
|
905 |
+
<?php echo($thumbnailsToProcess > 0 ? "(" . number_format($thumbnailsToProcess) . " " . __('thumbnails to optimize','shortpixel-image-optimiser') . ")" : "");?>
|
906 |
<p class="settings-info">
|
907 |
<?php _e('It is highly recommended that you optimize the thumbnails as they are usually the images most viewed by end users and can generate most traffic.<br>Please note that thumbnails count up to your total quota.','shortpixel-image-optimiser');?>
|
908 |
</p>
|
1181 |
_e('name:keepbig, path:/ignore_regex/i, size:1000x2000','shortpixel-image-optimiser');?>">
|
1182 |
<?php _e('Exclude certain images from being optimized, based on patterns.','shortpixel-image-optimiser');?>
|
1183 |
<p class="settings-info">
|
1184 |
+
<?php _e('Add patterns separated by comma. A pattern consists of a <strong>type:value</strong> pair; the accepted types are
|
1185 |
+
<strong>"name"</strong>, <strong>"path"</strong> and <strong>"size"</strong>.
|
1186 |
+
A file will be excluded if it matches any of the patterns.
|
1187 |
+
<br>For a <strong>"name"</strong> pattern only the filename will be matched but for a <strong>"path"</strong>,
|
1188 |
+
all the path will be matched (useful for excluding certain subdirectories altoghether).
|
1189 |
+
For these you can also use regular expressions accepted by preg_match, but without "," or ":".
|
1190 |
+
A pattern will be considered a regex if it starts with a "/" and is valid.
|
1191 |
+
<br>For the <strong>"size"</strong> type,
|
1192 |
+
which applies only to Media Library images, <strong>the main images (not thumbnails)</strong> that have the size in the specified range will be excluded.
|
1193 |
+
The format for the "size" exclude is: <strong>minWidth</strong>-<strong>maxWidth</strong>x<strong>minHeight</strong>-<strong>maxHeight</strong>, for example <strong>size:1000-1100x2000-2200</strong>. You can also specify a precise size, as <strong>1000x2000</strong>.','shortpixel-image-optimiser');?>
|
1194 |
</p>
|
1195 |
</td>
|
1196 |
</tr>
|
1455 |
case 'imgOptimized':
|
1456 |
$excluded = (isset($data['excludeSizes']) ? count($data['excludeSizes']) : 0);
|
1457 |
$successText = $this->getSuccessText($data['percent'],$data['bonus'],$data['type'],$data['thumbsOpt'],$data['thumbsTotal'], $data['retinasOpt'], $data['excludeSizes']);
|
1458 |
+
$missingThumbs = $excludeSizes = '';
|
1459 |
if($extended) {
|
|
|
1460 |
if(isset($data['excludeSizes'])) {
|
1461 |
$excludeSizes .= "<br><span> <span style='font-weight: bold;'>" . __("Excluded thumbnails:", 'shortpixel-image-optimiser') . "</span>";
|
1462 |
+
foreach($data['excludeSizes'] as $excludedItem) {
|
1463 |
+
$excludeSizes .= "<br> • " . $excludedItem;
|
1464 |
}
|
1465 |
$excludeSizes .= '</span>';
|
1466 |
}
|
|
|
1467 |
if(count($data['thumbsMissing'])) {
|
1468 |
$missingThumbs .= "<br><span> <span style='font-weight: bold;'>" . __("Missing thumbnails:", 'shortpixel-image-optimiser') . "</span>";
|
1469 |
foreach($data['thumbsMissing'] as $miss) {
|
class/wp-short-pixel.php
CHANGED
@@ -3123,6 +3123,27 @@ class WPShortPixel {
|
|
3123 |
email: "<?php $u = wp_get_current_user(); echo($u->user_email); ?>",
|
3124 |
apiKey: "<?php echo($this->getApiKey());?>"
|
3125 |
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
3126 |
});
|
3127 |
</script><?php
|
3128 |
}
|
3123 |
email: "<?php $u = wp_get_current_user(); echo($u->user_email); ?>",
|
3124 |
apiKey: "<?php echo($this->getApiKey());?>"
|
3125 |
});
|
3126 |
+
HS.beacon.suggest([<?php
|
3127 |
+
$screen = get_current_screen();
|
3128 |
+
if($screen) {
|
3129 |
+
switch($screen->id) {
|
3130 |
+
case 'media_page_wp-short-pixel-bulk':
|
3131 |
+
echo(" '5a5de2782c7d3a19436843af', '5a5de6902c7d3a19436843e9', '5a5de5c42c7d3a19436843d0', '5a9945e42c7d3a75495145d0', '5a5de1c2042863193801047c',
|
3132 |
+
'5a5de66f2c7d3a19436843e0', '5a9946e62c7d3a75495145d8', '5a5de4f02c7d3a19436843c8', '5a5de65f042863193801049f', '5a5de2df0428631938010485' ");
|
3133 |
+
break;
|
3134 |
+
case 'settings_page_wp-shortpixel':
|
3135 |
+
echo(" '5a5de1de2c7d3a19436843a8', '5a6612032c7d3a39e6263a1d', '5a5de1c2042863193801047c', '5a5de2782c7d3a19436843af', '5a6610c62c7d3a39e6263a02',
|
3136 |
+
'5a9945e42c7d3a75495145d0', '5a5de66f2c7d3a19436843e0', '5a6597e80428632faf620487', '5a5de5c42c7d3a19436843d0', '5a5de5642c7d3a19436843cc' ");
|
3137 |
+
break;
|
3138 |
+
case 'media_page_wp-short-pixel-custom':
|
3139 |
+
echo(" '5a9946e62c7d3a75495145d8', '5a5de1c2042863193801047c', '5a5de2782c7d3a19436843af', '5a5de6902c7d3a19436843e9', '5a5de4f02c7d3a19436843c8',
|
3140 |
+
'5a6610c62c7d3a39e6263a02', '5a9945e42c7d3a75495145d0', '5a5de46c2c7d3a19436843c1', '5a5de1de2c7d3a19436843a8', '5a5de25c2c7d3a19436843ad' ");
|
3141 |
+
break;
|
3142 |
+
default:
|
3143 |
+
die($screen->id);
|
3144 |
+
}
|
3145 |
+
}
|
3146 |
+
?>]);
|
3147 |
});
|
3148 |
</script><?php
|
3149 |
}
|
readme.txt
CHANGED
@@ -4,7 +4,7 @@ Tags: compress, image, compression, optimize, image optimizer, image optimiser,
|
|
4 |
Requires at least: 3.2.0
|
5 |
Tested up to: 4.9
|
6 |
Requires PHP: 5.2
|
7 |
-
Stable tag: 4.10.
|
8 |
License: GPLv2 or later
|
9 |
License URI: http://www.gnu.org/licenses/gpl-2.0.html
|
10 |
|
@@ -228,6 +228,10 @@ The ShortPixel team is here to help. <a href="https://shortpixel.com/contact">Co
|
|
228 |
|
229 |
== Changelog ==
|
230 |
|
|
|
|
|
|
|
|
|
231 |
= 4.10.2 =
|
232 |
* fix error when listing Other media in some circumstances
|
233 |
|
4 |
Requires at least: 3.2.0
|
5 |
Tested up to: 4.9
|
6 |
Requires PHP: 5.2
|
7 |
+
Stable tag: 4.10.3
|
8 |
License: GPLv2 or later
|
9 |
License URI: http://www.gnu.org/licenses/gpl-2.0.html
|
10 |
|
228 |
|
229 |
== Changelog ==
|
230 |
|
231 |
+
= 4.10.3 =
|
232 |
+
* improvements to context help beacon
|
233 |
+
* performance improvements to PNG to JPG conversion
|
234 |
+
|
235 |
= 4.10.2 =
|
236 |
* fix error when listing Other media in some circumstances
|
237 |
|
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.10.
|
7 |
* Author: ShortPixel
|
8 |
* Author URI: https://shortpixel.com
|
9 |
* Text Domain: shortpixel-image-optimiser
|
@@ -18,7 +18,7 @@ define('SHORTPIXEL_PLUGIN_FILE', __FILE__);
|
|
18 |
|
19 |
//define('SHORTPIXEL_AFFILIATE_CODE', '');
|
20 |
|
21 |
-
define('SHORTPIXEL_IMAGE_OPTIMISER_VERSION', "4.10.
|
22 |
define('SHORTPIXEL_MAX_TIMEOUT', 10);
|
23 |
define('SHORTPIXEL_VALIDATE_MAX_TIMEOUT', 15);
|
24 |
define('SHORTPIXEL_BACKUP', 'ShortpixelBackups');
|
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.10.3
|
7 |
* Author: ShortPixel
|
8 |
* Author URI: https://shortpixel.com
|
9 |
* Text Domain: shortpixel-image-optimiser
|
18 |
|
19 |
//define('SHORTPIXEL_AFFILIATE_CODE', '');
|
20 |
|
21 |
+
define('SHORTPIXEL_IMAGE_OPTIMISER_VERSION', "4.10.3");
|
22 |
define('SHORTPIXEL_MAX_TIMEOUT', 10);
|
23 |
define('SHORTPIXEL_VALIDATE_MAX_TIMEOUT', 15);
|
24 |
define('SHORTPIXEL_BACKUP', 'ShortpixelBackups');
|