reGenerate Thumbnails Advanced - Version 2.4.0

Version Description

Release date: December 1st 2020 * New: Pause Button; * New: Resuming process from another page now starts paused; * New: Added Filter for increasing number of items processed per run; * Fix: Users optimizing more than 50K images could run into a code loop protection.

Download this release

Release Info

Developer petredobrescu
Plugin Icon 128x128 reGenerate Thumbnails Advanced
Version 2.4.0
Comparing to
See all releases

Code changes from version 2.3.2 to 2.4.0

build/shortpixel/PackageLoader.php CHANGED
@@ -3,31 +3,33 @@ namespace ReThumbAdvanced\Build;
3
 
4
  class PackageLoader
5
  {
6
- public $dir;
7
- public $composerFile = false;
8
 
9
- public function __construct()
10
- {
11
 
12
- }
13
 
14
- public function setComposerFile($filePath)
15
- {
16
- $this->composerFile = json_decode(file_get_contents($filePath),1);
17
- }
18
 
19
- public function getComposerFile($filePath = false )
20
- {
21
- if (! $this->composerFile)
22
- $this->composerFile = json_decode(file_get_contents($this->dir."/composer.json"), 1);
23
 
24
- return $this->composerFile;
25
- }
26
 
27
  public function load($dir)
28
  {
29
  $this->dir = $dir;
30
  $composer = $this->getComposerFile();
 
 
31
  if(isset($composer["autoload"]["psr-4"])){
32
  $this->loadPSR4($composer['autoload']['psr-4']);
33
  }
@@ -61,13 +63,11 @@ class PackageLoader
61
  public function loadPSR($namespaces, $psr4)
62
  {
63
  $dir = $this->dir;
64
-
65
  // Foreach namespace specified in the composer, load the given classes
66
  foreach ($namespaces as $namespace => $classpaths) {
67
  if (!is_array($classpaths)) {
68
  $classpaths = array($classpaths);
69
  }
70
-
71
  spl_autoload_register(function ($classname) use ($namespace, $classpaths, $dir, $psr4) {
72
  // Check if the namespace matches the class we are looking for
73
  if (preg_match("#^".preg_quote($namespace)."#", $classname)) {
@@ -76,7 +76,6 @@ class PackageLoader
76
  $classname = str_replace($namespace, "", $classname);
77
  }
78
 
79
-
80
  // $filename = preg_replace("#\\\\#", "", $classname).".php";
81
  // This is fix for nested classes which were losing a /
82
  $filename = ltrim($classname .'.php', '\\');
3
 
4
  class PackageLoader
5
  {
6
+ public $dir;
7
+ public $composerFile = false;
8
 
9
+ public function __construct()
10
+ {
11
 
12
+ }
13
 
14
+ public function setComposerFile($filePath)
15
+ {
16
+ $this->composerFile = json_decode(file_get_contents($filePath),1);
17
+ }
18
 
19
+ public function getComposerFile($filePath = false )
20
+ {
21
+ if (! $this->composerFile)
22
+ $this->composerFile = json_decode(file_get_contents($this->dir."/composer.json"), 1);
23
 
24
+ return $this->composerFile;
25
+ }
26
 
27
  public function load($dir)
28
  {
29
  $this->dir = $dir;
30
  $composer = $this->getComposerFile();
31
+
32
+
33
  if(isset($composer["autoload"]["psr-4"])){
34
  $this->loadPSR4($composer['autoload']['psr-4']);
35
  }
63
  public function loadPSR($namespaces, $psr4)
64
  {
65
  $dir = $this->dir;
 
66
  // Foreach namespace specified in the composer, load the given classes
67
  foreach ($namespaces as $namespace => $classpaths) {
68
  if (!is_array($classpaths)) {
69
  $classpaths = array($classpaths);
70
  }
 
71
  spl_autoload_register(function ($classname) use ($namespace, $classpaths, $dir, $psr4) {
72
  // Check if the namespace matches the class we are looking for
73
  if (preg_match("#^".preg_quote($namespace)."#", $classname)) {
76
  $classname = str_replace($namespace, "", $classname);
77
  }
78
 
 
79
  // $filename = preg_replace("#\\\\#", "", $classname).".php";
80
  // This is fix for nested classes which were losing a /
81
  $filename = ltrim($classname .'.php', '\\');
build/shortpixel/log/src/ShortPixelLogger.php CHANGED
@@ -138,6 +138,17 @@ namespace ReThumbAdvanced\ShortPixelLogger;
138
  return;
139
  }
140
 
 
 
 
 
 
 
 
 
 
 
 
141
  // Check where to log to.
142
  if ($this->logPath === false)
143
  {
@@ -237,6 +248,11 @@ namespace ReThumbAdvanced\ShortPixelLogger;
237
  $log = self::getInstance();
238
  $log->addLog($message, $level, $args);
239
  }
 
 
 
 
 
240
  public static function addInfo($message, $args = array())
241
  {
242
  $level = DebugItem::LEVEL_INFO;
@@ -321,6 +337,7 @@ namespace ReThumbAdvanced\ShortPixelLogger;
321
  $controller = $this;
322
 
323
  $template_path = __DIR__ . '/' . $this->template . '.php';
 
324
  if (file_exists($template_path))
325
  {
326
 
138
  return;
139
  }
140
 
141
+ // Force administrator on manuals.
142
+ if ( $this->is_manual_request )
143
+ {
144
+ if (! function_exists('wp_get_current_user')) // not loaded yet
145
+ return false;
146
+
147
+ $user_is_administrator = (current_user_can('manage_options')) ? true : false;
148
+ if (! $user_is_administrator)
149
+ return false;
150
+ }
151
+
152
  // Check where to log to.
153
  if ($this->logPath === false)
154
  {
248
  $log = self::getInstance();
249
  $log->addLog($message, $level, $args);
250
  }
251
+ // Alias, since it goes wrong so often.
252
+ public static function addWarning($message, $args = array())
253
+ {
254
+ self::addWarn($message, $args);
255
+ }
256
  public static function addInfo($message, $args = array())
257
  {
258
  $level = DebugItem::LEVEL_INFO;
337
  $controller = $this;
338
 
339
  $template_path = __DIR__ . '/' . $this->template . '.php';
340
+ // var_dump( $template_path);
341
  if (file_exists($template_path))
342
  {
343
 
build/shortpixel/notices/src/NoticeController.php CHANGED
@@ -19,7 +19,6 @@ class NoticeController //extends ShortPixelController
19
  /** For backward compat. Never call constructor directly. */
20
  public function __construct()
21
  {
22
- // $this->loadModel('notice');
23
  $ns = __NAMESPACE__;
24
  $ns = substr($ns, 0, strpos($ns, '\\')); // try to get first part of namespace
25
  $this->notice_option = $ns . '-notices';
@@ -40,6 +39,14 @@ class NoticeController //extends ShortPixelController
40
  return self::$instance;
41
  }
42
 
 
 
 
 
 
 
 
 
43
  /** Load Notices Config File, if any
44
  *
45
  * [ Future Use ]
@@ -68,7 +75,15 @@ class NoticeController //extends ShortPixelController
68
 
69
  if ($notices !== false && is_array($notices))
70
  {
71
- self::$notices = $notices;
 
 
 
 
 
 
 
 
72
  $this->has_stored = true;
73
  }
74
  else {
@@ -183,7 +198,7 @@ class NoticeController //extends ShortPixelController
183
  for($i = 0; $i < count(self::$notices); $i++)
184
  {
185
  $item = self::$notices[$i];
186
- if ($item->getID() == $id)
187
  {
188
  Log::addDebug('Removing notice with ID ' . $id);
189
  unset(self::$notices[$i]);
19
  /** For backward compat. Never call constructor directly. */
20
  public function __construct()
21
  {
 
22
  $ns = __NAMESPACE__;
23
  $ns = substr($ns, 0, strpos($ns, '\\')); // try to get first part of namespace
24
  $this->notice_option = $ns . '-notices';
39
  return self::$instance;
40
  }
41
 
42
+ /** Reset all notices, before loading them, to ensure on updates / activations one starts fresh */
43
+ public static function resetNotices()
44
+ {
45
+ $ns = __NAMESPACE__;
46
+ $ns = substr($ns, 0, strpos($ns, '\\')); // try to get first part of namespace
47
+ $result = delete_option($ns . '-notices');
48
+ }
49
+
50
  /** Load Notices Config File, if any
51
  *
52
  * [ Future Use ]
75
 
76
  if ($notices !== false && is_array($notices))
77
  {
78
+ $checked = array();
79
+ foreach($notices as $noticeObj)
80
+ {
81
+ if (is_object($noticeObj) && $noticeObj instanceOf NoticeModel)
82
+ {
83
+ $checked[] = $noticeObj;
84
+ }
85
+ }
86
+ self::$notices = $checked;
87
  $this->has_stored = true;
88
  }
89
  else {
198
  for($i = 0; $i < count(self::$notices); $i++)
199
  {
200
  $item = self::$notices[$i];
201
+ if (is_object($item) && $item->getID() == $id)
202
  {
203
  Log::addDebug('Removing notice with ID ' . $id);
204
  unset(self::$notices[$i]);
build/shortpixel/notices/src/NoticeModel.php CHANGED
@@ -134,6 +134,11 @@ class NoticeModel //extends ShortPixelModel
134
  self::$icons[$type] = $icon;
135
  }
136
 
 
 
 
 
 
137
  public function getForDisplay()
138
  {
139
  $this->viewed = true;
@@ -143,6 +148,21 @@ class NoticeModel //extends ShortPixelModel
143
 
144
  if ($this->callback)
145
  {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
146
  $return = call_user_func($this->callback, $this);
147
  if ($return === false) // don't display is callback returns false explicitly.
148
  return;
134
  self::$icons[$type] = $icon;
135
  }
136
 
137
+ private function checkIncomplete($var)
138
+ {
139
+ return ($var instanceof \__PHP_Incomplete_Class);
140
+ }
141
+
142
  public function getForDisplay()
143
  {
144
  $this->viewed = true;
148
 
149
  if ($this->callback)
150
  {
151
+ if (is_array($this->callback))
152
+ {
153
+ foreach($this->callback as $part)
154
+ {
155
+ if ($this->checkIncomplete($part) === true)
156
+ {
157
+ return false;
158
+ }
159
+ }
160
+ } elseif (is_object($this->callback))
161
+ {
162
+ if ($this->checkIncomplete($part) === true)
163
+ return false;
164
+ }
165
+
166
  $return = call_user_func($this->callback, $this);
167
  if ($return === false) // don't display is callback returns false explicitly.
168
  return;
build/shortpixel/shortq/composer.json CHANGED
@@ -1,7 +1,7 @@
1
  {
2
  "name": "shortpixel/shortq",
3
  "description": "Simple Queue",
4
- "version": 0.5,
5
  "type": "library",
6
  "license": "MIT",
7
  "authors": [
1
  {
2
  "name": "shortpixel/shortq",
3
  "description": "Simple Queue",
4
+ "version": 1.1,
5
  "type": "library",
6
  "license": "MIT",
7
  "authors": [
build/shortpixel/shortq/src/DataProvider/DataProvider.php CHANGED
@@ -10,14 +10,17 @@ use ReThumbAdvanced\ShortQ\Item as Item;
10
  */
11
  interface DataProvider
12
  {
13
-
14
  function __construct($pluginSlug, $queueName);
15
 
16
  //function add($items);
17
  function enqueue($items);
18
  function dequeue($args); // @return Items removed from queue and set to status. Returns Item Object
19
- function alterqueue($args); // @return Item Count / Boolean . Mass alteration of queue.
20
  function itemUpdate(Item $item, $new_status);
 
 
 
21
 
22
  // Returns number of items left in Queue.
23
  function itemCount($mode = 'waiting');
10
  */
11
  interface DataProvider
12
  {
13
+
14
  function __construct($pluginSlug, $queueName);
15
 
16
  //function add($items);
17
  function enqueue($items);
18
  function dequeue($args); // @return Items removed from queue and set to status. Returns Item Object
19
+ function alterQueue($changes, $conditions, $operators); // @return Item Count / Boolean . Mass alteration of queue. ( changes, what to change, conditions, basically where statement)
20
  function itemUpdate(Item $item, $new_status);
21
+ function getItem($item_id);
22
+ function getItems($args); // get items on basis of status / updated date /etc
23
+
24
 
25
  // Returns number of items left in Queue.
26
  function itemCount($mode = 'waiting');
build/shortpixel/shortq/src/DataProvider/MysqlDataProvider.php CHANGED
@@ -33,7 +33,7 @@ class MysqlDataProvider implements DataProvider
33
  return false;
34
  // start higher to allow priority additions easily.
35
  $list_order = (10 + $this->itemCount());
36
- $now = date('Y-m-d H:i:s');
37
 
38
  $sql = 'INSERT IGNORE INTO ' . $this->table . ' (queue_name, plugin_slug, value, list_order, item_id, updated, created) VALUES ';
39
  $values = array();
@@ -93,6 +93,7 @@ class MysqlDataProvider implements DataProvider
93
  'newstatus' => ShortQ::QSTATUS_DONE,
94
  'orderby' => 'list_order',
95
  'order' => 'ASC',
 
96
  );
97
 
98
  $args = wp_parse_args($args, $defaults);
@@ -105,6 +106,7 @@ class MysqlDataProvider implements DataProvider
105
  'status' => $args['status'],
106
  'orderby' => $args['orderby'],
107
  'order' => $args['order'],
 
108
  ));
109
 
110
  $id_array = array_keys($items);
@@ -112,8 +114,8 @@ class MysqlDataProvider implements DataProvider
112
  // Update status if results yielded.
113
  if ($args['status'] !== $args['newstatus'] && count($id_array) > 0)
114
  {
115
- $now = time();
116
- $this->updateRecords(array('status' => $args['newstatus'], 'updated' => $now ), array('id' => $id_array));
117
  foreach($items as $index => $item)
118
  {
119
  $item->status = $args['newstatus']; // update status to new situation.
@@ -130,7 +132,18 @@ class MysqlDataProvider implements DataProvider
130
  return array_values($items); // array values resets the id index returns by queryItems
131
  }
132
 
 
 
 
 
 
 
 
133
 
 
 
 
 
134
 
135
  private function queryItems($args = array())
136
  {
@@ -139,6 +152,9 @@ class MysqlDataProvider implements DataProvider
139
  'orderby' => 'list_order',
140
  'order' => 'ASC',
141
  'numitems' => -1,
 
 
 
142
  );
143
 
144
  $args = wp_parse_args($args, $defaults);
@@ -156,6 +172,48 @@ class MysqlDataProvider implements DataProvider
156
  $prepare[] = $args['status'];
157
  }
158
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
159
  if ($args['orderby'])
160
  {
161
  $order = (strtoupper($args['order']) == 'ASC') ? 'ASC ' : 'DESC ';
@@ -164,6 +222,7 @@ class MysqlDataProvider implements DataProvider
164
  // $prepare[] = $args['orderby'];
165
  }
166
 
 
167
  if ($args['numitems'] > 0)
168
  {
169
  $sql .= 'limit %d ';
@@ -197,9 +256,12 @@ class MysqlDataProvider implements DataProvider
197
  *
198
  * @return int Number of Records Updated
199
  */
200
- public function alterqueue($args)
201
  {
202
 
 
 
 
203
  }
204
 
205
  /** Updates one queued item, for instance in case of failing, or status update
@@ -216,6 +278,20 @@ class MysqlDataProvider implements DataProvider
216
  return false;
217
  }
218
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
219
 
220
  /* Counts Items in Database Queue
221
  * @param Status Mixed When supplied with ShortQ Status Constant it will count this status, will count all with ShortQ:QSTATUS_ALL.
@@ -262,19 +338,20 @@ class MysqlDataProvider implements DataProvider
262
  *
263
  * @param $Data Array. Data array to change, to WP standards
264
  * @param $where Array. Data Array on conditions, to WP standards
 
265
  * @return int Amount of records updates, or null|false
266
  */
267
- private function updateRecords($data, $where)
268
  {
269
  global $wpdb;
270
  $update_sql = 'UPDATE ' . $this->table . ' set updated = %s';
271
  if (isset($data['updated']))
272
  {
273
- $placeholders = array($data['updated']);
274
  unset($data['updated']);
275
  }
276
  else
277
- $placeholders = array(date('Y-m-d H:i:s'));
278
 
279
  foreach($data as $field => $value)
280
  {
@@ -295,6 +372,7 @@ class MysqlDataProvider implements DataProvider
295
  $placeholders = array_merge($placeholders, $value);
296
  }
297
  else {
 
298
  $update_sql .= ' AND ' . $field . ' = %s';
299
  $placeholders[] = $value;
300
  }
@@ -340,7 +418,7 @@ class MysqlDataProvider implements DataProvider
340
  elseif(! is_null($args['items']) && count($args['items']) > 0)
341
  {
342
  $items = $args['items'];
343
- $vals = implode( ', ', array_fill( 0, count( $items ), '%s' ));
344
  $delete_sql .= ' AND item_id in (' . $vals . ' ) ';
345
  $data = array_merge($data, $items);
346
  }
@@ -352,8 +430,8 @@ class MysqlDataProvider implements DataProvider
352
  return false; // prevent accidents if all is not set explicitly.
353
  }
354
 
355
- $result = $wpdb->query($wpdb->prepare($delete_sql, $data));
356
-
357
  return $result;
358
  }
359
 
@@ -386,6 +464,7 @@ class MysqlDataProvider implements DataProvider
386
  require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
387
 
388
  global $wpdb;
 
389
 
390
  $charset = $wpdb->get_charset_collate();
391
  $sql = "CREATE TABLE `" . $this->table . "` (
@@ -400,22 +479,20 @@ class MysqlDataProvider implements DataProvider
400
  created timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
401
  updated timestamp NULL DEFAULT CURRENT_TIMESTAMP,
402
  PRIMARY KEY (id),
403
- INDEX queue_name (queue_name),
404
- INDEX plugin_slug (plugin_slug),
405
- INDEX status (status),
406
- INDEX item_id (item_id),
407
- INDEX list_order (list_order)
408
  ) $charset; ";
409
 
410
  $result = dbDelta($sql);
411
 
412
-
413
-
414
- $sql = "SHOW INDEX FROM " . $this->table . " WHERE Key_name = 'uq'";
415
  $result = $wpdb->get_results($sql);
416
  if (is_null($result) || count($result) == 0)
417
  {
418
- $sql = 'ALTER TABLE '. $this->table . ' ADD CONSTRAINT UNIQUE uq(plugin_slug,queue_name,item_id)';
419
  $wpdb->query($sql);
420
  }
421
 
@@ -442,7 +519,6 @@ class MysqlDataProvider implements DataProvider
442
  $sql = ' DROP TABLE IF EXISTS ' . $this->table;
443
 
444
  $wpdb->query($sql);
445
- // dbDelta($sql);
446
 
447
  return $this->check();
448
  }
33
  return false;
34
  // start higher to allow priority additions easily.
35
  $list_order = (10 + $this->itemCount());
36
+ $now = $this->timestamptoSQL();
37
 
38
  $sql = 'INSERT IGNORE INTO ' . $this->table . ' (queue_name, plugin_slug, value, list_order, item_id, updated, created) VALUES ';
39
  $values = array();
93
  'newstatus' => ShortQ::QSTATUS_DONE,
94
  'orderby' => 'list_order',
95
  'order' => 'ASC',
96
+ 'priority' => false, // array('operator' => '<', 'value' => 10);
97
  );
98
 
99
  $args = wp_parse_args($args, $defaults);
106
  'status' => $args['status'],
107
  'orderby' => $args['orderby'],
108
  'order' => $args['order'],
109
+ 'priority' => $args['priority'],
110
  ));
111
 
112
  $id_array = array_keys($items);
114
  // Update status if results yielded.
115
  if ($args['status'] !== $args['newstatus'] && count($id_array) > 0)
116
  {
117
+ $now = $this->timestamptoSQL();
118
+ $this->updateRecords(array('status' => $args['newstatus'], 'updated' => $now), array('id' => $id_array));
119
  foreach($items as $index => $item)
120
  {
121
  $item->status = $args['newstatus']; // update status to new situation.
132
  return array_values($items); // array values resets the id index returns by queryItems
133
  }
134
 
135
+ private function timestampToSQL($timestamp = 0)
136
+ {
137
+ if (! is_numeric($timestamp))
138
+ return $timestamp; // possible already date;
139
+
140
+ if ($timestamp == 0)
141
+ $timestamp = time();
142
 
143
+ $date = date('Y-m-d H:i:s', $timestamp);
144
+
145
+ return $date;
146
+ }
147
 
148
  private function queryItems($args = array())
149
  {
152
  'orderby' => 'list_order',
153
  'order' => 'ASC',
154
  'numitems' => -1,
155
+ 'item_id' => false,
156
+ 'updated' => false, // updated since (Unix Timestamp) ( or array with operator)
157
+ 'priority' => false, // number (or array with operator)
158
  );
159
 
160
  $args = wp_parse_args($args, $defaults);
172
  $prepare[] = $args['status'];
173
  }
174
 
175
+ if ($args['item_id'] !== false && intval($args['item_id']) > 0)
176
+ {
177
+ $sql .= 'and item_id = %d ';
178
+ $prepare[] = intval($args['item_id']);
179
+ }
180
+
181
+ if ($args['updated'])
182
+ {
183
+ $operator = '=';
184
+
185
+ if (is_array($args['updated']))
186
+ {
187
+ $operator = isset($args['updated']['operator']) ? ($args['updated']['operator']) : $operator;
188
+ $value = isset($args['updated']['value']) ? $args['updated']['value'] : false;
189
+ }
190
+ else
191
+ {
192
+ $value = $args['updated'];
193
+ }
194
+
195
+ $sql .= 'and updated ' . $operator . ' %s ';
196
+ $prepare[] = $this->timestamptoSQL($value);
197
+ }
198
+
199
+ if ($args['priority'])
200
+ {
201
+ $operator = '=';
202
+
203
+ if (is_array($args['priority']))
204
+ {
205
+ $operator = isset($args['priority']['operator']) ? ($args['priority']['operator']) : $operator;
206
+ $value = isset($args['priority']['value']) ? $args['priority']['value'] : false;
207
+ }
208
+ else
209
+ {
210
+ $value = $args['priority'];
211
+ }
212
+
213
+ $sql .= 'and list_order ' . $operator . ' %d ';
214
+ $prepare[] = $value;
215
+ }
216
+
217
  if ($args['orderby'])
218
  {
219
  $order = (strtoupper($args['order']) == 'ASC') ? 'ASC ' : 'DESC ';
222
  // $prepare[] = $args['orderby'];
223
  }
224
 
225
+
226
  if ($args['numitems'] > 0)
227
  {
228
  $sql .= 'limit %d ';
256
  *
257
  * @return int Number of Records Updated
258
  */
259
+ public function alterQueue($data, $fields, $operators)
260
  {
261
 
262
+ return $this->updateRecords($data, $fields, $operators);
263
+
264
+
265
  }
266
 
267
  /** Updates one queued item, for instance in case of failing, or status update
278
  return false;
279
  }
280
 
281
+ public function getItem($item_id)
282
+ {
283
+ $items = $this->queryItems(array('item_id' => $item_id));
284
+
285
+ if (count($items) == 0)
286
+ return false;
287
+ else
288
+ return array_shift($items);
289
+ }
290
+
291
+ public function getItems($args)
292
+ {
293
+ return $this->queryItems($args);
294
+ }
295
 
296
  /* Counts Items in Database Queue
297
  * @param Status Mixed When supplied with ShortQ Status Constant it will count this status, will count all with ShortQ:QSTATUS_ALL.
338
  *
339
  * @param $Data Array. Data array to change, to WP standards
340
  * @param $where Array. Data Array on conditions, to WP standards
341
+ * @param $operators Array. Maps of Field => Operator to use anything else than standard = in the where query.
342
  * @return int Amount of records updates, or null|false
343
  */
344
+ private function updateRecords($data, $where, $operators = array() )
345
  {
346
  global $wpdb;
347
  $update_sql = 'UPDATE ' . $this->table . ' set updated = %s';
348
  if (isset($data['updated']))
349
  {
350
+ $placeholders = array($this->timestamptoSQL($data['updated']));
351
  unset($data['updated']);
352
  }
353
  else
354
+ $placeholders = array($this->timestamptoSQL());
355
 
356
  foreach($data as $field => $value)
357
  {
372
  $placeholders = array_merge($placeholders, $value);
373
  }
374
  else {
375
+ $operator = isset($operators[$field]) ? $operators[$field] : '=';
376
  $update_sql .= ' AND ' . $field . ' = %s';
377
  $placeholders[] = $value;
378
  }
418
  elseif(! is_null($args['items']) && count($args['items']) > 0)
419
  {
420
  $items = $args['items'];
421
+ $vals = implode( ', ', array_fill( 0, count( $items ), '%d' ));
422
  $delete_sql .= ' AND item_id in (' . $vals . ' ) ';
423
  $data = array_merge($data, $items);
424
  }
430
  return false; // prevent accidents if all is not set explicitly.
431
  }
432
 
433
+ $delete_sql = $wpdb->prepare($delete_sql, $data);
434
+ $result = $wpdb->query($delete_sql);
435
  return $result;
436
  }
437
 
464
  require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
465
 
466
  global $wpdb;
467
+ $prefix = $wpdb->prefix;
468
 
469
  $charset = $wpdb->get_charset_collate();
470
  $sql = "CREATE TABLE `" . $this->table . "` (
479
  created timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
480
  updated timestamp NULL DEFAULT CURRENT_TIMESTAMP,
481
  PRIMARY KEY (id),
482
+ KEY queue_name (queue_name),
483
+ KEY plugin_slug (plugin_slug),
484
+ KEY status (status),
485
+ KEY item_id (item_id),
486
+ KEY list_order (list_order)
487
  ) $charset; ";
488
 
489
  $result = dbDelta($sql);
490
 
491
+ $sql = "SHOW INDEX FROM " . $this->table . " WHERE Key_name = 'uq_" . $prefix . "'";
 
 
492
  $result = $wpdb->get_results($sql);
493
  if (is_null($result) || count($result) == 0)
494
  {
495
+ $sql = 'ALTER TABLE '. $this->table . ' ADD CONSTRAINT UNIQUE uq_' . $prefix . '(plugin_slug,queue_name,item_id)';
496
  $wpdb->query($sql);
497
  }
498
 
519
  $sql = ' DROP TABLE IF EXISTS ' . $this->table;
520
 
521
  $wpdb->query($sql);
 
522
 
523
  return $this->check();
524
  }
build/shortpixel/shortq/src/Item.php CHANGED
@@ -79,8 +79,10 @@ class Item
79
  case 'created':
80
  case 'updated':
81
  if (! is_numeric($value))
82
- $value = strtotime($value);
83
-
 
 
84
  $this->$name = $value;
85
  break;
86
  case 'value':
79
  case 'created':
80
  case 'updated':
81
  if (! is_numeric($value))
82
+ {
83
+ $dateObj = \DateTime::createFromFormat('Y-m-d H:i:s', $value);
84
+ $value = $dateObj->format('U');
85
+ }
86
  $this->$name = $value;
87
  break;
88
  case 'value':
build/shortpixel/shortq/src/Queue/Queue.php CHANGED
@@ -33,11 +33,12 @@ interface Queue
33
  public function addItems($items);
34
  public function enqueue();
35
  public function withOrder($items, $order); // chained method for adding items with an order. Returns Queue Object
36
- public function dequeue();
37
 
38
  /** Functions for async processing. Process should return item_id, put them on done or fail. */
39
  public function itemDone(Item $item);
40
  public function itemFailed(Item $item, $fatal = false);
 
41
 
42
  // return status object, for app to check what is going on.
43
  public function getStatus();
@@ -47,6 +48,9 @@ interface Queue
47
  public function hasItems();
48
  public function itemCount();
49
 
 
 
 
50
  //public function setDataProvider($DataProvider); // DataProvider Object
51
  public function uninstall();
52
 
33
  public function addItems($items);
34
  public function enqueue();
35
  public function withOrder($items, $order); // chained method for adding items with an order. Returns Queue Object
36
+ public function dequeue($args = array());
37
 
38
  /** Functions for async processing. Process should return item_id, put them on done or fail. */
39
  public function itemDone(Item $item);
40
  public function itemFailed(Item $item, $fatal = false);
41
+ public function getItem($item_id);
42
 
43
  // return status object, for app to check what is going on.
44
  public function getStatus();
48
  public function hasItems();
49
  public function itemCount();
50
 
51
+ // reset, start fresh
52
+ public function resetQueue();
53
+
54
  //public function setDataProvider($DataProvider); // DataProvider Object
55
  public function uninstall();
56
 
build/shortpixel/shortq/src/Queue/WPQ.php CHANGED
@@ -1,7 +1,7 @@
1
  <?php
2
  namespace ReThumbAdvanced\ShortQ\Queue;
3
  use ReThumbAdvanced\ShortQ\Item as Item;
4
- use \ReThumbAdvanced\ShortQ\Status as Status;
5
  use \ReThumbAdvanced\ShortQ\ShortQ as ShortQ;
6
 
7
  class WPQ implements Queue
@@ -49,6 +49,7 @@ class WPQ implements Queue
49
  $this->options->timeout_recount = 20000; // Time to recount and check stuff from datasource in MS
50
  $this->options->is_debug = false;
51
 
 
52
  }
53
 
54
  public function setOptions($options)
@@ -120,16 +121,14 @@ class WPQ implements Queue
120
  {
121
  $numitems += $this->DataProvider->enqueue($objItems);
122
 
123
- //$last_id = $objItems[count($objItems)-1]->item_id;
124
  $last_id = end($objItems)->item_id;
125
-
126
- //var_dump(end($objItems)); var_dump($last_id);
127
  $this->setStatus('last_item_id', $last_id); // save this, as a script termination safeguard.
128
  }
129
 
130
  $this->items = array(); // empty the item cache after inserting
131
  $this->setStatus('items', $numitems, false);
132
  $this->saveStatus();
 
133
  return $numitems;
134
  }
135
 
@@ -150,7 +149,7 @@ class WPQ implements Queue
150
  return $this;
151
  }
152
 
153
- /* Remove from Queue possible duplicates
154
  * Chained function. Removed items from queue
155
  * *Note* This should be used with small selections of items, not by default. Only when changes to item are needed, or to status.
156
  */
@@ -169,29 +168,46 @@ class WPQ implements Queue
169
  if ($count > 0)
170
  $this->setStatusCount('items', -$count );
171
 
 
 
 
 
 
 
172
  return $this;
173
  }
174
 
175
 
176
  // Dequeue a record, put it on done in queue.
177
- public function dequeue()
178
  {
 
 
179
 
180
  if ($this->currentStatus()->get('items') <= 0)
181
  {
182
  $still_here = $this->checkQueue();
183
  // @todo if there is queue todo, update items, and go.
184
  if (! $still_here)
185
- return false;
186
  }
187
 
188
  $newstatus = ($this->options->mode == 'wait') ? ShortQ::QSTATUS_INPROCESS : ShortQ::QSTATUS_DONE;
189
 
190
- $args = array(
191
  'numitems' => $this->options->numitems,
192
  'newstatus' => $newstatus,
 
193
  );
194
 
 
 
 
 
 
 
 
 
195
  $items = $this->DataProvider->dequeue($args);
196
 
197
  $itemcount = count($items);
@@ -199,6 +215,13 @@ class WPQ implements Queue
199
  // @todo Ask dprovder for dequeue
200
  // Update item count, average ask, last_run for this process
201
  // When Q is empty, reask for item count for DataProvider and check if it the same, if not, update number, continue.
 
 
 
 
 
 
 
202
  $items_left = $this->getStatus('items') - $itemcount;
203
  $this->setStatus('items', $items_left , false);
204
 
@@ -212,7 +235,8 @@ class WPQ implements Queue
212
  //$queue['average_ask'] = $this->calcAverageAsk($queue['average_ask']);
213
  //$this->updateQueue($queue);
214
  $this->setStatus('last_run', time(), false);
215
- $this->setStatus('running', true, false);
 
216
  $this->saveStatus();
217
 
218
  if ($items_left == 0)
@@ -221,6 +245,46 @@ class WPQ implements Queue
221
  return $items;
222
  }
223
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
224
  public function itemDone(Item $item)
225
  {
226
  if ($this->options->mode == 'direct')
@@ -259,15 +323,31 @@ class WPQ implements Queue
259
 
260
  }
261
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
262
  public function hasItems()
263
  {
264
  //$status = $this->getQueueStatus();
265
  $items = $this->itemCount(); // $status->get('items');
266
  if ($items > 0)
267
  return true;
268
- else {
269
  return false;
270
- }
271
  }
272
 
273
  public function itemCount()
@@ -335,7 +415,6 @@ class WPQ implements Queue
335
  $this->createQueue();
336
 
337
  $this->DataProvider->install();
338
-
339
  }
340
 
341
  /** Get the current status of this slug / queue */
@@ -350,6 +429,7 @@ class WPQ implements Queue
350
  {
351
  $this->status['queues'][$this->qName] = new Status();
352
  // $this->currentStatus = $this->status[$this->pSlug]['queues'][$this->qName];
 
353
  $this->saveStatus();
354
  }
355
  }
