ShortPixel Image Optimizer - Version 5.0.6

Version Description

Release date July 25th, 2022 * Fix: the "Search and Migrate All" tool now contains a fix for many cases where the message "Could not create backup" shows up; * Fix: a fatal error was crashing the plugin settings in PHP 7.2; * Fix: in certain cases, the optimization was looping due to WooCommerce's thumbnail system; * Fix: in some cases, WooCommerce as well as other plugins were returning a wrong thumbnail URL and this case was not treated properly; * Fix: optimization wasn't working correctly for multisite installs with the very old blogs.dir setup; * Fix: some notifications could not be properly dismissed (sorry for that!); * Fix: the integration with WP Offload Media has been enhanced for the case where the media files are not stored anymore on the local server; * Fix: some errors were showing up in certain cases where the next generation image delivery was active together with the WP Offload Media plugin; * Fix: the error box was not showing up anymore at the end of the bulk processing, or it was displaying wrong counts; * Fix: the "Optimize Now" action from the Custom Media had a wrong link; * Fix: in some cases, the bulk processing wasn't displaying the correct step for migration/restore operations; * Fix: the deactivation feedback was sent even if no selection was made in the pop-up; * Fix: the optimized/unoptimized filter was also displaying private posts; * Fix: various small fixes and code improvements to make the ShortPixel support team's lives easier; * Tweak: added a "processing" message when a new action is manually requested by the user; * Tweak: added a tool-tip for the number of items currently in the processing queue; * Tweak: added the resize type (cover/contain) on the image edit screen; * Language: 10 new strings added, 2 updated, 0 fuzzed, and 6 obsoleted.

Download this release

Release Info

Developer petredobrescu
Plugin Icon 128x128 ShortPixel Image Optimizer
Version 5.0.6
Comparing to
See all releases

Code changes from version 5.0.5 to 5.0.6

Files changed (46) hide show
  1. class/Controller/AdminController.php +1 -1
  2. class/Controller/AdminNoticesController.php +11 -6
  3. class/Controller/AjaxController.php +4 -2
  4. class/Controller/ApiController.php +3 -0
  5. class/Controller/FileSystemController.php +20 -9
  6. class/Controller/OptimizeController.php +1 -3
  7. class/Controller/Queue/Queue.php +0 -2
  8. class/Controller/QuotaController.php +8 -3
  9. class/Controller/SettingsController.php +0 -1
  10. class/Controller/View/EditMediaViewController.php +9 -2
  11. class/Controller/View/ListMediaViewController.php +0 -4
  12. class/Controller/View/OtherMediaViewController.php +16 -77
  13. class/Helper/UiHelper.php +4 -2
  14. class/Model/File/FileModel.php +11 -4
  15. class/Model/Image/ImageModel.php +31 -4
  16. class/Model/Image/ImageThumbnailMeta.php +2 -0
  17. class/Model/Image/MediaLibraryModel.php +78 -52
  18. class/Model/Image/MediaLibraryThumbnailModel.php +55 -1
  19. class/external/wp-offload-media.php +37 -34
  20. class/front/img-to-picture-webp.php +8 -1
  21. class/shortpixel-png2jpg.php +2 -2
  22. class/view/bulk/part-finished.php +4 -4
  23. class/view/bulk/part-process.php +5 -5
  24. class/view/bulk/part-summary.php +1 -1
  25. class/view/settings/part-advanced.php +3 -2
  26. class/view/shortpixel-feedback.php +3 -3
  27. class/view/view-edit-media.php +1 -1
  28. class/view/view-other-media.php +18 -7
  29. readme.txt +22 -1
  30. res/css/shortpixel-admin.css +119 -0
  31. res/css/shortpixel-admin.css.map +1 -1
  32. res/css/shortpixel-bulk.css.map +1 -1
  33. res/js/debug.js +3 -0
  34. res/js/screens/screen-bulk.js +5 -5
  35. res/js/screens/screen-custom.js +18 -0
  36. res/js/screens/screen-media.js +25 -1
  37. res/js/shortpixel-processor.js +4 -0
  38. res/js/shortpixel-tooltip.js +21 -0
  39. res/scss/elements/_animation.scss +28 -0
  40. res/scss/shortpixel-admin.scss +3 -0
  41. res/scss/shortpixel-bulk.scss +3 -25
  42. res/scss/view/_edit-media.scss +7 -0
  43. res/scss/view/_list-item.scss +4 -0
  44. res/scss/view/_other-media.scss +10 -0
  45. shortpixel-plugin.php +19 -0
  46. wp-shortpixel.php +2 -2
class/Controller/AdminController.php CHANGED
@@ -243,7 +243,7 @@ class AdminController extends \ShortPixel\Controller
243
  $extraClasses = " shortpixel-hide";
244
  /*translators: toolbar icon tooltip*/
245
  $id = 'short-pixel-notice-toolbar';
246
- $tooltip = __('ShortPixel optimizing...','shortpixel-image-optimiser') . " " . __('Please do not close this admin page.','shortpixel-image-optimiser');
247
  $icon = "shortpixel.png";
248
  $successLink = $link = admin_url(current_user_can( 'edit_others_posts')? 'upload.php?page=wp-short-pixel-bulk' : 'upload.php');
249
  $blank = "";
243
  $extraClasses = " shortpixel-hide";
244
  /*translators: toolbar icon tooltip*/
245
  $id = 'short-pixel-notice-toolbar';
246
+ $tooltip = __('ShortPixel optimizing...','shortpixel-image-optimiser');
247
  $icon = "shortpixel.png";
248
  $successLink = $link = admin_url(current_user_can( 'edit_others_posts')? 'upload.php?page=wp-short-pixel-bulk' : 'upload.php');
249
  $blank = "";
class/Controller/AdminNoticesController.php CHANGED
@@ -28,7 +28,7 @@ class AdminNoticesController extends \ShortPixel\Controller
28
  //const MSG_NO_
29
  const MSG_QUOTA_REACHED = 'QuotaReached100';
30
  const MSG_UPGRADE_MONTH = 'UpgradeNotice200'; // When processing more than the subscription allows on average..
31
- // @todo This one has been removed for now. Cleanup later on the line
32
  const MSG_UPGRADE_BULK = 'UpgradeNotice201'; // when there is no enough for a bulk run.
33
 
34
  const MSG_NO_APIKEY = 'ApiNotice300'; // API Key not found
@@ -360,7 +360,7 @@ class AdminNoticesController extends \ShortPixel\Controller
360
  if ($month_notice === false)
361
  {
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 ));
364
  $notice = Notices::addNormal($message);
365
  Notices::makePersistent($notice, self::MSG_UPGRADE_MONTH, YEAR_IN_SECONDS);
366
  }
@@ -549,8 +549,8 @@ class AdminNoticesController extends \ShortPixel\Controller
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</strong>."
553
- . " You might need to upgrade your plan in order to have all your images optimized.", 'shortpixel-image-optimiser'), $extra['monthAvg'], $extra['monthlyQuota']) . '</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;
@@ -720,13 +720,16 @@ class AdminNoticesController extends \ShortPixel\Controller
720
  return $notices;
721
  }
722
 
