ShortPixel Image Optimizer - Version 5.0.3

Version Description

Release date June 21st, 2022 * Fix: the plugin now recognizes the offloaded WebP/AVIF files, when they are not also present anymore on the server; * Fix: in some cases, the bulk and manual optimization was stuck due to some errors related to the legacy optimization information; * Fix: when saving the settings, the credits quota and other API-related data will be sent to the API, for faster sync; * Fix: when having the backups turned off, a placeholder image was displayed instead of the original one; * Fix: an empty space was sometimes shown on some pages, as a result of some dismissed notifications; * Fix: various small fixes around the plugin processing engine, for increased speed and stability; * Fix: updated various pieces of code in accordance with the WordPress Coding Standards; * Language: 1 new string added, 0 updated, 0 fuzzed, and 0 obsoleted.

Download this release

Release Info

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

Code changes from version 5.0.2 to 5.0.3

build/shortpixel/log/src/ShortPixelLogger.php CHANGED
@@ -344,8 +344,8 @@ namespace ShortPixel\ShortPixelLogger;
344
  include($template_path);
345
  }
346
  else {
347
- self::addError("View $template could not be found in " . $template_path,
348
- array('class' => get_class($this), 'req' => $_REQUEST));
349
  }
350
  }
351
 
344
  include($template_path);
345
  }
346
  else {
347
+ self::addError("View $template for ShortPixelLogger could not be found in " . $template_path,
348
+ array('class' => get_class($this)));
349
  }
350
  }
351
 
build/shortpixel/notices/src/NoticeModel.php CHANGED
@@ -279,6 +279,7 @@ class NoticeModel //extends ShortPixelModel
279
  var ev = event.detail;
280
  var target = event.target;
281
  var parent = target.parentElement;
 