@@ -442,7 +522,7 @@ class WPQ implements Queue
442
 
443
  // $this->saveStatus(); // save result to DB.
444
 
445
- if ($tasks_open > 0)
446
  return true;
447
  else {
448
  $this->finishQueue();
1
  <?php
2
  namespace ReThumbAdvanced\ShortQ\Queue;
3
  use ReThumbAdvanced\ShortQ\Item as Item;
4
+ use ReThumbAdvanced\ShortQ\Status as Status;
5
  use \ReThumbAdvanced\ShortQ\ShortQ as ShortQ;
6
 
7
  class WPQ implements Queue
49
  $this->options->timeout_recount = 20000; // Time to recount and check stuff from datasource in MS
50
  $this->options->is_debug = false;
51
 
52
+ $this->inProcessTimeout();
53
  }
54
 
55
  public function setOptions($options)
121
  {
122
  $numitems += $this->DataProvider->enqueue($objItems);
123
 
 
124
  $last_id = end($objItems)->item_id;
 
 
125
  $this->setStatus('last_item_id', $last_id); // save this, as a script termination safeguard.
126
  }
127
 
128
  $this->items = array(); // empty the item cache after inserting
129
  $this->setStatus('items', $numitems, false);
130
  $this->saveStatus();
131
+
132
  return $numitems;