723
- protected function monthlyUpgradeNeeded($quotaData) {
 
 
724
 
725
  if (isset($quotaData->monthly->total))
726
  {
727
  $monthAvg = $this->getMonthAvg($quotaData);
728
  // +20 I suspect to not trigger on very low values of monthly use(?)
729
- $threshold = $quotaData->monthly->total + $quotaData->onetime->remaining/6+20;
 
730
  if ($monthAvg > $threshold)
731
  {
732
  return true;
@@ -750,6 +753,8 @@ class AdminNoticesController extends \ShortPixel\Controller
750
  protected function getMonthAvg() {
751
  $stats = StatsController::getInstance();
752
 
 
 
753
  // Count how many months have some optimized images.
754
  for($i = 4, $count = 0; $i>=1; $i--) {
755
  if($count == 0 && $stats->find('period', 'months', $i) == 0)
28
  //const MSG_NO_
29
  const MSG_QUOTA_REACHED = 'QuotaReached100';
30
  const MSG_UPGRADE_MONTH = 'UpgradeNotice200'; // When processing more than the subscription allows on average..
31
+ // @todo This one has been removed for now. Cleanup later on the line
32
  const MSG_UPGRADE_BULK = 'UpgradeNotice201'; // when there is no enough for a bulk run.
33
 
34
  const MSG_NO_APIKEY = 'ApiNotice300'; // API Key not found
360
  if ($month_notice === false)
361
  {
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
  }
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;
720
  return $notices;
721
  }
722
 
723
+ protected function monthlyUpgradeNeeded($quotaData)
724
+ {
725
+
726
 
727
  if (isset($quotaData->monthly->total))
728
  {
729
  $monthAvg = $this->getMonthAvg($quotaData);
730
  // +20 I suspect to not trigger on very low values of monthly use(?)
731
+ $threshold = $quotaData->monthly->total + ($quotaData->onetime->remaining / 6 ) +20;
732
+
733
  if ($monthAvg > $threshold)
734
  {
735
  return true;
753
  protected function getMonthAvg() {
754
  $stats = StatsController::getInstance();
755
 
756
+ return 100000;
757
+
758
  // Count how many months have some optimized images.
759
  for($i = 4, $count = 0; $i>=1; $i--) {
760
  if($count == 0 && $stats->find('period', 'months', $i) == 0)
class/Controller/AjaxController.php CHANGED
@@ -498,9 +498,11 @@ class AjaxController
498
 
499
  // $this->ajax_getItemView();
500
 
501
- $mediaItem->deleteMeta(); // also does reset prevent.
502
- delete_post_meta($id, '_shortpixel_was_converted');
 
503
 
 
504
  //$mediaItem = $this->getMediaItem($id, $type);
505
 
506
  /* $json->status = true;
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
 
505
+ $mediaItem->migrate();
506
  //$mediaItem = $this->getMediaItem($id, $type);
507
 
508
  /* $json->status = true;
class/Controller/ApiController.php CHANGED
@@ -592,10 +592,13 @@ class ApiController
592
 
593
  if ($fail)
594
  {
 
 
595
  return $this->returnFailure($error, __('Error downloading file','shortpixel-image-optimiser') . " ({$optimizedUrl}) " . $error_message);
596
  }
597
  else
598
  {
 
599
  return $this->returnRetry($error, __('Error downloading file','shortpixel-image-optimiser') . " ({$optimizedUrl}) " . $error_message);
600
  }
601
  }
592
 
593
  if ($fail)
594
  {
595
+
596
+ Log::addError('[Fatal] Failed downloading file ', $error_message);
597
  return $this->returnFailure($error, __('Error downloading file','shortpixel-image-optimiser') . " ({$optimizedUrl}) " . $error_message);
598
  }
599
  else
600
  {
601
+ Log::addWarn('Failed downloading file ', $error_message);
602
  return $this->returnRetry($error, __('Error downloading file','shortpixel-image-optimiser') . " ({$optimizedUrl}) " . $error_message);
603
  }
604
  }
class/Controller/FileSystemController.php CHANGED
@@ -76,7 +76,7 @@ Class FileSystemController extends \ShortPixel\Controller
76
 
77
  if (is_object($imageObj))
78
  {
79
- self::$customItems[$id] = $imageObj;
80
  }
81
 
82
  return $imageObj;
@@ -250,12 +250,23 @@ Class FileSystemController extends \ShortPixel\Controller
250
  $filepath = $file->getFullPath();
251
  $directory = $file->getFileDir();
252
 
 
 
 
253
  // stolen from wp_get_attachment_url
254
  if ( ( $uploads = wp_get_upload_dir() ) && (false === $uploads['error'] || strlen(trim($uploads['error'])) == 0 ) ) {
255
  // Check that the upload base exists in the file location.
256
- if ( 0 === strpos( $filepath, $uploads['basedir'] ) ) {
257
  // Replace file location with url location.
258
  $url = str_replace( $uploads['basedir'], $uploads['baseurl'], $filepath );
 
 
 
 
 
 
 
 
259
  } elseif ( false !== strpos( $filepath, 'wp-content/uploads' ) ) {
260
  // Get the directory name relative to the basedir (back compat for pre-2.7 uploads)
261
  $url = trailingslashit( $uploads['baseurl'] . '/' . _wp_get_attachment_relative_path( $filepath ) ) . wp_basename( $filepath );
@@ -273,12 +284,12 @@ Class FileSystemController extends \ShortPixel\Controller
273
  // This is SITE URL, for the same reason it should be home_url in FILEMODEL. The difference is when the site is running on a subdirectory
274
  // (1) ** This is a fix for a real-life issue, do not change if this causes issues, another fix is needed then.
275
  // (2) ** Also a real life fix when a path is /wwwroot/assets/sites/2/ etc, in get site url, the home URL is the site URL, without appending the sites stuff. Fails on original image.
276
- if ($this->env->is_multisite && ! $this->env->is_mainsite)
277
- {
278
- $wp_home_path = wp_normalize_path(trailingslashit($uploads['basedir']));
279
- $home_url = trailingslashit($uploads['baseurl']);
280
- }
281
- else
282
  $home_url = trailingslashit(get_site_url()); // (1)
283
  $url = str_replace($wp_home_path, $home_url, $filepath);
284
  }
@@ -404,7 +415,7 @@ Class FileSystemController extends \ShortPixel\Controller
404
  }
405
 
406
  Log::addDebug('Remote Download attempt result', array($url, $destinationPath));
407
- if ($destinationPath->exists())
408
  return true;
409
  else
410
  return false;
76
 
77
  if (is_object($imageObj))
78
  {
79
+ self::$customItems[$id] = $imageObj;
80
  }
81
 
82
  return $imageObj;
250
  $filepath = $file->getFullPath();
251
  $directory = $file->getFileDir();
252
 
253
+ $is_multi_site = $this->env->is_multisite;
254
+ $is_main_site = $this->env->is_mainsite;
255
+
256
  // stolen from wp_get_attachment_url
257
  if ( ( $uploads = wp_get_upload_dir() ) && (false === $uploads['error'] || strlen(trim($uploads['error'])) == 0 ) ) {
258
  // Check that the upload base exists in the file location.
259
+ if ( 0 === strpos( $filepath, $uploads['basedir'] ) ) { // Simple as it should, filepath and basedir share.
260
  // Replace file location with url location.
261
  $url = str_replace( $uploads['basedir'], $uploads['baseurl'], $filepath );
262
+ }
263
+ // Multisite backups are stored under uploads/ShortpixelBackups/etc , but basedir would include uploads/sites/2 etc, not matching above
264
+ // If this is case, test if removing the last two directories will result in a 'clean' uploads reference.
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)
272
  $url = trailingslashit( $uploads['baseurl'] . '/' . _wp_get_attachment_relative_path( $filepath ) ) . wp_basename( $filepath );
284
  // This is SITE URL, for the same reason it should be home_url in FILEMODEL. The difference is when the site is running on a subdirectory
285
  // (1) ** This is a fix for a real-life issue, do not change if this causes issues, another fix is needed then.
286
  // (2) ** Also a real life fix when a path is /wwwroot/assets/sites/2/ etc, in get site url, the home URL is the site URL, without appending the sites stuff. Fails on original image.
287
+ if ($is_multi_site && ! $is_main_site)
288
+ {
289
+ $wp_home_path = wp_normalize_path(trailingslashit($uploads['basedir']));
290
+ $home_url = trailingslashit($uploads['baseurl']);
291
+ }
292
+ else
293
  $home_url = trailingslashit(get_site_url()); // (1)
294
  $url = str_replace($wp_home_path, $home_url, $filepath);
295
  }
415
  }
416
 
417
  Log::addDebug('Remote Download attempt result', array($url, $destinationPath));
418
+ if ($destinationFile->exists())
419
  return true;
420
  else
421
  return false;
class/Controller/OptimizeController.php CHANGED
@@ -420,12 +420,11 @@ class OptimizeController
420
  $imageObj->restore();
421
  break;
422
  case 'migrate':
423
- // Loading the item should already be enough to trigger.
424
  break;
425
  case 'png2jpg':
426
  $item = $this->convertPNG($item, $q);
427
  $item->result->is_done = false; // if not, finished to newly enqueued
428
- // @todo Tell ResponseControllers about those actions
429
  break;
430
  case 'removeLegacy':
431
  $imageObj->removeLegacyShortPixel();
@@ -578,7 +577,6 @@ class OptimizeController
578
  $item->result->apiStatus = ApiController::STATUS_SUCCESS;
579
  $item->fileStatus = ImageModel::FILE_STATUS_SUCCESS;
580
 
581
- // $item->result->message = sprintf(__('Image %s optimized', 'shortpixel-image-optimiser'), $imageItem->getFileName());
582
  do_action('shortpixel_image_optimised', $imageItem->get('id'));
583
  do_action('shortpixel/image/optimised', $imageItem);
584
  }
420
  $imageObj->restore();
421
  break;
422
  case 'migrate':
423
+ $imageObj->migrate(); // hard migrate in bulk, to check if all is there / resync on problems.
424
  break;
425
  case 'png2jpg':
426
  $item = $this->convertPNG($item, $q);
427
  $item->result->is_done = false; // if not, finished to newly enqueued
 
428
  break;
429
  case 'removeLegacy':
430
  $imageObj->removeLegacyShortPixel();
577
  $item->result->apiStatus = ApiController::STATUS_SUCCESS;
578
  $item->fileStatus = ImageModel::FILE_STATUS_SUCCESS;
579
 
 
580
  do_action('shortpixel_image_optimised', $imageItem->get('id'));
581
  do_action('shortpixel/image/optimised', $imageItem);
582
  }
class/Controller/Queue/Queue.php CHANGED
@@ -58,7 +58,6 @@ abstract class Queue
58
 
59
  public function resetQueue()
60
  {
61
- Log::addTemp('Resetting Queue: ' . $this->getQueueName());
62
  $this->q->resetQueue();
63
  }
64
 
@@ -244,7 +243,6 @@ abstract class Queue
244
  }
245
  else
246
  {
247
- Log::addTemp('MediaItem not is processable');
248
  $response = array(
249
  'is_error' => true,
250
  'item_type' => ResponseController::ISSUE_QUEUE_FAILED,
58
 
59
  public function resetQueue()
60
  {
 
61
  $this->q->resetQueue();
62
  }
63
 
243
  }
244
  else
245
  {
 
246
  $response = array(
247
  'is_error' => true,
248
  'item_type' => ResponseController::ISSUE_QUEUE_FAILED,
class/Controller/QuotaController.php CHANGED
@@ -145,9 +145,15 @@ class QuotaController
145
 
146
  $settings->prioritySkip = array();
147
  $settings->dismissedNotices = $dismissed;
 
148
  AdminNoticesController::resetAPINotices();
149
- AdminNoticesController::resetQuotaNotices();
150
- Log::addDebug('Reset Quota Exceeded and reset Notices');
 
 
 
 
 
151
  $settings->quotaExceeded = 0;
152
  }
153
 
@@ -159,7 +165,6 @@ class QuotaController
159
  {
160
  $keyControl = ApiKeyController::getInstance();
161
  $apiKey = $keyControl->forceGetApiKey();
162
- Log::addTemp('ApiKey for remoteQuota ' . $apiKey);
163
  }
164
 
165
 
145
 
146
  $settings->prioritySkip = array();
147
  $settings->dismissedNotices = $dismissed;
148
+
149
  AdminNoticesController::resetAPINotices();
150
+
151
+ // Only reset after a quotaExceeded situation, otherwise it keeps popping.
152
+ if ($settings->quotaExceeded == 1)
153
+ {
154
+ AdminNoticesController::resetQuotaNotices();
155
+ }
156
+ Log::addDebug('Reset Quota Exceeded and reset Notices');
157
  $settings->quotaExceeded = 0;
158
  }
159
 
165
  {
166
  $keyControl = ApiKeyController::getInstance();
167
  $apiKey = $keyControl->forceGetApiKey();
 
168
  }
169
 
170
 
class/Controller/SettingsController.php CHANGED
@@ -349,7 +349,6 @@ class SettingsController extends \ShortPixel\ViewController
349
 
350
 
351
  // Every save, force load the quota. One reason, because of the HTTP Auth settings refresh.
352
- Log::addTemp('calling load Quota');
353
  $this->loadQuotaData(true);
354
 
355
  // end
349
 
350
 
351
  // Every save, force load the quota. One reason, because of the HTTP Auth settings refresh.
 
352
  $this->loadQuotaData(true);
353
 
354
  // end
class/Controller/View/EditMediaViewController.php CHANGED
@@ -126,7 +126,8 @@ class EditMediaViewController extends \ShortPixel\ViewController
126
  {
127
  $from = $imageObj->getMeta('originalWidth') . 'x' . $imageObj->getMeta('originalHeight');
128
  $to = $imageObj->getMeta('resizeWidth') . 'x' . $imageObj->getMeta('resizeHeight');
129
- $stats[] = array(sprintf(__('Resized %s to %s'), $from, $to), '');
 
130
  }
131
 
132
  $tsOptimized = $imageObj->getMeta('tsOptimized');
@@ -176,6 +177,8 @@ class EditMediaViewController extends \ShortPixel\ViewController
176
  $thumbnails = $imageObj->get('thumbnails');
177
  $processable = ($imageObj->isProcessable()) ? '<span class="green">Yes</span>' : '<span class="red">No</span> (' . $imageObj->getReason('processable') . ')';
178
  $restorable = ($imageObj->isRestorable()) ? '<span class="green">Yes</span>' : '<span class="red">No</span> (' . $imageObj->getReason('restorable') . ')';
 
 
179
  // $sizes = isset($this->data['sizes']) ? $this->data['sizes'] : array();
180
 
181
  //$debugMeta = $imageObj->debugGetImageMeta();
@@ -196,6 +199,7 @@ class EditMediaViewController extends \ShortPixel\ViewController
196
 
197
  $debugInfo[] = array(__('Processable'), $processable);
198
  $debugInfo[] = array(__('Restorable'), $restorable);
 
199
 
200
  $debugInfo[] = array(__('WPML Duplicates'), json_encode($imageObj->getWPMLDuplicates()) );
201
 
@@ -261,10 +265,13 @@ class EditMediaViewController extends \ShortPixel\ViewController
261
 
262
  $processable = ($thumbObj->isProcessable()) ? '<span class="green">Yes</span>' : '<span class="red">No</span> (' . $thumbObj->getReason('processable') . ')';
263
  $restorable = ($thumbObj->isRestorable()) ? '<span class="green">Yes</span>' : '<span class="red">No</span> (' . $thumbObj->getReason('restorable') . ')';
 
 
 
264
 
265
  $debugInfo[] = array('', "<div class='$size previewwrapper'><img src='" . $url . "'><p class='label'>
266
  <b>URL:</b> $url ( $display_size - $width X $height ) <br><b>FileName:</b> $filename <br> <b>Backup:</b> $backup </p>
267
- <p><b>Processable: </b> $processable <br> <b>Restorable:</b> $restorable</p>
268
  <hr></div>");
269
  }
270
  }
126
  {
127
  $from = $imageObj->getMeta('originalWidth') . 'x' . $imageObj->getMeta('originalHeight');
128
  $to = $imageObj->getMeta('resizeWidth') . 'x' . $imageObj->getMeta('resizeHeight');
129
+ $type = ($imageObj->getMeta('resizeType') !== null) ? '(' . $imageObj->getMeta('resizeType') . ')' : '';
130
+ $stats[] = array(sprintf(__('Resized %s %s to %s'), $type, $from, $to), '');
131
  }
132
 
133
  $tsOptimized = $imageObj->getMeta('tsOptimized');
177
  $thumbnails = $imageObj->get('thumbnails');
178
  $processable = ($imageObj->isProcessable()) ? '<span class="green">Yes</span>' : '<span class="red">No</span> (' . $imageObj->getReason('processable') . ')';
179
  $restorable = ($imageObj->isRestorable()) ? '<span class="green">Yes</span>' : '<span class="red">No</span> (' . $imageObj->getReason('restorable') . ')';
180
+
181
+ $hasrecord = ($imageObj->hasDBRecord()) ? '<span class="green">Yes</span>' : '<span class="red">No</span> ';
182
  // $sizes = isset($this->data['sizes']) ? $this->data['sizes'] : array();
183
 
184
  //$debugMeta = $imageObj->debugGetImageMeta();
199
 
200
  $debugInfo[] = array(__('Processable'), $processable);
201
  $debugInfo[] = array(__('Restorable'), $restorable);
202
+ $debugInfo[] = array(__('Record'), $hasrecord);
203
 
204
  $debugInfo[] = array(__('WPML Duplicates'), json_encode($imageObj->getWPMLDuplicates()) );
205
 
265
 
266
  $processable = ($thumbObj->isProcessable()) ? '<span class="green">Yes</span>' : '<span class="red">No</span> (' . $thumbObj->getReason('processable') . ')';
267
  $restorable = ($thumbObj->isRestorable()) ? '<span class="green">Yes</span>' : '<span class="red">No</span> (' . $thumbObj->getReason('restorable') . ')';
268
+ $hasrecord = ($thumbObj->hasDBRecord()) ? '<span class="green">Yes</span>' : '<span class="red">No</span> ';
269
+
270
+ $dbid = $thumbObj->getMeta('databaseID');
271
 
272
  $debugInfo[] = array('', "<div class='$size previewwrapper'><img src='" . $url . "'><p class='label'>
273
  <b>URL:</b> $url ( $display_size - $width X $height ) <br><b>FileName:</b> $filename <br> <b>Backup:</b> $backup </p>
274
+ <p><b>Processable: </b> $processable <br> <b>Restorable:</b> $restorable <br> <b>Record:</b> $hasrecord ($dbid) </p>
275
  <hr></div>");
276
  }
277
  }
class/Controller/View/ListMediaViewController.php CHANGED
@@ -220,10 +220,6 @@ class ListMediaViewController extends \ShortPixel\ViewController
220
 
221
  $vars['shortpixel-filter'] = $filter;
222
 
223
- if (isset($vars['post_type']))
224
- {
225
- unset($vars['post_type']); // no need to query this when going custom.
226
- }
227
  }
228
 
229
  return $vars;
220
 
221
  $vars['shortpixel-filter'] = $filter;
222
 
 
 
 
 
223
  }
224
 
225
  return $vars;
class/Controller/View/OtherMediaViewController.php CHANGED
@@ -29,12 +29,10 @@ class OtherMediaViewController extends \ShortPixel\ViewController
29
  protected $show_hidden = false;
30
  protected $has_hidden_items = false;
31
 
32
- protected $actions = array();
33
-
34
  public function __construct()
35
  {
36
  parent::__construct();
37
- $this->setActions(); // possible actions for ROWS only..
38
 
39
  // 2015: https://github.com/WordPress/WordPress-Coding-Standards/issues/426 !
40
  // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- This is not a form
@@ -81,28 +79,6 @@ class OtherMediaViewController extends \ShortPixel\ViewController
81
  }
82
 
83
 
84
- /** Sets all possible actions and it's links. Doesn't check what can be loaded per individual case. */
85
-
86
- protected function setActions()
87
- {
88
- $nonce = wp_create_nonce( 'sp_custom_action' );
89
- $keyControl = ApiKeyController::getInstance();
90
-
91
- $actions = array(
92
- 'optimize' => array('action' => 'optimize', '_wpnonce' => $nonce , 'text' => __('Optimize now','shortpixel-image-optimiser'), 'class' => ''),
93
-
94
- 'quota' => array('action' => 'check-quota', '_wpnonce' => $nonce, 'text' =>__('Check quota','shortpixel-image-optimiser'), 'class' => 'button button-smaller'),
95
- 'extend-quota' => array('link' => '<a href="https://shortpixel.com/login/' . $keyControl->getKeyForDisplay() . '" target="_blank" class="button-primary button-smaller">' . __('Extend Quota','shortpixel-image-optimiser') . '</a>'),
96
-
97
-
98
- 'view' => array('link' => '<a href="%%item_url%%" target="_blank">%%text%%</a>', 'text' => __('View','shortpixel-image-optimiser')),
99
-
100
-
101
-
102
- );
103
- $this->actions = $actions;
104
- }
105
-
106
  protected function getHeadings()
107
  {
108
  $headings = array(
@@ -421,23 +397,26 @@ class OtherMediaViewController extends \ShortPixel\ViewController
421
  */
422
  protected function getRowActions($item)
423
  {
424
- $thisActions = array();
425
- $thisActions[] = $this->actions['view']; // always .
426
  $settings = \wpSPIO()->settings();
427
 
428
  $keyControl = ApiKeyController::getInstance();
429
 
430
- if ($settings->quotaExceeded || ! $keyControl->keyIsVerified() )
431
- {
432
- return $this->renderActions($thisActions, $item); // nothing more.
433
- }
434
 
435
- if ($item->isProcessable())
436
- {
437
- $thisActions[] = $this->actions['optimize'];
438
- }
 
 
 
 
 
439
 
440
- return $this->renderActions($thisActions, $item);
 
 
 
441
  }
442
 
443
  // Function to sync output exactly with Media Library functions for consistency
@@ -471,6 +450,7 @@ class OtherMediaViewController extends \ShortPixel\ViewController
471
  foreach($actions as $actionName => $action):
472
  $classes = ($action['display'] == 'button') ? " button-smaller button-primary $actionName " : "$actionName";
473
  $link = ($action['type'] == 'js') ? 'javascript:' . $action['function'] : $action['function'];
 
474
 
475
  // @todo Esc url is not successfull with JS links
476
  ?>
@@ -483,47 +463,6 @@ class OtherMediaViewController extends \ShortPixel\ViewController
483
  }
484
 
485
 
486
- // Used for row actions at the moment. Action under the image.
487
- protected function renderActions($actions, $item, $forceSingular = false)
488
- {
489
-
490
-
491
- foreach($actions as $index => $action)
492
- {
493
- $text = isset($action['text']) ? $action['text'] : '';
494
-
495
- if (isset($action['link']))
496
- {
497
- $fs = \wpSPIO()->filesystem();
498
- $item_url = $fs->pathToUrl($item);
499
-
500
- $link = $action['link'];
501
- $link = str_replace('%%item_id%%', $item->get('id'), $link);
502
- $link = str_replace('%%text%%', $text, $link);
503
- $link = str_replace('%%item_url%%', $item_url, $link);
504
- }
505
- else
506
- {
507
- $action_arg = $action['action']; //
508
- $nonce = $action['_wpnonce'];
509
- $url = $this->getPageURL(array('action' => $action_arg, '_wpnonce' => $nonce, 'item_id' => $item->get('id') ));
510
- if (isset($action['type']))
511
- $url = add_query_arg('type', $action['type'], $url);
512
- $class = (isset($action['class'])) ? $action['class'] : '';
513
-
514
- $link = '<a href="' . esc_url($url) . '" class="action-' . esc_attr($action_arg) . ' ' . esc_attr($class) . '">' . esc_html($text) . '</a>';
515
- }
516
-
517
- $actions[$index] = $link;
518
- }
519
-
520
- if ($forceSingular)
521
- {
522
- array_unshift($actions, 'render-loose');
523
- }
524
- return $actions;
525
- }
526
-
527
  protected function getDisplayHeading($heading)
528
  {
529
  $output = '';
29
  protected $show_hidden = false;
30
  protected $has_hidden_items = false;
31
 
 
 
32
  public function __construct()
33
  {
34
  parent::__construct();
35
+
36
 
37
  // 2015: https://github.com/WordPress/WordPress-Coding-Standards/issues/426 !
38
  // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- This is not a form
79
  }
80
 
81
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
82
  protected function getHeadings()
83
  {
84
  $headings = array(
397
  */
398
  protected function getRowActions($item)
399
  {
400
+
 
401
  $settings = \wpSPIO()->settings();
402
 
403
  $keyControl = ApiKeyController::getInstance();
404
 
 
 
 
 
405
 
406
+ $actions = UIHelper::getActions($item);
407
+
408
+ $viewAction = array('view' => array(
409
+ 'function' => $item->getUrl(),
410
+ 'type' => 'link',
411
+ 'text' => __('View', 'shortpixel-image-optimiser'),
412
+ 'display' => 'inline',
413
+
414
+ ));
415
 
416
+ if ($settings->quotaExceeded || ! $keyControl->keyIsVerified() )
417
+ $this->view->actions = $viewAction;
418
+ else
419
+ $this->view->actions = array_merge($viewAction,$actions);
420
  }
421
 
422
  // Function to sync output exactly with Media Library functions for consistency
450
  foreach($actions as $actionName => $action):
451
  $classes = ($action['display'] == 'button') ? " button-smaller button-primary $actionName " : "$actionName";
452
  $link = ($action['type'] == 'js') ? 'javascript:' . $action['function'] : $action['function'];
453
+ $newtab = ($actionName == 'extendquota') ? 'target="_blank"' : '';
454
 
455
  // @todo Esc url is not successfull with JS links
456
  ?>
463
  }
464
 
465
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
466
  protected function getDisplayHeading($heading)
467
  {
468
  $output = '';
class/Helper/UiHelper.php CHANGED
@@ -319,6 +319,10 @@ class UiHelper
319
  }
320
  } // hasBackup
321
 
 
 
 
 
322
  } //isOptimized
323
 
324
  if(! $quotaControl->hasQuota())
@@ -515,7 +519,6 @@ class UiHelper
515
  $action['text'] = __('Re-optimize Lossless','shortpixel-image-optimiser');
516
  $action['display'] = 'inline';
517
  break;
518
-
519
  case 'extendquota':
520
  $action['function'] = 'https://shortpixel.com/login/'. $keyControl->getKeyForDisplay();
521
  $action['type'] = 'button';
@@ -527,7 +530,6 @@ class UiHelper
527
  $action['type'] = 'js';
528
  $action['display'] = 'button';
529
  $action['text'] = __('Check&nbsp;&nbsp;Quota','shortpixel-image-optimiser');
530
-
531
  break;
532
  }
533
 
319
  }
320
  } // hasBackup
321
 
322
+ if (\wpSPIO()->env()->is_debug && $mediaItem->get('type') == 'media')
323
+ {
324
+ $list_actions['redo_legacy'] = self::getAction('redo_legacy', $id);
325
+ }
326
  } //isOptimized
327
 
328
  if(! $quotaControl->hasQuota())
519
  $action['text'] = __('Re-optimize Lossless','shortpixel-image-optimiser');
520
  $action['display'] = 'inline';
521
  break;
 
522
  case 'extendquota':
523
  $action['function'] = 'https://shortpixel.com/login/'. $keyControl->getKeyForDisplay();
524
  $action['type'] = 'button';
530
  $action['type'] = 'js';
531
  $action['display'] = 'button';
532
  $action['text'] = __('Check&nbsp;&nbsp;Quota','shortpixel-image-optimiser');
 
533
  break;
534
  }
535
 
class/Model/File/FileModel.php CHANGED
@@ -415,7 +415,7 @@ class FileModel extends \ShortPixel\Model
415
  if (is_null($this->mime))
416
  $this->setFileInfo();
417
 
418
- if ($this->exists())
419
  {
420
  $this->mime = wp_get_image_mime($this->fullpath);
421
  }
@@ -486,11 +486,17 @@ class FileModel extends \ShortPixel\Model
486
  {
487
  return $path;
488
  }
 
 
 
 
 
 
489
  elseif (strpos($path, $abspath->getPath()) === false)
490
  {
491
  // if path does not contain basepath.
492
- $uploadDir = $fs->getWPUploadBase();
493
- $abspath = $fs->getWPAbsPath();
494
 
495
  $path = $this->relativeToFullPath($path);
496
  }
@@ -535,7 +541,7 @@ class FileModel extends \ShortPixel\Model
535
 
536
  $this->is_virtual = true;
537
 
538
-
539
  $path = apply_filters('shortpixel/image/urltopath', false, $url);
540
 
541
  if ($path !== false)
@@ -675,6 +681,7 @@ class FileModel extends \ShortPixel\Model
675
  'exists' => $this->exists,
676
  'is_writable' => $this->is_writable,
677
  'is_readable' => $this->is_readable,
 
678
  ];
679
  }
680
 
415
  if (is_null($this->mime))
416
  $this->setFileInfo();
417
 
418
+ if ($this->exists() && ! $this->is_virtual() )
419
  {
420
  $this->mime = wp_get_image_mime($this->fullpath);
421
  }
486
  {
487
  return $path;
488
  }
489
+ // If attempted file does not exist, but the file is in a dir that exists, that is good enough.
490
+ elseif ( ! is_dir($path) && is_dir(dirname($path)) )
491
+ {
492
+ return $path;
493
+ }
494
+ // If path is not in the abspath, it might be relative.
495
  elseif (strpos($path, $abspath->getPath()) === false)
496
  {
497
  // if path does not contain basepath.
498
+ //$uploadDir = $fs->getWPUploadBase();
499
+ //$abspath = $fs->getWPAbsPath();
500
 
501
  $path = $this->relativeToFullPath($path);
502
  }
541
 
542
  $this->is_virtual = true;
543
 
544
+ // This filter checks if some supplier will be able to handle the file when needed.
545
  $path = apply_filters('shortpixel/image/urltopath', false, $url);
546
 
547
  if ($path !== false)
681
  'exists' => $this->exists,
682
  'is_writable' => $this->is_writable,
683
  'is_readable' => $this->is_readable,
684
+ 'is_virtual' => $this->is_virtual,
685
  ];
686
  }
687
 
class/Model/Image/ImageModel.php CHANGED
@@ -550,6 +550,8 @@ abstract class ImageModel extends \ShortPixel\Model\File\FileModel
550
  $this->setMeta('resizeWidth', $this->get('width') );
551
  $this->setMeta('resizeHeight', $this->get('height') );
552
  $this->setMeta('resize', true);
 
 
553
  }
