Version Description
Release date: 9th October 2019 * Don't convert to
Download this release
Release Info
Developer | ShortPixel |
Plugin | ShortPixel Image Optimizer |
Version | 4.14.6 |
Comparing to | |
See all releases |
Code changes from version 4.14.5 to 4.14.6
- build/shortpixel/autoload.php +1 -1
- class/controller/edit_media_controller.php +252 -0
- class/controller/filesystem_controller.php +10 -4
- class/controller/settings.php +10 -0
- class/db/shortpixel-custom-meta-dao.php +3 -4
- class/db/shortpixel-meta-facade.php +84 -50
- class/db/wp-shortpixel-media-library-adapter.php +365 -11
- class/external/wp-offload-media.php +29 -1
- class/front/img-to-picture-webp.php +4 -0
- class/model/directory_model.php +1 -1
- class/model/file_model.php +3 -0
- class/model/image_model.php +194 -0
- class/shortpixel-png2jpg.php +12 -5
- class/view/settings/part-debug.php +8 -0
- class/view/settings/part-general.php +4 -4
- class/view/shortpixel_view.php +13 -3
- class/view/view-edit-media.php +57 -0
- class/wp-short-pixel.php +34 -73
- readme.txt +20 -1
- res/css/shortpixel-admin.css +21 -0
- res/js/shortpixel.js +3 -4
- res/js/shortpixel.min.js +1 -1
- res/scss/shortpixel-admin.scss +2 -1
- res/scss/view/_edit-media.scss +48 -0
- shortpixel_api.php +2 -0
- wp-shortpixel.php +2 -2
build/shortpixel/autoload.php
CHANGED
@@ -1,5 +1,5 @@
|
|
1 |
<?php
|
2 |
-
require_once "PackageLoader.php";
|
3 |
$loader = new ShortPixel\Build\PackageLoader();
|
4 |
$loader->load(__DIR__);
|
5 |
|
1 |
<?php
|
2 |
+
require_once (dirname(__FILE__) . "/PackageLoader.php");
|
3 |
$loader = new ShortPixel\Build\PackageLoader();
|
4 |
$loader->load(__DIR__);
|
5 |
|
class/controller/edit_media_controller.php
ADDED
@@ -0,0 +1,252 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
namespace ShortPixel;
|
3 |
+
use ShortPixel\ShortpixelLogger\ShortPixelLogger as Log;
|
4 |
+
|
5 |
+
// Future contoller for the edit media metabox view.
|
6 |
+
class editMediaController extends ShortPixelController
|
7 |
+
{
|
8 |
+
//$this->model = new
|
9 |
+
protected $template = 'view-edit-media';
|
10 |
+
protected $model = 'image';
|
11 |
+
|
12 |
+
private $post_id;
|
13 |
+
private $actions_allowed;
|
14 |
+
|
15 |
+
private $legacyViewObj;
|
16 |
+
|
17 |
+
public function __construct()
|
18 |
+
{
|
19 |
+
|
20 |
+
$this->loadModel($this->model);
|
21 |
+
parent::__construct();
|
22 |
+
}
|
23 |
+
|
24 |
+
// This data should be rendered by Image Model in the future.
|
25 |
+
public function setTempData($data)
|
26 |
+
{
|
27 |
+
$this->data = $data;
|
28 |
+
}
|
29 |
+
|
30 |
+
public function load($post_id)
|
31 |
+
{
|
32 |
+
$this->post_id = $post_id;
|
33 |
+
|
34 |
+
$this->imageModel = new ImageModel();
|
35 |
+
$this->imageModel->setByPostID($post_id);
|
36 |
+
$this->imageModel->reAcquire(); // single display mode - reset things.
|
37 |
+
|
38 |
+
$this->view->id = $post_id;
|
39 |
+
$this->view->status_message = null;
|
40 |
+
|
41 |
+
$this->actions_allowed = $this->checkUserPrivileges();
|
42 |
+
|
43 |
+
$this->view->status_message = $this->getStatusMessage();
|
44 |
+
$this->view->actions = $this->getActions();
|
45 |
+
$this->view->stats = $this->getStatistics();
|
46 |
+
$this->view->todo = $this->getTodo();
|
47 |
+
$this->view->debugInfo = $this->getDebugInfo();
|
48 |
+
|
49 |
+
$this->view->message = isset($this->data['message']) ? $this->data['message'] : '';
|
50 |
+
//$this->view->r
|
51 |
+
$this->loadView();
|
52 |
+
|
53 |
+
}
|
54 |
+
|
55 |
+
|
56 |
+
// The old view, we are trying to get rid of.
|
57 |
+
public function setLegacyView($legacyView)
|
58 |
+
{
|
59 |
+
$this->legacyViewObj = $legacyView;
|
60 |
+
}
|
61 |
+
|
62 |
+
protected function getStatusMessage()
|
63 |
+
{
|
64 |
+
if (! isset($this->data['status']))
|
65 |
+
return;
|
66 |
+
|
67 |
+
switch($this->data['status'])
|
68 |
+
{
|
69 |
+
case 'n/a':
|
70 |
+
return _e('Optimization N/A','shortpixel-image-optimiser');
|
71 |
+
break;
|
72 |
+
case 'notFound':
|
73 |
+
return _e('Image does not exist.','shortpixel-image-optimiser');
|
74 |
+
break;
|
75 |
+
case 'invalidKey':
|
76 |
+
return _e('Invalid API Key. <a href="options-general.php?page=wp-shortpixel-settings">Check your Settings</a>','shortpixel-image-optimiser');
|
77 |
+
break;
|
78 |
+
case 'quotaExceeded':
|
79 |
+
return __('Quota Exceeded','shortpixel-image-optimiser');
|
80 |
+
break;
|
81 |
+
}
|
82 |
+
}
|
83 |
+
|
84 |
+
protected function getActions()
|
85 |
+
{
|
86 |
+
$actions = array();
|
87 |
+
if (! $this->actions_allowed)
|
88 |
+
return $actions;
|
89 |
+
|
90 |
+
switch($this->data['status'])
|
91 |
+
{
|
92 |
+
case 'optimizeNow':
|
93 |
+
$actions[] = '<a class="button button-smaller button-primary" href="javascript:manualOptimization(' . $this->post_id . ',false)">
|
94 |
+
' . __('Optimize now','shortpixel-image-optimiser') . '
|
95 |
+
</a>';
|
96 |
+
break;
|
97 |
+
case 'retry':
|
98 |
+
case 'waiting':
|
99 |
+
if (isset($this->data['cleanup']))
|
100 |
+
{
|
101 |
+
$actions[] = '<a class="button button-smaller button-primary" href="javascript:manualOptimization(' . $this->post_id . ', true)">' .
|
102 |
+
__('Cleanup&Retry','shortpixel-image-optimiser') . '</a>';
|
103 |
+
}
|
104 |
+
else {
|
105 |
+
if($this->data['status'] == 'retry' && (isset($this->data['backup']) && $this->data['backup']) ) {
|
106 |
+
$actions[] = '<a class="button button-smaller sp-action-restore"
|
107 |
+
href="admin.php?action=shortpixel_restore_backup&attachment_ID=' . $this->post_id . '" style="margin-left:5px;"
|
108 |
+
title="' . __('Restore Image from Backup', 'shortpixel-image-optimiser') . '">
|
109 |
+
' . __('Cleanup','shortpixel-image-optimiser') . '</a>';
|
110 |
+
|
111 |
+
}
|
112 |
+
$actions[] = '<a class="button button-smaller button-primary" href="javascript:manualOptimization(' . $this->post_id . ', false)">' .
|
113 |
+
__('Retry','shortpixel-image-optimiser') . '</a>';
|
114 |
+
}
|
115 |
+
break;
|
116 |
+
}
|
117 |
+
|
118 |
+
return $actions;
|
119 |
+
}
|
120 |
+
|
121 |
+
protected function getStatistics()
|
122 |
+
{
|
123 |
+
$data = $this->data;
|
124 |
+
|
125 |
+
if ( $data['status'] != 'pdfOptimized' && $data['status'] != 'imgOptimized')
|
126 |
+
return array();
|
127 |
+
|
128 |
+
$stats = array();
|
129 |
+
if ($data['percent'] && $data['percent'] > 0)
|
130 |
+
{
|
131 |
+
$stats[] = array(__('Reduced by','shortpixel-image-optimiser'), '<strong>' . $data['percent'] . '% </strong>');
|
132 |
+
}
|
133 |
+
|
134 |
+
$stats[] = array(__('Type: ', 'shortpixel-image-optimiser'), $data['type']);
|
135 |
+
if ($data['bonus'])
|
136 |
+
$stats[] = array(__('Bonus processing','shortpixel-image-optimiser'), '');
|
137 |
+
|
138 |
+
if ($data['thumbsOpt'])
|
139 |
+
{
|
140 |
+
if ($data['thumbsTotal'] > $data['thumbsOpt'] )
|
141 |
+
$stats[] = array(sprintf(__('+%s of %s thumbnails optimized','shortpixel-image-optimiser'),$data['thumbsOpt'],$data['thumbsTotal']), '');
|
142 |
+
else
|
143 |
+
$stats[] = array(sprintf(__('+ %s thumbnails optimized','shortpixel-image-optimiser'),$data['thumbsOpt']), '');
|
144 |
+
}
|
145 |
+
|
146 |
+
if ($data['retinasOpt'])
|
147 |
+
{
|
148 |
+
$stats[] = array(sprintf(__('+%s Retina images optimized','shortpixel-image-optimiser') , $data['retinasOpt']), '');
|
149 |
+
}
|
150 |
+
|
151 |
+
if ($data['webpCount'])
|
152 |
+
{
|
153 |
+
$stats[] = array(__(" WebP images", 'shortpixel-image-optimiser'), $data['webpCount']);
|
154 |
+
}
|
155 |
+
if ($data['exifKept'])
|
156 |
+
$stats[] = array(__('EXIF kept', 'shortpixel-image-optimiser'), '');
|
157 |
+
else {
|
158 |
+
$stats[] = array(__('EXIF removed', 'shortpixel-image-optimiser'), '');
|
159 |
+
}
|
160 |
+
|
161 |
+
if ($data['png2jpg'])
|
162 |
+
{
|
163 |
+
$stats[] = array( __('Converted from PNG','shortpixel-image-optimiser'), '');
|
164 |
+
}
|
165 |
+
|
166 |
+
$stats[] = array(__("Optimized on", 'shortpixel-image-optimiser') . ": " . $data['date'], '');
|
167 |
+
|
168 |
+
|
169 |
+
/* $successText .= ($data['webpCount'] ? "<br>+" . $data['webpCount'] . __(" WebP images", 'shortpixel-image-optimiser') : "")
|
170 |
+
. "<br>EXIF: " . ($data['exifKept'] ? __('kept','shortpixel-image-optimiser') : __('removed','shortpixel-image-optimiser'))
|
171 |
+
. ($data['png2jpg'] ? '<br>' . __('Converted from PNG','shortpixel-image-optimiser'): '')
|
172 |
+
. "<br>" . __("Optimized on", 'shortpixel-image-optimiser') . ": " . $data['date']
|
173 |
+
. $todoSizes . $excludeSizes . $missingThumbs;
|
174 |
+
*/
|
175 |
+
return $stats;
|
176 |
+
}
|
177 |
+
|
178 |
+
protected function getTodo()
|
179 |
+
{
|
180 |
+
$data = $this->data;
|
181 |
+
if ( $data['status'] != 'pdfOptimized' && $data['status'] != 'imgOptimized')
|
182 |
+
return array();
|
183 |
+
|
184 |
+
$excluded = (isset($data['excludeSizes']) ? count($data['excludeSizes']) : 0);
|
185 |
+
$todoSizes = $missingThumbs = $excludeSizes = '';
|
186 |
+
|
187 |
+
if(isset($data['thumbsToOptimizeList']) && count($data['thumbsToOptimizeList'])) {
|
188 |
+
$todoSizes .= "<br><span style='word-break: break-all;'> <span style='font-weight: bold;'>" . __("To optimize:", 'shortpixel-image-optimiser') . "</span>";
|
189 |
+
foreach($data['thumbsToOptimizeList'] as $todoItem) {
|
190 |
+
$todoSizes .= "<br> • " . $todoItem;
|
191 |
+
}
|
192 |
+
$todoSizes .= '</span>';
|
193 |
+
}
|
194 |
+
if(isset($data['excludeSizes']) && count($data['excludeSizes']) > 0 ) {
|
195 |
+
$excludeSizes .= "<br><span style='word-break: break-all;'> <span style='font-weight: bold;'>" . __("Excluded thumbnails:", 'shortpixel-image-optimiser') . "</span>";
|
196 |
+
foreach($data['excludeSizes'] as $excludedItem) {
|
197 |
+
$excludeSizes .= "<br> • " . $excludedItem;
|
198 |
+
}
|
199 |
+
$excludeSizes .= '</span>';
|
200 |
+
}
|
201 |
+
if(count($data['thumbsMissing'])) {
|
202 |
+
$missingThumbs .= "<br><span style='word-break: break-all;'> <span style='font-weight: bold;'>" . __("Missing thumbnails:", 'shortpixel-image-optimiser') . "</span>";
|
203 |
+
foreach($data['thumbsMissing'] as $miss) {
|
204 |
+
$missingThumbs .= "<br> • " . $miss;
|
205 |
+
}
|
206 |
+
$missingThumbs .= '</span>';
|
207 |
+
}
|
208 |
+
|
209 |
+
return array($todoSizes, $excludeSizes, $missingThumbs);
|
210 |
+
}
|
211 |
+
|
212 |
+
protected function getDebugInfo()
|
213 |
+
{
|
214 |
+
if(! Log::debugIsActive())
|
215 |
+
{
|
216 |
+
return null;
|
217 |
+
}
|
218 |
+
|
219 |
+
$sizes = isset($this->data['sizes']) ? $this->data['sizes'] : array();
|
220 |
+
|
221 |
+
$debugInfo = array();
|
222 |
+
$debugInfo[] = array(__('URL', 'shortpixel_image_optiser'), wp_get_attachment_url($this->post_id));
|
223 |
+
$debugInfo[] = array(__('WPML Duplicates'), json_encode(\ShortPixelMetaFacade::getWPMLDuplicates($this->post_id)) );
|
224 |
+
$debugInfo[] = array(__('Data'), $this->data);
|
225 |
+
$debugInfo[] = array(__('Meta'), wp_get_attachment_metadata($this->post_id) );
|
226 |
+
$debugInfo[] = array(__('Backup Folder'), $this->shortPixel->getBackupFolderAny($this->imageModel->getFile()->getFullPath(), $sizes));
|
227 |
+
$debugInfo[] = array(__('Status'), $this->imageModel->getMeta()->getStatus() );
|
228 |
+
|
229 |
+
return $debugInfo;
|
230 |
+
}
|
231 |
+
|
232 |
+
protected function renderLegacyCell()
|
233 |
+
{
|
234 |
+
|
235 |
+
$data = $this->data;
|
236 |
+
|
237 |
+
if ( $data['status'] != 'pdfOptimized' && $data['status'] != 'imgOptimized')
|
238 |
+
return null;
|
239 |
+
|
240 |
+
$this->legacyViewObj->renderListCell($this->post_id, $data['status'], $data['showActions'], $data['thumbsToOptimize'],
|
241 |
+
$data['backup'], $data['type'], $data['invType'], '');
|
242 |
+
}
|
243 |
+
|
244 |
+
private function checkUserPrivileges()
|
245 |
+
{
|
246 |
+
if ((current_user_can( 'manage_options' ) || current_user_can( 'upload_files' ) || current_user_can( 'edit_posts' )))
|
247 |
+
return true;
|
248 |
+
|
249 |
+
return false;
|
250 |
+
}
|
251 |
+
|
252 |
+
} // controller .
|
class/controller/filesystem_controller.php
CHANGED
@@ -87,22 +87,28 @@ Class FileSystemController extends ShortPixelController
|
|
87 |
// stolen from wp_get_attachment_url
|
88 |
if ( ( $uploads = wp_get_upload_dir() ) && false === $uploads['error'] ) {
|
89 |
// Check that the upload base exists in the file location.
|
90 |
-
if ( 0 === strpos( $
|
91 |
// Replace file location with url location.
|
92 |
$url = str_replace( $uploads['basedir'], $uploads['baseurl'], $filepath );
|
93 |
-
} elseif ( false !== strpos( $
|
94 |
// Get the directory name relative to the basedir (back compat for pre-2.7 uploads)
|
95 |
-
$url = trailingslashit( $uploads['baseurl'] . '/' . _wp_get_attachment_relative_path( $
|
96 |
} else {
|
97 |
// It's a newly-uploaded file, therefore $file is relative to the basedir.
|
98 |
$url = $uploads['baseurl'] . "/$filepath";
|
99 |
}
|
100 |
}
|
101 |
-
|
|
|
|
|
|
|
|
|
|
|
102 |
}
|
103 |
|
104 |
|
105 |
|
106 |
|
107 |
|
|
|
108 |
}
|
87 |
// stolen from wp_get_attachment_url
|
88 |
if ( ( $uploads = wp_get_upload_dir() ) && false === $uploads['error'] ) {
|
89 |
// Check that the upload base exists in the file location.
|
90 |
+
if ( 0 === strpos( $filepath, $uploads['basedir'] ) ) {
|
91 |
// Replace file location with url location.
|
92 |
$url = str_replace( $uploads['basedir'], $uploads['baseurl'], $filepath );
|
93 |
+
} elseif ( false !== strpos( $filepath, 'wp-content/uploads' ) ) {
|
94 |
// Get the directory name relative to the basedir (back compat for pre-2.7 uploads)
|
95 |
+
$url = trailingslashit( $uploads['baseurl'] . '/' . _wp_get_attachment_relative_path( $filepath ) ) . wp_basename( $filepath );
|
96 |
} else {
|
97 |
// It's a newly-uploaded file, therefore $file is relative to the basedir.
|
98 |
$url = $uploads['baseurl'] . "/$filepath";
|
99 |
}
|
100 |
}
|
101 |
+
|
102 |
+
if (parse_url($url) !== false)
|
103 |
+
return $url;
|
104 |
+
else {
|
105 |
+
return false;
|
106 |
+
}
|
107 |
}
|
108 |
|
109 |
|
110 |
|
111 |
|
112 |
|
113 |
+
|
114 |
}
|
class/controller/settings.php
CHANGED
@@ -94,6 +94,16 @@ class SettingsController extends shortPixelController
|
|
94 |
|
95 |
}
|
96 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
97 |
public function processSave()
|
98 |
{
|
99 |
Log::addDebug('after process postData', $this->postData);
|
94 |
|
95 |
}
|
96 |
|
97 |
+
public function action_debug_medialibrary()
|
98 |
+
{
|
99 |
+
$this->loadEnv();
|
100 |
+
$this->loadModel('image');
|
101 |
+
|
102 |
+
\WpShortPixelMediaLbraryAdapter::reCountMediaLibraryItems();
|
103 |
+
|
104 |
+
$this->load();
|
105 |
+
}
|
106 |
+
|
107 |
public function processSave()
|
108 |
{
|
109 |
Log::addDebug('after process postData', $this->postData);
|
class/db/shortpixel-custom-meta-dao.php
CHANGED
@@ -479,7 +479,7 @@ class ShortPixelCustomMetaDao {
|
|
479 |
|
480 |
public function update($meta) {
|
481 |
$metaClass = get_class($meta);
|
482 |
-
|
483 |
$tableSuffix = $metaClass::TABLE_SUFFIX;
|
484 |
$prefix = $this->db->getPrefix();
|
485 |
|
@@ -507,9 +507,8 @@ class ShortPixelCustomMetaDao {
|
|
507 |
|
508 |
public function delete($meta) {
|
509 |
$metaClass = get_class($meta);
|
510 |
-
$tableSuffix =
|
511 |
-
//
|
512 |
-
eval( '$tableSuffix = ' . $metaClass . '::TABLE_SUFFIX;');
|
513 |
$sql = "DELETE FROM {$this->db->getPrefix()}shortpixel_" . $tableSuffix . " WHERE id = %d";
|
514 |
$this->db->query($sql, array($meta->getId()));
|
515 |
}
|
479 |
|
480 |
public function update($meta) {
|
481 |
$metaClass = get_class($meta);
|
482 |
+
//$tableSuffix = "";
|
483 |
$tableSuffix = $metaClass::TABLE_SUFFIX;
|
484 |
$prefix = $this->db->getPrefix();
|
485 |
|
507 |
|
508 |
public function delete($meta) {
|
509 |
$metaClass = get_class($meta);
|
510 |
+
$tableSuffix = $metaClass::TABLE_SUFFIX;
|
511 |
+
//eval( '$tableSuffix = ' . $metaClass . '::TABLE_SUFFIX;');
|
|
|
512 |
$sql = "DELETE FROM {$this->db->getPrefix()}shortpixel_" . $tableSuffix . " WHERE id = %d";
|
513 |
$this->db->query($sql, array($meta->getId()));
|
514 |
}
|
class/db/shortpixel-meta-facade.php
CHANGED
@@ -101,7 +101,7 @@ class ShortPixelMetaFacade {
|
|
101 |
return $rawMeta;
|
102 |
}
|
103 |
|
104 |
-
//
|
105 |
public function updateMeta($newMeta = null, $replaceThumbs = false) {
|
106 |
if($newMeta) {
|
107 |
$this->meta = $newMeta;
|
@@ -251,7 +251,7 @@ class ShortPixelMetaFacade {
|
|
251 |
}
|
252 |
|
253 |
// remove SPFoudnMeta from image. Dirty. @todo <--
|
254 |
-
function removeSPFoundMeta()
|
255 |
{
|
256 |
if($this->type == ShortPixelMetaFacade::MEDIA_LIBRARY_TYPE) {
|
257 |
if(!isset($this->rawMeta)) {
|
@@ -378,6 +378,7 @@ class ShortPixelMetaFacade {
|
|
378 |
*/
|
379 |
public static function safeGetAttachmentUrl($id) {
|
380 |
$attURL = wp_get_attachment_url($id);
|
|
|
381 |
if(!$attURL || !strlen($attURL)) {
|
382 |
throw new Exception("Post metadata is corrupt (No attachment URL for $id)", ShortPixelAPI::ERR_POSTMETA_CORRUPT);
|
383 |
}
|
@@ -405,33 +406,28 @@ class ShortPixelMetaFacade {
|
|
405 |
$path = get_attached_file($this->ID);//get the full file PATH
|
406 |
$fsFile = $fs->getFile($path);
|
407 |
$mainExists = apply_filters('shortpixel_image_exists', file_exists($path), $path, $this->ID);
|
408 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
409 |
$urlList = array(); $filePaths = array();
|
410 |
|
411 |
-
Log::addDebug('attached file path: ' . $path );
|
412 |
|
413 |
if(!$mainExists) {
|
414 |
-
|
415 |
-
|
416 |
-
|
417 |
-
|
418 |
-
|
419 |
-
|
420 |
-
|
421 |
-
Log::addDebug('Downloading main file ' . $url );
|
422 |
-
$response = wp_remote_get( $url, $args_for_get );
|
423 |
-
if(is_wp_error( $response )) {
|
424 |
-
Log::addError('Download Mailfile failed', array($response->get_error_messages()));
|
425 |
-
}
|
426 |
-
elseif ($fsFile->exists())
|
427 |
-
{
|
428 |
-
$mainExists = true;
|
429 |
-
$fsUrl = $fs->pathToUrl($fsFile);
|
430 |
-
if ($fsUrl !== false)
|
431 |
-
$url = $fsUrl; // more secure way of getting url
|
432 |
-
|
433 |
-
Log::addDebug('FSFILE TO URL -' . $fsUrl);
|
434 |
-
}
|
435 |
}
|
436 |
|
437 |
if($mainExists) {
|
@@ -508,40 +504,23 @@ class ShortPixelMetaFacade {
|
|
508 |
}
|
509 |
|
510 |
if ( !$file_exists && !file_exists($tPath) ) {
|
511 |
-
$
|
|
|
|
|
512 |
}
|
513 |
|
514 |
if ( !$file_exists && !file_exists($tPath) ) {
|
515 |
-
$
|
|
|
|
|
516 |
}
|
517 |
|
518 |
if ( !$file_exists && !file_exists($tPath) ) {
|
519 |
//try and download the image from the URL (images present only on CDN)
|
520 |
// Log::addDebug('URLs and Paths - File didnt exists, trying to download', array($tUrl, $origPath));
|
521 |
// $tempThumb = download_url($tUrl, $downloadTimeout);
|
522 |
-
$args_for_get = array(
|
523 |
-
'stream' => true,
|
524 |
-
'filename' => $origFile->getFullPath(),
|
525 |
-
'timeout' => max(SHORTPIXEL_MAX_EXECUTION_TIME - 10, 15),
|
526 |
-
);
|
527 |
-
|
528 |
-
$response = wp_remote_get( $tUrl, $args_for_get );
|
529 |
-
Log::addDebug('Thumb not found, trying to download: ' . $tUrl);
|
530 |
|
531 |
-
|
532 |
-
{
|
533 |
-
Log::addError('Download Thumbnail failed', array($response->get_error_messages()));
|
534 |
-
}
|
535 |
-
elseif($origFile->exists())
|
536 |
-
{
|
537 |
-
$tPath = $origFile->getFullPath(); // download succesfull
|
538 |
-
$fsUrl = $fs->pathToUrl($origFile);
|
539 |
-
if ($fsUrl !== false) // this tranlation to domain url will not always hold to sendToProcessing when dealing w/ CDN and such.
|
540 |
-
$tUrl = $fsUrl; // more secure way of getting url
|
541 |
-
else {
|
542 |
-
Log::addError('Download - Could not tranlate to URL', array($fsUrl, $tPath, $origFile));
|
543 |
-
}
|
544 |
-
}
|
545 |
|
546 |
Log::addDebug('New TPath after download', array($tUrl, $tPath, $origPath, filesize($tPath)));
|
547 |
}
|
@@ -575,10 +554,65 @@ class ShortPixelMetaFacade {
|
|
575 |
array_walk($urlList, array( &$this, 'replacePlusChar') );
|
576 |
|
577 |
$filePaths = ShortPixelAPI::CheckAndFixImagePaths($filePaths);//check for images to make sure they exist on disk
|
578 |
-
|
579 |
return array("URLs" => $urlList, "PATHs" => $filePaths, "sizesMissing" => $sizesMissing);
|
580 |
}
|
581 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
582 |
protected function replacePlusChar(&$url) {
|
583 |
$url = str_replace("+", "%2B", $url);
|
584 |
}
|
101 |
return $rawMeta;
|
102 |
}
|
103 |
|
104 |
+
// Update MetaData of Image.
|
105 |
public function updateMeta($newMeta = null, $replaceThumbs = false) {
|
106 |
if($newMeta) {
|
107 |
$this->meta = $newMeta;
|
251 |
}
|
252 |
|
253 |
// remove SPFoudnMeta from image. Dirty. @todo <--
|
254 |
+
public function removeSPFoundMeta()
|
255 |
{
|
256 |
if($this->type == ShortPixelMetaFacade::MEDIA_LIBRARY_TYPE) {
|
257 |
if(!isset($this->rawMeta)) {
|
378 |
*/
|
379 |
public static function safeGetAttachmentUrl($id) {
|
380 |
$attURL = wp_get_attachment_url($id);
|
381 |
+
Log::addDebug('Attachment URL - safeGotten - ' . $attURL);
|
382 |
if(!$attURL || !strlen($attURL)) {
|
383 |
throw new Exception("Post metadata is corrupt (No attachment URL for $id)", ShortPixelAPI::ERR_POSTMETA_CORRUPT);
|
384 |
}
|
406 |
$path = get_attached_file($this->ID);//get the full file PATH
|
407 |
$fsFile = $fs->getFile($path);
|
408 |
$mainExists = apply_filters('shortpixel_image_exists', file_exists($path), $path, $this->ID);
|
409 |
+
try
|
410 |
+
{
|
411 |
+
$predownload_url = $url = self::safeGetAttachmentUrl($this->ID); // This function *can* return an PHP error.
|
412 |
+
Log::addDebug('Resulting URL -- ' . $url);
|
413 |
+
}
|
414 |
+
catch(Exception $e)
|
415 |
+
{
|
416 |
+
Log::addWarn('Attachment seems corrupted', array($e->getMessage() ));
|
417 |
+
return array("URLs" => array(), "PATHs" => array(), "sizesMissing" => array());
|
418 |
+
}
|
419 |
$urlList = array(); $filePaths = array();
|
420 |
|
421 |
+
Log::addDebug('attached file path: ' . $path, array( (string) $fsFile->getFileDir() ) );
|
422 |
|
423 |
if(!$mainExists) {
|
424 |
+
list($url, $path) = $this->attemptRemoteDownload($url, $path, $this->ID);
|
425 |
+
$downloadFile = $fs->getFile($path);
|
426 |
+
if ($downloadFile->exists()) // check for success.
|
427 |
+
{
|
428 |
+
$mainExists = true;
|
429 |
+
$fsFile = $downloadFile; // overwrite.
|
430 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
431 |
}
|
432 |
|
433 |
if($mainExists) {
|
504 |
}
|
505 |
|
506 |
if ( !$file_exists && !file_exists($tPath) ) {
|
507 |
+
$try_path = SHORTPIXEL_UPLOADS_BASE . substr($origPath, strpos($origPath, $StichString) + strlen($StichString));
|
508 |
+
if (file_exists($try_path))
|
509 |
+
$tPath = $try_path; // found!
|
510 |
}
|
511 |
|
512 |
if ( !$file_exists && !file_exists($tPath) ) {
|
513 |
+
$try_path = trailingslashit(SHORTPIXEL_UPLOADS_BASE) . $origPath;
|
514 |
+
if (file_exists($try_path))
|
515 |
+
$tPath = $try_path; // found!
|
516 |
}
|
517 |
|
518 |
if ( !$file_exists && !file_exists($tPath) ) {
|
519 |
//try and download the image from the URL (images present only on CDN)
|
520 |
// Log::addDebug('URLs and Paths - File didnt exists, trying to download', array($tUrl, $origPath));
|
521 |
// $tempThumb = download_url($tUrl, $downloadTimeout);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
522 |
|
523 |
+
list($tUrl, $tPath) = $this->attemptRemoteDownload($tUrl, $tPath, $this->ID);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
524 |
|
525 |
Log::addDebug('New TPath after download', array($tUrl, $tPath, $origPath, filesize($tPath)));
|
526 |
}
|
554 |
array_walk($urlList, array( &$this, 'replacePlusChar') );
|
555 |
|
556 |
$filePaths = ShortPixelAPI::CheckAndFixImagePaths($filePaths);//check for images to make sure they exist on disk
|
|
|
557 |
return array("URLs" => $urlList, "PATHs" => $filePaths, "sizesMissing" => $sizesMissing);
|
558 |
}
|
559 |
|
560 |
+
private function attemptRemoteDownload($url, $path, $attach_id)
|
561 |
+
{
|
562 |
+
$downloadTimeout = max(SHORTPIXEL_MAX_EXECUTION_TIME - 10, 15);
|
563 |
+
$fs = new \ShortPixel\FileSystemController();
|
564 |
+
$pathFile = $fs->getFile($path);
|
565 |
+
|
566 |
+
$args_for_get = array(
|
567 |
+
'stream' => true,
|
568 |
+
'filename' => $pathFile->getFullPath(),
|
569 |
+
);
|
570 |
+
|
571 |
+
$response = wp_remote_get( $url, $args_for_get );
|
572 |
+
|
573 |
+
if(is_wp_error( $response )) {
|
574 |
+
Log::addError('Download file failed', array($url, $response->get_error_messages(), $response->get_error_codes() ));
|
575 |
+
|
576 |
+
// Try to get it then via this way.
|
577 |
+
$response = download_url($url, $downloadTimeout);
|
578 |
+
if (!is_wp_error($response)) // response when alright is a tmp filepath. But given path can't be trusted since that can be reason for fail.
|
579 |
+
{
|
580 |
+
$tmpFile = $fs->getFile($response);
|
581 |
+
$post = get_post($attach_id);
|
582 |
+
$post_date = get_the_date('Y/m', $post); // get the date for the uploads tree.
|
583 |
+
|
584 |
+
$upload_dir = wp_upload_dir($post_date);
|
585 |
+
$upload_dir = $fs->getDirectory($upload_dir['path']); // get the upload dir.
|
586 |
+
|
587 |
+
$fixedFile = $fs->getFile($upload_dir->getPath() . $pathFile->getFileName() );
|
588 |
+
// try to move
|
589 |
+
$result = $tmpFile->move($fixedFile);
|
590 |
+
|
591 |
+
Log::addDebug('Fixed File', array($post_date, $fixedFile->getFullPath() ));
|
592 |
+
|
593 |
+
if ($result && $fixedFile->exists())
|
594 |
+
{
|
595 |
+
$path = $fixedFile->getFullPath(); // overwrite path with new fixed path.
|
596 |
+
$url = $fs->pathToUrl($fixedFile);
|
597 |
+
$pathFile = $fixedFile;
|
598 |
+
}
|
599 |
+
} // download_url ..
|
600 |
+
else {
|
601 |
+
Log::addError('Secondary download failed', array($url, $response->get_error_messages(), $response->get_error_codes() ));
|
602 |
+
}
|
603 |
+
}
|
604 |
+
else { // success
|
605 |
+
$pathFile = $fs->getFile($response['filename']);
|
606 |
+
}
|
607 |
+
|
608 |
+
$fsUrl = $fs->pathToUrl($pathFile);
|
609 |
+
if ($fsUrl !== false)
|
610 |
+
$url = $fsUrl; // more secure way of getting url
|
611 |
+
|
612 |
+
Log::addDebug('Remote Download attempt result', array($url, $path));
|
613 |
+
return array($url, $path);
|
614 |
+
}
|
615 |
+
|
616 |
protected function replacePlusChar(&$url) {
|
617 |
$url = str_replace("+", "%2B", $url);
|
618 |
}
|
class/db/wp-shortpixel-media-library-adapter.php
CHANGED
@@ -3,6 +3,246 @@ use ShortPixel\ShortpixelLogger\ShortPixelLogger as Log;
|
|
3 |
|
4 |
class WpShortPixelMediaLbraryAdapter {
|
5 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
6 |
//count all the processable files in media library (while limiting the results to max 10000)
|
7 |
public static function countAllProcessableFiles($settings = array(), $maxId = PHP_INT_MAX, $minId = 0){
|
8 |
global $wpdb;
|
@@ -35,6 +275,7 @@ class WpShortPixelMediaLbraryAdapter {
|
|
35 |
//count all the files, main and thumbs
|
36 |
while ( 1 ) {
|
37 |
$idInfo = self::getPostIdsChunk($minId, $maxId, $pointer, $limit);
|
|
|
38 |
if($idInfo === null) {
|
39 |
break; //we parsed all the results
|
40 |
}
|
@@ -43,9 +284,12 @@ class WpShortPixelMediaLbraryAdapter {
|
|
43 |
continue;
|
44 |
}
|
45 |
|
46 |
-
$filesList= $wpdb->get_results("SELECT
|
47 |
WHERE post_id IN (" . implode(',', $idInfo->ids) . ")
|
48 |
AND ( meta_key = '_wp_attached_file' OR meta_key = '_wp_attachment_metadata' )");
|
|
|
|
|
|
|
49 |
|
50 |
//in one case this query returned zero items but if fewer items in the IDs list, it worked so apply this workaround:
|
51 |
if($limit > 1000 && count($filesList) == 0) {
|
@@ -70,7 +314,7 @@ class WpShortPixelMediaLbraryAdapter {
|
|
70 |
}
|
71 |
elseif ( $file->meta_key == "_wp_attachment_metadata" ) //_wp_attachment_metadata
|
72 |
{
|
73 |
-
$attachment =
|
74 |
$sizesCount = isset($attachment['sizes']) ? self::countSizesNotExcluded($attachment['sizes'], $settings->excludeSizes) : 0;
|
75 |
|
76 |
// LA FIECARE 100 de imagini facem un test si daca findThumbs da diferit, sa dam o avertizare si eventual optiune
|
@@ -230,6 +474,7 @@ class WpShortPixelMediaLbraryAdapter {
|
|
230 |
);
|
231 |
}
|
232 |
|
|
|
233 |
public static function getPostMetaSlice($startId, $endId, $limit) {
|
234 |
global $wpdb;
|
235 |
$time = microtime(true);
|
@@ -271,6 +516,62 @@ class WpShortPixelMediaLbraryAdapter {
|
|
271 |
return $metaresult;
|
272 |
}
|
273 |
*/
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
274 |
public static function getPostsJoinLessReverse($startId, $endId, $limit)
|
275 |
{
|
276 |
global $wpdb;
|
@@ -365,7 +666,7 @@ class WpShortPixelMediaLbraryAdapter {
|
|
365 |
|
366 |
$base = $file->getFileBase();
|
367 |
$ext = $file->getExtension();
|
368 |
-
$pattern = '
|
369 |
|
370 |
$thumbs = array_merge($thumbs, self::getFilesByPattern($dirPath, $pattern));
|
371 |
|
@@ -392,7 +693,7 @@ class WpShortPixelMediaLbraryAdapter {
|
|
392 |
{
|
393 |
foreach ($suffixes as $suffix){
|
394 |
|
395 |
-
$pattern = '
|
396 |
$thumbs = array_merge($thumbs, self::getFilesByPattern($dirPath, $pattern));
|
397 |
/*foreach($thumbsCandidates as $th) {
|
398 |
if(preg_match($pattern, $th)) {
|
@@ -408,7 +709,7 @@ class WpShortPixelMediaLbraryAdapter {
|
|
408 |
{
|
409 |
foreach ($infixes as $infix){
|
410 |
//$thumbsCandidates = @glob($base . $infix . "-*." . $ext);
|
411 |
-
$pattern = '
|
412 |
$thumbs = array_merge($thumbs, self::getFilesByPattern($dirPath, $pattern));
|
413 |
|
414 |
/*foreach($thumbsCandidates as $th) {
|
@@ -449,7 +750,7 @@ class WpShortPixelMediaLbraryAdapter {
|
|
449 |
}
|
450 |
catch(\Exception $e)
|
451 |
{
|
452 |
-
Log::addWarn('GetFilesbyPattern issue with directory. ', $e->
|
453 |
return array();
|
454 |
}
|
455 |
|
@@ -485,13 +786,27 @@ class WpShortPixelMediaLbraryAdapter {
|
|
485 |
}
|
486 |
}
|
487 |
|
488 |
-
protected static function getPostIdsChunk($minId, $maxId, $pointer, $limit) {
|
489 |
global $wpdb;
|
490 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
491 |
$ids = $idDates = array();
|
492 |
-
$idList = $wpdb->get_results(
|
493 |
-
|
494 |
-
LIMIT $pointer,$limit");
|
495 |
if ( empty($idList) ) {
|
496 |
return null;
|
497 |
}
|
@@ -501,7 +816,46 @@ class WpShortPixelMediaLbraryAdapter {
|
|
501 |
$idDates[$item->ID] = $item->post_date;
|
502 |
}
|
503 |
}
|
504 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
505 |
}
|
506 |
|
507 |
}
|
3 |
|
4 |
class WpShortPixelMediaLbraryAdapter {
|
5 |
|
6 |
+
// Testing is this is better / faster than previous function.
|
7 |
+
public static function countAllProcessable($settings, $maxId = PHP_INT_MAX, $minId = 0)
|
8 |
+
{
|
9 |
+
global $wpdb;
|
10 |
+
|
11 |
+
$totalFiles = $mainFiles = $processedMainFiles = $processedTotalFiles = $totalFilesM1 = $totalFilesM2 = $totalFilesM3 = $totalFilesM4 =
|
12 |
+
$procGlossyMainFiles = $procGlossyTotalFiles = $procLossyMainFiles = $procLossyTotalFiles = $procLosslessMainFiles = $procLosslessTotalFiles = $procUndefMainFiles = $procUndefTotalFiles = $mainUnprocessedThumbs = 0;
|
13 |
+
$filesMap = $processedFilesMap = array();
|
14 |
+
$limit = self::getOptimalChunkSize();
|
15 |
+
$pointer = 0;
|
16 |
+
$filesWithErrors = array(); $moreFilesWithErrors = 0;
|
17 |
+
$run = true;
|
18 |
+
$excludePatterns = WPShortPixelSettings::getOpt("excludePatterns");
|
19 |
+
//idInfo = self::getPostIdsChunk($minId, $maxId, $pointer, $limit, true);
|
20 |
+
|
21 |
+
$foundUnlistedThumbs = false;
|
22 |
+
$counter = 0;
|
23 |
+
|
24 |
+
$filesWithErrors = array(); $moreFilesWithErrors = 0;
|
25 |
+
$excludePatterns = WPShortPixelSettings::getOpt("excludePatterns");
|
26 |
+
|
27 |
+
if (version_compare(PHP_VERSION, '5.3.0') >= 0) {
|
28 |
+
$month1 = new DateTime();
|
29 |
+
$month2 = new DateTime();
|
30 |
+
$month3 = new DateTime();
|
31 |
+
$month4 = new DateTime();
|
32 |
+
$mi1 = new DateInterval('P1M');
|
33 |
+
$mi2 = new DateInterval('P2M');
|
34 |
+
$mi3 = new DateInterval('P3M');
|
35 |
+
$mi4 = new DateInterval('P4M');
|
36 |
+
$month1->sub($mi1);
|
37 |
+
$month2->sub($mi2);
|
38 |
+
$month3->sub($mi3);
|
39 |
+
$month4->sub($mi4);
|
40 |
+
}
|
41 |
+
|
42 |
+
while ( $run == true ) {
|
43 |
+
$idInfo = self::getPostIdsChunk($minId, $maxId, $pointer, $limit, true);
|
44 |
+
$minId = isset($idInfo->last_id) ? $idInfo->last_id : -1;
|
45 |
+
|
46 |
+
if($idInfo === null) {
|
47 |
+
break; //we parsed all the results
|
48 |
+
}
|
49 |
+
elseif(count($idInfo->ids) == 0) {
|
50 |
+
//$minId += $limit; // This is a no results case.
|
51 |
+
continue;
|
52 |
+
}
|
53 |
+
|
54 |
+
$filesList= $wpdb->get_results("SELECT post_id, meta_key, meta_value FROM " . $wpdb->prefix . "postmeta
|
55 |
+
WHERE post_id IN (" . implode(',', $idInfo->ids) . ")
|
56 |
+
AND ( meta_key = '_wp_attached_file' OR meta_key = '_wp_attachment_metadata' )");
|
57 |
+
/* $filesList= $wpdb->get_results("SELECT post_id, meta_key, meta_value FROM " . $wpdb->prefix . "postmeta
|
58 |
+
WHERE post_id >= $minId and post_id <= $maxId
|
59 |
+
AND ( meta_key = '_wp_attached_file' OR meta_key = '_wp_attachment_metadata' )"); */
|
60 |
+
|
61 |
+
//$minId = $idInfo->ids[0];
|
62 |
+
//$minId = $idInfo->ids[count($idInfo->ids) - 1];
|
63 |
+
|
64 |
+
//in one case this query returned zero items but if fewer items in the IDs list, it worked so apply this workaround:
|
65 |
+
if($limit > 1000 && count($filesList) == 0) {
|
66 |
+
$limit = 1000;
|
67 |
+
continue;
|
68 |
+
}
|
69 |
+
|
70 |
+
foreach ( $filesList as $file )
|
71 |
+
{
|
72 |
+
$totalFilesThis = $processedFilesThis = 0;
|
73 |
+
|
74 |
+
if ( $file->meta_key == "_wp_attached_file" )
|
75 |
+
{//count pdf files only
|
76 |
+
$extension = substr($file->meta_value, strrpos($file->meta_value,".") + 1 );
|
77 |
+
if ( $extension == "pdf" && $settings->optimizePdfs && !isset($filesMap[$file->meta_value]))
|
78 |
+
{
|
79 |
+
$totalFiles++;
|
80 |
+
$totalFilesThis++;
|
81 |
+
$mainFiles++;
|
82 |
+
$filesMap[$file->meta_value] = 1;
|
83 |
+
}
|
84 |
+
}
|
85 |
+
elseif ( $file->meta_key == "_wp_attachment_metadata" ) //_wp_attachment_metadata
|
86 |
+
{
|
87 |
+
$attachment = maybe_unserialize($file->meta_value);
|
88 |
+
$sizesCount = isset($attachment['sizes']) ? self::countSizesNotExcluded($attachment['sizes'], $settings->excludeSizes) : 0;
|
89 |
+
|
90 |
+
// LA FIECARE 100 de imagini facem un test si daca findThumbs da diferit, sa dam o avertizare si eventual optiune
|
91 |
+
$dismissed = $settings->dismissedNotices ? $settings->dismissedNotices : array();
|
92 |
+
if( $foundUnlistedThumbs === false && $maxId == PHP_INT_MAX && !isset($dismissed['unlisted'])
|
93 |
+
&& ( in_array($counter, array(2,4,6,8)) || floor($counter/100) == 0 && $counter%10 == 0
|
94 |
+
|| floor($counter/1000) == 0 && $counter%100 == 0 || floor($counter/10000) == 0 && $counter%1000 == 0))
|
95 |
+
{
|
96 |
+
$filePath = isset($attachment['file']) ? trailingslashit(SHORTPIXEL_UPLOADS_BASE).$attachment['file'] : false;
|
97 |
+
if ($filePath && file_exists($filePath) && isset($attachment['sizes']) &&
|
98 |
+
( !isset($attachment['ShortPixelImprovement']) || $attachment['ShortPixelImprovement'] === 0
|
99 |
+
|| $attachment['ShortPixelImprovement'] === 0.0 || $attachment['ShortPixelImprovement'] === "0"))
|
100 |
+
{
|
101 |
+
$foundThumbs = WpShortPixelMediaLbraryAdapter::findThumbs($filePath);
|
102 |
+
|
103 |
+
$foundCount = count($foundThumbs);
|
104 |
+
|
105 |
+
if(count($foundThumbs) > $sizesCount) {
|
106 |
+
$unlisted = array();
|
107 |
+
foreach($foundThumbs as $found) {
|
108 |
+
$match = ShortPixelTools::findItem(wp_basename($found), $attachment['sizes'], 'file');
|
109 |
+
if(!$match) {
|
110 |
+
$unlisted[] = wp_basename($found);
|
111 |
+
}
|
112 |
+
}
|
113 |
+
$foundUnlistedThumbs = (object)array("id" => $file->post_id, "name" => wp_basename($attachment['file']), "unlisted" => $unlisted);
|
114 |
+
}
|
115 |
+
} else {
|
116 |
+
$counter--; // will take the next one
|
117 |
+
$realSizesCount = $sizesCount;
|
118 |
+
}
|
119 |
+
}
|
120 |
+
//processable
|
121 |
+
$isProcessable = false;
|
122 |
+
$isProcessed = isset($attachment['ShortPixelImprovement'])
|
123 |
+
&& ($attachment['ShortPixelImprovement'] > 0 || $attachment['ShortPixelImprovement'] === 0.0 || $attachment['ShortPixelImprovement'] === "0")
|
124 |
+
//for PDFs there is no file field so just let it pass.
|
125 |
+
&& (!isset($attachment['file']) || !isset($processedFilesMap[$attachment['file']]));
|
126 |
+
|
127 |
+
if( isset($attachment['file']) && !isset($filesMap[$attachment['file']])
|
128 |
+
&& WPShortPixel::_isProcessablePath($attachment['file'], array(), $excludePatterns)){
|
129 |
+
$isProcessable = true;
|
130 |
+
$totalFiles += $sizesCount;
|
131 |
+
$totalFilesThis += $sizesCount;
|
132 |
+
if ( isset($attachment['file']) )
|
133 |
+
{
|
134 |
+
$totalFiles++;
|
135 |
+
$totalFilesThis++;
|
136 |
+
$mainFiles++;
|
137 |
+
$filesMap[$attachment['file']] = 1;
|
138 |
+
}
|
139 |
+
}
|
140 |
+
//processed
|
141 |
+
if ($isProcessed) {
|
142 |
+
//add main file to counts
|
143 |
+
$processedMainFiles++;
|
144 |
+
$processedTotalFiles++;
|
145 |
+
$processedFilesThis++;
|
146 |
+
$type = isset($attachment['ShortPixel']['type']) ? $attachment['ShortPixel']['type'] : null;
|
147 |
+
switch($type) {
|
148 |
+
case 'lossy' :
|
149 |
+
$procLossyMainFiles++;
|
150 |
+
$procLossyTotalFiles++;
|
151 |
+
break;
|
152 |
+
case 'glossy':
|
153 |
+
$procGlossyMainFiles++;
|
154 |
+
$procGlossyTotalFiles++;
|
155 |
+
break;
|
156 |
+
case 'lossless':
|
157 |
+
$procLosslessMainFiles++;
|
158 |
+
$procLosslessTotalFiles++;
|
159 |
+
break;
|
160 |
+
default:
|
161 |
+
$procUndefMainFiles++;
|
162 |
+
$procUndefTotalFiles++;
|
163 |
+
}
|
164 |
+
|
165 |
+
//get the thumbs processed for that attachment
|
166 |
+
$thumbs = $allThumbs = 0;
|
167 |
+
if ( isset($attachment['ShortPixel']['thumbsOpt']) ) {
|
168 |
+
$thumbs = $attachment['ShortPixel']['thumbsOpt'];
|
169 |
+
}
|
170 |
+
elseif ( isset($attachment['sizes']) ) {
|
171 |
+
$thumbs = $sizesCount;
|
172 |
+
}
|
173 |
+
if(!isset($attachment['file'])) { //for the pdfs that have thumbs, have to add the thumbs too (not added above )
|
174 |
+
$totalFiles += $thumbs;
|
175 |
+
$totalFilesThis += $thumbs;
|
176 |
+
}
|
177 |
+
$thumbsMissing = isset($attachment['ShortPixel']['thumbsMissing']) ? $attachment['ShortPixel']['thumbsMissing'] : array();
|
178 |
+
|
179 |
+
if ( isset($attachment['sizes']) && $sizesCount > $thumbs + count($thumbsMissing)) {
|
180 |
+
$mainUnprocessedThumbs++;
|
181 |
+
}
|
182 |
+
|
183 |
+
//increment with thumbs processed
|
184 |
+
$processedTotalFiles += $thumbs;
|
185 |
+
$processedFilesThis += $thumbs;
|
186 |
+
if($type == 'glossy') {
|
187 |
+
$procGlossyTotalFiles += $thumbs;
|
188 |
+
} elseif ($type == 'lossy') {
|
189 |
+
$procLossyTotalFiles += $thumbs;
|
190 |
+
} else {
|
191 |
+
$procLosslessTotalFiles += $thumbs;
|
192 |
+
}
|
193 |
+
|
194 |
+
if ( isset($attachment['file']) ) {
|
195 |
+
$processedFilesMap[$attachment['file']] = 1;
|
196 |
+
}
|
197 |
+
}
|
198 |
+
elseif($isProcessable && isset($attachment['ShortPixelImprovement'])) {
|
199 |
+
if(count($filesWithErrors) < 50) {
|
200 |
+
$filePath = explode("/", $attachment["file"]);
|
201 |
+
$name = is_array($filePath)? $filePath[count($filePath) - 1] : $file->post_id;
|
202 |
+
$filesWithErrors[$file->post_id] = array('Id' => $file->post_id, 'Name' => $name, 'Message' => $attachment['ShortPixelImprovement']);
|
203 |
+
} else {
|
204 |
+
$moreFilesWithErrors++;
|
205 |
+
}
|
206 |
+
}
|
207 |
+
|
208 |
+
}
|
209 |
+
|
210 |
+
if (version_compare(PHP_VERSION, '5.3.0') >= 0) {
|
211 |
+
$dt = new DateTime($idInfo->idDates[$file->post_id]);
|
212 |
+
if ($dt > $month1) {
|
213 |
+
$totalFilesM1 += $totalFilesThis;
|
214 |
+
} else if ($dt > $month2) {
|
215 |
+
$totalFilesM2 += $totalFilesThis;
|
216 |
+
} else if ($dt > $month3) {
|
217 |
+
$totalFilesM3 += $totalFilesThis;
|
218 |
+
} else if ($dt > $month4) {
|
219 |
+
$totalFilesM4 += $totalFilesThis;
|
220 |
+
}
|
221 |
+
}
|
222 |
+
}
|
223 |
+
unset($filesList);
|
224 |
+
$pointer += $limit;
|
225 |
+
$counter++;
|
226 |
+
}//end while
|
227 |
+
|
228 |
+
return array("totalFiles" => $totalFiles, "mainFiles" => $mainFiles,
|
229 |
+
"totalProcessedFiles" => $processedTotalFiles, "mainProcessedFiles" => $processedMainFiles,
|
230 |
+
"totalProcLossyFiles" => $procLossyTotalFiles, "mainProcLossyFiles" => $procLossyMainFiles,
|
231 |
+
"totalProcGlossyFiles" => $procGlossyTotalFiles, "mainProcGlossyFiles" => $procGlossyMainFiles,
|
232 |
+
"totalProcLosslessFiles" => $procLosslessTotalFiles, "mainProcLosslessFiles" => $procLosslessMainFiles,
|
233 |
+
"totalMlFiles" => $totalFiles, "mainMlFiles" => $mainFiles,
|
234 |
+
"totalProcessedMlFiles" => $processedTotalFiles, "mainProcessedMlFiles" => $processedMainFiles,
|
235 |
+
"totalProcLossyMlFiles" => $procLossyTotalFiles, "mainProcLossyMlFiles" => $procLossyMainFiles,
|
236 |
+
"totalProcGlossyMlFiles" => $procGlossyTotalFiles, "mainProcGlossyMlFiles" => $procGlossyMainFiles,
|
237 |
+
"totalProcLosslessMlFiles" => $procLosslessTotalFiles, "mainProcLosslessMlFiles" => $procLosslessMainFiles,
|
238 |
+
"totalProcUndefMlFiles" => $procUndefTotalFiles, "mainProcUndefMlFiles" => $procUndefMainFiles,
|
239 |
+
"mainUnprocessedThumbs" => $mainUnprocessedThumbs, "totalM1" => $totalFilesM1, "totalM2" => $totalFilesM2, "totalM3" => $totalFilesM3, "totalM4" => $totalFilesM4,
|
240 |
+
"filesWithErrors" => $filesWithErrors,
|
241 |
+
"moreFilesWithErrors" => $moreFilesWithErrors,
|
242 |
+
"foundUnlistedThumbs" => $foundUnlistedThumbs
|
243 |
+
);
|
244 |
+
}
|
245 |
+
|
246 |
//count all the processable files in media library (while limiting the results to max 10000)
|
247 |
public static function countAllProcessableFiles($settings = array(), $maxId = PHP_INT_MAX, $minId = 0){
|
248 |
global $wpdb;
|
275 |
//count all the files, main and thumbs
|
276 |
while ( 1 ) {
|
277 |
$idInfo = self::getPostIdsChunk($minId, $maxId, $pointer, $limit);
|
278 |
+
|
279 |
if($idInfo === null) {
|
280 |
break; //we parsed all the results
|
281 |
}
|
284 |
continue;
|
285 |
}
|
286 |
|
287 |
+
$filesList= $wpdb->get_results("SELECT post_id, meta_key, meta_value FROM " . $wpdb->prefix . "postmeta
|
288 |
WHERE post_id IN (" . implode(',', $idInfo->ids) . ")
|
289 |
AND ( meta_key = '_wp_attached_file' OR meta_key = '_wp_attachment_metadata' )");
|
290 |
+
/* $filesList= $wpdb->get_results("SELECT post_id, meta_key, meta_value FROM " . $wpdb->prefix . "postmeta
|
291 |
+
WHERE post_id >= $minId and post_id <= $maxId
|
292 |
+
AND ( meta_key = '_wp_attached_file' OR meta_key = '_wp_attachment_metadata' )"); */
|
293 |
|
294 |
//in one case this query returned zero items but if fewer items in the IDs list, it worked so apply this workaround:
|
295 |
if($limit > 1000 && count($filesList) == 0) {
|
314 |
}
|
315 |
elseif ( $file->meta_key == "_wp_attachment_metadata" ) //_wp_attachment_metadata
|
316 |
{
|
317 |
+
$attachment = maybe_unserialize($file->meta_value);
|
318 |
$sizesCount = isset($attachment['sizes']) ? self::countSizesNotExcluded($attachment['sizes'], $settings->excludeSizes) : 0;
|
319 |
|
320 |
// LA FIECARE 100 de imagini facem un test si daca findThumbs da diferit, sa dam o avertizare si eventual optiune
|
474 |
);
|
475 |
}
|
476 |
|
477 |
+
|
478 |
public static function getPostMetaSlice($startId, $endId, $limit) {
|
479 |
global $wpdb;
|
480 |
$time = microtime(true);
|
516 |
return $metaresult;
|
517 |
}
|
518 |
*/
|
519 |
+
|
520 |
+
public static function getThumbsToOptimize($data, $filepath)
|
521 |
+
{
|
522 |
+
// @todo weak call. See how in future settings might come via central provider.
|
523 |
+
$settings = new \WPShortPixelSettings();
|
524 |
+
|
525 |
+
$fs = new \ShortPixel\FileSystemController();
|
526 |
+
$mainfile = $fs->getFile($filepath);
|
527 |
+
|
528 |
+
$sizesCount = isset($data['sizes']) ? WpShortPixelMediaLbraryAdapter::countSizesNotExcluded($data['sizes']) : 0;
|
529 |
+
$basedir = $mainfile->getFileDir()->getPath();
|
530 |
+
$thumbsOptList = isset($data['ShortPixel']['thumbsOptList']) ? $data['ShortPixel']['thumbsOptList'] : array();
|
531 |
+
$thumbsToOptimizeList = array(); // is returned, so should be defined before if.
|
532 |
+
|
533 |
+
if($sizesCount && $settings->processThumbnails) {
|
534 |
+
|
535 |
+
// findThumbs returns fullfilepath.
|
536 |
+
$found = $settings->optimizeUnlisted ? WpShortPixelMediaLbraryAdapter::findThumbs($mainfile->getFullPath()) : array();
|
537 |
+
|
538 |
+
$exclude = $settings->excludeSizes;
|
539 |
+
$exclude = is_array($exclude) ? $exclude : array();
|
540 |
+
foreach($data['sizes'] as $size => $sizeData) {
|
541 |
+
unset($found[\array_search($basedir . $sizeData['file'], $found)]); // @todo what is this intended to do?
|
542 |
+
|
543 |
+
// sizeData['file'] is *only* filename *but* can be wrong data, URL due to plugins. So check first, only get filename ( since it is supposed to fail with only a filename path ) and then reload.
|
544 |
+
$sizeFileCheck = $fs->getFile($sizeData['file']);
|
545 |
+
$file = $fs->getFile($basedir . $sizeFileCheck->getFileName());
|
546 |
+
|
547 |
+
if ($file->getExtension() !== $mainfile->getExtension())
|
548 |
+
{
|
549 |
+
continue;
|
550 |
+
}
|
551 |
+
|
552 |
+
if(!in_array($size, $exclude) && !in_array($file->getFileName(), $thumbsOptList)) {
|
553 |
+
$thumbsToOptimizeList[] = $file->getFileName();
|
554 |
+
}
|
555 |
+
}
|
556 |
+
//$found = array_diff($found, $thumbsOptList); // Wrong comparison. Found is full file path, thumbsOptList is not.
|
557 |
+
foreach($found as $path) {
|
558 |
+
$file = $fs->getFile($path);
|
559 |
+
|
560 |
+
// prevent Webp and what not from showing up.
|
561 |
+
if ($file->getExtension() !== $mainfile->getExtension())
|
562 |
+
{
|
563 |
+
continue;
|
564 |
+
}
|
565 |
+
// thumbs can already be in findThumbs.
|
566 |
+
if (! in_array($file->getFileName(), $thumbsToOptimizeList) && ! in_array($file->getFileName(), $thumbsOptList) )
|
567 |
+
{
|
568 |
+
$thumbsToOptimizeList[] = $file->getFileName();
|
569 |
+
}
|
570 |
+
}
|
571 |
+
}
|
572 |
+
return array($thumbsToOptimizeList, $sizesCount);
|
573 |
+
}
|
574 |
+
|
575 |
public static function getPostsJoinLessReverse($startId, $endId, $limit)
|
576 |
{
|
577 |
global $wpdb;
|
666 |
|
667 |
$base = $file->getFileBase();
|
668 |
$ext = $file->getExtension();
|
669 |
+
$pattern = '/^' . preg_quote($base, '/') . '-\d+x\d+\.'. $ext .'/';
|
670 |
|
671 |
$thumbs = array_merge($thumbs, self::getFilesByPattern($dirPath, $pattern));
|
672 |
|
693 |
{
|
694 |
foreach ($suffixes as $suffix){
|
695 |
|
696 |
+
$pattern = '/^' . preg_quote($base, '/') . '-\d+x\d+'. $suffix . '\.'. $ext .'/';
|
697 |
$thumbs = array_merge($thumbs, self::getFilesByPattern($dirPath, $pattern));
|
698 |
/*foreach($thumbsCandidates as $th) {
|
699 |
if(preg_match($pattern, $th)) {
|
709 |
{
|
710 |
foreach ($infixes as $infix){
|
711 |
//$thumbsCandidates = @glob($base . $infix . "-*." . $ext);
|
712 |
+
$pattern = '/^' . preg_quote($base, '/') . $infix . '-\d+x\d+' . '\.'. $ext .'/';
|
713 |
$thumbs = array_merge($thumbs, self::getFilesByPattern($dirPath, $pattern));
|
714 |
|
715 |
/*foreach($thumbsCandidates as $th) {
|
750 |
}
|
751 |
catch(\Exception $e)
|
752 |
{
|
753 |
+
Log::addWarn('GetFilesbyPattern issue with directory. ', $e->getMessage());
|
754 |
return array();
|
755 |
}
|
756 |
|
786 |
}
|
787 |
}
|
788 |
|
789 |
+
protected static function getPostIdsChunk($minId, $maxId, $pointer, $limit, $byMinMax = false) {
|
790 |
global $wpdb;
|
791 |
|
792 |
+
// min/max : the function feeds proper Min and MaxId to function so offset pointer is not needed.
|
793 |
+
if ($byMinMax)
|
794 |
+
{
|
795 |
+
$pointer = 0;
|
796 |
+
$sql = "SELECT ID, post_mime_type, post_date FROM " . $wpdb->prefix . "posts
|
797 |
+
WHERE ( ID > $minId )
|
798 |
+
and post_mime_type <> ''
|
799 |
+
LIMIT $limit";
|
800 |
+
}
|
801 |
+
else {
|
802 |
+
$sql = "SELECT ID, post_mime_type, post_date FROM " . $wpdb->prefix . "posts
|
803 |
+
WHERE ( ID <= $maxId AND ID > $minId )
|
804 |
+
LIMIT $pointer,$limit";
|
805 |
+
}
|
806 |
+
|
807 |
$ids = $idDates = array();
|
808 |
+
$idList = $wpdb->get_results($sql);
|
809 |
+
|
|
|
810 |
if ( empty($idList) ) {
|
811 |
return null;
|
812 |
}
|
816 |
$idDates[$item->ID] = $item->post_date;
|
817 |
}
|
818 |
}
|
819 |
+
|
820 |
+
return (object)array('ids' => $ids, 'idDates' => $idDates, 'last_id' => $ids[count($ids)-1] );
|
821 |
+
}
|
822 |
+
|
823 |
+
/* Recount images from the media library when something went wrong badly */
|
824 |
+
public static function reCountMediaLibraryItems()
|
825 |
+
{
|
826 |
+
$limit = self::getOptimalChunkSize();
|
827 |
+
$run = true;
|
828 |
+
$minId = 0;
|
829 |
+
$maxId = -1; // not in use
|
830 |
+
$pointer = -1; // not in use.
|
831 |
+
|
832 |
+
$timeout = get_transient('shortpixel_debug_media');
|
833 |
+
if ($timeout !== false)
|
834 |
+
$minId = $timeout;
|
835 |
+
|
836 |
+
while ( $run == true ) {
|
837 |
+
if ($minId == -1)
|
838 |
+
exit('Hanging Loop Detected');
|
839 |
+
$idInfo = self::getPostIdsChunk($minId, $maxId, $pointer, $limit, true);
|
840 |
+
$minId = isset($idInfo->last_id) ? $idInfo->last_id : -1;
|
841 |
+
|
842 |
+
if($idInfo === null) {
|
843 |
+
break; //we parsed all the results
|
844 |
+
}
|
845 |
+
elseif(count($idInfo->ids) == 0) {
|
846 |
+
//$minId += $limit; // This is a no results case.
|
847 |
+
continue;
|
848 |
+
}
|
849 |
+
foreach($idInfo->ids as $post_id)
|
850 |
+
{
|
851 |
+
$imageModel = new \ShortPixel\ImageModel();
|
852 |
+
$imageModel->setByPostID($post_id);
|
853 |
+
$imageModel->reAcquire();
|
854 |
+
Log::addDebug('Reacquired: ' . $post_id );
|
855 |
+
}
|
856 |
+
|
857 |
+
set_transient('shortpixel_debug_media', $post_id, 20 * MINUTE_IN_SECONDS);
|
858 |
+
}
|
859 |
}
|
860 |
|
861 |
}
|
class/external/wp-offload-media.php
CHANGED
@@ -8,6 +8,8 @@ class wpOffload
|
|
8 |
protected $as3cf;
|
9 |
protected $active = false;
|
10 |
|
|
|
|
|
11 |
public function __construct()
|
12 |
{
|
13 |
// This must be called before WordPress' init.
|
@@ -17,21 +19,27 @@ class wpOffload
|
|
17 |
public function init($as3cf)
|
18 |
{
|
19 |
|
|
|
|
|
20 |
$this->as3cf = $as3cf;
|
21 |
$this->active = true;
|
22 |
|
23 |
add_action('shortpixel_image_optimised', array($this, 'image_upload'));
|
24 |
add_action('shortpixel_after_restore_image', array($this, 'image_restore')); // hit this when restoring.
|
25 |
add_action('shortpixel/image/convertpng2jpg_after', array($this, 'image_converted'));
|
|
|
26 |
add_action('shortpixel/image/convertpng2jpg_before', array($this, 'remove_remote'));
|
27 |
add_filter('as3cf_attachment_file_paths', array($this, 'add_webp_paths'));
|
28 |
add_filter('as3cf_remove_attachment_paths', array($this, 'remove_webp_paths'));
|
29 |
|
30 |
add_filter('shortpixel/restore/targetfile', array($this, 'returnOriginalFile'),10,2);
|
31 |
|
|
|
|
|
32 |
add_filter('get_attached_file', function($file, $id)
|
33 |
{
|
34 |
-
|
|
|
35 |
{
|
36 |
return get_attached_file($id, true);
|
37 |
}
|
@@ -108,10 +116,30 @@ class wpOffload
|
|
108 |
|
109 |
public function image_upload($id)
|
110 |
{
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
111 |
Log::addDebug('Uploading New Attachment');
|
112 |
$this->as3cf->upload_attachment($id);
|
113 |
}
|
114 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
115 |
|
116 |
private function getWebpPaths($paths, $check_exists = true)
|
117 |
{
|
8 |
protected $as3cf;
|
9 |
protected $active = false;
|
10 |
|
11 |
+
protected $settings;
|
12 |
+
|
13 |
public function __construct()
|
14 |
{
|
15 |
// This must be called before WordPress' init.
|
19 |
public function init($as3cf)
|
20 |
{
|
21 |
|
22 |
+
|
23 |
+
|
24 |
$this->as3cf = $as3cf;
|
25 |
$this->active = true;
|
26 |
|
27 |
add_action('shortpixel_image_optimised', array($this, 'image_upload'));
|
28 |
add_action('shortpixel_after_restore_image', array($this, 'image_restore')); // hit this when restoring.
|
29 |
add_action('shortpixel/image/convertpng2jpg_after', array($this, 'image_converted'));
|
30 |
+
add_action('shortpixel_before_restore_image', array($this, 'remove_remote')); // not optimal, when backup fails this will cause issues.
|
31 |
add_action('shortpixel/image/convertpng2jpg_before', array($this, 'remove_remote'));
|
32 |
add_filter('as3cf_attachment_file_paths', array($this, 'add_webp_paths'));
|
33 |
add_filter('as3cf_remove_attachment_paths', array($this, 'remove_webp_paths'));
|
34 |
|
35 |
add_filter('shortpixel/restore/targetfile', array($this, 'returnOriginalFile'),10,2);
|
36 |
|
37 |
+
add_filter('as3cf_pre_update_attachment_metadata', array($this, 'preventInitialUpload'), 10,4);
|
38 |
+
|
39 |
add_filter('get_attached_file', function($file, $id)
|
40 |
{
|
41 |
+
$scheme = parse_url($file, PHP_URL_SCHEME);
|
42 |
+
if ($scheme !== false && strpos($scheme, 's3') !== false)
|
43 |
{
|
44 |
return get_attached_file($id, true);
|
45 |
}
|
116 |
|
117 |
public function image_upload($id)
|
118 |
{
|
119 |
+
//$this->as3cf->get_setting( 'copy-to-s3' )
|
120 |
+
if ( ! ( $old_provider_object = $this->as3cf->get_attachment_provider_info( $id ) ) && ! $this->as3cf->get_setting( 'copy-to-s3' ) ) {
|
121 |
+
// abort if not already uploaded to provider and the copy setting is off
|
122 |
+
Log::addDebug('As3cf image upload is off and object not previously uploaded');
|
123 |
+
return false;
|
124 |
+
}
|
125 |
+
|
126 |
Log::addDebug('Uploading New Attachment');
|
127 |
$this->as3cf->upload_attachment($id);
|
128 |
}
|
129 |
|
130 |
+
/** This function will cut out the initial upload to S3Offload and rely solely on the image_upload function provided here, after shortpixel optimize.
|
131 |
+
* Function will only work when plugin is set to auto-optimize new entries to the media library */
|
132 |
+
public function preventInitialUpload($bool, $data, $post_id, $old_provider_object)
|
133 |
+
{
|
134 |
+
// @todo weak call. See how in future settings might come via central provider.
|
135 |
+
$settings = new \WPShortPixelSettings();
|
136 |
+
|
137 |
+
if ($settings->autoMediaLibrary)
|
138 |
+
{
|
139 |
+
return true;
|
140 |
+
}
|
141 |
+
return $bool;
|
142 |
+
}
|
143 |
|
144 |
private function getWebpPaths($paths, $check_exists = true)
|
145 |
{
|
class/front/img-to-picture-webp.php
CHANGED
@@ -112,6 +112,10 @@ class ShortPixelImgToPictureWebp
|
|
112 |
}
|
113 |
|
114 |
$img = self::get_attributes($match[0]);
|
|
|
|
|
|
|
|
|
115 |
// [BS] Can return false in case of Module fail. Escape in that case with unmodified image
|
116 |
if ($img === false)
|
117 |
return $match[0];
|
112 |
}
|
113 |
|
114 |
$img = self::get_attributes($match[0]);
|
115 |
+
if(isset($img['style']) && strpos($img['style'], 'background') !== false) {
|
116 |
+
//don't replace for <img>'s that have background
|
117 |
+
return $match[0];
|
118 |
+
}
|
119 |
// [BS] Can return false in case of Module fail. Escape in that case with unmodified image
|
120 |
if ($img === false)
|
121 |
return $match[0];
|
class/model/directory_model.php
CHANGED
@@ -148,7 +148,7 @@ class DirectoryModel extends ShortPixelModel
|
|
148 |
private function constructUsualDirectories($path)
|
149 |
{
|
150 |
$pathar = array_values(array_filter(explode('/', $path))); // array value to reset index
|
151 |
-
$
|
152 |
if ( ($key = array_search('wp-content', $pathar)) !== false)
|
153 |
{
|
154 |
$testpath = implode('/', array_slice($pathar, $key));
|
148 |
private function constructUsualDirectories($path)
|
149 |
{
|
150 |
$pathar = array_values(array_filter(explode('/', $path))); // array value to reset index
|
151 |
+
$testpath = false;
|
152 |
if ( ($key = array_search('wp-content', $pathar)) !== false)
|
153 |
{
|
154 |
$testpath = implode('/', array_slice($pathar, $key));
|
class/model/file_model.php
CHANGED
@@ -26,6 +26,8 @@ class FileModel extends ShortPixelModel
|
|
26 |
protected $exists = false;
|
27 |
protected $is_writable = false;
|
28 |
protected $is_readable = false;
|
|
|
|
|
29 |
protected $status;
|
30 |
|
31 |
protected $backupDirectory;
|
@@ -246,6 +248,7 @@ class FileModel extends ShortPixelModel
|
|
246 |
*/
|
247 |
protected function processPath($path)
|
248 |
{
|
|
|
249 |
$original_path = $path;
|
250 |
$path = trim($path);
|
251 |
|
26 |
protected $exists = false;
|
27 |
protected $is_writable = false;
|
28 |
protected $is_readable = false;
|
29 |
+
|
30 |
+
|
31 |
protected $status;
|
32 |
|
33 |
protected $backupDirectory;
|
248 |
*/
|
249 |
protected function processPath($path)
|
250 |
{
|
251 |
+
|
252 |
$original_path = $path;
|
253 |
$path = trim($path);
|
254 |
|
class/model/image_model.php
ADDED
@@ -0,0 +1,194 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
namespace ShortPixel;
|
3 |
+
use ShortPixel\ShortpixelLogger\ShortPixelLogger as Log;
|
4 |
+
|
5 |
+
/* ImageModel class.
|
6 |
+
*
|
7 |
+
*
|
8 |
+
* - Represents a -single- image *not file*.
|
9 |
+
* - Can be either MediaLibrary, or Custom .
|
10 |
+
* - Not a replacement of Meta, but might be.
|
11 |
+
* - Goal: Structural ONE method calls of image related information, and combining information. Same task is now done on many places.
|
12 |
+
* -- Shortpixel Class should be able to blindly call model for information, correct metadata and such.
|
13 |
+
*/
|
14 |
+
class ImageModel extends ShortPixelModel
|
15 |
+
{
|
16 |
+
|
17 |
+
private $file; // the file representation
|
18 |
+
private $meta; // metadata of the image.
|
19 |
+
private $facade; // ShortPixelMetaFacade
|
20 |
+
|
21 |
+
protected $thumbsnails = array(); // thumbnails of this
|
22 |
+
|
23 |
+
|
24 |
+
public function __construct()
|
25 |
+
{
|
26 |
+
|
27 |
+
}
|
28 |
+
|
29 |
+
public function setByPostID($post_id)
|
30 |
+
{
|
31 |
+
// Set Meta
|
32 |
+
$fs = new FileSystemController();
|
33 |
+
$this->facade = new \ShortPixelMetaFacade($post_id);
|
34 |
+
$this->meta = $this->facade->getMeta();
|
35 |
+
|
36 |
+
$file = get_attached_file($post_id);
|
37 |
+
$this->file = $fs->getFile($file);
|
38 |
+
|
39 |
+
}
|
40 |
+
|
41 |
+
public function getMeta()
|
42 |
+
{
|
43 |
+
return $this->meta;
|
44 |
+
}
|
45 |
+
|
46 |
+
public function getFile()
|
47 |
+
{
|
48 |
+
return $this->file;
|
49 |
+
}
|
50 |
+
|
51 |
+
/* Sanity check in process. Should only be called upon special request, or with single image displays. Should check and recheck stats, thumbs, unlistedthumbs and all assumptions of data that might corrupt or change outside of this plugin */
|
52 |
+
public function reAcquire()
|
53 |
+
{
|
54 |
+
$this->addUnlistedThumbs();
|
55 |
+
$this->reCheckThumbnails();
|
56 |
+
|
57 |
+
// $this->recount();
|
58 |
+
}
|
59 |
+
|
60 |
+
// Rebuild the ThumbsOptList and others to fix old info, wrong builds.
|
61 |
+
private function reCheckThumbnails()
|
62 |
+
{
|
63 |
+
// Redo only on non-processed images.
|
64 |
+
if ($this->meta->getStatus() != \ShortPixelMeta::FILE_STATUS_SUCCESS)
|
65 |
+
{
|
66 |
+
return;
|
67 |
+
}
|
68 |
+
$data = $this->facade->getRawMeta();
|
69 |
+
$oldList = array();
|
70 |
+
if (isset($data['ShortPixel']['thumbsOptList']))
|
71 |
+
{
|
72 |
+
$oldList = $data['ShortPixel']['thumbsOptList'];
|
73 |
+
unset($data['ShortPixel']['thumbsOptList']); // reset the thumbsOptList, so unset to get what the function thinks should be there.
|
74 |
+
}
|
75 |
+
list($includedSizes, $thumbsCount) = \WpShortPixelMediaLbraryAdapter::getThumbsToOptimize($data, $this->file->getFullPath() );
|
76 |
+
|
77 |
+
// When identical, save the check and the Dbase update.
|
78 |
+
if ($oldList === $includedSizes)
|
79 |
+
{
|
80 |
+
return;
|
81 |
+
}
|
82 |
+
|
83 |
+
$newList = array();
|
84 |
+
foreach($this->meta->getThumbsOptList() as $index => $item)
|
85 |
+
{
|
86 |
+
if ( in_array($item, $includedSizes))
|
87 |
+
{
|
88 |
+
$newList[] = $item;
|
89 |
+
}
|
90 |
+
}
|
91 |
+
|
92 |
+
$this->meta->setThumbsOptList($newList);
|
93 |
+
$this->facade->updateMeta($this->meta);
|
94 |
+
|
95 |
+
}
|
96 |
+
|
97 |
+
private function addUnlistedThumbs()
|
98 |
+
{
|
99 |
+
// @todo weak call. See how in future settings might come via central provider.
|
100 |
+
$settings = new \WPShortPixelSettings();
|
101 |
+
|
102 |
+
// must be media library, setting must be on.
|
103 |
+
if($this->facade->getType() != \ShortPixelMetaFacade::MEDIA_LIBRARY_TYPE
|
104 |
+
|| ! $settings->optimizeUnlisted) {
|
105 |
+
return 0;
|
106 |
+
}
|
107 |
+
|
108 |
+
$this->facade->removeSPFoundMeta(); // remove all found meta. If will be re-added here every time.
|
109 |
+
$meta = $this->meta; //$itemHandler->getMeta();
|
110 |
+
|
111 |
+
Log::addDebug('Finding Thumbs on path' . $meta->getPath());
|
112 |
+
$thumbs = \WpShortPixelMediaLbraryAdapter::findThumbs($meta->getPath());
|
113 |
+
|
114 |
+
$fs = new FileSystemController();
|
115 |
+
$mainFile = $this->file;
|
116 |
+
|
117 |
+
// Find Thumbs returns *full file path*
|
118 |
+
$foundThumbs = \WpShortPixelMediaLbraryAdapter::findThumbs($mainFile->getFullPath());
|
119 |
+
|
120 |
+
// no thumbs, then done.
|
121 |
+
if (count($foundThumbs) == 0)
|
122 |
+
{
|
123 |
+
return 0;
|
124 |
+
}
|
125 |
+
//first identify which thumbs are not in the sizes
|
126 |
+
$sizes = $meta->getThumbs();
|
127 |
+
$mimeType = false;
|
128 |
+
|
129 |
+
$allSizes = array();
|
130 |
+
$basepath = $mainFile->getFileDir()->getPath();
|
131 |
+
|
132 |
+
foreach($sizes as $size) {
|
133 |
+
// Thumbs should have filename only. This is shortpixel-meta ! Not metadata!
|
134 |
+
// Provided filename can be unexpected (URL, fullpath), so first do check, get filename, then check the full path
|
135 |
+
$sizeFileCheck = $fs->getFile($size['file']);
|
136 |
+
$sizeFilePath = $basepath . $sizeFileCheck->getFileName();
|
137 |
+
$sizeFile = $fs->getFile($sizeFilePath);
|
138 |
+
|
139 |
+
//get the mime-type from one of the thumbs metas
|
140 |
+
if(isset($size['mime-type'])) { //situation from support case #9351 Ramesh Mehay
|
141 |
+
$mimeType = $size['mime-type'];
|
142 |
+
}
|
143 |
+
$allSizes[] = $sizeFile;
|
144 |
+
}
|
145 |
+
|
146 |
+
foreach($foundThumbs as $id => $found) {
|
147 |
+
$foundFile = $fs->getFile($found);
|
148 |
+
|
149 |
+
foreach($allSizes as $sizeFile) {
|
150 |
+
if ($sizeFile->getExtension() !== $foundFile->getExtension())
|
151 |
+
{
|
152 |
+
$foundThumbs[$id] = false;
|
153 |
+
}
|
154 |
+
elseif ($sizeFile->getFileName() === $foundFile->getFileName())
|
155 |
+
{
|
156 |
+
$foundThumbs[$id] = false;
|
157 |
+
}
|
158 |
+
}
|
159 |
+
}
|
160 |
+
// add the unfound ones to the sizes array
|
161 |
+
$ind = 1;
|
162 |
+
$counter = 0;
|
163 |
+
// Assumption:: there is no point in adding to this array since findThumbs should find *all* thumbs that are relevant to this image.
|
164 |
+
/*while (isset($sizes[ShortPixelMeta::FOUND_THUMB_PREFIX . str_pad("".$start, 2, '0', STR_PAD_LEFT)]))
|
165 |
+
{
|
166 |
+
$start++;
|
167 |
+
} */
|
168 |
+
// $start = $ind;
|
169 |
+
|
170 |
+
foreach($foundThumbs as $found) {
|
171 |
+
if($found !== false) {
|
172 |
+
Log::addDebug('Adding File to sizes -> ' . $found);
|
173 |
+
$size = getimagesize($found);
|
174 |
+
Log::addDebug('Add Unlisted, add size' . $found );
|
175 |
+
|
176 |
+
$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
|
177 |
+
'file' => \ShortPixelAPI::MB_basename($found),
|
178 |
+
'width' => $size[0],
|
179 |
+
'height' => $size[1],
|
180 |
+
'mime-type' => $mimeType
|
181 |
+
);
|
182 |
+
$ind++;
|
183 |
+
$counter++;
|
184 |
+
}
|
185 |
+
}
|
186 |
+
if($ind > 1) { // at least one thumbnail added, update
|
187 |
+
$meta->setThumbs($sizes);
|
188 |
+
$this->facade->updateMeta($meta);
|
189 |
+
}
|
190 |
+
|
191 |
+
return $counter;
|
192 |
+
}
|
193 |
+
|
194 |
+
} // model
|
class/shortpixel-png2jpg.php
CHANGED
@@ -25,7 +25,11 @@ class ShortPixelPng2Jpg {
|
|
25 |
|
26 |
//WPShortPixel::log("PNG2JPG SHELL EXEC: " . shell_exec('convert ' . $image . ' -format "%[opaque]" info:'));
|
27 |
|
28 |
-
if (!file_exists($image)
|
|
|
|
|
|
|
|
|
29 |
$transparent = 1;
|
30 |
} else {
|
31 |
$contents = file_get_contents($image);
|
@@ -110,8 +114,9 @@ class ShortPixelPng2Jpg {
|
|
110 |
WPShortPixel::log("PNG2JPG doConvert created JPEG at $newPath");
|
111 |
$newSize = filesize($newPath);
|
112 |
$origSize = filesize($image);
|
113 |
-
if($newSize > $origSize * 0.95) {
|
114 |
//if the image is not 5% smaller, don't bother.
|
|
|
115 |
WPShortPixel::log("PNG2JPG converted image is larger ($newSize vs. $origSize), keeping the PNG");
|
116 |
unlink($newPath);
|
117 |
return (object)array("params" => $params, "unlink" => false);
|
@@ -217,6 +222,8 @@ class ShortPixelPng2Jpg {
|
|
217 |
|
218 |
$meta = $itemHandler->getRawMeta();
|
219 |
$ID = $itemHandler->getId();
|
|
|
|
|
220 |
if(!$this->_settings->png2jpg || !isset($meta['file']) || strtolower(substr($meta['file'], -4)) !== '.png') {
|
221 |
return ;
|
222 |
}
|
@@ -224,8 +231,8 @@ class ShortPixelPng2Jpg {
|
|
224 |
|
225 |
WPShortPixel::log("Send to processing: Convert Media PNG to JPG #{$ID} META: " . json_encode($meta));
|
226 |
|
227 |
-
$image = $meta['file'];
|
228 |
-
$imagePath = get_attached_file($ID);
|
229 |
$basePath = trailingslashit(str_replace($image, "", $imagePath));
|
230 |
$imageUrl = wp_get_attachment_url($ID);
|
231 |
$baseUrl = self::removeUrlProtocol(trailingslashit(str_replace($image, "", $imageUrl))); //make the base url protocol agnostic if it's not already
|
@@ -248,7 +255,7 @@ class ShortPixelPng2Jpg {
|
|
248 |
if($this->_settings->png2jpg == 2) {
|
249 |
$doConvert = true;
|
250 |
} else {
|
251 |
-
$retC = $this->canConvertPng2Jpg($
|
252 |
$doConvert = $retC['notTransparent'];
|
253 |
}
|
254 |
if (!$doConvert) {
|
25 |
|
26 |
//WPShortPixel::log("PNG2JPG SHELL EXEC: " . shell_exec('convert ' . $image . ' -format "%[opaque]" info:'));
|
27 |
|
28 |
+
if (!file_exists($image)) {
|
29 |
+
WPShortPixel::log("PNG2JPG FILE MISSING: " . $image);
|
30 |
+
$transparent = 1;
|
31 |
+
} elseif(ord(file_get_contents($image, false, null, 25, 1)) & 4) {
|
32 |
+
WPShortPixel::log("PNG2JPG: 25th byte has thrid bit 1 - transparency");
|
33 |
$transparent = 1;
|
34 |
} else {
|
35 |
$contents = file_get_contents($image);
|
114 |
WPShortPixel::log("PNG2JPG doConvert created JPEG at $newPath");
|
115 |
$newSize = filesize($newPath);
|
116 |
$origSize = filesize($image);
|
117 |
+
if($newSize > $origSize * 0.95 || $newSize == 0) {
|
118 |
//if the image is not 5% smaller, don't bother.
|
119 |
+
//if the size is 0, a conversion (or disk write) problem happened, go on with the PNG
|
120 |
WPShortPixel::log("PNG2JPG converted image is larger ($newSize vs. $origSize), keeping the PNG");
|
121 |
unlink($newPath);
|
122 |
return (object)array("params" => $params, "unlink" => false);
|
222 |
|
223 |
$meta = $itemHandler->getRawMeta();
|
224 |
$ID = $itemHandler->getId();
|
225 |
+
$fs = new \Shortpixel\FileSystemController;
|
226 |
+
|
227 |
if(!$this->_settings->png2jpg || !isset($meta['file']) || strtolower(substr($meta['file'], -4)) !== '.png') {
|
228 |
return ;
|
229 |
}
|
231 |
|
232 |
WPShortPixel::log("Send to processing: Convert Media PNG to JPG #{$ID} META: " . json_encode($meta));
|
233 |
|
234 |
+
$image = $meta['file']; // This is not a full path!
|
235 |
+
$imagePath = get_attached_file($ID); // This is a full path.
|
236 |
$basePath = trailingslashit(str_replace($image, "", $imagePath));
|
237 |
$imageUrl = wp_get_attachment_url($ID);
|
238 |
$baseUrl = self::removeUrlProtocol(trailingslashit(str_replace($image, "", $imageUrl))); //make the base url protocol agnostic if it's not already
|
255 |
if($this->_settings->png2jpg == 2) {
|
256 |
$doConvert = true;
|
257 |
} else {
|
258 |
+
$retC = $this->canConvertPng2Jpg($imagePath);
|
259 |
$doConvert = $retC['notTransparent'];
|
260 |
}
|
261 |
if (!$doConvert) {
|
class/view/settings/part-debug.php
CHANGED
@@ -36,5 +36,13 @@ namespace ShortPixel;
|
|
36 |
<pre><?php var_export($this->quotaData); ?></pre>
|
37 |
</div>
|
38 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
39 |
</div> <!-- tab-content -->
|
40 |
</section>
|
36 |
<pre><?php var_export($this->quotaData); ?></pre>
|
37 |
</div>
|
38 |
|
39 |
+
<h3>Tools</h3>
|
40 |
+
<div class='debug-images'>
|
41 |
+
<form method="POST" action="<?php echo add_query_arg(array('sp-action' => 'action_debug_medialibrary')) ?>"
|
42 |
+
id="shortpixel-form-debug-medialib">
|
43 |
+
<button class='button' type='submit'>Reacquire Thumbnails on Media Library</button>
|
44 |
+
</form>
|
45 |
+
</div>
|
46 |
+
|
47 |
</div> <!-- tab-content -->
|
48 |
</section>
|
class/view/settings/part-general.php
CHANGED
@@ -28,7 +28,7 @@
|
|
28 |
if($showApiKey) {
|
29 |
$canValidate = true;?>
|
30 |
<input name="key" type="text" id="key" value="<?php echo( $view->data->apiKey );?>"
|
31 |
-
class="regular-text" <?php echo($editApiKey ? "" : 'disabled') ?>
|
32 |
<?php
|
33 |
}
|
34 |
elseif(defined("SHORTPIXEL_API_KEY")) {
|
@@ -43,10 +43,10 @@
|
|
43 |
<?php } ?>
|
44 |
<input type="hidden" name="validate" id="valid" value=""/>
|
45 |
<span class="spinner" id="pluginemail_spinner" style="float:none;"></span>
|
46 |
-
|
47 |
onclick="ShortPixel.validateKey(this)" <?php echo $canValidate ? "" : "disabled"?> <?php echo $this->is_verifiedkey ? 'style="display:none;"' : '' ?>>
|
48 |
-
<?php _e('
|
49 |
-
</button>
|
50 |
<span class="shortpixel-key-valid" <?php echo $this->is_verifiedkey ? '' : 'style="display:none;"' ?>>
|
51 |
<span class="dashicons dashicons-yes"></span><?php _e('Your API key is valid.','shortpixel-image-optimiser');?>
|
52 |
</span>
|
28 |
if($showApiKey) {
|
29 |
$canValidate = true;?>
|
30 |
<input name="key" type="text" id="key" value="<?php echo( $view->data->apiKey );?>"
|
31 |
+
class="regular-text" <?php echo($editApiKey ? "" : 'disabled') ?> <?php echo $this->is_verifiedkey ? 'onkeyup="ShortPixel.apiKeyChanged()"' : '' ?>>
|
32 |
<?php
|
33 |
}
|
34 |
elseif(defined("SHORTPIXEL_API_KEY")) {
|
43 |
<?php } ?>
|
44 |
<input type="hidden" name="validate" id="valid" value=""/>
|
45 |
<span class="spinner" id="pluginemail_spinner" style="float:none;"></span>
|
46 |
+
<button type="button" id="validate" class="button button-primary" title="<?php _e('Validate the provided API key','shortpixel-image-optimiser');?>"
|
47 |
onclick="ShortPixel.validateKey(this)" <?php echo $canValidate ? "" : "disabled"?> <?php echo $this->is_verifiedkey ? 'style="display:none;"' : '' ?>>
|
48 |
+
<?php _e('Save settings & validate','shortpixel-image-optimiser');?>
|
49 |
+
</button>
|
50 |
<span class="shortpixel-key-valid" <?php echo $this->is_verifiedkey ? '' : 'style="display:none;"' ?>>
|
51 |
<span class="dashicons dashicons-yes"></span><?php _e('Your API key is valid.','shortpixel-image-optimiser');?>
|
52 |
</span>
|
class/view/shortpixel_view.php
CHANGED
@@ -1662,6 +1662,16 @@ class ShortPixelView {
|
|
1662 |
}
|
1663 |
|
1664 |
public function renderCustomColumn($id, $data, $extended = false){ ?>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1665 |
<div id='sp-msg-<?php echo($id);?>' class='column-wp-shortPixel'>
|
1666 |
|
1667 |
<?php switch($data['status']) {
|
@@ -1720,13 +1730,13 @@ class ShortPixelView {
|
|
1720 |
$excluded = (isset($data['excludeSizes']) ? count($data['excludeSizes']) : 0);
|
1721 |
$successText = $this->getSuccessText($data['percent'],$data['bonus'],$data['type'],$data['thumbsOpt'],$data['thumbsTotal'], $data['retinasOpt'], $data['excludeSizes']);
|
1722 |
$todoSizes = $missingThumbs = $excludeSizes = '';
|
1723 |
-
if($extended) {
|
1724 |
if(isset($data['thumbsToOptimizeList']) && count($data['thumbsToOptimizeList'])) {
|
1725 |
$todoSizes .= "<br><span style='word-break: break-all;'> <span style='font-weight: bold;'>" . __("To optimize:", 'shortpixel-image-optimiser') . "</span>";
|
1726 |
foreach($data['thumbsToOptimizeList'] as $todoItem) {
|
1727 |
$todoSizes .= "<br> • " . $todoItem;
|
1728 |
}
|
1729 |
-
$
|
1730 |
}
|
1731 |
if(isset($data['excludeSizes'])) {
|
1732 |
$excludeSizes .= "<br><span style='word-break: break-all;'> <span style='font-weight: bold;'>" . __("Excluded thumbnails:", 'shortpixel-image-optimiser') . "</span>";
|
@@ -1747,7 +1757,7 @@ class ShortPixelView {
|
|
1747 |
. ($data['png2jpg'] ? '<br>' . __('Converted from PNG','shortpixel-image-optimiser'): '')
|
1748 |
. "<br>" . __("Optimized on", 'shortpixel-image-optimiser') . ": " . $data['date']
|
1749 |
. $todoSizes . $excludeSizes . $missingThumbs;
|
1750 |
-
}
|
1751 |
$this->renderListCell($id, $data['status'], $data['showActions'], $data['thumbsToOptimize'],
|
1752 |
$data['backup'], $data['type'], $data['invType'], $successText);
|
1753 |
|
1662 |
}
|
1663 |
|
1664 |
public function renderCustomColumn($id, $data, $extended = false){ ?>
|
1665 |
+
<?php if ($extended) // extended ( edit-media ) moved to it's own view.
|
1666 |
+
{
|
1667 |
+
$controller = new \ShortPixel\editMediaController();
|
1668 |
+
$controller->setTempData($data);
|
1669 |
+
$controller->setLegacyView($this);
|
1670 |
+
$controller->setShortPixel($this->ctrl);
|
1671 |
+
$controller->load($id);
|
1672 |
+
return;
|
1673 |
+
}
|
1674 |
+
?>
|
1675 |
<div id='sp-msg-<?php echo($id);?>' class='column-wp-shortPixel'>
|
1676 |
|
1677 |
<?php switch($data['status']) {
|
1730 |
$excluded = (isset($data['excludeSizes']) ? count($data['excludeSizes']) : 0);
|
1731 |
$successText = $this->getSuccessText($data['percent'],$data['bonus'],$data['type'],$data['thumbsOpt'],$data['thumbsTotal'], $data['retinasOpt'], $data['excludeSizes']);
|
1732 |
$todoSizes = $missingThumbs = $excludeSizes = '';
|
1733 |
+
/*if($extended) {
|
1734 |
if(isset($data['thumbsToOptimizeList']) && count($data['thumbsToOptimizeList'])) {
|
1735 |
$todoSizes .= "<br><span style='word-break: break-all;'> <span style='font-weight: bold;'>" . __("To optimize:", 'shortpixel-image-optimiser') . "</span>";
|
1736 |
foreach($data['thumbsToOptimizeList'] as $todoItem) {
|
1737 |
$todoSizes .= "<br> • " . $todoItem;
|
1738 |
}
|
1739 |
+
$todoSizes .= '</span>';
|
1740 |
}
|
1741 |
if(isset($data['excludeSizes'])) {
|
1742 |
$excludeSizes .= "<br><span style='word-break: break-all;'> <span style='font-weight: bold;'>" . __("Excluded thumbnails:", 'shortpixel-image-optimiser') . "</span>";
|
1757 |
. ($data['png2jpg'] ? '<br>' . __('Converted from PNG','shortpixel-image-optimiser'): '')
|
1758 |
. "<br>" . __("Optimized on", 'shortpixel-image-optimiser') . ": " . $data['date']
|
1759 |
. $todoSizes . $excludeSizes . $missingThumbs;
|
1760 |
+
} */
|
1761 |
$this->renderListCell($id, $data['status'], $data['showActions'], $data['thumbsToOptimize'],
|
1762 |
$data['backup'], $data['type'], $data['invType'], $successText);
|
1763 |
|
class/view/view-edit-media.php
ADDED
@@ -0,0 +1,57 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
namespace ShortPixel;
|
3 |
+
use ShortPixel\ShortpixelLogger\ShortPixelLogger as Log;
|
4 |
+
|
5 |
+
?>
|
6 |
+
|
7 |
+
<div id='sp-msg-<?php echo($view->id);?>' class='column-wp-shortPixel view-edit-media'>
|
8 |
+
<?php // Debug Data
|
9 |
+
if (! is_null($view->debugInfo)): ?>
|
10 |
+
<div class='debugInfo'>
|
11 |
+
<ul>
|
12 |
+
<?php foreach($view->debugInfo as $item): ?>
|
13 |
+
<li><strong><?php echo $item[0]; ?></strong>
|
14 |
+
<?php
|
15 |
+
if (is_array($item[1]) || is_object($item[1]))
|
16 |
+
echo "<PRE>" . print_r($item[1], true) . "</PRE>";
|
17 |
+
else
|
18 |
+
echo $item[1];
|
19 |
+
?>
|
20 |
+
</li>
|
21 |
+
<?php endforeach; ?>
|
22 |
+
</ul>
|
23 |
+
|
24 |
+
</div>
|
25 |
+
<?php endif; ?>
|
26 |
+
|
27 |
+
<?php if (! is_null($view->status_message)): ?>
|
28 |
+
<h5><?php echo $view->status_message; ?></h5>
|
29 |
+
<?php endif; ?>
|
30 |
+
|
31 |
+
<p><?php echo $view->message; ?></p>
|
32 |
+
|
33 |
+
<?php if (count($view->stats) > 0): ?>
|
34 |
+
<div class='sp-column-stats'>
|
35 |
+
<?php $this->renderLegacyCell(); ?>
|
36 |
+
<ul class='edit-media-stats'>
|
37 |
+
<?php foreach($view->stats as $index => $data)
|
38 |
+
{ ?>
|
39 |
+
<li><span><?php echo $data[0] ?></span> <span><?php echo $data[1] ?></span></li>
|
40 |
+
<?php } ?>
|
41 |
+
</ul>
|
42 |
+
</div>
|
43 |
+
<?php endif; ?>
|
44 |
+
|
45 |
+
<?php foreach($view->todo as $item)
|
46 |
+
echo $item ;
|
47 |
+
?>
|
48 |
+
|
49 |
+
<div class='main-actions'>
|
50 |
+
<?php foreach($view->actions as $action)
|
51 |
+
echo $action;
|
52 |
+
?>
|
53 |
+
</div>
|
54 |
+
|
55 |
+
|
56 |
+
|
57 |
+
</div>
|
class/wp-short-pixel.php
CHANGED
@@ -70,7 +70,7 @@ class WPShortPixel {
|
|
70 |
add_filter( 'request', array( &$this, 'columnOrderFilterBy') );
|
71 |
add_action('restrict_manage_posts', array( &$this, 'mediaAddFilterDropdown'));
|
72 |
//Edit media meta box
|
73 |
-
add_action( 'add_meta_boxes', array( &$this, 'shortpixelInfoBox') );
|
74 |
//for cleaning up the WebP images when an attachment is deleted
|
75 |
add_action( 'delete_attachment', array( &$this, 'onDeleteImage') );
|
76 |
|
@@ -1499,7 +1499,14 @@ class WPShortPixel {
|
|
1499 |
//$urlPath = implode("/", array_slice($filePath, 0, count($filePath) - 1));
|
1500 |
$thumb = $uploadsUrl . $urlPath . $thumb;
|
1501 |
} else {
|
|
|
1502 |
$mainUrl = ShortPixelMetaFacade::safeGetAttachmentUrl($itemHandler->getId());
|
|
|
|
|
|
|
|
|
|
|
|
|
1503 |
$thumb = dirname($mainUrl) . '/' . $thumb;
|
1504 |
}
|
1505 |
}
|
@@ -1624,6 +1631,7 @@ class WPShortPixel {
|
|
1624 |
* Will update meta. if any are found.
|
1625 |
* @param ShortPixelMetaFacade $itemHandler ShortpixelMetaFacade item handler.
|
1626 |
* @return int Number of additions to the sizes Metadata.
|
|
|
1627 |
*/
|
1628 |
private function addUnlistedThumbs($itemHandler)
|
1629 |
{
|
@@ -1729,14 +1737,13 @@ class WPShortPixel {
|
|
1729 |
}
|
1730 |
}
|
1731 |
|
1732 |
-
$meta = $itemHandler->getMeta();
|
1733 |
-
|
1734 |
//WpShortPixelMediaLbraryAdapter::cleanupFoundThumbs($itemHandler);
|
1735 |
$URLsAndPATHs = $this->getURLsAndPATHs($itemHandler, NULL, $onlyThumbs);
|
1736 |
Log::addDebug('Send to PRocessing - URLS -', array($URLsAndPATHs) );
|
1737 |
|
1738 |
//find thumbs that are not listed in the metadata and add them in the sizes array
|
1739 |
$this->addUnlistedThumbs($itemHandler);
|
|
|
1740 |
|
1741 |
//find any missing thumbs files and mark them as such
|
1742 |
$miss = $meta->getThumbsMissing();
|
@@ -2086,23 +2093,37 @@ class WPShortPixel {
|
|
2086 |
|
2087 |
$baseUrl = str_replace($fsFile->getFileName(), '', $imageUrl); // remove *only* filename from URL
|
2088 |
$baseUrl = ShortPixelPng2Jpg::removeUrlProtocol($baseUrl); // @todo parse_url with a util helper / model should be better here
|
|
|
|
|
|
|
|
|
|
|
2089 |
|
2090 |
// $baseUrl = ShortPixelPng2Jpg::removeUrlProtocol(trailingslashit(str_replace($image, "", $imageUrl))); //make the base url protocol agnostic if it's not already
|
2091 |
|
2092 |
// not needed, we don't do this weird remove anymore.
|
2093 |
$baseRelPath = ''; // trailingslashit(dirname($image)); // @todo Replace this (string) $fsFile->getFileDir();
|
2094 |
|
|
|
2095 |
$toReplace[ShortPixelPng2Jpg::removeUrlProtocol($imageUrl)] = $baseUrl . $baseRelPath . wp_basename($png2jpgMain);
|
2096 |
foreach($sizes as $key => $size) {
|
2097 |
if(isset($png2jpgSizes[$key])) {
|
2098 |
$toReplace[$baseUrl . $baseRelPath . $size['file']] = $baseUrl . $baseRelPath . wp_basename($png2jpgSizes[$key]['file']);
|
2099 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2100 |
}
|
2101 |
|
2102 |
//$file = $png2jpgMain;
|
2103 |
$sizes = $png2jpgSizes;
|
2104 |
|
2105 |
-
$fsFile = $fs->getFile($png2jpgMain); // original is non-existing at this time.
|
|
|
2106 |
|
2107 |
}
|
2108 |
|
@@ -2134,7 +2155,6 @@ class WPShortPixel {
|
|
2134 |
//$dest = $pathInfo['dirname'] . '/' . $imageData['file'];
|
2135 |
$destination = $fs->getFile($filePath . $imageData['file']);
|
2136 |
$source = $fs->getFile($bkFolder->getPath() . $imageData['file']); //trailingslashit($bkFolder) . $imageData['file'];
|
2137 |
-
|
2138 |
if(! $source->exists() ) continue; // if thumbs were not optimized, then the backups will not be there.
|
2139 |
if(! $source->is_readable() || ($destination->exists() && !$destination->is_writable() )) {
|
2140 |
$failedFile = ($destination->is_writable() ? $source->getFullPath() : $destination->getFullPath());
|
@@ -2177,9 +2197,6 @@ class WPShortPixel {
|
|
2177 |
Log::addError('DoRestore failed restoring retina backup', array($retinaBK->getFullPath(), $retinaDest->getFullPath() ));
|
2178 |
}
|
2179 |
}
|
2180 |
-
|
2181 |
-
//@rename($bkFile, $file);
|
2182 |
-
//@rename($this->retinaName($bkFile), $this->retinaName($file));
|
2183 |
}
|
2184 |
//getSize to update meta if image was resized by ShortPixel
|
2185 |
if($fsFile->exists()) {
|
@@ -2189,7 +2206,6 @@ class WPShortPixel {
|
|
2189 |
}
|
2190 |
|
2191 |
//overwriting thumbnails
|
2192 |
-
|
2193 |
foreach($thumbsPaths as $index => $data) {
|
2194 |
$source = $data['source'];
|
2195 |
$destination = $data['destination'];
|
@@ -2251,10 +2267,13 @@ class WPShortPixel {
|
|
2251 |
$spPng2Jpg = new ShortPixelPng2Jpg($this->_settings);
|
2252 |
$spPng2Jpg->png2JpgUpdateUrls(array(), $toReplace);
|
2253 |
}
|
|
|
2254 |
if(isset($toUnlink['PATHs'])) foreach($toUnlink['PATHs'] as $unlink) {
|
2255 |
if($png2jpgMain) {
|
2256 |
WPShortPixel::log("PNG2JPG unlink $unlink");
|
2257 |
-
|
|
|
|
|
2258 |
}
|
2259 |
//try also the .webp
|
2260 |
$unlinkWebpSymlink = trailingslashit(dirname($unlink)) . wp_basename($unlink, '.' . pathinfo($unlink, PATHINFO_EXTENSION)) . '.webp';
|
@@ -2614,7 +2633,7 @@ class WPShortPixel {
|
|
2614 |
{
|
2615 |
return $this->_settings->currentStats;
|
2616 |
} else {
|
2617 |
-
$imageCount = WpShortPixelMediaLbraryAdapter::
|
2618 |
$quotaData['time'] = time();
|
2619 |
$quotaData['optimizePdfs'] = $this->_settings->optimizePdfs;
|
2620 |
//$quotaData['quotaData'] = $quotaData;
|
@@ -2832,7 +2851,7 @@ class WPShortPixel {
|
|
2832 |
}//resume was clicked
|
2833 |
|
2834 |
//figure out the files that are left to be processed
|
2835 |
-
$qry_left = "SELECT count(
|
2836 |
WHERE meta_key = '_wp_attached_file' AND post_id <= " . (0 + $this->prioQ->getStartBulkId());
|
2837 |
$filesLeft = $wpdb->get_results($qry_left);
|
2838 |
|
@@ -3486,7 +3505,7 @@ class WPShortPixel {
|
|
3486 |
* @todo Move this to custom media controller
|
3487 |
*/
|
3488 |
public function generateCustomColumn( $column_name, $id, $extended = false ) {
|
3489 |
-
|
3490 |
|
3491 |
if(!$this->isProcessable($id)) {
|
3492 |
$renderData['status'] = 'n/a';
|
@@ -3499,19 +3518,6 @@ class WPShortPixel {
|
|
3499 |
$itemHandler = new ShortPixelMetaFacade($id);
|
3500 |
$meta = $itemHandler->getMeta();
|
3501 |
|
3502 |
-
if($extended && Log::debugIsActive()) {
|
3503 |
-
// var_dump($data);
|
3504 |
-
$sizes = isset($data['sizes']) ? $data['sizes'] : array();
|
3505 |
-
echo "<PRE style='font-size:11px; overflow:hidden; white-space:pre-wrap'>";
|
3506 |
-
echo "<strong>URL: </strong>"; print_r(wp_get_attachment_url($id));
|
3507 |
-
echo('<br><br>' . json_encode(ShortPixelMetaFacade::getWPMLDuplicates($id)));
|
3508 |
-
echo('<br><br><span class="array">'); print_r($data); echo ''; //json_encode($data))
|
3509 |
-
echo('</span><br><br>');
|
3510 |
-
echo '<p><strong>Backup Folder: </strong>' . $this->getBackupFolderAny($file, $sizes) . '</p>';
|
3511 |
-
echo '<p><strong>Status</strong>: ' . $meta->getStatus() . '</p>';
|
3512 |
-
echo "</PRE>";
|
3513 |
-
}
|
3514 |
-
|
3515 |
$fileExtension = strtolower(pathinfo($file, PATHINFO_EXTENSION));
|
3516 |
$invalidKey = !$this->_settings->verifiedKey;
|
3517 |
$quotaExceeded = $this->_settings->quotaExceeded;
|
@@ -3634,54 +3640,9 @@ class WPShortPixel {
|
|
3634 |
* @return array Array of Thumbs to Optimize - only the filename - , and count of sizes not excluded ...
|
3635 |
*/
|
3636 |
function getThumbsToOptimize($data, $filepath) {
|
3637 |
-
|
3638 |
-
$
|
3639 |
-
|
3640 |
-
$sizesCount = isset($data['sizes']) ? WpShortPixelMediaLbraryAdapter::countSizesNotExcluded($data['sizes']) : 0;
|
3641 |
-
$basedir = $mainfile->getFileDir()->getPath();
|
3642 |
-
$thumbsOptList = isset($data['ShortPixel']['thumbsOptList']) ? $data['ShortPixel']['thumbsOptList'] : array();
|
3643 |
-
$thumbsToOptimizeList = array(); // is returned, so should be defined before if.
|
3644 |
-
|
3645 |
-
if($sizesCount && $this->_settings->processThumbnails) {
|
3646 |
|
3647 |
-
// findThumbs returns fullfilepath.
|
3648 |
-
$found = $this->_settings->optimizeUnlisted ? WpShortPixelMediaLbraryAdapter::findThumbs($mainfile->getFullPath()) : array();
|
3649 |
-
|
3650 |
-
$exclude = $this->_settings->excludeSizes;
|
3651 |
-
$exclude = is_array($exclude) ? $exclude : array();
|
3652 |
-
foreach($data['sizes'] as $size => $sizeData) {
|
3653 |
-
unset($found[\array_search($basedir . $sizeData['file'], $found)]); // @todo what is this intended to do?
|
3654 |
-
|
3655 |
-
// sizeData['file'] is *only* filename *but* can be wrong data, URL due to plugins. So check first, only get filename ( since it is supposed to fail with only a filename path ) and then reload.
|
3656 |
-
$sizeFileCheck = $fs->getFile($sizeData['file']);
|
3657 |
-
$file = $fs->getFile($basedir . $sizeFileCheck->getFileName());
|
3658 |
-
|
3659 |
-
if ($file->getExtension() !== $mainfile->getExtension())
|
3660 |
-
{
|
3661 |
-
continue;
|
3662 |
-
}
|
3663 |
-
|
3664 |
-
if(!in_array($size, $exclude) && !in_array($file->getFileName(), $thumbsOptList)) {
|
3665 |
-
$thumbsToOptimizeList[] = $file->getFileName();
|
3666 |
-
}
|
3667 |
-
}
|
3668 |
-
//$found = array_diff($found, $thumbsOptList); // Wrong comparison. Found is full file path, thumbsOptList is not.
|
3669 |
-
foreach($found as $path) {
|
3670 |
-
$file = $fs->getFile($path);
|
3671 |
-
|
3672 |
-
// prevent Webp and what not from showing up.
|
3673 |
-
if ($file->getExtension() !== $mainfile->getExtension())
|
3674 |
-
{
|
3675 |
-
continue;
|
3676 |
-
}
|
3677 |
-
// thumbs can already be in findThumbs.
|
3678 |
-
if (! in_array($file->getFileName(), $thumbsToOptimizeList) && ! in_array($file->getFileName(), $thumbsOptList) )
|
3679 |
-
{
|
3680 |
-
$thumbsToOptimizeList[] = $file->getFileName();
|
3681 |
-
}
|
3682 |
-
}
|
3683 |
-
}
|
3684 |
-
return array($thumbsToOptimizeList, $sizesCount);
|
3685 |
}
|
3686 |
|
3687 |
/** Make columns sortable in Media Library
|
70 |
add_filter( 'request', array( &$this, 'columnOrderFilterBy') );
|
71 |
add_action('restrict_manage_posts', array( &$this, 'mediaAddFilterDropdown'));
|
72 |
//Edit media meta box
|
73 |
+
add_action( 'add_meta_boxes', array( &$this, 'shortpixelInfoBox') ); // the info box in edit-media
|
74 |
//for cleaning up the WebP images when an attachment is deleted
|
75 |
add_action( 'delete_attachment', array( &$this, 'onDeleteImage') );
|
76 |
|
1499 |
//$urlPath = implode("/", array_slice($filePath, 0, count($filePath) - 1));
|
1500 |
$thumb = $uploadsUrl . $urlPath . $thumb;
|
1501 |
} else {
|
1502 |
+
try {
|
1503 |
$mainUrl = ShortPixelMetaFacade::safeGetAttachmentUrl($itemHandler->getId());
|
1504 |
+
}
|
1505 |
+
catch(Exception $e)
|
1506 |
+
{
|
1507 |
+
Log::addError('Attachment seems corrupted!', array($e->getMessage() ));
|
1508 |
+
$mainUrl = null; // error state.
|
1509 |
+
}
|
1510 |
$thumb = dirname($mainUrl) . '/' . $thumb;
|
1511 |
}
|
1512 |
}
|
1631 |
* Will update meta. if any are found.
|
1632 |
* @param ShortPixelMetaFacade $itemHandler ShortpixelMetaFacade item handler.
|
1633 |
* @return int Number of additions to the sizes Metadata.
|
1634 |
+
* @todo This function should Dis/pear. addUnlistedThumbs is now part of image model, to be called via proper controller.
|
1635 |
*/
|
1636 |
private function addUnlistedThumbs($itemHandler)
|
1637 |
{
|
1737 |
}
|
1738 |
}
|
1739 |
|
|
|
|
|
1740 |
//WpShortPixelMediaLbraryAdapter::cleanupFoundThumbs($itemHandler);
|
1741 |
$URLsAndPATHs = $this->getURLsAndPATHs($itemHandler, NULL, $onlyThumbs);
|
1742 |
Log::addDebug('Send to PRocessing - URLS -', array($URLsAndPATHs) );
|
1743 |
|
1744 |
//find thumbs that are not listed in the metadata and add them in the sizes array
|
1745 |
$this->addUnlistedThumbs($itemHandler);
|
1746 |
+
$meta = $itemHandler->getMeta();
|
1747 |
|
1748 |
//find any missing thumbs files and mark them as such
|
1749 |
$miss = $meta->getThumbsMissing();
|
2093 |
|
2094 |
$baseUrl = str_replace($fsFile->getFileName(), '', $imageUrl); // remove *only* filename from URL
|
2095 |
$baseUrl = ShortPixelPng2Jpg::removeUrlProtocol($baseUrl); // @todo parse_url with a util helper / model should be better here
|
2096 |
+
$backupFileDir = $bkFile->getFileDir(); // directory of the backups.
|
2097 |
+
|
2098 |
+
// find the jpg optimized image in backups, and mark to remove
|
2099 |
+
if ($bkFile->exists())
|
2100 |
+
$toUnlink['PATHs'][] = $bkFile->getFullPath();
|
2101 |
|
2102 |
// $baseUrl = ShortPixelPng2Jpg::removeUrlProtocol(trailingslashit(str_replace($image, "", $imageUrl))); //make the base url protocol agnostic if it's not already
|
2103 |
|
2104 |
// not needed, we don't do this weird remove anymore.
|
2105 |
$baseRelPath = ''; // trailingslashit(dirname($image)); // @todo Replace this (string) $fsFile->getFileDir();
|
2106 |
|
2107 |
+
|
2108 |
$toReplace[ShortPixelPng2Jpg::removeUrlProtocol($imageUrl)] = $baseUrl . $baseRelPath . wp_basename($png2jpgMain);
|
2109 |
foreach($sizes as $key => $size) {
|
2110 |
if(isset($png2jpgSizes[$key])) {
|
2111 |
$toReplace[$baseUrl . $baseRelPath . $size['file']] = $baseUrl . $baseRelPath . wp_basename($png2jpgSizes[$key]['file']);
|
2112 |
}
|
2113 |
+
|
2114 |
+
$backuppedSize = $fs->getFile($backupFileDir . $size['file'] );
|
2115 |
+
Log::addDebug('Find optimized JPGEG backupFile Thing', array( $backuppedSize->getFullPath() ));
|
2116 |
+
if ($backuppedSize->exists())
|
2117 |
+
{
|
2118 |
+
$toUnlink['PATHs'][] = $backuppedSize ->getFullPath();
|
2119 |
+
}
|
2120 |
}
|
2121 |
|
2122 |
//$file = $png2jpgMain;
|
2123 |
$sizes = $png2jpgSizes;
|
2124 |
|
2125 |
+
$fsFile = $fs->getFile($png2jpgMain); // original is non-existing at this time. :: Target
|
2126 |
+
$bkFile = $fs->getFile($bkFolder->getPath() . $fsFile->getFileName()); // Update this, because of filename (extension)
|
2127 |
|
2128 |
}
|
2129 |
|
2155 |
//$dest = $pathInfo['dirname'] . '/' . $imageData['file'];
|
2156 |
$destination = $fs->getFile($filePath . $imageData['file']);
|
2157 |
$source = $fs->getFile($bkFolder->getPath() . $imageData['file']); //trailingslashit($bkFolder) . $imageData['file'];
|
|
|
2158 |
if(! $source->exists() ) continue; // if thumbs were not optimized, then the backups will not be there.
|
2159 |
if(! $source->is_readable() || ($destination->exists() && !$destination->is_writable() )) {
|
2160 |
$failedFile = ($destination->is_writable() ? $source->getFullPath() : $destination->getFullPath());
|
2197 |
Log::addError('DoRestore failed restoring retina backup', array($retinaBK->getFullPath(), $retinaDest->getFullPath() ));
|
2198 |
}
|
2199 |
}
|
|
|
|
|
|
|
2200 |
}
|
2201 |
//getSize to update meta if image was resized by ShortPixel
|
2202 |
if($fsFile->exists()) {
|
2206 |
}
|
2207 |
|
2208 |
//overwriting thumbnails
|
|
|
2209 |
foreach($thumbsPaths as $index => $data) {
|
2210 |
$source = $data['source'];
|
2211 |
$destination = $data['destination'];
|
2267 |
$spPng2Jpg = new ShortPixelPng2Jpg($this->_settings);
|
2268 |
$spPng2Jpg->png2JpgUpdateUrls(array(), $toReplace);
|
2269 |
}
|
2270 |
+
Log::addDebug('DoRestore, Unlinking', array($toUnlink) );
|
2271 |
if(isset($toUnlink['PATHs'])) foreach($toUnlink['PATHs'] as $unlink) {
|
2272 |
if($png2jpgMain) {
|
2273 |
WPShortPixel::log("PNG2JPG unlink $unlink");
|
2274 |
+
$unlinkFile = $fs->getFile($unlink);
|
2275 |
+
$unlinkFile->delete();
|
2276 |
+
// @unlink($unlink);
|
2277 |
}
|
2278 |
//try also the .webp
|
2279 |
$unlinkWebpSymlink = trailingslashit(dirname($unlink)) . wp_basename($unlink, '.' . pathinfo($unlink, PATHINFO_EXTENSION)) . '.webp';
|
2633 |
{
|
2634 |
return $this->_settings->currentStats;
|
2635 |
} else {
|
2636 |
+
$imageCount = WpShortPixelMediaLbraryAdapter::countAllProcessable($this->_settings);
|
2637 |
$quotaData['time'] = time();
|
2638 |
$quotaData['optimizePdfs'] = $this->_settings->optimizePdfs;
|
2639 |
//$quotaData['quotaData'] = $quotaData;
|
2851 |
}//resume was clicked
|
2852 |
|
2853 |
//figure out the files that are left to be processed
|
2854 |
+
$qry_left = "SELECT count(meta_id) FilesLeftToBeProcessed FROM " . $wpdb->prefix . "postmeta
|
2855 |
WHERE meta_key = '_wp_attached_file' AND post_id <= " . (0 + $this->prioQ->getStartBulkId());
|
2856 |
$filesLeft = $wpdb->get_results($qry_left);
|
2857 |
|
3505 |
* @todo Move this to custom media controller
|
3506 |
*/
|
3507 |
public function generateCustomColumn( $column_name, $id, $extended = false ) {
|
3508 |
+
if( 'wp-shortPixel' == $column_name ) {
|
3509 |
|
3510 |
if(!$this->isProcessable($id)) {
|
3511 |
$renderData['status'] = 'n/a';
|
3518 |
$itemHandler = new ShortPixelMetaFacade($id);
|
3519 |
$meta = $itemHandler->getMeta();
|
3520 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
3521 |
$fileExtension = strtolower(pathinfo($file, PATHINFO_EXTENSION));
|
3522 |
$invalidKey = !$this->_settings->verifiedKey;
|
3523 |
$quotaExceeded = $this->_settings->quotaExceeded;
|
3640 |
* @return array Array of Thumbs to Optimize - only the filename - , and count of sizes not excluded ...
|
3641 |
*/
|
3642 |
function getThumbsToOptimize($data, $filepath) {
|
3643 |
+
// This function moved, but lack of other destination.
|
3644 |
+
return WpShortPixelMediaLbraryAdapter::getThumbsToOptimize($data, $filepath);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
3645 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
3646 |
}
|
3647 |
|
3648 |
/** Make columns sortable in Media Library
|
readme.txt
CHANGED
@@ -4,7 +4,7 @@ Tags: compressor, image, compression, optimize, image optimizer, image optimiser
|
|
4 |
Requires at least: 3.2.0
|
5 |
Tested up to: 5.2
|
6 |
Requires PHP: 5.3
|
7 |
-
Stable tag: 4.14.
|
8 |
License: GPLv2 or later
|
9 |
License URI: http://www.gnu.org/licenses/gpl-2.0.html
|
10 |
|
@@ -246,6 +246,25 @@ define('SHORTPIXEL_CUSTOM_THUMB_INFIXES', '-uae'); will handle custom thumbnails
|
|
246 |
|
247 |
== Changelog ==
|
248 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
249 |
= 4.14.5 =
|
250 |
Release date: 29th August 2019
|
251 |
* If constant SHORTPIXEL_USE_DOUBLE_WEBP_EXTENSION is defined as true, use double extension for WebP (.jpg.webp)
|
4 |
Requires at least: 3.2.0
|
5 |
Tested up to: 5.2
|
6 |
Requires PHP: 5.3
|
7 |
+
Stable tag: 4.14.6
|
8 |
License: GPLv2 or later
|
9 |
License URI: http://www.gnu.org/licenses/gpl-2.0.html
|
10 |
|
246 |
|
247 |
== Changelog ==
|
248 |
|
249 |
+
= 4.14.6 =
|
250 |
+
Release date: 9th October 2019
|
251 |
+
* Don't convert to <picture> the <img>s with backgrounds.
|
252 |
+
* Remove unused eval() call.
|
253 |
+
* Restore the validate button next to API Key but change label to "Save and validate"
|
254 |
+
* Fixed: PNGtoJPG issue with already uploaded images
|
255 |
+
* Fixed: finding wrong unlisted thumbnails due to regex.
|
256 |
+
* Fixed: fatal error when trying to delete crashed attachement ( without proper URL )
|
257 |
+
* Fix for S3 offload - PNG2JPG , doesn't remove old JPG files
|
258 |
+
* Fixed: S3Offload will not offload anymore when 'Copy files to bucket' is off ( and object was not previously offloaded )
|
259 |
+
* S3Offload doesn't offload via optimiser anymore if this setting is off
|
260 |
+
* Fixed: cutting out initial offload if optimization needs to be done, when autolibrary is on
|
261 |
+
* Fix for PNG2JPG - JPG files remained in backupdir.
|
262 |
+
* Small fix for remote download thumbnails
|
263 |
+
* Fixed: notice in filemodel due meta-facade feeding array
|
264 |
+
* Fixed: bug in File2Url in filesystemcontroller
|
265 |
+
* Fixed: download issue in attempt to remote download
|
266 |
+
* Language – 0 new strings added, 0 updated, 0 fuzzied, and 0 obsoleted
|
267 |
+
|
268 |
= 4.14.5 =
|
269 |
Release date: 29th August 2019
|
270 |
* If constant SHORTPIXEL_USE_DOUBLE_WEBP_EXTENSION is defined as true, use double extension for WebP (.jpg.webp)
|
res/css/shortpixel-admin.css
CHANGED
@@ -109,3 +109,24 @@
|
|
109 |
.settings_page_wp-shortpixel-settings section#tab-debug .env .flex span {
|
110 |
width: 45%;
|
111 |
padding: 4px; }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
109 |
.settings_page_wp-shortpixel-settings section#tab-debug .env .flex span {
|
110 |
width: 45%;
|
111 |
padding: 4px; }
|
112 |
+
|
113 |
+
.view-edit-media .debugInfo pre {
|
114 |
+
font-size: 11px; }
|
115 |
+
.view-edit-media .sp-column-stats {
|
116 |
+
position: relative; }
|
117 |
+
.view-edit-media .sp-column-stats .sp-column-actions {
|
118 |
+
margin-right: 5px;
|
119 |
+
margin-top: 16px; }
|
120 |
+
.view-edit-media .sp-column-stats .edit-media-stats {
|
121 |
+
border: 1px solid #ccc;
|
122 |
+
padding: 16px; }
|
123 |
+
.view-edit-media .sp-column-stats .edit-media-stats li {
|
124 |
+
margin: 0;
|
125 |
+
line-height: 20px; }
|
126 |
+
.view-edit-media .main-actions {
|
127 |
+
display: inline-block;
|
128 |
+
width: 100%; }
|
129 |
+
.view-edit-media .main-actions .button.button-smaller {
|
130 |
+
padding: 6px 15px;
|
131 |
+
height: auto;
|
132 |
+
float: none; }
|
res/js/shortpixel.js
CHANGED
@@ -63,13 +63,12 @@ var ShortPixel = function() {
|
|
63 |
jQuery('#request_key').attr('href', jQuery('#request_key').attr('href').split('?')[0] + '?pluginemail=' + email);
|
64 |
}
|
65 |
|
66 |
-
/* Can be removed.
|
67 |
function validateKey(button){
|
68 |
console.log('validate');
|
69 |
jQuery('#valid').val('validate');
|
70 |
|
71 |
jQuery(button).parents('form').submit();
|
72 |
-
}
|
73 |
|
74 |
jQuery("#key").keypress(function(e) {
|
75 |
if(e.which == 13) {
|
@@ -256,7 +255,7 @@ var ShortPixel = function() {
|
|
256 |
ShortPixel.adjustSettingsTabs();
|
257 |
jQuery(section).find('.wp-shortpixel-tab-content').fadeIn(50);
|
258 |
}
|
259 |
-
if(typeof HS.beacon.suggest !== 'undefined' ){
|
260 |
switch(tab){
|
261 |
case "settings":
|
262 |
beacon = shortpixel_suggestions_settings;
|
@@ -794,7 +793,7 @@ var ShortPixel = function() {
|
|
794 |
setOptions : setOptions,
|
795 |
isEmailValid : isEmailValid,
|
796 |
updateSignupEmail : updateSignupEmail,
|
797 |
-
|
798 |
enableResize : enableResize,
|
799 |
setupGeneralTab : setupGeneralTab,
|
800 |
apiKeyChanged : apiKeyChanged,
|
63 |
jQuery('#request_key').attr('href', jQuery('#request_key').attr('href').split('?')[0] + '?pluginemail=' + email);
|
64 |
}
|
65 |
|
|
|
66 |
function validateKey(button){
|
67 |
console.log('validate');
|
68 |
jQuery('#valid').val('validate');
|
69 |
|
70 |
jQuery(button).parents('form').submit();
|
71 |
+
}
|
72 |
|
73 |
jQuery("#key").keypress(function(e) {
|
74 |
if(e.which == 13) {
|
255 |
ShortPixel.adjustSettingsTabs();
|
256 |
jQuery(section).find('.wp-shortpixel-tab-content').fadeIn(50);
|
257 |
}
|
258 |
+
if(typeof HS !== 'undefined' && typeof HS.beacon.suggest !== 'undefined' ){
|
259 |
switch(tab){
|
260 |
case "settings":
|
261 |
beacon = shortpixel_suggestions_settings;
|
793 |
setOptions : setOptions,
|
794 |
isEmailValid : isEmailValid,
|
795 |
updateSignupEmail : updateSignupEmail,
|
796 |
+
validateKey : validateKey,
|
797 |
enableResize : enableResize,
|
798 |
setupGeneralTab : setupGeneralTab,
|
799 |
apiKeyChanged : apiKeyChanged,
|
res/js/shortpixel.min.js
CHANGED
@@ -1 +1 @@
|
|
1 |
-
function showToolBarAlert(e,r,t){var s=jQuery("li.shortpixel-toolbar-processing");switch(e){case ShortPixel.STATUS_QUOTA_EXCEEDED:if(window.location.href.search("wp-short-pixel-bulk")>0&&0==jQuery(".sp-quota-exceeded-alert").length)return void location.reload();s.addClass("shortpixel-alert"),s.addClass("shortpixel-quota-exceeded"),jQuery("a",s).attr("href","options-general.php?page=wp-shortpixel-settings"),jQuery("a div",s).attr("title","ShortPixel quota exceeded. Click for details.");break;case ShortPixel.STATUS_SKIP:case ShortPixel.STATUS_FAIL:s.addClass("shortpixel-alert shortpixel-processing"),jQuery("a div",s).attr("title",r),void 0!==t&&jQuery("a",s).attr("href","post.php?post="+t+"&action=edit");break;case ShortPixel.STATUS_NO_KEY:s.addClass("shortpixel-alert"),s.addClass("shortpixel-quota-exceeded"),jQuery("a",s).attr("href","options-general.php?page=wp-shortpixel-settings"),jQuery("a div",s).attr("title","Get API Key");break;case ShortPixel.STATUS_SUCCESS:case ShortPixel.STATUS_RETRY:s.addClass("shortpixel-processing"),s.removeClass("shortpixel-alert"),jQuery("a",s).removeAttr("target"),jQuery("a",s).attr("href",jQuery("a img",s).attr("success-url"))}s.removeClass("shortpixel-hide")}function hideToolBarAlert(){jQuery("li.shortpixel-toolbar-processing.shortpixel-processing").addClass("shortpixel-hide")}function hideQuotaExceededToolBarAlert(){jQuery("li.shortpixel-toolbar-processing.shortpixel-quota-exceeded").addClass("shortpixel-hide")}function checkQuotaExceededAlert(){"undefined"!=typeof shortPixelQuotaExceeded&&(1==shortPixelQuotaExceeded?showToolBarAlert(ShortPixel.STATUS_QUOTA_EXCEEDED):hideQuotaExceededToolBarAlert())}function checkBulkProgress(){var e=function(e){return r?"/":(r=!0,e)},r=!1,t=window.location.href.toLowerCase().replace(/\/\//g,e);r=!1;var s=ShortPixel.WP_ADMIN_URL.toLowerCase().replace(/\/\//g,e);t.search(s)<0&&(t=ShortPixel.convertPunycode(t),s=ShortPixel.convertPunycode(s)),t.search(s+"upload.php")<0&&t.search(s+"edit.php")<0&&t.search(s+"edit-tags.php")<0&&t.search(s+"post-new.php")<0&&t.search(s+"post.php")<0&&t.search("page=nggallery-manage-gallery")<0&&(0==ShortPixel.FRONT_BOOTSTRAP||0==t.search(s))?hideToolBarAlert():(1==ShortPixel.bulkProcessor&&window.location.href.search("wp-short-pixel-bulk")<0&&void 0!==localStorage.bulkPage&&localStorage.bulkPage>0&&(ShortPixel.bulkProcessor=!1),window.location.href.search("wp-short-pixel-bulk")>=0&&(ShortPixel.bulkProcessor=!0,localStorage.bulkTime=Math.floor(Date.now()/1e3),localStorage.bulkPage=1),1==ShortPixel.bulkProcessor||void 0===localStorage.bulkTime||Math.floor(Date.now()/1e3)-localStorage.bulkTime>90?(ShortPixel.bulkProcessor=!0,localStorage.bulkPage=window.location.href.search("wp-short-pixel-bulk")>=0?1:0,localStorage.bulkTime=Math.floor(Date.now()/1e3),console.log(localStorage.bulkTime),checkBulkProcessingCallApi()):setTimeout(checkBulkProgress,5e3))}function checkBulkProcessingCallApi(){jQuery.ajax({type:"POST",url:ShortPixel.AJAX_URL,data:{action:"shortpixel_image_processing"},success:function(e){if(e.length>0){r=null;try{var r=JSON.parse(e)}catch(e){return void ShortPixel.retry(e.message)}ShortPixel.retries=0;var t=r.ImageID,s=jQuery("div.short-pixel-bulk-page").length>0;switch(r.Status&&r.Status!=ShortPixel.STATUS_SEARCHING&&(ShortPixel.returnedStatusSearching>=2&&jQuery(".bulk-notice-msg.bulk-searching").hide(),ShortPixel.returnedStatusSearching=0),r.Status){case ShortPixel.STATUS_NO_KEY:setCellMessage(t,r.Message,"<a class='button button-smaller button-primary' href=\"https://shortpixel.com/wp-apikey"+ShortPixel.AFFILIATE+'" target="_blank">'+_spTr.getApiKey+"</a>"),showToolBarAlert(ShortPixel.STATUS_NO_KEY);break;case ShortPixel.STATUS_QUOTA_EXCEEDED:setCellMessage(t,r.Message,"<a class='button button-smaller button-primary' href=\"https://shortpixel.com/login/"+ShortPixel.API_KEY+'" target="_blank">'+_spTr.extendQuota+"</a><a class='button button-smaller' href='admin.php?action=shortpixel_check_quota'>"+_spTr.check__Quota+"</a>"),showToolBarAlert(ShortPixel.STATUS_QUOTA_EXCEEDED),0==r.Stop&&setTimeout(checkBulkProgress,5e3),ShortPixel.otherMediaUpdateActions(t,["quota","view"]);break;case ShortPixel.STATUS_FAIL:setCellMessage(t,r.Message,"<a class='button button-smaller button-primary' href=\"javascript:manualOptimization('"+t+"', false)\">"+_spTr.retry+"</a>"),showToolBarAlert(ShortPixel.STATUS_FAIL,r.Message,t),s&&(ShortPixel.bulkShowError(t,r.Message,r.Filename,r.CustomImageLink),r.BulkPercent&&progressUpdate(r.BulkPercent,r.BulkMsg),ShortPixel.otherMediaUpdateActions(t,["retry","view"])),console.log(r.Message),setTimeout(checkBulkProgress,5e3);break;case ShortPixel.STATUS_EMPTY_QUEUE:console.log(r.Message),clearBulkProcessor(),hideToolBarAlert();var o=jQuery("#bulk-progress");s&&o.length&&"2"!=r.BulkStatus&&(progressUpdate(100,"Bulk finished!"),jQuery("a.bulk-cancel").attr("disabled","disabled"),hideSlider(),setTimeout(function(){window.location.reload()},3e3));break;case ShortPixel.STATUS_SUCCESS:s&&(ShortPixel.bulkHideLengthyMsg(),ShortPixel.bulkHideMaintenanceMsg());var i=r.PercentImprovement;showToolBarAlert(ShortPixel.STATUS_SUCCESS,"");var a=ShortPixel.isCustomImageId(t)?"":ShortPixel.successActions(t,r.Type,r.ThumbsCount,r.ThumbsTotal,r.BackupEnabled,r.Filename);setCellMessage(t,ShortPixel.successMsg(t,i,r.Type,r.ThumbsCount,r.RetinasCount),a),jQuery("#post-"+t).length>0&&jQuery("#post-"+t).find(".filename").text(r.Filename),jQuery(".misc-pub-filename strong").length>0&&jQuery(".misc-pub-filename strong").text(r.Filename),ShortPixel.isCustomImageId(t)&&r.TsOptimized&&r.TsOptimized.length>0&&(console.log(t),jQuery(".date-"+t).text(r.TsOptimized));var l=jQuery(["restore","view","redolossy","redoglossy","redolossless"]).not(["redo"+r.Type]).get();ShortPixel.otherMediaUpdateActions(t,l);new PercentageAnimator("#sp-msg-"+t+" span.percent",i).animate(i),s&&void 0!==r.Thumb&&(r.BulkPercent&&progressUpdate(r.BulkPercent,r.BulkMsg),r.Thumb.length>0&&(sliderUpdate(t,r.Thumb,r.BkThumb,r.PercentImprovement,r.Filename),void 0!==r.AverageCompression&&0+r.AverageCompression>0&&(jQuery("#sp-avg-optimization").html('<input type="text" class="dial" value="'+Math.round(r.AverageCompression)+'"/>'),ShortPixel.percentDial("#sp-avg-optimization .dial",60)))),console.log("Server response: "+e),s&&void 0!==r.BulkPercent&&progressUpdate(r.BulkPercent,r.BulkMsg),setTimeout(checkBulkProgress,5e3);break;case ShortPixel.STATUS_SKIP:1!==r.Silent&&ShortPixel.bulkShowError(t,r.Message,r.Filename,r.CustomImageLink);case ShortPixel.STATUS_ERROR:void 0!==r.Message&&(showToolBarAlert(ShortPixel.STATUS_SKIP,r.Message+" Image ID: "+t),setCellMessage(t,r.Message,"")),ShortPixel.otherMediaUpdateActions(t,["retry","view"]);case ShortPixel.STATUS_RETRY:console.log("Server response: "+e),showToolBarAlert(ShortPixel.STATUS_RETRY,""),s&&void 0!==r.BulkPercent&&progressUpdate(r.BulkPercent,r.BulkMsg),s&&r.Count>3&&ShortPixel.bulkShowLengthyMsg(t,r.Filename,r.CustomImageLink),setTimeout(checkBulkProgress,5e3);break;case ShortPixel.STATUS_SEARCHING:console.log("Server response: "+e),ShortPixel.returnedStatusSearching++,ShortPixel.returnedStatusSearching>=2&&jQuery(".bulk-notice-msg.bulk-searching").show(),setTimeout(checkBulkProgress,2500);break;case ShortPixel.STATUS_MAINTENANCE:ShortPixel.bulkShowMaintenanceMsg("maintenance"),setTimeout(checkBulkProgress,6e4);break;case ShortPixel.STATUS_QUEUE_FULL:ShortPixel.bulkShowMaintenanceMsg("queue-full"),setTimeout(checkBulkProgress,6e4);break;default:ShortPixel.retry("Unknown status "+r.Status+". Retrying...")}}},error:function(e){ShortPixel.retry(e.statusText)}})}function clearBulkProcessor(){ShortPixel.bulkProcessor=!1,localStorage.bulkTime=0,window.location.href.search("wp-short-pixel-bulk")>=0&&(localStorage.bulkPage=0)}function setCellMessage(e,r,t){var s=jQuery("#sp-msg-"+e);s.length>0&&(s.html("<div class='sp-column-actions'>"+t+"</div><div class='sp-column-info'>"+r+"</div>"),s.css("color","")),(s=jQuery("#sp-cust-msg-"+e)).length>0&&s.html("<div class='sp-column-info'>"+r+"</div>")}function manualOptimization(e,r){setCellMessage(e,"<img src='"+ShortPixel.WP_PLUGIN_URL+"/res/img/loading.gif' class='sp-loading-small'>Image waiting to be processed",""),jQuery("li.shortpixel-toolbar-processing").removeClass("shortpixel-hide"),jQuery("li.shortpixel-toolbar-processing").removeClass("shortpixel-alert"),jQuery("li.shortpixel-toolbar-processing").addClass("shortpixel-processing");var t={action:"shortpixel_manual_optimization",image_id:e,cleanup:r};jQuery.ajax({type:"GET",url:ShortPixel.AJAX_URL,data:t,success:function(r){var t=JSON.parse(r);t.Status==ShortPixel.STATUS_SUCCESS?setTimeout(checkBulkProgress,2e3):setCellMessage(e,void 0!==t.Message?t.Message:_spTr.thisContentNotProcessable,"")},error:function(r){t.action="shortpixel_check_status",jQuery.ajax({type:"GET",url:ShortPixel.AJAX_URL,data:t,success:function(r){var t=JSON.parse(r);t.Status!==ShortPixel.STATUS_SUCCESS&&setCellMessage(e,void 0!==t.Message?t.Message:_spTr.thisContentNotProcessable,"")}})}})}function reoptimize(e,r){setCellMessage(e,"<img src='"+ShortPixel.WP_PLUGIN_URL+"/res/img/loading.gif' class='sp-loading-small'>Image waiting to be reprocessed",""),jQuery("li.shortpixel-toolbar-processing").removeClass("shortpixel-hide"),jQuery("li.shortpixel-toolbar-processing").addClass("shortpixel-processing");var t={action:"shortpixel_redo",attachment_ID:e,type:r};jQuery.get(ShortPixel.AJAX_URL,t,function(r){(t=JSON.parse(r)).Status==ShortPixel.STATUS_SUCCESS?setTimeout(checkBulkProgress,2e3):($msg=void 0!==t.Message?t.Message:_spTr.thisContentNotProcessable,setCellMessage(e,$msg,""),showToolBarAlert(ShortPixel.STATUS_FAIL,$msg))})}function optimizeThumbs(e){setCellMessage(e,"<img src='"+ShortPixel.WP_PLUGIN_URL+"/res/img/loading.gif' class='sp-loading-small'>"+_spTr.imageWaitOptThumbs,""),jQuery("li.shortpixel-toolbar-processing").removeClass("shortpixel-hide"),jQuery("li.shortpixel-toolbar-processing").addClass("shortpixel-processing");var r={action:"shortpixel_optimize_thumbs",attachment_ID:e};jQuery.get(ShortPixel.AJAX_URL,r,function(t){(r=JSON.parse(t)).Status==ShortPixel.STATUS_SUCCESS?setTimeout(checkBulkProgress,2e3):setCellMessage(e,void 0!==r.Message?r.Message:_spTr.thisContentNotProcessable,"")})}function dismissShortPixelNoticeExceed(e){jQuery("#wp-admin-bar-shortpixel_processing").hide();var r={action:"shortpixel_dismiss_notice",notice_id:"exceed"};jQuery.get(ShortPixel.AJAX_URL,r,function(e){(r=JSON.parse(e)).Status==ShortPixel.STATUS_SUCCESS&&console.log("dismissed")}),e.preventDefault()}function dismissShortPixelNotice(e){jQuery("#short-pixel-notice-"+e).hide();var r={action:"shortpixel_dismiss_notice",notice_id:e};jQuery.get(ShortPixel.AJAX_URL,r,function(e){(r=JSON.parse(e)).Status==ShortPixel.STATUS_SUCCESS&&console.log("dismissed")})}function PercentageAnimator(e,r){this.animationSpeed=10,this.increment=2,this.curPercentage=0,this.targetPercentage=r,this.outputSelector=e,this.animate=function(e){this.targetPercentage=e,setTimeout(PercentageTimer.bind(null,this),this.animationSpeed)}}function PercentageTimer(e){e.curPercentage-e.targetPercentage<-e.increment?e.curPercentage+=e.increment:e.curPercentage-e.targetPercentage>e.increment?e.curPercentage-=e.increment:e.curPercentage=e.targetPercentage,jQuery(e.outputSelector).text(e.curPercentage+"%"),e.curPercentage!=e.targetPercentage&&setTimeout(PercentageTimer.bind(null,e),e.animationSpeed)}function progressUpdate(e,r){var t=jQuery("#bulk-progress");t.length&&(jQuery(".progress-left",t).css("width",e+"%"),jQuery(".progress-img",t).css("left",e+"%"),e>24?(jQuery(".progress-img span",t).html(""),jQuery(".progress-left",t).html(e+"%")):(jQuery(".progress-img span",t).html(e+"%"),jQuery(".progress-left",t).html("")),jQuery(".bulk-estimate").html(r))}function sliderUpdate(e,r,t,s,o){var i=jQuery(".bulk-slider div.bulk-slide:first-child");if(0!==i.length){"empty-slide"!=i.attr("id")&&i.hide(),i.css("z-index",1e3),jQuery(".bulk-img-opt",i).attr("src",""),void 0===t&&(t=""),t.length>0&&jQuery(".bulk-img-orig",i).attr("src","");var a=i.clone();a.attr("id","slide-"+e),jQuery(".bulk-img-opt",a).attr("src",r),t.length>0?(jQuery(".img-original",a).css("display","inline-block"),jQuery(".bulk-img-orig",a).attr("src",t)):jQuery(".img-original",a).css("display","none"),jQuery(".bulk-opt-percent",a).html('<input type="text" class="dial" value="'+s+'"/>'),jQuery(".bulk-slider").append(a),ShortPixel.percentDial("#"+a.attr("id")+" .dial",100),jQuery(".bulk-slider-container span.filename").html(" "+o),"empty-slide"==i.attr("id")?(i.remove(),jQuery(".bulk-slider-container").css("display","block")):i.animate({left:i.width()+i.position().left},"slow","swing",function(){i.remove(),a.fadeIn("slow")})}}function hideSlider(){jQuery(".bulk-slider-container").css("display","none")}function showStats(){jQuery(".bulk-stats").length}function SPstringFormat(){var e=Array.prototype.slice.call(arguments);if(0!==e.length){var r=e.shift();for(i=0;i<e.length;i++)r=r.replace(new RegExp("\\{"+i+"\\}","gm"),e[i]);return r}}jQuery(document).ready(function(){ShortPixel.init()});var ShortPixel=function(){function e(e){jQuery(e).is(":checked")?jQuery("#width,#height").removeAttr("disabled"):jQuery("#width,#height").attr("disabled","disabled")}function r(){jQuery("#shortpixel-hs-button-blind").remove(),jQuery("#shortpixel-hs-tools").remove(),jQuery("#hs-beacon").remove(),jQuery("#botbutton").remove(),jQuery("#shortpixel-hs-blind").remove()}return jQuery("#key").keypress(function(e){13==e.which&&jQuery("#valid").val("validate")}),{init:function(){void 0===ShortPixel.API_KEY&&(jQuery("table.wp-list-table.media").length>0&&jQuery('select[name^="action"] option:last-child').before('<option value="short-pixel-bulk">'+_spTr.optimizeWithSP+'</option><option value="short-pixel-bulk-lossy"> → '+_spTr.redoLossy+'</option><option value="short-pixel-bulk-glossy"> → '+_spTr.redoGlossy+'</option><option value="short-pixel-bulk-lossless"> → '+_spTr.redoLossless+'</option><option value="short-pixel-bulk-restore"> → '+_spTr.restoreOriginal+"</option>"),ShortPixel.setOptions(ShortPixelConstants[0]),jQuery("#backup-folder-size").length&&jQuery("#backup-folder-size").html(ShortPixel.getBackupSize()),"todo"==ShortPixel.MEDIA_ALERT&&jQuery("div.media-frame.mode-grid").length>0&&jQuery("div.media-frame.mode-grid").before('<div id="short-pixel-media-alert" class="notice notice-warning"><p>'+SPstringFormat(_spTr.changeMLToListMode,'<a href="upload.php?mode=list" class="view-list"><span class="screen-reader-text">'," </span>",'</a><a class="alignright" href="javascript:ShortPixel.dismissMediaAlert();">',"</a>")+"</p></div>"),jQuery(window).on("beforeunload",function(){1==ShortPixel.bulkProcessor&&clearBulkProcessor()}),checkQuotaExceededAlert(),checkBulkProgress())},setOptions:function(e){for(var r in e)ShortPixel[r]=e[r]},isEmailValid:function(e){return/^\w+([\.+-]?\w+)*@\w+([\.-]?\w+)*(\.\w{1,63})+$/.test(e)},updateSignupEmail:function(){var e=jQuery("#pluginemail").val();ShortPixel.isEmailValid(e)&&jQuery("#request_key").removeClass("disabled"),jQuery("#request_key").attr("href",jQuery("#request_key").attr("href").split("?")[0]+"?pluginemail="+e)},enableResize:e,setupGeneralTab:function(){var r=0;void 0!==document.wp_shortpixel_options&&(r=document.wp_shortpixel_options.compressionType);for(var t=0,s=null;t<r.length;t++)r[t].onclick=function(){this!==s&&(s=this),void 0===ShortPixel.setupGeneralTabAlert&&(alert(_spTr.alertOnlyAppliesToNewImages),ShortPixel.setupGeneralTabAlert=1)};ShortPixel.enableResize("#resize"),jQuery("#resize").change(function(){e(this)}),jQuery(".resize-sizes").blur(function(e){var r=jQuery(e.target);if(ShortPixel.resizeSizesAlert!=r.val()){ShortPixel.resizeSizesAlert=r.val();var t=jQuery("#min-"+r.attr("name")).val(),s=jQuery("#min-"+r.attr("name")).data("nicename");r.val()<Math.min(t,1024)?(t>1024?alert(SPstringFormat(_spTr.pleaseDoNotSetLesser1024,s)):alert(SPstringFormat(_spTr.pleaseDoNotSetLesserSize,s,s,t)),e.preventDefault(),r.focus()):this.defaultValue=r.val()}}),jQuery(".shortpixel-confirm").click(function(e){return!!confirm(e.target.getAttribute("data-confirm"))||(e.preventDefault(),!1)}),jQuery('input[name="removeExif"], input[name="png2jpg"]').on("change",function(){ShortPixel.checkExifWarning()}),ShortPixel.checkExifWarning()},apiKeyChanged:function(){jQuery(".wp-shortpixel-options .shortpixel-key-valid").css("display","none"),jQuery(".wp-shortpixel-options button#validate").css("display","inline-block")},setupAdvancedTab:function(){jQuery("input.remove-folder-button").click(function(){var e=jQuery(this).data("value");1==confirm(SPstringFormat(_spTr.areYouSureStopOptimizing,e))&&(jQuery("#removeFolder").val(e),jQuery("#wp_shortpixel_options").submit())}),jQuery("input.recheck-folder-button").click(function(){var e=jQuery(this).data("value");1==confirm(SPstringFormat(_spTr.areYouSureStopOptimizing,e))&&(jQuery("#recheckFolder").val(e),jQuery("#wp_shortpixel_options").submit())})},checkThumbsUpdTotal:function(e){var r=jQuery("#"+(e.checked?"total":"main")+"ToProcess").val();jQuery("div.bulk-play span.total").text(r),jQuery("#displayTotal").text(r)},initSettings:function(){ShortPixel.adjustSettingsTabs(),ShortPixel.setupGeneralTab(),jQuery(window).resize(function(){ShortPixel.adjustSettingsTabs()}),jQuery("article.sp-tabs a.tab-link").click(function(e){var r=jQuery(e.target).data("id");ShortPixel.switchSettingsTab(r)}),jQuery("input[type=radio][name=deliverWebpType]").change(function(){"deliverWebpAltered"==this.value?window.confirm(_spTr.alertDeliverWebPAltered)?0==jQuery("input[type=radio][name=deliverWebpAlteringType]:checked").length&&jQuery("#deliverWebpAlteredWP").prop("checked",!0):jQuery(this).prop("checked",!1):"deliverWebpUnaltered"==this.value&&window.alert(_spTr.alertDeliverWebPUnaltered)})},switchSettingsTab:function(e){var r=e.replace("tab-",""),t="",s=jQuery("section#"+e);jQuery('input[name="display_part"]').val(r);var o=window.location.href.toString();if(o.indexOf("?")>0){var i=o.substring(0,o.indexOf("?"));i+="?"+jQuery.param({page:"wp-shortpixel-settings",part:r}),window.history.replaceState({},document.title,i)}if(s.length>0&&(jQuery("section").removeClass("sel-tab"),jQuery("section .wp-shortpixel-tab-content").fadeOut(50),jQuery(s).addClass("sel-tab"),ShortPixel.adjustSettingsTabs(),jQuery(s).find(".wp-shortpixel-tab-content").fadeIn(50)),void 0!==HS.beacon.suggest){switch(r){case"settings":t=shortpixel_suggestions_settings;break;case"adv-settings":t=shortpixel_suggestions_adv_settings;break;case"cloudflare":case"stats":t=shortpixel_suggestions_cloudflare}HS.beacon.suggest(t)}},adjustSettingsTabs:function(){var e=jQuery("section.sel-tab").height()+90;jQuery(".section-wrapper").css("height",e)},onBulkThumbsCheck:function(e){e.checked?(jQuery("#with-thumbs").css("display","inherit"),jQuery("#without-thumbs").css("display","none")):(jQuery("#without-thumbs").css("display","inherit"),jQuery("#with-thumbs").css("display","none"))},dismissMediaAlert:function(){var e={action:"shortpixel_dismiss_media_alert"};jQuery.get(ShortPixel.AJAX_URL,e,function(r){"success"==(e=JSON.parse(r)).Status&&jQuery("#short-pixel-media-alert").hide()})},closeHelpPane:r,dismissHelpPane:function(){r(),dismissShortPixelNotice("help")},checkQuota:function(){jQuery.get(ShortPixel.AJAX_URL,{action:"shortpixel_check_quota"},function(){console.log("quota refreshed")})},percentDial:function(e,r){jQuery(e).knob({readOnly:!0,width:r,height:r,fgColor:"#1CAECB",format:function(e){return e+"%"}})},successMsg:function(e,r,t,s,o){return(r>0?"<div class='sp-column-info'>"+_spTr.reducedBy+" <strong><span class='percent'>"+r+"%</span></strong> ":"")+(r>0&&r<5?"<br>":"")+(r<5?_spTr.bonusProcessing:"")+(t.length>0?" ("+t+")":"")+(0+s>0?"<br>"+SPstringFormat(_spTr.plusXthumbsOpt,s):"")+(0+o>0?"<br>"+SPstringFormat(_spTr.plusXretinasOpt,o):"")+"</div>"},successActions:function(e,r,t,s,o,i){if(1==o){var a=jQuery(".sp-column-actions-template").clone();if(!a.length)return!1;var l;return l=0==r.length?["lossy","lossless"]:["lossy","glossy","lossless"].filter(function(e){return!(e==r)}),a.html(a.html().replace(/__SP_ID__/g,e)),"pdf"==i.substr(i.lastIndexOf(".")+1).toLowerCase()&&jQuery(".sp-action-compare",a).remove(),0==t&&s>0?a.html(a.html().replace("__SP_THUMBS_TOTAL__",s)):(jQuery(".sp-action-optimize-thumbs",a).remove(),jQuery(".sp-dropbtn",a).removeClass("button-primary")),a.html(a.html().replace(/__SP_FIRST_TYPE__/g,l[0])),a.html(a.html().replace(/__SP_SECOND_TYPE__/g,l[1])),a.html()}return""},otherMediaUpdateActions:function(e,r){if(e=e.substring(2),jQuery(".shortpixel-other-media").length){for(var t=["optimize","retry","restore","redo","quota","view"],s=0,o=t.length;s<o;s++)jQuery("#"+t[s]+"_"+e).css("display","none");for(var s=0,o=r.length;s<o;s++)jQuery("#"+r[s]+"_"+e).css("display","")}},retry:function(e){ShortPixel.retries++,isNaN(ShortPixel.retries)&&(ShortPixel.retries=1),ShortPixel.retries<6?(console.log("Invalid response from server (Error: "+e+"). Retrying pass "+(ShortPixel.retries+1)+"..."),setTimeout(checkBulkProgress,5e3)):(ShortPixel.bulkShowError(-1,"Invalid response from server received 6 times. Please retry later by reloading this page, or <a href='https://shortpixel.com/contact' target='_blank'>contact support</a>. (Error: "+e+")",""),console.log("Invalid response from server 6 times. Giving up."))},initFolderSelector:function(){jQuery(".select-folder-button").click(function(){jQuery(".sp-folder-picker-shade").fadeIn(100),jQuery(".shortpixel-modal.modal-folder-picker").show();var e=jQuery(".sp-folder-picker");e.parent().css("margin-left",-e.width()/2),e.fileTree({script:ShortPixel.browseContent,multiFolder:!1})}),jQuery(".shortpixel-modal input.select-folder-cancel, .sp-folder-picker-shade").click(function(){jQuery(".sp-folder-picker-shade").fadeOut(100),jQuery(".shortpixel-modal.modal-folder-picker").hide()}),jQuery(".shortpixel-modal input.select-folder").click(function(e){if(r=jQuery("UL.jqueryFileTree LI.directory.selected"),0==jQuery(r).length)var r=jQuery("UL.jqueryFileTree LI.selected").parents(".directory");var t=jQuery(r).children("a").attr("rel");if(void 0!==t)if(t=t.trim()){var s=jQuery("#customFolderBase").val()+t;"/"==s.slice(-1)&&(s=s.slice(0,-1)),jQuery("#addCustomFolder").val(s),jQuery("#addCustomFolderView").val(s),jQuery(".sp-folder-picker-shade").fadeOut(100),jQuery(".shortpixel-modal.modal-folder-picker").css("display","none"),jQuery("#saveAdvAddFolder").removeClass("hidden")}else alert("Please select a folder from the list.")})},browseContent:function(e){e.action="shortpixel_browse_content";var r="";return jQuery.ajax({type:"POST",url:ShortPixel.AJAX_URL,data:e,success:function(e){r=e},async:!1}),r},getBackupSize:function(){var e="";return jQuery.ajax({type:"POST",url:ShortPixel.AJAX_URL,data:{action:"shortpixel_get_backup_size"},success:function(r){e=r},async:!1}),e},newApiKey:function(e){if(!jQuery("#tos").is(":checked"))return e.preventDefault(),jQuery("#tos-robo").fadeIn(400,function(){jQuery("#tos-hand").fadeIn()}),void jQuery("#tos").click(function(){jQuery("#tos-robo").css("display","none"),jQuery("#tos-hand").css("display","none")});if(jQuery("#request_key").addClass("disabled"),jQuery("#pluginemail_spinner").addClass("is-active"),ShortPixel.updateSignupEmail(),ShortPixel.isEmailValid(jQuery("#pluginemail").val())){jQuery("#pluginemail-error").css("display","none");var r={action:"shortpixel_new_api_key",email:jQuery("#pluginemail").val()};jQuery.ajax({type:"POST",async:!1,url:ShortPixel.AJAX_URL,data:r,success:function(r){data=JSON.parse(r),"success"==data.Status?(e.preventDefault(),window.location.reload()):"invalid"==data.Status&&(jQuery("#pluginemail-error").html("<b>"+data.Details+"</b>"),jQuery("#pluginemail-error").css("display",""),jQuery("#pluginemail-info").css("display","none"),e.preventDefault())}}),jQuery("#request_key").removeAttr("onclick")}else jQuery("#pluginemail-error").css("display",""),jQuery("#pluginemail-info").css("display","none"),e.preventDefault();jQuery("#request_key").removeClass("disabled"),jQuery("#pluginemail_spinner").removeClass("is-active")},proposeUpgrade:function(){jQuery("#shortPixelProposeUpgrade .sp-modal-body").addClass("sptw-modal-spinner"),jQuery("#shortPixelProposeUpgrade .sp-modal-body").html(""),jQuery("#shortPixelProposeUpgradeShade").css("display","block"),jQuery("#shortPixelProposeUpgrade").removeClass("shortpixel-hide"),jQuery.ajax({type:"POST",url:ShortPixel.AJAX_URL,data:{action:"shortpixel_propose_upgrade"},success:function(e){jQuery("#shortPixelProposeUpgrade .sp-modal-body").removeClass("sptw-modal-spinner"),jQuery("#shortPixelProposeUpgrade .sp-modal-body").html(e)}})},closeProposeUpgrade:function(){jQuery("#shortPixelProposeUpgradeShade").css("display","none"),jQuery("#shortPixelProposeUpgrade").addClass("shortpixel-hide"),ShortPixel.toRefresh&&ShortPixel.recheckQuota()},includeUnlisted:function(){jQuery("#short-pixel-notice-unlisted").hide(),jQuery("#optimizeUnlisted").prop("checked",!0);var e={action:"shortpixel_dismiss_notice",notice_id:"unlisted",notice_data:"true"};jQuery.get(ShortPixel.AJAX_URL,e,function(r){(e=JSON.parse(r)).Status==ShortPixel.STATUS_SUCCESS&&console.log("dismissed")})},bulkShowLengthyMsg:function(e,r,t){var s=jQuery(".bulk-notice-msg.bulk-lengthy");if(0!=s.length){var o=jQuery("a",s);o.text(r),t?o.attr("href",t):o.attr("href",o.data("href").replace("__ID__",e)),s.css("display","block")}},bulkHideLengthyMsg:function(){jQuery(".bulk-notice-msg.bulk-lengthy").css("display","none")},bulkShowMaintenanceMsg:function(e){var r=jQuery(".bulk-notice-msg.bulk-"+e);0!=r.length&&r.css("display","block")},bulkHideMaintenanceMsg:function(e){jQuery(".bulk-notice-msg.bulk-"+e).css("display","none")},bulkShowError:function(e,r,t,s){var o=jQuery("#bulk-error-template");if(0!=o.length){var i=o.clone();i.attr("id","bulk-error-"+e),-1==e?(jQuery("span.sp-err-title",i).remove(),i.addClass("bulk-error-fatal")):(jQuery("img",i).remove(),jQuery("#bulk-error-".id).remove()),jQuery("span.sp-err-content",i).html(r);var a=jQuery("a.sp-post-link",i);s?a.attr("href",s):a.attr("href",a.attr("href").replace("__ID__",e)),a.text(t),o.after(i),i.css("display","block")}},confirmBulkAction:function(e,r){return!!confirm(_spTr["confirmBulk"+e])||(r.stopPropagation(),r.preventDefault(),!1)},checkRandomAnswer:function(e){var r=jQuery(e.target).val(),t=jQuery('input[name="random_answer"]').val(),s=jQuery('input[name="random_answer"]').data("target");r==t?(jQuery(s).removeClass("disabled").prop("disabled",!1),jQuery(s).removeAttr("aria-disabled")):jQuery(s).addClass("disabled").prop("disabled",!0)},removeBulkMsg:function(e){jQuery(e).parent().parent().remove()},isCustomImageId:function(e){return"C-"==e.substring(0,2)},recheckQuota:function(){var e=window.location.href.split("#");window.location.href=e[0]+(e[0].indexOf("?")>0?"&":"?")+"checkquota=1"+(void 0===e[1]?"":"#"+e[1])},openImageMenu:function(e){e.preventDefault(),this.menuCloseEvent||(jQuery(window).click(function(e){e.target.matches(".sp-dropbtn")||jQuery(".sp-dropdown.sp-show").removeClass("sp-show")}),this.menuCloseEvent=!0);var r=e.target.parentElement.classList.contains("sp-show");jQuery(".sp-dropdown.sp-show").removeClass("sp-show"),r||e.target.parentElement.classList.add("sp-show")},menuCloseEvent:!1,loadComparer:function(e){this.comparerData.origUrl=!1,!1===this.comparerData.cssLoaded&&(jQuery("<link>").appendTo("head").attr({type:"text/css",rel:"stylesheet",href:this.WP_PLUGIN_URL+"/res/css/twentytwenty.min.css"}),this.comparerData.cssLoaded=2),!1===this.comparerData.jsLoaded&&(jQuery.getScript(this.WP_PLUGIN_URL+"/res/js/jquery.twentytwenty.min.js",function(){ShortPixel.comparerData.jsLoaded=2,ShortPixel.comparerData.origUrl.length>0&&ShortPixel.displayComparerPopup(ShortPixel.comparerData.width,ShortPixel.comparerData.height,ShortPixel.comparerData.origUrl,ShortPixel.comparerData.optUrl)}),this.comparerData.jsLoaded=1),!1===this.comparerData.origUrl&&(jQuery.ajax({type:"POST",url:ShortPixel.AJAX_URL,data:{action:"shortpixel_get_comparer_data",id:e},success:function(e){data=JSON.parse(e),jQuery.extend(ShortPixel.comparerData,data),2==ShortPixel.comparerData.jsLoaded&&ShortPixel.displayComparerPopup(ShortPixel.comparerData.width,ShortPixel.comparerData.height,ShortPixel.comparerData.origUrl,ShortPixel.comparerData.optUrl)}}),this.comparerData.origUrl="")},displayComparerPopup:function(e,r,t,s){var o=e,i=r<150||e<350,a=jQuery(i?"#spUploadCompareSideBySide":"#spUploadCompare"),l=jQuery(".sp-modal-shade");i||jQuery("#spCompareSlider").html('<img class="spUploadCompareOriginal"/><img class="spUploadCompareOptimized"/>'),e=Math.max(350,Math.min(800,e<350?2*(e+25):r<150?e+25:e)),r=Math.max(150,i?o>350?2*(r+45):r+45:r*e/o);var n="-"+Math.round(e/2);jQuery(".sp-modal-body",a).css("width",e),jQuery(".shortpixel-slider",a).css("width",e),a.css("width",e),a.css("marginLeft",n+"px"),jQuery(".sp-modal-body",a).css("height",r),a.show(),l.show(),i||jQuery("#spCompareSlider").twentytwenty({slider_move:"mousemove"}),jQuery(".sp-close-button").on("click",ShortPixel.closeComparerPopup),jQuery(document).on("keyup.sp_modal_active",ShortPixel.closeComparerPopup),jQuery(".sp-modal-shade").on("click",ShortPixel.closeComparerPopup);var u=jQuery(".spUploadCompareOptimized",a);jQuery(".spUploadCompareOriginal",a).attr("src",t),setTimeout(function(){jQuery(window).trigger("resize")},1e3),u.load(function(){jQuery(window).trigger("resize")}),u.attr("src",s)},closeComparerPopup:function(e){jQuery("#spUploadCompareSideBySide").hide(),jQuery("#spUploadCompare").hide(),jQuery(".sp-modal-shade").hide(),jQuery(document).unbind("keyup.sp_modal_active"),jQuery(".sp-modal-shade").off("click"),jQuery(".sp-close-button").off("click")},convertPunycode:function(e){var r=document.createElement("a");return r.href=e,e.indexOf(r.protocol+"//"+r.hostname)<0?r.href:e.replace(r.protocol+"//"+r.hostname,r.protocol+"//"+r.hostname.split(".").map(function(e){return sp_punycode.toASCII(e)}).join("."))},checkExifWarning:function(){!jQuery('input[name="removeExif"]').is(":checked")&&jQuery('input[name="png2jpg"]').is(":checked")?jQuery(".exif_warning").fadeIn():jQuery(".exif_warning").fadeOut()},comparerData:{cssLoaded:!1,jsLoaded:!1,origUrl:!1,optUrl:!1,width:0,height:0},toRefresh:!1,resizeSizesAlert:!1,returnedStatusSearching:0}}();
|
1 |
+
jQuery(document).ready(function(){ShortPixel.init()});var ShortPixel=function(){function N(){if(typeof ShortPixel.API_KEY!=="undefined"){return}if(jQuery("table.wp-list-table.media").length>0){jQuery('select[name^="action"] option:last-child').before('<option value="short-pixel-bulk">'+_spTr.optimizeWithSP+'</option><option value="short-pixel-bulk-lossy"> → '+_spTr.redoLossy+'</option><option value="short-pixel-bulk-glossy"> → '+_spTr.redoGlossy+'</option><option value="short-pixel-bulk-lossless"> → '+_spTr.redoLossless+'</option><option value="short-pixel-bulk-restore"> → '+_spTr.restoreOriginal+"</option>")}ShortPixel.setOptions(ShortPixelConstants[0]);if(jQuery("#backup-folder-size").length){jQuery("#backup-folder-size").html(ShortPixel.getBackupSize())}if(ShortPixel.MEDIA_ALERT=="todo"&&jQuery("div.media-frame.mode-grid").length>0){jQuery("div.media-frame.mode-grid").before('<div id="short-pixel-media-alert" class="notice notice-warning"><p>'+SPstringFormat(_spTr.changeMLToListMode,'<a href="upload.php?mode=list" class="view-list"><span class="screen-reader-text">'," </span>",'</a><a class="alignright" href="javascript:ShortPixel.dismissMediaAlert();">',"</a>")+"</p></div>")}jQuery(window).on("beforeunload",function(){if(ShortPixel.bulkProcessor==true){clearBulkProcessor()}});checkQuotaExceededAlert();checkBulkProgress()}function o(V){for(var W in V){ShortPixel[W]=V[W]}}function x(V){return/^\w+([\.+-]?\w+)*@\w+([\.-]?\w+)*(\.\w{1,63})+$/.test(V)}function p(){var V=jQuery("#pluginemail").val();if(ShortPixel.isEmailValid(V)){jQuery("#request_key").removeClass("disabled")}jQuery("#request_key").attr("href",jQuery("#request_key").attr("href").split("?")[0]+"?pluginemail="+V)}function a(V){console.log("validate");jQuery("#valid").val("validate");jQuery(V).parents("form").submit()}jQuery("#key").keypress(function(V){if(V.which==13){jQuery("#valid").val("validate")}});function Q(V){if(jQuery(V).is(":checked")){jQuery("#width,#height").removeAttr("disabled")}else{jQuery("#width,#height").attr("disabled","disabled")}}function k(){if(!jQuery('input[name="removeExif"]').is(":checked")&&jQuery('input[name="png2jpg"]').is(":checked")){jQuery(".exif_warning").fadeIn()}else{jQuery(".exif_warning").fadeOut()}}function e(){var V=0;if(typeof document.wp_shortpixel_options!=="undefined"){V=document.wp_shortpixel_options.compressionType}for(var W=0,X=null;W<V.length;W++){V[W].onclick=function(){if(this!==X){X=this}if(typeof ShortPixel.setupGeneralTabAlert!=="undefined"){return}alert(_spTr.alertOnlyAppliesToNewImages);ShortPixel.setupGeneralTabAlert=1}}ShortPixel.enableResize("#resize");jQuery("#resize").change(function(){Q(this)});jQuery(".resize-sizes").blur(function(aa){var ab=jQuery(aa.target);if(ShortPixel.resizeSizesAlert==ab.val()){return}ShortPixel.resizeSizesAlert=ab.val();var Z=jQuery("#min-"+ab.attr("name")).val();var Y=jQuery("#min-"+ab.attr("name")).data("nicename");if(ab.val()<Math.min(Z,1024)){if(Z>1024){alert(SPstringFormat(_spTr.pleaseDoNotSetLesser1024,Y))}else{alert(SPstringFormat(_spTr.pleaseDoNotSetLesserSize,Y,Y,Z))}aa.preventDefault();ab.focus()}else{this.defaultValue=ab.val()}});jQuery(".shortpixel-confirm").click(function(Z){var Y=confirm(Z.target.getAttribute("data-confirm"));if(!Y){Z.preventDefault();return false}return true});jQuery('input[name="removeExif"], input[name="png2jpg"]').on("change",function(){ShortPixel.checkExifWarning()});ShortPixel.checkExifWarning()}function H(){jQuery(".wp-shortpixel-options .shortpixel-key-valid").css("display","none");jQuery(".wp-shortpixel-options button#validate").css("display","inline-block")}function y(){jQuery("input.remove-folder-button").click(function(){var W=jQuery(this).data("value");var V=confirm(SPstringFormat(_spTr.areYouSureStopOptimizing,W));if(V==true){jQuery("#removeFolder").val(W);jQuery("#wp_shortpixel_options").submit()}});jQuery("input.recheck-folder-button").click(function(){var W=jQuery(this).data("value");var V=confirm(SPstringFormat(_spTr.areYouSureStopOptimizing,W));if(V==true){jQuery("#recheckFolder").val(W);jQuery("#wp_shortpixel_options").submit()}})}function P(V){var W=jQuery("#"+(V.checked?"total":"main")+"ToProcess").val();jQuery("div.bulk-play span.total").text(W);jQuery("#displayTotal").text(W)}function g(){ShortPixel.adjustSettingsTabs();ShortPixel.setupGeneralTab();jQuery(window).resize(function(){ShortPixel.adjustSettingsTabs()});jQuery("article.sp-tabs a.tab-link").click(function(W){var V=jQuery(W.target).data("id");ShortPixel.switchSettingsTab(V)});jQuery("input[type=radio][name=deliverWebpType]").change(function(){if(this.value=="deliverWebpAltered"){if(window.confirm(_spTr.alertDeliverWebPAltered)){var V=jQuery("input[type=radio][name=deliverWebpAlteringType]:checked").length;if(V==0){jQuery("#deliverWebpAlteredWP").prop("checked",true)}}else{jQuery(this).prop("checked",false)}}else{if(this.value=="deliverWebpUnaltered"){window.alert(_spTr.alertDeliverWebPUnaltered)}}})}function C(aa){var X=aa.replace("tab-",""),V="",Z=jQuery("section#"+aa);jQuery('input[name="display_part"]').val(X);var Y=window.location.href.toString();if(Y.indexOf("?")>0){var W=Y.substring(0,Y.indexOf("?"));W+="?"+jQuery.param({page:"wp-shortpixel-settings",part:X});window.history.replaceState({},document.title,W)}if(Z.length>0){jQuery("section").removeClass("sel-tab");jQuery("section .wp-shortpixel-tab-content").fadeOut(50);jQuery(Z).addClass("sel-tab");ShortPixel.adjustSettingsTabs();jQuery(Z).find(".wp-shortpixel-tab-content").fadeIn(50)}if(typeof HS!=="undefined"&&typeof HS.beacon.suggest!=="undefined"){switch(X){case"settings":V=shortpixel_suggestions_settings;break;case"adv-settings":V=shortpixel_suggestions_adv_settings;break;case"cloudflare":case"stats":V=shortpixel_suggestions_cloudflare;break;default:break}HS.beacon.suggest(V)}}function D(){var V=jQuery("section.sel-tab").height()+90;jQuery(".section-wrapper").css("height",V)}function R(){var V={action:"shortpixel_dismiss_media_alert"};jQuery.get(ShortPixel.AJAX_URL,V,function(W){V=JSON.parse(W);if(V.Status=="success"){jQuery("#short-pixel-media-alert").hide()}})}function w(){jQuery("#shortpixel-hs-button-blind").remove();jQuery("#shortpixel-hs-tools").remove();jQuery("#hs-beacon").remove();jQuery("#botbutton").remove();jQuery("#shortpixel-hs-blind").remove()}function q(){w();dismissShortPixelNotice("help")}function m(){var V={action:"shortpixel_check_quota"};jQuery.get(ShortPixel.AJAX_URL,V,function(){console.log("quota refreshed")})}function G(V){if(V.checked){jQuery("#with-thumbs").css("display","inherit");jQuery("#without-thumbs").css("display","none")}else{jQuery("#without-thumbs").css("display","inherit");jQuery("#with-thumbs").css("display","none")}}function b(Z,X,W,Y,V){return(X>0?"<div class='sp-column-info'>"+_spTr.reducedBy+" <strong><span class='percent'>"+X+"%</span></strong> ":"")+(X>0&&X<5?"<br>":"")+(X<5?_spTr.bonusProcessing:"")+(W.length>0?" ("+W+")":"")+(0+Y>0?"<br>"+SPstringFormat(_spTr.plusXthumbsOpt,Y):"")+(0+V>0?"<br>"+SPstringFormat(_spTr.plusXretinasOpt,V):"")+"</div>"}function s(W,V){jQuery(W).knob({readOnly:true,width:V,height:V,fgColor:"#1CAECB",format:function(X){return X+"%"}})}function c(ac,X,aa,Z,W,ab){if(W==1){var Y=jQuery(".sp-column-actions-template").clone();if(!Y.length){return false}var V;if(X.length==0){V=["lossy","lossless"]}else{V=["lossy","glossy","lossless"].filter(function(ad){return !(ad==X)})}Y.html(Y.html().replace(/__SP_ID__/g,ac));if(ab.substr(ab.lastIndexOf(".")+1).toLowerCase()=="pdf"){jQuery(".sp-action-compare",Y).remove()}if(aa==0&&Z>0){Y.html(Y.html().replace("__SP_THUMBS_TOTAL__",Z))}else{jQuery(".sp-action-optimize-thumbs",Y).remove();jQuery(".sp-dropbtn",Y).removeClass("button-primary")}Y.html(Y.html().replace(/__SP_FIRST_TYPE__/g,V[0]));Y.html(Y.html().replace(/__SP_SECOND_TYPE__/g,V[1]));return Y.html()}return""}function j(Z,Y){Z=Z.substring(2);if(jQuery(".shortpixel-other-media").length){var X=["optimize","retry","restore","redo","quota","view"];for(var W=0,V=X.length;W<V;W++){jQuery("#"+X[W]+"_"+Z).css("display","none")}for(var W=0,V=Y.length;W<V;W++){jQuery("#"+Y[W]+"_"+Z).css("display","")}}}function l(V){ShortPixel.retries++;if(isNaN(ShortPixel.retries)){ShortPixel.retries=1}if(ShortPixel.retries<6){console.log("Invalid response from server (Error: "+V+"). Retrying pass "+(ShortPixel.retries+1)+"...");setTimeout(checkBulkProgress,5000)}else{ShortPixel.bulkShowError(-1,"Invalid response from server received 6 times. Please retry later by reloading this page, or <a href='https://shortpixel.com/contact' target='_blank'>contact support</a>. (Error: "+V+")","");console.log("Invalid response from server 6 times. Giving up.")}}function n(V){V.action="shortpixel_browse_content";var W="";jQuery.ajax({type:"POST",url:ShortPixel.AJAX_URL,data:V,success:function(X){W=X},async:false});return W}function d(){var V={action:"shortpixel_get_backup_size"};var W="";jQuery.ajax({type:"POST",url:ShortPixel.AJAX_URL,data:V,success:function(X){W=X},async:false});return W}function f(W){if(!jQuery("#tos").is(":checked")){W.preventDefault();jQuery("#tos-robo").fadeIn(400,function(){jQuery("#tos-hand").fadeIn()});jQuery("#tos").click(function(){jQuery("#tos-robo").css("display","none");jQuery("#tos-hand").css("display","none")});return}jQuery("#request_key").addClass("disabled");jQuery("#pluginemail_spinner").addClass("is-active");ShortPixel.updateSignupEmail();if(ShortPixel.isEmailValid(jQuery("#pluginemail").val())){jQuery("#pluginemail-error").css("display","none");var V={action:"shortpixel_new_api_key",email:jQuery("#pluginemail").val()};jQuery.ajax({type:"POST",async:false,url:ShortPixel.AJAX_URL,data:V,success:function(X){data=JSON.parse(X);if(data.Status=="success"){W.preventDefault();window.location.reload()}else{if(data.Status=="invalid"){jQuery("#pluginemail-error").html("<b>"+data.Details+"</b>");jQuery("#pluginemail-error").css("display","");jQuery("#pluginemail-info").css("display","none");W.preventDefault()}else{}}}});jQuery("#request_key").removeAttr("onclick")}else{jQuery("#pluginemail-error").css("display","");jQuery("#pluginemail-info").css("display","none");W.preventDefault()}jQuery("#request_key").removeClass("disabled");jQuery("#pluginemail_spinner").removeClass("is-active")}function S(){jQuery("#shortPixelProposeUpgrade .sp-modal-body").addClass("sptw-modal-spinner");jQuery("#shortPixelProposeUpgrade .sp-modal-body").html("");jQuery("#shortPixelProposeUpgradeShade").css("display","block");jQuery("#shortPixelProposeUpgrade").removeClass("shortpixel-hide");var V={action:"shortpixel_propose_upgrade"};jQuery.ajax({type:"POST",url:ShortPixel.AJAX_URL,data:V,success:function(W){jQuery("#shortPixelProposeUpgrade .sp-modal-body").removeClass("sptw-modal-spinner");jQuery("#shortPixelProposeUpgrade .sp-modal-body").html(W)}})}function L(){jQuery("#shortPixelProposeUpgradeShade").css("display","none");jQuery("#shortPixelProposeUpgrade").addClass("shortpixel-hide");if(ShortPixel.toRefresh){ShortPixel.recheckQuota()}}function z(){jQuery("#short-pixel-notice-unlisted").hide();jQuery("#optimizeUnlisted").prop("checked",true);var V={action:"shortpixel_dismiss_notice",notice_id:"unlisted",notice_data:"true"};jQuery.get(ShortPixel.AJAX_URL,V,function(W){V=JSON.parse(W);if(V.Status==ShortPixel.STATUS_SUCCESS){console.log("dismissed")}})}function r(){jQuery(".select-folder-button").click(function(){jQuery(".sp-folder-picker-shade").fadeIn(100);jQuery(".shortpixel-modal.modal-folder-picker").show();var V=jQuery(".sp-folder-picker");V.parent().css("margin-left",-V.width()/2);V.fileTree({script:ShortPixel.browseContent,multiFolder:false})});jQuery(".shortpixel-modal input.select-folder-cancel, .sp-folder-picker-shade").click(function(){jQuery(".sp-folder-picker-shade").fadeOut(100);jQuery(".shortpixel-modal.modal-folder-picker").hide()});jQuery(".shortpixel-modal input.select-folder").click(function(Y){var X=jQuery("UL.jqueryFileTree LI.directory.selected");if(jQuery(X).length==0){var X=jQuery("UL.jqueryFileTree LI.selected").parents(".directory")}var V=jQuery(X).children("a").attr("rel");if(typeof V==="undefined"){return}V=V.trim();if(V){var W=jQuery("#customFolderBase").val()+V;if(W.slice(-1)=="/"){W=W.slice(0,-1)}jQuery("#addCustomFolder").val(W);jQuery("#addCustomFolderView").val(W);jQuery(".sp-folder-picker-shade").fadeOut(100);jQuery(".shortpixel-modal.modal-folder-picker").css("display","none");jQuery("#saveAdvAddFolder").removeClass("hidden")}else{alert("Please select a folder from the list.")}})}function K(Z,Y,X){var W=jQuery(".bulk-notice-msg.bulk-lengthy");if(W.length==0){return}var V=jQuery("a",W);V.text(Y);if(X){V.attr("href",X)}else{V.attr("href",V.data("href").replace("__ID__",Z))}W.css("display","block")}function F(){jQuery(".bulk-notice-msg.bulk-lengthy").css("display","none")}function A(V){var W=jQuery(".bulk-notice-msg.bulk-"+V);if(W.length==0){return}W.css("display","block")}function T(V){jQuery(".bulk-notice-msg.bulk-"+V).css("display","none")}function v(ab,Z,aa,Y){var V=jQuery("#bulk-error-template");if(V.length==0){return}var X=V.clone();X.attr("id","bulk-error-"+ab);if(ab==-1){jQuery("span.sp-err-title",X).remove();X.addClass("bulk-error-fatal")}else{jQuery("img",X).remove();jQuery("#bulk-error-".id).remove()}jQuery("span.sp-err-content",X).html(Z);var W=jQuery("a.sp-post-link",X);if(Y){W.attr("href",Y)}else{W.attr("href",W.attr("href").replace("__ID__",ab))}W.text(aa);V.after(X);X.css("display","block")}function I(V,W){if(!confirm(_spTr["confirmBulk"+V])){W.stopPropagation();W.preventDefault();return false}return true}function B(Y){var W=jQuery(Y.target).val();var V=jQuery('input[name="random_answer"]').val();var X=jQuery('input[name="random_answer"]').data("target");if(W==V){jQuery(X).removeClass("disabled").prop("disabled",false);jQuery(X).removeAttr("aria-disabled")}else{jQuery(X).addClass("disabled").prop("disabled",true)}}function u(V){jQuery(V).parent().parent().remove()}function M(V){return V.substring(0,2)=="C-"}function O(){var V=window.location.href.split("#");window.location.href=V[0]+(V[0].indexOf("?")>0?"&":"?")+"checkquota=1"+(typeof V[1]==="undefined"?"":"#"+V[1])}function h(W){W.preventDefault();if(!this.menuCloseEvent){jQuery(window).click(function(X){if(!X.target.matches(".sp-dropbtn")){jQuery(".sp-dropdown.sp-show").removeClass("sp-show")}});this.menuCloseEvent=true}var V=W.target.parentElement.classList.contains("sp-show");jQuery(".sp-dropdown.sp-show").removeClass("sp-show");if(!V){W.target.parentElement.classList.add("sp-show")}}function U(V){this.comparerData.origUrl=false;if(this.comparerData.cssLoaded===false){jQuery("<link>").appendTo("head").attr({type:"text/css",rel:"stylesheet",href:this.WP_PLUGIN_URL+"/res/css/twentytwenty.min.css"});this.comparerData.cssLoaded=2}if(this.comparerData.jsLoaded===false){jQuery.getScript(this.WP_PLUGIN_URL+"/res/js/jquery.twentytwenty.min.js",function(){ShortPixel.comparerData.jsLoaded=2;if(ShortPixel.comparerData.origUrl.length>0){ShortPixel.displayComparerPopup(ShortPixel.comparerData.width,ShortPixel.comparerData.height,ShortPixel.comparerData.origUrl,ShortPixel.comparerData.optUrl)}});this.comparerData.jsLoaded=1}if(this.comparerData.origUrl===false){jQuery.ajax({type:"POST",url:ShortPixel.AJAX_URL,data:{action:"shortpixel_get_comparer_data",id:V},success:function(W){data=JSON.parse(W);jQuery.extend(ShortPixel.comparerData,data);if(ShortPixel.comparerData.jsLoaded==2){ShortPixel.displayComparerPopup(ShortPixel.comparerData.width,ShortPixel.comparerData.height,ShortPixel.comparerData.origUrl,ShortPixel.comparerData.optUrl)}}});this.comparerData.origUrl=""}}function J(X,ad,ae,Y){var ac=X;var W=(ad<150||X<350);var ab=jQuery(W?"#spUploadCompareSideBySide":"#spUploadCompare");var Z=jQuery(".sp-modal-shade");if(!W){jQuery("#spCompareSlider").html('<img class="spUploadCompareOriginal"/><img class="spUploadCompareOptimized"/>')}X=Math.max(350,Math.min(800,(X<350?(X+25)*2:(ad<150?X+25:X))));ad=Math.max(150,(W?(ac>350?2*(ad+45):ad+45):ad*X/ac));var aa="-"+Math.round(X/2);jQuery(".sp-modal-body",ab).css("width",X);jQuery(".shortpixel-slider",ab).css("width",X);ab.css("width",X);ab.css("marginLeft",aa+"px");jQuery(".sp-modal-body",ab).css("height",ad);ab.show();Z.show();if(!W){jQuery("#spCompareSlider").twentytwenty({slider_move:"mousemove"})}jQuery(".sp-close-button").on("click",ShortPixel.closeComparerPopup);jQuery(document).on("keyup.sp_modal_active",ShortPixel.closeComparerPopup);jQuery(".sp-modal-shade").on("click",ShortPixel.closeComparerPopup);var V=jQuery(".spUploadCompareOptimized",ab);jQuery(".spUploadCompareOriginal",ab).attr("src",ae);setTimeout(function(){jQuery(window).trigger("resize")},1000);V.load(function(){jQuery(window).trigger("resize")});V.attr("src",Y)}function t(V){jQuery("#spUploadCompareSideBySide").hide();jQuery("#spUploadCompare").hide();jQuery(".sp-modal-shade").hide();jQuery(document).unbind("keyup.sp_modal_active");jQuery(".sp-modal-shade").off("click");jQuery(".sp-close-button").off("click")}function E(V){var W=document.createElement("a");W.href=V;if(V.indexOf(W.protocol+"//"+W.hostname)<0){return W.href}return V.replace(W.protocol+"//"+W.hostname,W.protocol+"//"+W.hostname.split(".").map(function(X){return sp_punycode.toASCII(X)}).join("."))}return{init:N,setOptions:o,isEmailValid:x,updateSignupEmail:p,validateKey:a,enableResize:Q,setupGeneralTab:e,apiKeyChanged:H,setupAdvancedTab:y,checkThumbsUpdTotal:P,initSettings:g,switchSettingsTab:C,adjustSettingsTabs:D,onBulkThumbsCheck:G,dismissMediaAlert:R,closeHelpPane:w,dismissHelpPane:q,checkQuota:m,percentDial:s,successMsg:b,successActions:c,otherMediaUpdateActions:j,retry:l,initFolderSelector:r,browseContent:n,getBackupSize:d,newApiKey:f,proposeUpgrade:S,closeProposeUpgrade:L,includeUnlisted:z,bulkShowLengthyMsg:K,bulkHideLengthyMsg:F,bulkShowMaintenanceMsg:A,bulkHideMaintenanceMsg:T,bulkShowError:v,confirmBulkAction:I,checkRandomAnswer:B,removeBulkMsg:u,isCustomImageId:M,recheckQuota:O,openImageMenu:h,menuCloseEvent:false,loadComparer:U,displayComparerPopup:J,closeComparerPopup:t,convertPunycode:E,checkExifWarning:k,comparerData:{cssLoaded:false,jsLoaded:false,origUrl:false,optUrl:false,width:0,height:0},toRefresh:false,resizeSizesAlert:false,returnedStatusSearching:0}}();function showToolBarAlert(c,b,d){var a=jQuery("li.shortpixel-toolbar-processing");switch(c){case ShortPixel.STATUS_QUOTA_EXCEEDED:if(window.location.href.search("wp-short-pixel-bulk")>0&&jQuery(".sp-quota-exceeded-alert").length==0){location.reload();return}a.addClass("shortpixel-alert");a.addClass("shortpixel-quota-exceeded");jQuery("a",a).attr("href","options-general.php?page=wp-shortpixel-settings");jQuery("a div",a).attr("title","ShortPixel quota exceeded. Click for details.");break;case ShortPixel.STATUS_SKIP:case ShortPixel.STATUS_FAIL:a.addClass("shortpixel-alert shortpixel-processing");jQuery("a div",a).attr("title",b);if(typeof d!=="undefined"){jQuery("a",a).attr("href","post.php?post="+d+"&action=edit")}break;case ShortPixel.STATUS_NO_KEY:a.addClass("shortpixel-alert");a.addClass("shortpixel-quota-exceeded");jQuery("a",a).attr("href","options-general.php?page=wp-shortpixel-settings");jQuery("a div",a).attr("title","Get API Key");break;case ShortPixel.STATUS_SUCCESS:case ShortPixel.STATUS_RETRY:a.addClass("shortpixel-processing");a.removeClass("shortpixel-alert");jQuery("a",a).removeAttr("target");jQuery("a",a).attr("href",jQuery("a img",a).attr("success-url"))}a.removeClass("shortpixel-hide")}function hideToolBarAlert(){jQuery("li.shortpixel-toolbar-processing.shortpixel-processing").addClass("shortpixel-hide")}function hideQuotaExceededToolBarAlert(){jQuery("li.shortpixel-toolbar-processing.shortpixel-quota-exceeded").addClass("shortpixel-hide")}function checkQuotaExceededAlert(){if(typeof shortPixelQuotaExceeded!="undefined"){if(shortPixelQuotaExceeded==1){showToolBarAlert(ShortPixel.STATUS_QUOTA_EXCEEDED)}else{hideQuotaExceededToolBarAlert()}}}function checkBulkProgress(){var b=function(e){if(!d){d=true;return e}return"/"};var d=false;var a=window.location.href.toLowerCase().replace(/\/\//g,b);d=false;var c=ShortPixel.WP_ADMIN_URL.toLowerCase().replace(/\/\//g,b);if(a.search(c)<0){a=ShortPixel.convertPunycode(a);c=ShortPixel.convertPunycode(c)}if(a.search(c+"upload.php")<0&&a.search(c+"edit.php")<0&&a.search(c+"edit-tags.php")<0&&a.search(c+"post-new.php")<0&&a.search(c+"post.php")<0&&a.search("page=nggallery-manage-gallery")<0&&(ShortPixel.FRONT_BOOTSTRAP==0||a.search(c)==0)){hideToolBarAlert();return}if(ShortPixel.bulkProcessor==true&&window.location.href.search("wp-short-pixel-bulk")<0&&typeof localStorage.bulkPage!=="undefined"&&localStorage.bulkPage>0){ShortPixel.bulkProcessor=false}if(window.location.href.search("wp-short-pixel-bulk")>=0){ShortPixel.bulkProcessor=true;localStorage.bulkTime=Math.floor(Date.now()/1000);localStorage.bulkPage=1}if(ShortPixel.bulkProcessor==true||typeof localStorage.bulkTime=="undefined"||Math.floor(Date.now()/1000)-localStorage.bulkTime>90){ShortPixel.bulkProcessor=true;localStorage.bulkPage=(window.location.href.search("wp-short-pixel-bulk")>=0?1:0);localStorage.bulkTime=Math.floor(Date.now()/1000);console.log(localStorage.bulkTime);checkBulkProcessingCallApi()}else{setTimeout(checkBulkProgress,5000)}}function checkBulkProcessingCallApi(){var a={action:"shortpixel_image_processing"};jQuery.ajax({type:"POST",url:ShortPixel.AJAX_URL,data:a,success:function(g){if(g.length>0){var j=null;try{var j=JSON.parse(g)}catch(l){ShortPixel.retry(l.message);return}ShortPixel.retries=0;var d=j.ImageID;var k=(jQuery("div.short-pixel-bulk-page").length>0);if(j.Status&&j.Status!=ShortPixel.STATUS_SEARCHING){if(ShortPixel.returnedStatusSearching>=2){jQuery(".bulk-notice-msg.bulk-searching").hide()}ShortPixel.returnedStatusSearching=0}switch(j.Status){case ShortPixel.STATUS_NO_KEY:setCellMessage(d,j.Message,"<a class='button button-smaller button-primary' href=\"https://shortpixel.com/wp-apikey"+ShortPixel.AFFILIATE+'" target="_blank">'+_spTr.getApiKey+"</a>");showToolBarAlert(ShortPixel.STATUS_NO_KEY);break;case ShortPixel.STATUS_QUOTA_EXCEEDED:setCellMessage(d,j.Message,"<a class='button button-smaller button-primary' href=\"https://shortpixel.com/login/"+ShortPixel.API_KEY+'" target="_blank">'+_spTr.extendQuota+"</a><a class='button button-smaller' href='admin.php?action=shortpixel_check_quota'>"+_spTr.check__Quota+"</a>");showToolBarAlert(ShortPixel.STATUS_QUOTA_EXCEEDED);if(j.Stop==false){setTimeout(checkBulkProgress,5000)}ShortPixel.otherMediaUpdateActions(d,["quota","view"]);break;case ShortPixel.STATUS_FAIL:setCellMessage(d,j.Message,"<a class='button button-smaller button-primary' href=\"javascript:manualOptimization('"+d+"', false)\">"+_spTr.retry+"</a>");showToolBarAlert(ShortPixel.STATUS_FAIL,j.Message,d);if(k){ShortPixel.bulkShowError(d,j.Message,j.Filename,j.CustomImageLink);if(j.BulkPercent){progressUpdate(j.BulkPercent,j.BulkMsg)}ShortPixel.otherMediaUpdateActions(d,["retry","view"])}console.log(j.Message);setTimeout(checkBulkProgress,5000);break;case ShortPixel.STATUS_EMPTY_QUEUE:console.log(j.Message);clearBulkProcessor();hideToolBarAlert();var c=jQuery("#bulk-progress");if(k&&c.length&&j.BulkStatus!="2"){progressUpdate(100,"Bulk finished!");jQuery("a.bulk-cancel").attr("disabled","disabled");hideSlider();setTimeout(function(){window.location.reload()},3000)}break;case ShortPixel.STATUS_SUCCESS:if(k){ShortPixel.bulkHideLengthyMsg();ShortPixel.bulkHideMaintenanceMsg()}var m=j.PercentImprovement;showToolBarAlert(ShortPixel.STATUS_SUCCESS,"");var b=ShortPixel.isCustomImageId(d)?"":ShortPixel.successActions(d,j.Type,j.ThumbsCount,j.ThumbsTotal,j.BackupEnabled,j.Filename);setCellMessage(d,ShortPixel.successMsg(d,m,j.Type,j.ThumbsCount,j.RetinasCount),b);if(jQuery("#post-"+d).length>0){jQuery("#post-"+d).find(".filename").text(j.Filename)}if(jQuery(".misc-pub-filename strong").length>0){jQuery(".misc-pub-filename strong").text(j.Filename)}if(ShortPixel.isCustomImageId(d)&&j.TsOptimized&&j.TsOptimized.length>0){console.log(d);jQuery(".date-"+d).text(j.TsOptimized)}var h=jQuery(["restore","view","redolossy","redoglossy","redolossless"]).not(["redo"+j.Type]).get();ShortPixel.otherMediaUpdateActions(d,h);var f=new PercentageAnimator("#sp-msg-"+d+" span.percent",m);f.animate(m);if(k&&typeof j.Thumb!=="undefined"){if(j.BulkPercent){progressUpdate(j.BulkPercent,j.BulkMsg)}if(j.Thumb.length>0){sliderUpdate(d,j.Thumb,j.BkThumb,j.PercentImprovement,j.Filename);if(typeof j.AverageCompression!=="undefined"&&0+j.AverageCompression>0){jQuery("#sp-avg-optimization").html('<input type="text" class="dial" value="'+Math.round(j.AverageCompression)+'"/>');ShortPixel.percentDial("#sp-avg-optimization .dial",60)}}}console.log("Server response: "+g);if(k&&typeof j.BulkPercent!=="undefined"){progressUpdate(j.BulkPercent,j.BulkMsg)}setTimeout(checkBulkProgress,5000);break;case ShortPixel.STATUS_SKIP:if(j.Silent!==1){ShortPixel.bulkShowError(d,j.Message,j.Filename,j.CustomImageLink)}case ShortPixel.STATUS_ERROR:if(typeof j.Message!=="undefined"){showToolBarAlert(ShortPixel.STATUS_SKIP,j.Message+" Image ID: "+d);setCellMessage(d,j.Message,"")}ShortPixel.otherMediaUpdateActions(d,["retry","view"]);case ShortPixel.STATUS_RETRY:console.log("Server response: "+g);showToolBarAlert(ShortPixel.STATUS_RETRY,"");if(k&&typeof j.BulkPercent!=="undefined"){progressUpdate(j.BulkPercent,j.BulkMsg)}if(k&&j.Count>3){ShortPixel.bulkShowLengthyMsg(d,j.Filename,j.CustomImageLink)}setTimeout(checkBulkProgress,5000);break;case ShortPixel.STATUS_SEARCHING:console.log("Server response: "+g);ShortPixel.returnedStatusSearching++;if(ShortPixel.returnedStatusSearching>=2){jQuery(".bulk-notice-msg.bulk-searching").show()}setTimeout(checkBulkProgress,2500);break;case ShortPixel.STATUS_MAINTENANCE:ShortPixel.bulkShowMaintenanceMsg("maintenance");setTimeout(checkBulkProgress,60000);break;case ShortPixel.STATUS_QUEUE_FULL:ShortPixel.bulkShowMaintenanceMsg("queue-full");setTimeout(checkBulkProgress,60000);break;default:ShortPixel.retry("Unknown status "+j.Status+". Retrying...");break}}},error:function(b){ShortPixel.retry(b.statusText)}})}function clearBulkProcessor(){ShortPixel.bulkProcessor=false;localStorage.bulkTime=0;if(window.location.href.search("wp-short-pixel-bulk")>=0){localStorage.bulkPage=0}}function setCellMessage(d,a,c){var b=jQuery("#sp-msg-"+d);if(b.length>0){b.html("<div class='sp-column-actions'>"+c+"</div><div class='sp-column-info'>"+a+"</div>");b.css("color","")}b=jQuery("#sp-cust-msg-"+d);if(b.length>0){b.html("<div class='sp-column-info'>"+a+"</div>")}}function manualOptimization(c,a){setCellMessage(c,"<img src='"+ShortPixel.WP_PLUGIN_URL+"/res/img/loading.gif' class='sp-loading-small'>Image waiting to be processed","");jQuery("li.shortpixel-toolbar-processing").removeClass("shortpixel-hide");jQuery("li.shortpixel-toolbar-processing").removeClass("shortpixel-alert");jQuery("li.shortpixel-toolbar-processing").addClass("shortpixel-processing");var b={action:"shortpixel_manual_optimization",image_id:c,cleanup:a};jQuery.ajax({type:"GET",url:ShortPixel.AJAX_URL,data:b,success:function(d){var e=JSON.parse(d);if(e.Status==ShortPixel.STATUS_SUCCESS){setTimeout(checkBulkProgress,2000)}else{setCellMessage(c,typeof e.Message!=="undefined"?e.Message:_spTr.thisContentNotProcessable,"")}},error:function(d){b.action="shortpixel_check_status";jQuery.ajax({type:"GET",url:ShortPixel.AJAX_URL,data:b,success:function(e){var f=JSON.parse(e);if(f.Status!==ShortPixel.STATUS_SUCCESS){setCellMessage(c,typeof f.Message!=="undefined"?f.Message:_spTr.thisContentNotProcessable,"")}}})}})}function reoptimize(c,a){setCellMessage(c,"<img src='"+ShortPixel.WP_PLUGIN_URL+"/res/img/loading.gif' class='sp-loading-small'>Image waiting to be reprocessed","");jQuery("li.shortpixel-toolbar-processing").removeClass("shortpixel-hide");jQuery("li.shortpixel-toolbar-processing").addClass("shortpixel-processing");var b={action:"shortpixel_redo",attachment_ID:c,type:a};jQuery.get(ShortPixel.AJAX_URL,b,function(d){b=JSON.parse(d);if(b.Status==ShortPixel.STATUS_SUCCESS){setTimeout(checkBulkProgress,2000)}else{$msg=typeof b.Message!=="undefined"?b.Message:_spTr.thisContentNotProcessable;setCellMessage(c,$msg,"");showToolBarAlert(ShortPixel.STATUS_FAIL,$msg)}})}function optimizeThumbs(b){setCellMessage(b,"<img src='"+ShortPixel.WP_PLUGIN_URL+"/res/img/loading.gif' class='sp-loading-small'>"+_spTr.imageWaitOptThumbs,"");jQuery("li.shortpixel-toolbar-processing").removeClass("shortpixel-hide");jQuery("li.shortpixel-toolbar-processing").addClass("shortpixel-processing");var a={action:"shortpixel_optimize_thumbs",attachment_ID:b};jQuery.get(ShortPixel.AJAX_URL,a,function(c){a=JSON.parse(c);if(a.Status==ShortPixel.STATUS_SUCCESS){setTimeout(checkBulkProgress,2000)}else{setCellMessage(b,typeof a.Message!=="undefined"?a.Message:_spTr.thisContentNotProcessable,"")}})}function dismissShortPixelNoticeExceed(b){jQuery("#wp-admin-bar-shortpixel_processing").hide();var a={action:"shortpixel_dismiss_notice",notice_id:"exceed"};jQuery.get(ShortPixel.AJAX_URL,a,function(c){a=JSON.parse(c);if(a.Status==ShortPixel.STATUS_SUCCESS){console.log("dismissed")}});b.preventDefault()}function dismissShortPixelNotice(b){jQuery("#short-pixel-notice-"+b).hide();var a={action:"shortpixel_dismiss_notice",notice_id:b};jQuery.get(ShortPixel.AJAX_URL,a,function(c){a=JSON.parse(c);if(a.Status==ShortPixel.STATUS_SUCCESS){console.log("dismissed")}})}function PercentageAnimator(b,a){this.animationSpeed=10;this.increment=2;this.curPercentage=0;this.targetPercentage=a;this.outputSelector=b;this.animate=function(c){this.targetPercentage=c;setTimeout(PercentageTimer.bind(null,this),this.animationSpeed)}}function PercentageTimer(a){if(a.curPercentage-a.targetPercentage<-a.increment){a.curPercentage+=a.increment}else{if(a.curPercentage-a.targetPercentage>a.increment){a.curPercentage-=a.increment}else{a.curPercentage=a.targetPercentage}}jQuery(a.outputSelector).text(a.curPercentage+"%");if(a.curPercentage!=a.targetPercentage){setTimeout(PercentageTimer.bind(null,a),a.animationSpeed)}}function progressUpdate(c,b){var a=jQuery("#bulk-progress");if(a.length){jQuery(".progress-left",a).css("width",c+"%");jQuery(".progress-img",a).css("left",c+"%");if(c>24){jQuery(".progress-img span",a).html("");jQuery(".progress-left",a).html(c+"%")}else{jQuery(".progress-img span",a).html(c+"%");jQuery(".progress-left",a).html("")}jQuery(".bulk-estimate").html(b)}}function sliderUpdate(g,c,d,e,b){var f=jQuery(".bulk-slider div.bulk-slide:first-child");if(f.length===0){return}if(f.attr("id")!="empty-slide"){f.hide()}f.css("z-index",1000);jQuery(".bulk-img-opt",f).attr("src","");if(typeof d==="undefined"){d=""}if(d.length>0){jQuery(".bulk-img-orig",f).attr("src","")}var a=f.clone();a.attr("id","slide-"+g);jQuery(".bulk-img-opt",a).attr("src",c);if(d.length>0){jQuery(".img-original",a).css("display","inline-block");jQuery(".bulk-img-orig",a).attr("src",d)}else{jQuery(".img-original",a).css("display","none")}jQuery(".bulk-opt-percent",a).html('<input type="text" class="dial" value="'+e+'"/>');jQuery(".bulk-slider").append(a);ShortPixel.percentDial("#"+a.attr("id")+" .dial",100);jQuery(".bulk-slider-container span.filename").html(" "+b);if(f.attr("id")=="empty-slide"){f.remove();jQuery(".bulk-slider-container").css("display","block")}else{f.animate({left:f.width()+f.position().left},"slow","swing",function(){f.remove();a.fadeIn("slow")})}}function hideSlider(){jQuery(".bulk-slider-container").css("display","none")}function showStats(){var a=jQuery(".bulk-stats");if(a.length>0){}}function SPstringFormat(){var b=Array.prototype.slice.call(arguments);if(b.length===0){return}var a=b.shift();for(i=0;i<b.length;i++){a=a.replace(new RegExp("\\{"+i+"\\}","gm"),b[i])}return a};
|
res/scss/shortpixel-admin.scss
CHANGED
@@ -1,6 +1,7 @@
|
|
1 |
|
2 |
@import 'utils/notices';
|
3 |
@import 'view/bulk-restore-all';
|
4 |
-
@import 'view/bulk_dashboard';
|
5 |
@import 'view/settings-advanced';
|
6 |
@import 'view/settings';
|
|
1 |
|
2 |
@import 'utils/notices';
|
3 |
@import 'view/bulk-restore-all';
|
4 |
+
@import 'view/bulk_dashboard';
|
5 |
@import 'view/settings-advanced';
|
6 |
@import 'view/settings';
|
7 |
+
@import 'view/edit-media';
|
res/scss/view/_edit-media.scss
ADDED
@@ -0,0 +1,48 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
|
2 |
+
|
3 |
+
.view-edit-media
|
4 |
+
{
|
5 |
+
.debugInfo
|
6 |
+
{
|
7 |
+
pre
|
8 |
+
{
|
9 |
+
font-size: 11px;
|
10 |
+
// overflow: hidden;
|
11 |
+
}
|
12 |
+
}
|
13 |
+
.sp-column-stats
|
14 |
+
{
|
15 |
+
position: relative;
|
16 |
+
|
17 |
+
.sp-column-actions
|
18 |
+
{
|
19 |
+
margin-right: 5px;
|
20 |
+
margin-top: 16px;
|
21 |
+
}
|
22 |
+
.edit-media-stats
|
23 |
+
{
|
24 |
+
border: 1px solid #ccc;
|
25 |
+
padding: 16px;
|
26 |
+
|
27 |
+
li
|
28 |
+
{
|
29 |
+
margin: 0;
|
30 |
+
line-height: 20px;
|
31 |
+
}
|
32 |
+
}
|
33 |
+
}
|
34 |
+
.main-actions
|
35 |
+
{
|
36 |
+
display: inline-block;
|
37 |
+
width: 100%;
|
38 |
+
//text-align: center;
|
39 |
+
.button.button-smaller
|
40 |
+
{
|
41 |
+
//float: none;
|
42 |
+
padding: 6px 15px;
|
43 |
+
height: auto;
|
44 |
+
float: none;
|
45 |
+
}
|
46 |
+
}
|
47 |
+
|
48 |
+
} // view-edit-media
|
shortpixel_api.php
CHANGED
@@ -467,6 +467,8 @@ class ShortPixelAPI {
|
|
467 |
return array("Status" => self::STATUS_SUCCESS);
|
468 |
}
|
469 |
|
|
|
|
|
470 |
//$fullSubDir = str_replace(wp_normalize_path(get_home_path()), "", wp_normalize_path(dirname($itemHandler->getMeta()->getPath()))) . '/';
|
471 |
//$SubDir = ShortPixelMetaFacade::returnSubDir($itemHandler->getMeta()->getPath(), $itemHandler->getType());
|
472 |
$fullSubDir = ShortPixelMetaFacade::returnSubDir($mainPath);
|
467 |
return array("Status" => self::STATUS_SUCCESS);
|
468 |
}
|
469 |
|
470 |
+
Log::addDebug('Backing The Up', array($mainPath, $PATHs));
|
471 |
+
|
472 |
//$fullSubDir = str_replace(wp_normalize_path(get_home_path()), "", wp_normalize_path(dirname($itemHandler->getMeta()->getPath()))) . '/';
|
473 |
//$SubDir = ShortPixelMetaFacade::returnSubDir($itemHandler->getMeta()->getPath(), $itemHandler->getType());
|
474 |
$fullSubDir = ShortPixelMetaFacade::returnSubDir($mainPath);
|
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-settings" target="_blank">Settings > ShortPixel</a> page on how to start optimizing your image library and make your website load faster.
|
6 |
-
* Version: 4.14.
|
7 |
* Author: ShortPixel
|
8 |
* Author URI: https://shortpixel.com
|
9 |
* Text Domain: shortpixel-image-optimiser
|
@@ -19,7 +19,7 @@ define('SHORTPIXEL_PLUGIN_DIR', __DIR__);
|
|
19 |
|
20 |
//define('SHORTPIXEL_AFFILIATE_CODE', '');
|
21 |
|
22 |
-
define('SHORTPIXEL_IMAGE_OPTIMISER_VERSION', "4.14.
|
23 |
define('SHORTPIXEL_MAX_TIMEOUT', 10);
|
24 |
define('SHORTPIXEL_VALIDATE_MAX_TIMEOUT', 15);
|
25 |
define('SHORTPIXEL_BACKUP', 'ShortpixelBackups');
|
3 |
* Plugin Name: ShortPixel Image Optimizer
|
4 |
* Plugin URI: https://shortpixel.com/
|
5 |
* Description: ShortPixel optimizes images automatically, while guarding the quality of your images. Check your <a href="options-general.php?page=wp-shortpixel-settings" target="_blank">Settings > ShortPixel</a> page on how to start optimizing your image library and make your website load faster.
|
6 |
+
* Version: 4.14.6
|
7 |
* Author: ShortPixel
|
8 |
* Author URI: https://shortpixel.com
|
9 |
* Text Domain: shortpixel-image-optimiser
|
19 |
|
20 |
//define('SHORTPIXEL_AFFILIATE_CODE', '');
|
21 |
|
22 |
+
define('SHORTPIXEL_IMAGE_OPTIMISER_VERSION', "4.14.6");
|
23 |
define('SHORTPIXEL_MAX_TIMEOUT', 10);
|
24 |
define('SHORTPIXEL_VALIDATE_MAX_TIMEOUT', 15);
|
25 |
define('SHORTPIXEL_BACKUP', 'ShortpixelBackups');
|