Version Description
Release date August 8th, 2022
* Fix: the Previous Bulks
now displays the number of credits used instead of the number of Media Library items, to avoid confusion;
* Fix: the notification for migrating the old format of optimization information was not getting triggered anymore;
* Fix: excluded images and/or thumbnails can now be restored from the backup;
* Fix: added prevention for double database queries when checking if an item is already in the queue;
* Fix: the bulk restore and bulk migration of optimization data can now be done even if out of credits;
* Fix: reduced the number of database table checks done on wp-admin pages to the minimum possible;
* Fix: the out-of-quota message was not always showing up properly;
* Fix: the bulk migration of the optimization data now marks as optimized the images that have proper backups in place;
* Fix: the thousands separators are now displayed properly for all languages;
* Fix: the optimized/unoptimized Media Library filter has proper pagination and also works with WPML;
* Fix: in case the optimization percentage is an integer, drop the .00
(83.00% -> 83%);
* Fix: improved the settings and bulk pages load time for sites with a huge number of items in the Media Library;
* Fix: properly save the optimization information even if the filename is huge;
* Fix: the Optimize now
button wasn't showing up on Custom Media right after restoring an item from the backup;
* Fix: more fixes for multisite installs where the old blogs.dir
folder structure is used;
* Fix: multiple fixes and improvements for WP-CLI, including more detailed embedded docs and examples;
* Fix: multiple fixes and improvements to the whole exclusions module;
* Fix: multiple fixes and improvements in handling how retina images are optimized;
* Fix: various small fixes and improvements to the debug mode of the plugin;
* Tweak: CTRL+S
can now be used to save settings (you're welcome!);
* Tweak: added support for bulk processing via the processing hook;
* Tweak: various wording and text updates in the plugin and the readme file;
* Language: 10 new strings added, 8 updated, 0 fuzzed, and 2 obsoleted.
Release Info
Developer | petredobrescu |
Plugin | ShortPixel Image Optimizer |
Version | 5.0.8 |
Comparing to | |
See all releases |
Code changes from version 5.0.7 to 5.0.8
- build/shortpixel/log/src/ShortPixelLogger.php +40 -5
- build/shortpixel/notices/src/NoticeModel.php +6 -6
- build/shortpixel/shortq/src/Queue/WPQ.php +1 -1
- class/BuildAutoLoader.php +1 -0
- class/Controller/AdminController.php +5 -0
- class/Controller/AdminNoticesController.php +18 -12
- class/Controller/AjaxController.php +1 -16
- class/Controller/ApiController.php +1 -1
- class/Controller/BulkController.php +12 -1
- class/Controller/FileSystemController.php +9 -0
- class/Controller/OptimizeController.php +49 -24
- class/Controller/Queue/Queue.php +25 -8
- class/Controller/QuotaController.php +5 -5
- class/Controller/ResponseController.php +26 -5
- class/Controller/SettingsController.php +2 -1
- class/Controller/View/BulkViewController.php +4 -1
- class/Controller/View/EditMediaViewController.php +2 -1
- class/Controller/View/ListMediaViewController.php +7 -2
- class/Helper/InstallHelper.php +8 -13
- class/Helper/UiHelper.php +16 -8
- class/Model/EnvironmentModel.php +1 -1
- class/Model/Image/CustomImageModel.php +3 -4
- class/Model/Image/ImageModel.php +24 -5
- class/Model/Image/MediaLibraryModel.php +334 -82
- class/Model/Image/MediaLibraryThumbnailModel.php +18 -19
- class/Model/StatsModel.php +18 -1
- class/external/cache.php +153 -0
- class/external/gravityforms.php +23 -8
- class/external/wp-cli/wp-cli-base.php +46 -31
- class/external/wp-cli/wp-cli-bulk.php +67 -47
- class/external/wp-cli/wp-cli-single.php +8 -5
- class/front/img-to-picture-webp.php +2 -3
- class/plugin.json +1 -1
- class/view/bulk/part-selection.php +10 -3
- class/view/bulk/part-summary.php +2 -2
- class/view/settings/part-advanced.php +59 -43
- class/view/settings/part-debug.php +1 -0
- class/wp-shortpixel-settings.php +2 -8
- readme.txt +39 -7
- res/css/shortpixel-admin.css +4 -0
- res/css/shortpixel-admin.css.map +1 -1
- res/css/shortpixel-bulk.css +3 -0
- res/css/shortpixel-bulk.css.map +1 -1
- res/css/shortpixel-othermedia.css +4 -1
- res/css/shortpixel-othermedia.css.map +1 -1
- res/js/screens/screen-bulk.js +8 -2
- res/js/shortpixel-processor.js +11 -1
- res/js/shortpixel-settings.js +30 -1
- res/js/shortpixel.js +1 -1
- res/scss/shortpixel-admin.scss +5 -0
- res/scss/shortpixel-bulk.scss +6 -0
- res/scss/shortpixel-othermedia.scss +6 -1
- shortpixel-plugin.php +5 -5
- wp-shortpixel.php +3 -2
@@ -24,6 +24,8 @@ namespace ShortPixel\ShortPixelLogger;
|
|
24 |
protected $format_data = "\t %%data%% ";
|
25 |
|
26 |
protected $hooks = array();
|
|
|
|
|
27 |
/* protected $hooks = array(
|
28 |
'shortpixel_image_exists' => array('numargs' => 3),
|
29 |
'shortpixel_webp_image_base' => array('numargs' => 2),
|
@@ -78,8 +80,6 @@ namespace ShortPixel\ShortPixelLogger;
|
|
78 |
|
79 |
if (defined('SHORTPIXEL_DEBUG_TARGET') && SHORTPIXEL_DEBUG_TARGET || $this->is_manual_request)
|
80 |
{
|
81 |
-
//$this->logPath = SHORTPIXEL_BACKUP_FOLDER . "/shortpixel_log";
|
82 |
-
//$this->logMode = defined('SHORTPIXEL_LOG_OVERWRITE') ? 0 : FILE_APPEND;
|
83 |
if (defined('SHORTPIXEL_LOG_OVERWRITE')) // if overwrite, do this on init once.
|
84 |
file_put_contents($this->logPath,'-- Log Reset -- ' .PHP_EOL);
|
85 |
|
@@ -130,6 +130,7 @@ namespace ShortPixel\ShortPixelLogger;
|
|
130 |
public function setLogPath($logPath)
|
131 |
{
|
132 |
$this->logPath = $logPath;
|
|
|
133 |
}
|
134 |
protected function addLog($message, $level, $data = array())
|
135 |
{
|
@@ -187,16 +188,50 @@ namespace ShortPixel\ShortPixelLogger;
|
|
187 |
|
188 |
$line = $this->formatLine($items);
|
189 |
|
|
|
|
|
190 |
// try to write to file. Don't write if directory doesn't exists (leads to notices)
|
191 |
-
if ($
|
192 |
{
|
193 |
-
|
|
|
194 |
}
|
195 |
else {
|
196 |
-
|
197 |
}
|
198 |
}
|
199 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
200 |
protected function formatLine($args = array() )
|
201 |
{
|
202 |
$line= $this->format;
|
24 |
protected $format_data = "\t %%data%% ";
|
25 |
|
26 |
protected $hooks = array();
|
27 |
+
|
28 |
+
private $logFile; // pointer resource to the logFile.
|
29 |
/* protected $hooks = array(
|
30 |
'shortpixel_image_exists' => array('numargs' => 3),
|
31 |
'shortpixel_webp_image_base' => array('numargs' => 2),
|
80 |
|
81 |
if (defined('SHORTPIXEL_DEBUG_TARGET') && SHORTPIXEL_DEBUG_TARGET || $this->is_manual_request)
|
82 |
{
|
|
|
|
|
83 |
if (defined('SHORTPIXEL_LOG_OVERWRITE')) // if overwrite, do this on init once.
|
84 |
file_put_contents($this->logPath,'-- Log Reset -- ' .PHP_EOL);
|
85 |
|
130 |
public function setLogPath($logPath)
|
131 |
{
|
132 |
$this->logPath = $logPath;
|
133 |
+
$this->getWriteFile(true); // reset the writeFile here.
|
134 |
}
|
135 |
protected function addLog($message, $level, $data = array())
|
136 |
{
|
188 |
|
189 |
$line = $this->formatLine($items);
|
190 |
|
191 |
+
$file = $this->getWriteFile();
|
192 |
+
|
193 |
// try to write to file. Don't write if directory doesn't exists (leads to notices)
|
194 |
+
if ($file )
|
195 |
{
|
196 |
+
fwrite($file, $line);
|
197 |
+
// file_put_contents($this->logPath,$line, FILE_APPEND);
|
198 |
}
|
199 |
else {
|
200 |
+
// error_log($line);
|
201 |
}
|
202 |
}
|
203 |
|
204 |
+
protected function getWriteFile($reset = false)
|
205 |
+
{
|
206 |
+
if (! is_null($this->logFile) && $reset === false)
|
207 |
+
{
|
208 |
+
return $this->logFile;
|
209 |
+
}
|
210 |
+
elseif(is_object($this->logFile))
|
211 |
+
{
|
212 |
+
fclose($this->logFile);
|
213 |
+
}
|
214 |
+
|
215 |
+
$logDir = dirname($this->logPath);
|
216 |
+
if (! is_dir($logDir) || ! is_writable($logDir))
|
217 |
+
{
|
218 |
+
error_log('ShortpixelLogger: Log Directory is not writable');
|
219 |
+
$this->logFile = false;
|
220 |
+
return false;
|
221 |
+
}
|
222 |
+
|
223 |
+
$file = fopen($this->logPath, 'a');
|
224 |
+
if ($file === false)
|
225 |
+
{
|
226 |
+
error_log('ShortpixelLogger: File could not be opened / created: ' . $this->logPath);
|
227 |
+
$this->logFile = false;
|
228 |
+
return $file;
|
229 |
+
}
|
230 |
+
|
231 |
+
$this->logFile = $file;
|
232 |
+
return $file;
|
233 |
+
}
|
234 |
+
|
235 |
protected function formatLine($args = array() )
|
236 |
{
|
237 |
$line= $this->format;
|
@@ -234,9 +234,9 @@ class NoticeModel //extends ShortPixelModel
|
|
234 |
document.getElementById('button-$id').onclick = function()
|
235 |
{
|
236 |
var el = document.getElementById('$id');
|
237 |
-
|
238 |
-
|
239 |
-
|
240 |
})
|
241 |
});
|
242 |
} </script>";
|
@@ -289,9 +289,9 @@ class NoticeModel //extends ShortPixelModel
|
|
289 |
data.id = parent.getAttribute('id');
|
290 |
jQuery.post($url,data);
|
291 |
|
292 |
-
|
293 |
-
|
294 |
-
|
295 |
})
|
296 |
});
|
297 |
}";
|
234 |
document.getElementById('button-$id').onclick = function()
|
235 |
{
|
236 |
var el = document.getElementById('$id');
|
237 |
+
$(el).fadeTo(100,0,function() {
|
238 |
+
$(el).slideUp(100, 0, function () {
|
239 |
+
$(el).remove();
|
240 |
})
|
241 |
});
|
242 |
} </script>";
|
289 |
data.id = parent.getAttribute('id');
|
290 |
jQuery.post($url,data);
|
291 |
|
292 |
+
$(parent).fadeTo(100,0,function() {
|
293 |
+
$(parent).slideUp(100, 0, function () {
|
294 |
+
$(parent).remove();
|
295 |
})
|
296 |
});
|
297 |
}";
|
@@ -486,7 +486,7 @@ class WPQ implements Queue
|
|
486 |
{
|
487 |
$this->status = get_option($this->statusName);
|
488 |
|
489 |
-
if (! $this->status || ! is_object($this->status))
|
490 |
$this->createStatus();
|
491 |
|
492 |
|
486 |
{
|
487 |
$this->status = get_option($this->statusName);
|
488 |
|
489 |
+
if (! $this->status || ! is_object($this->status) && ! is_array($this->status))
|
490 |
$this->createStatus();
|
491 |
|
492 |
|
@@ -69,6 +69,7 @@ class BuildAutoLoader
|
|
69 |
'class/external/custom-suffixes.php',
|
70 |
'class/external/pantheon.php',
|
71 |
'class/external/spai.php',
|
|
|
72 |
);
|
73 |
|
74 |
echo "Build Plugin.JSON ";
|
69 |
'class/external/custom-suffixes.php',
|
70 |
'class/external/pantheon.php',
|
71 |
'class/external/spai.php',
|
72 |
+
'class/external/cache.php',
|
73 |
);
|
74 |
|
75 |
echo "Build Plugin.JSON ";
|
@@ -75,6 +75,7 @@ class AdminController extends \ShortPixel\Controller
|
|
75 |
'wait' => 3, // amount of time to wait for next round. Prevents high loads
|
76 |
'run_once' => false, // If true queue must be run at least every few minutes. If false, it tries to complete all.
|
77 |
'queues' => array('media','custom'),
|
|
|
78 |
);
|
79 |
|
80 |
if (wp_doing_cron())
|
@@ -85,6 +86,10 @@ class AdminController extends \ShortPixel\Controller
|
|
85 |
$args = wp_parse_args($args, $defaults);
|
86 |
|
87 |
$control = new OptimizeController();
|
|
|
|
|
|
|
|
|
88 |
|
89 |
if ($args['run_once'] === true)
|
90 |
{
|
75 |
'wait' => 3, // amount of time to wait for next round. Prevents high loads
|
76 |
'run_once' => false, // If true queue must be run at least every few minutes. If false, it tries to complete all.
|
77 |
'queues' => array('media','custom'),
|
78 |
+
'bulk' => false,
|
79 |
);
|
80 |
|
81 |
if (wp_doing_cron())
|
86 |
$args = wp_parse_args($args, $defaults);
|
87 |
|
88 |
$control = new OptimizeController();
|
89 |
+
if ($args['bulk'] === true)
|
90 |
+
{
|
91 |
+
$control->setBulk(true);
|
92 |
+
}
|
93 |
|
94 |
if ($args['run_once'] === true)
|
95 |
{
|
@@ -44,6 +44,7 @@ class AdminNoticesController extends \ShortPixel\Controller
|
|
44 |
private $remote_message_endpoint = 'https://api.shortpixel.com/v2/notices.php';
|
45 |
private $remote_readme_endpoint = 'https://plugins.svn.wordpress.org/shortpixel-image-optimiser/trunk/readme.txt';
|
46 |
|
|
|
47 |
public function __construct()
|
48 |
{
|
49 |
add_action('admin_notices', array($this, 'displayNotices'), 50); // notices occured before page load
|
@@ -290,11 +291,19 @@ class AdminNoticesController extends \ShortPixel\Controller
|
|
290 |
// Called by MediaLibraryModel
|
291 |
public function invokeLegacyNotice()
|
292 |
{
|
293 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
294 |
|
295 |
$message .= '<p>' . __('Prior to version 5.0, a different format was used to store ShortPixel optimization information. ShortPixel automatically migrates the media library items to the new format when they are opened. %s Please check if your images contain the optimization information after the migration. %s Read more %s', 'shortpixel-image-optimiser') . '</p>';
|
296 |
|
297 |
-
$message .= '<p>' . __('It is recommended to migrate all items to the modern format by clicking on the button below.', '
|
298 |
$message .= '<p><a href="%s" class="button button-primary">%s</a></p>';
|
299 |
|
300 |
$read_link = esc_url('https://shortpixel.com/knowledge-base/article/539-spio-5-tells-me-to-convert-legacy-data-what-is-this');
|
@@ -328,6 +337,7 @@ class AdminNoticesController extends \ShortPixel\Controller
|
|
328 |
$noticeController = Notices::getInstance();
|
329 |
$statsControl = StatsController::getInstance(); // @todo Implement this. (Figure out what this was )
|
330 |
|
|
|
331 |
|
332 |
if (! \wpSPIO()->settings()->verifiedKey)
|
333 |
{
|
@@ -362,7 +372,7 @@ class AdminNoticesController extends \ShortPixel\Controller
|
|
362 |
//looks like the user hasn't got enough credits to process the monthly images, display a notice telling this
|
363 |
$message = $this->getMonthlyUpgradeMessage(array('monthAvg' => $this->getMonthAvg(), 'monthlyQuota' => $quotaData->monthly->total, 'onetimeTotal' => $quotaData->onetime->remaining ));
|
364 |
$notice = Notices::addNormal($message);
|
365 |
-
Notices::makePersistent($notice, self::MSG_UPGRADE_MONTH, YEAR_IN_SECONDS);
|
366 |
}
|
367 |
}
|
368 |
}
|
@@ -374,7 +384,7 @@ class AdminNoticesController extends \ShortPixel\Controller
|
|
374 |
{
|
375 |
$message = $this->getQuotaExceededMessage();
|
376 |
$notice = Notices::addError($message);
|
377 |
-
Notices::makePersistent($notice, self::MSG_QUOTA_REACHED, WEEK_IN_SECONDS);
|
378 |
}
|
379 |
|
380 |
Notices::removeNoticeByID(self::MSG_UPGRADE_MONTH); // get rid of doubles. reset
|
@@ -538,6 +548,7 @@ class AdminNoticesController extends \ShortPixel\Controller
|
|
538 |
return $message;
|
539 |
}
|
540 |
|
|
|
541 |
protected function getBulkUpgradeMessage($extra)
|
542 |
{
|
543 |
$message = '<p>' . sprintf(__("You currently have <strong>%d images and thumbnails to optimize</strong> but you only have <strong>%d images</strong> available in your current plan."
|
@@ -546,13 +557,12 @@ class AdminNoticesController extends \ShortPixel\Controller
|
|
546 |
$this->proposeUpgradePopup();
|
547 |
return $message;
|
548 |
}
|
549 |
-
|
550 |
protected function getMonthlyUpgradeMessage($extra)
|
551 |
{
|
552 |
$message = '<p>' . sprintf(__("You are adding an average of <strong>%d images and thumbnails every month</strong> to your Media Library and you have <strong>a plan of %d images/month (and %d one-time images)</strong>.%s"
|
553 |
. " You might need to upgrade your plan in order to have all your images optimized.", 'shortpixel-image-optimiser'), $extra['monthAvg'], $extra['monthlyQuota'], $extra['onetimeTotal'], '<br>') . '</p>';
|
554 |
$message .= ' <button class="button button-primary" id="shortpixel-upgrade-advice" onclick="ShortPixel.proposeUpgrade()" style="margin-right:10px;"><strong>' . __('Show me the best available options', 'shortpixel-image-optimiser') . '</strong></button>';
|
555 |
-
$this->proposeUpgradePopup();
|
556 |
return $message;
|
557 |
}
|
558 |
|
@@ -623,12 +633,10 @@ class AdminNoticesController extends \ShortPixel\Controller
|
|
623 |
</div>';
|
624 |
|
625 |
$message .= '</div>'; /// closing div
|
626 |
-
$this->proposeUpgradePopup();
|
627 |
return $message;
|
628 |
}
|
629 |
|
630 |
-
|
631 |
-
// @todo LoadView Snippet here.
|
632 |
$view = new ViewController();
|
633 |
$view->loadView('snippets/part-upgrade-options');
|
634 |
}
|
@@ -722,8 +730,6 @@ class AdminNoticesController extends \ShortPixel\Controller
|
|
722 |
|
723 |
protected function monthlyUpgradeNeeded($quotaData)
|
724 |
{
|
725 |
-
|
726 |
-
|
727 |
if (isset($quotaData->monthly->total))
|
728 |
{
|
729 |
$monthAvg = $this->getMonthAvg($quotaData);
|
@@ -752,7 +758,7 @@ class AdminNoticesController extends \ShortPixel\Controller
|
|
752 |
|
753 |
protected function getMonthAvg() {
|
754 |
$stats = StatsController::getInstance();
|
755 |
-
|
756 |
// Count how many months have some optimized images.
|
757 |
for($i = 4, $count = 0; $i>=1; $i--) {
|
758 |
if($count == 0 && $stats->find('period', 'months', $i) == 0)
|
44 |
private $remote_message_endpoint = 'https://api.shortpixel.com/v2/notices.php';
|
45 |
private $remote_readme_endpoint = 'https://plugins.svn.wordpress.org/shortpixel-image-optimiser/trunk/readme.txt';
|
46 |
|
47 |
+
|
48 |
public function __construct()
|
49 |
{
|
50 |
add_action('admin_notices', array($this, 'displayNotices'), 50); // notices occured before page load
|
291 |
// Called by MediaLibraryModel
|
292 |
public function invokeLegacyNotice()
|
293 |
{
|
294 |
+
$noticeController = Notices::getInstance();
|
295 |
+
|
296 |
+
$notice = $noticeController->getNoticeByID(self::MSG_CONVERT_LEGACY);
|
297 |
+
Log::addTemp('Legacy Notice', $notice);
|
298 |
+
// If already in system, don't bother doing it again.
|
299 |
+
if ($notice !== false)
|
300 |
+
return;
|
301 |
+
|
302 |
+
$message = '<p><strong>' . __('ShortPixel found items in media library with a legacy optimization format!', 'shortpixel-image-optimiser') . '</strong></p>';
|
303 |
|
304 |
$message .= '<p>' . __('Prior to version 5.0, a different format was used to store ShortPixel optimization information. ShortPixel automatically migrates the media library items to the new format when they are opened. %s Please check if your images contain the optimization information after the migration. %s Read more %s', 'shortpixel-image-optimiser') . '</p>';
|
305 |
|
306 |
+
$message .= '<p>' . __('It is recommended to migrate all items to the modern format by clicking on the button below.', 'shortpixel-image-optimser') . '</p>';
|
307 |
$message .= '<p><a href="%s" class="button button-primary">%s</a></p>';
|
308 |
|
309 |
$read_link = esc_url('https://shortpixel.com/knowledge-base/article/539-spio-5-tells-me-to-convert-legacy-data-what-is-this');
|
337 |
$noticeController = Notices::getInstance();
|
338 |
$statsControl = StatsController::getInstance(); // @todo Implement this. (Figure out what this was )
|
339 |
|
340 |
+
$callback = array(AdminNoticesController::getInstance(), 'proposeUpgradePopup');
|
341 |
|
342 |
if (! \wpSPIO()->settings()->verifiedKey)
|
343 |
{
|
372 |
//looks like the user hasn't got enough credits to process the monthly images, display a notice telling this
|
373 |
$message = $this->getMonthlyUpgradeMessage(array('monthAvg' => $this->getMonthAvg(), 'monthlyQuota' => $quotaData->monthly->total, 'onetimeTotal' => $quotaData->onetime->remaining ));
|
374 |
$notice = Notices::addNormal($message);
|
375 |
+
Notices::makePersistent($notice, self::MSG_UPGRADE_MONTH, YEAR_IN_SECONDS, $callback);
|
376 |
}
|
377 |
}
|
378 |
}
|
384 |
{
|
385 |
$message = $this->getQuotaExceededMessage();
|
386 |
$notice = Notices::addError($message);
|
387 |
+
Notices::makePersistent($notice, self::MSG_QUOTA_REACHED, WEEK_IN_SECONDS, $callback);
|
388 |
}
|
389 |
|
390 |
Notices::removeNoticeByID(self::MSG_UPGRADE_MONTH); // get rid of doubles. reset
|
548 |
return $message;
|
549 |
}
|
550 |
|
551 |
+
/* Seems unused @todo Remove in a few versions
|
552 |
protected function getBulkUpgradeMessage($extra)
|
553 |
{
|
554 |
$message = '<p>' . sprintf(__("You currently have <strong>%d images and thumbnails to optimize</strong> but you only have <strong>%d images</strong> available in your current plan."
|
557 |
$this->proposeUpgradePopup();
|
558 |
return $message;
|
559 |
}
|
560 |
+
*/
|
561 |
protected function getMonthlyUpgradeMessage($extra)
|
562 |
{
|
563 |
$message = '<p>' . sprintf(__("You are adding an average of <strong>%d images and thumbnails every month</strong> to your Media Library and you have <strong>a plan of %d images/month (and %d one-time images)</strong>.%s"
|
564 |
. " You might need to upgrade your plan in order to have all your images optimized.", 'shortpixel-image-optimiser'), $extra['monthAvg'], $extra['monthlyQuota'], $extra['onetimeTotal'], '<br>') . '</p>';
|
565 |
$message .= ' <button class="button button-primary" id="shortpixel-upgrade-advice" onclick="ShortPixel.proposeUpgrade()" style="margin-right:10px;"><strong>' . __('Show me the best available options', 'shortpixel-image-optimiser') . '</strong></button>';
|
|
|
566 |
return $message;
|
567 |
}
|
568 |
|
633 |
</div>';
|
634 |
|
635 |
$message .= '</div>'; /// closing div
|
|
|
636 |
return $message;
|
637 |
}
|
638 |
|
639 |
+
public function proposeUpgradePopup() {
|
|
|
640 |
$view = new ViewController();
|
641 |
$view->loadView('snippets/part-upgrade-options');
|
642 |
}
|
730 |
|
731 |
protected function monthlyUpgradeNeeded($quotaData)
|
732 |
{
|
|
|
|
|
733 |
if (isset($quotaData->monthly->total))
|
734 |
{
|
735 |
$monthAvg = $this->getMonthAvg($quotaData);
|
758 |
|
759 |
protected function getMonthAvg() {
|
760 |
$stats = StatsController::getInstance();
|
761 |
+
|
762 |
// Count how many months have some optimized images.
|
763 |
for($i = 4, $count = 0; $i>=1; $i--) {
|
764 |
if($count == 0 && $stats->find('period', 'months', $i) == 0)
|
@@ -157,11 +157,6 @@ class AjaxController
|
|
157 |
$this->checkProcessorKey();
|
158 |
|
159 |
|
160 |
-
if ($this->getProcessorKey() == 'shortpixel-test')
|
161 |
-
{
|
162 |
-
$this->returnTestData();
|
163 |
-
}
|
164 |
-
|
165 |
// Notice that POST variables are always string, so 'true', not true.
|
166 |
// phpcs:ignore -- Nonce is checked
|
167 |
$isBulk = (isset($_POST['isBulk']) && $_POST['isBulk'] === 'true') ? true : false;
|
@@ -498,7 +493,7 @@ class AjaxController
|
|
498 |
|
499 |
// $this->ajax_getItemView();
|
500 |
|
501 |
-
// Changed since updated function should detect what is what.
|
502 |
// $mediaItem->deleteMeta(); // also does reset prevent.
|
503 |
// delete_post_meta($id, '_shortpixel_was_converted');
|
504 |
|
@@ -732,16 +727,6 @@ class AjaxController
|
|
732 |
exit();
|
733 |
}
|
734 |
|
735 |
-
private function returnTestData()
|
736 |
-
{
|
737 |
-
$is_error = rand(1, 10);
|
738 |
-
$path = \wpSPIO()->plugin_path('tests/jsonresults/');
|
739 |
-
$json = file_get_contents($path . 'error.json');
|
740 |
-
$json = json_decode($json);
|
741 |
-
wp_send_json($json);
|
742 |
-
|
743 |
-
|
744 |
-
}
|
745 |
|
746 |
private function removeAllData($json, $data)
|
747 |
{
|
157 |
$this->checkProcessorKey();
|
158 |
|
159 |
|
|
|
|
|
|
|
|
|
|
|
160 |
// Notice that POST variables are always string, so 'true', not true.
|
161 |
// phpcs:ignore -- Nonce is checked
|
162 |
$isBulk = (isset($_POST['isBulk']) && $_POST['isBulk'] === 'true') ? true : false;
|
493 |
|
494 |
// $this->ajax_getItemView();
|
495 |
|
496 |
+
// Changed since updated function should detect what is what.
|
497 |
// $mediaItem->deleteMeta(); // also does reset prevent.
|
498 |
// delete_post_meta($id, '_shortpixel_was_converted');
|
499 |
|
727 |
exit();
|
728 |
}
|
729 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
730 |
|
731 |
private function removeAllData($json, $data)
|
732 |
{
|
@@ -66,7 +66,7 @@ class ApiController
|
|
66 |
*/
|
67 |
public function processMediaItem($item, $imageObj)
|
68 |
{
|
69 |
-
if (! $imageObj->isProcessable())
|
70 |
{
|
71 |
if ($imageObj->isOptimized())
|
72 |
{
|
66 |
*/
|
67 |
public function processMediaItem($item, $imageObj)
|
68 |
{
|
69 |
+
if (! $imageObj->isProcessable() || $imageObj->isOptimizePrevented() == true)
|
70 |
{
|
71 |
if ($imageObj->isOptimized())
|
72 |
{
|
@@ -36,8 +36,19 @@ class BulkController
|
|
36 |
$optimizeController = new OptimizeController();
|
37 |
$optimizeController->setBulk(true);
|
38 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
39 |
$Q = $optimizeController->getQueue($type);
|
40 |
|
|
|
41 |
$Q->createNewBulk(array());
|
42 |
|
43 |
if (! is_null($customOp))
|
@@ -105,7 +116,7 @@ class BulkController
|
|
105 |
$q->startBulk();
|
106 |
}
|
107 |
|
108 |
-
return $optimizeControl->processQueue(
|
109 |
}
|
110 |
|
111 |
public function finishBulk($type = 'media')
|
36 |
$optimizeController = new OptimizeController();
|
37 |
$optimizeController->setBulk(true);
|
38 |
|
39 |
+
$fs = \wpSPIO()->filesystem();
|
40 |
+
$backupDir = $fs->getDirectory(SHORTPIXEL_BACKUP_FOLDER);
|
41 |
+
$current_log = $fs->getFile($backupDir->getPath() . 'current_bulk_' . $type . '.log');
|
42 |
+
|
43 |
+
// When starting new bulk remove any open 'current logs';
|
44 |
+
if ($current_log->exists() && $current_log->is_writable())
|
45 |
+
{
|
46 |
+
$current_log->delete();
|
47 |
+
}
|
48 |
+
|
49 |
$Q = $optimizeController->getQueue($type);
|
50 |
|
51 |
+
|
52 |
$Q->createNewBulk(array());
|
53 |
|
54 |
if (! is_null($customOp))
|
116 |
$q->startBulk();
|
117 |
}
|
118 |
|
119 |
+
return $optimizeControl->processQueue($types);
|
120 |
}
|
121 |
|
122 |
public function finishBulk($type = 'media')
|
@@ -265,7 +265,16 @@ Class FileSystemController extends \ShortPixel\Controller
|
|
265 |
// This is used by getting preview path ( backup pathToUrl) in bulk and for comparer..
|
266 |
elseif ($is_multi_site && ! $is_main_site && 0 === strpos($filepath, dirname(dirname($uploads['basedir']))) )
|
267 |
{
|
|
|
268 |
$url = str_replace( dirname(dirname($uploads['basedir'])), dirname(dirname($uploads['baseurl'])), $filepath );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
269 |
|
270 |
} elseif ( false !== strpos( $filepath, 'wp-content/uploads' ) ) {
|
271 |
// Get the directory name relative to the basedir (back compat for pre-2.7 uploads)
|
265 |
// This is used by getting preview path ( backup pathToUrl) in bulk and for comparer..
|
266 |
elseif ($is_multi_site && ! $is_main_site && 0 === strpos($filepath, dirname(dirname($uploads['basedir']))) )
|
267 |
{
|
268 |
+
|
269 |
$url = str_replace( dirname(dirname($uploads['basedir'])), dirname(dirname($uploads['baseurl'])), $filepath );
|
270 |
+
$homeUrl = home_url();
|
271 |
+
|
272 |
+
// The result didn't end in a full URL because URL might have less subdirs ( dirname dirname) .
|
273 |
+
// This happens when site has blogs.dir (sigh) on a subdomain . Try to substitue the ABSPATH root with the home_url
|
274 |
+
if (strpos($url, $homeUrl) === false)
|
275 |
+
{
|
276 |
+
$url = str_replace( trailingslashit(ABSPATH), trailingslashit($homeUrl), $filepath);
|
277 |
+
}
|
278 |
|
279 |
} elseif ( false !== strpos( $filepath, 'wp-content/uploads' ) ) {
|
280 |
// Get the directory name relative to the basedir (back compat for pre-2.7 uploads)
|
@@ -150,21 +150,23 @@ class OptimizeController
|
|
150 |
return $json;
|
151 |
}
|
152 |
|
153 |
-
/** Check if item is in queue.
|
154 |
* @param Object $mediaItem
|
155 |
*/
|
156 |
public function isItemInQueue($mediaItem)
|
157 |
{
|
|
|
|
|
|
|
158 |
$type = $mediaItem->get('type');
|
159 |
-
$q = $this->getQueue($type);
|
160 |
|
161 |
-
|
162 |
|
163 |
-
|
164 |
-
return true;
|
165 |
-
else
|
166 |
-
return false;
|
167 |
|
|
|
|
|
|
|
168 |
}
|
169 |
|
170 |
/** Restores an item
|
@@ -179,6 +181,8 @@ class OptimizeController
|
|
179 |
$json->status = 0;
|
180 |
$json->result = new \stdClass;
|
181 |
|
|
|
|
|
182 |
if (! is_object($mediaItem)) // something wrong
|
183 |
{
|
184 |
|
@@ -189,13 +193,21 @@ class OptimizeController
|
|
189 |
$json->result->is_done = true;
|
190 |
$json->result->is_error = true;
|
191 |
|
192 |
-
ResponseController::addData($
|
|
|
|
|
193 |
|
194 |
-
Log::addWarn('Item with id ' . $
|
195 |
|
196 |
return $json;
|
197 |
}
|
198 |
|
|
|
|
|
|
|
|
|
|
|
|
|
199 |
$item_id = $mediaItem->get('id');
|
200 |
|
201 |
$json->result->item_id = $item_id;
|
@@ -209,7 +221,7 @@ class OptimizeController
|
|
209 |
else
|
210 |
{
|
211 |
$result = false;
|
212 |
-
$json->result->message = $mediaItem->getReason('restorable');
|
213 |
}
|
214 |
|
215 |
// Compat for ancient WP
|
@@ -238,10 +250,8 @@ class OptimizeController
|
|
238 |
else
|
239 |
{
|
240 |
|
241 |
-
|
242 |
-
|
243 |
-
$json->result->message = __('Item is not restorable', 'shortpixel-image-optimiser');
|
244 |
-
}
|
245 |
$json->result->is_done = true;
|
246 |
$json->fileStatus = ImageModel::FILE_STATUS_ERROR;
|
247 |
$json->result->is_error = true;
|
@@ -308,8 +318,8 @@ class OptimizeController
|
|
308 |
*/
|
309 |
public function processQueue($queueTypes = array())
|
310 |
{
|
311 |
-
|
312 |
$keyControl = ApiKeyController::getInstance();
|
|
|
313 |
if ($keyControl->keyIsVerified() === false)
|
314 |
{
|
315 |
$json = $this->getJsonResponse();
|
@@ -323,11 +333,28 @@ class OptimizeController
|
|
323 |
$quotaControl = QuotaController::getInstance();
|
324 |
if ($quotaControl->hasQuota() === false)
|
325 |
{
|
326 |
-
|
327 |
-
|
328 |
-
|
329 |
-
|
330 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
331 |
}
|
332 |
|
333 |
// @todo Here prevent bulk from running when running flag is off
|
@@ -495,7 +522,8 @@ class OptimizeController
|
|
495 |
}
|
496 |
else
|
497 |
{
|
498 |
-
|
|
|
499 |
ResponseController::addData($item->item_id, 'fileName', $imageItem->getFileName());
|
500 |
}
|
501 |
|
@@ -614,9 +642,6 @@ class OptimizeController
|
|
614 |
$item->result->optimized = $fs->pathToUrl($showItem);
|
615 |
}
|
616 |
|
617 |
-
|
618 |
-
|
619 |
-
|
620 |
}
|
621 |
// This was not a request process, just handle it and mark it as done.
|
622 |
elseif ($result->apiStatus == ApiController::STATUS_NOT_API)
|
150 |
return $json;
|
151 |
}
|
152 |
|
153 |
+
/** Check if item is in queue. || Only checks the single queue!
|
154 |
* @param Object $mediaItem
|
155 |
*/
|
156 |
public function isItemInQueue($mediaItem)
|
157 |
{
|
158 |
+
if (! is_null($mediaItem->is_in_queue))
|
159 |
+
return $mediaItem->is_in_queue;
|
160 |
+
|
161 |
$type = $mediaItem->get('type');
|
|
|
162 |
|
163 |
+
$q = $this->getQueue($type);
|
164 |
|
165 |
+
$bool = $q->isItemInQueue($mediaItem->get('id'));
|
|
|
|
|
|
|
166 |
|
167 |
+
// Preventing double queries here
|
168 |
+
$mediaItem->is_in_queue = $bool;
|
169 |
+
return $bool;
|
170 |
}
|
171 |
|
172 |
/** Restores an item
|
181 |
$json->status = 0;
|
182 |
$json->result = new \stdClass;
|
183 |
|
184 |
+
$item_id = $mediaItem->get('id');
|
185 |
+
|
186 |
if (! is_object($mediaItem)) // something wrong
|
187 |
{
|
188 |
|
193 |
$json->result->is_done = true;
|
194 |
$json->result->is_error = true;
|
195 |
|
196 |
+
ResponseController::addData($item_id, 'is_error', true);
|
197 |
+
ResponseController::addData($item_id, 'is_done', true);
|
198 |
+
ResponseController::addData($item_id, 'message', $item->result->message);
|
199 |
|
200 |
+
Log::addWarn('Item with id ' . $item_id . ' is not restorable,');
|
201 |
|
202 |
return $json;
|
203 |
}
|
204 |
|
205 |
+
$data = array(
|
206 |
+
'item_type' => $mediaItem->get('type'),
|
207 |
+
'fileName' => $mediaItem->getFileName(),
|
208 |
+
);
|
209 |
+
ResponseController::addData($item_id, $data);
|
210 |
+
|
211 |
$item_id = $mediaItem->get('id');
|
212 |
|
213 |
$json->result->item_id = $item_id;
|
221 |
else
|
222 |
{
|
223 |
$result = false;
|
224 |
+
$json->result->message = ResponseController::formatItem($mediaItem->get('id')); // $mediaItem->getReason('restorable');
|
225 |
}
|
226 |
|
227 |
// Compat for ancient WP
|
250 |
else
|
251 |
{
|
252 |
|
253 |
+
$json->result->message = ResponseController::formatItem($mediaItem->get('id'));
|
254 |
+
|
|
|
|
|
255 |
$json->result->is_done = true;
|
256 |
$json->fileStatus = ImageModel::FILE_STATUS_ERROR;
|
257 |
$json->result->is_error = true;
|
318 |
*/
|
319 |
public function processQueue($queueTypes = array())
|
320 |
{
|
|
|
321 |
$keyControl = ApiKeyController::getInstance();
|
322 |
+
|
323 |
if ($keyControl->keyIsVerified() === false)
|
324 |
{
|
325 |
$json = $this->getJsonResponse();
|
333 |
$quotaControl = QuotaController::getInstance();
|
334 |
if ($quotaControl->hasQuota() === false)
|
335 |
{
|
336 |
+
// If we are doing something special (restore, migrate etc), it should runs without credits, so we shouldn't be using any.
|
337 |
+
$isCustomOperation = false;
|
338 |
+
foreach($queueTypes as $qType)
|
339 |
+
{
|
340 |
+
$queue = $this->getQueue($qType);
|
341 |
+
if ($queue && true === $queue->isCustomOperation())
|
342 |
+
{
|
343 |
+
$isCustomOperation = true;
|
344 |
+
break;
|
345 |
+
}
|
346 |
+
}
|
347 |
+
|
348 |
+
// Break out of quota if we are on normal operations.
|
349 |
+
if (false === $isCustomOperation )
|
350 |
+
{
|
351 |
+
$quotaControl->forceCheckRemoteQuota(); // on next load check if something happenend when out and asking.
|
352 |
+
$json = $this->getJsonResponse();
|
353 |
+
$json->error = AjaxController::NOQUOTA;
|
354 |
+
$json->status = false;
|
355 |
+
$json->message = __('Quota Exceeded','shortpixel-image-optimiser');
|
356 |
+
return $json;
|
357 |
+
}
|
358 |
}
|
359 |
|
360 |
// @todo Here prevent bulk from running when running flag is off
|
522 |
}
|
523 |
else
|
524 |
{
|
525 |
+
//$item->result->filename = $imageItem->getFileName();
|
526 |
+
// Used in WP-CLI
|
527 |
ResponseController::addData($item->item_id, 'fileName', $imageItem->getFileName());
|
528 |
}
|
529 |
|
642 |
$item->result->optimized = $fs->pathToUrl($showItem);
|
643 |
}
|
644 |
|
|
|
|
|
|
|
645 |
}
|
646 |
// This was not a request process, just handle it and mark it as done.
|
647 |
elseif ($result->apiStatus == ApiController::STATUS_NOT_API)
|
@@ -29,13 +29,6 @@ abstract class Queue
|
|
29 |
const RESULT_UNKNOWN = -10;
|
30 |
|
31 |
|
32 |
-
/* Result status (per item) to communicate back to frontend */
|
33 |
-
/* const FILE_NOTEXISTS = -1;
|
34 |
-
const FILE_ALREADYOPTIMIZED = -2;
|
35 |
-
const FILE_OK = 1;
|
36 |
-
const FILE_SUCCESS = 2;
|
37 |
-
const FILE_WAIT = 3; */
|
38 |
-
|
39 |
abstract protected function prepare();
|
40 |
abstract public function getType();
|
41 |
|
@@ -328,6 +321,8 @@ abstract class Queue
|
|
328 |
$stats->is_finished = (bool) $this->getStatus('finished');
|
329 |
$stats->in_queue = (int) $this->getStatus('items');
|
330 |
$stats->in_process = (int) $this->getStatus('in_process');
|
|
|
|
|
331 |
$stats->errors = (int) $this->getStatus('errors');
|
332 |
$stats->fatal_errors = (int) $this->getStatus('fatal_errors');
|
333 |
$stats->done = (int) $this->getStatus('done');
|
@@ -373,7 +368,6 @@ abstract class Queue
|
|
373 |
$count->images_basecount = $customData->baseCount;
|
374 |
}
|
375 |
|
376 |
-
|
377 |
return $count;
|
378 |
}
|
379 |
|
@@ -407,6 +401,17 @@ abstract class Queue
|
|
407 |
$this->getShortQ()->setStatus('custom_data', $customData);
|
408 |
}
|
409 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
410 |
public function getCustomDataItem($name)
|
411 |
{
|
412 |
$customData = $this->getStatus('custom_data');
|
@@ -603,6 +608,18 @@ abstract class Queue
|
|
603 |
|
604 |
}
|
605 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
606 |
public function itemFailed($item, $fatal = false)
|
607 |
{
|
608 |
if ($fatal)
|
29 |
const RESULT_UNKNOWN = -10;
|
30 |
|
31 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
32 |
abstract protected function prepare();
|
33 |
abstract public function getType();
|
34 |
|
321 |
$stats->is_finished = (bool) $this->getStatus('finished');
|
322 |
$stats->in_queue = (int) $this->getStatus('items');
|
323 |
$stats->in_process = (int) $this->getStatus('in_process');
|
324 |
+
$stats->awaiting = $stats->in_queue + $stats->in_process; // calculation used for WP-CLI.
|
325 |
+
|
326 |
$stats->errors = (int) $this->getStatus('errors');
|
327 |
$stats->fatal_errors = (int) $this->getStatus('fatal_errors');
|
328 |
$stats->done = (int) $this->getStatus('done');
|
368 |
$count->images_basecount = $customData->baseCount;
|
369 |
}
|
370 |
|
|
|
371 |
return $count;
|
372 |
}
|
373 |
|
401 |
$this->getShortQ()->setStatus('custom_data', $customData);
|
402 |
}
|
403 |
|
404 |
+
// Return if this queue has any special operation outside of normal optimizing.
|
405 |
+
// Use to give the go processing when out of credits (ie)
|
406 |
+
public function isCustomOperation()
|
407 |
+
{
|
408 |
+
if ($this->getCustomDataItem('customOperation'))
|
409 |
+
{
|
410 |
+
return true;
|
411 |
+
}
|
412 |
+
return false;
|
413 |
+
}
|
414 |
+
|
415 |
public function getCustomDataItem($name)
|
416 |
{
|
417 |
$customData = $this->getStatus('custom_data');
|
608 |
|
609 |
}
|
610 |
|
611 |
+
// Check if item is in queue. Considered not in queue if status is done.
|
612 |
+
public function isItemInQueue($item_id)
|
613 |
+
{
|
614 |
+
$itemObj = $this->q->getItem($item_id);
|
615 |
+
|
616 |
+
if (is_object($itemObj) && intval($itemObj->status) <> ShortQ::QSTATUS_DONE)
|
617 |
+
{
|
618 |
+
return true;
|
619 |
+
}
|
620 |
+
return false;
|
621 |
+
}
|
622 |
+
|
623 |
public function itemFailed($item, $fatal = false)
|
624 |
{
|
625 |
if ($fatal)
|
@@ -76,7 +76,7 @@ class QuotaController
|
|
76 |
|
77 |
$quota = (object) [
|
78 |
'monthly' => (object) [
|
79 |
-
'text' =>
|
80 |
'total' => $quotaData['APICallsQuotaNumeric'],
|
81 |
'consumed' => $quotaData['APICallsMadeNumeric'],
|
82 |
'remaining' => max($quotaData['APICallsQuotaNumeric'] - $quotaData['APICallsMadeNumeric'], 0),
|
@@ -302,10 +302,10 @@ class QuotaController
|
|
302 |
|
303 |
$dataArray = array(
|
304 |
"APIKeyValid" => true,
|
305 |
-
"APICallsMade" => number_format($data->APICallsMade) . __('
|
306 |
-
"APICallsQuota" => number_format($data->APICallsQuota) . __('
|
307 |
-
"APICallsMadeOneTime" => number_format($data->APICallsMadeOneTime) . __('
|
308 |
-
"APICallsQuotaOneTime" => number_format($data->APICallsQuotaOneTime) . __('
|
309 |
"APICallsMadeNumeric" => (int) max($data->APICallsMade, 0),
|
310 |
"APICallsQuotaNumeric" => (int) max($data->APICallsQuota, 0),
|
311 |
"APICallsMadeOneTimeNumeric" => (int) max($data->APICallsMadeOneTime, 0),
|
76 |
|
77 |
$quota = (object) [
|
78 |
'monthly' => (object) [
|
79 |
+
'text' => sprintf(__('%s/month', 'shortpixel-image-optimiser'), $quotaData['APICallsQuota']),
|
80 |
'total' => $quotaData['APICallsQuotaNumeric'],
|
81 |
'consumed' => $quotaData['APICallsMadeNumeric'],
|
82 |
'remaining' => max($quotaData['APICallsQuotaNumeric'] - $quotaData['APICallsMadeNumeric'], 0),
|
302 |
|
303 |
$dataArray = array(
|
304 |
"APIKeyValid" => true,
|
305 |
+
"APICallsMade" => number_format($data->APICallsMade) . __(' credits','shortpixel-image-optimiser'),
|
306 |
+
"APICallsQuota" => number_format($data->APICallsQuota) . __(' credits','shortpixel-image-optimiser'),
|
307 |
+
"APICallsMadeOneTime" => number_format($data->APICallsMadeOneTime) . __(' credits','shortpixel-image-optimiser'),
|
308 |
+
"APICallsQuotaOneTime" => number_format($data->APICallsQuotaOneTime) . __(' credits','shortpixel-image-optimiser'),
|
309 |
"APICallsMadeNumeric" => (int) max($data->APICallsMade, 0),
|
310 |
"APICallsQuotaNumeric" => (int) max($data->APICallsQuota, 0),
|
311 |
"APICallsMadeOneTimeNumeric" => (int) max($data->APICallsMadeOneTime, 0),
|
@@ -5,6 +5,7 @@ use ShortPixel\ShortpixelLogger\ShortPixelLogger as Log;
|
|
5 |
use ShortPixel\Model\ResponseModel as ResponseModel;
|
6 |
use ShortPixel\Model\Image\ImageModel as ImageModel;
|
7 |
|
|
|
8 |
class ResponseController
|
9 |
{
|
10 |
|
@@ -31,8 +32,9 @@ class ResponseController
|
|
31 |
const OUTPUT_CLI = 3; // Has no context, needs more information
|
32 |
|
33 |
|
34 |
-
/**
|
35 |
* @param Object QueueObject being used.
|
|
|
36 |
*/
|
37 |
public static function setQ($q)
|
38 |
{
|
@@ -56,14 +58,17 @@ class ResponseController
|
|
56 |
|
57 |
public static function getResponseItem($item_id)
|
58 |
{
|
59 |
-
|
60 |
-
|
61 |
$itemType = "Unknown";
|
|
|
|
|
|
|
|
|
62 |
|
63 |
if (isset(self::$items[$itemType][$item_id]))
|
64 |
{
|
65 |
$item = self::$items[$itemType][$item_id];
|
66 |
-
|
67 |
}
|
68 |
else {
|
69 |
$item = new ResponseModel($item_id, $itemType);
|
@@ -74,7 +79,7 @@ class ResponseController
|
|
74 |
|
75 |
protected static function updateResponseItem($item)
|
76 |
{
|
77 |
-
$itemType =
|
78 |
self::$items[$itemType][$item->item_id] = $item;
|
79 |
}
|
80 |
|
@@ -90,6 +95,14 @@ class ResponseController
|
|
90 |
$data = $name;
|
91 |
}
|
92 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
93 |
$resp = self::getResponseItem($item_id); // responseModel
|
94 |
|
95 |
foreach($data as $prop => $val)
|
@@ -137,6 +150,14 @@ class ResponseController
|
|
137 |
break;
|
138 |
}
|
139 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
140 |
if (self::$screenOutput == self::OUTPUT_CLI)
|
141 |
{
|
142 |
$text = '(' . self::$queueName . ' : ' . $item->fileName . ') ' . $text . ' ';
|
5 |
use ShortPixel\Model\ResponseModel as ResponseModel;
|
6 |
use ShortPixel\Model\Image\ImageModel as ImageModel;
|
7 |
|
8 |
+
|
9 |
class ResponseController
|
10 |
{
|
11 |
|
32 |
const OUTPUT_CLI = 3; // Has no context, needs more information
|
33 |
|
34 |
|
35 |
+
/** Correlates type of item with the queue being used. Be aware that usage *outside* the queue system needs to manually set type
|
36 |
* @param Object QueueObject being used.
|
37 |
+
*
|
38 |
*/
|
39 |
public static function setQ($q)
|
40 |
{
|
58 |
|
59 |
public static function getResponseItem($item_id)
|
60 |
{
|
61 |
+
if (is_null(self::$queueType)) // fail-safe
|
62 |
+
{
|
63 |
$itemType = "Unknown";
|
64 |
+
}
|
65 |
+
else {
|
66 |
+
$itemType = self::$queueType;
|
67 |
+
}
|
68 |
|
69 |
if (isset(self::$items[$itemType][$item_id]))
|
70 |
{
|
71 |
$item = self::$items[$itemType][$item_id];
|
|
|
72 |
}
|
73 |
else {
|
74 |
$item = new ResponseModel($item_id, $itemType);
|
79 |
|
80 |
protected static function updateResponseItem($item)
|
81 |
{
|
82 |
+
$itemType = $item->item_type;
|
83 |
self::$items[$itemType][$item->item_id] = $item;
|
84 |
}
|
85 |
|
95 |
$data = $name;
|
96 |
}
|
97 |
|
98 |
+
|
99 |
+
$item_type = (array_key_exists('item_type', $data)) ? $data['item_type'] : false;
|
100 |
+
// If no queue / queue type is set, set it if item type is passed to ResponseController. For items outside the queue system.
|
101 |
+
if ($item_type && is_null(self::$queueType))
|
102 |
+
{
|
103 |
+
self::$queueType = $item_type;
|
104 |
+
}
|
105 |
+
|
106 |
$resp = self::getResponseItem($item_id); // responseModel
|
107 |
|
108 |
foreach($data as $prop => $val)
|
150 |
break;
|
151 |
}
|
152 |
|
153 |
+
switch($item->apiStatus)
|
154 |
+
{
|
155 |
+
case ApiController::STATUS_FAIL:
|
156 |
+
$text .= sprintf(__('( %s %d ) ', 'shortpixel-image-optimizer'), (strtolower($item->item_type) == 'media') ? __('Attachment ID ') : __('Custom Type '), $item->item_id);
|
157 |
+
break;
|
158 |
+
}
|
159 |
+
|
160 |
+
|
161 |
if (self::$screenOutput == self::OUTPUT_CLI)
|
162 |
{
|
163 |
$text = '(' . self::$queueName . ' : ' . $item->fileName . ') ' . $text . ' ';
|
@@ -481,6 +481,7 @@ class SettingsController extends \ShortPixel\ViewController
|
|
481 |
|
482 |
protected function loadStatistics()
|
483 |
{
|
|
|
484 |
$statsControl = StatsController::getInstance();
|
485 |
$stats = new \stdClass;
|
486 |
|
@@ -496,7 +497,7 @@ class SettingsController extends \ShortPixel\ViewController
|
|
496 |
|
497 |
|
498 |
$this->view->stats = $stats;
|
499 |
-
|
500 |
}
|
501 |
|
502 |
/** @todo Remove this check in Version 5.1 including all data on the old CF token */
|
481 |
|
482 |
protected function loadStatistics()
|
483 |
{
|
484 |
+
/*
|
485 |
$statsControl = StatsController::getInstance();
|
486 |
$stats = new \stdClass;
|
487 |
|
497 |
|
498 |
|
499 |
$this->view->stats = $stats;
|
500 |
+
*/
|
501 |
}
|
502 |
|
503 |
/** @todo Remove this check in Version 5.1 including all data on the old CF token */
|
@@ -103,10 +103,13 @@ class BulkViewController extends \ShortPixel\ViewController
|
|
103 |
|
104 |
$approx->total->images = $approx->media->total + $approx->custom->images; // $sc->totalImagesToOptimize();
|
105 |
|
|
|
|
|
106 |
// Prevent any guesses to go below zero.
|
107 |
foreach($approx->media as $item => $value)
|
108 |
{
|
109 |
-
|
|
|
110 |
}
|
111 |
return $approx;
|
112 |
|
103 |
|
104 |
$approx->total->images = $approx->media->total + $approx->custom->images; // $sc->totalImagesToOptimize();
|
105 |
|
106 |
+
$approx->media->isLimited = $sc->find('media', 'isLimited');
|
107 |
+
|
108 |
// Prevent any guesses to go below zero.
|
109 |
foreach($approx->media as $item => $value)
|
110 |
{
|
111 |
+
if (is_numeric($value))
|
112 |
+
$approx->media->$item = max($value, 0);
|
113 |
}
|
114 |
return $approx;
|
115 |
|
@@ -68,6 +68,7 @@ class EditMediaViewController extends \ShortPixel\ViewController
|
|
68 |
return false;
|
69 |
}
|
70 |
|
|
|
71 |
$this->view->status_message = null;
|
72 |
|
73 |
$this->view->text = UiHelper::getStatusText($this->imageModel);
|
@@ -259,7 +260,7 @@ class EditMediaViewController extends \ShortPixel\ViewController
|
|
259 |
$url = $thumbObj->getURL(); //$fs->pathToURL($thumbObj); //wp_get_attachment_image_src($this->post_id, $size);
|
260 |
$filename = $thumbObj->getFullPath();
|
261 |
$backup = $thumbObj->hasBackup() ? $thumbObj->getBackupFile()->getFullPath() : 'n/a';
|
262 |
-
|
263 |
$width = $thumbObj->get('width');
|
264 |
$height = $thumbObj->get('height');
|
265 |
|
68 |
return false;
|
69 |
}
|
70 |
|
71 |
+
|
72 |
$this->view->status_message = null;
|
73 |
|
74 |
$this->view->text = UiHelper::getStatusText($this->imageModel);
|
260 |
$url = $thumbObj->getURL(); //$fs->pathToURL($thumbObj); //wp_get_attachment_image_src($this->post_id, $size);
|
261 |
$filename = $thumbObj->getFullPath();
|
262 |
$backup = $thumbObj->hasBackup() ? $thumbObj->getBackupFile()->getFullPath() : 'n/a';
|
263 |
+
|
264 |
$width = $thumbObj->get('width');
|
265 |
$height = $thumbObj->get('height');
|
266 |
|
@@ -249,12 +249,17 @@ class ListMediaViewController extends \ShortPixel\ViewController
|
|
249 |
|
250 |
if ($filter && $filter == 'optimized')
|
251 |
{
|
252 |
-
$
|
|
|
|
|
|
|
|
|
|
|
253 |
$sql .= ' INNER JOIN ' . $wpdb->posts . ' ON ' . $wpdb->posts . '.ID = ' . $tableName . '.attach_id ';
|
254 |
|
255 |
$sql .= 'WHERE image_type = %d AND status = %d';
|
256 |
$sql = $wpdb->prepare($sql, MediaLibraryModel::IMAGE_TYPE_MAIN, $fileStatus);
|
257 |
-
$sql .= ' AND ' . $post_where; // glue back the orders, and the all.
|
258 |
}
|
259 |
if ($filter && $filter == 'unoptimized')
|
260 |
{
|
249 |
|
250 |
if ($filter && $filter == 'optimized')
|
251 |
{
|
252 |
+
$where = " AND " . $wpdb->posts . '.ID in ( SELECT attach_id FROM ' . $tableName . " WHERE parent = %d and status = %d) ";
|
253 |
+
$where = $wpdb->prepare($where, MediaLibraryModel::IMAGE_TYPE_MAIN, ImageModel::FILE_STATUS_SUCCESS);
|
254 |
+
|
255 |
+
$sql = substr_replace($request, $where, ($post_pos + strlen($post_pos)) ,0);
|
256 |
+
|
257 |
+
/*$sql = ' SELECT SQL_CALC_FOUND_ROWS * FROM ' . $tableName;
|
258 |
$sql .= ' INNER JOIN ' . $wpdb->posts . ' ON ' . $wpdb->posts . '.ID = ' . $tableName . '.attach_id ';
|
259 |
|
260 |
$sql .= 'WHERE image_type = %d AND status = %d';
|
261 |
$sql = $wpdb->prepare($sql, MediaLibraryModel::IMAGE_TYPE_MAIN, $fileStatus);
|
262 |
+
$sql .= ' AND ' . $post_where; // glue back the orders, and the all. */
|
263 |
}
|
264 |
if ($filter && $filter == 'unoptimized')
|
265 |
{
|
@@ -152,18 +152,13 @@ class InstallHelper
|
|
152 |
global $wpdb;
|
153 |
require_once( ABSPATH . 'wp-admin/includes/upgrade.php' );
|
154 |
|
155 |
-
|
156 |
-
|
157 |
-
|
158 |
-
|
159 |
-
|
160 |
-
|
161 |
-
|
162 |
-
}
|
163 |
-
if (self::checkTableExists('shortpixel_postmeta') === false)
|
164 |
-
{
|
165 |
-
dbDelta(self::getPostMetaSQL());
|
166 |
-
}
|
167 |
|
168 |
self::checkIndexes();
|
169 |
}
|
@@ -291,7 +286,7 @@ class InstallHelper
|
|
291 |
attach_id bigint unsigned NOT NULL,
|
292 |
parent bigint unsigned NOT NULL,
|
293 |
image_type tinyint default 0,
|
294 |
-
size varchar(
|
295 |
status tinyint default 0,
|
296 |
compression_type tinyint,
|
297 |
compressed_size int,
|
152 |
global $wpdb;
|
153 |
require_once( ABSPATH . 'wp-admin/includes/upgrade.php' );
|
154 |
|
155 |
+
|
156 |
+
dbDelta(self::getFolderTableSQL());
|
157 |
+
|
158 |
+
dbDelta(self::getMetaTableSQL());
|
159 |
+
|
160 |
+
dbDelta(self::getPostMetaSQL());
|
161 |
+
|
|
|
|
|
|
|
|
|
|
|
162 |
|
163 |
self::checkIndexes();
|
164 |
}
|
286 |
attach_id bigint unsigned NOT NULL,
|
287 |
parent bigint unsigned NOT NULL,
|
288 |
image_type tinyint default 0,
|
289 |
+
size varchar(150),
|
290 |
status tinyint default 0,
|
291 |
compression_type tinyint,
|
292 |
compressed_size int,
|
@@ -202,9 +202,6 @@ class UiHelper
|
|
202 |
|
203 |
}
|
204 |
|
205 |
-
|
206 |
-
|
207 |
-
|
208 |
public static function compressionTypeToText($type)
|
209 |
{
|
210 |
if ($type == ImageModel::COMPRESSION_LOSSLESS )
|
@@ -241,7 +238,7 @@ class UiHelper
|
|
241 |
if ($id === 0)
|
242 |
return array();
|
243 |
|
244 |
-
if ($mediaItem->isOptimized())
|
245 |
{
|
246 |
$optimizable = $mediaItem->getOptimizeURLS(true);
|
247 |
|
@@ -410,8 +407,8 @@ class UiHelper
|
|
410 |
$text = __('This item is waiting to be processed', 'shortpixel-image-optimiser');
|
411 |
}
|
412 |
|
413 |
-
|
414 |
-
|
415 |
|
416 |
$retry = self::getAction('retry', $mediaItem->get('id'));
|
417 |
|
@@ -429,7 +426,7 @@ class UiHelper
|
|
429 |
}
|
430 |
}
|
431 |
|
432 |
-
$text .= "<div class='shortpixel-image-error'>" . esc_html($mediaItem->
|
433 |
$text .= "<span class='shortpixel-error-reset'>" . sprintf(__('After you have fixed this issue, you can %s click here to retry %s', 'shortpixel-image-optimiser'), '<a href="javascript:' . $retry['function'] . '">', '</a>');
|
434 |
|
435 |
$text .= '</div>';
|
@@ -608,7 +605,18 @@ class UiHelper
|
|
608 |
|
609 |
public static function formatNumber($number, $precision = 2)
|
610 |
{
|
611 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
612 |
}
|
613 |
|
614 |
protected static function convertImageTypeName($name, $type)
|
202 |
|
203 |
}
|
204 |
|
|
|
|
|
|
|
205 |
public static function compressionTypeToText($type)
|
206 |
{
|
207 |
if ($type == ImageModel::COMPRESSION_LOSSLESS )
|
238 |
if ($id === 0)
|
239 |
return array();
|
240 |
|
241 |
+
if ($mediaItem->isOptimized() )
|
242 |
{
|
243 |
$optimizable = $mediaItem->getOptimizeURLS(true);
|
244 |
|
407 |
$text = __('This item is waiting to be processed', 'shortpixel-image-optimiser');
|
408 |
}
|
409 |
|
410 |
+
if ($mediaItem->isOptimizePrevented() !== false)
|
411 |
+
{
|
412 |
|
413 |
$retry = self::getAction('retry', $mediaItem->get('id'));
|
414 |
|
426 |
}
|
427 |
}
|
428 |
|
429 |
+
$text .= "<div class='shortpixel-image-error'>" . esc_html($mediaItem->getReason('processable'));
|
430 |
$text .= "<span class='shortpixel-error-reset'>" . sprintf(__('After you have fixed this issue, you can %s click here to retry %s', 'shortpixel-image-optimiser'), '<a href="javascript:' . $retry['function'] . '">', '</a>');
|
431 |
|
432 |
$text .= '</div>';
|
605 |
|
606 |
public static function formatNumber($number, $precision = 2)
|
607 |
{
|
608 |
+
global $wp_locale;
|
609 |
+
$decimalpoint = isset($wp_locale->number_format['decimal_point']) ? $wp_locale->number_format['decimal_point'] : false;
|
610 |
+
$number = number_format_i18n( (int) $number, $precision);
|
611 |
+
|
612 |
+
// Don't show trailing zeroes if number is a whole unbroken number.
|
613 |
+
if ($decimalpoint !== false && substr($number, strpos($number, $decimalpoint)) == 00)
|
614 |
+
{
|
615 |
+
$number = number_format_i18n($number, 0);
|
616 |
+
}
|
617 |
+
// Some locale's have no-breaking-space as thousands separator. This doesn't work well in JS / Cron Shell so replace with space.
|
618 |
+
$number = str_replace(' ', ' ', $number);
|
619 |
+
return $number;
|
620 |
}
|
621 |
|
622 |
protected static function convertImageTypeName($name, $type)
|
@@ -184,7 +184,7 @@ class EnvironmentModel extends \ShortPixel\Model
|
|
184 |
$use_screens = apply_filters('shortpixel/init/optimize_on_screens', $use_screens);
|
185 |
|
186 |
$this->screen_id = $screen->id;
|
187 |
-
if(in_array($screen->id, $use_screens)) {
|
188 |
$this->is_screen_to_use = true;
|
189 |
}
|
190 |
|
184 |
$use_screens = apply_filters('shortpixel/init/optimize_on_screens', $use_screens);
|
185 |
|
186 |
$this->screen_id = $screen->id;
|
187 |
+
if(is_array($use_screens) && in_array($screen->id, $use_screens)) {
|
188 |
$this->is_screen_to_use = true;
|
189 |
}
|
190 |
|
@@ -204,10 +204,9 @@ class CustomImageModel extends \ShortPixel\Model\Image\ImageModel
|
|
204 |
if ($bool)
|
205 |
{
|
206 |
$this->setMeta('status', ImageModel::FILE_STATUS_UNPROCESSED);
|
207 |
-
$this->setMeta('
|
208 |
-
$this->setMeta('
|
209 |
-
|
210 |
-
$this->setMeta('retries', 0);
|
211 |
|
212 |
$this->saveMeta();
|
213 |
|
204 |
if ($bool)
|
205 |
{
|
206 |
$this->setMeta('status', ImageModel::FILE_STATUS_UNPROCESSED);
|
207 |
+
$this->setMeta('compressedSize', 0);
|
208 |
+
$this->setMeta('compressionType', null);
|
209 |
+
|
|
|
210 |
|
211 |
$this->saveMeta();
|
212 |
|
@@ -66,6 +66,9 @@ abstract class ImageModel extends \ShortPixel\Model\File\FileModel
|
|
66 |
protected $processable_status = 0;
|
67 |
protected $restorable_status = 0;
|
68 |
|
|
|
|
|
|
|
69 |
//protected $is_optimized = false;
|
70 |
// protected $is_image = false;
|
71 |
|
@@ -112,8 +115,6 @@ abstract class ImageModel extends \ShortPixel\Model\File\FileModel
|
|
112 |
/* Check if an image in theory could be processed. Check only exclusions, don't check status etc */
|
113 |
public function isProcessable()
|
114 |
{
|
115 |
-
$this->processable_status = 0; // reset everytime.
|
116 |
-
|
117 |
if ( $this->isOptimized() || ! $this->exists() || $this->isPathExcluded() || $this->isExtensionExcluded() || $this->isSizeExcluded() || (! $this->is_writable() && ! $this->is_virtual()) || $this->isOptimizePrevented() !== false )
|
118 |
{
|
119 |
if(! $this->is_writable() && $this->processable_status == 0)
|
@@ -124,7 +125,10 @@ abstract class ImageModel extends \ShortPixel\Model\File\FileModel
|
|
124 |
return false;
|
125 |
}
|
126 |
else
|
|
|
|
|
127 |
return true;
|
|
|
128 |
}
|
129 |
|
130 |
public function isProcessableFileType($type = 'webp')
|
@@ -190,7 +194,7 @@ abstract class ImageModel extends \ShortPixel\Model\File\FileModel
|
|
190 |
$message = __('Image Size Excluded', 'shortpixel-image-optimiser');
|
191 |
break;
|
192 |
case self::P_EXCLUDE_PATH:
|
193 |
-
$message = __('Image
|
194 |
break;
|
195 |
case self::P_IS_OPTIMIZED:
|
196 |
$message = __('Image is already optimized', 'shortpixel-image-optimiser');
|
@@ -206,7 +210,10 @@ abstract class ImageModel extends \ShortPixel\Model\File\FileModel
|
|
206 |
break;
|
207 |
case self::P_OPTIMIZE_PREVENTED:
|
208 |
$message = __('Fatal error preventing processing', 'shortpixel-image-optimiser');
|
|
|
|
|
209 |
break;
|
|
|
210 |
case self::P_RESTORABLE:
|
211 |
$message = __('Image restorable', 'shortpixel-image-optimiser');
|
212 |
break;
|
@@ -468,6 +475,7 @@ abstract class ImageModel extends \ShortPixel\Model\File\FileModel
|
|
468 |
'is_error' => true,
|
469 |
'issue_type' => ResponseController::ISSUE_BACKUP_CREATE,
|
470 |
'message' => __('Could not create backup. Please check file permissions', 'shortpixel-image-optimiser'),
|
|
|
471 |
);
|
472 |
|
473 |
ResponseController::addData($this->get('id'), $response);
|
@@ -513,7 +521,7 @@ abstract class ImageModel extends \ShortPixel\Model\File\FileModel
|
|
513 |
|
514 |
$optimizedSize = $tempFile->getFileSize();
|
515 |
$this->setImageSize();
|
516 |
-
}
|
517 |
|
518 |
if ($copyok)
|
519 |
{
|
@@ -580,6 +588,7 @@ abstract class ImageModel extends \ShortPixel\Model\File\FileModel
|
|
580 |
'is_error' => true,
|
581 |
'issue_type' => ResponseController::ISSUE_BACKUP_CREATE,
|
582 |
'message' => __('Could not copy optimized image from temporary files. Check file permissions', 'shortpixel-image-optimiser'),
|
|
|
583 |
);
|
584 |
|
585 |
ResponseController::addData($this->get('id'), $response);;
|
@@ -597,6 +606,7 @@ abstract class ImageModel extends \ShortPixel\Model\File\FileModel
|
|
597 |
'is_error' => true,
|
598 |
'issue_type' => ResponseController::ISSUE_OPTIMIZED_NOFILE,
|
599 |
'message' => __('Image is reporting as optimized, but file couldn\'t be found in the downloaded files', 'shortpixel-image-optimiser'),
|
|
|
600 |
|
601 |
);
|
602 |
|
@@ -635,6 +645,7 @@ abstract class ImageModel extends \ShortPixel\Model\File\FileModel
|
|
635 |
|
636 |
public function isRestorable()
|
637 |
{
|
|
|
638 |
if (! $this->isOptimized())
|
639 |
{
|
640 |
$this->restorable_status = self::P_NOT_OPTIMIZED;
|
@@ -873,6 +884,7 @@ abstract class ImageModel extends \ShortPixel\Model\File\FileModel
|
|
873 |
if ($type == 'regex-name' || $type == 'regex-path')
|
874 |
{
|
875 |
$result = $this->matchExludeRegexPattern($target, $pattern);
|
|
|
876 |
}
|
877 |
else {
|
878 |
$result = $this->matchExcludePattern($target, $pattern);
|
@@ -915,7 +927,9 @@ abstract class ImageModel extends \ShortPixel\Model\File\FileModel
|
|
915 |
if(strlen($pattern) == 0) // can happen on faulty input in settings.
|
916 |
return false;
|
917 |
|
918 |
-
|
|
|
|
|
919 |
if ($m !== false && $m > 0) // valid regex, more hits than zero
|
920 |
{
|
921 |
return true;
|
@@ -953,6 +967,11 @@ abstract class ImageModel extends \ShortPixel\Model\File\FileModel
|
|
953 |
|
954 |
$this->error_message = __('Backup already exists, but image is recoverable and the plugin will rollback. Will retry to optimize again. ', 'shortpixel-image-optimiser');
|
955 |
}
|
|
|
|
|
|
|
|
|
|
|
956 |
else
|
957 |
{
|
958 |
$this->preventNextTry(__('Fatal Issue: The Backup file already exists. The backup seems not restorable, or the original file is bigger than the backup, indicating an error.', 'shortpixel-image-optimiser'));
|
66 |
protected $processable_status = 0;
|
67 |
protected $restorable_status = 0;
|
68 |
|
69 |
+
// Public var that can be set by OptimizeController to prevent double queries.
|
70 |
+
public $is_in_queue;
|
71 |
+
|
72 |
//protected $is_optimized = false;
|
73 |
// protected $is_image = false;
|
74 |
|
115 |
/* Check if an image in theory could be processed. Check only exclusions, don't check status etc */
|
116 |
public function isProcessable()
|
117 |
{
|
|
|
|
|
118 |
if ( $this->isOptimized() || ! $this->exists() || $this->isPathExcluded() || $this->isExtensionExcluded() || $this->isSizeExcluded() || (! $this->is_writable() && ! $this->is_virtual()) || $this->isOptimizePrevented() !== false )
|
119 |
{
|
120 |
if(! $this->is_writable() && $this->processable_status == 0)
|
125 |
return false;
|
126 |
}
|
127 |
else
|
128 |
+
{
|
129 |
+
$this->processable_status = 0;
|
130 |
return true;
|
131 |
+
}
|
132 |
}
|
133 |
|
134 |
public function isProcessableFileType($type = 'webp')
|
194 |
$message = __('Image Size Excluded', 'shortpixel-image-optimiser');
|
195 |
break;
|
196 |
case self::P_EXCLUDE_PATH:
|
197 |
+
$message = __('Image Excluded', 'shortpixel-image-optimiser');
|
198 |
break;
|
199 |
case self::P_IS_OPTIMIZED:
|
200 |
$message = __('Image is already optimized', 'shortpixel-image-optimiser');
|
210 |
break;
|
211 |
case self::P_OPTIMIZE_PREVENTED:
|
212 |
$message = __('Fatal error preventing processing', 'shortpixel-image-optimiser');
|
213 |
+
if (property_exists($this, 'optimizePrevented'))
|
214 |
+
$message = $this->get('optimizePrevented');
|
215 |
break;
|
216 |
+
// Restorable Reasons
|
217 |
case self::P_RESTORABLE:
|
218 |
$message = __('Image restorable', 'shortpixel-image-optimiser');
|
219 |
break;
|
475 |
'is_error' => true,
|
476 |
'issue_type' => ResponseController::ISSUE_BACKUP_CREATE,
|
477 |
'message' => __('Could not create backup. Please check file permissions', 'shortpixel-image-optimiser'),
|
478 |
+
'fileName' => $this->getFileName(),
|
479 |
);
|
480 |
|
481 |
ResponseController::addData($this->get('id'), $response);
|
521 |
|
522 |
$optimizedSize = $tempFile->getFileSize();
|
523 |
$this->setImageSize();
|
524 |
+
} // else
|
525 |
|
526 |
if ($copyok)
|
527 |
{
|
588 |
'is_error' => true,
|
589 |
'issue_type' => ResponseController::ISSUE_BACKUP_CREATE,
|
590 |
'message' => __('Could not copy optimized image from temporary files. Check file permissions', 'shortpixel-image-optimiser'),
|
591 |
+
'fileName' => $this->getFileName(),
|
592 |
);
|
593 |
|
594 |
ResponseController::addData($this->get('id'), $response);;
|
606 |
'is_error' => true,
|
607 |
'issue_type' => ResponseController::ISSUE_OPTIMIZED_NOFILE,
|
608 |
'message' => __('Image is reporting as optimized, but file couldn\'t be found in the downloaded files', 'shortpixel-image-optimiser'),
|
609 |
+
'fileName' => $this->getFileName(),
|
610 |
|
611 |
);
|
612 |
|
645 |
|
646 |
public function isRestorable()
|
647 |
{
|
648 |
+
|
649 |
if (! $this->isOptimized())
|
650 |
{
|
651 |
$this->restorable_status = self::P_NOT_OPTIMIZED;
|
884 |
if ($type == 'regex-name' || $type == 'regex-path')
|
885 |
{
|
886 |
$result = $this->matchExludeRegexPattern($target, $pattern);
|
887 |
+
Log::addTemp('Exclude RegeX result', $result);
|
888 |
}
|
889 |
else {
|
890 |
$result = $this->matchExcludePattern($target, $pattern);
|
927 |
if(strlen($pattern) == 0) // can happen on faulty input in settings.
|
928 |
return false;
|
929 |
|
930 |
+
$matches = array();
|
931 |
+
$m = preg_match($pattern, $target, $matches);
|
932 |
+
|
933 |
if ($m !== false && $m > 0) // valid regex, more hits than zero
|
934 |
{
|
935 |
return true;
|
967 |
|
968 |
$this->error_message = __('Backup already exists, but image is recoverable and the plugin will rollback. Will retry to optimize again. ', 'shortpixel-image-optimiser');
|
969 |
}
|
970 |
+
/* elseif ($backupFile->getFileSize() > $this->getFileSize() && ! $backupFile->is_virtual() ) // Where there is a backup and it's bigger, assume some hickup, but there is backup so hooray
|
971 |
+
{
|
972 |
+
Log::addWarn('Backup already exists. Backup file is bigger, so assume that all is good with backup and proceed');
|
973 |
+
return true; // ok it.
|
974 |
+
} */
|
975 |
else
|
976 |
{
|
977 |
$this->preventNextTry(__('Fatal Issue: The Backup file already exists. The backup seems not restorable, or the original file is bigger than the backup, indicating an error.', 'shortpixel-image-optimiser'));
|
@@ -13,7 +13,7 @@ class MediaLibraryModel extends \ShortPixel\Model\Image\MediaLibraryThumbnailMod
|
|
13 |
{
|
14 |
|
15 |
protected $thumbnails = array(); // thumbnails of this // MediaLibraryThumbnailModel .
|
16 |
-
protected $retinas
|
17 |
//protected $webps = array(); // webp files -
|
18 |
protected $original_file = false; // the original instead of the possibly _scaled one created by WP 5.3
|
19 |
|
@@ -27,7 +27,7 @@ class MediaLibraryModel extends \ShortPixel\Model\Image\MediaLibraryThumbnailMod
|
|
27 |
|
28 |
private static $unlistedChecked = array(); // limit checking unlisted.
|
29 |
|
30 |
-
|
31 |
private $justConverted = false; // check if conversion happened on same run, to prevent double runs.
|
32 |
|
33 |
const IMAGE_TYPE_MAIN = 0;
|
@@ -110,14 +110,18 @@ class MediaLibraryModel extends \ShortPixel\Model\Image\MediaLibraryThumbnailMod
|
|
110 |
}
|
111 |
|
112 |
// @todo Check Retina's
|
113 |
-
if ($settings->optimizeRetina)
|
114 |
-
{
|
115 |
|
|
|
|
|
116 |
foreach($this->retinas as $retinaObj)
|
117 |
{
|
|
|
118 |
$urls = array_merge($urls, $retinaObj->getOptimizeUrls($get_path));
|
119 |
}
|
|
|
120 |
}
|
|
|
|
|
121 |
$urls = array_values(array_unique($urls));
|
122 |
return $urls;
|
123 |
}
|
@@ -190,6 +194,23 @@ class MediaLibraryModel extends \ShortPixel\Model\Image\MediaLibraryThumbnailMod
|
|
190 |
}
|
191 |
}
|
192 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
193 |
return array_values(array_unique($toOptimize));
|
194 |
//foreach($types as $index => $)
|
195 |
}
|
@@ -287,9 +308,9 @@ class MediaLibraryModel extends \ShortPixel\Model\Image\MediaLibraryThumbnailMod
|
|
287 |
$thumbObj = $this->getThumbnailModel($this->getFileDir() . $data['file'], $name);
|
288 |
|
289 |
$meta = new ImageThumbnailMeta();
|
290 |
-
$thumbObj->setName($name);
|
291 |
$meta->originalWidth = (isset($data['width'])) ? $data['width'] : null; // get from WP
|
292 |
$meta->originalHeight = (isset($data['height'])) ? $data['height'] : null;
|
|
|
293 |
$thumbObj->setMetaObj($meta);
|
294 |
$thumbnails[$name] = $thumbObj;
|
295 |
}
|
@@ -301,31 +322,47 @@ class MediaLibraryModel extends \ShortPixel\Model\Image\MediaLibraryThumbnailMod
|
|
301 |
|
302 |
protected function getRetinas()
|
303 |
{
|
304 |
-
|
305 |
-
|
|
|
|
|
306 |
|
307 |
-
|
308 |
-
|
309 |
|
310 |
-
|
311 |
-
|
|
|
|
|
|
|
312 |
|
313 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
314 |
{
|
315 |
$retscaled = $this->original_file->getRetina();
|
316 |
if ($retscaled)
|
317 |
-
$retinas[1] = $retscaled; //see main
|
318 |
}
|
319 |
|
320 |
foreach ($this->thumbnails as $thumbname => $thumbObj)
|
321 |
{
|
322 |
-
|
323 |
-
|
324 |
-
|
|
|
|
|
|
|
325 |
}
|
326 |
|
327 |
-
|
328 |
-
return $retinas;
|
329 |
}
|
330 |
|
331 |
protected function getWebps()
|
@@ -342,6 +379,16 @@ class MediaLibraryModel extends \ShortPixel\Model\Image\MediaLibraryThumbnailMod
|
|
342 |
if ($webp)
|
343 |
$webps[$thumbname] = $webp;
|
344 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
345 |
if ($this->isScaled())
|
346 |
{
|
347 |
$webp = $this->original_file->getWebp();
|
@@ -366,6 +413,17 @@ class MediaLibraryModel extends \ShortPixel\Model\Image\MediaLibraryThumbnailMod
|
|
366 |
if ($avif)
|
367 |
$avifs[$thumbname] = $avif;
|
368 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
369 |
if ($this->isScaled())
|
370 |
{
|
371 |
$avif = $this->original_file->getAvif();
|
@@ -404,7 +462,6 @@ class MediaLibraryModel extends \ShortPixel\Model\Image\MediaLibraryThumbnailMod
|
|
404 |
$return = true;
|
405 |
$wpmeta = wp_get_attachment_metadata($this->get('id'));
|
406 |
|
407 |
-
|
408 |
if (! $this->isOptimized() && isset($tempFiles[$this->getFileName()]) ) // main file might not be contained in results
|
409 |
{
|
410 |
if ($this->getExtension() == 'heic')
|
@@ -439,6 +496,7 @@ class MediaLibraryModel extends \ShortPixel\Model\Image\MediaLibraryThumbnailMod
|
|
439 |
$compressionType = $this->getMeta('compressionType'); // CompressionType not set on subimages etc.
|
440 |
|
441 |
// If thumbnails should not be optimized, they should not be in result Array.
|
|
|
442 |
foreach($this->thumbnails as $thumbnail)
|
443 |
{
|
444 |
// Check if thumbnail is in the tempfiles return set. This might not always be the case
|
@@ -448,7 +506,6 @@ class MediaLibraryModel extends \ShortPixel\Model\Image\MediaLibraryThumbnailMod
|
|
448 |
}
|
449 |
|
450 |
$thumbnail->setMeta('compressionType', $compressionType);
|
451 |
-
|
452 |
$thumbnail->handleOptimizedFileType($tempFiles); // check for webps /etc
|
453 |
|
454 |
if ($thumbnail->isOptimized())
|
@@ -486,7 +543,6 @@ class MediaLibraryModel extends \ShortPixel\Model\Image\MediaLibraryThumbnailMod
|
|
486 |
}
|
487 |
|
488 |
$wpmeta['sizes'][$size]['filesize'] = $thumbnail->getFileSize();
|
489 |
-
|
490 |
}
|
491 |
|
492 |
if ($result)
|
@@ -500,6 +556,54 @@ class MediaLibraryModel extends \ShortPixel\Model\Image\MediaLibraryThumbnailMod
|
|
500 |
}
|
501 |
}
|
502 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
503 |
if ($this->isScaled() )
|
504 |
{
|
505 |
$original_file = $this->getOriginalFile();
|
@@ -588,7 +692,8 @@ class MediaLibraryModel extends \ShortPixel\Model\Image\MediaLibraryThumbnailMod
|
|
588 |
}
|
589 |
|
590 |
|
591 |
-
/**
|
|
|
592 |
* @return Object ThumbnailModel
|
593 |
* */
|
594 |
private function getThumbnailModel($path, $size)
|
@@ -649,7 +754,7 @@ class MediaLibraryModel extends \ShortPixel\Model\Image\MediaLibraryThumbnailMod
|
|
649 |
}
|
650 |
}
|
651 |
|
652 |
-
// Load Thumbnails.
|
653 |
if (property_exists($metadata,'thumbnails') && count($metadata->thumbnails) > 0) // unlisted in WordPress metadata sizes. Might be special unlisted one, one that was removed etc.
|
654 |
{
|
655 |
foreach($metadata->thumbnails as $name => $thumbMeta) // <!-- ThumbMeta is Object
|
@@ -678,7 +783,7 @@ class MediaLibraryModel extends \ShortPixel\Model\Image\MediaLibraryThumbnailMod
|
|
678 |
}
|
679 |
$this->thumbnails = $thumbnails;
|
680 |
|
681 |
-
if (property_exists($metadata, 'retinas') &&
|
682 |
{
|
683 |
$retinas = $this->getRetinas();
|
684 |
foreach($metadata->retinas as $name => $retinaMeta)
|
@@ -690,6 +795,9 @@ class MediaLibraryModel extends \ShortPixel\Model\Image\MediaLibraryThumbnailMod
|
|
690 |
$retMeta = new ImageThumbnailMeta();
|
691 |
$retMeta->fromClass($retinaMeta);
|
692 |
$retinaObj->setMetaObj($retMeta);
|
|
|
|
|
|
|
693 |
$this->retinas[$name] = $retinaObj;
|
694 |
}
|
695 |
}
|
@@ -716,11 +824,7 @@ class MediaLibraryModel extends \ShortPixel\Model\Image\MediaLibraryThumbnailMod
|
|
716 |
if (is_null($this->getMeta('originalWidth')))
|
717 |
$this->setMeta('originalWidth', $this->get('width') );
|
718 |
|
719 |
-
|
720 |
-
// This is bound to be bad for performance and not good for big sites!
|
721 |
-
// Moved this from isProcessable to be a bit more performance friendly.
|
722 |
-
$this->addUnlisted();
|
723 |
-
|
724 |
}
|
725 |
|
726 |
protected function getDBMeta()
|
@@ -779,13 +883,10 @@ class MediaLibraryModel extends \ShortPixel\Model\Image\MediaLibraryThumbnailMod
|
|
779 |
}
|
780 |
|
781 |
// Thumbnails
|
782 |
-
// $sql = 'SELECT * FROM ' . $wpdb->prefix . 'shortpixel_postmeta where parent = %d';
|
783 |
-
// $sql = $wpdb->prepare($sql, $this->id);
|
784 |
|
785 |
// Mimic the previous SPixel solution regarding the return Metadata Object needed, with all thunbnails there.
|
786 |
$metadata = new \stdClass;
|
787 |
$metadata->image_meta = new \stdClass;
|
788 |
-
$metadata->thumbnails = new \stdClass;
|
789 |
$metadata->thumbnails = array();
|
790 |
|
791 |
//$metadata = new \stdClass; // main image
|
@@ -816,11 +917,15 @@ class MediaLibraryModel extends \ShortPixel\Model\Image\MediaLibraryThumbnailMod
|
|
816 |
$data->$name = $val;
|
817 |
}
|
818 |
|
819 |
-
if ($record->parent == 0)
|
820 |
{
|
821 |
// Database ID should probably also be stored for the thumbnails, so updating / insert into the database will be easier. We have a free primary key, so why not use it?
|
822 |
$metadata->image_meta = $data;
|
823 |
}
|
|
|
|
|
|
|
|
|
824 |
elseif($record->parent > 0) // Thumbnails
|
825 |
{
|
826 |
switch($record->image_type)
|
@@ -1050,13 +1155,17 @@ class MediaLibraryModel extends \ShortPixel\Model\Image\MediaLibraryThumbnailMod
|
|
1050 |
$thumbnails[$thumbName] = $thumbObj->toClass();
|
1051 |
}
|
1052 |
}
|
1053 |
-
|
1054 |
-
|
1055 |
-
|
1056 |
-
|
1057 |
-
|
1058 |
-
|
1059 |
-
|
|
|
|
|
|
|
|
|
1060 |
|
1061 |
if (count($thumbnails) > 0)
|
1062 |
$metadata->thumbnails = $thumbnails;
|
@@ -1184,7 +1293,7 @@ class MediaLibraryModel extends \ShortPixel\Model\Image\MediaLibraryThumbnailMod
|
|
1184 |
}
|
1185 |
|
1186 |
// The exclude size on the main image - via regex - if fails, prevents the whole thing from optimization.
|
1187 |
-
if ($this->processable_status == ImageModel::P_EXCLUDE_SIZE)
|
1188 |
{
|
1189 |
return $bool;
|
1190 |
}
|
@@ -1210,6 +1319,18 @@ class MediaLibraryModel extends \ShortPixel\Model\Image\MediaLibraryThumbnailMod
|
|
1210 |
}
|
1211 |
}
|
1212 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1213 |
// Todo check if Webp / Avisf is active, check for unoptimized items
|
1214 |
if ($this->isProcessableFileType('webp'))
|
1215 |
{
|
@@ -1392,6 +1513,8 @@ class MediaLibraryModel extends \ShortPixel\Model\Image\MediaLibraryThumbnailMod
|
|
1392 |
if (! $excludePatterns || ! is_array($excludePatterns) ) // no patterns, nothing excluded
|
1393 |
return false;
|
1394 |
|
|
|
|
|
1395 |
foreach($excludePatterns as $item) {
|
1396 |
$type = trim($item["type"]);
|
1397 |
if($type == "size") {
|
@@ -1399,23 +1522,23 @@ class MediaLibraryModel extends \ShortPixel\Model\Image\MediaLibraryThumbnailMod
|
|
1399 |
$width = $this->get('width');
|
1400 |
$height = $this->get('height');
|
1401 |
|
1402 |
-
|
1403 |
if( $width && $height
|
1404 |
&& $this->isProcessableSize($width, $height, $item["value"]) === false){
|
1405 |
$this->processable_status = self::P_EXCLUDE_SIZE;
|
1406 |
-
return true;
|
1407 |
}
|
1408 |
else
|
1409 |
-
|
1410 |
}
|
1411 |
}
|
1412 |
|
|
|
|
|
1413 |
}
|
1414 |
|
1415 |
private function isProcessableSize($width, $height, $excludePattern) {
|
1416 |
|
1417 |
$ranges = preg_split("/(x|×|X)/",$excludePattern);
|
1418 |
-
|
1419 |
$widthBounds = explode("-", $ranges[0]);
|
1420 |
$minWidth = intval($widthBounds[0]);
|
1421 |
$maxWidth = (!isset($widthBounds[1])) ? intval($widthBounds[0]) : intval($widthBounds[1]);
|
@@ -1559,7 +1682,7 @@ class MediaLibraryModel extends \ShortPixel\Model\Image\MediaLibraryThumbnailMod
|
|
1559 |
{
|
1560 |
$this->processable_status = self::P_OPTIMIZE_PREVENTED;
|
1561 |
$this->optimizePrevented = $reason;
|
1562 |
-
return
|
1563 |
}
|
1564 |
}
|
1565 |
|
@@ -1631,6 +1754,17 @@ class MediaLibraryModel extends \ShortPixel\Model\Image\MediaLibraryThumbnailMod
|
|
1631 |
elseif ($thumbObj->isRestorable())
|
1632 |
{
|
1633 |
$bool = $thumbObj->restore(); // resets metadata
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1634 |
}
|
1635 |
|
1636 |
if ($unlisted_file === null)
|
@@ -1645,16 +1779,38 @@ class MediaLibraryModel extends \ShortPixel\Model\Image\MediaLibraryThumbnailMod
|
|
1645 |
$wpmeta['sizes'][$size]['filesize'] = $thumbObj->getFileSize();
|
1646 |
}
|
1647 |
|
1648 |
-
|
1649 |
-
|
1650 |
-
|
1651 |
-
|
1652 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1653 |
{
|
1654 |
-
|
|
|
1655 |
}
|
|
|
|
|
|
|
1656 |
|
1657 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1658 |
|
1659 |
if ($this->isScaled() )
|
1660 |
{
|
@@ -1725,6 +1881,28 @@ class MediaLibraryModel extends \ShortPixel\Model\Image\MediaLibraryThumbnailMod
|
|
1725 |
return $bool;
|
1726 |
}
|
1727 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1728 |
/** New Setup of RestorePNG2JPG. Runs after copying backupfile back to uploads.
|
1729 |
*/
|
1730 |
protected function restorePNG2JPG()
|
@@ -1863,6 +2041,15 @@ class MediaLibraryModel extends \ShortPixel\Model\Image\MediaLibraryThumbnailMod
|
|
1863 |
}
|
1864 |
}
|
1865 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1866 |
private function generateThumbnails()
|
1867 |
{
|
1868 |
$metadata = wp_generate_attachment_metadata($this->get('id'), $this->getFullPath());
|
@@ -1908,6 +2095,47 @@ class MediaLibraryModel extends \ShortPixel\Model\Image\MediaLibraryThumbnailMod
|
|
1908 |
|
1909 |
delete_post_meta($this->id, '_shortpixel_was_converted');
|
1910 |
$result = $this->checkLegacy();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1911 |
if ($result)
|
1912 |
{
|
1913 |
$this->saveMeta();
|
@@ -1958,7 +2186,7 @@ class MediaLibraryModel extends \ShortPixel\Model\Image\MediaLibraryThumbnailMod
|
|
1958 |
}
|
1959 |
|
1960 |
$quotaController = QuotaController::getInstance();
|
1961 |
-
if ($quotaController->hasQuota() ===
|
1962 |
{
|
1963 |
$adminNotices = AdminNoticesController::getInstance();
|
1964 |
$adminNotices->invokeLegacyNotice();
|
@@ -2127,38 +2355,52 @@ class MediaLibraryModel extends \ShortPixel\Model\Image\MediaLibraryThumbnailMod
|
|
2127 |
|
2128 |
if (isset($data['retinasOpt']))
|
2129 |
{
|
2130 |
-
$count = $data['retinasOpt'];
|
|
|
2131 |
|
|
|
2132 |
$retinas = $this->getRetinas();
|
2133 |
|
2134 |
foreach($retinas as $index => $retinaObj) // Thumbnail Model
|
2135 |
{
|
2136 |
-
|
2137 |
-
|
2138 |
-
|
2139 |
-
|
2140 |
-
|
2141 |
-
|
2142 |
-
|
2143 |
-
|
2144 |
-
|
2145 |
-
|
2146 |
-
|
2147 |
-
|
2148 |
-
|
2149 |
-
|
2150 |
-
|
2151 |
-
|
2152 |
-
|
2153 |
-
|
2154 |
-
|
2155 |
-
|
2156 |
-
|
2157 |
-
|
2158 |
-
|
2159 |
-
|
2160 |
-
|
2161 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2162 |
}
|
2163 |
|
2164 |
|
@@ -2345,11 +2587,21 @@ class MediaLibraryModel extends \ShortPixel\Model\Image\MediaLibraryThumbnailMod
|
|
2345 |
|
2346 |
$currentFiles = array($this->getFileName());
|
2347 |
foreach($this->thumbnails as $thumbObj)
|
2348 |
-
|
|
|
|
|
2349 |
|
2350 |
if ($this->isScaled())
|
2351 |
$currentFiles[] = $this->getOriginalFile()->getFileName();
|
2352 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2353 |
$processFiles = array();
|
2354 |
$unlisted = array();
|
2355 |
|
13 |
{
|
14 |
|
15 |
protected $thumbnails = array(); // thumbnails of this // MediaLibraryThumbnailModel .
|
16 |
+
protected $retinas; // retina files - MediaLibraryThumbnailModel (or retina / webp and move to thumbnail? )
|
17 |
//protected $webps = array(); // webp files -
|
18 |
protected $original_file = false; // the original instead of the possibly _scaled one created by WP 5.3
|
19 |
|
27 |
|
28 |
private static $unlistedChecked = array(); // limit checking unlisted.
|
29 |
|
30 |
+
protected $optimizePrevented; // cache if there is any reason to prevent optimizing
|
31 |
private $justConverted = false; // check if conversion happened on same run, to prevent double runs.
|
32 |
|
33 |
const IMAGE_TYPE_MAIN = 0;
|
110 |
}
|
111 |
|
112 |
// @todo Check Retina's
|
|
|
|
|
113 |
|
114 |
+
if ($settings->optimizeRetina && ! is_null($this->retinas))
|
115 |
+
{
|
116 |
foreach($this->retinas as $retinaObj)
|
117 |
{
|
118 |
+
if ($retinaObj->isThumbnailProcessable())
|
119 |
$urls = array_merge($urls, $retinaObj->getOptimizeUrls($get_path));
|
120 |
}
|
121 |
+
|
122 |
}
|
123 |
+
|
124 |
+
|
125 |
$urls = array_values(array_unique($urls));
|
126 |
return $urls;
|
127 |
}
|
194 |
}
|
195 |
}
|
196 |
|
197 |
+
if (! is_null($this->retinas))
|
198 |
+
{
|
199 |
+
foreach($this->retinas as $retinaName => $retinaObj)
|
200 |
+
{
|
201 |
+
if ($retinaObj->getOptimizeFileType($type))
|
202 |
+
{
|
203 |
+
if (true === $get_path)
|
204 |
+
{
|
205 |
+
$toOptimize[] = $retinaObj->getFullPath();
|
206 |
+
}
|
207 |
+
else{
|
208 |
+
$toOptimize[] = $retinaObj->getURL(); //$fs->pathToUrl($thumbObj);
|
209 |
+
}
|
210 |
+
}
|
211 |
+
}
|
212 |
+
}
|
213 |
+
|
214 |
return array_values(array_unique($toOptimize));
|
215 |
//foreach($types as $index => $)
|
216 |
}
|
308 |
$thumbObj = $this->getThumbnailModel($this->getFileDir() . $data['file'], $name);
|
309 |
|
310 |
$meta = new ImageThumbnailMeta();
|
|
|
311 |
$meta->originalWidth = (isset($data['width'])) ? $data['width'] : null; // get from WP
|
312 |
$meta->originalHeight = (isset($data['height'])) ? $data['height'] : null;
|
313 |
+
$thumbObj->setName($name); // name is size mostly
|
314 |
$thumbObj->setMetaObj($meta);
|
315 |
$thumbnails[$name] = $thumbObj;
|
316 |
}
|
322 |
|
323 |
protected function getRetinas()
|
324 |
{
|
325 |
+
if (is_null($this->retinas))
|
326 |
+
{
|
327 |
+
$this->addRetinas();
|
328 |
+
}
|
329 |
|
330 |
+
return $this->retinas;
|
331 |
+
}
|
332 |
|
333 |
+
protected function addRetinas()
|
334 |
+
{
|
335 |
+
// Don't load retina's if option is off.
|
336 |
+
if (! \wpSPIO()->settings()->optimizeRetina)
|
337 |
+
return;
|
338 |
|
339 |
+
if (! isset($this->retinas[0]))
|
340 |
+
{
|
341 |
+
$main = $this->getRetina();
|
342 |
+
|
343 |
+
if ($main)
|
344 |
+
{
|
345 |
+
$this->retinas[0] = $main; // on purpose not a string, but number to prevent any custom image sizes to get overwritten.
|
346 |
+
}
|
347 |
+
}
|
348 |
+
|
349 |
+
if ($this->isScaled() && ! isset($this->retinas[1]))
|
350 |
{
|
351 |
$retscaled = $this->original_file->getRetina();
|
352 |
if ($retscaled)
|
353 |
+
$this->retinas[1] = $retscaled; //see main
|
354 |
}
|
355 |
|
356 |
foreach ($this->thumbnails as $thumbname => $thumbObj)
|
357 |
{
|
358 |
+
if (! isset($this->retinas[$thumbname]))
|
359 |
+
{
|
360 |
+
$retinaObj = $thumbObj->getRetina();
|
361 |
+
if ($retinaObj)
|
362 |
+
$this->retinas[$thumbname] = $retinaObj;
|
363 |
+
}
|
364 |
}
|
365 |
|
|
|
|
|
366 |
}
|
367 |
|
368 |
protected function getWebps()
|
379 |
if ($webp)
|
380 |
$webps[$thumbname] = $webp;
|
381 |
}
|
382 |
+
|
383 |
+
if (! is_null($this->retinas))
|
384 |
+
{
|
385 |
+
foreach ($this->retinas as $retinaName => $retinaObj)
|
386 |
+
{
|
387 |
+
$webp = $retinaObj->getWebp();
|
388 |
+
if ($webp)
|
389 |
+
$webps['retina-' . $retinaName] = $webp; // adding a prefix to make sure it will not overwrite thumbnames, they share the same name.
|
390 |
+
}
|
391 |
+
}
|
392 |
if ($this->isScaled())
|
393 |
{
|
394 |
$webp = $this->original_file->getWebp();
|
413 |
if ($avif)
|
414 |
$avifs[$thumbname] = $avif;
|
415 |
}
|
416 |
+
|
417 |
+
if (! is_null($this->retinas))
|
418 |
+
{
|
419 |
+
foreach ($this->retinas as $retinaName => $retinaObj)
|
420 |
+
{
|
421 |
+
$avif = $retinaObj->getAvif();
|
422 |
+
if ($avif)
|
423 |
+
$avifs['retina-' . $retinaName] = $avif; // adding a prefix to make sure it will not overwrite thumbnames, they share the same name.
|
424 |
+
}
|
425 |
+
}
|
426 |
+
|
427 |
if ($this->isScaled())
|
428 |
{
|
429 |
$avif = $this->original_file->getAvif();
|
462 |
$return = true;
|
463 |
$wpmeta = wp_get_attachment_metadata($this->get('id'));
|
464 |
|
|
|
465 |
if (! $this->isOptimized() && isset($tempFiles[$this->getFileName()]) ) // main file might not be contained in results
|
466 |
{
|
467 |
if ($this->getExtension() == 'heic')
|
496 |
$compressionType = $this->getMeta('compressionType'); // CompressionType not set on subimages etc.
|
497 |
|
498 |
// If thumbnails should not be optimized, they should not be in result Array.
|
499 |
+
// #### THUMBNAILS ####
|
500 |
foreach($this->thumbnails as $thumbnail)
|
501 |
{
|
502 |
// Check if thumbnail is in the tempfiles return set. This might not always be the case
|
506 |
}
|
507 |
|
508 |
$thumbnail->setMeta('compressionType', $compressionType);
|
|
|
509 |
$thumbnail->handleOptimizedFileType($tempFiles); // check for webps /etc
|
510 |
|
511 |
if ($thumbnail->isOptimized())
|
543 |
}
|
544 |
|
545 |
$wpmeta['sizes'][$size]['filesize'] = $thumbnail->getFileSize();
|
|
|
546 |
}
|
547 |
|
548 |
if ($result)
|
556 |
}
|
557 |
}
|
558 |
|
559 |
+
/** #### RETINAS ***/
|
560 |
+
if (is_array($this->retinas))
|
561 |
+
{
|
562 |
+
foreach($this->retinas as $name => $retinaObj)
|
563 |
+
{
|
564 |
+
if (! isset($tempFiles[$retinaObj->getFileName()]) )
|
565 |
+
{
|
566 |
+
continue;
|
567 |
+
}
|
568 |
+
|
569 |
+
$retinaObj->setMeta('compressionType', $compressionType);
|
570 |
+
$retinaObj->handleOptimizedFileType($tempFiles); // check for webps /etc
|
571 |
+
|
572 |
+
if ($retinaObj->isOptimized())
|
573 |
+
{
|
574 |
+
continue;
|
575 |
+
}
|
576 |
+
if (!$retinaObj->isProcessable())
|
577 |
+
{
|
578 |
+
continue; // when excluded.
|
579 |
+
}
|
580 |
+
$filebase = $retinaObj->getFileBase();
|
581 |
+
$result = false;
|
582 |
+
|
583 |
+
if (isset($optimized[$filebase])) // double sizes.
|
584 |
+
{
|
585 |
+
$databaseID = $retinaObj->getMeta('databaseID');
|
586 |
+
$retinaObj->setMetaObj($optimized[$filebase]);
|
587 |
+
$retinaObj->setMeta('databaseID', $databaseID); // keep dbase id the same, otherwise it won't write this thumb to DB due to same ID.
|
588 |
+
$result = false;
|
589 |
+
}
|
590 |
+
else
|
591 |
+
{
|
592 |
+
$result = $retinaObj->handleOptimized($tempFiles);
|
593 |
+
}
|
594 |
+
|
595 |
+
if ($result)
|
596 |
+
{
|
597 |
+
$optimized[$filebase] = $retinaObj->getMetaObj();
|
598 |
+
}
|
599 |
+
elseif ($retinaObj->get('prevent_next_try') !== false) // in case of fatal issues.
|
600 |
+
{
|
601 |
+
$this->preventNextTry($retinaObj->get('prevent_next_try'));
|
602 |
+
$return = false; //failed
|
603 |
+
}
|
604 |
+
} // retinas loop
|
605 |
+
}
|
606 |
+
|
607 |
if ($this->isScaled() )
|
608 |
{
|
609 |
$original_file = $this->getOriginalFile();
|
692 |
}
|
693 |
|
694 |
|
695 |
+
/** Function to go from path -> thumbnail mode. This should be used for unlisted etc, but nothing that already is loaded in thumbnails.
|
696 |
+
* @param String Full Path to the Thumbnail File
|
697 |
* @return Object ThumbnailModel
|
698 |
* */
|
699 |
private function getThumbnailModel($path, $size)
|
754 |
}
|
755 |
}
|
756 |
|
757 |
+
// Load Unlisted Thumbnails.
|
758 |
if (property_exists($metadata,'thumbnails') && count($metadata->thumbnails) > 0) // unlisted in WordPress metadata sizes. Might be special unlisted one, one that was removed etc.
|
759 |
{
|
760 |
foreach($metadata->thumbnails as $name => $thumbMeta) // <!-- ThumbMeta is Object
|
783 |
}
|
784 |
$this->thumbnails = $thumbnails;
|
785 |
|
786 |
+
if (property_exists($metadata, 'retinas') && count($metadata->retinas) > 0 )
|
787 |
{
|
788 |
$retinas = $this->getRetinas();
|
789 |
foreach($metadata->retinas as $name => $retinaMeta)
|
795 |
$retMeta = new ImageThumbnailMeta();
|
796 |
$retMeta->fromClass($retinaMeta);
|
797 |
$retinaObj->setMetaObj($retMeta);
|
798 |
+
$retinaObj->setName($name);
|
799 |
+
$retinaObj->is_retina = true;
|
800 |
+
|
801 |
$this->retinas[$name] = $retinaObj;
|
802 |
}
|
803 |
}
|
824 |
if (is_null($this->getMeta('originalWidth')))
|
825 |
$this->setMeta('originalWidth', $this->get('width') );
|
826 |
|
827 |
+
$this->loadLooseItems();
|
|
|
|
|
|
|
|
|
828 |
}
|
829 |
|
830 |
protected function getDBMeta()
|
883 |
}
|
884 |
|
885 |
// Thumbnails
|
|
|
|
|
886 |
|
887 |
// Mimic the previous SPixel solution regarding the return Metadata Object needed, with all thunbnails there.
|
888 |
$metadata = new \stdClass;
|
889 |
$metadata->image_meta = new \stdClass;
|
|
|
890 |
$metadata->thumbnails = array();
|
891 |
|
892 |
//$metadata = new \stdClass; // main image
|
917 |
$data->$name = $val;
|
918 |
}
|
919 |
|
920 |
+
if ($record->parent == 0 && $record->image_type == self::IMAGE_TYPE_MAIN)
|
921 |
{
|
922 |
// Database ID should probably also be stored for the thumbnails, so updating / insert into the database will be easier. We have a free primary key, so why not use it?
|
923 |
$metadata->image_meta = $data;
|
924 |
}
|
925 |
+
elseif ($record->parent == 0 && $record->image_type = self::IMAGE_TYPE_RETINA)
|
926 |
+
{
|
927 |
+
$metadata->retinas[0] = $data;
|
928 |
+
}
|
929 |
elseif($record->parent > 0) // Thumbnails
|
930 |
{
|
931 |
switch($record->image_type)
|
1155 |
$thumbnails[$thumbName] = $thumbObj->toClass();
|
1156 |
}
|
1157 |
}
|
1158 |
+
|
1159 |
+
if (is_array($this->retinas))
|
1160 |
+
{
|
1161 |
+
foreach($this->retinas as $index => $retinaObj)
|
1162 |
+
{
|
1163 |
+
if ($retinaObj->getMeta('status') > 0)
|
1164 |
+
{
|
1165 |
+
$retinas[$index] = $retinaObj->toClass();
|
1166 |
+
}
|
1167 |
+
}
|
1168 |
+
}
|
1169 |
|
1170 |
if (count($thumbnails) > 0)
|
1171 |
$metadata->thumbnails = $thumbnails;
|
1293 |
}
|
1294 |
|
1295 |
// The exclude size on the main image - via regex - if fails, prevents the whole thing from optimization.
|
1296 |
+
if ($this->processable_status == ImageModel::P_EXCLUDE_SIZE || $this->processable_status == ImageModel::P_EXCLUDE_PATH)
|
1297 |
{
|
1298 |
return $bool;
|
1299 |
}
|
1319 |
}
|
1320 |
}
|
1321 |
|
1322 |
+
if (! $bool && ! is_null($this->retinas) && count($this->retinas) > 0)
|
1323 |
+
{
|
1324 |
+
foreach($this->retinas as $name => $retinaObj)
|
1325 |
+
{
|
1326 |
+
if ($retinaObj->isThumbnailProcessable())
|
1327 |
+
{
|
1328 |
+
$bool = true;
|
1329 |
+
return true;
|
1330 |
+
}
|
1331 |
+
}
|
1332 |
+
}
|
1333 |
+
|
1334 |
// Todo check if Webp / Avisf is active, check for unoptimized items
|
1335 |
if ($this->isProcessableFileType('webp'))
|
1336 |
{
|
1513 |
if (! $excludePatterns || ! is_array($excludePatterns) ) // no patterns, nothing excluded
|
1514 |
return false;
|
1515 |
|
1516 |
+
$bool = false;
|
1517 |
+
|
1518 |
foreach($excludePatterns as $item) {
|
1519 |
$type = trim($item["type"]);
|
1520 |
if($type == "size") {
|
1522 |
$width = $this->get('width');
|
1523 |
$height = $this->get('height');
|
1524 |
|
|
|
1525 |
if( $width && $height
|
1526 |
&& $this->isProcessableSize($width, $height, $item["value"]) === false){
|
1527 |
$this->processable_status = self::P_EXCLUDE_SIZE;
|
1528 |
+
return true; // exit directly because we have our exclusion
|
1529 |
}
|
1530 |
else
|
1531 |
+
$bool = false; // continue and check all patterns, there might be multiple.
|
1532 |
}
|
1533 |
}
|
1534 |
|
1535 |
+
return $bool;
|
1536 |
+
|
1537 |
}
|
1538 |
|
1539 |
private function isProcessableSize($width, $height, $excludePattern) {
|
1540 |
|
1541 |
$ranges = preg_split("/(x|×|X)/",$excludePattern);
|
|
|
1542 |
$widthBounds = explode("-", $ranges[0]);
|
1543 |
$minWidth = intval($widthBounds[0]);
|
1544 |
$maxWidth = (!isset($widthBounds[1])) ? intval($widthBounds[0]) : intval($widthBounds[1]);
|
1682 |
{
|
1683 |
$this->processable_status = self::P_OPTIMIZE_PREVENTED;
|
1684 |
$this->optimizePrevented = $reason;
|
1685 |
+
return true;
|
1686 |
}
|
1687 |
}
|
1688 |
|
1754 |
elseif ($thumbObj->isRestorable())
|
1755 |
{
|
1756 |
$bool = $thumbObj->restore(); // resets metadata
|
1757 |
+
if (! $bool)
|
1758 |
+
{
|
1759 |
+
$cleanRestore = false;
|
1760 |
+
}
|
1761 |
+
else
|
1762 |
+
{
|
1763 |
+
$restored[$filebase] = true;
|
1764 |
+
}
|
1765 |
+
}
|
1766 |
+
else {
|
1767 |
+
Log::addWarn('Thumbnail not restorable ' . $size, $this->getReason('restorable'));
|
1768 |
}
|
1769 |
|
1770 |
if ($unlisted_file === null)
|
1779 |
$wpmeta['sizes'][$size]['filesize'] = $thumbObj->getFileSize();
|
1780 |
}
|
1781 |
|
1782 |
+
}
|
1783 |
+
|
1784 |
+
if (! is_null($this->retinas))
|
1785 |
+
{
|
1786 |
+
$restored = array();
|
1787 |
+
|
1788 |
+
foreach($this->retinas as $name => $retinaObj)
|
1789 |
+
{
|
1790 |
+
$filebase = $retinaObj->getFileBase();
|
1791 |
+
$size = $retinaObj->get('size');
|
1792 |
+
|
1793 |
+
if (isset($restored[$filebase]))
|
1794 |
{
|
1795 |
+
$bool = true; // this filebase already restored. In case of duplicate sizes.
|
1796 |
+
$retinaObj->image_meta = new ImageThumbnailMeta();
|
1797 |
}
|
1798 |
+
elseif ($retinaObj->isRestorable())
|
1799 |
+
{
|
1800 |
+
$bool = $retinaObj->restore();
|
1801 |
|
1802 |
+
if (! $bool)
|
1803 |
+
{
|
1804 |
+
$cleanRestore = false;
|
1805 |
+
}
|
1806 |
+
else
|
1807 |
+
{
|
1808 |
+
$restored[$filebase] = true;
|
1809 |
+
}
|
1810 |
+
}
|
1811 |
+
|
1812 |
+
}
|
1813 |
+
}
|
1814 |
|
1815 |
if ($this->isScaled() )
|
1816 |
{
|
1881 |
return $bool;
|
1882 |
}
|
1883 |
|
1884 |
+
// This is check for the mainFile.
|
1885 |
+
public function hasDBRecord()
|
1886 |
+
{
|
1887 |
+
|
1888 |
+
global $wpdb;
|
1889 |
+
|
1890 |
+
$sql = 'SELECT id FROM ' . $wpdb->prefix . 'shortpixel_postmeta WHERE attach_id = %d AND size IS NULL and image_type = %d';
|
1891 |
+
$sql = $wpdb->prepare($sql, $this->id, self::IMAGE_TYPE_MAIN);
|
1892 |
+
|
1893 |
+
$id = $wpdb->get_var($sql);
|
1894 |
+
|
1895 |
+
if (is_null($id))
|
1896 |
+
{
|
1897 |
+
return false;
|
1898 |
+
}
|
1899 |
+
elseif (is_numeric($id)) {
|
1900 |
+
return true;
|
1901 |
+
}
|
1902 |
+
|
1903 |
+
}
|
1904 |
+
|
1905 |
+
|
1906 |
/** New Setup of RestorePNG2JPG. Runs after copying backupfile back to uploads.
|
1907 |
*/
|
1908 |
protected function restorePNG2JPG()
|
2041 |
}
|
2042 |
}
|
2043 |
|
2044 |
+
// Load items that might be processable but not in WP metadata or other meta's .
|
2045 |
+
// used for IsProcessable ( check if we have something ) and handleOptimized ( to check against the optimized stuff )
|
2046 |
+
private function loadLooseItems()
|
2047 |
+
{
|
2048 |
+
// Load items that might be not recorded when loading.
|
2049 |
+
$this->addUnlisted();
|
2050 |
+
$this->addRetinas();
|
2051 |
+
}
|
2052 |
+
|
2053 |
private function generateThumbnails()
|
2054 |
{
|
2055 |
$metadata = wp_generate_attachment_metadata($this->get('id'), $this->getFullPath());
|
2095 |
|
2096 |
delete_post_meta($this->id, '_shortpixel_was_converted');
|
2097 |
$result = $this->checkLegacy();
|
2098 |
+
|
2099 |
+
// Check the whole thing to find any images that have a backup, but are not marked as optimized, and just mark them.
|
2100 |
+
if (! $this->isOptimized() && $this->hasBackup() )
|
2101 |
+
{
|
2102 |
+
$this->setMeta('status', self::FILE_STATUS_SUCCESS);
|
2103 |
+
$result = true;
|
2104 |
+
}
|
2105 |
+
if ($this->hasOriginal())
|
2106 |
+
{
|
2107 |
+
$originalFile = $this->getOriginalFile();
|
2108 |
+
if (! $originalFile->isOptimized() && $originalFile->hasBackup() )
|
2109 |
+
{
|
2110 |
+
$originalFile->setMeta('status', self::FILE_STATUS_SUCCESS);
|
2111 |
+
$result = true;
|
2112 |
+
}
|
2113 |
+
}
|
2114 |
+
if (is_array($this->thumbnails) && count($this->thumbnails) > 0)
|
2115 |
+
{
|
2116 |
+
foreach($this->thumbnails as $thumbObj)
|
2117 |
+
{
|
2118 |
+
if (! $thumbObj->isOptimized() && $thumbObj->hasBackup())
|
2119 |
+
{
|
2120 |
+
$thumbObj->setMeta('status', self::FILE_STATUS_SUCCESS);
|
2121 |
+
$result = true;
|
2122 |
+
}
|
2123 |
+
}
|
2124 |
+
}
|
2125 |
+
if (is_array($this->retinas) && count($this->retinas) > 0)
|
2126 |
+
{
|
2127 |
+
foreach($this->retinas as $retinaObj)
|
2128 |
+
{
|
2129 |
+
if (! $retinaObj->isOptimized() && $retinaObj->hasBackup())
|
2130 |
+
{
|
2131 |
+
$retinaObj->setMeta('status', self::FILE_STATUS_SUCCESS);
|
2132 |
+
$result = true;
|
2133 |
+
}
|
2134 |
+
|
2135 |
+
}
|
2136 |
+
}
|
2137 |
+
|
2138 |
+
|
2139 |
if ($result)
|
2140 |
{
|
2141 |
$this->saveMeta();
|
2186 |
}
|
2187 |
|
2188 |
$quotaController = QuotaController::getInstance();
|
2189 |
+
if ($quotaController->hasQuota() === true)
|
2190 |
{
|
2191 |
$adminNotices = AdminNoticesController::getInstance();
|
2192 |
$adminNotices->invokeLegacyNotice();
|
2355 |
|
2356 |
if (isset($data['retinasOpt']))
|
2357 |
{
|
2358 |
+
$count = $data['retinasOpt']; // a number.
|
2359 |
+
$addedCounter = 0;
|
2360 |
|
2361 |
+
$retinasOpt = $data['retinasOpt'];
|
2362 |
$retinas = $this->getRetinas();
|
2363 |
|
2364 |
foreach($retinas as $index => $retinaObj) // Thumbnail Model
|
2365 |
{
|
2366 |
+
if ($retinaObj->hasDBRecord() === true)
|
2367 |
+
{
|
2368 |
+
continue;
|
2369 |
+
}
|
2370 |
+
|
2371 |
+
// Check if thumbnail ('parent') is Optimized, if so, then retina probably should be optimized as well.
|
2372 |
+
if ( (isset($this->thumbnails[$index]) &&
|
2373 |
+
is_object($this->thumbnails[$index]) &&
|
2374 |
+
$this->thumbnails[$index]->isOptimized) || $retinaObj->hasBackup() )
|
2375 |
+
{
|
2376 |
+
$retinaObj->image_meta->status = $status;
|
2377 |
+
$retinaObj->image_meta->compressionType = $type;
|
2378 |
+
if ($status == self::FILE_STATUS_SUCCESS)
|
2379 |
+
$retinaObj->image_meta->compressedSize = $retinaObj->getFileSize();
|
2380 |
+
else
|
2381 |
+
$retinaObj->image_meta->originalSize = $retinaObj->getFileSize();
|
2382 |
+
// $retinaObj->image_meta->improvement = -1; // n/a
|
2383 |
+
$retinaObj->image_meta->tsAdded = $tsAdded;
|
2384 |
+
$retinaObj->image_meta->tsOptimized = $tsOptimized;
|
2385 |
+
$retinaObj->image_meta->did_jpg2png = $did_jpg2png;
|
2386 |
+
if ($retinaObj->hasBackup())
|
2387 |
+
{
|
2388 |
+
$retinaObj->has_backup = true;
|
2389 |
+
if ($status == self::FILE_STATUS_SUCCESS)
|
2390 |
+
$retinaObj->image_meta->originalSize = $retinaObj->getBackupFile()->getFileSize();
|
2391 |
+
}
|
2392 |
+
|
2393 |
+
$retinaObj->recordChanged(true);
|
2394 |
+
$retinas[$index] = $retinaObj;
|
2395 |
+
$addedCounter++;
|
2396 |
+
}
|
2397 |
+
} // foreach
|
2398 |
+
|
2399 |
+
$this->retinas = $retinas;
|
2400 |
+
if ($count !== $addedCounter)
|
2401 |
+
{
|
2402 |
+
Log::addWarning("Conversion: $count retinas expected in legacy, " . $addedCounter . 'found. This can be due to overlapping image sizes.');
|
2403 |
+
}
|
2404 |
}
|
2405 |
|
2406 |
|
2587 |
|
2588 |
$currentFiles = array($this->getFileName());
|
2589 |
foreach($this->thumbnails as $thumbObj)
|
2590 |
+
{
|
2591 |
+
$currentFiles[] = $thumbObj->getFileName();
|
2592 |
+
}
|
2593 |
|
2594 |
if ($this->isScaled())
|
2595 |
$currentFiles[] = $this->getOriginalFile()->getFileName();
|
2596 |
|
2597 |
+
if (is_array($this->retinas))
|
2598 |
+
{
|
2599 |
+
foreach($this->retinas as $retinaObj)
|
2600 |
+
{
|
2601 |
+
$currentFiles[] = $retinaObj->getFileName();
|
2602 |
+
}
|
2603 |
+
}
|
2604 |
+
|
2605 |
$processFiles = array();
|
2606 |
$unlisted = array();
|
2607 |
|
@@ -18,6 +18,7 @@ class MediaLibraryThumbnailModel extends \ShortPixel\Model\Image\ImageModel
|
|
18 |
public $mime; */
|
19 |
protected $prevent_next_try = false;
|
20 |
protected $is_main_file = false;
|
|
|
21 |
protected $id; // this is the parent attachment id
|
22 |
protected $size; // size of image in WP, if applicable.
|
23 |
|
@@ -47,6 +48,7 @@ class MediaLibraryThumbnailModel extends \ShortPixel\Model\Image\ImageModel
|
|
47 |
'image_meta' => $this->image_meta,
|
48 |
'name' => $this->name,
|
49 |
'path' => $this->getFullPath(),
|
|
|
50 |
'exists' => ($this->exists()) ? 'yes' : 'no',
|
51 |
|
52 |
);
|
@@ -64,7 +66,9 @@ class MediaLibraryThumbnailModel extends \ShortPixel\Model\Image\ImageModel
|
|
64 |
$filepath = (string) $this->getFileDir();
|
65 |
$extension = $this->getExtension();
|
66 |
|
67 |
-
$retina = new MediaLibraryThumbnailModel($filepath . $filebase . '@2x.' . $extension); // mind the dot in after 2x
|
|
|
|
|
68 |
|
69 |
if ($retina->exists())
|
70 |
return $retina;
|
@@ -153,7 +157,7 @@ class MediaLibraryThumbnailModel extends \ShortPixel\Model\Image\ImageModel
|
|
153 |
{
|
154 |
$fs = \wpSPIO()->filesystem();
|
155 |
|
156 |
-
if ($this->size == 'original')
|
157 |
{
|
158 |
$url = wp_get_original_image_url($this->id);
|
159 |
}
|
@@ -168,7 +172,7 @@ class MediaLibraryThumbnailModel extends \ShortPixel\Model\Image\ImageModel
|
|
168 |
// https://app.asana.com/0/1200110778640816/1202589533659780
|
169 |
$size_array = image_get_intermediate_size($this->id, $this->size);
|
170 |
|
171 |
-
if ($size_array === false)
|
172 |
{
|
173 |
$url = $fs->pathToUrl($this);
|
174 |
}
|
@@ -221,7 +225,10 @@ class MediaLibraryThumbnailModel extends \ShortPixel\Model\Image\ImageModel
|
|
221 |
// if thumbnail processing is off, thumbs are never processable.
|
222 |
// This is also used by main file, so check for that!
|
223 |
if ( $this->excludeThumbnails() && $this->is_main_file === false)
|
|
|
|
|
224 |
return false;
|
|
|
225 |
else
|
226 |
{
|
227 |
$bool = parent::isProcessable();
|
@@ -246,14 +253,15 @@ class MediaLibraryThumbnailModel extends \ShortPixel\Model\Image\ImageModel
|
|
246 |
// !Important . This doubles as checking excluded image sizes.
|
247 |
protected function isSizeExcluded()
|
248 |
{
|
|
|
249 |
$excludeSizes = \wpSPIO()->settings()->excludeSizes;
|
250 |
if (is_array($excludeSizes) && in_array($this->name, $excludeSizes))
|
|
|
|
|
251 |
return true;
|
252 |
-
|
253 |
-
|
254 |
-
|
255 |
-
|
256 |
-
|
257 |
|
258 |
protected function excludeThumbnails()
|
259 |
{
|
@@ -292,18 +300,9 @@ class MediaLibraryThumbnailModel extends \ShortPixel\Model\Image\ImageModel
|
|
292 |
{
|
293 |
global $wpdb;
|
294 |
|
295 |
-
$size = (! $this->is_main_file) ? $this->size : null;
|
296 |
-
|
297 |
-
if (is_null($size))
|
298 |
-
{
|
299 |
-
$sql = 'SELECT id FROM ' . $wpdb->prefix . 'shortpixel_postmeta WHERE attach_id = %d AND size IS NULL';
|
300 |
-
$sql = $wpdb->prepare($sql, $this->id);
|
301 |
-
}
|
302 |
-
else {
|
303 |
-
$sql = 'SELECT id FROM ' . $wpdb->prefix . 'shortpixel_postmeta WHERE attach_id = %d AND size = %s';
|
304 |
-
$sql = $wpdb->prepare($sql, $this->id, $size);
|
305 |
-
}
|
306 |
|
|
|
|
|
307 |
|
308 |
$id = $wpdb->get_var($sql);
|
309 |
|
18 |
public $mime; */
|
19 |
protected $prevent_next_try = false;
|
20 |
protected $is_main_file = false;
|
21 |
+
protected $is_retina = false; // diffentiate from thumbnail / retina.
|
22 |
protected $id; // this is the parent attachment id
|
23 |
protected $size; // size of image in WP, if applicable.
|
24 |
|
48 |
'image_meta' => $this->image_meta,
|
49 |
'name' => $this->name,
|
50 |
'path' => $this->getFullPath(),
|
51 |
+
'size' => $this->size,
|
52 |
'exists' => ($this->exists()) ? 'yes' : 'no',
|
53 |
|
54 |
);
|
66 |
$filepath = (string) $this->getFileDir();
|
67 |
$extension = $this->getExtension();
|
68 |
|
69 |
+
$retina = new MediaLibraryThumbnailModel($filepath . $filebase . '@2x.' . $extension, $this->id, $this->size); // mind the dot in after 2x
|
70 |
+
$retina->setName($this->size);
|
71 |
+
$retina->is_retina = true;
|
72 |
|
73 |
if ($retina->exists())
|
74 |
return $retina;
|
157 |
{
|
158 |
$fs = \wpSPIO()->filesystem();
|
159 |
|
160 |
+
if ($this->size == 'original' && ! $this->get('is_retina'))
|
161 |
{
|
162 |
$url = wp_get_original_image_url($this->id);
|
163 |
}
|
172 |
// https://app.asana.com/0/1200110778640816/1202589533659780
|
173 |
$size_array = image_get_intermediate_size($this->id, $this->size);
|
174 |
|
175 |
+
if ($size_array === false || ! isset($size_array['url']))
|
176 |
{
|
177 |
$url = $fs->pathToUrl($this);
|
178 |
}
|
225 |
// if thumbnail processing is off, thumbs are never processable.
|
226 |
// This is also used by main file, so check for that!
|
227 |
if ( $this->excludeThumbnails() && $this->is_main_file === false)
|
228 |
+
{
|
229 |
+
$this->processable_status = self::P_EXCLUDE_SIZE;
|
230 |
return false;
|
231 |
+
}
|
232 |
else
|
233 |
{
|
234 |
$bool = parent::isProcessable();
|
253 |
// !Important . This doubles as checking excluded image sizes.
|
254 |
protected function isSizeExcluded()
|
255 |
{
|
256 |
+
|
257 |
$excludeSizes = \wpSPIO()->settings()->excludeSizes;
|
258 |
if (is_array($excludeSizes) && in_array($this->name, $excludeSizes))
|
259 |
+
{
|
260 |
+
$this->processable_status = self::P_EXCLUDE_SIZE;
|
261 |
return true;
|
262 |
+
}
|
263 |
+
return false;
|
264 |
+
}
|
|
|
|
|
265 |
|
266 |
protected function excludeThumbnails()
|
267 |
{
|
300 |
{
|
301 |
global $wpdb;
|
302 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
303 |
|
304 |
+
$sql = 'SELECT id FROM ' . $wpdb->prefix . 'shortpixel_postmeta WHERE attach_id = %d AND size = %s';
|
305 |
+
$sql = $wpdb->prepare($sql, $this->id, $this->size);
|
306 |
|
307 |
$id = $wpdb->get_var($sql);
|
308 |
|
@@ -30,6 +30,7 @@ class StatsModel
|
|
30 |
|
31 |
protected $refreshStatTime;
|
32 |
|
|
|
33 |
// Commented out stats were dropped.
|
34 |
// Note: the difference in items / images including thumbs and the counts don't . This is due to technical difference in acquiring the data.
|
35 |
protected $defaults = array(
|
@@ -38,6 +39,7 @@ class StatsModel
|
|
38 |
'thumbs' => -1, // Optimized thumbs - SQL does thumbs, but queue doesn't. (imprecise query)
|
39 |
'itemsTotal' => -1, // Total items in media ( sql )
|
40 |
'thumbsTotal' => -1, // Total thumbs in media ( sql ) - imprecise query
|
|
|
41 |
/* 'lossy' => 0, // processed x compression
|
42 |
'lossy_thumbs' => 0, // main / thumbs
|
43 |
'lossless' => 0, // main /thumbs
|
@@ -66,6 +68,7 @@ class StatsModel
|
|
66 |
'itemsTotal' => -1,
|
67 |
'thumbsTotal' => -1,
|
68 |
),
|
|
|
69 |
/* 'total' => array('items' => 0, // total items found
|
70 |
'images' => 0, // total images found
|
71 |
), */
|
@@ -215,6 +218,9 @@ class StatsModel
|
|
215 |
case 'thumbsTotal':
|
216 |
$data = $this->countMediaThumbnails();
|
217 |
break;
|
|
|
|
|
|
|
218 |
}
|
219 |
|
220 |
if ($data >= 0)
|
@@ -291,6 +297,7 @@ class StatsModel
|
|
291 |
|
292 |
$defaults = array(
|
293 |
'optimizedOnly' => false,
|
|
|
294 |
);
|
295 |
|
296 |
$args = wp_parse_args($args,$defaults);
|
@@ -303,17 +310,27 @@ class StatsModel
|
|
303 |
}
|
304 |
else {
|
305 |
// This query will return 2 positions after the thumbnail array declaration. Value can be up to two positions ( 0-100 thumbnails) . If positions is 1-10 intval will filter out the string part.
|
306 |
-
$sql = "SELECT
|
307 |
|
308 |
$sql .= " AND post_id NOT IN ( SELECT post_id FROM " . $wpdb->postmeta . " where meta_key = '_shortpixel_prevent_optimize' )"; // exclude 'crashed items'
|
|
|
|
|
309 |
}
|
310 |
|
|
|
311 |
if (count($prepare) > 0)
|
312 |
{
|
313 |
$sql = $wpdb->prepare($sql, $prepare);
|
314 |
}
|
315 |
|
316 |
$results = $wpdb->get_results($sql);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
317 |
$thumbCount = 0;
|
318 |
|
319 |
foreach($results as $row)
|
30 |
|
31 |
protected $refreshStatTime;
|
32 |
|
33 |
+
|
34 |
// Commented out stats were dropped.
|
35 |
// Note: the difference in items / images including thumbs and the counts don't . This is due to technical difference in acquiring the data.
|
36 |
protected $defaults = array(
|
39 |
'thumbs' => -1, // Optimized thumbs - SQL does thumbs, but queue doesn't. (imprecise query)
|
40 |
'itemsTotal' => -1, // Total items in media ( sql )
|
41 |
'thumbsTotal' => -1, // Total thumbs in media ( sql ) - imprecise query
|
42 |
+
'isLimited' => false,
|
43 |
/* 'lossy' => 0, // processed x compression
|
44 |
'lossy_thumbs' => 0, // main / thumbs
|
45 |
'lossless' => 0, // main /thumbs
|
68 |
'itemsTotal' => -1,
|
69 |
'thumbsTotal' => -1,
|
70 |
),
|
71 |
+
|
72 |
/* 'total' => array('items' => 0, // total items found
|
73 |
'images' => 0, // total images found
|
74 |
), */
|
218 |
case 'thumbsTotal':
|
219 |
$data = $this->countMediaThumbnails();
|
220 |
break;
|
221 |
+
case 'isLimited':
|
222 |
+
$data = $this->stats['media']['isLimited'];
|
223 |
+
break;
|
224 |
}
|
225 |
|
226 |
if ($data >= 0)
|
297 |
|
298 |
$defaults = array(
|
299 |
'optimizedOnly' => false,
|
300 |
+
'limit' => 50000,
|
301 |
);
|
302 |
|
303 |
$args = wp_parse_args($args,$defaults);
|
310 |
}
|
311 |
else {
|
312 |
// This query will return 2 positions after the thumbnail array declaration. Value can be up to two positions ( 0-100 thumbnails) . If positions is 1-10 intval will filter out the string part.
|
313 |
+
$sql = "SELECT meta_id, post_id, substr(meta_value, instr(meta_value,'sizes')+9,2) as thumbcount, LOCATE('original_image', meta_value) as originalImage FROM " . $wpdb->postmeta . " WHERE meta_key = '_wp_attachment_metadata' ";
|
314 |
|
315 |
$sql .= " AND post_id NOT IN ( SELECT post_id FROM " . $wpdb->postmeta . " where meta_key = '_shortpixel_prevent_optimize' )"; // exclude 'crashed items'
|
316 |
+
|
317 |
+
$sql .= " limit 0," . $args['limit'];
|
318 |
}
|
319 |
|
320 |
+
|
321 |
if (count($prepare) > 0)
|
322 |
{
|
323 |
$sql = $wpdb->prepare($sql, $prepare);
|
324 |
}
|
325 |
|
326 |
$results = $wpdb->get_results($sql);
|
327 |
+
|
328 |
+
//og::addDebug('Limit and count results' . $args['limit'] . ' ' . count($results));
|
329 |
+
if ($args['limit'] <= count($results))
|
330 |
+
{
|
331 |
+
$this->stats['media']['isLimited']= true;
|
332 |
+
}
|
333 |
+
|
334 |
$thumbCount = 0;
|
335 |
|
336 |
foreach($results as $row)
|
@@ -0,0 +1,153 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
namespace ShortPixel;
|
3 |
+
use ShortPixel\ShortpixelLogger\ShortPixelLogger as Log;
|
4 |
+
|
5 |
+
class cacheRemover
|
6 |
+
{
|
7 |
+
protected $has_supercache = false; // supercache seems to replace quite fine, without our help. @todo Test if this is needed
|
8 |
+
protected $has_w3tc = false;
|
9 |
+
protected $has_wpengine = false;
|
10 |
+
protected $has_fastestcache = false;
|
11 |
+
protected $has_siteground = false;
|
12 |
+
protected $has_litespeed = false;
|
13 |
+
|
14 |
+
private static $instance;
|
15 |
+
|
16 |
+
public function __construct()
|
17 |
+
{
|
18 |
+
$this->addHooks();
|
19 |
+
}
|
20 |
+
|
21 |
+
public static function getInstance()
|
22 |
+
{
|
23 |
+
if (is_null(self::$instance))
|
24 |
+
self::$instance = new cacheRemover();
|
25 |
+
|
26 |
+
return self::$instance;
|
27 |
+
}
|
28 |
+
|
29 |
+
public function addHooks()
|
30 |
+
{
|
31 |
+
add_action('shortpixel/image/optimised', array($this, 'flushCache'));
|
32 |
+
}
|
33 |
+
|
34 |
+
/** Checks which cache plugins are active on the moment a flush is needed */
|
35 |
+
public function checkCaches()
|
36 |
+
{
|
37 |
+
if ( function_exists( 'w3tc_pgcache_flush' ) )
|
38 |
+
$this->has_w3tc = true;
|
39 |
+
|
40 |
+
if ( function_exists('wp_cache_clean_cache') )
|
41 |
+
$this->has_supercache = true;
|
42 |
+
|
43 |
+
if ( class_exists( 'WpeCommon' ) )
|
44 |
+
$this->has_wpengine = true;
|
45 |
+
|
46 |
+
global $wp_fastest_cache;
|
47 |
+
if ( method_exists( 'WpFastestCache', 'deleteCache' ) && !empty( $wp_fastest_cache ) )
|
48 |
+
$this->has_fastestcache = true;
|
49 |
+
|
50 |
+
// SG SuperCacher
|
51 |
+
if (function_exists('sg_cachepress_purge_cache')) {
|
52 |
+
$this->has_siteground = true;
|
53 |
+
}
|
54 |
+
|
55 |
+
if (defined( 'LSCWP_DIR' ))
|
56 |
+
{
|
57 |
+
$this->has_litespeed = true;
|
58 |
+
}
|
59 |
+
|
60 |
+
// @todo WpRocket?
|
61 |
+
// @todo BlueHost Caching?
|
62 |
+
}
|
63 |
+
|
64 |
+
/* Tries to flush cache there were we have issues
|
65 |
+
*
|
66 |
+
* @param Array $args Argument Array to provide data.
|
67 |
+
*/
|
68 |
+
public function flushCache($imageItem)
|
69 |
+
{
|
70 |
+
if ($imageItem->get('type') == 'custom')
|
71 |
+
{
|
72 |
+
$post_id = 0;
|
73 |
+
}
|
74 |
+
else {
|
75 |
+
$post_id = $imageItem->get('id');
|
76 |
+
}
|
77 |
+
|
78 |
+
// important - first check the available cache plugins
|
79 |
+
$this->checkCaches();
|
80 |
+
|
81 |
+
// general WP
|
82 |
+
if ($post_id > 0)
|
83 |
+
clean_post_cache($post_id);
|
84 |
+
else
|
85 |
+
wp_cache_flush();
|
86 |
+
|
87 |
+
/* Verified working without.
|
88 |
+
if ($this->has_supercache)
|
89 |
+
$this->removeSuperCache();
|
90 |
+
*/
|
91 |
+
if ($this->has_w3tc)
|
92 |
+
$this->removeW3tcCache();
|
93 |
+
|
94 |
+
if ($this->has_wpengine)
|
95 |
+
$this->removeWpeCache();
|
96 |
+
|
97 |
+
if ($this->has_siteground)
|
98 |
+
$this->removeSiteGround();
|
99 |
+
|
100 |
+
if ($this->has_fastestcache)
|
101 |
+
$this->removeFastestCache();
|
102 |
+
|
103 |
+
if ($this->has_litespeed)
|
104 |
+
$this->litespeedReset($post_id);
|
105 |
+
|
106 |
+
}
|
107 |
+
|
108 |
+
protected function removeSuperCache()
|
109 |
+
{
|
110 |
+
global $file_prefix, $supercachedir;
|
111 |
+
if ( empty( $supercachedir ) && function_exists( 'get_supercache_dir' ) ) {
|
112 |
+
$supercachedir = get_supercache_dir();
|
113 |
+
}
|
114 |
+
wp_cache_clean_cache( $file_prefix );
|
115 |
+
}
|
116 |
+
|
117 |
+
protected function removeW3tcCache()
|
118 |
+
{
|
119 |
+
w3tc_pgcache_flush();
|
120 |
+
}
|
121 |
+
|
122 |
+
protected function removeWpeCache()
|
123 |
+
{
|
124 |
+
if ( method_exists( 'WpeCommon', 'purge_memcached' ) ) {
|
125 |
+
\WpeCommon::purge_memcached();
|
126 |
+
}
|
127 |
+
if ( method_exists( 'WpeCommon', 'clear_maxcdn_cache' ) ) {
|
128 |
+
\WpeCommon::clear_maxcdn_cache();
|
129 |
+
}
|
130 |
+
if ( method_exists( 'WpeCommon', 'purge_varnish_cache' ) ) {
|
131 |
+
\WpeCommon::purge_varnish_cache();
|
132 |
+
}
|
133 |
+
}
|
134 |
+
|
135 |
+
protected function removeFastestCache()
|
136 |
+
{
|
137 |
+
global $wp_fastest_cache;
|
138 |
+
$wp_fastest_cache->deleteCache();
|
139 |
+
}
|
140 |
+
|
141 |
+
protected function removeSiteGround()
|
142 |
+
{
|
143 |
+
sg_cachepress_purge_cache();
|
144 |
+
}
|
145 |
+
|
146 |
+
protected function litespeedReset($post_id)
|
147 |
+
{
|
148 |
+
do_action('litespeed_media_reset', $post_id);
|
149 |
+
}
|
150 |
+
|
151 |
+
}
|
152 |
+
|
153 |
+
cacheRemover::getInstance();
|
@@ -1,5 +1,7 @@
|
|
1 |
<?php
|
2 |
namespace ShortPixel;
|
|
|
|
|
3 |
|
4 |
// Gravity Forms integrations.
|
5 |
class gravityForms
|
@@ -7,7 +9,7 @@ class gravityForms
|
|
7 |
|
8 |
public function __construct()
|
9 |
{
|
10 |
-
// @todo All this off, because it can only fatal error.
|
11 |
// add_filter( 'gform_save_field_value', array($this,'shortPixelGravityForms'), 10, 5 );
|
12 |
}
|
13 |
|
@@ -20,20 +22,33 @@ class gravityForms
|
|
20 |
|
21 |
public function handleGravityFormsImageField($value) {
|
22 |
|
23 |
-
$shortPixelObj = wpSPIO()->getShortPixel();
|
24 |
|
25 |
-
|
26 |
-
|
27 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
28 |
if(strpos($value , '|:|')) {
|
29 |
$cleanup = explode('|:|', $value);
|
30 |
$value = $cleanup[0];
|
31 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
32 |
//ShortPixel is monitoring the gravity forms folder, add the image to queue
|
33 |
-
|
34 |
-
|
35 |
|
36 |
-
return $shortPixelObj->addPathToCustomFolder($localPath, $folder->getId(), 0);
|
37 |
}
|
38 |
|
39 |
} // class
|
1 |
<?php
|
2 |
namespace ShortPixel;
|
3 |
+
use ShortPixel\Controller\OtherMediaController as OtherMediaController;
|
4 |
+
|
5 |
|
6 |
// Gravity Forms integrations.
|
7 |
class gravityForms
|
9 |
|
10 |
public function __construct()
|
11 |
{
|
12 |
+
// @todo All this off, because it can only fatal error.
|
13 |
// add_filter( 'gform_save_field_value', array($this,'shortPixelGravityForms'), 10, 5 );
|
14 |
}
|
15 |
|
22 |
|
23 |
public function handleGravityFormsImageField($value) {
|
24 |
|
|
|
25 |
|
26 |
+
$fs = \wpSPIO()->filesystem();
|
27 |
+
$otherMediaController = OtherMediaController::getInstance();
|
28 |
+
$uploadBase = $fs->getWPUploadBase();
|
29 |
+
|
30 |
+
|
31 |
+
$gravFolder = $otherMediaController->getFolderByPath($uploadBase->getPath() . 'gravity_forms');
|
32 |
+
|
33 |
+
if (! $gravFolder->exists())
|
34 |
+
return false;
|
35 |
+
|
36 |
+
/* no clue what this legacy is suppposed to be.
|
37 |
if(strpos($value , '|:|')) {
|
38 |
$cleanup = explode('|:|', $value);
|
39 |
$value = $cleanup[0];
|
40 |
}
|
41 |
+
*/
|
42 |
+
if (! $gravFolder->get('in_db'))
|
43 |
+
{
|
44 |
+
$otherMediaController->addDirectory($gravFolder->getPath());
|
45 |
+
}
|
46 |
+
|
47 |
//ShortPixel is monitoring the gravity forms folder, add the image to queue
|
48 |
+
// $uploadDir = wp_upload_dir();
|
49 |
+
//$localPath = str_replace($uploadDir['baseurl'], SHORTPIXEL_UPLOADS_BASE, $value);
|
50 |
|
51 |
+
//return $shortPixelObj->addPathToCustomFolder($localPath, $folder->getId(), 0);
|
52 |
}
|
53 |
|
54 |
} // class
|
@@ -22,6 +22,10 @@ class WpCliController
|
|
22 |
|
23 |
public function __construct()
|
24 |
{
|
|
|
|
|
|
|
|
|
25 |
$this->initCommands();
|
26 |
}
|
27 |
|
@@ -30,6 +34,8 @@ class WpCliController
|
|
30 |
if (is_null(self::$instance))
|
31 |
self::$instance = new WpCliController();
|
32 |
|
|
|
|
|
33 |
return self::$instance;
|
34 |
}
|
35 |
|
@@ -52,12 +58,12 @@ class SpioCommandBase
|
|
52 |
|
53 |
protected static $runs = 0;
|
54 |
/**
|
55 |
-
*
|
56 |
*
|
57 |
* ## OPTIONS
|
58 |
*
|
59 |
* <id>
|
60 |
-
* :
|
61 |
*
|
62 |
*
|
63 |
* [--type=<type>]
|
@@ -70,12 +76,13 @@ class SpioCommandBase
|
|
70 |
* ---
|
71 |
*
|
72 |
* [--halt]
|
73 |
-
|
74 |
-
|
75 |
*
|
76 |
* ## EXAMPLES
|
77 |
*
|
78 |
-
* wp spio add
|
|
|
79 |
*
|
80 |
* @when after_wp_load
|
81 |
*/
|
@@ -126,35 +133,39 @@ class SpioCommandBase
|
|
126 |
|
127 |
|
128 |
/**
|
129 |
-
*
|
|
|
|
|
130 |
*
|
131 |
-
*
|
132 |
*
|
133 |
* ## OPTIONS
|
134 |
*
|
135 |
* [--ticks=<number>]
|
136 |
-
* : How
|
137 |
* ---
|
138 |
*
|
139 |
-
* [--wait=<
|
140 |
-
* : How
|
141 |
* ---
|
142 |
* default: 3
|
143 |
* ---
|
144 |
*
|
145 |
-
*
|
146 |
-
*
|
147 |
* [--queue=<name>]
|
148 |
-
* : Either 'media' or 'custom'
|
149 |
* ---
|
150 |
* default: media,custom
|
151 |
* ---
|
|
|
|
|
|
|
|
|
152 |
*
|
153 |
* ## EXAMPLES
|
154 |
*
|
155 |
-
|
156 |
-
* wp spio run --ticks=20 --wait=3 | Ticks and wait time.
|
157 |
-
|
158 |
*
|
159 |
*
|
160 |
* @when after_wp_load
|
@@ -380,30 +391,30 @@ class SpioCommandBase
|
|
380 |
protected function displayStatsLine($name, $stats)
|
381 |
{
|
382 |
|
383 |
-
$line = sprintf('Current Status for %s : (%
|
384 |
|
385 |
\WP_CLI::line($line);
|
386 |
}
|
387 |
|
388 |
-
/**
|
|
|
|
|
|
|
|
|
|
|
389 |
*
|
390 |
-
|
391 |
-
* : Dump more information for debugging
|
392 |
*
|
|
|
393 |
*
|
394 |
-
* ---
|
395 |
-
*
|
396 |
-
* ## EXAMPLES
|
397 |
-
*
|
398 |
-
* wp spio status [--show-debug]
|
399 |
-
*
|
400 |
*/
|
401 |
public function status($args, $assoc)
|
402 |
{
|
403 |
-
$queue = $this->getQueueArgument($assoc);
|
404 |
|
|
|
405 |
$startupData = $this->getStatus();
|
406 |
|
|
|
407 |
$items = array();
|
408 |
$fields = array('queue name', 'in queue', 'in process', 'fatal errors', 'done', 'total', 'preparing', 'running', 'finished');
|
409 |
|
@@ -436,14 +447,15 @@ class SpioCommandBase
|
|
436 |
\WP_CLI\Utils\format_items('table', $items, $fields);
|
437 |
}
|
438 |
|
439 |
-
/**
|
|
|
440 |
*
|
441 |
*
|
442 |
* ---
|
443 |
*
|
444 |
* ## EXAMPLES
|
445 |
*
|
446 |
-
* wp settings
|
447 |
*
|
448 |
*/
|
449 |
public function settings()
|
@@ -464,17 +476,20 @@ class SpioCommandBase
|
|
464 |
}
|
465 |
|
466 |
/**
|
467 |
-
*
|
468 |
*
|
469 |
*
|
470 |
* [--queue=<name>]
|
471 |
-
* : Either 'media' or 'custom'
|
472 |
* ---
|
473 |
* default: media,custom
|
474 |
* options:
|
475 |
* - media
|
476 |
* - custom
|
477 |
*
|
|
|
|
|
|
|
478 |
*/
|
479 |
public function clear($args, $assoc)
|
480 |
{
|
22 |
|
23 |
public function __construct()
|
24 |
{
|
25 |
+
$log = \ShortPixel\ShortPixelLogger\ShortPixelLogger::getInstance();
|
26 |
+
if (\ShortPixel\ShortPixelLogger\ShortPixelLogger::debugIsActive())
|
27 |
+
$log->setLogPath(SHORTPIXEL_BACKUP_FOLDER . "/shortpixel_log_wpcli");
|
28 |
+
|
29 |
$this->initCommands();
|
30 |
}
|
31 |
|
34 |
if (is_null(self::$instance))
|
35 |
self::$instance = new WpCliController();
|
36 |
|
37 |
+
|
38 |
+
|
39 |
return self::$instance;
|
40 |
}
|
41 |
|
58 |
|
59 |
protected static $runs = 0;
|
60 |
/**
|
61 |
+
* Adds a single item to the queue(s).
|
62 |
*
|
63 |
* ## OPTIONS
|
64 |
*
|
65 |
* <id>
|
66 |
+
* : Media Library ID or Custom Media ID
|
67 |
*
|
68 |
*
|
69 |
* [--type=<type>]
|
76 |
* ---
|
77 |
*
|
78 |
* [--halt]
|
79 |
+
* : Stops (does not process the queues) after the item is added.
|
80 |
+
*
|
81 |
*
|
82 |
* ## EXAMPLES
|
83 |
*
|
84 |
+
* wp spio [bulk] add 123
|
85 |
+
* wp spio [bulk] add 21 --type=custom --halt
|
86 |
*
|
87 |
* @when after_wp_load
|
88 |
*/
|
133 |
|
134 |
|
135 |
/**
|
136 |
+
* Starts processing what has been added to the processing queue(s), optionally stopping after a specified number of "ticks".
|
137 |
+
*
|
138 |
+
* A tick (or cycle) means a request sent to the API, either to send an image to be processed or to check if the API has completed processing. Use the ticks (cycles) if you want to run the script regularly (every few minutes) want to run the script.
|
139 |
*
|
140 |
+
* If you do not define ticks, the queue will run until everything has been processed.
|
141 |
*
|
142 |
* ## OPTIONS
|
143 |
*
|
144 |
* [--ticks=<number>]
|
145 |
+
* : How often the queue runs (how many ticks/cycles)
|
146 |
* ---
|
147 |
*
|
148 |
+
* [--wait=<seconds>]
|
149 |
+
* : How many seconds the system waits for next tick (cycle).
|
150 |
* ---
|
151 |
* default: 3
|
152 |
* ---
|
153 |
*
|
|
|
|
|
154 |
* [--queue=<name>]
|
155 |
+
* : Either 'media' or 'custom'. Omit the parameter to run both queues.
|
156 |
* ---
|
157 |
* default: media,custom
|
158 |
* ---
|
159 |
+
* options:
|
160 |
+
* - media
|
161 |
+
* - custom
|
162 |
+
* ---
|
163 |
*
|
164 |
* ## EXAMPLES
|
165 |
*
|
166 |
+
* wp spio [bulk] run | Complete all processes
|
167 |
+
* wp spio [bulk] run --ticks=20 --wait=3 | Ticks and wait time.
|
168 |
+
* wp spio [bulk] run --queue=media | Only run a specific queue.
|
169 |
*
|
170 |
*
|
171 |
* @when after_wp_load
|
391 |
protected function displayStatsLine($name, $stats)
|
392 |
{
|
393 |
|
394 |
+
$line = sprintf('Current Status for %s : (%s\%s) Done (%s%%), %s awaiting %s errors --', $name, $stats->done, $stats->total, $stats->percentage_done, ( $stats->awaiting ), $stats->fatal_errors);
|
395 |
|
396 |
\WP_CLI::line($line);
|
397 |
}
|
398 |
|
399 |
+
/**
|
400 |
+
* Displays the current status of the processing queue(s)
|
401 |
+
*
|
402 |
+
* [--show-debug]
|
403 |
+
* : Dumps more information for debugging purposes
|
404 |
+
* ---
|
405 |
*
|
406 |
+
* ## EXAMPLES
|
|
|
407 |
*
|
408 |
+
* wp spio [bulk] status [--show-debug]
|
409 |
*
|
|
|
|
|
|
|
|
|
|
|
|
|
410 |
*/
|
411 |
public function status($args, $assoc)
|
412 |
{
|
|
|
413 |
|
414 |
+
$queue = $this->getQueueArgument($assoc);
|
415 |
$startupData = $this->getStatus();
|
416 |
|
417 |
+
|
418 |
$items = array();
|
419 |
$fields = array('queue name', 'in queue', 'in process', 'fatal errors', 'done', 'total', 'preparing', 'running', 'finished');
|
420 |
|
447 |
\WP_CLI\Utils\format_items('table', $items, $fields);
|
448 |
}
|
449 |
|
450 |
+
/**
|
451 |
+
* Displays the key settings that are applied when executing commands with WP-CLI.
|
452 |
*
|
453 |
*
|
454 |
* ---
|
455 |
*
|
456 |
* ## EXAMPLES
|
457 |
*
|
458 |
+
* wp spio [bulk] settings
|
459 |
*
|
460 |
*/
|
461 |
public function settings()
|
476 |
}
|
477 |
|
478 |
/**
|
479 |
+
* Clears the Queue(s)
|
480 |
*
|
481 |
*
|
482 |
* [--queue=<name>]
|
483 |
+
* : Either 'media' or 'custom'. Omit the parameter to clear both queues.
|
484 |
* ---
|
485 |
* default: media,custom
|
486 |
* options:
|
487 |
* - media
|
488 |
* - custom
|
489 |
*
|
490 |
+
* ## EXAMPLES
|
491 |
+
*
|
492 |
+
* wp spio [bulk] clear
|
493 |
*/
|
494 |
public function clear($args, $assoc)
|
495 |
{
|
@@ -8,29 +8,29 @@ use ShortPixel\Controller\Queue\Queue as Queue;
|
|
8 |
use ShortPixel\Controller\ApiController as ApiController;
|
9 |
use ShortPixel\Controller\ResponseController as ResponseController;
|
10 |
|
11 |
-
|
|
|
|
|
12 |
class SpioBulk extends SpioCommandBase
|
13 |
{
|
14 |
/**
|
15 |
-
* Starts prepared queue. The bulk needs an express command to start
|
16 |
-
*
|
17 |
*
|
18 |
* ## OPTIONS
|
19 |
|
20 |
* [--queue=<name>]
|
21 |
-
* : Either 'media' or 'custom'
|
22 |
* ---
|
23 |
* default: media,custom
|
24 |
* options:
|
25 |
* - media
|
26 |
* - custom
|
27 |
-
*
|
28 |
* ---
|
29 |
*
|
30 |
* ## EXAMPLES
|
31 |
*
|
32 |
-
*
|
33 |
-
* wp spio start
|
34 |
*
|
35 |
*
|
36 |
* @when after_wp_load
|
@@ -54,13 +54,24 @@ class SpioBulk extends SpioCommandBase
|
|
54 |
}
|
55 |
|
56 |
|
57 |
-
|
58 |
-
|
59 |
-
|
60 |
-
|
61 |
-
|
62 |
-
|
63 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
64 |
public function auto($args, $assoc)
|
65 |
{
|
66 |
$queue = $this->getQueueArgument($assoc);
|
@@ -100,7 +111,7 @@ class SpioBulk extends SpioCommandBase
|
|
100 |
}
|
101 |
elseif ($combined->is_finished)
|
102 |
{
|
103 |
-
if ($created) // means we already ran the whole thing once.
|
104 |
{
|
105 |
\WP_CLI::Line('[Auto Bulk] Seems finished and done running');
|
106 |
$running = false;
|
@@ -127,18 +138,23 @@ class SpioBulk extends SpioCommandBase
|
|
127 |
}
|
128 |
|
129 |
/**
|
130 |
-
*
|
131 |
*
|
132 |
* ## OPTIONS
|
133 |
*
|
134 |
* [--queue=<name>]
|
135 |
-
* : Either 'media' or 'custom'
|
|
|
|
|
|
|
|
|
|
|
|
|
136 |
*
|
137 |
* ## EXAMPLES
|
138 |
*
|
139 |
-
*
|
140 |
*
|
141 |
-
|
142 |
*
|
143 |
* @when after_wp_load
|
144 |
*/
|
@@ -164,29 +180,28 @@ class SpioBulk extends SpioCommandBase
|
|
164 |
return $stats;
|
165 |
}
|
166 |
|
167 |
-
|
168 |
-
|
169 |
-
|
170 |
-
|
171 |
-
|
172 |
*
|
173 |
* <end-id>
|
174 |
* : ID to stop restore
|
175 |
*
|
176 |
-
|
177 |
-
|
178 |
-
|
179 |
-
|
180 |
-
|
181 |
-
|
182 |
-
|
183 |
-
|
184 |
-
|
185 |
* ## EXAMPLES
|
186 |
*
|
187 |
* wp spio bulk restore 0 100
|
188 |
*
|
189 |
-
|
190 |
*
|
191 |
* @when after_wp_load
|
192 |
*/
|
@@ -216,19 +231,24 @@ class SpioBulk extends SpioCommandBase
|
|
216 |
return $optimizeController;
|
217 |
}
|
218 |
|
219 |
-
|
220 |
-
|
221 |
-
|
222 |
-
|
223 |
-
|
224 |
-
|
225 |
-
|
226 |
-
|
227 |
-
|
228 |
-
|
229 |
-
|
230 |
-
|
231 |
-
|
|
|
|
|
|
|
|
|
|
|
232 |
public function prepare($args, $assoc)
|
233 |
{
|
234 |
$queues = $this->getQueueArgument($assoc);
|
8 |
use ShortPixel\Controller\ApiController as ApiController;
|
9 |
use ShortPixel\Controller\ResponseController as ResponseController;
|
10 |
|
11 |
+
/**
|
12 |
+
* Actions for running bulk operations from WP-CLI
|
13 |
+
*/
|
14 |
class SpioBulk extends SpioCommandBase
|
15 |
{
|
16 |
/**
|
17 |
+
* Starts the prepared queue(s). The bulk needs an express command to start processing.
|
18 |
+
* Once started, the queue(s) can be processed and finished with the run command.
|
19 |
*
|
20 |
* ## OPTIONS
|
21 |
|
22 |
* [--queue=<name>]
|
23 |
+
* : Either 'media' or 'custom'. Omit the parameter to start both queues.
|
24 |
* ---
|
25 |
* default: media,custom
|
26 |
* options:
|
27 |
* - media
|
28 |
* - custom
|
|
|
29 |
* ---
|
30 |
*
|
31 |
* ## EXAMPLES
|
32 |
*
|
33 |
+
* wp spio bulk start
|
|
|
34 |
*
|
35 |
*
|
36 |
* @when after_wp_load
|
54 |
}
|
55 |
|
56 |
|
57 |
+
/**
|
58 |
+
* Automatically Bulk Processes everything that needs to be done.
|
59 |
+
*
|
60 |
+
* [--queue=<name>]
|
61 |
+
* : Either 'media' or 'custom'. Omit the parameter to process both queues.
|
62 |
+
* ---
|
63 |
+
* default: media,custom
|
64 |
+
* options:
|
65 |
+
* - media
|
66 |
+
* - custom
|
67 |
+
* ---
|
68 |
+
*
|
69 |
+
* ## EXAMPLES
|
70 |
+
*
|
71 |
+
* wp spio bulk auto
|
72 |
+
*
|
73 |
+
*
|
74 |
+
*/
|
75 |
public function auto($args, $assoc)
|
76 |
{
|
77 |
$queue = $this->getQueueArgument($assoc);
|
111 |
}
|
112 |
elseif ($combined->is_finished)
|
113 |
{
|
114 |
+
if ($combined->done > 0 || $created == true) // means we already ran the whole thing once.
|
115 |
{
|
116 |
\WP_CLI::Line('[Auto Bulk] Seems finished and done running');
|
117 |
$running = false;
|
138 |
}
|
139 |
|
140 |
/**
|
141 |
+
* Creates the queue(s) for bulk optimization of media library and/or custom media items.
|
142 |
*
|
143 |
* ## OPTIONS
|
144 |
*
|
145 |
* [--queue=<name>]
|
146 |
+
* : Either 'media' or 'custom'. Omit the parameter to create both queues.
|
147 |
+
* ---
|
148 |
+
* default: media,custom
|
149 |
+
* options:
|
150 |
+
* - media
|
151 |
+
* - custom
|
152 |
+
* ---
|
153 |
*
|
154 |
* ## EXAMPLES
|
155 |
*
|
156 |
+
* wp spio bulk create
|
157 |
*
|
|
|
158 |
*
|
159 |
* @when after_wp_load
|
160 |
*/
|
180 |
return $stats;
|
181 |
}
|
182 |
|
183 |
+
/**
|
184 |
+
* ## OPTIONS
|
185 |
+
*
|
186 |
+
* <start-id>
|
187 |
+
* : ID to start restore
|
188 |
*
|
189 |
* <end-id>
|
190 |
* : ID to stop restore
|
191 |
*
|
192 |
+
* [--type=<type>]
|
193 |
+
* : media or custom
|
194 |
+
* ---
|
195 |
+
* default: media
|
196 |
+
* options:
|
197 |
+
* - media
|
198 |
+
* - custom
|
199 |
+
* ---
|
200 |
+
*
|
201 |
* ## EXAMPLES
|
202 |
*
|
203 |
* wp spio bulk restore 0 100
|
204 |
*
|
|
|
205 |
*
|
206 |
* @when after_wp_load
|
207 |
*/
|
231 |
return $optimizeController;
|
232 |
}
|
233 |
|
234 |
+
/**
|
235 |
+
* Prepares the items by adding them to the queue(s). It runs only when the queue is in the preparing phase and finishes when everything is prepared.
|
236 |
+
*
|
237 |
+
*
|
238 |
+
* [--queue=<name>]
|
239 |
+
* : Either 'media' or 'custom'. Omit the parameter to run both queues.
|
240 |
+
* ---
|
241 |
+
* default: media,custom
|
242 |
+
* options:
|
243 |
+
* - media
|
244 |
+
* - custom
|
245 |
+
* ---
|
246 |
+
*
|
247 |
+
* ## EXAMPLES
|
248 |
+
*
|
249 |
+
* wp spio bulk prepare
|
250 |
+
*
|
251 |
+
*/
|
252 |
public function prepare($args, $assoc)
|
253 |
{
|
254 |
$queues = $this->getQueueArgument($assoc);
|
@@ -8,19 +8,22 @@ use ShortPixel\Controller\Queue\Queue as Queue;
|
|
8 |
use ShortPixel\Controller\ApiController as ApiController;
|
9 |
use ShortPixel\Controller\ResponseController as ResponseController;
|
10 |
|
|
|
|
|
|
|
11 |
class SpioSingle extends SpioCommandBase
|
12 |
{
|
13 |
|
14 |
/**
|
15 |
-
* Restores optimized item to original (
|
16 |
*
|
17 |
* ## OPTIONS
|
18 |
*
|
19 |
* <id>
|
20 |
-
* :
|
21 |
*
|
22 |
* [--type=<type>]
|
23 |
-
* :
|
24 |
* ---
|
25 |
* default: media
|
26 |
* options:
|
@@ -30,8 +33,8 @@ class SpioSingle extends SpioCommandBase
|
|
30 |
*
|
31 |
* ## EXAMPLES
|
32 |
*
|
33 |
-
* wp spio restore
|
34 |
-
|
35 |
*
|
36 |
* @when after_wp_load
|
37 |
*/
|
8 |
use ShortPixel\Controller\ApiController as ApiController;
|
9 |
use ShortPixel\Controller\ResponseController as ResponseController;
|
10 |
|
11 |
+
/**
|
12 |
+
* Actions and operations for the ShortPixel Image Optimizer plugin
|
13 |
+
*/
|
14 |
class SpioSingle extends SpioCommandBase
|
15 |
{
|
16 |
|
17 |
/**
|
18 |
+
* Restores the optimized item to its original state (if backups are active).
|
19 |
*
|
20 |
* ## OPTIONS
|
21 |
*
|
22 |
* <id>
|
23 |
+
* : Media Library ID or Custom Media ID
|
24 |
*
|
25 |
* [--type=<type>]
|
26 |
+
* : media | custom
|
27 |
* ---
|
28 |
* default: media
|
29 |
* options:
|
33 |
*
|
34 |
* ## EXAMPLES
|
35 |
*
|
36 |
+
* wp spio restore 123
|
37 |
+
* wp spio restore 21 --type=custom
|
38 |
*
|
39 |
* @when after_wp_load
|
40 |
*/
|
@@ -17,7 +17,6 @@ class ShortPixelImgToPictureWebp
|
|
17 |
return $content; // . (isset($_GET['SHORTPIXEL_DEBUG']) ? '<!-- -->' : '');
|
18 |
}
|
19 |
|
20 |
-
|
21 |
$new_content = $this->testPictures($content);
|
22 |
if ($new_content !== false)
|
23 |
{
|
@@ -36,7 +35,7 @@ class ShortPixelImgToPictureWebp
|
|
36 |
// [BS] No callback because we need preg_match_all
|
37 |
$content = $this->testInlineStyle($content);
|
38 |
// $content = preg_replace_callback('/background.*[^:]url\([\'|"](.*)[\'|"]\)[,;]/imU',array('self', 'convertInlineStyle'), $content);
|
39 |
-
|
40 |
|
41 |
return $content; // . (isset($_GET['SHORTPIXEL_DEBUG']) ? '<!-- SPDBG WebP converted -->' : '');
|
42 |
|
@@ -216,7 +215,7 @@ class ShortPixelImgToPictureWebp
|
|
216 |
continue;
|
217 |
$condition = isset($parts[1]) ? ' ' . $parts[1] : '';
|
218 |
|
219 |
-
|
220 |
|
221 |
$fsFile = $fs->getFile($fileurl);
|
222 |
$extension = $fsFile->getExtension(); // trigger setFileinfo, which will resolve URL -> Path
|
17 |
return $content; // . (isset($_GET['SHORTPIXEL_DEBUG']) ? '<!-- -->' : '');
|
18 |
}
|
19 |
|
|
|
20 |
$new_content = $this->testPictures($content);
|
21 |
if ($new_content !== false)
|
22 |
{
|
35 |
// [BS] No callback because we need preg_match_all
|
36 |
$content = $this->testInlineStyle($content);
|
37 |
// $content = preg_replace_callback('/background.*[^:]url\([\'|"](.*)[\'|"]\)[,;]/imU',array('self', 'convertInlineStyle'), $content);
|
38 |
+
// Log::addDebug('SPDBG WebP process done');
|
39 |
|
40 |
return $content; // . (isset($_GET['SHORTPIXEL_DEBUG']) ? '<!-- SPDBG WebP converted -->' : '');
|
41 |
|
215 |
continue;
|
216 |
$condition = isset($parts[1]) ? ' ' . $parts[1] : '';
|
217 |
|
218 |
+
// Log::addDebug('Running item - ' . $item, $fileurl);
|
219 |
|
220 |
$fsFile = $fs->getFile($fileurl);
|
221 |
$extension = $fsFile->getExtension(); // trigger setFileinfo, which will resolve URL -> Path
|
@@ -1 +1 @@
|
|
1 |
-
{"name":"ShortPixel\/Plugin","description":"ShortPixel AutoLoader","type":"function","autoload":{"psr-4":{"ShortPixel":"class"},"files":["class\/wp-shortpixel-settings.php","class\/shortpixel-png2jpg.php","class\/front\/img-to-picture-webp.php","class\/external\/cloudflare.php","class\/external\/flywheel.php","class\/external\/nextgen\/nextGenController.php","class\/external\/nextgen\/nextGenViewController.php","class\/external\/visualcomposer.php","class\/external\/wp-offload-media.php","class\/external\/wp-cli\/wp-cli-base.php","class\/external\/wp-cli\/wp-cli-single.php","class\/external\/wp-cli\/wp-cli-bulk.php","class\/external\/custom-suffixes.php","class\/external\/pantheon.php","class\/external\/spai.php"]}}
|
1 |
+
{"name":"ShortPixel\/Plugin","description":"ShortPixel AutoLoader","type":"function","autoload":{"psr-4":{"ShortPixel":"class"},"files":["class\/wp-shortpixel-settings.php","class\/shortpixel-png2jpg.php","class\/front\/img-to-picture-webp.php","class\/external\/cloudflare.php","class\/external\/flywheel.php","class\/external\/nextgen\/nextGenController.php","class\/external\/nextgen\/nextGenViewController.php","class\/external\/visualcomposer.php","class\/external\/wp-offload-media.php","class\/external\/wp-cli\/wp-cli-base.php","class\/external\/wp-cli\/wp-cli-single.php","class\/external\/wp-cli\/wp-cli-bulk.php","class\/external\/custom-suffixes.php","class\/external\/pantheon.php","class\/external\/spai.php","class\/external\/cache.php"]}}
|
@@ -35,8 +35,14 @@ $approx = $this->view->approx;
|
|
35 |
<h2><?php esc_html_e('Optimize:','shortpixel-image-optimiser'); ?> </h2>
|
36 |
<p><?php printf(esc_html__('ShortPixel has %sestimated%s the number of images that can still be optimized. %sAfter you select the options, the plugin will calculate exactly how many images to optimize.','shortpixel-image-optimiser'), '<b>','</b>', '<br />'); ?></p>
|
37 |
|
|
|
|
|
|
|
|
|
|
|
38 |
<div class="media-library optiongroup">
|
39 |
|
|
|
40 |
<div class='switch_button'>
|
41 |
<label>
|
42 |
<input type="checkbox" class="switch" id="media_checkbox" checked>
|
@@ -50,6 +56,7 @@ $approx = $this->view->approx;
|
|
50 |
<label><?php esc_html_e('Images (estimate)', 'shortpixel-image-optimiser'); ?></label>
|
51 |
<span class="number" ><?php echo esc_html($approx->media->items) ?></span>
|
52 |
</div>
|
|
|
53 |
<?php if (\wpSPIO()->settings()->processThumbnails == 1): ?>
|
54 |
<div class='option'>
|
55 |
<label><?php esc_html_e('Thumbnails (estimate)','shortpixel-image-optimiser'); ?></label> <span class="number" ><?php echo esc_html($approx->media->thumbs) ?> </span>
|
@@ -106,7 +113,7 @@ $approx = $this->view->approx;
|
|
106 |
|
107 |
</div>
|
108 |
<h4><label for="webp_checkbox">
|
109 |
-
<?php printf(esc_html__('Also create
|
110 |
</label></h4>
|
111 |
<div class="option"><?php esc_html_e('The total number of WebP images will be calculated in the next step.','shortpixel-image-optimiser'); ?></div>
|
112 |
</div>
|
@@ -121,7 +128,7 @@ $approx = $this->view->approx;
|
|
121 |
</label>
|
122 |
|
123 |
</div>
|
124 |
-
<h4><label for="avif_checkbox"><?php esc_html_e('Also create AVIF
|
125 |
<div class="option"><?php esc_html_e('The total number of AVIF images will be calculated in the next step.','shortpixel-image-optimiser'); ?></div>
|
126 |
</div>
|
127 |
</div>
|
@@ -135,7 +142,7 @@ $approx = $this->view->approx;
|
|
135 |
<h4 class='approx'><?php esc_html_e('An estimate of unoptimized images in this installation', 'shortpixel-image-optimiser'); ?> :
|
136 |
<span data-check-approx-total><?php echo esc_html($approx->total->images) ?></span> </h4>
|
137 |
|
138 |
-
<div><p><?php printf(
|
139 |
</div>
|
140 |
|
141 |
<nav>
|
35 |
<h2><?php esc_html_e('Optimize:','shortpixel-image-optimiser'); ?> </h2>
|
36 |
<p><?php printf(esc_html__('ShortPixel has %sestimated%s the number of images that can still be optimized. %sAfter you select the options, the plugin will calculate exactly how many images to optimize.','shortpixel-image-optimiser'), '<b>','</b>', '<br />'); ?></p>
|
37 |
|
38 |
+
<?php if ($approx->media->isLimited): ?>
|
39 |
+
<h4 class='count_limited'><?php esc_html_e('Shortpixel has detected a high number of images. This estimates are limited for performance reasons. On the next step an accurate count will be produced', 'shortpixel-image-optimiser'); ?></h4>
|
40 |
+
<?php endif; ?>
|
41 |
+
|
42 |
+
|
43 |
<div class="media-library optiongroup">
|
44 |
|
45 |
+
|
46 |
<div class='switch_button'>
|
47 |
<label>
|
48 |
<input type="checkbox" class="switch" id="media_checkbox" checked>
|
56 |
<label><?php esc_html_e('Images (estimate)', 'shortpixel-image-optimiser'); ?></label>
|
57 |
<span class="number" ><?php echo esc_html($approx->media->items) ?></span>
|
58 |
</div>
|
59 |
+
|
60 |
<?php if (\wpSPIO()->settings()->processThumbnails == 1): ?>
|
61 |
<div class='option'>
|
62 |
<label><?php esc_html_e('Thumbnails (estimate)','shortpixel-image-optimiser'); ?></label> <span class="number" ><?php echo esc_html($approx->media->thumbs) ?> </span>
|
113 |
|
114 |
</div>
|
115 |
<h4><label for="webp_checkbox">
|
116 |
+
<?php printf(esc_html__('Also create WebP versions of the images' ,'shortpixel-image-optimiser') ); ?>
|
117 |
</label></h4>
|
118 |
<div class="option"><?php esc_html_e('The total number of WebP images will be calculated in the next step.','shortpixel-image-optimiser'); ?></div>
|
119 |
</div>
|
128 |
</label>
|
129 |
|
130 |
</div>
|
131 |
+
<h4><label for="avif_checkbox"><?php esc_html_e('Also create AVIF versions of the images','shortpixel-image-optimiser'); ?></label></h4>
|
132 |
<div class="option"><?php esc_html_e('The total number of AVIF images will be calculated in the next step.','shortpixel-image-optimiser'); ?></div>
|
133 |
</div>
|
134 |
</div>
|
142 |
<h4 class='approx'><?php esc_html_e('An estimate of unoptimized images in this installation', 'shortpixel-image-optimiser'); ?> :
|
143 |
<span data-check-approx-total><?php echo esc_html($approx->total->images) ?></span> </h4>
|
144 |
|
145 |
+
<div><p><?php printf(__('In the next step, the plugin will calculate the total number of images to be optimized, and your bulk process will be prepared. The processing %s will not start yet %s, but a summary of the images to be optimized will be displayed.', 'shortpixel-image-optimiser'),'<b>','</b>'); ?></p></div>
|
146 |
</div>
|
147 |
|
148 |
<nav>
|
@@ -19,7 +19,7 @@ namespace ShortPixel;
|
|
19 |
</h3>
|
20 |
<div class="section-wrapper" data-check-visibility data-control="data-check-media-total">
|
21 |
<h4><span class='dashicons dashicons-images-alt2'> </span>
|
22 |
-
<?php esc_html_e('Media Library','shortpixel-image-optimiser'); ?> (<span data-stats-media="in_queue">0</span> <?php esc_html_e('items','shortpixel-image-optimiser');
|
23 |
<div class="list-table">
|
24 |
|
25 |
|
@@ -41,7 +41,7 @@ namespace ShortPixel;
|
|
41 |
</div>
|
42 |
|
43 |
<div class="section-wrapper" data-check-visibility data-control="data-check-custom-total">
|
44 |
-
<h4><span class='dashicons dashicons-open-folder'> </span><?php esc_html_e('Custom Media', 'shortpixel-image-optimiser') ?> (<span data-stats-custom="in_queue">0</span> <?php esc_html_e('
|
45 |
<div class="list-table">
|
46 |
|
47 |
<div><span><?php esc_html_e('Images','shortpixel-image-optimiser'); ?></span>
|
19 |
</h3>
|
20 |
<div class="section-wrapper" data-check-visibility data-control="data-check-media-total">
|
21 |
<h4><span class='dashicons dashicons-images-alt2'> </span>
|
22 |
+
<?php esc_html_e('Media Library','shortpixel-image-optimiser'); ?> (<span data-stats-media="in_queue">0</span> <?php esc_html_e('items','shortpixel-image-optimiser'); ?>)</h4>
|
23 |
<div class="list-table">
|
24 |
|
25 |
|
41 |
</div>
|
42 |
|
43 |
<div class="section-wrapper" data-check-visibility data-control="data-check-custom-total">
|
44 |
+
<h4><span class='dashicons dashicons-open-folder'> </span><?php esc_html_e('Custom Media', 'shortpixel-image-optimiser') ?> (<span data-stats-custom="in_queue">0</span> <?php esc_html_e('items','shortpixel-image-optimiser'); ?>)</h4>
|
45 |
<div class="list-table">
|
46 |
|
47 |
<div><span><?php esc_html_e('Images','shortpixel-image-optimiser'); ?></span>
|
@@ -321,54 +321,70 @@ use \ShortPixel\Helper\UiHelper as UiHelper;
|
|
321 |
<div class="option-content">
|
322 |
<div class="spio-inline-help"><span class="dashicons dashicons-editor-help" title="Click for more info" data-link="https://shortpixel.com/knowledge-base/article/88-how-to-exclude-images-from-being-optimized"></span></div>
|
323 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
324 |
<textarea name="excludePatterns" type="text" id="excludePatterns" placeholder="<?php
|
325 |
esc_html_e('name:keepbig, path:/full/path/to/exclude/, regex-name:/valid_regex/, size:1000x2000','shortpixel-image-optimiser');?>" rows="4" cols="60"><?php echo esc_html( $excludePatterns );?></textarea>
|
326 |
|
327 |
</div>
|
328 |
-
|
329 |
-
|
330 |
-
|
331 |
-
printf(esc_html__('Add patterns separated by comma. A pattern consist of a %stype:value%s pair; the accepted types are
|
332 |
-
%s"name"%s, %s"path"%s, %s"size"%s, %s"regex-name"%s and %s"regex-path"%s.
|
333 |
-
A file is excluded if it matches any of the patterns. %s
|
334 |
-
|
335 |
-
%s For a %s"name"%s pattern only the filename is matched, for %s"path"%s,
|
336 |
-
the whole path will be matched (useful for excluding certain (sub)-directories altoghether).
|
337 |
-
%s %s
|
338 |
-
%s"regex-path"%s and %s"regex-name"%s work the same, except it requires a valid regular expression, contained between slashes. Special characters should be escaped by adding \ in front of them.
|
339 |
-
%s %s
|
340 |
-
|
341 |
-
For the %s"size"%s type, which applies only to Media Library images, %sthe main images (not thumbnails)%s that have the size in the specified range are excluded.
|
342 |
-
The format for the "size" exclude is: %sminWidth%s- %smaxWidth%sx%sminHeight%s%s>maxHeight%s, for example %ssize:1000-1100x2000-2200%s. You can also specify a precise size, such as %s1000x2000%s.','shortpixel-image-optimiser'),
|
343 |
-
'<strong>', '</strong>',
|
344 |
-
'<strong>', '</strong>',
|
345 |
-
'<strong>', '</strong>',
|
346 |
-
'<strong>', '</strong>',
|
347 |
-
'<strong>', '</strong>',
|
348 |
-
'<strong>', '</strong>',
|
349 |
-
'<br>',
|
350 |
-
'<br>',
|
351 |
-
'<strong>', '</strong>',
|
352 |
-
'<strong>', '</strong>',
|
353 |
-
'<strong>', '</strong>',
|
354 |
-
'<strong>', '</strong>',
|
355 |
-
'<br>',
|
356 |
-
'<br>',
|
357 |
-
'<strong>', '</strong>',
|
358 |
-
'<strong>', '</strong>',
|
359 |
-
'<br>',
|
360 |
-
'<br>',
|
361 |
-
'<strong>', '</strong>',
|
362 |
-
'<strong>', '</strong>',
|
363 |
-
'<strong>', '</strong>',
|
364 |
-
'<strong>', '</strong>',
|
365 |
-
'<strong>', '</strong>',
|
366 |
-
'<strong>', '</strong>',
|
367 |
-
'<strong>', '</strong>',
|
368 |
-
'<strong>', '</strong>'
|
369 |
-
);
|
370 |
-
?>
|
371 |
</p>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
372 |
</td>
|
373 |
</tr>
|
374 |
<tr>
|
321 |
<div class="option-content">
|
322 |
<div class="spio-inline-help"><span class="dashicons dashicons-editor-help" title="Click for more info" data-link="https://shortpixel.com/knowledge-base/article/88-how-to-exclude-images-from-being-optimized"></span></div>
|
323 |
|
324 |
+
<p class="settings-info" data-toggle="exclude-settings-expanded">
|
325 |
+
<?php
|
326 |
+
printf(esc_html__('Use this section to exclude images based on patterns (separated by commas). A pattern consists of a %s type:value %s pair and the accepted types are %s "name", "path", "size", "regex-name" and "regex-path" %s. A file is excluded if it matches any of the patterns. Examples can be found in the collapsible area below the exclusion list.','shortpixel-image-optimiser'),
|
327 |
+
'<b>','</b>',
|
328 |
+
'<b>','</b>'
|
329 |
+
);
|
330 |
+
?>
|
331 |
+
<br /><br />
|
332 |
+
|
333 |
+
</p>
|
334 |
+
|
335 |
<textarea name="excludePatterns" type="text" id="excludePatterns" placeholder="<?php
|
336 |
esc_html_e('name:keepbig, path:/full/path/to/exclude/, regex-name:/valid_regex/, size:1000x2000','shortpixel-image-optimiser');?>" rows="4" cols="60"><?php echo esc_html( $excludePatterns );?></textarea>
|
337 |
|
338 |
</div>
|
339 |
+
|
340 |
+
<p class="settings-info">
|
341 |
+
<label><input type='checkbox' class='shortpixel-hide' data-toggle='exclude-settings-expanded'> >> <?php printf(esc_html__('See examples')); ?></label>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
342 |
</p>
|
343 |
+
|
344 |
+
<div class='exclude-settings-expanded toggleTarget ' id="exclude-settings-expanded">
|
345 |
+
<p class="settings-info">
|
346 |
+
<?php
|
347 |
+
printf(esc_html__('For the pattern %s"name"%s, only the file name is matched, e.g. the pattern %sname:flower.jpg%s tells ShortPixel to exclude all JPEG images ending in “flower” (lowercase). At the same time, the pattern %sname:logo%s,excludes all images – PNG/JPEG/GIF – that contain the word “logo” in their name: “nicelogo.jpg”, “alllogos.png”, “logo.gif”.', 'shortpixel-image-optimiser'),
|
348 |
+
'<b>','</b>',
|
349 |
+
'<b>','</b>',
|
350 |
+
'<b>','</b>'
|
351 |
+
);
|
352 |
+
?>
|
353 |
+
|
354 |
+
</p>
|
355 |
+
<br />
|
356 |
+
<p class="settings-info">
|
357 |
+
<?php
|
358 |
+
printf(esc_html__('For the %s"path"%s pattern, the entire path is matched (useful to exclude certain (sub)-directories altogether). For example, %spath:2022%s excludes all images uploaded in 2022, but also excludes images that contain 2022 in the filename (since this is also part of the path). If you want to exclude only the images uploaded in 2022, use %spath:/2022/%s instead.','shortpixel-image-optimiser'),
|
359 |
+
'<b>','</b>',
|
360 |
+
'<b>','</b>',
|
361 |
+
'<b>','</b>'
|
362 |
+
);
|
363 |
+
?>
|
364 |
+
</p>
|
365 |
+
<br />
|
366 |
+
<p class="settings-info">
|
367 |
+
<?php
|
368 |
+
printf(esc_html__('%s"regex-path"%s and %s"regex-name"%s work the same way, but require a valid regular expression placed between slashes. Special characters should be escaped by prefixing them with \ . For example %sregex-name:/[0-9]+[^\/]*\.(PNG|png)/%s excludes all PNG images that have a numeric prefix.','shortpixel-image-optimiser'),
|
369 |
+
'<b>','</b>',
|
370 |
+
'<b>','</b>',
|
371 |
+
'<b>','</b>'
|
372 |
+
);
|
373 |
+
?>
|
374 |
+
</p>
|
375 |
+
<br />
|
376 |
+
<p class="settings-info">
|
377 |
+
<?php
|
378 |
+
printf(esc_html__('The %s"size"%s type, which applies only to Media Library images, excludes the main images (not thumbnails) whose size is in the specified range. The format for the "size" exclusion type is: %sminWidth-maxWidthxminHeight-maxHeight%s, for example %ssize:1000-1100x2000-2200%s. You can also specify a exact size, for example, %s1000x2000%s.','shortpixel-image-optimiser'),
|
379 |
+
'<b>','</b>',
|
380 |
+
'<b>','</b>',
|
381 |
+
'<b>','</b>',
|
382 |
+
'<b>','</b>'
|
383 |
+
);
|
384 |
+
?>
|
385 |
+
</p>
|
386 |
+
|
387 |
+
</div>
|
388 |
</td>
|
389 |
</tr>
|
390 |
<tr>
|
@@ -79,6 +79,7 @@ $env = \wpSPIO()->env();
|
|
79 |
<span>Images</span><span><?php echo esc_html($statsControl->find('media', 'images')); ?></span>
|
80 |
<span>ItemsTotal</span><span><?php echo esc_html($statsControl->find('media', 'itemsTotal')); ?></span>
|
81 |
<span>ThumbsTotal</span><span><?php echo esc_html($statsControl->find('media', 'thumbsTotal')); ?></span>
|
|
|
82 |
</div>
|
83 |
<h4>Custom</h4>
|
84 |
<div class='flex'>
|
79 |
<span>Images</span><span><?php echo esc_html($statsControl->find('media', 'images')); ?></span>
|
80 |
<span>ItemsTotal</span><span><?php echo esc_html($statsControl->find('media', 'itemsTotal')); ?></span>
|
81 |
<span>ThumbsTotal</span><span><?php echo esc_html($statsControl->find('media', 'thumbsTotal')); ?></span>
|
82 |
+
|
83 |
</div>
|
84 |
<h4>Custom</h4>
|
85 |
<div class='flex'>
|
@@ -211,10 +211,9 @@ class WPShortPixelSettings extends \ShortPixel\Model {
|
|
211 |
|
212 |
public static function onDeactivate() {
|
213 |
delete_option('wp-short-pixel-activation-notice');
|
214 |
-
delete_option(
|
215 |
-
delete_option(
|
216 |
delete_option('wp-short-pixel-remove-settings-on-delete-plugin');
|
217 |
-
|
218 |
}
|
219 |
|
220 |
|
@@ -249,11 +248,6 @@ class WPShortPixelSettings extends \ShortPixel\Model {
|
|
249 |
$default = self::$_optionsMap[$key]['default']; // first do default do to overwrite.
|
250 |
$key = self::$_optionsMap[$key]['key'];
|
251 |
}
|
252 |
-
if(get_option($key) === false) {
|
253 |
-
|
254 |
-
add_option( $key, $default, '', 'no' );
|
255 |
-
|
256 |
-
}
|
257 |
|
258 |
$opt = get_option($key, $default);
|
259 |
return $opt;
|
211 |
|
212 |
public static function onDeactivate() {
|
213 |
delete_option('wp-short-pixel-activation-notice');
|
214 |
+
delete_option('wp-short-pixel-bulk-last-status'); // legacy shizzle
|
215 |
+
delete_option('wp-short-pixel-current-total-files');
|
216 |
delete_option('wp-short-pixel-remove-settings-on-delete-plugin');
|
|
|
217 |
}
|
218 |
|
219 |
|
248 |
$default = self::$_optionsMap[$key]['default']; // first do default do to overwrite.
|
249 |
$key = self::$_optionsMap[$key]['key'];
|
250 |
}
|
|
|
|
|
|
|
|
|
|
|
251 |
|
252 |
$opt = get_option($key, $default);
|
253 |
return $opt;
|
@@ -4,7 +4,7 @@ Tags: convert webp, optimize images, image optimization, resize, compressor, ima
|
|
4 |
Requires at least: 4.8.0
|
5 |
Tested up to: 6.0
|
6 |
Requires PHP: 5.6
|
7 |
-
Stable tag: 5.0.
|
8 |
License: GPLv2 or later
|
9 |
License URI: http://www.gnu.org/licenses/gpl-2.0.html
|
10 |
|
@@ -32,25 +32,30 @@ Make an instant <a href="https://shortpixel.com/image-compression-test" target="
|
|
32 |
|
33 |
* popular plugin with over 300,000 active installations - according to WordPress
|
34 |
* compress JPG (and its variations JPEG, JPEG 2000, JPEG XR), PNG, GIF (still or animated) images and also PDF documents
|
35 |
-
* option to convert any JPEG, PNG or GIF (even animated ones!) to **WebP** and **AVIF** for more Google love. <a href="https://
|
|
|
|
|
36 |
* option to automatically convert PNG to JPG if that will result in smaller images. Ideal for large images in PNG format
|
37 |
* option to include the next generation images (WebP and AVIF) into the front-end pages by using the `<picture>` tag instead of `<img>`, independent from generating them through the plugin
|
38 |
-
* compatible with WP Retina 2x - all **retina images** are automatically compressed. <a href="https://
|
39 |
* optimize thumbnails as well as featured images. You can also **select individual thumbnails to exclude** from optimization
|
|
|
40 |
* ability to optimize any image on your site including images in **NextGEN Gallery** and any other image galleries or sliders
|
41 |
* option to scale images down, with 2 different options, which is very useful to automatically resize large images. This applies to the featured images and there is no need for additional plugins like Imsanity
|
42 |
* CMYK to RGB conversion
|
43 |
* skip already optimized images
|
44 |
* **24h <a href="https://wordpress.org/support/plugin/shortpixel-image-optimiser/reviews/?filter=5" target="_blank">stellar support</a>** (24/7) directly from developers.
|
45 |
* easily **test lossy/glossy/lossless** versions of the images with a single click in your Media Library
|
46 |
-
* **great for photographers**: <a href="https://
|
47 |
* works well with both HTTPS and HTTP websites
|
|
|
48 |
* uses progressive JPEG for larger images in order to speed up the image display
|
49 |
* you can run ShortPixel plugin on **multiple websites** or on a **multisite** with a **single API Key**
|
50 |
* it is **safe to test** and use the plugin: all the original images are by default saved in a local backup that can be restored with a click, either one by one or in bulk
|
51 |
* 'Bulk' optimize all the existing images in Media Library or in any gallery with one click
|
52 |
* works great for **eCommerce websites using WooCommerce** or other plugins
|
53 |
* works great with NextGEN gallery, Foo Gallery and any other galleries and sliders
|
|
|
54 |
* compatible with WP Engine hosted websites and all the major hosting providers
|
55 |
* compatible with WPML and WPML Media plugins
|
56 |
* no file size limit
|
@@ -58,7 +63,7 @@ Make an instant <a href="https://shortpixel.com/image-compression-test" target="
|
|
58 |
* compatible with watermarking plugins
|
59 |
* option to deactivate auto-optimizing images on upload
|
60 |
* no credits are used for the images that are optimised less that 5%
|
61 |
-
* direct integration with
|
62 |
* 30 days optimization report with all image details and overall statistics
|
63 |
* We are GDPR compliant! <a href="https://shortpixel.com/privacy#gdpr" target="_blank">Read more.</a>
|
64 |
* **free optimization credits for non-profits**, <a href="https://shortpixel.com/contact" target="_blank">contact us</a> for details
|
@@ -86,6 +91,7 @@ Help us spread the word by recommending ShortPixel to your friends and collect *
|
|
86 |
* [reGenerate Thumbnails Advanced](https://wordpress.org/plugins/regenerate-thumbnails-advanced/) - Easily regenerate thumbnails
|
87 |
* [Resize Image After Upload](https://wordpress.org/plugins/resize-image-after-upload/) - Automatically resize each uploaded image
|
88 |
* [WP SVG Images](https://wordpress.org/plugins/wp-svg-images/) - Secure upload of SVG files to Media Library
|
|
|
89 |
|
90 |
**Get in touch!**
|
91 |
|
@@ -96,13 +102,13 @@ Help us spread the word by recommending ShortPixel to your friends and collect *
|
|
96 |
|
97 |
== Installation ==
|
98 |
|
99 |
-
Let's get ShortPixel plugin running on your WordPress website:
|
100 |
|
101 |
|
102 |
1. Sign up using your email at <a href="https://shortpixel.com/wp-apikey" target="_blank">https://shortpixel.com/wp-apikey</a>.
|
103 |
2. You will receive your personal API key in a confirmation email, to the address you provided.
|
104 |
3. Upload the ShortPixel plugin to the /wp-content/plugins/ directory
|
105 |
-
4. Use your unique API key to activate ShortPixel plugin in the 'Plugins' menu in WordPress.
|
106 |
5. Uploaded images can be automatically optimized in the Media Library.
|
107 |
6. Done!
|
108 |
|
@@ -309,6 +315,32 @@ Add HTTP basic authentication credentials by defining these constants in wp-conf
|
|
309 |
|
310 |
== Changelog ==
|
311 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
312 |
= 5.0.7 =
|
313 |
Release date July 26th, 2022
|
314 |
* Fix: the notification about credits used had some test data, resulting in wrong information (sorry again!);
|
4 |
Requires at least: 4.8.0
|
5 |
Tested up to: 6.0
|
6 |
Requires PHP: 5.6
|
7 |
+
Stable tag: 5.0.8
|
8 |
License: GPLv2 or later
|
9 |
License URI: http://www.gnu.org/licenses/gpl-2.0.html
|
10 |
|
32 |
|
33 |
* popular plugin with over 300,000 active installations - according to WordPress
|
34 |
* compress JPG (and its variations JPEG, JPEG 2000, JPEG XR), PNG, GIF (still or animated) images and also PDF documents
|
35 |
+
* option to convert any JPEG, PNG or GIF (even animated ones!) to **WebP** and **AVIF** for more Google love. <a href="https://shortpixel.com/blog/how-webp-images-can-speed-up-your-site/" target="_blank">How to enable WebP?</a>. <a href="https://shortpixel.com/blog/what-is-avif-and-why-is-it-good/" target="_blank">What is AVIF and why is it good?</a>.
|
36 |
+
* **New!:** full <a href="https://shortpixel.com/knowledge-base/article/537-wp-cli-support-for-shortpixel-image-optimizer" target="_blank">WP-CLI support</a> for background processing, useful especially for websites with a very large Media Library
|
37 |
+
* **New!:** Easily add <a href="https://shortpixel.com/knowledge-base/article/543-how-to-schedule-a-cron-event-to-run-shortpixel-image-optimizer" target="_blank">recurrent cron jobs</a> for background optimization. Useful if you have users uploading images via the front end of your website
|
38 |
* option to automatically convert PNG to JPG if that will result in smaller images. Ideal for large images in PNG format
|
39 |
* option to include the next generation images (WebP and AVIF) into the front-end pages by using the `<picture>` tag instead of `<img>`, independent from generating them through the plugin
|
40 |
+
* compatible with WP Retina 2x - all **retina images** are automatically compressed. <a href="https://shortpixel.com/blog/how-to-use-optimized-retina-images-on-your-wordpress-site-for-best-user-experience-on-apple-devices/" target="_blank">How to benefit from Retina displays?</a>
|
41 |
* optimize thumbnails as well as featured images. You can also **select individual thumbnails to exclude** from optimization
|
42 |
+
* advanced exclusion options that allow excluding images based on filename, path, size or complex regex exclusions
|
43 |
* ability to optimize any image on your site including images in **NextGEN Gallery** and any other image galleries or sliders
|
44 |
* option to scale images down, with 2 different options, which is very useful to automatically resize large images. This applies to the featured images and there is no need for additional plugins like Imsanity
|
45 |
* CMYK to RGB conversion
|
46 |
* skip already optimized images
|
47 |
* **24h <a href="https://wordpress.org/support/plugin/shortpixel-image-optimiser/reviews/?filter=5" target="_blank">stellar support</a>** (24/7) directly from developers.
|
48 |
* easily **test lossy/glossy/lossless** versions of the images with a single click in your Media Library
|
49 |
+
* **great for photographers**: <a href="https://shortpixel.com/blog/how-much-smaller-can-be-images-without-exif-icc/" target="_blank">keep or remove EXIF</a> data from your images, compress photos with lossless option
|
50 |
* works well with both HTTPS and HTTP websites
|
51 |
+
* fully compatible with any WordPress multisite install (either with sub-folders or sub-domains)
|
52 |
* uses progressive JPEG for larger images in order to speed up the image display
|
53 |
* you can run ShortPixel plugin on **multiple websites** or on a **multisite** with a **single API Key**
|
54 |
* it is **safe to test** and use the plugin: all the original images are by default saved in a local backup that can be restored with a click, either one by one or in bulk
|
55 |
* 'Bulk' optimize all the existing images in Media Library or in any gallery with one click
|
56 |
* works great for **eCommerce websites using WooCommerce** or other plugins
|
57 |
* works great with NextGEN gallery, Foo Gallery and any other galleries and sliders
|
58 |
+
* fully compatible with the <a href="https://wordpress.org/plugins/amazon-s3-and-cloudfront/" target="_blank">WP Offload Media</a> plugin
|
59 |
* compatible with WP Engine hosted websites and all the major hosting providers
|
60 |
* compatible with WPML and WPML Media plugins
|
61 |
* no file size limit
|
63 |
* compatible with watermarking plugins
|
64 |
* option to deactivate auto-optimizing images on upload
|
65 |
* no credits are used for the images that are optimised less that 5%
|
66 |
+
* direct integration with Cloudflare by using a Cloudflare Token
|
67 |
* 30 days optimization report with all image details and overall statistics
|
68 |
* We are GDPR compliant! <a href="https://shortpixel.com/privacy#gdpr" target="_blank">Read more.</a>
|
69 |
* **free optimization credits for non-profits**, <a href="https://shortpixel.com/contact" target="_blank">contact us</a> for details
|
91 |
* [reGenerate Thumbnails Advanced](https://wordpress.org/plugins/regenerate-thumbnails-advanced/) - Easily regenerate thumbnails
|
92 |
* [Resize Image After Upload](https://wordpress.org/plugins/resize-image-after-upload/) - Automatically resize each uploaded image
|
93 |
* [WP SVG Images](https://wordpress.org/plugins/wp-svg-images/) - Secure upload of SVG files to Media Library
|
94 |
+
* [ShortPixel Critical CSS](https://wordpress.org/plugins/shortpixel-critical-css/) - Automatically generate above-the-fold CSS for fatster loading times and better SEO scores
|
95 |
|
96 |
**Get in touch!**
|
97 |
|
102 |
|
103 |
== Installation ==
|
104 |
|
105 |
+
Let's get the ShortPixel plugin running on your WordPress website:
|
106 |
|
107 |
|
108 |
1. Sign up using your email at <a href="https://shortpixel.com/wp-apikey" target="_blank">https://shortpixel.com/wp-apikey</a>.
|
109 |
2. You will receive your personal API key in a confirmation email, to the address you provided.
|
110 |
3. Upload the ShortPixel plugin to the /wp-content/plugins/ directory
|
111 |
+
4. Use your unique API key to activate the ShortPixel plugin in the 'Plugins' menu in WordPress.
|
112 |
5. Uploaded images can be automatically optimized in the Media Library.
|
113 |
6. Done!
|
114 |
|
315 |
|
316 |
== Changelog ==
|
317 |
|
318 |
+
= 5.0.8 =
|
319 |
+
Release date August 8th, 2022
|
320 |
+
* Fix: the `Previous Bulks` now displays the number of credits used instead of the number of Media Library items, to avoid confusion;
|
321 |
+
* Fix: the notification for migrating the old format of optimization information was not getting triggered anymore;
|
322 |
+
* Fix: excluded images and/or thumbnails can now be restored from the backup;
|
323 |
+
* Fix: added prevention for double database queries when checking if an item is already in the queue;
|
324 |
+
* Fix: the bulk restore and bulk migration of optimization data can now be done even if out of credits;
|
325 |
+
* Fix: reduced the number of database table checks done on wp-admin pages to the minimum possible;
|
326 |
+
* Fix: the out-of-quota message was not always showing up properly;
|
327 |
+
* Fix: the bulk migration of the optimization data now marks as optimized the images that have proper backups in place;
|
328 |
+
* Fix: the thousands separators are now displayed properly for all languages;
|
329 |
+
* Fix: the optimized/unoptimized Media Library filter has proper pagination and also works with WPML;
|
330 |
+
* Fix: in case the optimization percentage is an integer, drop the `.00` (83.00% -> 83%);
|
331 |
+
* Fix: improved the settings and bulk pages load time for sites with a huge number of items in the Media Library;
|
332 |
+
* Fix: properly save the optimization information even if the filename is huge;
|
333 |
+
* Fix: the `Optimize now` button wasn't showing up on Custom Media right after restoring an item from the backup;
|
334 |
+
* Fix: more fixes for multisite installs where the old `blogs.dir` folder structure is used;
|
335 |
+
* Fix: multiple fixes and improvements for WP-CLI, including more detailed embedded docs and examples;
|
336 |
+
* Fix: multiple fixes and improvements to the whole exclusions module;
|
337 |
+
* Fix: multiple fixes and improvements in handling how retina images are optimized;
|
338 |
+
* Fix: various small fixes and improvements to the debug mode of the plugin;
|
339 |
+
* Tweak: `CTRL+S` can now be used to save settings (you're welcome!);
|
340 |
+
* Tweak: added support for bulk processing via the processing hook;
|
341 |
+
* Tweak: various wording and text updates in the plugin and the readme file;
|
342 |
+
* Language: 10 new strings added, 8 updated, 0 fuzzed, and 2 obsoleted.
|
343 |
+
|
344 |
= 5.0.7 =
|
345 |
Release date July 26th, 2022
|
346 |
* Fix: the notification about credits used had some test data, resulting in wrong information (sorry again!);
|
@@ -404,6 +404,10 @@ body.debug-model-active {
|
|
404 |
display: none !important;
|
405 |
}
|
406 |
|
|
|
|
|
|
|
|
|
407 |
.switch_button {
|
408 |
line-height: 12px;
|
409 |
margin: 2px -5px 10px -5px;
|
404 |
display: none !important;
|
405 |
}
|
406 |
|
407 |
+
.button-primary.optimize {
|
408 |
+
margin-bottom: 16px;
|
409 |
+
}
|
410 |
+
|
411 |
.switch_button {
|
412 |
line-height: 12px;
|
413 |
margin: 2px -5px 10px -5px;
|
@@ -1 +1 @@
|
|
1 |
-
{"version":3,"sourceRoot":"","sources":["../scss/view/_edit-media.scss","../scss/elements/_animation.scss","../scss/view/_other-media.scss","../scss/view/_list-item.scss","../scss/view/_modal.scss","../scss/view/_debug.scss","../scss/shortpixel-admin.scss"],"names":[],"mappings":"AAII;EAEG;EACA;;AAGH;EAEE;;AAEA;EAEE;EACA;;AAOA;EAEE;EACA;;AAIN;EAEE;EACA;;AAEA;EAGE;EACA;EACA;;;AAQP;EC/CC;EACI;EACA;EACA;EACA;ED6CH;;AC3CF;EACC;IAAM;IAA2B;;;AAGlC;EACC;IAAM;IAA8B;;;AAGrC;EACC;IAAM;IAA+B;;;AAGtC;EACC;IAAM;IAAmC;;;AAG1C;EACC;IAAM;IAAgC;;;;ADmCjC;EAEC;EACA;;AAEF;EACC;;AAUJ;EAAS;;AACT;EAAO;;;AEzEP;EAEG;EACA;EACA;;AAIL;EAEC;EACA;;AACA;EDdA;EACI;EACA;EACA;EACA;ECYF;;ADVH;EACC;IAAM;IAA2B;;;AAGlC;EACC;IAAM;IAA8B;;;AAGrC;EACC;IAAM;IAA+B;;;AAGtC;EACC;IAAM;IAAmC;;;AAG1C;EACC;IAAM;IAAgC;;;;AExBxC;EAEE;;AAEA;EAEE;;AAKA;EAEK;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACJ;;AACI;EAEI;EACA;;AAEL;EACC;EACA;EACA;EACA;;AAEK;EACI;EACT;EACA;;AACU;EAEG;EACA;EAEA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;;AAOhB;EACI;;AAKV;EAEG;EACA;EACA;;AAEH;EAEG;;AACA;EACI;;AAIJ;EAAkB;;AAGrB;EAAK;;AACL;EACI;EACA;EACA;EACA;EACA;EACA;;AAEA;EAEG;EACA;EACA;;;AASP;EAEG;EACA;EACF;;AACA;EF1GD;EACI;EACA;EACA;EACA;EEwGF;;AFtGH;EACC;IAAM;IAA2B;;;AAGlC;EACC;IAAM;IAA8B;;;AAGrC;EACC;IAAM;IAA+B;;;AAGtC;EACC;IAAM;IAAmC;;;AAG1C;EACC;IAAM;IAAgC;;;;AGzBxC;EACI;AAAe;EACf;AAAiB;EACjB;AAAgB;EAChB;EACA;EACA;AAAa;EACb;AAAc;EACd;AAAgB;EAChB;AAAwB;EACxB;AAA6B;EAC7B;;;AAEJ;EACI;AACA;EACA;EACA;EACA;AAAY;EACZ;AAAkB;EAClB;AAAiB;EACjB;EACA;EACA;EACA;EACA;;AACA;EAEE;EACA;EACA;EACA;EACA;EACA;EACA;;AAGF;EACI;EACA;EACA;;;AAKR;EACI;;;AAEJ;EACI;;;AC/CJ;EACE;;;AAGF;EAEC;;AACA;EACC;;AAED;EAEC;;;AAKF;EACC;EACA;EACA;EACA;EACA;EACA;EACC;EACA;EAED;EACA;EACA;EAEA;EAGA;EACA;;AAEA;EAEE;;AAGF;EACE;;AACA;EAAK;;AAGP;EACE;;AAIF;EACC;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACC;EACA;EACA;EACA;EACA;EACA;EACA;;AAGD;EACC;EACA;EACA;EACA;EACA;EACA;EACA;;AACA;EACC;EACA;;AAIH;EACC;EAIA;;;AAKF;EAEE;EACD;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AC/FD;EACI;;;AAIJ;EAGC;EACA;EACA;;AAEA;EACC;;AAEA;EACC;;AAGF;EAAQ;;AACP;EAA0B;;AAC1B;EACC;EACA;;AAED;EACC;EACA;;AAED;EAAiC;;AAElC;EACC;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACC;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EAGA;EACH;EACA;;AAEE;EAAiB;;AACjB;EACC","file":"shortpixel-admin.css"}
|
1 |
+
{"version":3,"sourceRoot":"","sources":["../scss/view/_edit-media.scss","../scss/elements/_animation.scss","../scss/view/_other-media.scss","../scss/view/_list-item.scss","../scss/view/_modal.scss","../scss/view/_debug.scss","../scss/shortpixel-admin.scss"],"names":[],"mappings":"AAII;EAEG;EACA;;AAGH;EAEE;;AAEA;EAEE;EACA;;AAOA;EAEE;EACA;;AAIN;EAEE;EACA;;AAEA;EAGE;EACA;EACA;;;AAQP;EC/CC;EACI;EACA;EACA;EACA;ED6CH;;AC3CF;EACC;IAAM;IAA2B;;;AAGlC;EACC;IAAM;IAA8B;;;AAGrC;EACC;IAAM;IAA+B;;;AAGtC;EACC;IAAM;IAAmC;;;AAG1C;EACC;IAAM;IAAgC;;;;ADmCjC;EAEC;EACA;;AAEF;EACC;;AAUJ;EAAS;;AACT;EAAO;;;AEzEP;EAEG;EACA;EACA;;AAIL;EAEC;EACA;;AACA;EDdA;EACI;EACA;EACA;EACA;ECYF;;ADVH;EACC;IAAM;IAA2B;;;AAGlC;EACC;IAAM;IAA8B;;;AAGrC;EACC;IAAM;IAA+B;;;AAGtC;EACC;IAAM;IAAmC;;;AAG1C;EACC;IAAM;IAAgC;;;;AExBxC;EAEE;;AAEA;EAEE;;AAKA;EAEK;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACJ;;AACI;EAEI;EACA;;AAEL;EACC;EACA;EACA;EACA;;AAEK;EACI;EACT;EACA;;AACU;EAEG;EACA;EAEA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;;AAOhB;EACI;;AAKV;EAEG;EACA;EACA;;AAEH;EAEG;;AACA;EACI;;AAIJ;EAAkB;;AAGrB;EAAK;;AACL;EACI;EACA;EACA;EACA;EACA;EACA;;AAEA;EAEG;EACA;EACA;;;AASP;EAEG;EACA;EACF;;AACA;EF1GD;EACI;EACA;EACA;EACA;EEwGF;;AFtGH;EACC;IAAM;IAA2B;;;AAGlC;EACC;IAAM;IAA8B;;;AAGrC;EACC;IAAM;IAA+B;;;AAGtC;EACC;IAAM;IAAmC;;;AAG1C;EACC;IAAM;IAAgC;;;;AGzBxC;EACI;AAAe;EACf;AAAiB;EACjB;AAAgB;EAChB;EACA;EACA;AAAa;EACb;AAAc;EACd;AAAgB;EAChB;AAAwB;EACxB;AAA6B;EAC7B;;;AAEJ;EACI;AACA;EACA;EACA;EACA;AAAY;EACZ;AAAkB;EAClB;AAAiB;EACjB;EACA;EACA;EACA;EACA;;AACA;EAEE;EACA;EACA;EACA;EACA;EACA;EACA;;AAGF;EACI;EACA;EACA;;;AAKR;EACI;;;AAEJ;EACI;;;AC/CJ;EACE;;;AAGF;EAEC;;AACA;EACC;;AAED;EAEC;;;AAKF;EACC;EACA;EACA;EACA;EACA;EACA;EACC;EACA;EAED;EACA;EACA;EAEA;EAGA;EACA;;AAEA;EAEE;;AAGF;EACE;;AACA;EAAK;;AAGP;EACE;;AAIF;EACC;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACC;EACA;EACA;EACA;EACA;EACA;EACA;;AAGD;EACC;EACA;EACA;EACA;EACA;EACA;EACA;;AACA;EACC;EACA;;AAIH;EACC;EAIA;;;AAKF;EAEE;EACD;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AC/FD;EACI;;;AAIJ;EAEE;;;AAGF;EAGC;EACA;EACA;;AAEA;EACC;;AAEA;EACC;;AAGF;EAAQ;;AACP;EAA0B;;AAC1B;EACC;EACA;;AAED;EACC;EACA;;AAED;EAAiC;;AAElC;EACC;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACC;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EAGA;EACH;EACA;;AAEE;EAAiB;;AACjB;EACC","file":"shortpixel-admin.css"}
|
@@ -546,6 +546,9 @@
|
|
546 |
.shortpixel-bulk-wrapper section.panel.selection .optiongroup .option .number {
|
547 |
font-weight: 700;
|
548 |
}
|
|
|
|
|
|
|
549 |
.shortpixel-bulk-wrapper section.panel.summary .spio-progressbar .select .line {
|
550 |
background: #1FBEC9;
|
551 |
}
|
546 |
.shortpixel-bulk-wrapper section.panel.selection .optiongroup .option .number {
|
547 |
font-weight: 700;
|
548 |
}
|
549 |
+
.shortpixel-bulk-wrapper section.panel.selection .count_limited {
|
550 |
+
color: #ff0000;
|
551 |
+
}
|
552 |
.shortpixel-bulk-wrapper section.panel.summary .spio-progressbar .select .line {
|
553 |
background: #1FBEC9;
|
554 |
}
|
@@ -1 +1 @@
|
|
1 |
-
{"version":3,"sourceRoot":"","sources":["../scss/shortpixel-bulk.scss","../scss/elements/_colors.scss","../scss/elements/_animation.scss"],"names":[],"mappings":"AAAA;AAKE;AAqWF;AAoLI;
|
1 |
+
{"version":3,"sourceRoot":"","sources":["../scss/shortpixel-bulk.scss","../scss/elements/_colors.scss","../scss/elements/_animation.scss"],"names":[],"mappings":"AAAA;AAKE;AAqWF;AAoLI;AA2GF;;AAnoBE;EACE;EACA;EACA;EACA;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EAEI;EACA;;AAGN;EACE;;AAGF;EAEG;EAGA;;AAGL;EACC;EACA;EACA;EACA;EAEA;EACA;EACA,YC3CiB;ED4CjB,OC/CU;EDgDV;EACA;EACA;EACA;EACA;EACA;;AAEA;EAEC,YCzDS;ED0DT;EACA;;AAGD;EACC,cC/DS;EDgET,YChES;;ADkEV;EAEE;EACA;EACA;;AAGF;EACE;EACA;EACA;EACA;;AAID;EAEE,YCpFU;EDqFV;EACA;EACA;EACA;;AAGJ;EACE;EAED;EACA;;AACA;EAEE;;AAIH;EACG;;AAGD;EACE;;AAGJ;EACG;EACA;;AAGJ;EACG;IACG;;EAEH;IACG;;;AAIN;EAEE;EACA;;AAID;EAEE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AACC;EAEE;EACA;EACA;EACA;EACA;EACA;;AAEH;EAEE;EACD;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAED;EAEC;EACA;EACA;;AACA;EACC;;AACA;EAAW;;AACR;EAAS;EAA+B;;AAE3C;EAAQ;;AACR;EACE;EACD;;AAGF;EAAI;EAAuB;;AAK5B;EAEI;EACA;EACA;EACA;;AAGA;EAGG;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAGA;EAEE;EACA;EACA;EACN;EACA;;AAGG;EACI;EACA;EACA;EACA;EACA;EACA;;AACA;EAAU;;AACV;EAEN;EACA;;AAMH;EAEG;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EAEJ;;AAGI;EAEI;EACA;EACA;EACA;;AAGJ;EAEG;EAED;EACA;;AAKE;EAAK;;AACL;EACE;EACA;;AACA;EAAS;;AAGf;EACE;EACA;EAEA;EACL;EACK;EACA;EACA;EACA;EACA;EACL;EACA;EAEK;EACL;EACA;EACA;;AACA;EAAS;;AAMT;EAGE;EAGH;EACG;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AACA;EACE;;AAEF;EAEE;;AACA;EAEG;EACA;EACA;;AAGH;EAAiB;;AAIvB;EAEE;EACA;EAGA;EACA;EACA;EACA;EACA;EACA;;AACA;EACA;EACA;EACA;;AAEA;EAEC;EACA;EACC;;AASA;EAAa;;AAIb;EAEK;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AACA;EAEE;EACA;EACA;EAAS;;AAGX;EAEG;EAEA;EACA;EACA;EACA;EACP;EAEA;EACA;;AAEO;EAGP,YCnZQ;EDqZP;EACA;EAES;;AAKH;EACE;EACA;;AAEF;EAEN;;AAMF;EAEG;EACA;EACA;;AACA;EAAK;EAAwB;;AAC7B;EACE;;AACA;EAAS;EAAqB;;AAI9B;EACE;EACA;;AAKF;EACE;EACA;EAGA;EACA;;AAHA;EAAgB;;AAChB;EAAgB;;AAGhB;EACG;EACA;EACA;;AAYb;EAEI;;AACA;EAEE;EACA;EACA;EACA;;AAEA;EAEG;EACA;EACA;EACA;EACA;;AAGH;EAEE;;AAGF;EACE;EACA;EACA;EAEA;EACA;EACA;EACA;EACA;EACA;;AAGF;EAEE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACN;;AAEI;EAEE;EACA;EACA;EACA;EACN;;AAoBG;EATH;;AAUG;EAAe;;AACf;EAAQ;;AAEX;EAEG;EACJ;EACI;;AAKA;EACE;EACL;EACA;;AAKE;EAEG;EACL;;AAKG;EAEG;EACA;EACA;EACA;EACA;EACA;;AACN;EACC;;AACA;EAAI;;AAEC;EACE;;AAEF;EE9kBV;EACI;EACA;EACA;EACA;;AAEL;EACC;IAAM;IAA2B;;;AAGlC;EACC;IAAM;IAA8B;;;AAGrC;EACC;IAAM;IAA+B;;;AAGtC;EACC;IAAM;IAAmC;;;AAG1C;EACC;IAAM;IAAgC;;;AF6jBrC;EAEE;EACA;;AACA;EACE;EACD;;AAED;EAAI;;AAWA;EACG;;AAEH;EACG;EACA;EACA;EACA;;AAEH;EACE;EAEA;;AACA;EACI;EACA;;AAEJ;EACI;;AAMZ;EAEE;;AAYI;EAAQ;;AACR;EAAe;;AACf;EAAQ;;AAIR;EA1HH;;AA2HG;EAAe;;AACf;EAAQ;;AAEX;EAEI;EACA;EACA;;AACA;EACE;EACA;EACA;EACA;EACA;EACA;;AACA;EACE;EACA;EACA;;AAKD;EACI;EACA;EACA;;AACA;EAEG;EACA;;AAIN;EAEG;EAEA;EACA;;AAEA;EACE;EACA;EACA;;AACA;EAEG;EACA;EACA;;AACA;EAEG;;AAIR;EAEG;EACA;EACA;EAEA;;AAOd;EAEE;EACA;EACA;EACA;;AAEA;EAAU;;AAGZ;EACI;EAEA;EAEL;;AACK;EAAM;;AACN;EACG;EACA;EACA;EACN;;AACM;EAAgB;EAAkB;;AACxC;EAAkB;;AAClB;EAAkB;;AAClB;EAAU;EAAc;;AAGrB;EACE;EACA;;AAIN;EAEG;EACA;EACA;EACA;EACA;EACA;;AACA;EACE;;AAEF;EACE;EACA;EACA;;AACA;EAAO;;AAET;EACE;EACA;EACA;EACA;EACA;EACA;;AAGL;EAEI;EACA;EACA;;AASD;EAAQ;;AACR;EAAe;;AACf;EAAQ;;AAIR;EA/QH;;AAgRG;EAAe;;AACf;EAAQ;;AAGX;EAEE;EACA;EACA;EACA;EACA;EACJ;EACA;;AAEI;EACE;EACA;EACL;EAGA;EACA;EACA;EACA;EACA;EACA;EACA;;AAGG;EACI;EACA;EACA;;AAEA;EACE;;AAEF;EACE,QC/0BD;EDg1BC;EACA;;AAEF;EAEE;EACA;EACA;EACA;EACA;;AAKR;EAEE;EACA;EACA;;AACA;EAAQ;;AACR;EACI;EACA;EACN;;AAEE;EACG;EACA;;AAEH;EAEE;EACA;EACA;EACA;EACA;EACL;;AAGK;EAEE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;AAIN;EAEE;;AAMJ;EACC;;AAIC;EACG;EACA;EACA;EACA;EACJ;;AAEA;EACG;EACD;EACA;EACA;EACA;EACA;EACA;EACA;;AAIC;EAEG;EACA;EACA;EACA;EACA;;AAGN;EAEC;EACA;;AAGK;EACI;EACA;EACA;;AAEA;EACE;;AAEF;EACE;EACA;EACA;;AAEF;EAEE;EACA;EACA;EACA;EACA;;AAKR;EAIH;EACA;EAGK;;AAEL;EAIC;EACA;EACA;;AAID;EAEC;EACC;EACD;EACA;EACA;EACA;EACA;;AAED;EAEE;;AAIF;EAGC;;AASI;EAEG;EACA;EACA;EACA;;AAEA;EACE;EACR;EACA;EASA;EACA;;AATA;EAEC;;AAED;EAEC;;AAKF;EACE;EACA;EACA;EACA;EACA;EACA;;AAGK;EACE;EACA;EACA;EACA;EACA;EACA;;AAGL;EAEG;;AAEH;EAEE;;AAKP;EACI;EACA;;AAYD;EAAQ;;AACR;EAAe;;AACf;EAAQ;;AAIR;EApjBH;;AAqjBG;EAAe;;AACf;EAAQ;;AAGX;EACI;;AAEF;EAEI;EACA;EACA;EACA;EACA;EACA;;AACA;EACE;;AAOV;EAEG;EACA;EACA;EACA;EACA;;AAKL;EAEE;EAEA;;AACA;EAAK;EACH;EACA;;AAEA;EAEE;EACA;;AAIJ;EAAW;;AAEX;EAEC;EACA;;AAEK;EACG;;AAEH;EACG;EACA;EACA;EACA;EACN;;AAEG;EACE;EAEA;;AACA;EACI;EACA;;AAEJ;EACI;;AAGX;EAEE;EACA","file":"shortpixel-bulk.css"}
|
@@ -70,6 +70,10 @@
|
|
70 |
.shortpixel-other-media .list-overview .item:nth-child(odd) {
|
71 |
background-color: #f9f9f9;
|
72 |
}
|
|
|
|
|
|
|
|
|
73 |
.shortpixel-other-media .list-overview .item:hover .row-actions {
|
74 |
left: 0;
|
75 |
color: #bbb;
|
@@ -126,7 +130,6 @@
|
|
126 |
display: block;
|
127 |
}
|
128 |
.shortpixel-other-media .list-overview .item .sp-column-info {
|
129 |
-
max-width: 400px;
|
130 |
width: 100%;
|
131 |
min-width: 250px;
|
132 |
display: inline-block;
|
70 |
.shortpixel-other-media .list-overview .item:nth-child(odd) {
|
71 |
background-color: #f9f9f9;
|
72 |
}
|
73 |
+
.shortpixel-other-media .list-overview .item span:last-child {
|
74 |
+
min-width: 400px;
|
75 |
+
max-width: 400px;
|
76 |
+
}
|
77 |
.shortpixel-other-media .list-overview .item:hover .row-actions {
|
78 |
left: 0;
|
79 |
color: #bbb;
|
130 |
display: block;
|
131 |
}
|
132 |
.shortpixel-other-media .list-overview .item .sp-column-info {
|
|
|
133 |
width: 100%;
|
134 |
min-width: 250px;
|
135 |
display: inline-block;
|
@@ -1 +1 @@
|
|
1 |
-
{"version":3,"sourceRoot":"","sources":["../scss/shortpixel-othermedia.scss"],"names":[],"mappings":"AAAA;EAEE;IAEE;;;AAIJ;EAEE;;AACA;EAEE;;AACA;EAEE;;AAGJ;EAEG;;AACD;EAEI;IAEG;IACA;;EAEH;IAEE;;;AAKP;EAEG;EACA;EACA;EACA;EACA;EACA;;AAEA;EAEE;;AAEA;EAEE;EACA;EACA;EACA;;AAGJ;EAEE;EACA;;AACA;EACE;EACA;EACA;;AACA;EAEE;;AAEF;EAEG;;AAID;EAEE;EACA;;AAEF;EAEE;;AAKN;EAEE;EACA;;AAKD;EACG;;
|
1 |
+
{"version":3,"sourceRoot":"","sources":["../scss/shortpixel-othermedia.scss"],"names":[],"mappings":"AAAA;EAEE;IAEE;;;AAIJ;EAEE;;AACA;EAEE;;AACA;EAEE;;AAGJ;EAEG;;AACD;EAEI;IAEG;IACA;;EAEH;IAEE;;;AAKP;EAEG;EACA;EACA;EACA;EACA;EACA;;AAEA;EAEE;;AAEA;EAEE;EACA;EACA;EACA;;AAGJ;EAEE;EACA;;AACA;EACE;EACA;EACA;;AACA;EAEE;;AAEF;EAEG;;AAID;EAEE;EACA;;AAEF;EAEE;;AAKN;EAEE;EACA;;AAKD;EACG;;AAEP;EAEE;EACD;;AAIK;EAEE;EACA;;AACA;EAGE;EACA;EACA;;AACA;EACG;;AAKT;EAEE;EACL;;AAEG;EAEE;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;;AAGJ;EAEE;;AAOF;EAEE;;AACA;EAEE;EACA;EACA;;AAGF;EAEE;;AAIJ;EAEE;EACA;;AACA;EAEE;EACA;;AACA;EAEE;;AAMN;EAEH;EACK;EACA;EACL;;AAEK;EAPF;IAQM;;;AAET;EAEE;EACD;EACA;;AAID;EAII;IAAQ;;EAGP;IAAa;;EACb;IAAyB;IAAkB;IAAkB;;;AAIlE;EAIG;IAAQ;;EAKN;IAAQ;;;AAGb;EAEE;;AACA;EACE","file":"shortpixel-othermedia.css"}
|
@@ -55,6 +55,8 @@ var ShortPixelScreen = function (MainScreen, processor)
|
|
55 |
if (isPreparing)
|
56 |
{
|
57 |
this.SwitchPanel('selection');
|
|
|
|
|
58 |
}
|
59 |
else if (isRunning)
|
60 |
{
|
@@ -582,7 +584,11 @@ console.log("Screen Init Done", initMedia, initCustom);
|
|
582 |
else
|
583 |
{
|
584 |
if (value !== false)
|
585 |
-
|
|
|
|
|
|
|
|
|
586 |
}
|
587 |
|
588 |
});
|
@@ -618,9 +624,9 @@ console.log("Screen Init Done", initMedia, initCustom);
|
|
618 |
}
|
619 |
|
620 |
var error = this.processor.aStatusError[result.error];
|
621 |
-
|
622 |
if (error == 'NOQUOTA')
|
623 |
{
|
|
|
624 |
this.ToggleOverQuotaNotice(true);
|
625 |
}
|
626 |
|
55 |
if (isPreparing)
|
56 |
{
|
57 |
this.SwitchPanel('selection');
|
58 |
+
this.UpdatePanelStatus('loading', 'selection');
|
59 |
+
this.PrepareBulk();
|
60 |
}
|
61 |
else if (isRunning)
|
62 |
{
|
584 |
else
|
585 |
{
|
586 |
if (value !== false)
|
587 |
+
{
|
588 |
+
|
589 |
+
element.textContent = value;
|
590 |
+
|
591 |
+
}
|
592 |
}
|
593 |
|
594 |
});
|
624 |
}
|
625 |
|
626 |
var error = this.processor.aStatusError[result.error];
|
|
|
627 |
if (error == 'NOQUOTA')
|
628 |
{
|
629 |
+
|
630 |
this.ToggleOverQuotaNotice(true);
|
631 |
}
|
632 |
|
@@ -300,7 +300,9 @@ window.ShortPixelProcessor =
|
|
300 |
if (data.status == true && data.response) // data status is from shortpixel worker, not the response object
|
301 |
{
|
302 |
var response = data.response;
|
|
|
303 |
this.workerErrors = 0;
|
|
|
304 |
if ( response.callback)
|
305 |
{
|
306 |
console.log('Running callback : ' + response.callback);
|
@@ -312,11 +314,13 @@ window.ShortPixelProcessor =
|
|
312 |
}
|
313 |
if ( response.status == false)
|
314 |
{
|
|
|
315 |
// This is error status, or a usual shutdown, i.e. when process is in another browser.
|
316 |
var error = this.aStatusError[response.error];
|
317 |
if (error == 'PROCESSOR_ACTIVE')
|
318 |
{
|
319 |
this.Debug(response.message);
|
|
|
320 |
this.StopProcess();
|
321 |
}
|
322 |
else if (error == 'NONCE_FAILED')
|
@@ -331,12 +335,18 @@ window.ShortPixelProcessor =
|
|
331 |
this.screen.HandleError(response);
|
332 |
this.Debug('No Quota - CheckResponse handler');
|
333 |
this.PauseProcess();
|
|
|
334 |
}
|
335 |
else if (response.error < 0) // something happened.
|
336 |
{
|
337 |
this.StopProcess();
|
|
|
|
|
338 |
}
|
339 |
-
|
|
|
|
|
|
|
340 |
|
341 |
// Check the screen if we are custom or media ( or bulk ) . Check the responses for each of those.
|
342 |
if (typeof response.custom == 'object' && response.custom !== null)
|
300 |
if (data.status == true && data.response) // data status is from shortpixel worker, not the response object
|
301 |
{
|
302 |
var response = data.response;
|
303 |
+
var handledError = false; // prevent passing to regular queueHandler is some action is taken.
|
304 |
this.workerErrors = 0;
|
305 |
+
|
306 |
if ( response.callback)
|
307 |
{
|
308 |
console.log('Running callback : ' + response.callback);
|
314 |
}
|
315 |
if ( response.status == false)
|
316 |
{
|
317 |
+
|
318 |
// This is error status, or a usual shutdown, i.e. when process is in another browser.
|
319 |
var error = this.aStatusError[response.error];
|
320 |
if (error == 'PROCESSOR_ACTIVE')
|
321 |
{
|
322 |
this.Debug(response.message);
|
323 |
+
handledError = true;
|
324 |
this.StopProcess();
|
325 |
}
|
326 |
else if (error == 'NONCE_FAILED')
|
335 |
this.screen.HandleError(response);
|
336 |
this.Debug('No Quota - CheckResponse handler');
|
337 |
this.PauseProcess();
|
338 |
+
handledError = true;
|
339 |
}
|
340 |
else if (response.error < 0) // something happened.
|
341 |
{
|
342 |
this.StopProcess();
|
343 |
+
handledError = true;
|
344 |
+
console.error('Some unknown error occured!', response.error, response);
|
345 |
}
|
346 |
+
|
347 |
+
if (handledError == true)
|
348 |
+
return;
|
349 |
+
} // status false handler.
|
350 |
|
351 |
// Check the screen if we are custom or media ( or bulk ) . Check the responses for each of those.
|
352 |
if (typeof response.custom == 'object' && response.custom !== null)
|
@@ -6,8 +6,8 @@ var ShortPixelSettings = function()
|
|
6 |
|
7 |
this.Init = function()
|
8 |
{
|
9 |
-
console.log('Init Settings');
|
10 |
this.InitActions();
|
|
|
11 |
}
|
12 |
|
13 |
this.InitActions = function()
|
@@ -30,8 +30,11 @@ var ShortPixelSettings = function()
|
|
30 |
modal.addEventListener('click', self.OpenModal.bind(self));
|
31 |
});
|
32 |
|
|
|
|
|
33 |
}
|
34 |
|
|
|
35 |
this.DoToggleAction = function(event)
|
36 |
{
|
37 |
event.preventDefault();
|
@@ -47,6 +50,12 @@ var ShortPixelSettings = function()
|
|
47 |
var checked = checkbox.checked;
|
48 |
}
|
49 |
|
|
|
|
|
|
|
|
|
|
|
|
|
50 |
if (checked)
|
51 |
{
|
52 |
// target.classList.add('is-visible');
|
@@ -191,9 +200,29 @@ this.ReceiveModal = function(elem)
|
|
191 |
|
192 |
}
|
193 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
194 |
this.Init();
|
195 |
} // SPSettings
|
196 |
|
|
|
197 |
document.addEventListener("DOMContentLoaded", function(){
|
198 |
var s = new ShortPixelSettings();
|
199 |
});
|
6 |
|
7 |
this.Init = function()
|
8 |
{
|
|
|
9 |
this.InitActions();
|
10 |
+
this.SaveOnKey();
|
11 |
}
|
12 |
|
13 |
this.InitActions = function()
|
30 |
modal.addEventListener('click', self.OpenModal.bind(self));
|
31 |
});
|
32 |
|
33 |
+
|
34 |
+
|
35 |
}
|
36 |
|
37 |
+
|
38 |
this.DoToggleAction = function(event)
|
39 |
{
|
40 |
event.preventDefault();
|
50 |
var checked = checkbox.checked;
|
51 |
}
|
52 |
|
53 |
+
if (target === null)
|
54 |
+
{
|
55 |
+
console.error('Target element ID not found', checkbox);
|
56 |
+
return false;
|
57 |
+
}
|
58 |
+
|
59 |
if (checked)
|
60 |
{
|
61 |
// target.classList.add('is-visible');
|
200 |
|
201 |
}
|
202 |
|
203 |
+
this.SaveOnKey = function()
|
204 |
+
{
|
205 |
+
var saveForm = document.getElementById('wp_shortpixel_options');
|
206 |
+
if (saveForm === null)
|
207 |
+
return false; // no form no save.
|
208 |
+
|
209 |
+
window.addEventListener('keydown', function(event) {
|
210 |
+
|
211 |
+
if (! (event.key == 's' || event.key == 'S') || ! event.ctrlKey)
|
212 |
+
{
|
213 |
+
return true;
|
214 |
+
}
|
215 |
+
document.getElementById('wp_shortpixel_options').submit();
|
216 |
+
event.preventDefault();
|
217 |
+
return false;
|
218 |
+
});
|
219 |
+
}
|
220 |
+
|
221 |
+
|
222 |
this.Init();
|
223 |
} // SPSettings
|
224 |
|
225 |
+
|
226 |
document.addEventListener("DOMContentLoaded", function(){
|
227 |
var s = new ShortPixelSettings();
|
228 |
});
|
@@ -634,7 +634,7 @@ var ShortPixel = function() {
|
|
634 |
},
|
635 |
complete: function(response, status)
|
636 |
{
|
637 |
-
console.log(response, status);
|
638 |
|
639 |
}
|
640 |
});
|
634 |
},
|
635 |
complete: function(response, status)
|
636 |
{
|
637 |
+
//console.log(response, status);
|
638 |
|
639 |
}
|
640 |
});
|
@@ -15,6 +15,11 @@
|
|
15 |
display: none !important;
|
16 |
}
|
17 |
|
|
|
|
|
|
|
|
|
|
|
18 |
|
19 |
.switch_button
|
20 |
{
|
15 |
display: none !important;
|
16 |
}
|
17 |
|
18 |
+
// Reserve some space for the processing text on bottom.
|
19 |
+
.button-primary.optimize
|
20 |
+
{
|
21 |
+
margin-bottom: 16px;
|
22 |
+
}
|
23 |
|
24 |
.switch_button
|
25 |
{
|
@@ -639,6 +639,12 @@
|
|
639 |
|
640 |
}
|
641 |
|
|
|
|
|
|
|
|
|
|
|
|
|
642 |
} // panel
|
643 |
|
644 |
/**************** SUMMARY ******/
|
639 |
|
640 |
}
|
641 |
|
642 |
+
.count_limited
|
643 |
+
{
|
644 |
+
color: #ff0000;
|
645 |
+
|
646 |
+
}
|
647 |
+
|
648 |
} // panel
|
649 |
|
650 |
/**************** SUMMARY ******/
|
@@ -96,6 +96,11 @@
|
|
96 |
&:nth-child(odd) {
|
97 |
background-color: #f9f9f9;
|
98 |
}
|
|
|
|
|
|
|
|
|
|
|
99 |
&:hover
|
100 |
{
|
101 |
.row-actions
|
@@ -177,7 +182,7 @@
|
|
177 |
|
178 |
}
|
179 |
.sp-column-info {
|
180 |
-
|
181 |
width: 100%;
|
182 |
min-width: 250px;
|
183 |
display: inline-block;
|
96 |
&:nth-child(odd) {
|
97 |
background-color: #f9f9f9;
|
98 |
}
|
99 |
+
span:last-child
|
100 |
+
{
|
101 |
+
min-width: 400px;
|
102 |
+
max-width: 400px;
|
103 |
+
}
|
104 |
&:hover
|
105 |
{
|
106 |
.row-actions
|
182 |
|
183 |
}
|
184 |
.sp-column-info {
|
185 |
+
// max-width: 400px;
|
186 |
width: 100%;
|
187 |
min-width: 250px;
|
188 |
display: inline-block;
|
@@ -494,16 +494,12 @@ class ShortPixelPlugin {
|
|
494 |
global $plugin_page;
|
495 |
$screen_id = $this->env()->screen_id;
|
496 |
|
497 |
-
//var_dump(\wpSPIO()->env()->is_screen_to_use);
|
498 |
-
//exit($screen_id);
|
499 |
|
500 |
// $load = array();
|
501 |
$load_processor = array( 'shortpixel', 'shortpixel-processor' ); // a whole suit needed for processing, not more. Always needs a screen as well!
|
502 |
$load_bulk = array(); // the whole suit needed for bulking.
|
503 |
|
504 |
-
|
505 |
-
$this->load_script( 'shortpixel-debug' );
|
506 |
-
}
|
507 |
|
508 |
if ( \wpSPIO()->env()->is_screen_to_use ) {
|
509 |
$this->load_script( 'shortpixel-tooltip' );
|
@@ -535,6 +531,10 @@ class ShortPixelPlugin {
|
|
535 |
|
536 |
$this->load_style( 'shortpixel-admin' );
|
537 |
$this->load_style( 'shortpixel' );
|
|
|
|
|
|
|
|
|
538 |
|
539 |
} elseif ( $plugin_page == 'wp-short-pixel-custom' ) {
|
540 |
$this->load_style( 'shortpixel' );
|
494 |
global $plugin_page;
|
495 |
$screen_id = $this->env()->screen_id;
|
496 |
|
|
|
|
|
497 |
|
498 |
// $load = array();
|
499 |
$load_processor = array( 'shortpixel', 'shortpixel-processor' ); // a whole suit needed for processing, not more. Always needs a screen as well!
|
500 |
$load_bulk = array(); // the whole suit needed for bulking.
|
501 |
|
502 |
+
|
|
|
|
|
503 |
|
504 |
if ( \wpSPIO()->env()->is_screen_to_use ) {
|
505 |
$this->load_script( 'shortpixel-tooltip' );
|
531 |
|
532 |
$this->load_style( 'shortpixel-admin' );
|
533 |
$this->load_style( 'shortpixel' );
|
534 |
+
|
535 |
+
if ( $this->env()->is_debug ) {
|
536 |
+
$this->load_script( 'shortpixel-debug' );
|
537 |
+
}
|
538 |
|
539 |
} elseif ( $plugin_page == 'wp-short-pixel-custom' ) {
|
540 |
$this->load_style( 'shortpixel' );
|
@@ -3,7 +3,7 @@
|
|
3 |
* Plugin Name: ShortPixel Image Optimizer
|
4 |
* Plugin URI: https://shortpixel.com/
|
5 |
* Description: ShortPixel optimizes images automatically, while guarding the quality of your images. Check your <a href="/wp-admin/options-general.php?page=wp-shortpixel-settings" target="_blank">Settings > ShortPixel</a> page on how to start optimizing your image library and make your website load faster.
|
6 |
-
* Version: 5.0.
|
7 |
* Author: ShortPixel
|
8 |
* Author URI: https://shortpixel.com
|
9 |
* GitHub Plugin URI: https://github.com/short-pixel-optimizer/shortpixel-image-optimiser
|
@@ -31,7 +31,7 @@ if (! defined('SHORTPIXEL_RESET_ON_ACTIVATE'))
|
|
31 |
define('SHORTPIXEL_PLUGIN_FILE', __FILE__);
|
32 |
define('SHORTPIXEL_PLUGIN_DIR', __DIR__);
|
33 |
|
34 |
-
define('SHORTPIXEL_IMAGE_OPTIMISER_VERSION', "5.0.
|
35 |
|
36 |
define('SHORTPIXEL_BACKUP', 'ShortpixelBackups');
|
37 |
define('SHORTPIXEL_MAX_FAIL_RETRIES', 3);
|
@@ -62,6 +62,7 @@ define('SHORTPIXEL_UPLOADS_BASE', (file_exists($sp__uploads['basedir']) ? '' : A
|
|
62 |
define('SHORTPIXEL_UPLOADS_NAME', basename(is_main_site() ? SHORTPIXEL_UPLOADS_BASE : dirname(dirname(SHORTPIXEL_UPLOADS_BASE))));
|
63 |
$sp__backupBase = is_main_site() ? SHORTPIXEL_UPLOADS_BASE : dirname(dirname(SHORTPIXEL_UPLOADS_BASE));
|
64 |
define('SHORTPIXEL_BACKUP_FOLDER', $sp__backupBase . '/' . SHORTPIXEL_BACKUP);
|
|
|
65 |
define('SHORTPIXEL_BACKUP_URL',
|
66 |
((is_main_site() || (defined( 'SUBDOMAIN_INSTALL' ) && SUBDOMAIN_INSTALL))
|
67 |
? $sp__uploads['baseurl']
|
3 |
* Plugin Name: ShortPixel Image Optimizer
|
4 |
* Plugin URI: https://shortpixel.com/
|
5 |
* Description: ShortPixel optimizes images automatically, while guarding the quality of your images. Check your <a href="/wp-admin/options-general.php?page=wp-shortpixel-settings" target="_blank">Settings > ShortPixel</a> page on how to start optimizing your image library and make your website load faster.
|
6 |
+
* Version: 5.0.8
|
7 |
* Author: ShortPixel
|
8 |
* Author URI: https://shortpixel.com
|
9 |
* GitHub Plugin URI: https://github.com/short-pixel-optimizer/shortpixel-image-optimiser
|
31 |
define('SHORTPIXEL_PLUGIN_FILE', __FILE__);
|
32 |
define('SHORTPIXEL_PLUGIN_DIR', __DIR__);
|
33 |
|
34 |
+
define('SHORTPIXEL_IMAGE_OPTIMISER_VERSION', "5.0.8");
|
35 |
|
36 |
define('SHORTPIXEL_BACKUP', 'ShortpixelBackups');
|
37 |
define('SHORTPIXEL_MAX_FAIL_RETRIES', 3);
|
62 |
define('SHORTPIXEL_UPLOADS_NAME', basename(is_main_site() ? SHORTPIXEL_UPLOADS_BASE : dirname(dirname(SHORTPIXEL_UPLOADS_BASE))));
|
63 |
$sp__backupBase = is_main_site() ? SHORTPIXEL_UPLOADS_BASE : dirname(dirname(SHORTPIXEL_UPLOADS_BASE));
|
64 |
define('SHORTPIXEL_BACKUP_FOLDER', $sp__backupBase . '/' . SHORTPIXEL_BACKUP);
|
65 |
+
// @todo Backup URL not in use. Candidate for removal.
|
66 |
define('SHORTPIXEL_BACKUP_URL',
|
67 |
((is_main_site() || (defined( 'SUBDOMAIN_INSTALL' ) && SUBDOMAIN_INSTALL))
|
68 |
? $sp__uploads['baseurl']
|