ShortPixel Image Optimizer - Version 4.18.0

Version Description

Release date 7th May 2020 * Added a warning for the case when Imagik library isn't available and "Keep EXIF data is enabled"; * Added a check to prevent the bulk process to be called in multiple browsers in order to decrease the load on admin-heavy sites; * Fix for the situation when the bulk process would enter a loop in certain situations; * Fix for the notices after bulk restore that would duplicate the files missing form backups; * Fix for multisite when DB tables were created even for sub-sites without the plugin being active; * Language 1 new strings added, 0 updated, 0 fuzzied, and 5 obsoleted.

Download this release

Release Info

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

Code changes from version 4.17.4 to 4.18.0

build/shortpixel/notices/src/NoticeModel.php CHANGED
@@ -89,10 +89,11 @@ class NoticeModel //extends ShortPixelModel
89
  */
90
  public function addDetail($detail, $clean = false)
91
  {
92
- if (! $clean)
93
- $this->details[] = $detail;
94
- else
95
- $this->details = array($detail);
 
96
  }
97
 
98
 
89
  */
90
  public function addDetail($detail, $clean = false)
91
  {
92
+ if ($clean)
93
+ $this->details = array();
94
+
95
+ if (! in_array($detail, $this->details) )
96
+ $this->details[] = $detail;
97
  }
98
 
99
 
class/controller/adminnotices_controller.php CHANGED
@@ -325,7 +325,7 @@ class adminNoticesController extends ShortPixelController
325
  $quotaData = $stats;
326
 
327
  $message = $this->getQuotaExceededMessage($quotaData);
328
- Log::addtemp('Quota Exceeded message', $message);
329
  $notice = Notices::addError($message);
330
  Notices::makePersistent($notice, self::MSG_QUOTA_REACHED, WEEK_IN_SECONDS);
331
 
325
  $quotaData = $stats;
326
 
327
  $message = $this->getQuotaExceededMessage($quotaData);
328
+
329
  $notice = Notices::addError($message);
330
  Notices::makePersistent($notice, self::MSG_QUOTA_REACHED, WEEK_IN_SECONDS);
331
 
class/controller/bulk-restore-all.php CHANGED
@@ -1,82 +1,2 @@
1
  <?php
2
- namespace ShortPixel;
3
-
4
- class BulkRestoreAll extends ShortPixelController
5
- {
6
- protected static $slug = 'bulk-restore-all';
7
- protected $template = 'view-restore-all';
8
- protected $form_action = 'bulk-restore-all';
9
-
10
- protected $selected_folders = array();
11
-
12
- public function __construct()
13
- {
14
- parent::__construct();
15
-
16
- }
17
-
18
- public function randomCheck()
19
- {
20
-
21
- $output = '';
22
- for ($i=1; $i<= 10; $i++)
23
- {
24
- $output .= "<span><input type='radio' name='random_check[]' value='$i' onchange='ShortPixel.checkRandomAnswer(event)' /> $i </span>";
25
- }
26
-
27
- return $output;
28
- }
29
-
30
- public function randomAnswer()
31
- {
32
- $correct = rand(1,10);
33
- $output = "<input type='hidden' name='random_answer' value='$correct' data-target='#bulkRestore' /> <span class='answer'>$correct</span> ";
34
-
35
- return $output;
36
- }
37
-
38
- public function getCustomFolders()
39
- {
40
- //wpshortPixel::refreshCustomFolders();
41
- //$spMetaDao = $this->shortPixel->getSpMetaDao();
42
- //$customFolders = $spMetaDao->getFolders();
43
- $otherMedia = new OtherMediaController();
44
-
45
- return $otherMedia->getAllFolders();
46
-
47
- }
48
-
49
- protected function processPostData($post)
50
- {
51
- if (isset($post['selected_folders']))
52
- {
53
- $folders = array_filter($post['selected_folders'], 'intval');
54
- if (count($folders) > 0)
55
- {
56
- $this->selected_folders = $folders;
57
- }
58
- unset($post['selected_folders']);
59
- }
60
-
61
- parent::processPostData($post);
62
-
63
- }
64
-
65
- public function setupBulk()
66
- {
67
- $this->checkPost(); // check if any POST vars are there ( which should be if custom restore is on )
68
-
69
- // handle the custom folders if there are any.
70
- if (count($this->selected_folders) > 0)
71
- {
72
- $spMetaDao = \wpSPIO()->getShortPixel()->getSpMetaDao();
73
-
74
- foreach($this->selected_folders as $folder_id)
75
- {
76
- $spMetaDao->setBulkRestore($folder_id);
77
- }
78
- }
79
- }
80
-
81
-
82
- }
1
  <?php
2
+ // Silence is golden.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
class/controller/cache_controller.php CHANGED
@@ -37,7 +37,6 @@ class CacheController extends ShortPixelController
37
  {
38
  self::$cached_items[$cache->getName()] = $cache;
39
  $cache->save();
40
-
41
  }
42
 
43
  public function getItem($name)
37
  {
38
  self::$cached_items[$cache->getName()] = $cache;
39
  $cache->save();
 
40
  }
41
 
42
  public function getItem($name)
class/controller/controller.php CHANGED
@@ -47,6 +47,8 @@ class ShortPixelController
47
  return $className; // found!
48
  }
49
  }
 
 
50
  }
51
 
52
  public function __construct()
47
  return $className; // found!
48
  }
49
  }
50
+
51
+ return false;
52
  }
53
 
54
  public function __construct()