554
  else
555
  $this->setMeta('resize', false);
@@ -605,7 +607,10 @@ abstract class ImageModel extends \ShortPixel\Model\File\FileModel
605
 
606
  public function handleOptimizedFileType($downloadResults)
607
  {
608
- $webpFile = $this->getFileBase() . '.webp';
 
 
 
609
 
610
  if (isset($downloadResults[$webpFile]) && isset($downloadResults[$webpFile]->file)) // check if there is webp with same filename
611
  {
@@ -616,7 +621,7 @@ abstract class ImageModel extends \ShortPixel\Model\File\FileModel
616
  $this->setMeta('webp', $webpResult->getFileName());
617
  }
618
 
619
- $avifFile = $this->getFileBase() . '.avif';
620
 
621
  if (isset($downloadResults[$avifFile]) && isset($downloadResults[$avifFile]->file)) // check if there is webp with same filename
622
  {
@@ -782,7 +787,18 @@ abstract class ImageModel extends \ShortPixel\Model\File\FileModel
782
  protected function handleWebp(FileModel $tempFile)
783
  {
784
  $fs = \wpSPIO()->filesystem();
785
- $target = $fs->getFile( (string) $this->getFileDir() . $this->getFileBase() . '.webp');
 
 
 
 
 
 
 
 
 
 
 
786
 
787
  // only copy when this constant is set.
788
  if( (defined('SHORTPIXEL_USE_DOUBLE_WEBP_EXTENSION') && SHORTPIXEL_USE_DOUBLE_WEBP_EXTENSION) == true ) {
@@ -790,6 +806,7 @@ abstract class ImageModel extends \ShortPixel\Model\File\FileModel
790
  }
791
 
792
 
 
793
  $result = false;
794
 
795
  if (! $target->exists()) // don't copy if exists.
@@ -815,7 +832,17 @@ abstract class ImageModel extends \ShortPixel\Model\File\FileModel
815
  protected function handleAvif(FileModel $tempFile)
816
  {
817
  $fs = \wpSPIO()->filesystem();
818
- $target = $fs->getFile( (string) $this->getFileDir() . $this->getFileBase() . '.avif');
 
 
 
 
 
 
 
 
 
 
819
 
820
  // only copy when this constant is set.
821
  if( (defined('SHORTPIXEL_USE_DOUBLE_AVIF_EXTENSION') && SHORTPIXEL_USE_DOUBLE_AVIF_EXTENSION) == true ) {
550
  $this->setMeta('resizeWidth', $this->get('width') );
551
  $this->setMeta('resizeHeight', $this->get('height') );
552
  $this->setMeta('resize', true);
553
+ $resizeType = ($settings->resizeType == 1) ? __('Cover', 'shortpixel-image-optimiser') : __('Contain', 'shortpixel-image-optimiser');
554
+ $this->setMeta('resizeType', $resizeType);
555
  }
556
  else
557
  $this->setMeta('resize', false);
607
 
608
  public function handleOptimizedFileType($downloadResults)
609
  {
610
+
611
+ $filebase = $this->getFileBase();
612
+
613
+ $webpFile = $filebase . '.webp';
614
 
615
  if (isset($downloadResults[$webpFile]) && isset($downloadResults[$webpFile]->file)) // check if there is webp with same filename
616
  {
621
  $this->setMeta('webp', $webpResult->getFileName());
622
  }
623
 
624
+ $avifFile = $filebase . '.avif';
625
 
626
  if (isset($downloadResults[$avifFile]) && isset($downloadResults[$avifFile]->file)) // check if there is webp with same filename
627
  {
787
  protected function handleWebp(FileModel $tempFile)
788
  {
789
  $fs = \wpSPIO()->filesystem();
790
+ if ($this->is_virtual())
791
+ {
792
+ $fullpath = apply_filters('shortpixel/file/virtual/translate', $this->getFullPath(), $this);
793
+ $fileObj = $fs->getFile($fullpath);
794
+ $fileDir = $fileObj->getFileDir();
795
+ }
796
+ else {
797
+ $fileDir = $this->getFileDir();
798
+ }
799
+
800
+ $target = $fs->getFile( (string) $fileDir . $this->getFileBase() . '.webp');
801
+
802
 
803
  // only copy when this constant is set.
804
  if( (defined('SHORTPIXEL_USE_DOUBLE_WEBP_EXTENSION') && SHORTPIXEL_USE_DOUBLE_WEBP_EXTENSION) == true ) {
806
  }
807
 
808
 
809
+
810
  $result = false;
811
 
812
  if (! $target->exists()) // don't copy if exists.
832
  protected function handleAvif(FileModel $tempFile)
833
  {
834
  $fs = \wpSPIO()->filesystem();
835
+ if ($this->is_virtual())
836
+ {
837
+ $fullpath = apply_filters('shortpixel/file/virtual/translate', $this->getFullPath(), $this);
838
+ $fileObj = $fs->getFile($fullpath);
839
+ $fileDir = $fileObj->getFileDir();
840
+ }
841
+ else {
842
+ $fileDir = $this->getFileDir();
843
+ }
844
+
845
+ $target = $fs->getFile( (string) $fileDir . $this->getFileBase() . '.avif');
846
 
847
  // only copy when this constant is set.
848
  if( (defined('SHORTPIXEL_USE_DOUBLE_AVIF_EXTENSION') && SHORTPIXEL_USE_DOUBLE_AVIF_EXTENSION) == true ) {
class/Model/Image/ImageThumbnailMeta.php CHANGED
@@ -18,6 +18,7 @@ class ImageThumbnailMeta
18
  public $resize;
19
  public $resizeWidth;
20
  public $resizeHeight;
 
21
  public $originalWidth;
22
  public $originalHeight;
23
 
@@ -26,6 +27,7 @@ class ImageThumbnailMeta
26
  public $webp;
27
  public $avif;
28
 
 
29
  public $file; // **Only for unlisted images. This defines an unlisted image */
30
 
31
  // Only for customImageModel! Exception to prevent having to create a whole class. Second var here, warrants a subclass.
18
  public $resize;
19
  public $resizeWidth;
20
  public $resizeHeight;
21
+ public $resizeType;
22
  public $originalWidth;
23
  public $originalHeight;
24
 
27
  public $webp;
28
  public $avif;
29
 
30
+
31
  public $file; // **Only for unlisted images. This defines an unlisted image */
32
 
33
  // Only for customImageModel! Exception to prevent having to create a whole class. Second var here, warrants a subclass.
class/Model/Image/MediaLibraryModel.php CHANGED
@@ -28,6 +28,7 @@ class MediaLibraryModel extends \ShortPixel\Model\Image\MediaLibraryThumbnailMod
28
  private static $unlistedChecked = array(); // limit checking unlisted.
29
 
30
  private $optimizePrevented; // cache if there is any reason to prevent optimizing
 
31
 
32
  const IMAGE_TYPE_MAIN = 0;
33
  const IMAGE_TYPE_THUMB = 1;
@@ -1398,9 +1399,6 @@ class MediaLibraryModel extends \ShortPixel\Model\Image\MediaLibraryThumbnailMod
1398
  $width = $this->get('width');
1399
  $height = $this->get('height');
1400
 
1401
- // echo 'w/h'; print_r($width); echo ' '; print_r($height);
1402
- Log::addTemp('Excluded w/h check ' . $width . ' ' . $height);
1403
- // Log::addTemp('Check via', debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 3));
1404
 
1405
  if( $width && $height
1406
  && $this->isProcessableSize($width, $height, $item["value"]) === false){
@@ -1899,6 +1897,23 @@ class MediaLibraryModel extends \ShortPixel\Model\Image\MediaLibraryThumbnailMod
1899
  return $updated;
1900
  }
1901
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1902
  // Convert from old metadata if needed.
1903
  private function checkLegacy()
1904
  {
@@ -1965,59 +1980,61 @@ class MediaLibraryModel extends \ShortPixel\Model\Image\MediaLibraryThumbnailMod
1965
 
1966
  $tsAdded = time();
1967
 
1968
- if ($status == self::FILE_STATUS_SUCCESS)
1969
- {
1970
- //strtotime($tsOptimized)
1971
- $thedate = (isset($data['date'])) ? $data['date'] : false;
1972
- $newdate = \DateTime::createFromFormat('Y-m-d H:i:s', $thedate);
1973
-
1974
- if ($newdate === false)
1975
- {
1976
- $newdate = \DateTime::createFromFormat('Y-m-d H:i:s', get_post_time('Y-m-d H:i:s', false, $this->id));
1977
- }
1978
-
1979
- $newdate = $newdate->getTimestamp();
1980
-
1981
- $tsOptimized = $newdate;
1982
- $this->image_meta->tsOptimized = $tsOptimized;
1983
- }
1984
 
1985
- $this->image_meta->wasConverted = true;
1986
- $this->image_meta->status = $status;
1987
- //$this->image_meta->type = $type;
1988
- $this->image_meta->improvement = $improvement;
1989
- $this->image_meta->compressionType = $type;
1990
- $this->image_meta->compressedSize = $this->getFileSize();
1991
- // $this->image_meta->retries = $retries;
1992
- $this->image_meta->tsAdded = $tsAdded;
1993
- // $this->image_meta->has_backup = $this->hasBackup();
1994
- $this->image_meta->errorMessage = $error_message;
1995
-
1996
- $this->image_meta->did_keepExif = $exifkept;
1997
-
1998
- if ($this->hasBackup())
1999
- {
2000
- $backup = $this->getBackupFile();
2001
- $this->image_meta->originalSize = $backup->getFileSize();
2002
- }
2003
- elseif ( isset($metadata['ShortPixelImprovement']))
2004
- {
2005
- // If the improvement is set, calculate back originalsize.
2006
- $imp = intval($metadata['ShortPixelImprovement']); // try to make int. Legacy can contain errors / message / crap here.
2007
- if ($imp > 0)
2008
- $this->image_meta->originalSize = ($this->getFileSize() / (100 - $imp)) * 100;
2009
- }
2010
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2011
 
2012
- $this->image_meta->webp = $this->checkLegacyFileTypeFileName($this, 'webp');
2013
- $this->image_meta->avif = $this->checkLegacyFileTypeFileName($this, 'avif');
2014
 
 
 
2015
 
2016
- $this->width = isset($metadata['width']) ? $metadata['width'] : false;
2017
- $this->height = isset($metadata['height']) ? $metadata['height'] : false;
2018
 
2019
- $this->recordChanged(true);
 
2020
 
 
 
2021
 
2022
  if (isset($metadata['ShortPixelPng2Jpg']))
2023
  {
@@ -2031,12 +2048,19 @@ class MediaLibraryModel extends \ShortPixel\Model\Image\MediaLibraryThumbnailMod
2031
 
2032
  foreach($this->thumbnails as $thumbname => $thumbnailObj) // ThumbnailModel
2033
  {
2034
- if (in_array($thumbnailObj->getFileName(), $optimized_thumbnails))
 
 
 
 
 
2035
  {
2036
  $thumbnailObj->image_meta->status = $status;
2037
  $thumbnailObj->image_meta->compressionType = $type;
2038
  $thumbnailObj->image_meta->compressedSize = $thumbnailObj->getFileSize();
2039
  $thumbnailObj->image_meta->did_jpg2png = $did_jpg2png;
 
 
2040
  // $thumbnailObj->image_meta->improvement = -1; // n/a
2041
  if ($thumbnailObj->hasBackup())
2042
  {
@@ -2064,11 +2088,11 @@ class MediaLibraryModel extends \ShortPixel\Model\Image\MediaLibraryThumbnailMod
2064
  }
2065
  }
2066
 
2067
- if ($this->isScaled())
2068
  {
2069
  $originalFile = $this->original_file;
2070
 
2071
- if (isset($metadata['original_image']))
2072
  {
2073
 
2074
  $originalFile->image_meta->status = $status;
@@ -2097,6 +2121,7 @@ class MediaLibraryModel extends \ShortPixel\Model\Image\MediaLibraryThumbnailMod
2097
  }
2098
 
2099
  $originalFile->recordChanged(true);
 
2100
  }
2101
  }
2102
 
@@ -2140,6 +2165,7 @@ class MediaLibraryModel extends \ShortPixel\Model\Image\MediaLibraryThumbnailMod
2140
  update_post_meta($this->id, '_shortpixel_was_converted', time());
2141
  delete_post_meta($this->id, '_shortpixel_status');
2142
 
 
2143
  return true;
2144
  }
2145
 
28
  private static $unlistedChecked = array(); // limit checking unlisted.
29
 
30
  private $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;
34
  const IMAGE_TYPE_THUMB = 1;
1399
  $width = $this->get('width');
1400
  $height = $this->get('height');
1401
 
 
 
 
1402
 
1403
  if( $width && $height
1404
  && $this->isProcessableSize($width, $height, $item["value"]) === false){
1897
  return $updated;
1898
  }
1899
 
1900
+ // Function to be called only by migrate all bulk and certain debug cases.
1901
+ public function migrate()
1902
+ {
1903
+ $this->resetPrevent();
1904
+
1905
+ // Don't double.
1906
+ if ($this->justConverted === true)
1907
+ return;
1908
+
1909
+ delete_post_meta($this->id, '_shortpixel_was_converted');
1910
+ $result = $this->checkLegacy();
1911
+ if ($result)
1912
+ {
1913
+ $this->saveMeta();
1914
+ }
1915
+ }
1916
+
1917
  // Convert from old metadata if needed.
1918
  private function checkLegacy()
1919
  {
1980
 
1981
  $tsAdded = time();
1982
 
1983
+ if ($this->hasDBRecord() === false)
1984
+ {
1985
+ if ($status == self::FILE_STATUS_SUCCESS)
1986
+ {
1987
+ //strtotime($tsOptimized)
1988
+ $thedate = (isset($data['date'])) ? $data['date'] : false;
1989
+ $newdate = \DateTime::createFromFormat('Y-m-d H:i:s', $thedate);
 
 
 
 
 
 
 
 
 
1990
 
1991
+ if ($newdate === false)
1992
+ {
1993
+ $newdate = \DateTime::createFromFormat('Y-m-d H:i:s', get_post_time('Y-m-d H:i:s', false, $this->id));
1994
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1995
 
1996
+ $newdate = $newdate->getTimestamp();
1997
+
1998
+ $tsOptimized = $newdate;
1999
+ $this->image_meta->tsOptimized = $tsOptimized;
2000
+ }
2001
+
2002
+ $this->image_meta->wasConverted = true;
2003
+ $this->image_meta->status = $status;
2004
+ //$this->image_meta->type = $type;
2005
+ $this->image_meta->improvement = $improvement;
2006
+ $this->image_meta->compressionType = $type;
2007
+ $this->image_meta->compressedSize = $this->getFileSize();
2008
+ // $this->image_meta->retries = $retries;
2009
+ $this->image_meta->tsAdded = $tsAdded;
2010
+ // $this->image_meta->has_backup = $this->hasBackup();
2011
+ $this->image_meta->errorMessage = $error_message;
2012
+
2013
+ $this->image_meta->did_keepExif = $exifkept;
2014
+
2015
+ if ($this->hasBackup())
2016
+ {
2017
+ $backup = $this->getBackupFile();
2018
+ $this->image_meta->originalSize = $backup->getFileSize();
2019
+ }
2020
+ elseif ( isset($metadata['ShortPixelImprovement']))
2021
+ {
2022
+ // If the improvement is set, calculate back originalsize.
2023
+ $imp = intval($metadata['ShortPixelImprovement']); // try to make int. Legacy can contain errors / message / crap here.
2024
+ if ($imp > 0)
2025
+ $this->image_meta->originalSize = ($this->getFileSize() / (100 - $imp)) * 100;
2026
+ }
2027
 
 
 
2028
 
2029
+ $this->image_meta->webp = $this->checkLegacyFileTypeFileName($this, 'webp');
2030
+ $this->image_meta->avif = $this->checkLegacyFileTypeFileName($this, 'avif');
2031
 
 
 
2032
 
2033
+ $this->width = isset($metadata['width']) ? $metadata['width'] : false;
2034
+ $this->height = isset($metadata['height']) ? $metadata['height'] : false;
2035
 
2036
+ $this->recordChanged(true);
2037
+ }
2038
 
2039
  if (isset($metadata['ShortPixelPng2Jpg']))
2040
  {
2048
 
2049
  foreach($this->thumbnails as $thumbname => $thumbnailObj) // ThumbnailModel
2050
  {
2051
+ if ($thumbnailObj->hasDBRecord() === true)
2052
+ {
2053
+ continue;
2054
+ }
2055
+
2056
+ if (in_array($thumbnailObj->getFileName(), $optimized_thumbnails) || $thumbnailObj->hasBackup() )
2057
  {
2058
  $thumbnailObj->image_meta->status = $status;
2059
  $thumbnailObj->image_meta->compressionType = $type;
2060
  $thumbnailObj->image_meta->compressedSize = $thumbnailObj->getFileSize();
2061
  $thumbnailObj->image_meta->did_jpg2png = $did_jpg2png;
2062
+
2063
+
2064
  // $thumbnailObj->image_meta->improvement = -1; // n/a
2065
  if ($thumbnailObj->hasBackup())
2066
  {
2088
  }
2089
  }
2090
 
2091
+ if ($this->isScaled() && $this->original_file->hasDBRecord() === false)
2092
  {
2093
  $originalFile = $this->original_file;
2094
 
2095
+ if (isset($metadata['original_image']) || $originalFile->hasBackup())
2096
  {
2097
 
2098
  $originalFile->image_meta->status = $status;
2121
  }
2122
 
2123
  $originalFile->recordChanged(true);
2124
+ $this->original_file = $originalFile;
2125
  }
2126
  }
2127
 
2165
  update_post_meta($this->id, '_shortpixel_was_converted', time());
2166
  delete_post_meta($this->id, '_shortpixel_status');
2167
 
2168
+ $this->justConverted = true;
2169
  return true;
2170
  }
2171
 
class/Model/Image/MediaLibraryThumbnailModel.php CHANGED
@@ -158,10 +158,35 @@ class MediaLibraryThumbnailModel extends \ShortPixel\Model\Image\ImageModel
158
  $url = wp_get_original_image_url($this->id);
159
  }
160
  elseif ($this->isUnlisted())
 
161
  $url = $fs->pathToUrl($this);
 
162
  else
163
  {
164
- $url = wp_get_attachment_image_url($this->id, $this->size);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
165
  }
166
 
167
 
@@ -263,6 +288,35 @@ class MediaLibraryThumbnailModel extends \ShortPixel\Model\Image\ImageModel
263
  }
264
  }
265
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
266
  public function restore()
267
  {
268
  if ($this->is_virtual())
158
  $url = wp_get_original_image_url($this->id);
159
  }
160
  elseif ($this->isUnlisted())
161
+ {
162
  $url = $fs->pathToUrl($this);
163
+ }
164
  else
165
  {
166
+ // We can't trust higher lever function, or any WP functions. I.e. Woocommerce messes with the URL's if they like so.
167
+ // So get it from intermediate and if that doesn't work, default to pathToUrl - better than nothing.
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
+ }
175
+ elseif (isset($size_array['url']))
176
+ {
177
+ $url = $size_array['url'];
178
+ // Even this can go wrong :/
179
+ if (strpos($url, $this->getFileName() ) === false)
180
+ {
181
+ // Taken from image_get_intermediate_size if somebody still messes with the filters.
182
+ $mainurl = wp_get_attachment_url( $this->id);
183
+ $url = path_join( dirname( $mainurl ), $this->getFileName() );
184
+ }
185
+ }
186
+ else {
187
+ return false;
188
+ }
189
+
190
  }
191
 
192
 
288
  }
289
  }
290
 
291
+ public function hasDBRecord()
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
+
310
+ if (is_null($id))
311
+ {
312
+ return false;
313
+ }
314
+ elseif (is_numeric($id)) {
315
+ return true;
316
+ }
317
+
318
+ }
319
+
320
  public function restore()
321
  {
322
  if ($this->is_virtual())
class/external/wp-offload-media.php CHANGED
@@ -57,11 +57,12 @@ class wpOffload
57
  $this->offloading = false;
58
  }
59
 
60
- if ('cloudfront' === $this->as3cf->get_setting( 'domain' ))
 
61
  {
62
  $this->is_cname = true;
63
  $this->cname = $this->as3cf->get_setting( 'cloudfront' );
64
- }
65
 
66
  // $provider = $this->as3cf->get_provider();
67
  add_action('shortpixel/image/optimised', array($this, 'image_upload'), 10);
@@ -77,6 +78,8 @@ class wpOffload
77
  {
78
  // add_filter('as3cf_remove_source_files_from_provider', array($this, 'remove_webp_paths'), 10);
79
  add_action('shortpixel/image/convertpng2jpg_success', array($this, 'image_converted'), 10);
 
 
80
  }
81
  else {
82
  add_filter('as3cf_remove_attachment_paths', array($this, 'remove_webp_paths'));
@@ -92,7 +95,7 @@ class wpOffload
92
  add_filter('shortpixel/file/virtual/translate', array($this, 'getLocalPathByURL'));
93
 
94
  // for webp picture paths rendered via output
95
- add_filter('shortpixel_webp_image_base', array($this, 'checkWebpRemotePath'), 10, 2);
96
  add_filter('shortpixel/front/webp_notfound', array($this, 'fixWebpRemotePath'), 10, 4);
97
 
98
  }
@@ -307,13 +310,14 @@ class wpOffload
307
  {
308
  $source_id = $this->getSourceIDByURL($url);
309
 
 
310
  if ($source_id == false)
311
  {
312
-
313
  return false;
314
  }
315
  $item = $this->getItemById($source_id);
316
 
 
317
  $original_path = $item->original_source_path(); // $values['original_source_path'];
318
 
319
  if (wp_basename($url) !== wp_basename($original_path)) // thumbnails translate to main file.
@@ -574,13 +578,13 @@ class wpOffload
574
  $newPaths[$size . '_webp'] = $webpformat1;
575
  }
576
  else {
577
- $newPaths[$size . '_webp1'] = $webpformat1;
578
  }
579
 
580
  if ($check_exists)
581
  {
582
  if(file_exists($webpformat2))
583
- $newPaths[$size . '_webp'] = $webpformat2;
584
  }
585
  else {
586
  $newPaths[$size . '_webp2'] = $webpformat2;
@@ -608,6 +612,7 @@ class wpOffload
608
  public function add_webp_paths($paths)
609
  {
610
  $paths = $this->getWebpPaths($paths, true);
 
611
  return $paths;
612
  }
613
 
@@ -615,7 +620,7 @@ class wpOffload
615
  public function remove_webp_paths($paths)
616
  {
617
  $paths = $this->getWebpPaths($paths, false);
618
- //Log::addDebug('Remove S3 Paths', array($paths));
619
 
620
  return $paths;
621
  }
@@ -630,7 +635,7 @@ class wpOffload
630
  }
631
  elseif($this->is_cname) // check this. the webp to picture will convert subdomains with CNAME to some local path when offloaded.
632
  {
633
- Log::addDebug('S3 active, checking on CNAME for path' . $this->cname);
634
  if (strpos($original, $this->cname) !== false)
635
  return $this->convertWebPRemotePath($url, $original);
636
  }
@@ -639,37 +644,35 @@ class wpOffload
639
 
640
  }
641
 
642
- private function convertWebPRemotePath($url, $original)
643
- {
644
- $mediaItem = $this->getByURL($original); // test if exists remote.
645
- Log::addDebug('ImageBaseName check for S3 - ', array($original, $mediaItem));
646
 
647
- if ($mediaItem === false)
648
- {
649
- $pattern = '/-\d+x\d*/i';
650
- $replaced_url = preg_replace($pattern, '', $original);
651
- $mediaItem = $this->getByURL($replaced_url);
652
- }
653
-
654
- if ($mediaItem === false)
655
- {
656
- return $url;
657
- }
658
- $parsed = parse_url($original);
659
- $url = str_replace($parsed['scheme'], '', $original);
660
- $url = str_replace(basename($url), '', $url);
661
- Log::addDebug('New BasePath, External' . $url);
662
 
663
- return $url;
664
- }
 
 
 
 
 
 
665
 
666
- // GetbyURL can't find thumbnails, only the main image. We are going to assume, if imagebase is ok, the webp might be there.
667
- public function fixWebpRemotePath($bool, $file, $url, $imagebase)
668
- {
669
- if (strpos($url, $imagebase ) !== false)
670
- return $file;
671
  else
672
  return $bool;
 
673
  }
674
 
675
  }
57
  $this->offloading = false;
58
  }
59
 
60
+ /* // Lets see if this can be without
61
+ if ('cloudfront' === $this->as3cf->get_setting( 'domain' ))
62
  {
63
  $this->is_cname = true;
64
  $this->cname = $this->as3cf->get_setting( 'cloudfront' );
65
+ } */
66
 
67
  // $provider = $this->as3cf->get_provider();
68
  add_action('shortpixel/image/optimised', array($this, 'image_upload'), 10);
78
  {
79
  // add_filter('as3cf_remove_source_files_from_provider', array($this, 'remove_webp_paths'), 10);
80
  add_action('shortpixel/image/convertpng2jpg_success', array($this, 'image_converted'), 10);
81
+ add_filter('as3cf_remove_source_files_from_provider', array($this, 'remove_webp_paths'));
82
+
83
  }
84
  else {
85
  add_filter('as3cf_remove_attachment_paths', array($this, 'remove_webp_paths'));
95
  add_filter('shortpixel/file/virtual/translate', array($this, 'getLocalPathByURL'));
96
 
97
  // for webp picture paths rendered via output
98
+ // add_filter('shortpixel_webp_image_base', array($this, 'checkWebpRemotePath'), 10, 2);
99
  add_filter('shortpixel/front/webp_notfound', array($this, 'fixWebpRemotePath'), 10, 4);
100
 
101
  }
310
  {
311
  $source_id = $this->getSourceIDByURL($url);
312
 
313
+
314
  if ($source_id == false)
315
  {
 
316
  return false;
317
  }
318
  $item = $this->getItemById($source_id);
319
 
320
+
321
  $original_path = $item->original_source_path(); // $values['original_source_path'];
322
 
323
  if (wp_basename($url) !== wp_basename($original_path)) // thumbnails translate to main file.
578
  $newPaths[$size . '_webp'] = $webpformat1;
579
  }
580
  else {
581
+ $newPaths[$size . '_webp'] = $webpformat1;
582
  }
583
 
584
  if ($check_exists)
585
  {
586
  if(file_exists($webpformat2))
587
+ $newPaths[$size . '_webp2'] = $webpformat2;
588
  }
589
  else {
590
  $newPaths[$size . '_webp2'] = $webpformat2;
612
  public function add_webp_paths($paths)
613
  {
614
  $paths = $this->getWebpPaths($paths, true);
615
+ //Log::addDebug('Add S3 Paths', array($paths));
616
  return $paths;
617
  }
618
 
620
  public function remove_webp_paths($paths)
621
  {
622
  $paths = $this->getWebpPaths($paths, false);
623
+ Log::addDebug('Remove S3 Paths', array($paths));
624
 
625
  return $paths;
626
  }
635
  }
636
  elseif($this->is_cname) // check this. the webp to picture will convert subdomains with CNAME to some local path when offloaded.
637
  {
638
+ Log::addDebug('S3 active, checking on CNAME for path' . $this->cname, $url);
639
  if (strpos($original, $this->cname) !== false)
640
  return $this->convertWebPRemotePath($url, $original);
641
  }
644
 
645
  }
646
 
 
 
 
 
647
 
648
+ // GetbyURL can't find thumbnails, only the main image. Check via extrainfo method if we can find needed filetype
649
+ // @param $bool Boolean
650
+ // @param $fileObj FileModel The webp file we are searching for
651
+ // @param $url string The URL of the main file ( aka .jpg )
652
+ // @param $imagebaseDir DirectoryModel The remote path / path this all takes place at.
653
+ public function fixWebpRemotePath($bool, $fileObj, $url, $imagebaseDir)
654
+ {
655
+ return false;
656
+ /*
657
+ if (! is_object($imagebaseDir))
658
+ {
659
+ return $bool;
660
+ }
 
 
661
 
662
+ // Check if main file is offloaded. This should also trigger sourceCache.
663
+ if ($this->checkifOffloaded($bool, $url) && $this->checkIfOffloaded($bool, $fileObj->getFullPath()) )
664
+ {
665
+ return $fileObj;
666
+ }
667
+ else {
668
+ return false;
669
+ } */
670
 
671
+ /* if (strpos($url, $imagebaseDir->getPath() ) !== false)
672
+ return $fileObj;
 
 
 
673
  else
674
  return $bool;
675
+ */
676
  }
677
 
678
  }