282
  var data = {
283
  'plugin_action': 'dismiss',
284
  'action' : '$this->notice_action',
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',
build/shortpixel/replacer/src/Replacer.php CHANGED
@@ -412,7 +412,6 @@ class Replacer
412
  */
413
  private function findNearestSize($sizeName)
414
  {
415
- Log::addTemp('Find Nearest: '. $sizeName);
416
 
417
  if (! isset($this->source_metadata['sizes'][$sizeName]) || ! isset($this->target_metadata['width'])) // This can happen with non-image files like PDF.
418
  {
412
  */
413
  private function findNearestSize($sizeName)
414
  {
 
415
 
416
  if (! isset($this->source_metadata['sizes'][$sizeName]) || ! isset($this->target_metadata['width'])) // This can happen with non-image files like PDF.
417
  {
class/BuildAutoLoader.php CHANGED
@@ -55,7 +55,7 @@ class BuildAutoLoader
55
  'class/external/cloudflare.php',
56
  'class/external/flywheel.php',
57
  //'class/external/gravityforms.php',
58
- 'class/external/helpscout.php',
59
  'class/external/nextgen/nextGenController.php',
60
  'class/external/nextgen/nextGenViewController.php',
61
  //'class/external/securi.php',
55
  'class/external/cloudflare.php',
56
  'class/external/flywheel.php',
57
  //'class/external/gravityforms.php',
58
+ //'class/external/helpscout.php',
59
  'class/external/nextgen/nextGenController.php',
60
  'class/external/nextgen/nextGenViewController.php',
61
  //'class/external/securi.php',
class/Controller/AdminController.php CHANGED
@@ -101,12 +101,15 @@ class AdminController extends \ShortPixel\Controller
101
 
102
  foreach($args['queues'] as $qname)
103
  {
104
- $result = $results->$qname;
105
- // If Queue is not completely empty, there should be something to do.
106
- if ($result->qstatus != QUEUE::RESULT_QUEUE_EMPTY)
107
  {
108
- $running = true;
109
- continue;
 
 
 
 
 
110
  }
111
  }
112
 
101
 
102
  foreach($args['queues'] as $qname)
103
  {
104
+ if (property_exists($results, $qname))
 
 
105
  {
106
+ $result = $results->$qname;
107
+ // If Queue is not completely empty, there should be something to do.
108
+ if ($result->qstatus != QUEUE::RESULT_QUEUE_EMPTY)
109
+ {
110
+ $running = true;
111
+ continue;
112
+ }
113
  }
114
  }
115
 
class/Controller/AdminNoticesController.php CHANGED
@@ -325,6 +325,9 @@ class AdminNoticesController extends \ShortPixel\Controller
325
  $settings = \wpSPIO()->settings();
326
 
327
  $quotaController = QuotaController::getInstance();
 
 
 
328
 
329
  if (! \wpSPIO()->settings()->verifiedKey)
330
  {
@@ -348,8 +351,6 @@ class AdminNoticesController extends \ShortPixel\Controller
348
  $quotaController = QuotaController::getInstance();
349
  $quotaData = $quotaController->getQuota();
350
 
351
- $statsControl = StatsController::getInstance(); // @todo Implement this. (Figure out what this was )
352
- $noticeController = Notices::getInstance();
353
 
354
  $bulk_notice = $noticeController->getNoticeByID(self::MSG_UPGRADE_BULK);
355
  $bulk_is_dismissed = ($bulk_notice && $bulk_notice->isDismissed() ) ? true : false;
@@ -365,29 +366,35 @@ class AdminNoticesController extends \ShortPixel\Controller
365
  'quotaAvailable' => $available);
366
 
367
  //looks like the user hasn't got enough credits to bulk process all media library
368
- $message = $this->getBulkUpgradeMessage($data);
369
- $notice = Notices::addNormal($message);
370
- Notices::makePersistent($notice, self::MSG_UPGRADE_BULK, YEAR_IN_SECONDS, array($this, 'upgradeBulkCallback'));
371
-
 
 
372
  }
373
  //consider the monthly plus 1/6 of the available one-time credits.
374
  elseif( $this->monthlyUpgradeNeeded($quotaData)) {
375
- //looks like the user hasn't got enough credits to process the monthly images, display a notice telling this
376
- $message = $this->getMonthlyUpgradeMessage(array('monthAvg' => $this->getMonthAvg(), 'monthlyQuota' => $quotaData->monthly->total ));
377
 
378
- $notice = Notices::addNormal($message);
379
- Notices::makePersistent($notice, self::MSG_UPGRADE_MONTH, YEAR_IN_SECONDS);
 
 
 
 
 
380
  }
381
  }
382
  elseif ($quotaController->hasQuota() === false)
383
  {
384
- // $stats = $shortpixel->countAllIfNeeded($settings->currentStats, 86400);
385
- // $quotaData = $stats;
386
- Log::addDebug('Over quota detected, loading message (adminnotices)');
387
- $message = $this->getQuotaExceededMessage();
388
 
389
- $notice = Notices::addError($message);
390
- Notices::makePersistent($notice, self::MSG_QUOTA_REACHED, WEEK_IN_SECONDS);
 
 
 
 
 
391
 
392
  Notices::removeNoticeByID(self::MSG_UPGRADE_MONTH); // get rid of doubles. reset
393
  Notices::removeNoticeByID(self::MSG_UPGRADE_BULK);
325
  $settings = \wpSPIO()->settings();
326
 
327
  $quotaController = QuotaController::getInstance();
328
+ $noticeController = Notices::getInstance();
329
+ $statsControl = StatsController::getInstance(); // @todo Implement this. (Figure out what this was )
330
+
331
 
332
  if (! \wpSPIO()->settings()->verifiedKey)
333
  {
351
  $quotaController = QuotaController::getInstance();
352
  $quotaData = $quotaController->getQuota();
353
 
 
 
354
 
355
  $bulk_notice = $noticeController->getNoticeByID(self::MSG_UPGRADE_BULK);
356
  $bulk_is_dismissed = ($bulk_notice && $bulk_notice->isDismissed() ) ? true : false;
366
  'quotaAvailable' => $available);
367
 
368
  //looks like the user hasn't got enough credits to bulk process all media library
369
+ if ($bulk_notice === false)
370
+ {
371
+ $message = $this->getBulkUpgradeMessage($data);
372
+ $notice = Notices::addNormal($message);
373
+ Notices::makePersistent($notice, self::MSG_UPGRADE_BULK, YEAR_IN_SECONDS, array($this, 'upgradeBulkCallback'));
374
+ }
375
  }
376
  //consider the monthly plus 1/6 of the available one-time credits.
377
  elseif( $this->monthlyUpgradeNeeded($quotaData)) {
 
 
378
 
379
+ if ($month_notice === false)
380
+ {
381
+ //looks like the user hasn't got enough credits to process the monthly images, display a notice telling this
382
+ $message = $this->getMonthlyUpgradeMessage(array('monthAvg' => $this->getMonthAvg(), 'monthlyQuota' => $quotaData->monthly->total ));
383
+ $notice = Notices::addNormal($message);
384
+ Notices::makePersistent($notice, self::MSG_UPGRADE_MONTH, YEAR_IN_SECONDS);
385
+ }
386
  }
387
  }
388
  elseif ($quotaController->hasQuota() === false)
389
  {
 
 
 
 
390
 
391
+ $notice = $noticeController->getNoticeByID(self::MSG_QUOTA_REACHED);
392
+ if ($notice === false)
393
+ {
394
+ $message = $this->getQuotaExceededMessage();
395
+ $notice = Notices::addError($message);
396
+ Notices::makePersistent($notice, self::MSG_QUOTA_REACHED, WEEK_IN_SECONDS);
397
+ }
398
 
399
  Notices::removeNoticeByID(self::MSG_UPGRADE_MONTH); // get rid of doubles. reset
400
  Notices::removeNoticeByID(self::MSG_UPGRADE_BULK);
class/Controller/FileSystemController.php CHANGED
@@ -387,6 +387,8 @@ Class FileSystemController extends \ShortPixel\Controller
387
  return false;
388
  }
389
 
 
 
390
  /** Get all files from a directory tree, starting at given dir.
391
  * @param DirectoryModel $dir to recursive into
392
  * @param Array $filters Collection of optional filters as accepted by FileFilter in directoryModel
@@ -412,6 +414,30 @@ Class FileSystemController extends \ShortPixel\Controller
412
  return $fileArray;
413
  }
414
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
415
  /** Old method of getting a subDir. This is messy and hopefully should not be used anymore. It's added here for backward compat in case of exceptions */
416
  private function returnOldSubDir($file)
417
  {
387
  return false;
388
  }
389
 
390
+
391
+
392
  /** Get all files from a directory tree, starting at given dir.
393
  * @param DirectoryModel $dir to recursive into
394
  * @param Array $filters Collection of optional filters as accepted by FileFilter in directoryModel
414
  return $fileArray;
415
  }
416
 
417
+ // Url very sparingly.
418
+ public function url_exists($url)
419
+ {
420
+ if (! \wpSPIO()->env()->is_function_usable('curl_init'))
421
+ {
422
+ return null;
423
+ }
424
+
425
+ $ch = curl_init($url);
426
+ curl_setopt($ch, CURLOPT_NOBODY, true);
427
+ curl_exec($ch);
428
+ $responseCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
429
+ curl_close($ch);
430
+
431
+ if ($responseCode == 200)
432
+ {
433
+ return true;
434
+ }
435
+ else {
436
+ return false;
437
+ }
438
+
439
+ }
440
+
441
  /** Old method of getting a subDir. This is messy and hopefully should not be used anymore. It's added here for backward compat in case of exceptions */
442
  private function returnOldSubDir($file)
443
  {
class/Controller/OptimizeController.php CHANGED
@@ -332,9 +332,7 @@ class OptimizeController
332
  }
333
 
334
  // @todo Here prevent bulk from running when running flag is off
335
-
336
  // @todo Here prevent a runTick is the queue is empty and done already ( reliably )
337
-
338
  $results = new \stdClass;
339
  if ( in_array('media', $queueTypes))
340
  {
332
  }
333
 
334
  // @todo Here prevent bulk from running when running flag is off
 
335
  // @todo Here prevent a runTick is the queue is empty and done already ( reliably )
 
336
  $results = new \stdClass;
337
  if ( in_array('media', $queueTypes))
338
  {
class/Controller/OtherMediaController.php CHANGED
@@ -377,7 +377,6 @@ class OtherMediaController extends \ShortPixel\Controller
377
  if( count($subdirs) > 0 ) {
378
  echo "<ul class='jqueryFileTree'>";
379
  foreach($subdirs as $dir ) {
380
-
381
  $returnDir = substr($dir->getPath(), strlen($rootDirObj->getPath())); // relative to root.
382
  $dirpath = $dir->getPath();
383
  $dirname = $dir->getName();
@@ -389,7 +388,7 @@ class OtherMediaController extends \ShortPixel\Controller
389
 
390
  if( $dir->exists() ) {
391
  //KEEP the spaces in front of the rel values - it's a trick to make WP Hide not replace the wp-content path
392
- echo "<li class='directory collapsed'><a rel=' " .$htmlRel. "'>" . $htmlName . "</a></li>";
393
  }
394
 
395
  }
377
  if( count($subdirs) > 0 ) {
378
  echo "<ul class='jqueryFileTree'>";
379
  foreach($subdirs as $dir ) {
 
380
  $returnDir = substr($dir->getPath(), strlen($rootDirObj->getPath())); // relative to root.
381
  $dirpath = $dir->getPath();
382
  $dirname = $dir->getName();
388
 
389
  if( $dir->exists() ) {
390
  //KEEP the spaces in front of the rel values - it's a trick to make WP Hide not replace the wp-content path
391
+ echo "<li class='directory collapsed'><a rel=' " .esc_attr($htmlRel) . "'>" . esc_html($htmlName) . "</a></li>";
392
  }
393
 
394
  }
class/Controller/Queue/Queue.php CHANGED
@@ -335,6 +335,8 @@ abstract class Queue
335
  $stats->done = (int) $this->getStatus('done');
336
  $stats->bulk_running = (bool) $this->getStatus('bulk_running');
337
 
 
 
338
  $stats->total = $stats->in_queue + $stats->fatal_errors + $stats->errors + $stats->done + $stats->in_process;
339
  if ($stats->total > 0)
340
  $stats->percentage_done = round((100 / $stats->total) * ($stats->done + $stats->fatal_errors));
335
  $stats->done = (int) $this->getStatus('done');
336
  $stats->bulk_running = (bool) $this->getStatus('bulk_running');
337
 
338
+ $customData = $this->getStatus('custom_data');
339
+
340
  $stats->total = $stats->in_queue + $stats->fatal_errors + $stats->errors + $stats->done + $stats->in_process;
341
  if ($stats->total > 0)
342
  $stats->percentage_done = round((100 / $stats->total) * ($stats->done + $stats->fatal_errors));
class/Controller/SettingsController.php CHANGED
@@ -352,7 +352,9 @@ class SettingsController extends \ShortPixel\ViewController
352
  $this->keyModel->checkKey($check_key);
353
  }
354
 
355
- // $this->loadQuotaData(true);
 
 
356
 
357
  // end
358
 
352
  $this->keyModel->checkKey($check_key);
353
  }
354
 
355
+
356
+ // Every save, force load the quota. One reason, because of the HTTP Auth settings refresh.
357
+ $this->loadQuotaData(true);
358
 
359
  // end
360
 
class/Controller/View/EditMediaViewController.php CHANGED
@@ -68,7 +68,7 @@ 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);
@@ -187,9 +187,17 @@ class EditMediaViewController extends \ShortPixel\ViewController
187
  $debugInfo = array();
188
  $debugInfo[] = array(__('URL (get attachment URL)', 'shortpixel_image_optiser'), wp_get_attachment_url($this->post_id));
189
  $debugInfo[] = array(__('File (get attached)'), get_attached_file($this->post_id));
 
 
 
 
 
 
190
  $debugInfo[] = array(__('Size and Mime (ImageObj)'), $imageObj->get('width') . 'x' . $imageObj->get('height'). ' (' . $imageObj->get('mime') . ')');
191
  $debugInfo[] = array(__('Status (ShortPixel)'), $imageObj->getMeta('status') . ' ' );
192
 
 
 
193
  $debugInfo[] = array(__('Processable'), $processable);
194
  $debugInfo[] = array(__('Restorable'), $restorable);
195
 
68
  return false;
69
  }
70
 
71
+
72
  $this->view->status_message = null;
73
 
74
  $this->view->text = UiHelper::getStatusText($this->imageModel);
187
  $debugInfo = array();
188
  $debugInfo[] = array(__('URL (get attachment URL)', 'shortpixel_image_optiser'), wp_get_attachment_url($this->post_id));
189
  $debugInfo[] = array(__('File (get attached)'), get_attached_file($this->post_id));
190
+
191
+ if ($imageObj->is_virtual())
192
+ {
193
+ $debugInfo[] = array(__('Is Virtual'), $imageObj->getFullPath() );
194
+ }
195
+
196
  $debugInfo[] = array(__('Size and Mime (ImageObj)'), $imageObj->get('width') . 'x' . $imageObj->get('height'). ' (' . $imageObj->get('mime') . ')');
197
  $debugInfo[] = array(__('Status (ShortPixel)'), $imageObj->getMeta('status') . ' ' );
198
 
199
+
200
+
201
  $debugInfo[] = array(__('Processable'), $processable);
202
  $debugInfo[] = array(__('Restorable'), $restorable);
203
 
class/Controller/View/ListMediaViewController.php CHANGED
@@ -304,7 +304,7 @@ class ListMediaViewController extends \ShortPixel\ViewController
304
  foreach($options as $optname => $optval)
305
  {
306
  $selected = ($status == $optname) ? 'selected' : '';
307
- echo "<option value='". $optname . "' $selected>" . $optval . "</option>\n";
308
  }
309
  echo "</select>";
310
 
304
  foreach($options as $optname => $optval)
305
  {
306
  $selected = ($status == $optname) ? 'selected' : '';
307
+ echo "<option value='". esc_attr($optname) . "' $selected >" . esc_html($optval) . "</option>\n";
308
  }
309
  echo "</select>";
310
 
class/Controller/View/OtherMediaViewController.php CHANGED
@@ -434,9 +434,8 @@ class OtherMediaViewController extends \ShortPixel\ViewController
434
  public function doActionColumn($item)
435
  {
436
  ?>
437
- <div id='sp-msg-<?php echo $item->get('id') ?>' class='sp-column-info'><?php
438
- //echo $this->getDisplayStatus($item);
439
- $this->printItemActions($item);
440
  echo "<div>" . UiHelper::getStatusText($item) . "</div>";
441
 
442
  ?>
@@ -464,7 +463,7 @@ class OtherMediaViewController extends \ShortPixel\ViewController
464
  $link = ($action['type'] == 'js') ? 'javascript:' . $action['function'] : $action['function'];
465
 
466
  ?>
467
- <a href="<?php echo $link ?>" class="<?php echo $classes ?>"><?php echo $action['text'] ?></a>
468
 
469
  <?php
470
  endforeach;
@@ -501,7 +500,7 @@ class OtherMediaViewController extends \ShortPixel\ViewController
501
  $class = (isset($action['class'])) ? $action['class'] : '';
502
 
503
 
504
- $link = '<a href="' . esc_url($url) . '" class="action-' . $action_arg . ' ' . $class . '">' . $text . '</a>';
505
  }
506
 
507
  $actions[$index] = $link;
434
  public function doActionColumn($item)
435
  {
436
  ?>
437
+ <div id='sp-msg-<?php echo esc_attr($item->get('id')) ?>' class='sp-column-info'><?php
438
+ $this->printItemActions($item);
 
439
  echo "<div>" . UiHelper::getStatusText($item) . "</div>";
440
 
441
  ?>
463
  $link = ($action['type'] == 'js') ? 'javascript:' . $action['function'] : $action['function'];
464
 
465
  ?>
466
+ <a href="<?php echo esc_url($link) ?>" class="<?php echo esc_attr($classes) ?>"><?php echo esc_html($action['text']) ?></a>
467
 
468
  <?php
469
  endforeach;
500
  $class = (isset($action['class'])) ? $action['class'] : '';
501
 
502
 
503
+ $link = '<a href="' . esc_url($url) . '" class="action-' . esc_attr($action_arg) . ' ' . esc_attr($class) . '">' . esc_html($text) . '</a>';
504
  }
505
 
506
  $actions[$index] = $link;
class/Helper/UiHelper.php CHANGED
@@ -413,7 +413,7 @@ class UiHelper
413
  {
414
 
415
  $retry = self::getAction('retry', $mediaItem->get('id'));
416
- $text .= "<div class='shortpixel-image-error'>" . $mediaItem->isOptimizePrevented();
417
  $text .= "<span class='shortpixel-error-reset'>" . sprintf(__('After you have fixed this issue, you can %s click here to retry %s', 'shortpixel-image-optimiser'), '<a href="javascript:' . $retry['function'] . '">', '</a>');
418
  $text .= '</div>';
419
  }
413
  {
414
 
415
  $retry = self::getAction('retry', $mediaItem->get('id'));
416
+ $text .= "<div class='shortpixel-image-error'>" . esc_html($mediaItem->isOptimizePrevented());
417
  $text .= "<span class='shortpixel-error-reset'>" . sprintf(__('After you have fixed this issue, you can %s click here to retry %s', 'shortpixel-image-optimiser'), '<a href="javascript:' . $retry['function'] . '">', '</a>');
418
  $text .= '</div>';
419
  }
class/Model/EnvironmentModel.php CHANGED
@@ -93,8 +93,11 @@ class EnvironmentModel extends \ShortPixel\Model
93
  case 'spai':
94
  $plugin = 'shortpixel-adaptive-images/short-pixel-ai.php';
95
  break;
 
 
 
96
  default:
97
- $plugin = 'none';
98
  break;
99
  }
