ShortPixel Image Optimizer - Version 5.0.9

Version Description

Release date August 29th, 2022 * Fix: one of the processing queues was flooded in certain situations, on sites with many concurrent editors; * Fix: the file name was missing in the bulk processing preview; * Fix: the queues were deleted when activating the plugin; now they are preserved and bulk processing can continue after updating/reactivating the plugin; * Fix: retina backups were not removed when an image was deleted from the Media Library; * Fix: NGG screen check caused processor to load on plugin/dashboard pages; * Fix: stats were saved incorrectly when the plugin was deactivated; * Fix: some PHP notices were displayed due to numbering format for Polish language; * Fix: various minor fixes, error code handling and code cleanup; * Fix: screenshots were updated to reflect the latest version of the plugin; * Fix: updates to wording throughout the plugin and in the readme file; * Language: 1 new string added, 0 updated, 0 fuzzed, and 1 deprecated.

Download this release

Release Info

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

Code changes from version 5.0.8 to 5.0.9

build/shortpixel/notices/src/NoticeModel.php CHANGED
@@ -279,7 +279,7 @@ class NoticeModel //extends ShortPixelModel
279
  var ev = event.detail;
280
  var target = event.target;
281
  var parent = target.parentElement;
282
- console.log(ev);
283
  var data = {
284
  'plugin_action': 'dismiss',
285
  'action' : '$this->notice_action',
@@ -289,9 +289,9 @@ class NoticeModel //extends ShortPixelModel
289
  data.id = parent.getAttribute('id');
290
  jQuery.post($url,data);
291
 
292
- $(parent).fadeTo(100,0,function() {
293
- $(parent).slideUp(100, 0, function () {
294
- $(parent).remove();
295
  })
296
  });
297
  }";
279
  var ev = event.detail;
280
  var target = event.target;
281
  var parent = target.parentElement;
282
+
283
  var data = {
284
  'plugin_action': 'dismiss',
285
  'action' : '$this->notice_action',
289
  data.id = parent.getAttribute('id');
290
  jQuery.post($url,data);
291
 
292
+ jQuery(parent).fadeTo(100,0,function() {
293
+ jQuery(parent).slideUp(100, 0, function () {
294
+ jQuery(parent).remove();
295
  })
296
  });
297
  }";
build/shortpixel/notices/src/css/notices.css CHANGED
@@ -1,5 +1,11 @@
1
  .shortpixel.shortpixel-notice {
2
  padding: 8px;
 
 
 
 
 
 
3
  }
4
  .shortpixel.shortpixel-notice img {
5
  display: inline-block;
@@ -7,7 +13,19 @@
7
  max-height: 50px;
8
  }
9
  .shortpixel.shortpixel-notice .notice-dismiss {
10
- margin-top: 10px;
 
 
 
 
 
 
 
 
 
 
 
 
11
  }
12
 
13
  /* In-view notice ( not on top, between the options ) - styled after WP notice */
1
  .shortpixel.shortpixel-notice {
2
  padding: 8px;
3
+ background: #fff;
4
+ border: 1px solid #c3c4c7;
5
+ border-left-width: 4px;
6
+ box-shadow: 0 1px 1px rgba(0, 0, 0, 0.04);
7
+ margin: 5px 15px 2px;
8
+ position: relative;
9
  }
10
  .shortpixel.shortpixel-notice img {
11
  display: inline-block;
13
  max-height: 50px;
14
  }
15
  .shortpixel.shortpixel-notice .notice-dismiss {
16
+ margin-top: 6px;
17
+ }
18
+ .shortpixel.shortpixel-notice.notice-success {
19
+ border-left-color: #00a32a;
20
+ }
21
+ .shortpixel.shortpixel-notice.notice-warning {
22
+ border-left-color: #dba617;
23
+ }
24
+ .shortpixel.shortpixel-notice.notice-error {
25
+ border-left-color: #ff0000;
26
+ }
27
+ .shortpixel.shortpixel-notice.notice-info {
28
+ border-left-color: #72aee6;
29
  }
30
 
31
  /* In-view notice ( not on top, between the options ) - styled after WP notice */
build/shortpixel/notices/src/css/notices.css.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sourceRoot":"","sources":["notices.scss"],"names":[],"mappings":"AACA;EAIG;;AACA;EAEE;EACA;EACA;;AAEF;EAEE;;;AAIL;AACA;EAGE;EACA;EAEA;;AACA;EACE;;AAEF;EAEE;;;AAIJ;EAEE","file":"notices.css"}
1
+ {"version":3,"sourceRoot":"","sources":["notices.scss"],"names":[],"mappings":"AACA;EAIG;EACF;EACA;EACA;EACA;EACA;EACA;;AAEE;EAEE;EACA;EACA;;AAEF;EAEE;;AAGH;EAEC;;AAED;EAEC;;AAED;EAEC;;AAED;EAEE;;;AAIJ;AACA;EAGE;EACA;EAEA;;AACA;EACE;;AAEF;EAEE;;;AAIJ;EAEE","file":"notices.css"}
build/shortpixel/notices/src/css/notices.scss CHANGED
@@ -4,6 +4,13 @@
4
  //padding: 18px;
5
  //min-height: 50px;
6
  padding: 8px;
 
 
 
 
 
 
 
7
  img