class/front/img-to-picture-webp.php CHANGED
@@ -159,13 +159,13 @@ class ShortPixelImgToPictureWebp
159
  $srcsetInfo = $this->lazyGet($img, 'srcset');
160
  $sizesInfo = $this->lazyGet($img, 'sizes');
161
 
 
162
  $imageBase = apply_filters( 'shortpixel_webp_image_base', $this->getImageBase($srcInfo['value']), $srcInfo['value']);
163
 
164
  if($imageBase === false) {
165
  Log::addInfo('SPDBG baseurl doesn\'t match ' . $srcInfo['value'], array($imageBase) );
166
  return $match[0]; // . (isset($_GET['SHORTPIXEL_DEBUG']) ? '<!-- SPDBG baseurl doesn\'t match ' . $src . ' -->' : '');
167
  }
168
- // Log::addDebug('ImageBase ' . $imageBase);
169
 
170
  //some attributes should not be moved from <img>
171
  // @todo Move these to unset on (imgpicture) and put via create_attributes back
@@ -222,6 +222,11 @@ class ShortPixelImgToPictureWebp
222
  $extension = $fsFile->getExtension(); // trigger setFileinfo, which will resolve URL -> Path
223
 
224
  $mime = $fsFile->getMime();
 
 
 
 
 