133
  }
134
 
149
  return $this;
150
  }
151
 
152
+ /* Remove from Queue possible duplicates
153
  * Chained function. Removed items from queue
154
  * *Note* This should be used with small selections of items, not by default. Only when changes to item are needed, or to status.
155
  */
168
  if ($count > 0)
169
  $this->setStatusCount('items', -$count );
170
 
171
+ // Probabably not the full solution, but this can happen if deleted items were already Dequeued with status Done.
172
+ if ($this->getStatus('items') <= 0)
173
+ {
174
+ $this->resetInternalCounts();
175
+ }
176
+
177
  return $this;
178
  }
179
 
180
 
181
  // Dequeue a record, put it on done in queue.
182
+ public function dequeue($args = array())
183
  {
184
+ // Check if anything has a timeout, do that first.
185
+ $this->inProcessTimeout();
186
 
187
  if ($this->currentStatus()->get('items') <= 0)
188
  {
189
  $still_here = $this->checkQueue();
190
  // @todo if there is queue todo, update items, and go.
191
  if (! $still_here)
192
+ return array();
193
  }
194
 
195
  $newstatus = ($this->options->mode == 'wait') ? ShortQ::QSTATUS_INPROCESS : ShortQ::QSTATUS_DONE;
196
 
197
+ $defaults = array(
198
  'numitems' => $this->options->numitems,
199
  'newstatus' => $newstatus,
200
+ 'onlypriority' => false,
201
  );
202
 
203
+ $args = wp_parse_args($args, $defaults);
204
+
205
+ if ($args['onlypriority'])
206
+ {
207
+ $args['priority'] = array('operator' => '<', 'value' => 10);
208
+ unset($args['onlypriority']);
209
+ }
210
+
211
  $items = $this->DataProvider->dequeue($args);
212
 
213
  $itemcount = count($items);
215
  // @todo Ask dprovder for dequeue
216
  // Update item count, average ask, last_run for this process
217
  // When Q is empty, reask for item count for DataProvider and check if it the same, if not, update number, continue.
218
+ if ($itemcount == 0 && $args['onlypriority'] == false)
219
+ { // This pieces prevents stalling. If the cached count is wrong, reset it, and if empty already will go to items_left / end queue system. Oterhwise resume.
220
+ $this->resetInternalCounts();
221
+ $items = $this->DataProvider->dequeue($args);
222
+ $itemcount = count($items);
223
+ }
224
+
225
  $items_left = $this->getStatus('items') - $itemcount;
226
  $this->setStatus('items', $items_left , false);
227
 
235
  //$queue['average_ask'] = $this->calcAverageAsk($queue['average_ask']);
236
  //$this->updateQueue($queue);
237
  $this->setStatus('last_run', time(), false);
238
+ if (! isset($args['priority']))
239
+ $this->setStatus('running', true, false);
240
  $this->saveStatus();
241
 
242
  if ($items_left == 0)
245
  return $items;
246
  }
247
 
248
+
249
+
250
+ /* Handles in processTimeOuts
251
+ if TimeOut is reached:
252
+ - Reset the status back to waiting
253
+ - Increment Retries by 1
254
+ -
255
+ */
256
+ public function inProcessTimeout()
257
+ {
258
+ // Not waiting for anything.
259
+ if (! $this->options->mode == 'wait')
260
+ return;
261
+
262
+ /* $fields = array('status' => ShortQ::QSTATUS_WAITING, 'tries' => 'tries + 1');
263
+ $where = array('updated' => time() - $this->options->process_timeout,
264
+ 'status' => ShortQ::QSTATUS_INPROCESS);
265
+
266
+ $operators = array('updated' => '<=');
267
+ */
268
+ $args = array('status' => ShortQ::QSTATUS_INPROCESS, 'updated' => array('value' => time() - ($this->options->process_timeout/1000), 'operator' => '<='));
269
+
270
+ $items = $this->DataProvider->getItems($args);
271
+ $updated = 0;
272
+
273
+ foreach($items as $item)
274
+ {
275
+ $item->tries++;
276
+ $updated += $this->DataProvider->itemUpdate($item, array('status' => ShortQ::QSTATUS_WAITING, 'tries' => $item->tries));
277
+ }
278
+
279
+
280
+ return $updated;
281
+ /* if ($result >= 0)
282
+ {
283
+ $this->resetInternalCounts();
284
+ } */
285
+
286
+ }
287
+
288
  public function itemDone(Item $item)
289
  {
290
  if ($this->options->mode == 'direct')
323
 
324
  }
325
 
326
+ public function updateItemValue(Item $item)
327
+ {
328
+ if (!property_exists($item, 'value'))
329
+ {
330
+ return false;
331
+ }
332
+
333
+ return $this->DataProvider->itemUpdate($item, array('value' => $item->getRaw('value') ));
334
+ }
335
+
336
+ public function getItem($item_id)
337
+ {
338
+ return $this->DataProvider->getItem($item_id);
339
+
340
+ }
341
+
342
  public function hasItems()
343
  {
344
  //$status = $this->getQueueStatus();
345
  $items = $this->itemCount(); // $status->get('items');
346
  if ($items > 0)
347
  return true;
348
+ else
349
  return false;
350
+
351
  }
352
 
353
  public function itemCount()
415
  $this->createQueue();
416
 
417
  $this->DataProvider->install();
 
418
  }
419
 
420
  /** Get the current status of this slug / queue */
429
  {
430
  $this->status['queues'][$this->qName] = new Status();
431
  // $this->currentStatus = $this->status[$this->pSlug]['queues'][$this->qName];
432
+
433
  $this->saveStatus();
434
  }
435
  }
522
 
523
  // $this->saveStatus(); // save result to DB.
524
 
525
+ if ($tasks_open > 0 || $tasks_inprocess > 0)
526
  return true;
527
  else {
528
  $this->finishQueue();
build/shortpixel/shortq/src/Status.php CHANGED
@@ -14,6 +14,7 @@ class Status
14
  protected $preparing = false; // flag to signal queue is being created and items are being uploaded. Don't run.
15
  protected $running = false; // flag to signal the queue is currently running
16
  protected $finished = false; // flag to signal nothing can move this queue anymore.
 
17
  protected $done = 0; // number of items processed
18
  protected $errors = 0;
19
  protected $fatal_errors = 0;
14
  protected $preparing = false; // flag to signal queue is being created and items are being uploaded. Don't run.
15
  protected $running = false; // flag to signal the queue is currently running
16
  protected $finished = false; // flag to signal nothing can move this queue anymore.
17
+ protected $bulk_running = false; // external flag to note if a large amount is being more [optional]
18
  protected $done = 0; // number of items processed
19
  protected $errors = 0;
20
  protected $fatal_errors = 0;
classes/Image.php CHANGED
@@ -124,7 +124,7 @@ class Image
124
  $result = $this->saveNewMeta($new_metadata); // this here calls the regeneration.
125
  Log::addDebug('Result :', $result);
126
 
127
- $is_a_bulk = true; // we are sending multiple images.
128
  $regenSizes = isset($new_metadata['sizes']) ? $new_metadata['sizes'] : array();
129
 
130
  // Do not send if nothing was regenerated, otherwise SP thinks all needs to be redone
124
  $result = $this->saveNewMeta($new_metadata); // this here calls the regeneration.
125
  Log::addDebug('Result :', $result);
126
 
127
+ $is_a_bulk = false; // not a bulk in the SPIO sense ( directly optimize )
128
  $regenSizes = isset($new_metadata['sizes']) ? $new_metadata['sizes'] : array();
129
 
130
  // Do not send if nothing was regenerated, otherwise SP thinks all needs to be redone
classes/Process.php CHANGED
@@ -46,7 +46,7 @@ class Process
46
  if ($process !== false)
47
  $this->set_process($process);
48
 
49
- $this->q->setOption('numitems', 3);
50
  }
51
 
52
  public static function getInstance()
@@ -126,9 +126,10 @@ class Process
126
  $this->end_process();
127
  }
128
 
129
- // Chain function to limit runtimes in seconds..
130
  public function limitTime($limit = 6)
131
  {
 
132
  if ($this->run_limit == 0)
133
  {
134
  $this->run_start = time();
@@ -159,19 +160,13 @@ class Process
159
  break;
160
  }
161
 
162
- if ($i >= 50)
163
- {
164
- exit('Prepare loop went over maximum count!');
165
- Log::addError('Fatal error on preparation. Hanging loop detected');
166
- }
167
-
168
  $result += $this_result;
169
  $i++;
170
  }
171
 
172
  if ($this_result == false)
173
  {
174
- $this->q->setStatus('preparing', false);
175
  $this->q->setStatus('running', true);
176
  Log::addDebug('Preparing done, Starting run status');
177
  }
@@ -221,7 +216,7 @@ class Process
221
  $prepare[] = $this->query_prepare_limit;
222
 
223
  $sql = $wpdb->prepare($query, $prepare);
224
- Log::addTemp('Preparing SQL' . $sql);
225
  $result = $wpdb->get_results($sql);
226
  $resultCount = count($result);
227
 
46
  if ($process !== false)
47
  $this->set_process($process);
48
 
49
+ $this->q->setOption('numitems', apply_filters('rta/process/numitems', 3));
50
  }
51
 
52
  public static function getInstance()
126
  $this->end_process();
127
  }
128
 
129
+ // function to limit runtimes in seconds..
130
  public function limitTime($limit = 6)
131
  {
132
+ $limit = apply_filters('rta/process/prepare_limit', $limit);
133
  if ($this->run_limit == 0)
134
  {
135
  $this->run_start = time();
160
  break;
161
  }
162
 
 
 
 
 
 
 
163
  $result += $this_result;
164
  $i++;
165
  }
166
 
167
  if ($this_result == false)
168
  {
169
+ $this->q->setStatus('preparing', false, false);
170
  $this->q->setStatus('running', true);
171
  Log::addDebug('Preparing done, Starting run status');
172
  }
216
  $prepare[] = $this->query_prepare_limit;
217
 
218
  $sql = $wpdb->prepare($query, $prepare);
219
+ //Log::addTemp('Preparing SQL' . $sql);
220
  $result = $wpdb->get_results($sql);
221
  $resultCount = count($result);
222
 