class/controller/settings.php CHANGED
@@ -171,6 +171,9 @@ class SettingsController extends shortPixelController
171
  {
172
  if ($this->is_verifiedkey) // supress quotaData alerts when handing unset API's.
173
  $this->loadQuotaData();
 
 
 
174
 
175
  $this->view->data = (Object) $this->model->getData();
176
  if (($this->is_constant_key))
@@ -273,7 +276,7 @@ class SettingsController extends shortPixelController
273
 
274
  protected function loadCustomFolders()
275
  {
276
-
277
  $otherMedia = new OtherMediaController();
278
 
279
  $otherMedia->refreshFolders();
171
  {
172
  if ($this->is_verifiedkey) // supress quotaData alerts when handing unset API's.
173
  $this->loadQuotaData();
174
+ else
175
+ \WpShortPixelDb::checkCustomTables();
176
+
177
 
178
  $this->view->data = (Object) $this->model->getData();
179
  if (($this->is_constant_key))
276
 
277
  protected function loadCustomFolders()
278
  {
279
+
280
  $otherMedia = new OtherMediaController();
281
 
282
  $otherMedia->refreshFolders();
class/controller/views/bulk-restore-all.php ADDED
@@ -0,0 +1,91 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace ShortPixel;
3
+ use ShortPixel\ShortpixelLogger\ShortPixelLogger as Log;
4
+
5
+
6
+ class BulkRestoreAll extends ShortPixelController
7
+ {
8
+ protected static $slug = 'bulk-restore-all';
9
+ protected $template = 'view-restore-all';
10
+ protected $form_action = 'sp-bulk';
11
+
12
+ protected $selected_folders = array();
13
+
14
+ public function __construct()
15
+ {
16
+ parent::__construct();
17
+
18
+ }
19
+
20
+ public function load()
21
+ {
22
+ $this->loadView();
23
+ }
24
+
25
+ public function randomCheck()
26
+ {
27
+
28
+ $output = '';
29
+ for ($i=1; $i<= 10; $i++)
30
+ {
31
+ $output .= "<span><input type='radio' name='random_check[]' value='$i' onchange='ShortPixel.checkRandomAnswer(event)' /> $i </span>";
32
+ }
33
+
34
+ return $output;
35
+ }
36
+
37
+ public function randomAnswer()
38
+ {
39
+ $correct = rand(1,10);
40
+ $output = "<input type='hidden' name='random_answer' value='$correct' data-target='#bulkRestore' /> <span class='answer'>$correct</span> ";
41
+
42
+ return $output;
43
+ }
44
+
45
+ public function getCustomFolders()
46
+ {
47
+ //wpshortPixel::refreshCustomFolders();
48
+ //$spMetaDao = $this->shortPixel->getSpMetaDao();
49
+ //$customFolders = $spMetaDao->getFolders();
50
+ $otherMedia = new OtherMediaController();
51
+
52
+ return $otherMedia->getAllFolders();
53
+
54
+ }
55
+
56
+ protected function processPostData($post)
57
+ {
58
+ if (isset($post['selected_folders']))
59
+ {
60
+ $folders = array_filter($post['selected_folders'], 'intval');
61
+ if (count($folders) > 0)
62
+ {
63
+ $this->selected_folders = $folders;
64
+ }
65
+ unset($post['selected_folders']);
66
+ }
67
+
68
+ parent::processPostData($post);
69
+
70
+ }
71
+
72
+ public function setupBulk()
73
+ {
74
+ // Not doing this, since it's deliverd from bulk_view_controller. Yes, this is hacky. Prob. controller should merge.
75
+ // $this->checkPost(); // check if any POST vars are there ( which should be if custom restore is on )
76
+ $selected_folders = isset($_POST['selected_folders']) ? $_POST['selected_folders'] : array();
77
+
78
+ // handle the custom folders if there are any.
79
+ if (count($selected_folders) > 0)
80
+ {
81
+ $spMetaDao = \wpSPIO()->getShortPixel()->getSpMetaDao();
82
+
83
+ foreach($selected_folders as $folder_id)
84
+ {
85
+ $spMetaDao->setBulkRestore($folder_id);
86
+ }
87
+ }
88
+ }
89
+
90
+
91
+ }
class/controller/views/bulk_view_controller.php ADDED
@@ -0,0 +1,211 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace ShortPixel;
3
+ use ShortPixel\ShortpixelLogger\ShortPixelLogger as Log;
4
+ use ShortPixel\Notices\NoticeController as Notices;
5
+
6
+ class BulkViewController extends ShortPixelController
7
+ {
8
+
9
+ protected $form_action = 'sp-bulk';
10
+
11
+ protected $quotaData;
12
+ protected $pendingMeta;
13
+ protected $selected_folders = array();
14
+
15
+ public function load()
16
+ {
17
+ $this->checkPost();
18
+ if ($this->is_form_submit)
19
+ {
20
+ $this->doBulkAction();
21
+ }
22
+
23
+ $this->quotaData = \wpSPIO()->getShortPixel()->checkQuotaAndAlert(null, isset($_GET['checkquota']), 0);
24
+
25
+ if ($this->checkDoingBulk())
26
+ {
27
+ $this->loadViewProgress();
28
+ }
29
+ else
30
+ {
31
+ $this->loadView();
32
+ }
33
+
34
+ }
35
+
36
+ public function checkDoingBulk()
37
+ {
38
+ $prioQ = \wpSPIO()->getShortPixel()->getPrioQ();
39
+ $settings = \wpSPIO()->settings();
40
+ $spMetaDao = \wpSPIO()->getShortPixel()->getSPMetaDao();
41
+
42
+ global $wpdb;
43
+
44
+ $qry_left = "SELECT count(meta_id) FilesLeftToBeProcessed FROM " . $wpdb->prefix . "postmeta
45
+ WHERE meta_key = '_wp_attached_file' AND post_id <= " . (0 + $prioQ->getStartBulkId());
46
+ $filesLeft = $wpdb->get_results($qry_left);
47
+
48
+ //check the custom bulk
49
+ $pendingMeta = $settings->hasCustomFolders ? $spMetaDao->getPendingMetaCount() : 0;
50
+
51
+ $this->pendingMeta = $pendingMeta;
52
+
53
+
54
+ return ( ($filesLeft[0]->FilesLeftToBeProcessed > 0 && $prioQ->bulkRunning())
55
+ || (0 + $pendingMeta > 0 && !$settings->customBulkPaused && $prioQ->bulkRan() )//bulk processing was started
56
+ && (!$prioQ->bulkPaused() || $settings->skipToCustom));
57
+ }
58
+
59
+ public function doBulkAction()
60
+ {
61
+ $spMetaDao = \wpSPIO()->getShortPixel()->getSPMetaDao();
62
+ $prioQ = \wpSPIO()->getShortPixel()->getPrioQ();
63
+ $settings = \wpSPIO()->settings();
64
+
65
+ if(isset($_POST['bulkProcessPause']))
66
+ {//pause an ongoing bulk processing, it might be needed sometimes
67
+ $prioQ->pauseBulk();
68
+ if($settings->hasCustomFolders && $spMetaDao->getPendingMetaCount()) {
69
+ $settings->customBulkPaused = 1;
70
+ }
71
+ }
72
+
73
+ if(isset($_POST['bulkProcessStop']))
74
+ {//stop an ongoing bulk processing
75
+ $prioQ->stopBulk();
76
+ if($settings->hasCustomFolders && $spMetaDao->getPendingMetaCount()) {
77
+ $settings->customBulkPaused = 1;
78
+ }
79
+ $settings->cancelPointer = NULL;
80
+ }
81
+
82
+ if(isset($_POST["bulkProcess"]))
83
+ {
84
+ //set the thumbnails option
85
+ if ( isset($_POST['thumbnails']) ) {
86
+ $settings->processThumbnails = 1;
87
+ } else {
88
+ $settings->processThumbnails = 0;
89
+ }
90
+
91
+ if ( isset($_POST['createWebp']) )
92
+ $settings->createWebp = 1;
93
+ else
94
+ $settings->createWebp = 0;
95
+
96
+ //clean the custom files errors in order to process them again
97
+ if($settings->hasCustomFolders) {
98
+ $spMetaDao->resetFailed();
99
+ $spMetaDao->resetRestored();
100
+ $spMetaDao->setPending();
101
+ }
102
+
103
+ $prioQ->startBulk(\ShortPixelQueue::BULK_TYPE_OPTIMIZE);
104
+ $settings->customBulkPaused = 0;
105
+ Log::addInfo("BULK: Start: " . $prioQ->getStartBulkId() . ", stop: " . $prioQ->getStopBulkId() . " PrioQ: "
106
+ .json_encode($prioQ->get()));
107
+ }//end bulk process was clicked
108
+
109
+ if(isset($_POST["bulkRestore"]))
110
+ {
111
+ Log::addInfo('Bulk Process - Bulk Restore');
112
+ $bulkRestore = new \ShortPixel\BulkRestoreAll(); // controller
113
+ $bulkRestore->setupBulk();
114
+
115
+ $prioQ->startBulk(\ShortPixelQueue::BULK_TYPE_RESTORE);
116
+ $settings->customBulkPaused = 0;
117
+ }//end bulk restore was clicked
118
+
119
+ if(isset($_POST["bulkCleanup"]))
120
+ {
121
+ Log::addInfo('Bulk Process - Bulk Cleanup ');
122
+ $prioQ->startBulk(\ShortPixelQueue::BULK_TYPE_CLEANUP);
123
+ $settings->customBulkPaused = 0;
124
+ }//end bulk restore was clicked
125
+
126
+ if(isset($_POST["bulkCleanupPending"]))
127
+ {
128
+ Log::addInfo('Bulk Process - Clean Pending');
129
+ $prioQ->startBulk(\ShortPixelQueue::BULK_TYPE_CLEANUP_PENDING);
130
+ $settings->customBulkPaused = 0;
131
+ }//end bulk restore was clicked
132
+
133
+ if(isset($_POST["bulkProcessResume"]))
134
+ {
135
+ Log::addInfo('Bulk Process - Bulk Resume');
136
+ $prioQ->resumeBulk();
137
+ $settings->customBulkPaused = 0;
138
+ }//resume was clicked
139
+
140
+ if(isset($_POST["skipToCustom"]))
141
+ {
142
+ Log::addInfo('Bulk Process - Skipping to Custom Media Process');
143
+ $settings->skipToCustom = true;
144
+ $settings->customBulkPaused = 0;
145
+
146
+ }//resume was clicked
147
+
148
+ }
149
+
150
+ public function loadView($template = null)
151
+ {
152
+ $settings = \wpSPIO()->settings();
153
+ $prioQ = \wpSPIO()->getShortPixel()->getPrioQ();
154
+ /*
155
+ $template_part = isset($_GET['part']) ? sanitize_text_field($_GET['part']) : false;
156
+ $controller = \ShortPixelTools::namespaceit('ShortPixelController');
157
+ $partControl = $controller::findControllerbySlug($template_part);
158
+
159
+ if ($partControl)
160
+ {
161
+ $viewObj = new $partControl();
162
+ $viewObj->setShortPixel($this);
163
+ $viewObj->loadView(); // TODO [BS] This should call load, which should init and call view inside controller.
164
+ }
165
+
166
+ if (! $template_part)
167
+ { */
168
+ $averageCompression = \wpSPIO()->getShortPixel()->getAverageCompression();
169
+ $thumbsProcessedCount = $settings->thumbsCount;//amount of optimized thumbnails
170
+ $under5PercentCount = $settings->under5Percent;//amount of under 5% optimized imgs.
171
+ $quotaData = $this->quotaData;
172
+ $percent = $prioQ->bulkPaused() ? \wpSPIO()->getShortPixel()->getPercent($quotaData) : false;
173
+
174
+ $view = new \ShortPixelView(\wpSPIO()->getShortPixel());
175
+ $view->displayBulkProcessingForm($quotaData, $thumbsProcessedCount, $under5PercentCount,
176
+ $prioQ->bulkRan(), $averageCompression, $settings->fileCount,
177
+ \ShortPixelTools::formatBytes($settings->savedSpace), $percent, $this->pendingMeta);
178
+ // }
179
+ }
180
+
181
+ public function loadViewProgress()
182
+ {
183
+ $settings = \wpSPIO()->settings();
184
+ $prioQ = \wpSPIO()->getShortPixel()->getPrioQ();
185
+
186
+ if($settings->quotaExceeded == 1) {
187
+ \ShortPixel\adminNoticesController::reInstateQuotaExceeded();
188
+ return false;
189
+ }
190
+
191
+ if( $settings->verifiedKey == false ) {//invalid API Key
192
+ return;
193
+ }
194
+
195
+ $quotaData = $this->quotaData;
196
+ $prioQ = \wpSPIO()->getShortPixel()->getPrioQ();
197
+
198
+ //average compression
199
+ $averageCompression = \wpSPIO()->getShortPixel()->getAverageCompression();
200
+
201
+ $msg = \wpSPIO()->getShortPixel()->bulkProgressMessage($prioQ->getDeltaBulkPercent(), $prioQ->getTimeRemaining());
202
+
203
+ $view = new \ShortPixelView(\wpSPIO()->getShortPixel());
204
+ $view->displayBulkProcessingRunning(\wpSPIO()->getShortPixel()->getPercent($quotaData), $msg, $quotaData['APICallsRemaining'], $averageCompression,
205
+ $prioQ->getBulkType() == \ShortPixelQueue::BULK_TYPE_RESTORE ? 0 :
206
+ ( $prioQ->getBulkType() == \ShortPixelQueue::BULK_TYPE_CLEANUP
207
+ || $prioQ->getBulkType() == \ShortPixelQueue::BULK_TYPE_CLEANUP_PENDING ? -1 : ($this->pendingMeta !== null ? ($prioQ->bulkRunning() ? 3 : 2) : 1)), $quotaData);
208
+
209
+ }
210
+
211
+ } // class
class/db/shortpixel-custom-meta-dao.php CHANGED
@@ -116,6 +116,7 @@ class ShortPixelCustomMetaDao {
116
  }
117
 
118
  public function createUpdateShortPixelTables() {
 
119
  $res = $this->db->createUpdateSchema(array(
120
  self::getCreateFolderTableSQL($this->db->getPrefix(), $this->db->getCharsetCollate()),
121
  self::getCreateMetaTableSQL($this->db->getPrefix(), $this->db->getCharsetCollate())
@@ -306,7 +307,7 @@ class ShortPixelCustomMetaDao {
306
  $placeholders = array();
307
  $status = (\wpSPIO()->settings()->autoMediaLibrary == 1) ? ShortPixelMeta::FILE_STATUS_PENDING : ShortPixelMeta::FILE_STATUS_UNPROCESSED;
308
  $created = date("Y-m-d H:i:s");
309
-
310
  foreach($files as $file) {
311
  $filepath = $file->getFullPath();
312
  $filename = $file->getFileName();
@@ -348,6 +349,13 @@ class ShortPixelCustomMetaDao {
348
  $this->db->query($sql);
349
  }
350
 
 
 
 
 
 
 
 
351
  public function getPaginatedMetas($hasNextGen, $filters, $count, $page, $orderby = false, $order = false) {
352
  // [BS] Remove exclusion for sm.status <> 3. Status 3 is 'restored, perform no action'
353
  if ($page <= 0)
@@ -395,7 +403,7 @@ class ShortPixelCustomMetaDao {
395
  public function getPendingMetaCount() {
396
  $res = $this->db->query("SELECT COUNT(sm.id) recCount from {$this->db->getPrefix()}shortpixel_meta sm "
397
  . "INNER JOIN {$this->db->getPrefix()}shortpixel_folders sf on sm.folder_id = sf.id "
398
- . "WHERE sf.status <> -1 AND sm.status <> 3 AND ( sm.status = 0 OR sm.status = 1 OR (sm.status < 0 AND sm.retries < 3))");
399
  return isset($res[0]->recCount) ? $res[0]->recCount : null;
400
  }
401
 
116
  }
117
 
118
  public function createUpdateShortPixelTables() {
119
+
120
  $res = $this->db->createUpdateSchema(array(
121
  self::getCreateFolderTableSQL($this->db->getPrefix(), $this->db->getCharsetCollate()),
122
  self::getCreateMetaTableSQL($this->db->getPrefix(), $this->db->getCharsetCollate())
307
  $placeholders = array();
308
  $status = (\wpSPIO()->settings()->autoMediaLibrary == 1) ? ShortPixelMeta::FILE_STATUS_PENDING : ShortPixelMeta::FILE_STATUS_UNPROCESSED;
309
  $created = date("Y-m-d H:i:s");
310
+
311
  foreach($files as $file) {
312
  $filepath = $file->getFullPath();
313
  $filename = $file->getFileName();
349
  $this->db->query($sql);
350
  }
351
 
352
+ /** When auto-optimize is off, the status is 0 ( not processed ), so that the usuals SPIO JS doesn't pick it up. Put custom to pending when starting bulk */
353
+ public function setPending()
354
+ {
355
+ $sql = "UPDATE {$this->db->getPrefix()}shortpixel_meta SET status = 1, retries = 0 WHERE status = 0";
356
+ $this->db->query($sql);
357
+ }
358
+
359
  public function getPaginatedMetas($hasNextGen, $filters, $count, $page, $orderby = false, $order = false) {
360
  // [BS] Remove exclusion for sm.status <> 3. Status 3 is 'restored, perform no action'
361
  if ($page <= 0)
403
  public function getPendingMetaCount() {
404
  $res = $this->db->query("SELECT COUNT(sm.id) recCount from {$this->db->getPrefix()}shortpixel_meta sm "
405
  . "INNER JOIN {$this->db->getPrefix()}shortpixel_folders sf on sm.folder_id = sf.id "
406
+ . "WHERE sf.status <> -1 AND sm.status <> 3 AND ( sm.status = 1 OR (sm.status < 0 AND sm.retries < 3))");
407
  return isset($res[0]->recCount) ? $res[0]->recCount : null;
408
  }
409
 
class/db/wp-shortpixel-db.php CHANGED
@@ -28,21 +28,52 @@ class WpShortPixelDb implements ShortPixelDb {
28
 
29
  public static function checkCustomTables() {
30
  global $wpdb;
31
- if(function_exists("is_multisite") && is_multisite()) {
32
- $sites = function_exists("get_sites") ? get_sites() : wp_get_sites();
 
 
 
 
 
 
 
 
33
  foreach($sites as $site) {
34
- if(!is_array($site)) {
35
- $site = (array)$site;
36
- }
37
- $prefix = $wpdb->get_blog_prefix($site['blog_id']);
38
- $spMetaDao = new ShortPixelCustomMetaDao(new WpShortPixelDb($prefix));
39
- $spMetaDao->createUpdateShortPixelTables();
40
  }
41
 
42
- } else {
43
- $spMetaDao = new ShortPixelCustomMetaDao(new WpShortPixelDb());
44
- $spMetaDao->createUpdateShortPixelTables();
45
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
46
  }
47
 
48
  public function getCharsetCollate() {
@@ -52,7 +83,8 @@ class WpShortPixelDb implements ShortPixelDb {
52
 
53
  public function getPrefix() {
54
  global $wpdb;
55
- return $this->prefix ? $this->prefix : $wpdb->prefix;
 
56
  }
57
 
58
  public function getDbName() {
28
 
29
  public static function checkCustomTables() {
30
  global $wpdb;
31
+
32
+ /*$slug = \wpSPIO()->env()->getRelativePluginSlug();
33
+ $network_active = \wpSPIO()->env()->is_multisite && function_exists('is_plugin_active_for_network') && is_plugin_active_for_network($slug) ? true : false;
34
+
35
+ if($network_active)
36
+ {
37
+ if (! function_exists("get_sites") )
38
+ { exit('get_sites fail'); return null; }
39
+
40
+ $sites = get_sites();
41
  foreach($sites as $site) {
42
+ $site_id = $site->blog_id;
43
+ $prefix = $wpdb->get_blog_prefix($site_id);
44
+
45
+
46
+ $spMetaDao = new ShortPixelCustomMetaDao(new WpShortPixelDb($prefix));
47
+ $spMetaDao->createUpdateShortPixelTables();
48
  }
49
 
50
+ } else { */
51
+
52
+ /* if (! $spMetaDao->tablesExist())
53
+ {
54
+
55
+ } */
56
+ /* **** **** **** **** **** **** **** **** **** ***** **** **** **** ****
57
+ * Check why database is not created like this.
58
+ */
59
+ $spMetaDao = new ShortPixelCustomMetaDao(new WpShortPixelDb());
60
+
61
+ $spMetaDao->createUpdateShortPixelTables();
62
+ //}
63
+ }
64
+
65
+ private static function activeOnBlog($site, $slug)
66
+ {
67
+ $option = get_blog_option($site, 'active_plugins');
68
+
69
+ var_dump($option);
70
+ foreach($option as $active_slug)
71
+ {
72
+ if ($active_slug == $slug)
73
+ return true;
74
+ }
75
+
76
+ return false;
77
  }
78
 
79
  public function getCharsetCollate() {
83
 
84
  public function getPrefix() {
85
  global $wpdb;
86
+ // return $this->prefix ? $this->prefix : $wpdb->prefix;
87
+ return $wpdb->prefix;
88
  }
89
 
90
  public function getDbName() {
class/external/nextgen.php CHANGED
@@ -326,7 +326,6 @@ class nextGenView
326
  'message' => "Not optimized"
327
  ));
328
  }
329
- // return var_dump($meta);
330
  }
331
 
332
  } // class
326
  'message' => "Not optimized"
327
  ));
328
  }
 
329
  }
330
 
331
  } // class
class/model/directory_model.php CHANGED
@@ -32,13 +32,15 @@ class DirectoryModel extends ShortPixelModel
32
  public function __construct($path)
33
  {
34
  $path = wp_normalize_path($path);
35
- if (! is_dir($path)) // path is wrong, *or* simply doesn't exist.
 
36
  {
37
  /* Test for file input.
38
  * If pathinfo is fed a fullpath, it rips of last entry without setting extension, don't further trust.
39
  * If it's a file extension is set, then trust.
40
  */
41
  $pathinfo = pathinfo($path);
 
42
  if (isset($pathinfo['extension']))
43
  {
44
  $path = $pathinfo['dirname'];
@@ -58,7 +60,11 @@ class DirectoryModel extends ShortPixelModel
58
  }
59
 
60
  $this->path = trailingslashit($path);
61
- $this->name = basename($this->path);
 
 
 
 
62
 
63
  if (file_exists($this->path))
64
  {
@@ -322,4 +328,15 @@ class DirectoryModel extends ShortPixelModel
322
  return false;
323
  }
324
 
 
 
 
 
 
 
 
 
 
 
 
325
  }
32
  public function __construct($path)
33
  {
34
  $path = wp_normalize_path($path);
35
+
36
+ if (! is_dir($path) ) // path is wrong, *or* simply doesn't exist.
37
  {
38
  /* Test for file input.
39
  * If pathinfo is fed a fullpath, it rips of last entry without setting extension, don't further trust.
40
  * If it's a file extension is set, then trust.
41
  */
42
  $pathinfo = pathinfo($path);
43
+
44
  if (isset($pathinfo['extension']))
45
  {
46
  $path = $pathinfo['dirname'];
60
  }
61
 
62
  $this->path = trailingslashit($path);
63
+
64
+ // Basename doesn't work properly on non-latin ( cyrillic, greek etc ) directory names, returning the parent path instead.
65
+ $dir = new \SplFileInfo($path);
66
+ //basename($this->path);
67
+ $this->name = $dir->getFileName();
68
 
69
  if (file_exists($this->path))
70
  {
328
  return false;
329
  }
330
 
331
+ /** Get this paths parent */
332
+ public function getParent()
333
+ {
334
+ $path = $this->getPath();
335
+ $parentPath = dirname($path);
336
+
337
+ $parentDir = new DirectoryModel($parentPath);
338
+
339
+ return $parentDir;
340
+ }
341
+
342
  }
class/model/directory_othermedia_model.php CHANGED
@@ -286,6 +286,7 @@ class DirectoryOtherMediaModel extends DirectoryModel
286
 
287
  // $folderObj->setFileCount( count($files) );
288
 
 
289
  \wpSPIO()->getShortPixel()->getSpMetaDao()->batchInsertImages($files, $this->id);
290
 
291
  $stats = $this->getStats();
286
 
287
  // $folderObj->setFileCount( count($files) );
288
 
289
+ \wpSPIO()->settings()->hasCustomFolders = time(); // note, check this against bulk when removing. Custom Media Bulk depends on having a setting.
290
  \wpSPIO()->getShortPixel()->getSpMetaDao()->batchInsertImages($files, $this->id);
291
 
292
  $stats = $this->getStats();
class/model/environment_model.php CHANGED
@@ -59,7 +59,7 @@ class EnvironmentModel extends ShortPixelModel
59
 
60
  /** Check ENV is a specific function is allowed. Use this with functions that might be turned off on configurations
61
  * @param $function String The name of the function being tested
62
- * Note: In future this function can be extended with other function edge cases.
63
  */
64
  public function is_function_usable($function)
65
  {
@@ -79,6 +79,18 @@ class EnvironmentModel extends ShortPixelModel
79
 
80
  }
81
 
 
 
 
 
 
 
 
 
 
 
 
 
82
  private function setServer()
83
  {
84
  $this->is_nginx = strpos(strtolower($_SERVER["SERVER_SOFTWARE"]), 'nginx') !== false ? true : false;
@@ -166,4 +178,19 @@ class EnvironmentModel extends ShortPixelModel
166
  $this->has_nextgen = $ng->has_nextgen();
167
 
168
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
169
  }
59
 
60
  /** Check ENV is a specific function is allowed. Use this with functions that might be turned off on configurations
61
  * @param $function String The name of the function being tested
62
+ * Note: In future this function can be extended with other function edge cases.
63
  */
64
  public function is_function_usable($function)
65
  {
79
 
80
  }
81
 
82
+ /* https://github.com/WordPress/WordPress/blob/master/wp-includes/class-wp-image-editor-imagick.php */
83
+ public function hasImagick()
84
+ {
85
+ $editor = wp_get_image_editor(\wpSPIO()->plugin_path('res/img/test.jpg'));
86
+ $className = get_class($editor);
87
+
88
+ if ($className == 'WP_Image_Editor_Imagick')
89
+ return true;
90
+ else
91
+ return false;
92
+ }
93
+
94
  private function setServer()
95
  {
96
  $this->is_nginx = strpos(strtolower($_SERVER["SERVER_SOFTWARE"]), 'nginx') !== false ? true : false;
178
  $this->has_nextgen = $ng->has_nextgen();
179
 
180
  }
181
+
182
+ public function getRelativePluginSlug()
183
+ {
184
+ $dir = SHORTPIXEL_PLUGIN_DIR;
185
+ $file = SHORTPIXEL_PLUGIN_FILE;
186
+
187
+ $fs = \wpSPIO()->filesystem();
188
+
189
+ $plugins_dir = $fs->getDirectory($dir)->getParent();
190
+
191
+ $slug = str_replace($plugins_dir->getPath(), '', $file);
192
+
193
+ return $slug;
194
+
195
+ }
196
  }
class/view/settings/part-advanced.php CHANGED
@@ -41,6 +41,7 @@ namespace ShortPixel;
41
  }
42
  $excludePatterns = substr($excludePatterns, 0, -2);
43
  }
 
44
  ?>
45
 
46
  <div class="wp-shortpixel-options wp-shortpixel-tab-content" style='visibility: hidden'>
@@ -72,7 +73,7 @@ namespace ShortPixel;
72
  $stat = $dirObj->getStats();
73
 
74
  $cnt = $stat->Total;
75
-
76
  $st = ($cnt == 0
77
  ? __("Empty",'shortpixel-image-optimiser')
78
  : ($stat->Total == $stat->Optimized
41
  }
42
  $excludePatterns = substr($excludePatterns, 0, -2);
43
  }
44
+
45
  ?>
46
 
47
  <div class="wp-shortpixel-options wp-shortpixel-tab-content" style='visibility: hidden'>
73
  $stat = $dirObj->getStats();
74
 
75
  $cnt = $stat->Total;
76
+
77
  $st = ($cnt == 0
78
  ? __("Empty",'shortpixel-image-optimiser')
79
  : ($stat->Total == $stat->Optimized
class/view/settings/part-debug.php CHANGED
@@ -2,9 +2,6 @@
2
  namespace ShortPixel;
3
  use ShortPixel\Notices\NoticeController as Notices;
4
 
5
- $path = '/var/www/shortpixel/wp-content/uploads/2019/09/';
6
-
7
-
8
  ?>
9
 
10
  <section id="tab-debug" <?php echo ($this->display_part == 'debug') ? ' class="sel-tab" ' :''; ?>>
2
  namespace ShortPixel;
3
  use ShortPixel\Notices\NoticeController as Notices;
4
 
 
 
 
5
  ?>
6
 
7
  <section id="tab-debug" <?php echo ($this->display_part == 'debug') ? ' class="sel-tab" ' :''; ?>>
class/view/settings/part-general.php CHANGED
@@ -130,6 +130,7 @@
130
  <label for="removeExif"><?php _e('Remove the EXIF tag of the image (recommended).','shortpixel-image-optimiser');?></label>
131
  <p class="settings-info"> <?php _e('EXIF is a set of various pieces of information that are automatically embedded into the image upon creation. This can include GPS position, camera manufacturer, date and time, etc.
132
  Unless you really need that data to be preserved, we recommend removing it as it can lead to <a href="http://blog.shortpixel.com/how-much-smaller-can-be-images-without-exif-icc" target="_blank">better compression rates</a>.','shortpixel-image-optimiser');?></p>
 
133
  </td>
134
  </tr>
135
  <tr class='exif_warning view-notice-row'>
@@ -138,6 +139,15 @@
138
  <div class='view-notice warning'><p><?php printf(__('Warning - Converting from PNG to JPG will %s not %s keep the EXIF-information!'), "<strong>","</strong>"); ?></p></div>
139
  </td>
140
  </tr>
 
 
 
 
 
 
 
 
 
141
  <tr>
142
  <?php $resizeDisabled = (! $this->view->data->resizeImages) ? 'disabled' : '';
143
  // @todo Inline styling here can be decluttered.
130
  <label for="removeExif"><?php _e('Remove the EXIF tag of the image (recommended).','shortpixel-image-optimiser');?></label>
131
  <p class="settings-info"> <?php _e('EXIF is a set of various pieces of information that are automatically embedded into the image upon creation. This can include GPS position, camera manufacturer, date and time, etc.
132
  Unless you really need that data to be preserved, we recommend removing it as it can lead to <a href="http://blog.shortpixel.com/how-much-smaller-can-be-images-without-exif-icc" target="_blank">better compression rates</a>.','shortpixel-image-optimiser');?></p>
133
+
134
  </td>
135
  </tr>
136
  <tr class='exif_warning view-notice-row'>
139
  <div class='view-notice warning'><p><?php printf(__('Warning - Converting from PNG to JPG will %s not %s keep the EXIF-information!'), "<strong>","</strong>"); ?></p></div>
140
  </td>
141
  </tr>
142
+
143
+ <?php $imagick = (\wpSPIO()->env()->hasImagick()) ? 1 : 0; ?>
144
+ <tr class='exif_imagick_warning view-notice-row' data-imagick="<?php echo $imagick ?>">
145
+ <th scope="row">&nbsp;</th>
146
+ <td>
147
+ <div class='view-notice warning'><p><?php printf(__('Warning - Imagick library not detected on server. WordPress will use another library to resize images, which may result in loss of EXIF-information'), "<strong>","</strong>"); ?></p></div>
148
+ </td>
149
+ </tr>
150
+
151
  <tr>
152
  <?php $resizeDisabled = (! $this->view->data->resizeImages) ? 'disabled' : '';
153
  // @todo Inline styling here can be decluttered.
class/view/shortpixel_view.php CHANGED
@@ -71,149 +71,6 @@ class ShortPixelView {
71
  </div> <?php self::includeProposeUpgradePopup();
72
  }
73
 
74
- /*
75
- public static function displayApiKeyAlert()
76
- { ?>
77
- <p><?php _e('In order to start the optimization process, you need to validate your API Key in the '
78
- . '<a href="options-general.php?page=wp-shortpixel-settings">ShortPixel Settings</a> page in your WordPress Admin.','shortpixel-image-optimiser');?>
79
- </p>
80
- <p><?php _e('If you don’t have an API Key, you can get one delivered to your inbox, for free.','shortpixel-image-optimiser');?></p>
81
- <p><?php _e('Please <a href="https://shortpixel.com/wp-apikey' . WPShortPixel::getAffiliateSufix() . '" target="_blank">sign up to get your API key.</a>','shortpixel-image-optimiser');?>
82
- </p>
83
- <?php
84
- }
85
-
86
- public static function displayActivationNotice($when = 'activate', $extra = '') {
87
- $extraStyle = ($when == 'compat' || $when == 'fileperms' ? "background-color: #ff9999;margin: 5px 20px 15px 0;'" : '');
88
- $icon = false;
89
- $extraClass = 'notice-warning';
90
- switch($when) {
91
- case 'compat': $extraClass = 'notice-error below-h2';
92
- case 'fileperms': $icon = 'scared'; $extraClass = 'notice-error'; break;
93
- case 'unlisted': $icon = 'magnifier'; break;
94
- case 'upgmonth':
95
- case 'upgbulk': $icon = 'notes'; $extraClass = 'notice-success'; break;
96
- case 'spai':
97
- case 'generic-err': $extraClass = 'notice-error is-dismissible'; break;
98
- case 'activate': $icon = 'scared'; break;
99
- }
100
- ?>
101
- <div class='notice <?php echo($extraClass);?> notice-warning' id='short-pixel-notice-<?php echo($when);?>' <?php echo($extraStyle);?>>
102
- <?php if($when != 'activate') { ?>
103
- <div style="float:right;">
104
- <?php if($when == 'upgmonth' || $when == 'upgbulk'){ ?>
105
- <button class="button button-primary" id="shortpixel-upgrade-advice" onclick="ShortPixel.proposeUpgrade()" style="margin-top:10px;margin-left:10px;"><strong>
106
- <?php _e('Show me the best available options', 'shortpixel-image-optimiser'); ?></strong></button>
107
- <?php } ?>
108
- <?php if($when == 'unlisted'){ ?>
109
- <a href="javascript:ShortPixel.includeUnlisted()" class="button button-primary" style="margin-top:10px;margin-left:10px;">
110
- <strong><?php _e('Yes, include these thumbnails','shortpixel-image-optimiser');?></strong></a>
111
- <?php }
112
- if($when !== 'fileperms' && $when !== 'compat' && $when !== 'generic-err' && $when !== 'spai') { ?>
113
- <a href="javascript:dismissShortPixelNotice('<?php echo($when);?>')" class="button" style="margin-top:10px;"><?php _e('Dismiss','shortpixel-image-optimiser');?></a>
114
- <?php }
115
- if($when == 'compat') { ?>
116
- <a href="javascript:dismissShortPixelNotice('<?php echo($when);?>')" class="button" style="margin-top:10px;"><?php _e('I know what I\'m doing','shortpixel-image-optimiser');?></a>
117
- <?php } ?>
118
- </div>
119
- <?php
120
- if($when == 'generic-err') {?>
121
- <button type="button" class="notice-dismiss"><span class="screen-reader-text"><?php _e('Dismiss this notice.','shortpixel-image-optimiser');?></span></button>
122
- <?php }
123
- }
124
- if($icon){ ?>
125
- <img src="<?php echo(wpSPIO()->plugin_url('res/img/robo-' . $icon . '.png'));?>"
126
- srcset='<?php echo(wpSPIO()->plugin_url('res/img/robo-' . $icon . '.png' ));?> 1x, <?php echo(wpSPIO()->plugin_url('res/img/robo-' . $icon . '@2x.png' ));?> 2x'
127
- class='short-pixel-notice-icon'>
128
- <?php } ?>
129
- <h3><?php _e('ShortPixel Image Optimizer','shortpixel-image-optimiser');
130
- if($when == 'compat') { echo(' '); _e('Warning','shortpixel-image-optimiser');}
131
- if($when == 'unlisted') { echo(' '); _e(' alert','shortpixel-image-optimiser');}
132
- if($when == 'upgmonth' || $when == 'upgbulk') { echo(' '); _e('advice','shortpixel-image-optimiser');}
133
- ?></h3> <?php
134
- switch($when) {
135
- case '2h' :
136
- _e("Action needed. Please <a href='https://shortpixel.com/wp-apikey' target='_blank'>get your API key</a> to activate your ShortPixel plugin.",'shortpixel-image-optimiser');
137
- break;
138
- case '3d':
139
- _e("Your image gallery is not optimized. It takes 2 minutes to <a href='https://shortpixel.com/wp-apikey' target='_blank'>get your API key</a> and activate your ShortPixel plugin.",'shortpixel-image-optimiser') . "<BR><BR>";
140
- break;
141
- case 'activate':
142
- self::displayApiKeyAlert();
143
- break;
144
- case 'fileperms' :
145
- printf(__("ShortPixel is not able to write to the uploads folder so it cannot optimize images, please check permissions (tried to create the file %s/.shortpixel-q-1).",'shortpixel-image-optimiser'),
146
- SHORTPIXEL_UPLOADS_BASE);
147
- break;
148
- case 'compat' :
149
- _e("The following plugins are not compatible with ShortPixel and may lead to unexpected results: ",'shortpixel-image-optimiser');
150
- echo('<ul class="sp-conflict-plugins">');
151
- foreach($extra as $plugin) {
152
- //ShortPixelVDD($plugin);
153
- $action = $plugin['action'];
154
- $link = ( $action == 'Deactivate' )
155
- ? wp_nonce_url( admin_url( 'admin-post.php?action=shortpixel_deactivate_plugin&plugin=' . urlencode( $plugin['path'] ) ), 'sp_deactivate_plugin_nonce' )
156
- : $plugin['href'];
157
- echo('<li class="sp-conflict-plugins-list"><strong>' . $plugin['name'] . '</strong>');
158
- echo('<a href="' . $link . '" class="button button-primary">'
159
- . __( $action, 'shortpixel_image_optimiser' ) . '</a>');
160
- if($plugin['details']) echo('<br>');
161
- if($plugin['details']) echo('<span>' . $plugin['details'] . '</span>');
162
- }
163
- echo("</ul>");
164
- break;
165
- case 'upgmonth' :
166
- case 'upgbulk' : ?>
167
- <p> <?php
168
- if($when == 'upgmonth') {
169
- printf(__("You are adding an average of <strong>%d images and thumbnails every month</strong> to your Media Library and you have <strong>a plan of %d images/month</strong>."
170
- . " You might need to upgrade your plan in order to have all your images optimized.", 'shortpixel-image-optimiser'), $extra['monthAvg'], $extra['monthlyQuota']);
171
- } else {
172
- printf(__("You currently have <strong>%d images and thumbnails to optimize</strong> but you only have <strong>%d images</strong> available in your current plan."
173
- . " You might need to upgrade your plan in order to have all your images optimized.", 'shortpixel-image-optimiser'), $extra['filesTodo'], $extra['quotaAvailable']);
174
- }?></p><?php
175
- self::includeProposeUpgradePopup();
176
- break;
177
- case 'unlisted' :
178
- _e("<p>ShortPixel found thumbnails which are not registered in the metadata but present alongside the other thumbnails. These thumbnails could be created and needed by some plugin or by the theme. Let ShortPixel optimize them as well?</p>", 'shortpixel-image-optimiser');?>
179
- <p>
180
- <?php _e("For example, the image", 'shortpixel-image-optimiser');?>
181
- <a href='post.php?post=<?php echo($extra->id);?>&action=edit' target='_blank'>
182
- <?php echo($extra->name); ?>
183
- </a> has also these thumbs not listed in metadata:
184
- <?php echo(implode(', ', $extra->unlisted)); ?>
185
- </p><?php
186
- break;
187
- case 'spai' :
188
- case 'generic' :
189
- case 'generic-err' :
190
- echo("<p>$extra</p>");
191
- break;
192
- }
193
- ?>
194
- </div>
195
- <?php
196
- }
197
- */
198
-
199
- /*
200
- protected static function includeProposeUpgradePopup() {
201
- wp_enqueue_style('short-pixel-modal.min.css', plugins_url('/res/css/short-pixel-modal.min.css',SHORTPIXEL_PLUGIN_FILE), array(), SHORTPIXEL_IMAGE_OPTIMISER_VERSION);
202
- ?>
203
-
204
- <div id="shortPixelProposeUpgradeShade" class="sp-modal-shade" style="display:none;">
205
- <div id="shortPixelProposeUpgrade" class="shortpixel-modal shortpixel-hide" style="min-width:610px;margin-left:-305px;">
206
- <div class="sp-modal-title">
207
- <button type="button" class="sp-close-upgrade-button" onclick="ShortPixel.closeProposeUpgrade()">&times;</button>
208
- <?php _e('Upgrade your ShortPixel account', 'shortpixel-image-optimiser');?>
209
- </div>
210
- <div class="sp-modal-body sptw-modal-spinner" style="height:auto;min-height:400px;padding:0;">
211
- </div>
212
- </div>
213
- </div>
214
- <?php }
215
- */
216
-
217
  public function displayBulkProcessingForm($quotaData, $thumbsProcessedCount, $under5PercentCount, $bulkRan,
218
  $averageCompression, $filesOptimized, $savedSpace, $percent, $customCount) {
219
  $settings = $this->ctrl->getSettings();
@@ -230,6 +87,7 @@ class ShortPixelView {
230
  ?>
231
  <div class="sp-notice sp-notice-info sp-floating-block sp-full-width">
232
  <form class='start' action='' method='POST' id='startBulk'>
 
233
  <input type='hidden' id='mainToProcess' value='<?php echo($quotaData['mainFiles'] - $quotaData['mainProcessedFiles']);?>'/>
234
  <input type='hidden' id='totalToProcess' value='<?php echo($quotaData['totalFiles'] - $quotaData['totalProcessedFiles']);?>'/>
235
  <div class="bulk-stats-container">
@@ -568,6 +426,8 @@ class ShortPixelView {
568
  <?php } ?>
569
  </p>
570
  <form action='' method='POST' >
 
 
571
  <input type='checkbox' id='bulk-thumbnails' name='thumbnails' <?php echo($this->ctrl->processThumbnails() ? "checked":"");?>
572
  onchange="ShortPixel.onBulkThumbsCheck(this)"> <?php _e('Include thumbnails','shortpixel-image-optimiser');?><br><br>
573
 
@@ -765,11 +625,14 @@ class ShortPixelView {
765
  &nbsp;<?php echo($message);?>
766
  </div>
767
  <form action='' method='POST' style="display:inline;">
 
768
  <input type="submit" class="button button-primary bulk-cancel" onclick="clearBulkProcessor();"
769
  name="bulkProcessStop" value="Stop" style="margin-left:10px"/>
770
  <input type="submit" class="button button-primary bulk-cancel" onclick="clearBulkProcessor();"
771
  name="<?php echo($running ? "bulkProcessPause" : "bulkProcessResume");?>" value="<?php echo($running ? __('Pause','shortpixel-image-optimiser') : __('All media','shortpixel-image-optimiser'));?>"/>
772
- <?php if(!$running && $customPending) {?>
 
 
773
  <input type="submit" class="button button-primary bulk-cancel" onclick="clearBulkProcessor();"
774
  name="skipToCustom" value="<?php _e('Only other media','shortpixel-image-optimiser');?>" title="<?php _e('Process only the other media, skipping the Media Library','shortpixel-image-optimiser');?>" style="margin-right:10px"/>
775
  <?php }?>
71
  </div> <?php self::includeProposeUpgradePopup();
72
  }
73
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
74
  public function displayBulkProcessingForm($quotaData, $thumbsProcessedCount, $under5PercentCount, $bulkRan,
75
  $averageCompression, $filesOptimized, $savedSpace, $percent, $customCount) {
76
  $settings = $this->ctrl->getSettings();
87
  ?>
88
  <div class="sp-notice sp-notice-info sp-floating-block sp-full-width">
89
  <form class='start' action='' method='POST' id='startBulk'>
90
+ <?php wp_nonce_field('sp-bulk', 'sp-nonce'); ?>
91
  <input type='hidden' id='mainToProcess' value='<?php echo($quotaData['mainFiles'] - $quotaData['mainProcessedFiles']);?>'/>
92
  <input type='hidden' id='totalToProcess' value='<?php echo($quotaData['totalFiles'] - $quotaData['totalProcessedFiles']);?>'/>
93
  <div class="bulk-stats-container">
426
  <?php } ?>
427
  </p>
428
  <form action='' method='POST' >
429
+ <?php wp_nonce_field('sp-bulk', 'sp-nonce'); ?>
430
+
431
  <input type='checkbox' id='bulk-thumbnails' name='thumbnails' <?php echo($this->ctrl->processThumbnails() ? "checked":"");?>
432
  onchange="ShortPixel.onBulkThumbsCheck(this)"> <?php _e('Include thumbnails','shortpixel-image-optimiser');?><br><br>
433
 
625
  &nbsp;<?php echo($message);?>
626
  </div>
627
  <form action='' method='POST' style="display:inline;">
628
+ <?php wp_nonce_field('sp-bulk', 'sp-nonce'); ?>
629
  <input type="submit" class="button button-primary bulk-cancel" onclick="clearBulkProcessor();"
630
  name="bulkProcessStop" value="Stop" style="margin-left:10px"/>
631
  <input type="submit" class="button button-primary bulk-cancel" onclick="clearBulkProcessor();"
632
  name="<?php echo($running ? "bulkProcessPause" : "bulkProcessResume");?>" value="<?php echo($running ? __('Pause','shortpixel-image-optimiser') : __('All media','shortpixel-image-optimiser'));?>"/>
633
+ <?php
634
+ // Off since this doesn't work.
635
+ if(false && !$running && $customPending) {?>
636
  <input type="submit" class="button button-primary bulk-cancel" onclick="clearBulkProcessor();"
637
  name="skipToCustom" value="<?php _e('Only other media','shortpixel-image-optimiser');?>" title="<?php _e('Process only the other media, skipping the Media Library','shortpixel-image-optimiser');?>" style="margin-right:10px"/>
638
  <?php }?>
class/view/view-restore-all.php CHANGED
@@ -1,7 +1,7 @@
1
 
2
  <div class="wrap short-pixel-bulk-page bulk-restore-all">
3
  <form action='<?php echo remove_query_arg('part'); ?>' method='POST' >
4
- <?php wp_nonce_field('bulk-restore-all', 'sp-nonce'); ?>
5
  <h1><?php _e('Bulk Image Optimization by ShortPixel','shortpixel-image-optimiser');?></h1>
6
 
7
  <div class="sp-notice sp-notice-info sp-floating-block sp-full-width">
1
 
2
  <div class="wrap short-pixel-bulk-page bulk-restore-all">
3
  <form action='<?php echo remove_query_arg('part'); ?>' method='POST' >
4
+ <?php wp_nonce_field('sp-bulk', 'sp-nonce'); ?>
5
  <h1><?php _e('Bulk Image Optimization by ShortPixel','shortpixel-image-optimiser');?></h1>
6
 
7
  <div class="sp-notice sp-notice-info sp-floating-block sp-full-width">
class/wp-short-pixel.php CHANGED
@@ -327,6 +327,12 @@ class WPShortPixel {
327
  $keyControl = \ShortPixel\ApiKeyController::getInstance();
328
  $apikey = $keyControl->getKeyForDisplay();
329
 
 
 
 
 
 
 
330
  // Using an Array within another Array to protect the primitive values from being cast to strings
331
  $ShortPixelConstants = array(array(
332
  'STATUS_SUCCESS'=>ShortPixelAPI::STATUS_SUCCESS,
@@ -348,7 +354,8 @@ class WPShortPixel {
348
  'MEDIA_ALERT'=>$this->_settings->mediaAlert ? "done" : "todo",
349
  'FRONT_BOOTSTRAP'=>$this->_settings->frontBootstrap && (!isset($this->_settings->lastBackAction) || (time() - $this->_settings->lastBackAction > 600)) ? 1 : 0,
350
  'AJAX_URL'=>admin_url('admin-ajax.php'),
351
- 'AFFILIATE'=>false
 
352
  ));
353
 
354
  if (Log::isManualDebug() )
@@ -837,6 +844,8 @@ class WPShortPixel {
837
  $startQueryID = $crtStartQueryID = $this->prioQ->getStartBulkId();
838
  $endQueryID = $this->prioQ->getStopBulkId();
839
 
 
 
840
  if ( $startQueryID <= $endQueryID ) {
841
  return false;
842
  }
@@ -851,6 +860,7 @@ class WPShortPixel {
851
  }
852
  $restored = array();
853
 
 
854
  //$ind = 0;
855
  while( $crtStartQueryID >= $endQueryID && time() - $startTime < $maxTime) {
856
  //if($ind > 1) break;
@@ -1131,10 +1141,28 @@ class WPShortPixel {
1131
  $this->_settings->lastBackAction = time();
1132
  }
1133
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1134
  $rawPrioQ = $this->prioQ->get();
1135
  if(count($rawPrioQ)) { Log::addInfo("HIP: 0 Priority Queue: ".json_encode($rawPrioQ)); }
1136
  Log::addInfo("HIP: 0 Bulk running? " . $this->prioQ->bulkRunning() . " START " . $this->_settings->startBulkId . " STOP " . $this->_settings->stopBulkId . " MaxTime: " . SHORTPIXEL_MAX_EXECUTION_TIME);
1137
 
 
 
1138
  //handle the bulk restore and cleanup first - these are fast operations taking precedece over optimization
1139
  if( $this->prioQ->bulkRunning()
1140
  && ( $this->prioQ->getBulkType() == ShortPixelQueue::BULK_TYPE_RESTORE
@@ -1149,7 +1177,6 @@ class WPShortPixel {
1149
  "BulkPercent" => $this->prioQ->getBulkPercent(),
1150
  "Restored" => $res )));
1151
  }
1152
-
1153
  }
1154
 
1155
  //1: get 3 ids to process. Take them with priority from the queue
@@ -1189,15 +1216,12 @@ class WPShortPixel {
1189
  } */
1190
 
1191
  $customIds = $this->spMetaDao->getPendingMetas( SHORTPIXEL_PRESEND_ITEMS - count($ids));
1192
-
1193
  if(is_array($customIds)) {
1194
  $ids = array_merge($ids, array_map(array('ShortPixelMetaFacade', 'getNewFromRow'), $customIds));
1195
  }
1196
  }
1197
 
1198
 
1199
-
1200
-
1201
  if(count($ids)) {$idl='';foreach($ids as $i){$idl.=$i->getId().' ';}
1202
  Log::addInfo("HIP: 1 Selected IDs: $idl");}
1203
 
@@ -1235,7 +1259,7 @@ class WPShortPixel {
1235
  "Message" => __('Searching images to optimize... ','shortpixel-image-optimiser') . $this->prioQ->getStartBulkId() . '->' . $this->prioQ->getStopBulkId() )));
1236
  }
1237
  //in this case the queue is really empty
1238
- self::log("HIP: 1 STOP BULK");
1239
  $bulkEverRan = $this->prioQ->stopBulk();
1240
  $this->sendEmptyQueue();
1241
  }
@@ -2339,6 +2363,7 @@ class WPShortPixel {
2339
  {
2340
  Log::addWarn("Custom File $ID - $file does not have a backup");
2341
  $notice = Notices::addWarning(__('Not able to restore file(s). Could not find backup', 'shortpixel-image-optimiser'), true);
 
2342
  Notices::addDetail($notice, (string) $file);
2343
  return false;
2344
  }
@@ -2691,230 +2716,6 @@ class WPShortPixel {
2691
  return substr($id, 0, 2 ) == "C-" ? $this->spMetaDao->getMeta(substr($id, 2)) : wp_get_attachment_url($id);
2692
  }
2693
 
2694
- /** View for Custom media
2695
- * @todo Move this to own view.
2696
- */
2697
- /* Gone! @todo Must go when new ListCMedia is done */
2698
- /*
2699
- public function listCustomMedia() {
2700
- if( ! class_exists( 'ShortPixelListTable' ) ) {
2701
- require_once('view/shortpixel-list-table.php');
2702
- }
2703
- if(isset($_REQUEST['refresh']) && esc_attr($_REQUEST['refresh']) == 1) {
2704
- $notice = null;
2705
- $this->refreshCustomFolders(true);
2706
- }
2707
- if(isset($_REQUEST['action']) && esc_attr($_REQUEST['action']) == 'optimize' && isset($_REQUEST['image'])) {
2708
- //die(ShortPixelMetaFacade::queuedId(ShortPixelMetaFacade::CUSTOM_TYPE, $_REQUEST['image']));
2709
- $this->prioQ->push(ShortPixelMetaFacade::queuedId(ShortPixelMetaFacade::CUSTOM_TYPE, $_REQUEST['image']));
2710
- }
2711
-
2712
- $customMediaListTable = new ShortPixelListTable($this, $this->spMetaDao, \wpSPIO()->env()->has_nextgen);
2713
- $items = $customMediaListTable->prepare_items();
2714
- if ( isset($_GET['noheader']) ) {
2715
- require_once(ABSPATH . 'wp-admin/admin-header.php');
2716
- }
2717
-
2718
- ?>
2719
- <div class="wrap shortpixel-other-media">
2720
- <h2>
2721
- <?php _e('Other Media optimized by ShortPixel','shortpixel-image-optimiser');?>
2722
- </h2>
2723
-
2724
- <div id="legacy">
2725
- <div id="legacy" class="metabox-holder">
2726
- <div id="legacy">
2727
- <div style="float:left;">
2728
- <a href="upload.php?page=wp-short-pixel-custom&refresh=1" id="refresh" class="button button-primary" title="<?php _e('Refresh custom folders content','shortpixel-image-optimiser');?>">
2729
- <?php _e('Refresh folders','shortpixel-image-optimiser');?>
2730
- </a>
2731
- </div>
2732
- <div class="meta-box-sortables ui-sortable">
2733
- <form method="get">
2734
- <input type="hidden" name="page" value="wp-short-pixel-custom" />
2735
- <?php $customMediaListTable->search_box("Search", "sp_search_file"); ?>
2736
- </form>
2737
- <form method="post" class="shortpixel-table">
2738
- <?php
2739
- $customMediaListTable->display();
2740
- //push to the processing list the pending ones, just in case
2741
- //$count = $this->spMetaDao->getCustomMetaCount();
2742
- if($this->_settings->autoMediaLibrary) foreach ($items as $item) {
2743
- if($item->status == 1){
2744
- $this->prioQ->push(ShortPixelMetaFacade::queuedId(ShortPixelMetaFacade::CUSTOM_TYPE, $item->id));
2745
- }
2746
- }
2747
- ?>
2748
- </form>
2749
- </div>
2750
- </div>
2751
- </div>
2752
- <br class="clear">
2753
- </div>
2754
- </div> <?php
2755
- } */
2756
-
2757
-
2758
- /** Front End function that controls bulk processes.
2759
- * TODO This is a Bulk controller
2760
- */
2761
- public function bulkProcess() {
2762
- global $wpdb;
2763
-
2764
- if( $this->_settings->verifiedKey == false ) {//invalid API Key
2765
- //ShortPixelView::displayActivationNotice();
2766
- return;
2767
- }
2768
-
2769
- $quotaData = $this->checkQuotaAndAlert(null, isset($_GET['checkquota']), 0);
2770
- if($this->_settings->quotaExceeded == 1) {
2771
- \ShortPixel\adminNoticesController::reInstateQuotaExceeded();
2772
- }
2773
- //return;
2774
- //}
2775
-
2776
-
2777
- if(isset($_POST['bulkProcessPause']))
2778
- {//pause an ongoing bulk processing, it might be needed sometimes
2779
- $this->prioQ->pauseBulk();
2780
- if($this->_settings->hasCustomFolders && $this->spMetaDao->getPendingMetaCount()) {
2781
- $this->_settings->customBulkPaused = 1;
2782
- }
2783
- }
2784
-
2785
- if(isset($_POST['bulkProcessStop']))
2786
- {//stop an ongoing bulk processing
2787
- $this->prioQ->stopBulk();
2788
- if($this->_settings->hasCustomFolders && $this->spMetaDao->getPendingMetaCount()) {
2789
- $this->_settings->customBulkPaused = 1;
2790
- }
2791
- $this->_settings->cancelPointer = NULL;
2792
- }
2793
-
2794
- if(isset($_POST["bulkProcess"]))
2795
- {
2796
- //set the thumbnails option
2797
- if ( isset($_POST['thumbnails']) ) {
2798
- $this->_settings->processThumbnails = 1;
2799
- } else {
2800
- $this->_settings->processThumbnails = 0;
2801
- }
2802
-
2803
- if ( isset($_POST['createWebp']) )
2804
- $this->_settings->createWebp = 1;
2805
- else
2806
- $this->_settings->createWebp = 0;
2807
-
2808
- //clean the custom files errors in order to process them again
2809
- if($this->_settings->hasCustomFolders) {
2810
- $this->spMetaDao->resetFailed();
2811
- $this->spMetaDao->resetRestored();
2812
- }
2813
-
2814
- $this->prioQ->startBulk(ShortPixelQueue::BULK_TYPE_OPTIMIZE);
2815
- $this->_settings->customBulkPaused = 0;
2816
- self::log("BULK: Start: " . $this->prioQ->getStartBulkId() . ", stop: " . $this->prioQ->getStopBulkId() . " PrioQ: "
2817
- .json_encode($this->prioQ->get()));
2818
- }//end bulk process was clicked
2819
-
2820
- if(isset($_POST["bulkRestore"]))
2821
- {
2822
- Log::addInfo('Bulk Process - Bulk Restore');
2823
-
2824
- $bulkRestore = new \ShortPixel\BulkRestoreAll(); // controller
2825
- $bulkRestore->setupBulk();
2826
-
2827
- $this->prioQ->startBulk(ShortPixelQueue::BULK_TYPE_RESTORE);
2828
- $this->_settings->customBulkPaused = 0;
2829
- }//end bulk restore was clicked
2830
-
2831
- if(isset($_POST["bulkCleanup"]))
2832
- {
2833
- Log::addInfo('Bulk Process - Bulk Cleanup ');
2834
- $this->prioQ->startBulk(ShortPixelQueue::BULK_TYPE_CLEANUP);
2835
- $this->_settings->customBulkPaused = 0;
2836
- }//end bulk restore was clicked
2837
-
2838
- if(isset($_POST["bulkCleanupPending"]))
2839
- {
2840
- Log::addInfo('Bulk Process - Clean Pending');
2841
- $this->prioQ->startBulk(ShortPixelQueue::BULK_TYPE_CLEANUP_PENDING);
2842
- $this->_settings->customBulkPaused = 0;
2843
- }//end bulk restore was clicked
2844
-
2845
- if(isset($_POST["bulkProcessResume"]))
2846
- {
2847
- Log::addInfo('Bulk Process - Bulk Resume');
2848
- $this->prioQ->resumeBulk();
2849
- $this->_settings->customBulkPaused = 0;
2850
- }//resume was clicked
2851
-
2852
- if(isset($_POST["skipToCustom"]))
2853
- {
2854
- Log::addInfo('Bulk Process - Skipping to Custom Media Process');
2855
- $this->_settings->skipToCustom = true;
2856
- $this->_settings->customBulkPaused = 0;
2857
-
2858
- }//resume was clicked
2859
-
2860
- //figure out the files that are left to be processed
2861
- $qry_left = "SELECT count(meta_id) FilesLeftToBeProcessed FROM " . $wpdb->prefix . "postmeta
2862
- WHERE meta_key = '_wp_attached_file' AND post_id <= " . (0 + $this->prioQ->getStartBulkId());
2863
- $filesLeft = $wpdb->get_results($qry_left);
2864
-
2865
- //check the custom bulk
2866
- $pendingMeta = $this->_settings->hasCustomFolders ? $this->spMetaDao->getPendingMetaCount() : 0;
2867
- Log::addInfo('Bulk Process - Pending Meta Count ' . $pendingMeta);
2868
- Log::addInfo('Bulk Process - File left ' . $filesLeft[0]->FilesLeftToBeProcessed );
2869
-
2870
-
2871
- if ( ($filesLeft[0]->FilesLeftToBeProcessed > 0 && $this->prioQ->bulkRunning())
2872
- || (0 + $pendingMeta > 0 && !$this->_settings->customBulkPaused && $this->prioQ->bulkRan())//bulk processing was started
2873
- && (!$this->prioQ->bulkPaused() || $this->_settings->skipToCustom)) //bulk not paused or if paused, user pressed Process Custom button
2874
- {
2875
- $msg = $this->bulkProgressMessage($this->prioQ->getDeltaBulkPercent(), $this->prioQ->getTimeRemaining());
2876
-
2877
- $this->view->displayBulkProcessingRunning($this->getPercent($quotaData), $msg, $quotaData['APICallsRemaining'], $this->getAverageCompression(),
2878
- $this->prioQ->getBulkType() == ShortPixelQueue::BULK_TYPE_RESTORE ? 0 :
2879
- ( $this->prioQ->getBulkType() == ShortPixelQueue::BULK_TYPE_CLEANUP
2880
- || $this->prioQ->getBulkType() == ShortPixelQueue::BULK_TYPE_CLEANUP_PENDING ? -1 : ($pendingMeta !== null ? ($this->prioQ->bulkRunning() ? 3 : 2) : 1)), $quotaData);
2881
-
2882
- } else
2883
- {
2884
- if($this->prioQ->bulkRan() && !$this->prioQ->bulkPaused()) {
2885
- $this->prioQ->markBulkComplete();
2886
- Log::addInfo("Bulk Process - Marked Bulk Complete");
2887
- }
2888
-
2889
- //image count
2890
- $thumbsProcessedCount = $this->_settings->thumbsCount;//amount of optimized thumbnails
2891
- $under5PercentCount = $this->_settings->under5Percent;//amount of under 5% optimized imgs.
2892
-
2893
- //average compression
2894
- $averageCompression = self::getAverageCompression();
2895
- $percent = $this->prioQ->bulkPaused() ? $this->getPercent($quotaData) : false;
2896
-
2897
- // [BS] If some template part is around, use it and find the controller.
2898
- $template_part = isset($_GET['part']) ? sanitize_text_field($_GET['part']) : false;
2899
- $controller = ShortPixelTools::namespaceit('ShortPixelController');
2900
- $partControl = $controller::findControllerbySlug($template_part);
2901
-
2902
- if ($partControl)
2903
- {
2904
- $viewObj = new $partControl();
2905
- $viewObj->setShortPixel($this);
2906
- $viewObj->loadView(); // TODO [BS] This should call load, which should init and call view inside controller.
2907
- }
2908
-
2909
- if (! $template_part)
2910
- {
2911
- $this->view->displayBulkProcessingForm($quotaData, $thumbsProcessedCount, $under5PercentCount,
2912
- $this->prioQ->bulkRan(), $averageCompression, $this->_settings->fileCount,
2913
- self::formatBytes($this->_settings->savedSpace), $percent, $pendingMeta);
2914
- }
2915
- }
2916
- }
2917
- //end bulk processing
2918
 
2919
  public function getPercent($quotaData) {
2920
  if($this->_settings->processThumbnails) {
@@ -2996,16 +2797,12 @@ class WPShortPixel {
2996
 
2997
  if( file_exists($postDir) ) {
2998
 
2999
-
3000
  $dir = $fs->getDirectory($postDir);
3001
  $files = $dir->getFiles();
3002
  $subdirs = $fs->sortFiles($dir->getSubDirectories()); // runs through FS sort.
3003
 
3004
- // $files = scandir($postDir);
3005
  $returnDir = substr($postDir, strlen($root));
3006
 
3007
- //natcasesort($files);
3008
-
3009
  if( count($subdirs) > 0 ) {
3010
  echo "<ul class='jqueryFileTree'>";
3011
  foreach($subdirs as $dir ) {
@@ -3852,6 +3649,7 @@ class WPShortPixel {
3852
 
3853
  // @todo Should be utility function
3854
  static public function formatBytes($bytes, $precision = 2) {
 
3855
  return \ShortPixelTools::formatBytes($bytes, $precision);
3856
 
3857
  }
327
  $keyControl = \ShortPixel\ApiKeyController::getInstance();
328
  $apikey = $keyControl->getKeyForDisplay();
329
 
330
+ // Get a Secret Key.
331
+ $cacheControl = new \ShortPixel\CacheController();
332
+ $bulkSecret = $cacheControl->getItem('bulk-secret');
333
+ $secretKey = (! is_null($bulkSecret->getValue() )) ? $bulkSecret->getValue() : false;
334
+
335
+
336
  // Using an Array within another Array to protect the primitive values from being cast to strings
337
  $ShortPixelConstants = array(array(
338
  'STATUS_SUCCESS'=>ShortPixelAPI::STATUS_SUCCESS,
354
  'MEDIA_ALERT'=>$this->_settings->mediaAlert ? "done" : "todo",
355
  'FRONT_BOOTSTRAP'=>$this->_settings->frontBootstrap && (!isset($this->_settings->lastBackAction) || (time() - $this->_settings->lastBackAction > 600)) ? 1 : 0,
356
  'AJAX_URL'=>admin_url('admin-ajax.php'),
357
+ 'AFFILIATE'=>false,
358
+ 'BULK_SECRET' => $secretKey,
359
  ));
360
 
361
  if (Log::isManualDebug() )
844
  $startQueryID = $crtStartQueryID = $this->prioQ->getStartBulkId();
845
  $endQueryID = $this->prioQ->getStopBulkId();
846
 
847
+ Log::addDebug('Bulk Restore' . $startQueryID . ' ' . $endQueryID);
848
+
849
  if ( $startQueryID <= $endQueryID ) {
850
  return false;
851
  }
860
  }
861
  $restored = array();
862
 
863
+
864
  //$ind = 0;
865
  while( $crtStartQueryID >= $endQueryID && time() - $startTime < $maxTime) {
866
  //if($ind > 1) break;
1141
  $this->_settings->lastBackAction = time();
1142
  }
1143
 
1144
+ if (isset($_POST['bulk-secret']))
1145
+ {
1146
+ $secret = sanitize_text_field($_POST['bulk-secret']);
1147
+ $cacheControl = new \ShortPixel\CacheController();
1148
+ $cachedObj = $cacheControl->getItem('bulk-secret');
1149
+
1150
+ if (! $cachedObj->exists())
1151
+ {
1152
+ $cachedObj->setValue($secret);
1153
+ $cachedObj->setExpires(3 * MINUTE_IN_SECONDS);
1154
+ $cacheControl->storeItemObject($cachedObj);
1155
+ }
1156
+
1157
+ }
1158
+
1159
+
1160
  $rawPrioQ = $this->prioQ->get();
1161
  if(count($rawPrioQ)) { Log::addInfo("HIP: 0 Priority Queue: ".json_encode($rawPrioQ)); }
1162
  Log::addInfo("HIP: 0 Bulk running? " . $this->prioQ->bulkRunning() . " START " . $this->_settings->startBulkId . " STOP " . $this->_settings->stopBulkId . " MaxTime: " . SHORTPIXEL_MAX_EXECUTION_TIME);
1163
 
1164
+ Log::addDebug('Bulk Running', array($this->prioQ->bulkRunning()) );
1165
+
1166
  //handle the bulk restore and cleanup first - these are fast operations taking precedece over optimization
1167
  if( $this->prioQ->bulkRunning()
1168
  && ( $this->prioQ->getBulkType() == ShortPixelQueue::BULK_TYPE_RESTORE
1177
  "BulkPercent" => $this->prioQ->getBulkPercent(),
1178
  "Restored" => $res )));
1179
  }
 
1180
  }
1181
 
1182
  //1: get 3 ids to process. Take them with priority from the queue
1216
  } */
1217
 
1218
  $customIds = $this->spMetaDao->getPendingMetas( SHORTPIXEL_PRESEND_ITEMS - count($ids));
 
1219
  if(is_array($customIds)) {
1220
  $ids = array_merge($ids, array_map(array('ShortPixelMetaFacade', 'getNewFromRow'), $customIds));
1221
  }
1222
  }
1223
 
1224
 
 
 
1225
  if(count($ids)) {$idl='';foreach($ids as $i){$idl.=$i->getId().' ';}
1226
  Log::addInfo("HIP: 1 Selected IDs: $idl");}
1227
 
1259
  "Message" => __('Searching images to optimize... ','shortpixel-image-optimiser') . $this->prioQ->getStartBulkId() . '->' . $this->prioQ->getStopBulkId() )));
1260
  }
1261
  //in this case the queue is really empty
1262
+ Log::addDebug("HIP: 1 STOP BULK");
1263
  $bulkEverRan = $this->prioQ->stopBulk();
1264
  $this->sendEmptyQueue();
1265
  }
2363
  {
2364
  Log::addWarn("Custom File $ID - $file does not have a backup");
2365
  $notice = Notices::addWarning(__('Not able to restore file(s). Could not find backup', 'shortpixel-image-optimiser'), true);
2366
+ Log::addTemp('BackupFILe Notice', $notice);
2367
  Notices::addDetail($notice, (string) $file);
2368
  return false;
2369
  }
2716
  return substr($id, 0, 2 ) == "C-" ? $this->spMetaDao->getMeta(substr($id, 2)) : wp_get_attachment_url($id);
2717
  }
2718
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2719
 
2720
  public function getPercent($quotaData) {
2721
  if($this->_settings->processThumbnails) {
2797
 
2798
  if( file_exists($postDir) ) {
2799
 
 
2800
  $dir = $fs->getDirectory($postDir);
2801
  $files = $dir->getFiles();
2802
  $subdirs = $fs->sortFiles($dir->getSubDirectories()); // runs through FS sort.
2803
 
 
2804
  $returnDir = substr($postDir, strlen($root));
2805
 
 
 
2806
  if( count($subdirs) > 0 ) {
2807
  echo "<ul class='jqueryFileTree'>";
2808
  foreach($subdirs as $dir ) {
3649
 
3650
  // @todo Should be utility function
3651
  static public function formatBytes($bytes, $precision = 2) {
3652
+ Log::addDebug('Deprecated function called: formatBytes');
3653
  return \ShortPixelTools::formatBytes($bytes, $precision);
3654
 
3655
  }
readme.txt CHANGED
@@ -2,9 +2,9 @@
2
  Contributors: ShortPixel
3
  Tags: compressor, image, compression, optimize, image optimizer, image optimiser, image compression, resize, compress pdf, compress jpg, compress png, image compression
4
  Requires at least: 3.2.0
5
- Tested up to: 5.4
6
  Requires PHP: 5.3
7
- Stable tag: 4.17.4
8
  License: GPLv2 or later
9
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
10
 
@@ -281,6 +281,16 @@ Hide the Cloudflare settings by defining these constants in wp-config.php:
281
 
282
  == Changelog ==
283
 
 
 
 
 
 
 
 
 
 
 
284
  = 4.17.4 =
285
 
286
  Release date: 22nd April 2020
2
  Contributors: ShortPixel
3
  Tags: compressor, image, compression, optimize, image optimizer, image optimiser, image compression, resize, compress pdf, compress jpg, compress png, image compression
4
  Requires at least: 3.2.0
5
+ Tested up to: 5.4.1
6
  Requires PHP: 5.3
7
+ Stable tag: 4.18.0
8
  License: GPLv2 or later
9
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
10
 
281
 
282
  == Changelog ==
283
 
284
+ = 4.18.0 =
285
+
286
+ Release date 7th May 2020
287
+ * Added a warning for the case when Imagik library isn't available and "Keep EXIF data is enabled";
288
+ * Added a check to prevent the bulk process to be called in multiple browsers in order to decrease the load on admin-heavy sites;
289
+ * Fix for the situation when the bulk process would enter a loop in certain situations;
290
+ * Fix for the notices after bulk restore that would duplicate the files missing form backups;
291
+ * Fix for multisite when DB tables were created even for sub-sites without the plugin being active;
292
+ * Language – 1 new strings added, 0 updated, 0 fuzzied, and 5 obsoleted.
293
+
294
  = 4.17.4 =
295
 
296
  Release date: 22nd April 2020
res/css/short-pixel.min.css CHANGED
@@ -1 +1 @@
1
- .reset{font-weight:normal;font-style:normal}.clearfix:before,.clearfix:after{content:" ";display:table}.clearfix:after{clear:both}.clearfix{zoom:1}.resumeLabel{float:right;line-height:30px;margin-right:20px;font-size:16px}.sp-dropbtn.button{box-sizing:content-box;padding:0 5px;font-size:20px;line-height:20px;cursor:pointer}.sp-dropdown{position:relative;display:inline-block}.sp-dropdown-content{display:none;right:0;position:absolute;background-color:#f9f9f9;min-width:190px;box-shadow:0 8px 16px 0 rgba(0,0,0,0.2);z-index:1}.rtl .sp-dropdown-content{right:auto;left:0}.sp-dropdown-content a{color:black;padding:12px 16px;text-decoration:none;display:block}.sp-dropdown-content a:hover{background-color:#f1f1f1}.sp-dropdown.sp-show .sp-dropdown-content{display:block}div.fb-like{transform:scale(1.3);-ms-transform:scale(1.3);-webkit-transform:scale(1.3);-o-transform:scale(1.3);-moz-transform:scale(1.3);transform-origin:bottom left;-ms-transform-origin:bottom left;-webkit-transform-origin:bottom left;-moz-transform-origin:bottom left;-webkit-transform-origin:bottom left}.wp-core-ui .button.button-alert,.wp-core-ui .button.button-alert:hover{background:#f79797}.wp-core-ui .button.remove-folder-button{min-width:120px}.sp-notice{background:#fff;border-left:4px solid #fff;-webkit-box-shadow:0 1px 1px 0 rgba(0,0,0,.1);box-shadow:0 1px 1px 0 rgba(0,0,0,.1);padding:1px 12px}.sp-notice img{vertical-align:bottom}@media(max-width:1249px){.sp-notice{margin:5px 15px 2px}}.sp-notice-info{border-left-color:#00a0d2}.sp-notice-success{border-left-color:#46b450}.sp-notice-warning{border-left-color:#f1e02a}div.short-pixel-bulk-page input.dial{font-size:16px !important}div.short-pixel-bulk-page h1{margin-bottom:20px}div.bulk-progress div.sp-h2{margin-top:0;margin-bottom:10px;font-size:23px;font-weight:400;padding:9px 15px 4px 0;line-height:29px}div.bulk-progress-partners{margin-top:20px}div.bulk-progress.bulk-progress-partners a div{display:inline-block;vertical-align:top;line-height:50px;margin-left:30px;font-size:1.2em}div.bulk-progress .bulk-progress-indicator,div.sp-quota-exceeded-alert .bulk-progress-indicator{display:inline-block;text-align:center;padding:0 10px;margin-left:10px;float:left;height:90px;overflow:hidden;border:1px solid #1caecb}div.wrap.short-pixel-bulk-page .bulk-notice-container{margin-top:15px;position:absolute;width:500px}div.wrap.short-pixel-bulk-page .bulk-notice-container .bulk-notice-msg{text-align:center;margin:10px 0 0 32px;overflow:hidden;border:1px solid #1caecb;background-color:#9ddbe0;border-radius:5px;padding:7px 10px 10px;display:none;max-width:600px;margin-right:20px}div.wrap.short-pixel-bulk-page .bulk-notice-container .bulk-notice-msg.bulk-error{border:1px solid #b5914d;background-color:#ffe996;margin-right:20px;position:relative;z-index:10}div.wrap.short-pixel-bulk-page .bulk-notice-container .bulk-notice-msg.bulk-error.bulk-error-fatal{border:1px solid #c32525;background-color:#ff969d}div.wrap.short-pixel-bulk-page .bulk-notice-msg img{float:left;margin-top:3px;margin-right:5px}div.sp-bulk-summary{float:right;margin:8px 5px 3px 20px}.sp-notice .bulk-error-show{cursor:pointer}.sp-notice div.bulk-error-list{background-color:#f1f1f1;padding:0 10px;display:none;max-height:200px;overflow-y:scroll}.sp-notice div.bulk-error-list ul{padding:3px 0 0;margin-top:5px}.sp-notice div.bulk-error-list ul>li:not(:last-child){border-bottom:1px solid white;padding-bottom:4px}input.dial{box-shadow:none}.shortpixel-table .column-filename{max-width:32em;width:40%}.shortpixel-table .column-folder{max-width:20em;width:20%}.shortpixel-table .column-media_type{max-width:8em;width:10%}.shortpixel-table .column-status{max-width:16em;width:15%}.shortpixel-table .column-options{max-width:16em;width:15%}.form-table th{width:220px}.form-table td{position:relative}div.shortpixel-rate-us{display:inline-block;margin-left:10px;vertical-align:top;font-weight:bold}div.shortpixel-rate-us>a{vertical-align:middle;padding:1px 5px 0;text-align:center;display:inline-block}div.shortpixel-rate-us>a>span{display:inline-block;vertical-align:top;margin-top:5px}div.shortpixel-rate-us>a>img{padding-top:7px}div.shortpixel-rate-us>a:active,div.shortpixel-rate-us>a:hover,div.shortpixel-rate-us>a:focus{outline:0;border-style:none}.sp-loading-small{margin-top:2px;float:left;margin-right:5px}.twentytwenty-horizontal .twentytwenty-before-label:before,.twentytwenty-horizontal .twentytwenty-after-label:before{font-family:inherit;font-size:16px}.short-pixel-bulk-page p{margin:.6em 0}.short-pixel-bulk-page form.start{display:table;content:" ";width:98%;background-color:white;padding:10px 10px 0;position:relative}.bulk-stats-container{display:inline-block;min-width:450px;width:45%;float:left;padding-right:50px;font-size:1.1em;line-height:1.5em}.bulk-text-container{display:inline-block;min-width:440px;width:45%;float:left;padding-right:50px}.bulk-text-container h3{border-bottom:1px solid #a8a8a8;margin-bottom:.5em;padding-bottom:.5em}.bulk-wide{display:inline-block;width:90%;float:left;margin-top:25px}.bulk-stats-container .bulk-label{width:220px;display:inline-block}.bulk-stats-container .bulk-val{width:50px;display:inline-block;text-align:right}.bulk-stats-container .bulk-total{font-weight:bold;margin-top:10px;margin-bottom:10px}.wp-core-ui .bulk-play{display:inline;width:310px;float:left;margin-bottom:20px}.wp-core-ui .bulk-play.bulk-nothing-optimize{font-weight:bold;color:#0080b2;border:1px solid;border-radius:5px;margin-top:60px;padding:5px 12px}.wp-core-ui .bulk-play a.button{height:60px;margin-top:27px;overflow:hidden}.wp-core-ui .column-wp-shortPixel .sp-column-actions{max-width:140px;float:right;text-align:right}.wp-core-ui .column-wp-shortPixel .sp-column-actions .button.button-smaller{margin-right:0}.wp-core-ui .column-wp-shortPixel .button.button-smaller{font-size:13px;padding:0 5px;margin-bottom:4px;min-height:30px;float:right}.wp-core-ui.rtl .column-wp-shortPixel .sp-column-actions,.wp-core-ui.rtl .column-wp-shortPixel .button.button-smaller{float:left}th.sortable.column-wp-shortPixel a,th.sorted.column-wp-shortPixel a{display:inline-block}.column-wp-shortPixel .sorting-indicator{display:inline-block}.wp-core-ui .bulk-play a.button .bulk-btn-img{display:inline-block;padding-top:6px}.wp-core-ui .bulk-play a.button .bulk-btn-txt{display:inline-block;text-align:right;line-height:1.3em;margin:11px 10px}.wp-core-ui .bulk-play a.button .bulk-btn-txt span.label{font-size:1.6em}.wp-core-ui .bulk-play a.button .bulk-btn-txt span.total{font-size:1.4em}.bulk-progress{padding:20px 32px 17px;background-color:#fff}.bulk-progress.bulk-stats>div{display:inline-block}.bulk-progress.bulk-stats>div.label{width:320px}.bulk-progress.bulk-stats>div.stat-value{width:80px;text-align:right}.short-pixel-bulk-page .progress{background-color:#ecedee;height:30px;position:relative;width:60%;display:inline-block;margin-right:28px;overflow:visible}.progress .progress-img{position:absolute;top:-10px;z-index:2;margin-left:-35px;line-height:48px;font-size:22px;font-weight:bold}.progress .progress-img span{vertical-align:top;margin-left:-7px}.progress .progress-left{background-color:#1cbecb;bottom:0;left:0;position:absolute;top:0;z-index:1;font-size:22px;font-weight:bold;line-height:28px;text-align:center;color:#fff}.bulk-estimate{font-size:20px;line-height:30px;vertical-align:top;display:inline-block}.wp-core-ui .button-primary.bulk-cancel{float:right;height:30px}.short-pixel-block-title{font-size:22px;font-weight:bold;text-align:center;margin-bottom:30px}.sp-floating-block.bulk-slider-container{display:none}.sp-floating-block.sp-notice.bulk-notices-parent{padding:0;margin:0;float:right;margin-right:500px !important}.bulk-slider-container{margin-top:20px;min-height:300px;overflow:hidden}.bulk-slider-container h2{margin-bottom:15px}.bulk-slider-container span.filename{font-weight:normal}.bulk-slider{display:table;margin:0 auto}.bulk-slider .bulk-slide{margin:0 auto;padding-left:120px;display:inline-block;font-weight:bold}.bulk-slider .img-original,.bulk-slider .img-optimized{display:inline-block;margin-right:20px;text-align:center}.bulk-slider .img-original div,.bulk-slider .img-optimized div{max-height:450px;overflow:hidden}.bulk-slider .img-original img,.bulk-slider .img-optimized img{max-width:300px}.bulk-slider .img-info{display:inline-block;vertical-align:top;font-size:48px;max-width:150px;padding:10px 0 0 20px}.bulk-slide-images{display:inline-block;border:1px solid #1caecb;padding:15px 0 0 20px}p.settings-info{padding-top:0;color:#818181;font-size:13px !important}p.settings-info.shortpixel-settings-error{color:#c32525}.shortpixel-key-valid{font-weight:bold}.shortpixel-key-valid .dashicons-yes:before{font-size:2em;line-height:25px;color:#3485ba;margin-left:-20px}.shortpixel-compression .shortpixel-compression-options{color:#999}.shortpixel-compression strong{line-height:22px}.shortpixel-compression .shortpixel-compression-options{display:inline-block}.shortpixel-compression label{width:158px;margin:0 -2px;background-color:#e2faff;font-weight:bold;display:inline-block}.shortpixel-compression label span{text-align:center;font-size:18px;padding:8px 0;display:block}.shortpixel-compression label input{display:none}.shortpixel-compression input:checked+span{background-color:#0085ba;color:#f7f7f7}.shortpixel-compression .shortpixel-radio-info{min-height:60px}article.sp-tabs{position:relative;display:block;width:100%;margin:2em auto}article.sp-tabs section{position:absolute;display:block;top:1.8em;left:0;width:100%;max-width:100%;box-sizing:border-box;padding:10px 20px;z-index:0}article.sp-tabs section.sel-tab{box-shadow:0 3px 3px rgba(0,0,0,0.1)}article.sp-tabs section .wp-shortpixel-tab-content{visibility:hidden}article.sp-tabs section.sel-tab .wp-shortpixel-tab-content{visibility:visible !important}article.sp-tabs section:first-child{z-index:1}article.sp-tabs section h2 a:focus,article.sp-tabs section#tab-resources a:focus{box-shadow:none;outline:0}article.sp-tabs section.sel-tab,article.sp-tabs section.sel-tab h2{color:#333;background-color:#fff;z-index:2}#tab-stats .sp-bulk-summary{position:absolute;right:0;top:0;z-index:100}.deliverWebpSettings,.deliverWebpTypes,.deliverWebpAlteringTypes{display:none}.deliverWebpTypes .sp-notice{color:red}.deliverWebpSettings{margin:16px 0}.deliverWebpSettings input:disabled+label{color:#818181}.deliverWebpTypes,.deliverWebpAlteringTypes{margin:16px 0 16px 16px}#png2jpg:not(:checked) ~ #png2jpgForce,#png2jpg:not(:checked) ~ label[for=png2jpgForce]{display:none}article.sp-tabs section #createWebp:checked ~ .deliverWebpSettings,article.sp-tabs section #deliverWebp:checked ~ .deliverWebpTypes,article.sp-tabs section #deliverWebpAltered:checked ~ .deliverWebpAlteringTypes{display:block}.shortpixel-help-link span.dashicons{text-decoration:none;margin-top:-1px}@media(min-width:1000px){section#tab-resources .col-md-6{display:inline-block;width:45%}}@media(max-width:999px){section#tab-resources .col-sm-12{display:inline-block;width:100%}}section#tab-resources .text-center{text-align:center}section#tab-resources p{font-size:16px}.wrap.short-pixel-bulk-page{margin-right:0}.sp-container{overflow:hidden;display:block;width:100%}.sp-floating-block{overflow:hidden;display:inline-block;float:left;margin-right:1.1% !important}.sp-full-width{width:98.8%;box-sizing:border-box}.sp-double-width{width:65.52%;box-sizing:border-box}.sp-single-width{width:32.23%;box-sizing:border-box}@media(max-width:1759px){.sp-floating-block{margin-right:1.3% !important}.sp-double-width,.sp-full-width{width:98.65%}.sp-single-width{width:48.7%}}@media(max-width:1249px){.sp-floating-block{margin-right:2% !important}.sp-double-width,.sp-full-width,.sp-single-width{width:97%}}.sp-tabs h2:before{content:none}.sp-column-actions-template+.sp-column-info{display:none}
1
+ .reset{font-weight:400;font-style:normal}.clearfix:after,.clearfix:before{content:" ";display:table}.clearfix:after{clear:both}.clearfix{zoom:1}.resumeLabel{float:right;line-height:30px;margin-right:20px;font-size:16px}.sp-dropbtn.button{box-sizing:content-box;padding:0 5px;font-size:20px;line-height:20px;cursor:pointer}.sp-dropdown{position:relative;display:inline-block}.sp-dropdown-content{display:none;right:0;position:absolute;background-color:#f9f9f9;min-width:190px;box-shadow:0 8px 16px 0 rgba(0,0,0,.2);z-index:1}.rtl .sp-dropdown-content{right:auto;left:0}.sp-dropdown-content a{color:#000;padding:12px 16px;text-decoration:none;display:block}.sp-dropdown-content a:hover{background-color:#f1f1f1}.sp-dropdown.sp-show .sp-dropdown-content{display:block}div.fb-like{transform:scale(1.3);-ms-transform:scale(1.3);-webkit-transform:scale(1.3);-o-transform:scale(1.3);-moz-transform:scale(1.3);transform-origin:bottom left;-ms-transform-origin:bottom left;-webkit-transform-origin:bottom left;-moz-transform-origin:bottom left;-webkit-transform-origin:bottom left}.wp-core-ui .button.button-alert,.wp-core-ui .button.button-alert:hover{background:#f79797}.wp-core-ui .button.remove-folder-button{min-width:120px}.sp-notice{background:#fff;border-left:4px solid #fff;-webkit-box-shadow:0 1px 1px 0 rgba(0,0,0,.1);box-shadow:0 1px 1px 0 rgba(0,0,0,.1);padding:1px 12px}.sp-notice img{vertical-align:bottom}@media(max-width:1249px){.sp-notice{margin:5px 15px 2px}}.sp-notice-info{border-left-color:#00a0d2}.sp-notice-success{border-left-color:#46b450}.sp-notice-warning{border-left-color:#f1e02a}div.short-pixel-bulk-page input.dial{font-size:16px!important}div.short-pixel-bulk-page h1{margin-bottom:20px}div.bulk-progress div.sp-h2{margin-top:0;margin-bottom:10px;font-size:23px;font-weight:400;padding:9px 15px 4px 0;line-height:29px}div.bulk-progress-partners{margin-top:20px}div.bulk-progress.bulk-progress-partners a div{display:inline-block;vertical-align:top;line-height:50px;margin-left:30px;font-size:1.2em}div.bulk-progress .bulk-progress-indicator,div.sp-quota-exceeded-alert .bulk-progress-indicator{display:inline-block;text-align:center;padding:0 10px;margin-left:10px;float:left;height:90px;overflow:hidden;border:1px solid #1caecb}div.wrap.short-pixel-bulk-page .bulk-notice-container{margin-top:15px;position:absolute;width:500px}div.wrap.short-pixel-bulk-page .bulk-notice-container .bulk-notice-msg{text-align:center;margin:10px 0 0 32px;overflow:hidden;border:1px solid #1caecb;background-color:#9ddbe0;border-radius:5px;padding:7px 10px 10px;display:none;max-width:600px;margin-right:20px}div.wrap.short-pixel-bulk-page .bulk-notice-container .bulk-notice-msg.bulk-error{border:1px solid #b5914d;background-color:#ffe996;margin-right:20px;position:relative;z-index:10}div.wrap.short-pixel-bulk-page .bulk-notice-container .bulk-notice-msg.bulk-error.bulk-error-fatal{border:1px solid #c32525;background-color:#ff969d}div.wrap.short-pixel-bulk-page .bulk-notice-msg img{float:left;margin-top:3px;margin-right:5px}div.sp-bulk-summary{float:right;margin:8px 5px 3px 20px}.sp-notice .bulk-error-show{cursor:pointer}.sp-notice div.bulk-error-list{background-color:#f1f1f1;padding:0 10px;display:none;max-height:200px;overflow-y:scroll}.sp-notice div.bulk-error-list ul{padding:3px 0 0;margin-top:5px}.sp-notice div.bulk-error-list ul>li:not(:last-child){border-bottom:1px solid #fff;padding-bottom:4px}input.dial{box-shadow:none}.shortpixel-table .column-filename{max-width:32em;width:40%}.shortpixel-table .column-folder{max-width:20em;width:20%}.shortpixel-table .column-media_type{max-width:8em;width:10%}.shortpixel-table .column-status{max-width:16em;width:15%}.shortpixel-table .column-options{max-width:16em;width:15%}.form-table th{width:220px}.form-table td{position:relative}div.shortpixel-rate-us{display:inline-block;margin-left:10px;vertical-align:top;font-weight:700}div.shortpixel-rate-us>a{vertical-align:middle;padding:1px 5px 0;text-align:center;display:inline-block}div.shortpixel-rate-us>a>span{display:inline-block;vertical-align:top;margin-top:5px}div.shortpixel-rate-us>a>img{padding-top:7px}div.shortpixel-rate-us>a:active,div.shortpixel-rate-us>a:focus,div.shortpixel-rate-us>a:hover{outline:0;border-style:none}.sp-loading-small{margin-top:2px;float:left;margin-right:5px}.twentytwenty-horizontal .twentytwenty-after-label:before,.twentytwenty-horizontal .twentytwenty-before-label:before{font-family:inherit;font-size:16px}.short-pixel-bulk-page p{margin:.6em 0}.short-pixel-bulk-page form.start{display:table;content:" ";width:98%;background-color:#fff;padding:10px 10px 0;position:relative}.bulk-stats-container{display:inline-block;min-width:450px;width:45%;float:left;padding-right:50px;font-size:1.1em;line-height:1.5em}.bulk-text-container{display:inline-block;min-width:440px;width:45%;float:left;padding-right:50px}.bulk-text-container h3{border-bottom:1px solid #a8a8a8;margin-bottom:.5em;padding-bottom:.5em}.bulk-wide{display:inline-block;width:90%;float:left;margin-top:25px}.bulk-stats-container .bulk-label{width:220px;display:inline-block}.bulk-stats-container .bulk-val{width:50px;display:inline-block;text-align:right}.bulk-stats-container .bulk-total{font-weight:700;margin-top:10px;margin-bottom:10px}.wp-core-ui .bulk-play{display:inline;width:310px;float:left;margin-bottom:20px}.wp-core-ui .bulk-play.bulk-nothing-optimize{font-weight:700;color:#0080b2;border:1px solid;border-radius:5px;margin-top:60px;padding:5px 12px}.wp-core-ui .bulk-play a.button{height:60px;margin-top:27px;overflow:hidden}.wp-core-ui .column-wp-shortPixel .sp-column-actions{max-width:140px;float:right;text-align:right}.wp-core-ui .column-wp-shortPixel .sp-column-actions .button.button-smaller{margin-right:0}.wp-core-ui .column-wp-shortPixel .button.button-smaller{font-size:13px;padding:0 5px;margin-bottom:4px;min-height:30px;float:right}.wp-core-ui.rtl .column-wp-shortPixel .button.button-smaller,.wp-core-ui.rtl .column-wp-shortPixel .sp-column-actions{float:left}th.sortable.column-wp-shortPixel a,th.sorted.column-wp-shortPixel a{display:inline-block}.column-wp-shortPixel .sorting-indicator{display:inline-block}.wp-core-ui .bulk-play a.button .bulk-btn-img{display:inline-block;padding-top:6px}.wp-core-ui .bulk-play a.button .bulk-btn-txt{display:inline-block;text-align:right;line-height:1.3em;margin:11px 10px}.wp-core-ui .bulk-play a.button .bulk-btn-txt span.label{font-size:1.6em}.wp-core-ui .bulk-play a.button .bulk-btn-txt span.total{font-size:1.4em}.bulk-progress{padding:20px 32px 17px;background-color:#fff}.bulk-progress.bulk-stats>div{display:inline-block}.bulk-progress.bulk-stats>div.label{width:320px}.bulk-progress.bulk-stats>div.stat-value{width:80px;text-align:right}.short-pixel-bulk-page .progress{background-color:#ecedee;height:30px;position:relative;width:60%;display:inline-block;margin-right:28px;overflow:visible}.progress .progress-img{position:absolute;top:-10px;z-index:2;margin-left:-35px;line-height:48px;font-size:22px;font-weight:700}.progress .progress-img span{vertical-align:top;margin-left:-7px}.progress .progress-left{background-color:#1cbecb;bottom:0;left:0;position:absolute;top:0;z-index:1;font-size:22px;font-weight:700;line-height:28px;text-align:center;color:#fff}.bulk-estimate{font-size:20px;line-height:30px;vertical-align:top;display:inline-block}.wp-core-ui .button-primary.bulk-cancel{float:right;height:30px}.short-pixel-block-title{font-size:22px;font-weight:700;text-align:center;margin-bottom:30px}.sp-floating-block.bulk-slider-container{display:none}.sp-floating-block.sp-notice.bulk-notices-parent{padding:0;margin:0;float:right;margin-right:500px!important}.bulk-slider-container{margin-top:20px;min-height:300px;overflow:hidden}.bulk-slider-container h2{margin-bottom:15px}.bulk-slider-container span.filename{font-weight:400}.bulk-slider{display:table;margin:0 auto}.bulk-slider .bulk-slide{margin:0 auto;padding-left:120px;display:inline-block;font-weight:700}.bulk-slider .img-optimized,.bulk-slider .img-original{display:inline-block;margin-right:20px;text-align:center}.bulk-slider .img-optimized div,.bulk-slider .img-original div{max-height:450px;overflow:hidden}.bulk-slider .img-optimized img,.bulk-slider .img-original img{max-width:300px}.bulk-slider .img-info{display:inline-block;vertical-align:top;font-size:48px;max-width:150px;padding:10px 0 0 20px}.bulk-slide-images{display:inline-block;border:1px solid #1caecb;padding:15px 0 0 20px}p.settings-info{padding-top:0;color:#818181;font-size:13px!important}p.settings-info.shortpixel-settings-error{color:#c32525}.shortpixel-key-valid{font-weight:700}.shortpixel-key-valid .dashicons-yes:before{font-size:2em;line-height:25px;color:#3485ba;margin-left:-20px}.shortpixel-compression .shortpixel-compression-options{color:#999}.shortpixel-compression strong{line-height:22px}.shortpixel-compression .shortpixel-compression-options{display:inline-block}.shortpixel-compression label{width:158px;margin:0 -2px;background-color:#e2faff;font-weight:700;display:inline-block}.shortpixel-compression label span{text-align:center;font-size:18px;padding:8px 0;display:block}.shortpixel-compression label input{display:none}.shortpixel-compression input:checked+span{background-color:#0085ba;color:#f7f7f7}.shortpixel-compression .shortpixel-radio-info{min-height:60px}article.sp-tabs{position:relative;display:block;width:100%;margin:2em auto}article.sp-tabs section{position:absolute;display:block;top:1.8em;left:0;width:100%;max-width:100%;box-sizing:border-box;padding:10px 20px;z-index:0}article.sp-tabs section.sel-tab{box-shadow:0 3px 3px rgba(0,0,0,.1)}article.sp-tabs section .wp-shortpixel-tab-content{visibility:hidden}article.sp-tabs section.sel-tab .wp-shortpixel-tab-content{visibility:visible!important}article.sp-tabs section:first-child{z-index:1}article.sp-tabs section h2 a:focus,article.sp-tabs section#tab-resources a:focus{box-shadow:none;outline:0}article.sp-tabs section.sel-tab,article.sp-tabs section.sel-tab h2{color:#333;background-color:#fff;z-index:2}#tab-stats .sp-bulk-summary{position:absolute;right:0;top:0;z-index:100}.deliverWebpAlteringTypes,.deliverWebpSettings,.deliverWebpTypes{display:none}.deliverWebpTypes .sp-notice{color:red}.deliverWebpSettings{margin:16px 0}.deliverWebpSettings input:disabled+label{color:#818181}.deliverWebpAlteringTypes,.deliverWebpTypes{margin:16px 0 16px 16px}#png2jpg:not(:checked)~#png2jpgForce,#png2jpg:not(:checked)~label[for=png2jpgForce]{display:none}article.sp-tabs section #createWebp:checked~.deliverWebpSettings,article.sp-tabs section #deliverWebp:checked~.deliverWebpTypes,article.sp-tabs section #deliverWebpAltered:checked~.deliverWebpAlteringTypes{display:block}.shortpixel-help-link span.dashicons{text-decoration:none;margin-top:-1px}@media(min-width:1000px){section#tab-resources .col-md-6{display:inline-block;width:45%}}@media(max-width:999px){section#tab-resources .col-sm-12{display:inline-block;width:100%}}section#tab-resources .text-center{text-align:center}section#tab-resources p{font-size:16px}.wrap.short-pixel-bulk-page{margin-right:0}.sp-container{overflow:hidden;display:block;width:100%}.sp-floating-block{overflow:hidden;display:inline-block;float:left;margin-right:1.1%!important}.sp-full-width{width:98.8%;box-sizing:border-box}.sp-double-width{width:65.52%;box-sizing:border-box}.sp-single-width{width:32.23%;box-sizing:border-box}@media(max-width:1759px){.sp-floating-block{margin-right:1.3%!important}.sp-double-width,.sp-full-width{width:98.65%}.sp-single-width{width:48.7%}}@media(max-width:1249px){.sp-floating-block{margin-right:2%!important}.sp-double-width,.sp-full-width,.sp-single-width{width:97%}}.sp-tabs h2:before{content:none}.sp-column-actions-template+.sp-column-info{display:none}
res/js/shortpixel.js CHANGED
@@ -89,12 +89,15 @@ var ShortPixel = function() {
89
  function checkExifWarning()
90
  {
91
  if (! jQuery('input[name="removeExif"]').is(':checked') && jQuery('input[name="png2jpg"]').is(':checked') )
92
- {
93
  jQuery('.exif_warning').fadeIn();
94
- }
95
- else {
96
  jQuery('.exif_warning').fadeOut();
97
- }
 
 
 
 
 
98
  }
99
 
100
  function checkBackUpWarning()
@@ -414,7 +417,7 @@ var ShortPixel = function() {
414
  if(isNaN(ShortPixel.retries)) ShortPixel.retries = 1;
415
  if(ShortPixel.retries < 6) {
416
  console.log("Invalid response from server (Error: " + msg + "). Retrying pass " + (ShortPixel.retries + 1) + "...");
417
- setTimeout(checkBulkProgress, 5000);
418
  } else {
419
  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 + ")", "");
420
  console.log("Invalid response from server 6 times. Giving up.");
@@ -423,6 +426,7 @@ var ShortPixel = function() {
423
 
424
  function browseContent(browseData) {
425
  browseData.action = 'shortpixel_browse_content';
 
426
  var browseResponse = "";
427
  jQuery.ajax({
428
  type: "POST",
@@ -538,8 +542,6 @@ var ShortPixel = function() {
538
  }
539
  });
540
  } */
541
-
542
-
543
  function initFolderSelector() {
544
  jQuery(".select-folder-button").click(function(){
545
  jQuery(".sp-folder-picker-shade").fadeIn(100); //.css("display", "block");
@@ -549,9 +551,7 @@ var ShortPixel = function() {
549
  picker.parent().css('margin-left', -picker.width() / 2);
550
  picker.fileTree({
551
  script: ShortPixel.browseContent,
552
- //folderEvent: 'dblclick',
553
- multiFolder: false
554
- //onlyFolders: true
555
  });
556
  });
557
  jQuery(".shortpixel-modal input.select-folder-cancel, .sp-folder-picker-shade").click(function(){
@@ -561,6 +561,8 @@ var ShortPixel = function() {
561
  jQuery(".shortpixel-modal input.select-folder").click(function(e){
562
  //var subPath = jQuery("UL.jqueryFileTree LI.directory.selected A").attr("rel").trim();
563
 
 
 
564
  // check if selected item is a directory. If so, we are good.
565
  var selected = jQuery('UL.jqueryFileTree LI.directory.selected');
566
 
@@ -988,24 +990,54 @@ function checkBulkProgress() {
988
  //if i'm the bulk page, steal the bulk processor
989
  if( window.location.href.search("wp-short-pixel-bulk") >= 0 ) {
990
  ShortPixel.bulkProcessor = true;
991
- localStorage.bulkTime = Math.floor(Date.now() / 1000);
992
  localStorage.bulkPage = 1;
 
 
 
 
 
 
 
 
 
 
 
 
 
993
  }
994
 
995
  //if I'm not the bulk processor, check every 20 sec. if the bulk processor is running, otherwise take the role
996
- if(ShortPixel.bulkProcessor == true || typeof localStorage.bulkTime == 'undefined' || Math.floor(Date.now() / 1000) - localStorage.bulkTime > 90) {
997
  ShortPixel.bulkProcessor = true;
998
  localStorage.bulkPage = (window.location.href.search("wp-short-pixel-bulk") >= 0 ? 1 : 0);
999
- localStorage.bulkTime = Math.floor(Date.now() / 1000);
1000
- console.log(localStorage.bulkTime);
 
 
1001
  checkBulkProcessingCallApi();
 
1002
  } else {
1003
- setTimeout(checkBulkProgress, 5000);
1004
  }
1005
  }
1006
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1007
  function checkBulkProcessingCallApi(){
1008
- var data = { 'action': 'shortpixel_image_processing' };
 
1009
  // since WP 2.8 ajaxurl is always defined in the admin header and points to admin-ajax.php
1010
  jQuery.ajax({
1011
  type: "POST",
@@ -1048,7 +1080,7 @@ function checkBulkProcessingCallApi(){
1048
  + "<a class='button button-smaller' href='admin.php?action=shortpixel_check_quota'>" + _spTr.check__Quota + "</a>");
1049
  showToolBarAlert(ShortPixel.STATUS_QUOTA_EXCEEDED);
1050
  if(data['Stop'] == false) { //there are other items in the priority list, maybe processed, try those
1051
- setTimeout(checkBulkProgress, 5000);
1052
  }
1053
  ShortPixel.otherMediaUpdateActions(id, ['quota','view']);
1054
  break;
@@ -1064,7 +1096,7 @@ function checkBulkProcessingCallApi(){
1064
  ShortPixel.otherMediaUpdateActions(id, ['retry','view']);
1065
  }
1066
  console.log(data["Message"]);
1067
- setTimeout(checkBulkProgress, 5000);
1068
  break;
1069
  case ShortPixel.STATUS_EMPTY_QUEUE:
1070
  console.log(data["Message"]);
@@ -1138,7 +1170,7 @@ function checkBulkProcessingCallApi(){
1138
  if(isBulkPage && typeof data["BulkPercent"] !== 'undefined') {
1139
  progressUpdate(data["BulkPercent"], data["BulkMsg"]);
1140
  }
1141
- setTimeout(checkBulkProgress, 5000);
1142
  break;
1143
 
1144
  case ShortPixel.STATUS_SKIP:
@@ -1162,7 +1194,7 @@ function checkBulkProcessingCallApi(){
1162
  if(isBulkPage && data["Count"] > 3) {
1163
  ShortPixel.bulkShowLengthyMsg(id, data["Filename"], data["CustomImageLink"]);
1164
  }
1165
- setTimeout(checkBulkProgress, 5000);
1166
  break;
1167
  case ShortPixel.STATUS_SEARCHING:
1168
  console.log('Server response: ' + response);
@@ -1171,15 +1203,15 @@ function checkBulkProcessingCallApi(){
1171
  {
1172
  jQuery('.bulk-notice-msg.bulk-searching').show();
1173
  }
1174
- setTimeout(checkBulkProgress, 2500);
1175
  break;
1176
  case ShortPixel.STATUS_MAINTENANCE:
1177
  ShortPixel.bulkShowMaintenanceMsg('maintenance');
1178
- setTimeout(checkBulkProgress, 60000);
1179
  break;
1180
  case ShortPixel.STATUS_QUEUE_FULL:
1181
  ShortPixel.bulkShowMaintenanceMsg('queue-full');
1182
- setTimeout(checkBulkProgress, 60000);
1183
  break;
1184
  default:
1185
  ShortPixel.retry("Unknown status " + data["Status"] + ". Retrying...");
@@ -1207,7 +1239,9 @@ function checkBulkProcessingCallApi(){
1207
 
1208
  function clearBulkProcessor(){
1209
  ShortPixel.bulkProcessor = false; //nothing to process, leave the role. Next page load will check again
1210
- localStorage.bulkTime = 0;
 
 
1211
  if(window.location.href.search("wp-short-pixel-bulk") >= 0) {
1212
  localStorage.bulkPage = 0;
1213
  }
@@ -1241,7 +1275,8 @@ function manualOptimization(id, cleanup) {
1241
  var resp = JSON.parse(response);
1242
  if(resp["Status"] == ShortPixel.STATUS_SUCCESS) {
1243
  //TODO - when calling several manual optimizations, the checkBulkProgress gets scheduled several times so several loops run in || - make only one.
1244
- setTimeout(checkBulkProgress, 2000);
 
1245
  } else {
1246
  setCellMessage(id, typeof resp["Message"] !== "undefined" ? resp["Message"] : _spTr.thisContentNotProcessable, "");
1247
  }
@@ -1276,7 +1311,8 @@ function reoptimize(id, type) {
1276
  jQuery.get(ShortPixel.AJAX_URL, data, function(response) {
1277
  data = JSON.parse(response);
1278
  if(data["Status"] == ShortPixel.STATUS_SUCCESS) {
1279
- setTimeout(checkBulkProgress, 2000);
 
1280
  } else {
1281
  $msg = typeof data["Message"] !== "undefined" ? data["Message"] : _spTr.thisContentNotProcessable;
1282
  setCellMessage(id, $msg, "");
@@ -1294,7 +1330,8 @@ function optimizeThumbs(id) {
1294
  jQuery.get(ShortPixel.AJAX_URL, data, function(response) {
1295
  data = JSON.parse(response);
1296
  if(data["Status"] == ShortPixel.STATUS_SUCCESS) {
1297
- setTimeout(checkBulkProgress, 2000);
 
1298
  } else {
1299
  setCellMessage(id, typeof data["Message"] !== "undefined" ? data["Message"] : _spTr.thisContentNotProcessable, "");
1300
  }
89
  function checkExifWarning()
90
  {
91
  if (! jQuery('input[name="removeExif"]').is(':checked') && jQuery('input[name="png2jpg"]').is(':checked') )
 
92
  jQuery('.exif_warning').fadeIn();
93
+ else
 
94
  jQuery('.exif_warning').fadeOut();
95
+
96
+ if (! jQuery('input[name="removeExif"]').is(':checked') && jQuery('.exif_imagick_warning').data('imagick') <= 0)
97
+ jQuery('.exif_imagick_warning').fadeIn();
98
+ else
99
+ jQuery('.exif_imagick_warning').fadeOut();
100
+
101
  }
102
 
103
  function checkBackUpWarning()
417
  if(isNaN(ShortPixel.retries)) ShortPixel.retries = 1;
418
  if(ShortPixel.retries < 6) {
419
  console.log("Invalid response from server (Error: " + msg + "). Retrying pass " + (ShortPixel.retries + 1) + "...");
420
+ setBulkTimer(5000);
421
  } else {
422
  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 + ")", "");
423
  console.log("Invalid response from server 6 times. Giving up.");
426
 
427
  function browseContent(browseData) {
428
  browseData.action = 'shortpixel_browse_content';
429
+
430
  var browseResponse = "";
431
  jQuery.ajax({
432
  type: "POST",
542
  }
543
  });
544
  } */
 
 
545
  function initFolderSelector() {
546
  jQuery(".select-folder-button").click(function(){
547
  jQuery(".sp-folder-picker-shade").fadeIn(100); //.css("display", "block");
551
  picker.parent().css('margin-left', -picker.width() / 2);
552
  picker.fileTree({
553
  script: ShortPixel.browseContent,
554
+ multiFolder: false,
 
 
555
  });
556
  });
557
  jQuery(".shortpixel-modal input.select-folder-cancel, .sp-folder-picker-shade").click(function(){
561
  jQuery(".shortpixel-modal input.select-folder").click(function(e){
562
  //var subPath = jQuery("UL.jqueryFileTree LI.directory.selected A").attr("rel").trim();
563
 
564
+ // @todo This whole thing might go, since we don't display files anymore in folderTree.
565
+
566
  // check if selected item is a directory. If so, we are good.
567
  var selected = jQuery('UL.jqueryFileTree LI.directory.selected');
568
 
990
  //if i'm the bulk page, steal the bulk processor
991
  if( window.location.href.search("wp-short-pixel-bulk") >= 0 ) {
992
  ShortPixel.bulkProcessor = true;
993
+ localStorage.bulkTime = Date.now();
994
  localStorage.bulkPage = 1;
995
+ ShortPixel.BULK_SECRET = false;
996
+ }
997
+
998
+ if (ShortPixel.BULK_SECRET !== false)
999
+ {
1000
+ if (ShortPixel.BULK_SECRET != localStorage.bulkSecret)
1001
+ {
1002
+ // console.log('Cancelled Processing. Bulk Processor in use');
1003
+ clearBulkProcessor();
1004
+ jQuery("li.shortpixel-toolbar-processing").removeClass("shortpixel-processing");
1005
+ jQuery("li.shortpixel-toolbar-processing").addClass("shortpixel-hide");
1006
+ return;
1007
+ }
1008
  }
1009
 
1010
  //if I'm not the bulk processor, check every 20 sec. if the bulk processor is running, otherwise take the role
1011
+ if(ShortPixel.bulkProcessor == true || typeof localStorage.bulkTime == 'undefined' || Date.now() - localStorage.bulkTime > 10000) {
1012
  ShortPixel.bulkProcessor = true;
1013
  localStorage.bulkPage = (window.location.href.search("wp-short-pixel-bulk") >= 0 ? 1 : 0);
1014
+ localStorage.bulkTime = Date.now();
1015
+ if (localStorage.getItem('bulkSecret') == null)
1016
+ localStorage.bulkSecret = Math.random().toString(36).substring(7);
1017
+
1018
  checkBulkProcessingCallApi();
1019
+ setBulkTimer(5000);
1020
  } else {
1021
+ setBulkTimer(20000);
1022
  }
1023
  }
1024
 
1025
+ var bulkTimer; // scope
1026
+ function setBulkTimer(time)
1027
+ {
1028
+ window.clearTimeout(bulkTimer);
1029
+ //console.log('Clearing TimeOut');
1030
+
1031
+ if (time > 0)
1032
+ {
1033
+ bulkTimer = window.setTimeout(checkBulkProgress, time);
1034
+ //console.log('Set Timeout ' + time + ' ms');
1035
+ }
1036
+ }
1037
+
1038
  function checkBulkProcessingCallApi(){
1039
+ // console.log('CheckBulkProcessingAPI');
1040
+ var data = { 'action': 'shortpixel_image_processing', 'bulk-secret': localStorage.bulkSecret };
1041
  // since WP 2.8 ajaxurl is always defined in the admin header and points to admin-ajax.php
1042
  jQuery.ajax({
1043
  type: "POST",
1080
  + "<a class='button button-smaller' href='admin.php?action=shortpixel_check_quota'>" + _spTr.check__Quota + "</a>");
1081
  showToolBarAlert(ShortPixel.STATUS_QUOTA_EXCEEDED);
1082
  if(data['Stop'] == false) { //there are other items in the priority list, maybe processed, try those
1083
+ setBulkTimer(5000);
1084
  }
1085
  ShortPixel.otherMediaUpdateActions(id, ['quota','view']);
1086
  break;
1096
  ShortPixel.otherMediaUpdateActions(id, ['retry','view']);
1097
  }
1098
  console.log(data["Message"]);
1099
+ setBulkTimer(5000);
1100
  break;
1101
  case ShortPixel.STATUS_EMPTY_QUEUE:
1102
  console.log(data["Message"]);
1170
  if(isBulkPage && typeof data["BulkPercent"] !== 'undefined') {
1171
  progressUpdate(data["BulkPercent"], data["BulkMsg"]);
1172
  }
1173
+ setBulkTimer(5000);
1174
  break;
1175
 
1176
  case ShortPixel.STATUS_SKIP:
1194
  if(isBulkPage && data["Count"] > 3) {
1195
  ShortPixel.bulkShowLengthyMsg(id, data["Filename"], data["CustomImageLink"]);
1196
  }
1197
+ setBulkTimer(5000);
1198
  break;
1199
  case ShortPixel.STATUS_SEARCHING:
1200
  console.log('Server response: ' + response);
1203
  {
1204
  jQuery('.bulk-notice-msg.bulk-searching').show();
1205
  }
1206
+ setBulkTimer(2500);
1207
  break;
1208
  case ShortPixel.STATUS_MAINTENANCE:
1209
  ShortPixel.bulkShowMaintenanceMsg('maintenance');
1210
+ setBulkTimer(60000);
1211
  break;
1212
  case ShortPixel.STATUS_QUEUE_FULL:
1213
  ShortPixel.bulkShowMaintenanceMsg('queue-full');
1214
+ setBulkTimer(60000);
1215
  break;
1216
  default:
1217
  ShortPixel.retry("Unknown status " + data["Status"] + ". Retrying...");
1239
 
1240
  function clearBulkProcessor(){
1241
  ShortPixel.bulkProcessor = false; //nothing to process, leave the role. Next page load will check again
1242
+ localStorage.bulkTime = Date.now();
1243
+ setBulkTimer(0); // stop checking.
1244
+
1245
  if(window.location.href.search("wp-short-pixel-bulk") >= 0) {
1246
  localStorage.bulkPage = 0;
1247
  }
1275
  var resp = JSON.parse(response);
1276
  if(resp["Status"] == ShortPixel.STATUS_SUCCESS) {
1277
  //TODO - when calling several manual optimizations, the checkBulkProgress gets scheduled several times so several loops run in || - make only one.
1278
+ setBulkTimer(2000);
1279
+ ShortPixel.BULK_SECRET = false;
1280
  } else {
1281
  setCellMessage(id, typeof resp["Message"] !== "undefined" ? resp["Message"] : _spTr.thisContentNotProcessable, "");
1282
  }
1311
  jQuery.get(ShortPixel.AJAX_URL, data, function(response) {
1312
  data = JSON.parse(response);
1313
  if(data["Status"] == ShortPixel.STATUS_SUCCESS) {
1314
+ setBulkTimer(2000);
1315
+ ShortPixel.BULK_SECRET = false;
1316
  } else {
1317
  $msg = typeof data["Message"] !== "undefined" ? data["Message"] : _spTr.thisContentNotProcessable;
1318
  setCellMessage(id, $msg, "");
1330
  jQuery.get(ShortPixel.AJAX_URL, data, function(response) {
1331
  data = JSON.parse(response);
1332
  if(data["Status"] == ShortPixel.STATUS_SUCCESS) {
1333
+ setBulkTimer(2000);
1334
+ ShortPixel.BULK_SECRET = false;
1335
  } else {
1336
  setCellMessage(id, typeof data["Message"] !== "undefined" ? data["Message"] : _spTr.thisContentNotProcessable, "");
1337
  }
res/js/shortpixel.min.js CHANGED
@@ -1 +1 @@
1
- function showToolBarAlert(e,r,t){var o=jQuery("li.shortpixel-toolbar-processing");switch(e){case ShortPixel.STATUS_QUOTA_EXCEEDED:if(window.location.href.search("wp-short-pixel-bulk")>0&&0==jQuery(".sp-quota-exceeded-alert").length)return;o.addClass("shortpixel-alert"),o.addClass("shortpixel-quota-exceeded"),jQuery("a",o).attr("href","options-general.php?page=wp-shortpixel-settings"),jQuery("a div",o).attr("title","ShortPixel quota exceeded. Click for details.");break;case ShortPixel.STATUS_SKIP:case ShortPixel.STATUS_FAIL:o.addClass("shortpixel-alert shortpixel-processing"),jQuery("a div",o).attr("title",r),void 0!==t&&jQuery("a",o).attr("href","post.php?post="+t+"&action=edit");break;case ShortPixel.STATUS_NO_KEY:o.addClass("shortpixel-alert"),o.addClass("shortpixel-quota-exceeded"),jQuery("a",o).attr("href","options-general.php?page=wp-shortpixel-settings"),jQuery("a div",o).attr("title","Get API Key");break;case ShortPixel.STATUS_SUCCESS:case ShortPixel.STATUS_RETRY:o.addClass("shortpixel-processing"),o.removeClass("shortpixel-alert"),jQuery("a",o).removeAttr("target"),jQuery("a",o).attr("href",jQuery("a img",o).attr("success-url"))}o.removeClass("shortpixel-hide")}function hideToolBarAlert(e){var r=jQuery("li.shortpixel-toolbar-processing.shortpixel-processing");ShortPixel.STATUS_EMPTY_QUEUE==e&&(r.hasClass("shortpixel-alert")||r.hasClass("shortpixel-quota-exceeded"))||r.addClass("shortpixel-hide")}function hideQuotaExceededToolBarAlert(){jQuery("li.shortpixel-toolbar-processing.shortpixel-quota-exceeded").addClass("shortpixel-hide")}function checkQuotaExceededAlert(){"undefined"!=typeof shortPixelQuotaExceeded&&(1==shortPixelQuotaExceeded?showToolBarAlert(ShortPixel.STATUS_QUOTA_EXCEEDED):hideQuotaExceededToolBarAlert())}function checkBulkProgress(){var e=function(e){return r?"/":(r=!0,e)},r=!1,t=window.location.href.toLowerCase().replace(/\/\//g,e);r=!1;var o=ShortPixel.WP_ADMIN_URL.toLowerCase().replace(/\/\//g,e);t.search(o)<0&&(t=ShortPixel.convertPunycode(t),o=ShortPixel.convertPunycode(o)),1==ShortPixel.bulkProcessor&&window.location.href.search("wp-short-pixel-bulk")<0&&void 0!==localStorage.bulkPage&&localStorage.bulkPage>0&&(ShortPixel.bulkProcessor=!1),window.location.href.search("wp-short-pixel-bulk")>=0&&(ShortPixel.bulkProcessor=!0,localStorage.bulkTime=Math.floor(Date.now()/1e3),localStorage.bulkPage=1),1==ShortPixel.bulkProcessor||void 0===localStorage.bulkTime||Math.floor(Date.now()/1e3)-localStorage.bulkTime>90?(ShortPixel.bulkProcessor=!0,localStorage.bulkPage=window.location.href.search("wp-short-pixel-bulk")>=0?1:0,localStorage.bulkTime=Math.floor(Date.now()/1e3),console.log(localStorage.bulkTime),checkBulkProcessingCallApi()):setTimeout(checkBulkProgress,5e3)}function checkBulkProcessingCallApi(){jQuery.ajax({type:"POST",url:ShortPixel.AJAX_URL,data:{action:"shortpixel_image_processing"},success:function(e){if(e.length>0){r=null;try{var r=JSON.parse(e)}catch(e){return void ShortPixel.retry(e.message)}ShortPixel.retries=0;var t=r.ImageID,o=jQuery("div.short-pixel-bulk-page").length>0;switch(r.Status&&r.Status!=ShortPixel.STATUS_SEARCHING&&(ShortPixel.returnedStatusSearching>=2&&jQuery(".bulk-notice-msg.bulk-searching").hide(),ShortPixel.returnedStatusSearching=0),r.Status){case ShortPixel.STATUS_NO_KEY:setCellMessage(t,r.Message,'<a class=\'button button-smaller button-primary\' href="https://shortpixel.com/wp-apikey" target="_blank">'+_spTr.getApiKey+"</a>"),showToolBarAlert(ShortPixel.STATUS_NO_KEY);break;case ShortPixel.STATUS_QUOTA_EXCEEDED:setCellMessage(t,r.Message,'<a class=\'button button-smaller button-primary\' href="https://shortpixel.com/login/" target="_blank">'+_spTr.extendQuota+"</a><a class='button button-smaller' href='admin.php?action=shortpixel_check_quota'>"+_spTr.check__Quota+"</a>"),showToolBarAlert(ShortPixel.STATUS_QUOTA_EXCEEDED),0==r.Stop&&setTimeout(checkBulkProgress,5e3),ShortPixel.otherMediaUpdateActions(t,["quota","view"]);break;case ShortPixel.STATUS_FAIL:setCellMessage(t,r.Message,"<a class='button button-smaller button-primary' href=\"javascript:manualOptimization('"+t+"', true)\">"+_spTr.retry+"</a>"),showToolBarAlert(ShortPixel.STATUS_FAIL,r.Message,t),o&&(ShortPixel.bulkShowError(t,r.Message,r.Filename,r.CustomImageLink),r.BulkPercent&&progressUpdate(r.BulkPercent,r.BulkMsg),ShortPixel.otherMediaUpdateActions(t,["retry","view"])),console.log(r.Message),setTimeout(checkBulkProgress,5e3);break;case ShortPixel.STATUS_EMPTY_QUEUE:console.log(r.Message),clearBulkProcessor(),hideToolBarAlert(r.Status);var s=jQuery("#bulk-progress");o&&s.length&&"2"!=r.BulkStatus&&(progressUpdate(100,"Bulk finished!"),jQuery("a.bulk-cancel").attr("disabled","disabled"),hideSlider(),setTimeout(function(){window.location.reload()},3e3));break;case ShortPixel.STATUS_SUCCESS:o&&(ShortPixel.bulkHideLengthyMsg(),ShortPixel.bulkHideMaintenanceMsg());var i=r.PercentImprovement;showToolBarAlert(ShortPixel.STATUS_SUCCESS,"");var a=ShortPixel.isCustomImageId(t)?"":ShortPixel.successActions(t,r.Type,r.ThumbsCount,r.ThumbsTotal,r.BackupEnabled,r.Filename);if(setCellMessage(t,ShortPixel.successMsg(t,i,r.Type,r.ThumbsCount,r.RetinasCount),a),jQuery("#post-"+t).length>0&&jQuery("#post-"+t).find(".filename").text(r.Filename),jQuery(".misc-pub-filename strong").length>0&&jQuery(".misc-pub-filename strong").text(r.Filename),ShortPixel.isCustomImageId(t)&&r.TsOptimized&&r.TsOptimized.length>0){n=jQuery(".list-overview .item-"+t);jQuery(n).children(".date").text(r.TsOptimized),jQuery(n).find(".row-actions .action-optimize").remove()}var l=jQuery(["restore","view","redolossy","redoglossy","redolossless"]).not(["redo"+r.Type]).get();ShortPixel.otherMediaUpdateActions(t,l);new PercentageAnimator("#sp-msg-"+t+" span.percent",i).animate(i),o&&void 0!==r.Thumb&&(r.BulkPercent&&progressUpdate(r.BulkPercent,r.BulkMsg),r.Thumb.length>0&&(sliderUpdate(t,r.Thumb,r.BkThumb,r.PercentImprovement,r.Filename),void 0!==r.AverageCompression&&0+r.AverageCompression>0&&(jQuery("#sp-avg-optimization").html('<input type="text" class="dial" value="'+Math.round(r.AverageCompression)+'"/>'),ShortPixel.percentDial("#sp-avg-optimization .dial",60)))),console.log("Server response: "+e),o&&void 0!==r.BulkPercent&&progressUpdate(r.BulkPercent,r.BulkMsg),setTimeout(checkBulkProgress,5e3);break;case ShortPixel.STATUS_SKIP:1!==r.Silent&&ShortPixel.bulkShowError(t,r.Message,r.Filename,r.CustomImageLink);case ShortPixel.STATUS_ERROR:void 0!==r.Message&&(showToolBarAlert(ShortPixel.STATUS_SKIP,r.Message+" Image ID: "+t),setCellMessage(t,r.Message,"")),ShortPixel.otherMediaUpdateActions(t,["retry","view"]);case ShortPixel.STATUS_RETRY:console.log("Server response: "+e),showToolBarAlert(ShortPixel.STATUS_RETRY,""),o&&void 0!==r.BulkPercent&&progressUpdate(r.BulkPercent,r.BulkMsg),o&&r.Count>3&&ShortPixel.bulkShowLengthyMsg(t,r.Filename,r.CustomImageLink),setTimeout(checkBulkProgress,5e3);break;case ShortPixel.STATUS_SEARCHING:console.log("Server response: "+e),ShortPixel.returnedStatusSearching++,ShortPixel.returnedStatusSearching>=2&&jQuery(".bulk-notice-msg.bulk-searching").show(),setTimeout(checkBulkProgress,2500);break;case ShortPixel.STATUS_MAINTENANCE:ShortPixel.bulkShowMaintenanceMsg("maintenance"),setTimeout(checkBulkProgress,6e4);break;case ShortPixel.STATUS_QUEUE_FULL:ShortPixel.bulkShowMaintenanceMsg("queue-full"),setTimeout(checkBulkProgress,6e4);break;default:ShortPixel.retry("Unknown status "+r.Status+". Retrying...")}if(void 0!==t&&ShortPixel.isCustomImageId(t)){var n=jQuery(".list-overview .item-"+t);jQuery(n).find(".row-actions .action-optimize").remove(),r.actions&&jQuery(n).children(".actions").html(r.actions)}}},error:function(e){ShortPixel.retry(e.statusText)}})}function clearBulkProcessor(){ShortPixel.bulkProcessor=!1,localStorage.bulkTime=0,window.location.href.search("wp-short-pixel-bulk")>=0&&(localStorage.bulkPage=0)}function setCellMessage(e,r,t){var o=jQuery("#sp-msg-"+e);o.length>0&&(o.html("<div class='sp-column-actions'>"+t+"</div><div class='sp-column-info'>"+r+"</div>"),o.css("color","")),(o=jQuery("#sp-cust-msg-"+e)).length>0&&o.html("<div class='sp-column-info'>"+r+"</div>")}function manualOptimization(e,r){setCellMessage(e,"<img src='"+ShortPixel.WP_PLUGIN_URL+"/res/img/loading.gif' alt='"+_spTr.loading+"' class='sp-loading-small'>Image waiting to be processed",""),jQuery("li.shortpixel-toolbar-processing").removeClass("shortpixel-hide"),jQuery("li.shortpixel-toolbar-processing").removeClass("shortpixel-alert"),jQuery("li.shortpixel-toolbar-processing").addClass("shortpixel-processing");var t={action:"shortpixel_manual_optimization",image_id:e,cleanup:r};jQuery.ajax({type:"GET",url:ShortPixel.AJAX_URL,data:t,success:function(r){var t=JSON.parse(r);t.Status==ShortPixel.STATUS_SUCCESS?setTimeout(checkBulkProgress,2e3):setCellMessage(e,void 0!==t.Message?t.Message:_spTr.thisContentNotProcessable,"")},error:function(r){t.action="shortpixel_check_status",jQuery.ajax({type:"GET",url:ShortPixel.AJAX_URL,data:t,success:function(r){var t=JSON.parse(r);t.Status!==ShortPixel.STATUS_SUCCESS&&setCellMessage(e,void 0!==t.Message?t.Message:_spTr.thisContentNotProcessable,"")}})}})}function reoptimize(e,r){setCellMessage(e,"<img src='"+ShortPixel.WP_PLUGIN_URL+"/res/img/loading.gif' alt='"+_spTr.loading+"' class='sp-loading-small'>Image waiting to be reprocessed",""),jQuery("li.shortpixel-toolbar-processing").removeClass("shortpixel-hide"),jQuery("li.shortpixel-toolbar-processing").addClass("shortpixel-processing");var t={action:"shortpixel_redo",attachment_ID:e,type:r};jQuery.get(ShortPixel.AJAX_URL,t,function(r){(t=JSON.parse(r)).Status==ShortPixel.STATUS_SUCCESS?setTimeout(checkBulkProgress,2e3):($msg=void 0!==t.Message?t.Message:_spTr.thisContentNotProcessable,setCellMessage(e,$msg,""),showToolBarAlert(ShortPixel.STATUS_FAIL,$msg))})}function optimizeThumbs(e){setCellMessage(e,"<img src='"+ShortPixel.WP_PLUGIN_URL+"/res/img/loading.gif' alt='"+_spTr.loading+"' class='sp-loading-small'>"+_spTr.imageWaitOptThumbs,""),jQuery("li.shortpixel-toolbar-processing").removeClass("shortpixel-hide"),jQuery("li.shortpixel-toolbar-processing").addClass("shortpixel-processing");var r={action:"shortpixel_optimize_thumbs",attachment_ID:e};jQuery.get(ShortPixel.AJAX_URL,r,function(t){(r=JSON.parse(t)).Status==ShortPixel.STATUS_SUCCESS?setTimeout(checkBulkProgress,2e3):setCellMessage(e,void 0!==r.Message?r.Message:_spTr.thisContentNotProcessable,"")})}function dismissShortPixelNotice(e){jQuery("#short-pixel-notice-"+e).hide();var r={action:"shortpixel_dismiss_notice",notice_id:e};jQuery.get(ShortPixel.AJAX_URL,r,function(e){(r=JSON.parse(e)).Status==ShortPixel.STATUS_SUCCESS&&console.log("dismissed")})}function dismissFileError(){jQuery(".shortpixel-alert").hide();var e={action:"shortpixel_dismissFileError"};jQuery.get(ShortPixel.AJAX_URL,e,function(r){(e=JSON.parse(r)).Status==ShortPixel.STATUS_SUCCESS&&console.log("dismissed")})}function PercentageAnimator(e,r){this.animationSpeed=10,this.increment=2,this.curPercentage=0,this.targetPercentage=r,this.outputSelector=e,this.animate=function(e){this.targetPercentage=e,setTimeout(PercentageTimer.bind(null,this),this.animationSpeed)}}function PercentageTimer(e){e.curPercentage-e.targetPercentage<-e.increment?e.curPercentage+=e.increment:e.curPercentage-e.targetPercentage>e.increment?e.curPercentage-=e.increment:e.curPercentage=e.targetPercentage,jQuery(e.outputSelector).text(e.curPercentage+"%"),e.curPercentage!=e.targetPercentage&&setTimeout(PercentageTimer.bind(null,e),e.animationSpeed)}function progressUpdate(e,r){var t=jQuery("#bulk-progress");t.length&&(jQuery(".progress-left",t).css("width",e+"%"),jQuery(".progress-img",t).css("left",e+"%"),e>24?(jQuery(".progress-img span",t).html(""),jQuery(".progress-left",t).html(e+"%")):(jQuery(".progress-img span",t).html(e+"%"),jQuery(".progress-left",t).html("")),jQuery(".bulk-estimate").html(r))}function sliderUpdate(e,r,t,o,s){var i=jQuery(".bulk-slider div.bulk-slide:first-child");if(0!==i.length){"empty-slide"!=i.attr("id")&&i.hide(),i.css("z-index",1e3),jQuery(".bulk-img-opt",i).attr("src",""),void 0===t&&(t=""),t.length>0&&jQuery(".bulk-img-orig",i).attr("src","");var a=i.clone();a.attr("id","slide-"+e),jQuery(".bulk-img-opt",a).attr("src",r),t.length>0?(jQuery(".img-original",a).css("display","inline-block"),jQuery(".bulk-img-orig",a).attr("src",t)):jQuery(".img-original",a).css("display","none"),jQuery(".bulk-opt-percent",a).html('<input type="text" class="dial" value="'+o+'"/>'),jQuery(".bulk-slider").append(a),ShortPixel.percentDial("#"+a.attr("id")+" .dial",100),jQuery(".bulk-slider-container span.filename").html("&nbsp;&nbsp;"+s),"empty-slide"==i.attr("id")?(i.remove(),jQuery(".bulk-slider-container").css("display","block")):i.animate({left:i.width()+i.position().left},"slow","swing",function(){i.remove(),a.fadeIn("slow")})}}function hideSlider(){jQuery(".bulk-slider-container").css("display","none")}function showStats(){jQuery(".bulk-stats").length}function SPstringFormat(){var e=Array.prototype.slice.call(arguments);if(0!==e.length){var r=e.shift();for(i=0;i<e.length;i++)r=r.replace(new RegExp("\\{"+i+"\\}","gm"),e[i]);return r}}jQuery(document).ready(function(){ShortPixel.init()});var ShortPixel=function(){function e(e){jQuery(e).is(":checked")?jQuery("#width,#height").removeAttr("disabled"):jQuery("#width,#height").attr("disabled","disabled")}function r(){jQuery("#shortpixel-hs-button-blind").remove(),jQuery("#shortpixel-hs-tools").remove(),jQuery("#hs-beacon").remove(),jQuery("#botbutton").remove(),jQuery("#shortpixel-hs-blind").remove()}return jQuery("#key").keypress(function(e){13==e.which&&jQuery("#valid").val("validate")}),{init:function(){void 0===ShortPixel.API_IS_ACTIVE&&(jQuery("table.wp-list-table.media").length>0&&jQuery('select[name^="action"] option:last-child').before('<option value="short-pixel-bulk">'+_spTr.optimizeWithSP+'</option><option value="short-pixel-bulk-lossy"> → '+_spTr.redoLossy+'</option><option value="short-pixel-bulk-glossy"> → '+_spTr.redoGlossy+'</option><option value="short-pixel-bulk-lossless"> → '+_spTr.redoLossless+'</option><option value="short-pixel-bulk-restore"> → '+_spTr.restoreOriginal+"</option>"),ShortPixel.setOptions(ShortPixelConstants[0]),jQuery("#backup-folder-size").length&&jQuery("#backup-folder-size").html(ShortPixel.getBackupSize()),"todo"==ShortPixel.MEDIA_ALERT&&jQuery("div.media-frame.mode-grid").length>0&&jQuery("div.media-frame.mode-grid").before('<div id="short-pixel-media-alert" class="notice notice-warning"><p>'+SPstringFormat(_spTr.changeMLToListMode,'<a href="upload.php?mode=list" class="view-list"><span class="screen-reader-text">'," </span>",'</a><a class="alignright" href="javascript:ShortPixel.dismissMediaAlert();">',"</a>")+"</p></div>"),jQuery(window).on("beforeunload",function(){1==ShortPixel.bulkProcessor&&clearBulkProcessor()}),checkQuotaExceededAlert(),checkBulkProgress())},setOptions:function(e){for(var r in e)ShortPixel[r]=e[r]},isEmailValid:function(e){return/^\w+([\.+-]?\w+)*@\w+([\.-]?\w+)*(\.\w{1,63})+$/.test(e)},updateSignupEmail:function(){var e=jQuery("#pluginemail").val();ShortPixel.isEmailValid(e)&&jQuery("#request_key").removeClass("disabled"),jQuery("#request_key").attr("href",jQuery("#request_key").attr("href").split("?")[0]+"?pluginemail="+e)},validateKey:function(e){jQuery("#valid").val("validate"),jQuery(e).parents("form").submit()},enableResize:e,setupGeneralTab:function(){var r=0;void 0!==document.wp_shortpixel_options&&(r=document.wp_shortpixel_options.compressionType);for(var t=0,o=null;t<r.length;t++)r[t].onclick=function(){this!==o&&(o=this),void 0===ShortPixel.setupGeneralTabAlert&&(alert(_spTr.alertOnlyAppliesToNewImages),ShortPixel.setupGeneralTabAlert=1)};ShortPixel.enableResize("#resize"),jQuery("#resize").change(function(){e(this)}),jQuery(".resize-sizes").blur(function(e){var r=jQuery(e.target);if(ShortPixel.resizeSizesAlert!=r.val()){ShortPixel.resizeSizesAlert=r.val();var t=jQuery("#min-"+r.attr("name")).val(),o=jQuery("#min-"+r.attr("name")).data("nicename");r.val()<Math.min(t,1024)?(t>1024?alert(SPstringFormat(_spTr.pleaseDoNotSetLesser1024,o)):alert(SPstringFormat(_spTr.pleaseDoNotSetLesserSize,o,o,t)),e.preventDefault(),r.focus()):this.defaultValue=r.val()}}),jQuery(".shortpixel-confirm").click(function(e){return!!confirm(e.target.getAttribute("data-confirm"))||(e.preventDefault(),!1)}),jQuery('input[name="removeExif"], input[name="png2jpg"]').on("change",function(){ShortPixel.checkExifWarning()}),ShortPixel.checkExifWarning(),jQuery('input[name="backupImages"]').on("change",function(){ShortPixel.checkBackUpWarning()}),ShortPixel.checkBackUpWarning()},apiKeyChanged:function(){jQuery(".wp-shortpixel-options .shortpixel-key-valid").css("display","none"),jQuery(".wp-shortpixel-options button#validate").css("display","inline-block")},setupAdvancedTab:function(){jQuery("input.remove-folder-button").click(function(){var e=jQuery(this).data("value"),r=jQuery(this).data("name");1==confirm(SPstringFormat(_spTr.areYouSureStopOptimizing,r))&&(jQuery("#removeFolder").val(e),jQuery("#wp_shortpixel_options").submit())}),jQuery("input.recheck-folder-button").click(function(){var e=jQuery(this).data("value");1==confirm(SPstringFormat(_spTr.areYouSureStopOptimizing,e))&&(jQuery("#recheckFolder").val(e),jQuery("#wp_shortpixel_options").submit())})},checkThumbsUpdTotal:function(e){var r=jQuery("#"+(e.checked?"total":"main")+"ToProcess").val();jQuery("div.bulk-play span.total").text(r),jQuery("#displayTotal").text(r)},initSettings:function(){ShortPixel.adjustSettingsTabs(),ShortPixel.setupGeneralTab(),jQuery(window).resize(function(){ShortPixel.adjustSettingsTabs()}),jQuery("article.sp-tabs a.tab-link").click(function(e){var r=jQuery(e.target).data("id");ShortPixel.switchSettingsTab(r)}),jQuery("input[type=radio][name=deliverWebpType]").change(function(){"deliverWebpAltered"==this.value?window.confirm(_spTr.alertDeliverWebPAltered)?0==jQuery("input[type=radio][name=deliverWebpAlteringType]:checked").length&&jQuery("#deliverWebpAlteredWP").prop("checked",!0):jQuery(this).prop("checked",!1):"deliverWebpUnaltered"==this.value&&window.alert(_spTr.alertDeliverWebPUnaltered)})},switchSettingsTab:function(e){var r=e.replace("tab-",""),t="",o=jQuery("section#"+e);jQuery('input[name="display_part"]').val(r);var s=window.location.href.toString();if(s.indexOf("?")>0){var i=s.substring(0,s.indexOf("?"));i+="?"+jQuery.param({page:"wp-shortpixel-settings",part:r}),window.history.replaceState({},document.title,i)}if(o.length>0&&(jQuery("section").removeClass("sel-tab"),jQuery("section .wp-shortpixel-tab-content").fadeOut(50),jQuery(o).addClass("sel-tab"),ShortPixel.adjustSettingsTabs(),jQuery(o).find(".wp-shortpixel-tab-content").fadeIn(50)),"undefined"!=typeof HS&&void 0!==HS.beacon.suggest){switch(r){case"settings":t=shortpixel_suggestions_settings;break;case"adv-settings":t=shortpixel_suggestions_adv_settings;break;case"cloudflare":case"stats":t=shortpixel_suggestions_cloudflare}HS.beacon.suggest(t)}},adjustSettingsTabs:function(){var e=jQuery("section.sel-tab").height()+90;jQuery(".section-wrapper").css("height",e)},onBulkThumbsCheck:function(e){e.checked?(jQuery("#with-thumbs").css("display","inherit"),jQuery("#without-thumbs").css("display","none")):(jQuery("#without-thumbs").css("display","inherit"),jQuery("#with-thumbs").css("display","none"))},dismissMediaAlert:function(){var e={action:"shortpixel_dismiss_media_alert"};jQuery.get(ShortPixel.AJAX_URL,e,function(r){"success"==(e=JSON.parse(r)).Status&&jQuery("#short-pixel-media-alert").hide()})},closeHelpPane:r,dismissHelpPane:function(){r(),dismissShortPixelNotice("help")},checkQuota:function(){jQuery.get(ShortPixel.AJAX_URL,{action:"shortpixel_check_quota"},function(){console.log("quota refreshed")})},percentDial:function(e,r){jQuery(e).knob({readOnly:!0,width:r,height:r,fgColor:"#1CAECB",format:function(e){return e+"%"}})},successMsg:function(e,r,t,o,s){return(r>0?"<div class='sp-column-info'>"+_spTr.reducedBy+" <strong><span class='percent'>"+r+"%</span></strong> ":"")+(r>0&&r<5?"<br>":"")+(r<5?_spTr.bonusProcessing:"")+(t.length>0?" ("+t+")":"")+(0+o>0?"<br>"+SPstringFormat(_spTr.plusXthumbsOpt,o):"")+(0+s>0?"<br>"+SPstringFormat(_spTr.plusXretinasOpt,s):"")+"</div>"},successActions:function(e,r,t,o,s,i){if(1==s){var a=jQuery(".sp-column-actions-template").clone();if(!a.length)return!1;var l;return l=0==r.length?["lossy","lossless"]:["lossy","glossy","lossless"].filter(function(e){return!(e==r)}),a.html(a.html().replace(/__SP_ID__/g,e)),"pdf"==i.substr(i.lastIndexOf(".")+1).toLowerCase()&&jQuery(".sp-action-compare",a).remove(),0==t&&o>0?a.html(a.html().replace("__SP_THUMBS_TOTAL__",o)):(jQuery(".sp-action-optimize-thumbs",a).remove(),jQuery(".sp-dropbtn",a).removeClass("button-primary")),a.html(a.html().replace(/__SP_FIRST_TYPE__/g,l[0])),a.html(a.html().replace(/__SP_SECOND_TYPE__/g,l[1])),a.html()}return""},otherMediaUpdateActions:function(e,r){if(e=e.substring(2),jQuery(".shortpixel-other-media").length){for(var t=["optimize","retry","restore","redo","quota","view"],o=0,s=t.length;o<s;o++)jQuery("#"+t[o]+"_"+e).css("display","none");for(var o=0,s=r.length;o<s;o++)jQuery("#"+r[o]+"_"+e).css("display","")}},retry:function(e){ShortPixel.retries++,isNaN(ShortPixel.retries)&&(ShortPixel.retries=1),ShortPixel.retries<6?(console.log("Invalid response from server (Error: "+e+"). Retrying pass "+(ShortPixel.retries+1)+"..."),setTimeout(checkBulkProgress,5e3)):(ShortPixel.bulkShowError(-1,"Invalid response from server received 6 times. Please retry later by reloading this page, or <a href='https://shortpixel.com/contact' target='_blank'>contact support</a>. (Error: "+e+")",""),console.log("Invalid response from server 6 times. Giving up."))},initFolderSelector:function(){jQuery(".select-folder-button").click(function(){jQuery(".sp-folder-picker-shade").fadeIn(100),jQuery(".shortpixel-modal.modal-folder-picker").show();var e=jQuery(".sp-folder-picker");e.parent().css("margin-left",-e.width()/2),e.fileTree({script:ShortPixel.browseContent,multiFolder:!1})}),jQuery(".shortpixel-modal input.select-folder-cancel, .sp-folder-picker-shade").click(function(){jQuery(".sp-folder-picker-shade").fadeOut(100),jQuery(".shortpixel-modal.modal-folder-picker").hide()}),jQuery(".shortpixel-modal input.select-folder").click(function(e){if(r=jQuery("UL.jqueryFileTree LI.directory.selected"),0==jQuery(r).length)var r=jQuery("UL.jqueryFileTree LI.selected").parents(".directory");var t=jQuery(r).children("a").attr("rel");if(void 0!==t)if(t=t.trim()){var o=jQuery("#customFolderBase").val()+t;o=o.replace(/\/\//,"/"),console.debug("FullPath"+o),jQuery("#addCustomFolder").val(o),jQuery("#addCustomFolderView").val(o),jQuery(".sp-folder-picker-shade").fadeOut(100),jQuery(".shortpixel-modal.modal-folder-picker").css("display","none"),jQuery("#saveAdvAddFolder").removeClass("hidden")}else alert("Please select a folder from the list.")})},browseContent:function(e){e.action="shortpixel_browse_content";var r="";return jQuery.ajax({type:"POST",url:ShortPixel.AJAX_URL,data:e,success:function(e){r=e},async:!1}),r},getBackupSize:function(){var e="";return jQuery.ajax({type:"POST",url:ShortPixel.AJAX_URL,data:{action:"shortpixel_get_backup_size"},success:function(r){e=r},async:!1}),e},newApiKey:function(e){if(!jQuery("#tos").is(":checked"))return e.preventDefault(),jQuery("#tos-robo").fadeIn(400,function(){jQuery("#tos-hand").fadeIn()}),void jQuery("#tos").click(function(){jQuery("#tos-robo").css("display","none"),jQuery("#tos-hand").css("display","none")});if(jQuery("#request_key").addClass("disabled"),jQuery("#pluginemail_spinner").addClass("is-active"),ShortPixel.updateSignupEmail(),ShortPixel.isEmailValid(jQuery("#pluginemail").val())){jQuery("#pluginemail-error").css("display","none");var r={action:"shortpixel_new_api_key",email:jQuery("#pluginemail").val()};jQuery.ajax({type:"POST",async:!1,url:ShortPixel.AJAX_URL,data:r,success:function(r){data=JSON.parse(r),"success"==data.Status?(e.preventDefault(),window.location.reload()):"invalid"==data.Status&&(jQuery("#pluginemail-error").html("<b>"+data.Details+"</b>"),jQuery("#pluginemail-error").css("display",""),jQuery("#pluginemail-info").css("display","none"),e.preventDefault())}}),jQuery("#request_key").removeAttr("onclick")}else jQuery("#pluginemail-error").css("display",""),jQuery("#pluginemail-info").css("display","none"),e.preventDefault();jQuery("#request_key").removeClass("disabled"),jQuery("#pluginemail_spinner").removeClass("is-active")},proposeUpgrade:function(){jQuery("#shortPixelProposeUpgrade .sp-modal-body").addClass("sptw-modal-spinner"),jQuery("#shortPixelProposeUpgrade .sp-modal-body").html(""),jQuery("#shortPixelProposeUpgradeShade").css("display","block"),jQuery("#shortPixelProposeUpgrade").removeClass("shortpixel-hide"),jQuery.ajax({type:"POST",url:ShortPixel.AJAX_URL,data:{action:"shortpixel_propose_upgrade"},success:function(e){jQuery("#shortPixelProposeUpgrade .sp-modal-body").removeClass("sptw-modal-spinner"),jQuery("#shortPixelProposeUpgrade .sp-modal-body").html(e)}})},closeProposeUpgrade:function(){jQuery("#shortPixelProposeUpgradeShade").css("display","none"),jQuery("#shortPixelProposeUpgrade").addClass("shortpixel-hide"),ShortPixel.toRefresh&&ShortPixel.recheckQuota()},bulkShowLengthyMsg:function(e,r,t){var o=jQuery(".bulk-notice-msg.bulk-lengthy");if(0!=o.length){var s=jQuery("a",o);s.text(r),t?s.attr("href",t):s.attr("href",s.data("href").replace("__ID__",e)),o.css("display","block")}},bulkHideLengthyMsg:function(){jQuery(".bulk-notice-msg.bulk-lengthy").css("display","none")},bulkShowMaintenanceMsg:function(e){var r=jQuery(".bulk-notice-msg.bulk-"+e);0!=r.length&&r.css("display","block")},bulkHideMaintenanceMsg:function(e){jQuery(".bulk-notice-msg.bulk-"+e).css("display","none")},bulkShowError:function(e,r,t,o){var s=jQuery("#bulk-error-template");if(0!=s.length){var i=s.clone();i.attr("id","bulk-error-"+e),-1==e?(jQuery("span.sp-err-title",i).remove(),i.addClass("bulk-error-fatal")):(jQuery("img",i).remove(),jQuery("#bulk-error-".id).remove()),jQuery("span.sp-err-content",i).html(r);var a=jQuery("a.sp-post-link",i);o?a.attr("href",o):a.attr("href",a.attr("href").replace("__ID__",e)),a.text(t),s.after(i),i.css("display","block")}},confirmBulkAction:function(e,r){return!!confirm(_spTr["confirmBulk"+e])||(r.stopPropagation(),r.preventDefault(),!1)},checkRandomAnswer:function(e){var r=jQuery(e.target).val(),t=jQuery('input[name="random_answer"]').val(),o=jQuery('input[name="random_answer"]').data("target");r==t?(jQuery(o).removeClass("disabled").prop("disabled",!1),jQuery(o).removeAttr("aria-disabled")):jQuery(o).addClass("disabled").prop("disabled",!0)},removeBulkMsg:function(e){jQuery(e).parent().parent().remove()},isCustomImageId:function(e){return"C-"==e.substring(0,2)},recheckQuota:function(){var e=window.location.href.split("#");window.location.href=e[0]+(e[0].indexOf("?")>0?"&":"?")+"checkquota=1"+(void 0===e[1]?"":"#"+e[1])},openImageMenu:function(e){e.preventDefault(),this.menuCloseEvent||(jQuery(window).click(function(e){e.target.matches(".sp-dropbtn")||jQuery(".sp-dropdown.sp-show").removeClass("sp-show")}),this.menuCloseEvent=!0);var r=e.target.parentElement.classList.contains("sp-show");jQuery(".sp-dropdown.sp-show").removeClass("sp-show"),r||e.target.parentElement.classList.add("sp-show")},menuCloseEvent:!1,loadComparer:function(e){this.comparerData.origUrl=!1,!1===this.comparerData.cssLoaded&&(jQuery("<link>").appendTo("head").attr({type:"text/css",rel:"stylesheet",href:this.WP_PLUGIN_URL+"/res/css/twentytwenty.min.css"}),this.comparerData.cssLoaded=2),!1===this.comparerData.jsLoaded&&(jQuery.getScript(this.WP_PLUGIN_URL+"/res/js/jquery.twentytwenty.min.js",function(){ShortPixel.comparerData.jsLoaded=2,ShortPixel.comparerData.origUrl.length>0&&ShortPixel.displayComparerPopup(ShortPixel.comparerData.width,ShortPixel.comparerData.height,ShortPixel.comparerData.origUrl,ShortPixel.comparerData.optUrl)}),this.comparerData.jsLoaded=1),!1===this.comparerData.origUrl&&(jQuery.ajax({type:"POST",url:ShortPixel.AJAX_URL,data:{action:"shortpixel_get_comparer_data",id:e},success:function(e){data=JSON.parse(e),jQuery.extend(ShortPixel.comparerData,data),2==ShortPixel.comparerData.jsLoaded&&ShortPixel.displayComparerPopup(ShortPixel.comparerData.width,ShortPixel.comparerData.height,ShortPixel.comparerData.origUrl,ShortPixel.comparerData.optUrl)}}),this.comparerData.origUrl="")},displayComparerPopup:function(e,r,t,o){var s=e,i=r<150||e<350,a=jQuery(i?"#spUploadCompareSideBySide":"#spUploadCompare"),l=jQuery(".sp-modal-shade");i||jQuery("#spCompareSlider").html('<img alt="'+_spTr.originalImage+'" class="spUploadCompareOriginal"/><img alt="'+_spTr.optimizedImage+'" class="spUploadCompareOptimized"/>'),e=Math.max(350,Math.min(800,e<350?2*(e+25):r<150?e+25:e)),r=Math.max(150,i?s>350?2*(r+45):r+45:r*e/s);var n="-"+Math.round(e/2);jQuery(".sp-modal-body",a).css("width",e),jQuery(".shortpixel-slider",a).css("width",e),a.css("width",e),a.css("marginLeft",n+"px"),jQuery(".sp-modal-body",a).css("height",r),a.show(),l.show(),i||jQuery("#spCompareSlider").twentytwenty({slider_move:"mousemove"}),jQuery(".sp-close-button").on("click",ShortPixel.closeComparerPopup),jQuery(document).on("keyup.sp_modal_active",ShortPixel.closeComparerPopup),jQuery(".sp-modal-shade").on("click",ShortPixel.closeComparerPopup);var u=jQuery(".spUploadCompareOptimized",a);jQuery(".spUploadCompareOriginal",a).attr("src",t),setTimeout(function(){jQuery(window).trigger("resize")},1e3),u.load(function(){jQuery(window).trigger("resize")}),u.attr("src",o)},closeComparerPopup:function(e){jQuery("#spUploadCompareSideBySide").hide(),jQuery("#spUploadCompare").hide(),jQuery(".sp-modal-shade").hide(),jQuery(document).unbind("keyup.sp_modal_active"),jQuery(".sp-modal-shade").off("click"),jQuery(".sp-close-button").off("click")},convertPunycode:function(e){var r=document.createElement("a");return r.href=e,e.indexOf(r.protocol+"//"+r.hostname)<0?r.href:e.replace(r.protocol+"//"+r.hostname,r.protocol+"//"+r.hostname.split(".").map(function(e){return sp_punycode.toASCII(e)}).join("."))},checkExifWarning:function(){!jQuery('input[name="removeExif"]').is(":checked")&&jQuery('input[name="png2jpg"]').is(":checked")?jQuery(".exif_warning").fadeIn():jQuery(".exif_warning").fadeOut()},checkBackUpWarning:function(){jQuery('input[name="backupImages"]').is(":checked")?jQuery(".backup_warning").fadeOut():jQuery(".backup_warning").fadeIn()},comparerData:{cssLoaded:!1,jsLoaded:!1,origUrl:!1,optUrl:!1,width:0,height:0},toRefresh:!1,resizeSizesAlert:!1,returnedStatusSearching:0}}();
1
+ function showToolBarAlert(e,r,t){var o=jQuery("li.shortpixel-toolbar-processing");switch(e){case ShortPixel.STATUS_QUOTA_EXCEEDED:if(window.location.href.search("wp-short-pixel-bulk")>0&&0==jQuery(".sp-quota-exceeded-alert").length)return;o.addClass("shortpixel-alert"),o.addClass("shortpixel-quota-exceeded"),jQuery("a",o).attr("href","options-general.php?page=wp-shortpixel-settings"),jQuery("a div",o).attr("title","ShortPixel quota exceeded. Click for details.");break;case ShortPixel.STATUS_SKIP:case ShortPixel.STATUS_FAIL:o.addClass("shortpixel-alert shortpixel-processing"),jQuery("a div",o).attr("title",r),void 0!==t&&jQuery("a",o).attr("href","post.php?post="+t+"&action=edit");break;case ShortPixel.STATUS_NO_KEY:o.addClass("shortpixel-alert"),o.addClass("shortpixel-quota-exceeded"),jQuery("a",o).attr("href","options-general.php?page=wp-shortpixel-settings"),jQuery("a div",o).attr("title","Get API Key");break;case ShortPixel.STATUS_SUCCESS:case ShortPixel.STATUS_RETRY:o.addClass("shortpixel-processing"),o.removeClass("shortpixel-alert"),jQuery("a",o).removeAttr("target"),jQuery("a",o).attr("href",jQuery("a img",o).attr("success-url"))}o.removeClass("shortpixel-hide")}function hideToolBarAlert(e){var r=jQuery("li.shortpixel-toolbar-processing.shortpixel-processing");ShortPixel.STATUS_EMPTY_QUEUE==e&&(r.hasClass("shortpixel-alert")||r.hasClass("shortpixel-quota-exceeded"))||r.addClass("shortpixel-hide")}function hideQuotaExceededToolBarAlert(){jQuery("li.shortpixel-toolbar-processing.shortpixel-quota-exceeded").addClass("shortpixel-hide")}function checkQuotaExceededAlert(){"undefined"!=typeof shortPixelQuotaExceeded&&(1==shortPixelQuotaExceeded?showToolBarAlert(ShortPixel.STATUS_QUOTA_EXCEEDED):hideQuotaExceededToolBarAlert())}function checkBulkProgress(){var e=function(e){return r?"/":(r=!0,e)};var r=!1,t=window.location.href.toLowerCase().replace(/\/\//g,e);r=!1;var o=ShortPixel.WP_ADMIN_URL.toLowerCase().replace(/\/\//g,e);if(t.search(o)<0&&(t=ShortPixel.convertPunycode(t),o=ShortPixel.convertPunycode(o)),1==ShortPixel.bulkProcessor&&window.location.href.search("wp-short-pixel-bulk")<0&&void 0!==localStorage.bulkPage&&localStorage.bulkPage>0&&(ShortPixel.bulkProcessor=!1),window.location.href.search("wp-short-pixel-bulk")>=0&&(ShortPixel.bulkProcessor=!0,localStorage.bulkTime=Date.now(),localStorage.bulkPage=1,ShortPixel.BULK_SECRET=!1),!1!==ShortPixel.BULK_SECRET&&ShortPixel.BULK_SECRET!=localStorage.bulkSecret)return clearBulkProcessor(),jQuery("li.shortpixel-toolbar-processing").removeClass("shortpixel-processing"),void jQuery("li.shortpixel-toolbar-processing").addClass("shortpixel-hide");1==ShortPixel.bulkProcessor||void 0===localStorage.bulkTime||Date.now()-localStorage.bulkTime>1e4?(ShortPixel.bulkProcessor=!0,localStorage.bulkPage=window.location.href.search("wp-short-pixel-bulk")>=0?1:0,localStorage.bulkTime=Date.now(),null==localStorage.getItem("bulkSecret")&&(localStorage.bulkSecret=Math.random().toString(36).substring(7)),checkBulkProcessingCallApi(),setBulkTimer(5e3)):setBulkTimer(2e4)}function setBulkTimer(e){window.clearTimeout(bulkTimer),e>0&&(bulkTimer=window.setTimeout(checkBulkProgress,e))}function checkBulkProcessingCallApi(){var e={action:"shortpixel_image_processing","bulk-secret":localStorage.bulkSecret};jQuery.ajax({type:"POST",url:ShortPixel.AJAX_URL,data:e,success:function(e){if(e.length>0){r=null;try{var r=JSON.parse(e)}catch(e){return void ShortPixel.retry(e.message)}ShortPixel.retries=0;var t=r.ImageID,o=jQuery("div.short-pixel-bulk-page").length>0;switch(r.Status&&r.Status!=ShortPixel.STATUS_SEARCHING&&(ShortPixel.returnedStatusSearching>=2&&jQuery(".bulk-notice-msg.bulk-searching").hide(),ShortPixel.returnedStatusSearching=0),r.Status){case ShortPixel.STATUS_NO_KEY:setCellMessage(t,r.Message,'<a class=\'button button-smaller button-primary\' href="https://shortpixel.com/wp-apikey" target="_blank">'+_spTr.getApiKey+"</a>"),showToolBarAlert(ShortPixel.STATUS_NO_KEY);break;case ShortPixel.STATUS_QUOTA_EXCEEDED:setCellMessage(t,r.Message,'<a class=\'button button-smaller button-primary\' href="https://shortpixel.com/login/" target="_blank">'+_spTr.extendQuota+"</a><a class='button button-smaller' href='admin.php?action=shortpixel_check_quota'>"+_spTr.check__Quota+"</a>"),showToolBarAlert(ShortPixel.STATUS_QUOTA_EXCEEDED),0==r.Stop&&setBulkTimer(5e3),ShortPixel.otherMediaUpdateActions(t,["quota","view"]);break;case ShortPixel.STATUS_FAIL:setCellMessage(t,r.Message,"<a class='button button-smaller button-primary' href=\"javascript:manualOptimization('"+t+"', true)\">"+_spTr.retry+"</a>"),showToolBarAlert(ShortPixel.STATUS_FAIL,r.Message,t),o&&(ShortPixel.bulkShowError(t,r.Message,r.Filename,r.CustomImageLink),r.BulkPercent&&progressUpdate(r.BulkPercent,r.BulkMsg),ShortPixel.otherMediaUpdateActions(t,["retry","view"])),console.log(r.Message),setBulkTimer(5e3);break;case ShortPixel.STATUS_EMPTY_QUEUE:console.log(r.Message),clearBulkProcessor(),hideToolBarAlert(r.Status);var s=jQuery("#bulk-progress");o&&s.length&&"2"!=r.BulkStatus&&(progressUpdate(100,"Bulk finished!"),jQuery("a.bulk-cancel").attr("disabled","disabled"),hideSlider(),setTimeout(function(){window.location.reload()},3e3));break;case ShortPixel.STATUS_SUCCESS:o&&(ShortPixel.bulkHideLengthyMsg(),ShortPixel.bulkHideMaintenanceMsg());var i=r.PercentImprovement;showToolBarAlert(ShortPixel.STATUS_SUCCESS,"");var a=ShortPixel.isCustomImageId(t)?"":ShortPixel.successActions(t,r.Type,r.ThumbsCount,r.ThumbsTotal,r.BackupEnabled,r.Filename);if(setCellMessage(t,ShortPixel.successMsg(t,i,r.Type,r.ThumbsCount,r.RetinasCount),a),jQuery("#post-"+t).length>0&&jQuery("#post-"+t).find(".filename").text(r.Filename),jQuery(".misc-pub-filename strong").length>0&&jQuery(".misc-pub-filename strong").text(r.Filename),ShortPixel.isCustomImageId(t)&&r.TsOptimized&&r.TsOptimized.length>0){n=jQuery(".list-overview .item-"+t);jQuery(n).children(".date").text(r.TsOptimized),jQuery(n).find(".row-actions .action-optimize").remove()}var l=jQuery(["restore","view","redolossy","redoglossy","redolossless"]).not(["redo"+r.Type]).get();ShortPixel.otherMediaUpdateActions(t,l);new PercentageAnimator("#sp-msg-"+t+" span.percent",i).animate(i),o&&void 0!==r.Thumb&&(r.BulkPercent&&progressUpdate(r.BulkPercent,r.BulkMsg),r.Thumb.length>0&&(sliderUpdate(t,r.Thumb,r.BkThumb,r.PercentImprovement,r.Filename),void 0!==r.AverageCompression&&0+r.AverageCompression>0&&(jQuery("#sp-avg-optimization").html('<input type="text" class="dial" value="'+Math.round(r.AverageCompression)+'"/>'),ShortPixel.percentDial("#sp-avg-optimization .dial",60)))),console.log("Server response: "+e),o&&void 0!==r.BulkPercent&&progressUpdate(r.BulkPercent,r.BulkMsg),setBulkTimer(5e3);break;case ShortPixel.STATUS_SKIP:1!==r.Silent&&ShortPixel.bulkShowError(t,r.Message,r.Filename,r.CustomImageLink);case ShortPixel.STATUS_ERROR:void 0!==r.Message&&(showToolBarAlert(ShortPixel.STATUS_SKIP,r.Message+" Image ID: "+t),setCellMessage(t,r.Message,"")),ShortPixel.otherMediaUpdateActions(t,["retry","view"]);case ShortPixel.STATUS_RETRY:console.log("Server response: "+e),showToolBarAlert(ShortPixel.STATUS_RETRY,""),o&&void 0!==r.BulkPercent&&progressUpdate(r.BulkPercent,r.BulkMsg),o&&r.Count>3&&ShortPixel.bulkShowLengthyMsg(t,r.Filename,r.CustomImageLink),setBulkTimer(5e3);break;case ShortPixel.STATUS_SEARCHING:console.log("Server response: "+e),ShortPixel.returnedStatusSearching++,ShortPixel.returnedStatusSearching>=2&&jQuery(".bulk-notice-msg.bulk-searching").show(),setBulkTimer(2500);break;case ShortPixel.STATUS_MAINTENANCE:ShortPixel.bulkShowMaintenanceMsg("maintenance"),setBulkTimer(6e4);break;case ShortPixel.STATUS_QUEUE_FULL:ShortPixel.bulkShowMaintenanceMsg("queue-full"),setBulkTimer(6e4);break;default:ShortPixel.retry("Unknown status "+r.Status+". Retrying...")}if(void 0!==t&&ShortPixel.isCustomImageId(t)){var n=jQuery(".list-overview .item-"+t);jQuery(n).find(".row-actions .action-optimize").remove(),r.actions&&jQuery(n).children(".actions").html(r.actions)}}},error:function(e){ShortPixel.retry(e.statusText)}})}function clearBulkProcessor(){ShortPixel.bulkProcessor=!1,localStorage.bulkTime=Date.now(),setBulkTimer(0),window.location.href.search("wp-short-pixel-bulk")>=0&&(localStorage.bulkPage=0)}function setCellMessage(e,r,t){var o=jQuery("#sp-msg-"+e);o.length>0&&(o.html("<div class='sp-column-actions'>"+t+"</div><div class='sp-column-info'>"+r+"</div>"),o.css("color","")),(o=jQuery("#sp-cust-msg-"+e)).length>0&&o.html("<div class='sp-column-info'>"+r+"</div>")}function manualOptimization(e,r){setCellMessage(e,"<img src='"+ShortPixel.WP_PLUGIN_URL+"/res/img/loading.gif' alt='"+_spTr.loading+"' class='sp-loading-small'>Image waiting to be processed",""),jQuery("li.shortpixel-toolbar-processing").removeClass("shortpixel-hide"),jQuery("li.shortpixel-toolbar-processing").removeClass("shortpixel-alert"),jQuery("li.shortpixel-toolbar-processing").addClass("shortpixel-processing");var t={action:"shortpixel_manual_optimization",image_id:e,cleanup:r};jQuery.ajax({type:"GET",url:ShortPixel.AJAX_URL,data:t,success:function(r){var t=JSON.parse(r);t.Status==ShortPixel.STATUS_SUCCESS?(setBulkTimer(2e3),ShortPixel.BULK_SECRET=!1):setCellMessage(e,void 0!==t.Message?t.Message:_spTr.thisContentNotProcessable,"")},error:function(r){t.action="shortpixel_check_status",jQuery.ajax({type:"GET",url:ShortPixel.AJAX_URL,data:t,success:function(r){var t=JSON.parse(r);t.Status!==ShortPixel.STATUS_SUCCESS&&setCellMessage(e,void 0!==t.Message?t.Message:_spTr.thisContentNotProcessable,"")}})}})}function reoptimize(e,r){setCellMessage(e,"<img src='"+ShortPixel.WP_PLUGIN_URL+"/res/img/loading.gif' alt='"+_spTr.loading+"' class='sp-loading-small'>Image waiting to be reprocessed",""),jQuery("li.shortpixel-toolbar-processing").removeClass("shortpixel-hide"),jQuery("li.shortpixel-toolbar-processing").addClass("shortpixel-processing");var t={action:"shortpixel_redo",attachment_ID:e,type:r};jQuery.get(ShortPixel.AJAX_URL,t,function(r){(t=JSON.parse(r)).Status==ShortPixel.STATUS_SUCCESS?(setBulkTimer(2e3),ShortPixel.BULK_SECRET=!1):($msg=void 0!==t.Message?t.Message:_spTr.thisContentNotProcessable,setCellMessage(e,$msg,""),showToolBarAlert(ShortPixel.STATUS_FAIL,$msg))})}function optimizeThumbs(e){setCellMessage(e,"<img src='"+ShortPixel.WP_PLUGIN_URL+"/res/img/loading.gif' alt='"+_spTr.loading+"' class='sp-loading-small'>"+_spTr.imageWaitOptThumbs,""),jQuery("li.shortpixel-toolbar-processing").removeClass("shortpixel-hide"),jQuery("li.shortpixel-toolbar-processing").addClass("shortpixel-processing");var r={action:"shortpixel_optimize_thumbs",attachment_ID:e};jQuery.get(ShortPixel.AJAX_URL,r,function(t){(r=JSON.parse(t)).Status==ShortPixel.STATUS_SUCCESS?(setBulkTimer(2e3),ShortPixel.BULK_SECRET=!1):setCellMessage(e,void 0!==r.Message?r.Message:_spTr.thisContentNotProcessable,"")})}function dismissShortPixelNotice(e){jQuery("#short-pixel-notice-"+e).hide();var r={action:"shortpixel_dismiss_notice",notice_id:e};jQuery.get(ShortPixel.AJAX_URL,r,function(e){(r=JSON.parse(e)).Status==ShortPixel.STATUS_SUCCESS&&console.log("dismissed")})}function dismissFileError(){jQuery(".shortpixel-alert").hide();var e={action:"shortpixel_dismissFileError"};jQuery.get(ShortPixel.AJAX_URL,e,function(r){(e=JSON.parse(r)).Status==ShortPixel.STATUS_SUCCESS&&console.log("dismissed")})}function PercentageAnimator(e,r){this.animationSpeed=10,this.increment=2,this.curPercentage=0,this.targetPercentage=r,this.outputSelector=e,this.animate=function(e){this.targetPercentage=e,setTimeout(PercentageTimer.bind(null,this),this.animationSpeed)}}function PercentageTimer(e){e.curPercentage-e.targetPercentage<-e.increment?e.curPercentage+=e.increment:e.curPercentage-e.targetPercentage>e.increment?e.curPercentage-=e.increment:e.curPercentage=e.targetPercentage,jQuery(e.outputSelector).text(e.curPercentage+"%"),e.curPercentage!=e.targetPercentage&&setTimeout(PercentageTimer.bind(null,e),e.animationSpeed)}function progressUpdate(e,r){var t=jQuery("#bulk-progress");t.length&&(jQuery(".progress-left",t).css("width",e+"%"),jQuery(".progress-img",t).css("left",e+"%"),e>24?(jQuery(".progress-img span",t).html(""),jQuery(".progress-left",t).html(e+"%")):(jQuery(".progress-img span",t).html(e+"%"),jQuery(".progress-left",t).html("")),jQuery(".bulk-estimate").html(r))}function sliderUpdate(e,r,t,o,s){var i=jQuery(".bulk-slider div.bulk-slide:first-child");if(0!==i.length){"empty-slide"!=i.attr("id")&&i.hide(),i.css("z-index",1e3),jQuery(".bulk-img-opt",i).attr("src",""),void 0===t&&(t=""),t.length>0&&jQuery(".bulk-img-orig",i).attr("src","");var a=i.clone();a.attr("id","slide-"+e),jQuery(".bulk-img-opt",a).attr("src",r),t.length>0?(jQuery(".img-original",a).css("display","inline-block"),jQuery(".bulk-img-orig",a).attr("src",t)):jQuery(".img-original",a).css("display","none"),jQuery(".bulk-opt-percent",a).html('<input type="text" class="dial" value="'+o+'"/>'),jQuery(".bulk-slider").append(a),ShortPixel.percentDial("#"+a.attr("id")+" .dial",100),jQuery(".bulk-slider-container span.filename").html("&nbsp;&nbsp;"+s),"empty-slide"==i.attr("id")?(i.remove(),jQuery(".bulk-slider-container").css("display","block")):i.animate({left:i.width()+i.position().left},"slow","swing",function(){i.remove(),a.fadeIn("slow")})}}function hideSlider(){jQuery(".bulk-slider-container").css("display","none")}function showStats(){jQuery(".bulk-stats").length}function SPstringFormat(){var e=Array.prototype.slice.call(arguments);if(0!==e.length){var r=e.shift();for(i=0;i<e.length;i++)r=r.replace(new RegExp("\\{"+i+"\\}","gm"),e[i]);return r}}jQuery(document).ready(function(){ShortPixel.init()});var bulkTimer,ShortPixel=function(){function e(e){jQuery(e).is(":checked")?jQuery("#width,#height").removeAttr("disabled"):jQuery("#width,#height").attr("disabled","disabled")}function r(){jQuery("#shortpixel-hs-button-blind").remove(),jQuery("#shortpixel-hs-tools").remove(),jQuery("#hs-beacon").remove(),jQuery("#botbutton").remove(),jQuery("#shortpixel-hs-blind").remove()}return jQuery("#key").keypress(function(e){13==e.which&&jQuery("#valid").val("validate")}),{init:function(){void 0===ShortPixel.API_IS_ACTIVE&&(jQuery("table.wp-list-table.media").length>0&&jQuery('select[name^="action"] option:last-child').before('<option value="short-pixel-bulk">'+_spTr.optimizeWithSP+'</option><option value="short-pixel-bulk-lossy"> → '+_spTr.redoLossy+'</option><option value="short-pixel-bulk-glossy"> → '+_spTr.redoGlossy+'</option><option value="short-pixel-bulk-lossless"> → '+_spTr.redoLossless+'</option><option value="short-pixel-bulk-restore"> → '+_spTr.restoreOriginal+"</option>"),ShortPixel.setOptions(ShortPixelConstants[0]),jQuery("#backup-folder-size").length&&jQuery("#backup-folder-size").html(ShortPixel.getBackupSize()),"todo"==ShortPixel.MEDIA_ALERT&&jQuery("div.media-frame.mode-grid").length>0&&jQuery("div.media-frame.mode-grid").before('<div id="short-pixel-media-alert" class="notice notice-warning"><p>'+SPstringFormat(_spTr.changeMLToListMode,'<a href="upload.php?mode=list" class="view-list"><span class="screen-reader-text">'," </span>",'</a><a class="alignright" href="javascript:ShortPixel.dismissMediaAlert();">',"</a>")+"</p></div>"),jQuery(window).on("beforeunload",function(){1==ShortPixel.bulkProcessor&&clearBulkProcessor()}),checkQuotaExceededAlert(),checkBulkProgress())},setOptions:function(e){for(var r in e)ShortPixel[r]=e[r]},isEmailValid:function(e){return/^\w+([\.+-]?\w+)*@\w+([\.-]?\w+)*(\.\w{1,63})+$/.test(e)},updateSignupEmail:function(){var e=jQuery("#pluginemail").val();ShortPixel.isEmailValid(e)&&jQuery("#request_key").removeClass("disabled"),jQuery("#request_key").attr("href",jQuery("#request_key").attr("href").split("?")[0]+"?pluginemail="+e)},validateKey:function(e){jQuery("#valid").val("validate"),jQuery(e).parents("form").submit()},enableResize:e,setupGeneralTab:function(){var r=0;void 0!==document.wp_shortpixel_options&&(r=document.wp_shortpixel_options.compressionType);for(var t=0,o=null;t<r.length;t++)r[t].onclick=function(){this!==o&&(o=this),void 0===ShortPixel.setupGeneralTabAlert&&(alert(_spTr.alertOnlyAppliesToNewImages),ShortPixel.setupGeneralTabAlert=1)};ShortPixel.enableResize("#resize"),jQuery("#resize").change(function(){e(this)}),jQuery(".resize-sizes").blur(function(e){var r=jQuery(e.target);if(ShortPixel.resizeSizesAlert!=r.val()){ShortPixel.resizeSizesAlert=r.val();var t=jQuery("#min-"+r.attr("name")).val(),o=jQuery("#min-"+r.attr("name")).data("nicename");r.val()<Math.min(t,1024)?(t>1024?alert(SPstringFormat(_spTr.pleaseDoNotSetLesser1024,o)):alert(SPstringFormat(_spTr.pleaseDoNotSetLesserSize,o,o,t)),e.preventDefault(),r.focus()):this.defaultValue=r.val()}}),jQuery(".shortpixel-confirm").click(function(e){return!!confirm(e.target.getAttribute("data-confirm"))||(e.preventDefault(),!1)}),jQuery('input[name="removeExif"], input[name="png2jpg"]').on("change",function(){ShortPixel.checkExifWarning()}),ShortPixel.checkExifWarning(),jQuery('input[name="backupImages"]').on("change",function(){ShortPixel.checkBackUpWarning()}),ShortPixel.checkBackUpWarning()},apiKeyChanged:function(){jQuery(".wp-shortpixel-options .shortpixel-key-valid").css("display","none"),jQuery(".wp-shortpixel-options button#validate").css("display","inline-block")},setupAdvancedTab:function(){jQuery("input.remove-folder-button").click(function(){var e=jQuery(this).data("value"),r=jQuery(this).data("name");1==confirm(SPstringFormat(_spTr.areYouSureStopOptimizing,r))&&(jQuery("#removeFolder").val(e),jQuery("#wp_shortpixel_options").submit())}),jQuery("input.recheck-folder-button").click(function(){var e=jQuery(this).data("value");1==confirm(SPstringFormat(_spTr.areYouSureStopOptimizing,e))&&(jQuery("#recheckFolder").val(e),jQuery("#wp_shortpixel_options").submit())})},checkThumbsUpdTotal:function(e){var r=jQuery("#"+(e.checked?"total":"main")+"ToProcess").val();jQuery("div.bulk-play span.total").text(r),jQuery("#displayTotal").text(r)},initSettings:function(){ShortPixel.adjustSettingsTabs(),ShortPixel.setupGeneralTab(),jQuery(window).resize(function(){ShortPixel.adjustSettingsTabs()}),jQuery("article.sp-tabs a.tab-link").click(function(e){var r=jQuery(e.target).data("id");ShortPixel.switchSettingsTab(r)}),jQuery("input[type=radio][name=deliverWebpType]").change(function(){"deliverWebpAltered"==this.value?window.confirm(_spTr.alertDeliverWebPAltered)?0==jQuery("input[type=radio][name=deliverWebpAlteringType]:checked").length&&jQuery("#deliverWebpAlteredWP").prop("checked",!0):jQuery(this).prop("checked",!1):"deliverWebpUnaltered"==this.value&&window.alert(_spTr.alertDeliverWebPUnaltered)})},switchSettingsTab:function(e){var r=e.replace("tab-",""),t="",o=jQuery("section#"+e);jQuery('input[name="display_part"]').val(r);var s=window.location.href.toString();if(s.indexOf("?")>0){var i=s.substring(0,s.indexOf("?"));i+="?"+jQuery.param({page:"wp-shortpixel-settings",part:r}),window.history.replaceState({},document.title,i)}if(o.length>0&&(jQuery("section").removeClass("sel-tab"),jQuery("section .wp-shortpixel-tab-content").fadeOut(50),jQuery(o).addClass("sel-tab"),ShortPixel.adjustSettingsTabs(),jQuery(o).find(".wp-shortpixel-tab-content").fadeIn(50)),"undefined"!=typeof HS&&void 0!==HS.beacon.suggest){switch(r){case"settings":t=shortpixel_suggestions_settings;break;case"adv-settings":t=shortpixel_suggestions_adv_settings;break;case"cloudflare":case"stats":t=shortpixel_suggestions_cloudflare}HS.beacon.suggest(t)}},adjustSettingsTabs:function(){var e=jQuery("section.sel-tab").height()+90;jQuery(".section-wrapper").css("height",e)},onBulkThumbsCheck:function(e){e.checked?(jQuery("#with-thumbs").css("display","inherit"),jQuery("#without-thumbs").css("display","none")):(jQuery("#without-thumbs").css("display","inherit"),jQuery("#with-thumbs").css("display","none"))},dismissMediaAlert:function(){var e={action:"shortpixel_dismiss_media_alert"};jQuery.get(ShortPixel.AJAX_URL,e,function(r){"success"==(e=JSON.parse(r)).Status&&jQuery("#short-pixel-media-alert").hide()})},closeHelpPane:r,dismissHelpPane:function(){r(),dismissShortPixelNotice("help")},checkQuota:function(){jQuery.get(ShortPixel.AJAX_URL,{action:"shortpixel_check_quota"},function(){console.log("quota refreshed")})},percentDial:function(e,r){jQuery(e).knob({readOnly:!0,width:r,height:r,fgColor:"#1CAECB",format:function(e){return e+"%"}})},successMsg:function(e,r,t,o,s){return(r>0?"<div class='sp-column-info'>"+_spTr.reducedBy+" <strong><span class='percent'>"+r+"%</span></strong> ":"")+(r>0&&r<5?"<br>":"")+(r<5?_spTr.bonusProcessing:"")+(t.length>0?" ("+t+")":"")+(0+o>0?"<br>"+SPstringFormat(_spTr.plusXthumbsOpt,o):"")+(0+s>0?"<br>"+SPstringFormat(_spTr.plusXretinasOpt,s):"")+"</div>"},successActions:function(e,r,t,o,s,i){if(1==s){var a=jQuery(".sp-column-actions-template").clone();if(!a.length)return!1;var l;return l=0==r.length?["lossy","lossless"]:["lossy","glossy","lossless"].filter(function(e){return!(e==r)}),a.html(a.html().replace(/__SP_ID__/g,e)),"pdf"==i.substr(i.lastIndexOf(".")+1).toLowerCase()&&jQuery(".sp-action-compare",a).remove(),0==t&&o>0?a.html(a.html().replace("__SP_THUMBS_TOTAL__",o)):(jQuery(".sp-action-optimize-thumbs",a).remove(),jQuery(".sp-dropbtn",a).removeClass("button-primary")),a.html(a.html().replace(/__SP_FIRST_TYPE__/g,l[0])),a.html(a.html().replace(/__SP_SECOND_TYPE__/g,l[1])),a.html()}return""},otherMediaUpdateActions:function(e,r){if(e=e.substring(2),jQuery(".shortpixel-other-media").length){for(var t=["optimize","retry","restore","redo","quota","view"],o=0,s=t.length;o<s;o++)jQuery("#"+t[o]+"_"+e).css("display","none");for(var o=0,s=r.length;o<s;o++)jQuery("#"+r[o]+"_"+e).css("display","")}},retry:function(e){ShortPixel.retries++,isNaN(ShortPixel.retries)&&(ShortPixel.retries=1),ShortPixel.retries<6?(console.log("Invalid response from server (Error: "+e+"). Retrying pass "+(ShortPixel.retries+1)+"..."),setBulkTimer(5e3)):(ShortPixel.bulkShowError(-1,"Invalid response from server received 6 times. Please retry later by reloading this page, or <a href='https://shortpixel.com/contact' target='_blank'>contact support</a>. (Error: "+e+")",""),console.log("Invalid response from server 6 times. Giving up."))},initFolderSelector:function(){jQuery(".select-folder-button").click(function(){jQuery(".sp-folder-picker-shade").fadeIn(100),jQuery(".shortpixel-modal.modal-folder-picker").show();var e=jQuery(".sp-folder-picker");e.parent().css("margin-left",-e.width()/2),e.fileTree({script:ShortPixel.browseContent,multiFolder:!1})}),jQuery(".shortpixel-modal input.select-folder-cancel, .sp-folder-picker-shade").click(function(){jQuery(".sp-folder-picker-shade").fadeOut(100),jQuery(".shortpixel-modal.modal-folder-picker").hide()}),jQuery(".shortpixel-modal input.select-folder").click(function(e){if(r=jQuery("UL.jqueryFileTree LI.directory.selected"),0==jQuery(r).length)var r=jQuery("UL.jqueryFileTree LI.selected").parents(".directory");var t=jQuery(r).children("a").attr("rel");if(void 0!==t)if(t=t.trim()){var o=jQuery("#customFolderBase").val()+t;o=o.replace(/\/\//,"/"),console.debug("FullPath"+o),jQuery("#addCustomFolder").val(o),jQuery("#addCustomFolderView").val(o),jQuery(".sp-folder-picker-shade").fadeOut(100),jQuery(".shortpixel-modal.modal-folder-picker").css("display","none"),jQuery("#saveAdvAddFolder").removeClass("hidden")}else alert("Please select a folder from the list.")})},browseContent:function(e){e.action="shortpixel_browse_content";var r="";return jQuery.ajax({type:"POST",url:ShortPixel.AJAX_URL,data:e,success:function(e){r=e},async:!1}),r},getBackupSize:function(){var e="";return jQuery.ajax({type:"POST",url:ShortPixel.AJAX_URL,data:{action:"shortpixel_get_backup_size"},success:function(r){e=r},async:!1}),e},newApiKey:function(e){if(!jQuery("#tos").is(":checked"))return e.preventDefault(),jQuery("#tos-robo").fadeIn(400,function(){jQuery("#tos-hand").fadeIn()}),void jQuery("#tos").click(function(){jQuery("#tos-robo").css("display","none"),jQuery("#tos-hand").css("display","none")});if(jQuery("#request_key").addClass("disabled"),jQuery("#pluginemail_spinner").addClass("is-active"),ShortPixel.updateSignupEmail(),ShortPixel.isEmailValid(jQuery("#pluginemail").val())){jQuery("#pluginemail-error").css("display","none");var r={action:"shortpixel_new_api_key",email:jQuery("#pluginemail").val()};jQuery.ajax({type:"POST",async:!1,url:ShortPixel.AJAX_URL,data:r,success:function(r){data=JSON.parse(r),"success"==data.Status?(e.preventDefault(),window.location.reload()):"invalid"==data.Status&&(jQuery("#pluginemail-error").html("<b>"+data.Details+"</b>"),jQuery("#pluginemail-error").css("display",""),jQuery("#pluginemail-info").css("display","none"),e.preventDefault())}}),jQuery("#request_key").removeAttr("onclick")}else jQuery("#pluginemail-error").css("display",""),jQuery("#pluginemail-info").css("display","none"),e.preventDefault();jQuery("#request_key").removeClass("disabled"),jQuery("#pluginemail_spinner").removeClass("is-active")},proposeUpgrade:function(){jQuery("#shortPixelProposeUpgrade .sp-modal-body").addClass("sptw-modal-spinner"),jQuery("#shortPixelProposeUpgrade .sp-modal-body").html(""),jQuery("#shortPixelProposeUpgradeShade").css("display","block"),jQuery("#shortPixelProposeUpgrade").removeClass("shortpixel-hide"),jQuery.ajax({type:"POST",url:ShortPixel.AJAX_URL,data:{action:"shortpixel_propose_upgrade"},success:function(e){jQuery("#shortPixelProposeUpgrade .sp-modal-body").removeClass("sptw-modal-spinner"),jQuery("#shortPixelProposeUpgrade .sp-modal-body").html(e)}})},closeProposeUpgrade:function(){jQuery("#shortPixelProposeUpgradeShade").css("display","none"),jQuery("#shortPixelProposeUpgrade").addClass("shortpixel-hide"),ShortPixel.toRefresh&&ShortPixel.recheckQuota()},bulkShowLengthyMsg:function(e,r,t){var o=jQuery(".bulk-notice-msg.bulk-lengthy");if(0!=o.length){var s=jQuery("a",o);s.text(r),t?s.attr("href",t):s.attr("href",s.data("href").replace("__ID__",e)),o.css("display","block")}},bulkHideLengthyMsg:function(){jQuery(".bulk-notice-msg.bulk-lengthy").css("display","none")},bulkShowMaintenanceMsg:function(e){var r=jQuery(".bulk-notice-msg.bulk-"+e);0!=r.length&&r.css("display","block")},bulkHideMaintenanceMsg:function(e){jQuery(".bulk-notice-msg.bulk-"+e).css("display","none")},bulkShowError:function(e,r,t,o){var s=jQuery("#bulk-error-template");if(0!=s.length){var i=s.clone();i.attr("id","bulk-error-"+e),-1==e?(jQuery("span.sp-err-title",i).remove(),i.addClass("bulk-error-fatal")):(jQuery("img",i).remove(),jQuery("#bulk-error-".id).remove()),jQuery("span.sp-err-content",i).html(r);var a=jQuery("a.sp-post-link",i);o?a.attr("href",o):a.attr("href",a.attr("href").replace("__ID__",e)),a.text(t),s.after(i),i.css("display","block")}},confirmBulkAction:function(e,r){return!!confirm(_spTr["confirmBulk"+e])||(r.stopPropagation(),r.preventDefault(),!1)},checkRandomAnswer:function(e){var r=jQuery(e.target).val(),t=jQuery('input[name="random_answer"]').val(),o=jQuery('input[name="random_answer"]').data("target");r==t?(jQuery(o).removeClass("disabled").prop("disabled",!1),jQuery(o).removeAttr("aria-disabled")):jQuery(o).addClass("disabled").prop("disabled",!0)},removeBulkMsg:function(e){jQuery(e).parent().parent().remove()},isCustomImageId:function(e){return"C-"==e.substring(0,2)},recheckQuota:function(){var e=window.location.href.split("#");window.location.href=e[0]+(e[0].indexOf("?")>0?"&":"?")+"checkquota=1"+(void 0===e[1]?"":"#"+e[1])},openImageMenu:function(e){e.preventDefault(),this.menuCloseEvent||(jQuery(window).click(function(e){e.target.matches(".sp-dropbtn")||jQuery(".sp-dropdown.sp-show").removeClass("sp-show")}),this.menuCloseEvent=!0);var r=e.target.parentElement.classList.contains("sp-show");jQuery(".sp-dropdown.sp-show").removeClass("sp-show"),r||e.target.parentElement.classList.add("sp-show")},menuCloseEvent:!1,loadComparer:function(e){this.comparerData.origUrl=!1,!1===this.comparerData.cssLoaded&&(jQuery("<link>").appendTo("head").attr({type:"text/css",rel:"stylesheet",href:this.WP_PLUGIN_URL+"/res/css/twentytwenty.min.css"}),this.comparerData.cssLoaded=2),!1===this.comparerData.jsLoaded&&(jQuery.getScript(this.WP_PLUGIN_URL+"/res/js/jquery.twentytwenty.min.js",function(){ShortPixel.comparerData.jsLoaded=2,ShortPixel.comparerData.origUrl.length>0&&ShortPixel.displayComparerPopup(ShortPixel.comparerData.width,ShortPixel.comparerData.height,ShortPixel.comparerData.origUrl,ShortPixel.comparerData.optUrl)}),this.comparerData.jsLoaded=1),!1===this.comparerData.origUrl&&(jQuery.ajax({type:"POST",url:ShortPixel.AJAX_URL,data:{action:"shortpixel_get_comparer_data",id:e},success:function(e){data=JSON.parse(e),jQuery.extend(ShortPixel.comparerData,data),2==ShortPixel.comparerData.jsLoaded&&ShortPixel.displayComparerPopup(ShortPixel.comparerData.width,ShortPixel.comparerData.height,ShortPixel.comparerData.origUrl,ShortPixel.comparerData.optUrl)}}),this.comparerData.origUrl="")},displayComparerPopup:function(e,r,t,o){var s=e,i=r<150||e<350,a=jQuery(i?"#spUploadCompareSideBySide":"#spUploadCompare"),l=jQuery(".sp-modal-shade");i||jQuery("#spCompareSlider").html('<img alt="'+_spTr.originalImage+'" class="spUploadCompareOriginal"/><img alt="'+_spTr.optimizedImage+'" class="spUploadCompareOptimized"/>'),e=Math.max(350,Math.min(800,e<350?2*(e+25):r<150?e+25:e)),r=Math.max(150,i?s>350?2*(r+45):r+45:r*e/s);var n="-"+Math.round(e/2);jQuery(".sp-modal-body",a).css("width",e),jQuery(".shortpixel-slider",a).css("width",e),a.css("width",e),a.css("marginLeft",n+"px"),jQuery(".sp-modal-body",a).css("height",r),a.show(),l.show(),i||jQuery("#spCompareSlider").twentytwenty({slider_move:"mousemove"}),jQuery(".sp-close-button").on("click",ShortPixel.closeComparerPopup),jQuery(document).on("keyup.sp_modal_active",ShortPixel.closeComparerPopup),jQuery(".sp-modal-shade").on("click",ShortPixel.closeComparerPopup);var u=jQuery(".spUploadCompareOptimized",a);jQuery(".spUploadCompareOriginal",a).attr("src",t),setTimeout(function(){jQuery(window).trigger("resize")},1e3),u.load(function(){jQuery(window).trigger("resize")}),u.attr("src",o)},closeComparerPopup:function(e){jQuery("#spUploadCompareSideBySide").hide(),jQuery("#spUploadCompare").hide(),jQuery(".sp-modal-shade").hide(),jQuery(document).unbind("keyup.sp_modal_active"),jQuery(".sp-modal-shade").off("click"),jQuery(".sp-close-button").off("click")},convertPunycode:function(e){var r=document.createElement("a");return r.href=e,e.indexOf(r.protocol+"//"+r.hostname)<0?r.href:e.replace(r.protocol+"//"+r.hostname,r.protocol+"//"+r.hostname.split(".").map(function(e){return sp_punycode.toASCII(e)}).join("."))},checkExifWarning:function(){!jQuery('input[name="removeExif"]').is(":checked")&&jQuery('input[name="png2jpg"]').is(":checked")?jQuery(".exif_warning").fadeIn():jQuery(".exif_warning").fadeOut(),!jQuery('input[name="removeExif"]').is(":checked")&&jQuery(".exif_imagick_warning").data("imagick")<=0?jQuery(".exif_imagick_warning").fadeIn():jQuery(".exif_imagick_warning").fadeOut()},checkBackUpWarning:function(){jQuery('input[name="backupImages"]').is(":checked")?jQuery(".backup_warning").fadeOut():jQuery(".backup_warning").fadeIn()},comparerData:{cssLoaded:!1,jsLoaded:!1,origUrl:!1,optUrl:!1,width:0,height:0},toRefresh:!1,resizeSizesAlert:!1,returnedStatusSearching:0}}();
shortpixel-plugin.php CHANGED
@@ -187,7 +187,7 @@ class ShortPixelPlugin
187
  $admin_pages[] = add_media_page( __('Other Media Optimized by ShortPixel','shortpixel-image-optimiser'), __('Other Media','shortpixel-image-optimiser'), 'edit_others_posts', 'wp-short-pixel-custom', array( $this, 'route' ) );
188
  }
189
  /*translators: title and menu name for the Bulk Processing page*/
190
- $admin_pages[] = add_media_page( __('ShortPixel Bulk Process','shortpixel-image-optimiser'), __('Bulk ShortPixel','shortpixel-image-optimiser'), 'edit_others_posts', 'wp-short-pixel-bulk', array( $this->shortPixel, 'bulkProcess' ) );
191
 
192
  $this->admin_pages = $admin_pages;
193
  }
@@ -289,6 +289,8 @@ class ShortPixelPlugin
289
 
290
  $default_action = 'load'; // generic action on controller.
291
  $action = isset($_REQUEST['sp-action']) ? sanitize_text_field($_REQUEST['sp-action']) : $default_action;
 
 
292
  $controller = false;
293
 
294
  if ($this->env()->is_debug)
@@ -296,21 +298,27 @@ class ShortPixelPlugin
296
  $this->load_script('shortpixel-debug');
297
  }
298
 
 
 
 
299
  switch($plugin_page)
300
  {
301
  case 'wp-shortpixel-settings': // settings
302
- /* $this->load_style('shortpixel-admin');
303
- $this->load_style('shortpixel');
304
- $this->load_style('shortpixel-modal');
305
- $this->load_style('sp-file-tree');
306
- $this->load_script('sp-file-tree'); */
307
  $controller = \shortPixelTools::namespaceit("SettingsController");
308
- $url = menu_page_url($plugin_page, false);
309
  break;
310
  case 'wp-short-pixel-custom': // other media
311
  /* $this->load_style('shortpixel-othermedia'); */
312
  $controller = \shortPixelTools::namespaceit('OtherMediaViewController');
313
- $url = menu_page_url($plugin_page, false);
 
 
 
 
 
 
 
 
 
314
  break;
315
  }
316
 
@@ -397,6 +405,8 @@ class ShortPixelPlugin
397
  \WpShortPixel::alterHtaccess(); //add the htaccess lines
398
  }
399
 
 
 
400
  adminNoticesController::resetCompatNotice();
401
  adminNoticesController::resetAPINotices();
402
  adminNoticesController::resetQuotaNotices();
187
  $admin_pages[] = add_media_page( __('Other Media Optimized by ShortPixel','shortpixel-image-optimiser'), __('Other Media','shortpixel-image-optimiser'), 'edit_others_posts', 'wp-short-pixel-custom', array( $this, 'route' ) );
188
  }
189
  /*translators: title and menu name for the Bulk Processing page*/
190
+ $admin_pages[] = add_media_page( __('ShortPixel Bulk Process','shortpixel-image-optimiser'), __('Bulk ShortPixel','shortpixel-image-optimiser'), 'edit_others_posts', 'wp-short-pixel-bulk', array( $this, 'route' ) );
191
 
192
  $this->admin_pages = $admin_pages;
193
  }
289
 
290
  $default_action = 'load'; // generic action on controller.
291
  $action = isset($_REQUEST['sp-action']) ? sanitize_text_field($_REQUEST['sp-action']) : $default_action;
292
+ $template_part = isset($_GET['part']) ? sanitize_text_field($_GET['part']) : false;
293
+
294
  $controller = false;
295
 
296
  if ($this->env()->is_debug)
298
  $this->load_script('shortpixel-debug');
299
  }
300
 
301
+ $url = menu_page_url($plugin_page, false);
302
+
303
+
304
  switch($plugin_page)
305
  {
306
  case 'wp-shortpixel-settings': // settings
 
 
 
 
 
307
  $controller = \shortPixelTools::namespaceit("SettingsController");
 
308
  break;
309
  case 'wp-short-pixel-custom': // other media
310
  /* $this->load_style('shortpixel-othermedia'); */
311
  $controller = \shortPixelTools::namespaceit('OtherMediaViewController');
312
+ break;
313
+ case 'wp-short-pixel-bulk':
314
+ if ($template_part)
315
+ {
316
+ $partControl = ShortPixelController::findControllerbySlug($template_part);
317
+ if ($partControl)
318
+ $controller = $partControl;
319
+ }
320
+ else
321
+ $controller = \shortPixelTools::namespaceit('BulkViewController');
322
  break;
323
  }
324
 
405
  \WpShortPixel::alterHtaccess(); //add the htaccess lines
406
  }
407
 
408
+ \WpShortPixelDb::checkCustomTables();
409
+
410
  adminNoticesController::resetCompatNotice();
411
  adminNoticesController::resetAPINotices();
412
  adminNoticesController::resetQuotaNotices();
shortpixel_api.php CHANGED
@@ -112,7 +112,6 @@ class ShortPixelAPI {
112
  throw new Exception(__('Invalid API Key', 'shortpixel-image-optimiser'));
113
  }
114
 
115
- // WpShortPixel::log("DO REQUESTS for META: " . json_encode($itemHandler->getRawMeta()) . " STACK: " . json_encode(debug_backtrace()));
116
  $URLs = apply_filters('shortpixel_image_urls', $URLs, $itemHandler->getId()) ;
117
 
118
  $requestParameters = array(
@@ -143,10 +142,6 @@ class ShortPixelAPI {
143
  //only if $Blocking is true analyze the response
144
  if ( $Blocking )
145
  {
146
- //WpShortPixel::log("API response : " . json_encode($response));
147
-
148
- //die(var_dump(array('URL: ' => $this->_apiEndPoint, '<br><br>REQUEST:' => $requestParameters, '<br><br>RESPONSE: ' => $response, '<br><br>BODY: ' => isset($response['body']) ? $response['body'] : '' )));
149
- //there was an error, save this error inside file's SP optimization field
150
  if ( is_object($response) && get_class($response) == 'WP_Error' )
151
  {
152
  $errorMessage = $response->errors['http_request_failed'][0];
@@ -251,6 +246,7 @@ class ShortPixelAPI {
251
  }
252
  catch(Exception $e) {
253
  Log::addError('Api DoRequest Thrown ' . $e->getMessage());
 
254
  }
255
 
256
  //die($response['body']);
@@ -274,7 +270,7 @@ class ShortPixelAPI {
274
  $firstImage = $APIresponse[0];//extract as object first image
275
  switch($firstImage->Status->Code)
276
  {
277
- case 2: //self::STATUS_SUCCESS: <- @todo Success in this constant is 1 ,but appears to be 2? // success
278
  //handle image has been processed
279
  if(!isset($firstImage->Status->QuotaExceeded)) {
280
  $this->_settings->quotaExceeded = 0;//reset the quota exceeded flag
112
  throw new Exception(__('Invalid API Key', 'shortpixel-image-optimiser'));
113
  }
114
 
 
115
  $URLs = apply_filters('shortpixel_image_urls', $URLs, $itemHandler->getId()) ;
116
 
117
  $requestParameters = array(
142
  //only if $Blocking is true analyze the response
143
  if ( $Blocking )
144
  {
 
 
 
 
145
  if ( is_object($response) && get_class($response) == 'WP_Error' )
146
  {
147
  $errorMessage = $response->errors['http_request_failed'][0];
246
  }
247
  catch(Exception $e) {
248
  Log::addError('Api DoRequest Thrown ' . $e->getMessage());
249
+ $response = array(); // otherwise not set.
250
  }
251
 
252
  //die($response['body']);
270
  $firstImage = $APIresponse[0];//extract as object first image
271
  switch($firstImage->Status->Code)
272
  {
273
+ case 2: //self::STATUS_SUCCESS: <- @todo Success in this constant is 1 ,but appears to be 2? // success
274
  //handle image has been processed
275
  if(!isset($firstImage->Status->QuotaExceeded)) {
276
  $this->_settings->quotaExceeded = 0;//reset the quota exceeded flag
wp-shortpixel.php CHANGED
@@ -3,7 +3,7 @@
3
  * Plugin Name: ShortPixel Image Optimizer
4
  * Plugin URI: https://shortpixel.com/
5
  * Description: ShortPixel optimizes images automatically, while guarding the quality of your images. Check your <a href="options-general.php?page=wp-shortpixel-settings" target="_blank">Settings &gt; ShortPixel</a> page on how to start optimizing your image library and make your website load faster.
6
- * Version: 4.17.4
7
  * Author: ShortPixel
8
  * Author URI: https://shortpixel.com
9
  * Text Domain: shortpixel-image-optimiser
@@ -32,7 +32,7 @@ define('SHORTPIXEL_PLUGIN_DIR', __DIR__);
32
 
33
  //define('SHORTPIXEL_AFFILIATE_CODE', '');
34
 
35
- define('SHORTPIXEL_IMAGE_OPTIMISER_VERSION', "4.17.4");
36
  define('SHORTPIXEL_MAX_TIMEOUT', 10);
37
  define('SHORTPIXEL_VALIDATE_MAX_TIMEOUT', 15);
38
  define('SHORTPIXEL_BACKUP', 'ShortpixelBackups');
3
  * Plugin Name: ShortPixel Image Optimizer
4
  * Plugin URI: https://shortpixel.com/
5
  * Description: ShortPixel optimizes images automatically, while guarding the quality of your images. Check your <a href="options-general.php?page=wp-shortpixel-settings" target="_blank">Settings &gt; ShortPixel</a> page on how to start optimizing your image library and make your website load faster.
6
+ * Version: 4.18.0
7
  * Author: ShortPixel
8
  * Author URI: https://shortpixel.com
9
  * Text Domain: shortpixel-image-optimiser
32
 
33
  //define('SHORTPIXEL_AFFILIATE_CODE', '');
34
 
35
+ define('SHORTPIXEL_IMAGE_OPTIMISER_VERSION', "4.18.0");
36
  define('SHORTPIXEL_MAX_TIMEOUT', 10);
37
  define('SHORTPIXEL_VALIDATE_MAX_TIMEOUT', 15);
38
  define('SHORTPIXEL_BACKUP', 'ShortpixelBackups');