8
  {
9
  display:inline-block;
@@ -14,6 +21,23 @@
14
  {
15
  margin-top: 6px;
16
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
17
  }
18
 
19
  /* In-view notice ( not on top, between the options ) - styled after WP notice */
4
  //padding: 18px;
5
  //min-height: 50px;
6
  padding: 8px;
7
+ background: #fff;
8
+ border: 1px solid #c3c4c7;
9
+ border-left-width: 4px;
10
+ box-shadow: 0 1px 1px rgba(0, 0, 0, 0.04);
11
+ margin: 5px 15px 2px;
12
+ position: relative;
13
+
14
  img
15
  {
16
  display:inline-block;
21
  {
22
  margin-top: 6px;
23
  }
24
+
25
+ &.notice-success
26
+ {
27
+ border-left-color: #00a32a;
28
+ }
29
+ &.notice-warning
30
+ {
31
+ border-left-color: #dba617;
32
+ }
33
+ &.notice-error
34
+ {
35
+ border-left-color: #ff0000;
36
+ }
37
+ &.notice-info
38
+ {
39
+ border-left-color: #72aee6;
40
+ }
41
  }
42
 
43
  /* In-view notice ( not on top, between the options ) - styled after WP notice */
build/shortpixel/shortq/src/DataProvider/MysqlDataProvider.php CHANGED
@@ -399,6 +399,12 @@ class MysqlDataProvider implements DataProvider
399
  else
400
  $placeholders = array($this->timestamptoSQL());
401
 
 
 
 
 
 
 
402
  foreach($data as $field => $value)
403
  {
404
  $update_sql .= ' ,' . $field . ' = %s ';
399
  else
400
  $placeholders = array($this->timestamptoSQL());
401
 
402
+ // Certain older SQL servers like to auto-update created date, creating a mess.
403
+ if (! isset($data['created']))
404
+ {
405
+ $update_sql .= ', created = created';
406
+ }
407
+
408
  foreach($data as $field => $value)
409
  {
410
  $update_sql .= ' ,' . $field . ' = %s ';
build/shortpixel/shortq/src/Queue/WPQ.php CHANGED
@@ -74,10 +74,11 @@ class WPQ implements Queue
74
  /** Prepare items for enqueue, if you want to deliver items in batch, but not flush to storage directly
75
  * Every Item needs to have an (item)_id and (item)_value. That's the only thing remote app should be aware of.
76
  * @param Array Item Array with fields: id, value [order]
 
77
  *
78
  *
79
  */
80
- public function addItems($items)
81
  {
82
  foreach($items as $item)
83
  {
@@ -100,7 +101,7 @@ class WPQ implements Queue
100
  $this->items[] = $itemObj;
101
 
102
  }
103
- if (count($items) > 0)
104
  {
105
  $this->setStatus('preparing', true, false);
106
  $this->setStatus('finished', false, false); // can't be finished when adding items.
74
  /** Prepare items for enqueue, if you want to deliver items in batch, but not flush to storage directly
75
  * Every Item needs to have an (item)_id and (item)_value. That's the only thing remote app should be aware of.
76
  * @param Array Item Array with fields: id, value [order]
77
+ * @param bool If status should be updated due to adding items.
78
  *
79
  *
80
  */
81
+ public function addItems($items, $updateStatus = true)
82
  {
83
  foreach($items as $item)
84
  {
101
  $this->items[] = $itemObj;
102
 
103
  }
104
+ if (count($items) > 0 && true === $updateStatus)
105
  {
106
  $this->setStatus('preparing', true, false);
107
  $this->setStatus('finished', false, false); // can't be finished when adding items.
class/Controller/AdminController.php CHANGED
@@ -220,6 +220,7 @@ class AdminController extends \ShortPixel\Controller
220
  try
221
  {
222
  $imageObj = $fs->getImage($post_id, 'media');
 
223
  if ($imageObj !== false)
224
  $result = $imageObj->onDelete();
225
  }
220
  try
221
  {
222
  $imageObj = $fs->getImage($post_id, 'media');
223
+ Log::addDebug('OnDelete ImageObj', $imageObj);
224
  if ($imageObj !== false)
225
  $result = $imageObj->onDelete();
226
  }
class/Controller/AdminNoticesController.php CHANGED
@@ -160,7 +160,7 @@ class AdminNoticesController extends \ShortPixel\Controller
160
  || $notice->getID() == AdminNoticesController::MSG_UPGRADE_BULK)
161
  {
162
  wp_enqueue_script('jquery.knob.min.js');
163
- wp_enqueue_script('jquery.tooltip.min.js');
164
  wp_enqueue_script('shortpixel');
165
  // \wpSPIO()->load_style('shortpixel-modal');
166
  }
@@ -294,7 +294,6 @@ class AdminNoticesController extends \ShortPixel\Controller
294
  $noticeController = Notices::getInstance();
295
 
296
  $notice = $noticeController->getNoticeByID(self::MSG_CONVERT_LEGACY);
297
- Log::addTemp('Legacy Notice', $notice);
298
  // If already in system, don't bother doing it again.
299
  if ($notice !== false)
300
  return;
160
  || $notice->getID() == AdminNoticesController::MSG_UPGRADE_BULK)
161
  {
162
  wp_enqueue_script('jquery.knob.min.js');
163
+ //wp_enqueue_script('jquery.tooltip.min.js');
164
  wp_enqueue_script('shortpixel');
165
  // \wpSPIO()->load_style('shortpixel-modal');
166
  }
294
  $noticeController = Notices::getInstance();
295
 
296
  $notice = $noticeController->getNoticeByID(self::MSG_CONVERT_LEGACY);
 
297
  // If already in system, don't bother doing it again.
298
  if ($notice !== false)
299
  return;
class/Controller/ApiController.php CHANGED
@@ -303,7 +303,11 @@ class ApiController
303
 
304
  return $this->returnRetry( self::STATUS_QUOTA_EXCEEDED, __('Quota exceeded.','shortpixel-image-optimiser'));
305
  break;
 
 
 
306
  case -401: // Invalid Api Key
 
307
  return $this->returnFailure( self::STATUS_NO_KEY, $status->Message);
308
  break;
309
  case -404: // Maximum number in optimization queue (remote)
303
 
304
  return $this->returnRetry( self::STATUS_QUOTA_EXCEEDED, __('Quota exceeded.','shortpixel-image-optimiser'));
305
  break;
306
+ case -306:
307
+ return $this->returnFailure( self::STATUS_FAIL, __('Files need to be from a single domain per request.', 'shortpixel-image-optimiser'));
308
+ break;
309
  case -401: // Invalid Api Key
310
+ case -402: // Wrong API key
311
  return $this->returnFailure( self::STATUS_NO_KEY, $status->Message);
312
  break;
313
  case -404: // Maximum number in optimization queue (remote)
class/Controller/OptimizeController.php CHANGED
@@ -522,7 +522,8 @@ class OptimizeController
522
  }
523
  else
524
  {
525
- //$item->result->filename = $imageItem->getFileName();
 
526
  // Used in WP-CLI
527
  ResponseController::addData($item->item_id, 'fileName', $imageItem->getFileName());
528
  }
@@ -957,7 +958,16 @@ class OptimizeController
957
  {
958
  if ($key == 'percentage_done')
959
  {
960
- $object->stats->$key = (($object->stats->$key + $value) / 2); //exceptionnes.
 
 
 
 
 
 
 
 
 
961
  }
962
  elseif (is_numeric($object->stats->$key)) // add only if number.
963
  {
522
  }
523
  else
524
  {
525
+ // This used in bulk preview for formatting filename.
526
+ $item->result->filename = $imageItem->getFileName();
527
  // Used in WP-CLI
528
  ResponseController::addData($item->item_id, 'fileName', $imageItem->getFileName());
529
  }
958
  {
959
  if ($key == 'percentage_done')
960
  {
961
+ if (property_exists($results->custom->stats, 'total') && $results->custom->stats->total == 0)
962
+ $perc = $value;
963
+ elseif(property_exists($results->media->stats, 'total') && $results->media->stats->total == 0)
964
+ {
965
+ $perc = $object->stats->$key;
966
+ }
967
+ else
968
+ $perc = round(($object->stats->$key + $value) / 2); //exceptionnes.
969
+
970
+ $object->stats->$key = $perc;
971
  }
972
  elseif (is_numeric($object->stats->$key)) // add only if number.
973
  {
class/Controller/Queue/Queue.php CHANGED
@@ -73,16 +73,16 @@ abstract class Queue
73
  public function addSingleItem(ImageModel $imageModel)
74
  {
75
 
76
- $preparing = $this->getStatus('preparing');
77
 
78
  $qItem = $this->imageModelToQueue($imageModel);
79
  $counts = $qItem->counts;
80
 
81
  $item = array('id' => $imageModel->get('id'), 'value' => $qItem, 'item_count' => $counts->creditCount);
82
- $this->q->addItems(array($item));
83
  $numitems = $this->q->withRemoveDuplicates()->enqueue(); // enqueue returns numitems
84
 
85
- $this->q->setStatus('preparing', $preparing); // add single should not influence preparing status.
86
  $result = new \stdClass;
87
  $result = $this->getQStatus($result, $numitems);
88
  $result->numitems = $numitems;
@@ -332,10 +332,13 @@ abstract class Queue
332
 
333
  $stats->total = $stats->in_queue + $stats->fatal_errors + $stats->errors + $stats->done + $stats->in_process;
334
  if ($stats->total > 0)
335
- $stats->percentage_done = round((100 / $stats->total) * ($stats->done + $stats->fatal_errors));
336
- else
 
 
337
  $stats->percentage_done = 100; // no items means all done.
338
 
 
339
  if (! $stats->is_running)
340
  {
341
  $stats->images = $this->countQueue();
@@ -613,7 +616,8 @@ abstract class Queue
613
  {
614
  $itemObj = $this->q->getItem($item_id);
615
 
616
- if (is_object($itemObj) && intval($itemObj->status) <> ShortQ::QSTATUS_DONE)
 
617
  {
618
  return true;
619
  }
73
  public function addSingleItem(ImageModel $imageModel)
74
  {
75
 
76
+ // $preparing = $this->getStatus('preparing');
77
 
78
  $qItem = $this->imageModelToQueue($imageModel);
79
  $counts = $qItem->counts;
80
 
81
  $item = array('id' => $imageModel->get('id'), 'value' => $qItem, 'item_count' => $counts->creditCount);
82
+ $this->q->addItems(array($item), false);
83
  $numitems = $this->q->withRemoveDuplicates()->enqueue(); // enqueue returns numitems
84
 
85
+ // $this->q->setStatus('preparing', $preparing, true); // add single should not influence preparing status.
86
  $result = new \stdClass;
87
  $result = $this->getQStatus($result, $numitems);
88
  $result->numitems = $numitems;
332
 
333
  $stats->total = $stats->in_queue + $stats->fatal_errors + $stats->errors + $stats->done + $stats->in_process;
334
  if ($stats->total > 0)
335
+ {
336
+ $stats->percentage_done = round(round((100 / $stats->total) * ($stats->done + $stats->fatal_errors)), 0, PHP_ROUND_HALF_DOWN);
337
+ }
338
+ else
339
  $stats->percentage_done = 100; // no items means all done.
340
 
341
+
342
  if (! $stats->is_running)
343
  {
344
  $stats->images = $this->countQueue();
616
  {
617
  $itemObj = $this->q->getItem($item_id);
618
 
619
+ $notQ = array(ShortQ::QSTATUS_DONE, ShortQ::QSTATUS_FATAL);
620
+ if (is_object($itemObj) && in_array(floor($itemObj->status), $notQ) === false )
621
  {
622
  return true;
623
  }
class/Controller/QuotaController.php CHANGED
@@ -141,10 +141,6 @@ class QuotaController
141
  private function resetQuotaExceeded()
142
  {
143
  $settings = \wpSPIO()->settings();
144
- $dismissed = $settings->dismissedNotices ? $settings->dismissedNotices : array();
145
-
146
- $settings->prioritySkip = array();
147
- $settings->dismissedNotices = $dismissed;
148
 
149
  AdminNoticesController::resetAPINotices();
150
 
141
  private function resetQuotaExceeded()
142
  {
143
  $settings = \wpSPIO()->settings();
 
 
 
 
144
 
145
  AdminNoticesController::resetAPINotices();
146
 
class/Controller/SettingsController.php CHANGED
@@ -395,7 +395,6 @@ class SettingsController extends \ShortPixel\ViewController
395
  $this->view->cloudflare_constant = defined('SHORTPIXEL_CFTOKEN') ? true : false;
396
 
397
  $settings = \wpSPIO()->settings();
398
- $this->view->dismissedNotices = $settings->dismissedNotices;
399
 
400
  if ($this->view->data->createAvif == 1)
401
  $this->avifServerCheck();
@@ -734,11 +733,6 @@ class SettingsController extends \ShortPixel\ViewController
734
 
735
  parent::processPostData($post);
736
 
737
- // Unset front optimization when automedialib. is off
738
- if ($this->postData['autoMediaLibrary'] == 0)
739
- {
740
- $this->postData['frontBootstrap'] = 0;
741
- }
742
 
743
  }
744
 
395
  $this->view->cloudflare_constant = defined('SHORTPIXEL_CFTOKEN') ? true : false;
396
 
397
  $settings = \wpSPIO()->settings();
 
398
 
399
  if ($this->view->data->createAvif == 1)
400
  $this->avifServerCheck();
733
 
734
  parent::processPostData($post);
735
 
 
 
 
 
 
736
 
737
  }
738
 
class/Controller/View/EditMediaViewController.php CHANGED
@@ -68,7 +68,6 @@ class EditMediaViewController extends \ShortPixel\ViewController
68
  return false;
69
  }
70
 
71
-
72
  $this->view->status_message = null;
73
 
74
  $this->view->text = UiHelper::getStatusText($this->imageModel);
68
  return false;
69
  }
70
 
 
71
  $this->view->status_message = null;
72
 
73
  $this->view->text = UiHelper::getStatusText($this->imageModel);
class/Helper/InstallHelper.php CHANGED
@@ -28,7 +28,6 @@ class InstallHelper
28
 
29
  AdminNoticesController::resetAllNotices();
30
  \WPShortPixelSettings::onActivate();
31
- OptimizeController::resetQueues();
32
 
33
  $settings->currentVersion = SHORTPIXEL_IMAGE_OPTIMISER_VERSION;
34
  }
28
 
29
  AdminNoticesController::resetAllNotices();
30
  \WPShortPixelSettings::onActivate();
 
31
 
32
  $settings->currentVersion = SHORTPIXEL_IMAGE_OPTIMISER_VERSION;
33
  }
class/Helper/UiHelper.php CHANGED
@@ -607,12 +607,12 @@ class UiHelper
607
  {
608
  global $wp_locale;
609
  $decimalpoint = isset($wp_locale->number_format['decimal_point']) ? $wp_locale->number_format['decimal_point'] : false;
610
- $number = number_format_i18n( (int) $number, $precision);
611
 
612
- // Don't show trailing zeroes if number is a whole unbroken number.
613
- if ($decimalpoint !== false && substr($number, strpos($number, $decimalpoint)) == 00)
614
  {
615
- $number = number_format_i18n($number, 0);
616
  }
617
  // Some locale's have no-breaking-space as thousands separator. This doesn't work well in JS / Cron Shell so replace with space.
618
  $number = str_replace('&nbsp;', ' ', $number);
607
  {
608
  global $wp_locale;
609
  $decimalpoint = isset($wp_locale->number_format['decimal_point']) ? $wp_locale->number_format['decimal_point'] : false;
610
+ $number = number_format_i18n( (float) $number, $precision);
611
 
612
+ // Don't show trailing zeroes if number is a whole unbroken number. -> string comparison because number_format_i18n returns string.
613
+ if ($decimalpoint !== false && substr($number, strpos($number, $decimalpoint) + 1) === '00')
614
  {
615
+ $number = substr($number, 0, strpos($number, $decimalpoint));
616
  }
617
  // Some locale's have no-breaking-space as thousands separator. This doesn't work well in JS / Cron Shell so replace with space.
618
  $number = str_replace('&nbsp;', ' ', $number);
class/Model.php CHANGED
@@ -11,8 +11,9 @@ abstract class Model
11
  $data = array();
12
  foreach($this->model as $item => $options)
13
  {
14
- $data[$item] = $this->{$item};
15
 
 
 
16
  }
17
  return $data;
18
  }
11
  $data = array();
12
  foreach($this->model as $item => $options)
13
  {
 
14
 
15
+ $data[$item] = $this->{$item};
16
+
17
  }
18
  return $data;
19
  }
class/Model/Image/ImageModel.php CHANGED
@@ -645,7 +645,7 @@ abstract class ImageModel extends \ShortPixel\Model\File\FileModel
645
 
646
  public function isRestorable()
647
  {
648
-
649
  if (! $this->isOptimized())
650
  {
651
  $this->restorable_status = self::P_NOT_OPTIMIZED;
@@ -884,7 +884,6 @@ abstract class ImageModel extends \ShortPixel\Model\File\FileModel
884
  if ($type == 'regex-name' || $type == 'regex-path')
885
  {
886
  $result = $this->matchExludeRegexPattern($target, $pattern);
887
- Log::addTemp('Exclude RegeX result', $result);
888
  }
889
  else {
890
  $result = $this->matchExcludePattern($target, $pattern);
645
 
646
  public function isRestorable()
647
  {
648
+
649
  if (! $this->isOptimized())
650
  {
651
  $this->restorable_status = self::P_NOT_OPTIMIZED;
884
  if ($type == 'regex-name' || $type == 'regex-path')
885
  {
886
  $result = $this->matchExludeRegexPattern($target, $pattern);
 
887
  }
888
  else {
889
  $result = $this->matchExcludePattern($target, $pattern);
class/Model/Image/MediaLibraryModel.php CHANGED
@@ -705,7 +705,6 @@ class MediaLibraryModel extends \ShortPixel\Model\Image\MediaLibraryThumbnailMod
705
  protected function loadMeta()
706
  {
707
  $metadata = $this->getDBMeta();
708
-
709
  $settings = \wpSPIO()->settings();
710
 
711
  $this->image_meta = new ImageMeta();
@@ -884,7 +883,7 @@ class MediaLibraryModel extends \ShortPixel\Model\Image\MediaLibraryThumbnailMod
884
 
885
  // Thumbnails
886
 
887
- // Mimic the previous SPixel solution regarding the return Metadata Object needed, with all thunbnails there.
888
  $metadata = new \stdClass;
889
  $metadata->image_meta = new \stdClass;
890
  $metadata->thumbnails = array();
@@ -1244,6 +1243,18 @@ class MediaLibraryModel extends \ShortPixel\Model\Image\MediaLibraryThumbnailMod
1244
  $originalFile->onDelete($fileDelete);
1245
  }
1246
 
 
 
 
 
 
 
 
 
 
 
 
 
1247
  $this->removeLegacy();
1248
  $this->deleteMeta();
1249
  $this->dropFromQueue();
705
  protected function loadMeta()
706
  {
707
  $metadata = $this->getDBMeta();
 
708
  $settings = \wpSPIO()->settings();
709
 
710
  $this->image_meta = new ImageMeta();
883
 
884
  // Thumbnails
885
 
886
+ // Mimic the previous SPixel solution regarding the return Metadata Object needed, with all thumbnails there.
887
  $metadata = new \stdClass;
888
  $metadata->image_meta = new \stdClass;
889
  $metadata->thumbnails = array();
1243
  $originalFile->onDelete($fileDelete);
1244
  }
1245
 
1246
+ if (! is_null($this->retinas))
1247
+ {
1248
+ foreach($this->retinas as $retinaObj)
1249
+ {
1250
+ if ($fileDelete === true)
1251
+ {
1252
+ $retinaObj->onDelete($fileDelete);
1253
+ }
1254
+ }
1255
+ }
1256
+
1257
+
1258
  $this->removeLegacy();
1259
  $this->deleteMeta();
1260
  $this->dropFromQueue();
class/Model/StatsModel.php CHANGED
@@ -118,7 +118,9 @@ class StatsModel
118
  public function reset()
119
  {
120
  $this->stats = $this->defaults;
121
- $this->save();
 
 
122
  }
123
 
124
  // @todo This is not functional
@@ -225,7 +227,11 @@ class StatsModel
225
 
226
  if ($data >= 0)
227
  {
228
- $this->stats['media'][$path[1]] = $data;
 
 
 
 
229
  $this->save();
230
  }
231
  }
118
  public function reset()
119
  {
120
  $this->stats = $this->defaults;
121
+ \wpSPIO()->settings()->deleteOption('currentStats');
122
+
123
+ // $this->save();
124
  }
125
 
126
  // @todo This is not functional
227
 
228
  if ($data >= 0)
229
  {
230
+ if (is_numeric($data))
231
+ {
232
+ $data = max($data, 0);
233
+ }
234
+ $this->stats['media'][$path[1]] = $data; // never allow any data below zero.
235
  $this->save();
236
  }
237
  }
class/Tools.php CHANGED
@@ -242,14 +242,7 @@ static public function DBtoTimestamp($date)
242
  )
243
  ));
244
  }
245
- if(!$settings->frontBootstrap){
246
- $conflictPlugins['Bulk Images to Posts Frontend'] = array (
247
- 'action'=>'Change Setting',
248
- 'data'=>'bulk-images-to-posts-front/bulk-images-to-posts.php',
249
- 'href'=>'options-general.php?page=wp-shortpixel-settings&part=adv-settings#siteAuthUser',
250
- 'details' => __('This plugin is uploading images in front-end so please activate the "Process in front-end" advanced option in ShortPixel in order to have your images optimized.','shortpixel-image-optimiser')
251
- );
252
- }
253
 
254
  $found = array();
255
  foreach($conflictPlugins as $name => $path) {
242
  )
243
  ));
244
  }
245
+
 
 
 
 
 
 
 
246
 
247
  $found = array();
248
  foreach($conflictPlugins as $name => $path) {
class/external/nextgen/nextGenController.php CHANGED
@@ -94,10 +94,9 @@ class NextGenController
94
  {
95
  return false;
96
  }
97
- $screen = get_current_screen();
98
 
99
-
100
- if (in_array($screen->id, $screens))
101
  return true;
102
  else
103
  return false;
94
  {
95
  return false;
96
  }
97
+ $screen_id = \wpSPIO()->env()->screen_id;
98
 
99
+ if (in_array($screen_id, $screens))
 
100
  return true;
101
  else
102
  return false;
class/view/shortpixel-feedback.php CHANGED
@@ -315,11 +315,6 @@ class ShortPixelFeedback {
315
 
316
  check_ajax_referer( 'shortpixel_deactivate_plugin', 'security' );
317
 
318
- $keep_settings = isset($_POST['keep-settings']) ? intval($_POST['keep-settings']) : null;
319
-
320
- if(is_null($keep_settings) === false) {
321
- \wpSPIO()->settings()->removeSettingsOnDeletePlugin = 1 - $keep_settings;
322
- }
323
 
324
  Log::addDebug('Deactive Plugin Callback POST', $_POST);
325
 
315
 
316
  check_ajax_referer( 'shortpixel_deactivate_plugin', 'security' );
317
 
 
 
 
 
 
318
 
319
  Log::addDebug('Deactive Plugin Callback POST', $_POST);
320
 
class/wp-shortpixel-settings.php CHANGED
@@ -19,7 +19,7 @@ class WPShortPixelSettings extends \ShortPixel\Model {
19
  private static $_optionsMap = array(
20
  //This one is accessed also directly via get_option
21
  'frontBootstrap' => array('key' => 'wp-short-pixel-front-bootstrap', 'default' => null, 'group' => 'options'), //set to 1 when need the plugin active for logged in user in the front-end
22
- 'lastBackAction' => array('key' => 'wp-short-pixel-last-back-action', 'default' => null, 'group' => 'state'), //when less than 10 min. passed from this timestamp, the front-bootstrap is ineffective.
23
 
24
  //optimization options
25
  'apiKey' => array('key' => 'wp-short-pixel-apiKey', 'default' => '', 'group' => 'options'),
@@ -59,7 +59,7 @@ class WPShortPixelSettings extends \ShortPixel\Model {
59
  'customBulkPaused' => array('key' => 'wp-short-pixel-custom-bulk-paused', 'default' => false, 'group' => 'options'),
60
 
61
  //uninstall
62
- 'removeSettingsOnDeletePlugin' => array('key' => 'wp-short-pixel-remove-settings-on-delete-plugin', 'default' => false, 'group' => 'options'),
63
 
64
  //stats, notices, etc.
65
  // @todo Most of this can go. See state machine comment.
@@ -77,38 +77,38 @@ class WPShortPixelSettings extends \ShortPixel\Model {
77
  'downloadProto' => array('key' => 'wp-short-pixel-download-protocol', 'default' => null, 'group' => 'state'),
78
 
79
  'downloadArchive' => array('key' => 'wp-short-pixel-download-archive', 'default' => -1, 'group' => 'state'),
80
- 'mediaAlert' => array('key' => 'wp-short-pixel-media-alert', 'default' => null, 'group' => 'state'),
81
- 'dismissedNotices' => array('key' => 'wp-short-pixel-dismissed-notices', 'default' => array(), 'group' => 'state'),
82
  'activationDate' => array('key' => 'wp-short-pixel-activation-date', 'default' => null, 'group' => 'state'),
83
- 'activationNotice' => array('key' => 'wp-short-pixel-activation-notice', 'default' => null, 'group' => 'state'),
84
  'mediaLibraryViewMode' => array('key' => 'wp-short-pixel-view-mode', 'default' => false, 'group' => 'state'),
85
  'redirectedSettings' => array('key' => 'wp-short-pixel-redirected-settings', 'default' => null, 'group' => 'state'),
86
  'convertedPng2Jpg' => array('key' => 'wp-short-pixel-converted-png2jpg', 'default' => array(), 'group' => 'state'),
87
- 'helpscoutOptin' => array('key' => 'wp-short-pixel-helpscout-optin', 'default' => -1, 'group' => 'state'),
88
 
89
 
90
  //bulk state machine
91
  // @todo These options can all go. Add as well to onDeactivate / onActivate deletions.
92
- 'bulkType' => array('key' => 'wp-short-pixel-bulk-type', 'default' => null, 'group' => 'bulk'),
93
- 'bulkLastStatus' => array('key' => 'wp-short-pixel-bulk-last-status', 'default' => null, 'group' => 'bulk'),
94
- 'startBulkId' => array('key' => 'wp-short-pixel-query-id-start', 'default' => 0, 'group' => 'bulk'),
95
- 'stopBulkId' => array('key' => 'wp-short-pixel-query-id-stop', 'default' => 0, 'group' => 'bulk'),
96
- 'bulkCount' => array('key' => 'wp-short-pixel-bulk-count', 'default' => 0, 'group' => 'bulk'),
97
- 'bulkPreviousPercent' => array('key' => 'wp-short-pixel-bulk-previous-percent', 'default' => 0, 'group' => 'bulk'),
98
- 'bulkCurrentlyProcessed' => array('key' => 'wp-short-pixel-bulk-processed-items', 'default' => 0, 'group' => 'bulk'),
99
- 'bulkAlreadyDoneCount' => array('key' => 'wp-short-pixel-bulk-done-count', 'default' => 0, 'group' => 'bulk'),
100
- 'lastBulkStartTime' => array('key' => 'wp-short-pixel-last-bulk-start-time', 'default' => 0, 'group' => 'bulk'),
101
- 'lastBulkSuccessTime' => array('key' => 'wp-short-pixel-last-bulk-success-time', 'default' => 0, 'group' => 'bulk'),
102
- 'bulkRunningTime' => array('key' => 'wp-short-pixel-bulk-running-time', 'default' => 0, 'group' => 'bulk'),
103
- 'cancelPointer' => array('key' => 'wp-short-pixel-cancel-pointer', 'default' => 0, 'group' => 'bulk'),
104
- 'skipToCustom' => array('key' => 'wp-short-pixel-skip-to-custom', 'default' => null, 'group' => 'bulk'),
105
- 'bulkEverRan' => array('key' => 'wp-short-pixel-bulk-ever-ran', 'default' => false, 'group' => 'bulk'),
106
- 'flagId' => array('key' => 'wp-short-pixel-flag-id', 'default' => 0, 'group' => 'bulk'),
107
- 'failedImages' => array('key' => 'wp-short-pixel-failed-imgs', 'default' => 0, 'group' => 'bulk'),
108
- 'bulkProcessingStatus' => array('key' => 'bulkProcessingStatus', 'default' => null, 'group' => 'bulk'),
109
 
110
  //'priorityQueue' => array('key' => 'wp-short-pixel-priorityQueue', 'default' => array()),
111
- 'prioritySkip' => array('key' => 'wp-short-pixel-prioritySkip', 'default' => array(), 'group' => 'state'),
112
 
113
  //'' => array('key' => 'wp-short-pixel-', 'default' => null),
114
  );
@@ -147,7 +147,7 @@ class WPShortPixelSettings extends \ShortPixel\Model {
147
  'savedSpace' => array('s' => 'skip'),
148
  'fileCount' => array('s' => 'skip'), // int
149
  'under5Percent' => array('s' => 'skip'), // int
150
- 'helpscoutOptin' => array('s' => 'boolean'), // checkbox
151
  );
152
 
153
  public function __construct() {
@@ -188,9 +188,11 @@ class WPShortPixelSettings extends \ShortPixel\Model {
188
  update_option('wp-short-pixel-activation-notice', true, 'no');
189
  }
190
  update_option( 'wp-short-pixel-activation-date', time(), 'no');
191
- delete_option( 'wp-short-pixel-bulk-last-status'); // legacy shizzle
 
192
  delete_option( 'wp-short-pixel-current-total-files');
193
  delete_option('wp-short-pixel-remove-settings-on-delete-plugin');
 
194
  delete_option(self::$_optionsMap['removeSettingsOnDeletePlugin']['key']);
195
 
196
  // Dismissed now via Notices Controller.
@@ -200,20 +202,64 @@ class WPShortPixelSettings extends \ShortPixel\Model {
200
  update_option('wp-short-pixel-dismissed-notices', $dismissed, 'no');
201
  } */
202
 
203
- $formerPrio = get_option('wp-short-pixel-priorityQueue');
204
  // $qGet = (! defined('SHORTPIXEL_NOFLOCK')) ? ShortPixelQueue::get() : ShortPixelQueueDB::get();
205
  /* if(is_array($formerPrio) && !count($qGet)) {
206
 
207
  (! defined('SHORTPIXEL_NOFLOCK')) ? ShortPixelQueue::set($formerPrio) : ShortPixelQueueDB::set($formerPrio); */
208
- delete_option('wp-short-pixel-priorityQueue');
209
  // }
210
  }
211
 
212
  public static function onDeactivate() {
 
213
  delete_option('wp-short-pixel-activation-notice');
214
  delete_option('wp-short-pixel-bulk-last-status'); // legacy shizzle
215
  delete_option('wp-short-pixel-current-total-files');
216
  delete_option('wp-short-pixel-remove-settings-on-delete-plugin');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
217
  }
218
 
219
 
@@ -241,6 +287,16 @@ class WPShortPixelSettings extends \ShortPixel\Model {
241
  }
242
  }
243
 
 
 
 
 
 
 
 
 
 
 
244
  public static function getOpt($key, $default = null) {
245
 
246
  // This function required the internal Key. If this not given, but settings key, overwrite.
19
  private static $_optionsMap = array(
20
  //This one is accessed also directly via get_option
21
  'frontBootstrap' => array('key' => 'wp-short-pixel-front-bootstrap', 'default' => null, 'group' => 'options'), //set to 1 when need the plugin active for logged in user in the front-end
22
+ // 'lastBackAction' => array('key' => 'wp-short-pixel-last-back-action', 'default' => null, 'group' => 'state'), //when less than 10 min. passed from this timestamp, the front-bootstrap is ineffective.
23
 
24
  //optimization options
25
  'apiKey' => array('key' => 'wp-short-pixel-apiKey', 'default' => '', 'group' => 'options'),
59
  'customBulkPaused' => array('key' => 'wp-short-pixel-custom-bulk-paused', 'default' => false, 'group' => 'options'),
60
 
61
  //uninstall
62
+ // 'removeSettingsOnDeletePlugin' => array('key' => 'wp-short-pixel-remove-settings-on-delete-plugin', 'default' => false, 'group' => 'options'),
63
 
64
  //stats, notices, etc.
65
  // @todo Most of this can go. See state machine comment.
77
  'downloadProto' => array('key' => 'wp-short-pixel-download-protocol', 'default' => null, 'group' => 'state'),
78
 
79
  'downloadArchive' => array('key' => 'wp-short-pixel-download-archive', 'default' => -1, 'group' => 'state'),
80
+ // 'mediaAlert' => array('key' => 'wp-short-pixel-media-alert', 'default' => null, 'group' => 'state'),
81
+ // 'dismissedNotices' => array('key' => 'wp-short-pixel-dismissed-notices', 'default' => array(), 'group' => 'state'),
82
  'activationDate' => array('key' => 'wp-short-pixel-activation-date', 'default' => null, 'group' => 'state'),
83
+ //'activationNotice' => array('key' => 'wp-short-pixel-activation-notice', 'default' => null, 'group' => 'state'),
84
  'mediaLibraryViewMode' => array('key' => 'wp-short-pixel-view-mode', 'default' => false, 'group' => 'state'),
85
  'redirectedSettings' => array('key' => 'wp-short-pixel-redirected-settings', 'default' => null, 'group' => 'state'),
86
  'convertedPng2Jpg' => array('key' => 'wp-short-pixel-converted-png2jpg', 'default' => array(), 'group' => 'state'),
87
+ //'helpscoutOptin' => array('key' => 'wp-short-pixel-helpscout-optin', 'default' => -1, 'group' => 'state'),
88
 
89
 
90
  //bulk state machine
91
  // @todo These options can all go. Add as well to onDeactivate / onActivate deletions.
92
+ // 'bulkType' => array('key' => 'wp-short-pixel-bulk-type', 'default' => null, 'group' => 'bulk'),
93
+ // 'bulkLastStatus' => array('key' => 'wp-short-pixel-bulk-last-status', 'default' => null, 'group' => 'bulk'),
94
+ // 'startBulkId' => array('key' => 'wp-short-pixel-query-id-start', 'default' => 0, 'group' => 'bulk'),
95
+ // 'stopBulkId' => array('key' => 'wp-short-pixel-query-id-stop', 'default' => 0, 'group' => 'bulk'),
96
+ // 'bulkCount' => array('key' => 'wp-short-pixel-bulk-count', 'default' => 0, 'group' => 'bulk'),
97
+ // 'bulkPreviousPercent' => array('key' => 'wp-short-pixel-bulk-previous-percent', 'default' => 0, 'group' => 'bulk'),
98
+ // 'bulkCurrentlyProcessed' => array('key' => 'wp-short-pixel-bulk-processed-items', 'default' => 0, 'group' => 'bulk'),
99
+ // 'bulkAlreadyDoneCount' => array('key' => 'wp-short-pixel-bulk-done-count', 'default' => 0, 'group' => 'bulk'),
100
+ // 'lastBulkStartTime' => array('key' => 'wp-short-pixel-last-bulk-start-time', 'default' => 0, 'group' => 'bulk'),
101
+ // 'lastBulkSuccessTime' => array('key' => 'wp-short-pixel-last-bulk-success-time', 'default' => 0, 'group' => 'bulk'),
102
+ // 'bulkRunningTime' => array('key' => 'wp-short-pixel-bulk-running-time', 'default' => 0, 'group' => 'bulk'),
103
+ // 'cancelPointer' => array('key' => 'wp-short-pixel-cancel-pointer', 'default' => 0, 'group' => 'bulk'),
104
+ // 'skipToCustom' => array('key' => 'wp-short-pixel-skip-to-custom', 'default' => null, 'group' => 'bulk'),
105
+ // 'bulkEverRan' => array('key' => 'wp-short-pixel-bulk-ever-ran', 'default' => false, 'group' => 'bulk'),
106
+ // 'flagId' => array('key' => 'wp-short-pixel-flag-id', 'default' => 0, 'group' => 'bulk'),
107
+ // 'failedImages' => array('key' => 'wp-short-pixel-failed-imgs', 'default' => 0, 'group' => 'bulk'),
108
+ // 'bulkProcessingStatus' => array('key' => 'bulkProcessingStatus', 'default' => null, 'group' => 'bulk'),
109
 
110
  //'priorityQueue' => array('key' => 'wp-short-pixel-priorityQueue', 'default' => array()),
111
+ // 'prioritySkip' => array('key' => 'wp-short-pixel-prioritySkip', 'default' => array(), 'group' => 'state'),
112
 
113
  //'' => array('key' => 'wp-short-pixel-', 'default' => null),
114
  );
147
  'savedSpace' => array('s' => 'skip'),
148
  'fileCount' => array('s' => 'skip'), // int
149
  'under5Percent' => array('s' => 'skip'), // int
150
+ // 'helpscoutOptin' => array('s' => 'boolean'), // checkbox
151
  );
152
 
153
  public function __construct() {
188
  update_option('wp-short-pixel-activation-notice', true, 'no');
189
  }
190
  update_option( 'wp-short-pixel-activation-date', time(), 'no');
191
+
192
+ delete_option( 'wp-short-pixel-bulk-last-status'); // legacy shizzle
193
  delete_option( 'wp-short-pixel-current-total-files');
194
  delete_option('wp-short-pixel-remove-settings-on-delete-plugin');
195
+
196
  delete_option(self::$_optionsMap['removeSettingsOnDeletePlugin']['key']);
197
 
198
  // Dismissed now via Notices Controller.
202
  update_option('wp-short-pixel-dismissed-notices', $dismissed, 'no');
203
  } */
204
 
205
+ //$formerPrio = get_option('wp-short-pixel-priorityQueue');
206
  // $qGet = (! defined('SHORTPIXEL_NOFLOCK')) ? ShortPixelQueue::get() : ShortPixelQueueDB::get();
207
  /* if(is_array($formerPrio) && !count($qGet)) {
208
 
209
  (! defined('SHORTPIXEL_NOFLOCK')) ? ShortPixelQueue::set($formerPrio) : ShortPixelQueueDB::set($formerPrio); */
210
+ // delete_option('wp-short-pixel-priorityQueue');
211
  // }
212
  }
213
 
214
  public static function onDeactivate() {
215
+
216
  delete_option('wp-short-pixel-activation-notice');
217
  delete_option('wp-short-pixel-bulk-last-status'); // legacy shizzle
218
  delete_option('wp-short-pixel-current-total-files');
219
  delete_option('wp-short-pixel-remove-settings-on-delete-plugin');
220
+
221
+ // Bulk State machine legacy
222
+ $bulkLegacyOptions = array(
223
+ 'wp-short-pixel-bulk-type',
224
+ 'wp-short-pixel-bulk-last-status',
225
+ 'wp-short-pixel-query-id-start',
226
+ 'wp-short-pixel-query-id-stop',
227
+ 'wp-short-pixel-bulk-count',
228
+ 'wp-short-pixel-bulk-previous-percent',
229
+ 'wp-short-pixel-bulk-processed-items',
230
+ 'wp-short-pixel-bulk-done-count',
231
+ 'wp-short-pixel-last-bulk-start-time',
232
+ 'wp-short-pixel-last-bulk-success-time',
233
+ 'wp-short-pixel-bulk-running-time',
234
+ 'wp-short-pixel-cancel-pointer',
235
+ 'wp-short-pixel-skip-to-custom',
236
+ 'wp-short-pixel-bulk-ever-ran',
237
+ 'wp-short-pixel-flag-id',
238
+ 'wp-short-pixel-failed-imgs',
239
+ 'bulkProcessingStatus',
240
+ 'wp-short-pixel-prioritySkip',
241
+ );
242
+
243
+ $removedStats = array(
244
+ 'wp-short-pixel-helpscout-optin',
245
+ 'wp-short-pixel-activation-notice',
246
+ 'wp-short-pixel-dismissed-notices',
247
+ 'wp-short-pixel-media-alert',
248
+ );
249
+
250
+ $removedOptions = array(
251
+ 'wp-short-pixel-remove-settings-on-delete-plugin',
252
+ 'wp-short-pixel-custom-bulk-paused',
253
+ 'wp-short-pixel-last-back-action',
254
+ 'wp-short-pixel-front-bootstrap',
255
+ );
256
+
257
+ $toRemove = array_merge($bulkLegacyOptions, $removedStats, $removedOptions);
258
+
259
+ foreach($toRemove as $option)
260
+ {
261
+ delete_option($option);
262
+ }
263
  }
264
 
265
 
287
  }
288
  }
289
 
290
+ // Remove option. Only deletes with defined key!
291
+ public function deleteOption($key)
292
+ {
293
+ if(isset(self::$_optionsMap[$key]) && isset(self::$_optionsMap[$key]['key']))
294
+ {
295
+ $deleteKey = self::$_optionsMap[$key]['key'];
296
+ delete_option($deleteKey);
297
+ }
298
+ }
299
+
300
  public static function getOpt($key, $default = null) {
301
 
302
  // This function required the internal Key. If this not given, but settings key, overwrite.
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.8
8
  License: GPLv2 or later
9
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
10
 
@@ -12,19 +12,19 @@ Speed up your website & boost your SEO by compressing old & new images and PDFs.
12
 
13
  == Description ==
14
 
15
- **A freemium, easy to use, comprehensive, stable and frequently updated image compression plugin supported by the friendly team that created it. :)**
16
 
17
- Increase your website's SEO ranking, number of visitors and ultimately your sales by optimising any image or PDF document on your website.
18
- ShortPixel is an easy to use, lightweight, install-and-forget-about-it <a href="https://shortpixel.com" target="_blank">image optimization</a> plugin that can compress all your past images and PDF documents with a single click. New images are automatically resized/rescaled and optimized on the fly, in the background. It's also compatible with any gallery, slider or ecommerce plugin.
19
 
20
  **Ready for a quick DEMO? Test our plugin <a href="https://demo.tastewp.com/shortpixel-image-optimiser" target="_blank">here</a> and <a href="https://wpsandbox.net/" target="_blank">here</a>.**
21
  Or you can create a staging copy of your site using <a href="https://wp-staging.com/" target="_blank">WP Staging</a> and test it there.
22
 
23
  Short Pixel uses minimal resources and works well with any shared, cloud, VPS or dedicated web hosting. It can optimize any image you have on your website even the images that aren't listed in Media Library like those in galleries like <a href="https://wordpress.org/plugins/nextgen-gallery/" target="_blank">NextGEN</a>, <a href="https://wordpress.org/plugins/modula-best-grid-gallery/" target="_blank">Modula</a> or added directly via FTP!
24
 
25
- Both lossy and lossless image compression are available for the most common image types (JPG, PNG, GIF, WebP and AVIF) plus PDF files.
26
- We also offer **glossy** JPEG compression which is a very high quality lossy optimization algorithm. Specially designed for photographers!
27
- Optimized images mean better user experience, better PageSpeed Insights or GTmetrix results, better Google PageRank and more visitors.
28
 
29
  Make an instant <a href="https://shortpixel.com/image-compression-test" target="_blank">image compression test</a> of your site or <a href="https://shortpixel.com/online-image-compression" target="_blank">compress some images</a> to test our optimization algorithms.
30
 
@@ -148,14 +148,14 @@ Let's get the ShortPixel plugin running on your WordPress website:
148
 
149
  = A credit = an optimized image? =
150
  Yes, that is correct.
151
- But please note that usually an image in Media Library has 3, 5 or more associated thumbs. Each optimized thumb requires a credit. In the rare cases when ShortPixel does not optimise the image (lossy) with at least 5%, the credit will not be consumed, though.
152
 
153
  = Can I restore my images? What happens with the originals? =
154
  If you choose the "Image backup" option in Settings/ShortPixel then the original version of any optimized image or PDF will be saved in the backup folder.
155
- The original image is needed if you want to restore an image or if you want to convert an image from lossy/glossy to lossless or viceversa.
156
 
157
  = What types of formats can be optimized? =
158
- ShortPixel optimises JPEG (JPG, JPEG, JPEG 2000, JPEG XR), PNG, GIF (animated and still) and PDF type of files.
159
 
160
  = Do you have one-time plans? =
161
  Yes we do.
@@ -166,13 +166,13 @@ Let's get the ShortPixel plugin running on your WordPress website:
166
  If you choose the backup option then the originals will be saved in a separate folder so you can restore them should you ever need/want to do that.
167
 
168
  = How does the plugin work? =
169
- Our light-weight plugin sends the original images to our Image Optimization Cloud where they are compressed. ShortPixel then downloads the optimized images and the unoptimized originals are replaced with the optimised versions.
170
 
171
  = Do you optimize images in the cloud? =
172
- Yes, all the images processsed by ShortPixel are optimized in the Cloud. This takes the load off of your server and allows us to produce the best results.
173
 
174
  = What payment methods are accepted? =
175
- We accept payments via card (Mastercard, Visa, Maestro, American Express, Discover, Diners Club, JCB, UnionPay), PayPal and Apple Pay.
176
 
177
  = How do I activate the API key on a multisite? =
178
  You have to activate the plugin in the network admin and then activate it manually on each individual site in the multisite. Once you have done that, the Settings menu appears and you can add the API key for each individual site.
@@ -182,7 +182,7 @@ Let's get the ShortPixel plugin running on your WordPress website:
182
  where `APIKEY` is the API Key received upon sign up.
183
  If configured that way, the API key will be used for all the sites of the multisite but will only be visible on the main site’s Settings page, being hidden for the rest of the sites.
184
 
185
- = I am not the only one working in the WordPress Dashboard. How can I hide my API key? =
186
  There is a simple way to hide the API key, all you need to do is to add these two lines in your wp-config.php:
187
 
188
  `define('SHORTPIXEL_API_KEY', '<<your api key here>>');`
@@ -192,9 +192,9 @@ where `APIKEY` is the API Key received upon sign up.
192
  A credit is used each time ShortPixel optimizes an image or thumbnail by at least 5%. If we're not able to optimize an image or thumbnail by at least 5% then no credit will be used :-)
193
  Please also note that usually images in your Media Library have 3-5 thumbs associated and a credit will be used for each featured image or associated thumbnail that is optimized.
194
 
195
- = Why shall I use a wordpress plugin and not an offline tool? =
196
  Because ShortPixel algorithms were perfected while optimizing over 3.5 billion real-life images.
197
- ShortPixel not only offers the best compression for JPEG, PNG, GIF and PDF files but it also saves you a lot of time. You just install it on your site and then ShortPixel will take care that all the images on your site are immediately optimized after upload.
198
 
199
  = Does optimizing images affect my ALT tags? =
200
  No, ShortPixel only optimizes images, it won't touch anything else like your HTML/CSS.
@@ -205,13 +205,13 @@ where `APIKEY` is the API Key received upon sign up.
205
 
206
  = Do I have to pay monthly or one time? =
207
  We have both options available.
208
- One-time credits never expire are a bit more expensive. Check out our prices <a href="https://shortpixel.com/pricing" >here</a>
209
 
210
  = When can I cancel a monthly plan? =
211
  Whenever you want.
212
  The credits you still have available for the current billing period will still be available until the end of the billing period. At the end of it, you won't be billed again and the plan will be reset to the free plan.
213
 
214
- = When credits expire? =
215
  Monthly credits expire after 30 days while one-time credits never expire.
216
 
217
  = Do you have an API? =
@@ -219,7 +219,7 @@ where `APIKEY` is the API Key received upon sign up.
219
  You can learn more about it here:
220
  <a href="https://shortpixel.com/api-tools">https://shortpixel.com/api-tools</a>
221
 
222
- = Can I use ShortPixel WP plugin on a localhost installation? =
223
  Unfortunately not :-(
224
  But you can use either our command line tool or our web tool
225
  <a href="https://shortpixel.com/web-tool-docs">https://shortpixel.com/web-tool-docs</a>
@@ -250,27 +250,55 @@ before restoring an image from backup;
250
  `do_action("shortpixel_after_restore_image", $post_id);`
251
  after succesful restore;
252
 
 
 
253
  `apply_filters("shortpixel_backup_folder", $backup_folder, $main_file_path, $sizes);`
254
  just before returning the ShortPixel backup folder, usually /wp-content/uploads/ShortpixelBackups. The `$sizes` are the sizes array from metadata;
255
 
 
 
 
 
 
256
  `apply_filters('shortpixel_image_exists', file_exists($path), $path, $post_id);`
257
  post ID is not always set, only if it's an image from Media Library;
258
 
259
  `apply_filters('shortpixel_image_urls', $URLs, $post_id);`
260
  filters the URLs that will be sent to optimisation, `$URLs` is a plain array;
261
 
 
 
262
  `apply_filters('shortpixel/db/chunk_size', $chunk);`
263
- the `$chunk` is the value ShortPixel chooses to use as number of selected records in one query (based on total table size), some hosts work better with a different value;
264
 
265
  `apply_filters('shortpixel/backup/paths', $PATHs, $mainPath);`
266
  filters the array of paths of the images sent for backup and can be used to exclude certain paths/images/thumbs from being backed up, based on the image path. `$mainPath` is the path of the main image, while `$PATHs` is an array with all files to be backed up (including thumbnails);
267
 
268
  `apply_filters('shortpixel/settings/image_sizes', $sizes);`
269
- filters the array (`$sizes`) of image sizes which can be excluded from processing (displayed in the plugin Advanced settings);
270
 
271
  `apply_filters('shortpixel/api/request', $requestParameters, $item_id);`
272
  filters the parameters sent to the optimization API (through `$requestParameters`), described in detail here: <a href="https://shortpixel.com/api-docs" target="_blank">ShortPixel Reducer API</a>; `$item_id` contains the ID of the Media Library item, or the ID of the Custom Media item (when used). In short, this filter can be used to alter any parameters sent to the API, depending on the needs. For example, you can set different resize parameters for different post types, different compression levels, remove EXIF or not, covert WebP/AVIF, and basically any other parameter that is sent to the API for a specific image (together with all its thumbnails).
273
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
274
  In order to define custom thumbnails to be picked up by the optimization you have two options, both comma separated defines:
275
 
276
  `define('SHORTPIXEL_CUSTOM_THUMB_SUFFIXES', '_tl,_tr');`
@@ -281,7 +309,7 @@ will handle custom thumbnails like image-100x100_tl.jpg;
281
 
282
  `define('SHORTPIXEL_USE_DOUBLE_WEBP_EXTENSION', true);`
283
  `define('SHORTPIXEL_USE_DOUBLE_AVIF_EXTENSION', true);`
284
- will tell the plugin to create double extensions for the WebP/AVIF image counterparts, for example image.jpg.webp/image.jpg.avif for image.jpg;
285
 
286
  Hide the Cloudflare settings by defining these constants in wp-config.php:
287
 
@@ -299,22 +327,34 @@ Add HTTP basic authentication credentials by defining these constants in wp-conf
299
 
300
  2. Activate your API key in the plugin Settings. (Settings>ShortPixel)
301
 
302
- 3. Check out the main settings after API key activated. (Settings>ShortPixel)
303
 
304
  4. Tweak it using Advanced settings. (Settings>ShortPixel)
305
 
306
  5. Compress all your past images with one click. (Media>Bulk ShortPixel)
307
 
308
- 6. Check your stats: number of processed files, saved space, average compression, saved bandwidth, remaining images. (Settings>ShortPixel)
309
 
310
- 7. Check images optimization status, restore or reoptimize the image. (Media>Library)
311
 
312
- 8. Check image optimisation details. (Media>Library->Edit)
313
-
314
- 9. Check other optimized images status - themes or other plugins' images. (Media>Other Media)
315
 
316
  == Changelog ==
317
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
318
  = 5.0.8 =
319
  Release date August 8th, 2022
320
  * Fix: the `Previous Bulks` now displays the number of credits used instead of the number of Media Library items, to avoid confusion;
4
  Requires at least: 4.8.0
5
  Tested up to: 6.0
6
  Requires PHP: 5.6
7
+ Stable tag: 5.0.9
8
  License: GPLv2 or later
9
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
10
 
12
 
13
  == Description ==
14
 
15
+ **A freemium, easy to use, comprehensive, stable, and frequently updated image compression plugin supported by the friendly team that created it. :)**
16
 
17
+ Increase your website's SEO ranking, number of visitors, and ultimately your sales by optimising any image or PDF document on your website.
18
+ ShortPixel is an easy to use, lightweight, install-and-forget-about-it <a href="https://shortpixel.com" target="_blank">image optimization</a> plugin that can compress all your past images and PDF documents with a single click. New images are automatically resized/rescaled and optimized on the fly, in the background. It's also compatible with any gallery, slider or eCommerce plugin.
19
 
20
  **Ready for a quick DEMO? Test our plugin <a href="https://demo.tastewp.com/shortpixel-image-optimiser" target="_blank">here</a> and <a href="https://wpsandbox.net/" target="_blank">here</a>.**
21
  Or you can create a staging copy of your site using <a href="https://wp-staging.com/" target="_blank">WP Staging</a> and test it there.
22
 
23
  Short Pixel uses minimal resources and works well with any shared, cloud, VPS or dedicated web hosting. It can optimize any image you have on your website even the images that aren't listed in Media Library like those in galleries like <a href="https://wordpress.org/plugins/nextgen-gallery/" target="_blank">NextGEN</a>, <a href="https://wordpress.org/plugins/modula-best-grid-gallery/" target="_blank">Modula</a> or added directly via FTP!
24
 
25
+ Both lossy and lossless image compression are available for the most common image types (JPG, PNG, GIF, WebP, and AVIF) plus PDF files.
26
+ We also offer **glossy** JPEG compression which is a very high-quality lossy optimization algorithm. Specially designed for photographers!
27
+ Optimized images mean better user experience, better PageSpeed Insights or GTmetrix results, better Google PageRank, and more visitors.
28
 
29
  Make an instant <a href="https://shortpixel.com/image-compression-test" target="_blank">image compression test</a> of your site or <a href="https://shortpixel.com/online-image-compression" target="_blank">compress some images</a> to test our optimization algorithms.
30
 
148
 
149
  = A credit = an optimized image? =
150
  Yes, that is correct.
151
+ But please note that usually, an image in Media Library has 5 or more associated thumbs. Each optimized thumbnail requires a credit. In the rare cases when ShortPixel does not optimise the image (lossy) with at least 5%, the credit will not be consumed, though.
152
 
153
  = Can I restore my images? What happens with the originals? =
154
  If you choose the "Image backup" option in Settings/ShortPixel then the original version of any optimized image or PDF will be saved in the backup folder.
155
+ The original image is needed if you want to restore an image or if you want to convert an image from lossy/glossy to lossless or vice-versa.
156
 
157
  = What types of formats can be optimized? =
158
+ ShortPixel optimises JPEG (JPG, JPEG, JPEG 2000, JPEG XR), PNG, GIF (animated and still), and PDF type of files.
159
 
160
  = Do you have one-time plans? =
161
  Yes we do.
166
  If you choose the backup option then the originals will be saved in a separate folder so you can restore them should you ever need/want to do that.
167
 
168
  = How does the plugin work? =
169
+ Our lightweight plugin sends the original images to our Image Optimization Cloud where they are compressed. ShortPixel then downloads the optimized images and the unoptimized originals are replaced with the optimised versions.
170
 
171
  = Do you optimize images in the cloud? =
172
+ Yes, all the images processed by ShortPixel are optimized in the Cloud. This takes the load off of your server and allows us to produce the best results.
173
 
174
  = What payment methods are accepted? =
175
+ We accept payments via card (Mastercard, Visa, Maestro, American Express, Discover, Diners Club, JCB, UnionPay), PayPal, and Apple Pay.
176
 
177
  = How do I activate the API key on a multisite? =
178
  You have to activate the plugin in the network admin and then activate it manually on each individual site in the multisite. Once you have done that, the Settings menu appears and you can add the API key for each individual site.
182
  where `APIKEY` is the API Key received upon sign up.
183
  If configured that way, the API key will be used for all the sites of the multisite but will only be visible on the main site’s Settings page, being hidden for the rest of the sites.
184
 
185
+ = I am not the only one working on the WordPress Dashboard. How can I hide my API key? =
186
  There is a simple way to hide the API key, all you need to do is to add these two lines in your wp-config.php:
187
 
188
  `define('SHORTPIXEL_API_KEY', '<<your api key here>>');`
192
  A credit is used each time ShortPixel optimizes an image or thumbnail by at least 5%. If we're not able to optimize an image or thumbnail by at least 5% then no credit will be used :-)
193
  Please also note that usually images in your Media Library have 3-5 thumbs associated and a credit will be used for each featured image or associated thumbnail that is optimized.
194
 
195
+ = Why shall I use a WordPress plugin and not an offline tool? =
196
  Because ShortPixel algorithms were perfected while optimizing over 3.5 billion real-life images.
197
+ ShortPixel not only offers the best compression for JPEG, PNG, GIF, and PDF files but it also saves you a lot of time. You just install it on your site and then ShortPixel will take care that all the images on your site are immediately optimized after upload.
198
 
199
  = Does optimizing images affect my ALT tags? =
200
  No, ShortPixel only optimizes images, it won't touch anything else like your HTML/CSS.
205
 
206
  = Do I have to pay monthly or one time? =
207
  We have both options available.
208
+ One-time credits never expire and are a bit more expensive. Check out our prices <a href="https://shortpixel.com/pricing" >here</a>
209
 
210
  = When can I cancel a monthly plan? =
211
  Whenever you want.
212
  The credits you still have available for the current billing period will still be available until the end of the billing period. At the end of it, you won't be billed again and the plan will be reset to the free plan.
213
 
214
+ = When do credits expire? =
215
  Monthly credits expire after 30 days while one-time credits never expire.
216
 
217
  = Do you have an API? =
219
  You can learn more about it here:
220
  <a href="https://shortpixel.com/api-tools">https://shortpixel.com/api-tools</a>
221
 
222
+ = Can I use the ShortPixel WP plugin on a localhost installation? =
223
  Unfortunately not :-(
224
  But you can use either our command line tool or our web tool
225
  <a href="https://shortpixel.com/web-tool-docs">https://shortpixel.com/web-tool-docs</a>
250
  `do_action("shortpixel_after_restore_image", $post_id);`
251
  after succesful restore;
252
 
253
+ For version 4.22.10 and earlier:
254
+
255
  `apply_filters("shortpixel_backup_folder", $backup_folder, $main_file_path, $sizes);`
256
  just before returning the ShortPixel backup folder, usually /wp-content/uploads/ShortpixelBackups. The `$sizes` are the sizes array from metadata;
257
 
258
+ For version 5.0.0 and later:
259
+
260
+ `$directory = apply_filters("shortpixel/file/backup_folder", $directory, $file);`
261
+ just before returning the ShortPixel backup folder, usually /wp-content/uploads/ShortpixelBackups).
262
+
263
  `apply_filters('shortpixel_image_exists', file_exists($path), $path, $post_id);`
264
  post ID is not always set, only if it's an image from Media Library;
265
 
266
  `apply_filters('shortpixel_image_urls', $URLs, $post_id);`
267
  filters the URLs that will be sent to optimisation, `$URLs` is a plain array;
268
 
269
+ <strong>The filter below is deprecated starting with version 5.0.0!</strong>
270
+
271
  `apply_filters('shortpixel/db/chunk_size', $chunk);`
272
+ the `$chunk` is the value ShortPixel chooses to use as the number of selected records in one query (based on total table size), some hosts work better with a different value;
273
 
274
  `apply_filters('shortpixel/backup/paths', $PATHs, $mainPath);`
275
  filters the array of paths of the images sent for backup and can be used to exclude certain paths/images/thumbs from being backed up, based on the image path. `$mainPath` is the path of the main image, while `$PATHs` is an array with all files to be backed up (including thumbnails);
276
 
277
  `apply_filters('shortpixel/settings/image_sizes', $sizes);`
278
+ filters the array (`$sizes`) of image sizes that can be excluded from processing (displayed in the plugin Advanced settings);
279
 
280
  `apply_filters('shortpixel/api/request', $requestParameters, $item_id);`
281
  filters the parameters sent to the optimization API (through `$requestParameters`), described in detail here: <a href="https://shortpixel.com/api-docs" target="_blank">ShortPixel Reducer API</a>; `$item_id` contains the ID of the Media Library item, or the ID of the Custom Media item (when used). In short, this filter can be used to alter any parameters sent to the API, depending on the needs. For example, you can set different resize parameters for different post types, different compression levels, remove EXIF or not, covert WebP/AVIF, and basically any other parameter that is sent to the API for a specific image (together with all its thumbnails).
282
 
283
+ This filter enables the background ShortPixel processing in additional pages (see <a href="https://shortpixel.com/knowledge-base/article/334-on-what-pages-does-spio-optimize-images" target="_blank">here</a> the original list). Here's an example of this filter that enables the processing on the Comments screen (to be placed in your functions.php file):
284
+
285
+ `
286
+ add_filter('shortpixel/init/optimize_on_screens', function ($screens) {
287
+ $screens[] = 'edit-comments';
288
+ return $screens;
289
+ });
290
+ `
291
+ The `edit-comments` is the ID of the screen where you want to enable the processing.
292
+
293
+ If you want to add multiple pages, here's what the snippet looks like:
294
+
295
+ `
296
+ add_filter('shortpixel/init/optimize_on_screens', function ($screens) {
297
+ $screens = array('edit-comments', 'plugins', 'another-custom-post-type-page');
298
+ return $screens;
299
+ });
300
+ `
301
+
302
  In order to define custom thumbnails to be picked up by the optimization you have two options, both comma separated defines:
303
 
304
  `define('SHORTPIXEL_CUSTOM_THUMB_SUFFIXES', '_tl,_tr');`
309
 
310
  `define('SHORTPIXEL_USE_DOUBLE_WEBP_EXTENSION', true);`
311
  `define('SHORTPIXEL_USE_DOUBLE_AVIF_EXTENSION', true);`
312
+ will tell the plugin to create double extensions for the WebP/AVIF image counterparts, for example, image.jpg.webp/image.jpg.avif for image.jpg;
313
 
314
  Hide the Cloudflare settings by defining these constants in wp-config.php:
315
 
327
 
328
  2. Activate your API key in the plugin Settings. (Settings>ShortPixel)
329
 
330
+ 3. Check out the main settings after the API key is activated. (Settings>ShortPixel)
331
 
332
  4. Tweak it using Advanced settings. (Settings>ShortPixel)
333
 
334
  5. Compress all your past images with one click. (Media>Bulk ShortPixel)
335
 
336
+ 6. Check image optimization status, and restore or reoptimize the image. (Media>Library)
337
 
338
+ 7. Check image optimisation details. (Media>Library->Edit)
339
 
340
+ 8. Check other optimized images' status - themes or other plugins' images. (Media>Other Media)
 
 
341
 
342
  == Changelog ==
343
 
344
+ = 5.0.9 =
345
+ Release date August 29th, 2022
346
+ * Fix: one of the processing queues was flooded in certain situations, on sites with many concurrent editors;
347
+ * Fix: the file name was missing in the bulk processing preview;
348
+ * Fix: the queues were deleted when activating the plugin; now they are preserved and bulk processing can continue after updating/reactivating the plugin;
349
+ * Fix: retina backups were not removed when an image was deleted from the Media Library;
350
+ * Fix: NGG screen check caused processor to load on plugin/dashboard pages;
351
+ * Fix: stats were saved incorrectly when the plugin was deactivated;
352
+ * Fix: some PHP notices were displayed due to numbering format for Polish language;
353
+ * Fix: various minor fixes, error code handling and code cleanup;
354
+ * Fix: screenshots were updated to reflect the latest version of the plugin;
355
+ * Fix: updates to wording throughout the plugin and in the readme file;
356
+ * Language: 1 new string added, 0 updated, 0 fuzzed, and 1 deprecated.
357
+
358
  = 5.0.8 =
359
  Release date August 8th, 2022
360
  * Fix: the `Previous Bulks` now displays the number of credits used instead of the number of Media Library items, to avoid confusion;
res/js/jquery.tooltip.js DELETED
@@ -1,207 +0,0 @@
1
- (function($){
2
-
3
- $.fn.spTooltip = function(instanceSettings){
4
-
5
- $.fn.spTooltip.defaultsSettings = {
6
- attributeName:'title',
7
- borderColor:'#ccc',
8
- borderSize:'1',
9
- cancelClick:0,
10
- followMouse:1,
11
- height:'auto',
12
- hoverIntent:{sensitivity:7,interval:100,timeout:0},
13
- loader:0,
14
- loaderHeight:0,
15
- loaderImagePath:'',
16
- loaderWidth:0,
17
- positionTop: 12,
18
- positionLeft: 12,
19
- width:'auto',
20
- titleAttributeContent:'',
21
- tooltipBGColor:'#fff',
22
- tooltipBGImage:'none', // http path
23
- tooltipHTTPType:'get',
24
- tooltipPadding:10,
25
- tooltipSource:'attribute', //inline, ajax, iframe, attribute
26
- tooltipSourceID:'',
27
- tooltipSourceURL:'',
28
- tooltipID:'tooltip'
29
- };
30
-
31
- //s = settings
32
- var s = $.extend({}, $.fn.spTooltip.defaultsSettings , instanceSettings || {});
33
-
34
- var positionTooltip = function(e){
35
- e.preventDefault();
36
-
37
- var posx = 0;
38
- var posy = 0;
39
- if (!e) var e = window.event;
40
- if (e.pageX || e.pageY) {
41
- posx = e.pageX;
42
- posy = e.pageY;
43
- }
44
- else if (e.clientX || e.clientY) {
45
- posx = e.clientX + document.body.scrollLeft + document.documentElement.scrollLeft;
46
- posy = e.clientY + document.body.scrollTop + document.documentElement.scrollTop;
47
- }
48
-
49
- var p = {
50
- x: posx + s.positionLeft,
51
- y: posy + s.positionTop,
52
- w: $('#'+s.tooltipID).width(),
53
- h: $('#'+s.tooltipID).height()
54
- }
55
-
56
- var v = {
57
- x: $(window).scrollLeft(),
58
- y: $(window).scrollTop(),
59
- w: $(window).width() - 20,
60
- h: $(window).height() - 20
61
- };
62
-
63
- //don't go off screen
64
- if(p.y + p.h > v.y + v.h && p.x + p.w > v.x + v.w){
65
- p.x = (p.x - p.w) - 45;
66
- p.y = (p.y - p.h) - 45;
67
- }else if(p.x + p.w > v.x + v.w){
68
- p.x = p.x - (((p.x+p.w)-(v.x+v.w)) + 20);
69
- }else if(p.y + p.h > v.y + v.h){
70
- p.y = p.y - (((p.y+p.h)-(v.y+v.h)) + 20);
71
- }
72
-
73
- $('#'+s.tooltipID).css({'left':p.x + 'px','top':p.y + 'px'});
74
- }
75
-
76
- var showTooltip = function(){
77
- $('#tooltipLoader').remove();
78
-
79
- $('#'+s.tooltipID+' #tooltipContent').show();
80
-
81
-
82
- }
83
-
84
- var hideTooltip = function(valueOfThis){
85
- $('#'+s.tooltipID).fadeOut('fast').trigger("unload").remove();
86
- if($(valueOfThis).filter('[title]')){
87
- $(valueOfThis).attr('title',s.titleAttributeContent);
88
- }
89
- }
90
-
91
- var urlQueryToObject = function(s){
92
- var query = {};
93
- s.replace(/b([^&=]*)=([^&=]*)b/g, function (m, a, d) {
94
- if (typeof query[a] != 'undefined') {
95
- query[a] += ',' + d;
96
- } else {
97
- query[a] = d;
98
- }
99
- });
100
- return query;
101
- };
102
-
103
- return this.each(function(index){
104
-
105
- if(s.cancelClick){
106
- $(this).bind("click", function(){return false});
107
- }
108
-
109
- if($.fn.hoverIntent){
110
- $(this).hoverIntent({
111
- sensitivity:s.hoverIntent.sensitivity,
112
- interval:s.hoverIntent.interval,
113
- over:on,
114
- timeout:s.hoverIntent.timeout,
115
- out:off
116
- });
117
- }else{
118
- $(this).hover(on,off);
119
- }
120
- function on(e){
121
-
122
- $('body').append('<div id="'+s.tooltipID+'" style="background-repeat:no-repeat;background-image:url('+s.tooltipBGImage+');padding:'+s.tooltipPadding+'px;display:none;height:'+s.height+';width:'+s.width+';background-color:'+s.tooltipBGColor+';border:'+s.borderSize+'px solid '+s.borderColor+'; position:absolute;z-index:100000000000;"><div id="tooltipContent" style="display:none;"></div></div>');
123
-
124
- var $tt = $('#'+s.tooltipID);
125
- var $ttContent = $('#'+s.tooltipID+' #tooltipContent');
126
-
127
- if(s.loader && s.loaderImagePath != ''){
128
- $tt.append('<div id="tooltipLoader" style="width:'+s.loaderWidth+'px;height:'+s.loaderHeight+'px;"><img src="'+s.loaderImagePath+'" /></div>');
129
- }
130
-
131
- if($(this).attr('title')){
132
- s.titleAttributeContent = $(this).attr('title');
133
- $(this).attr('title','');
134
- }
135
-
136
- if($(this).is('input')){
137
- $(this).focus(function(){ hideTooltip(this); });
138
- }
139
-
140
- e.preventDefault();//stop
141
- positionTooltip(e);
142
-
143
- $tt.show();
144
-
145
- //get values from element clicked, or assume its passed as an option
146
- s.tooltipSourceID = $(this).attr('href') || s.tooltipSourceID;
147
- s.tooltipSourceURL = $(this).attr('href') || s.tooltipSourceURL;
148
-
149
- switch(s.tooltipSource){
150
- case 'attribute':/*/////////////////////////////// attribute //////////////////////////////////////////*/
151
- $ttContent.text(s.titleAttributeContent);
152
- showTooltip();
153
- break;
154
- case 'inline':/*/////////////////////////////// inline //////////////////////////////////////////*/
155
- $ttContent.html($(s.tooltipSourceID).children());
156
- $tt.unload(function(){// move elements back when you're finished
157
- $(s.tooltipSourceID).html($ttContent.children());
158
- });
159
- showTooltip();
160
- break;
161
- case 'ajax':/*/////////////////////////////// ajax //////////////////////////////////////////*/
162
-
163
- if(s.tooltipHTTPType == 'post'){
164
- var urlOnly, urlQueryObject;
165
- if(s.tooltipSourceURL.indexOf("?") !== -1){//has a query string
166
- urlOnly = s.windowSourceURL.substr(0, s.windowSourceURL.indexOf("?"));
167
- urlQueryObject = urlQueryToObject(s.tooltipSourceURL);
168
- }else{
169
- urlOnly = s.tooltipSourceURL;
170
- urlQueryObject = {};
171
- }
172
- $ttContent.load(urlOnly,urlQueryObject,function(){
173
- showTooltip();
174
- });
175
- }else{
176
- if(s.tooltipSourceURL.indexOf("?") == -1){ //no query string, so add one
177
- s.tooltipSourceURL += '?';
178
- }
179
- $ttContent.load(
180
- s.tooltipSourceURL + '&random=' + (new Date().getTime()),function(){
181
- showTooltip();
182
- });
183
- }
184
- break;
185
- };
186
-
187
- return false;
188
-
189
- };
190
-
191
-
192
- function off(e){
193
- hideTooltip(this);
194
- return false;
195
- };
196
-
197
- if(s.followMouse){
198
- $(this).bind("mousemove", function(e){
199
- positionTooltip(e);
200
- return false;
201
- });
202
- }
203
-
204
- });
205
- };
206
-
207
- })(jQuery);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
res/js/jquery.tooltip.min.js DELETED
@@ -1 +0,0 @@
1
- !function(t){t.fn.spTooltip=function(o){t.fn.spTooltip.defaultsSettings={attributeName:"title",borderColor:"#ccc",borderSize:"1",cancelClick:0,followMouse:1,height:"auto",hoverIntent:{sensitivity:7,interval:100,timeout:0},loader:0,loaderHeight:0,loaderImagePath:"",loaderWidth:0,positionTop:12,positionLeft:12,width:"auto",titleAttributeContent:"",tooltipBGColor:"#fff",tooltipBGImage:"none",tooltipHTTPType:"get",tooltipPadding:10,tooltipSource:"attribute",tooltipSourceID:"",tooltipSourceURL:"",tooltipID:"tooltip"};var e=t.extend({},t.fn.spTooltip.defaultsSettings,o||{}),i=function(o){o.preventDefault();var i=0,n=0;if(!o)o=window.event;o.pageX||o.pageY?(i=o.pageX,n=o.pageY):(o.clientX||o.clientY)&&(i=o.clientX+document.body.scrollLeft+document.documentElement.scrollLeft,n=o.clientY+document.body.scrollTop+document.documentElement.scrollTop);var l={x:i+e.positionLeft,y:n+e.positionTop,w:t("#"+e.tooltipID).width(),h:t("#"+e.tooltipID).height()},r={x:t(window).scrollLeft(),y:t(window).scrollTop(),w:t(window).width()-20,h:t(window).height()-20};l.y+l.h>r.y+r.h&&l.x+l.w>r.x+r.w?(l.x=l.x-l.w-45,l.y=l.y-l.h-45):l.x+l.w>r.x+r.w?l.x=l.x-(l.x+l.w-(r.x+r.w)+20):l.y+l.h>r.y+r.h&&(l.y=l.y-(l.y+l.h-(r.y+r.h)+20)),t("#"+e.tooltipID).css({left:l.x+"px",top:l.y+"px"})},n=function(){t("#tooltipLoader").remove(),t("#"+e.tooltipID+" #tooltipContent").show()},l=function(o){t("#"+e.tooltipID).fadeOut("fast").trigger("unload").remove(),t(o).filter("[title]")&&t(o).attr("title",e.titleAttributeContent)},r=function(t){var o={};return t.replace(/b([^&=]*)=([^&=]*)b/g,function(t,e,i){void 0!==o[e]?o[e]+=","+i:o[e]=i}),o};return this.each(function(o){function p(o){t("body").append('<div id="'+e.tooltipID+'" style="background-repeat:no-repeat;background-image:url('+e.tooltipBGImage+");padding:"+e.tooltipPadding+"px;display:none;height:"+e.height+";width:"+e.width+";background-color:"+e.tooltipBGColor+";border:"+e.borderSize+"px solid "+e.borderColor+'; position:absolute;z-index:100000000000;"><div id="tooltipContent" style="display:none;"></div></div>');var p=t("#"+e.tooltipID),a=t("#"+e.tooltipID+" #tooltipContent");switch(e.loader&&""!=e.loaderImagePath&&p.append('<div id="tooltipLoader" style="width:'+e.loaderWidth+"px;height:"+e.loaderHeight+'px;"><img src="'+e.loaderImagePath+'" /></div>'),t(this).attr("title")&&(e.titleAttributeContent=t(this).attr("title"),t(this).attr("title","")),t(this).is("input")&&t(this).focus(function(){l(this)}),o.preventDefault(),i(o),p.show(),e.tooltipSourceID=t(this).attr("href")||e.tooltipSourceID,e.tooltipSourceURL=t(this).attr("href")||e.tooltipSourceURL,e.tooltipSource){case"attribute":a.text(e.titleAttributeContent),n();break;case"inline":a.html(t(e.tooltipSourceID).children()),p.unload(function(){t(e.tooltipSourceID).html(a.children())}),n();break;case"ajax":if("post"==e.tooltipHTTPType){var d,u;-1!==e.tooltipSourceURL.indexOf("?")?(d=e.windowSourceURL.substr(0,e.windowSourceURL.indexOf("?")),u=r(e.tooltipSourceURL)):(d=e.tooltipSourceURL,u={}),a.load(d,u,function(){n()})}else-1==e.tooltipSourceURL.indexOf("?")&&(e.tooltipSourceURL+="?"),a.load(e.tooltipSourceURL+"&random="+(new Date).getTime(),function(){n()})}return!1}function a(t){return l(this),!1}e.cancelClick&&t(this).bind("click",function(){return!1}),t.fn.hoverIntent?t(this).hoverIntent({sensitivity:e.hoverIntent.sensitivity,interval:e.hoverIntent.interval,over:p,timeout:e.hoverIntent.timeout,out:a}):t(this).hover(p,a),e.followMouse&&t(this).bind("mousemove",function(t){return i(t),!1})})}}(jQuery);
 
res/js/screens/screen-media.js CHANGED
@@ -228,7 +228,8 @@ var ShortPixelScreen = function (MainScreen, processor)
228
  var id = data.media.id;
229
 
230
  var element = document.getElementById('sp-msg-' + id);
231
- element.outerHTML = data.media.itemView;
 
232
  }
233
  return false; // callback shouldn't do more, see processor.
234
  }
228
  var id = data.media.id;
229
 
230
  var element = document.getElementById('sp-msg-' + id);
231
+ if (element !== null) // Could be other page / not visible / whatever.
232
+ element.outerHTML = data.media.itemView;
233
  }
234
  return false; // callback shouldn't do more, see processor.
235
  }
res/js/shortpixel.js CHANGED
@@ -48,20 +48,6 @@ var ShortPixel = function() {
48
  jQuery('#request_key').on('click', jQuery.proxy(this.newApiKey, this));
49
  }
50
 
51
- if( ShortPixel.MEDIA_ALERT == 'todo' && jQuery('div.media-frame.mode-grid').length > 0) {
52
- //the media table is not in the list mode, alert the user
53
- jQuery('div.media-frame.mode-grid').before('<div id="short-pixel-media-alert" class="notice notice-warning"><p>'
54
- + SPstringFormat(_spTr.changeMLToListMode,'<a href="upload.php?mode=list" class="view-list"><span class="screen-reader-text">',' </span>',
55
- '</a><a class="alignright" href="javascript:ShortPixel.dismissMediaAlert();">','</a>')
56
- + '</p></div>');
57
- }
58
- //
59
- jQuery(window).on('beforeunload', function(){
60
- if(ShortPixel.bulkProcessor == true) {
61
- clearBulkProcessor();
62
- }
63
- });
64
-
65
  if (window.ShortPixelProcessor)
66
  {
67
  window.ShortPixelProcessor.Load(ShortPixel['HAS_QUOTA']);
@@ -279,8 +265,6 @@ var ShortPixel = function() {
279
  ShortPixel.adjustSettingsTabs();
280
  });
281
 
282
- // shortpixel.ui is the designation for settings and ui-related events not in processor realm.
283
- window.addEventListener('shortpixel.ui.settingsTabLoad', this.loadTabData.bind(this));
284
 
285
  jQuery("article.sp-tabs a.tab-link").on('click', function(e){
286
  var theID = jQuery(e.target).data("id");
@@ -351,62 +335,12 @@ var ShortPixel = function() {
351
  window.dispatchEvent(event);
352
 
353
  }
354
- /* if(typeof HS !== 'undefined' && typeof HS.beacon.suggest !== 'undefined' ){
355
- switch(tab){
356
- case "settings":
357
- beacon = shortpixel_suggestions_settings;
358
- break;
359
- case "adv-settings":
360
- beacon = shortpixel_suggestions_adv_settings;
361
- break;
362
- case "cloudflare":
363
- case "stats":
364
- beacon = shortpixel_suggestions_cloudflare;
365
- break;
366
- default:
367
- break;
368
- }
369
- HS.beacon.suggest(beacon);
370
- } */
371
- }
372
-
373
- // Newer function to load tab specific data, removing load from general init.
374
- function loadTabData(e)
375
- {
376
- var detail = e.detail;
377
- if (detail.tabName == 'tools')
378
- {
379
- this.loadToolsTabData();
380
 
381
- }
382
- }
383
-
384
- function loadToolsTabData()
385
- {
386
- /*var sizeText = document.querySelector('[data-tabfield="backupSize"]');
387
- if (sizeText.dataset.value == '')
388
- {
389
- var backupSize = this.getBackupSize(sizeText);
390
- } */
391
- }
392
 
393
  // Fixes the height of the current active tab.
394
  function adjustSettingsTabsHeight(){
395
- //sectionHeight = Math.max(sectionHeight, jQuery('section#tab-adv-settings .wp-shortpixel-options').height() + 20);
396
- // sectionHeight = Math.max(sectionHeight, jQuery('section#tab-resources .area1').height() + 60);
397
  jQuery('.wso.banner').css('opacity', 1);
398
- //jQuery('#shortpixel-settings-tabs section').css('height', sectionHeight);
399
- }
400
-
401
- function dismissMediaAlert() {
402
- var data = { action : 'shortpixel_dismiss_media_alert'};
403
- jQuery.get(ShortPixel.AJAX_URL, data, function(response) {
404
- data = JSON.parse(response);
405
- if(data["Status"] == 'success') {
406
- jQuery("#short-pixel-media-alert").hide();
407
- //console.log("dismissed");
408
- }
409
- });
410
  }
411
 
412
  function closeHelpPane() {
@@ -417,10 +351,7 @@ var ShortPixel = function() {
417
  jQuery('#shortpixel-hs-blind').remove();
418
  }
419
 
420
- function dismissHelpPane() {
421
- closeHelpPane();
422
- dismissShortPixelNotice('help');
423
- }
424
 
425
  function checkQuota() {
426
  var data = {
@@ -436,25 +367,6 @@ var ShortPixel = function() {
436
  });
437
  }
438
 
439
- function onBulkThumbsCheck(check) {
440
- if(check.checked) {
441
- jQuery("#with-thumbs").css('display', 'inherit');
442
- jQuery("#without-thumbs").css('display', 'none');
443
- } else {
444
- jQuery("#without-thumbs").css('display', 'inherit');
445
- jQuery("#with-thumbs").css('display', 'none');
446
- }
447
- }
448
-
449
- function successMsg(id, percent, type, thumbsCount, retinasCount) {
450
- return (percent > 0 ? "<div class='sp-column-info'>" + _spTr.reducedBy + " <strong><span class='percent'>" + percent + "%</span></strong> " : "")
451
- + (percent > 0 && percent < 5 ? "<br>" : '')
452
- + (percent < 5 ? _spTr.bonusProcessing : '')
453
- + (type.length > 0 ? " ("+type+")" : "")
454
- + (0 + thumbsCount > 0 ? "<br>" + SPstringFormat(_spTr.plusXthumbsOpt, thumbsCount) :"")
455
- + (0 + retinasCount > 0 ? "<br>" + SPstringFormat(_spTr.plusXretinasOpt, retinasCount) :"")
456
- + "</div>";
457
- }
458
 
459
  function percentDial(query, size) {
460
  jQuery(query).knob({
@@ -468,61 +380,11 @@ var ShortPixel = function() {
468
  });
469
  }
470
 
471
- function successActions(id, type, thumbsCount, thumbsTotal, backupEnabled, fileName) {
472
- if(backupEnabled == 1) {
473
 
474
- var successActions = jQuery('.sp-column-actions-template').clone();
475
 
476
- if(!successActions.length) return false;
477
 
478
- var otherTypes;
479
- if(type.length == 0) {
480
- otherTypes = ['lossy', 'lossless'];
481
- } else {
482
- otherTypes = ['lossy','glossy','lossless'].filter(function(el) {return !(el == type);});
483
- }
484
 
485
- successActions.html(successActions.html().replace(/__SP_ID__/g, id));
486
- if(fileName.substr(fileName.lastIndexOf('.') + 1).toLowerCase() == 'pdf') {
487
- jQuery('.sp-action-compare', successActions).remove();
488
- }
489
- if(thumbsCount == 0 && thumbsTotal > 0) {
490
- successActions.html(successActions.html().replace('__SP_THUMBS_TOTAL__', thumbsTotal));
491
- } else {
492
- jQuery('.sp-action-optimize-thumbs', successActions).remove();
493
- jQuery('.sp-dropbtn', successActions).removeClass('button-primary');
494
- }
495
- successActions.html(successActions.html().replace(/__SP_FIRST_TYPE__/g, otherTypes[0]));
496
- successActions.html(successActions.html().replace(/__SP_SECOND_TYPE__/g, otherTypes[1]));
497
- return successActions.html();
498
- }
499
- return "";
500
- }
501
 
502
- function otherMediaUpdateActions(id, actions) {
503
- id = id.substring(2);
504
- if(jQuery(".shortpixel-other-media").length) {
505
- var allActions = ['optimize', 'retry', 'restore','redo', 'quota', 'view'];
506
- for(var i=0, tot=allActions.length; i < tot; i++) {
507
- jQuery("#"+allActions[i]+"_"+id).css("display", "none");
508
- }
509
- for(var i=0, tot=actions.length; i < tot; i++) {
510
- jQuery("#"+actions[i]+"_"+id).css("display", "");
511
- }
512
- }
513
- }
514
-
515
- function retry(msg) {
516
- ShortPixel.retries++;
517
- if(isNaN(ShortPixel.retries)) ShortPixel.retries = 1;
518
- if(ShortPixel.retries < 6) {
519
- console.log("Invalid response from server (Error: " + msg + "). Retrying pass " + (ShortPixel.retries + 1) + "...");
520
- setBulkTimer(5000);
521
- } else {
522
- ShortPixel.bulkShowError(-1,"Invalid response from server received 6 times. Please retry later by reloading this page, or <a href='https://shortpixel.com/contact' target='_blank'>contact support</a>. (Error: " + msg + ")", "");
523
- console.log("Invalid response from server 6 times. Giving up.");
524
- }
525
- }
526
 
527
  function browseContent(browseData) {
528
  browseData.action = 'shortpixel_browse_content';
@@ -579,42 +441,9 @@ var ShortPixel = function() {
579
  jQuery('#pluginemail_spinner').addClass('is-active');
580
 
581
  jQuery('#shortpixel-form-request-key').submit();
582
- /* if (ShortPixel.isEmailValid(jQuery('#pluginemail').val())) {
583
- jQuery('#pluginemail-error').css('display', 'none');
584
- var browseData = { 'screen_action': 'request_new_api_key',
585
- 'action' : 'shortpixel_ajaxRequest',
586
- 'email': jQuery('#pluginemail').val(), nonce: ShortPixelConstants[0].nonce_ajaxrequest};
587
- jQuery.ajax({
588
- type: "POST",
589
- async: false,
590
- url: ShortPixel.AJAX_URL,
591
- data: browseData,
592
- success: function(response) {
593
- data = JSON.parse(response);
594
- if(data["Status"] == 'success') {
595
- event.preventDefault();
596
- window.location.reload();
597
- } else if(data["Status"] == 'invalid') {
598
- jQuery('#pluginemail-error').html('<b>' + data['Details'] + '</b>');
599
- jQuery('#pluginemail-error').css('display', '');
600
- jQuery('#pluginemail-info').css('display', 'none');
601
- event.preventDefault();
602
- } else {
603
- }
604
- }
605
- });
606
- jQuery('#request_key').removeAttr('onclick');
607
- } else {
608
- jQuery('#pluginemail-error').css('display', '');
609
- jQuery('#pluginemail-info').css('display', 'none');
610
- event.preventDefault();
611
- }
612
- jQuery('#request_key').removeClass('disabled');
613
- jQuery('#pluginemail_spinner').removeClass('is-active');
614
- */
615
  }
616
 
617
- // [TODO] Check where this function is called and if modal is working here.
618
  function proposeUpgrade() {
619
  //first open the popup window with the spinner
620
  jQuery("#shortPixelProposeUpgrade .sp-modal-body").addClass('sptw-modal-spinner');
@@ -648,19 +477,6 @@ var ShortPixel = function() {
648
  }
649
  }
650
 
651
- /* function includeUnlisted() {
652
- jQuery("#short-pixel-notice-unlisted").hide();
653
- jQuery("#optimizeUnlisted").prop('checked', true);
654
- var data = { action : 'shortpixel_dismiss_notice',
655
- notice_id: 'unlisted',
656
- notice_data: 'true'};
657
- jQuery.get(ShortPixel.AJAX_URL, data, function(response) {
658
- data = JSON.parse(response);
659
- if(data["Status"] == ShortPixel.STATUS_SUCCESS) {
660
- console.log("dismissed");
661
- }
662
- });
663
- } */
664
  function initFolderSelector() {
665
  jQuery(".select-folder-button").on('click', function(){
666
  jQuery(".sp-folder-picker-shade").fadeIn(100); //.css("display", "block");
@@ -715,66 +531,7 @@ var ShortPixel = function() {
715
  });
716
  }
717
 
718
- function bulkShowLengthyMsg(id, fileName, customLink){
719
- var notice = jQuery(".bulk-notice-msg.bulk-lengthy");
720
- if(notice.length == 0) return;
721
- var link = jQuery("a", notice);
722
- link.text(fileName);
723
- if(customLink) {
724
- link.attr("href", customLink);
725
- } else {
726
- link.attr("href", link.data("href").replace("__ID__", id));
727
- }
728
-
729
- notice.css("display", "block");
730
- }
731
 
732
- function bulkHideLengthyMsg(){
733
- jQuery(".bulk-notice-msg.bulk-lengthy").css("display", "none");
734
- }
735
-
736
- function bulkShowMaintenanceMsg(type){
737
- var notice = jQuery(".bulk-notice-msg.bulk-" + type);
738
- if(notice.length == 0) return;
739
- notice.css("display", "block");
740
- }
741
-
742
- function bulkHideMaintenanceMsg(type){
743
- jQuery(".bulk-notice-msg.bulk-" + type).css("display", "none");
744
- }
745
-
746
- function bulkShowError(id, msg, fileName, customLink) {
747
- var noticeTpl = jQuery("#bulk-error-template");
748
- if(noticeTpl.length == 0) return;
749
- var notice = noticeTpl.clone();
750
- notice.attr("id", "bulk-error-" + id);
751
- if(id == -1) {
752
- jQuery("span.sp-err-title", notice).remove();
753
- notice.addClass("bulk-error-fatal");
754
- } else {
755
- jQuery("img", notice).remove();
756
- jQuery("#bulk-error-" . id).remove();
757
- }
758
- jQuery("span.sp-err-content", notice).html(msg);
759
- var link = jQuery("a.sp-post-link", notice);
760
- if(customLink) {
761
- link.attr("href", customLink);
762
- } else {
763
- link.attr("href", link.attr("href").replace("__ID__", id));
764
- }
765
- link.text(fileName);
766
- noticeTpl.after(notice);
767
- notice.css("display", "block");
768
- }
769
-
770
- function confirmBulkAction(type, e) {
771
- if(!confirm(_spTr['confirmBulk' + type])) {
772
- e.stopPropagation();
773
- e.preventDefault();
774
- return false;
775
- }
776
- return true;
777
- }
778
 
779
  // used in bulk restore all interface
780
  function checkRandomAnswer(e)
@@ -796,15 +553,6 @@ var ShortPixel = function() {
796
 
797
  }
798
 
799
- function removeBulkMsg(me) {
800
- jQuery(me).parent().parent().remove();
801
- }
802
-
803
- function isCustomImageId(id) {
804
- return id.substring(0,2) == "C-";
805
- }
806
-
807
-
808
 
809
  function openImageMenu(e) {
810
  e.preventDefault();
@@ -918,9 +666,7 @@ var ShortPixel = function() {
918
  }
919
 
920
  function closeComparerPopup(e) {
921
- // jQuery("#spUploadCompareSideBySide").parent().css("display", 'none');
922
- // jQuery("#spUploadCompareSideBySide").hide();
923
- //jQuery("#spUploadCompare").hide();
924
  e.data.modal.addClass('shortpixel-hide');
925
  jQuery('.sp-modal-shade').hide();
926
  jQuery(document).unbind('keyup.sp_modal_active');
@@ -937,24 +683,7 @@ var ShortPixel = function() {
937
  return url.replace(parser.protocol + '//' + parser.hostname, parser.protocol + '//' + parser.hostname.split('.').map(function(part) {return sp_punycode.toASCII(part)}).join('.'));
938
  }
939
 
940
- function optInHelp(e,toggle)
941
- {
942
- var toggle = e.currentTarget.toggleParam;
943
 
944
- var data = {
945
- action: 'shortpixel_helpscoutOptin',
946
- toggle: toggle,
947
- };
948
- var $target = jQuery(e.target);
949
-
950
- jQuery.post(ShortPixel.AJAX_URL, data, function(response) {
951
- //data = JSON.parse(response);
952
- if(response.Status == 'success') {
953
- $target.parents('.shortpixel.notice').fadeOut();
954
- //console.log("dismissed");
955
- }
956
- });
957
- }
958
 
959
  return {
960
  init : init,
@@ -965,24 +694,15 @@ var ShortPixel = function() {
965
  validateKey : validateKey,
966
  enableResize : enableResize,
967
  setupGeneralTab : setupGeneralTab,
968
- loadTabData : loadTabData,
969
- loadToolsTabData : loadToolsTabData,
970
  apiKeyChanged : apiKeyChanged,
971
  setupAdvancedTab : setupAdvancedTab,
972
  checkThumbsUpdTotal : checkThumbsUpdTotal,
973
  initSettings : initSettings,
974
  switchSettingsTab : switchSettingsTab,
975
  adjustSettingsTabs : adjustSettingsTabsHeight,
976
- onBulkThumbsCheck : onBulkThumbsCheck,
977
- dismissMediaAlert : dismissMediaAlert,
978
  closeHelpPane : closeHelpPane,
979
- dismissHelpPane : dismissHelpPane,
980
  checkQuota : checkQuota,
981
  percentDial : percentDial,
982
- successMsg : successMsg,
983
- successActions : successActions,
984
- otherMediaUpdateActions: otherMediaUpdateActions,
985
- retry : retry,
986
  initFolderSelector : initFolderSelector,
987
  browseContent : browseContent,
988
  getBackupSize : getBackupSize,
@@ -990,15 +710,7 @@ var ShortPixel = function() {
990
  proposeUpgrade : proposeUpgrade,
991
  closeProposeUpgrade : closeProposeUpgrade,
992
  // includeUnlisted : includeUnlisted,
993
- bulkShowLengthyMsg : bulkShowLengthyMsg,
994
- bulkHideLengthyMsg : bulkHideLengthyMsg,
995
- bulkShowMaintenanceMsg : bulkShowMaintenanceMsg,
996
- bulkHideMaintenanceMsg : bulkHideMaintenanceMsg,
997
- bulkShowError : bulkShowError,
998
- confirmBulkAction : confirmBulkAction,
999
  checkRandomAnswer : checkRandomAnswer,
1000
- removeBulkMsg : removeBulkMsg,
1001
- isCustomImageId : isCustomImageId,
1002
  // recheckQuota : recheckQuota,
1003
  openImageMenu : openImageMenu,
1004
  menuCloseEvent : false,
@@ -1019,507 +731,9 @@ var ShortPixel = function() {
1019
  toRefresh : false,
1020
  resizeSizesAlert: false,
1021
  returnedStatusSearching: 0, // How often this status has come back in a row from server.
1022
- optInHelp: optInHelp, // Optin for Helpscout cs
1023
- }
1024
- }(); // End of ShortPixel
1025
-
1026
- function showToolBarAlert($status, $message, id) {
1027
- var robo = jQuery("li.shortpixel-toolbar-processing");
1028
-
1029
- switch($status) {
1030
- case ShortPixel.STATUS_QUOTA_EXCEEDED:
1031
- if( window.location.href.search("wp-short-pixel-bulk") > 0
1032
- && jQuery(".sp-quota-exceeded-alert").length == 0) { //if we're in bulk and the alert is not displayed reload to see all options
1033
-
1034
- return;
1035
- }
1036
- robo.addClass("shortpixel-alert");
1037
- robo.addClass("shortpixel-quota-exceeded");
1038
- jQuery("a", robo).attr("href", "options-general.php?page=wp-shortpixel-settings");
1039
- //jQuery("a", robo).attr("target", "_blank");
1040
- //jQuery("a div", robo).attr("title", "ShortPixel quota exceeded. Click to top-up");
1041
- jQuery("a div", robo).attr("title", "ShortPixel quota exceeded. Click for details.");
1042
- break;
1043
- case ShortPixel.STATUS_SKIP:
1044
- case ShortPixel.STATUS_FAIL:
1045
- robo.addClass("shortpixel-alert shortpixel-processing");
1046
- jQuery("a div", robo).attr("title", $message);
1047
- if(typeof id !== 'undefined') {
1048
- jQuery("a", robo).attr("href", "post.php?post=" + id + "&action=edit");
1049
- }
1050
- break;
1051
- case ShortPixel.STATUS_NO_KEY:
1052
- robo.addClass("shortpixel-alert");
1053
- robo.addClass("shortpixel-quota-exceeded");
1054
- jQuery("a", robo).attr("href", "options-general.php?page=wp-shortpixel-settings");//"http://shortpixel.com/wp-apikey");
1055
- //jQuery("a", robo).attr("target", "_blank");
1056
- jQuery("a div", robo).attr("title", "Get API Key");
1057
- break;
1058
- case ShortPixel.STATUS_SUCCESS:
1059
- case ShortPixel.STATUS_RETRY:
1060
- robo.addClass("shortpixel-processing");
1061
- robo.removeClass("shortpixel-alert");
1062
- jQuery("a", robo).removeAttr("target");
1063
- jQuery("a", robo).attr("href", jQuery("a img", robo).attr("success-url"));
1064
- }
1065
- robo.removeClass("shortpixel-hide");
1066
- }
1067
- function hideToolBarAlert (status) {
1068
- var $toolbar = jQuery("li.shortpixel-toolbar-processing.shortpixel-processing");
1069
-
1070
- // When Queue is empty, but we have errors, don't hide the toolbar.
1071
- if (ShortPixel.STATUS_EMPTY_QUEUE == status)
1072
- {
1073
- if ($toolbar.hasClass("shortpixel-alert") || $toolbar.hasClass("shortpixel-quota-exceeded") )
1074
- {
1075
- return;
1076
- }
1077
- }
1078
- $toolbar.addClass("shortpixel-hide");
1079
- }
1080
-
1081
- function hideQuotaExceededToolBarAlert () {
1082
- jQuery("li.shortpixel-toolbar-processing.shortpixel-quota-exceeded").addClass("shortpixel-hide");
1083
- }
1084
-
1085
- function checkQuotaExceededAlert() {
1086
- if(typeof shortPixelQuotaExceeded != 'undefined') {
1087
- if(shortPixelQuotaExceeded == 1) {
1088
- showToolBarAlert(ShortPixel.STATUS_QUOTA_EXCEEDED);
1089
- } else {
1090
- hideQuotaExceededToolBarAlert();
1091
- }
1092
- }
1093
- }
1094
- /**
1095
- * JavaScript image processing - this method gets executed on every footer load and afterwards
1096
- * calls itself until receives an Empty queue message
1097
- */
1098
- function checkBulkProgress() {
1099
- //the replace stands for malformed urls on some sites, like wp-admin//upload.php which are accepted by the browser.
1100
- //using a replacer function to avoid replacing the first occurence (https:// ...)
1101
- var replacer = function(match) {
1102
- if(!first) {
1103
- first = true;
1104
- return match;
1105
- }
1106
- return '/';
1107
- };
1108
-
1109
- var first = false; //arm replacer
1110
- var url = window.location.href.toLowerCase().replace(/\/\//g , replacer);
1111
-
1112
- first = false; //rearm replacer
1113
- var adminUrl = ShortPixel.WP_ADMIN_URL.toLowerCase().replace(/\/\//g , replacer);
1114
- //handle possible Punycode domain names.
1115
- if(url.search(adminUrl) < 0) {
1116
- url = ShortPixel.convertPunycode(url);
1117
- adminUrl = ShortPixel.convertPunycode(adminUrl);
1118
- }
1119
-
1120
- /* NO. If it shouldn't go, this JS file shouldn't load.
1121
- if( url.search(adminUrl + "upload.php") < 0
1122
- && url.search(adminUrl + "edit.php") < 0
1123
- && url.search(adminUrl + "edit-tags.php") < 0
1124
- && url.search(adminUrl + "post-new.php") < 0
1125
- && url.search(adminUrl + "post.php") < 0
1126
- && url.search("page=nggallery-manage-gallery") < 0
1127
- && (ShortPixel.FRONT_BOOTSTRAP == 0 || url.search(adminUrl) == 0)
1128
- ) {
1129
- hideToolBarAlert();
1130
- return;
1131
- } */
1132
-
1133
- //if i'm the bulk processor and i'm not the bulk page and a bulk page comes around, leave the bulk processor role
1134
- if(ShortPixel.bulkProcessor == true && window.location.href.search("wp-short-pixel-bulk") < 0
1135
- && typeof localStorage.bulkPage !== 'undefined' && localStorage.bulkPage > 0) {
1136
- ShortPixel.bulkProcessor = false;
1137
- }
1138
-
1139
- //if i'm the bulk page, steal the bulk processor
1140
- if( window.location.href.search("wp-short-pixel-bulk") >= 0 ) {
1141
- ShortPixel.bulkProcessor = true;
1142
- localStorage.bulkTime = Date.now();
1143
- localStorage.bulkPage = 1;
1144
- ShortPixel.BULK_SECRET = false;
1145
- }
1146
 
1147
- if (ShortPixel.BULK_SECRET !== false)
1148
- {
1149
- if (ShortPixel.BULK_SECRET != localStorage.bulkSecret)
1150
- {
1151
- // console.log('Cancelled Processing. Bulk Processor in use');
1152
- clearBulkProcessor();
1153
- jQuery("li.shortpixel-toolbar-processing").removeClass("shortpixel-processing");
1154
- jQuery("li.shortpixel-toolbar-processing").addClass("shortpixel-hide");
1155
- return;
1156
- }
1157
- }
1158
-
1159
- //if I'm not the bulk processor, check every 20 sec. if the bulk processor is running, otherwise take the role
1160
- if(ShortPixel.bulkProcessor == true || typeof localStorage.bulkTime == 'undefined' || Date.now() - localStorage.bulkTime > 10000) {
1161
- ShortPixel.bulkProcessor = true;
1162
- localStorage.bulkPage = (window.location.href.search("wp-short-pixel-bulk") >= 0 ? 1 : 0);
1163
- localStorage.bulkTime = Date.now();
1164
- if (localStorage.getItem('bulkSecret') == null)
1165
- localStorage.bulkSecret = Math.random().toString(36).substring(7);
1166
-
1167
- checkBulkProcessingCallApi();
1168
- } else {
1169
- setBulkTimer(20000);
1170
  }
1171
- }
1172
-
1173
- var bulkTimer; // scope
1174
- function setBulkTimer(time)
1175
- {
1176
- window.clearTimeout(bulkTimer);
1177
- //console.log('Clearing TimeOut');
1178
-
1179
- if (time > 0)
1180
- {
1181
- bulkTimer = window.setTimeout(checkBulkProgress, time);
1182
- //console.log('Set Timeout ' + time + ' ms');
1183
- }
1184
- }
1185
-
1186
- function checkBulkProcessingCallApi(){
1187
- // console.log('CheckBulkProcessingAPI');
1188
- var data = { 'action': 'shortpixel_image_processing', 'bulk-secret': localStorage.bulkSecret };
1189
- // since WP 2.8 ajaxurl is always defined in the admin header and points to admin-ajax.php
1190
- jQuery.ajax({
1191
- type: "POST",
1192
- url: ShortPixel.AJAX_URL, //formerly ajaxurl , but changed it because it's not available in the front-end and now we have an option to run in the front-end
1193
- data: data,
1194
- success: function(response)
1195
- {
1196
- if(response.length > 0) {
1197
- var data = null;
1198
- try {
1199
- var data = JSON.parse(response);
1200
- } catch (e) {
1201
- ShortPixel.retry(e.message);
1202
- return;
1203
- }
1204
- ShortPixel.retries = 0;
1205
-
1206
- var id = data["ImageID"];
1207
-
1208
- var isBulkPage = (jQuery("div.short-pixel-bulk-page").length > 0);
1209
-
1210
- if (data["Status"] && data["Status"] != ShortPixel.STATUS_SEARCHING)
1211
- {
1212
- if (ShortPixel.returnedStatusSearching >= 2)
1213
- jQuery('.bulk-notice-msg.bulk-searching').hide();
1214
-
1215
- ShortPixel.returnedStatusSearching = 0;
1216
- }
1217
-
1218
-
1219
- switch (data["Status"]) {
1220
- case ShortPixel.STATUS_NO_KEY:
1221
- setCellMessage(id, data["Message"], "<a class='button button-smaller button-primary' href=\"https://shortpixel.com/wp-apikey"
1222
- + "\" target=\"_blank\">" + _spTr.getApiKey + "</a>");
1223
- showToolBarAlert(ShortPixel.STATUS_NO_KEY);
1224
- break;
1225
- case ShortPixel.STATUS_QUOTA_EXCEEDED:
1226
- setCellMessage(id, data["Message"], "<a class='button button-smaller button-primary' href=\"https://shortpixel.com/login/"
1227
- + "\" target=\"_blank\">" + _spTr.extendQuota + "</a>"
1228
- + "<a class='button button-smaller' href='javascript:ShortPixel.checkQuota()'>" + _spTr.check__Quota + "</a>");
1229
- showToolBarAlert(ShortPixel.STATUS_QUOTA_EXCEEDED);
1230
- if(data['Stop'] == false) { //there are other items in the priority list, maybe processed, try those
1231
- setBulkTimer(5000);
1232
- }
1233
- ShortPixel.otherMediaUpdateActions(id, ['quota','view']);
1234
- break;
1235
- case ShortPixel.STATUS_FAIL:
1236
- setCellMessage(id, data["Message"], "<a class='button button-smaller button-primary' href=\"javascript:manualOptimization('" + id + "', true)\">"
1237
- + _spTr.retry + "</a>");
1238
- showToolBarAlert(ShortPixel.STATUS_FAIL, data["Message"], id);
1239
- if(isBulkPage) {
1240
- ShortPixel.bulkShowError(id, data["Message"], data["Filename"], data["CustomImageLink"]);
1241
- if(data["BulkPercent"]) {
1242
- progressUpdate(data["BulkPercent"], data["BulkMsg"]);
1243
- }
1244
- ShortPixel.otherMediaUpdateActions(id, ['retry','view']);
1245
- }
1246
- console.log(data["Message"]);
1247
- setBulkTimer(5000);
1248
- break;
1249
- case ShortPixel.STATUS_EMPTY_QUEUE:
1250
- console.log(data["Message"]);
1251
- clearBulkProcessor(); //nothing to process, leave the role. Next page load will check again
1252
-
1253
- hideToolBarAlert(data["Status"]);
1254
- var progress = jQuery("#bulk-progress");
1255
- if(isBulkPage && progress.length && data["BulkStatus"] != '2') {
1256
- progressUpdate(100, "Bulk finished!");
1257
- jQuery("a.bulk-cancel").attr("disabled", "disabled");
1258
- hideSlider();
1259
- //showStats();
1260
-
1261
- setTimeout(function(){
1262
- window.location.reload();
1263
- }, 3000);
1264
- }
1265
- break;
1266
- case ShortPixel.STATUS_SUCCESS:
1267
- if(isBulkPage) {
1268
- ShortPixel.bulkHideLengthyMsg();
1269
- ShortPixel.bulkHideMaintenanceMsg();
1270
- }
1271
- var percent = data["PercentImprovement"];
1272
-
1273
- showToolBarAlert(ShortPixel.STATUS_SUCCESS, "");
1274
- //for now, until 4.1
1275
- var successActions = ShortPixel.isCustomImageId(id)
1276
- ? ""
1277
- : ShortPixel.successActions(id, data["Type"], data['ThumbsCount'], data['ThumbsTotal'], data["BackupEnabled"], data['Filename']);
1278
-
1279
- // [BS] Set success message to Box.
1280
- setCellMessage(id, ShortPixel.successMsg(id, percent, data["Type"], data['ThumbsCount'], data['RetinasCount']), successActions);
1281
-
1282
- // [BS] Replace fileName in Media Library Row to return fileName.
1283
- if (jQuery('#post-' + id).length > 0)
1284
- jQuery('#post-' + id).find('.filename').text(data['Filename']);
1285
-
1286
- // [BS] Replace filename if in media item edit view
1287
- if (jQuery('.misc-pub-filename strong').length > 0)
1288
- jQuery('.misc-pub-filename strong').text(data['Filename']);
1289
-
1290
- // [BS] Only update date on Custom Media Page.
1291
- if (ShortPixel.isCustomImageId(id) && data['TsOptimized'] && data['TsOptimized'].length > 0)
1292
- {
1293
- var row = jQuery('.list-overview .item-' + id);
1294
-
1295
- jQuery(row).children('.date').text(data['TsOptimized']);
1296
- jQuery(row).find('.row-actions .action-optimize').remove(); // gets complicated
1297
- }
1298
-
1299
-
1300
- var actions = jQuery(['restore', 'view', 'redolossy', 'redoglossy', 'redolossless']).not(['redo'+data["Type"]]).get();
1301
- ShortPixel.otherMediaUpdateActions(id, actions);
1302
- var animator = new PercentageAnimator("#sp-msg-" + id + " span.percent", percent);
1303
- animator.animate(percent);
1304
- if(isBulkPage && typeof data["Thumb"] !== 'undefined') { // && data["PercentImprovement"] > 0) {
1305
- if(data["BulkPercent"]) {
1306
- progressUpdate(data["BulkPercent"], data["BulkMsg"]);
1307
- }
1308
- if(data["Thumb"].length > 0){
1309
- sliderUpdate(id, data["Thumb"], data["BkThumb"], data["PercentImprovement"], data["Filename"]);
1310
- if(typeof data["AverageCompression"] !== 'undefined' && 0 + data["AverageCompression"] > 0){
1311
- jQuery("#sp-avg-optimization").html('<input type="text" class="dial" value="' + Math.round(data["AverageCompression"]) + '"/>');
1312
- ShortPixel.percentDial("#sp-avg-optimization .dial", 60);
1313
- }
1314
- }
1315
- }
1316
-
1317
- console.log('Server response: ' + response);
1318
- if(isBulkPage && typeof data["BulkPercent"] !== 'undefined') {
1319
- progressUpdate(data["BulkPercent"], data["BulkMsg"]);
1320
- }
1321
- setBulkTimer(5000);
1322
- break;
1323
-
1324
- case ShortPixel.STATUS_SKIP:
1325
- if(data["Silent"] !== 1) {
1326
- ShortPixel.bulkShowError(id, data["Message"], data["Filename"], data["CustomImageLink"]);
1327
- }
1328
- //fall through
1329
- case ShortPixel.STATUS_ERROR: //for error and skip also we retry
1330
- if(typeof data["Message"] !== 'undefined') {
1331
- showToolBarAlert(ShortPixel.STATUS_SKIP, data["Message"] + ' Image ID: ' + id);
1332
- setCellMessage(id, data["Message"], "");
1333
- }
1334
- ShortPixel.otherMediaUpdateActions(id, ['retry','view']);
1335
- //fall through
1336
- case ShortPixel.STATUS_RETRY:
1337
- console.log('Server response: ' + response);
1338
- showToolBarAlert(ShortPixel.STATUS_RETRY, "");
1339
- if(isBulkPage && typeof data["BulkPercent"] !== 'undefined') {
1340
- progressUpdate(data["BulkPercent"], data["BulkMsg"]);
1341
- }
1342
- if(isBulkPage && data["Count"] > 3) {
1343
- ShortPixel.bulkShowLengthyMsg(id, data["Filename"], data["CustomImageLink"]);
1344
- }
1345
- setBulkTimer(5000);
1346
- break;
1347
- case ShortPixel.STATUS_SEARCHING:
1348
- console.log('Server response: ' + response);
1349
- ShortPixel.returnedStatusSearching++;
1350
- if (ShortPixel.returnedStatusSearching >= 2)
1351
- {
1352
- jQuery('.bulk-notice-msg.bulk-searching').show();
1353
- }
1354
- setBulkTimer(2500);
1355
- break;
1356
- case ShortPixel.STATUS_MAINTENANCE:
1357
- ShortPixel.bulkShowMaintenanceMsg('maintenance');
1358
- setBulkTimer(60000);
1359
- break;
1360
- case ShortPixel.STATUS_QUEUE_FULL:
1361
- ShortPixel.bulkShowMaintenanceMsg('queue-full');
1362
- setBulkTimer(60000);
1363
- break;
1364
- default:
1365
- ShortPixel.retry("Unknown status " + data["Status"] + ". Retrying...");
1366
- break;
1367
- } // switch
1368
-
1369
- // If custom, if has ID ( returned something about image )
1370
- if (typeof id != 'undefined' && ShortPixel.isCustomImageId(id))
1371
- {
1372
- var row = jQuery('.list-overview .item-' + id);
1373
- jQuery(row).find('.row-actions .action-optimize').remove(); // gets complicated
1374
- if (data['actions'])
1375
- {
1376
- jQuery(row).children('.actions').html(data['actions']);
1377
- }
1378
- }
1379
-
1380
- }
1381
- },
1382
- error: function(response){
1383
- ShortPixel.retry(response.statusText);
1384
- }
1385
- });
1386
- }
1387
-
1388
- function clearBulkProcessor(){
1389
- ShortPixel.bulkProcessor = false; //nothing to process, leave the role. Next page load will check again
1390
- localStorage.bulkTime = Date.now();
1391
- setBulkTimer(0); // stop checking.
1392
-
1393
- if(window.location.href.search("wp-short-pixel-bulk") >= 0) {
1394
- localStorage.bulkPage = 0;
1395
- }
1396
- }
1397
-
1398
- function setCellMessage(id, message, actions){
1399
- var msg = jQuery("#sp-msg-" + id);
1400
- if(msg.length > 0) {
1401
- msg.html("<div class='sp-column-actions'>" + actions + "</div>"
1402
- + "<div class='sp-column-info'>" + message + "</div>");
1403
- msg.css("color", "");
1404
- }
1405
- msg = jQuery("#sp-cust-msg-" + id);
1406
- if(msg.length > 0) {
1407
- msg.html("<div class='sp-column-info'>" + message + "</div>");
1408
- }
1409
- }
1410
-
1411
- function manualOptimization(id, cleanup) {
1412
- setCellMessage(id, "<img src='" + ShortPixel.WP_PLUGIN_URL + "/res/img/loading.gif' alt='" + _spTr.loading + "' class='sp-loading-small'>Image waiting to be processed", "");
1413
- jQuery("li.shortpixel-toolbar-processing").removeClass("shortpixel-hide");
1414
- jQuery("li.shortpixel-toolbar-processing").removeClass("shortpixel-alert");
1415
- jQuery("li.shortpixel-toolbar-processing").addClass("shortpixel-processing");
1416
- var data = { action : 'shortpixel_manual_optimization',
1417
- id: id, type: 'media'};
1418
- jQuery.ajax({
1419
- type: "POST",
1420
- url: ShortPixel.AJAX_URL, //formerly ajaxurl , but changed it because it's not available in the front-end and now we have an option to run in the front-end
1421
- data: data,
1422
- success: function(response) {
1423
- /// var resp = JSON.parse(response);
1424
- /*if (response.responses)
1425
- {
1426
- jQuery.each(response.responses, function (index, message)
1427
- {
1428
- setCellMessage(id, message.message);
1429
- });
1430
- } */
1431
-
1432
- if(response.status > 0) {
1433
- //TODO - when calling several manual optimizations, the checkBulkProgress gets scheduled several times so several loops run in || - make only one.
1434
- setBulkTimer(2000);
1435
- ShortPixel.BULK_SECRET = false;
1436
- } else {
1437
- setCellMessage(id, typeof resp["message"] !== "undefined" ? resp["message"] : _spTr.thisContentNotProcessable, "");
1438
- }
1439
- //aici e aici
1440
- },
1441
- error: function(response){
1442
- //if error, give the ajax processor a chance to maybe find out why.
1443
- data.action = 'shortpixel_check_status'
1444
- jQuery.ajax({
1445
- type: "GET",
1446
- url: ShortPixel.AJAX_URL, //formerly ajaxurl , but changed it because it's not available in the front-end and now we have an option to run in the front-end
1447
- data: data,
1448
- success: function (response) {
1449
- var resp = JSON.parse(response);
1450
- if (resp["Status"] !== ShortPixel.STATUS_SUCCESS) {
1451
- setCellMessage(id, typeof resp["Message"] !== "undefined" ? resp["Message"] : _spTr.thisContentNotProcessable, "");
1452
- }
1453
- //aici e aici
1454
- }
1455
- });
1456
- }
1457
- });
1458
- }
1459
-
1460
- function reoptimize(id, type) {
1461
- setCellMessage(id, "<img src='" + ShortPixel.WP_PLUGIN_URL + "/res/img/loading.gif' alt='" + _spTr.loading + "' class='sp-loading-small'>Image waiting to be reprocessed", "");
1462
- jQuery("li.shortpixel-toolbar-processing").removeClass("shortpixel-hide");
1463
- jQuery("li.shortpixel-toolbar-processing").addClass("shortpixel-processing");
1464
- var data = { action : 'shortpixel_redo',
1465
- attachment_ID: id,
1466
- type: type};
1467
- jQuery.get(ShortPixel.AJAX_URL, data, function(response) {
1468
- data = JSON.parse(response);
1469
- if(data["Status"] == ShortPixel.STATUS_SUCCESS) {
1470
- setBulkTimer(2000);
1471
- ShortPixel.BULK_SECRET = false;
1472
- } else {
1473
- $msg = typeof data["Message"] !== "undefined" ? data["Message"] : _spTr.thisContentNotProcessable;
1474
- setCellMessage(id, $msg, "");
1475
- showToolBarAlert(ShortPixel.STATUS_FAIL, $msg);
1476
- }
1477
- });
1478
- }
1479
-
1480
- function optimizeThumbs(id) {
1481
- setCellMessage(id, "<img src='" + ShortPixel.WP_PLUGIN_URL + "/res/img/loading.gif' alt='" + _spTr.loading + "' class='sp-loading-small'>" + _spTr.imageWaitOptThumbs, "");
1482
- jQuery("li.shortpixel-toolbar-processing").removeClass("shortpixel-hide");
1483
- jQuery("li.shortpixel-toolbar-processing").addClass("shortpixel-processing");
1484
- var data = { action : 'shortpixel_optimize_thumbs',
1485
- attachment_ID: id};
1486
- jQuery.get(ShortPixel.AJAX_URL, data, function(response) {
1487
- data = JSON.parse(response);
1488
- if(data["Status"] == ShortPixel.STATUS_SUCCESS) {
1489
- setBulkTimer(2000);
1490
- ShortPixel.BULK_SECRET = false;
1491
- } else {
1492
- setCellMessage(id, typeof data["Message"] !== "undefined" ? data["Message"] : _spTr.thisContentNotProcessable, "");
1493
- }
1494
- });
1495
- }
1496
-
1497
- /* @todo Must go, still in use in some parts */
1498
- function dismissShortPixelNotice(id) {
1499
- jQuery("#short-pixel-notice-" + id).hide();
1500
- var data = { action : 'shortpixel_dismiss_notice',
1501
- notice_id: id};
1502
- jQuery.get(ShortPixel.AJAX_URL, data, function(response) {
1503
- data = JSON.parse(response);
1504
- if(data["Status"] == ShortPixel.STATUS_SUCCESS) {
1505
- console.log("dismissed");
1506
- }
1507
- });
1508
- }
1509
-
1510
- function dismissFileError() {
1511
- jQuery('.shortpixel-alert').hide();
1512
- var data = { action : 'shortpixel_dismissFileError'
1513
- };
1514
- jQuery.get(ShortPixel.AJAX_URL, data, function(response) {
1515
- data = JSON.parse(response);
1516
- if(data["Status"] == ShortPixel.STATUS_SUCCESS) {
1517
- console.log("dismissed");
1518
- }
1519
- });
1520
- }
1521
-
1522
-
1523
 
1524
  // first is string to replace, rest are arguments.
1525
  function SPstringFormat() {
48
  jQuery('#request_key').on('click', jQuery.proxy(this.newApiKey, this));
49
  }
50
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
51
  if (window.ShortPixelProcessor)
52
  {
53
  window.ShortPixelProcessor.Load(ShortPixel['HAS_QUOTA']);
265
  ShortPixel.adjustSettingsTabs();
266
  });
267
 
 
 
268
 
269
  jQuery("article.sp-tabs a.tab-link").on('click', function(e){
270
  var theID = jQuery(e.target).data("id");
335
  window.dispatchEvent(event);
336
 
337
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
338
 
339
+ }
 
 
 
 
 
 
 
 
 
 
340
 
341
  // Fixes the height of the current active tab.
342
  function adjustSettingsTabsHeight(){
 
 
343
  jQuery('.wso.banner').css('opacity', 1);
 
 
 
 
 
 
 
 
 
 
 
 
344
  }
345
 
346
  function closeHelpPane() {
351
  jQuery('#shortpixel-hs-blind').remove();
352
  }
353
 
354
+
 
 
 
355
 
356
  function checkQuota() {
357
  var data = {
367
  });
368
  }
369
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
370
 
371
  function percentDial(query, size) {
372
  jQuery(query).knob({
380
  });
381
  }
382
 
 
 
383
 
 
384
 
 
385
 
 
 
 
 
 
 
386
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
387
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
388
 
389
  function browseContent(browseData) {
390
  browseData.action = 'shortpixel_browse_content';
441
  jQuery('#pluginemail_spinner').addClass('is-active');
442
 
443
  jQuery('#shortpixel-form-request-key').submit();
444
+
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
445
  }
446
 
 
447
  function proposeUpgrade() {
448
  //first open the popup window with the spinner
449
  jQuery("#shortPixelProposeUpgrade .sp-modal-body").addClass('sptw-modal-spinner');
477
  }
478
  }
479
 
 
 
 
 
 
 
 
 
 
 
 
 
 
480
  function initFolderSelector() {
481
  jQuery(".select-folder-button").on('click', function(){
482
  jQuery(".sp-folder-picker-shade").fadeIn(100); //.css("display", "block");
531
  });
532
  }
533
 
 
 
 
 
 
 
 
 
 
 
 
 
 
534
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
535
 
536
  // used in bulk restore all interface
537
  function checkRandomAnswer(e)
553
 
554
  }
555
 
 
 
 
 
 
 
 
 
 
556
 
557
  function openImageMenu(e) {
558
  e.preventDefault();
666
  }
667
 
668
  function closeComparerPopup(e) {
669
+
 
 
670
  e.data.modal.addClass('shortpixel-hide');
671
  jQuery('.sp-modal-shade').hide();
672
  jQuery(document).unbind('keyup.sp_modal_active');
683
  return url.replace(parser.protocol + '//' + parser.hostname, parser.protocol + '//' + parser.hostname.split('.').map(function(part) {return sp_punycode.toASCII(part)}).join('.'));
684
  }
685
 
 
 
 
686
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
687
 
688
  return {
689
  init : init,
694
  validateKey : validateKey,
695
  enableResize : enableResize,
696
  setupGeneralTab : setupGeneralTab,
 
 
697
  apiKeyChanged : apiKeyChanged,
698
  setupAdvancedTab : setupAdvancedTab,
699
  checkThumbsUpdTotal : checkThumbsUpdTotal,
700
  initSettings : initSettings,
701
  switchSettingsTab : switchSettingsTab,
702
  adjustSettingsTabs : adjustSettingsTabsHeight,
 
 
703
  closeHelpPane : closeHelpPane,
 
704
  checkQuota : checkQuota,
705
  percentDial : percentDial,
 
 
 
 
706
  initFolderSelector : initFolderSelector,
707
  browseContent : browseContent,
708
  getBackupSize : getBackupSize,
710
  proposeUpgrade : proposeUpgrade,
711
  closeProposeUpgrade : closeProposeUpgrade,
712
  // includeUnlisted : includeUnlisted,
 
 
 
 
 
 
713
  checkRandomAnswer : checkRandomAnswer,
 
 
714
  // recheckQuota : recheckQuota,
715
  openImageMenu : openImageMenu,
716
  menuCloseEvent : false,
731
  toRefresh : false,
732
  resizeSizesAlert: false,
733
  returnedStatusSearching: 0, // How often this status has come back in a row from server.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
734
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
735
  }
736
+ }(); // End of ShortPixel
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
737
 
738
  // first is string to replace, rest are arguments.
739
  function SPstringFormat() {
shortpixel-plugin.php CHANGED
@@ -184,8 +184,8 @@ class ShortPixelPlugin {
184
 
185
  add_filter( 'plugin_action_links_' . plugin_basename( SHORTPIXEL_PLUGIN_FILE ), array( $admin, 'generatePluginLinks' ) );// for plugin settings page
186
 
187
- // for cleaning up the WebP images when an attachment is deleted
188
- add_action( 'delete_attachment', array( $admin, 'onDeleteAttachment' ) );
189
  add_action( 'mime_types', array( $admin, 'addMimes' ) );
190
 
191
  // integration with WP/LR Sync plugin
@@ -279,7 +279,7 @@ class ShortPixelPlugin {
279
 
280
  wp_register_script( 'jquery.knob.min.js', plugins_url( '/res/js/jquery.knob.min.js', SHORTPIXEL_PLUGIN_FILE ), array(), SHORTPIXEL_IMAGE_OPTIMISER_VERSION, true );
281
 
282
- wp_register_script( 'jquery.tooltip.min.js', plugins_url( '/res/js/jquery.tooltip.min.js', SHORTPIXEL_PLUGIN_FILE ), array(), SHORTPIXEL_IMAGE_OPTIMISER_VERSION, true );
283
 
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
 
@@ -363,7 +363,6 @@ class ShortPixelPlugin {
363
  'WP_PLUGIN_URL' => plugins_url( '', SHORTPIXEL_PLUGIN_FILE ),
364
  'WP_ADMIN_URL' => admin_url(),
365
  'API_IS_ACTIVE' => $keyControl->keyIsVerified(),
366
- 'FRONT_BOOTSTRAP' => $settings->frontBootstrap && ( ! isset( $settings->lastBackAction ) || ( time() - $settings->lastBackAction > 600 ) ) ? 1 : 0,
367
  'AJAX_URL' => admin_url( 'admin-ajax.php' ),
368
  'BULK_SECRET' => $secretKey,
369
  'nonce_ajaxrequest' => wp_create_nonce( 'ajax_request' ),
@@ -500,17 +499,15 @@ class ShortPixelPlugin {
500
  $load_bulk = array(); // the whole suit needed for bulking.
501
 
502
 
503
-
504
  if ( \wpSPIO()->env()->is_screen_to_use ) {
505
  $this->load_script( 'shortpixel-tooltip' );
506
  $this->load_style( 'shortpixel-toolbar' );
507
-
508
  }
509
 
510
  if ( $plugin_page == 'wp-shortpixel-settings' ) {
511
  $this->load_script( $load_processor );
512
  $this->load_script( 'shortpixel-screen-nolist' ); // screen
513
- $this->load_script( 'jquery.tooltip.min.js' );
514
  $this->load_script( 'sp-file-tree' );
515
  $this->load_script( 'shortpixel-settings' );
516
 
@@ -531,7 +528,7 @@ class ShortPixelPlugin {
531
 
532
  $this->load_style( 'shortpixel-admin' );
533
  $this->load_style( 'shortpixel' );
534
-
535
  if ( $this->env()->is_debug ) {
536
  $this->load_script( 'shortpixel-debug' );
537
  }
@@ -541,7 +538,6 @@ class ShortPixelPlugin {
541
  $this->load_style( 'shortpixel-admin' );
542
 
543
  $this->load_style( 'shortpixel-othermedia' );
544
-
545
  $this->load_script( $load_processor );
546
  $this->load_script( 'shortpixel-screen-custom' ); // screen
547
 
184
 
185
  add_filter( 'plugin_action_links_' . plugin_basename( SHORTPIXEL_PLUGIN_FILE ), array( $admin, 'generatePluginLinks' ) );// for plugin settings page
186
 
187
+ // for cleaning up the WebP images when an attachment is deleted . Loading this early because it's possible other plugins delete files in the uploads, but we need those to remove backups.
188
+ add_action( 'delete_attachment', array( $admin, 'onDeleteAttachment' ), 5 );
189
  add_action( 'mime_types', array( $admin, 'addMimes' ) );
190
 
191
  // integration with WP/LR Sync plugin
279
 
280
  wp_register_script( 'jquery.knob.min.js', plugins_url( '/res/js/jquery.knob.min.js', SHORTPIXEL_PLUGIN_FILE ), array(), SHORTPIXEL_IMAGE_OPTIMISER_VERSION, true );
281
 
282
+ //wp_register_script( 'jquery.tooltip.min.js', plugins_url( '/res/js/jquery.tooltip.min.js', SHORTPIXEL_PLUGIN_FILE ), array(), SHORTPIXEL_IMAGE_OPTIMISER_VERSION, true );
283
 
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
 
363
  'WP_PLUGIN_URL' => plugins_url( '', SHORTPIXEL_PLUGIN_FILE ),
364
  'WP_ADMIN_URL' => admin_url(),
365
  'API_IS_ACTIVE' => $keyControl->keyIsVerified(),
 
366
  'AJAX_URL' => admin_url( 'admin-ajax.php' ),
367
  'BULK_SECRET' => $secretKey,
368
  'nonce_ajaxrequest' => wp_create_nonce( 'ajax_request' ),
499
  $load_bulk = array(); // the whole suit needed for bulking.
500
 
501
 
 
502
  if ( \wpSPIO()->env()->is_screen_to_use ) {
503
  $this->load_script( 'shortpixel-tooltip' );
504
  $this->load_style( 'shortpixel-toolbar' );
 
505
  }
506
 
507
  if ( $plugin_page == 'wp-shortpixel-settings' ) {
508
  $this->load_script( $load_processor );
509
  $this->load_script( 'shortpixel-screen-nolist' ); // screen
510
+ //$this->load_script( 'jquery.tooltip.min.js' );
511
  $this->load_script( 'sp-file-tree' );
512
  $this->load_script( 'shortpixel-settings' );
513
 
528
 
529
  $this->load_style( 'shortpixel-admin' );
530
  $this->load_style( 'shortpixel' );
531
+
532
  if ( $this->env()->is_debug ) {
533
  $this->load_script( 'shortpixel-debug' );
534
  }
538
  $this->load_style( 'shortpixel-admin' );
539
 
540
  $this->load_style( 'shortpixel-othermedia' );
 
541
  $this->load_script( $load_processor );
542
  $this->load_script( 'shortpixel-screen-custom' ); // screen
543
 
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.8
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.8");
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.9
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.9");
35
 
36
  define('SHORTPIXEL_BACKUP', 'ShortpixelBackups');
37
  define('SHORTPIXEL_MAX_FAIL_RETRIES', 3);