css/rta-admin-progress.css CHANGED
@@ -1,150 +1 @@
1
- section.regenerate {
2
- background-color: #fff;
3
- margin-bottom: 200px; }
4
- section.regenerate .rta_panel_off {
5
- opacity: 0;
6
- transition: all 0ms linear; }
7
- section.regenerate .rta_progress {
8
- position: relative;
9
- min-height: 310px;
10
- width: 65%;
11
- justify-content: flex-start; }
12
- section.regenerate .rta_progress .rta_progress_view {
13
- margin: 0 auto;
14
- align-self: center; }
15
- section.regenerate .rta_progress .rta_progress_view svg.CircularProgressbar {
16
- display: inline-block;
17
- width: 200px;
18
- padding: 0 0 15px 0; }
19
- section.regenerate .rta_progress .rta_progress_view svg.CircularProgressbar .CircularProgressbar-trail {
20
- stroke: #d6d6d6; }
21
- section.regenerate .rta_progress .rta_progress_view svg.CircularProgressbar .CircularProgressbar-path {
22
- stroke: #00bcd4;
23
- stroke-linecap: round;
24
- transition: stroke-dashoffset 0.5s ease 0s; }
25
- section.regenerate .rta_progress .rta_progress_view svg.CircularProgressbar .CircularProgressbar-text {
26
- fill: #00bcd4;
27
- font-size: 20px;
28
- dominant-baseline: middle;
29
- text-anchor: middle; }
30
- section.regenerate .rta_progress .rta_progress_view svg.CircularProgressbar .progress-count {
31
- font-size: 9px;
32
- font-weight: bold;
33
- dominant-baseline: middle;
34
- text-anchor: middle;
35
- fill: 999; }
36
- section.regenerate .rta_progress .images {
37
- padding: 15px;
38
- width: 60%; }
39
- section.regenerate .rta_progress .images h5 {
40
- text-align: right; }
41
- section.regenerate .rta_progress .images h4.thumb-label {
42
- text-align: center; }
43
- section.regenerate .rta_progress .images .thumbnail {
44
- text-align: center;
45
- margin-top: 35px; }
46
- section.regenerate .rta_progress .images .thumbnail img {
47
- max-width: 500px;
48
- max-height: 500px; }
49
- @media (max-width: 1200px) {
50
- section.regenerate .rta_progress .images {
51
- min-height: 300px;
52
- width: 100%; }
53
- section.regenerate .rta_progress .images .thumbnail img {
54
- opacity: 0.5;
55
- max-width: 100%;
56
- overflow: hidden; }
57
- section.regenerate .rta_progress .rta_progress_view {
58
- width: 200px;
59
- height: 220px;
60
- position: absolute;
61
- left: 50%;
62
- top: 50%;
63
- margin-left: -100px;
64
- margin-top: -120px; } }
65
- section.regenerate .rta_status_box {
66
- width: 35%;
67
- min-width: 300px;
68
- border-left: 1px solid #ccc;
69
- position: relative;
70
- z-index: 10; }
71
- section.regenerate .rta_status_box .rta_wait_loader {
72
- margin-top: 35px;
73
- padding-left: 20px;
74
- opacity: 0;
75
- position: relative;
76
- z-index: 1; }
77
- section.regenerate .rta_status_box .rta_wait_loader .dashicons {
78
- animation: wait-spin 2000ms infinite linear;
79
- animation-play-state: running;
80
- width: 35px;
81
- height: 35px;
82
- font-size: 35px;
83
- float: left;
84
- margin-right: 30px; }
85
- section.regenerate .rta_status_box .rta_wait_loader.rta_panel_off .dashicons {
86
- animation-play-state: paused; }
87
- section.regenerate .rta_status_box .rta_notices ul.statuslist {
88
- max-height: 350px;
89
- overflow-y: auto;
90
- overflow-x: visible;
91
- margin-left: 15px; }
92
- section.regenerate .rta_status_box .rta_notices ul.statuslist li {
93
- font-size: 14px; }
94
- section.regenerate .rta_status_box .rta_notices ul.statuslist li.error {
95
- color: #ff0000; }
96
- section.regenerate .rta_status_box h4 {
97
- font-size: 22px;
98
- font-weight: bold; }
99
- @keyframes wait-spin {
100
- 0% {
101
- transform: rotate(0); }
102
- 100% {
103
- transform: rotate(360deg); } }
104
- section.regenerate .rta_success_box {
105
- position: absolute;
106
- left: 30%;
107
- top: -5%;
108
- width: 45%;
109
- margin-left: -200px;
110
- opacity: 0.9;
111
- background-color: #fff;
112
- text-align: center;
113
- padding: 15px;
114
- border: 1px solid #00bcd4;
115
- border-radius: 8px; }
116
- section.regenerate .rta_success_box p {
117
- font-size: 16px; }
118
- section.regenerate .rta_success_box h3.header {
119
- font-size: 32px;
120
- font-weight: bold;
121
- color: green; }
122
- section.regenerate .rta_success_box .shortpixel h3 a {
123
- line-height: 28px; }
124
- section.regenerate .rta_success_box .modal-close {
125
- position: absolute;
126
- right: 15px;
127
- top: 15px;
128
- cursor: pointer; }
129
- section.regenerate .rta_success_box .modal-close .dashicons {
130
- font-size: 36px;
131
- width: 36px;
132
- height: 36px; }
133
- section.regenerate .shortpixel-notice {
134
- background: #fff;
135
- width: 250px;
136
- min-height: 270px;
137
- border: 1px solid #ccc;
138
- padding: 15px;
139
- margin: 0 5% 10px 25px;
140
- float: right; }
141
- section.regenerate .shortpixel-notice h3 {
142
- line-height: 1.3em; }
143
- section.regenerate button.stop-process {
144
- position: absolute;
145
- bottom: 10px;
146
- left: 15px;
147
- font-weight: normal;
148
- text-transform: none;
149
- padding: 4px 20px;
150
- font-size: 14px; }
1
+ section.regenerate{background-color:#fff;margin-bottom:200px}section.regenerate .rta_panel_off{opacity:0;transition:all 0ms linear}section.regenerate .rta_progress{position:relative;min-height:310px;width:65%;justify-content:flex-start}section.regenerate .rta_progress .rta_progress_view{margin:0 auto;align-self:center}section.regenerate .rta_progress .rta_progress_view svg.CircularProgressbar{display:inline-block;width:200px;padding:0 0 15px 0}section.regenerate .rta_progress .rta_progress_view svg.CircularProgressbar .CircularProgressbar-trail{stroke:#d6d6d6}section.regenerate .rta_progress .rta_progress_view svg.CircularProgressbar .CircularProgressbar-path{stroke:#00bcd4;stroke-linecap:round;transition:stroke-dashoffset 0.5s ease 0s}section.regenerate .rta_progress .rta_progress_view svg.CircularProgressbar .CircularProgressbar-text{fill:#00bcd4;font-size:20px;dominant-baseline:middle;text-anchor:middle}section.regenerate .rta_progress .rta_progress_view svg.CircularProgressbar .progress-count{font-size:9px;font-weight:bold;dominant-baseline:middle;text-anchor:middle;fill:999}section.regenerate .rta_progress .images{padding:15px;width:60%}section.regenerate .rta_progress .images h5{text-align:right}section.regenerate .rta_progress .images h4.thumb-label{text-align:center}section.regenerate .rta_progress .images .thumbnail{text-align:center;margin-top:35px}section.regenerate .rta_progress .images .thumbnail img{max-width:500px;max-height:500px}@media (max-width: 1200px){section.regenerate .rta_progress .images{min-height:300px;width:100%}section.regenerate .rta_progress .images .thumbnail img{opacity:0.5;max-width:100%;overflow:hidden}section.regenerate .rta_progress .rta_progress_view{width:200px;height:220px;position:absolute;left:50%;top:50%;margin-left:-100px;margin-top:-120px}}section.regenerate .rta_status_box{width:35%;min-width:300px;border-left:1px solid #ccc;position:relative;z-index:10;padding-bottom:75px}section.regenerate .rta_status_box .rta_wait_loader,section.regenerate .rta_status_box .rta_wait_paused,section.regenerate .rta_status_box .rta_wait_pausing{margin-top:35px;padding-left:20px;opacity:1;position:relative;z-index:1;transition:opacity 750ms}section.regenerate .rta_status_box .rta_wait_loader .dashicons,section.regenerate .rta_status_box .rta_wait_paused .dashicons,section.regenerate .rta_status_box .rta_wait_pausing .dashicons{display:inline-block;width:35px;height:35px;font-size:35px;float:left;margin-right:30px}section.regenerate .rta_status_box .rta_wait_loader .dashicons.dashicons-update,section.regenerate .rta_status_box .rta_wait_paused .dashicons.dashicons-update,section.regenerate .rta_status_box .rta_wait_pausing .dashicons.dashicons-update{animation:wait-spin 2000ms infinite linear;animation-play-state:running}section.regenerate .rta_status_box .rta_wait_loader.rta_panel_off,section.regenerate .rta_status_box .rta_wait_paused.rta_panel_off,section.regenerate .rta_status_box .rta_wait_pausing.rta_panel_off{opacity:0}section.regenerate .rta_status_box .rta_wait_loader.rta_panel_off .dashicons,section.regenerate .rta_status_box .rta_wait_paused.rta_panel_off .dashicons,section.regenerate .rta_status_box .rta_wait_pausing.rta_panel_off .dashicons{animation-play-state:paused}section.regenerate .rta_status_box .rta_notices ul.statuslist{max-height:350px;overflow-y:auto;overflow-x:visible;margin-left:15px}section.regenerate .rta_status_box .rta_notices ul.statuslist li{font-size:14px}section.regenerate .rta_status_box .rta_notices ul.statuslist li.error{color:#ff0000}section.regenerate .rta_status_box h4{font-size:22px;font-weight:bold}@keyframes wait-spin{0%{transform:rotate(0)}100%{transform:rotate(360deg)}}section.regenerate .rta_success_box{position:absolute;left:30%;top:-5%;width:45%;margin-left:-200px;opacity:0.9;background-color:#fff;text-align:center;padding:15px;border:1px solid #00bcd4;border-radius:8px}section.regenerate .rta_success_box p{font-size:16px}section.regenerate .rta_success_box h3.header{font-size:32px;font-weight:bold;color:green}section.regenerate .rta_success_box .shortpixel h3 a{line-height:28px}section.regenerate .rta_success_box .modal-close{position:absolute;right:15px;top:15px;cursor:pointer}section.regenerate .rta_success_box .modal-close .dashicons{font-size:36px;width:36px;height:36px}section.regenerate .shortpixel-notice{background:#fff;width:250px;min-height:270px;border:1px solid #ccc;padding:15px;margin:0 5% 10px 25px;float:right}section.regenerate .shortpixel-notice h3{line-height:1.3em}section.regenerate button.stop-process,section.regenerate button.pause-process{position:absolute;bottom:10px;right:15px;font-weight:normal;text-transform:none;padding:4px 20px;font-size:14px}section.regenerate button.stop-process .dashicons,section.regenerate button.pause-process .dashicons{vertical-align:middle}section.regenerate button.pause-process{left:15px;right:auto}section.regenerate button.pause-process .resume{display:none}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
css/rta-admin-view.css CHANGED
@@ -1,247 +1 @@
1
- .rta-admin .two-panel-wrap {
2
- display: flex;
3
- justify-content: space-between;
4
- margin-bottom: 20px; }
5
- @media (max-width: 1200px) {
6
- .rta-admin .two-panel-wrap.settings-panels {
7
- flex-direction: column-reverse; }
8
- .rta-admin .two-panel-wrap.settings-panels .rta-settings-wrap, .rta-admin .two-panel-wrap.settings-panels .rta-regenerate-wrap {
9
- width: 100%;
10
- max-width: none;
11
- margin: 14px 0; } }
12
- .rta-admin h2 {
13
- font-size: 26px;
14
- padding-left: 8px; }
15
- .rta-admin h4 {
16
- font-size: 16px;
17
- margin: 8px 0 8px 15px; }
18
- .rta-admin form {
19
- min-height: 600px;
20
- padding-bottom: 65px; }
21
- .rta-admin .rta-notice {
22
- margin: 8px 0;
23
- padding: 8px;
24
- border-width: 1px;
25
- border-style: solid;
26
- transition: all 500ms ease-in; }
27
- .rta-admin .rta-notice .icon {
28
- font-size: 35px;
29
- float: left;
30
- display: inline-block;
31
- width: auto;
32
- height: auto; }
33
- .rta-admin .rta-notice p {
34
- font-size: 15px;
35
- margin: 4px 0;
36
- margin-left: 45px; }
37
- .rta-admin .rta-notice p.small {
38
- font-size: 0.8em; }
39
- .rta-admin .rta-notice.warning {
40
- border-color: #ffb900; }
41
- .rta-admin .rta-notice.warning .icon {
42
- color: #ffb900; }
43
- .rta-admin .rta-notice.error {
44
- border-color: #ff0000; }
45
- .rta-admin .rta-regenerate-wrap, .rta-admin .rta-settings-wrap {
46
- flex: 1;
47
- position: relative;
48
- padding: 0 0 0 15px;
49
- background: #fff; }
50
- .rta-admin .rta-regenerate-wrap {
51
- margin-right: 8px; }
52
- .rta-admin .rta-settings-wrap {
53
- flex: 2; }
54
- .rta-admin button, .rta-admin .btn_add_more {
55
- color: white;
56
- background: #00bcd4;
57
- position: relative;
58
- box-shadow: none;
59
- cursor: pointer;
60
- border: 0;
61
- border-right: 1px solid #ccc;
62
- border-bottom: 1px solid #ccc;
63
- box-shadow: 0px 0px 4px #aaa; }
64
- .rta-admin .container {
65
- padding: 20px 8px;
66
- position: relative;
67
- margin: 0 auto; }
68
- .rta-admin .option {
69
- padding: 10px; }
70
- .rta-admin .option > label {
71
- width: 150px;
72
- display: inline-block;
73
- margin-right: 15px;
74
- padding: 0 15px;
75
- font-weight: bold;
76
- vertical-align: top;
77
- line-height: 15px;
78
- position: relative; }
79
- .rta-admin .option > label input {
80
- vertical-align: middle;
81
- display: inline-block;
82
- position: absolute;
83
- margin-top: 2px; }
84
- .rta-admin .option > label span {
85
- display: inline-block;
86
- margin-left: 25px;
87
- line-height: 20px; }
88
- .rta-admin .option .note {
89
- margin-left: 15px; }
90
- .rta-admin .option .note p {
91
- margin-top: 0; }
92
- .rta-admin input.tiny {
93
- width: 65px; }
94
- .rta-admin button {
95
- font-size: 14px;
96
- text-transform: uppercase;
97
- font-weight: 700;
98
- margin: 0px;
99
- padding: 16px;
100
- border-radius: 4px; }
101
- .rta-admin button.disabled {
102
- background: #ccc;
103
- cursor: default;
104
- color: #eee; }
105
- .rta-admin .btn_add_more {
106
- font-size: 13px;
107
- padding: 5px 6px;
108
- margin-left: 25px; }
109
- .rta-admin .table {
110
- display: flex;
111
- flex-direction: column;
112
- border-spacing: 10px 0;
113
- border: 1px solid #eee;
114
- word-wrap: normal;
115
- white-space: nowrap; }
116
- .rta-admin .table .header, .rta-admin .table .row {
117
- display: flex; }
118
- .rta-admin .table .header input.image_sizes_pname, .rta-admin .table .row input.image_sizes_pname {
119
- max-width: 110px; }
120
- .rta-admin .table .header input.image_sizes_name, .rta-admin .table .row input.image_sizes_name {
121
- font-size: 10px;
122
- border: 0;
123
- background: unset;
124
- margin: 0;
125
- padding: 0; }
126
- .rta-admin .table .header span, .rta-admin .table .row span {
127
- padding: 5px;
128
- flex-basis: 100px; }
129
- .rta-admin .table .header span:nth-of-type(1), .rta-admin .table .row span:nth-of-type(1) {
130
- flex-basis: 120px; }
131
- .rta-admin .table .header span:nth-of-type(4), .rta-admin .table .row span:nth-of-type(4) {
132
- flex-basis: 150px; }
133
- .rta-admin .table .header span button, .rta-admin .table .row span button {
134
- padding: 0;
135
- background: unset;
136
- border: 0;
137
- box-shadow: none; }
138
- .rta-admin .table .header span button span, .rta-admin .table .row span button span {
139
- color: #ff0000; }
140
- .rta-admin .table .row.proto, .rta-admin .table .rta_hidden {
141
- display: none; }
142
- .rta-admin .flex {
143
- display: flex; }
144
- .rta-admin .checkbox-list {
145
- display: inline-block; }
146
- .rta-admin .checkbox-list .item {
147
- display: flex;
148
- margin: 5px 0px;
149
- float: left;
150
- clear: both;
151
- justify-content: space-between;
152
- width: 100%; }
153
- .rta-admin .checkbox-list .item span {
154
- display: inline-block;
155
- margin-right: 14px; }
156
- .rta-admin .checkbox-list .item span.hidden {
157
- visibility: hidden; }
158
- .rta-admin .checkbox-list input {
159
- margin-right: 8px; }
160
- .rta-admin .select-options {
161
- margin-left: 200px;
162
- margin-top: 15px; }
163
- .rta-admin .select-options > span {
164
- cursor: pointer;
165
- color: #222;
166
- margin-right: 12px;
167
- display: inline-block; }
168
- .rta-admin .select-options .note {
169
- margin-left: 0;
170
- border: 1px solid #ccc;
171
- padding: 8px; }
172
- .rta-admin .cleanup-wrapper {
173
- padding: 8px;
174
- border: 1px solid #ddd; }
175
- .rta-admin .cleanup-wrapper .option {
176
- display: flex;
177
- flex: 1; }
178
- .rta-admin .cleanup-wrapper .option .note {
179
- flex: 2;
180
- display: inline-block; }
181
- @media (max-width: 1500px) {
182
- .rta-admin .cleanup-wrapper .option {
183
- flex-wrap: wrap; }
184
- .rta-admin .cleanup-wrapper .option label {
185
- width: 100%; }
186
- .rta-admin .cleanup-wrapper .option .note {
187
- width: 100%;
188
- margin: 4px 0; } }
189
- .rta-admin .warning-removal {
190
- position: relative;
191
- text-decoration: line-through; }
192
- .rta-admin .warning-removal .icon-warning {
193
- font-size: 30px;
194
- color: #ff0000;
195
- width: 20px;
196
- height: 20px;
197
- text-decoration: none;
198
- position: absolute;
199
- left: -30px;
200
- top: -7px;
201
- margin: 0; }
202
- .rta-admin .form_controls {
203
- position: absolute;
204
- left: 45px;
205
- bottom: 0px; }
206
- .rta-admin .form_controls .save_indicator {
207
- display: none;
208
- color: #049901;
209
- font-weight: 700;
210
- background: url("/wp-admin/images/wpspin_light.gif") no-repeat left center;
211
- background-size: 16px 16px;
212
- padding-left: 20px; }
213
- .rta-admin .form_controls .save_indicator .saved {
214
- font-size: 60px; }
215
- .rta-admin .form_controls .save_note {
216
- color: orange;
217
- float: right;
218
- margin-left: 30px; }
219
- .rta-admin .toggle-window {
220
- cursor: pointer; }
221
- .rta-admin .toggle-window h4 {
222
- display: inline-block; }
223
- .rta-admin .toggle-window span {
224
- font-size: 26px;
225
- vertical-align: top;
226
- margin-top: 4px; }
227
- .rta-admin .window-up, .rta-admin .window-down {
228
- transition: all 500ms linear; }
229
- .rta-admin .window-up {
230
- opacity: 0; }
231
- .rta-admin .window-down {
232
- opacity: 100; }
233
- .rta-admin .rta-ad {
234
- background: #fff;
235
- border: 1px solid #eee;
236
- padding: 16px;
237
- margin: 20px 0;
238
- display: flex;
239
- align-items: center; }
240
- .rta-admin .rta-ad .img-wrapper {
241
- margin-right: 25px; }
242
- .rta-admin .rta-ad h3, .rta-admin .rta-ad p {
243
- margin: 6px 0; }
244
- .rta-admin .rta-ad a {
245
- font-size: 16px;
246
- font-weight: 700;
247
- text-decoration: underline; }
1
+ .rta-admin .two-panel-wrap{display:flex;justify-content:space-between;margin-bottom:20px}@media (max-width: 1200px){.rta-admin .two-panel-wrap.settings-panels{flex-direction:column-reverse}.rta-admin .two-panel-wrap.settings-panels .rta-settings-wrap,.rta-admin .two-panel-wrap.settings-panels .rta-regenerate-wrap{width:100%;max-width:none;margin:14px 0}}.rta-admin h2{font-size:26px;padding-left:8px}.rta-admin h4{font-size:16px;margin:8px 0 8px 15px}.rta-admin form{min-height:600px;padding-bottom:65px}.rta-admin .rta-notice{margin:8px 0;padding:8px;border-width:1px;border-style:solid;transition:all 500ms ease-in}.rta-admin .rta-notice .icon{font-size:35px;float:left;display:inline-block;width:auto;height:auto}.rta-admin .rta-notice p{font-size:15px;margin:4px 0;margin-left:45px}.rta-admin .rta-notice p.small{font-size:0.8em}.rta-admin .rta-notice.warning{border-color:#ffb900}.rta-admin .rta-notice.warning .icon{color:#ffb900}.rta-admin .rta-notice.error{border-color:#ff0000}.rta-admin .rta-regenerate-wrap,.rta-admin .rta-settings-wrap{flex:1;position:relative;padding:0 0 0 15px;background:#fff}.rta-admin .rta-regenerate-wrap{margin-right:8px}.rta-admin .rta-settings-wrap{flex:2}.rta-admin button,.rta-admin .btn_add_more{color:#fff;background:#00bcd4;position:relative;box-shadow:none;cursor:pointer;border:0;border-right:1px solid #ccc;border-bottom:1px solid #ccc;box-shadow:0px 0px 4px #aaa}.rta-admin .container{padding:20px 8px;position:relative;margin:0 auto}.rta-admin .option{padding:10px}.rta-admin .option>label{width:150px;display:inline-block;margin-right:15px;padding:0 15px;font-weight:bold;vertical-align:top;line-height:15px;position:relative}.rta-admin .option>label input{vertical-align:middle;display:inline-block;position:absolute;margin-top:2px}.rta-admin .option>label span{display:inline-block;margin-left:25px;line-height:20px}.rta-admin .option .note{margin-left:15px}.rta-admin .option .note p{margin-top:0}.rta-admin input.tiny{width:65px}.rta-admin button{font-size:14px;text-transform:uppercase;font-weight:700;margin:0px;padding:16px;border-radius:4px}.rta-admin button.disabled{background:#ccc;cursor:default;color:#eee}.rta-admin .btn_add_more{font-size:13px;padding:5px 6px;margin-left:25px}.rta-admin .table{display:flex;flex-direction:column;border-spacing:10px 0;border:1px solid #eee;word-wrap:normal;white-space:nowrap}.rta-admin .table .header,.rta-admin .table .row{display:flex}.rta-admin .table .header input.image_sizes_pname,.rta-admin .table .row input.image_sizes_pname{max-width:110px}.rta-admin .table .header input.image_sizes_name,.rta-admin .table .row input.image_sizes_name{font-size:10px;border:0;background:unset;margin:0;padding:0}.rta-admin .table .header span,.rta-admin .table .row span{padding:5px;flex-basis:100px}.rta-admin .table .header span:nth-of-type(1),.rta-admin .table .row span:nth-of-type(1){flex-basis:120px}.rta-admin .table .header span:nth-of-type(4),.rta-admin .table .row span:nth-of-type(4){flex-basis:150px}.rta-admin .table .header span button,.rta-admin .table .row span button{padding:0;background:unset;border:0;box-shadow:none}.rta-admin .table .header span button span,.rta-admin .table .row span button span{color:#ff0000}.rta-admin .table .row.proto,.rta-admin .table .rta_hidden{display:none}.rta-admin .flex{display:flex}.rta-admin .checkbox-list{display:inline-block}.rta-admin .checkbox-list .item{display:flex;margin:5px 0px;float:left;clear:both;justify-content:space-between;width:100%}.rta-admin .checkbox-list .item span{display:inline-block;margin-right:14px}.rta-admin .checkbox-list .item span.hidden{visibility:hidden}.rta-admin .checkbox-list input{margin-right:8px}.rta-admin .select-options{margin-left:200px;margin-top:15px}.rta-admin .select-options>span{cursor:pointer;color:#222;margin-right:12px;display:inline-block}.rta-admin .select-options .note{margin-left:0;border:1px solid #ccc;padding:8px}.rta-admin .cleanup-wrapper{padding:8px;border:1px solid #ddd}.rta-admin .cleanup-wrapper .option{display:flex;flex:1}.rta-admin .cleanup-wrapper .option .note{flex:2;display:inline-block}@media (max-width: 1500px){.rta-admin .cleanup-wrapper .option{flex-wrap:wrap}.rta-admin .cleanup-wrapper .option label{width:100%}.rta-admin .cleanup-wrapper .option .note{width:100%;margin:4px 0}}.rta-admin .warning-removal{position:relative;text-decoration:line-through}.rta-admin .warning-removal .icon-warning{font-size:30px;color:#ff0000;width:20px;height:20px;text-decoration:none;position:absolute;left:-30px;top:-7px;margin:0}.rta-admin .form_controls{position:absolute;left:45px;bottom:0px}.rta-admin .form_controls .save_indicator{display:none;color:#049901;font-weight:700;background:url("/wp-admin/images/wpspin_light.gif") no-repeat left center;background-size:16px 16px;padding-left:20px}.rta-admin .form_controls .save_indicator .saved{font-size:60px}.rta-admin .form_controls .save_note{color:orange;float:right;margin-left:30px}.rta-admin .toggle-window{cursor:pointer}.rta-admin .toggle-window h4{display:inline-block}.rta-admin .toggle-window span{font-size:26px;vertical-align:top;margin-top:4px}.rta-admin .window-up,.rta-admin .window-down{transition:all 500ms linear}.rta-admin .window-up{opacity:0}.rta-admin .window-down{opacity:100}.rta-admin .rta-ad{background:#fff;border:1px solid #eee;padding:16px;margin:20px 0;display:flex;align-items:center}.rta-admin .rta-ad .img-wrapper{margin-right:25px}.rta-admin .rta-ad h3,.rta-admin .rta-ad p{margin:6px 0}.rta-admin .rta-ad a{font-size:16px;font-weight:700;text-decoration:underline}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
js/rta.js CHANGED
@@ -6,8 +6,9 @@ rtaJS.prototype = {
6
  //offset: 0,
7
  process: false,
8
  is_interrupted_process: false, // was the process killed by reload earlier?
9
- in_process: false, // currently pushing it through.
10
- is_stopped: false,
 
11
  is_saved: true,
12
  is_debug: false, // use sparingly
13
  status: []
@@ -40,6 +41,7 @@ rtaJS.prototype.init = function()
40
  $(document).on('click', '.table.imagesizes .btn_remove_row', $.proxy(this.remove_image_size_row, this));
41
  $(document).on('click', '#btn_add_image_size', $.proxy(this.add_image_size_row, this));
42
  $(document).on('click', '.stop-process', $.proxy(this.stopProcess,this));
 
43
  $(document).on('click', '.rta_success_box .modal-close', $.proxy(function(e){
44
  this.togglePanel('success', false);
45
  }, this));
@@ -125,7 +127,6 @@ rtaJS.prototype.initProcess = function()
125
  this.resumeProcess();
126
  }
127
 
128
-
129
  }
130
 
131
  rtaJS.prototype.selectAll = function(e)
@@ -151,6 +152,11 @@ rtaJS.prototype.startProcess = function (e)
151
  this.togglePanel('main', true);
152
  this.togglePanel('loading', true);
153
 
 
 
 
 
 
154
  var status = new Object;
155
  status.id = -1;
156
  status.message = rta_data.strings.status_start;
@@ -201,9 +207,11 @@ rtaJS.prototype.startProcess = function (e)
201
  // function was interrupted, but will continue now; draw panels.
202
  rtaJS.prototype.resumeProcess = function()
203
  {
204
- this.resetPanels();
205
  this.togglePanel('main', true);
 
 
206
  this.togglePanel('loading', true);
 
207
 
208
  var status = new Object;
209
  status.id = -1;
@@ -211,13 +219,20 @@ rtaJS.prototype.resumeProcess = function()
211
  status.error = true;
212
  this.add_status([status]);
213
 
214
- this.doProcess();
 
 
 
 
 
 
 
 
215
  }
216
 
217
  // function for getting the next image in line.
218
  rtaJS.prototype.doProcess = function()
219
  {
220
- this.togglePanel('loading', false);
221
 
222
  if (this.is_stopped)
223
  return; // escape if process has been stopped.
@@ -225,6 +240,7 @@ rtaJS.prototype.doProcess = function()
225
  //total = this.total;
226
 
227
  this.in_process = true;
 
228
  this.checkSubmitReady();
229
 
230
  this.togglePanel('progress', true);
@@ -244,6 +260,9 @@ rtaJS.prototype.doProcess = function()
244
  //genform: JSON.stringify(form),
245
  },
246
  success: function (response) {
 
 
 
247
  if (typeof response.items !== 'undefined') // return is a process var..
248
  {
249
  self.process = response;
@@ -261,6 +280,13 @@ rtaJS.prototype.doProcess = function()
261
  // self.offset = response.current;
262
  setTimeout(function(){ self.doProcess(); },500);
263
  }
 
 
 
 
 
 
 
264
  }else{
265
  self.finishProcess(); // done, or so.
266
  }
@@ -268,13 +294,14 @@ rtaJS.prototype.doProcess = function()
268
  },
269
  error: function (response) {
270
 
 
271
  var status = new Object;
272
  status.id = -1;
273
  status.message = response.status + ' ' + response.statusText + ' :: ';
274
  status.error = true;
275
  self.add_status([status]);
276
 
277
- setTimeout(function(){ self.process(); },1000);
278
 
279
  },
280
  });
@@ -295,9 +322,15 @@ rtaJS.prototype.processStoppable = function()
295
  stoppable = true;
296
 
297
  if (stoppable)
 
298
  $('.stop-process').prop('disabled', false);
 
 
299
  else
 
300
  $('.stop-process').prop('disabled', true);
 
 
301
 
302
  }
303
 
@@ -307,6 +340,8 @@ rtaJS.prototype.processStoppable = function()
307
  this.is_interrupted_process = false;
308
 
309
  this.togglePanel('success', true);
 
 
310
  this.processStoppable();
311
  //this.toggleShortPixelNotice(true);
312
  // $('.stop-process').addClass('rta_hidden');
@@ -319,6 +354,47 @@ rtaJS.prototype.processStoppable = function()
319
  this.checkSubmitReady();
320
  }
321
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
322
  rtaJS.prototype.stopProcess = function()
323
  {
324
  if (window.confirm(rta_data.strings.confirm_stop))
@@ -353,7 +429,7 @@ rtaJS.prototype.processStoppable = function()
353
  }
354
  }
355
 
356
- rtaJS.prototype.updateProgress = function(percentage_done) {
357
 
358
  if (! this.process)
359
  return;
@@ -396,6 +472,12 @@ rtaJS.prototype.processStoppable = function()
396
  case 'loading':
397
  panel = ".rta_wait_loader";
398
  break;
 
 
 
 
 
 
399
  case 'progress':
400
  panel = '.rta_progress_view';
401
  break;
@@ -410,15 +492,15 @@ rtaJS.prototype.processStoppable = function()
410
  break;
411
  }
412
 
413
- var is_visible = $(panel).is(':visible');
414
  if (is_visible)
415
  {
416
  // zero opacity is considered visible by Jquery.
417
  if ($(panel).css('opacity') == 0)
418
  is_visible = false;
419
- }
420
 
421
- if (show && ! is_visible)
422
  {
423
  if ($(panel).hasClass('rta_hidden'))
424
  {
@@ -428,19 +510,26 @@ rtaJS.prototype.processStoppable = function()
428
  $(panel).css('opacity', 1);
429
  }
430
 
 
 
431
  }
432
- else if (! show && is_visible)
433
  {
434
  if ($(panel).hasClass('rta_hidden'))
435
  $(panel).hide();
436
  else
437
  $(panel).css('opacity', 0);
 
 
438
  }
 
439
  }
440
 
441
  rtaJS.prototype.resetPanels = function()
442
  {
443
  this.togglePanel('loading', false);
 
 
444
  this.togglePanel('progress', false);
445
  this.togglePanel('thumbnail', false);
446
  this.togglePanel('success', false);
@@ -448,6 +537,10 @@ rtaJS.prototype.processStoppable = function()
448
 
449
  $('.rta_notices .statuslist li').remove(); // empty previous statuses
450
 
 
 
 
 
451
  }
452
 
453
  rtaJS.prototype.add_status = function(status) {
@@ -507,7 +600,7 @@ rtaJS.prototype.processStoppable = function()
507
  var row = $('.row.proto').clone();
508
  $(row).attr('id', uniqueId);
509
  $(row).removeClass('proto');
510
- container.append(row); // row.css('display', 'flex')
511
 
512
  container.find('.header').removeClass('rta_hidden');
513
  }
6
  //offset: 0,
7
  process: false,
8
  is_interrupted_process: false, // was the process killed by reload earlier?
9
+ in_process: false, // processing, in general. can be set via server
10
+ in_ajax: false, // currently waiting for an ajax response.
11
+ is_stopped: false, // is_stopped: paused, when stopped permanently it also removes server-queue.
12
  is_saved: true,
13
  is_debug: false, // use sparingly
14
  status: []
41
  $(document).on('click', '.table.imagesizes .btn_remove_row', $.proxy(this.remove_image_size_row, this));
42
  $(document).on('click', '#btn_add_image_size', $.proxy(this.add_image_size_row, this));
43
  $(document).on('click', '.stop-process', $.proxy(this.stopProcess,this));
44
+ $(document).on('click', '.pause-process', $.proxy(this.pauseProcess,this));
45
  $(document).on('click', '.rta_success_box .modal-close', $.proxy(function(e){
46
  this.togglePanel('success', false);
47
  }, this));
127
  this.resumeProcess();
128
  }
129
 
 
130
  }
131
 
132
  rtaJS.prototype.selectAll = function(e)
152
  this.togglePanel('main', true);
153
  this.togglePanel('loading', true);
154
 
155
+ $([document.documentElement, document.body]).animate({
156
+ scrollTop: $("section.regenerate").offset().top
157
+ }, 1000);
158
+
159
+
160
  var status = new Object;
161
  status.id = -1;
162
  status.message = rta_data.strings.status_start;
207
  // function was interrupted, but will continue now; draw panels.
208
  rtaJS.prototype.resumeProcess = function()
209
  {
 
210
  this.togglePanel('main', true);
211
+ //this.resetPanels();
212
+ //this.togglePanel('main', true);
213
  this.togglePanel('loading', true);
214
+ this.togglePanel('progress', true);
215
 
216
  var status = new Object;
217
  status.id = -1;
219
  status.error = true;
220
  this.add_status([status]);
221
 
222
+ $([document.documentElement, document.body]).animate({
223
+ scrollTop: $("section.regenerate").offset().top
224
+ }, 1000);
225
+
226
+ this.processStoppable();
227
+ this.togglePanel('loading', false);
228
+ this.pauseProcess();
229
+ // this.doProcess();
230
+
231
  }
232
 
233
  // function for getting the next image in line.
234
  rtaJS.prototype.doProcess = function()
235
  {
 
236
 
237
  if (this.is_stopped)
238
  return; // escape if process has been stopped.
240
  //total = this.total;
241
 
242
  this.in_process = true;
243
+ this.in_ajax = true;
244
  this.checkSubmitReady();
245
 
246
  this.togglePanel('progress', true);
260
  //genform: JSON.stringify(form),
261
  },
262
  success: function (response) {
263
+ self.in_ajax = false;
264
+ self.togglePanel('loading', false);
265
+
266
  if (typeof response.items !== 'undefined') // return is a process var..
267
  {
268
  self.process = response;
280
  // self.offset = response.current;
281
  setTimeout(function(){ self.doProcess(); },500);
282
  }
283
+ else
284
+ {
285
+ self.in_process = false;
286
+ self.togglePanel('paused', true);
287
+ self.togglePanel('pausing', false);
288
+ $('.button.pause-process').prop('disabled', false);
289
+ }
290
  }else{
291
  self.finishProcess(); // done, or so.
292
  }
294
  },
295
  error: function (response) {
296
 
297
+ self.togglePanel('loading', false);
298
  var status = new Object;
299
  status.id = -1;
300
  status.message = response.status + ' ' + response.statusText + ' :: ';
301
  status.error = true;
302
  self.add_status([status]);
303
 
304
+ setTimeout(function(){ self.doProcess(); },1000);
305
 
306
  },
307
  });