100
 
93
  case 'spai':
94
  $plugin = 'shortpixel-adaptive-images/short-pixel-ai.php';
95
  break;
96
+ case 's3-offload':
97
+ $plugin = 'amazon-s3-and-cloudfront/wordpress-s3.php';
98
+ break;
99
  default:
100
+ $plugin = 'none';
101
  break;
102
  }
103
 
class/Model/Image/ImageModel.php CHANGED
@@ -296,7 +296,7 @@ abstract class ImageModel extends \ShortPixel\Model\File\FileModel
296
  {
297
  $fs = \wpSPIO()->filesystem();
298
 
299
- if (! is_null($this->getMeta($type)))
300
  {
301
  $filepath = $this->getFileDir() . $this->getMeta($type);
302
  $file = $fs->getFile($filepath);
296
  {
297
  $fs = \wpSPIO()->filesystem();
298
 
299
+ if (! is_null($this->getMeta($type)))
300
  {
301
  $filepath = $this->getFileDir() . $this->getMeta($type);
302
  $file = $fs->getFile($filepath);
class/Model/Image/MediaLibraryModel.php CHANGED
@@ -729,7 +729,6 @@ class MediaLibraryModel extends \ShortPixel\Model\Image\MediaLibraryThumbnailMod
729
 
730
  $prepare = array_merge( array(self::IMAGE_TYPE_MAIN), $duplicates);
731
 
732
-
733
  $sql = 'SELECT attach_id FROM ' . $wpdb->prefix . 'shortpixel_postmeta WHERE image_type = %d and attach_id in ( ' . $in_str . ') ';
734
  $sql = $wpdb->prepare($sql, $prepare);
735
 
@@ -1864,6 +1863,7 @@ class MediaLibraryModel extends \ShortPixel\Model\Image\MediaLibraryThumbnailMod
1864
  return false;
1865
  }
1866
 
 
1867
  $data = $metadata['ShortPixel'];
1868
 
1869
  if (count($data) == 0) // This can happen. Empty array is still nothing to convert.
@@ -1942,9 +1942,10 @@ class MediaLibraryModel extends \ShortPixel\Model\Image\MediaLibraryThumbnailMod
1942
  $this->image_meta->originalSize = ($this->getFileSize() / (100 - $imp)) * 100;
1943
  }
1944
 
1945
- $webp = $this->getWebp();
1946
- if ($webp)
1947
- $this->image_meta->webp = $webp->getFileName();
 
1948
 
1949
  $this->width = isset($metadata['width']) ? $metadata['width'] : false;
1950
  $this->height = isset($metadata['height']) ? $metadata['height'] : false;
@@ -1983,11 +1984,8 @@ class MediaLibraryModel extends \ShortPixel\Model\Image\MediaLibraryThumbnailMod
1983
 
1984
  $thumbnailObj->has_backup = $thumbnailObj->hasBackup();
1985
 
1986
- $webp = $thumbnailObj->getWebp();
1987
- if ($webp)
1988
- {
1989
- $thumbnailObj->image_meta->webp = $webp->getFileName();
1990
- }
1991
 
1992
  if (strpos($thumbname, 'sp-found') !== false) // File is 'unlisted', also save file information.
1993
  {
@@ -2012,7 +2010,8 @@ class MediaLibraryModel extends \ShortPixel\Model\Image\MediaLibraryThumbnailMod
2012
  $originalFile->image_meta->compressedSize = $originalFile->getFileSize();
2013
  $originalFile->image_meta->did_jpg2png = $did_jpg2png;
2014
  // $thumbnailObj->image_meta->improvement = -1; // n/a
2015
- if ($thumbnailObj->hasBackup())
 
2016
  {
2017
  $backup = $originalFile->getBackupFile();
2018
  $originalFile->image_meta->originalSize = $backup->getFileSize();
@@ -2022,11 +2021,9 @@ class MediaLibraryModel extends \ShortPixel\Model\Image\MediaLibraryThumbnailMod
2022
  $originalFile->image_meta->tsOptimized = $tsOptimized;
2023
  $originalFile->has_backup = $originalFile->hasBackup();
2024
 
2025
- $webp = $originalFile->getWebp();
2026
- if ($webp)
2027
- {
2028
- $originalFile->image_meta->webp = $webp->getFileName();
2029
- }
2030
 
2031
  if (strpos($thumbname, 'sp-found') !== false) // File is 'unlisted', also save file information.
2032
  {
@@ -2080,6 +2077,65 @@ class MediaLibraryModel extends \ShortPixel\Model\Image\MediaLibraryThumbnailMod
2080
  return true;
2081
  }
2082
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2083
  private function legacyConvertType($string_type)
2084
  {
2085
  switch($string_type)
729
 
730
  $prepare = array_merge( array(self::IMAGE_TYPE_MAIN), $duplicates);
731
 
 
732
  $sql = 'SELECT attach_id FROM ' . $wpdb->prefix . 'shortpixel_postmeta WHERE image_type = %d and attach_id in ( ' . $in_str . ') ';
733
  $sql = $wpdb->prepare($sql, $prepare);
734
 
1863
  return false;
1864
  }
1865
 
1866
+
1867
  $data = $metadata['ShortPixel'];
1868
 
1869
  if (count($data) == 0) // This can happen. Empty array is still nothing to convert.
1942
  $this->image_meta->originalSize = ($this->getFileSize() / (100 - $imp)) * 100;
1943
  }
1944
 
1945
+
1946
+ $this->image_meta->webp = $this->checkLegacyFileTypeFileName($this, 'webp');
1947
+ $this->image_meta->avif = $this->checkLegacyFileTypeFileName($this, 'avif');
1948
+
1949
 
1950
  $this->width = isset($metadata['width']) ? $metadata['width'] : false;
1951
  $this->height = isset($metadata['height']) ? $metadata['height'] : false;
1984
 
1985
  $thumbnailObj->has_backup = $thumbnailObj->hasBackup();
1986
 
1987
+ $thumbnailObj->image_meta->webp = $this->checkLegacyFileTypeFileName($thumbnailObj, 'webp');
1988
+ $thumbnailObj->image_meta->avif = $this->checkLegacyFileTypeFileName($thumbnailObj, 'avif');
 
 
 
1989
 
1990
  if (strpos($thumbname, 'sp-found') !== false) // File is 'unlisted', also save file information.
1991
  {
2010
  $originalFile->image_meta->compressedSize = $originalFile->getFileSize();
2011
  $originalFile->image_meta->did_jpg2png = $did_jpg2png;
2012
  // $thumbnailObj->image_meta->improvement = -1; // n/a
2013
+
2014
+ if ($originalFile->hasBackup())
2015
  {
2016
  $backup = $originalFile->getBackupFile();
2017
  $originalFile->image_meta->originalSize = $backup->getFileSize();
2021
  $originalFile->image_meta->tsOptimized = $tsOptimized;
2022
  $originalFile->has_backup = $originalFile->hasBackup();
2023
 
2024
+ $originalFile->image_meta->webp = $this->checkLegacyFileTypeFileName($originalFile, 'webp');
2025
+ $originalFile->image_meta->avif = $this->checkLegacyFileTypeFileName($originalFile, 'avif');
2026
+
 
 
2027
 
2028
  if (strpos($thumbname, 'sp-found') !== false) // File is 'unlisted', also save file information.
2029
  {
2077
  return true;
2078
  }
2079
 
2080
+ private function checkLegacyFileTypeFileName($fileObj, $type)
2081
+ {
2082
+ $fileType = $fileObj->getImageType($type);
2083
+ if ($fileType !== false)
2084
+ {
2085
+ return $fileType->getFileName();
2086
+ }
2087
+ $env = \wpSPIO()->env();
2088
+ $fs = \wpSPIO()->filesystem();
2089
+
2090
+ // try the whole thing, but fetching remote URLS, test if really S3 not in case something went wrong with is_virtual, or it's just something messed up.
2091
+ if ($fileObj->is_virtual() && $env->plugin_active('s3-offload') )
2092
+ {
2093
+ if ($type == 'webp')
2094
+ {
2095
+ $is_double = \wpSPIO()->env()->useDoubleWebpExtension();
2096
+ }
2097
+ if ($type == 'avif')
2098
+ {
2099
+ $is_double = \wpSPIO()->env()->useDoubleAvifExtension();
2100
+ }
2101
+
2102
+ $url = str_replace('.' . $fileObj->getExtension(), '.' . $type, $fileObj->getURL());
2103
+ $double_url = $fileObj->getURL() . '.' . $type;
2104
+
2105
+ $double_filename = $fileObj->getFileName() . '.' . $type;
2106
+ $filename = $fileObj->getFileBase() . '.' . $type;
2107
+
2108
+ if ($is_double)
2109
+ {
2110
+ $url_exists = $fs->url_exists($double_url);
2111
+ if ($url_exists === true)
2112
+ return $double_filename;
2113
+ }
2114
+ else
2115
+ {
2116
+ $url_exists = $fs->url_exists($url);
2117
+ if ($url_exists === true)
2118
+ return $filename;
2119
+ }
2120
+
2121
+ // If double extension is enabled, but no file, check the alternative.
2122
+ if ($is_double)
2123
+ {
2124
+ $url_exists = $fs->url_exists($url);
2125
+ if ($url_exists === true)
2126
+ return $filename;
2127
+ }
2128
+ else
2129
+ {
2130
+ $url_exists = $fs->getFile($double_url);
2131
+ if ($url_exists === true)
2132
+ return $double_filename;
2133
+ }
2134
+ } // is_virtual
2135
+
2136
+ return null;
2137
+ }
2138
+
2139
  private function legacyConvertType($string_type)
2140
  {
2141
  switch($string_type)
class/Model/StatsModel.php CHANGED
@@ -371,17 +371,28 @@ class StatsModel
371
  //$monthsAgo = 0 - $monthsAgo; // minus it for the sub.
372
  /*$sql = "select meta_id from wp_postmeta where meta_key = '_shortpixel_meta' HAVING substr(meta_value, instr(meta_value, 'tsOptimized')+15,10) as stamp >= %d and stamp <= %d"; */
373
 
374
- $sql = 'SELECT count(post_id) FROM ' . $wpdb->postmeta . ' WHERE meta_key = "_shortpixel_optdate" and meta_value >= %d and meta_value <= %d';
375
-
376
- $date = new \DateTime();
377
  $date->sub( new \DateInterval('P' . $monthsAgo . 'M'));
378
 
379
  $dateUntil = new \DateTime();
380
  $dateUntil->sub( new \DateInterval('P' . ($monthsAgo-1). 'M'));
381
 
382
- $sql = $wpdb->prepare($sql, $date->getTimeStamp(), $dateUntil->getTimeStamp() );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
383
 
384
- $count = $wpdb->get_var($sql);
385
 
386
  return $count;
387
  }
371
  //$monthsAgo = 0 - $monthsAgo; // minus it for the sub.
372
  /*$sql = "select meta_id from wp_postmeta where meta_key = '_shortpixel_meta' HAVING substr(meta_value, instr(meta_value, 'tsOptimized')+15,10) as stamp >= %d and stamp <= %d"; */
373
 
374
+ $date = new \DateTime();
 
 
375
  $date->sub( new \DateInterval('P' . $monthsAgo . 'M'));
376
 
377
  $dateUntil = new \DateTime();
378
  $dateUntil->sub( new \DateInterval('P' . ($monthsAgo-1). 'M'));
379
 
380
+ $sql = 'SELECT count(id) FROM ' . $wpdb->prefix . 'shortpixel_postmeta WHERE tsOptimized >= %s and tsOptimized <= %s';
381
+ $sql = $wpdb->prepare($sql, $date->format('Y-m-d H:i:s'), $dateUntil->format('Y-m-d H:i:s') );
382
+ $count_media = $wpdb->get_var($sql);
383
+
384
+ // Custom
385
+ $sql = 'SELECT count(id) FROM ' . $wpdb->prefix . 'shortpixel_meta WHERE ts_optimized >= %s and ts_optimized <= %s';
386
+ $sql = $wpdb->prepare($sql, $date->format('Y-m-d H:i:s'), $dateUntil->format('Y-m-d H:i:s') );
387
+ $count_custom = $wpdb->get_var($sql);
388
+
389
+ $count = 0;
390
+ if (! is_null($count_media) && is_numeric($count_media))
391
+ $count += $count_media;
392
+
393
+ if (! is_null($count_custom) && is_numeric($count_custom))
394
+ $count += $count_custom;
395
 
 
396
 
397
  return $count;
398
  }
class/ViewController.php CHANGED
@@ -75,7 +75,6 @@ class ViewController extends Controller
75
  // load either param or class template.
76
  $template = (is_null($template)) ? $this->template : $template;
77
 
78
-
79
  if (is_null($template) )
80
  {
81
  return false;
@@ -93,7 +92,7 @@ class ViewController extends Controller
93
  if (file_exists($template_path) === false)
94
  {
95
  Log::addError("View $template could not be found in " . $template_path,
96
- array('class' => get_class($this), 'req' => $_REQUEST));
97
  }
98
  elseif ($unique === false || ! in_array($template, self::$viewsLoaded))
99
  {
75
  // load either param or class template.
76
  $template = (is_null($template)) ? $this->template : $template;
77
 
 
78
  if (is_null($template) )
79
  {
80
  return false;
92
  if (file_exists($template_path) === false)
93
  {
94
  Log::addError("View $template could not be found in " . $template_path,
95
+ array('class' => get_class($this)));
96
  }
97
  elseif ($unique === false || ! in_array($template, self::$viewsLoaded))
98
  {
class/external/helpscout.php DELETED
@@ -1,179 +0,0 @@
1
- <?php
2
- namespace ShortPixel;
3
-
4
- use ShortPixel\Controller\ApiKeyController as ApiKeyController;
5
-
6
- // Integration class for HelpScout
7
- class HelpScout
8
- {
9
- public static function outputBeacon()
10
- {
11
- return; // this is disabled.
12
-
13
- global $shortPixelPluginInstance;
14
- $settings = \wpSPIO()->settings();
15
- $dismissed = $settings->dismissedNotices ? $settings->dismissedNotices : array();
16
- if(isset($dismissed['help'])) {
17
- return;
18
- }
19
-
20
- // if ($settings->helpscoutOptin <> 1)
21
-
22
-
23
- $keyControl = ApiKeyController::getInstance();
24
- $apikey = $keyControl->getKeyForDisplay();
25
-
26
- ?>
27
- <style>
28
- .shortpixel-hs-blind {
29
- position: fixed;
30
- bottom: 4px;
31
- right: 0;
32
- z-index: 20003;
33
- background-color: white;
34
- width: 87px;
35
- height: 188px;
36
- border-radius: 20px 0 0 20px;
37
- text-align: right;
38
- padding-right: 15px;
39
- }
40
- .shortpixel-hs-blind a {
41
- color: lightgray;
42
- text-decoration: none;
43
- }
44
- .shortpixel-hs-blind i.dashicons {
45
- margin-top: -8px;
46
- }
47
- .shortpixel-hs-blind .dashicons-minus {
48
- border: 3px solid;
49
- border-radius: 12px;
50
- font-size: 12px;
51
- font-weight: bold;
52
- line-height: 15px;
53
- height: 13px;
54
- width: 13px;
55
- display:none;
56
- }
57
- .shortpixel-hs-blind .dashicons-dismiss {
58
- font-size: 23px;
59
- line-height: 19px;
60
- display: none;
61
- }
62
- .shortpixel-hs-blind:hover .dashicons-minus,
63
- .shortpixel-hs-blind:hover .dashicons-dismiss {
64
- display: inline-block;
65
- }
66
- .shortpixel-hs-button-blind {
67
- display:none;
68
- position: fixed;
69
- bottom: 115px;right: 0;
70
- z-index: 20003;
71
- background-color: white;
72
- width: 237px;
73
- height: 54px;
74
- }
75
- .shortpixel-hs-tools {
76
- position: fixed;
77
- bottom: 116px;
78
- right: 0px;
79
- z-index: 20003;
80
- background-color: #ecf9fc;
81
- padding: 8px 18px 3px 12px;
82
- border-radius: 26px 0 0 26px;
83
- -webkit-box-shadow: 1px 1px 5px 0px rgba(6,109,117,1);
84
- -moz-box-shadow: 1px 1px 5px 0px rgba(6,109,117,1);
85
- box-shadow: 1px 1px 10px 0px rgb(172, 173, 173);
86
- }
87
- @media (max-width: 767px) {
88
- .shortpixel-hs-blind {
89
- bottom: 8px;
90
- height: 194px;
91
- }
92
- .shortpixel-hs-button-blind {
93
- bottom: 100px;
94
- }
95
- }
96
- </style>
97
- <div id="shortpixel-hs-blind" class="shortpixel-hs-blind">
98
- <a href="javascript:ShortPixel.closeHelpPane();">
99
- <i class="dashicons dashicons-minus" title="<?php _e('Dismiss for now', 'shortpixel-image-optimiser'); ?> "></i>
100
- </a>
101
- <a href="javascript:ShortPixel.dismissHelpPane();">
102
- <i class="dashicons dashicons-dismiss" title="<?php _e('Never display again', 'shortpixel-image-optimiser'); ?>"></i>
103
- </a>
104
- </div>
105
- <!--<div id="shortpixel-hs-button-blind" class="shortpixel-hs-button-blind"></div>-->
106
- <div id="shortpixel-hs-tools" class="shortpixel-hs-tools">
107
- <a href="javascript:shortpixelToggleHS();" class="shortpixel-hs-tools-docs" title="<?php _e('Search through our online documentation.', 'shortpixel-image-optimiser'); ?>">
108
- <img alt="<?php _e('ShortPixel document icon', 'shortpixel-image-optimiser'); ?>" src="<?php echo( wpSPIO()->plugin_url('res/img/notes-sp.png') );?>" style="margin-bottom: 2px;width: 36px;">
109
- </a>
110
- </div>
111
- <script>
112
- window.shortpixelHSOpen = 0;//-1;
113
- function shortpixelToggleHS() {
114
- //if(window.shortpixelHSOpen == -1) {
115
- // HS.beacon.init();
116
- //}
117
- if(window.shortpixelHSOpen == 1) {
118
- window.Beacon('close');
119
- jQuery('#botbutton').addClass('show');
120
- jQuery('div.shortpixel-hs-tools').css('bottom', '116px');
121
- jQuery('div.shortpixel-hs-blind').css('height', '188px');
122
- jQuery('div.shortpixel-hs-blind').css('border-radius', '20px 0 0 20px');
123
- jQuery('div.shortpixel-hs-blind a').css('display', 'inline');
124
- window.shortpixelHSOpen = 0;
125
- } else {
126
- window.Beacon('open');
127
- jQuery('#botbutton').removeClass('show');
128
- jQuery('div.shortpixel-hs-tools').css('bottom', '40px');
129
- jQuery('div.shortpixel-hs-blind').css('height', '93px');
130
- jQuery('div.shortpixel-hs-blind').css('border-radius', '0 0 0 20px');
131
- jQuery('div.shortpixel-hs-blind a').css('display', 'none');
132
- window.shortpixelHSOpen = 1;
133
- }
134
- }
135
- </script>
136
- <script type="text/javascript" src="https://quriobot.com/qb/widget/KoPqxmzqzjbg5eNl/V895xbyndnmeqZYd" async defer></script>
137
-
138
- <script>
139
- <?php
140
- $screen = get_current_screen();
141
- if($screen) {
142
- switch($screen->id) {
143
- case 'media_page_wp-short-pixel-bulk':
144
- echo("var shortpixel_suggestions = [ '5a5de2782c7d3a19436843af', '5a5de6902c7d3a19436843e9', '5a5de5c42c7d3a19436843d0', '5a9945e42c7d3a75495145d0', '5a5de1c2042863193801047c', '5a5de66f2c7d3a19436843e0', '5a9946e62c7d3a75495145d8', '5a5de4f02c7d3a19436843c8', '5a5de65f042863193801049f', '5a5de2df0428631938010485' ]; ");
145
- $suggestions = "shortpixel_suggestions";
146
- break;
147
- case 'settings_page_wp-shortpixel-settings':
148
- echo("var shortpixel_suggestions_settings = [ '5a5de1de2c7d3a19436843a8', '5a6612032c7d3a39e6263a1d', '5a5de1c2042863193801047c', '5a5de2782c7d3a19436843af', '5a6610c62c7d3a39e6263a02', '5a9945e42c7d3a75495145d0', '5a5de66f2c7d3a19436843e0', '5a6597e80428632faf620487', '5a5de5c42c7d3a19436843d0', '5a5de5642c7d3a19436843cc' ]; ");
149
- echo("var shortpixel_suggestions_adv_settings = [ '5a5de4f02c7d3a19436843c8', '5a8431f00428634376d01dc4', '5a5de58b0428631938010497', '5a5de65f042863193801049f', '5a9945e42c7d3a75495145d0', '5a9946e62c7d3a75495145d8', '5a5de57c0428631938010495', '5a5de2d22c7d3a19436843b1', '5a5de5c42c7d3a19436843d0', '5a5de5642c7d3a19436843cc' ]; ");
150
- echo("var shortpixel_suggestions_cloudflare = [ '5a5de1f62c7d3a19436843a9', '5a5de58b0428631938010497', '5a5de66f2c7d3a19436843e0', '5a5de5c42c7d3a19436843d0', '5a5de6902c7d3a19436843e9', '5a5de51a2c7d3a19436843c9', '5a9946e62c7d3a75495145d8', '5a5de46c2c7d3a19436843c1', '5a5de1de2c7d3a19436843a8', '5a6597e80428632faf620487' ]; ");
151
- $suggestions = "shortpixel_suggestions_settings";
152
- break;
153
- case 'media_page_wp-short-pixel-custom':
154
- echo("var shortpixel_suggestions = [ '5a9946e62c7d3a75495145d8', '5a5de1c2042863193801047c', '5a5de2782c7d3a19436843af', '5a5de6902c7d3a19436843e9', '5a5de4f02c7d3a19436843c8', '5a6610c62c7d3a39e6263a02', '5a9945e42c7d3a75495145d0', '5a5de46c2c7d3a19436843c1', '5a5de1de2c7d3a19436843a8', '5a5de25c2c7d3a19436843ad' ]; ");
155
- $suggestions = "shortpixel_suggestions";
156
- break;
157
- }
158
- }
159
- ?>
160
- !function(e,t,n){
161
- function a(){
162
- var e=t.getElementsByTagName("script")[0],n=t.createElement("script");n.type="text/javascript",n.async=!0,n.src="https://beacon-v2.helpscout.net",e.parentNode.insertBefore(n,e)
163
- }
164
- if(e.Beacon=n=function(t,n,a){
165
- e.Beacon.readyQueue.push({method:t,options:n,data:a})
166
- },n.readyQueue=[],"complete"===t.readyState) return a();
167
- e.attachEvent?e.attachEvent("onload",a):e.addEventListener("load",a,!1)
168
- }(window,document,window.Beacon||function(){});
169
- window.Beacon('init', 'e41d21e0-f3c4-4399-bcfe-358e59a860de');
170
-
171
- window.Beacon('identify', {
172
- email: "<?php $u = wp_get_current_user(); echo($u->user_email); ?>",
173
- apiKey: "<?php echo($apikey);?>"
174
- });
175
- window.Beacon('suggest', <?php echo( $suggestions ) ?>);
176
- </script>
177
- <?php
178
- }
179
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
class/plugin.json CHANGED
@@ -1 +1 @@
1
- {"name":"ShortPixel\/Plugin","description":"ShortPixel AutoLoader","type":"function","autoload":{"psr-4":{"ShortPixel":"class"},"files":["class\/wp-shortpixel-settings.php","class\/shortpixel-png2jpg.php","class\/front\/img-to-picture-webp.php","class\/external\/cloudflare.php","class\/external\/flywheel.php","class\/external\/helpscout.php","class\/external\/nextgen\/nextGenController.php","class\/external\/nextgen\/nextGenViewController.php","class\/external\/visualcomposer.php","class\/external\/wp-offload-media.php","class\/external\/wp-cli\/wp-cli-base.php","class\/external\/wp-cli\/wp-cli-single.php","class\/external\/wp-cli\/wp-cli-bulk.php","class\/external\/custom-suffixes.php","class\/external\/pantheon.php","class\/external\/spai.php"]}}
1
+ {"name":"ShortPixel\/Plugin","description":"ShortPixel AutoLoader","type":"function","autoload":{"psr-4":{"ShortPixel":"class"},"files":["class\/wp-shortpixel-settings.php","class\/shortpixel-png2jpg.php","class\/front\/img-to-picture-webp.php","class\/external\/cloudflare.php","class\/external\/flywheel.php","class\/external\/nextgen\/nextGenController.php","class\/external\/nextgen\/nextGenViewController.php","class\/external\/visualcomposer.php","class\/external\/wp-offload-media.php","class\/external\/wp-cli\/wp-cli-base.php","class\/external\/wp-cli\/wp-cli-single.php","class\/external\/wp-cli\/wp-cli-bulk.php","class\/external\/custom-suffixes.php","class\/external\/pantheon.php","class\/external\/spai.php"]}}
class/view/bulk/part-bulk-special.php CHANGED
@@ -79,7 +79,8 @@ use \ShortPixel\Controller\BulkController as BulkController;
79
 
80
  <button class="button" type="button" data-action="open-panel" data-panel="dashboard"><?php _e('Back','shortpixel-image-optimiser'); ?></button>
81
 
82
- <button type="button" type="button" class="button disabled button-primary" disabled id='bulk-migrate-button' data-action="BulkMigrateAll" ><?php _e('Search and migrate All Images', 'shortpixel-image-optimiser') ?></button>
 
83
 
84
  </nav>
85
  </div>
79
 
80
  <button class="button" type="button" data-action="open-panel" data-panel="dashboard"><?php _e('Back','shortpixel-image-optimiser'); ?></button>
81
 
82
+ <button type="button" type="button" class="button disabled button-primary" disabled id='bulk-migrate-button' data-action="BulkMigrateAll" ><?php _e('Search and migrate All Images', 'shortpixel-image-optimiser') ?>
83
+ </button>
84
 
85
  </nav>
86
  </div>
class/view/settings/part-debug.php CHANGED
@@ -161,13 +161,13 @@ $env = \wpSPIO()->env();
161
  foreach($queues as $name => $queue):
162
  $stats = $queue->getStats();
163
  echo "<div>";
164
- echo "<span>" . $name . '</span>';
165
- echo "<span>" . $stats->in_queue . '</span>';
166
- echo "<span>" . $stats->in_process . '</span>';
167
- echo "<span>" . $stats->errors . '</span>';
168
- echo "<span>" . $stats->fatal_errors . '</span>';
169
- echo "<span>" . $stats->done . '</span>';
170
- echo "<span>" . $stats->total . '</span>';
171
 
172
  echo "</div>";
173
  ?>
161
  foreach($queues as $name => $queue):
162
  $stats = $queue->getStats();
163
  echo "<div>";
164
+ echo "<span>" . esc_html($name) . '</span>';
165
+ echo "<span>" . esc_html($stats->in_queue) . '</span>';
166
+ echo "<span>" . esc_html($stats->in_process) . '</span>';
167
+ echo "<span>" . esc_html($stats->errors) . '</span>';
168
+ echo "<span>" . esc_html($stats->fatal_errors) . '</span>';
169
+ echo "<span>" . esc_html($stats->done) . '</span>';
170
+ echo "<span>" . esc_html($stats->total) . '</span>';
171
 
172
  echo "</div>";
173
  ?>
class/view/shortpixel-plugin-request.php CHANGED
@@ -95,9 +95,9 @@ class ShortPixelPluginRequest {
95
  *
96
  */
97
  private function _collect_server_data() {
98
- $this->data['server']['server'] = isset( $_SERVER['SERVER_SOFTWARE'] ) ? $_SERVER['SERVER_SOFTWARE'] : '';
99
  $this->data['server']['php_version'] = phpversion();
100
- $this->data['server']['url'] = home_url();
101
  }
102
 
103
  /**
95
  *
96
  */
97
  private function _collect_server_data() {
98
+ $this->data['server']['server'] = isset( $_SERVER['SERVER_SOFTWARE'] ) ? sanitize_text_field($_SERVER['SERVER_SOFTWARE']) : '';
99
  $this->data['server']['php_version'] = phpversion();
100
+ $this->data['server']['url'] = esc_url(home_url());
101
  }
102
 
103
  /**
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.2
8
  License: GPLv2 or later
9
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
10
 
@@ -309,6 +309,17 @@ Add HTTP basic authentication credentials by defining these constants in wp-conf
309
 
310
  == Changelog ==
311
 
 
 
 
 
 
 
 
 
 
 
 
312
  = 5.0.2 =
313
  Release date June 16th, 2022
314
  * Fix: an uncaught error was fixed for the sites running without the `fileinfo` PHP extension that is needed by the plugin to get the mime type of the files;
4
  Requires at least: 4.8.0
5
  Tested up to: 6.0
6
  Requires PHP: 5.6
7
+ Stable tag: 5.0.3
8
  License: GPLv2 or later
9
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
10
 
309
 
310
  == Changelog ==
311
 
312
+ = 5.0.3 =
313
+ Release date June 21st, 2022
314
+ * Fix: the plugin now recognizes the offloaded WebP/AVIF files, when they are not also present anymore on the server;
315
+ * Fix: in some cases, the bulk and manual optimization was stuck due to some errors related to the legacy optimization information;
316
+ * Fix: when saving the settings, the credits quota and other API-related data will be sent to the API, for faster sync;
317
+ * Fix: when having the backups turned off, a placeholder image was displayed instead of the original one;
318
+ * Fix: an empty space was sometimes shown on some pages, as a result of some dismissed notifications;
319
+ * Fix: various small fixes around the plugin processing engine, for increased speed and stability;
320
+ * Fix: updated various pieces of code in accordance with the WordPress Coding Standards;
321
+ * Language: 1 new string added, 0 updated, 0 fuzzed, and 0 obsoleted.
322
+
323
  = 5.0.2 =
324
  Release date June 16th, 2022
325
  * Fix: an uncaught error was fixed for the sites running without the `fileinfo` PHP extension that is needed by the plugin to get the mime type of the files;
res/js/screens/screen-bulk.js CHANGED
@@ -121,20 +121,23 @@ console.log("Screen Init Done", initMedia, initCustom);
121
  var eventName = (action.getAttribute('data-event')) ? action.getAttribute('data-event') : 'click';
122
 
123
  action.addEventListener(eventName, self.DoActionEvent.bind(self));
 
 
124
  if (action.children.length > 0)
125
  {
126
  for(var i = 0; i < action.children.length; i++)
127
  {
128
- action.children[i].addEventListener(eventName, self.DoActionEvent.bind(self));
129
  }
130
  }
 
131
  });
132
- },
 
133
  this.DoActionEvent = function(event)
134
  {
135
  var element = event.target;
136
- event.preventDefault();
137
- event.stopPropagation();
138
 
139
  // Might be the child
140
  if (element.getAttribute('data-action') == null)
@@ -148,7 +151,6 @@ console.log("Screen Init Done", initMedia, initCustom);
148
  var actionName = element.getAttribute('data-action');
149
  var isPanelAction = (actionName == 'open-panel');
150
 
151
-
152
  if (isPanelAction)
153
  {
154
  var doPanel = element.getAttribute('data-panel');
@@ -161,7 +163,6 @@ console.log("Screen Init Done", initMedia, initCustom);
161
  this[actionName].call(this,event);
162
  }
163
  }
164
-
165
  }
166
 
167
  this.UpdatePanelStatus = function(status, panelName)
@@ -421,8 +422,7 @@ console.log("Screen Init Done", initMedia, initCustom);
421
  preview.querySelector('.new.preview-image .image.source img').src = originalSrc;
422
  }
423
  else {
424
- preview.querySelector('.new.preview-image .image.source img').src = placeHolder;
425
- preview.querySelector('.new.preview-image .image.source img').classList.add('notempty');
426
  }
427
 
428
  if (optimizedSrc)
@@ -430,7 +430,9 @@ console.log("Screen Init Done", initMedia, initCustom);
430
  preview.querySelector('.new.preview-image .image.result img').src = optimizedSrc;
431
  }
432
  else {
433
- preview.querySelector('.new.preview-image .image.result').style.display = 'none';
 
 
434
  }
435
  // currentItem.classList.add('slideleft');
436
  currentItem.style.marginLeft = '-' + offset + 'px';
121
  var eventName = (action.getAttribute('data-event')) ? action.getAttribute('data-event') : 'click';
122
 
123
  action.addEventListener(eventName, self.DoActionEvent.bind(self));
124
+ /*
125
+ This is off, since I can't find any clue that children don't get triggered, but it does create double events when added.
126
  if (action.children.length > 0)
127
  {
128
  for(var i = 0; i < action.children.length; i++)
129
  {
130
+ // action.children[i].addEventListener(eventName, self.DoActionEvent.bind(self));
131
  }
132
  }
133
+ */
134
  });
135
+ }
136
+
137
  this.DoActionEvent = function(event)
138
  {
139
  var element = event.target;
140
+ var action = element.getAttribute('data-action');
 
141
 
142
  // Might be the child
143
  if (element.getAttribute('data-action') == null)
151
  var actionName = element.getAttribute('data-action');
152
  var isPanelAction = (actionName == 'open-panel');
153
 
 
154
  if (isPanelAction)
155
  {
156
  var doPanel = element.getAttribute('data-panel');
163
  this[actionName].call(this,event);
164
  }
165
  }
 
166
  }
167
 
168
  this.UpdatePanelStatus = function(status, panelName)
422
  preview.querySelector('.new.preview-image .image.source img').src = originalSrc;
423
  }
424
  else {
425
+ preview.querySelector('.new.preview-image .image.source').style.display = 'none';
 
426
  }
427
 
428
  if (optimizedSrc)
430
  preview.querySelector('.new.preview-image .image.result img').src = optimizedSrc;
431
  }
432
  else {
433
+ preview.querySelector('.new.preview-image .image.result img').src = placeHolder;
434
+ preview.querySelector('.new.preview-image .image.result img').classList.add('notempty');
435
+
436
  }
437
  // currentItem.classList.add('slideleft');
438
  currentItem.style.marginLeft = '-' + offset + 'px';
res/js/shortpixel-processor.js CHANGED
@@ -99,7 +99,7 @@ window.ShortPixelProcessor =
99
 
100
 
101
  this.tooltip = new ShortPixelToolTip({}, this);
102
-
103
  if (typeof ShortPixelScreen == 'undefined')
104
  {
105
  console.error('Missing Screen!');
@@ -411,6 +411,7 @@ window.ShortPixelProcessor =
411
  // If there are items, give them to the screen for display of optimization, waiting status etc.
412
  var imageHandled = false; // Only post one image per result-set to the ImageHandler (on bulk), to prevent flooding.
413
 
 
414
  if (typeof response.results !== 'undefined' && response.results !== null)
415
  {
416
  for (var i = 0; i < response.results.length; i++)
@@ -436,9 +437,10 @@ window.ShortPixelProcessor =
436
  if (typeof response.result !== 'undefined' && response.result !== null)
437
  {
438
  if (response.result.is_error)
439
- this.HandleItemError(response.result, type);
440
-
441
- if (! imageHandled)
 
442
  {
443
  imageHandled = this.screen.HandleImage(response, type); // whole response here is single item. (final!)
444
  }
@@ -500,11 +502,8 @@ window.ShortPixelProcessor =
500
  else if (qstatus == "PREPARING_DONE")
501
  {
502
  console.log('Processor: Preparing is done');
503
- //this.tooltip.ProcessEnd();
504
  this.StopProcess();
505
 
506
- //if (typeof this.screen.preparingDone == 'function')
507
- // this.screen.PreparingDone();
508
  }
509
 
510
  // React to status of the queue.
@@ -512,6 +511,7 @@ window.ShortPixelProcessor =
512
  this.screen.QueueStatus(qstatus, data);
513
  }
514
  },
 
515
  HandleItemError : function(result, type)
516
  {
517
  console.log('Handle Item Error', result, type);
99
 
100
 
101
  this.tooltip = new ShortPixelToolTip({}, this);
102
+
103
  if (typeof ShortPixelScreen == 'undefined')
104
  {
105
  console.error('Missing Screen!');
411
  // If there are items, give them to the screen for display of optimization, waiting status etc.
412
  var imageHandled = false; // Only post one image per result-set to the ImageHandler (on bulk), to prevent flooding.
413
 
414
+ // @todo Make sure that .result and .results can be iterated the same.
415
  if (typeof response.results !== 'undefined' && response.results !== null)
416
  {
417
  for (var i = 0; i < response.results.length; i++)
437
  if (typeof response.result !== 'undefined' && response.result !== null)
438
  {
439
  if (response.result.is_error)
440
+ {
441
+ this.HandleItemError(response.result, type);
442
+ }
443
+ elseif (! imageHandled)
444
  {
445
  imageHandled = this.screen.HandleImage(response, type); // whole response here is single item. (final!)
446
  }
502
  else if (qstatus == "PREPARING_DONE")
503
  {
504
  console.log('Processor: Preparing is done');
 
505
  this.StopProcess();
506
 
 
 
507
  }
508
 
509
  // React to status of the queue.
511
  this.screen.QueueStatus(qstatus, data);
512
  }
513
  },
514
+
515
  HandleItemError : function(result, type)
516
  {
517
  console.log('Handle Item Error', result, type);
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.2
7
  * Author: ShortPixel
8
  * Author URI: https://shortpixel.com
9
  * GitHub Plugin URI: https://github.com/short-pixel-optimizer/shortpixel-image-optimiser
@@ -30,7 +30,7 @@ if (! defined('SHORTPIXEL_RESET_ON_ACTIVATE'))
30
  define('SHORTPIXEL_PLUGIN_FILE', __FILE__);
31
  define('SHORTPIXEL_PLUGIN_DIR', __DIR__);
32
 
33
- define('SHORTPIXEL_IMAGE_OPTIMISER_VERSION', "5.0.2");
34
 
35
  define('SHORTPIXEL_BACKUP', 'ShortpixelBackups');
36
  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.3
7
  * Author: ShortPixel
8
  * Author URI: https://shortpixel.com
9
  * GitHub Plugin URI: https://github.com/short-pixel-optimizer/shortpixel-image-optimiser
30
  define('SHORTPIXEL_PLUGIN_FILE', __FILE__);
31
  define('SHORTPIXEL_PLUGIN_DIR', __DIR__);
32
 
33
+ define('SHORTPIXEL_IMAGE_OPTIMISER_VERSION', "5.0.3");
34
 
35
  define('SHORTPIXEL_BACKUP', 'ShortpixelBackups');
36
  define('SHORTPIXEL_MAX_FAIL_RETRIES', 3);