225
 
226
  $fileWebp = $fs->getFile($imageBase . $fsFile->getFileBase() . '.webp');
227
  $fileWebpCompat = $fs->getFile($imageBase . $fsFile->getFileName() . '.webp');
@@ -236,6 +241,7 @@ class ShortPixelImgToPictureWebp
236
  {
237
  if (! $thisfile->exists())
238
  {
 
239
  $thisfile = $fileWebp_exists = apply_filters('shortpixel/front/webp_notfound', false, $thisfile, $fileurl, $imageBase);
240
  }
241
 
@@ -248,6 +254,7 @@ class ShortPixelImgToPictureWebp
248
  }
249
  }
250
 
 
251
  if ($fileAvif->exists())
252
  {
253
  $fileurl_base = str_replace($fsFile->getFileName(), '', $fileurl);
159
  $srcsetInfo = $this->lazyGet($img, 'srcset');
160
  $sizesInfo = $this->lazyGet($img, 'sizes');
161
 
162
+ // FILTERS : FileDir (OBJECT) - URL
163
  $imageBase = apply_filters( 'shortpixel_webp_image_base', $this->getImageBase($srcInfo['value']), $srcInfo['value']);
164
 
165
  if($imageBase === false) {
166
  Log::addInfo('SPDBG baseurl doesn\'t match ' . $srcInfo['value'], array($imageBase) );
167
  return $match[0]; // . (isset($_GET['SHORTPIXEL_DEBUG']) ? '<!-- SPDBG baseurl doesn\'t match ' . $src . ' -->' : '');
168
  }
 
169
 
170
  //some attributes should not be moved from <img>
171
  // @todo Move these to unset on (imgpicture) and put via create_attributes back
222
  $extension = $fsFile->getExtension(); // trigger setFileinfo, which will resolve URL -> Path
223
 
224
  $mime = $fsFile->getMime();
225
+ // Can happen when file is virtual, or other cases. Just assume this type.
226
+ if ($mime === false)
227
+ {
228
+ $mime = 'image/' . $extension;
229
+ }
230
 
231
  $fileWebp = $fs->getFile($imageBase . $fsFile->getFileBase() . '.webp');
232
  $fileWebpCompat = $fs->getFile($imageBase . $fsFile->getFileName() . '.webp');
241
  {
242
  if (! $thisfile->exists())
243
  {
244
+ // FILTER: boolean, object, string, filedir
245
  $thisfile = $fileWebp_exists = apply_filters('shortpixel/front/webp_notfound', false, $thisfile, $fileurl, $imageBase);
246
  }
247
 
254
  }
255
  }
256
 
257
+ //@todo This will not work with offloaded avifs.
258
  if ($fileAvif->exists())