322
  stoppable = true;
323
 
324
  if (stoppable)
325
+ {
326
  $('.stop-process').prop('disabled', false);
327
+ $('.pause-process').prop('disabled', false);
328
+ }
329
  else
330
+ {
331
  $('.stop-process').prop('disabled', true);
332
+ $('.pause-process').prop('disabled', true);
333
+ }
334
 
335
  }
336
 
340
  this.is_interrupted_process = false;
341
 
342
  this.togglePanel('success', true);
343
+ this.togglePanel('paused', false);
344
+ this.togglePanel('pausing', false);
345
  this.processStoppable();
346
  //this.toggleShortPixelNotice(true);
347
  // $('.stop-process').addClass('rta_hidden');
354
  this.checkSubmitReady();
355
  }
356
 
357
+ // This functions as a toggle
358
+ rtaJS.prototype.pauseProcess = function(e)
359
+ {
360
+ // Disable button pending action.
361
+ $('.button.pause-process').prop('disabled', true);
362
+
363
+ if (this.is_stopped == false)
364
+ {
365
+ this.is_stopped = true;
366
+ $('.pause-process .pause').css('display', 'none');
367
+ $('.pause-process .resume').css('display', 'inline');
368
+
369
+ if (this.in_ajax == false)
370
+ {
371
+ this.togglePanel('paused', true);
372
+ $('.button.pause-process').prop('disabled', false);
373
+ }
374
+ else
375
+ {
376
+ this.togglePanel('pausing', true);
377
+ }
378
+
379
+ }
380
+ else if (this.is_stopped == true)
381
+ {
382
+ this.is_stopped = false;
383
+ $('.pause-process .pause').css('display', 'inline');
384
+ $('.pause-process .resume').css('display', 'none');
385
+ var self = this;
386
+ this.togglePanel('pausing', false);
387
+ this.togglePanel('paused', false);
388
+ this.togglePanel('loading', true);
389
+
390
+ setTimeout(function(){
391
+ $('.button.pause-process').prop('disabled', false);
392
+ self.doProcess();
393
+ },500);
394
+ }
395
+
396
+ }
397
+
398
  rtaJS.prototype.stopProcess = function()
