Version Description
- fix bug when searching for thumbanils of files with same prefix
- fix bug when several successive images have all files missing
Download this release
Release Info
Developer | ShortPixel |
Plugin | ShortPixel Image Optimizer |
Version | 4.2.8 |
Comparing to | |
See all releases |
Code changes from version 4.2.7 to 4.2.8
- class/db/shortpixel-meta-facade.php +1 -1
- class/db/wp-shortpixel-media-library-adapter.php +23 -2
- class/view/shortpixel_view.php +1 -1
- class/wp-short-pixel.php +2457 -0
- readme.txt +6 -1
- shortpixel_api.php +5 -0
- wp-shortpixel-req.php +1 -0
- wp-shortpixel.php +8 -2454
class/db/shortpixel-meta-facade.php
CHANGED
@@ -49,7 +49,7 @@ class ShortPixelMetaFacade {
|
|
49 |
$path = get_attached_file($ID);
|
50 |
return new ShortPixelMeta(array(
|
51 |
"id" => $ID,
|
52 |
-
"name" =>
|
53 |
"path" => $path,
|
54 |
"webPath" => (isset($rawMeta["file"]) ? $rawMeta["file"] : null),
|
55 |
"thumbs" => (isset($rawMeta["sizes"]) ? $rawMeta["sizes"] : array()),
|
49 |
$path = get_attached_file($ID);
|
50 |
return new ShortPixelMeta(array(
|
51 |
"id" => $ID,
|
52 |
+
"name" => ShortPixelAPI::MB_basename($path),
|
53 |
"path" => $path,
|
54 |
"webPath" => (isset($rawMeta["file"]) ? $rawMeta["file"] : null),
|
55 |
"thumbs" => (isset($rawMeta["sizes"]) ? $rawMeta["sizes"] : array()),
|
class/db/wp-shortpixel-media-library-adapter.php
CHANGED
@@ -141,9 +141,30 @@ class WpShortPixelMediaLbraryAdapter {
|
|
141 |
return $count;
|
142 |
}
|
143 |
|
144 |
-
public static function
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
145 |
$ext = pathinfo($mainFile, PATHINFO_EXTENSION);
|
146 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
147 |
}
|
148 |
|
149 |
protected static function getOptimalChunkSize() {
|
141 |
return $count;
|
142 |
}
|
143 |
|
144 |
+
public static function cleanupFoundThumbs($itemHandler) {
|
145 |
+
$meta = $itemHandler->getMeta();
|
146 |
+
$sizesAll = $meta->getThumbs();
|
147 |
+
$sizes = array();
|
148 |
+
foreach($sizesAll as $key => $size) {
|
149 |
+
if (strpos($key, ShortPixelMeta::FOUND_THUMB_PREFIX) === 0) continue;
|
150 |
+
$sizes[$key] = $size;
|
151 |
+
}
|
152 |
+
$meta->setThumbs($sizes);
|
153 |
+
$itemHandler->updateMeta($meta);
|
154 |
+
}
|
155 |
+
|
156 |
+
public static function findThumbs($mainFile) {
|
157 |
$ext = pathinfo($mainFile, PATHINFO_EXTENSION);
|
158 |
+
$base = substr($mainFile, 0, strlen($mainFile) - strlen($ext) - 1);
|
159 |
+
$pattern = '/' . preg_quote($base, '/') . '-\d+x\d+\.'. $ext .'/';
|
160 |
+
$thumbsCandidates = @glob($base . "-*." . $ext);
|
161 |
+
$thumbs = array();
|
162 |
+
foreach($thumbsCandidates as $th) {
|
163 |
+
if(preg_match($pattern, $th)) {
|
164 |
+
$thumbs[]= $th;
|
165 |
+
}
|
166 |
+
}
|
167 |
+
return $thumbs;
|
168 |
}
|
169 |
|
170 |
protected static function getOptimalChunkSize() {
|
class/view/shortpixel_view.php
CHANGED
@@ -907,7 +907,7 @@ class ShortPixelView {
|
|
907 |
<tr>
|
908 |
<th scope="row"><label for="optimizePdfs"><?php _e('Optimize PDFs','shortpixel-image-optimiser');?></label></th>
|
909 |
<td>
|
910 |
-
<input name="optimizePdfs" type="checkbox" id="optimizePdfs" <?php echo( $optimizePdfs );?>> <?php _e('
|
911 |
</td>
|
912 |
</tr>
|
913 |
<tr>
|
907 |
<tr>
|
908 |
<th scope="row"><label for="optimizePdfs"><?php _e('Optimize PDFs','shortpixel-image-optimiser');?></label></th>
|
909 |
<td>
|
910 |
+
<input name="optimizePdfs" type="checkbox" id="optimizePdfs" <?php echo( $optimizePdfs );?>> <?php _e('Automatically optimize PDF documents.','shortpixel-image-optimiser');?>
|
911 |
</td>
|
912 |
</tr>
|
913 |
<tr>
|
class/wp-short-pixel.php
ADDED
@@ -0,0 +1,2457 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
class WPShortPixel {
|
4 |
+
|
5 |
+
const BULK_EMPTY_QUEUE = 0;
|
6 |
+
|
7 |
+
private $_affiliateSufix;
|
8 |
+
|
9 |
+
private $_apiInterface = null;
|
10 |
+
private $_settings = null;
|
11 |
+
private $prioQ = null;
|
12 |
+
private $view = null;
|
13 |
+
|
14 |
+
private $hasNextGen = false;
|
15 |
+
private $spMetaDao = null;
|
16 |
+
|
17 |
+
public static $PROCESSABLE_EXTENSIONS = array('jpg', 'jpeg', 'gif', 'png', 'pdf');
|
18 |
+
|
19 |
+
public function __construct() {
|
20 |
+
if (!session_id()) {
|
21 |
+
session_start();
|
22 |
+
}
|
23 |
+
|
24 |
+
load_plugin_textdomain('shortpixel-image-optimiser', false, plugin_basename(dirname( SHORTPIXEL_PLUGIN_FILE )).'/lang');
|
25 |
+
|
26 |
+
$isAdminUser = current_user_can( 'manage_options' );
|
27 |
+
|
28 |
+
$this->_affiliateSufix = (strlen(SP_AFFILIATE_CODE)) ? "/affiliate/" . SP_AFFILIATE_CODE : "";
|
29 |
+
$this->_settings = new WPShortPixelSettings();
|
30 |
+
$this->_apiInterface = new ShortPixelAPI($this->_settings);
|
31 |
+
$this->hasNextGen = ShortPixelNextGenAdapter::hasNextGen();
|
32 |
+
$this->spMetaDao = new ShortPixelCustomMetaDao(new WpShortPixelDb(), $this->_settings->hasCustomFolders);
|
33 |
+
$this->prioQ = new ShortPixelQueue($this, $this->_settings);
|
34 |
+
$this->view = new ShortPixelView($this);
|
35 |
+
|
36 |
+
define('QUOTA_EXCEEDED', $this->view->getQuotaExceededHTML());
|
37 |
+
|
38 |
+
$this->setDefaultViewModeList();//set default mode as list. only @ first run
|
39 |
+
|
40 |
+
//add hook for image upload processing
|
41 |
+
//add_filter( 'wp_generate_attachment_metadata', array( &$this, 'handleMediaLibraryImageUpload' ), 10, 2 ); // now external
|
42 |
+
add_filter( 'plugin_action_links_' . plugin_basename(SHORTPIXEL_PLUGIN_FILE), array(&$this, 'generatePluginLinks'));//for plugin settings page
|
43 |
+
|
44 |
+
//add_action( 'admin_footer', array(&$this, 'handleImageProcessing'));
|
45 |
+
|
46 |
+
//Media custom column
|
47 |
+
add_filter( 'manage_media_columns', array( &$this, 'columns' ) );//add media library column header
|
48 |
+
add_action( 'manage_media_custom_column', array( &$this, 'generateCustomColumn' ), 10, 2 );//generate the media library column
|
49 |
+
//Edit media meta box
|
50 |
+
add_action( 'add_meta_boxes', array( &$this, 'shortpixelInfoBox') );
|
51 |
+
//for cleaning up the WebP images when an attachment is deleted
|
52 |
+
add_action( 'delete_attachment', array( &$this, 'onDeleteImage') );
|
53 |
+
|
54 |
+
//for NextGen
|
55 |
+
if($this->_settings->hasCustomFolders) {
|
56 |
+
add_filter( 'ngg_manage_images_columns', array( &$this, 'nggColumns' ) );
|
57 |
+
add_filter( 'ngg_manage_images_number_of_columns', array( &$this, 'nggCountColumns' ) );
|
58 |
+
add_filter( 'ngg_manage_images_column_7_header', array( &$this, 'nggColumnHeader' ) );
|
59 |
+
add_filter( 'ngg_manage_images_column_7_content', array( &$this, 'nggColumnContent' ) );
|
60 |
+
// hook on the NextGen gallery list update
|
61 |
+
add_action('ngg_update_addgallery_page', array( &$this, 'addNextGenGalleriesToCustom'));
|
62 |
+
}
|
63 |
+
|
64 |
+
// integration with WP/LR Sync plugin
|
65 |
+
add_action( 'wplr_update_media', array( &$this, 'onWpLrUpdateMedia' ), 10, 2);
|
66 |
+
|
67 |
+
//custom hook
|
68 |
+
add_action( 'shortpixel-optimize-now', array( &$this, 'optimizeNowHook' ), 10, 1);
|
69 |
+
|
70 |
+
if($isAdminUser) {
|
71 |
+
//add settings page
|
72 |
+
add_action( 'admin_menu', array( &$this, 'registerSettingsPage' ) );//display SP in Settings menu
|
73 |
+
add_action( 'admin_menu', array( &$this, 'registerAdminPage' ) );
|
74 |
+
|
75 |
+
add_action('wp_ajax_shortpixel_browse_content', array(&$this, 'browseContent'));
|
76 |
+
add_action('wp_ajax_shortpixel_get_backup_size', array(&$this, 'getBackupSize'));
|
77 |
+
|
78 |
+
add_action( 'delete_attachment', array( &$this, 'handleDeleteAttachmentInBackup' ) );
|
79 |
+
add_action( 'load-upload.php', array( &$this, 'handleCustomBulk'));
|
80 |
+
|
81 |
+
//backup restore
|
82 |
+
add_action('admin_action_shortpixel_restore_backup', array(&$this, 'handleRestoreBackup'));
|
83 |
+
//reoptimize with a different algorithm (losless/lossy)
|
84 |
+
add_action('wp_ajax_shortpixel_redo', array(&$this, 'handleRedo'));
|
85 |
+
//optimize thumbnails
|
86 |
+
add_action('wp_ajax_shortpixel_optimize_thumbs', array(&$this, 'handleOptimizeThumbs'));
|
87 |
+
|
88 |
+
//toolbar notifications
|
89 |
+
add_action( 'admin_bar_menu', array( &$this, 'toolbar_shortpixel_processing'), 999 );
|
90 |
+
//deactivate plugin
|
91 |
+
add_action( 'admin_post_shortpixel_deactivate_plugin', array(&$this, 'deactivatePlugin'));
|
92 |
+
}
|
93 |
+
|
94 |
+
//automatic optimization
|
95 |
+
add_action( 'wp_ajax_shortpixel_image_processing', array( &$this, 'handleImageProcessing') );
|
96 |
+
//manual optimization
|
97 |
+
add_action( 'wp_ajax_shortpixel_manual_optimization', array(&$this, 'handleManualOptimization'));
|
98 |
+
//dismiss notices
|
99 |
+
add_action( 'wp_ajax_shortpixel_dismiss_notice', array(&$this, 'dismissAdminNotice'));
|
100 |
+
add_action( 'wp_ajax_shortpixel_dismiss_media_alert', array(&$this, 'dismissMediaAlert'));
|
101 |
+
//check quota
|
102 |
+
add_action('admin_action_shortpixel_check_quota', array(&$this, 'handleCheckQuota'));
|
103 |
+
//This adds the constants used in PHP to be available also in JS
|
104 |
+
add_action( 'admin_footer', array( &$this, 'shortPixelJS') );
|
105 |
+
|
106 |
+
if($this->_settings->frontBootstrap) {
|
107 |
+
//also need to have it in the front footer then
|
108 |
+
add_action( 'wp_footer', array( &$this, 'shortPixelJS') );
|
109 |
+
//need to add the nopriv action for when items exist in the queue and no user is logged in
|
110 |
+
add_action( 'wp_ajax_nopriv_shortpixel_image_processing', array( &$this, 'handleImageProcessing') );
|
111 |
+
}
|
112 |
+
//register a method to display admin notices if necessary
|
113 |
+
add_action('admin_notices', array( &$this, 'displayAdminNotices'));
|
114 |
+
|
115 |
+
$this->migrateBackupFolder();
|
116 |
+
|
117 |
+
if(!$this->_settings->redirectedSettings && !$this->_settings->verifiedKey && (!function_exists("is_multisite") || !is_multisite())) {
|
118 |
+
$this->_settings->redirectedSettings = 1;
|
119 |
+
wp_redirect(admin_url("options-general.php?page=wp-shortpixel"));
|
120 |
+
exit();
|
121 |
+
}
|
122 |
+
}
|
123 |
+
|
124 |
+
//handling older
|
125 |
+
public function WPShortPixel() {
|
126 |
+
$this->__construct();
|
127 |
+
}
|
128 |
+
|
129 |
+
public function registerSettingsPage() {
|
130 |
+
add_options_page( __('ShortPixel Settings','shortpixel-image-optimiser'), 'ShortPixel', 'manage_options', 'wp-shortpixel', array($this, 'renderSettingsMenu'));
|
131 |
+
}
|
132 |
+
|
133 |
+
function registerAdminPage( ) {
|
134 |
+
if($this->spMetaDao->hasFoldersTable() && count($this->spMetaDao->getFolders())) {
|
135 |
+
/*translators: title and menu name for the Other media page*/
|
136 |
+
add_media_page( __('Other Media Optimized by ShortPixel','shortpixel-image-optimiser'), __('Other Media','shortpixel-image-optimiser'), 'edit_others_posts', 'wp-short-pixel-custom', array( &$this, 'listCustomMedia' ) );
|
137 |
+
}
|
138 |
+
/*translators: title and menu name for the Bulk Processing page*/
|
139 |
+
add_media_page( __('ShortPixel Bulk Process','shortpixel-image-optimiser'), __('Bulk ShortPixel','shortpixel-image-optimiser'), 'edit_others_posts', 'wp-short-pixel-bulk', array( &$this, 'bulkProcess' ) );
|
140 |
+
}
|
141 |
+
|
142 |
+
public static function shortPixelActivatePlugin()//reset some params to avoid trouble for plugins that were activated/deactivated/activated
|
143 |
+
{
|
144 |
+
self::shortPixelDeactivatePlugin();
|
145 |
+
if(SP_RESET_ON_ACTIVATE === true && WP_DEBUG === true) { //force reset plugin counters, only on specific occasions and on test environments
|
146 |
+
WPShortPixelSettings::debugResetOptions();
|
147 |
+
|
148 |
+
$settings = new WPShortPixelSettings();
|
149 |
+
$spMetaDao = new ShortPixelCustomMetaDao(new WpShortPixelDb(), $settings->hasCustomFolders);
|
150 |
+
$spMetaDao->dropTables();
|
151 |
+
}
|
152 |
+
WPShortPixelSettings::onActivate();
|
153 |
+
}
|
154 |
+
|
155 |
+
public static function shortPixelDeactivatePlugin()//reset some params to avoid trouble for plugins that were activated/deactivated/activated
|
156 |
+
{
|
157 |
+
include_once dirname( SHORTPIXEL_PLUGIN_FILE ) . '/wp-shortpixel-req.php';
|
158 |
+
ShortPixelQueue::resetBulk();
|
159 |
+
ShortPixelQueue::resetPrio();
|
160 |
+
WPShortPixelSettings::onDeactivate();
|
161 |
+
}
|
162 |
+
|
163 |
+
public static function getConflictingPlugins() {
|
164 |
+
$conflictPlugins = array(
|
165 |
+
'WP Smush - Image Optimization' => 'wp-smushit/wp-smush.php',
|
166 |
+
'Imagify Image Optimizer' => 'imagify/imagify.php',
|
167 |
+
'Compress JPEG & PNG images (TinyPNG)' => 'tiny-compress-images/tiny-compress-images.php',
|
168 |
+
'Kraken.io Image Optimizer' => 'kraken-image-optimizer/kraken.php',
|
169 |
+
'Optimus - WordPress Image Optimizer' => 'optimus/optimus.php',
|
170 |
+
'EWWW Image Optimizer' => 'ewww-image-optimizer/ewww-image-optimizer.php',
|
171 |
+
'ImageRecycle pdf & image compression' => 'imagerecycle-pdf-image-compression/wp-image-recycle.php',
|
172 |
+
'CheetahO Image Optimizer' => 'cheetaho-image-optimizer/cheetaho.php',
|
173 |
+
'Zara 4 Image Compression' => 'zara-4/zara-4.php',
|
174 |
+
'Prizm Image' => 'prizm-image/wp-prizmimage.php',
|
175 |
+
'CW Image Optimizer' => 'cw-image-optimizer/cw-image-optimizer.php'
|
176 |
+
);
|
177 |
+
$found = array();
|
178 |
+
foreach($conflictPlugins as $name => $path) {
|
179 |
+
if(is_plugin_active($path)) {
|
180 |
+
$found[] = array('name' => $name, 'path' => $path);
|
181 |
+
}
|
182 |
+
}
|
183 |
+
return $found;
|
184 |
+
}
|
185 |
+
|
186 |
+
public function displayAdminNotices() {
|
187 |
+
$dismissed = $this->_settings->dismissedNotices ? $this->_settings->dismissedNotices : array();
|
188 |
+
if(!$this->_settings->verifiedKey) {
|
189 |
+
$now = time();
|
190 |
+
$act = $this->_settings->activationDate ? $this->_settings->activationDate : $now;
|
191 |
+
if($this->_settings->activationNotice && $this->_settings->redirectedSettings >= 2) {
|
192 |
+
ShortPixelView::displayActivationNotice();
|
193 |
+
$this->_settings->activationNotice = null;
|
194 |
+
}
|
195 |
+
if( ($now > $act + 7200) && !isset($dismissed['2h'])) {
|
196 |
+
ShortPixelView::displayActivationNotice('2h');
|
197 |
+
} else if( ($now > $act + 72 * 3600) && !isset($dismissed['3d'])) {
|
198 |
+
ShortPixelView::displayActivationNotice('3d');
|
199 |
+
}
|
200 |
+
}
|
201 |
+
if(!isset($dismissed['compat'])) {
|
202 |
+
$conflictPlugins = self::getConflictingPlugins();
|
203 |
+
if(count($conflictPlugins)) {
|
204 |
+
ShortPixelView::displayActivationNotice('compat', $conflictPlugins);
|
205 |
+
}
|
206 |
+
}
|
207 |
+
}
|
208 |
+
|
209 |
+
public function dismissAdminNotice() {
|
210 |
+
$noticeId = preg_replace('|[^a-z0-9]|i', '', $_GET['notice_id']);
|
211 |
+
$dismissed = $this->_settings->dismissedNotices ? $this->_settings->dismissedNotices : array();
|
212 |
+
$dismissed[$noticeId] = true;
|
213 |
+
$this->_settings->dismissedNotices = $dismissed;
|
214 |
+
die(json_encode(array("Status" => 'success', "Message" => 'Notice ID: ' . $noticeId . ' dismissed')));
|
215 |
+
}
|
216 |
+
|
217 |
+
public function dismissMediaAlert() {
|
218 |
+
$this->_settings->mediaAlert = 1;
|
219 |
+
die(json_encode(array("Status" => 'success', "Message" => __('Media alert dismissed','shortpixel-image-optimiser'))));
|
220 |
+
}
|
221 |
+
|
222 |
+
//set default move as "list". only set once, it won't try to set the default mode again.
|
223 |
+
public function setDefaultViewModeList()
|
224 |
+
{
|
225 |
+
if($this->_settings->mediaLibraryViewMode === false)
|
226 |
+
{
|
227 |
+
$this->_settings->mediaLibraryViewMode = 1;
|
228 |
+
$currentUserID = false;
|
229 |
+
if ( function_exists('wp_get_current_user') ) {
|
230 |
+
$current_user = wp_get_current_user();
|
231 |
+
$currentUserID = $current_user->ID;
|
232 |
+
update_user_meta($currentUserID, "wp_media_library_mode", "list");
|
233 |
+
}
|
234 |
+
}
|
235 |
+
|
236 |
+
}
|
237 |
+
|
238 |
+
static function log($message) {
|
239 |
+
if (SHORTPIXEL_DEBUG === true) {
|
240 |
+
if (is_array($message) || is_object($message)) {
|
241 |
+
error_log(print_r($message, true));
|
242 |
+
} else {
|
243 |
+
error_log($message);
|
244 |
+
}
|
245 |
+
}
|
246 |
+
}
|
247 |
+
|
248 |
+
function shortPixelJS() { ?>
|
249 |
+
<script type="text/javascript" >
|
250 |
+
var ShortPixelConstants = {
|
251 |
+
STATUS_SUCCESS: <?php echo ShortPixelAPI::STATUS_SUCCESS; ?>,
|
252 |
+
STATUS_EMPTY_QUEUE: <?php echo self::BULK_EMPTY_QUEUE; ?>,
|
253 |
+
STATUS_ERROR: <?php echo ShortPixelAPI::STATUS_ERROR; ?>,
|
254 |
+
STATUS_FAIL: <?php echo ShortPixelAPI::STATUS_FAIL; ?>,
|
255 |
+
STATUS_QUOTA_EXCEEDED: <?php echo ShortPixelAPI::STATUS_QUOTA_EXCEEDED; ?>,
|
256 |
+
STATUS_SKIP: <?php echo ShortPixelAPI::STATUS_SKIP; ?>,
|
257 |
+
STATUS_NO_KEY: <?php echo ShortPixelAPI::STATUS_NO_KEY; ?>,
|
258 |
+
STATUS_RETRY: <?php echo ShortPixelAPI::STATUS_RETRY; ?>,
|
259 |
+
STATUS_QUEUE_FULL: <?php echo ShortPixelAPI::STATUS_QUEUE_FULL; ?>,
|
260 |
+
STATUS_MAINTENANCE: <?php echo ShortPixelAPI::STATUS_MAINTENANCE; ?>,
|
261 |
+
WP_PLUGIN_URL: '<?php echo plugins_url( '', SHORTPIXEL_PLUGIN_FILE ); ?>',
|
262 |
+
WP_ADMIN_URL: '<?php echo admin_url(); ?>',
|
263 |
+
API_KEY: "<?php echo $this->_settings->apiKey; ?>",
|
264 |
+
MEDIA_ALERT: '<?php echo $this->_settings->mediaAlert ? "done" : "todo"; ?>',
|
265 |
+
FRONT_BOOTSTRAP: <?php echo $this->_settings->frontBootstrap && (!isset($this->_settings->lastBackAction) || (time() - $this->_settings->lastBackAction > 600)) ? 1 : 0; ?>,
|
266 |
+
AJAX_URL: '<?php echo admin_url('admin-ajax.php'); ?>'
|
267 |
+
};
|
268 |
+
</script> <?php
|
269 |
+
wp_enqueue_style('short-pixel.css', plugins_url('/res/css/short-pixel.css',SHORTPIXEL_PLUGIN_FILE) );
|
270 |
+
|
271 |
+
wp_register_script('short-pixel.js', plugins_url('/res/js/short-pixel.js',SHORTPIXEL_PLUGIN_FILE) );
|
272 |
+
$jsTranslation = array(
|
273 |
+
'optimizeWithSP' => __( 'Optimize with ShortPixel', 'shortpixel-image-optimiser' ),
|
274 |
+
'changeMLToListMode' => __( 'In order to access the ShortPixel Optimization actions and info, please change to {0}List View{1}List View{2}Dismiss{3}', 'shortpixel-image-optimiser' ),
|
275 |
+
'alertOnlyAppliesToNewImages' => __( 'This type of optimization will apply to new uploaded images. Images that were already processed will not be re-optimized unless you restart the bulk process.', 'shortpixel-image-optimiser' ),
|
276 |
+
'areYouSureStopOptimizing' => __( 'Are you sure you want to stop optimizing the folder {0}?', 'shortpixel-image-optimiser' ),
|
277 |
+
'reducedBy' => __( 'Reduced by', 'shortpixel-image-optimiser' ),
|
278 |
+
'bonusProcessing' => __( 'Bonus processing', 'shortpixel-image-optimiser' ),
|
279 |
+
'plusXthumbsOpt' => __( '+{0} thumbnails optimized', 'shortpixel-image-optimiser' ),
|
280 |
+
'plusXretinasOpt' => __( '+{0} Retina images optimized', 'shortpixel-image-optimiser' ),
|
281 |
+
'optXThumbs' => __( 'Optimize {0} thumbnails', 'shortpixel-image-optimiser' ),
|
282 |
+
'reOptimizeAs' => __( 'Reoptimize {0}', 'shortpixel-image-optimiser' ),
|
283 |
+
'restoreBackup' => __( 'Restore backup', 'shortpixel-image-optimiser' ),
|
284 |
+
'getApiKey' => __( 'Get API Key', 'shortpixel-image-optimiser' ),
|
285 |
+
'extendQuota' => __( 'Extend Quota', 'shortpixel-image-optimiser' ),
|
286 |
+
'check__Quota' => __( 'Check Quota', 'shortpixel-image-optimiser' ),
|
287 |
+
'retry' => __( 'Retry', 'shortpixel-image-optimiser' ),
|
288 |
+
'thisContentNotProcessable' => __( 'This content is not processable.', 'shortpixel-image-optimiser' ),
|
289 |
+
'imageWaitOptThumbs' => __( 'Image waiting to optimize thumbnails', 'shortpixel-image-optimiser' ),
|
290 |
+
'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' ),
|
291 |
+
'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' )
|
292 |
+
);
|
293 |
+
wp_localize_script( 'short-pixel.js', '_spTr', $jsTranslation );
|
294 |
+
wp_enqueue_script('short-pixel.js');
|
295 |
+
|
296 |
+
wp_enqueue_script('jquery.knob.js', plugins_url('/res/js/jquery.knob.js',SHORTPIXEL_PLUGIN_FILE) );
|
297 |
+
wp_enqueue_script('jquery.tooltip.js', plugins_url('/res/js/jquery.tooltip.js',SHORTPIXEL_PLUGIN_FILE) );
|
298 |
+
wp_enqueue_script('punycode.js', plugins_url('/res/js/punycode.js',SHORTPIXEL_PLUGIN_FILE) );
|
299 |
+
}
|
300 |
+
|
301 |
+
function toolbar_shortpixel_processing( $wp_admin_bar ) {
|
302 |
+
|
303 |
+
$extraClasses = " shortpixel-hide";
|
304 |
+
/*translators: toolbar icon tooltip*/
|
305 |
+
$id = 'short-pixel-notice-toolbar';
|
306 |
+
$tooltip = __('ShortPixel optimizing...','shortpixel-image-optimiser');
|
307 |
+
$icon = "shortpixel.png";
|
308 |
+
$successLink = $link = current_user_can( 'edit_others_posts')? 'upload.php?page=wp-short-pixel-bulk' : 'upload.php';
|
309 |
+
$blank = "";
|
310 |
+
if($this->prioQ->processing()) {
|
311 |
+
$extraClasses = " shortpixel-processing";
|
312 |
+
}
|
313 |
+
if($this->_settings->quotaExceeded && !isset($this->_settings->dismissedNotices['exceed'])) {
|
314 |
+
$extraClasses = " shortpixel-alert shortpixel-quota-exceeded";
|
315 |
+
/*translators: toolbar icon tooltip*/
|
316 |
+
$id = 'short-pixel-notice-exceed';
|
317 |
+
$tooltip = '';
|
318 |
+
$exceedTooltip = __('ShortPixel quota exceeded. Click for details.','shortpixel-image-optimiser');
|
319 |
+
//$link = "http://shortpixel.com/login/" . $this->_settings->apiKey;
|
320 |
+
$link = "options-general.php?page=wp-shortpixel";
|
321 |
+
//$blank = '_blank';
|
322 |
+
//$icon = "shortpixel-alert.png";
|
323 |
+
}
|
324 |
+
$lastStatus = $this->_settings->bulkLastStatus;
|
325 |
+
if($lastStatus && $lastStatus['Status'] != ShortPixelAPI::STATUS_SUCCESS) {
|
326 |
+
$extraClasses = " shortpixel-alert shortpixel-processing";
|
327 |
+
$tooltip = $lastStatus['Message'];
|
328 |
+
}
|
329 |
+
|
330 |
+
$args = array(
|
331 |
+
'id' => 'shortpixel_processing',
|
332 |
+
'title' => '<div id="' . $id . '" title="' . $tooltip . '" ><img src="'
|
333 |
+
. plugins_url( 'res/img/'.$icon, SHORTPIXEL_PLUGIN_FILE ) . '" success-url="' . $successLink . '"><span class="shp-alert">!</span></div>',
|
334 |
+
'href' => $link,
|
335 |
+
'meta' => array('target'=> $blank, 'class' => 'shortpixel-toolbar-processing' . $extraClasses)
|
336 |
+
);
|
337 |
+
$wp_admin_bar->add_node( $args );
|
338 |
+
if($this->_settings->quotaExceeded && !isset($this->_settings->dismissedNotices['exceed'])) {
|
339 |
+
$wp_admin_bar->add_node( array(
|
340 |
+
'id' => 'shortpixel_processing-title',
|
341 |
+
'parent' => 'shortpixel_processing',
|
342 |
+
'title' => $exceedTooltip,
|
343 |
+
'href' => $link
|
344 |
+
));
|
345 |
+
$wp_admin_bar->add_node( array(
|
346 |
+
'id' => 'shortpixel_processing-dismiss',
|
347 |
+
'parent' => 'shortpixel_processing',
|
348 |
+
'title' => '<div style="text-align: right;">Dismiss</div>',
|
349 |
+
'href' => "#",
|
350 |
+
'meta' => array('onclick'=> 'dismissShortPixelNoticeExceed(event)')
|
351 |
+
));
|
352 |
+
}
|
353 |
+
}
|
354 |
+
|
355 |
+
public function handleCustomBulk() {
|
356 |
+
// 1. get the action
|
357 |
+
$wp_list_table = _get_list_table('WP_Media_List_Table');
|
358 |
+
$action = $wp_list_table->current_action();
|
359 |
+
|
360 |
+
switch($action) {
|
361 |
+
// 2. Perform the action
|
362 |
+
case 'short-pixel-bulk':
|
363 |
+
// security check
|
364 |
+
check_admin_referer('bulk-media');
|
365 |
+
if(!is_array($_GET['media'])) {
|
366 |
+
break;
|
367 |
+
}
|
368 |
+
$mediaIds = array_reverse($_GET['media']);
|
369 |
+
foreach( $mediaIds as $ID ) {
|
370 |
+
$meta = wp_get_attachment_metadata($ID);
|
371 |
+
if( ( !isset($meta['ShortPixel']) //never touched by ShortPixel
|
372 |
+
|| (isset($meta['ShortPixel']['WaitingProcessing']) && $meta['ShortPixel']['WaitingProcessing'] == true))
|
373 |
+
&& (!isset($meta['ShortPixelImprovement']) || $meta['ShortPixelImprovement'] == __('Optimization N/A','shortpixel-image-optimiser'))) {
|
374 |
+
$this->prioQ->push($ID);
|
375 |
+
$meta['ShortPixel']['WaitingProcessing'] = true;
|
376 |
+
wp_update_attachment_metadata($ID, $meta);
|
377 |
+
}
|
378 |
+
}
|
379 |
+
break;
|
380 |
+
}
|
381 |
+
}
|
382 |
+
|
383 |
+
/**
|
384 |
+
* this is hooked onto the MediaLibrary image upload
|
385 |
+
* @param array $meta - the wordpress postmeta structure
|
386 |
+
* @param type $ID - the Media Library ID
|
387 |
+
* @return the meta structure updated with ShortPixel info if case
|
388 |
+
*/
|
389 |
+
public function handleMediaLibraryImageUpload($meta, $ID = null)
|
390 |
+
{
|
391 |
+
if( !$this->_settings->verifiedKey) {// no API Key set/verified -> do nothing here, just return
|
392 |
+
return $meta;
|
393 |
+
}
|
394 |
+
//else
|
395 |
+
//self::log("IMG: Auto-analyzing file ID #{$ID}");
|
396 |
+
|
397 |
+
if( self::isProcessable($ID) == false )
|
398 |
+
{//not a file that we can process
|
399 |
+
$meta['ShortPixelImprovement'] = __('Optimization N/A','shortpixel-image-optimiser');
|
400 |
+
return $meta;
|
401 |
+
}
|
402 |
+
else
|
403 |
+
{//the kind of file we can process. goody.
|
404 |
+
$this->prioQ->push($ID);
|
405 |
+
//that's a hack for watermarking plugins, don't send the image right away to processing, only add it in the queue
|
406 |
+
include_once( ABSPATH . 'wp-admin/includes/plugin.php' );
|
407 |
+
if( !is_plugin_active('image-watermark/image-watermark.php')
|
408 |
+
&& !is_plugin_active('easy-watermark/index.php')) {
|
409 |
+
$itemHandler = new ShortPixelMetaFacade($ID);
|
410 |
+
$itemHandler->setRawMeta($meta);
|
411 |
+
try {
|
412 |
+
$URLsAndPATHs = $this->getURLsAndPATHs($itemHandler);
|
413 |
+
//send a processing request right after a file was uploaded, do NOT wait for response
|
414 |
+
$this->_apiInterface->doRequests($URLsAndPATHs['URLs'], false, $ID);
|
415 |
+
} catch(Exception $e) {
|
416 |
+
$meta['ShortPixelImprovement'] = $e->getMessage();
|
417 |
+
return $meta;
|
418 |
+
}
|
419 |
+
//self::log("IMG: sent: " . json_encode($URLsAndPATHs));
|
420 |
+
}
|
421 |
+
$meta['ShortPixel']['WaitingProcessing'] = true;
|
422 |
+
return $meta;
|
423 |
+
}
|
424 |
+
}//end handleMediaLibraryImageUpload
|
425 |
+
|
426 |
+
/**
|
427 |
+
* this is hooked onto the NextGen upload
|
428 |
+
* @param type $image
|
429 |
+
*/
|
430 |
+
public function handleNextGenImageUpload($image) {
|
431 |
+
if($this->_settings->includeNextGen == 1) {
|
432 |
+
$imageFsPath = ShortPixelNextGenAdapter::getImageAbspath($image);
|
433 |
+
|
434 |
+
$customFolders = $this->spMetaDao->getFolders();
|
435 |
+
|
436 |
+
$folderId = -1;
|
437 |
+
foreach($customFolders as $folder) {
|
438 |
+
if(strpos($imageFsPath, $folder->getPath()) === 0) {
|
439 |
+
$folderId = $folder->getId();
|
440 |
+
break;
|
441 |
+
}
|
442 |
+
}
|
443 |
+
if($folderId == -1) { //if not found, create
|
444 |
+
$galleryPath = dirname($imageFsPath);
|
445 |
+
$folder = new ShortPixelFolder(array("path" => $galleryPath));
|
446 |
+
$folderMsg = $this->spMetaDao->saveFolder($folder);
|
447 |
+
$folderId = $folder->getId();
|
448 |
+
//self::log("NG Image Upload: created folder from path $galleryPath : Folder info: " . json_encode($folder));
|
449 |
+
}
|
450 |
+
$pathParts = explode('/', trim($imageFsPath));
|
451 |
+
//Add the main image
|
452 |
+
$meta = new ShortPixelMeta();
|
453 |
+
$meta->setPath($imageFsPath);
|
454 |
+
$meta->setName($pathParts[count($pathParts) - 1]);
|
455 |
+
$meta->setFolderId($folderId);
|
456 |
+
$meta->setExtMetaId($image->pid); // do this only for main image, not for thumbnais.
|
457 |
+
$meta->setCompressionType($this->_settings->compressionType);
|
458 |
+
$meta->setKeepExif($this->_settings->keepExif);
|
459 |
+
$meta->setCmyk2rgb($this->_settings->CMYKtoRGBconversion);
|
460 |
+
$meta->setResize($this->_settings->resizeImages);
|
461 |
+
$meta->setResizeWidth($this->_settings->resizeWidth);
|
462 |
+
$meta->setResizeHeight($this->_settings->resizeHeight);
|
463 |
+
$ID = $this->spMetaDao->addImage($meta);
|
464 |
+
$meta->setId($ID);
|
465 |
+
$this->prioQ->push('C-' . $ID);
|
466 |
+
//add the thumb image if exists
|
467 |
+
$pathParts[] = "thumbs_" . $pathParts[count($pathParts) - 1];
|
468 |
+
$pathParts[count($pathParts) - 2] = "thumbs";
|
469 |
+
$thumbPath = implode('/', $pathParts);
|
470 |
+
if(file_exists($thumbPath)) {
|
471 |
+
$metaThumb = new ShortPixelMeta();
|
472 |
+
$metaThumb->setPath($thumbPath);
|
473 |
+
$metaThumb->setName($pathParts[count($pathParts) - 1]);
|
474 |
+
$metaThumb->setFolderId($folderId);
|
475 |
+
$metaThumb->setCompressionType($this->_settings->compressionType);
|
476 |
+
$metaThumb->setKeepExif($this->_settings->keepExif);
|
477 |
+
$metaThumb->setCmyk2rgb($this->_settings->CMYKtoRGBconversion);
|
478 |
+
$metaThumb->setResize($this->_settings->resizeImages);
|
479 |
+
$metaThumb->setResizeWidth($this->_settings->resizeWidth);
|
480 |
+
$metaThumb->setResizeHeight($this->_settings->resizeHeight);
|
481 |
+
$ID = $this->spMetaDao->addImage($metaThumb);
|
482 |
+
$metaThumb->setId($ID);
|
483 |
+
$this->prioQ->push('C-' . $ID);
|
484 |
+
}
|
485 |
+
return $meta;
|
486 |
+
}
|
487 |
+
}
|
488 |
+
|
489 |
+
public function optimizeCustomImage($id) {
|
490 |
+
$meta = $this->spMetaDao->getMeta($id);
|
491 |
+
if($meta->getStatus() != 2) {
|
492 |
+
$meta->setStatus(1);
|
493 |
+
$meta->setRetries(0);
|
494 |
+
$this->spMetaDao->update($meta);
|
495 |
+
$this->prioQ->push('C-' . $id);
|
496 |
+
}
|
497 |
+
}
|
498 |
+
|
499 |
+
//TODO muta in bulkProvider
|
500 |
+
public function getBulkItemsFromDb(){
|
501 |
+
global $wpdb;
|
502 |
+
|
503 |
+
$startQueryID = $this->prioQ->getStartBulkId();
|
504 |
+
$endQueryID = $this->prioQ->getStopBulkId();
|
505 |
+
$skippedAlreadyProcessed = 0;
|
506 |
+
|
507 |
+
if ( $startQueryID <= $endQueryID ) {
|
508 |
+
return false;
|
509 |
+
}
|
510 |
+
$idList = array();
|
511 |
+
$itemList = array();
|
512 |
+
for ($sanityCheck = 0, $crtStartQueryID = $startQueryID;
|
513 |
+
($crtStartQueryID >= $endQueryID) && (count($itemList) < 3) && ($sanityCheck < 150); $sanityCheck++) {
|
514 |
+
|
515 |
+
self::log("GETDB: current StartID: " . $crtStartQueryID);
|
516 |
+
|
517 |
+
$queryPostMeta = "SELECT * FROM " . $wpdb->prefix . "postmeta
|
518 |
+
WHERE ( post_id <= $crtStartQueryID AND post_id >= $endQueryID )
|
519 |
+
AND ( meta_key = '_wp_attached_file' OR meta_key = '_wp_attachment_metadata' )
|
520 |
+
ORDER BY post_id DESC
|
521 |
+
LIMIT " . SP_MAX_RESULTS_QUERY;
|
522 |
+
$resultsPostMeta = $wpdb->get_results($queryPostMeta);
|
523 |
+
|
524 |
+
if ( empty($resultsPostMeta) ) {
|
525 |
+
$crtStartQueryID -= SP_MAX_RESULTS_QUERY;
|
526 |
+
$startQueryID = $crtStartQueryID;
|
527 |
+
$this->prioQ->setStartBulkId($startQueryID);
|
528 |
+
continue;
|
529 |
+
}
|
530 |
+
|
531 |
+
foreach ( $resultsPostMeta as $itemMetaData ) {
|
532 |
+
$crtStartQueryID = $itemMetaData->post_id;
|
533 |
+
if(!in_array($crtStartQueryID, $idList) && self::isProcessable($crtStartQueryID, ($this->_settings->optimizePdfs ? array() : array('pdf')))) {
|
534 |
+
$item = new ShortPixelMetaFacade($crtStartQueryID);
|
535 |
+
$meta = $item->getMeta();//wp_get_attachment_metadata($crtStartQueryID);
|
536 |
+
|
537 |
+
if($meta->getStatus() != 2) {
|
538 |
+
$itemList[] = $item;
|
539 |
+
$idList[] = $crtStartQueryID;
|
540 |
+
}
|
541 |
+
elseif($meta->getCompressionType() !== null && $meta->getCompressionType() != $this->_settings->compressionType) {//a different type of compression was chosen in settings
|
542 |
+
if($this->doRestore($crtStartQueryID)) {
|
543 |
+
$itemList[] = $item = new ShortPixelMetaFacade($crtStartQueryID); //force reload after restore
|
544 |
+
$idList[] = $crtStartQueryID;
|
545 |
+
} else {
|
546 |
+
$skippedAlreadyProcessed++;
|
547 |
+
}
|
548 |
+
}
|
549 |
+
elseif( $this->_settings->processThumbnails && $meta->getThumbsOpt() !== null
|
550 |
+
&& $meta->getThumbsOpt() == 0 && count($meta->getThumbs()) > 0) { //thumbs were chosen in settings
|
551 |
+
//if($crtStartQueryID == 44 || $crtStartQueryID == 49) {echo("No THuMBS?");die(var_dump($meta));}
|
552 |
+
$meta->setThumbsTodo(true);
|
553 |
+
$item->updateMeta($meta);//wp_update_attachment_metadata($crtStartQueryID, $meta);
|
554 |
+
$itemList[] = $item;
|
555 |
+
$idList[] = $crtStartQueryID;
|
556 |
+
}
|
557 |
+
elseif($itemMetaData->meta_key == '_wp_attachment_metadata') { //count skipped
|
558 |
+
$skippedAlreadyProcessed++;
|
559 |
+
}
|
560 |
+
}
|
561 |
+
}
|
562 |
+
if(!count($idList) && $crtStartQueryID <= $startQueryID) {
|
563 |
+
//daca n-am adaugat niciuna pana acum, n-are sens sa mai selectez zona asta de id-uri in bulk-ul asta.
|
564 |
+
$leapStart = $this->prioQ->getStartBulkId();
|
565 |
+
$crtStartQueryID = $startQueryID = $itemMetaData->post_id - 1; //decrement it so we don't select it again
|
566 |
+
$res = WpShortPixelMediaLbraryAdapter::countAllProcessableFiles($this->_settings->optimizePdfs, $leapStart, $crtStartQueryID);
|
567 |
+
$skippedAlreadyProcessed += $res["mainProcessedFiles"] - $res["mainProc".($this->getCompressionType() == 1 ? "Lossy" : "Lossless")."Files"];
|
568 |
+
$this->prioQ->setStartBulkId($startQueryID);
|
569 |
+
} else {
|
570 |
+
$crtStartQueryID--;
|
571 |
+
}
|
572 |
+
}
|
573 |
+
return array("items" => $itemList, "skipped" => $skippedAlreadyProcessed, "searching" => ($sanityCheck >= 150));
|
574 |
+
}
|
575 |
+
|
576 |
+
/**
|
577 |
+
* Get last added items from priority
|
578 |
+
* @return type
|
579 |
+
*/
|
580 |
+
//TODO muta in bulkProvider - prio
|
581 |
+
public function getFromPrioAndCheck() {
|
582 |
+
$items = array();
|
583 |
+
foreach ($this->prioQ->getFromPrioAndCheck() as $id) {
|
584 |
+
$items[] = new ShortPixelMetaFacade($id);
|
585 |
+
}
|
586 |
+
return $items;
|
587 |
+
}
|
588 |
+
|
589 |
+
public function handleImageProcessing($ID = null) {
|
590 |
+
//if(rand(1,2) == 2) {
|
591 |
+
// header($_SERVER['SERVER_PROTOCOL'] . ' 500 Internal Server Error', true, 500);
|
592 |
+
// die("za stop");
|
593 |
+
//}
|
594 |
+
//0: check key
|
595 |
+
if( $this->_settings->verifiedKey == false) {
|
596 |
+
if($ID == null){
|
597 |
+
$ids = $this->getFromPrioAndCheck();
|
598 |
+
$itemHandler = (count($ids) > 0 ? $ids[0] : null);
|
599 |
+
}
|
600 |
+
$response = array("Status" => ShortPixelAPI::STATUS_NO_KEY, "ImageID" => $itemHandler ? $itemHandler->getId() : "-1", "Message" => __('Missing API Key','shortpixel-image-optimiser'));
|
601 |
+
$this->_settings->bulkLastStatus = $response;
|
602 |
+
die(json_encode($response));
|
603 |
+
}
|
604 |
+
|
605 |
+
if($this->_settings->frontBootstrap && is_admin() && !ShortPixelTools::requestIsFrontendAjax()) {
|
606 |
+
//if in backend, and front-end is activated, mark processing from backend to shut off the front-end for 10 min.
|
607 |
+
$this->_settings->lastBackAction = time();
|
608 |
+
}
|
609 |
+
|
610 |
+
self::log("HIP: 0 Priority Queue: ".json_encode($this->prioQ->get()));
|
611 |
+
//self::log("HIP: 0 Bulk running? " . $this->prioQ->bulkRunning() . " START " . $this->_settings->startBulkId . " STOP " . $this->_settings->stopBulkId);
|
612 |
+
|
613 |
+
//1: get 3 ids to process. Take them with priority from the queue
|
614 |
+
$ids = $this->getFromPrioAndCheck();
|
615 |
+
if(count($ids) < 3 ) { //take from bulk if bulk processing active
|
616 |
+
if($this->prioQ->bulkRunning()) {
|
617 |
+
$res = $this->getBulkItemsFromDb();
|
618 |
+
$bulkItems = $res['items'];
|
619 |
+
//merge them into the $ids array based on the ID (the same ID could be in prio also)
|
620 |
+
if($bulkItems){
|
621 |
+
foreach($bulkItems as $bi) {
|
622 |
+
$add = true;
|
623 |
+
foreach($ids as $pi) {
|
624 |
+
if($pi->getType() == ShortPixelMetaFacade::MEDIA_LIBRARY_TYPE && $bi->getId() == $pi->getId()) {
|
625 |
+
$add = false;
|
626 |
+
}
|
627 |
+
}
|
628 |
+
$ids[] = $bi;
|
629 |
+
}
|
630 |
+
}
|
631 |
+
}
|
632 |
+
}
|
633 |
+
|
634 |
+
self::log("HIP: 0 Bulk ran: " . $this->prioQ->bulkRan());
|
635 |
+
$customIds = false;
|
636 |
+
if(count($ids) < 3 && $this->prioQ->bulkRan() && $this->_settings->hasCustomFolders
|
637 |
+
&& (!$this->_settings->cancelPointer || $this->_settings->skipToCustom)
|
638 |
+
&& !$this->_settings->customBulkPaused)
|
639 |
+
{ //take from custom images if any left to optimize - only if bulk was ever started
|
640 |
+
$customIds = $this->spMetaDao->getPendingMetas( 3 - count($ids));
|
641 |
+
if(is_array($customIds)) {
|
642 |
+
$ids = array_merge($ids, array_map(array('ShortPixelMetaFacade', 'getNewFromRow'), $customIds));
|
643 |
+
}
|
644 |
+
}
|
645 |
+
//var_dump($ids);
|
646 |
+
//die("za stop 2");
|
647 |
+
|
648 |
+
self::log("HIP: 1 Prio Queue: ".json_encode($this->prioQ->get()));
|
649 |
+
self::log("HIP: 1 Selected IDs count: ".count($ids));
|
650 |
+
|
651 |
+
//2: Send up to 3 files to the server for processing
|
652 |
+
for($i = 0, $itemHandler = false; $ids !== false && $i < min(3, count($ids)); $i++) {
|
653 |
+
$crtItemHandler = $ids[$i];
|
654 |
+
$tmpMeta = $crtItemHandler->getMeta();
|
655 |
+
$compType = ($tmpMeta->getCompressionType() !== null ? $tmpMeta->getCompressionType() : $this->_settings->compressionType);
|
656 |
+
try {
|
657 |
+
self::log("HIP: 1 sendToProcessing: ".$crtItemHandler->getId());
|
658 |
+
$URLsAndPATHs = $this->sendToProcessing($crtItemHandler, $compType, $tmpMeta->getThumbsTodo());
|
659 |
+
if(!$itemHandler) { //save for later use
|
660 |
+
$itemHandler = $ids[$i];
|
661 |
+
$firstUrlAndPaths = $URLsAndPATHs;
|
662 |
+
}
|
663 |
+
} catch(Exception $e) { // Exception("Post metadata is corrupt (No attachment URL)") or Exception("Image files are missing.")
|
664 |
+
$meta = $crtItemHandler->setError(ShortPixelAPI::ERR_FILE_NOT_FOUND, $e->getMessage());
|
665 |
+
$crtItemHandler->incrementRetries();
|
666 |
+
if(! $this->prioQ->remove($crtItemHandler->getQueuedId()) ){
|
667 |
+
$this->advanceBulk($crtItemHandler->getId());
|
668 |
+
$res['searching'] = true;
|
669 |
+
}
|
670 |
+
}
|
671 |
+
}
|
672 |
+
|
673 |
+
if (!$itemHandler){
|
674 |
+
//if searching, than the script is searching for not processed items and found none yet, should be relaunced
|
675 |
+
if(isset($res['searching']) && $res['searching']) {
|
676 |
+
die(json_encode(array("Status" => ShortPixelAPI::STATUS_RETRY,
|
677 |
+
"Message" => __('Searching images to optimize... ','shortpixel-image-optimiser') . $this->prioQ->getStartBulkId() . '->' . $this->prioQ->getStopBulkId() )));
|
678 |
+
}
|
679 |
+
//in this case the queue is really empty
|
680 |
+
self::log("HIP: 1 STOP BULK");
|
681 |
+
$bulkEverRan = $this->prioQ->stopBulk();
|
682 |
+
$avg = $this->getAverageCompression();
|
683 |
+
$fileCount = $this->_settings->fileCount;
|
684 |
+
$response = array("Status" => self::BULK_EMPTY_QUEUE,
|
685 |
+
/* translators: console message Empty queue 1234 -> 1234 */
|
686 |
+
"Message" => __('Empty queue ','shortpixel-image-optimiser') . $this->prioQ->getStartBulkId() . '->' . $this->prioQ->getStopBulkId(),
|
687 |
+
"BulkStatus" => ($this->prioQ->bulkRunning()
|
688 |
+
? "1" : ($this->prioQ->bulkPaused() ? "2" : "0")),
|
689 |
+
"AverageCompression" => $avg,
|
690 |
+
"FileCount" => $fileCount,
|
691 |
+
"BulkPercent" => $this->prioQ->getBulkPercent());
|
692 |
+
die(json_encode($response));
|
693 |
+
}
|
694 |
+
|
695 |
+
self::log("HIP: 2 Prio Queue: ".json_encode($this->prioQ->get()));
|
696 |
+
//3: $itemHandler contains the first element of the list
|
697 |
+
$itemId = $itemHandler->getQueuedId();
|
698 |
+
$result = $this->_apiInterface->processImage($firstUrlAndPaths['URLs'], $firstUrlAndPaths['PATHs'], $itemHandler);
|
699 |
+
|
700 |
+
$result["ImageID"] = $itemId;
|
701 |
+
$meta = $itemHandler->getMeta();
|
702 |
+
$result["Filename"] = ShortPixelAPI::MB_basename($meta->getPath());
|
703 |
+
|
704 |
+
self::log("HIP: 3 Prio Queue: ".json_encode($this->prioQ->get()));
|
705 |
+
|
706 |
+
//4: update counters and priority list
|
707 |
+
if( $result["Status"] == ShortPixelAPI::STATUS_SUCCESS) {
|
708 |
+
self::log("HIP: Image ID " . $itemId . " optimized successfully: ".json_encode($result));
|
709 |
+
$prio = $this->prioQ->remove($itemId);
|
710 |
+
//remove also from the failed list if it failed in the past
|
711 |
+
$prio = $this->prioQ->removeFromFailed($itemId);
|
712 |
+
$result["Type"] = $meta->getCompressionType() !== null ? ShortPixelAPI::getCompressionTypeName($meta->getCompressionType()) : '';
|
713 |
+
$result["ThumbsTotal"] = $meta->getThumbs() && is_array($meta->getThumbs()) ? WpShortPixelMediaLbraryAdapter::countNonWebpSizes($meta->getThumbs()): 0;
|
714 |
+
$result["ThumbsTotal"] -= count($meta->getThumbsMissing());
|
715 |
+
$result["ThumbsCount"] = $meta->getThumbsOpt()
|
716 |
+
? $meta->getThumbsOpt() //below is the fallback for old optimized images that don't have thumbsOpt
|
717 |
+
: ($this->_settings->processThumbnails ? $result["ThumbsTotal"] : 0);
|
718 |
+
|
719 |
+
$result["RetinasCount"] = $meta->getRetinasOpt();
|
720 |
+
$result["BackupEnabled"] = ($this->getBackupFolderAny($meta->getPath(), $meta->getThumbs()) ? true : false);//$this->_settings->backupImages;
|
721 |
+
|
722 |
+
if(!$prio && $itemId <= $this->prioQ->getStartBulkId()) {
|
723 |
+
$this->advanceBulk($itemId);
|
724 |
+
$this->setBulkInfo($itemId, $result);
|
725 |
+
}
|
726 |
+
|
727 |
+
$result["AverageCompression"] = $this->getAverageCompression();
|
728 |
+
|
729 |
+
if($itemHandler->getType() == ShortPixelMetaFacade::MEDIA_LIBRARY_TYPE) {
|
730 |
+
|
731 |
+
$thumb = $bkThumb = "";
|
732 |
+
//$percent = 0;
|
733 |
+
$percent = $meta->getImprovementPercent();
|
734 |
+
if($percent){
|
735 |
+
$filePath = explode("/", $meta->getPath());
|
736 |
+
|
737 |
+
//Get a suitable thumb
|
738 |
+
$sizes = $meta->getThumbs();
|
739 |
+
if('pdf' == strtolower(pathinfo($result["Filename"], PATHINFO_EXTENSION))) {
|
740 |
+
// echo($result["Filename"] . " ESTE --> "); die(var_dump(strtolower(pathinfo($result["Filename"], PATHINFO_EXTENSION))));
|
741 |
+
$thumb = plugins_url( 'shortpixel-image-optimiser/res/img/logo-pdf.png' );
|
742 |
+
$bkThumb = '';
|
743 |
+
} else {
|
744 |
+
if(count($sizes)) {
|
745 |
+
$thumb = (isset($sizes["medium"]) ? $sizes["medium"]["file"] : (isset($sizes["thumbnail"]) ? $sizes["thumbnail"]["file"]: ""));
|
746 |
+
if(!strlen($thumb)) { //fallback to the first in the list
|
747 |
+
$sizeVals = array_values($sizes);
|
748 |
+
$thumb = count($sizeVals) ? $sizeVals[0]['file'] : '';
|
749 |
+
}
|
750 |
+
} else { //fallback to the image itself
|
751 |
+
$thumb = is_array($filePath) ? $filePath[count($filePath) - 1] : $filePath;
|
752 |
+
}
|
753 |
+
|
754 |
+
if(strlen($thumb) && $this->_settings->backupImages && $this->_settings->processThumbnails) {
|
755 |
+
$backupUrl = content_url() . "/" . SP_UPLOADS_NAME . "/" . SP_BACKUP . "/";
|
756 |
+
//$urlBkPath = $this->_apiInterface->returnSubDir(get_attached_file($ID));
|
757 |
+
$urlBkPath = ShortPixelMetaFacade::returnSubDir($meta->getPath(), ShortPixelMetaFacade::MEDIA_LIBRARY_TYPE);
|
758 |
+
$bkThumb = $backupUrl . $urlBkPath . $thumb;
|
759 |
+
}
|
760 |
+
if(strlen($thumb)) {
|
761 |
+
$uploadsUrl = ShortPixelMetaFacade::getHomeUrl();
|
762 |
+
$urlPath = ShortPixelMetaFacade::returnSubDir($meta->getPath(), ShortPixelMetaFacade::MEDIA_LIBRARY_TYPE);
|
763 |
+
//$urlPath = implode("/", array_slice($filePath, 0, count($filePath) - 1));
|
764 |
+
$thumb = $uploadsUrl . $urlPath . $thumb;
|
765 |
+
}
|
766 |
+
}
|
767 |
+
|
768 |
+
$result["Thumb"] = $thumb;
|
769 |
+
$result["BkThumb"] = $bkThumb;
|
770 |
+
}
|
771 |
+
}
|
772 |
+
elseif( is_array($customIds)) { // this item is from custom bulk
|
773 |
+
foreach($customIds as $customId) {
|
774 |
+
$rootUrl = ShortPixelMetaFacade::getHomeUrl();
|
775 |
+
if($customId->id == $itemHandler->getId()) {
|
776 |
+
if('pdf' == strtolower(pathinfo($meta->getName(), PATHINFO_EXTENSION))) {
|
777 |
+
$result["Thumb"] = plugins_url( 'shortpixel-image-optimiser/res/img/logo-pdf.png' );
|
778 |
+
$result["BkThumb"] = "";
|
779 |
+
} else {
|
780 |
+
$result["Thumb"] = $thumb = $rootUrl . $meta->getWebPath();
|
781 |
+
if($this->_settings->backupImages) {
|
782 |
+
$result["BkThumb"] = str_replace($rootUrl, $rootUrl. "/" . basename(dirname(dirname(SP_BACKUP_FOLDER))) . "/" . SP_UPLOADS_NAME . "/" . SP_BACKUP . "/", $thumb);
|
783 |
+
}
|
784 |
+
}
|
785 |
+
$this->setBulkInfo($itemId, $result);
|
786 |
+
break;
|
787 |
+
}
|
788 |
+
}
|
789 |
+
}
|
790 |
+
}
|
791 |
+
elseif ($result["Status"] == ShortPixelAPI::STATUS_ERROR) {
|
792 |
+
if($meta->getRetries() > MAX_ERR_RETRIES) {
|
793 |
+
if(! $this->prioQ->remove($itemId) ){
|
794 |
+
$this->advanceBulk($meta->getId());
|
795 |
+
}
|
796 |
+
if($itemHandler->getType() == ShortPixelMetaFacade::MEDIA_LIBRARY_TYPE) {
|
797 |
+
$itemHandler->deleteMeta(); //this deletes only the ShortPixel fields from meta, in case of WP Media library
|
798 |
+
}
|
799 |
+
$result["Status"] = ShortPixelAPI::STATUS_SKIP;
|
800 |
+
$result["Message"] .= __(' Retry limit reached. Skipping file ID ','shortpixel-image-optimiser') . $itemId . ".";
|
801 |
+
$itemHandler->setError(isset($result['Code']) ? $result['Code'] : ShortPixelAPI::ERR_INCORRECT_FILE_SIZE, $result["Message"] );
|
802 |
+
}
|
803 |
+
else {
|
804 |
+
if(isset($result['Code'])) {
|
805 |
+
$itemHandler->setError($result['Code'], $result["Message"] );
|
806 |
+
}
|
807 |
+
$itemHandler->incrementRetries();
|
808 |
+
}
|
809 |
+
}
|
810 |
+
elseif ($result["Status"] == ShortPixelAPI::STATUS_SKIP
|
811 |
+
|| $result["Status"] == ShortPixelAPI::STATUS_FAIL) {
|
812 |
+
$meta = $itemHandler->getMeta();
|
813 |
+
//$prio = $this->prioQ->remove($ID);
|
814 |
+
$prio = $this->prioQ->remove($itemId);
|
815 |
+
if(isset($result["Code"])
|
816 |
+
&& ( $result["Code"] == "write-fail" //could not write
|
817 |
+
|| (in_array(0+$result["Code"], array(-201)) && $meta->getRetries() >= 3))) { //for -201 (invalid image format) we retry only 3 times.
|
818 |
+
//put this one in the failed images list - to show the user at the end
|
819 |
+
$prio = $this->prioQ->addToFailed($itemHandler->getQueuedId());
|
820 |
+
}
|
821 |
+
$this->advanceBulk($meta->getId());
|
822 |
+
if($itemHandler->getType() == ShortPixelMetaFacade::CUSTOM_TYPE) {
|
823 |
+
$result["CustomImageLink"] = ShortPixelMetaFacade::getHomeUrl() . $meta->getWebPath();
|
824 |
+
}
|
825 |
+
}
|
826 |
+
elseif($result["Status"] == ShortPixelAPI::STATUS_QUEUE_FULL) {
|
827 |
+
//nimic?
|
828 |
+
}
|
829 |
+
elseif($result["Status"] == ShortPixelAPI::STATUS_MAINTENANCE) {
|
830 |
+
//nimic?
|
831 |
+
}
|
832 |
+
elseif ($this->prioQ->isPrio($itemId) && $result["Status"] == ShortPixelAPI::STATUS_QUOTA_EXCEEDED) {
|
833 |
+
if(!$this->prioQ->skippedCount()) {
|
834 |
+
$this->prioQ->reverse(); //for the first prio item with quota exceeded, revert the prio queue as probably the bottom ones were processed
|
835 |
+
}
|
836 |
+
if($this->prioQ->allSkipped()) {
|
837 |
+
$result["Stop"] = true;
|
838 |
+
} else {
|
839 |
+
$result["Stop"] = false;
|
840 |
+
$this->prioQ->skip($itemId);
|
841 |
+
}
|
842 |
+
self::log("HIP: 5 Prio Skipped: ".json_encode($this->prioQ->getSkipped()));
|
843 |
+
}
|
844 |
+
elseif($result["Status"] == ShortPixelAPI::STATUS_RETRY && is_array($customIds)) {
|
845 |
+
$result["CustomImageLink"] = $thumb = ShortPixelMetaFacade::getHomeUrl() . $meta->getWebPath();
|
846 |
+
}
|
847 |
+
|
848 |
+
if($result["Status"] !== ShortPixelAPI::STATUS_RETRY) {
|
849 |
+
$this->_settings->bulkLastStatus = $result;
|
850 |
+
}
|
851 |
+
die(json_encode($result));
|
852 |
+
}
|
853 |
+
|
854 |
+
|
855 |
+
private function advanceBulk($processedID) {
|
856 |
+
if($processedID <= $this->prioQ->getStartBulkId()) {
|
857 |
+
$this->prioQ->setStartBulkId($processedID - 1);
|
858 |
+
$this->prioQ->logBulkProgress();
|
859 |
+
}
|
860 |
+
}
|
861 |
+
|
862 |
+
private function setBulkInfo($processedID, &$result) {
|
863 |
+
$deltaBulkPercent = $this->prioQ->getDeltaBulkPercent();
|
864 |
+
$minutesRemaining = $this->prioQ->getTimeRemaining();
|
865 |
+
$pendingMeta = $this->_settings->hasCustomFolders ? $this->spMetaDao->getPendingMetaCount() : 0;
|
866 |
+
$percent = $this->prioQ->getBulkPercent();
|
867 |
+
if(0 + $pendingMeta > 0) {
|
868 |
+
$customMeta = $this->spMetaDao->getCustomMetaCount();
|
869 |
+
$totalPercent = round(($percent * $this->_settings->currentTotalFiles + ($customMeta - $pendingMeta) * 100) / ($this->_settings->currentTotalFiles + $customMeta));
|
870 |
+
$minutesRemaining = round($minutesRemaining * (100 - $totalPercent) / max(1, 100 - $percent));
|
871 |
+
$percent = $totalPercent;
|
872 |
+
}
|
873 |
+
$result["BulkPercent"] = $percent;
|
874 |
+
$result["BulkMsg"] = $this->bulkProgressMessage($deltaBulkPercent, $minutesRemaining);
|
875 |
+
}
|
876 |
+
|
877 |
+
private function sendToProcessing($itemHandler, $compressionType = false, $onlyThumbs = false) {
|
878 |
+
$URLsAndPATHs = $this->getURLsAndPATHs($itemHandler, NULL, $onlyThumbs);
|
879 |
+
|
880 |
+
$meta = $itemHandler->getMeta();
|
881 |
+
//find thumbs that are not listed in the metadata and add them in the sizes array
|
882 |
+
if($itemHandler->getType() == ShortPixelMetaFacade::MEDIA_LIBRARY_TYPE) {
|
883 |
+
$mainFile = $meta->getPath();
|
884 |
+
|
885 |
+
$foundThumbs = WpShortPixelMediaLbraryAdapter::findThumbs($mainFile);
|
886 |
+
//first identify which thumbs are not in the sizes
|
887 |
+
$sizes = $meta->getThumbs();
|
888 |
+
foreach($foundThumbs as $id => $found) {
|
889 |
+
//get the mime-type from one of the thumbs metas
|
890 |
+
foreach($sizes as $size) {
|
891 |
+
if(pathinfo($mainFile, PATHINFO_EXTENSION) !== pathinfo($size['file'], PATHINFO_EXTENSION)){
|
892 |
+
continue;
|
893 |
+
}
|
894 |
+
$mimeType = $size['mime-type'];
|
895 |
+
if($size['file'] === ShortPixelAPI::MB_basename($found)) {
|
896 |
+
$foundThumbs[$id] = false;
|
897 |
+
}
|
898 |
+
}
|
899 |
+
}
|
900 |
+
// add the unfound ones to the sizes array
|
901 |
+
$ind = 1;
|
902 |
+
while (isset($sizes[ShortPixelMeta::FOUND_THUMB_PREFIX . str_pad("".$ind, 2, '0', STR_PAD_LEFT)])) $ind++;
|
903 |
+
$start = $ind;
|
904 |
+
foreach($foundThumbs as $found) {
|
905 |
+
if($found !== false) {
|
906 |
+
$size = getimagesize($found);
|
907 |
+
$sizes[ShortPixelMeta::FOUND_THUMB_PREFIX . str_pad("".$ind, 2, '0', STR_PAD_LEFT)]= array( // it's a file that has no corresponding thumb so it's the WEBP for the main file
|
908 |
+
'file' => ShortPixelAPI::MB_basename($found),
|
909 |
+
'width' => $size[0],
|
910 |
+
'height' => $size[1],
|
911 |
+
'mime-type' => $mimeType
|
912 |
+
);
|
913 |
+
$ind++;
|
914 |
+
}
|
915 |
+
}
|
916 |
+
if($ind > $start) { // at least one thumbnail added, update
|
917 |
+
$meta->setThumbs($sizes);
|
918 |
+
$itemHandler->updateMeta($meta);
|
919 |
+
$URLsAndPATHs = $this->getURLsAndPATHs($itemHandler, NULL, $onlyThumbs);
|
920 |
+
}
|
921 |
+
}
|
922 |
+
|
923 |
+
//find any missing thumbs files and mark them as such
|
924 |
+
if( isset($URLsAndPATHs['sizesMissing']) && count($URLsAndPATHs['sizesMissing'])
|
925 |
+
&& (null === $meta->getThumbsMissing() || count(array_diff_key($meta->getThumbsMissing(), array_merge($URLsAndPATHs['sizesMissing'], $meta->getThumbsMissing()))))) {
|
926 |
+
//fix missing thumbs in the metadata before sending to processing
|
927 |
+
$meta->setThumbsMissing($URLsAndPATHs['sizesMissing']);
|
928 |
+
$itemHandler->updateMeta();
|
929 |
+
}
|
930 |
+
//die(var_dump($itemHandler));
|
931 |
+
$refresh = $meta->getStatus() === ShortPixelAPI::ERR_INCORRECT_FILE_SIZE;
|
932 |
+
//echo("URLS: "); die(var_dump($URLsAndPATHs));
|
933 |
+
$this->_apiInterface->doRequests($URLsAndPATHs['URLs'], false, $itemHandler,
|
934 |
+
$compressionType === false ? $this->_settings->compressionType : $compressionType, $refresh);//send a request, do NOT wait for response
|
935 |
+
$itemHandler->setWaitingProcessing();
|
936 |
+
//$meta = wp_get_attachment_metadata($ID);
|
937 |
+
//$meta['ShortPixel']['WaitingProcessing'] = true;
|
938 |
+
//wp_update_attachment_metadata($ID, $meta);
|
939 |
+
return $URLsAndPATHs;
|
940 |
+
}
|
941 |
+
|
942 |
+
public function handleManualOptimization() {
|
943 |
+
$imageId = $_GET['image_id'];
|
944 |
+
$cleanup = $_GET['cleanup'];
|
945 |
+
switch(substr($imageId, 0, 2)) {
|
946 |
+
case "N-":
|
947 |
+
return "Add the gallery to the custom folders list in ShortPixel settings.";
|
948 |
+
// Later
|
949 |
+
if(class_exists("C_Image_Mapper")) { //this is a NextGen image but not added to our tables, so add it now.
|
950 |
+
$image_mapper = C_Image_Mapper::get_instance();
|
951 |
+
$image = $image_mapper->find(intval(substr($imageId, 2)));
|
952 |
+
if($image) {
|
953 |
+
$this->handleNextGenImageUpload($image, true);
|
954 |
+
return array("Status" => ShortPixelAPI::STATUS_SUCCESS, "message" => "");
|
955 |
+
}
|
956 |
+
}
|
957 |
+
return array("Status" => ShortPixelAPI::STATUS_FAIL, "message" => __('NextGen image not found','shortpixel-image-optimiser'));
|
958 |
+
break;
|
959 |
+
case "C-":
|
960 |
+
throw new Exception("HandleManualOptimization for custom images not implemented");
|
961 |
+
default:
|
962 |
+
$this->optimizeNowHook(intval($imageId), true);
|
963 |
+
break;
|
964 |
+
}
|
965 |
+
//do_action('shortpixel-optimize-now', $imageId);
|
966 |
+
|
967 |
+
}
|
968 |
+
|
969 |
+
//custom hook
|
970 |
+
public function optimizeNowHook($imageId, $manual = false) {
|
971 |
+
if(self::isProcessable($imageId)) {
|
972 |
+
$this->prioQ->push($imageId);
|
973 |
+
$itemHandler = new ShortPixelMetaFacade($imageId);
|
974 |
+
$path = get_attached_file($ID);//get the full file PATH
|
975 |
+
if(!$manual && 'pdf' === pathinfo($path, PATHINFO_EXTENSION) && !$this->_settings->optimizePdfs) {
|
976 |
+
$ret = array("Status" => ShortPixelAPI::STATUS_SKIP, "Message" => $imageId);
|
977 |
+
} else {
|
978 |
+
try {
|
979 |
+
$this->sendToProcessing($itemHandler);
|
980 |
+
$ret = array("Status" => ShortPixelAPI::STATUS_SUCCESS, "Message" => "");
|
981 |
+
} catch(Exception $e) { // Exception("Post metadata is corrupt (No attachment URL)")
|
982 |
+
$itemHandler->getMeta();
|
983 |
+
$itemHandler->setError(ShortPixelAPI::ERR_FILE_NOT_FOUND, $e->getMessage());
|
984 |
+
$ret = array("Status" => ShortPixelAPI::STATUS_FAIL, "Message" => $e->getMessage());
|
985 |
+
}
|
986 |
+
}
|
987 |
+
} else {
|
988 |
+
$ret = array("Status" => ShortPixelAPI::STATUS_SKIP, "Message" => $imageId);
|
989 |
+
}
|
990 |
+
die(json_encode($ret));
|
991 |
+
}
|
992 |
+
|
993 |
+
//WP/LR Sync plugin integration
|
994 |
+
public function onWpLrUpdateMedia($imageId, $galleryIdsUnused) {
|
995 |
+
$meta = wp_get_attachment_metadata($imageId);
|
996 |
+
if(is_array($meta)) {
|
997 |
+
unset($meta['ShortPixel']);
|
998 |
+
$meta['ShortPixel'] = array();
|
999 |
+
$meta['ShortPixel']['WaitingProcessing'] = true;
|
1000 |
+
$this->prioQ->push($imageId);
|
1001 |
+
wp_update_attachment_metadata($imageId, $meta);
|
1002 |
+
}
|
1003 |
+
}
|
1004 |
+
|
1005 |
+
|
1006 |
+
//save error in file's meta data
|
1007 |
+
public function handleError($ID, $result)
|
1008 |
+
{
|
1009 |
+
$meta = wp_get_attachment_metadata($ID);
|
1010 |
+
$meta['ShortPixelImprovement'] = $result;
|
1011 |
+
wp_update_attachment_metadata($ID, $meta);
|
1012 |
+
}
|
1013 |
+
|
1014 |
+
public function getBackupFolder($file) {
|
1015 |
+
if(realpath($file)) {
|
1016 |
+
$file = realpath($file); //found cases when $file contains for example /wp/../wp-content - clean it up
|
1017 |
+
}
|
1018 |
+
$fileExtension = strtolower(substr($file,strrpos($file,".")+1));
|
1019 |
+
$SubDir = ShortPixelMetaFacade::returnSubDir($file, ShortPixelMetaFacade::MEDIA_LIBRARY_TYPE);
|
1020 |
+
$SubDirOld = ShortPixelMetaFacade::returnSubDirOld($file, ShortPixelMetaFacade::MEDIA_LIBRARY_TYPE);
|
1021 |
+
|
1022 |
+
if ( !file_exists(SP_BACKUP_FOLDER . '/' . $SubDir . ShortPixelAPI::MB_basename($file))
|
1023 |
+
&& !file_exists(SP_BACKUP_FOLDER . '/' . date("Y") . "/" . date("m") . "/" . ShortPixelAPI::MB_basename($file)) ) {
|
1024 |
+
$SubDir = $SubDirOld; //maybe the folder was saved with the old method that returned the full path if the wp-content was not inside the root of the site.
|
1025 |
+
}
|
1026 |
+
if ( !file_exists(SP_BACKUP_FOLDER . '/' . $SubDir . ShortPixelAPI::MB_basename($file))
|
1027 |
+
&& !file_exists(SP_BACKUP_FOLDER . '/' . date("Y") . "/" . date("m") . "/" . ShortPixelAPI::MB_basename($file)) ) {
|
1028 |
+
$SubDir = trailingslashit(substr(dirname($file), 1)); //try this too
|
1029 |
+
}
|
1030 |
+
//sometimes the month of original file and backup can differ
|
1031 |
+
if ( !file_exists(SP_BACKUP_FOLDER . '/' . $SubDir . ShortPixelAPI::MB_basename($file)) ) {
|
1032 |
+
$SubDir = date("Y") . "/" . date("m") . "/";
|
1033 |
+
if( !file_exists(SP_BACKUP_FOLDER . '/' . $SubDir . ShortPixelAPI::MB_basename($file)) ) {
|
1034 |
+
return false;
|
1035 |
+
}
|
1036 |
+
}
|
1037 |
+
return SP_BACKUP_FOLDER . '/' . $SubDir;
|
1038 |
+
}
|
1039 |
+
|
1040 |
+
public function getBackupFolderAny($file, $thumbs) {
|
1041 |
+
if(!file_exists($file)) {
|
1042 |
+
//try with the thumbnails
|
1043 |
+
if(isset($thumbs)) foreach($thumbs as $size) {
|
1044 |
+
$backup = $this->getBackupFolder(trailingslashit(dirname($file)) . $size['file']);
|
1045 |
+
if($backup) return $backup;
|
1046 |
+
}
|
1047 |
+
} else {
|
1048 |
+
return $this->getBackupFolder($file);
|
1049 |
+
}
|
1050 |
+
}
|
1051 |
+
|
1052 |
+
protected function setFilePerms($file) {
|
1053 |
+
//die(getenv('USERNAME') ? getenv('USERNAME') : getenv('USER'));
|
1054 |
+
if(strtoupper(substr(PHP_OS, 0, 3)) !== 'WIN') {
|
1055 |
+
//on *nix platforms check also the owner
|
1056 |
+
$owner = fileowner($file);
|
1057 |
+
if($owner !== false && $owner != posix_getuid()) { //files with changed owner
|
1058 |
+
return false;
|
1059 |
+
}
|
1060 |
+
}
|
1061 |
+
$perms = @fileperms($file);
|
1062 |
+
if(!($perms & 0x0100) || !($perms & 0x0080)) {
|
1063 |
+
if(!@chmod($file, $perms | 0x0100 | 0x0080)) {
|
1064 |
+
return false;
|
1065 |
+
}
|
1066 |
+
}
|
1067 |
+
return true;
|
1068 |
+
}
|
1069 |
+
|
1070 |
+
protected function doRestore($attachmentID, $meta = null) {
|
1071 |
+
$file = $origFile = get_attached_file($attachmentID);
|
1072 |
+
if(!$meta) {
|
1073 |
+
$meta = wp_get_attachment_metadata($attachmentID);
|
1074 |
+
}
|
1075 |
+
$pathInfo = pathinfo($file);
|
1076 |
+
|
1077 |
+
$bkFolder = $this->getBackupFolderAny($file, $meta["sizes"]);
|
1078 |
+
$bkFile = trailingslashit($bkFolder) . ShortPixelAPI::MB_basename($file);
|
1079 |
+
|
1080 |
+
//first check if the file is readable by the current user - otherwise it will be unaccessible for the web browser
|
1081 |
+
// - collect the thumbs paths in the process
|
1082 |
+
$bkCount = 0; $main = false;
|
1083 |
+
if(file_exists($bkFile)) {
|
1084 |
+
if(!$this->setFilePerms($bkFile) || (file_exists($file) && !$this->setFilePerms($file)) ) {
|
1085 |
+
return false;
|
1086 |
+
}
|
1087 |
+
$bkCount++;
|
1088 |
+
$main = true;
|
1089 |
+
}
|
1090 |
+
$thumbsPaths = array();
|
1091 |
+
if( !empty($meta['file']) && is_array($meta["sizes"]) ) {
|
1092 |
+
foreach($meta["sizes"] as $size => $imageData) {
|
1093 |
+
$dest = $pathInfo['dirname'] . '/' . $imageData['file'];
|
1094 |
+
$source = trailingslashit($bkFolder) . $imageData['file'];
|
1095 |
+
if(!file_exists($source)) continue; // if thumbs were not optimized, then the backups will not be there.
|
1096 |
+
if(!$this->setFilePerms($source) || (file_exists($dest) && !$this->setFilePerms($dest))) {
|
1097 |
+
return false;
|
1098 |
+
}
|
1099 |
+
$bkCount++;
|
1100 |
+
$thumbsPaths[$source] = $dest;
|
1101 |
+
}
|
1102 |
+
}
|
1103 |
+
if(!$bkCount) {
|
1104 |
+
return false;
|
1105 |
+
}
|
1106 |
+
|
1107 |
+
if($bkFolder) {
|
1108 |
+
try {
|
1109 |
+
//main file
|
1110 |
+
if($main) {
|
1111 |
+
$this->renameWithRetina($bkFile, $file);
|
1112 |
+
}
|
1113 |
+
//getSize to update meta if image was resized by ShortPixel
|
1114 |
+
$width = false;
|
1115 |
+
if(file_exists($file)) {
|
1116 |
+
$size = getimagesize($file);
|
1117 |
+
$width = $size[0];
|
1118 |
+
$height = $size[1];
|
1119 |
+
}
|
1120 |
+
|
1121 |
+
//overwriting thumbnails
|
1122 |
+
foreach($thumbsPaths as $source => $destination) {
|
1123 |
+
$this->renameWithRetina($source, $destination);
|
1124 |
+
}
|
1125 |
+
$duplicates = ShortPixelMetaFacade::getWPMLDuplicates($attachmentID);
|
1126 |
+
foreach($duplicates as $ID) {
|
1127 |
+
$crtMeta = $attachmentID == $ID ? $meta : wp_get_attachment_metadata($ID);
|
1128 |
+
if(is_numeric($crtMeta["ShortPixelImprovement"]) && 0 + $crtMeta["ShortPixelImprovement"] < 5 && $this->_settings->under5Percent > 0) {
|
1129 |
+
$this->_settings->under5Percent = $this->_settings->under5Percent - 1; // - (isset($crtMeta["ShortPixel"]["thumbsOpt"]) ? $crtMeta["ShortPixel"]["thumbsOpt"] : 0);
|
1130 |
+
}
|
1131 |
+
unset($crtMeta["ShortPixelImprovement"]);
|
1132 |
+
unset($crtMeta['ShortPixel']);
|
1133 |
+
if($width && $height) {
|
1134 |
+
$crtMeta['width'] = $width;
|
1135 |
+
$crtMeta['height'] = $height;
|
1136 |
+
}
|
1137 |
+
wp_update_attachment_metadata($ID, $crtMeta);
|
1138 |
+
}
|
1139 |
+
unset($meta["ShortPixelImprovement"]);
|
1140 |
+
unset($meta['ShortPixel']);
|
1141 |
+
|
1142 |
+
} catch(Exception $e) {
|
1143 |
+
//what to do, what to do?
|
1144 |
+
return false;
|
1145 |
+
}
|
1146 |
+
} else {
|
1147 |
+
return false;
|
1148 |
+
}
|
1149 |
+
|
1150 |
+
return $meta;
|
1151 |
+
}
|
1152 |
+
|
1153 |
+
protected function renameWithRetina($bkFile, $file) {
|
1154 |
+
@rename($bkFile, $file);
|
1155 |
+
$ext = pathinfo($file, PATHINFO_EXTENSION);
|
1156 |
+
@rename(substr($bkFile, 0, strlen($bkFile) - 1 - strlen($ext)) . "@2x." . $ext, substr($file, 0, strlen($file) - 1 - strlen($ext)) . "@2x." . $ext);
|
1157 |
+
|
1158 |
+
}
|
1159 |
+
|
1160 |
+
public function doCustomRestore($ID) {
|
1161 |
+
$meta = $this->spMetaDao->getMeta($ID);
|
1162 |
+
if(!$meta || $meta->getStatus() != 2) return false;
|
1163 |
+
|
1164 |
+
$file = $meta->getPath();
|
1165 |
+
$fullSubDir = str_replace(get_home_path(), "", dirname($file)) . '/';
|
1166 |
+
$bkFile = SP_BACKUP_FOLDER . '/' . $fullSubDir . ShortPixelAPI::MB_basename($file);
|
1167 |
+
|
1168 |
+
if(file_exists($bkFile)) {
|
1169 |
+
@rename($bkFile, $file);
|
1170 |
+
$meta->setStatus(3);
|
1171 |
+
$this->spMetaDao->update($meta);
|
1172 |
+
}
|
1173 |
+
|
1174 |
+
return $meta;
|
1175 |
+
}
|
1176 |
+
|
1177 |
+
public function handleRestoreBackup() {
|
1178 |
+
$attachmentID = intval($_GET['attachment_ID']);
|
1179 |
+
|
1180 |
+
$this->doRestore($attachmentID);
|
1181 |
+
|
1182 |
+
// get the referring webpage location
|
1183 |
+
$sendback = wp_get_referer();
|
1184 |
+
// sanitize the referring webpage location
|
1185 |
+
$sendback = preg_replace('|[^a-z0-9-~+_.?#=&;,/:]|i', '', $sendback);
|
1186 |
+
// send the user back where they came from
|
1187 |
+
wp_redirect($sendback);
|
1188 |
+
// we are done
|
1189 |
+
}
|
1190 |
+
|
1191 |
+
public function handleRedo() {
|
1192 |
+
die(json_encode($this->redo($_GET['attachment_ID'], $_GET['type'])));
|
1193 |
+
}
|
1194 |
+
|
1195 |
+
public function redo($qID, $type = false) {
|
1196 |
+
if(ShortPixelMetaFacade::isCustomQueuedId($qID)) {
|
1197 |
+
$ID = ShortPixelMetaFacade::stripQueuedIdType($qID);
|
1198 |
+
$meta = $this->doCustomRestore($ID);
|
1199 |
+
if($meta) {
|
1200 |
+
$meta->setCompressionType(1 - $meta->getCompressionType());
|
1201 |
+
$meta->setStatus(1);
|
1202 |
+
$this->spMetaDao->update($meta);
|
1203 |
+
$this->prioQ->push($qID);
|
1204 |
+
$ret = array("Status" => ShortPixelAPI::STATUS_SUCCESS, "Message" => "");
|
1205 |
+
} else {
|
1206 |
+
$ret = array("Status" => ShortPixelAPI::STATUS_SKIP, "Message" => __('Could not restore from backup: ','shortpixel-image-optimiser') . $qID);
|
1207 |
+
}
|
1208 |
+
} else {
|
1209 |
+
$ID = intval($qID);
|
1210 |
+
$compressionType = ($type == 'lossless' ? 'lossless' : 'lossy'); //sanity check
|
1211 |
+
|
1212 |
+
$meta = $this->doRestore($ID);
|
1213 |
+
if($meta) { //restore succeeded
|
1214 |
+
$meta['ShortPixel'] = array("type" => $compressionType);
|
1215 |
+
wp_update_attachment_metadata($ID, $meta);
|
1216 |
+
try {
|
1217 |
+
$this->sendToProcessing(new ShortPixelMetaFacade($ID), $compressionType == 'lossy' ? 1 : 0);
|
1218 |
+
$this->prioQ->push($ID);
|
1219 |
+
$ret = array("Status" => ShortPixelAPI::STATUS_SUCCESS, "Message" => "");
|
1220 |
+
} catch(Exception $e) { // Exception("Post metadata is corrupt (No attachment URL)") or Exception("Image files are missing.")
|
1221 |
+
$meta['ShortPixelImprovement'] = $e->getMessage();
|
1222 |
+
$meta['ShortPixel']['ErrCode'] = ShortPixelAPI::STATUS_FAIL;
|
1223 |
+
unset($meta['ShortPixel']['WaitingProcessing']);
|
1224 |
+
wp_update_attachment_metadata($ID, $meta);
|
1225 |
+
$ret = array("Status" => ShortPixelAPI::STATUS_FAIL, "Message" => $e->getMessage());
|
1226 |
+
}
|
1227 |
+
} else {
|
1228 |
+
$ret = array("Status" => ShortPixelAPI::STATUS_SKIP, "Message" => __('Could not restore from backup: ','shortpixel-image-optimiser') . $ID);
|
1229 |
+
}
|
1230 |
+
}
|
1231 |
+
return $ret;
|
1232 |
+
}
|
1233 |
+
|
1234 |
+
public function handleOptimizeThumbs() {
|
1235 |
+
$ID = intval($_GET['attachment_ID']);
|
1236 |
+
$meta = wp_get_attachment_metadata($ID);
|
1237 |
+
//die(var_dump($meta));
|
1238 |
+
if( isset($meta['ShortPixelImprovement'])
|
1239 |
+
&& isset($meta['sizes']) && WpShortPixelMediaLbraryAdapter::countNonWebpSizes($meta['sizes'])
|
1240 |
+
&& ( !isset($meta['ShortPixel']['thumbsOpt']) || $meta['ShortPixel']['thumbsOpt'] == 0)) { //optimized without thumbs, thumbs exist
|
1241 |
+
$meta['ShortPixel']['thumbsTodo'] = true;
|
1242 |
+
wp_update_attachment_metadata($ID, $meta);
|
1243 |
+
$this->prioQ->push($ID);
|
1244 |
+
try {
|
1245 |
+
$this->sendToProcessing(new ShortPixelMetaFacade($ID));
|
1246 |
+
$ret = array("Status" => ShortPixelAPI::STATUS_SUCCESS, "message" => "");
|
1247 |
+
} catch(Exception $e) { // Exception("Post metadata is corrupt (No attachment URL)") or Exception("Image files are missing.")
|
1248 |
+
$meta['ShortPixelImprovement'] = $e->getMessage();
|
1249 |
+
$meta['ShortPixel']['ErrCode'] = ShortPixelAPI::STATUS_FAIL;
|
1250 |
+
unset($meta['ShortPixel']['WaitingProcessing']);
|
1251 |
+
wp_update_attachment_metadata($ID, $meta);
|
1252 |
+
$ret = array("Status" => ShortPixelAPI::STATUS_FAIL, "Message" => $e->getMessage());
|
1253 |
+
}
|
1254 |
+
} else {
|
1255 |
+
$ret = array("Status" => ShortPixelAPI::STATUS_SKIP, "message" => (isset($meta['ShortPixelImprovement']) ? __('No thumbnails to optimize for ID: ','shortpixel-image-optimiser') : __('Please optimize image for ID: ','shortpixel-image-optimiser')) . $ID);
|
1256 |
+
}
|
1257 |
+
die(json_encode($ret));
|
1258 |
+
}
|
1259 |
+
|
1260 |
+
public function handleCheckQuota() {
|
1261 |
+
$this->getQuotaInformation();
|
1262 |
+
// store the referring webpage location
|
1263 |
+
$sendback = wp_get_referer();
|
1264 |
+
// sanitize the referring webpage location
|
1265 |
+
$sendback = preg_replace('|[^a-z0-9-~+_.?#=&;,/:]|i', '', $sendback);
|
1266 |
+
// send the user back where they came from
|
1267 |
+
wp_redirect($sendback);
|
1268 |
+
// we are done
|
1269 |
+
}
|
1270 |
+
|
1271 |
+
public function handleDeleteAttachmentInBackup($ID) {
|
1272 |
+
$file = get_attached_file($ID);
|
1273 |
+
$meta = wp_get_attachment_metadata($ID);
|
1274 |
+
|
1275 |
+
if(self::isProcessable($ID) != false)
|
1276 |
+
{
|
1277 |
+
try {
|
1278 |
+
$SubDir = ShortPixelMetaFacade::returnSubDir($file, ShortPixelMetaFacade::MEDIA_LIBRARY_TYPE);
|
1279 |
+
|
1280 |
+
@unlink(SP_BACKUP_FOLDER . '/' . $SubDir . ShortPixelAPI::MB_basename($file));
|
1281 |
+
|
1282 |
+
if ( !empty($meta['file']) )
|
1283 |
+
{
|
1284 |
+
$filesPath = SP_BACKUP_FOLDER . '/' . $SubDir;//base BACKUP path
|
1285 |
+
//remove thumbs thumbnails
|
1286 |
+
if(isset($meta["sizes"])) {
|
1287 |
+
foreach($meta["sizes"] as $size => $imageData) {
|
1288 |
+
@unlink($filesPath . ShortPixelAPI::MB_basename($imageData['file']));//remove thumbs
|
1289 |
+
}
|
1290 |
+
}
|
1291 |
+
}
|
1292 |
+
|
1293 |
+
} catch(Exception $e) {
|
1294 |
+
//what to do, what to do?
|
1295 |
+
}
|
1296 |
+
}
|
1297 |
+
}
|
1298 |
+
|
1299 |
+
public function deactivatePlugin() {
|
1300 |
+
if ( ! wp_verify_nonce( $_GET['_wpnonce'], 'sp_deactivate_plugin_nonce' ) ) {
|
1301 |
+
wp_nonce_ays( '' );
|
1302 |
+
}
|
1303 |
+
deactivate_plugins( $_GET['plugin'] );
|
1304 |
+
wp_safe_redirect( wp_get_referer() );
|
1305 |
+
die();
|
1306 |
+
}
|
1307 |
+
|
1308 |
+
public function checkQuotaAndAlert($quotaData = null, $recheck = false) {
|
1309 |
+
if(!$quotaData) {
|
1310 |
+
$quotaData = $this->getQuotaInformation();
|
1311 |
+
}
|
1312 |
+
if ( !$quotaData['APIKeyValid']) {
|
1313 |
+
return $quotaData;
|
1314 |
+
}
|
1315 |
+
//$tempus = microtime(true);
|
1316 |
+
$imageCount = WpShortPixelMediaLbraryAdapter::countAllProcessableFiles($this->_settings->optimizePdfs);
|
1317 |
+
|
1318 |
+
$this->_settings->currentTotalFiles = $imageCount['totalFiles'];
|
1319 |
+
|
1320 |
+
//echo("Count took (seconds): " . (microtime(true) - $tempus));
|
1321 |
+
foreach($imageCount as $key => $val) {
|
1322 |
+
$quotaData[$key] = $val;
|
1323 |
+
}
|
1324 |
+
|
1325 |
+
if($this->_settings->hasCustomFolders) {
|
1326 |
+
$customImageCount = $this->spMetaDao->countAllProcessableFiles();
|
1327 |
+
foreach($customImageCount as $key => $val) {
|
1328 |
+
$quotaData[$key] = isset($quotaData[$key])
|
1329 |
+
? (is_array($quotaData[$key]) ? array_merge($quotaData[$key], $val) : $quotaData[$key] + $val)
|
1330 |
+
: $val;
|
1331 |
+
}
|
1332 |
+
}
|
1333 |
+
|
1334 |
+
if($quotaData['APICallsQuotaNumeric'] + $quotaData['APICallsQuotaOneTimeNumeric'] > $quotaData['APICallsMadeNumeric'] + $quotaData['APICallsMadeOneTimeNumeric']) {
|
1335 |
+
$this->_settings->quotaExceeded = '0';
|
1336 |
+
$this->_settings->prioritySkip = NULL;
|
1337 |
+
self::log("CHECK QUOTA: Skipped: ".json_encode($this->prioQ->getSkipped()));
|
1338 |
+
|
1339 |
+
?><script>var shortPixelQuotaExceeded = 0;</script><?php
|
1340 |
+
}
|
1341 |
+
else {
|
1342 |
+
$this->view->displayQuotaExceededAlert($quotaData, self::getAverageCompression(), $recheck);
|
1343 |
+
?><script>var shortPixelQuotaExceeded = 1;</script><?php
|
1344 |
+
}
|
1345 |
+
return $quotaData;
|
1346 |
+
}
|
1347 |
+
|
1348 |
+
public function isValidMetaId($id) {
|
1349 |
+
return substr($id, 0, 2 ) == "C-" ? $this->spMetaDao->getMeta(substr($id, 2)) : wp_get_attachment_url($id);
|
1350 |
+
}
|
1351 |
+
|
1352 |
+
public function listCustomMedia() {
|
1353 |
+
if( ! class_exists( 'ShortPixelListTable' ) ) {
|
1354 |
+
require_once('view/shortpixel-list-table.php');
|
1355 |
+
}
|
1356 |
+
if(isset($_REQUEST['refresh']) && esc_attr($_REQUEST['refresh']) == 1) {
|
1357 |
+
$notice = null;
|
1358 |
+
$this->refreshCustomFolders($notice);
|
1359 |
+
}
|
1360 |
+
if(isset($_REQUEST['action']) && esc_attr($_REQUEST['action']) == 'optimize' && isset($_REQUEST['image'])) {
|
1361 |
+
//die(ShortPixelMetaFacade::queuedId(ShortPixelMetaFacade::CUSTOM_TYPE, $_REQUEST['image']));
|
1362 |
+
$this->prioQ->push(ShortPixelMetaFacade::queuedId(ShortPixelMetaFacade::CUSTOM_TYPE, $_REQUEST['image']));
|
1363 |
+
}
|
1364 |
+
$customMediaListTable = new ShortPixelListTable($this, $this->spMetaDao, $this->hasNextGen);
|
1365 |
+
$items = $customMediaListTable->prepare_items();
|
1366 |
+
if ( isset($_GET['noheader']) ) {
|
1367 |
+
require_once(ABSPATH . 'wp-admin/admin-header.php');
|
1368 |
+
}
|
1369 |
+
|
1370 |
+
?>
|
1371 |
+
<div class="wrap shortpixel-other-media">
|
1372 |
+
<h2>
|
1373 |
+
<div style="float:right;">
|
1374 |
+
<a href="upload.php?page=wp-short-pixel-custom&refresh=1" id="refresh" class="button button-primary" title="<?php _e('Refresh custom folders content','shortpixel-image-optimiser');?>">
|
1375 |
+
<?php _e('Refresh folders','shortpixel-image-optimiser');?>
|
1376 |
+
</a>
|
1377 |
+
</div>
|
1378 |
+
<?php _e('Other Media optimized by ShortPixel','shortpixel-image-optimiser');?>
|
1379 |
+
</h2>
|
1380 |
+
|
1381 |
+
<div id="poststuff">
|
1382 |
+
<div id="post-body" class="metabox-holder columns-2">
|
1383 |
+
<div id="post-body-content">
|
1384 |
+
<div class="meta-box-sortables ui-sortable">
|
1385 |
+
<form method="post" class="shortpixel-table">
|
1386 |
+
<?php
|
1387 |
+
$customMediaListTable->display();
|
1388 |
+
//push to the processing list the pending ones, just in case
|
1389 |
+
//$count = $this->spMetaDao->getCustomMetaCount();
|
1390 |
+
foreach ($items as $item) {
|
1391 |
+
if($item->status == 1){
|
1392 |
+
$this->prioQ->push(ShortPixelMetaFacade::queuedId(ShortPixelMetaFacade::CUSTOM_TYPE, $item->id));
|
1393 |
+
}
|
1394 |
+
}
|
1395 |
+
?>
|
1396 |
+
</form>
|
1397 |
+
</div>
|
1398 |
+
</div>
|
1399 |
+
</div>
|
1400 |
+
<br class="clear">
|
1401 |
+
</div>
|
1402 |
+
</div> <?php
|
1403 |
+
}
|
1404 |
+
public function bulkProcess() {
|
1405 |
+
global $wpdb;
|
1406 |
+
|
1407 |
+
if( $this->_settings->verifiedKey == false ) {//invalid API Key
|
1408 |
+
ShortPixelView::displayActivationNotice();
|
1409 |
+
return;
|
1410 |
+
}
|
1411 |
+
|
1412 |
+
$quotaData = $this->checkQuotaAndAlert(null, isset($_GET['checkquota']));
|
1413 |
+
if($this->_settings->quotaExceeded != 0) {
|
1414 |
+
return;
|
1415 |
+
}
|
1416 |
+
|
1417 |
+
if(isset($_POST['bulkProcessPause']))
|
1418 |
+
{//pause an ongoing bulk processing, it might be needed sometimes
|
1419 |
+
$this->prioQ->pauseBulk();
|
1420 |
+
if($this->_settings->hasCustomFolders && $this->spMetaDao->getPendingMetaCount()) {
|
1421 |
+
$this->_settings->customBulkPaused = 1;
|
1422 |
+
}
|
1423 |
+
}
|
1424 |
+
|
1425 |
+
if(isset($_POST['bulkProcessStop']))
|
1426 |
+
{//stop an ongoing bulk processing
|
1427 |
+
$this->prioQ->cancelBulk();
|
1428 |
+
if($this->_settings->hasCustomFolders && $this->spMetaDao->getPendingMetaCount()) {
|
1429 |
+
$this->_settings->customBulkPaused = 1;
|
1430 |
+
}
|
1431 |
+
}
|
1432 |
+
|
1433 |
+
if(isset($_POST["bulkProcess"]))
|
1434 |
+
{
|
1435 |
+
//set the thumbnails option
|
1436 |
+
if ( isset($_POST['thumbnails']) ) {
|
1437 |
+
$this->_settings->processThumbnails = 1;
|
1438 |
+
} else {
|
1439 |
+
$this->_settings->processThumbnails = 0;
|
1440 |
+
}
|
1441 |
+
//clean the custom files errors in order to process them again
|
1442 |
+
if($this->_settings->hasCustomFolders) {
|
1443 |
+
$this->spMetaDao->resetFailed();
|
1444 |
+
}
|
1445 |
+
|
1446 |
+
$this->prioQ->startBulk();
|
1447 |
+
$this->_settings->customBulkPaused = 0;
|
1448 |
+
self::log("BULK: Start: " . $this->prioQ->getStartBulkId() . ", stop: " . $this->prioQ->getStopBulkId() . " PrioQ: "
|
1449 |
+
.json_encode($this->prioQ->get()));
|
1450 |
+
}//end bulk process was clicked
|
1451 |
+
|
1452 |
+
if(isset($_POST["bulkProcessResume"]))
|
1453 |
+
{
|
1454 |
+
$this->prioQ->resumeBulk();
|
1455 |
+
$this->_settings->customBulkPaused = 0;
|
1456 |
+
}//resume was clicked
|
1457 |
+
|
1458 |
+
if(isset($_POST["skipToCustom"]))
|
1459 |
+
{
|
1460 |
+
$this->_settings->skipToCustom = true;
|
1461 |
+
}//resume was clicked
|
1462 |
+
|
1463 |
+
//figure out the files that are left to be processed
|
1464 |
+
$qry_left = "SELECT count(*) FilesLeftToBeProcessed FROM " . $wpdb->prefix . "postmeta
|
1465 |
+
WHERE meta_key = '_wp_attached_file' AND post_id <= " . (0 + $this->prioQ->getStartBulkId());
|
1466 |
+
$filesLeft = $wpdb->get_results($qry_left);
|
1467 |
+
|
1468 |
+
//check the custom bulk
|
1469 |
+
$pendingMeta = $this->_settings->hasCustomFolders ? $this->spMetaDao->getPendingMetaCount() : 0;
|
1470 |
+
|
1471 |
+
if ( ($filesLeft[0]->FilesLeftToBeProcessed > 0 && $this->prioQ->bulkRunning())
|
1472 |
+
|| (0 + $pendingMeta > 0 && !$this->_settings->customBulkPaused && $this->prioQ->bulkRan())//bulk processing was started
|
1473 |
+
&& (!$this->prioQ->bulkPaused() || $this->_settings->skipToCustom)) //bulk not paused or if paused, user pressed Process Custom button
|
1474 |
+
{
|
1475 |
+
$msg = $this->bulkProgressMessage($this->prioQ->getDeltaBulkPercent(), $this->prioQ->getTimeRemaining());
|
1476 |
+
|
1477 |
+
$this->view->displayBulkProcessingRunning($this->getPercent($quotaData), $msg, $quotaData['APICallsRemaining'], $this->getAverageCompression(),
|
1478 |
+
($pendingMeta !== null ? ($this->prioQ->bulkRunning() ? 3 : 2) : 1));
|
1479 |
+
|
1480 |
+
} else
|
1481 |
+
{
|
1482 |
+
if($this->prioQ->bulkRan() && !$this->prioQ->bulkPaused()) {
|
1483 |
+
$this->prioQ->markBulkComplete();
|
1484 |
+
}
|
1485 |
+
|
1486 |
+
//image count
|
1487 |
+
$thumbsProcessedCount = $this->_settings->thumbsCount;//amount of optimized thumbnails
|
1488 |
+
$under5PercentCount = $this->_settings->under5Percent;//amount of under 5% optimized imgs.
|
1489 |
+
|
1490 |
+
//average compression
|
1491 |
+
$averageCompression = self::getAverageCompression();
|
1492 |
+
$percent = $this->prioQ->bulkPaused() ? $this->getPercent($quotaData) : false;
|
1493 |
+
|
1494 |
+
$this->view->displayBulkProcessingForm($quotaData, $thumbsProcessedCount, $under5PercentCount,
|
1495 |
+
$this->prioQ->bulkRan(), $averageCompression, $this->_settings->fileCount,
|
1496 |
+
self::formatBytes($this->_settings->savedSpace), $percent, $pendingMeta);
|
1497 |
+
}
|
1498 |
+
}
|
1499 |
+
//end bulk processing
|
1500 |
+
|
1501 |
+
public function getPercent($quotaData) {
|
1502 |
+
if($this->_settings->processThumbnails) {
|
1503 |
+
return min(99, round($quotaData["totalProcessedFiles"] *100.0 / $quotaData["totalFiles"]));
|
1504 |
+
} else {
|
1505 |
+
return min(99, round($quotaData["mainProcessedFiles"] *100.0 / $quotaData["mainFiles"]));
|
1506 |
+
}
|
1507 |
+
}
|
1508 |
+
|
1509 |
+
public function bulkProgressMessage($percent, $minutes) {
|
1510 |
+
$timeEst = "";
|
1511 |
+
self::log("bulkProgressMessage(): percent: " . $percent);
|
1512 |
+
if($percent < 1 || $minutes == 0) {
|
1513 |
+
$timeEst = "";
|
1514 |
+
} elseif( $minutes > 2880) {
|
1515 |
+
$timeEst = "~ " . round($minutes / 1440) . " days left";
|
1516 |
+
} elseif ($minutes > 240) {
|
1517 |
+
$timeEst = "~ " . round($minutes / 60) . " hours left";
|
1518 |
+
} elseif ($minutes > 60) {
|
1519 |
+
$timeEst = "~ " . round($minutes / 60) . " hours " . round($minutes % 60 / 10) * 10 . " min. left";
|
1520 |
+
} elseif ($minutes > 20) {
|
1521 |
+
$timeEst = "~ " . round($minutes / 10) * 10 . " minutes left";
|
1522 |
+
} else {
|
1523 |
+
$timeEst = "~ " . $minutes . " minutes left";
|
1524 |
+
}
|
1525 |
+
return $timeEst;
|
1526 |
+
}
|
1527 |
+
|
1528 |
+
public function emptyBackup(){
|
1529 |
+
if(file_exists(SP_BACKUP_FOLDER)) {
|
1530 |
+
|
1531 |
+
//extract all images from DB in an array. of course
|
1532 |
+
$attachments = null;
|
1533 |
+
$attachments = get_posts( array(
|
1534 |
+
'numberposts' => -1,
|
1535 |
+
'post_type' => 'attachment',
|
1536 |
+
'post_mime_type' => 'image'
|
1537 |
+
));
|
1538 |
+
|
1539 |
+
|
1540 |
+
//parse all images and set the right flag that the image has no backup
|
1541 |
+
/* this is obsolete as the backup exists decision is taken on verfication of the actual backup files
|
1542 |
+
foreach($attachments as $attachment)
|
1543 |
+
{
|
1544 |
+
if(self::isProcessable($attachment->ID) == false) continue;
|
1545 |
+
|
1546 |
+
$meta = wp_get_attachment_metadata($attachment->ID);
|
1547 |
+
$meta['ShortPixel']['NoBackup'] = true;
|
1548 |
+
wp_update_attachment_metadata($attachment->ID, $meta);
|
1549 |
+
}
|
1550 |
+
*/
|
1551 |
+
|
1552 |
+
//delete the actual files on disk
|
1553 |
+
$this->deleteDir(SP_BACKUP_FOLDER);//call a recursive function to empty files and sub-dirs in backup dir
|
1554 |
+
}
|
1555 |
+
}
|
1556 |
+
|
1557 |
+
public function backupFolderIsEmpty() {
|
1558 |
+
return count(scandir(SP_BACKUP_FOLDER)) > 2 ? false : true;
|
1559 |
+
}
|
1560 |
+
|
1561 |
+
public function getBackupSize() {
|
1562 |
+
if ( !current_user_can( 'manage_options' ) ) {
|
1563 |
+
wp_die(__('You do not have sufficient permissions to access this page.','shortpixel-image-optimiser'));
|
1564 |
+
}
|
1565 |
+
die(self::formatBytes(self::folderSize(SP_BACKUP_FOLDER)));
|
1566 |
+
}
|
1567 |
+
|
1568 |
+
public function browseContent() {
|
1569 |
+
if ( !current_user_can( 'manage_options' ) ) {
|
1570 |
+
wp_die(__('You do not have sufficient permissions to access this page.','shortpixel-image-optimiser'));
|
1571 |
+
}
|
1572 |
+
|
1573 |
+
$root = self::getCustomFolderBase();
|
1574 |
+
|
1575 |
+
$postDir = rawurldecode($root.(isset($_POST['dir']) ? $_POST['dir'] : null ));
|
1576 |
+
|
1577 |
+
// set checkbox if multiSelect set to true
|
1578 |
+
$checkbox = ( isset($_POST['multiSelect']) && $_POST['multiSelect'] == 'true' ) ? "<input type='checkbox' />" : null;
|
1579 |
+
$onlyFolders = ($_POST['dir'] == '/' || isset($_POST['onlyFolders']) && $_POST['onlyFolders'] == 'true' ) ? true : false;
|
1580 |
+
$onlyFiles = ( isset($_POST['onlyFiles']) && $_POST['onlyFiles'] == 'true' ) ? true : false;
|
1581 |
+
|
1582 |
+
if( file_exists($postDir) ) {
|
1583 |
+
|
1584 |
+
$files = scandir($postDir);
|
1585 |
+
$returnDir = substr($postDir, strlen($root));
|
1586 |
+
|
1587 |
+
natcasesort($files);
|
1588 |
+
|
1589 |
+
if( count($files) > 2 ) { // The 2 accounts for . and ..
|
1590 |
+
echo "<ul class='jqueryFileTree'>";
|
1591 |
+
foreach( $files as $file ) {
|
1592 |
+
|
1593 |
+
if($file == 'ShortpixelBackups') continue;
|
1594 |
+
|
1595 |
+
$htmlRel = str_replace("'", "'", $returnDir . $file);
|
1596 |
+
$htmlName = htmlentities($file);
|
1597 |
+
$ext = preg_replace('/^.*\./', '', $file);
|
1598 |
+
|
1599 |
+
if( file_exists($postDir . $file) && $file != '.' && $file != '..' ) {
|
1600 |
+
if( is_dir($postDir . $file) && (!$onlyFiles || $onlyFolders) )
|
1601 |
+
echo "<li class='directory collapsed'>{$checkbox}<a rel='" .$htmlRel. "/'>" . $htmlName . "</a></li>";
|
1602 |
+
else if (!$onlyFolders || $onlyFiles)
|
1603 |
+
echo "<li class='file ext_{$ext}'>{$checkbox}<a rel='" . $htmlRel . "'>" . $htmlName . "</a></li>";
|
1604 |
+
}
|
1605 |
+
}
|
1606 |
+
|
1607 |
+
echo "</ul>";
|
1608 |
+
}
|
1609 |
+
}
|
1610 |
+
die();
|
1611 |
+
}
|
1612 |
+
|
1613 |
+
public static function getCustomFolderBase() {
|
1614 |
+
if(is_main_site()) {
|
1615 |
+
$base = get_home_path();
|
1616 |
+
return realpath(rtrim($base, '/'));
|
1617 |
+
} else {
|
1618 |
+
$up = wp_upload_dir();
|
1619 |
+
return realpath($up['basedir']);
|
1620 |
+
}
|
1621 |
+
}
|
1622 |
+
|
1623 |
+
protected function fullRefreshCustomFolder($path, &$notice) {
|
1624 |
+
$folder = $this->spMetaDao->getFolder($path);
|
1625 |
+
$diff = $folder->checkFolderContents(array('ShortPixelCustomMetaDao', 'getPathFiles'));
|
1626 |
+
}
|
1627 |
+
|
1628 |
+
protected function refreshCustomFolders(&$notice, $ignore = false) {
|
1629 |
+
$customFolders = array();
|
1630 |
+
if($this->_settings->hasCustomFolders) {
|
1631 |
+
$customFolders = $this->spMetaDao->getFolders();
|
1632 |
+
foreach($customFolders as $folder) {
|
1633 |
+
if($folder->getPath() === $ignore) continue;
|
1634 |
+
try {
|
1635 |
+
$mt = $folder->getFolderContentsChangeDate();
|
1636 |
+
if($mt > strtotime($folder->getTsUpdated())) {
|
1637 |
+
$fileList = $folder->getFileList(strtotime($folder->getTsUpdated()));
|
1638 |
+
$this->spMetaDao->batchInsertImages($fileList, $folder->getId());
|
1639 |
+
$folder->setTsUpdated(date("Y-m-d H:i:s", $mt));
|
1640 |
+
$folder->setFileCount($folder->countFiles());
|
1641 |
+
$this->spMetaDao->update($folder);
|
1642 |
+
}
|
1643 |
+
//echo ("mt: " . $mt);
|
1644 |
+
//die(var_dump($folder));
|
1645 |
+
} catch(SpFileRightsException $ex) {
|
1646 |
+
if(is_array($notice)) {
|
1647 |
+
if($notice['status'] == 'error') {
|
1648 |
+
$notice['msg'] .= " " . $ex->getMessage();
|
1649 |
+
}
|
1650 |
+
} else {
|
1651 |
+
$notice = array("status" => "error", "msg" => $ex->getMessage());
|
1652 |
+
}
|
1653 |
+
}
|
1654 |
+
}
|
1655 |
+
}
|
1656 |
+
return $customFolders;
|
1657 |
+
}
|
1658 |
+
|
1659 |
+
public function renderSettingsMenu() {
|
1660 |
+
if ( !current_user_can( 'manage_options' ) ) {
|
1661 |
+
wp_die(__('You do not have sufficient permissions to access this page.','shortpixel-image-optimiser'));
|
1662 |
+
}
|
1663 |
+
|
1664 |
+
wp_enqueue_style('sp-file-tree.css', plugins_url('/res/css/sp-file-tree.css',SHORTPIXEL_PLUGIN_FILE) );
|
1665 |
+
wp_enqueue_script('sp-file-tree.js', plugins_url('/res/js/sp-file-tree.js',SHORTPIXEL_PLUGIN_FILE) );
|
1666 |
+
|
1667 |
+
//die(var_dump($_POST));
|
1668 |
+
$noticeHTML = "";
|
1669 |
+
$notice = null;
|
1670 |
+
$folderMsg = false;
|
1671 |
+
$addedFolder = false;
|
1672 |
+
|
1673 |
+
$this->_settings->redirectedSettings = 2;
|
1674 |
+
|
1675 |
+
//by default we try to fetch the API Key from wp-config.php (if defined)
|
1676 |
+
if ( defined("SHORTPIXEL_API_KEY") && strlen(SHORTPIXEL_API_KEY) == 20)
|
1677 |
+
{
|
1678 |
+
if(!isset($_POST['save']) && (strlen($this->getApiKey()) == 0 || SHORTPIXEL_API_KEY != $this->getApiKey())) {
|
1679 |
+
$_POST['validate'] = "validate";
|
1680 |
+
}
|
1681 |
+
$_POST['key'] = SHORTPIXEL_API_KEY;
|
1682 |
+
}
|
1683 |
+
|
1684 |
+
//check all custom folders and update meta table if files appeared
|
1685 |
+
$customFolders = $this->refreshCustomFolders($notice, isset($_POST['removeFolder']) ? $_POST['removeFolder'] : null);
|
1686 |
+
|
1687 |
+
if(isset($_POST['request']) && $_POST['request'] == 'request') {
|
1688 |
+
//a new API Key was requested
|
1689 |
+
if(filter_var($_POST['email'], FILTER_VALIDATE_EMAIL)) {
|
1690 |
+
|
1691 |
+
}
|
1692 |
+
else {
|
1693 |
+
$notice = array("status" => "error",
|
1694 |
+
"msg" => __("Please provide a valid e-mail.",'shortpixel-image-optimiser')
|
1695 |
+
. "<BR> "
|
1696 |
+
. __('For any question regarding obtaining your API Key, please contact us at ','shortpixel-image-optimiser')
|
1697 |
+
. "<a href='mailto:help@shortpixel.com?Subject=API Key issues' target='_top'>help@shortpixel.com</a>"
|
1698 |
+
. __(' or ','shortpixel-image-optimiser')
|
1699 |
+
. "<a href='https://shortpixel.com/contact' target='_blank'>" . __('here','shortpixel-image-optimiser') . "</a>.");
|
1700 |
+
}
|
1701 |
+
}
|
1702 |
+
|
1703 |
+
if( isset($_POST['save']) || isset($_POST['saveAdv'])
|
1704 |
+
|| (isset($_POST['validate']) && $_POST['validate'] == "validate")
|
1705 |
+
|| isset($_POST['removeFolder']) || isset($_POST['recheckFolder'])) {
|
1706 |
+
|
1707 |
+
//handle API Key - common for save and validate.
|
1708 |
+
$_POST['key'] = trim(str_replace("*", "", isset($_POST['key']) ? $_POST['key'] : $this->_settings->apiKey)); //the API key might not be set if the editing is disabled.
|
1709 |
+
|
1710 |
+
if ( strlen($_POST['key']) <> 20 )
|
1711 |
+
{
|
1712 |
+
$KeyLength = strlen($_POST['key']);
|
1713 |
+
|
1714 |
+
$notice = array("status" => "error",
|
1715 |
+
"msg" => sprintf(__("The key you provided has %s characters. The API key should have 20 characters, letters and numbers only.",'shortpixel-image-optimiser'), $KeyLength)
|
1716 |
+
. "<BR> <b>"
|
1717 |
+
. __('Please check that the API key is the same as the one you received in your confirmation email.','shortpixel-image-optimiser')
|
1718 |
+
. "</b><BR> "
|
1719 |
+
. __('If this problem persists, please contact us at ','shortpixel-image-optimiser')
|
1720 |
+
. "<a href='mailto:help@shortpixel.com?Subject=API Key issues' target='_top'>help@shortpixel.com</a>"
|
1721 |
+
. __(' or ','shortpixel-image-optimiser')
|
1722 |
+
. "<a href='https://shortpixel.com/contact' target='_blank'>" . __('here','shortpixel-image-optimiser') . "</a>.");
|
1723 |
+
}
|
1724 |
+
else
|
1725 |
+
{
|
1726 |
+
$validityData = $this->getQuotaInformation($_POST['key'], true, isset($_POST['validate']) && $_POST['validate'] == "validate");
|
1727 |
+
|
1728 |
+
$this->_settings->apiKey = $_POST['key'];
|
1729 |
+
if($validityData['APIKeyValid']) {
|
1730 |
+
if(isset($_POST['validate']) && $_POST['validate'] == "validate") {
|
1731 |
+
// delete last status if it was no valid key
|
1732 |
+
$lastStatus = $this->_settings->bulkLastStatus;
|
1733 |
+
if(isset($lastStatus['Status']) && $lastStatus['Status'] == ShortPixelAPI::STATUS_NO_KEY) {
|
1734 |
+
$this->_settings->bulkLastStatus = null;
|
1735 |
+
}
|
1736 |
+
//display notification
|
1737 |
+
$urlParts = explode("/", get_site_url());
|
1738 |
+
if( $validityData['DomainCheck'] == 'NOT Accessible'){
|
1739 |
+
$notice = array("status" => "warn", "msg" => __("API Key is valid but your site is not accessible from our servers. Please make sure that your server is accessible from the Internet before using the API or otherwise we won't be able to optimize them.",'shortpixel-image-optimiser'));
|
1740 |
+
} else {
|
1741 |
+
if ( function_exists("is_multisite") && is_multisite() && !defined("SHORTPIXEL_API_KEY"))
|
1742 |
+
$notice = array("status" => "success", "msg" => __("Great, your API Key is valid! <br>You seem to be running a multisite, please note that API Key can also be configured in wp-config.php like this:",'shortpixel-image-optimiser')
|
1743 |
+
. "<BR> <b>define('SHORTPIXEL_API_KEY', '".$this->_settings->apiKey."');</b>");
|
1744 |
+
else
|
1745 |
+
$notice = array("status" => "success", "msg" => __('Great, your API Key is valid. Please take a few moments to review the plugin settings below before starting to optimize your images.','shortpixel-image-optimiser'));
|
1746 |
+
}
|
1747 |
+
}
|
1748 |
+
$this->_settings->verifiedKey = true;
|
1749 |
+
//test that the "uploads" have the right rights and also we can create the backup dir for ShortPixel
|
1750 |
+
if ( !file_exists(SP_BACKUP_FOLDER) && !@mkdir(SP_BACKUP_FOLDER, 0777, true) )
|
1751 |
+
$notice = array("status" => "error",
|
1752 |
+
"msg" => sprintf(__("There is something preventing us to create a new folder for backing up your original files.<BR>Please make sure that folder <b>%s</b> has the necessary write and read rights.",'shortpixel-image-optimiser'),
|
1753 |
+
WP_CONTENT_DIR . '/' . SP_UPLOADS_NAME ));
|
1754 |
+
} else {
|
1755 |
+
if(isset($_POST['validate'])) {
|
1756 |
+
//display notification
|
1757 |
+
$notice = array("status" => "error", "msg" => $validityData["Message"]);
|
1758 |
+
}
|
1759 |
+
$this->_settings->verifiedKey = false;
|
1760 |
+
}
|
1761 |
+
}
|
1762 |
+
|
1763 |
+
//if save button - we process the rest of the form elements
|
1764 |
+
if(isset($_POST['save']) || isset($_POST['saveAdv'])) {
|
1765 |
+
$this->_settings->compressionType = $_POST['compressionType'];
|
1766 |
+
if(isset($_POST['thumbnails'])) { $this->_settings->processThumbnails = 1; } else { $this->_settings->processThumbnails = 0; }
|
1767 |
+
if(isset($_POST['backupImages'])) { $this->_settings->backupImages = 1; } else { $this->_settings->backupImages = 0; }
|
1768 |
+
if(isset($_POST['cmyk2rgb'])) { $this->_settings->CMYKtoRGBconversion = 1; } else { $this->_settings->CMYKtoRGBconversion = 0; }
|
1769 |
+
$this->_settings->keepExif = isset($_POST['removeExif']) ? 0 : 1;
|
1770 |
+
//delete_option('wp-short-pixel-keep-exif');
|
1771 |
+
$this->_settings->resizeImages = (isset($_POST['resize']) ? 1: 0);
|
1772 |
+
$this->_settings->resizeType = (isset($_POST['resize_type']) ? $_POST['resize_type']: false);
|
1773 |
+
$this->_settings->resizeWidth = (isset($_POST['width']) ? $_POST['width']: $this->_settings->resizeWidth);
|
1774 |
+
$this->_settings->resizeHeight = (isset($_POST['height']) ? $_POST['height']: $this->_settings->resizeHeight);
|
1775 |
+
$this->_settings->siteAuthUser = (isset($_POST['siteAuthUser']) ? $_POST['siteAuthUser']: $this->_settings->siteAuthUser);
|
1776 |
+
$this->_settings->siteAuthPass = (isset($_POST['siteAuthPass']) ? $_POST['siteAuthPass']: $this->_settings->siteAuthPass);
|
1777 |
+
|
1778 |
+
$uploadDir = wp_upload_dir();
|
1779 |
+
$uploadPath = realpath($uploadDir["basedir"]);
|
1780 |
+
|
1781 |
+
if(isset($_POST['nextGen'])) {
|
1782 |
+
WpShortPixelDb::checkCustomTables(); // check if custom tables are created, if not, create them
|
1783 |
+
$prevNextGen = $this->_settings->includeNextGen;
|
1784 |
+
$this->_settings->includeNextGen = 1;
|
1785 |
+
$ret = $this->addNextGenGalleriesToCustom($prevNextGen);
|
1786 |
+
$folderMsg = $ret["message"];
|
1787 |
+
$customFolders = $ret["customFolders"];
|
1788 |
+
} else {
|
1789 |
+
$this->_settings->includeNextGen = 0;
|
1790 |
+
}
|
1791 |
+
if(isset($_POST['addCustomFolder']) && strlen($_POST['addCustomFolder']) > 0) {
|
1792 |
+
$folderMsg = $this->spMetaDao->newFolderFromPath(stripslashes($_POST['addCustomFolder']), $uploadPath, self::getCustomFolderBase());
|
1793 |
+
if(!$folderMsg) {
|
1794 |
+
$notice = array("status" => "success", "msg" => __('Folder added successfully.','shortpixel-image-optimiser'));
|
1795 |
+
}
|
1796 |
+
$customFolders = $this->spMetaDao->getFolders();
|
1797 |
+
$this->_settings->hasCustomFolders = true;
|
1798 |
+
}
|
1799 |
+
|
1800 |
+
$this->_settings->createWebp = (isset($_POST['createWebp']) ? 1: 0);
|
1801 |
+
$this->_settings->optimizeRetina = (isset($_POST['optimizeRetina']) ? 1: 0);
|
1802 |
+
$this->_settings->optimizePdfs = (isset($_POST['optimizePdfs']) ? 1: 0);
|
1803 |
+
$this->_settings->frontBootstrap = (isset($_POST['frontBootstrap']) ? 1: 0);
|
1804 |
+
$this->_settings->autoMediaLibrary = (isset($_POST['autoMediaLibrary']) ? 1: 0);
|
1805 |
+
|
1806 |
+
//Redirect to bulk processing if requested
|
1807 |
+
if( isset($_POST['save']) && $_POST['save'] == __("Save and Go to Bulk Process",'shortpixel-image-optimiser')
|
1808 |
+
|| isset($_POST['saveAdv']) && $_POST['saveAdv'] == __("Save and Go to Bulk Process",'shortpixel-image-optimiser')) {
|
1809 |
+
wp_redirect("upload.php?page=wp-short-pixel-bulk");
|
1810 |
+
exit();
|
1811 |
+
}
|
1812 |
+
}
|
1813 |
+
if(isset($_POST['removeFolder']) && strlen(($_POST['removeFolder']))) {
|
1814 |
+
$this->spMetaDao->removeFolder($_POST['removeFolder']);
|
1815 |
+
$customFolders = $this->spMetaDao->getFolders();
|
1816 |
+
$_POST["saveAdv"] = true;
|
1817 |
+
}
|
1818 |
+
if(isset($_POST['recheckFolder']) && strlen(($_POST['recheckFolder']))) {
|
1819 |
+
//$folder->fullRefreshCustomFolder($_POST['recheckFolder']); //aici singura solutie pare callback care spune daca exita url-ul complet
|
1820 |
+
}
|
1821 |
+
}
|
1822 |
+
|
1823 |
+
//now output headers. They were prevented with noheaders=true in the form url in order to be able to redirect if bulk was pressed
|
1824 |
+
if(isset($_REQUEST['noheader'])) {
|
1825 |
+
require_once(ABSPATH . 'wp-admin/admin-header.php');
|
1826 |
+
}
|
1827 |
+
|
1828 |
+
//empty backup
|
1829 |
+
if(isset($_POST['emptyBackup'])) {
|
1830 |
+
$this->emptyBackup();
|
1831 |
+
}
|
1832 |
+
|
1833 |
+
$quotaData = $this->checkQuotaAndAlert(isset($validityData) ? $validityData : null, isset($_GET['checkquota']));
|
1834 |
+
|
1835 |
+
if($this->hasNextGen) {
|
1836 |
+
$ngg = array_map(array('ShortPixelNextGenAdapter','pathToAbsolute'), ShortPixelNextGenAdapter::getGalleries());
|
1837 |
+
//die(var_dump($ngg));
|
1838 |
+
for($i = 0; $i < count($customFolders); $i++) {
|
1839 |
+
if(in_array($customFolders[$i]->getPath(), $ngg )) {
|
1840 |
+
$customFolders[$i]->setType("NextGen");
|
1841 |
+
}
|
1842 |
+
}
|
1843 |
+
}
|
1844 |
+
|
1845 |
+
$showApiKey = is_main_site() || (function_exists("is_multisite") && is_multisite() && !defined("SHORTPIXEL_API_KEY"));
|
1846 |
+
$editApiKey = !defined("SHORTPIXEL_API_KEY") && $showApiKey;
|
1847 |
+
|
1848 |
+
if($this->_settings->verifiedKey) {
|
1849 |
+
$fileCount = number_format($this->_settings->fileCount);
|
1850 |
+
$savedSpace = self::formatBytes($this->_settings->savedSpace,2);
|
1851 |
+
$averageCompression = $this->getAverageCompression();
|
1852 |
+
$savedBandwidth = self::formatBytes($this->_settings->savedSpace * 10000,2);
|
1853 |
+
if (is_numeric($quotaData['APICallsQuota'])) {
|
1854 |
+
$quotaData['APICallsQuota'] .= "/month";
|
1855 |
+
}
|
1856 |
+
$remainingImages = $quotaData['APICallsRemaining'];
|
1857 |
+
$remainingImages = ( $remainingImages < 0 ) ? 0 : number_format($remainingImages);
|
1858 |
+
$totalCallsMade = number_format($quotaData['APICallsMadeNumeric'] + $quotaData['APICallsMadeOneTimeNumeric']);
|
1859 |
+
|
1860 |
+
$resources = wp_remote_post($this->_settings->httpProto . "://shortpixel.com/resources-frag");
|
1861 |
+
if(is_wp_error( $resources )) {
|
1862 |
+
$resources = array();
|
1863 |
+
}
|
1864 |
+
$this->view->displaySettings($showApiKey, $editApiKey,
|
1865 |
+
$quotaData, $notice, $resources, $averageCompression, $savedSpace, $savedBandwidth, $remainingImages,
|
1866 |
+
$totalCallsMade, $fileCount, null /*folder size now on AJAX*/, $customFolders,
|
1867 |
+
$folderMsg, $folderMsg ? $addedFolder : false, isset($_POST['saveAdv']));
|
1868 |
+
} else {
|
1869 |
+
$this->view->displaySettings($showApiKey, $editApiKey, $quotaData, $notice);
|
1870 |
+
}
|
1871 |
+
|
1872 |
+
}
|
1873 |
+
|
1874 |
+
public function addNextGenGalleriesToCustom($silent) {
|
1875 |
+
$customFolders = array();
|
1876 |
+
$folderMsg = "";
|
1877 |
+
if($this->_settings->includeNextGen) {
|
1878 |
+
//add the NextGen galleries to custom folders
|
1879 |
+
$ngGalleries = ShortPixelNextGenAdapter::getGalleries();
|
1880 |
+
foreach($ngGalleries as $gallery) {
|
1881 |
+
$folderMsg = $this->spMetaDao->newFolderFromPath($gallery, get_home_path(), self::getCustomFolderBase());
|
1882 |
+
$this->_settings->hasCustomFolders = true;
|
1883 |
+
}
|
1884 |
+
$customFolders = $this->spMetaDao->getFolders();
|
1885 |
+
}
|
1886 |
+
return array("message" => $silent? "" : $folderMsg, "customFolders" => $customFolders);
|
1887 |
+
}
|
1888 |
+
|
1889 |
+
public function getAverageCompression(){
|
1890 |
+
return $this->_settings->totalOptimized > 0
|
1891 |
+
? round(( 1 - ( $this->_settings->totalOptimized / $this->_settings->totalOriginal ) ) * 100, 2)
|
1892 |
+
: 0;
|
1893 |
+
}
|
1894 |
+
|
1895 |
+
/**
|
1896 |
+
*
|
1897 |
+
* @param type $apiKey
|
1898 |
+
* @param type $appendUserAgent
|
1899 |
+
* @param type $validate - true if we are validating the api key, send also the domain name and number of pics
|
1900 |
+
* @return type
|
1901 |
+
*/
|
1902 |
+
public function getQuotaInformation($apiKey = null, $appendUserAgent = false, $validate = false) {
|
1903 |
+
|
1904 |
+
if(is_null($apiKey)) { $apiKey = $this->_settings->apiKey; }
|
1905 |
+
|
1906 |
+
if($this->_settings->httpProto != 'https' && $this->_settings->httpProto != 'http') {
|
1907 |
+
$this->_settings->httpProto = 'https';
|
1908 |
+
}
|
1909 |
+
|
1910 |
+
$requestURL = $this->_settings->httpProto . '://api.shortpixel.com/v2/api-status.php';
|
1911 |
+
$args = array(
|
1912 |
+
'timeout'=> SP_VALIDATE_MAX_TIMEOUT,
|
1913 |
+
'body' => array('key' => $apiKey)
|
1914 |
+
);
|
1915 |
+
$argsStr = "?key=".$apiKey;
|
1916 |
+
|
1917 |
+
if($appendUserAgent) {
|
1918 |
+
$args['body']['useragent'] = "Agent" . urlencode($_SERVER['HTTP_USER_AGENT']);
|
1919 |
+
$argsStr .= "&useragent=Agent".$args['body']['useragent'];
|
1920 |
+
}
|
1921 |
+
if($validate) {
|
1922 |
+
$args['body']['DomainCheck'] = get_site_url();
|
1923 |
+
$args['body']['Info'] = get_bloginfo('version') . '|' . phpversion();
|
1924 |
+
$imageCount = WpShortPixelMediaLbraryAdapter::countAllProcessableFiles($this->_settings->optimizePdfs);
|
1925 |
+
$args['body']['ImagesCount'] = $imageCount['mainFiles'];
|
1926 |
+
$args['body']['ThumbsCount'] = $imageCount['totalFiles'] - $imageCount['mainFiles'];
|
1927 |
+
$argsStr .= "&DomainCheck={$args['body']['DomainCheck']}&Info={$args['body']['Info']}&ImagesCount={$imageCount['mainFiles']}&ThumbsCount={$args['body']['ThumbsCount']}";
|
1928 |
+
}
|
1929 |
+
if(strlen($this->_settings->siteAuthUser)) {
|
1930 |
+
$args['body']['url'] = parse_url(get_site_url(),PHP_URL_HOST);
|
1931 |
+
$args['body']['user'] = $this->_settings->siteAuthUser;
|
1932 |
+
$args['body']['pass'] = urlencode($this->_settings->siteAuthPass);
|
1933 |
+
$argsStr .= "&url={$args['body']['url']}&user={$args['body']['user']}&pass={$args['body']['pass']}";
|
1934 |
+
}
|
1935 |
+
|
1936 |
+
$comm = array();
|
1937 |
+
|
1938 |
+
//Try first HTTPS post. add the sslverify = false if https
|
1939 |
+
if($this->_settings->httpProto === 'https') {
|
1940 |
+
$args['sslverify'] = false;
|
1941 |
+
}
|
1942 |
+
$response = wp_remote_post($requestURL, $args);
|
1943 |
+
$comm[] = array("sent" => "POST: " . $requestURL, "args" => $args, "received" => $response);
|
1944 |
+
|
1945 |
+
//some hosting providers won't allow https:// POST connections so we try http:// as well
|
1946 |
+
if(is_wp_error( $response )) {
|
1947 |
+
//echo("protocol " . $this->_settings->httpProto . " failed. switching...");
|
1948 |
+
$requestURL = $this->_settings->httpProto == 'https' ?
|
1949 |
+
str_replace('https://', 'http://', $requestURL) :
|
1950 |
+
str_replace('http://', 'https://', $requestURL);
|
1951 |
+
// add or remove the sslverify
|
1952 |
+
if($this->_settings->httpProto === 'http') {
|
1953 |
+
$args['sslverify'] = false;
|
1954 |
+
} else {
|
1955 |
+
unset($args['sslverify']);
|
1956 |
+
}
|
1957 |
+
$response = wp_remote_post($requestURL, $args);
|
1958 |
+
$comm[] = array("sent" => "POST: " . $requestURL, "args" => $args, "received" => $response);
|
1959 |
+
|
1960 |
+
if(!is_wp_error( $response )){
|
1961 |
+
$this->_settings->httpProto = ($this->_settings->httpProto == 'https' ? 'http' : 'https');
|
1962 |
+
//echo("protocol " . $this->_settings->httpProto . " succeeded");
|
1963 |
+
} else {
|
1964 |
+
//echo("protocol " . $this->_settings->httpProto . " failed too");
|
1965 |
+
}
|
1966 |
+
}
|
1967 |
+
//Second fallback to HTTP get
|
1968 |
+
if(is_wp_error( $response )){
|
1969 |
+
$args['body'] = null;
|
1970 |
+
$requestURL .= $argsStr;
|
1971 |
+
$response = wp_remote_get($requestURL, $args);
|
1972 |
+
$comm[] = array("sent" => "POST: " . $requestURL, "args" => $args, "received" => $response);
|
1973 |
+
}
|
1974 |
+
|
1975 |
+
$defaultData = array(
|
1976 |
+
"APIKeyValid" => false,
|
1977 |
+
"Message" => __('API Key could not be validated due to a connectivity error.<BR>Your firewall may be blocking us. Please contact your hosting provider and ask them to allow connections from your site to IP 176.9.106.46.<BR> If you still cannot validate your API Key after this, please <a href="https://shortpixel.com/contact" target="_blank">contact us</a> and we will try to help. ','shortpixel-image-optimiser'),
|
1978 |
+
"APICallsMade" => __('Information unavailable. Please check your API key.','shortpixel-image-optimiser'),
|
1979 |
+
"APICallsQuota" => __('Information unavailable. Please check your API key.','shortpixel-image-optimiser'),
|
1980 |
+
"DomainCheck" => 'NOT Accessible');
|
1981 |
+
|
1982 |
+
if(is_object($response) && get_class($response) == 'WP_Error') {
|
1983 |
+
|
1984 |
+
$urlElements = parse_url($requestURL);
|
1985 |
+
$portConnect = @fsockopen($urlElements['host'],8,$errno,$errstr,15);
|
1986 |
+
if(!$portConnect) {
|
1987 |
+
$defaultData['Message'] .= "<BR>Debug info: <i>$errstr</i>";
|
1988 |
+
}
|
1989 |
+
return $defaultData;
|
1990 |
+
}
|
1991 |
+
|
1992 |
+
if($response['response']['code'] != 200) {
|
1993 |
+
//$defaultData['Message'] .= "<BR><i>Debug info: response code {$response['response']['code']} URL $requestURL , Response ".json_encode($response)."</i>";
|
1994 |
+
return $defaultData;
|
1995 |
+
}
|
1996 |
+
|
1997 |
+
$data = $response['body'];
|
1998 |
+
$data = ShortPixelTools::parseJSON($data);
|
1999 |
+
|
2000 |
+
if(empty($data)) { return $defaultData; }
|
2001 |
+
|
2002 |
+
if($data->Status->Code != 2) {
|
2003 |
+
$defaultData['Message'] = $data->Status->Message;
|
2004 |
+
return $defaultData;
|
2005 |
+
}
|
2006 |
+
|
2007 |
+
if ( ( $data->APICallsMade + $data->APICallsMadeOneTime ) < ( $data->APICallsQuota + $data->APICallsQuotaOneTime ) ) //reset quota exceeded flag -> user is allowed to process more images.
|
2008 |
+
$this->resetQuotaExceeded();
|
2009 |
+
else
|
2010 |
+
$this->_settings->quotaExceeded = 1;//activate quota limiting
|
2011 |
+
|
2012 |
+
//if a non-valid status exists, delete it
|
2013 |
+
$lastStatus = $this->_settings->bulkLastStatus = null;
|
2014 |
+
if($lastStatus && $lastStatus['Status'] == ShortPixelAPI::STATUS_NO_KEY) {
|
2015 |
+
$this->_settings->bulkLastStatus = null;
|
2016 |
+
}
|
2017 |
+
|
2018 |
+
return array(
|
2019 |
+
"APIKeyValid" => true,
|
2020 |
+
"APICallsMade" => number_format($data->APICallsMade) . __(' images','shortpixel-image-optimiser'),
|
2021 |
+
"APICallsQuota" => number_format($data->APICallsQuota) . __(' images','shortpixel-image-optimiser'),
|
2022 |
+
"APICallsMadeOneTime" => number_format($data->APICallsMadeOneTime) . __(' images','shortpixel-image-optimiser'),
|
2023 |
+
"APICallsQuotaOneTime" => number_format($data->APICallsQuotaOneTime) . __(' images','shortpixel-image-optimiser'),
|
2024 |
+
"APICallsMadeNumeric" => $data->APICallsMade,
|
2025 |
+
"APICallsQuotaNumeric" => $data->APICallsQuota,
|
2026 |
+
"APICallsMadeOneTimeNumeric" => $data->APICallsMadeOneTime,
|
2027 |
+
"APICallsQuotaOneTimeNumeric" => $data->APICallsQuotaOneTime,
|
2028 |
+
"APICallsRemaining" => $data->APICallsQuota + $data->APICallsQuotaOneTime - $data->APICallsMade - $data->APICallsMadeOneTime,
|
2029 |
+
"APILastRenewalDate" => $data->DateSubscription,
|
2030 |
+
"DomainCheck" => (isset($data->DomainCheck) ? $data->DomainCheck : null)
|
2031 |
+
);
|
2032 |
+
}
|
2033 |
+
|
2034 |
+
public function resetQuotaExceeded() {
|
2035 |
+
if( $this->_settings->quotaExceeded == 1) {
|
2036 |
+
$dismissed = $this->_settings->dismissedNotices ? $this->_settings->dismissedNotices : array();
|
2037 |
+
unset($dismissed['exceed']);
|
2038 |
+
$this->_settings->dismissedNotices = $dismissed;
|
2039 |
+
}
|
2040 |
+
$this->_settings->quotaExceeded = 0;
|
2041 |
+
}
|
2042 |
+
|
2043 |
+
public function generateCustomColumn( $column_name, $id, $extended = false ) {
|
2044 |
+
if( 'wp-shortPixel' == $column_name ) {
|
2045 |
+
|
2046 |
+
$file = get_attached_file($id);
|
2047 |
+
if(!self::isProcessablePath($file)) {
|
2048 |
+
$renderData['status'] = 'n/a';
|
2049 |
+
$this->view->renderCustomColumn($id, $renderData, $extended);
|
2050 |
+
return;
|
2051 |
+
}
|
2052 |
+
|
2053 |
+
$data = wp_get_attachment_metadata($id);
|
2054 |
+
$fileExtension = strtolower(pathinfo($file, PATHINFO_EXTENSION));
|
2055 |
+
$invalidKey = !$this->_settings->verifiedKey;
|
2056 |
+
$quotaExceeded = $this->_settings->quotaExceeded;
|
2057 |
+
$renderData = array("id" => $id, "showActions" => (current_user_can( 'manage_options' ) || current_user_can( 'upload_files' ) || current_user_can( 'edit_posts' )));
|
2058 |
+
|
2059 |
+
if($invalidKey) { //invalid key - let the user first register and only then
|
2060 |
+
$renderData['status'] = 'invalidKey';
|
2061 |
+
$this->view->renderCustomColumn($id, $renderData, $extended);
|
2062 |
+
return;
|
2063 |
+
}
|
2064 |
+
|
2065 |
+
//empty data means document, we handle only PDF
|
2066 |
+
elseif (empty($data)) { //TODO asta devine if si decomentam returnurile
|
2067 |
+
if($fileExtension == "pdf") {
|
2068 |
+
$renderData['status'] = $quotaExceeded ? 'quotaExceeded' : 'optimizeNow';
|
2069 |
+
$renderData['message'] = __('PDF not processed.','shortpixel-image-optimiser');
|
2070 |
+
}
|
2071 |
+
else { //Optimization N/A
|
2072 |
+
$renderData['status'] = 'n/a';
|
2073 |
+
}
|
2074 |
+
$this->view->renderCustomColumn($id, $renderData, $extended);
|
2075 |
+
return;
|
2076 |
+
}
|
2077 |
+
|
2078 |
+
if(!isset($data['ShortPixelImprovement'])) { //new image
|
2079 |
+
$data['ShortPixelImprovement'] = '';
|
2080 |
+
}
|
2081 |
+
|
2082 |
+
if(is_numeric($data['ShortPixelImprovement'])) { //already optimized
|
2083 |
+
$sizesCount = isset($data['sizes']) ? WpShortPixelMediaLbraryAdapter::countNonWebpSizes($data['sizes']) : 0;
|
2084 |
+
|
2085 |
+
$renderData['status'] = $fileExtension == "pdf" ? 'pdfOptimized' : 'imgOptimized';
|
2086 |
+
$renderData['percent'] = $data['ShortPixelImprovement'];
|
2087 |
+
$renderData['bonus'] = ($data['ShortPixelImprovement'] < 5);
|
2088 |
+
$renderData['backup'] = $this->getBackupFolderAny(get_attached_file($id), $sizesCount? $data['sizes'] : array());
|
2089 |
+
$renderData['type'] = isset($data['ShortPixel']['type']) ? $data['ShortPixel']['type'] : '';
|
2090 |
+
$renderData['thumbsTotal'] = $sizesCount;
|
2091 |
+
$renderData['thumbsOpt'] = isset($data['ShortPixel']['thumbsOpt']) ? $data['ShortPixel']['thumbsOpt'] : $sizesCount;
|
2092 |
+
$renderData['thumbsMissing'] = isset($data['ShortPixel']['thumbsMissing']) ? $data['ShortPixel']['thumbsMissing'] : array();
|
2093 |
+
$renderData['retinasOpt'] = isset($data['ShortPixel']['retinasOpt']) ? $data['ShortPixel']['retinasOpt'] : null;
|
2094 |
+
$renderData['exifKept'] = isset($data['ShortPixel']['exifKept']) ? $data['ShortPixel']['exifKept'] : null;
|
2095 |
+
$renderData['date'] = isset($data['ShortPixel']['date']) ? $data['ShortPixel']['date'] : null;
|
2096 |
+
$renderData['quotaExceeded'] = $quotaExceeded;
|
2097 |
+
$webP = 0;
|
2098 |
+
if($extended) {
|
2099 |
+
if(file_exists(dirname($file) . '/' . ShortPixelAPI::MB_basename($file, '.'.$fileExtension) . '.webp' )){
|
2100 |
+
$webP++;
|
2101 |
+
}
|
2102 |
+
if(isset($data['sizes'])) {
|
2103 |
+
foreach($data['sizes'] as $key => $size) {
|
2104 |
+
if (strpos($key, ShortPixelMeta::WEBP_THUMB_PREFIX) === 0) continue;
|
2105 |
+
$sizeName = $size['file'];
|
2106 |
+
if(file_exists(dirname($file) . '/' . ShortPixelAPI::MB_basename($sizeName, '.'.$fileExtension) . '.webp' )){
|
2107 |
+
$webP++;
|
2108 |
+
}
|
2109 |
+
}
|
2110 |
+
}
|
2111 |
+
}
|
2112 |
+
$renderData['webpCount'] = $webP;
|
2113 |
+
}
|
2114 |
+
elseif($data['ShortPixelImprovement'] == __('Optimization N/A','shortpixel-image-optimiser')) { //We don't optimize this
|
2115 |
+
$renderData['status'] = 'n/a';
|
2116 |
+
}
|
2117 |
+
elseif(isset($meta['ShortPixel']['BulkProcessing'])) { //Scheduled to bulk.
|
2118 |
+
$renderData['status'] = $quotaExceeded ? 'quotaExceeded' : 'optimizeNow';
|
2119 |
+
$renderData['message'] = 'Waiting for bulk processing.';
|
2120 |
+
}
|
2121 |
+
elseif( trim(strip_tags($data['ShortPixelImprovement'])) == __("Cannot write optimized file",'shortpixel-image-optimiser') ) {
|
2122 |
+
$renderData['status'] = $quotaExceeded ? 'quotaExceeded' : 'retry';
|
2123 |
+
$renderData['message'] = __("Cannot write optimized file",'shortpixel-image-optimiser') . " - <a href='https://shortpixel.com/faq#cannot-write-optimized-file' target='_blank'>"
|
2124 |
+
. __("Why?",'shortpixel-image-optimiser') . "</a>";
|
2125 |
+
}
|
2126 |
+
elseif( strlen(trim(strip_tags($data['ShortPixelImprovement']))) > 0 ) {
|
2127 |
+
$renderData['status'] = $quotaExceeded ? 'quotaExceeded' : 'retry';
|
2128 |
+
$renderData['message'] = $data['ShortPixelImprovement'];
|
2129 |
+
if(strpos($renderData['message'], __('The file(s) do not exist on disk: ','shortpixel-image-optimiser')) !== false) {
|
2130 |
+
$renderData['cleanup'] = true;
|
2131 |
+
}
|
2132 |
+
}
|
2133 |
+
elseif(isset($data['ShortPixel']['NoFileOnDisk'])) {
|
2134 |
+
$renderData['status'] = 'notFound';
|
2135 |
+
$renderData['message'] = __('Image does not exist','shortpixel-image-optimiser');
|
2136 |
+
}
|
2137 |
+
elseif(isset($data['ShortPixel']['WaitingProcessing'])) {
|
2138 |
+
$renderData['status'] = $quotaExceeded ? 'quotaExceeded' : 'retry';
|
2139 |
+
$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');
|
2140 |
+
if($id > $this->prioQ->getFlagBulkId() || !$this->prioQ->bulkRunning()) $this->prioQ->push($id); //should be there but just to make sure
|
2141 |
+
}
|
2142 |
+
else { //finally
|
2143 |
+
$renderData['status'] = $quotaExceeded ? 'quotaExceeded' : 'optimizeNow';
|
2144 |
+
$sizes = isset($data['sizes']) ? WpShortPixelMediaLbraryAdapter::countNonWebpSizes($data['sizes']) : 0;
|
2145 |
+
$renderData['thumbsTotal'] = $sizes;
|
2146 |
+
$renderData['message'] = ($fileExtension == "pdf" ? 'PDF' : 'Image') . ' not processed.';
|
2147 |
+
}
|
2148 |
+
|
2149 |
+
$this->view->renderCustomColumn($id, $renderData, $extended);
|
2150 |
+
}
|
2151 |
+
}
|
2152 |
+
|
2153 |
+
function shortpixelInfoBox() {
|
2154 |
+
if(get_post_type( ) == 'attachment') {
|
2155 |
+
add_meta_box(
|
2156 |
+
'shortpixel_info_box', // this is HTML id of the box on edit screen
|
2157 |
+
__('ShortPixel Info', 'shortpixel-image-optimiser'), // title of the box
|
2158 |
+
array( &$this, 'shortpixelInfoBoxContent'), // function to be called to display the info
|
2159 |
+
null,//, // on which edit screen the box should appear
|
2160 |
+
'side'//'normal', // part of page where the box should appear
|
2161 |
+
//'default' // priority of the box
|
2162 |
+
);
|
2163 |
+
}
|
2164 |
+
}
|
2165 |
+
|
2166 |
+
function shortpixelInfoBoxContent( $post ) {
|
2167 |
+
$this->generateCustomColumn( 'wp-shortPixel', $post->ID, true );
|
2168 |
+
}
|
2169 |
+
|
2170 |
+
function onDeleteImage($post_id) {
|
2171 |
+
$itemHandler = new ShortPixelMetaFacade($post_id);
|
2172 |
+
$urlsPaths = $itemHandler->getURLsAndPATHs(true, false, false);
|
2173 |
+
foreach($urlsPaths['PATHs'] as $path) {
|
2174 |
+
$pos = strrpos($path, ".");
|
2175 |
+
if ($pos !== false) {
|
2176 |
+
//$webpPath = substr($path, 0, $pos) . ".webp";
|
2177 |
+
//echo($webpPath . "<br>");
|
2178 |
+
@unlink(substr($path, 0, $pos) . ".webp");
|
2179 |
+
@unlink(substr($path, 0, $pos) . "@2x.webp");
|
2180 |
+
}
|
2181 |
+
}
|
2182 |
+
}
|
2183 |
+
|
2184 |
+
public function columns( $defaults ) {
|
2185 |
+
$defaults['wp-shortPixel'] = 'ShortPixel Compression';
|
2186 |
+
if(current_user_can( 'manage_options' )) {
|
2187 |
+
$defaults['wp-shortPixel'] .= ' <a href="options-general.php?page=wp-shortpixel#stats" title="'
|
2188 |
+
. __('ShortPixel Statistics','shortpixel-image-optimiser') . '"><span class="dashicons dashicons-dashboard"></span></a>';
|
2189 |
+
}
|
2190 |
+
return $defaults;
|
2191 |
+
}
|
2192 |
+
|
2193 |
+
public function nggColumns( $defaults ) {
|
2194 |
+
$this->nggColumnIndex = count($defaults) + 1;
|
2195 |
+
add_filter( 'ngg_manage_images_column_' . $this->nggColumnIndex . '_header', array( &$this, 'nggColumnHeader' ) );
|
2196 |
+
add_filter( 'ngg_manage_images_column_' . $this->nggColumnIndex . '_content', array( &$this, 'nggColumnContent' ), 10, 2 );
|
2197 |
+
$defaults['wp-shortPixelNgg'] = 'ShortPixel Compression';
|
2198 |
+
return $defaults;
|
2199 |
+
}
|
2200 |
+
|
2201 |
+
public function nggCountColumns( $count ) {
|
2202 |
+
return $count + 1;
|
2203 |
+
}
|
2204 |
+
|
2205 |
+
public function nggColumnHeader( $default ) {
|
2206 |
+
return __('ShortPixel Compression','shortpixel-image-optimiser');
|
2207 |
+
}
|
2208 |
+
|
2209 |
+
public function nggColumnContent( $unknown, $picture ) {
|
2210 |
+
|
2211 |
+
$meta = $this->spMetaDao->getMetaForPath($picture->imagePath);
|
2212 |
+
if($meta) {
|
2213 |
+
switch($meta->getStatus()) {
|
2214 |
+
case "0": echo("<div id='sp-msg-C-{$meta->getId()}' class='column-wp-shortPixel' style='color: #928B1E'>Waiting</div>"); break;
|
2215 |
+
case "1": echo("<div id='sp-msg-C-{$meta->getId()}' class='column-wp-shortPixel' style='color: #1919E2'>Pending</div>"); break;
|
2216 |
+
case "2": $this->view->renderCustomColumn("C-" . $meta->getId(), array(
|
2217 |
+
'showActions' => false && current_user_can( 'manage_options' ),
|
2218 |
+
'status' => 'imgOptimized',
|
2219 |
+
'type' => ShortPixelAPI::getCompressionTypeName($meta->getCompressionType()),
|
2220 |
+
'percent' => $meta->getImprovementPercent(),
|
2221 |
+
'bonus' => $meta->getImprovementPercent() < 5,
|
2222 |
+
'thumbsOpt' => 0,
|
2223 |
+
'thumbsTotal' => 0,
|
2224 |
+
'retinasOpt' => 0,
|
2225 |
+
'backup' => true
|
2226 |
+
));
|
2227 |
+
break;
|
2228 |
+
}
|
2229 |
+
} else {
|
2230 |
+
$this->view->renderCustomColumn($meta ? "C-" . $meta->getId() : "N-" . $picture->pid, array(
|
2231 |
+
'showActions' => false && current_user_can( 'manage_options' ),
|
2232 |
+
'status' => 'optimizeNow',
|
2233 |
+
'thumbsOpt' => 0,
|
2234 |
+
'thumbsTotal' => 0,
|
2235 |
+
'retinasOpt' => 0,
|
2236 |
+
'message' => "Not optimized"
|
2237 |
+
));
|
2238 |
+
}
|
2239 |
+
// return var_dump($meta);
|
2240 |
+
}
|
2241 |
+
|
2242 |
+
public function generatePluginLinks($links) {
|
2243 |
+
$in = '<a href="options-general.php?page=wp-shortpixel">Settings</a>';
|
2244 |
+
array_unshift($links, $in);
|
2245 |
+
return $links;
|
2246 |
+
}
|
2247 |
+
|
2248 |
+
static public function formatBytes($bytes, $precision = 2) {
|
2249 |
+
$units = array('B', 'KB', 'MB', 'GB', 'TB');
|
2250 |
+
|
2251 |
+
$bytes = max($bytes, 0);
|
2252 |
+
$pow = floor(($bytes ? log($bytes) : 0) / log(1024));
|
2253 |
+
$pow = min($pow, count($units) - 1);
|
2254 |
+
|
2255 |
+
$bytes /= pow(1024, $pow);
|
2256 |
+
|
2257 |
+
return round($bytes, $precision) . ' ' . $units[$pow];
|
2258 |
+
}
|
2259 |
+
|
2260 |
+
static public function isProcessable($ID, $exclude = array()) {
|
2261 |
+
$path = get_attached_file($ID);//get the full file PATH
|
2262 |
+
return $path ? self::isProcessablePath($path, $exclude) : false;
|
2263 |
+
}
|
2264 |
+
|
2265 |
+
static public function isProcessablePath($path, $exclude = array()) {
|
2266 |
+
$pathParts = pathinfo($path);
|
2267 |
+
$ext = $pathParts['extension'];
|
2268 |
+
if( isset($ext) && in_array(strtolower($ext), array_diff(self::$PROCESSABLE_EXTENSIONS, $exclude))) {
|
2269 |
+
return true;
|
2270 |
+
} else {
|
2271 |
+
return false;
|
2272 |
+
}
|
2273 |
+
}
|
2274 |
+
|
2275 |
+
|
2276 |
+
//return an array with URL(s) and PATH(s) for this file
|
2277 |
+
public function getURLsAndPATHs($itemHandler, $meta = NULL, $onlyThumbs = false) {
|
2278 |
+
return $itemHandler->getURLsAndPATHs($this->_settings->processThumbnails, $onlyThumbs, $this->_settings->optimizeRetina);
|
2279 |
+
}
|
2280 |
+
|
2281 |
+
|
2282 |
+
public static function deleteDir($dirPath) {
|
2283 |
+
if (substr($dirPath, strlen($dirPath) - 1, 1) != '/') {
|
2284 |
+
$dirPath .= '/';
|
2285 |
+
}
|
2286 |
+
$files = glob($dirPath . '*', GLOB_MARK);
|
2287 |
+
foreach ($files as $file) {
|
2288 |
+
if (is_dir($file)) {
|
2289 |
+
self::deleteDir($file);
|
2290 |
+
@rmdir($file);//remove empty dir
|
2291 |
+
} else {
|
2292 |
+
@unlink($file);//remove file
|
2293 |
+
}
|
2294 |
+
}
|
2295 |
+
}
|
2296 |
+
|
2297 |
+
static public function folderSize($path) {
|
2298 |
+
$total_size = 0;
|
2299 |
+
if(file_exists($path)) {
|
2300 |
+
$files = scandir($path);
|
2301 |
+
} else {
|
2302 |
+
return $total_size;
|
2303 |
+
}
|
2304 |
+
$cleanPath = rtrim($path, '/'). '/';
|
2305 |
+
foreach($files as $t) {
|
2306 |
+
if ($t<>"." && $t<>"..")
|
2307 |
+
{
|
2308 |
+
$currentFile = $cleanPath . $t;
|
2309 |
+
if (is_dir($currentFile)) {
|
2310 |
+
$size = self::folderSize($currentFile);
|
2311 |
+
$total_size += $size;
|
2312 |
+
}
|
2313 |
+
else {
|
2314 |
+
$size = filesize($currentFile);
|
2315 |
+
$total_size += $size;
|
2316 |
+
}
|
2317 |
+
}
|
2318 |
+
}
|
2319 |
+
return $total_size;
|
2320 |
+
}
|
2321 |
+
|
2322 |
+
public function migrateBackupFolder() {
|
2323 |
+
$oldBackupFolder = WP_CONTENT_DIR . '/' . SP_BACKUP;
|
2324 |
+
|
2325 |
+
if(file_exists($oldBackupFolder)) { //if old backup folder does not exist then there is nothing to do
|
2326 |
+
|
2327 |
+
if(!file_exists(SP_BACKUP_FOLDER)) {
|
2328 |
+
//we check that the backup folder exists, if not we create it so we can copy into it
|
2329 |
+
if(!mkdir(SP_BACKUP_FOLDER, 0777, true)) return;
|
2330 |
+
}
|
2331 |
+
|
2332 |
+
$scannedDirectory = array_diff(scandir($oldBackupFolder), array('..', '.'));
|
2333 |
+
foreach($scannedDirectory as $file) {
|
2334 |
+
@rename($oldBackupFolder.'/'.$file, SP_BACKUP_FOLDER.'/'.$file);
|
2335 |
+
}
|
2336 |
+
$scannedDirectory = array_diff(scandir($oldBackupFolder), array('..', '.'));
|
2337 |
+
if(empty($scannedDirectory)) {
|
2338 |
+
@rmdir($oldBackupFolder);
|
2339 |
+
}
|
2340 |
+
}
|
2341 |
+
//now if the backup folder does not contain the uploads level, create it
|
2342 |
+
if( !is_dir(SP_BACKUP_FOLDER . '/' . SP_UPLOADS_NAME )
|
2343 |
+
&& !is_dir(SP_BACKUP_FOLDER . '/' . basename(WP_CONTENT_DIR))) {
|
2344 |
+
@rename(SP_BACKUP_FOLDER, SP_BACKUP_FOLDER."_tmp");
|
2345 |
+
@mkdir(SP_BACKUP_FOLDER);
|
2346 |
+
@rename(SP_BACKUP_FOLDER."_tmp", SP_BACKUP_FOLDER.'/'.SP_UPLOADS_NAME);
|
2347 |
+
if(!file_exists(SP_BACKUP_FOLDER)) {//just in case..
|
2348 |
+
@rename(SP_BACKUP_FOLDER."_tmp", SP_BACKUP_FOLDER);
|
2349 |
+
}
|
2350 |
+
}
|
2351 |
+
//then create the wp-content level if not present
|
2352 |
+
if(!is_dir(SP_BACKUP_FOLDER . '/' . basename(WP_CONTENT_DIR))) {
|
2353 |
+
@rename(SP_BACKUP_FOLDER, SP_BACKUP_FOLDER."_tmp");
|
2354 |
+
@mkdir(SP_BACKUP_FOLDER);
|
2355 |
+
@rename(SP_BACKUP_FOLDER."_tmp", SP_BACKUP_FOLDER.'/' . basename(WP_CONTENT_DIR));
|
2356 |
+
if(!file_exists(SP_BACKUP_FOLDER)) {//just in case..
|
2357 |
+
@rename(SP_BACKUP_FOLDER."_tmp", SP_BACKUP_FOLDER);
|
2358 |
+
}
|
2359 |
+
}
|
2360 |
+
return;
|
2361 |
+
}
|
2362 |
+
|
2363 |
+
function getMaxIntermediateImageSize() {
|
2364 |
+
global $_wp_additional_image_sizes;
|
2365 |
+
|
2366 |
+
$width = 0;
|
2367 |
+
$height = 0;
|
2368 |
+
$get_intermediate_image_sizes = get_intermediate_image_sizes();
|
2369 |
+
|
2370 |
+
// Create the full array with sizes and crop info
|
2371 |
+
foreach( $get_intermediate_image_sizes as $_size ) {
|
2372 |
+
if ( in_array( $_size, array( 'thumbnail', 'medium', 'large' ) ) ) {
|
2373 |
+
$width = max($width, get_option( $_size . '_size_w' ));
|
2374 |
+
$height = max($height, get_option( $_size . '_size_h' ));
|
2375 |
+
//$sizes[ $_size ]['crop'] = (bool) get_option( $_size . '_crop' );
|
2376 |
+
} elseif ( isset( $_wp_additional_image_sizes[ $_size ] ) ) {
|
2377 |
+
$width = max($width, $_wp_additional_image_sizes[ $_size ]['width']);
|
2378 |
+
$height = max($height, $_wp_additional_image_sizes[ $_size ]['height']);
|
2379 |
+
//'crop' => $_wp_additional_image_sizes[ $_size ]['crop']
|
2380 |
+
}
|
2381 |
+
}
|
2382 |
+
return array('width' => $width, 'height' => $height);
|
2383 |
+
}
|
2384 |
+
|
2385 |
+
/* public function getEncryptedData() {
|
2386 |
+
return base64_encode(self::encrypt($this->getApiKey() . "|" . get_site_url(), "sh0r+Pix3l8im1N3r"));
|
2387 |
+
}
|
2388 |
+
*/
|
2389 |
+
|
2390 |
+
/**
|
2391 |
+
* Returns an encrypted & utf8-encoded
|
2392 |
+
*/
|
2393 |
+
/* public static function encrypt($pure_string, $encryption_key)
|
2394 |
+
{
|
2395 |
+
if(!function_exists("mcrypt_get_iv_size") || !function_exists('utf8_encode')) {
|
2396 |
+
return "";
|
2397 |
+
}
|
2398 |
+
$iv_size = \mcrypt_get_iv_size(MCRYPT_BLOWFISH, MCRYPT_MODE_ECB);
|
2399 |
+
$iv = \mcrypt_create_iv($iv_size, MCRYPT_RAND);
|
2400 |
+
$encrypted_string = \mcrypt_encrypt(MCRYPT_BLOWFISH, $encryption_key, utf8_encode($pure_string), MCRYPT_MODE_ECB, $iv);
|
2401 |
+
return $encrypted_string;
|
2402 |
+
}
|
2403 |
+
*/
|
2404 |
+
|
2405 |
+
public function getApiKey() {
|
2406 |
+
return $this->_settings->apiKey;
|
2407 |
+
}
|
2408 |
+
|
2409 |
+
public function getPrioQ() {
|
2410 |
+
return $this->prioQ;
|
2411 |
+
}
|
2412 |
+
|
2413 |
+
public function backupImages() {
|
2414 |
+
return $this->_settings->backupImages;
|
2415 |
+
}
|
2416 |
+
|
2417 |
+
public function processThumbnails() {
|
2418 |
+
return $this->_settings->processThumbnails;
|
2419 |
+
}
|
2420 |
+
|
2421 |
+
public function getCMYKtoRGBconversion() {
|
2422 |
+
return $this->_settings->CMYKtoRGBconversion;
|
2423 |
+
}
|
2424 |
+
|
2425 |
+
public function getSettings() {
|
2426 |
+
return $this->_settings;
|
2427 |
+
}
|
2428 |
+
|
2429 |
+
public function getResizeImages() {
|
2430 |
+
return $this->_settings->resizeImages;
|
2431 |
+
}
|
2432 |
+
|
2433 |
+
public function getResizeWidth() {
|
2434 |
+
return $this->_settings->resizeWidth;
|
2435 |
+
}
|
2436 |
+
|
2437 |
+
public function getResizeHeight() {
|
2438 |
+
return $this->_settings->resizeHeight;
|
2439 |
+
}
|
2440 |
+
public function getAffiliateSufix() {
|
2441 |
+
return $this->_affiliateSufix;
|
2442 |
+
}
|
2443 |
+
public function getVerifiedKey() {
|
2444 |
+
return $this->_settings->verifiedKey;
|
2445 |
+
}
|
2446 |
+
public function getCompressionType() {
|
2447 |
+
return $this->_settings->compressionType;
|
2448 |
+
}
|
2449 |
+
public function hasNextGen() {
|
2450 |
+
return $this->hasNextGen;
|
2451 |
+
}
|
2452 |
+
|
2453 |
+
public function getSpMetaDao() {
|
2454 |
+
return $this->spMetaDao;
|
2455 |
+
}
|
2456 |
+
|
2457 |
+
}
|
readme.txt
CHANGED
@@ -5,7 +5,7 @@ Tags: image optimizer, image optimization, compress pdf, compress jpeg, compress
|
|
5 |
|
6 |
Requires at least: 3.2.0
|
7 |
Tested up to: 4.7
|
8 |
-
Stable tag: 4.2.
|
9 |
License: GPLv2 or later
|
10 |
License URI: http://www.gnu.org/licenses/gpl-2.0.html
|
11 |
|
@@ -217,6 +217,11 @@ The ShortPixel team is here to help. <a href="https://shortpixel.com/contact">Co
|
|
217 |
|
218 |
== Changelog ==
|
219 |
|
|
|
|
|
|
|
|
|
|
|
220 |
= 4.2.7 =
|
221 |
|
222 |
* fix bug when quota expires
|
5 |
|
6 |
Requires at least: 3.2.0
|
7 |
Tested up to: 4.7
|
8 |
+
Stable tag: 4.2.8
|
9 |
License: GPLv2 or later
|
10 |
License URI: http://www.gnu.org/licenses/gpl-2.0.html
|
11 |
|
217 |
|
218 |
== Changelog ==
|
219 |
|
220 |
+
= 4.2.8 =
|
221 |
+
|
222 |
+
* fix bug when searching for thumbanils of files with same prefix
|
223 |
+
* fix bug when several successive images have all files missing
|
224 |
+
|
225 |
= 4.2.7 =
|
226 |
|
227 |
* fix bug when quota expires
|
shortpixel_api.php
CHANGED
@@ -43,6 +43,11 @@ class ShortPixelAPI {
|
|
43 |
* @return response from wp_remote_post or error
|
44 |
*/
|
45 |
public function doRequests($URLs, $Blocking, $itemHandler, $compressionType = false, $refresh = false) {
|
|
|
|
|
|
|
|
|
|
|
46 |
$requestParameters = array(
|
47 |
'plugin_version' => PLUGIN_VERSION,
|
48 |
'key' => $this->_settings->apiKey,
|
43 |
* @return response from wp_remote_post or error
|
44 |
*/
|
45 |
public function doRequests($URLs, $Blocking, $itemHandler, $compressionType = false, $refresh = false) {
|
46 |
+
|
47 |
+
if(!count($URLs)) {
|
48 |
+
throw new Exception(__('Image files are missing.','shortpixel-image-optimiser'));
|
49 |
+
}
|
50 |
+
|
51 |
$requestParameters = array(
|
52 |
'plugin_version' => PLUGIN_VERSION,
|
53 |
'key' => $this->_settings->apiKey,
|
wp-shortpixel-req.php
CHANGED
@@ -5,6 +5,7 @@ if(defined('SHORTPIXEL_DEBUG') && SHORTPIXEL_DEBUG === true) {
|
|
5 |
define('SHORTPIXEL_DEBUG', false);
|
6 |
}
|
7 |
|
|
|
8 |
require_once('class/wp-shortpixel-settings.php');
|
9 |
require_once('shortpixel_api.php');
|
10 |
require_once('class/shortpixel_queue.php');
|
5 |
define('SHORTPIXEL_DEBUG', false);
|
6 |
}
|
7 |
|
8 |
+
require_once('class/wp-short-pixel.php');
|
9 |
require_once('class/wp-shortpixel-settings.php');
|
10 |
require_once('shortpixel_api.php');
|
11 |
require_once('class/shortpixel_queue.php');
|
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.2.
|
7 |
* Author: ShortPixel
|
8 |
* Author URI: https://shortpixel.com
|
9 |
* Text Domain: shortpixel-image-optimiser
|
@@ -14,9 +14,11 @@ define('SP_RESET_ON_ACTIVATE', false); //if true TODO set false
|
|
14 |
|
15 |
//define('SHORTPIXEL_DEBUG', true);
|
16 |
|
|
|
|
|
17 |
define('SP_AFFILIATE_CODE', '');
|
18 |
|
19 |
-
define('PLUGIN_VERSION', "4.2.
|
20 |
define('SP_MAX_TIMEOUT', 10);
|
21 |
define('SP_VALIDATE_MAX_TIMEOUT', 15);
|
22 |
define('SP_BACKUP', 'ShortpixelBackups');
|
@@ -44,2457 +46,6 @@ else
|
|
44 |
define('MAX_EXECUTION_TIME', 2 );
|
45 |
define("SP_MAX_RESULTS_QUERY", 6);
|
46 |
|
47 |
-
class WPShortPixel {
|
48 |
-
|
49 |
-
const BULK_EMPTY_QUEUE = 0;
|
50 |
-
|
51 |
-
private $_affiliateSufix;
|
52 |
-
|
53 |
-
private $_apiInterface = null;
|
54 |
-
private $_settings = null;
|
55 |
-
private $prioQ = null;
|
56 |
-
private $view = null;
|
57 |
-
|
58 |
-
private $hasNextGen = false;
|
59 |
-
private $spMetaDao = null;
|
60 |
-
|
61 |
-
public static $PROCESSABLE_EXTENSIONS = array('jpg', 'jpeg', 'gif', 'png', 'pdf');
|
62 |
-
|
63 |
-
public function __construct() {
|
64 |
-
if (!session_id()) {
|
65 |
-
session_start();
|
66 |
-
}
|
67 |
-
|
68 |
-
require_once('wp-shortpixel-req.php');
|
69 |
-
load_plugin_textdomain('shortpixel-image-optimiser', false, plugin_basename(dirname( __FILE__ )).'/lang');
|
70 |
-
|
71 |
-
$isAdminUser = current_user_can( 'manage_options' );
|
72 |
-
|
73 |
-
$this->_affiliateSufix = (strlen(SP_AFFILIATE_CODE)) ? "/affiliate/" . SP_AFFILIATE_CODE : "";
|
74 |
-
$this->_settings = new WPShortPixelSettings();
|
75 |
-
$this->_apiInterface = new ShortPixelAPI($this->_settings);
|
76 |
-
$this->hasNextGen = ShortPixelNextGenAdapter::hasNextGen();
|
77 |
-
$this->spMetaDao = new ShortPixelCustomMetaDao(new WpShortPixelDb(), $this->_settings->hasCustomFolders);
|
78 |
-
$this->prioQ = new ShortPixelQueue($this, $this->_settings);
|
79 |
-
$this->view = new ShortPixelView($this);
|
80 |
-
|
81 |
-
if(!$this->_settings->optimizePdfs) {
|
82 |
-
self::$PROCESSABLE_EXTENSIONS = array_diff(self::$PROCESSABLE_EXTENSIONS, array('pdf'));
|
83 |
-
}
|
84 |
-
|
85 |
-
define('QUOTA_EXCEEDED', $this->view->getQuotaExceededHTML());
|
86 |
-
|
87 |
-
$this->setDefaultViewModeList();//set default mode as list. only @ first run
|
88 |
-
|
89 |
-
//add hook for image upload processing
|
90 |
-
//add_filter( 'wp_generate_attachment_metadata', array( &$this, 'handleMediaLibraryImageUpload' ), 10, 2 ); // now external
|
91 |
-
add_filter( 'plugin_action_links_' . plugin_basename(__FILE__), array(&$this, 'generatePluginLinks'));//for plugin settings page
|
92 |
-
|
93 |
-
//add_action( 'admin_footer', array(&$this, 'handleImageProcessing'));
|
94 |
-
|
95 |
-
//Media custom column
|
96 |
-
add_filter( 'manage_media_columns', array( &$this, 'columns' ) );//add media library column header
|
97 |
-
add_action( 'manage_media_custom_column', array( &$this, 'generateCustomColumn' ), 10, 2 );//generate the media library column
|
98 |
-
//Edit media meta box
|
99 |
-
add_action( 'add_meta_boxes', array( &$this, 'shortpixelInfoBox') );
|
100 |
-
//for cleaning up the WebP images when an attachment is deleted
|
101 |
-
add_action( 'delete_attachment', array( &$this, 'onDeleteImage') );
|
102 |
-
|
103 |
-
//for NextGen
|
104 |
-
if($this->_settings->hasCustomFolders) {
|
105 |
-
add_filter( 'ngg_manage_images_columns', array( &$this, 'nggColumns' ) );
|
106 |
-
add_filter( 'ngg_manage_images_number_of_columns', array( &$this, 'nggCountColumns' ) );
|
107 |
-
add_filter( 'ngg_manage_images_column_7_header', array( &$this, 'nggColumnHeader' ) );
|
108 |
-
add_filter( 'ngg_manage_images_column_7_content', array( &$this, 'nggColumnContent' ) );
|
109 |
-
// hook on the NextGen gallery list update
|
110 |
-
add_action('ngg_update_addgallery_page', array( &$this, 'addNextGenGalleriesToCustom'));
|
111 |
-
}
|
112 |
-
|
113 |
-
// integration with WP/LR Sync plugin
|
114 |
-
add_action( 'wplr_update_media', array( &$this, 'onWpLrUpdateMedia' ), 10, 2);
|
115 |
-
|
116 |
-
//custom hook
|
117 |
-
add_action( 'shortpixel-optimize-now', array( &$this, 'optimizeNowHook' ), 10, 1);
|
118 |
-
|
119 |
-
if($isAdminUser) {
|
120 |
-
//add settings page
|
121 |
-
add_action( 'admin_menu', array( &$this, 'registerSettingsPage' ) );//display SP in Settings menu
|
122 |
-
add_action( 'admin_menu', array( &$this, 'registerAdminPage' ) );
|
123 |
-
|
124 |
-
add_action('wp_ajax_shortpixel_browse_content', array(&$this, 'browseContent'));
|
125 |
-
add_action('wp_ajax_shortpixel_get_backup_size', array(&$this, 'getBackupSize'));
|
126 |
-
|
127 |
-
add_action( 'delete_attachment', array( &$this, 'handleDeleteAttachmentInBackup' ) );
|
128 |
-
add_action( 'load-upload.php', array( &$this, 'handleCustomBulk'));
|
129 |
-
|
130 |
-
//backup restore
|
131 |
-
add_action('admin_action_shortpixel_restore_backup', array(&$this, 'handleRestoreBackup'));
|
132 |
-
//reoptimize with a different algorithm (losless/lossy)
|
133 |
-
add_action('wp_ajax_shortpixel_redo', array(&$this, 'handleRedo'));
|
134 |
-
//optimize thumbnails
|
135 |
-
add_action('wp_ajax_shortpixel_optimize_thumbs', array(&$this, 'handleOptimizeThumbs'));
|
136 |
-
|
137 |
-
//toolbar notifications
|
138 |
-
add_action( 'admin_bar_menu', array( &$this, 'toolbar_shortpixel_processing'), 999 );
|
139 |
-
//deactivate plugin
|
140 |
-
add_action( 'admin_post_shortpixel_deactivate_plugin', array(&$this, 'deactivatePlugin'));
|
141 |
-
}
|
142 |
-
|
143 |
-
//automatic optimization
|
144 |
-
add_action( 'wp_ajax_shortpixel_image_processing', array( &$this, 'handleImageProcessing') );
|
145 |
-
//manual optimization
|
146 |
-
add_action( 'wp_ajax_shortpixel_manual_optimization', array(&$this, 'handleManualOptimization'));
|
147 |
-
//dismiss notices
|
148 |
-
add_action( 'wp_ajax_shortpixel_dismiss_notice', array(&$this, 'dismissAdminNotice'));
|
149 |
-
add_action( 'wp_ajax_shortpixel_dismiss_media_alert', array(&$this, 'dismissMediaAlert'));
|
150 |
-
//check quota
|
151 |
-
add_action('admin_action_shortpixel_check_quota', array(&$this, 'handleCheckQuota'));
|
152 |
-
//This adds the constants used in PHP to be available also in JS
|
153 |
-
add_action( 'admin_footer', array( &$this, 'shortPixelJS') );
|
154 |
-
|
155 |
-
if($this->_settings->frontBootstrap) {
|
156 |
-
//also need to have it in the front footer then
|
157 |
-
add_action( 'wp_footer', array( &$this, 'shortPixelJS') );
|
158 |
-
//need to add the nopriv action for when items exist in the queue and no user is logged in
|
159 |
-
add_action( 'wp_ajax_nopriv_shortpixel_image_processing', array( &$this, 'handleImageProcessing') );
|
160 |
-
}
|
161 |
-
//register a method to display admin notices if necessary
|
162 |
-
add_action('admin_notices', array( &$this, 'displayAdminNotices'));
|
163 |
-
|
164 |
-
$this->migrateBackupFolder();
|
165 |
-
|
166 |
-
if(!$this->_settings->redirectedSettings && !$this->_settings->verifiedKey && (!function_exists("is_multisite") || !is_multisite())) {
|
167 |
-
$this->_settings->redirectedSettings = 1;
|
168 |
-
wp_redirect(admin_url("options-general.php?page=wp-shortpixel"));
|
169 |
-
exit();
|
170 |
-
}
|
171 |
-
}
|
172 |
-
|
173 |
-
//handling older
|
174 |
-
public function WPShortPixel() {
|
175 |
-
$this->__construct();
|
176 |
-
}
|
177 |
-
|
178 |
-
public function registerSettingsPage() {
|
179 |
-
add_options_page( __('ShortPixel Settings','shortpixel-image-optimiser'), 'ShortPixel', 'manage_options', 'wp-shortpixel', array($this, 'renderSettingsMenu'));
|
180 |
-
}
|
181 |
-
|
182 |
-
function registerAdminPage( ) {
|
183 |
-
if($this->spMetaDao->hasFoldersTable() && count($this->spMetaDao->getFolders())) {
|
184 |
-
/*translators: title and menu name for the Other media page*/
|
185 |
-
add_media_page( __('Other Media Optimized by ShortPixel','shortpixel-image-optimiser'), __('Other Media','shortpixel-image-optimiser'), 'edit_others_posts', 'wp-short-pixel-custom', array( &$this, 'listCustomMedia' ) );
|
186 |
-
}
|
187 |
-
/*translators: title and menu name for the Bulk Processing page*/
|
188 |
-
add_media_page( __('ShortPixel Bulk Process','shortpixel-image-optimiser'), __('Bulk ShortPixel','shortpixel-image-optimiser'), 'edit_others_posts', 'wp-short-pixel-bulk', array( &$this, 'bulkProcess' ) );
|
189 |
-
}
|
190 |
-
|
191 |
-
public static function shortPixelActivatePlugin()//reset some params to avoid trouble for plugins that were activated/deactivated/activated
|
192 |
-
{
|
193 |
-
self::shortPixelDeactivatePlugin();
|
194 |
-
if(SP_RESET_ON_ACTIVATE === true && WP_DEBUG === true) { //force reset plugin counters, only on specific occasions and on test environments
|
195 |
-
WPShortPixelSettings::debugResetOptions();
|
196 |
-
|
197 |
-
$settings = new WPShortPixelSettings();
|
198 |
-
$spMetaDao = new ShortPixelCustomMetaDao(new WpShortPixelDb(), $settings->hasCustomFolders);
|
199 |
-
$spMetaDao->dropTables();
|
200 |
-
}
|
201 |
-
WPShortPixelSettings::onActivate();
|
202 |
-
}
|
203 |
-
|
204 |
-
public static function shortPixelDeactivatePlugin()//reset some params to avoid trouble for plugins that were activated/deactivated/activated
|
205 |
-
{
|
206 |
-
include_once dirname( __FILE__ ) . '/wp-shortpixel-req.php';
|
207 |
-
ShortPixelQueue::resetBulk();
|
208 |
-
ShortPixelQueue::resetPrio();
|
209 |
-
WPShortPixelSettings::onDeactivate();
|
210 |
-
}
|
211 |
-
|
212 |
-
public static function getConflictingPlugins() {
|
213 |
-
$conflictPlugins = array(
|
214 |
-
'WP Smush - Image Optimization' => 'wp-smushit/wp-smush.php',
|
215 |
-
'Imagify Image Optimizer' => 'imagify/imagify.php',
|
216 |
-
'Compress JPEG & PNG images (TinyPNG)' => 'tiny-compress-images/tiny-compress-images.php',
|
217 |
-
'Kraken.io Image Optimizer' => 'kraken-image-optimizer/kraken.php',
|
218 |
-
'Optimus - WordPress Image Optimizer' => 'optimus/optimus.php',
|
219 |
-
'EWWW Image Optimizer' => 'ewww-image-optimizer/ewww-image-optimizer.php',
|
220 |
-
'ImageRecycle pdf & image compression' => 'imagerecycle-pdf-image-compression/wp-image-recycle.php',
|
221 |
-
'CheetahO Image Optimizer' => 'cheetaho-image-optimizer/cheetaho.php',
|
222 |
-
'Zara 4 Image Compression' => 'zara-4/zara-4.php',
|
223 |
-
'Prizm Image' => 'prizm-image/wp-prizmimage.php',
|
224 |
-
'CW Image Optimizer' => 'cw-image-optimizer/cw-image-optimizer.php'
|
225 |
-
);
|
226 |
-
$found = array();
|
227 |
-
foreach($conflictPlugins as $name => $path) {
|
228 |
-
if(is_plugin_active($path)) {
|
229 |
-
$found[] = array('name' => $name, 'path' => $path);
|
230 |
-
}
|
231 |
-
}
|
232 |
-
return $found;
|
233 |
-
}
|
234 |
-
|
235 |
-
public function displayAdminNotices() {
|
236 |
-
$dismissed = $this->_settings->dismissedNotices ? $this->_settings->dismissedNotices : array();
|
237 |
-
if(!$this->_settings->verifiedKey) {
|
238 |
-
$now = time();
|
239 |
-
$act = $this->_settings->activationDate ? $this->_settings->activationDate : $now;
|
240 |
-
if($this->_settings->activationNotice && $this->_settings->redirectedSettings >= 2) {
|
241 |
-
ShortPixelView::displayActivationNotice();
|
242 |
-
$this->_settings->activationNotice = null;
|
243 |
-
}
|
244 |
-
if( ($now > $act + 7200) && !isset($dismissed['2h'])) {
|
245 |
-
ShortPixelView::displayActivationNotice('2h');
|
246 |
-
} else if( ($now > $act + 72 * 3600) && !isset($dismissed['3d'])) {
|
247 |
-
ShortPixelView::displayActivationNotice('3d');
|
248 |
-
}
|
249 |
-
}
|
250 |
-
if(!isset($dismissed['compat'])) {
|
251 |
-
$conflictPlugins = self::getConflictingPlugins();
|
252 |
-
if(count($conflictPlugins)) {
|
253 |
-
ShortPixelView::displayActivationNotice('compat', $conflictPlugins);
|
254 |
-
}
|
255 |
-
}
|
256 |
-
}
|
257 |
-
|
258 |
-
public function dismissAdminNotice() {
|
259 |
-
$noticeId = preg_replace('|[^a-z0-9]|i', '', $_GET['notice_id']);
|
260 |
-
$dismissed = $this->_settings->dismissedNotices ? $this->_settings->dismissedNotices : array();
|
261 |
-
$dismissed[$noticeId] = true;
|
262 |
-
$this->_settings->dismissedNotices = $dismissed;
|
263 |
-
die(json_encode(array("Status" => 'success', "Message" => 'Notice ID: ' . $noticeId . ' dismissed')));
|
264 |
-
}
|
265 |
-
|
266 |
-
public function dismissMediaAlert() {
|
267 |
-
$this->_settings->mediaAlert = 1;
|
268 |
-
die(json_encode(array("Status" => 'success', "Message" => __('Media alert dismissed','shortpixel-image-optimiser'))));
|
269 |
-
}
|
270 |
-
|
271 |
-
//set default move as "list". only set once, it won't try to set the default mode again.
|
272 |
-
public function setDefaultViewModeList()
|
273 |
-
{
|
274 |
-
if($this->_settings->mediaLibraryViewMode === false)
|
275 |
-
{
|
276 |
-
$this->_settings->mediaLibraryViewMode = 1;
|
277 |
-
$currentUserID = false;
|
278 |
-
if ( function_exists('wp_get_current_user') ) {
|
279 |
-
$current_user = wp_get_current_user();
|
280 |
-
$currentUserID = $current_user->ID;
|
281 |
-
update_user_meta($currentUserID, "wp_media_library_mode", "list");
|
282 |
-
}
|
283 |
-
}
|
284 |
-
|
285 |
-
}
|
286 |
-
|
287 |
-
static function log($message) {
|
288 |
-
if (SHORTPIXEL_DEBUG === true) {
|
289 |
-
if (is_array($message) || is_object($message)) {
|
290 |
-
error_log(print_r($message, true));
|
291 |
-
} else {
|
292 |
-
error_log($message);
|
293 |
-
}
|
294 |
-
}
|
295 |
-
}
|
296 |
-
|
297 |
-
function shortPixelJS() { ?>
|
298 |
-
<script type="text/javascript" >
|
299 |
-
var ShortPixelConstants = {
|
300 |
-
STATUS_SUCCESS: <?php echo ShortPixelAPI::STATUS_SUCCESS; ?>,
|
301 |
-
STATUS_EMPTY_QUEUE: <?php echo self::BULK_EMPTY_QUEUE; ?>,
|
302 |
-
STATUS_ERROR: <?php echo ShortPixelAPI::STATUS_ERROR; ?>,
|
303 |
-
STATUS_FAIL: <?php echo ShortPixelAPI::STATUS_FAIL; ?>,
|
304 |
-
STATUS_QUOTA_EXCEEDED: <?php echo ShortPixelAPI::STATUS_QUOTA_EXCEEDED; ?>,
|
305 |
-
STATUS_SKIP: <?php echo ShortPixelAPI::STATUS_SKIP; ?>,
|
306 |
-
STATUS_NO_KEY: <?php echo ShortPixelAPI::STATUS_NO_KEY; ?>,
|
307 |
-
STATUS_RETRY: <?php echo ShortPixelAPI::STATUS_RETRY; ?>,
|
308 |
-
STATUS_QUEUE_FULL: <?php echo ShortPixelAPI::STATUS_QUEUE_FULL; ?>,
|
309 |
-
STATUS_MAINTENANCE: <?php echo ShortPixelAPI::STATUS_MAINTENANCE; ?>,
|
310 |
-
WP_PLUGIN_URL: '<?php echo plugins_url( '', __FILE__ ); ?>',
|
311 |
-
WP_ADMIN_URL: '<?php echo admin_url(); ?>',
|
312 |
-
API_KEY: "<?php echo $this->_settings->apiKey; ?>",
|
313 |
-
MEDIA_ALERT: '<?php echo $this->_settings->mediaAlert ? "done" : "todo"; ?>',
|
314 |
-
FRONT_BOOTSTRAP: <?php echo $this->_settings->frontBootstrap && (!isset($this->_settings->lastBackAction) || (time() - $this->_settings->lastBackAction > 600)) ? 1 : 0; ?>,
|
315 |
-
AJAX_URL: '<?php echo admin_url('admin-ajax.php'); ?>'
|
316 |
-
};
|
317 |
-
</script> <?php
|
318 |
-
wp_enqueue_style('short-pixel.css', plugins_url('/res/css/short-pixel.css',__FILE__) );
|
319 |
-
|
320 |
-
wp_register_script('short-pixel.js', plugins_url('/res/js/short-pixel.js',__FILE__) );
|
321 |
-
$jsTranslation = array(
|
322 |
-
'optimizeWithSP' => __( 'Optimize with ShortPixel', 'shortpixel-image-optimiser' ),
|
323 |
-
'changeMLToListMode' => __( 'In order to access the ShortPixel Optimization actions and info, please change to {0}List View{1}List View{2}Dismiss{3}', 'shortpixel-image-optimiser' ),
|
324 |
-
'alertOnlyAppliesToNewImages' => __( 'This type of optimization will apply to new uploaded images. Images that were already processed will not be re-optimized unless you restart the bulk process.', 'shortpixel-image-optimiser' ),
|
325 |
-
'areYouSureStopOptimizing' => __( 'Are you sure you want to stop optimizing the folder {0}?', 'shortpixel-image-optimiser' ),
|
326 |
-
'reducedBy' => __( 'Reduced by', 'shortpixel-image-optimiser' ),
|
327 |
-
'bonusProcessing' => __( 'Bonus processing', 'shortpixel-image-optimiser' ),
|
328 |
-
'plusXthumbsOpt' => __( '+{0} thumbnails optimized', 'shortpixel-image-optimiser' ),
|
329 |
-
'plusXretinasOpt' => __( '+{0} Retina images optimized', 'shortpixel-image-optimiser' ),
|
330 |
-
'optXThumbs' => __( 'Optimize {0} thumbnails', 'shortpixel-image-optimiser' ),
|
331 |
-
'reOptimizeAs' => __( 'Reoptimize {0}', 'shortpixel-image-optimiser' ),
|
332 |
-
'restoreBackup' => __( 'Restore backup', 'shortpixel-image-optimiser' ),
|
333 |
-
'getApiKey' => __( 'Get API Key', 'shortpixel-image-optimiser' ),
|
334 |
-
'extendQuota' => __( 'Extend Quota', 'shortpixel-image-optimiser' ),
|
335 |
-
'check__Quota' => __( 'Check Quota', 'shortpixel-image-optimiser' ),
|
336 |
-
'retry' => __( 'Retry', 'shortpixel-image-optimiser' ),
|
337 |
-
'thisContentNotProcessable' => __( 'This content is not processable.', 'shortpixel-image-optimiser' ),
|
338 |
-
'imageWaitOptThumbs' => __( 'Image waiting to optimize thumbnails', 'shortpixel-image-optimiser' ),
|
339 |
-
'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' ),
|
340 |
-
'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' )
|
341 |
-
);
|
342 |
-
wp_localize_script( 'short-pixel.js', '_spTr', $jsTranslation );
|
343 |
-
wp_enqueue_script('short-pixel.js');
|
344 |
-
|
345 |
-
wp_enqueue_script('jquery.knob.js', plugins_url('/res/js/jquery.knob.js',__FILE__) );
|
346 |
-
wp_enqueue_script('jquery.tooltip.js', plugins_url('/res/js/jquery.tooltip.js',__FILE__) );
|
347 |
-
wp_enqueue_script('punycode.js', plugins_url('/res/js/punycode.js',__FILE__) );
|
348 |
-
}
|
349 |
-
|
350 |
-
function toolbar_shortpixel_processing( $wp_admin_bar ) {
|
351 |
-
|
352 |
-
$extraClasses = " shortpixel-hide";
|
353 |
-
/*translators: toolbar icon tooltip*/
|
354 |
-
$id = 'short-pixel-notice-toolbar';
|
355 |
-
$tooltip = __('ShortPixel optimizing...','shortpixel-image-optimiser');
|
356 |
-
$icon = "shortpixel.png";
|
357 |
-
$successLink = $link = current_user_can( 'edit_others_posts')? 'upload.php?page=wp-short-pixel-bulk' : 'upload.php';
|
358 |
-
$blank = "";
|
359 |
-
if($this->prioQ->processing()) {
|
360 |
-
$extraClasses = " shortpixel-processing";
|
361 |
-
}
|
362 |
-
if($this->_settings->quotaExceeded && !isset($this->_settings->dismissedNotices['exceed'])) {
|
363 |
-
$extraClasses = " shortpixel-alert shortpixel-quota-exceeded";
|
364 |
-
/*translators: toolbar icon tooltip*/
|
365 |
-
$id = 'short-pixel-notice-exceed';
|
366 |
-
$tooltip = '';
|
367 |
-
$exceedTooltip = __('ShortPixel quota exceeded. Click for details.','shortpixel-image-optimiser');
|
368 |
-
//$link = "http://shortpixel.com/login/" . $this->_settings->apiKey;
|
369 |
-
$link = "options-general.php?page=wp-shortpixel";
|
370 |
-
//$blank = '_blank';
|
371 |
-
//$icon = "shortpixel-alert.png";
|
372 |
-
}
|
373 |
-
$lastStatus = $this->_settings->bulkLastStatus;
|
374 |
-
if($lastStatus && $lastStatus['Status'] != ShortPixelAPI::STATUS_SUCCESS) {
|
375 |
-
$extraClasses = " shortpixel-alert shortpixel-processing";
|
376 |
-
$tooltip = $lastStatus['Message'];
|
377 |
-
}
|
378 |
-
|
379 |
-
$args = array(
|
380 |
-
'id' => 'shortpixel_processing',
|
381 |
-
'title' => '<div id="' . $id . '" title="' . $tooltip . '" ><img src="'
|
382 |
-
. plugins_url( 'res/img/'.$icon, __FILE__ ) . '" success-url="' . $successLink . '"><span class="shp-alert">!</span></div>',
|
383 |
-
'href' => $link,
|
384 |
-
'meta' => array('target'=> $blank, 'class' => 'shortpixel-toolbar-processing' . $extraClasses)
|
385 |
-
);
|
386 |
-
$wp_admin_bar->add_node( $args );
|
387 |
-
if($this->_settings->quotaExceeded && !isset($this->_settings->dismissedNotices['exceed'])) {
|
388 |
-
$wp_admin_bar->add_node( array(
|
389 |
-
'id' => 'shortpixel_processing-title',
|
390 |
-
'parent' => 'shortpixel_processing',
|
391 |
-
'title' => $exceedTooltip,
|
392 |
-
'href' => $link
|
393 |
-
));
|
394 |
-
$wp_admin_bar->add_node( array(
|
395 |
-
'id' => 'shortpixel_processing-dismiss',
|
396 |
-
'parent' => 'shortpixel_processing',
|
397 |
-
'title' => '<div style="text-align: right;">Dismiss</div>',
|
398 |
-
'href' => "#",
|
399 |
-
'meta' => array('onclick'=> 'dismissShortPixelNoticeExceed(event)')
|
400 |
-
));
|
401 |
-
}
|
402 |
-
}
|
403 |
-
|
404 |
-
public function handleCustomBulk() {
|
405 |
-
// 1. get the action
|
406 |
-
$wp_list_table = _get_list_table('WP_Media_List_Table');
|
407 |
-
$action = $wp_list_table->current_action();
|
408 |
-
|
409 |
-
switch($action) {
|
410 |
-
// 2. Perform the action
|
411 |
-
case 'short-pixel-bulk':
|
412 |
-
// security check
|
413 |
-
check_admin_referer('bulk-media');
|
414 |
-
if(!is_array($_GET['media'])) {
|
415 |
-
break;
|
416 |
-
}
|
417 |
-
$mediaIds = array_reverse($_GET['media']);
|
418 |
-
foreach( $mediaIds as $ID ) {
|
419 |
-
$meta = wp_get_attachment_metadata($ID);
|
420 |
-
if( ( !isset($meta['ShortPixel']) //never touched by ShortPixel
|
421 |
-
|| (isset($meta['ShortPixel']['WaitingProcessing']) && $meta['ShortPixel']['WaitingProcessing'] == true))
|
422 |
-
&& (!isset($meta['ShortPixelImprovement']) || $meta['ShortPixelImprovement'] == __('Optimization N/A','shortpixel-image-optimiser'))) {
|
423 |
-
$this->prioQ->push($ID);
|
424 |
-
$meta['ShortPixel']['WaitingProcessing'] = true;
|
425 |
-
wp_update_attachment_metadata($ID, $meta);
|
426 |
-
}
|
427 |
-
}
|
428 |
-
break;
|
429 |
-
}
|
430 |
-
}
|
431 |
-
|
432 |
-
/**
|
433 |
-
* this is hooked onto the MediaLibrary image upload
|
434 |
-
* @param array $meta - the wordpress postmeta structure
|
435 |
-
* @param type $ID - the Media Library ID
|
436 |
-
* @return the meta structure updated with ShortPixel info if case
|
437 |
-
*/
|
438 |
-
public function handleMediaLibraryImageUpload($meta, $ID = null)
|
439 |
-
{
|
440 |
-
if( !$this->_settings->verifiedKey) {// no API Key set/verified -> do nothing here, just return
|
441 |
-
return $meta;
|
442 |
-
}
|
443 |
-
//else
|
444 |
-
//self::log("IMG: Auto-analyzing file ID #{$ID}");
|
445 |
-
|
446 |
-
if( self::isProcessable($ID) == false )
|
447 |
-
{//not a file that we can process
|
448 |
-
$meta['ShortPixelImprovement'] = __('Optimization N/A','shortpixel-image-optimiser');
|
449 |
-
return $meta;
|
450 |
-
}
|
451 |
-
else
|
452 |
-
{//the kind of file we can process. goody.
|
453 |
-
$this->prioQ->push($ID);
|
454 |
-
//that's a hack for watermarking plugins, don't send the image right away to processing, only add it in the queue
|
455 |
-
include_once( ABSPATH . 'wp-admin/includes/plugin.php' );
|
456 |
-
if( !is_plugin_active('image-watermark/image-watermark.php')
|
457 |
-
&& !is_plugin_active('easy-watermark/index.php')) {
|
458 |
-
$itemHandler = new ShortPixelMetaFacade($ID);
|
459 |
-
$itemHandler->setRawMeta($meta);
|
460 |
-
try {
|
461 |
-
$URLsAndPATHs = $this->getURLsAndPATHs($itemHandler);
|
462 |
-
} catch(Exception $e) {
|
463 |
-
$meta['ShortPixelImprovement'] = $e->getMessage();
|
464 |
-
return $meta;
|
465 |
-
}
|
466 |
-
//send a processing request right after a file was uploaded, do NOT wait for response
|
467 |
-
$this->_apiInterface->doRequests($URLsAndPATHs['URLs'], false, $ID);
|
468 |
-
//self::log("IMG: sent: " . json_encode($URLsAndPATHs));
|
469 |
-
}
|
470 |
-
$meta['ShortPixel']['WaitingProcessing'] = true;
|
471 |
-
return $meta;
|
472 |
-
}
|
473 |
-
}//end handleMediaLibraryImageUpload
|
474 |
-
|
475 |
-
/**
|
476 |
-
* this is hooked onto the NextGen upload
|
477 |
-
* @param type $image
|
478 |
-
*/
|
479 |
-
public function handleNextGenImageUpload($image) {
|
480 |
-
if($this->_settings->includeNextGen == 1) {
|
481 |
-
$imageFsPath = ShortPixelNextGenAdapter::getImageAbspath($image);
|
482 |
-
|
483 |
-
$customFolders = $this->spMetaDao->getFolders();
|
484 |
-
|
485 |
-
$folderId = -1;
|
486 |
-
foreach($customFolders as $folder) {
|
487 |
-
if(strpos($imageFsPath, $folder->getPath()) === 0) {
|
488 |
-
$folderId = $folder->getId();
|
489 |
-
break;
|
490 |
-
}
|
491 |
-
}
|
492 |
-
if($folderId == -1) { //if not found, create
|
493 |
-
$galleryPath = dirname($imageFsPath);
|
494 |
-
$folder = new ShortPixelFolder(array("path" => $galleryPath));
|
495 |
-
$folderMsg = $this->spMetaDao->saveFolder($folder);
|
496 |
-
$folderId = $folder->getId();
|
497 |
-
//self::log("NG Image Upload: created folder from path $galleryPath : Folder info: " . json_encode($folder));
|
498 |
-
}
|
499 |
-
$pathParts = explode('/', trim($imageFsPath));
|
500 |
-
//Add the main image
|
501 |
-
$meta = new ShortPixelMeta();
|
502 |
-
$meta->setPath($imageFsPath);
|
503 |
-
$meta->setName($pathParts[count($pathParts) - 1]);
|
504 |
-
$meta->setFolderId($folderId);
|
505 |
-
$meta->setExtMetaId($image->pid); // do this only for main image, not for thumbnais.
|
506 |
-
$meta->setCompressionType($this->_settings->compressionType);
|
507 |
-
$meta->setKeepExif($this->_settings->keepExif);
|
508 |
-
$meta->setCmyk2rgb($this->_settings->CMYKtoRGBconversion);
|
509 |
-
$meta->setResize($this->_settings->resizeImages);
|
510 |
-
$meta->setResizeWidth($this->_settings->resizeWidth);
|
511 |
-
$meta->setResizeHeight($this->_settings->resizeHeight);
|
512 |
-
$ID = $this->spMetaDao->addImage($meta);
|
513 |
-
$meta->setId($ID);
|
514 |
-
$this->prioQ->push('C-' . $ID);
|
515 |
-
//add the thumb image if exists
|
516 |
-
$pathParts[] = "thumbs_" . $pathParts[count($pathParts) - 1];
|
517 |
-
$pathParts[count($pathParts) - 2] = "thumbs";
|
518 |
-
$thumbPath = implode('/', $pathParts);
|
519 |
-
if(file_exists($thumbPath)) {
|
520 |
-
$metaThumb = new ShortPixelMeta();
|
521 |
-
$metaThumb->setPath($thumbPath);
|
522 |
-
$metaThumb->setName($pathParts[count($pathParts) - 1]);
|
523 |
-
$metaThumb->setFolderId($folderId);
|
524 |
-
$metaThumb->setCompressionType($this->_settings->compressionType);
|
525 |
-
$metaThumb->setKeepExif($this->_settings->keepExif);
|
526 |
-
$metaThumb->setCmyk2rgb($this->_settings->CMYKtoRGBconversion);
|
527 |
-
$metaThumb->setResize($this->_settings->resizeImages);
|
528 |
-
$metaThumb->setResizeWidth($this->_settings->resizeWidth);
|
529 |
-
$metaThumb->setResizeHeight($this->_settings->resizeHeight);
|
530 |
-
$ID = $this->spMetaDao->addImage($metaThumb);
|
531 |
-
$metaThumb->setId($ID);
|
532 |
-
$this->prioQ->push('C-' . $ID);
|
533 |
-
}
|
534 |
-
return $meta;
|
535 |
-
}
|
536 |
-
}
|
537 |
-
|
538 |
-
public function optimizeCustomImage($id) {
|
539 |
-
$meta = $this->spMetaDao->getMeta($id);
|
540 |
-
if($meta->getStatus() != 2) {
|
541 |
-
$meta->setStatus(1);
|
542 |
-
$meta->setRetries(0);
|
543 |
-
$this->spMetaDao->update($meta);
|
544 |
-
$this->prioQ->push('C-' . $id);
|
545 |
-
}
|
546 |
-
}
|
547 |
-
|
548 |
-
//TODO muta in bulkProvider
|
549 |
-
public function getBulkItemsFromDb(){
|
550 |
-
global $wpdb;
|
551 |
-
|
552 |
-
$startQueryID = $this->prioQ->getStartBulkId();
|
553 |
-
$endQueryID = $this->prioQ->getStopBulkId();
|
554 |
-
$skippedAlreadyProcessed = 0;
|
555 |
-
|
556 |
-
if ( $startQueryID <= $endQueryID ) {
|
557 |
-
return false;
|
558 |
-
}
|
559 |
-
$idList = array();
|
560 |
-
$itemList = array();
|
561 |
-
for ($sanityCheck = 0, $crtStartQueryID = $startQueryID;
|
562 |
-
($crtStartQueryID >= $endQueryID) && (count($itemList) < 3) && ($sanityCheck < 150); $sanityCheck++) {
|
563 |
-
|
564 |
-
self::log("GETDB: current StartID: " . $crtStartQueryID);
|
565 |
-
|
566 |
-
$queryPostMeta = "SELECT * FROM " . $wpdb->prefix . "postmeta
|
567 |
-
WHERE ( post_id <= $crtStartQueryID AND post_id >= $endQueryID )
|
568 |
-
AND ( meta_key = '_wp_attached_file' OR meta_key = '_wp_attachment_metadata' )
|
569 |
-
ORDER BY post_id DESC
|
570 |
-
LIMIT " . SP_MAX_RESULTS_QUERY;
|
571 |
-
$resultsPostMeta = $wpdb->get_results($queryPostMeta);
|
572 |
-
|
573 |
-
if ( empty($resultsPostMeta) ) {
|
574 |
-
$crtStartQueryID -= SP_MAX_RESULTS_QUERY;
|
575 |
-
$startQueryID = $crtStartQueryID;
|
576 |
-
$this->prioQ->setStartBulkId($startQueryID);
|
577 |
-
continue;
|
578 |
-
}
|
579 |
-
|
580 |
-
foreach ( $resultsPostMeta as $itemMetaData ) {
|
581 |
-
$crtStartQueryID = $itemMetaData->post_id;
|
582 |
-
if(!in_array($crtStartQueryID, $idList) && self::isProcessable($crtStartQueryID)) {
|
583 |
-
$item = new ShortPixelMetaFacade($crtStartQueryID);
|
584 |
-
$meta = $item->getMeta();//wp_get_attachment_metadata($crtStartQueryID);
|
585 |
-
|
586 |
-
if($meta->getStatus() != 2) {
|
587 |
-
$itemList[] = $item;
|
588 |
-
$idList[] = $crtStartQueryID;
|
589 |
-
}
|
590 |
-
elseif($meta->getCompressionType() !== null && $meta->getCompressionType() != $this->_settings->compressionType) {//a different type of compression was chosen in settings
|
591 |
-
if($this->doRestore($crtStartQueryID)) {
|
592 |
-
$itemList[] = $item = new ShortPixelMetaFacade($crtStartQueryID); //force reload after restore
|
593 |
-
$idList[] = $crtStartQueryID;
|
594 |
-
} else {
|
595 |
-
$skippedAlreadyProcessed++;
|
596 |
-
}
|
597 |
-
}
|
598 |
-
elseif( $this->_settings->processThumbnails && $meta->getThumbsOpt() !== null
|
599 |
-
&& $meta->getThumbsOpt() == 0 && count($meta->getThumbs()) > 0) { //thumbs were chosen in settings
|
600 |
-
//if($crtStartQueryID == 44 || $crtStartQueryID == 49) {echo("No THuMBS?");die(var_dump($meta));}
|
601 |
-
$meta->setThumbsTodo(true);
|
602 |
-
$item->updateMeta($meta);//wp_update_attachment_metadata($crtStartQueryID, $meta);
|
603 |
-
$itemList[] = $item;
|
604 |
-
$idList[] = $crtStartQueryID;
|
605 |
-
}
|
606 |
-
elseif($itemMetaData->meta_key == '_wp_attachment_metadata') { //count skipped
|
607 |
-
$skippedAlreadyProcessed++;
|
608 |
-
}
|
609 |
-
}
|
610 |
-
}
|
611 |
-
if(!count($idList) && $crtStartQueryID <= $startQueryID) {
|
612 |
-
//daca n-am adaugat niciuna pana acum, n-are sens sa mai selectez zona asta de id-uri in bulk-ul asta.
|
613 |
-
$leapStart = $this->prioQ->getStartBulkId();
|
614 |
-
$crtStartQueryID = $startQueryID = $itemMetaData->post_id - 1; //decrement it so we don't select it again
|
615 |
-
$res = WpShortPixelMediaLbraryAdapter::countAllProcessableFiles($this->_settings->optimizePdfs, $leapStart, $crtStartQueryID);
|
616 |
-
$skippedAlreadyProcessed += $res["mainProcessedFiles"] - $res["mainProc".($this->getCompressionType() == 1 ? "Lossy" : "Lossless")."Files"];
|
617 |
-
$this->prioQ->setStartBulkId($startQueryID);
|
618 |
-
} else {
|
619 |
-
$crtStartQueryID--;
|
620 |
-
}
|
621 |
-
}
|
622 |
-
return array("items" => $itemList, "skipped" => $skippedAlreadyProcessed, "searching" => ($sanityCheck >= 150));
|
623 |
-
}
|
624 |
-
|
625 |
-
/**
|
626 |
-
* Get last added items from priority
|
627 |
-
* @return type
|
628 |
-
*/
|
629 |
-
//TODO muta in bulkProvider - prio
|
630 |
-
public function getFromPrioAndCheck() {
|
631 |
-
$items = array();
|
632 |
-
foreach ($this->prioQ->getFromPrioAndCheck() as $id) {
|
633 |
-
$items[] = new ShortPixelMetaFacade($id);
|
634 |
-
}
|
635 |
-
return $items;
|
636 |
-
}
|
637 |
-
|
638 |
-
public function handleImageProcessing($ID = null) {
|
639 |
-
//if(rand(1,2) == 2) {
|
640 |
-
// header($_SERVER['SERVER_PROTOCOL'] . ' 500 Internal Server Error', true, 500);
|
641 |
-
// die("za stop");
|
642 |
-
//}
|
643 |
-
//0: check key
|
644 |
-
if( $this->_settings->verifiedKey == false) {
|
645 |
-
if($ID == null){
|
646 |
-
$ids = $this->getFromPrioAndCheck();
|
647 |
-
$itemHandler = (count($ids) > 0 ? $ids[0] : null);
|
648 |
-
}
|
649 |
-
$response = array("Status" => ShortPixelAPI::STATUS_NO_KEY, "ImageID" => $itemHandler ? $itemHandler->getId() : "-1", "Message" => __('Missing API Key','shortpixel-image-optimiser'));
|
650 |
-
$this->_settings->bulkLastStatus = $response;
|
651 |
-
die(json_encode($response));
|
652 |
-
}
|
653 |
-
|
654 |
-
if($this->_settings->frontBootstrap && is_admin() && !ShortPixelTools::requestIsFrontendAjax()) {
|
655 |
-
//if in backend, and front-end is activated, mark processing from backend to shut off the front-end for 10 min.
|
656 |
-
$this->_settings->lastBackAction = time();
|
657 |
-
}
|
658 |
-
|
659 |
-
self::log("HIP: 0 Priority Queue: ".json_encode($this->prioQ->get()));
|
660 |
-
//self::log("HIP: 0 Bulk running? " . $this->prioQ->bulkRunning() . " START " . $this->_settings->startBulkId . " STOP " . $this->_settings->stopBulkId);
|
661 |
-
|
662 |
-
//1: get 3 ids to process. Take them with priority from the queue
|
663 |
-
$ids = $this->getFromPrioAndCheck();
|
664 |
-
if(count($ids) < 3 ) { //take from bulk if bulk processing active
|
665 |
-
if($this->prioQ->bulkRunning()) {
|
666 |
-
$res = $this->getBulkItemsFromDb();
|
667 |
-
$bulkItems = $res['items'];
|
668 |
-
//merge them into the $ids array based on the ID (the same ID could be in prio also)
|
669 |
-
if($bulkItems){
|
670 |
-
foreach($bulkItems as $bi) {
|
671 |
-
$add = true;
|
672 |
-
foreach($ids as $pi) {
|
673 |
-
if($pi->getType() == ShortPixelMetaFacade::MEDIA_LIBRARY_TYPE && $bi->getId() == $pi->getId()) {
|
674 |
-
$add = false;
|
675 |
-
}
|
676 |
-
}
|
677 |
-
$ids[] = $bi;
|
678 |
-
}
|
679 |
-
}
|
680 |
-
}
|
681 |
-
}
|
682 |
-
|
683 |
-
self::log("HIP: 0 Bulk ran: " . $this->prioQ->bulkRan());
|
684 |
-
$customIds = false;
|
685 |
-
if(count($ids) < 3 && $this->prioQ->bulkRan() && $this->_settings->hasCustomFolders
|
686 |
-
&& (!$this->_settings->cancelPointer || $this->_settings->skipToCustom)
|
687 |
-
&& !$this->_settings->customBulkPaused)
|
688 |
-
{ //take from custom images if any left to optimize - only if bulk was ever started
|
689 |
-
$customIds = $this->spMetaDao->getPendingMetas( 3 - count($ids));
|
690 |
-
if(is_array($customIds)) {
|
691 |
-
$ids = array_merge($ids, array_map(array('ShortPixelMetaFacade', 'getNewFromRow'), $customIds));
|
692 |
-
}
|
693 |
-
}
|
694 |
-
//var_dump($ids);
|
695 |
-
//die("za stop 2");
|
696 |
-
|
697 |
-
self::log("HIP: 1 Prio Queue: ".json_encode($this->prioQ->get()));
|
698 |
-
self::log("HIP: 1 Selected IDs count: ".count($ids));
|
699 |
-
|
700 |
-
//2: Send up to 3 files to the server for processing
|
701 |
-
for($i = 0, $first = true; $ids !== false && $i < min(3, count($ids)); $i++) {
|
702 |
-
$itemHandler = $ids[$i];
|
703 |
-
$tmpMeta = $itemHandler->getMeta();
|
704 |
-
$compType = ($tmpMeta->getCompressionType() !== null ? $tmpMeta->getCompressionType() : $this->_settings->compressionType);
|
705 |
-
try {
|
706 |
-
self::log("HIP: 1 sendToProcessing: ".$itemHandler->getId());
|
707 |
-
$URLsAndPATHs = $this->sendToProcessing($itemHandler, $compType, $tmpMeta->getThumbsTodo());
|
708 |
-
//make sure it gets processed even if the user stops the bulk or the bulk skips somehow
|
709 |
-
$this->prioQ->enqueue($itemHandler->getId()); //this adds it to the end of the queue instead as first as push does
|
710 |
-
if(!count($URLsAndPATHs['PATHs'])) {
|
711 |
-
throw new Exception(__('Image files are missing.','shortpixel-image-optimiser'));
|
712 |
-
}
|
713 |
-
} catch(Exception $e) { // Exception("Post metadata is corrupt (No attachment URL)")
|
714 |
-
$meta = $itemHandler->setError(ShortPixelAPI::ERR_FILE_NOT_FOUND, $e->getMessage());
|
715 |
-
unset($ids[$i]);
|
716 |
-
}
|
717 |
-
if($first) { //save for later use
|
718 |
-
$firstUrlAndPaths = $URLsAndPATHs;
|
719 |
-
$first = false;
|
720 |
-
}
|
721 |
-
}
|
722 |
-
|
723 |
-
if ($ids === false || count( $ids ) == 0 ){
|
724 |
-
//if searching, than the script is searching for not processed items and found none yet, should be relaunced
|
725 |
-
if(isset($res['searching']) && $res['searching']) {
|
726 |
-
die(json_encode(array("Status" => ShortPixelAPI::STATUS_RETRY,
|
727 |
-
"Message" => __('Searching images to optimize... ','shortpixel-image-optimiser') . $this->prioQ->getStartBulkId() . '->' . $this->prioQ->getStopBulkId() )));
|
728 |
-
}
|
729 |
-
//in this case the queue is really empty
|
730 |
-
self::log("HIP: 1 STOP BULK");
|
731 |
-
$bulkEverRan = $this->prioQ->stopBulk();
|
732 |
-
$avg = $this->getAverageCompression();
|
733 |
-
$fileCount = $this->_settings->fileCount;
|
734 |
-
$response = array("Status" => self::BULK_EMPTY_QUEUE,
|
735 |
-
/* translators: console message Empty queue 1234 -> 1234 */
|
736 |
-
"Message" => __('Empty queue ','shortpixel-image-optimiser') . $this->prioQ->getStartBulkId() . '->' . $this->prioQ->getStopBulkId(),
|
737 |
-
"BulkStatus" => ($this->prioQ->bulkRunning()
|
738 |
-
? "1" : ($this->prioQ->bulkPaused() ? "2" : "0")),
|
739 |
-
"AverageCompression" => $avg,
|
740 |
-
"FileCount" => $fileCount,
|
741 |
-
"BulkPercent" => $this->prioQ->getBulkPercent());
|
742 |
-
die(json_encode($response));
|
743 |
-
}
|
744 |
-
|
745 |
-
self::log("HIP: 2 Prio Queue: ".json_encode($this->prioQ->get()));
|
746 |
-
//3: Retrieve the file for the first element of the list
|
747 |
-
$itemHandler = $ids[0];
|
748 |
-
$itemId = $itemHandler->getQueuedId();
|
749 |
-
$result = $this->_apiInterface->processImage($firstUrlAndPaths['URLs'], $firstUrlAndPaths['PATHs'], $itemHandler);
|
750 |
-
|
751 |
-
$result["ImageID"] = $itemId;
|
752 |
-
$meta = $itemHandler->getMeta();
|
753 |
-
$result["Filename"] = basename($meta->getPath());
|
754 |
-
|
755 |
-
self::log("HIP: 3 Prio Queue: ".json_encode($this->prioQ->get()));
|
756 |
-
|
757 |
-
//4: update counters and priority list
|
758 |
-
if( $result["Status"] == ShortPixelAPI::STATUS_SUCCESS) {
|
759 |
-
self::log("HIP: Image ID " . $itemId . " optimized successfully: ".json_encode($result));
|
760 |
-
$prio = $this->prioQ->remove($itemId);
|
761 |
-
//remove also from the failed list if it failed in the past
|
762 |
-
$prio = $this->prioQ->removeFromFailed($itemId);
|
763 |
-
$result["Type"] = $meta->getCompressionType() !== null ? ShortPixelAPI::getCompressionTypeName($meta->getCompressionType()) : '';
|
764 |
-
$result["ThumbsTotal"] = $meta->getThumbs() && is_array($meta->getThumbs()) ? WpShortPixelMediaLbraryAdapter::countNonWebpSizes($meta->getThumbs()): 0;
|
765 |
-
$result["ThumbsTotal"] -= count($meta->getThumbsMissing());
|
766 |
-
$result["ThumbsCount"] = $meta->getThumbsOpt()
|
767 |
-
? $meta->getThumbsOpt() //below is the fallback for old optimized images that don't have thumbsOpt
|
768 |
-
: ($this->_settings->processThumbnails ? $result["ThumbsTotal"] : 0);
|
769 |
-
|
770 |
-
$result["RetinasCount"] = $meta->getRetinasOpt();
|
771 |
-
$result["BackupEnabled"] = ($this->getBackupFolderAny($meta->getPath(), $meta->getThumbs()) ? true : false);//$this->_settings->backupImages;
|
772 |
-
|
773 |
-
if(!$prio && $itemId <= $this->prioQ->getStartBulkId()) {
|
774 |
-
$this->advanceBulk($itemId, $result);
|
775 |
-
$this->setBulkInfo($itemId, $result);
|
776 |
-
}
|
777 |
-
|
778 |
-
$result["AverageCompression"] = $this->getAverageCompression();
|
779 |
-
|
780 |
-
if($itemHandler->getType() == ShortPixelMetaFacade::MEDIA_LIBRARY_TYPE) {
|
781 |
-
|
782 |
-
$thumb = $bkThumb = "";
|
783 |
-
//$percent = 0;
|
784 |
-
$percent = $meta->getImprovementPercent();
|
785 |
-
if($percent){
|
786 |
-
$filePath = explode("/", $meta->getPath());
|
787 |
-
|
788 |
-
//Get a suitable thumb
|
789 |
-
$sizes = $meta->getThumbs();
|
790 |
-
if('pdf' == strtolower(pathinfo($result["Filename"], PATHINFO_EXTENSION))) {
|
791 |
-
// echo($result["Filename"] . " ESTE --> "); die(var_dump(strtolower(pathinfo($result["Filename"], PATHINFO_EXTENSION))));
|
792 |
-
$thumb = plugins_url( 'shortpixel-image-optimiser/res/img/logo-pdf.png' );
|
793 |
-
$bkThumb = '';
|
794 |
-
} else {
|
795 |
-
if(count($sizes)) {
|
796 |
-
$thumb = (isset($sizes["medium"]) ? $sizes["medium"]["file"] : (isset($sizes["thumbnail"]) ? $sizes["thumbnail"]["file"]: ""));
|
797 |
-
if(!strlen($thumb)) { //fallback to the first in the list
|
798 |
-
$sizeVals = array_values($sizes);
|
799 |
-
$thumb = count($sizeVals) ? $sizeVals[0]['file'] : '';
|
800 |
-
}
|
801 |
-
} else { //fallback to the image itself
|
802 |
-
$thumb = is_array($filePath) ? $filePath[count($filePath) - 1] : $filePath;
|
803 |
-
}
|
804 |
-
|
805 |
-
if(strlen($thumb) && $this->_settings->backupImages && $this->_settings->processThumbnails) {
|
806 |
-
$backupUrl = content_url() . "/" . SP_UPLOADS_NAME . "/" . SP_BACKUP . "/";
|
807 |
-
//$urlBkPath = $this->_apiInterface->returnSubDir(get_attached_file($ID));
|
808 |
-
$urlBkPath = ShortPixelMetaFacade::returnSubDir($meta->getPath(), ShortPixelMetaFacade::MEDIA_LIBRARY_TYPE);
|
809 |
-
$bkThumb = $backupUrl . $urlBkPath . $thumb;
|
810 |
-
}
|
811 |
-
if(strlen($thumb)) {
|
812 |
-
$uploadsUrl = ShortPixelMetaFacade::getHomeUrl2();
|
813 |
-
$urlPath = ShortPixelMetaFacade::returnSubDir($meta->getPath(), ShortPixelMetaFacade::MEDIA_LIBRARY_TYPE);
|
814 |
-
//$urlPath = implode("/", array_slice($filePath, 0, count($filePath) - 1));
|
815 |
-
$thumb = $uploadsUrl . $urlPath . $thumb;
|
816 |
-
}
|
817 |
-
}
|
818 |
-
|
819 |
-
$result["Thumb"] = $thumb;
|
820 |
-
$result["BkThumb"] = $bkThumb;
|
821 |
-
}
|
822 |
-
}
|
823 |
-
elseif( is_array($customIds)) { // this item is from custom bulk
|
824 |
-
foreach($customIds as $customId) {
|
825 |
-
$rootUrl = ShortPixelMetaFacade::getHomeUrl();
|
826 |
-
if($customId->id == $itemHandler->getId()) {
|
827 |
-
if('pdf' == strtolower(pathinfo($meta->getName(), PATHINFO_EXTENSION))) {
|
828 |
-
$result["Thumb"] = plugins_url( 'shortpixel-image-optimiser/res/img/logo-pdf.png' );
|
829 |
-
$result["BkThumb"] = "";
|
830 |
-
} else {
|
831 |
-
$result["Thumb"] = $thumb = $rootUrl . $meta->getWebPath();
|
832 |
-
if($this->_settings->backupImages) {
|
833 |
-
$result["BkThumb"] = str_replace($rootUrl, $rootUrl. "/" . basename(dirname(dirname(SP_BACKUP_FOLDER))) . "/" . SP_UPLOADS_NAME . "/" . SP_BACKUP . "/", $thumb);
|
834 |
-
}
|
835 |
-
}
|
836 |
-
$this->setBulkInfo($itemId, $result);
|
837 |
-
break;
|
838 |
-
}
|
839 |
-
}
|
840 |
-
}
|
841 |
-
}
|
842 |
-
elseif ($result["Status"] == ShortPixelAPI::STATUS_ERROR) {
|
843 |
-
if($meta->getRetries() > MAX_ERR_RETRIES) {
|
844 |
-
if(! $this->prioQ->remove($itemId) ){
|
845 |
-
$this->advanceBulk($meta->getId(), $result);
|
846 |
-
}
|
847 |
-
if($itemHandler->getType() == ShortPixelMetaFacade::MEDIA_LIBRARY_TYPE) {
|
848 |
-
$itemHandler->deleteMeta(); //this deletes only the ShortPixel fields from meta, in case of WP Media library
|
849 |
-
}
|
850 |
-
$result["Status"] = ShortPixelAPI::STATUS_SKIP;
|
851 |
-
$result["Message"] .= __(' Retry limit reached. Skipping file ID ','shortpixel-image-optimiser') . $itemId . ".";
|
852 |
-
$itemHandler->setError(isset($result['Code']) ? $result['Code'] : ShortPixelAPI::ERR_INCORRECT_FILE_SIZE, $result["Message"] );
|
853 |
-
}
|
854 |
-
else {
|
855 |
-
if(isset($result['Code'])) {
|
856 |
-
$itemHandler->setError($result['Code'], $result["Message"] );
|
857 |
-
}
|
858 |
-
$itemHandler->incrementRetries();
|
859 |
-
}
|
860 |
-
}
|
861 |
-
elseif ($result["Status"] == ShortPixelAPI::STATUS_SKIP
|
862 |
-
|| $result["Status"] == ShortPixelAPI::STATUS_FAIL) {
|
863 |
-
$meta = $itemHandler->getMeta();
|
864 |
-
//$prio = $this->prioQ->remove($ID);
|
865 |
-
$prio = $this->prioQ->remove($itemId);
|
866 |
-
if(isset($result["Code"])
|
867 |
-
&& ( $result["Code"] == "write-fail" //could not write
|
868 |
-
|| (in_array(0+$result["Code"], array(-201)) && $meta->getRetries() >= 3))) { //for -201 (invalid image format) we retry only 3 times.
|
869 |
-
//put this one in the failed images list - to show the user at the end
|
870 |
-
$prio = $this->prioQ->addToFailed($itemHandler->getQueuedId());
|
871 |
-
}
|
872 |
-
$this->advanceBulk($meta->getId(), $result);
|
873 |
-
if($itemHandler->getType() == ShortPixelMetaFacade::CUSTOM_TYPE) {
|
874 |
-
$result["CustomImageLink"] = ShortPixelMetaFacade::getHomeUrl() . $meta->getWebPath();
|
875 |
-
}
|
876 |
-
}
|
877 |
-
elseif($result["Status"] == ShortPixelAPI::STATUS_QUEUE_FULL) {
|
878 |
-
//nimic?
|
879 |
-
}
|
880 |
-
elseif($result["Status"] == ShortPixelAPI::STATUS_MAINTENANCE) {
|
881 |
-
//nimic?
|
882 |
-
}
|
883 |
-
elseif ($this->prioQ->isPrio($itemId) && $result["Status"] == ShortPixelAPI::STATUS_QUOTA_EXCEEDED) {
|
884 |
-
if(!$this->prioQ->skippedCount()) {
|
885 |
-
$this->prioQ->reverse(); //for the first prio item with quota exceeded, revert the prio queue as probably the bottom ones were processed
|
886 |
-
}
|
887 |
-
if($this->prioQ->allSkipped()) {
|
888 |
-
$result["Stop"] = true;
|
889 |
-
} else {
|
890 |
-
$result["Stop"] = false;
|
891 |
-
$this->prioQ->skip($itemId);
|
892 |
-
}
|
893 |
-
self::log("HIP: 5 Prio Skipped: ".json_encode($this->prioQ->getSkipped()));
|
894 |
-
}
|
895 |
-
elseif($result["Status"] == ShortPixelAPI::STATUS_RETRY && is_array($customIds)) {
|
896 |
-
$result["CustomImageLink"] = $thumb = ShortPixelMetaFacade::getHomeUrl() . $meta->getWebPath();
|
897 |
-
}
|
898 |
-
|
899 |
-
if($result["Status"] !== ShortPixelAPI::STATUS_RETRY) {
|
900 |
-
$this->_settings->bulkLastStatus = $result;
|
901 |
-
}
|
902 |
-
die(json_encode($result));
|
903 |
-
}
|
904 |
-
|
905 |
-
|
906 |
-
private function advanceBulk($processedID, &$result) {
|
907 |
-
//echo("ADVANCE BULK: ");die(var_dump($result));
|
908 |
-
if($processedID <= $this->prioQ->getStartBulkId()) {
|
909 |
-
$this->prioQ->setStartBulkId($processedID - 1);
|
910 |
-
$this->prioQ->logBulkProgress();
|
911 |
-
}
|
912 |
-
}
|
913 |
-
|
914 |
-
private function setBulkInfo($processedID, &$result) {
|
915 |
-
$deltaBulkPercent = $this->prioQ->getDeltaBulkPercent();
|
916 |
-
$minutesRemaining = $this->prioQ->getTimeRemaining();
|
917 |
-
$pendingMeta = $this->_settings->hasCustomFolders ? $this->spMetaDao->getPendingMetaCount() : 0;
|
918 |
-
$percent = $this->prioQ->getBulkPercent();
|
919 |
-
if(0 + $pendingMeta > 0) {
|
920 |
-
$customMeta = $this->spMetaDao->getCustomMetaCount();
|
921 |
-
$totalPercent = round(($percent * $this->_settings->currentTotalFiles + ($customMeta - $pendingMeta) * 100) / ($this->_settings->currentTotalFiles + $customMeta));
|
922 |
-
$minutesRemaining = round($minutesRemaining * (100 - $totalPercent) / max(1, 100 - $percent));
|
923 |
-
$percent = $totalPercent;
|
924 |
-
}
|
925 |
-
$result["BulkPercent"] = $percent;
|
926 |
-
$result["BulkMsg"] = $this->bulkProgressMessage($deltaBulkPercent, $minutesRemaining);
|
927 |
-
}
|
928 |
-
|
929 |
-
|
930 |
-
|
931 |
-
private function sendToProcessing($itemHandler, $compressionType = false, $onlyThumbs = false) {
|
932 |
-
$URLsAndPATHs = $this->getURLsAndPATHs($itemHandler, NULL, $onlyThumbs);
|
933 |
-
|
934 |
-
$meta = $itemHandler->getMeta();
|
935 |
-
//find thumbs that are not listed in the metadata and add them in the sizes array
|
936 |
-
if($itemHandler->getType() == ShortPixelMetaFacade::MEDIA_LIBRARY_TYPE) {
|
937 |
-
$mainFile = $meta->getPath();
|
938 |
-
|
939 |
-
$foundThumbs = @glob(WpShortPixelMediaLbraryAdapter::thumbsSearchPattern($mainFile));
|
940 |
-
//first identify which thumbs are not in the sizes
|
941 |
-
$sizes = $meta->getThumbs();
|
942 |
-
foreach($foundThumbs as $id => $found) {
|
943 |
-
//get the mime-type from one of the thumbs metas
|
944 |
-
foreach($sizes as $size) {
|
945 |
-
if(pathinfo($mainFile, PATHINFO_EXTENSION) !== pathinfo($size['file'], PATHINFO_EXTENSION)){
|
946 |
-
continue;
|
947 |
-
}
|
948 |
-
$mimeType = $size['mime-type'];
|
949 |
-
if($size['file'] === ShortPixelAPI::MB_basename($found)) {
|
950 |
-
$foundThumbs[$id] = false;
|
951 |
-
}
|
952 |
-
}
|
953 |
-
}
|
954 |
-
// add the unfound ones to the sizes array
|
955 |
-
$ind = 1;
|
956 |
-
while (isset($sizes[ShortPixelMeta::FOUND_THUMB_PREFIX . str_pad("".$ind, 2, '0', STR_PAD_LEFT)])) $ind++;
|
957 |
-
$start = $ind;
|
958 |
-
foreach($foundThumbs as $found) {
|
959 |
-
if($found !== false) {
|
960 |
-
$size = getimagesize($found);
|
961 |
-
$sizes[ShortPixelMeta::FOUND_THUMB_PREFIX . str_pad("".$ind, 2, '0', STR_PAD_LEFT)]= array( // it's a file that has no corresponding thumb so it's the WEBP for the main file
|
962 |
-
'file' => ShortPixelAPI::MB_basename($found),
|
963 |
-
'width' => $size[0],
|
964 |
-
'height' => $size[1],
|
965 |
-
'mime-type' => $mimeType
|
966 |
-
);
|
967 |
-
$ind++;
|
968 |
-
}
|
969 |
-
}
|
970 |
-
if($ind > $start) { // at least one thumbnail added, update
|
971 |
-
$meta->setThumbs($sizes);
|
972 |
-
$itemHandler->updateMeta($meta);
|
973 |
-
$URLsAndPATHs = $this->getURLsAndPATHs($itemHandler, NULL, $onlyThumbs);
|
974 |
-
}
|
975 |
-
}
|
976 |
-
|
977 |
-
//find any missing thumbs files and mark them as such
|
978 |
-
if( isset($URLsAndPATHs['sizesMissing']) && count($URLsAndPATHs['sizesMissing'])
|
979 |
-
&& (null === $meta->getThumbsMissing() || count(array_diff_key($meta->getThumbsMissing(), array_merge($URLsAndPATHs['sizesMissing'], $meta->getThumbsMissing()))))) {
|
980 |
-
//fix missing thumbs in the metadata before sending to processing
|
981 |
-
$meta->setThumbsMissing($URLsAndPATHs['sizesMissing']);
|
982 |
-
$itemHandler->updateMeta();
|
983 |
-
}
|
984 |
-
//die(var_dump($itemHandler));
|
985 |
-
$refresh = $meta->getStatus() === ShortPixelAPI::ERR_INCORRECT_FILE_SIZE;
|
986 |
-
//echo("URLS: "); die(var_dump($URLsAndPATHs));
|
987 |
-
$this->_apiInterface->doRequests($URLsAndPATHs['URLs'], false, $itemHandler,
|
988 |
-
$compressionType === false ? $this->_settings->compressionType : $compressionType, $refresh);//send a request, do NOT wait for response
|
989 |
-
$itemHandler->setWaitingProcessing();
|
990 |
-
//$meta = wp_get_attachment_metadata($ID);
|
991 |
-
//$meta['ShortPixel']['WaitingProcessing'] = true;
|
992 |
-
//wp_update_attachment_metadata($ID, $meta);
|
993 |
-
return $URLsAndPATHs;
|
994 |
-
}
|
995 |
-
|
996 |
-
public function handleManualOptimization() {
|
997 |
-
$imageId = $_GET['image_id'];
|
998 |
-
$cleanup = $_GET['cleanup'];
|
999 |
-
switch(substr($imageId, 0, 2)) {
|
1000 |
-
case "N-":
|
1001 |
-
return "Add the gallery to the custom folders list in ShortPixel settings.";
|
1002 |
-
// Later
|
1003 |
-
if(class_exists("C_Image_Mapper")) { //this is a NextGen image but not added to our tables, so add it now.
|
1004 |
-
$image_mapper = C_Image_Mapper::get_instance();
|
1005 |
-
$image = $image_mapper->find(intval(substr($imageId, 2)));
|
1006 |
-
if($image) {
|
1007 |
-
$this->handleNextGenImageUpload($image, true);
|
1008 |
-
return array("Status" => ShortPixelAPI::STATUS_SUCCESS, "message" => "");
|
1009 |
-
}
|
1010 |
-
}
|
1011 |
-
return array("Status" => ShortPixelAPI::STATUS_FAIL, "message" => __('NextGen image not found','shortpixel-image-optimiser'));
|
1012 |
-
break;
|
1013 |
-
case "C-":
|
1014 |
-
throw new Exception("HandleManualOptimization for custom images not implemented");
|
1015 |
-
default:
|
1016 |
-
$this->optimizeNowHook(intval($imageId));
|
1017 |
-
break;
|
1018 |
-
}
|
1019 |
-
//do_action('shortpixel-optimize-now', $imageId);
|
1020 |
-
|
1021 |
-
}
|
1022 |
-
|
1023 |
-
//custom hook
|
1024 |
-
public function optimizeNowHook($imageId) {
|
1025 |
-
if(self::isProcessable($imageId)) {
|
1026 |
-
$this->prioQ->push($imageId);
|
1027 |
-
$itemHandler = new ShortPixelMetaFacade($imageId);
|
1028 |
-
try {
|
1029 |
-
$this->sendToProcessing($itemHandler);
|
1030 |
-
$ret = array("Status" => ShortPixelAPI::STATUS_SUCCESS, "Message" => "");
|
1031 |
-
} catch(Exception $e) { // Exception("Post metadata is corrupt (No attachment URL)")
|
1032 |
-
$itemHandler->getMeta();
|
1033 |
-
$itemHandler->setError(ShortPixelAPI::ERR_FILE_NOT_FOUND, $e->getMessage());
|
1034 |
-
$ret = array("Status" => ShortPixelAPI::STATUS_FAIL, "Message" => $e->getMessage());
|
1035 |
-
}
|
1036 |
-
} else {
|
1037 |
-
$ret = array("Status" => ShortPixelAPI::STATUS_SKIP, "Message" => $imageId);
|
1038 |
-
}
|
1039 |
-
die(json_encode($ret));
|
1040 |
-
}
|
1041 |
-
|
1042 |
-
//WP/LR Sync plugin integration
|
1043 |
-
public function onWpLrUpdateMedia($imageId, $galleryIdsUnused) {
|
1044 |
-
$meta = wp_get_attachment_metadata($imageId);
|
1045 |
-
if(is_array($meta)) {
|
1046 |
-
unset($meta['ShortPixel']);
|
1047 |
-
$meta['ShortPixel'] = array();
|
1048 |
-
$meta['ShortPixel']['WaitingProcessing'] = true;
|
1049 |
-
$this->prioQ->push($imageId);
|
1050 |
-
wp_update_attachment_metadata($imageId, $meta);
|
1051 |
-
}
|
1052 |
-
}
|
1053 |
-
|
1054 |
-
|
1055 |
-
//save error in file's meta data
|
1056 |
-
public function handleError($ID, $result)
|
1057 |
-
{
|
1058 |
-
$meta = wp_get_attachment_metadata($ID);
|
1059 |
-
$meta['ShortPixelImprovement'] = $result;
|
1060 |
-
wp_update_attachment_metadata($ID, $meta);
|
1061 |
-
}
|
1062 |
-
|
1063 |
-
public function getBackupFolder($file) {
|
1064 |
-
if(realpath($file)) {
|
1065 |
-
$file = realpath($file); //found cases when $file contains for example /wp/../wp-content - clean it up
|
1066 |
-
}
|
1067 |
-
$fileExtension = strtolower(substr($file,strrpos($file,".")+1));
|
1068 |
-
$SubDir = ShortPixelMetaFacade::returnSubDir($file, ShortPixelMetaFacade::MEDIA_LIBRARY_TYPE);
|
1069 |
-
$SubDirOld = ShortPixelMetaFacade::returnSubDirOld($file, ShortPixelMetaFacade::MEDIA_LIBRARY_TYPE);
|
1070 |
-
|
1071 |
-
if ( !file_exists(SP_BACKUP_FOLDER . '/' . $SubDir . ShortPixelAPI::MB_basename($file))
|
1072 |
-
&& !file_exists(SP_BACKUP_FOLDER . '/' . date("Y") . "/" . date("m") . "/" . ShortPixelAPI::MB_basename($file)) ) {
|
1073 |
-
$SubDir = $SubDirOld; //maybe the folder was saved with the old method that returned the full path if the wp-content was not inside the root of the site.
|
1074 |
-
}
|
1075 |
-
if ( !file_exists(SP_BACKUP_FOLDER . '/' . $SubDir . ShortPixelAPI::MB_basename($file))
|
1076 |
-
&& !file_exists(SP_BACKUP_FOLDER . '/' . date("Y") . "/" . date("m") . "/" . ShortPixelAPI::MB_basename($file)) ) {
|
1077 |
-
$SubDir = trailingslashit(substr(dirname($file), 1)); //try this too
|
1078 |
-
}
|
1079 |
-
//sometimes the month of original file and backup can differ
|
1080 |
-
if ( !file_exists(SP_BACKUP_FOLDER . '/' . $SubDir . ShortPixelAPI::MB_basename($file)) ) {
|
1081 |
-
$SubDir = date("Y") . "/" . date("m") . "/";
|
1082 |
-
if( !file_exists(SP_BACKUP_FOLDER . '/' . $SubDir . ShortPixelAPI::MB_basename($file)) ) {
|
1083 |
-
return false;
|
1084 |
-
}
|
1085 |
-
}
|
1086 |
-
return SP_BACKUP_FOLDER . '/' . $SubDir;
|
1087 |
-
}
|
1088 |
-
|
1089 |
-
public function getBackupFolderAny($file, $thumbs) {
|
1090 |
-
if(!file_exists($file)) {
|
1091 |
-
//try with the thumbnails
|
1092 |
-
if(isset($thumbs)) foreach($thumbs as $size) {
|
1093 |
-
$backup = $this->getBackupFolder(trailingslashit(dirname($file)) . $size['file']);
|
1094 |
-
if($backup) return $backup;
|
1095 |
-
}
|
1096 |
-
} else {
|
1097 |
-
return $this->getBackupFolder($file);
|
1098 |
-
}
|
1099 |
-
}
|
1100 |
-
|
1101 |
-
protected function setFilePerms($file) {
|
1102 |
-
//die(getenv('USERNAME') ? getenv('USERNAME') : getenv('USER'));
|
1103 |
-
if(strtoupper(substr(PHP_OS, 0, 3)) !== 'WIN') {
|
1104 |
-
//on *nix platforms check also the owner
|
1105 |
-
$owner = fileowner($file);
|
1106 |
-
if($owner !== false && $owner != posix_getuid()) { //files with changed owner
|
1107 |
-
return false;
|
1108 |
-
}
|
1109 |
-
}
|
1110 |
-
$perms = @fileperms($file);
|
1111 |
-
if(!($perms & 0x0100) || !($perms & 0x0080)) {
|
1112 |
-
if(!@chmod($file, $perms | 0x0100 | 0x0080)) {
|
1113 |
-
return false;
|
1114 |
-
}
|
1115 |
-
}
|
1116 |
-
return true;
|
1117 |
-
}
|
1118 |
-
|
1119 |
-
protected function doRestore($attachmentID, $meta = null) {
|
1120 |
-
$file = $origFile = get_attached_file($attachmentID);
|
1121 |
-
if(!$meta) {
|
1122 |
-
$meta = wp_get_attachment_metadata($attachmentID);
|
1123 |
-
}
|
1124 |
-
$pathInfo = pathinfo($file);
|
1125 |
-
|
1126 |
-
$bkFolder = $this->getBackupFolderAny($file, $meta["sizes"]);
|
1127 |
-
$bkFile = trailingslashit($bkFolder) . ShortPixelAPI::MB_basename($file);
|
1128 |
-
|
1129 |
-
//first check if the file is readable by the current user - otherwise it will be unaccessible for the web browser
|
1130 |
-
// - collect the thumbs paths in the process
|
1131 |
-
$bkCount = 0; $main = false;
|
1132 |
-
if(file_exists($bkFile)) {
|
1133 |
-
if(!$this->setFilePerms($bkFile) || (file_exists($file) && !$this->setFilePerms($file)) ) {
|
1134 |
-
return false;
|
1135 |
-
}
|
1136 |
-
$bkCount++;
|
1137 |
-
$main = true;
|
1138 |
-
}
|
1139 |
-
$thumbsPaths = array();
|
1140 |
-
if( !empty($meta['file']) && is_array($meta["sizes"]) ) {
|
1141 |
-
foreach($meta["sizes"] as $size => $imageData) {
|
1142 |
-
$dest = $pathInfo['dirname'] . '/' . $imageData['file'];
|
1143 |
-
$source = trailingslashit($bkFolder) . $imageData['file'];
|
1144 |
-
if(!file_exists($source)) continue; // if thumbs were not optimized, then the backups will not be there.
|
1145 |
-
if(!$this->setFilePerms($source) || (file_exists($dest) && !$this->setFilePerms($dest))) {
|
1146 |
-
return false;
|
1147 |
-
}
|
1148 |
-
$bkCount++;
|
1149 |
-
$thumbsPaths[$source] = $dest;
|
1150 |
-
}
|
1151 |
-
}
|
1152 |
-
if(!$bkCount) {
|
1153 |
-
return false;
|
1154 |
-
}
|
1155 |
-
|
1156 |
-
if($bkFolder) {
|
1157 |
-
try {
|
1158 |
-
//main file
|
1159 |
-
if($main) {
|
1160 |
-
$this->renameWithRetina($bkFile, $file);
|
1161 |
-
}
|
1162 |
-
//getSize to update meta if image was resized by ShortPixel
|
1163 |
-
$width = false;
|
1164 |
-
if(file_exists($file)) {
|
1165 |
-
$size = getimagesize($file);
|
1166 |
-
$width = $size[0];
|
1167 |
-
$height = $size[1];
|
1168 |
-
}
|
1169 |
-
|
1170 |
-
//overwriting thumbnails
|
1171 |
-
foreach($thumbsPaths as $source => $destination) {
|
1172 |
-
$this->renameWithRetina($source, $destination);
|
1173 |
-
}
|
1174 |
-
$duplicates = ShortPixelMetaFacade::getWPMLDuplicates($attachmentID);
|
1175 |
-
foreach($duplicates as $ID) {
|
1176 |
-
$crtMeta = $attachmentID == $ID ? $meta : wp_get_attachment_metadata($ID);
|
1177 |
-
if(is_numeric($crtMeta["ShortPixelImprovement"]) && 0 + $crtMeta["ShortPixelImprovement"] < 5 && $this->_settings->under5Percent > 0) {
|
1178 |
-
$this->_settings->under5Percent = $this->_settings->under5Percent - 1; // - (isset($crtMeta["ShortPixel"]["thumbsOpt"]) ? $crtMeta["ShortPixel"]["thumbsOpt"] : 0);
|
1179 |
-
}
|
1180 |
-
unset($crtMeta["ShortPixelImprovement"]);
|
1181 |
-
unset($crtMeta['ShortPixel']);
|
1182 |
-
if($width && $height) {
|
1183 |
-
$crtMeta['width'] = $width;
|
1184 |
-
$crtMeta['height'] = $height;
|
1185 |
-
}
|
1186 |
-
wp_update_attachment_metadata($ID, $crtMeta);
|
1187 |
-
}
|
1188 |
-
unset($meta["ShortPixelImprovement"]);
|
1189 |
-
unset($meta['ShortPixel']);
|
1190 |
-
|
1191 |
-
} catch(Exception $e) {
|
1192 |
-
//what to do, what to do?
|
1193 |
-
return false;
|
1194 |
-
}
|
1195 |
-
} else {
|
1196 |
-
return false;
|
1197 |
-
}
|
1198 |
-
|
1199 |
-
return $meta;
|
1200 |
-
}
|
1201 |
-
|
1202 |
-
protected function renameWithRetina($bkFile, $file) {
|
1203 |
-
@rename($bkFile, $file);
|
1204 |
-
$ext = pathinfo($file, PATHINFO_EXTENSION);
|
1205 |
-
@rename(substr($bkFile, 0, strlen($bkFile) - 1 - strlen($ext)) . "@2x." . $ext, substr($file, 0, strlen($file) - 1 - strlen($ext)) . "@2x." . $ext);
|
1206 |
-
|
1207 |
-
}
|
1208 |
-
|
1209 |
-
public function doCustomRestore($ID) {
|
1210 |
-
$meta = $this->spMetaDao->getMeta($ID);
|
1211 |
-
if(!$meta || $meta->getStatus() != 2) return false;
|
1212 |
-
|
1213 |
-
$file = $meta->getPath();
|
1214 |
-
$fullSubDir = str_replace(get_home_path(), "", dirname($file)) . '/';
|
1215 |
-
$bkFile = SP_BACKUP_FOLDER . '/' . $fullSubDir . ShortPixelAPI::MB_basename($file);
|
1216 |
-
|
1217 |
-
if(file_exists($bkFile)) {
|
1218 |
-
@rename($bkFile, $file);
|
1219 |
-
$meta->setStatus(3);
|
1220 |
-
$this->spMetaDao->update($meta);
|
1221 |
-
}
|
1222 |
-
|
1223 |
-
return $meta;
|
1224 |
-
}
|
1225 |
-
|
1226 |
-
public function handleRestoreBackup() {
|
1227 |
-
$attachmentID = intval($_GET['attachment_ID']);
|
1228 |
-
|
1229 |
-
$this->doRestore($attachmentID);
|
1230 |
-
|
1231 |
-
// get the referring webpage location
|
1232 |
-
$sendback = wp_get_referer();
|
1233 |
-
// sanitize the referring webpage location
|
1234 |
-
$sendback = preg_replace('|[^a-z0-9-~+_.?#=&;,/:]|i', '', $sendback);
|
1235 |
-
// send the user back where they came from
|
1236 |
-
wp_redirect($sendback);
|
1237 |
-
// we are done
|
1238 |
-
}
|
1239 |
-
|
1240 |
-
public function handleRedo() {
|
1241 |
-
die(json_encode($this->redo($_GET['attachment_ID'], $_GET['type'])));
|
1242 |
-
}
|
1243 |
-
|
1244 |
-
public function redo($qID, $type = false) {
|
1245 |
-
if(ShortPixelMetaFacade::isCustomQueuedId($qID)) {
|
1246 |
-
$ID = ShortPixelMetaFacade::stripQueuedIdType($qID);
|
1247 |
-
$meta = $this->doCustomRestore($ID);
|
1248 |
-
if($meta) {
|
1249 |
-
$meta->setCompressionType(1 - $meta->getCompressionType());
|
1250 |
-
$meta->setStatus(1);
|
1251 |
-
$this->spMetaDao->update($meta);
|
1252 |
-
$this->prioQ->push($qID);
|
1253 |
-
$ret = array("Status" => ShortPixelAPI::STATUS_SUCCESS, "Message" => "");
|
1254 |
-
} else {
|
1255 |
-
$ret = array("Status" => ShortPixelAPI::STATUS_SKIP, "Message" => __('Could not restore from backup: ','shortpixel-image-optimiser') . $qID);
|
1256 |
-
}
|
1257 |
-
} else {
|
1258 |
-
$ID = intval($qID);
|
1259 |
-
$compressionType = ($type == 'lossless' ? 'lossless' : 'lossy'); //sanity check
|
1260 |
-
|
1261 |
-
$meta = $this->doRestore($ID);
|
1262 |
-
if($meta) { //restore succeeded
|
1263 |
-
$meta['ShortPixel'] = array("type" => $compressionType);
|
1264 |
-
wp_update_attachment_metadata($ID, $meta);
|
1265 |
-
$this->prioQ->push($ID);
|
1266 |
-
$this->sendToProcessing(new ShortPixelMetaFacade($ID), $compressionType == 'lossy' ? 1 : 0);
|
1267 |
-
$ret = array("Status" => ShortPixelAPI::STATUS_SUCCESS, "Message" => "");
|
1268 |
-
} else {
|
1269 |
-
$ret = array("Status" => ShortPixelAPI::STATUS_SKIP, "Message" => __('Could not restore from backup: ','shortpixel-image-optimiser') . $ID);
|
1270 |
-
}
|
1271 |
-
}
|
1272 |
-
return $ret;
|
1273 |
-
}
|
1274 |
-
|
1275 |
-
public function handleOptimizeThumbs() {
|
1276 |
-
$ID = intval($_GET['attachment_ID']);
|
1277 |
-
$meta = wp_get_attachment_metadata($ID);
|
1278 |
-
//die(var_dump($meta));
|
1279 |
-
if( isset($meta['ShortPixelImprovement'])
|
1280 |
-
&& isset($meta['sizes']) && WpShortPixelMediaLbraryAdapter::countNonWebpSizes($meta['sizes'])
|
1281 |
-
&& ( !isset($meta['ShortPixel']['thumbsOpt']) || $meta['ShortPixel']['thumbsOpt'] == 0)) { //optimized without thumbs, thumbs exist
|
1282 |
-
$meta['ShortPixel']['thumbsTodo'] = true;
|
1283 |
-
wp_update_attachment_metadata($ID, $meta);
|
1284 |
-
$this->prioQ->push($ID);
|
1285 |
-
$this->sendToProcessing(new ShortPixelMetaFacade($ID));
|
1286 |
-
$ret = array("Status" => ShortPixelAPI::STATUS_SUCCESS, "message" => "");
|
1287 |
-
} else {
|
1288 |
-
$ret = array("Status" => ShortPixelAPI::STATUS_SKIP, "message" => (isset($meta['ShortPixelImprovement']) ? __('No thumbnails to optimize for ID: ','shortpixel-image-optimiser') : __('Please optimize image for ID: ','shortpixel-image-optimiser')) . $ID);
|
1289 |
-
}
|
1290 |
-
die(json_encode($ret));
|
1291 |
-
}
|
1292 |
-
|
1293 |
-
public function handleCheckQuota() {
|
1294 |
-
$this->getQuotaInformation();
|
1295 |
-
// store the referring webpage location
|
1296 |
-
$sendback = wp_get_referer();
|
1297 |
-
// sanitize the referring webpage location
|
1298 |
-
$sendback = preg_replace('|[^a-z0-9-~+_.?#=&;,/:]|i', '', $sendback);
|
1299 |
-
// send the user back where they came from
|
1300 |
-
wp_redirect($sendback);
|
1301 |
-
// we are done
|
1302 |
-
}
|
1303 |
-
|
1304 |
-
public function handleDeleteAttachmentInBackup($ID) {
|
1305 |
-
$file = get_attached_file($ID);
|
1306 |
-
$meta = wp_get_attachment_metadata($ID);
|
1307 |
-
|
1308 |
-
if(self::isProcessable($ID) != false)
|
1309 |
-
{
|
1310 |
-
try {
|
1311 |
-
$SubDir = ShortPixelMetaFacade::returnSubDir($file, ShortPixelMetaFacade::MEDIA_LIBRARY_TYPE);
|
1312 |
-
|
1313 |
-
@unlink(SP_BACKUP_FOLDER . '/' . $SubDir . ShortPixelAPI::MB_basename($file));
|
1314 |
-
|
1315 |
-
if ( !empty($meta['file']) )
|
1316 |
-
{
|
1317 |
-
$filesPath = SP_BACKUP_FOLDER . '/' . $SubDir;//base BACKUP path
|
1318 |
-
//remove thumbs thumbnails
|
1319 |
-
if(isset($meta["sizes"])) {
|
1320 |
-
foreach($meta["sizes"] as $size => $imageData) {
|
1321 |
-
@unlink($filesPath . ShortPixelAPI::MB_basename($imageData['file']));//remove thumbs
|
1322 |
-
}
|
1323 |
-
}
|
1324 |
-
}
|
1325 |
-
|
1326 |
-
} catch(Exception $e) {
|
1327 |
-
//what to do, what to do?
|
1328 |
-
}
|
1329 |
-
}
|
1330 |
-
}
|
1331 |
-
|
1332 |
-
public function deactivatePlugin() {
|
1333 |
-
if ( ! wp_verify_nonce( $_GET['_wpnonce'], 'sp_deactivate_plugin_nonce' ) ) {
|
1334 |
-
wp_nonce_ays( '' );
|
1335 |
-
}
|
1336 |
-
deactivate_plugins( $_GET['plugin'] );
|
1337 |
-
wp_safe_redirect( wp_get_referer() );
|
1338 |
-
die();
|
1339 |
-
}
|
1340 |
-
|
1341 |
-
public function checkQuotaAndAlert($quotaData = null, $recheck = false) {
|
1342 |
-
if(!$quotaData) {
|
1343 |
-
$quotaData = $this->getQuotaInformation();
|
1344 |
-
}
|
1345 |
-
if ( !$quotaData['APIKeyValid']) {
|
1346 |
-
return $quotaData;
|
1347 |
-
}
|
1348 |
-
//$tempus = microtime(true);
|
1349 |
-
$imageCount = WpShortPixelMediaLbraryAdapter::countAllProcessableFiles($this->_settings->optimizePdfs);
|
1350 |
-
|
1351 |
-
$this->_settings->currentTotalFiles = $imageCount['totalFiles'];
|
1352 |
-
|
1353 |
-
//echo("Count took (seconds): " . (microtime(true) - $tempus));
|
1354 |
-
foreach($imageCount as $key => $val) {
|
1355 |
-
$quotaData[$key] = $val;
|
1356 |
-
}
|
1357 |
-
|
1358 |
-
if($this->_settings->hasCustomFolders) {
|
1359 |
-
$customImageCount = $this->spMetaDao->countAllProcessableFiles();
|
1360 |
-
foreach($customImageCount as $key => $val) {
|
1361 |
-
$quotaData[$key] = isset($quotaData[$key])
|
1362 |
-
? (is_array($quotaData[$key]) ? array_merge($quotaData[$key], $val) : $quotaData[$key] + $val)
|
1363 |
-
: $val;
|
1364 |
-
}
|
1365 |
-
}
|
1366 |
-
|
1367 |
-
if($quotaData['APICallsQuotaNumeric'] + $quotaData['APICallsQuotaOneTimeNumeric'] > $quotaData['APICallsMadeNumeric'] + $quotaData['APICallsMadeOneTimeNumeric']) {
|
1368 |
-
$this->_settings->quotaExceeded = '0';
|
1369 |
-
$this->_settings->prioritySkip = NULL;
|
1370 |
-
self::log("CHECK QUOTA: Skipped: ".json_encode($this->prioQ->getSkipped()));
|
1371 |
-
|
1372 |
-
?><script>var shortPixelQuotaExceeded = 0;</script><?php
|
1373 |
-
}
|
1374 |
-
else {
|
1375 |
-
$this->view->displayQuotaExceededAlert($quotaData, self::getAverageCompression(), $recheck);
|
1376 |
-
?><script>var shortPixelQuotaExceeded = 1;</script><?php
|
1377 |
-
}
|
1378 |
-
return $quotaData;
|
1379 |
-
}
|
1380 |
-
|
1381 |
-
public function isValidMetaId($id) {
|
1382 |
-
return substr($id, 0, 2 ) == "C-" ? $this->spMetaDao->getMeta(substr($id, 2)) : wp_get_attachment_url($id);
|
1383 |
-
}
|
1384 |
-
|
1385 |
-
public function listCustomMedia() {
|
1386 |
-
if( ! class_exists( 'ShortPixelListTable' ) ) {
|
1387 |
-
require_once('class/view/shortpixel-list-table.php');
|
1388 |
-
}
|
1389 |
-
if(isset($_REQUEST['refresh']) && esc_attr($_REQUEST['refresh']) == 1) {
|
1390 |
-
$notice = null;
|
1391 |
-
$this->refreshCustomFolders($notice);
|
1392 |
-
}
|
1393 |
-
if(isset($_REQUEST['action']) && esc_attr($_REQUEST['action']) == 'optimize' && isset($_REQUEST['image'])) {
|
1394 |
-
//die(ShortPixelMetaFacade::queuedId(ShortPixelMetaFacade::CUSTOM_TYPE, $_REQUEST['image']));
|
1395 |
-
$this->prioQ->push(ShortPixelMetaFacade::queuedId(ShortPixelMetaFacade::CUSTOM_TYPE, $_REQUEST['image']));
|
1396 |
-
}
|
1397 |
-
$customMediaListTable = new ShortPixelListTable($this, $this->spMetaDao, $this->hasNextGen);
|
1398 |
-
$items = $customMediaListTable->prepare_items();
|
1399 |
-
if ( isset($_GET['noheader']) ) {
|
1400 |
-
require_once(ABSPATH . 'wp-admin/admin-header.php');
|
1401 |
-
}
|
1402 |
-
|
1403 |
-
?>
|
1404 |
-
<div class="wrap shortpixel-other-media">
|
1405 |
-
<h2>
|
1406 |
-
<div style="float:right;">
|
1407 |
-
<a href="upload.php?page=wp-short-pixel-custom&refresh=1" id="refresh" class="button button-primary" title="<?php _e('Refresh custom folders content','shortpixel-image-optimiser');?>">
|
1408 |
-
<?php _e('Refresh folders','shortpixel-image-optimiser');?>
|
1409 |
-
</a>
|
1410 |
-
</div>
|
1411 |
-
<?php _e('Other Media optimized by ShortPixel','shortpixel-image-optimiser');?>
|
1412 |
-
</h2>
|
1413 |
-
|
1414 |
-
<div id="poststuff">
|
1415 |
-
<div id="post-body" class="metabox-holder columns-2">
|
1416 |
-
<div id="post-body-content">
|
1417 |
-
<div class="meta-box-sortables ui-sortable">
|
1418 |
-
<form method="post" class="shortpixel-table">
|
1419 |
-
<?php
|
1420 |
-
$customMediaListTable->display();
|
1421 |
-
//push to the processing list the pending ones, just in case
|
1422 |
-
//$count = $this->spMetaDao->getCustomMetaCount();
|
1423 |
-
foreach ($items as $item) {
|
1424 |
-
if($item->status == 1){
|
1425 |
-
$this->prioQ->push(ShortPixelMetaFacade::queuedId(ShortPixelMetaFacade::CUSTOM_TYPE, $item->id));
|
1426 |
-
}
|
1427 |
-
}
|
1428 |
-
?>
|
1429 |
-
</form>
|
1430 |
-
</div>
|
1431 |
-
</div>
|
1432 |
-
</div>
|
1433 |
-
<br class="clear">
|
1434 |
-
</div>
|
1435 |
-
</div> <?php
|
1436 |
-
}
|
1437 |
-
public function bulkProcess() {
|
1438 |
-
global $wpdb;
|
1439 |
-
|
1440 |
-
if( $this->_settings->verifiedKey == false ) {//invalid API Key
|
1441 |
-
ShortPixelView::displayActivationNotice();
|
1442 |
-
return;
|
1443 |
-
}
|
1444 |
-
|
1445 |
-
$quotaData = $this->checkQuotaAndAlert(null, isset($_GET['checkquota']));
|
1446 |
-
if($this->_settings->quotaExceeded != 0) {
|
1447 |
-
return;
|
1448 |
-
}
|
1449 |
-
|
1450 |
-
if(isset($_POST['bulkProcessPause']))
|
1451 |
-
{//pause an ongoing bulk processing, it might be needed sometimes
|
1452 |
-
$this->prioQ->pauseBulk();
|
1453 |
-
if($this->_settings->hasCustomFolders && $this->spMetaDao->getPendingMetaCount()) {
|
1454 |
-
$this->_settings->customBulkPaused = 1;
|
1455 |
-
}
|
1456 |
-
}
|
1457 |
-
|
1458 |
-
if(isset($_POST['bulkProcessStop']))
|
1459 |
-
{//stop an ongoing bulk processing
|
1460 |
-
$this->prioQ->cancelBulk();
|
1461 |
-
if($this->_settings->hasCustomFolders && $this->spMetaDao->getPendingMetaCount()) {
|
1462 |
-
$this->_settings->customBulkPaused = 1;
|
1463 |
-
}
|
1464 |
-
}
|
1465 |
-
|
1466 |
-
if(isset($_POST["bulkProcess"]))
|
1467 |
-
{
|
1468 |
-
//set the thumbnails option
|
1469 |
-
if ( isset($_POST['thumbnails']) ) {
|
1470 |
-
$this->_settings->processThumbnails = 1;
|
1471 |
-
} else {
|
1472 |
-
$this->_settings->processThumbnails = 0;
|
1473 |
-
}
|
1474 |
-
//clean the custom files errors in order to process them again
|
1475 |
-
if($this->_settings->hasCustomFolders) {
|
1476 |
-
$this->spMetaDao->resetFailed();
|
1477 |
-
}
|
1478 |
-
|
1479 |
-
$this->prioQ->startBulk();
|
1480 |
-
$this->_settings->customBulkPaused = 0;
|
1481 |
-
self::log("BULK: Start: " . $this->prioQ->getStartBulkId() . ", stop: " . $this->prioQ->getStopBulkId() . " PrioQ: "
|
1482 |
-
.json_encode($this->prioQ->get()));
|
1483 |
-
}//end bulk process was clicked
|
1484 |
-
|
1485 |
-
if(isset($_POST["bulkProcessResume"]))
|
1486 |
-
{
|
1487 |
-
$this->prioQ->resumeBulk();
|
1488 |
-
$this->_settings->customBulkPaused = 0;
|
1489 |
-
}//resume was clicked
|
1490 |
-
|
1491 |
-
if(isset($_POST["skipToCustom"]))
|
1492 |
-
{
|
1493 |
-
$this->_settings->skipToCustom = true;
|
1494 |
-
}//resume was clicked
|
1495 |
-
|
1496 |
-
//figure out the files that are left to be processed
|
1497 |
-
$qry_left = "SELECT count(*) FilesLeftToBeProcessed FROM " . $wpdb->prefix . "postmeta
|
1498 |
-
WHERE meta_key = '_wp_attached_file' AND post_id <= " . (0 + $this->prioQ->getStartBulkId());
|
1499 |
-
$filesLeft = $wpdb->get_results($qry_left);
|
1500 |
-
|
1501 |
-
//check the custom bulk
|
1502 |
-
$pendingMeta = $this->_settings->hasCustomFolders ? $this->spMetaDao->getPendingMetaCount() : 0;
|
1503 |
-
|
1504 |
-
if ( ($filesLeft[0]->FilesLeftToBeProcessed > 0 && $this->prioQ->bulkRunning())
|
1505 |
-
|| (0 + $pendingMeta > 0 && !$this->_settings->customBulkPaused && $this->prioQ->bulkRan())//bulk processing was started
|
1506 |
-
&& (!$this->prioQ->bulkPaused() || $this->_settings->skipToCustom)) //bulk not paused or if paused, user pressed Process Custom button
|
1507 |
-
{
|
1508 |
-
$msg = $this->bulkProgressMessage($this->prioQ->getDeltaBulkPercent(), $this->prioQ->getTimeRemaining());
|
1509 |
-
|
1510 |
-
$this->view->displayBulkProcessingRunning($this->getPercent($quotaData), $msg, $quotaData['APICallsRemaining'], $this->getAverageCompression(),
|
1511 |
-
($pendingMeta !== null ? ($this->prioQ->bulkRunning() ? 3 : 2) : 1));
|
1512 |
-
|
1513 |
-
} else
|
1514 |
-
{
|
1515 |
-
if($this->prioQ->bulkRan() && !$this->prioQ->bulkPaused()) {
|
1516 |
-
$this->prioQ->markBulkComplete();
|
1517 |
-
}
|
1518 |
-
|
1519 |
-
//image count
|
1520 |
-
$thumbsProcessedCount = $this->_settings->thumbsCount;//amount of optimized thumbnails
|
1521 |
-
$under5PercentCount = $this->_settings->under5Percent;//amount of under 5% optimized imgs.
|
1522 |
-
|
1523 |
-
//average compression
|
1524 |
-
$averageCompression = self::getAverageCompression();
|
1525 |
-
$percent = $this->prioQ->bulkPaused() ? $this->getPercent($quotaData) : false;
|
1526 |
-
|
1527 |
-
$this->view->displayBulkProcessingForm($quotaData, $thumbsProcessedCount, $under5PercentCount,
|
1528 |
-
$this->prioQ->bulkRan(), $averageCompression, $this->_settings->fileCount,
|
1529 |
-
self::formatBytes($this->_settings->savedSpace), $percent, $pendingMeta);
|
1530 |
-
}
|
1531 |
-
}
|
1532 |
-
//end bulk processing
|
1533 |
-
|
1534 |
-
public function getPercent($quotaData) {
|
1535 |
-
if($this->_settings->processThumbnails) {
|
1536 |
-
return min(99, round($quotaData["totalProcessedFiles"] *100.0 / $quotaData["totalFiles"]));
|
1537 |
-
} else {
|
1538 |
-
return min(99, round($quotaData["mainProcessedFiles"] *100.0 / $quotaData["mainFiles"]));
|
1539 |
-
}
|
1540 |
-
}
|
1541 |
-
|
1542 |
-
public function bulkProgressMessage($percent, $minutes) {
|
1543 |
-
$timeEst = "";
|
1544 |
-
self::log("bulkProgressMessage(): percent: " . $percent);
|
1545 |
-
if($percent < 1 || $minutes == 0) {
|
1546 |
-
$timeEst = "";
|
1547 |
-
} elseif( $minutes > 2880) {
|
1548 |
-
$timeEst = "~ " . round($minutes / 1440) . " days left";
|
1549 |
-
} elseif ($minutes > 240) {
|
1550 |
-
$timeEst = "~ " . round($minutes / 60) . " hours left";
|
1551 |
-
} elseif ($minutes > 60) {
|
1552 |
-
$timeEst = "~ " . round($minutes / 60) . " hours " . round($minutes % 60 / 10) * 10 . " min. left";
|
1553 |
-
} elseif ($minutes > 20) {
|
1554 |
-
$timeEst = "~ " . round($minutes / 10) * 10 . " minutes left";
|
1555 |
-
} else {
|
1556 |
-
$timeEst = "~ " . $minutes . " minutes left";
|
1557 |
-
}
|
1558 |
-
return $timeEst;
|
1559 |
-
}
|
1560 |
-
|
1561 |
-
public function emptyBackup(){
|
1562 |
-
if(file_exists(SP_BACKUP_FOLDER)) {
|
1563 |
-
|
1564 |
-
//extract all images from DB in an array. of course
|
1565 |
-
$attachments = null;
|
1566 |
-
$attachments = get_posts( array(
|
1567 |
-
'numberposts' => -1,
|
1568 |
-
'post_type' => 'attachment',
|
1569 |
-
'post_mime_type' => 'image'
|
1570 |
-
));
|
1571 |
-
|
1572 |
-
|
1573 |
-
//parse all images and set the right flag that the image has no backup
|
1574 |
-
/* this is obsolete as the backup exists decision is taken on verfication of the actual backup files
|
1575 |
-
foreach($attachments as $attachment)
|
1576 |
-
{
|
1577 |
-
if(self::isProcessable($attachment->ID) == false) continue;
|
1578 |
-
|
1579 |
-
$meta = wp_get_attachment_metadata($attachment->ID);
|
1580 |
-
$meta['ShortPixel']['NoBackup'] = true;
|
1581 |
-
wp_update_attachment_metadata($attachment->ID, $meta);
|
1582 |
-
}
|
1583 |
-
*/
|
1584 |
-
|
1585 |
-
//delete the actual files on disk
|
1586 |
-
$this->deleteDir(SP_BACKUP_FOLDER);//call a recursive function to empty files and sub-dirs in backup dir
|
1587 |
-
}
|
1588 |
-
}
|
1589 |
-
|
1590 |
-
public function backupFolderIsEmpty() {
|
1591 |
-
return count(scandir(SP_BACKUP_FOLDER)) > 2 ? false : true;
|
1592 |
-
}
|
1593 |
-
|
1594 |
-
public function getBackupSize() {
|
1595 |
-
if ( !current_user_can( 'manage_options' ) ) {
|
1596 |
-
wp_die(__('You do not have sufficient permissions to access this page.','shortpixel-image-optimiser'));
|
1597 |
-
}
|
1598 |
-
die(self::formatBytes(self::folderSize(SP_BACKUP_FOLDER)));
|
1599 |
-
}
|
1600 |
-
|
1601 |
-
public function browseContent() {
|
1602 |
-
if ( !current_user_can( 'manage_options' ) ) {
|
1603 |
-
wp_die(__('You do not have sufficient permissions to access this page.','shortpixel-image-optimiser'));
|
1604 |
-
}
|
1605 |
-
|
1606 |
-
$root = self::getCustomFolderBase();
|
1607 |
-
|
1608 |
-
$postDir = rawurldecode($root.(isset($_POST['dir']) ? $_POST['dir'] : null ));
|
1609 |
-
|
1610 |
-
// set checkbox if multiSelect set to true
|
1611 |
-
$checkbox = ( isset($_POST['multiSelect']) && $_POST['multiSelect'] == 'true' ) ? "<input type='checkbox' />" : null;
|
1612 |
-
$onlyFolders = ($_POST['dir'] == '/' || isset($_POST['onlyFolders']) && $_POST['onlyFolders'] == 'true' ) ? true : false;
|
1613 |
-
$onlyFiles = ( isset($_POST['onlyFiles']) && $_POST['onlyFiles'] == 'true' ) ? true : false;
|
1614 |
-
|
1615 |
-
if( file_exists($postDir) ) {
|
1616 |
-
|
1617 |
-
$files = scandir($postDir);
|
1618 |
-
$returnDir = substr($postDir, strlen($root));
|
1619 |
-
|
1620 |
-
natcasesort($files);
|
1621 |
-
|
1622 |
-
if( count($files) > 2 ) { // The 2 accounts for . and ..
|
1623 |
-
echo "<ul class='jqueryFileTree'>";
|
1624 |
-
foreach( $files as $file ) {
|
1625 |
-
|
1626 |
-
if($file == 'ShortpixelBackups') continue;
|
1627 |
-
|
1628 |
-
$htmlRel = str_replace("'", "'", $returnDir . $file);
|
1629 |
-
$htmlName = htmlentities($file);
|
1630 |
-
$ext = preg_replace('/^.*\./', '', $file);
|
1631 |
-
|
1632 |
-
if( file_exists($postDir . $file) && $file != '.' && $file != '..' ) {
|
1633 |
-
if( is_dir($postDir . $file) && (!$onlyFiles || $onlyFolders) )
|
1634 |
-
echo "<li class='directory collapsed'>{$checkbox}<a rel='" .$htmlRel. "/'>" . $htmlName . "</a></li>";
|
1635 |
-
else if (!$onlyFolders || $onlyFiles)
|
1636 |
-
echo "<li class='file ext_{$ext}'>{$checkbox}<a rel='" . $htmlRel . "'>" . $htmlName . "</a></li>";
|
1637 |
-
}
|
1638 |
-
}
|
1639 |
-
|
1640 |
-
echo "</ul>";
|
1641 |
-
}
|
1642 |
-
}
|
1643 |
-
die();
|
1644 |
-
}
|
1645 |
-
|
1646 |
-
public static function getCustomFolderBase() {
|
1647 |
-
if(is_main_site()) {
|
1648 |
-
$base = get_home_path();
|
1649 |
-
return realpath(rtrim($base, '/'));
|
1650 |
-
} else {
|
1651 |
-
$up = wp_upload_dir();
|
1652 |
-
return realpath($up['basedir']);
|
1653 |
-
}
|
1654 |
-
}
|
1655 |
-
|
1656 |
-
protected function fullRefreshCustomFolder($path, &$notice) {
|
1657 |
-
$folder = $this->spMetaDao->getFolder($path);
|
1658 |
-
$diff = $folder->checkFolderContents(array('ShortPixelCustomMetaDao', 'getPathFiles'));
|
1659 |
-
}
|
1660 |
-
|
1661 |
-
protected function refreshCustomFolders(&$notice, $ignore = false) {
|
1662 |
-
$customFolders = array();
|
1663 |
-
if($this->_settings->hasCustomFolders) {
|
1664 |
-
$customFolders = $this->spMetaDao->getFolders();
|
1665 |
-
foreach($customFolders as $folder) {
|
1666 |
-
if($folder->getPath() === $ignore) continue;
|
1667 |
-
try {
|
1668 |
-
$mt = $folder->getFolderContentsChangeDate();
|
1669 |
-
if($mt > strtotime($folder->getTsUpdated())) {
|
1670 |
-
$fileList = $folder->getFileList(strtotime($folder->getTsUpdated()));
|
1671 |
-
$this->spMetaDao->batchInsertImages($fileList, $folder->getId());
|
1672 |
-
$folder->setTsUpdated(date("Y-m-d H:i:s", $mt));
|
1673 |
-
$folder->setFileCount($folder->countFiles());
|
1674 |
-
$this->spMetaDao->update($folder);
|
1675 |
-
}
|
1676 |
-
//echo ("mt: " . $mt);
|
1677 |
-
//die(var_dump($folder));
|
1678 |
-
} catch(SpFileRightsException $ex) {
|
1679 |
-
if(is_array($notice)) {
|
1680 |
-
if($notice['status'] == 'error') {
|
1681 |
-
$notice['msg'] .= " " . $ex->getMessage();
|
1682 |
-
}
|
1683 |
-
} else {
|
1684 |
-
$notice = array("status" => "error", "msg" => $ex->getMessage());
|
1685 |
-
}
|
1686 |
-
}
|
1687 |
-
}
|
1688 |
-
}
|
1689 |
-
return $customFolders;
|
1690 |
-
}
|
1691 |
-
|
1692 |
-
public function renderSettingsMenu() {
|
1693 |
-
if ( !current_user_can( 'manage_options' ) ) {
|
1694 |
-
wp_die(__('You do not have sufficient permissions to access this page.','shortpixel-image-optimiser'));
|
1695 |
-
}
|
1696 |
-
|
1697 |
-
wp_enqueue_style('sp-file-tree.css', plugins_url('/res/css/sp-file-tree.css',__FILE__) );
|
1698 |
-
wp_enqueue_script('sp-file-tree.js', plugins_url('/res/js/sp-file-tree.js',__FILE__) );
|
1699 |
-
|
1700 |
-
//die(var_dump($_POST));
|
1701 |
-
$noticeHTML = "";
|
1702 |
-
$notice = null;
|
1703 |
-
$folderMsg = false;
|
1704 |
-
$addedFolder = false;
|
1705 |
-
|
1706 |
-
$this->_settings->redirectedSettings = 2;
|
1707 |
-
|
1708 |
-
//by default we try to fetch the API Key from wp-config.php (if defined)
|
1709 |
-
if ( defined("SHORTPIXEL_API_KEY") && strlen(SHORTPIXEL_API_KEY) == 20)
|
1710 |
-
{
|
1711 |
-
if(!isset($_POST['save']) && (strlen($this->getApiKey()) == 0 || SHORTPIXEL_API_KEY != $this->getApiKey())) {
|
1712 |
-
$_POST['validate'] = "validate";
|
1713 |
-
}
|
1714 |
-
$_POST['key'] = SHORTPIXEL_API_KEY;
|
1715 |
-
}
|
1716 |
-
|
1717 |
-
//check all custom folders and update meta table if files appeared
|
1718 |
-
$customFolders = $this->refreshCustomFolders($notice, isset($_POST['removeFolder']) ? $_POST['removeFolder'] : null);
|
1719 |
-
|
1720 |
-
if(isset($_POST['request']) && $_POST['request'] == 'request') {
|
1721 |
-
//a new API Key was requested
|
1722 |
-
if(filter_var($_POST['email'], FILTER_VALIDATE_EMAIL)) {
|
1723 |
-
|
1724 |
-
}
|
1725 |
-
else {
|
1726 |
-
$notice = array("status" => "error",
|
1727 |
-
"msg" => __("Please provide a valid e-mail.",'shortpixel-image-optimiser')
|
1728 |
-
. "<BR> "
|
1729 |
-
. __('For any question regarding obtaining your API Key, please contact us at ','shortpixel-image-optimiser')
|
1730 |
-
. "<a href='mailto:help@shortpixel.com?Subject=API Key issues' target='_top'>help@shortpixel.com</a>"
|
1731 |
-
. __(' or ','shortpixel-image-optimiser')
|
1732 |
-
. "<a href='https://shortpixel.com/contact' target='_blank'>" . __('here','shortpixel-image-optimiser') . "</a>.");
|
1733 |
-
}
|
1734 |
-
}
|
1735 |
-
|
1736 |
-
if( isset($_POST['save']) || isset($_POST['saveAdv'])
|
1737 |
-
|| (isset($_POST['validate']) && $_POST['validate'] == "validate")
|
1738 |
-
|| isset($_POST['removeFolder']) || isset($_POST['recheckFolder'])) {
|
1739 |
-
|
1740 |
-
//handle API Key - common for save and validate.
|
1741 |
-
$_POST['key'] = trim(str_replace("*", "", isset($_POST['key']) ? $_POST['key'] : $this->_settings->apiKey)); //the API key might not be set if the editing is disabled.
|
1742 |
-
|
1743 |
-
if ( strlen($_POST['key']) <> 20 )
|
1744 |
-
{
|
1745 |
-
$KeyLength = strlen($_POST['key']);
|
1746 |
-
|
1747 |
-
$notice = array("status" => "error",
|
1748 |
-
"msg" => sprintf(__("The key you provided has %s characters. The API key should have 20 characters, letters and numbers only.",'shortpixel-image-optimiser'), $KeyLength)
|
1749 |
-
. "<BR> <b>"
|
1750 |
-
. __('Please check that the API key is the same as the one you received in your confirmation email.','shortpixel-image-optimiser')
|
1751 |
-
. "</b><BR> "
|
1752 |
-
. __('If this problem persists, please contact us at ','shortpixel-image-optimiser')
|
1753 |
-
. "<a href='mailto:help@shortpixel.com?Subject=API Key issues' target='_top'>help@shortpixel.com</a>"
|
1754 |
-
. __(' or ','shortpixel-image-optimiser')
|
1755 |
-
. "<a href='https://shortpixel.com/contact' target='_blank'>" . __('here','shortpixel-image-optimiser') . "</a>.");
|
1756 |
-
}
|
1757 |
-
else
|
1758 |
-
{
|
1759 |
-
$validityData = $this->getQuotaInformation($_POST['key'], true, isset($_POST['validate']) && $_POST['validate'] == "validate");
|
1760 |
-
|
1761 |
-
$this->_settings->apiKey = $_POST['key'];
|
1762 |
-
if($validityData['APIKeyValid']) {
|
1763 |
-
if(isset($_POST['validate']) && $_POST['validate'] == "validate") {
|
1764 |
-
// delete last status if it was no valid key
|
1765 |
-
$lastStatus = $this->_settings->bulkLastStatus;
|
1766 |
-
if(isset($lastStatus['Status']) && $lastStatus['Status'] == ShortPixelAPI::STATUS_NO_KEY) {
|
1767 |
-
$this->_settings->bulkLastStatus = null;
|
1768 |
-
}
|
1769 |
-
//display notification
|
1770 |
-
$urlParts = explode("/", get_site_url());
|
1771 |
-
if( $validityData['DomainCheck'] == 'NOT Accessible'){
|
1772 |
-
$notice = array("status" => "warn", "msg" => __("API Key is valid but your site is not accessible from our servers. Please make sure that your server is accessible from the Internet before using the API or otherwise we won't be able to optimize them.",'shortpixel-image-optimiser'));
|
1773 |
-
} else {
|
1774 |
-
if ( function_exists("is_multisite") && is_multisite() && !defined("SHORTPIXEL_API_KEY"))
|
1775 |
-
$notice = array("status" => "success", "msg" => __("Great, your API Key is valid! <br>You seem to be running a multisite, please note that API Key can also be configured in wp-config.php like this:",'shortpixel-image-optimiser')
|
1776 |
-
. "<BR> <b>define('SHORTPIXEL_API_KEY', '".$this->_settings->apiKey."');</b>");
|
1777 |
-
else
|
1778 |
-
$notice = array("status" => "success", "msg" => __('Great, your API Key is valid. Please take a few moments to review the plugin settings below before starting to optimize your images.','shortpixel-image-optimiser'));
|
1779 |
-
}
|
1780 |
-
}
|
1781 |
-
$this->_settings->verifiedKey = true;
|
1782 |
-
//test that the "uploads" have the right rights and also we can create the backup dir for ShortPixel
|
1783 |
-
if ( !file_exists(SP_BACKUP_FOLDER) && !@mkdir(SP_BACKUP_FOLDER, 0777, true) )
|
1784 |
-
$notice = array("status" => "error",
|
1785 |
-
"msg" => sprintf(__("There is something preventing us to create a new folder for backing up your original files.<BR>Please make sure that folder <b>%s</b> has the necessary write and read rights.",'shortpixel-image-optimiser'),
|
1786 |
-
WP_CONTENT_DIR . '/' . SP_UPLOADS_NAME ));
|
1787 |
-
} else {
|
1788 |
-
if(isset($_POST['validate'])) {
|
1789 |
-
//display notification
|
1790 |
-
$notice = array("status" => "error", "msg" => $validityData["Message"]);
|
1791 |
-
}
|
1792 |
-
$this->_settings->verifiedKey = false;
|
1793 |
-
}
|
1794 |
-
}
|
1795 |
-
|
1796 |
-
//if save button - we process the rest of the form elements
|
1797 |
-
if(isset($_POST['save']) || isset($_POST['saveAdv'])) {
|
1798 |
-
$this->_settings->compressionType = $_POST['compressionType'];
|
1799 |
-
if(isset($_POST['thumbnails'])) { $this->_settings->processThumbnails = 1; } else { $this->_settings->processThumbnails = 0; }
|
1800 |
-
if(isset($_POST['backupImages'])) { $this->_settings->backupImages = 1; } else { $this->_settings->backupImages = 0; }
|
1801 |
-
if(isset($_POST['cmyk2rgb'])) { $this->_settings->CMYKtoRGBconversion = 1; } else { $this->_settings->CMYKtoRGBconversion = 0; }
|
1802 |
-
$this->_settings->keepExif = isset($_POST['removeExif']) ? 0 : 1;
|
1803 |
-
//delete_option('wp-short-pixel-keep-exif');
|
1804 |
-
$this->_settings->resizeImages = (isset($_POST['resize']) ? 1: 0);
|
1805 |
-
$this->_settings->resizeType = (isset($_POST['resize_type']) ? $_POST['resize_type']: false);
|
1806 |
-
$this->_settings->resizeWidth = (isset($_POST['width']) ? $_POST['width']: $this->_settings->resizeWidth);
|
1807 |
-
$this->_settings->resizeHeight = (isset($_POST['height']) ? $_POST['height']: $this->_settings->resizeHeight);
|
1808 |
-
$this->_settings->siteAuthUser = (isset($_POST['siteAuthUser']) ? $_POST['siteAuthUser']: $this->_settings->siteAuthUser);
|
1809 |
-
$this->_settings->siteAuthPass = (isset($_POST['siteAuthPass']) ? $_POST['siteAuthPass']: $this->_settings->siteAuthPass);
|
1810 |
-
|
1811 |
-
$uploadDir = wp_upload_dir();
|
1812 |
-
$uploadPath = realpath($uploadDir["basedir"]);
|
1813 |
-
|
1814 |
-
if(isset($_POST['nextGen'])) {
|
1815 |
-
WpShortPixelDb::checkCustomTables(); // check if custom tables are created, if not, create them
|
1816 |
-
$prevNextGen = $this->_settings->includeNextGen;
|
1817 |
-
$this->_settings->includeNextGen = 1;
|
1818 |
-
$ret = $this->addNextGenGalleriesToCustom($prevNextGen);
|
1819 |
-
$folderMsg = $ret["message"];
|
1820 |
-
$customFolders = $ret["customFolders"];
|
1821 |
-
} else {
|
1822 |
-
$this->_settings->includeNextGen = 0;
|
1823 |
-
}
|
1824 |
-
if(isset($_POST['addCustomFolder']) && strlen($_POST['addCustomFolder']) > 0) {
|
1825 |
-
$folderMsg = $this->spMetaDao->newFolderFromPath(stripslashes($_POST['addCustomFolder']), $uploadPath, self::getCustomFolderBase());
|
1826 |
-
if(!$folderMsg) {
|
1827 |
-
$notice = array("status" => "success", "msg" => __('Folder added successfully.','shortpixel-image-optimiser'));
|
1828 |
-
}
|
1829 |
-
$customFolders = $this->spMetaDao->getFolders();
|
1830 |
-
$this->_settings->hasCustomFolders = true;
|
1831 |
-
}
|
1832 |
-
|
1833 |
-
$this->_settings->createWebp = (isset($_POST['createWebp']) ? 1: 0);
|
1834 |
-
$this->_settings->optimizeRetina = (isset($_POST['optimizeRetina']) ? 1: 0);
|
1835 |
-
$this->_settings->optimizePdfs = (isset($_POST['optimizePdfs']) ? 1: 0);
|
1836 |
-
$this->_settings->frontBootstrap = (isset($_POST['frontBootstrap']) ? 1: 0);
|
1837 |
-
$this->_settings->autoMediaLibrary = (isset($_POST['autoMediaLibrary']) ? 1: 0);
|
1838 |
-
|
1839 |
-
//Redirect to bulk processing if requested
|
1840 |
-
if( isset($_POST['save']) && $_POST['save'] == __("Save and Go to Bulk Process",'shortpixel-image-optimiser')
|
1841 |
-
|| isset($_POST['saveAdv']) && $_POST['saveAdv'] == __("Save and Go to Bulk Process",'shortpixel-image-optimiser')) {
|
1842 |
-
wp_redirect("upload.php?page=wp-short-pixel-bulk");
|
1843 |
-
exit();
|
1844 |
-
}
|
1845 |
-
}
|
1846 |
-
if(isset($_POST['removeFolder']) && strlen(($_POST['removeFolder']))) {
|
1847 |
-
$this->spMetaDao->removeFolder($_POST['removeFolder']);
|
1848 |
-
$customFolders = $this->spMetaDao->getFolders();
|
1849 |
-
$_POST["saveAdv"] = true;
|
1850 |
-
}
|
1851 |
-
if(isset($_POST['recheckFolder']) && strlen(($_POST['recheckFolder']))) {
|
1852 |
-
//$folder->fullRefreshCustomFolder($_POST['recheckFolder']); //aici singura solutie pare callback care spune daca exita url-ul complet
|
1853 |
-
}
|
1854 |
-
}
|
1855 |
-
|
1856 |
-
//now output headers. They were prevented with noheaders=true in the form url in order to be able to redirect if bulk was pressed
|
1857 |
-
if(isset($_REQUEST['noheader'])) {
|
1858 |
-
require_once(ABSPATH . 'wp-admin/admin-header.php');
|
1859 |
-
}
|
1860 |
-
|
1861 |
-
//empty backup
|
1862 |
-
if(isset($_POST['emptyBackup'])) {
|
1863 |
-
$this->emptyBackup();
|
1864 |
-
}
|
1865 |
-
|
1866 |
-
$quotaData = $this->checkQuotaAndAlert(isset($validityData) ? $validityData : null, isset($_GET['checkquota']));
|
1867 |
-
|
1868 |
-
if($this->hasNextGen) {
|
1869 |
-
$ngg = array_map(array('ShortPixelNextGenAdapter','pathToAbsolute'), ShortPixelNextGenAdapter::getGalleries());
|
1870 |
-
//die(var_dump($ngg));
|
1871 |
-
for($i = 0; $i < count($customFolders); $i++) {
|
1872 |
-
if(in_array($customFolders[$i]->getPath(), $ngg )) {
|
1873 |
-
$customFolders[$i]->setType("NextGen");
|
1874 |
-
}
|
1875 |
-
}
|
1876 |
-
}
|
1877 |
-
|
1878 |
-
$showApiKey = is_main_site() || (function_exists("is_multisite") && is_multisite() && !defined("SHORTPIXEL_API_KEY"));
|
1879 |
-
$editApiKey = !defined("SHORTPIXEL_API_KEY") && $showApiKey;
|
1880 |
-
|
1881 |
-
if($this->_settings->verifiedKey) {
|
1882 |
-
$fileCount = number_format($this->_settings->fileCount);
|
1883 |
-
$savedSpace = self::formatBytes($this->_settings->savedSpace,2);
|
1884 |
-
$averageCompression = $this->getAverageCompression();
|
1885 |
-
$savedBandwidth = self::formatBytes($this->_settings->savedSpace * 10000,2);
|
1886 |
-
if (is_numeric($quotaData['APICallsQuota'])) {
|
1887 |
-
$quotaData['APICallsQuota'] .= "/month";
|
1888 |
-
}
|
1889 |
-
$remainingImages = $quotaData['APICallsRemaining'];
|
1890 |
-
$remainingImages = ( $remainingImages < 0 ) ? 0 : number_format($remainingImages);
|
1891 |
-
$totalCallsMade = number_format($quotaData['APICallsMadeNumeric'] + $quotaData['APICallsMadeOneTimeNumeric']);
|
1892 |
-
|
1893 |
-
$resources = wp_remote_post($this->_settings->httpProto . "://shortpixel.com/resources-frag");
|
1894 |
-
if(is_wp_error( $resources )) {
|
1895 |
-
$resources = array();
|
1896 |
-
}
|
1897 |
-
$this->view->displaySettings($showApiKey, $editApiKey,
|
1898 |
-
$quotaData, $notice, $resources, $averageCompression, $savedSpace, $savedBandwidth, $remainingImages,
|
1899 |
-
$totalCallsMade, $fileCount, null /*folder size now on AJAX*/, $customFolders,
|
1900 |
-
$folderMsg, $folderMsg ? $addedFolder : false, isset($_POST['saveAdv']));
|
1901 |
-
} else {
|
1902 |
-
$this->view->displaySettings($showApiKey, $editApiKey, $quotaData, $notice);
|
1903 |
-
}
|
1904 |
-
|
1905 |
-
}
|
1906 |
-
|
1907 |
-
public function addNextGenGalleriesToCustom($silent) {
|
1908 |
-
$customFolders = array();
|
1909 |
-
$folderMsg = "";
|
1910 |
-
if($this->_settings->includeNextGen) {
|
1911 |
-
//add the NextGen galleries to custom folders
|
1912 |
-
$ngGalleries = ShortPixelNextGenAdapter::getGalleries();
|
1913 |
-
foreach($ngGalleries as $gallery) {
|
1914 |
-
$folderMsg = $this->spMetaDao->newFolderFromPath($gallery, get_home_path(), self::getCustomFolderBase());
|
1915 |
-
$this->_settings->hasCustomFolders = true;
|
1916 |
-
}
|
1917 |
-
$customFolders = $this->spMetaDao->getFolders();
|
1918 |
-
}
|
1919 |
-
return array("message" => $silent? "" : $folderMsg, "customFolders" => $customFolders);
|
1920 |
-
}
|
1921 |
-
|
1922 |
-
public function getAverageCompression(){
|
1923 |
-
return $this->_settings->totalOptimized > 0
|
1924 |
-
? round(( 1 - ( $this->_settings->totalOptimized / $this->_settings->totalOriginal ) ) * 100, 2)
|
1925 |
-
: 0;
|
1926 |
-
}
|
1927 |
-
|
1928 |
-
/**
|
1929 |
-
*
|
1930 |
-
* @param type $apiKey
|
1931 |
-
* @param type $appendUserAgent
|
1932 |
-
* @param type $validate - true if we are validating the api key, send also the domain name and number of pics
|
1933 |
-
* @return type
|
1934 |
-
*/
|
1935 |
-
public function getQuotaInformation($apiKey = null, $appendUserAgent = false, $validate = false) {
|
1936 |
-
|
1937 |
-
if(is_null($apiKey)) { $apiKey = $this->_settings->apiKey; }
|
1938 |
-
|
1939 |
-
if($this->_settings->httpProto != 'https' && $this->_settings->httpProto != 'http') {
|
1940 |
-
$this->_settings->httpProto = 'https';
|
1941 |
-
}
|
1942 |
-
|
1943 |
-
$requestURL = $this->_settings->httpProto . '://api.shortpixel.com/v2/api-status.php';
|
1944 |
-
$args = array(
|
1945 |
-
'timeout'=> SP_VALIDATE_MAX_TIMEOUT,
|
1946 |
-
'body' => array('key' => $apiKey)
|
1947 |
-
);
|
1948 |
-
$argsStr = "?key=".$apiKey;
|
1949 |
-
|
1950 |
-
if($appendUserAgent) {
|
1951 |
-
$args['body']['useragent'] = "Agent" . urlencode($_SERVER['HTTP_USER_AGENT']);
|
1952 |
-
$argsStr .= "&useragent=Agent".$args['body']['useragent'];
|
1953 |
-
}
|
1954 |
-
if($validate) {
|
1955 |
-
$args['body']['DomainCheck'] = get_site_url();
|
1956 |
-
$args['body']['Info'] = get_bloginfo('version') . '|' . phpversion();
|
1957 |
-
$imageCount = WpShortPixelMediaLbraryAdapter::countAllProcessableFiles($this->_settings->optimizePdfs);
|
1958 |
-
$args['body']['ImagesCount'] = $imageCount['mainFiles'];
|
1959 |
-
$args['body']['ThumbsCount'] = $imageCount['totalFiles'] - $imageCount['mainFiles'];
|
1960 |
-
$argsStr .= "&DomainCheck={$args['body']['DomainCheck']}&Info={$args['body']['Info']}&ImagesCount={$imageCount['mainFiles']}&ThumbsCount={$args['body']['ThumbsCount']}";
|
1961 |
-
}
|
1962 |
-
if(strlen($this->_settings->siteAuthUser)) {
|
1963 |
-
$args['body']['url'] = parse_url(get_site_url(),PHP_URL_HOST);
|
1964 |
-
$args['body']['user'] = $this->_settings->siteAuthUser;
|
1965 |
-
$args['body']['pass'] = urlencode($this->_settings->siteAuthPass);
|
1966 |
-
$argsStr .= "&url={$args['body']['url']}&user={$args['body']['user']}&pass={$args['body']['pass']}";
|
1967 |
-
}
|
1968 |
-
|
1969 |
-
$comm = array();
|
1970 |
-
|
1971 |
-
//Try first HTTPS post. add the sslverify = false if https
|
1972 |
-
if($this->_settings->httpProto === 'https') {
|
1973 |
-
$args['sslverify'] = false;
|
1974 |
-
}
|
1975 |
-
$response = wp_remote_post($requestURL, $args);
|
1976 |
-
$comm[] = array("sent" => "POST: " . $requestURL, "args" => $args, "received" => $response);
|
1977 |
-
|
1978 |
-
//some hosting providers won't allow https:// POST connections so we try http:// as well
|
1979 |
-
if(is_wp_error( $response )) {
|
1980 |
-
//echo("protocol " . $this->_settings->httpProto . " failed. switching...");
|
1981 |
-
$requestURL = $this->_settings->httpProto == 'https' ?
|
1982 |
-
str_replace('https://', 'http://', $requestURL) :
|
1983 |
-
str_replace('http://', 'https://', $requestURL);
|
1984 |
-
// add or remove the sslverify
|
1985 |
-
if($this->_settings->httpProto === 'http') {
|
1986 |
-
$args['sslverify'] = false;
|
1987 |
-
} else {
|
1988 |
-
unset($args['sslverify']);
|
1989 |
-
}
|
1990 |
-
$response = wp_remote_post($requestURL, $args);
|
1991 |
-
$comm[] = array("sent" => "POST: " . $requestURL, "args" => $args, "received" => $response);
|
1992 |
-
|
1993 |
-
if(!is_wp_error( $response )){
|
1994 |
-
$this->_settings->httpProto = ($this->_settings->httpProto == 'https' ? 'http' : 'https');
|
1995 |
-
//echo("protocol " . $this->_settings->httpProto . " succeeded");
|
1996 |
-
} else {
|
1997 |
-
//echo("protocol " . $this->_settings->httpProto . " failed too");
|
1998 |
-
}
|
1999 |
-
}
|
2000 |
-
//Second fallback to HTTP get
|
2001 |
-
if(is_wp_error( $response )){
|
2002 |
-
$args['body'] = null;
|
2003 |
-
$requestURL .= $argsStr;
|
2004 |
-
$response = wp_remote_get($requestURL, $args);
|
2005 |
-
$comm[] = array("sent" => "POST: " . $requestURL, "args" => $args, "received" => $response);
|
2006 |
-
}
|
2007 |
-
|
2008 |
-
$defaultData = array(
|
2009 |
-
"APIKeyValid" => false,
|
2010 |
-
"Message" => __('API Key could not be validated due to a connectivity error.<BR>Your firewall may be blocking us. Please contact your hosting provider and ask them to allow connections from your site to IP 176.9.106.46.<BR> If you still cannot validate your API Key after this, please <a href="https://shortpixel.com/contact" target="_blank">contact us</a> and we will try to help. ','shortpixel-image-optimiser'),
|
2011 |
-
"APICallsMade" => __('Information unavailable. Please check your API key.','shortpixel-image-optimiser'),
|
2012 |
-
"APICallsQuota" => __('Information unavailable. Please check your API key.','shortpixel-image-optimiser'),
|
2013 |
-
"DomainCheck" => 'NOT Accessible');
|
2014 |
-
|
2015 |
-
if(is_object($response) && get_class($response) == 'WP_Error') {
|
2016 |
-
|
2017 |
-
$urlElements = parse_url($requestURL);
|
2018 |
-
$portConnect = @fsockopen($urlElements['host'],8,$errno,$errstr,15);
|
2019 |
-
if(!$portConnect) {
|
2020 |
-
$defaultData['Message'] .= "<BR>Debug info: <i>$errstr</i>";
|
2021 |
-
}
|
2022 |
-
return $defaultData;
|
2023 |
-
}
|
2024 |
-
|
2025 |
-
if($response['response']['code'] != 200) {
|
2026 |
-
//$defaultData['Message'] .= "<BR><i>Debug info: response code {$response['response']['code']} URL $requestURL , Response ".json_encode($response)."</i>";
|
2027 |
-
return $defaultData;
|
2028 |
-
}
|
2029 |
-
|
2030 |
-
$data = $response['body'];
|
2031 |
-
$data = ShortPixelTools::parseJSON($data);
|
2032 |
-
|
2033 |
-
if(empty($data)) { return $defaultData; }
|
2034 |
-
|
2035 |
-
if($data->Status->Code != 2) {
|
2036 |
-
$defaultData['Message'] = $data->Status->Message;
|
2037 |
-
return $defaultData;
|
2038 |
-
}
|
2039 |
-
|
2040 |
-
if ( ( $data->APICallsMade + $data->APICallsMadeOneTime ) < ( $data->APICallsQuota + $data->APICallsQuotaOneTime ) ) //reset quota exceeded flag -> user is allowed to process more images.
|
2041 |
-
$this->resetQuotaExceeded();
|
2042 |
-
else
|
2043 |
-
$this->_settings->quotaExceeded = 1;//activate quota limiting
|
2044 |
-
|
2045 |
-
//if a non-valid status exists, delete it
|
2046 |
-
$lastStatus = $this->_settings->bulkLastStatus = null;
|
2047 |
-
if($lastStatus && $lastStatus['Status'] == ShortPixelAPI::STATUS_NO_KEY) {
|
2048 |
-
$this->_settings->bulkLastStatus = null;
|
2049 |
-
}
|
2050 |
-
|
2051 |
-
return array(
|
2052 |
-
"APIKeyValid" => true,
|
2053 |
-
"APICallsMade" => number_format($data->APICallsMade) . __(' images','shortpixel-image-optimiser'),
|
2054 |
-
"APICallsQuota" => number_format($data->APICallsQuota) . __(' images','shortpixel-image-optimiser'),
|
2055 |
-
"APICallsMadeOneTime" => number_format($data->APICallsMadeOneTime) . __(' images','shortpixel-image-optimiser'),
|
2056 |
-
"APICallsQuotaOneTime" => number_format($data->APICallsQuotaOneTime) . __(' images','shortpixel-image-optimiser'),
|
2057 |
-
"APICallsMadeNumeric" => $data->APICallsMade,
|
2058 |
-
"APICallsQuotaNumeric" => $data->APICallsQuota,
|
2059 |
-
"APICallsMadeOneTimeNumeric" => $data->APICallsMadeOneTime,
|
2060 |
-
"APICallsQuotaOneTimeNumeric" => $data->APICallsQuotaOneTime,
|
2061 |
-
"APICallsRemaining" => $data->APICallsQuota + $data->APICallsQuotaOneTime - $data->APICallsMade - $data->APICallsMadeOneTime,
|
2062 |
-
"APILastRenewalDate" => $data->DateSubscription,
|
2063 |
-
"DomainCheck" => (isset($data->DomainCheck) ? $data->DomainCheck : null)
|
2064 |
-
);
|
2065 |
-
}
|
2066 |
-
|
2067 |
-
public function resetQuotaExceeded() {
|
2068 |
-
if( $this->_settings->quotaExceeded == 1) {
|
2069 |
-
$dismissed = $this->_settings->dismissedNotices ? $this->_settings->dismissedNotices : array();
|
2070 |
-
unset($dismissed['exceed']);
|
2071 |
-
$this->_settings->dismissedNotices = $dismissed;
|
2072 |
-
}
|
2073 |
-
$this->_settings->quotaExceeded = 0;
|
2074 |
-
}
|
2075 |
-
|
2076 |
-
public function generateCustomColumn( $column_name, $id, $extended = false ) {
|
2077 |
-
if( 'wp-shortPixel' == $column_name ) {
|
2078 |
-
|
2079 |
-
$file = get_attached_file($id);
|
2080 |
-
if(!self::isProcessablePath($file)) {
|
2081 |
-
$renderData['status'] = 'n/a';
|
2082 |
-
$this->view->renderCustomColumn($id, $renderData, $extended);
|
2083 |
-
return;
|
2084 |
-
}
|
2085 |
-
|
2086 |
-
$data = wp_get_attachment_metadata($id);
|
2087 |
-
$fileExtension = strtolower(pathinfo($file, PATHINFO_EXTENSION));
|
2088 |
-
$invalidKey = !$this->_settings->verifiedKey;
|
2089 |
-
$quotaExceeded = $this->_settings->quotaExceeded;
|
2090 |
-
$renderData = array("id" => $id, "showActions" => (current_user_can( 'manage_options' ) || current_user_can( 'upload_files' ) || current_user_can( 'edit_posts' )));
|
2091 |
-
|
2092 |
-
if($invalidKey) { //invalid key - let the user first register and only then
|
2093 |
-
$renderData['status'] = 'invalidKey';
|
2094 |
-
$this->view->renderCustomColumn($id, $renderData, $extended);
|
2095 |
-
return;
|
2096 |
-
}
|
2097 |
-
|
2098 |
-
//empty data means document, we handle only PDF
|
2099 |
-
elseif (empty($data)) { //TODO asta devine if si decomentam returnurile
|
2100 |
-
if($fileExtension == "pdf") {
|
2101 |
-
$renderData['status'] = $quotaExceeded ? 'quotaExceeded' : 'optimizeNow';
|
2102 |
-
$renderData['message'] = __('PDF not processed.','shortpixel-image-optimiser');
|
2103 |
-
}
|
2104 |
-
else { //Optimization N/A
|
2105 |
-
$renderData['status'] = 'n/a';
|
2106 |
-
}
|
2107 |
-
$this->view->renderCustomColumn($id, $renderData, $extended);
|
2108 |
-
return;
|
2109 |
-
}
|
2110 |
-
|
2111 |
-
if(!isset($data['ShortPixelImprovement'])) { //new image
|
2112 |
-
$data['ShortPixelImprovement'] = '';
|
2113 |
-
}
|
2114 |
-
|
2115 |
-
if(is_numeric($data['ShortPixelImprovement'])) { //already optimized
|
2116 |
-
$sizesCount = isset($data['sizes']) ? WpShortPixelMediaLbraryAdapter::countNonWebpSizes($data['sizes']) : 0;
|
2117 |
-
|
2118 |
-
$renderData['status'] = $fileExtension == "pdf" ? 'pdfOptimized' : 'imgOptimized';
|
2119 |
-
$renderData['percent'] = $data['ShortPixelImprovement'];
|
2120 |
-
$renderData['bonus'] = ($data['ShortPixelImprovement'] < 5);
|
2121 |
-
$renderData['backup'] = $this->getBackupFolderAny(get_attached_file($id), $sizesCount? $data['sizes'] : array());
|
2122 |
-
$renderData['type'] = isset($data['ShortPixel']['type']) ? $data['ShortPixel']['type'] : '';
|
2123 |
-
$renderData['thumbsTotal'] = $sizesCount;
|
2124 |
-
$renderData['thumbsOpt'] = isset($data['ShortPixel']['thumbsOpt']) ? $data['ShortPixel']['thumbsOpt'] : $sizesCount;
|
2125 |
-
$renderData['thumbsMissing'] = isset($data['ShortPixel']['thumbsMissing']) ? $data['ShortPixel']['thumbsMissing'] : array();
|
2126 |
-
$renderData['retinasOpt'] = isset($data['ShortPixel']['retinasOpt']) ? $data['ShortPixel']['retinasOpt'] : null;
|
2127 |
-
$renderData['exifKept'] = isset($data['ShortPixel']['exifKept']) ? $data['ShortPixel']['exifKept'] : null;
|
2128 |
-
$renderData['date'] = isset($data['ShortPixel']['date']) ? $data['ShortPixel']['date'] : null;
|
2129 |
-
$renderData['quotaExceeded'] = $quotaExceeded;
|
2130 |
-
$webP = 0;
|
2131 |
-
if($extended) {
|
2132 |
-
if(file_exists(dirname($file) . '/' . basename($file, '.'.$fileExtension) . '.webp' )){
|
2133 |
-
$webP++;
|
2134 |
-
}
|
2135 |
-
if(isset($data['sizes'])) {
|
2136 |
-
foreach($data['sizes'] as $key => $size) {
|
2137 |
-
if (strpos($key, ShortPixelMeta::WEBP_THUMB_PREFIX) === 0) continue;
|
2138 |
-
$sizeName = $size['file'];
|
2139 |
-
if(file_exists(dirname($file) . '/' . basename($sizeName, '.'.$fileExtension) . '.webp' )){
|
2140 |
-
$webP++;
|
2141 |
-
}
|
2142 |
-
}
|
2143 |
-
}
|
2144 |
-
}
|
2145 |
-
$renderData['webpCount'] = $webP;
|
2146 |
-
}
|
2147 |
-
elseif($data['ShortPixelImprovement'] == __('Optimization N/A','shortpixel-image-optimiser')) { //We don't optimize this
|
2148 |
-
if('pdf' === $fileExtension && $this->_settings->optimizePdfs) {
|
2149 |
-
$renderData['status'] = $quotaExceeded ? 'quotaExceeded' : 'optimizeNow';
|
2150 |
-
$renderData['message'] = 'PDF not processed.';
|
2151 |
-
} else {
|
2152 |
-
$renderData['status'] = 'n/a';
|
2153 |
-
}
|
2154 |
-
}
|
2155 |
-
elseif(isset($meta['ShortPixel']['BulkProcessing'])) { //Scheduled to bulk.
|
2156 |
-
$renderData['status'] = $quotaExceeded ? 'quotaExceeded' : 'optimizeNow';
|
2157 |
-
$renderData['message'] = 'Waiting for bulk processing.';
|
2158 |
-
}
|
2159 |
-
elseif( trim(strip_tags($data['ShortPixelImprovement'])) == __("Cannot write optimized file",'shortpixel-image-optimiser') ) {
|
2160 |
-
$renderData['status'] = $quotaExceeded ? 'quotaExceeded' : 'retry';
|
2161 |
-
$renderData['message'] = __("Cannot write optimized file",'shortpixel-image-optimiser') . " - <a href='https://shortpixel.com/faq#cannot-write-optimized-file' target='_blank'>"
|
2162 |
-
. __("Why?",'shortpixel-image-optimiser') . "</a>";
|
2163 |
-
}
|
2164 |
-
elseif( strlen(trim(strip_tags($data['ShortPixelImprovement']))) > 0 ) {
|
2165 |
-
$renderData['status'] = $quotaExceeded ? 'quotaExceeded' : 'retry';
|
2166 |
-
$renderData['message'] = $data['ShortPixelImprovement'];
|
2167 |
-
if(strpos($renderData['message'], __('The file(s) do not exist on disk: ','shortpixel-image-optimiser')) !== false) {
|
2168 |
-
$renderData['cleanup'] = true;
|
2169 |
-
}
|
2170 |
-
}
|
2171 |
-
elseif(isset($data['ShortPixel']['NoFileOnDisk'])) {
|
2172 |
-
$renderData['status'] = 'notFound';
|
2173 |
-
$renderData['message'] = __('Image does not exist','shortpixel-image-optimiser');
|
2174 |
-
}
|
2175 |
-
elseif(isset($data['ShortPixel']['WaitingProcessing'])) {
|
2176 |
-
$renderData['status'] = $quotaExceeded ? 'quotaExceeded' : 'retry';
|
2177 |
-
$renderData['message'] = "<img src=\"" . plugins_url( 'res/img/loading.gif', __FILE__ ) . "\" class='sp-loading-small'> " . __("Image waiting to be processed.",'shortpixel-image-optimiser');
|
2178 |
-
if($id > $this->prioQ->getFlagBulkId() || !$this->prioQ->bulkRunning()) $this->prioQ->push($id); //should be there but just to make sure
|
2179 |
-
}
|
2180 |
-
else { //finally
|
2181 |
-
$renderData['status'] = $quotaExceeded ? 'quotaExceeded' : 'optimizeNow';
|
2182 |
-
$sizes = isset($data['sizes']) ? WpShortPixelMediaLbraryAdapter::countNonWebpSizes($data['sizes']) : 0;
|
2183 |
-
$renderData['thumbsTotal'] = $sizes;
|
2184 |
-
$renderData['message'] = ($fileExtension == "pdf" ? 'PDF' : 'Image') . ' not processed.';
|
2185 |
-
}
|
2186 |
-
|
2187 |
-
$this->view->renderCustomColumn($id, $renderData, $extended);
|
2188 |
-
}
|
2189 |
-
}
|
2190 |
-
|
2191 |
-
function shortpixelInfoBox() {
|
2192 |
-
if(get_post_type( ) == 'attachment') {
|
2193 |
-
add_meta_box(
|
2194 |
-
'shortpixel_info_box', // this is HTML id of the box on edit screen
|
2195 |
-
__('ShortPixel Info', 'shortpixel-image-optimiser'), // title of the box
|
2196 |
-
array( &$this, 'shortpixelInfoBoxContent'), // function to be called to display the info
|
2197 |
-
null,//, // on which edit screen the box should appear
|
2198 |
-
'side'//'normal', // part of page where the box should appear
|
2199 |
-
//'default' // priority of the box
|
2200 |
-
);
|
2201 |
-
}
|
2202 |
-
}
|
2203 |
-
|
2204 |
-
function shortpixelInfoBoxContent( $post ) {
|
2205 |
-
$this->generateCustomColumn( 'wp-shortPixel', $post->ID, true );
|
2206 |
-
}
|
2207 |
-
|
2208 |
-
function onDeleteImage($post_id) {
|
2209 |
-
$itemHandler = new ShortPixelMetaFacade($post_id);
|
2210 |
-
$urlsPaths = $itemHandler->getURLsAndPATHs(true, false, false);
|
2211 |
-
foreach($urlsPaths['PATHs'] as $path) {
|
2212 |
-
$pos = strrpos($path, ".");
|
2213 |
-
if ($pos !== false) {
|
2214 |
-
//$webpPath = substr($path, 0, $pos) . ".webp";
|
2215 |
-
//echo($webpPath . "<br>");
|
2216 |
-
@unlink(substr($path, 0, $pos) . ".webp");
|
2217 |
-
@unlink(substr($path, 0, $pos) . "@2x.webp");
|
2218 |
-
}
|
2219 |
-
}
|
2220 |
-
}
|
2221 |
-
|
2222 |
-
public function columns( $defaults ) {
|
2223 |
-
$defaults['wp-shortPixel'] = 'ShortPixel Compression';
|
2224 |
-
if(current_user_can( 'manage_options' )) {
|
2225 |
-
$defaults['wp-shortPixel'] .= ' <a href="options-general.php?page=wp-shortpixel#stats" title="'
|
2226 |
-
. __('ShortPixel Statistics','shortpixel-image-optimiser') . '"><span class="dashicons dashicons-dashboard"></span></a>';
|
2227 |
-
}
|
2228 |
-
return $defaults;
|
2229 |
-
}
|
2230 |
-
|
2231 |
-
public function nggColumns( $defaults ) {
|
2232 |
-
$this->nggColumnIndex = count($defaults) + 1;
|
2233 |
-
add_filter( 'ngg_manage_images_column_' . $this->nggColumnIndex . '_header', array( &$this, 'nggColumnHeader' ) );
|
2234 |
-
add_filter( 'ngg_manage_images_column_' . $this->nggColumnIndex . '_content', array( &$this, 'nggColumnContent' ), 10, 2 );
|
2235 |
-
$defaults['wp-shortPixelNgg'] = 'ShortPixel Compression';
|
2236 |
-
return $defaults;
|
2237 |
-
}
|
2238 |
-
|
2239 |
-
public function nggCountColumns( $count ) {
|
2240 |
-
return $count + 1;
|
2241 |
-
}
|
2242 |
-
|
2243 |
-
public function nggColumnHeader( $default ) {
|
2244 |
-
return __('ShortPixel Compression','shortpixel-image-optimiser');
|
2245 |
-
}
|
2246 |
-
|
2247 |
-
public function nggColumnContent( $unknown, $picture ) {
|
2248 |
-
|
2249 |
-
$meta = $this->spMetaDao->getMetaForPath($picture->imagePath);
|
2250 |
-
if($meta) {
|
2251 |
-
switch($meta->getStatus()) {
|
2252 |
-
case "0": echo("<div id='sp-msg-C-{$meta->getId()}' class='column-wp-shortPixel' style='color: #928B1E'>Waiting</div>"); break;
|
2253 |
-
case "1": echo("<div id='sp-msg-C-{$meta->getId()}' class='column-wp-shortPixel' style='color: #1919E2'>Pending</div>"); break;
|
2254 |
-
case "2": $this->view->renderCustomColumn("C-" . $meta->getId(), array(
|
2255 |
-
'showActions' => false && current_user_can( 'manage_options' ),
|
2256 |
-
'status' => 'imgOptimized',
|
2257 |
-
'type' => ShortPixelAPI::getCompressionTypeName($meta->getCompressionType()),
|
2258 |
-
'percent' => $meta->getImprovementPercent(),
|
2259 |
-
'bonus' => $meta->getImprovementPercent() < 5,
|
2260 |
-
'thumbsOpt' => 0,
|
2261 |
-
'thumbsTotal' => 0,
|
2262 |
-
'retinasOpt' => 0,
|
2263 |
-
'backup' => true
|
2264 |
-
));
|
2265 |
-
break;
|
2266 |
-
}
|
2267 |
-
} else {
|
2268 |
-
$this->view->renderCustomColumn($meta ? "C-" . $meta->getId() : "N-" . $picture->pid, array(
|
2269 |
-
'showActions' => false && current_user_can( 'manage_options' ),
|
2270 |
-
'status' => 'optimizeNow',
|
2271 |
-
'thumbsOpt' => 0,
|
2272 |
-
'thumbsTotal' => 0,
|
2273 |
-
'retinasOpt' => 0,
|
2274 |
-
'message' => "Not optimized"
|
2275 |
-
));
|
2276 |
-
}
|
2277 |
-
// return var_dump($meta);
|
2278 |
-
}
|
2279 |
-
|
2280 |
-
public function generatePluginLinks($links) {
|
2281 |
-
$in = '<a href="options-general.php?page=wp-shortpixel">Settings</a>';
|
2282 |
-
array_unshift($links, $in);
|
2283 |
-
return $links;
|
2284 |
-
}
|
2285 |
-
|
2286 |
-
static public function formatBytes($bytes, $precision = 2) {
|
2287 |
-
$units = array('B', 'KB', 'MB', 'GB', 'TB');
|
2288 |
-
|
2289 |
-
$bytes = max($bytes, 0);
|
2290 |
-
$pow = floor(($bytes ? log($bytes) : 0) / log(1024));
|
2291 |
-
$pow = min($pow, count($units) - 1);
|
2292 |
-
|
2293 |
-
$bytes /= pow(1024, $pow);
|
2294 |
-
|
2295 |
-
return round($bytes, $precision) . ' ' . $units[$pow];
|
2296 |
-
}
|
2297 |
-
|
2298 |
-
static public function isProcessable($ID) {
|
2299 |
-
$path = get_attached_file($ID);//get the full file PATH
|
2300 |
-
return $path ? self::isProcessablePath($path) : false;
|
2301 |
-
}
|
2302 |
-
|
2303 |
-
static public function isProcessablePath($path) {
|
2304 |
-
$pathParts = pathinfo($path);
|
2305 |
-
$ext = $pathParts['extension'];
|
2306 |
-
if( isset($ext) && in_array(strtolower($ext), self::$PROCESSABLE_EXTENSIONS)) {
|
2307 |
-
return true;
|
2308 |
-
} else {
|
2309 |
-
return false;
|
2310 |
-
}
|
2311 |
-
}
|
2312 |
-
|
2313 |
-
|
2314 |
-
//return an array with URL(s) and PATH(s) for this file
|
2315 |
-
public function getURLsAndPATHs($itemHandler, $meta = NULL, $onlyThumbs = false) {
|
2316 |
-
return $itemHandler->getURLsAndPATHs($this->_settings->processThumbnails, $onlyThumbs, $this->_settings->optimizeRetina);
|
2317 |
-
}
|
2318 |
-
|
2319 |
-
|
2320 |
-
public static function deleteDir($dirPath) {
|
2321 |
-
if (substr($dirPath, strlen($dirPath) - 1, 1) != '/') {
|
2322 |
-
$dirPath .= '/';
|
2323 |
-
}
|
2324 |
-
$files = glob($dirPath . '*', GLOB_MARK);
|
2325 |
-
foreach ($files as $file) {
|
2326 |
-
if (is_dir($file)) {
|
2327 |
-
self::deleteDir($file);
|
2328 |
-
@rmdir($file);//remove empty dir
|
2329 |
-
} else {
|
2330 |
-
@unlink($file);//remove file
|
2331 |
-
}
|
2332 |
-
}
|
2333 |
-
}
|
2334 |
-
|
2335 |
-
static public function folderSize($path) {
|
2336 |
-
$total_size = 0;
|
2337 |
-
if(file_exists($path)) {
|
2338 |
-
$files = scandir($path);
|
2339 |
-
} else {
|
2340 |
-
return $total_size;
|
2341 |
-
}
|
2342 |
-
$cleanPath = rtrim($path, '/'). '/';
|
2343 |
-
foreach($files as $t) {
|
2344 |
-
if ($t<>"." && $t<>"..")
|
2345 |
-
{
|
2346 |
-
$currentFile = $cleanPath . $t;
|
2347 |
-
if (is_dir($currentFile)) {
|
2348 |
-
$size = self::folderSize($currentFile);
|
2349 |
-
$total_size += $size;
|
2350 |
-
}
|
2351 |
-
else {
|
2352 |
-
$size = filesize($currentFile);
|
2353 |
-
$total_size += $size;
|
2354 |
-
}
|
2355 |
-
}
|
2356 |
-
}
|
2357 |
-
return $total_size;
|
2358 |
-
}
|
2359 |
-
|
2360 |
-
public function migrateBackupFolder() {
|
2361 |
-
$oldBackupFolder = WP_CONTENT_DIR . '/' . SP_BACKUP;
|
2362 |
-
|
2363 |
-
if(file_exists($oldBackupFolder)) { //if old backup folder does not exist then there is nothing to do
|
2364 |
-
|
2365 |
-
if(!file_exists(SP_BACKUP_FOLDER)) {
|
2366 |
-
//we check that the backup folder exists, if not we create it so we can copy into it
|
2367 |
-
if(!mkdir(SP_BACKUP_FOLDER, 0777, true)) return;
|
2368 |
-
}
|
2369 |
-
|
2370 |
-
$scannedDirectory = array_diff(scandir($oldBackupFolder), array('..', '.'));
|
2371 |
-
foreach($scannedDirectory as $file) {
|
2372 |
-
@rename($oldBackupFolder.'/'.$file, SP_BACKUP_FOLDER.'/'.$file);
|
2373 |
-
}
|
2374 |
-
$scannedDirectory = array_diff(scandir($oldBackupFolder), array('..', '.'));
|
2375 |
-
if(empty($scannedDirectory)) {
|
2376 |
-
@rmdir($oldBackupFolder);
|
2377 |
-
}
|
2378 |
-
}
|
2379 |
-
//now if the backup folder does not contain the uploads level, create it
|
2380 |
-
if( !is_dir(SP_BACKUP_FOLDER . '/' . SP_UPLOADS_NAME )
|
2381 |
-
&& !is_dir(SP_BACKUP_FOLDER . '/' . basename(WP_CONTENT_DIR))) {
|
2382 |
-
@rename(SP_BACKUP_FOLDER, SP_BACKUP_FOLDER."_tmp");
|
2383 |
-
@mkdir(SP_BACKUP_FOLDER);
|
2384 |
-
@rename(SP_BACKUP_FOLDER."_tmp", SP_BACKUP_FOLDER.'/'.SP_UPLOADS_NAME);
|
2385 |
-
if(!file_exists(SP_BACKUP_FOLDER)) {//just in case..
|
2386 |
-
@rename(SP_BACKUP_FOLDER."_tmp", SP_BACKUP_FOLDER);
|
2387 |
-
}
|
2388 |
-
}
|
2389 |
-
//then create the wp-content level if not present
|
2390 |
-
if(!is_dir(SP_BACKUP_FOLDER . '/' . basename(WP_CONTENT_DIR))) {
|
2391 |
-
@rename(SP_BACKUP_FOLDER, SP_BACKUP_FOLDER."_tmp");
|
2392 |
-
@mkdir(SP_BACKUP_FOLDER);
|
2393 |
-
@rename(SP_BACKUP_FOLDER."_tmp", SP_BACKUP_FOLDER.'/' . basename(WP_CONTENT_DIR));
|
2394 |
-
if(!file_exists(SP_BACKUP_FOLDER)) {//just in case..
|
2395 |
-
@rename(SP_BACKUP_FOLDER."_tmp", SP_BACKUP_FOLDER);
|
2396 |
-
}
|
2397 |
-
}
|
2398 |
-
return;
|
2399 |
-
}
|
2400 |
-
|
2401 |
-
function getMaxIntermediateImageSize() {
|
2402 |
-
global $_wp_additional_image_sizes;
|
2403 |
-
|
2404 |
-
$width = 0;
|
2405 |
-
$height = 0;
|
2406 |
-
$get_intermediate_image_sizes = get_intermediate_image_sizes();
|
2407 |
-
|
2408 |
-
// Create the full array with sizes and crop info
|
2409 |
-
foreach( $get_intermediate_image_sizes as $_size ) {
|
2410 |
-
if ( in_array( $_size, array( 'thumbnail', 'medium', 'large' ) ) ) {
|
2411 |
-
$width = max($width, get_option( $_size . '_size_w' ));
|
2412 |
-
$height = max($height, get_option( $_size . '_size_h' ));
|
2413 |
-
//$sizes[ $_size ]['crop'] = (bool) get_option( $_size . '_crop' );
|
2414 |
-
} elseif ( isset( $_wp_additional_image_sizes[ $_size ] ) ) {
|
2415 |
-
$width = max($width, $_wp_additional_image_sizes[ $_size ]['width']);
|
2416 |
-
$height = max($height, $_wp_additional_image_sizes[ $_size ]['height']);
|
2417 |
-
//'crop' => $_wp_additional_image_sizes[ $_size ]['crop']
|
2418 |
-
}
|
2419 |
-
}
|
2420 |
-
return array('width' => $width, 'height' => $height);
|
2421 |
-
}
|
2422 |
-
|
2423 |
-
/* public function getEncryptedData() {
|
2424 |
-
return base64_encode(self::encrypt($this->getApiKey() . "|" . get_site_url(), "sh0r+Pix3l8im1N3r"));
|
2425 |
-
}
|
2426 |
-
*/
|
2427 |
-
|
2428 |
-
/**
|
2429 |
-
* Returns an encrypted & utf8-encoded
|
2430 |
-
*/
|
2431 |
-
/* public static function encrypt($pure_string, $encryption_key)
|
2432 |
-
{
|
2433 |
-
if(!function_exists("mcrypt_get_iv_size") || !function_exists('utf8_encode')) {
|
2434 |
-
return "";
|
2435 |
-
}
|
2436 |
-
$iv_size = \mcrypt_get_iv_size(MCRYPT_BLOWFISH, MCRYPT_MODE_ECB);
|
2437 |
-
$iv = \mcrypt_create_iv($iv_size, MCRYPT_RAND);
|
2438 |
-
$encrypted_string = \mcrypt_encrypt(MCRYPT_BLOWFISH, $encryption_key, utf8_encode($pure_string), MCRYPT_MODE_ECB, $iv);
|
2439 |
-
return $encrypted_string;
|
2440 |
-
}
|
2441 |
-
*/
|
2442 |
-
|
2443 |
-
public function getApiKey() {
|
2444 |
-
return $this->_settings->apiKey;
|
2445 |
-
}
|
2446 |
-
|
2447 |
-
public function getPrioQ() {
|
2448 |
-
return $this->prioQ;
|
2449 |
-
}
|
2450 |
-
|
2451 |
-
public function backupImages() {
|
2452 |
-
return $this->_settings->backupImages;
|
2453 |
-
}
|
2454 |
-
|
2455 |
-
public function processThumbnails() {
|
2456 |
-
return $this->_settings->processThumbnails;
|
2457 |
-
}
|
2458 |
-
|
2459 |
-
public function getCMYKtoRGBconversion() {
|
2460 |
-
return $this->_settings->CMYKtoRGBconversion;
|
2461 |
-
}
|
2462 |
-
|
2463 |
-
public function getSettings() {
|
2464 |
-
return $this->_settings;
|
2465 |
-
}
|
2466 |
-
|
2467 |
-
public function getResizeImages() {
|
2468 |
-
return $this->_settings->resizeImages;
|
2469 |
-
}
|
2470 |
-
|
2471 |
-
public function getResizeWidth() {
|
2472 |
-
return $this->_settings->resizeWidth;
|
2473 |
-
}
|
2474 |
-
|
2475 |
-
public function getResizeHeight() {
|
2476 |
-
return $this->_settings->resizeHeight;
|
2477 |
-
}
|
2478 |
-
public function getAffiliateSufix() {
|
2479 |
-
return $this->_affiliateSufix;
|
2480 |
-
}
|
2481 |
-
public function getVerifiedKey() {
|
2482 |
-
return $this->_settings->verifiedKey;
|
2483 |
-
}
|
2484 |
-
public function getCompressionType() {
|
2485 |
-
return $this->_settings->compressionType;
|
2486 |
-
}
|
2487 |
-
public function hasNextGen() {
|
2488 |
-
return $this->hasNextGen;
|
2489 |
-
}
|
2490 |
-
|
2491 |
-
public function getSpMetaDao() {
|
2492 |
-
return $this->spMetaDao;
|
2493 |
-
}
|
2494 |
-
|
2495 |
-
}
|
2496 |
-
|
2497 |
-
|
2498 |
function shortpixelInit() {
|
2499 |
global $pluginInstance;
|
2500 |
//is admin, is logged in - :) seems funny but it's not, ajax scripts are admin even if no admin is logged in.
|
@@ -2510,6 +61,7 @@ function shortpixelInit() {
|
|
2510 |
)
|
2511 |
)
|
2512 |
{
|
|
|
2513 |
$pluginInstance = new WPShortPixel;
|
2514 |
}
|
2515 |
}
|
@@ -2517,6 +69,7 @@ function shortpixelInit() {
|
|
2517 |
function handleImageUploadHook($meta, $ID = null) {
|
2518 |
global $pluginInstance;
|
2519 |
if(!isset($pluginInstance)) {
|
|
|
2520 |
$pluginInstance = new WPShortPixel;
|
2521 |
}
|
2522 |
return $pluginInstance->handleMediaLibraryImageUpload($meta, $ID);
|
@@ -2525,6 +78,7 @@ function handleImageUploadHook($meta, $ID = null) {
|
|
2525 |
function shortpixelNggAdd($image) {
|
2526 |
global $pluginInstance;
|
2527 |
if(!isset($pluginInstance)) {
|
|
|
2528 |
$pluginInstance = new WPShortPixel;
|
2529 |
}
|
2530 |
$pluginInstance->handleNextGenImageUpload($image);
|
@@ -2543,4 +97,4 @@ if ( !function_exists( 'vc_action' ) || vc_action() !== 'vc_inline' ) { //handle
|
|
2543 |
register_deactivation_hook( __FILE__, array( 'WPShortPixel', 'shortPixelDeactivatePlugin' ) );
|
2544 |
|
2545 |
}
|
2546 |
-
?>
|
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.2.8
|
7 |
* Author: ShortPixel
|
8 |
* Author URI: https://shortpixel.com
|
9 |
* Text Domain: shortpixel-image-optimiser
|
14 |
|
15 |
//define('SHORTPIXEL_DEBUG', true);
|
16 |
|
17 |
+
define('SHORTPIXEL_PLUGIN_FILE', __FILE__);
|
18 |
+
|
19 |
define('SP_AFFILIATE_CODE', '');
|
20 |
|
21 |
+
define('PLUGIN_VERSION', "4.2.8");
|
22 |
define('SP_MAX_TIMEOUT', 10);
|
23 |
define('SP_VALIDATE_MAX_TIMEOUT', 15);
|
24 |
define('SP_BACKUP', 'ShortpixelBackups');
|
46 |
define('MAX_EXECUTION_TIME', 2 );
|
47 |
define("SP_MAX_RESULTS_QUERY", 6);
|
48 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
49 |
function shortpixelInit() {
|
50 |
global $pluginInstance;
|
51 |
//is admin, is logged in - :) seems funny but it's not, ajax scripts are admin even if no admin is logged in.
|
61 |
)
|
62 |
)
|
63 |
{
|
64 |
+
require_once('wp-shortpixel-req.php');
|
65 |
$pluginInstance = new WPShortPixel;
|
66 |
}
|
67 |
}
|
69 |
function handleImageUploadHook($meta, $ID = null) {
|
70 |
global $pluginInstance;
|
71 |
if(!isset($pluginInstance)) {
|
72 |
+
require_once('wp-shortpixel-req.php');
|
73 |
$pluginInstance = new WPShortPixel;
|
74 |
}
|
75 |
return $pluginInstance->handleMediaLibraryImageUpload($meta, $ID);
|
78 |
function shortpixelNggAdd($image) {
|
79 |
global $pluginInstance;
|
80 |
if(!isset($pluginInstance)) {
|
81 |
+
require_once('wp-shortpixel-req.php');
|
82 |
$pluginInstance = new WPShortPixel;
|
83 |
}
|
84 |
$pluginInstance->handleNextGenImageUpload($image);
|
97 |
register_deactivation_hook( __FILE__, array( 'WPShortPixel', 'shortPixelDeactivatePlugin' ) );
|
98 |
|
99 |
}
|
100 |
+
?>
|