259
  {
260
  $fileurl_base = str_replace($fsFile->getFileName(), '', $fileurl);
class/shortpixel-png2jpg.php CHANGED
@@ -45,8 +45,8 @@ class ShortPixelPng2Jpg {
45
  return false;
46
  }
47
 
 
48
  $this->current_image = $this->getPNGImage($imageObj);
49
- $this->raiseMemoryLimit();
50
 
51
  if (is_null($this->current_image)) // image creation failed. @todo Error back
52
  return false;
@@ -207,7 +207,7 @@ class ShortPixelPng2Jpg {
207
 
208
  $x = imagesx($img);
209
  $y = imagesy($img);
210
- Log::addDebug("PNG2JPG doConvert width $x height $y");
211
  $bg = imagecreatetruecolor($x, $y);
212
  if(!$bg)
213
  {
45
  return false;
46
  }
47
 
48
+ $this->raiseMemoryLimit();
49
  $this->current_image = $this->getPNGImage($imageObj);
 
50
 
51
  if (is_null($this->current_image)) // image creation failed. @todo Error back
52
  return false;
207
 
208
  $x = imagesx($img);
209
  $y = imagesy($img);
210
+ Log::addDebug("PNG2JPG doConvert width $x height $y", memory_get_usage());
211
  $bg = imagecreatetruecolor($x, $y);
212
  if(!$bg)
213
  {
class/view/bulk/part-finished.php CHANGED
@@ -41,15 +41,15 @@ namespace ShortPixel;
41
  <span class='done' data-stats-media="percentage_done" data-presentation="css.width.percentage"></span>
42
  </span>
43
  </span>
44
- <span><?php esc_html_e('Processing','shortpixel-image-optimiser') ?>: <i data-stats-media="in_process">-</i></span>
45
 
46
  </div>
47
 
48
  <div>
49
- <span><?php esc_html_e('Processed','shortpixel-image-optimiser'); ?>: <i data-stats-media="done">-</i></span>
50
 
51
- <span><?php esc_html_e('Images Left','shortpixel-image-optimiser'); ?>: <i data-stats-media="in_queue">-</i></span>
52
- <span><?php esc_html_e('Errors','shortpixel-image-optimiser'); ?>: <i data-check-media-fatalerrors data-stats-media="fatal_errors" class='error'>- </i>
53
  <span class="display-error-box" data-check-visibility data-control="data-check-media-fatalerrors" ><label title="<?php esc_html_e('Show Errors', 'shortpixel-image-optimiser'); ?>">
54
  <input type="checkbox" name="show-errors" value="show" data-action='ToggleErrorBox' data-errorbox='media' data-event='change'><?php esc_html_e('Show Errors','shortpixel-image-optimiser'); ?></label>
55
  </span>
41
  <span class='done' data-stats-media="percentage_done" data-presentation="css.width.percentage"></span>
42
  </span>
43
  </span>
44
+ <span><?php esc_html_e('Processing','shortpixel-image-optimiser') ?>: <i data-stats-media="in_process">0</i></span>
45
 
46
  </div>
47
 
48
  <div>
49
+ <span><?php esc_html_e('Processed','shortpixel-image-optimiser'); ?>: <i data-stats-media="done">0</i></span>
50
 
51
+ <span><?php esc_html_e('Images Left','shortpixel-image-optimiser'); ?>: <i data-stats-media="in_queue">0</i></span>
52
+ <span><?php esc_html_e('Errors','shortpixel-image-optimiser'); ?>: <i data-check-media-fatalerrors data-stats-media="fatal_errors" class='error'>0 </i>
53
  <span class="display-error-box" data-check-visibility data-control="data-check-media-fatalerrors" ><label title="<?php esc_html_e('Show Errors', 'shortpixel-image-optimiser'); ?>">
54
  <input type="checkbox" name="show-errors" value="show" data-action='ToggleErrorBox' data-errorbox='media' data-event='change'><?php esc_html_e('Show Errors','shortpixel-image-optimiser'); ?></label>
55
  </span>
class/view/bulk/part-process.php CHANGED
@@ -47,14 +47,14 @@ namespace ShortPixel;
47
  <span class='dashicons spin dashicons-update line-progressbar-spinner' data-check-visibility data-control="data-check-media-in_process">&nbsp;</span>
48
 
49
  </span>
50
- <span><?php esc_html_e('Processing', 'shortpixel-image-optimiser') ?>: <i data-stats-media="in_process" data-check-media-in_process >-</i></span>
51
  </div>
52
 
53
  <div>
54
- <span><?php esc_html_e('Processed', 'shortpixel-image-optimiser'); ?>: <i data-stats-media="done">-</i></span>
55
 
56
- <span><?php esc_html_e('Waiting','shortpixel-image-optimiser'); ?>: <i data-stats-media="in_queue">-</i></span>
57
- <span><?php esc_html_e('Errors','shortpixel-image-optimiser') ?>: <i data-check-media-fatalerrors data-stats-media="fatalesc_html_errors" class='error'>- </i>
58
  <span class="display-error-box" data-check-visibility data-control="data-check-media-fatalerrors" ><label title="<?php esc_html_e('Show Errors', 'shortpixel-image-optimiser'); ?>">
59
  <input type="checkbox" name="show-errors" value="show" data-action='ToggleErrorBox' data-errorbox='media' data-event='change'>
60
  <?php esc_html_e('Show Errors','shortpixel-image-optimiser'); ?></label>
@@ -96,7 +96,7 @@ namespace ShortPixel;
96
  <span><?php esc_html_e('Processed','shortpixel-image-optimiser'); ?>: <i data-stats-custom="done">-</i></span>
97
 
98
  <span><?php esc_html_e('Waiting','shortpixel-image-optimiser'); ?>: <i data-stats-custom="in_queue">-</i></span>
99
- <span><?php esc_html_e('Errors') ?>: <i data-check-custom-fatalerrors data-stats-custom="fatalesc_html_errors" class='error'>-</i>
100
 
101
  <span class="display-error-box" data-check-visibility data-control="data-check-custom-fatalerrors" ><label title="<?php esc_html_e('Show Errors', 'shortpixel-image-optimiser'); ?>">
102
  <input type="checkbox" name="show-errors" value="show" data-action='ToggleErrorBox' data-errorbox='custom' data-event='change'><?php esc_html_e('Show Errors','shortpixel-image-optimiser'); ?></label>
47
  <span class='dashicons spin dashicons-update line-progressbar-spinner' data-check-visibility data-control="data-check-media-in_process">&nbsp;</span>
48
 
49
  </span>
50
+ <span><?php esc_html_e('Processing', 'shortpixel-image-optimiser') ?>: <i data-stats-media="in_process" data-check-media-in_process >0</i></span>
51
  </div>
52
 
53
  <div>
54
+ <span><?php esc_html_e('Processed', 'shortpixel-image-optimiser'); ?>: <i data-stats-media="done">0</i></span>
55
 
56
+ <span><?php esc_html_e('Waiting','shortpixel-image-optimiser'); ?>: <i data-stats-media="in_queue">0</i></span>
57
+ <span><?php esc_html_e('Errors','shortpixel-image-optimiser') ?>: <i data-check-media-fatalerrors data-stats-media="fatal_errors" class='error'>0 </i>
58
  <span class="display-error-box" data-check-visibility data-control="data-check-media-fatalerrors" ><label title="<?php esc_html_e('Show Errors', 'shortpixel-image-optimiser'); ?>">
59
  <input type="checkbox" name="show-errors" value="show" data-action='ToggleErrorBox' data-errorbox='media' data-event='change'>
60
  <?php esc_html_e('Show Errors','shortpixel-image-optimiser'); ?></label>
96
  <span><?php esc_html_e('Processed','shortpixel-image-optimiser'); ?>: <i data-stats-custom="done">-</i></span>
97
 
98
  <span><?php esc_html_e('Waiting','shortpixel-image-optimiser'); ?>: <i data-stats-custom="in_queue">-</i></span>
99
+ <span><?php esc_html_e('Errors') ?>: <i data-check-custom-fatalerrors data-stats-custom="fatal_errors" class='error'>-</i>
100
 
101
  <span class="display-error-box" data-check-visibility data-control="data-check-custom-fatalerrors" ><label title="<?php esc_html_e('Show Errors', 'shortpixel-image-optimiser'); ?>">
102
  <input type="checkbox" name="show-errors" value="show" data-action='ToggleErrorBox' data-errorbox='custom' data-event='change'><?php esc_html_e('Show Errors','shortpixel-image-optimiser'); ?></label>
class/view/bulk/part-summary.php CHANGED
@@ -98,7 +98,7 @@ namespace ShortPixel;
98
 
99
  <div class="over-quota" data-check-visibility="false" data-control="data-quota-remaining" data-control-check="data-check-total-total">
100
  <span><img src="<?php echo esc_url(wpSPIO()->plugin_url('res/img/bulk/over-quota.svg')) ?>" /></span>
101
- <p><?php printf(esc_html_e('In your ShortPixel account you %shave only %s credits available %s, but you have chosen %s images to be optimized in this bulk process. You can either go back and select less images, or you can upgrade to a higher plan or buy one-time credits.','shortpixel-image-optimiser'), '<span class="red">', esc_html($this->formatNumber($quotaData->total->remaining, 0)), '</span>', '<b data-stats-total="images-images">0</b>'); ?>
102
 
103
  <button type="button" class="button" onClick="ShortPixel.proposeUpgrade();"><?php esc_html_e('Show me the best options') ?></button>
104
  </p>
98
 
99
  <div class="over-quota" data-check-visibility="false" data-control="data-quota-remaining" data-control-check="data-check-total-total">
100
  <span><img src="<?php echo esc_url(wpSPIO()->plugin_url('res/img/bulk/over-quota.svg')) ?>" /></span>
101
+ <p><?php printf(esc_html('In your ShortPixel account you %shave only %s credits available %s, but you have chosen %s images to be optimized in this bulk process. You can either go back and select less images, or you can upgrade to a higher plan or buy one-time credits.','shortpixel-image-optimiser'), '<span class="red">', esc_html($this->formatNumber($quotaData->total->remaining, 0)), '</span>', '<b data-stats-total="images-images">0</b>'); ?>
102
 
103
  <button type="button" class="button" onClick="ShortPixel.proposeUpgrade();"><?php esc_html_e('Show me the best options') ?></button>
104
  </p>
class/view/settings/part-advanced.php CHANGED
@@ -365,8 +365,9 @@ use \ShortPixel\Helper\UiHelper as UiHelper;
365
  '<strong>', '</strong>',
366
  '<strong>', '</strong>',
367
  '<strong>', '</strong>',
368
- '<strong>', '</strong>',
369
- );?>
 
370
  </p>
371
  </td>
372
  </tr>
365
  '<strong>', '</strong>',
366
  '<strong>', '</strong>',
367
  '<strong>', '</strong>',
368
+ '<strong>', '</strong>'
369
+ );
370
+ ?>
371
  </p>
372
  </td>
373
  </tr>
class/view/shortpixel-feedback.php CHANGED
@@ -271,11 +271,11 @@ class ShortPixelFeedback {
271
 
272
  formContainer.on('click', '#shortpixel-deactivate-submit-form', function(e){
273
  e.preventDefault();
274
- if( formContainer.find('#shortpixel-keep-settings:checked').length ) {
275
  window.location.href = url;
276
- } else {
277
  SubmitFeedback({}, formContainer);
278
- }
279
  });
280
 
281
  // If we click outside the form, the form will close
271
 
272
  formContainer.on('click', '#shortpixel-deactivate-submit-form', function(e){
273
  e.preventDefault();
274
+ // if( formContainer.find('#shortpixel-keep-settings:checked').length ) {
275
  window.location.href = url;
276
+ /* } else {
277
  SubmitFeedback({}, formContainer);
278
+ } */
279
  });
280
 
281
  // If we click outside the form, the form will close
class/view/view-edit-media.php CHANGED
@@ -67,7 +67,7 @@ if (! is_null($view->debugInfo) && is_array($view->debugInfo) && count($view->de
67
  </div>
68
  </div>
69
 
70
- <div id="sp-message-<?php echo( esc_attr($this->view->id) ); ?>" class='messages'>
71
  <?php if (! is_null($view->status_message)): ?>
72
  <?php echo esc_html($view->status_message); ?>
73
  <?php endif; ?>
67
  </div>
68
  </div>
69
 
70
+ <div id="sp-message-<?php echo( esc_attr($this->view->id) ); ?>" class='spio-message'>
71
  <?php if (! is_null($view->status_message)): ?>
72
  <?php echo esc_html($view->status_message); ?>
73
  <?php endif; ?>
class/view/view-other-media.php CHANGED
@@ -128,13 +128,24 @@ if ( isset($_GET['noheader']) ) {
128
  </a></span>
129
  <span class='filename'><?php echo esc_html($item->getFileName()) ?>
130
  <div class="row-actions"><?php
131
- $numberActions = count($rowActions);
132
- for ($i = 0; $i < $numberActions; $i++)
133
- {
134
- echo $rowActions[$i];
135
- if ($i < ($numberActions-1) )
136
- echo '|';
137
- }
 
 
 
 
 
 
 
 
 
 
 
138
  ?>
139
  <span class='item-id'>#<?php echo esc_attr($item->get('id')); ?></span>
140
  </div>
128
  </a></span>
129
  <span class='filename'><?php echo esc_html($item->getFileName()) ?>
130
  <div class="row-actions"><?php
131
+ if (isset($this->view->actions)):
132
+ $i = 0;
133
+ foreach($this->view->actions as $actionName => $action):
134
+ $classes = ''; // ($action['display'] == 'button') ? " button-smaller button-primary $actionName " : "$actionName";
135
+ $link = ($action['type'] == 'js') ? 'javascript:' . $action['function'] : $action['function'];
136
+ $newtab = ($actionName == 'extendquota' || $actionName == 'view') ? 'target="_blank"' : '';
137
+
138
+ if ($i > 0)
139
+ echo "|";
140
+ ?>
141
+ <a href="<?php echo $link ?>" <?php echo esc_attr($newtab); ?> class="<?php echo $classes ?>"><?php echo $action['text'] ?></a>
142
+ <?php
143
+ $i++;
144
+ endforeach;
145
+
146
+ endif;
147
+
148
+
149
  ?>
150
  <span class='item-id'>#<?php echo esc_attr($item->get('id')); ?></span>
151
  </div>
readme.txt CHANGED
@@ -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.5
8
  License: GPLv2 or later
9
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
10
 
@@ -309,6 +309,27 @@ Add HTTP basic authentication credentials by defining these constants in wp-conf
309
 
310
  == Changelog ==
311
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
312
  = 5.0.5 =
313
  Release date July 7th, 2022
314
  * Fix: in some cases the legacy optimization data was not migrated properly, resulting in backup-related errors;
4
  Requires at least: 4.8.0
5
  Tested up to: 6.0
6
  Requires PHP: 5.6
7
+ Stable tag: 5.0.6
8
  License: GPLv2 or later
9
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
10
 
309
 
310
  == Changelog ==
311
 
312
+ = 5.0.6 =
313
+ Release date July 25th, 2022
314
+ * Fix: the "Search and Migrate All" tool now contains a fix for many cases where the message "Could not create backup" shows up;
315
+ * Fix: a fatal error was crashing the plugin settings in PHP 7.2;
316
+ * Fix: in certain cases, the optimization was looping due to WooCommerce's thumbnail system;
317
+ * Fix: in some cases, WooCommerce as well as other plugins were returning a wrong thumbnail URL and this case was not treated properly;
318
+ * Fix: optimization wasn't working correctly for multisite installs with the very old `blogs.dir` setup;
319
+ * Fix: some notifications could not be properly dismissed (sorry for that!);
320
+ * Fix: the integration with WP Offload Media has been enhanced for the case where the media files are not stored anymore on the local server;
321
+ * Fix: some errors were showing up in certain cases where the next generation image delivery was active together with the WP Offload Media plugin;
322
+ * Fix: the error box was not showing up anymore at the end of the bulk processing, or it was displaying wrong counts;
323
+ * Fix: the "Optimize Now" action from the Custom Media had a wrong link;
324
+ * Fix: in some cases, the bulk processing wasn't displaying the correct step for migration/restore operations;
325
+ * Fix: the deactivation feedback was sent even if no selection was made in the pop-up;
326
+ * Fix: the optimized/unoptimized filter was also displaying private posts;
327
+ * Fix: various small fixes and code improvements to make the ShortPixel support team's lives easier;
328
+ * Tweak: added a "processing" message when a new action is manually requested by the user;
329
+ * Tweak: added a tool-tip for the number of items currently in the processing queue;
330
+ * Tweak: added the resize type (cover/contain) on the image edit screen;
331
+ * Language: 10 new strings added, 2 updated, 0 fuzzed, and 6 obsoleted.
332
+
333
  = 5.0.5 =
334
  Release date July 7th, 2022
335
  * Fix: in some cases the legacy optimization data was not migrated properly, resulting in backup-related errors;
res/css/shortpixel-admin.css CHANGED
@@ -23,6 +23,45 @@
23
  float: none;
24
  }
25
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
26
  .shortpixel-modal-active .debug-modal.debugInfo ul li strong {
27
  display: inline-block;
28
  min-width: 200px;
@@ -42,6 +81,48 @@
42
  float: right;
43
  text-align: right;
44
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
45
 
46
  .sp-column-info {
47
  position: relative;
@@ -127,6 +208,44 @@
127
  font-weight: 700;
128
  margin: 12px 0;
129
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
130
 
131
  div.sp-modal-shade {
132
  display: none;
23
  float: none;
24
  }
25
 
26
+ .spio-message img {
27
+ animation: cssload-spin 5000ms infinite linear;
28
+ -o-animation: cssload-spin 5000ms infinite linear;
29
+ -ms-animation: cssload-spin 5000ms infinite linear;
30
+ -webkit-animation: cssload-spin 5000ms infinite linear;
31
+ -moz-animation: cssload-spin 5000ms infinite linear;
32
+ vertical-align: top;
33
+ }
34
+ @keyframes loading-spin {
35
+ 100% {
36
+ transform: rotate(360deg);
37
+ transform: rotate(360deg);
38
+ }
39
+ }
40
+ @-o-keyframes loading-spin {
41
+ 100% {
42
+ -o-transform: rotate(360deg);
43
+ transform: rotate(360deg);
44
+ }
45
+ }
46
+ @-ms-keyframes loading-spin {
47
+ 100% {
48
+ -ms-transform: rotate(360deg);
49
+ transform: rotate(360deg);
50
+ }
51
+ }
52
+ @-webkit-keyframes loading-spin {
53
+ 100% {
54
+ -webkit-transform: rotate(360deg);
55
+ transform: rotate(360deg);
56
+ }
57
+ }
58
+ @-moz-keyframes loading-spin {
59
+ 100% {
60
+ -moz-transform: rotate(360deg);
61
+ transform: rotate(360deg);
62
+ }
63
+ }
64
+
65
  .shortpixel-modal-active .debug-modal.debugInfo ul li strong {
66
  display: inline-block;
67
  min-width: 200px;
81
  float: right;
82
  text-align: right;
83
  }
84
+ .shortpixel-other-media .message {
85
+ font-weight: 700;
86
+ margin: 8px 0;
87
+ }
88
+ .shortpixel-other-media .message img {
89
+ animation: cssload-spin 5000ms infinite linear;
90
+ -o-animation: cssload-spin 5000ms infinite linear;
91
+ -ms-animation: cssload-spin 5000ms infinite linear;
92
+ -webkit-animation: cssload-spin 5000ms infinite linear;
93
+ -moz-animation: cssload-spin 5000ms infinite linear;
94
+ vertical-align: top;
95
+ }
96
+ @keyframes loading-spin {
97
+ 100% {
98
+ transform: rotate(360deg);
99
+ transform: rotate(360deg);
100
+ }
101
+ }
102
+ @-o-keyframes loading-spin {
103
+ 100% {
104
+ -o-transform: rotate(360deg);
105
+ transform: rotate(360deg);
106
+ }
107
+ }
108
+ @-ms-keyframes loading-spin {
109
+ 100% {
110
+ -ms-transform: rotate(360deg);
111
+ transform: rotate(360deg);
112
+ }
113
+ }
114
+ @-webkit-keyframes loading-spin {
115
+ 100% {
116
+ -webkit-transform: rotate(360deg);
117
+ transform: rotate(360deg);
118
+ }
119
+ }
120
+ @-moz-keyframes loading-spin {
121
+ 100% {
122
+ -moz-transform: rotate(360deg);
123
+ transform: rotate(360deg);
124
+ }
125
+ }
126
 
127
  .sp-column-info {
128
  position: relative;
208
  font-weight: 700;
209
  margin: 12px 0;
210
  }
211
+ .column-wp-shortPixel .message img {
212
+ animation: cssload-spin 5000ms infinite linear;
213
+ -o-animation: cssload-spin 5000ms infinite linear;
214
+ -ms-animation: cssload-spin 5000ms infinite linear;
215
+ -webkit-animation: cssload-spin 5000ms infinite linear;
216
+ -moz-animation: cssload-spin 5000ms infinite linear;
217
+ vertical-align: top;
218
+ }
219
+ @keyframes loading-spin {
220
+ 100% {
221
+ transform: rotate(360deg);
222
+ transform: rotate(360deg);
223
+ }
224
+ }
225
+ @-o-keyframes loading-spin {
226
+ 100% {
227
+ -o-transform: rotate(360deg);
228
+ transform: rotate(360deg);
229
+ }
230
+ }
231
+ @-ms-keyframes loading-spin {
232
+ 100% {
233
+ -ms-transform: rotate(360deg);
234
+ transform: rotate(360deg);
235
+ }
236
+ }
237
+ @-webkit-keyframes loading-spin {
238
+ 100% {
239
+ -webkit-transform: rotate(360deg);
240
+ transform: rotate(360deg);
241
+ }
242
+ }
243
+ @-moz-keyframes loading-spin {
244
+ 100% {
245
+ -moz-transform: rotate(360deg);
246
+ transform: rotate(360deg);
247
+ }
248
+ }
249
 
250
  div.sp-modal-shade {
251
  display: none;
res/css/shortpixel-admin.css.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sourceRoot":"","sources":["../scss/view/_edit-media.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;;;AAYD;EAEC;EACA;;AAEF;EACC;;AAUJ;EAAS;;AACT;EAAO;;;AClEP;EAEG;EACA;EACA;;;ACPN;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;;;AC3GH;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;;;AClGD;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;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"}
res/css/shortpixel-bulk.css.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sourceRoot":"","sources":["../scss/shortpixel-bulk.scss","../scss/elements/_colors.scss"],"names":[],"mappings":"AAAA;AAIE;AAqWF;AAoLI;AA4HF;;AAppBE;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,YC1CiB;ED2CjB,OC9CU;ED+CV;EACA;EACA;EACA;EACA;EACA;;AAEA;EAEC,YCxDS;EDyDT;EACA;;AAGD;EACC,cC9DS;ED+DT,YC/DS;;ADiEV;EAEE;EACA;EACA;;AAGF;EACE;EACA;EACA;EACA;;AAID;EAEE,YCnFU;EDoFV;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,YClZQ;EDoZP;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;EACE;EACQ;EACA;EACA;EACA;;AAEV;EACE;IAAM;IAA2B;;;AAGnC;EACE;IAAM;IAA8B;;;AAGtC;EACE;IAAM;IAA+B;;;AAGvC;EACE;IAAM;IAAmC;;;AAG3C;EACE;IAAM;IAAgC;;;AAKjD;EAEE;EACA;;AACA;EACE;EACD;;AAED;EAAI;;AAWA;EACG;;AAEH;EACG;EACA;EACA;EACA;;AAEH;EACE;EAEA;;AACA;EACI;EACA;;AAEJ;EACI;;AAcN;EAAQ;;AACR;EAAe;;AACf;EAAQ;;AAIR;EA3IH;;AA4IG;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;EAhSH;;AAiSG;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/1BD;EDg2BC;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;EArkBH;;AAskBG;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"}
1
+ {"version":3,"sourceRoot":"","sources":["../scss/shortpixel-bulk.scss","../scss/elements/_colors.scss","../scss/elements/_animation.scss"],"names":[],"mappings":"AAAA;AAKE;AAqWF;AAoLI;AAqGF;;AA7nBE;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;;AAcN;EAAQ;;AACR;EAAe;;AACf;EAAQ;;AAIR;EApHH;;AAqHG;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;EAzQH;;AA0QG;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,QCz0BD;ED00BC;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;EA9iBH;;AA+iBG;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"}
res/js/debug.js CHANGED
@@ -223,6 +223,9 @@ jQuery(document).ready(function(jq) {
223
  this.modals.push(modal);
224
  this.currentModal = modal;
225
 
 
 
 
226
  return this;
227
 
228
  }
223
  this.modals.push(modal);
224
  this.currentModal = modal;
225
 
226
+
227
+ document.querySelector('.debug-modal .modal_close').addEventListener('click', this.close.bind(this), { once: true} );
228
+
229
  return this;
230
 
231
  }
res/js/screens/screen-bulk.js CHANGED
@@ -259,8 +259,6 @@ console.log("Screen Init Done", initMedia, initCustom);
259
  if (document.getElementById('thumbnails_checkbox') !== null)
260
  data.thumbsActive = (document.getElementById('thumbnails_checkbox').checked) ? true : false;
261
 
262
-
263
- //this.SwitchPanel('selection');
264
  this.UpdatePanelStatus('loading', 'selection');
265
 
266
  // Prepare should happen after selecting what the optimize.
@@ -275,13 +273,15 @@ console.log("Screen Init Done", initMedia, initCustom);
275
 
276
 
277
  this.processor.SetInterval(200); // do this faster.
278
- // Show stats
279
  if (! this.processor.CheckActive())
280
  {
281
  this.processor.ResumeProcess();
282
- //this.processor.isManualPaused = false; // force run
283
  }
284
- this.processor.RunProcess();
 
 
 
285
  return false;
286
 
287
  // Run process.run process from now for prepare ( until prepare done? )
259
  if (document.getElementById('thumbnails_checkbox') !== null)
260
  data.thumbsActive = (document.getElementById('thumbnails_checkbox').checked) ? true : false;
261
 
 
 
262
  this.UpdatePanelStatus('loading', 'selection');
263
 
264
  // Prepare should happen after selecting what the optimize.
273
 
274
 
275
  this.processor.SetInterval(200); // do this faster.
276
+ // CheckActive. Both Resume and Run call to processor process run.
277
  if (! this.processor.CheckActive())
278
  {
279
  this.processor.ResumeProcess();
 
280
  }
281
+ else
282
+ {
283
+ this.processor.RunProcess();
284
+ }
285
  return false;
286
 
287
  // Run process.run process from now for prepare ( until prepare done? )
res/js/screens/screen-custom.js CHANGED
@@ -6,12 +6,14 @@ var ShortPixelScreen = function (MainScreen, processor)
6
  this.isMedia = true;
7
  this.processor = processor;
8
 
 
9
 
10
  this.Init = function()
11
  {
12
  window.addEventListener('shortpixel.custom.resumeprocessing', this.processor.ResumeProcess.bind(this.processor));
13
  window.addEventListener('shortpixel.RenderItemView', this.RenderItemView.bind(this) );
14
 
 
15
  },
16
  this.HandleImage = function(resultItem, type)
17
  {
@@ -94,6 +96,19 @@ var ShortPixelScreen = function (MainScreen, processor)
94
  this.processor.Debug('Update Message Column not found' + id);
95
  }
96
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
97
 
98
  this.UpdateStats = function(stats, type)
99
  {
@@ -205,6 +220,7 @@ var ShortPixelScreen = function (MainScreen, processor)
205
  data.screen_action = 'restoreItem';
206
  //data.callback = 'this.loadItemView';
207
  // AjaxRequest should return result, which will go through Handleresponse, then LoadiTemView.
 
208
  this.processor.AjaxRequest(data);
209
  //var id = data.id;
210
  }
@@ -220,6 +236,7 @@ var ShortPixelScreen = function (MainScreen, processor)
220
  if (! this.processor.CheckActive())
221
  data.callback = 'shortpixel.custom.resumeprocessing';
222
 
 
223
  this.processor.AjaxRequest(data);
224
  }
225
  this.Optimize = function (id)
@@ -234,6 +251,7 @@ var ShortPixelScreen = function (MainScreen, processor)
234
  if (! this.processor.CheckActive())
235
  data.callback = 'shortpixel.custom.resumeprocessing';
236
 
 
237
  this.processor.AjaxRequest(data);
238
  }
239
 
6
  this.isMedia = true;
7
  this.processor = processor;
8
 
9
+ this.strings = '';
10
 
11
  this.Init = function()
12
  {
13
  window.addEventListener('shortpixel.custom.resumeprocessing', this.processor.ResumeProcess.bind(this.processor));
14
  window.addEventListener('shortpixel.RenderItemView', this.RenderItemView.bind(this) );
15
 
16
+ this.strings = spio_screenStrings;
17
  },
18
  this.HandleImage = function(resultItem, type)
19
  {
96
  this.processor.Debug('Update Message Column not found' + id);
97
  }
98
  }
99
+ this.SetMessageProcessing = function(id)
100
+ {
101
+ var message = this.strings.startAction;
102
+
103
+ var loading = document.createElement('img');
104
+ loading.width = 20;
105
+ loading.height = 20;
106
+ loading.src = this.processor.GetPluginUrl() + '/res/img/bulk/loading-hourglass.svg';
107
+
108
+
109
+ message += loading.outerHTML;
110
+ this.UpdateMessage(id, message);
111
+ }
112
 
113
  this.UpdateStats = function(stats, type)
114
  {
220
  data.screen_action = 'restoreItem';
221
  //data.callback = 'this.loadItemView';
222
  // AjaxRequest should return result, which will go through Handleresponse, then LoadiTemView.
223
+ this.SetMessageProcessing(id);
224
  this.processor.AjaxRequest(data);
225
  //var id = data.id;
226
  }
236
  if (! this.processor.CheckActive())
237
  data.callback = 'shortpixel.custom.resumeprocessing';
238
 
239
+ this.SetMessageProcessing(id);
240
  this.processor.AjaxRequest(data);
241
  }
242
  this.Optimize = function (id)
251
  if (! this.processor.CheckActive())
252
  data.callback = 'shortpixel.custom.resumeprocessing';
253
 
254
+ this.SetMessageProcessing(id);
255
  this.processor.AjaxRequest(data);
256
  }
257
 
res/js/screens/screen-media.js CHANGED
@@ -8,12 +8,15 @@ var ShortPixelScreen = function (MainScreen, processor)
8
  this.processor = processor;
9
 
10
  this.currentMessage = '';
 
11
 
12
 
13
  this.Init = function()
14
  {
15
  window.addEventListener('shortpixel.media.resumeprocessing', this.processor.ResumeProcess.bind(this.processor));
16
  window.addEventListener('shortpixel.RenderItemView', this.RenderItemView.bind(this) );
 
 
17
  }
18
 
19
  this.HandleImage = function(resultItem, type)
@@ -106,6 +109,21 @@ var ShortPixelScreen = function (MainScreen, processor)
106
  this.processor.Debug('Update Message Column not found - ' + id);
107
  }
108
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
109
  this.QueueStatus = function(qStatus)
110
  {
111
  /* if (qStatus == 'QUEUE_EMPTY')
@@ -223,7 +241,9 @@ var ShortPixelScreen = function (MainScreen, processor)
223
  data.type = 'media';
224
  data.screen_action = 'restoreItem';
225
  // AjaxRequest should return result, which will go through Handleresponse, then LoadiTemView.
226
- this.processor.AjaxRequest(data);
 
 
227
  //var id = data.id;
228
  }
229
  this.ReOptimize = function(id, compression)
@@ -238,6 +258,7 @@ var ShortPixelScreen = function (MainScreen, processor)
238
  if (! this.processor.CheckActive())
239
  data.callback = 'shortpixel.custom.resumeprocessing';
240
 
 
241
  this.processor.AjaxRequest(data);
242
  }
243
  this.RedoLegacy = function(id)
@@ -253,9 +274,11 @@ var ShortPixelScreen = function (MainScreen, processor)
253
  var itemData = { id: e.detail.media.id, type: 'media' };
254
  this.processor.timesEmpty = 0; // reset the defer on this.
255
  this.processor.LoadItemView(itemData);
 
256
 
257
  }.bind(this), {'once': true} );
258
 
 
259
  this.processor.AjaxRequest(data);
260
  }
261
  this.Optimize = function (id)
@@ -270,6 +293,7 @@ var ShortPixelScreen = function (MainScreen, processor)
270
  if (! this.processor.CheckActive())
271
  data.callback = 'shortpixel.media.resumeprocessing';
272
 
 
273
  this.processor.AjaxRequest(data);
274
  }
275
 
8
  this.processor = processor;
9
 
10
  this.currentMessage = '';
11
+ this.strings = '';
12
 
13
 
14
  this.Init = function()
15
  {
16
  window.addEventListener('shortpixel.media.resumeprocessing', this.processor.ResumeProcess.bind(this.processor));
17
  window.addEventListener('shortpixel.RenderItemView', this.RenderItemView.bind(this) );
18
+
19
+ this.strings = spio_screenStrings;
20
  }
21
 
22
  this.HandleImage = function(resultItem, type)
109
  this.processor.Debug('Update Message Column not found - ' + id);
110
  }
111
  }
112
+ // Show a message that an action has started.
113
+ this.SetMessageProcessing = function(id)
114
+ {
115
+ var message = this.strings.startAction;
116
+
117
+ var loading = document.createElement('img');
118
+ loading.width = 20;
119
+ loading.height = 20;
120
+ loading.src = this.processor.GetPluginUrl() + '/res/img/bulk/loading-hourglass.svg';
121
+
122
+
123
+ message += loading.outerHTML;
124
+ this.UpdateMessage(id, message);
125
+ }
126
+
127
  this.QueueStatus = function(qStatus)
128
  {
129
  /* if (qStatus == 'QUEUE_EMPTY')
241
  data.type = 'media';
242
  data.screen_action = 'restoreItem';
243
  // AjaxRequest should return result, which will go through Handleresponse, then LoadiTemView.
244
+ this.SetMessageProcessing(id);
245
+ this.processor.AjaxRequest(data);
246
+
247
  //var id = data.id;
248
  }
249
  this.ReOptimize = function(id, compression)
258
  if (! this.processor.CheckActive())
259
  data.callback = 'shortpixel.custom.resumeprocessing';
260
 
261
+ this.SetMessageProcessing(id);
262
  this.processor.AjaxRequest(data);
263
  }
264
  this.RedoLegacy = function(id)
274
  var itemData = { id: e.detail.media.id, type: 'media' };
275
  this.processor.timesEmpty = 0; // reset the defer on this.
276
  this.processor.LoadItemView(itemData);
277
+ this.UpdateMessage(itemData.id, '');
278
 
279
  }.bind(this), {'once': true} );
280
 
281
+ this.SetMessageProcessing(id);
282
  this.processor.AjaxRequest(data);
283
  }
284
  this.Optimize = function (id)
293
  if (! this.processor.CheckActive())
294
  data.callback = 'shortpixel.media.resumeprocessing';
295
 
296
+ this.SetMessageProcessing(id);
297
  this.processor.AjaxRequest(data);
298
  }
299
 
res/js/shortpixel-processor.js CHANGED
@@ -545,6 +545,10 @@ window.ShortPixelProcessor =
545
 
546
  this.worker.postMessage({action: 'ajaxRequest', 'nonce' : this.nonce['ajaxRequest'], 'data': data });
547
  },
 
 
 
 
548
  Debug: function (message, messageType)
549
  {
550
  if (typeof messageType == 'undefined')
545
 
546
  this.worker.postMessage({action: 'ajaxRequest', 'nonce' : this.nonce['ajaxRequest'], 'data': data });
547
  },
548
+ GetPluginUrl: function()
549
+ {
550
+ return ShortPixelConstants[0].WP_PLUGIN_URL;
551
+ },
552
  Debug: function (message, messageType)
553
  {
554
  if (typeof messageType == 'undefined')
res/js/shortpixel-tooltip.js CHANGED
@@ -2,6 +2,7 @@
2
 
3
  var ShortPixelToolTip = function(reserved, processor)
4
  {
 
5
 
6
  this.Init = function()
7
  {
@@ -23,6 +24,7 @@ var ShortPixelToolTip = function(reserved, processor)
23
  this.ProcessPause();
24
  }
25
 
 
26
 
27
  window.addEventListener('shortpixel.processor.paused', this.ProcessChange.bind(this));
28
  }
@@ -66,6 +68,7 @@ var ShortPixelToolTip = function(reserved, processor)
66
  var toolTip = this.GetToolTip();
67
  if (toolTip === null)
68
  return false;
 
69
  var statTip = toolTip.querySelector('.stats');
70
 
71
  if (statTip == null)
@@ -85,6 +88,24 @@ var ShortPixelToolTip = function(reserved, processor)
85
  var number = parseInt(inqueue) + parseInt(inprocess);
86
  statTip.textContent = this.FormatNumber(number);
87
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
88
  if (statTip.classList.contains('hidden') && number > 0)
89
  statTip.classList.remove('hidden');
90
  else if (! statTip.classList.contains('hidden') && number == 0)
2
 
3
  var ShortPixelToolTip = function(reserved, processor)
4
  {
5
+ this.strings = '';
6
 
7
  this.Init = function()
8
  {
24
  this.ProcessPause();
25
  }
26
 
27
+ this.strings = spio_tooltipStrings;
28
 
29
  window.addEventListener('shortpixel.processor.paused', this.ProcessChange.bind(this));
30
  }
68
  var toolTip = this.GetToolTip();
69
  if (toolTip === null)
70
  return false;
71
+
72
  var statTip = toolTip.querySelector('.stats');
73
 
74
  if (statTip == null)
88
  var number = parseInt(inqueue) + parseInt(inprocess);
89
  statTip.textContent = this.FormatNumber(number);
90
 
91
+ // Updating the titles.
92
+
93
+ var itemTitle = statTip.textContent + ' ';
94
+ itemTitle += (number == 1) ? this.strings.item : this.strings.items;
95
+
96
+ if (toolTip.querySelector('#short-pixel-notice-toolbar') !== null)
97
+ {
98
+ toolTip.querySelector('#short-pixel-notice-toolbar').title = this.strings.processing + ' ' + itemTitle;
99
+ }
100
+ if (toolTip.querySelector('.dashicons.pause') !== null)
101
+ {
102
+ toolTip.querySelector('.dashicons.pause').title = itemTitle + '\n\n' + this.strings.pause;
103
+ }
104
+ if (toolTip.querySelector('.dashicons.play') !== null)
105
+ {
106
+ toolTip.querySelector('.dashicons.play').title = itemTitle + '\n\n' + this.strings.resume;
107
+ }
108
+
109
  if (statTip.classList.contains('hidden') && number > 0)
110
  statTip.classList.remove('hidden');
111
  else if (! statTip.classList.contains('hidden') && number == 0)
res/scss/elements/_animation.scss ADDED
@@ -0,0 +1,28 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ @mixin loadspinner()
2
+ {
3
+ animation: cssload-spin 5000ms infinite linear;
4
+ -o-animation: cssload-spin 5000ms infinite linear;
5
+ -ms-animation: cssload-spin 5000ms infinite linear;
6
+ -webkit-animation: cssload-spin 5000ms infinite linear;
7
+ -moz-animation: cssload-spin 5000ms infinite linear;
8
+
9
+ @keyframes loading-spin {
10
+ 100%{ transform: rotate(360deg); transform: rotate(360deg); }
11
+ }
12
+
13
+ @-o-keyframes loading-spin {
14
+ 100%{ -o-transform: rotate(360deg); transform: rotate(360deg); }
15
+ }
16
+
17
+ @-ms-keyframes loading-spin {
18
+ 100%{ -ms-transform: rotate(360deg); transform: rotate(360deg); }
19
+ }
20
+
21
+ @-webkit-keyframes loading-spin {
22
+ 100%{ -webkit-transform: rotate(360deg); transform: rotate(360deg); }
23
+ }
24
+
25
+ @-moz-keyframes loading-spin {
26
+ 100%{ -moz-transform: rotate(360deg); transform: rotate(360deg); }
27
+ }
28
+ }
res/scss/shortpixel-admin.scss CHANGED
@@ -1,3 +1,5 @@
 
 
1
 
2
  @import 'view/edit-media';
3
  @import 'view/other-media';
@@ -5,6 +7,7 @@
5
  @import 'view/modal';
6
  @import 'view/debug';
7
 
 
8
  // General Styles ( mostly from style.css )
9
 
10
  // Used in modals around
1
+ @import 'elements/animation';
2
+
3
 
4
  @import 'view/edit-media';
5
  @import 'view/other-media';
7
  @import 'view/modal';
8
  @import 'view/debug';
9
 
10
+
11
  // General Styles ( mostly from style.css )
12
 
13
  // Used in modals around
res/scss/shortpixel-bulk.scss CHANGED
@@ -1,6 +1,7 @@
1
  .shortpixel-bulk-wrapper
2
  {
3
  @import 'elements/colors';
 
4
 
5
  /** GENERAL STYLES **/
6
  h1 {
@@ -590,31 +591,8 @@
590
  margin-right: 20px;
591
  }
592
  img {
593
- animation: cssload-spin 5000ms infinite linear;
594
- -o-animation: cssload-spin 5000ms infinite linear;
595
- -ms-animation: cssload-spin 5000ms infinite linear;
596
- -webkit-animation: cssload-spin 5000ms infinite linear;
597
- -moz-animation: cssload-spin 5000ms infinite linear;
598
- }
599
- @keyframes loading-spin {
600
- 100%{ transform: rotate(360deg); transform: rotate(360deg); }
601
- }
602
-
603
- @-o-keyframes loading-spin {
604
- 100%{ -o-transform: rotate(360deg); transform: rotate(360deg); }
605
- }
606
-
607
- @-ms-keyframes loading-spin {
608
- 100%{ -ms-transform: rotate(360deg); transform: rotate(360deg); }
609
- }
610
-
611
- @-webkit-keyframes loading-spin {
612
- 100%{ -webkit-transform: rotate(360deg); transform: rotate(360deg); }
613
- }
614
-
615
- @-moz-keyframes loading-spin {
616
- 100%{ -moz-transform: rotate(360deg); transform: rotate(360deg); }
617
- }
618
  }
619
  }