399
  {
400
  if (window.confirm(rta_data.strings.confirm_stop))
429
  }
430
  }
431
 
432
+ rtaJS.prototype.updateProgress = function() {
433
 
434
  if (! this.process)
435
  return;
472
  case 'loading':
473
  panel = ".rta_wait_loader";
474
  break;
475
+ case 'paused':
476
+ panel = ".rta_wait_paused";
477
+ break;
478
+ case 'pausing':
479
+ panel = '.rta_wait_pausing';
480
+ break
481
  case 'progress':
482
  panel = '.rta_progress_view';
483
  break;
492
  break;
493
  }
494
 
495
+ /* var is_visible = $(panel).is(':visible');
496
  if (is_visible)
497
  {
498
  // zero opacity is considered visible by Jquery.
499
  if ($(panel).css('opacity') == 0)
500
  is_visible = false;
501
+ } */
502
 
503
+ if (show)
504
  {
505
  if ($(panel).hasClass('rta_hidden'))
506
  {
510
  $(panel).css('opacity', 1);
511
  }
512
 
513
+ $(panel).removeClass('rta_panel_off');
514
+
515
  }
516
+ else if (! show)
517
  {
518
  if ($(panel).hasClass('rta_hidden'))
519
  $(panel).hide();
520
  else
521
  $(panel).css('opacity', 0);
522
+
523
+ $(panel).addClass('rta_panel_off');
524
  }
525
+
526
  }
527
 
528
  rtaJS.prototype.resetPanels = function()
529
  {
530
  this.togglePanel('loading', false);
531
+ this.togglePanel('paused', false);
532
+ this.togglePanel('pausing', false);
533
  this.togglePanel('progress', false);
534
  this.togglePanel('thumbnail', false);
535
  this.togglePanel('success', false);
537
 
538
  $('.rta_notices .statuslist li').remove(); // empty previous statuses
539
 
540
+ // Flick back the pause / resume thing.
541
+ $('.pause-process .pause').css('display', 'inline');
542
+ $('.pause-process .resume').css('display', 'none');
543
+
544
  }
545
 
546
  rtaJS.prototype.add_status = function(status) {
600
  var row = $('.row.proto').clone();
601
  $(row).attr('id', uniqueId);
602
  $(row).removeClass('proto');
603
+ container.append(row); // row.css('display', 'flex')
604
 
605
  container.find('.header').removeClass('rta_hidden');
606
  }