620
 
1
  .shortpixel-bulk-wrapper
2
  {
3
  @import 'elements/colors';
4
+ @import 'elements/animation';
5
 
6
  /** GENERAL STYLES **/
7
  h1 {
591
  margin-right: 20px;
592
  }
593
  img {
594
+ @include loadspinner;
595
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
596
  }
597
  }
598
 
res/scss/view/_edit-media.scss CHANGED
@@ -45,6 +45,13 @@
45
 
46
  } // view-edit-media
47
 
 
 
 
 
 
 
 
48
  // Loads on the bottom body part, load strict
49
  .shortpixel-modal-active .debug-modal.debugInfo // Modal open
50
  {
45
 
46
  } // view-edit-media
47
 
48
+ .spio-message
49
+ {
50
+ img {
51
+ @include loadspinner;
52
+ vertical-align: top;
53
+ }
54
+ }
55
  // Loads on the bottom body part, load strict
56
  .shortpixel-modal-active .debug-modal.debugInfo // Modal open
57
  {
res/scss/view/_list-item.scss CHANGED
@@ -106,5 +106,9 @@
106
  font-size: 14px;
107
  font-weight: 700;
108
  margin: 12px 0;
 
 
 
 
109
  }
110
  }
106
  font-size: 14px;
107
  font-weight: 700;