js/rta.min.js CHANGED
@@ -1 +1 @@
1
- jQuery(document).ready(function(e){function s(){}(s.prototype={process:!1,is_interrupted_process:!1,in_process:!1,is_stopped:!1,is_saved:!0,is_debug:!1,status:[]}).init=function(){1==rta_data.is_debug&&(this.is_debug=!0,console.log(rta_data)),this.setStatusCodes(),this.initProcess(),this.checkSubmitReady(),e(".select, .deselect").on("click",e.proxy(this.selectAll,this)),e(document).on("change","input, select",e.proxy(this.checkSubmitReady,this)),e("#rtaform_process").on("submit",e.proxy(this.startProcess,this)),e(document).on("change",".table.imagesizes input, .table.imagesizes select",e.proxy(this.image_size_changed,this)),e(document).on("click",'button[name="save_settings"]',e.proxy(this.image_size_changed,this)),e(document).on("click",".table.imagesizes .btn_remove_row",e.proxy(this.remove_image_size_row,this)),e(document).on("click","#btn_add_image_size",e.proxy(this.add_image_size_row,this)),e(document).on("click",".stop-process",e.proxy(this.stopProcess,this)),e(document).on("click",".rta_success_box .modal-close",e.proxy(function(e){this.togglePanel("success",!1)},this)),e(document).on("change",'input[name="del_associated_thumbs"]',e.proxy(this.toggleDeleteItems,this)),e(document).on("change",'input[name^="regenerate_sizes"]',e.proxy(this.toggleDeleteItems,this)),this.toggleDeleteItems(),e(document).on("change",".rta-settings-wrap input, .rta-settings-wrap select",e.proxy(this.show_save_indicator,this)),e(document).on("change",'input[name^="regenerate_sizes"]',e.proxy(this.checkOptionsVisible,this)),e(".toggle-window").on("click",e.proxy(this.toggleWindow,this))},s.prototype.setStatusCodes=function(){},s.prototype.checkSubmitReady=function(){processReady=!0,inputs=e('input[name^="regenerate_sizes"]:checked'),!this.in_process&&this.is_saved||(processReady=!1),processReady?(e("button.rta_regenerate").removeClass("disabled"),e("button.rta_regenerate").prop("disabled",!1)):(e("button.rta_regenerate").addClass("disabled"),e("button.rta_regenerate").prop("disabled",!0)),this.is_saved?(e('button[name="save_settings"]').prop("disabled",!0),e('button[name="save_settings"]').addClass("disabled"),e(".save_note").addClass("rta_hidden")):(e('button[name="save_settings"]').prop("disabled",!1),e('button[name="save_settings"]').removeClass("disabled"),e(".save_note").removeClass("rta_hidden"))},s.prototype.initProcess=function(){process=rta_data.process,this.is_debug&&console.log(process),this.process=process,process.running&&(this.in_process=process.running),(process.running||process.preparing)&&(this.updateProgress(),this.resumeProcess())},s.prototype.selectAll=function(s){var t=e(s.target).data("action"),a=e(s.target).data("target");checked="select"==t,e('input[name^="'+a+'"]').prop("checked",checked).trigger("change")},s.prototype.startProcess=function(s){s.preventDefault(),this.resetPanels(),this.togglePanel("main",!0),this.togglePanel("loading",!0);var t=new Object;t.id=-1,t.message=rta_data.strings.status_start,t.error=!0,this.add_status([t]),this.in_process=!0,this.is_stopped=!1,this.checkSubmitReady();var a=this,i=e("#rtaform_process");e.ajax({type:"POST",dataType:"json",url:rta_data.ajaxurl,data:{nonce:rta_data.nonce_generate,action:"rta_start_process",genform:i.serialize()},success:function(e){e.status&&a.add_status(e.status),a.process=e,a.updateProgress(),a.doProcess()},error:function(e,s,t){var i=new Object;this.is_debug&&console.log(e),i.id=-1,i.message=rta_data.strings.status_fatal,i.error=!0,a.add_status([i]),a.finishProcess()}})},s.prototype.resumeProcess=function(){this.resetPanels(),this.togglePanel("main",!0),this.togglePanel("loading",!0);var e=new Object;e.id=-1,e.message=rta_data.strings.status_resume,e.error=!0,this.add_status([e]),this.doProcess()},s.prototype.doProcess=function(){if(this.togglePanel("loading",!1),!this.is_stopped){this.in_process=!0,this.checkSubmitReady(),this.togglePanel("progress",!0),this.processStoppable();var s=this;e.ajax({type:"POST",dataType:"json",url:rta_data.ajaxurl,data:{nonce:rta_data.nonce_doprocess,action:"rta_do_process",type:"submit"},success:function(e){void 0!==e.items&&(s.process=e,s.updateProgress()),e.status&&s.add_status(e.status),e.running||e.preparing?s.is_stopped||setTimeout(function(){s.doProcess()},500):s.finishProcess()},error:function(e){var t=new Object;t.id=-1,t.message=e.status+" "+e.statusText+" :: ",t.error=!0,s.add_status([t]),setTimeout(function(){s.process()},1e3)}})}},s.prototype.processStoppable=function(){var s=!1;this.in_process&&(s=!0),s?e(".stop-process").prop("disabled",!1):e(".stop-process").prop("disabled",!0)},s.prototype.finishProcess=function(){this.in_process=!1,this.is_interrupted_process=!1,this.togglePanel("success",!0),this.processStoppable();var e=new Object;e.id=-1,e.message=rta_data.strings.status_finish,e.error=!0,this.add_status([e]),this.checkSubmitReady()},s.prototype.stopProcess=function(){if(window.confirm(rta_data.strings.confirm_stop)){this.is_stopped=!0,this.togglePanel("loading",!0);var s=this;e.ajax({type:"POST",dataType:"json",url:rta_data.ajaxurl,data:{nonce:rta_data.nonce_generate,action:"rta_stop_process",type:"submit"},success:function(e){e.status&&s.add_status(e.status),s.process=!1,s.finishProcess(),s.togglePanel("loading",!1)}})}},s.prototype.updateProgress=function(s){if(this.process){var t=parseInt(this.process.items),a=parseInt(this.process.done),i=t+a,o=(this.process.errors,289.027);(s=0==a&&i>0?0:i>0?Math.round(a/i*100):100)>0&&(o=Math.round(o-o*s/100)),e(".CircularProgressbar-path").css("stroke-dashoffset",o+"px"),e(".CircularProgressbar-text").html(s+"%"),e(".progress-count .current").text(a),e(".progress-count .total").text(i)}},s.prototype.togglePanel=function(s,t){var a;switch(s){case"main":a="section.regenerate";break;case"loading":a=".rta_wait_loader";break;case"progress":a=".rta_progress_view";break;case"thumbnail":a=".rta_thumbnail_view";break;case"success":a=".rta_success_box";break;case"notices":a=".rta_notices"}var i=e(a).is(":visible");i&&0==e(a).css("opacity")&&(i=!1),t&&!i?e(a).hasClass("rta_hidden")?e(a).slideDown():e(a).css("opacity",1):!t&&i&&(e(a).hasClass("rta_hidden")?e(a).hide():e(a).css("opacity",0))},s.prototype.resetPanels=function(){this.togglePanel("loading",!1),this.togglePanel("progress",!1),this.togglePanel("thumbnail",!1),this.togglePanel("success",!1),this.togglePanel("notices",!1),e(".rta_notices .statuslist li").remove()},s.prototype.add_status=function(s){if(this.togglePanel("notices",!0),""!=s){for(var t="",a=0;a<s.length;a++){var i=s[a],o="";o=i.error?"error":"",1!=i.status?t=t+'<li class="list-group-item '+o+'">'+i.message+"</li>":this.showThumb(i.message)}e(".rta_status_box ul.statuslist").append(t)}},s.prototype.showThumb=function(s){this.togglePanel("thumbnail",!0),e(".rta_progress .images img").attr("src",s)},s.prototype.add_image_size_row=function(){var e=jQuery,s=e(".table.imagesizes"),t=Math.random().toString(36).substring(2)+(new Date).getTime().toString(36),a=e(".row.proto").clone();e(a).attr("id",t),e(a).removeClass("proto"),s.append(a),s.find(".header").removeClass("rta_hidden")},s.prototype.image_size_changed=function(s){s.preventDefault();var t=e(s.target).parents(".row").attr("id");this.update_thumb_name(t),this.save_image_sizes()},s.prototype.update_thumb_name=function(s){if(e("#"+s).length){var t=e("#"+s+" .image_sizes_name").val(),a=e("#"+s+" .image_sizes_width").val(),i=e("#"+s+" .image_sizes_height").val(),o=e("#"+s+" .image_sizes_cropping").val(),r=e("#"+s+" .image_sizes_pname").val();a<=0&&(a=""),i<=0&&(i="");var n=("rta_thumb "+o+" "+a+"x"+i).toLowerCase().replace(/ /g,"_");e('input[name^="regenerate_sizes"][value="'+t+'"]').val(n),r.length<=0&&e('input[name^="regenerate_sizes"][value="'+t+'"]').text(n),e('input[name="keep_'+t+'"]').attr("name","keep_"+n),e("#"+s+" .image_sizes_name").val(n)}},s.prototype.save_image_sizes=function(){this.settings_doingsave_indicator(!0);var s=rta_data.nonce_savesizes,t=this;e.ajax({type:"POST",dataType:"json",url:rta_data.ajaxurl,data:{action:"rta_save_image_sizes",save_nonce:s,saveform:e("#rta_settings_form").serialize()},success:function(s){s.error||s.new_image_sizes&&(e(".thumbnail_select .checkbox-list").fadeOut(80).html(s.new_image_sizes).fadeIn(80),t.checkOptionsVisible()),t.is_saved=!0,t.settings_doingsave_indicator(!1),t.checkSubmitReady(),t.toggleDeleteItems()}})},s.prototype.settings_doingsave_indicator=function(s){s?e(".form_controls .save_indicator").fadeIn(20):e(".form_controls .save_indicator").fadeOut(100)},s.prototype.show_save_indicator=function(){this.is_saved=!1,this.checkSubmitReady()},s.prototype.remove_image_size_row=function(s){var t=e(s.target).parents(".row").attr("id");if(confirm(rta_data.strings.confirm_delete)){var a=e("#"+t).find(".image_sizes_name").val();e('input[name^="regenerate_sizes"][value="'+a+'"]').remove(),e("#"+t).remove(),this.save_image_sizes()}},s.prototype.checkOptionsVisible=function(){e('input[name^="regenerate_sizes"]').each(function(){if(e(this).is(":checked")){e(this).parents(".item").find(".options").removeClass("hidden");var s=e(this).parents(".item").find('input[type="checkbox"]');void 0===e(s).data("setbyuser")&&(e(s).prop("checked",!0),e(s).data("setbyuser",!0))}else e(this).parents(".item").find(".options").addClass("hidden")})},s.prototype.toggleDeleteItems=function(){e(".checkbox-list label").removeClass("warning-removal"),e(".checkbox-list .icon-warning").remove();var s=e('input[name="del_associated_thumbs"]');if(e(s).is(":checked")){var t=!1;e('input[name^="regenerate_sizes"]').not(":checked").each(function(){e(this).parent("label").addClass("warning-removal"),e(this).parent("label").find("input").before("<span class='dashicons dashicons-no icon-warning'></span>"),t=!0}),t&&e("#warn-delete-items").removeClass("rta_hidden")}else e("#warn-delete-items").addClass("rta_hidden")},s.prototype.toggleWindow=function(s){var t=e(s.target);t.hasClass("toggle-window")||(t=e(s.target).parents(".toggle-window"));var a=e("#"+t.data("window"));a.hasClass("window-up")?(a.removeClass("window-up").addClass("window-down"),t.find("span.dashicons").removeClass("dashicons-arrow-down").addClass("dashicons-arrow-up")):(a.removeClass("window-down").addClass("window-up"),t.find("span.dashicons").addClass("dashicons-arrow-down").removeClass("dashicons-arrow-up"))},window.rtaJS=new s,window.rtaJS.init()});
1
+ jQuery(document).ready(function(e){function s(){}(s.prototype={process:!1,is_interrupted_process:!1,in_process:!1,in_ajax:!1,is_stopped:!1,is_saved:!0,is_debug:!1,status:[]}).init=function(){1==rta_data.is_debug&&(this.is_debug=!0,console.log(rta_data)),this.setStatusCodes(),this.initProcess(),this.checkSubmitReady(),e(".select, .deselect").on("click",e.proxy(this.selectAll,this)),e(document).on("change","input, select",e.proxy(this.checkSubmitReady,this)),e("#rtaform_process").on("submit",e.proxy(this.startProcess,this)),e(document).on("change",".table.imagesizes input, .table.imagesizes select",e.proxy(this.image_size_changed,this)),e(document).on("click",'button[name="save_settings"]',e.proxy(this.image_size_changed,this)),e(document).on("click",".table.imagesizes .btn_remove_row",e.proxy(this.remove_image_size_row,this)),e(document).on("click","#btn_add_image_size",e.proxy(this.add_image_size_row,this)),e(document).on("click",".stop-process",e.proxy(this.stopProcess,this)),e(document).on("click",".pause-process",e.proxy(this.pauseProcess,this)),e(document).on("click",".rta_success_box .modal-close",e.proxy(function(e){this.togglePanel("success",!1)},this)),e(document).on("change",'input[name="del_associated_thumbs"]',e.proxy(this.toggleDeleteItems,this)),e(document).on("change",'input[name^="regenerate_sizes"]',e.proxy(this.toggleDeleteItems,this)),this.toggleDeleteItems(),e(document).on("change",".rta-settings-wrap input, .rta-settings-wrap select",e.proxy(this.show_save_indicator,this)),e(document).on("change",'input[name^="regenerate_sizes"]',e.proxy(this.checkOptionsVisible,this)),e(".toggle-window").on("click",e.proxy(this.toggleWindow,this))},s.prototype.setStatusCodes=function(){},s.prototype.checkSubmitReady=function(){processReady=!0,inputs=e('input[name^="regenerate_sizes"]:checked'),!this.in_process&&this.is_saved||(processReady=!1),processReady?(e("button.rta_regenerate").removeClass("disabled"),e("button.rta_regenerate").prop("disabled",!1)):(e("button.rta_regenerate").addClass("disabled"),e("button.rta_regenerate").prop("disabled",!0)),this.is_saved?(e('button[name="save_settings"]').prop("disabled",!0),e('button[name="save_settings"]').addClass("disabled"),e(".save_note").addClass("rta_hidden")):(e('button[name="save_settings"]').prop("disabled",!1),e('button[name="save_settings"]').removeClass("disabled"),e(".save_note").removeClass("rta_hidden"))},s.prototype.initProcess=function(){process=rta_data.process,this.is_debug&&console.log(process),this.process=process,process.running&&(this.in_process=process.running),(process.running||process.preparing)&&(this.updateProgress(),this.resumeProcess())},s.prototype.selectAll=function(s){var t=e(s.target).data("action"),a=e(s.target).data("target");checked="select"==t,e('input[name^="'+a+'"]').prop("checked",checked).trigger("change")},s.prototype.startProcess=function(s){s.preventDefault(),this.resetPanels(),this.togglePanel("main",!0),this.togglePanel("loading",!0),e([document.documentElement,document.body]).animate({scrollTop:e("section.regenerate").offset().top},1e3);var t=new Object;t.id=-1,t.message=rta_data.strings.status_start,t.error=!0,this.add_status([t]),this.in_process=!0,this.is_stopped=!1,this.checkSubmitReady();var a=this,o=e("#rtaform_process");e.ajax({type:"POST",dataType:"json",url:rta_data.ajaxurl,data:{nonce:rta_data.nonce_generate,action:"rta_start_process",genform:o.serialize()},success:function(e){e.status&&a.add_status(e.status),a.process=e,a.updateProgress(),a.doProcess()},error:function(e,s,t){var o=new Object;this.is_debug&&console.log(e),o.id=-1,o.message=rta_data.strings.status_fatal,o.error=!0,a.add_status([o]),a.finishProcess()}})},s.prototype.resumeProcess=function(){this.togglePanel("main",!0),this.togglePanel("loading",!0),this.togglePanel("progress",!0);var s=new Object;s.id=-1,s.message=rta_data.strings.status_resume,s.error=!0,this.add_status([s]),e([document.documentElement,document.body]).animate({scrollTop:e("section.regenerate").offset().top},1e3),this.processStoppable(),this.togglePanel("loading",!1),this.pauseProcess()},s.prototype.doProcess=function(){if(!this.is_stopped){this.in_process=!0,this.in_ajax=!0,this.checkSubmitReady(),this.togglePanel("progress",!0),this.processStoppable();var s=this;e.ajax({type:"POST",dataType:"json",url:rta_data.ajaxurl,data:{nonce:rta_data.nonce_doprocess,action:"rta_do_process",type:"submit"},success:function(t){s.in_ajax=!1,s.togglePanel("loading",!1),void 0!==t.items&&(s.process=t,s.updateProgress()),t.status&&s.add_status(t.status),t.running||t.preparing?s.is_stopped?(s.in_process=!1,s.togglePanel("paused",!0),s.togglePanel("pausing",!1),e(".button.pause-process").prop("disabled",!1)):setTimeout(function(){s.doProcess()},500):s.finishProcess()},error:function(e){s.togglePanel("loading",!1);var t=new Object;t.id=-1,t.message=e.status+" "+e.statusText+" :: ",t.error=!0,s.add_status([t]),setTimeout(function(){s.doProcess()},1e3)}})}},s.prototype.processStoppable=function(){var s=!1;this.in_process&&(s=!0),s?(e(".stop-process").prop("disabled",!1),e(".pause-process").prop("disabled",!1)):(e(".stop-process").prop("disabled",!0),e(".pause-process").prop("disabled",!0))},s.prototype.finishProcess=function(){this.in_process=!1,this.is_interrupted_process=!1,this.togglePanel("success",!0),this.togglePanel("paused",!1),this.togglePanel("pausing",!1),this.processStoppable();var e=new Object;e.id=-1,e.message=rta_data.strings.status_finish,e.error=!0,this.add_status([e]),this.checkSubmitReady()},s.prototype.pauseProcess=function(s){if(e(".button.pause-process").prop("disabled",!0),0==this.is_stopped)this.is_stopped=!0,e(".pause-process .pause").css("display","none"),e(".pause-process .resume").css("display","inline"),0==this.in_ajax?(this.togglePanel("paused",!0),e(".button.pause-process").prop("disabled",!1)):this.togglePanel("pausing",!0);else if(1==this.is_stopped){this.is_stopped=!1,e(".pause-process .pause").css("display","inline"),e(".pause-process .resume").css("display","none");var t=this;this.togglePanel("pausing",!1),this.togglePanel("paused",!1),this.togglePanel("loading",!0),setTimeout(function(){e(".button.pause-process").prop("disabled",!1),t.doProcess()},500)}},s.prototype.stopProcess=function(){if(window.confirm(rta_data.strings.confirm_stop)){this.is_stopped=!0,this.togglePanel("loading",!0);var s=this;e.ajax({type:"POST",dataType:"json",url:rta_data.ajaxurl,data:{nonce:rta_data.nonce_generate,action:"rta_stop_process",type:"submit"},success:function(e){e.status&&s.add_status(e.status),s.process=!1,s.finishProcess(),s.togglePanel("loading",!1)}})}},s.prototype.updateProgress=function(){if(this.process){var s=parseInt(this.process.items),t=parseInt(this.process.done),a=s+t;this.process.errors;percentage_done=0==t&&a>0?0:a>0?Math.round(t/a*100):100;var o=289.027;percentage_done>0&&(o=Math.round(o-o*percentage_done/100)),e(".CircularProgressbar-path").css("stroke-dashoffset",o+"px"),e(".CircularProgressbar-text").html(percentage_done+"%"),e(".progress-count .current").text(t),e(".progress-count .total").text(a)}},s.prototype.togglePanel=function(s,t){var a;switch(s){case"main":a="section.regenerate";break;case"loading":a=".rta_wait_loader";break;case"paused":a=".rta_wait_paused";break;case"pausing":a=".rta_wait_pausing";break;case"progress":a=".rta_progress_view";break;case"thumbnail":a=".rta_thumbnail_view";break;case"success":a=".rta_success_box";break;case"notices":a=".rta_notices"}t?(e(a).hasClass("rta_hidden")?e(a).slideDown():e(a).css("opacity",1),e(a).removeClass("rta_panel_off")):t||(e(a).hasClass("rta_hidden")?e(a).hide():e(a).css("opacity",0),e(a).addClass("rta_panel_off"))},s.prototype.resetPanels=function(){this.togglePanel("loading",!1),this.togglePanel("paused",!1),this.togglePanel("pausing",!1),this.togglePanel("progress",!1),this.togglePanel("thumbnail",!1),this.togglePanel("success",!1),this.togglePanel("notices",!1),e(".rta_notices .statuslist li").remove(),e(".pause-process .pause").css("display","inline"),e(".pause-process .resume").css("display","none")},s.prototype.add_status=function(s){if(this.togglePanel("notices",!0),""!=s){for(var t="",a=0;a<s.length;a++){var o=s[a],i="";i=o.error?"error":"",1!=o.status?t=t+'<li class="list-group-item '+i+'">'+o.message+"</li>":this.showThumb(o.message)}e(".rta_status_box ul.statuslist").append(t)}},s.prototype.showThumb=function(s){this.togglePanel("thumbnail",!0),e(".rta_progress .images img").attr("src",s)},s.prototype.add_image_size_row=function(){var e=jQuery,s=e(".table.imagesizes"),t=Math.random().toString(36).substring(2)+(new Date).getTime().toString(36),a=e(".row.proto").clone();e(a).attr("id",t),e(a).removeClass("proto"),s.append(a),s.find(".header").removeClass("rta_hidden")},s.prototype.image_size_changed=function(s){s.preventDefault();var t=e(s.target).parents(".row").attr("id");this.update_thumb_name(t),this.save_image_sizes()},s.prototype.update_thumb_name=function(s){if(e("#"+s).length){var t=e("#"+s+" .image_sizes_name").val(),a=e("#"+s+" .image_sizes_width").val(),o=e("#"+s+" .image_sizes_height").val(),i=e("#"+s+" .image_sizes_cropping").val(),n=e("#"+s+" .image_sizes_pname").val();a<=0&&(a=""),o<=0&&(o="");var r=("rta_thumb "+i+" "+a+"x"+o).toLowerCase().replace(/ /g,"_");e('input[name^="regenerate_sizes"][value="'+t+'"]').val(r),n.length<=0&&e('input[name^="regenerate_sizes"][value="'+t+'"]').text(r),e('input[name="keep_'+t+'"]').attr("name","keep_"+r),e("#"+s+" .image_sizes_name").val(r)}},s.prototype.save_image_sizes=function(){this.settings_doingsave_indicator(!0);var s=rta_data.nonce_savesizes,t=this;e.ajax({type:"POST",dataType:"json",url:rta_data.ajaxurl,data:{action:"rta_save_image_sizes",save_nonce:s,saveform:e("#rta_settings_form").serialize()},success:function(s){s.error||s.new_image_sizes&&(e(".thumbnail_select .checkbox-list").fadeOut(80).html(s.new_image_sizes).fadeIn(80),t.checkOptionsVisible()),t.is_saved=!0,t.settings_doingsave_indicator(!1),t.checkSubmitReady(),t.toggleDeleteItems()}})},s.prototype.settings_doingsave_indicator=function(s){s?e(".form_controls .save_indicator").fadeIn(20):e(".form_controls .save_indicator").fadeOut(100)},s.prototype.show_save_indicator=function(){this.is_saved=!1,this.checkSubmitReady()},s.prototype.remove_image_size_row=function(s){var t=e(s.target).parents(".row").attr("id");if(confirm(rta_data.strings.confirm_delete)){var a=e("#"+t).find(".image_sizes_name").val();e('input[name^="regenerate_sizes"][value="'+a+'"]').remove(),e("#"+t).remove(),this.save_image_sizes()}},s.prototype.checkOptionsVisible=function(){e('input[name^="regenerate_sizes"]').each(function(){if(e(this).is(":checked")){e(this).parents(".item").find(".options").removeClass("hidden");var s=e(this).parents(".item").find('input[type="checkbox"]');void 0===e(s).data("setbyuser")&&(e(s).prop("checked",!0),e(s).data("setbyuser",!0))}else e(this).parents(".item").find(".options").addClass("hidden")})},s.prototype.toggleDeleteItems=function(){e(".checkbox-list label").removeClass("warning-removal"),e(".checkbox-list .icon-warning").remove();var s=e('input[name="del_associated_thumbs"]');if(e(s).is(":checked")){var t=!1;e('input[name^="regenerate_sizes"]').not(":checked").each(function(){e(this).parent("label").addClass("warning-removal"),e(this).parent("label").find("input").before("<span class='dashicons dashicons-no icon-warning'></span>"),t=!0}),t&&e("#warn-delete-items").removeClass("rta_hidden")}else e("#warn-delete-items").addClass("rta_hidden")},s.prototype.toggleWindow=function(s){var t=e(s.target);t.hasClass("toggle-window")||(t=e(s.target).parents(".toggle-window"));var a=e("#"+t.data("window"));a.hasClass("window-up")?(a.removeClass("window-up").addClass("window-down"),t.find("span.dashicons").removeClass("dashicons-arrow-down").addClass("dashicons-arrow-up")):(a.removeClass("window-down").addClass("window-up"),t.find("span.dashicons").addClass("dashicons-arrow-down").removeClass("dashicons-arrow-up"))},window.rtaJS=new s,window.rtaJS.init()});
readme.txt CHANGED
@@ -3,9 +3,9 @@ Contributors: ShortPixel
3
  Donate link: https://www.paypal.me/resizeImage
4
  Tags: regenerate, thumbnail, thumbnails, thumb, thumbs, easy, media, force regenerate, image, images, pics, date
5
  Requires at least: 4.0
6
- Tested up to: 5.5
7
  Requires PHP: 5.3
8
- Stable tag: 2.3.2
9
  License: GPLv2 or later
10
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
11
 
@@ -61,6 +61,14 @@ The script stops but it will resume after you open the settings page of the plug
61
 
62
  == Changelog ==
63
 
 
 
 
 
 
 
 
 
64
  = 2.3.2 =
65
 
66
  Release date: August 17th 2020
3
  Donate link: https://www.paypal.me/resizeImage
4
  Tags: regenerate, thumbnail, thumbnails, thumb, thumbs, easy, media, force regenerate, image, images, pics, date
5
  Requires at least: 4.0
6
+ Tested up to: 6.1
7
  Requires PHP: 5.3
8
+ Stable tag: 2.4.0
9
  License: GPLv2 or later
10
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
11
 
61
 
62
  == Changelog ==
63
 
64
+ = 2.4.0 =
65
+
66
+ Release date: December 1st 2020
67
+ * New: Pause Button;
68
+ * New: Resuming process from another page now starts paused;
69
+ * New: Added Filter for increasing number of items processed per run;
70
+ * Fix: Users optimizing more than 50K images could run into a code loop protection.
71
+
72
  = 2.3.2 =
73
 
74
  Release date: August 17th 2020
regenerate-thumbnails-advanced.php CHANGED
@@ -1,22 +1,23 @@
1
  <?php
2
  namespace ReThumbAdvanced;
3
- /*
4
- Plugin Name: Regenerate Thumbnails Advanced
5
- Description: Regenerate thumbnails fast and easy while removing unused thumbnails of existing images; very useful when changing a theme.
6
- Version: 2.3.2
7
- Author: ShortPixel
8
- Author URI: https://shortpixel.com/
9
- License: GPLv2 or later
10
- Text Domain: regenerate-thumbnails-advanced
11
- Domain Path: /languages
12
- */
 
13
 
14
  // Make sure we don't expose any info if called directly
15
  if ( !function_exists( 'add_action' ) ) {
16
  exit;
17
  }
18
 
19
- define( 'RTA_PLUGIN_VERSION', '2.3.2');
20
  define( 'RTA_PLUGIN_PATH', plugin_dir_path(__FILE__) );
21
  define( 'RTA_PLUGIN_URL', plugin_dir_url(__FILE__) );
22
  define( 'RTA_SITE_BASE_URL', rtrim(get_bloginfo('url'),"/")."/");
1
  <?php
2
  namespace ReThumbAdvanced;
3
+ /**
4
+ * Plugin Name: Regenerate Thumbnails Advanced
5
+ * Description: Regenerate thumbnails fast and easy while removing unused thumbnails of existing images; very useful when changing a theme.
6
+ * Version: 2.4.0
7
+ * Author: ShortPixel
8
+ * Author URI: https://shortpixel.com/
9
+ * License: GPLv2 or later
10
+ * GitHub Plugin URI: https://github.com/short-pixel-optimizer/regenerate-thumbnails-advanced-rewrite
11
+ * Text Domain: regenerate-thumbnails-advanced
12
+ * Domain Path: /languages
13
+ */
14
 
15
  // Make sure we don't expose any info if called directly
16
  if ( !function_exists( 'add_action' ) ) {
17
  exit;
18
  }
19
 
20
+ define( 'RTA_PLUGIN_VERSION', '2.4.0');
21
  define( 'RTA_PLUGIN_PATH', plugin_dir_path(__FILE__) );
22
  define( 'RTA_PLUGIN_URL', plugin_dir_url(__FILE__) );
23
  define( 'RTA_SITE_BASE_URL', rtrim(get_bloginfo('url'),"/")."/");
scss/rta-admin-progress.scss CHANGED
@@ -108,32 +108,42 @@ section.regenerate
108
  border-left: 1px solid #ccc;
109
  position: relative;
110
  z-index: 10;
 
111
 
112
- .rta_wait_loader
113
  {
114
  margin-top: 35px;
115
  padding-left: 20px;
116
- opacity: 0;
117
  position: relative;
118
  z-index: 1;
119
- //display:none;
 
120
  .dashicons {
121
- animation: wait-spin 2000ms infinite linear;
122
- animation-play-state: running;
123
  width: 35px;
124
  height: 35px;
125
  font-size: 35px;
126
  float: left;
127
  margin-right: 30px;
 
 
 
 
128
 
 
 
 
129
  }
130
  &.rta_panel_off // don't run when not visible.
131
  {
 
132
  .dashicons
133
  {
134
  animation-play-state: paused;
135
  }
136
  }
 
137
  }
138
  .rta_notices
139
  {
@@ -230,15 +240,24 @@ section.regenerate
230
  }
231
 
232
 
233
- button.stop-process
234
  {
235
  position: absolute;
236
  bottom: 10px;
237
- left: 15px;
238
  font-weight: normal;
239
  text-transform: none;
240
  padding: 4px 20px;
241
  font-size: 14px;
 
 
 
 
 
 
 
 
 
242
  }
243
 
244
 
108
  border-left: 1px solid #ccc;
109
  position: relative;
110
  z-index: 10;
111
+ padding-bottom : 75px; // Space for the stop / start controls.
112
 
113
+ .rta_wait_loader, .rta_wait_paused, .rta_wait_pausing
114
  {
115
  margin-top: 35px;
116
  padding-left: 20px;
117
+ opacity: 1;
118
  position: relative;
119
  z-index: 1;
120
+ transition: opacity 750ms;
121
+
122
  .dashicons {
123
+ display: inline-block;
 
124
  width: 35px;
125
  height: 35px;
126
  font-size: 35px;
127
  float: left;
128
  margin-right: 30px;
129
+ &.dashicons-update {
130
+ animation: wait-spin 2000ms infinite linear;
131
+ animation-play-state: running;
132
+ }
133
 
134
+ }
135
+ > div {
136
+ // display: inline-block; // content block
137
  }
138
  &.rta_panel_off // don't run when not visible.
139
  {
140
+ opacity: 0;
141
  .dashicons
142
  {
143
  animation-play-state: paused;
144
  }
145
  }
146
+
147
  }
148
  .rta_notices
149
  {
240
  }
241
 
242
 
243
+ button.stop-process, button.pause-process
244
  {
245
  position: absolute;
246
  bottom: 10px;
247
+ right: 15px;
248
  font-weight: normal;
249
  text-transform: none;
250
  padding: 4px 20px;
251
  font-size: 14px;
252
+ .dashicons {
253
+ vertical-align: middle;
254
+ }
255
+ }
256
+ button.pause-process
257
+ {
258
+ left: 15px;
259
+ right: auto;
260
+ .resume { display: none }
261
  }
262
 
263
 
templates/admin/view_regenerate_process.php CHANGED
@@ -33,7 +33,15 @@ namespace ReThumbAdvanced;
33
  </div>
34
 
35
  <div class="rta_status_box">
36
- <button class='button stop-process' disabled><?php _e('Stop Process', 'regenerate-thumbnails-advanced') ?></button>
 
 
 
 
 
 
 
 
37
 
38
  <div class="rta_notices rta_panel_off">
39
  <ul class="statuslist">
@@ -41,9 +49,25 @@ namespace ReThumbAdvanced;
41
  </div>
42
  <div class="rta_wait_loader rta_panel_off" >
43
  <span class='dashicons dashicons-update'>&nbsp;</span>
44
- <div>
45
  <h4><?php _e('Starting Process', 'regenerate-thumbnails-advanced', 'regenerate-thumbnails-advanced'); ?></h4>
46
- <?php _e('Please wait...','regenerate-thumbnails-advanced', 'regenerate-thumbnails-advanced'); ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
47
  </div>
48
  </div>
49
 
33
  </div>
34
 
35
  <div class="rta_status_box">
36
+ <button class='button pause-process' type="button" disabled>
37
+ <span class='pause'><span class="dashicons dashicons-controls-pause">&nbsp;</span> <?php _e('Pause Process', 'regenerate-thumbnails-advanced') ?></span>
38
+ <span class='resume'><span class="dashicons dashicons-controls-play">&nbsp;</span> <?php _e('Resume Process', 'regenerate-thumbnails-advanced') ?></span>
39
+ </button>
40
+
41
+ <button class='button stop-process' type="button" disabled>
42
+ <span class="dashicons dashicons-no">&nbsp;</span>
43
+ <?php _e('Stop Process', 'regenerate-thumbnails-advanced') ?>
44
+ </button>
45
 
46
  <div class="rta_notices rta_panel_off">
47
  <ul class="statuslist">
49
  </div>
50
  <div class="rta_wait_loader rta_panel_off" >
51
  <span class='dashicons dashicons-update'>&nbsp;</span>
52
+ <div class='start'>
53
  <h4><?php _e('Starting Process', 'regenerate-thumbnails-advanced', 'regenerate-thumbnails-advanced'); ?></h4>
54
+ <p><?php _e('Please wait...','regenerate-thumbnails-advanced', 'regenerate-thumbnails-advanced'); ?></p>
55
+ </div>
56
+ </div>
57
+
58
+ <div class="rta_wait_paused rta_panel_off" >
59
+ <span class='dashicons dashicons-controls-pause'>&nbsp;</span>
60
+ <div class='resume'>
61
+ <h4 ><?php _e('Process is paused', 'regenerate-thumbnails-advanced', 'regenerate-thumbnails-advanced'); ?></h4>
62
+ <p><?php _e('Click Resume Process to continue','regenerate-thumbnails-advanced', 'regenerate-thumbnails-advanced'); ?></p>
63
+ </div>
64
+ </div>
65
+
66
+ <div class="rta_wait_pausing rta_panel_off" >
67
+ <span class='dashicons dashicons-update'>&nbsp;</span>
68
+ <div class='pausing'>
69
+ <h4><?php _e('Process is pausing, please wait', 'regenerate-thumbnails-advanced'); ?></h4>
70
+ <p><?php _e('This can take a few seconds', 'regenerate-thumbnails-advanced') ?></p>
71
  </div>
72
  </div>
73