108
  margin: 12px 0;
109
+ img {
110
+ @include loadspinner;
111
+ vertical-align: top;
112
+ }
113
  }
114
  }
res/scss/view/_other-media.scss CHANGED
@@ -9,4 +9,14 @@
9
  text-align: right;
10
  }
11
  }
 
 
 
 
 
 
 
 
 
 
12
  }
9
  text-align: right;
10
  }
11
  }
12
+
13
+ .message
14
+ {
15
+ font-weight: 700;
16
+ margin: 8px 0;
17
+ img {
18
+ @include loadspinner;
19
+ vertical-align: top;
20
+ }
21
+ }
22
  }
shortpixel-plugin.php CHANGED
@@ -284,6 +284,17 @@ class ShortPixelPlugin {
284
  wp_register_script( 'shortpixel-debug', plugins_url( '/res/js/debug.js', SHORTPIXEL_PLUGIN_FILE ), array( 'jquery', 'jquery-ui-draggable' ), SHORTPIXEL_IMAGE_OPTIMISER_VERSION, true );
285
 
286
  wp_register_script( 'shortpixel-tooltip', plugins_url( '/res/js/shortpixel-tooltip.js', SHORTPIXEL_PLUGIN_FILE ), array( 'jquery' ), SHORTPIXEL_IMAGE_OPTIMISER_VERSION, true );
 
 
 
 
 
 
 
 
 
 
 
287
  wp_register_script( 'shortpixel-settings', plugins_url( 'res/js/shortpixel-settings.js', SHORTPIXEL_PLUGIN_FILE ), array(), SHORTPIXEL_IMAGE_OPTIMISER_VERSION, true );
288
 
289
  wp_register_script( 'shortpixel-processor', plugins_url( '/res/js/shortpixel-processor.js', SHORTPIXEL_PLUGIN_FILE ), array( 'jquery', 'shortpixel-tooltip' ), SHORTPIXEL_IMAGE_OPTIMISER_VERSION, true );
@@ -320,6 +331,14 @@ class ShortPixelPlugin {
320
 
321
  wp_register_script( 'shortpixel-screen-nolist', plugins_url( '/res/js/screens/screen-nolist.js', SHORTPIXEL_PLUGIN_FILE ), array( 'jquery', 'shortpixel-processor' ), SHORTPIXEL_IMAGE_OPTIMISER_VERSION, true );
322
 
 
 
 
 
 
 
 
 
323
  wp_register_script( 'shortpixel-screen-bulk', plugins_url( '/res/js/screens/screen-bulk.js', SHORTPIXEL_PLUGIN_FILE ), array( 'jquery', 'shortpixel-processor' ), SHORTPIXEL_IMAGE_OPTIMISER_VERSION, true );
324
 
325
  // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- This is not a form
284
  wp_register_script( 'shortpixel-debug', plugins_url( '/res/js/debug.js', SHORTPIXEL_PLUGIN_FILE ), array( 'jquery', 'jquery-ui-draggable' ), SHORTPIXEL_IMAGE_OPTIMISER_VERSION, true );
285
 
286
  wp_register_script( 'shortpixel-tooltip', plugins_url( '/res/js/shortpixel-tooltip.js', SHORTPIXEL_PLUGIN_FILE ), array( 'jquery' ), SHORTPIXEL_IMAGE_OPTIMISER_VERSION, true );
287
+
288
+ $tooltip_localize = array(
289
+ 'processing' => __('Processing... ','shortpixel-image-optimiser'),
290
+ 'pause' => __('Click to pause', 'shortpixel-image-optimiser'),
291
+ 'resume' => __('Click to resume', 'shortpixel-image-optimiser'),
292
+ 'item' => __('item in queue', 'shortpixel-image-optimiser'),
293
+ 'items' => __('items in queue', 'shortpixel-image-optimiser'),
294
+ );
295
+
296
+ wp_localize_script( 'shortpixel-tooltip', 'spio_tooltipStrings', $tooltip_localize);
297
+
298
  wp_register_script( 'shortpixel-settings', plugins_url( 'res/js/shortpixel-settings.js', SHORTPIXEL_PLUGIN_FILE ), array(), SHORTPIXEL_IMAGE_OPTIMISER_VERSION, true );
299
 
300
  wp_register_script( 'shortpixel-processor', plugins_url( '/res/js/shortpixel-processor.js', SHORTPIXEL_PLUGIN_FILE ), array( 'jquery', 'shortpixel-tooltip' ), SHORTPIXEL_IMAGE_OPTIMISER_VERSION, true );
331
 
332
  wp_register_script( 'shortpixel-screen-nolist', plugins_url( '/res/js/screens/screen-nolist.js', SHORTPIXEL_PLUGIN_FILE ), array( 'jquery', 'shortpixel-processor' ), SHORTPIXEL_IMAGE_OPTIMISER_VERSION, true );
333
 
334
+ $screen_localize = array(
335
+ 'startAction' => __('Processing... ','shortpixel-image-optimiser'),
336
+
337
+ ) ;
338
+
339
+ wp_localize_script( 'shortpixel-screen-media', 'spio_screenStrings', $screen_localize);
340
+ wp_localize_script( 'shortpixel-screen-custom', 'spio_screenStrings', $screen_localize);
341
+
342
  wp_register_script( 'shortpixel-screen-bulk', plugins_url( '/res/js/screens/screen-bulk.js', SHORTPIXEL_PLUGIN_FILE ), array( 'jquery', 'shortpixel-processor' ), SHORTPIXEL_IMAGE_OPTIMISER_VERSION, true );
343
 
344
  // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- This is not a form
wp-shortpixel.php CHANGED
@@ -3,7 +3,7 @@
3
  * Plugin Name: ShortPixel Image Optimizer
4
  * Plugin URI: https://shortpixel.com/
5
  * Description: ShortPixel optimizes images automatically, while guarding the quality of your images. Check your <a href="/wp-admin/options-general.php?page=wp-shortpixel-settings" target="_blank">Settings &gt; ShortPixel</a> page on how to start optimizing your image library and make your website load faster.
6
- * Version: 5.0.5
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.5");
35
 
36
  define('SHORTPIXEL_BACKUP', 'ShortpixelBackups');
37
  define('SHORTPIXEL_MAX_FAIL_RETRIES', 3);
3
  * Plugin Name: ShortPixel Image Optimizer
4
  * Plugin URI: https://shortpixel.com/
5
  * Description: ShortPixel optimizes images automatically, while guarding the quality of your images. Check your <a href="/wp-admin/options-general.php?page=wp-shortpixel-settings" target="_blank">Settings &gt; ShortPixel</a> page on how to start optimizing your image library and make your website load faster.
6
+ * Version: 5.0.6
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.6");
35
 
36
  define('SHORTPIXEL_BACKUP', 'ShortpixelBackups');
37
  define('SHORTPIXEL_MAX_FAIL_RETRIES', 3);