Media Cleaner - Version 4.0.6

Version Description

  • Update: Bulk analyze/prepare galleries, avoid the first request to time out.
  • Add: Many option to make the processing faster or slower depending on the server.
  • Fix: Handle server timeout.
  • Add: Pause button and Retry button.
Download this release

Release Info

Developer TigrouMeow
Plugin Icon 128x128 Media Cleaner
Version 4.0.6
Comparing to
See all releases

Code changes from version 4.0.4 to 4.0.6

Files changed (6) hide show
  1. core.php +55 -50
  2. media-cleaner.js +159 -60
  3. media-cleaner.php +4 -4
  4. readme.txt +7 -1
  5. wpmc_admin.php +76 -2
  6. wpmc_checkers.php +9 -7
core.php CHANGED
@@ -18,6 +18,7 @@ class Meow_WPMC_Core {
18
  add_action( 'wp_ajax_wpmc_get_all_issues', array( $this, 'wp_ajax_wpmc_get_all_issues' ) );
19
  add_action( 'wp_ajax_wpmc_get_all_deleted', array( $this, 'wp_ajax_wpmc_get_all_deleted' ) );
20
  add_action( 'wp_ajax_wpmc_scan_do', array( $this, 'wp_ajax_wpmc_scan_do' ) );
 
21
  add_action( 'wp_ajax_wpmc_delete_do', array( $this, 'wp_ajax_wpmc_delete_do' ) );
22
  add_action( 'wp_ajax_wpmc_ignore_do', array( $this, 'wp_ajax_wpmc_ignore_do' ) );
23
  add_action( 'wp_ajax_wpmc_recover_do', array( $this, 'wp_ajax_wpmc_recover_do' ) );
@@ -125,6 +126,9 @@ class Meow_WPMC_Core {
125
  }
126
 
127
  function wp_ajax_wpmc_scan_do () {
 
 
 
128
  ob_start();
129
  $type = $_POST['type'];
130
  $data = $_POST['data'];
@@ -187,51 +191,47 @@ class Meow_WPMC_Core {
187
  die;
188
  }
189
 
190
- function wpmc_get_galleries_images( $force = false ) {
191
- if ( $force ) {
192
- delete_transient( "wpmc_galleries_images" );
193
- $galleries_images = null;
194
- }
195
- else {
196
- $galleries_images = get_transient("wpmc_galleries_images");
 
 
 
 
 
197
  }
198
- if ( !$galleries_images ) {
199
- global $wpdb;
200
  $galleries_images = array();
201
- $posts = $wpdb->get_col( "SELECT id FROM $wpdb->posts WHERE post_type != 'attachment' AND post_status != 'inherit'" );
202
- foreach( $posts as $post ) {
203
- $galleries = get_post_galleries_images( $post );
204
- foreach( $galleries as $gallery ) {
205
- foreach( $gallery as $image ) {
206
- array_push( $galleries_images, $image );
207
- }
208
- }
209
- }
210
-
211
- $post_galleries = get_posts( array(
212
- 'tax_query' => array(
213
- array(
214
- 'taxonomy' => 'post_format',
215
- 'field' => 'slug',
216
- 'terms' => array( 'post-format-gallery' ),
217
- 'operator' => 'IN'
218
- )
219
- )
220
- ) );
221
-
222
- foreach( (array) $post_galleries as $gallery_post ) {
223
- $arrImages = get_children( 'post_type=attachment&post_mime_type=image&post_parent=' . $gallery_post->ID );
224
- if ( $arrImages ) {
225
- foreach( (array) $arrImages as $image_post ) {
226
- array_push( $galleries_images, $image_post->guid );
227
- }
228
  }
229
  }
230
- wp_reset_postdata();
231
-
232
- set_transient( "wpmc_galleries_images", $galleries_images, 60 * 60 * 2 );
233
  }
234
- return $galleries_images;
 
 
 
 
 
 
 
 
 
235
  }
236
 
237
  function wp_ajax_wpmc_scan() {
@@ -242,14 +242,7 @@ class Meow_WPMC_Core {
242
  $method = 'media';
243
  $path = isset( $_POST['path'] ) ? $_POST['path'] : null;
244
  $limit = isset( $_POST['limit'] ) ? $_POST['limit'] : 0;
245
- $limitsize = 100;
246
-
247
- if ( ( $method == 'media' && empty( $limit ) ) || ( $method == 'files' && empty( $path ) ) ) {
248
- // Reset and prepare all the Attachment IDs of all the galleries
249
- $this->wpmc_reset_issues();
250
- delete_transient( 'wpmc_posts_with_shortcode' );
251
- $this->wpmc_get_galleries_images( true );
252
- }
253
 
254
  if ( $method == 'files' ) {
255
  $output = apply_filters( 'wpmc_list_uploaded_files', array(
@@ -684,6 +677,8 @@ class Meow_WPMC_Core {
684
  else {
685
  $wpdb->query( "DELETE FROM $table_name WHERE ignored = 0 AND deleted = 0" );
686
  }
 
 
687
  }
688
 
689
  /**
@@ -694,7 +689,12 @@ class Meow_WPMC_Core {
694
 
695
  function admin_inline_js() {
696
  echo "<script type='text/javascript'>\n";
697
- echo 'var wpmc_cfg = { isPro: ' . ( $this->admin->is_registered() ? '1' : '0') . ', scanFiles: ' . ( ( get_option( 'wpmc_method', 'media' ) == 'files' && $this->admin->is_registered() ) ? '1' : '0' ) . ', scanMedia: ' . ( get_option( 'wpmc_method', 'media' ) == 'media' ? '1' : '0' ) . ' };';
 
 
 
 
 
698
  echo "\n</script>";
699
  }
700
 
@@ -810,7 +810,12 @@ class Meow_WPMC_Core {
810
 
811
  <!-- SCAN -->
812
  <?php if ( $view != 'deleted' ) { ?>
813
- <a id='wpmc_scan' onclick='wpmc_scan()' class='button-primary' style='float: left;'><span style="top: 3px; position: relative; left: -5px;" class="dashicons dashicons-search"></span><?php _e("Scan", 'media-cleaner'); ?></a>
 
 
 
 
 
814
  <?php } ?>
815
 
816
  <!-- DELETE SELECTED -->
18
  add_action( 'wp_ajax_wpmc_get_all_issues', array( $this, 'wp_ajax_wpmc_get_all_issues' ) );
19
  add_action( 'wp_ajax_wpmc_get_all_deleted', array( $this, 'wp_ajax_wpmc_get_all_deleted' ) );
20
  add_action( 'wp_ajax_wpmc_scan_do', array( $this, 'wp_ajax_wpmc_scan_do' ) );
21
+ add_action( 'wp_ajax_wpmc_prepare_do', array( $this, 'wp_ajax_wpmc_prepare_do' ) );
22
  add_action( 'wp_ajax_wpmc_delete_do', array( $this, 'wp_ajax_wpmc_delete_do' ) );
23
  add_action( 'wp_ajax_wpmc_ignore_do', array( $this, 'wp_ajax_wpmc_ignore_do' ) );
24
  add_action( 'wp_ajax_wpmc_recover_do', array( $this, 'wp_ajax_wpmc_recover_do' ) );
126
  }
127
 
128
  function wp_ajax_wpmc_scan_do () {
129
+ // For debug, to pretend there is a timeout
130
+ // header("HTTP/1.0 408 Request Timeout");
131
+ // exit;
132
  ob_start();
133
  $type = $_POST['type'];
134
  $data = $_POST['data'];
191
  die;
192
  }
193
 
194
+ function wp_ajax_wpmc_prepare_do() {
195
+ $limit = isset( $_POST['limit'] ) ? $_POST['limit'] : 0;
196
+ $limitsize = get_option( 'wpmc_posts_buffer', 10 );
197
+ if ( empty( $limit ) )
198
+ $this->wpmc_reset_issues();
199
+ if ( !get_option( 'wpmc_galleries', false ) ) {
200
+ echo json_encode( array(
201
+ 'results' => array(),
202
+ 'success' => true,
203
+ 'message' => __( "Galleries check is off. Prepare finished.", 'media-cleaner' )
204
+ ) );
205
+ die();
206
  }
207
+ $galleries_images = get_transient( "wpmc_galleries_images" );
208
+ if ( empty( $galleries_images ) )
209
  $galleries_images = array();
210
+ global $wpdb;
211
+ $posts = $wpdb->get_col( $wpdb->prepare( "SELECT p.ID FROM $wpdb->posts p
212
+ WHERE p.post_status != 'inherit'
213
+ AND p.post_type != 'attachment'
214
+ LIMIT %d, %d", $limit, $limitsize
215
+ )
216
+ );
217
+ foreach ( $posts as $post ) {
218
+ $galleries = get_post_galleries_images( $post );
219
+ foreach ( $galleries as $gallery ) {
220
+ foreach ( $gallery as $image ) {
221
+ array_push( $galleries_images, $image );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
222
  }
223
  }
 
 
 
224
  }
225
+ set_transient( "wpmc_galleries_images", $galleries_images, 60 * 60 * 2 );
226
+ $finished = count( $posts ) < $limitsize;
227
+ echo json_encode(
228
+ array(
229
+ 'success' => true,
230
+ 'finished' => $finished,
231
+ 'limit' => $limit + $limitsize,
232
+ 'message' => __( "Galleries prepared.", 'media-cleaner' ) )
233
+ );
234
+ die();
235
  }
236
 
237
  function wp_ajax_wpmc_scan() {
242
  $method = 'media';
243
  $path = isset( $_POST['path'] ) ? $_POST['path'] : null;
244
  $limit = isset( $_POST['limit'] ) ? $_POST['limit'] : 0;
245
+ $limitsize = get_option( 'wpmc_medias_buffer', 500 );
 
 
 
 
 
 
 
246
 
247
  if ( $method == 'files' ) {
248
  $output = apply_filters( 'wpmc_list_uploaded_files', array(
677
  else {
678
  $wpdb->query( "DELETE FROM $table_name WHERE ignored = 0 AND deleted = 0" );
679
  }
680
+ delete_transient( "wpmc_galleries_images" );
681
+ delete_transient( 'wpmc_posts_with_shortcode' );
682
  }
683
 
684
  /**
689
 
690
  function admin_inline_js() {
691
  echo "<script type='text/javascript'>\n";
692
+ echo 'var wpmc_cfg = {
693
+ delay: ' . get_option( 'wpmc_delay', 100 ) . ',
694
+ analysisBuffer: ' . get_option( 'wpmc_analysis_buffer', 5 ) . ',
695
+ isPro: ' . ( $this->admin->is_registered() ? '1' : '0') . ',
696
+ scanFiles: ' . ( ( get_option( 'wpmc_method', 'media' ) == 'files' && $this->admin->is_registered() ) ? '1' : '0' ) . ',
697
+ scanMedia: ' . ( get_option( 'wpmc_method', 'media' ) == 'media' ? '1' : '0' ) . ' };';
698
  echo "\n</script>";
699
  }
700
 
810
 
811
  <!-- SCAN -->
812
  <?php if ( $view != 'deleted' ) { ?>
813
+ <a id='wpmc_scan' onclick='wpmc_scan()' class='button-primary' style='float: left;'><span style="top: 3px; position: relative; left: -5px;" class="dashicons dashicons-search"></span><?php _e("Start Scan", 'media-cleaner'); ?></a>
814
+ <?php } ?>
815
+
816
+ <!-- PAUSE -->
817
+ <?php if ( $view != 'deleted' ) { ?>
818
+ <a id='wpmc_pause' onclick='wpmc_pause()' class='button' style='float: left; margin-left: 5px; display: none;'><span style="top: 3px; position: relative; left: -5px;" class="dashicons dashicons-controls-pause"></span><?php _e("Pause", 'media-cleaner'); ?></a>
819
  <?php } ?>
820
 
821
  <!-- DELETE SELECTED -->
media-cleaner.js CHANGED
@@ -48,6 +48,7 @@ function wpmc_recover_do(items, totalcount) {
48
  data = { action: 'wpmc_recover_do', data: newItems };
49
  }
50
  else {
 
51
  jQuery('#wpmc_progression').html("Done. Please <a href='?page=media-cleaner'>refresh</a> this page.");
52
  return;
53
  }
@@ -155,7 +156,9 @@ var wpmc = {
155
  files: [],
156
  medias: [],
157
  total: 0,
158
- issues: 0
 
 
159
  };
160
 
161
  // WPMC GET INITIAL INFO
@@ -168,6 +171,26 @@ function wpmc_scan_type_next(type, path) {
168
 
169
  }
170
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
171
  function wpmc_scan_type(type, path = null, limit = 0) {
172
  var data = { action: 'wpmc_scan', medias: type === 'medias', files: type === 'files', path: path, limit: limit };
173
  if (path) {
@@ -175,71 +198,125 @@ function wpmc_scan_type(type, path = null, limit = 0) {
175
  jQuery('#wpmc_progression').html('<span class="dashicons dashicons-portfolio"></span> Preparing files (' + elpath + ')...');
176
  }
177
  else if (type === 'medias')
178
- jQuery('#wpmc_progression').html('<span class="dashicons dashicons-admin-media"></span> Preparing medias (' + limit + ' media)....');
179
  else
180
  jQuery('#wpmc_progression').html('<span class="dashicons dashicons-portfolio"></span> Preparing files...');
181
 
 
 
 
 
 
 
 
 
182
 
183
- jQuery.post(ajaxurl, data, function (response) {
184
- reply = jQuery.parseJSON(response);
185
- if ( !reply.success ) {
186
- alert( reply.message );
187
- return;
188
- }
 
 
 
 
 
 
 
 
 
 
189
 
190
- // Store results
191
- for (var i = 0, len = reply.results.length; i < len; i++) {
192
- var r = reply.results[i];
193
- if (type === 'files') {
194
- if ( r.type === 'dir' )
195
- wpmc.dirs.push( r.path );
196
- else if ( r.type === 'file' ) {
197
- wpmc.files.push( r.path );
198
- wpmc.total++;
199
  }
200
- }
201
- else if (type === 'medias') {
202
- wpmc.medias.push( r );
203
- wpmc.total++;
204
- }
205
- }
 
 
 
 
 
206
 
207
- // Next query
208
- if (type === 'medias') {
209
- if (wpmc_cfg.scanFiles || !reply.finished)
210
- return wpmc_scan_type('medias', null, reply.limit);
211
- else
212
- return wpmc_scan_do();
213
- }
214
- else if (type === 'files') {
215
- var dir = wpmc.dirs.pop();
216
- if (dir)
217
- return wpmc_scan_type('files', dir);
218
- else
219
- return wpmc_scan_do();
220
- }
221
- });
222
  }
223
 
224
  function wpmc_scan() {
225
- wpmc = { dirs: [], files: [], medias: [], total: 0, issues: 0 };
 
 
 
 
 
 
 
 
 
226
  if (wpmc_cfg.scanMedia)
227
  wpmc_scan_type('medias', null);
228
  else if (wpmc_cfg.scanFiles)
229
  wpmc_scan_type('files', null);
230
  }
231
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
232
  function wpmc_scan_do() {
 
 
 
 
 
 
233
  wpmc_update_progress(wpmc.total - (wpmc.files.length + wpmc.medias.length), wpmc.total);
234
  var data = {};
235
  var expectedSuccess = 0;
236
  if (wpmc.files.length > 0) {
237
- newFiles = wpmc_pop_array(wpmc.files, 5);
238
  expectedSuccess = newFiles.length;
239
  data = { action: 'wpmc_scan_do', type: 'file', data: newFiles };
240
  }
241
  else if (wpmc.medias.length > 0) {
242
- newMedias = wpmc_pop_array(wpmc.medias, 5);
243
  expectedSuccess = newMedias.length;
244
  data = { action: 'wpmc_scan_do', type: 'media', data: newMedias };
245
  }
@@ -247,25 +324,47 @@ function wpmc_scan_do() {
247
  jQuery('#wpmc_progression').html(wpmc.issues + " issue(s) found. <a href='?page=media-cleaner'></span>Refresh</a>.");
248
  return;
249
  }
250
- jQuery.post(ajaxurl, data, function (response) {
251
- try {
252
- reply = jQuery.parseJSON(response);
253
- }
254
- catch (e) {
255
- reply = null;
256
- }
257
- if (!reply) {
258
- reply = { success: false, message: "The reply from the server is broken. The reply will be displayed in your Javascript console. You should also check your PHP Error Logs." };
259
- console.debug( "Media File Cleaner got this reply from the server: " + response);
260
- }
261
- if ( !reply.success ) {
262
- alert( reply.message );
263
- }
264
- if (reply.result) {
265
- wpmc.issues += expectedSuccess - reply.result.success;
266
- }
267
- wpmc_scan_do();
268
- });
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
269
  }
270
 
271
  /**
48
  data = { action: 'wpmc_recover_do', data: newItems };
49
  }
50
  else {
51
+ jQuery('#wpmc_pause').hide();
52
  jQuery('#wpmc_progression').html("Done. Please <a href='?page=media-cleaner'>refresh</a> this page.");
53
  return;
54
  }
156
  files: [],
157
  medias: [],
158
  total: 0,
159
+ issues: 0,
160
+ isPause: false,
161
+ isPendingPause: false
162
  };
163
 
164
  // WPMC GET INITIAL INFO
171
 
172
  }
173
 
174
+ function wpmc_prepare(limit = 0) {
175
+ var data = { action: 'wpmc_prepare_do', limit: limit };
176
+ setTimeout(
177
+ function() {
178
+ jQuery('#wpmc_progression').html('<span class="dashicons dashicons-portfolio"></span> Preparing posts (' + limit + ' posts)...');
179
+ jQuery.post(ajaxurl, data, function (response) {
180
+ reply = jQuery.parseJSON(response);
181
+ if ( !reply.success ) {
182
+ alert( reply.message );
183
+ return;
184
+ }
185
+ if (!reply.finished)
186
+ return wpmc_prepare(reply.limit);
187
+ else
188
+ return wpmc_scan_start();
189
+ });
190
+ }, wpmc_cfg.delay
191
+ );
192
+ }
193
+
194
  function wpmc_scan_type(type, path = null, limit = 0) {
195
  var data = { action: 'wpmc_scan', medias: type === 'medias', files: type === 'files', path: path, limit: limit };
196
  if (path) {
198
  jQuery('#wpmc_progression').html('<span class="dashicons dashicons-portfolio"></span> Preparing files (' + elpath + ')...');
199
  }
200
  else if (type === 'medias')
201
+ jQuery('#wpmc_progression').html('<span class="dashicons dashicons-admin-media"></span> Preparing medias (' + limit + ' medias)...');
202
  else
203
  jQuery('#wpmc_progression').html('<span class="dashicons dashicons-portfolio"></span> Preparing files...');
204
 
205
+ setTimeout(
206
+ function() {
207
+ jQuery.post(ajaxurl, data, function (response) {
208
+ reply = jQuery.parseJSON(response);
209
+ if ( !reply.success ) {
210
+ alert( reply.message );
211
+ return;
212
+ }
213
 
214
+ // Store results
215
+ for (var i = 0, len = reply.results.length; i < len; i++) {
216
+ var r = reply.results[i];
217
+ if (type === 'files') {
218
+ if ( r.type === 'dir' )
219
+ wpmc.dirs.push( r.path );
220
+ else if ( r.type === 'file' ) {
221
+ wpmc.files.push( r.path );
222
+ wpmc.total++;
223
+ }
224
+ }
225
+ else if (type === 'medias') {
226
+ wpmc.medias.push( r );
227
+ wpmc.total++;
228
+ }
229
+ }
230
 
231
+ // Next query
232
+ if (type === 'medias') {
233
+ if (wpmc_cfg.scanFiles || !reply.finished)
234
+ return wpmc_scan_type('medias', null, reply.limit);
235
+ else
236
+ return wpmc_scan_do();
 
 
 
237
  }
238
+ else if (type === 'files') {
239
+ var dir = wpmc.dirs.pop();
240
+ if (dir)
241
+ return wpmc_scan_type('files', dir);
242
+ else
243
+ return wpmc_scan_do();
244
+ }
245
+ });
246
+ }, wpmc_cfg.delay
247
+ );
248
+ }
249
 
250
+ function wpmc_pause() {
251
+ if (wpmc.isPause) {
252
+ jQuery('#wpmc_pause').html('<span style="top: 3px; position: relative; left: -5px;" class="dashicons dashicons-controls-pause"></span>Pause');
253
+ wpmc.isPause = false;
254
+ wpmc_scan_do();
255
+ }
256
+ else if (wpmc.isPendingPause) {
257
+ wpmc.isPendingPause = false;
258
+ }
259
+ else {
260
+ jQuery('#wpmc_pause').html('<span style="top: 3px; position: relative; left: -5px;" class="dashicons dashicons-controls-pause"></span>Pausing...');
261
+ wpmc.isPendingPause = true;
262
+ }
 
 
263
  }
264
 
265
  function wpmc_scan() {
266
+ if (!wpmc.isPause)
267
+ wpmc_prepare();
268
+ else
269
+ wpmc_scan_start();
270
+ }
271
+
272
+ function wpmc_scan_start() {
273
+ wpmc = { dirs: [], files: [], medias: [], total: 0, issues: 0, isPause: false, isPendingPause: false };
274
+ jQuery('#wpmc_pause').hide();
275
+ jQuery('#wpmc_pause').html('<span style="top: 3px; position: relative; left: -5px;" class="dashicons dashicons-controls-pause"></span>Pause');
276
  if (wpmc_cfg.scanMedia)
277
  wpmc_scan_type('medias', null);
278
  else if (wpmc_cfg.scanFiles)
279
  wpmc_scan_type('files', null);
280
  }
281
 
282
+ function wpmc_update_to_pause() {
283
+ if (wpmc.isPendingPause) {
284
+ var current = wpmc.total - (wpmc.files.length + wpmc.medias.length);
285
+ var totalcount = wpmc.total;
286
+ jQuery('#wpmc_progression').html('<span class="dashicons dashicons-controls-pause"></span> Paused at ' + current + "/" + totalcount + " (" + Math.round(current / totalcount * 100) + "%)");
287
+ jQuery('#wpmc_pause').html('<span style="top: 3px; position: relative; left: -5px;" class="dashicons dashicons-controls-play"></span>Continue');
288
+ wpmc.isPendingPause = false;
289
+ wpmc.isPause = true;
290
+ return;
291
+ }
292
+ }
293
+
294
+ function wpmc_update_to_error(error) {
295
+ var current = wpmc.total - (wpmc.files.length + wpmc.medias.length);
296
+ var totalcount = wpmc.total;
297
+ jQuery('#wpmc_progression').html('<span class="dashicons dashicons-controls-pause"></span> Error at ' + current + "/" + totalcount + " (" + Math.round(current / totalcount * 100) + "%): " + error);
298
+ jQuery('#wpmc_pause').html('<span style="top: 3px; position: relative; left: -5px;" class="dashicons dashicons-controls-play"></span>Retry');
299
+ wpmc.isPendingPause = false;
300
+ wpmc.isPause = true;
301
+ }
302
+
303
  function wpmc_scan_do() {
304
+ if (wpmc.isPendingPause)
305
+ return wpmc_update_to_pause();
306
+ else
307
+ jQuery('#wpmc_pause').show();
308
+ var newFiles = null;
309
+ var newMedias = null;
310
  wpmc_update_progress(wpmc.total - (wpmc.files.length + wpmc.medias.length), wpmc.total);
311
  var data = {};
312
  var expectedSuccess = 0;
313
  if (wpmc.files.length > 0) {
314
+ newFiles = wpmc_pop_array(wpmc.files, wpmc_cfg.analysisBuffer);
315
  expectedSuccess = newFiles.length;
316
  data = { action: 'wpmc_scan_do', type: 'file', data: newFiles };
317
  }
318
  else if (wpmc.medias.length > 0) {
319
+ newMedias = wpmc_pop_array(wpmc.medias, wpmc_cfg.analysisBuffer);
320
  expectedSuccess = newMedias.length;
321
  data = { action: 'wpmc_scan_do', type: 'media', data: newMedias };
322
  }
324
  jQuery('#wpmc_progression').html(wpmc.issues + " issue(s) found. <a href='?page=media-cleaner'></span>Refresh</a>.");
325
  return;
326
  }
327
+
328
+ setTimeout(
329
+ function () {
330
+ jQuery.ajax({
331
+ type: "POST",
332
+ url: ajaxurl,
333
+ data: data,
334
+ success: function (response) {
335
+ try {
336
+ reply = jQuery.parseJSON(response);
337
+ }
338
+ catch (e) {
339
+ reply = null;
340
+ }
341
+ if (!reply) {
342
+ reply = { success: false, message: "The reply from the server is broken. The reply will be displayed in your Javascript console. You should also check your PHP Error Logs." };
343
+ console.debug( "Media File Cleaner got this reply from the server: " + response);
344
+ }
345
+ if ( !reply.success ) {
346
+ alert( reply.message );
347
+ }
348
+ if (reply.result) {
349
+ wpmc.issues += expectedSuccess - reply.result.success;
350
+ }
351
+ wpmc_scan_do();
352
+ },
353
+ error: function(request, status, err) {
354
+ if (newFiles) {
355
+ while (newFiles.length > 0)
356
+ wpmc.files.push(newFiles.pop());
357
+ }
358
+ if (newMedias) {
359
+ while (newMedias.length > 0)
360
+ wpmc.medias.push(newMedias.pop());
361
+ }
362
+ wpmc_update_to_error(err);
363
+ console.debug("Media Cleaner got an error from server.", status, err);
364
+ }
365
+ });
366
+ }, wpmc_cfg.delay
367
+ );
368
  }
369
 
370
  /**
media-cleaner.php CHANGED
@@ -3,7 +3,7 @@
3
  Plugin Name: Media Cleaner
4
  Plugin URI: http://meowapps.com
5
  Description: Clean your Media Library, many options, trash system.
6
- Version: 4.0.4
7
  Author: Jordy Meow
8
  Author URI: http://meowapps.com
9
  Text Domain: media-cleaner
@@ -12,14 +12,14 @@ Big thanks to Matt (http://www.twistedtek.net/) for all his
12
  contributions made to the plugin.
13
 
14
  Originally developed for two of my websites:
15
- - Jordy Meow (http://jordymeow.com)
16
- - Haikyo (http://www.haikyo.org)
17
  */
18
 
19
  if ( is_admin() ) {
20
 
21
  global $wpmc_version;
22
- $wpmc_version = '4.0.4';
23
 
24
  // Admin
25
  require( 'wpmc_admin.php' );
3
  Plugin Name: Media Cleaner
4
  Plugin URI: http://meowapps.com
5
  Description: Clean your Media Library, many options, trash system.
6
+ Version: 4.0.6
7
  Author: Jordy Meow
8
  Author URI: http://meowapps.com
9
  Text Domain: media-cleaner
12
  contributions made to the plugin.
13
 
14
  Originally developed for two of my websites:
15
+ - Jordy Meow (http://offbeatjapan.org)
16
+ - Haikyo (http://haikyo.org)
17
  */
18
 
19
  if ( is_admin() ) {
20
 
21
  global $wpmc_version;
22
+ $wpmc_version = '4.0.6';
23
 
24
  // Admin
25
  require( 'wpmc_admin.php' );
readme.txt CHANGED
@@ -3,7 +3,7 @@ Contributors: TigrouMeow
3
  Tags: management, admin, file, files, images, image, media, library, upload, clean, cleaning
4
  Requires at least: 4.2
5
  Tested up to: 4.8
6
- Stable tag: 4.0.4
7
 
8
  Clean your Media Library and Uploads directory. It has an internal trash and recovery features.
9
 
@@ -50,6 +50,12 @@ It re-creates the Media Cleaner table in the database. You will need to re-run t
50
 
51
  == Changelog ==
52
 
 
 
 
 
 
 
53
  = 4.0.4 =
54
  * Update: Safest default values.
55
 
3
  Tags: management, admin, file, files, images, image, media, library, upload, clean, cleaning
4
  Requires at least: 4.2
5
  Tested up to: 4.8
6
+ Stable tag: 4.0.6
7
 
8
  Clean your Media Library and Uploads directory. It has an internal trash and recovery features.
9
 
50
 
51
  == Changelog ==
52
 
53
+ = 4.0.6 =
54
+ * Update: Bulk analyze/prepare galleries, avoid the first request to time out.
55
+ * Add: Many option to make the processing faster or slower depending on the server.
56
+ * Fix: Handle server timeout.
57
+ * Add: Pause button and Retry button.
58
+
59
  = 4.0.4 =
60
  * Update: Safest default values.
61
 
wpmc_admin.php CHANGED
@@ -11,6 +11,21 @@ class Meow_WPMC_Admin extends MeowApps_Admin {
11
  }
12
 
13
  function admin_notices() {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
14
  if ( !$this->is_registered() && get_option( 'wpmc_method', 'media' ) == 'files' ) {
15
  _e( "<div class='error'><p>The Pro version is required to scan files. You can <a target='_blank' href='http://meowapps.com/media-cleaner'>get a serial for the Pro version here</a>.</p></div>", 'media-cleaner' );
16
  }
@@ -58,7 +73,7 @@ class Meow_WPMC_Admin extends MeowApps_Admin {
58
  array( $this, 'admin_utf8_callback' ),
59
  'wpmc_settings-menu', 'wpmc_settings' );
60
 
61
- // SUBMENU > Settings > Settings
62
  add_settings_section( 'wpmc_ui_settings', null, null, 'wpmc_ui_settings-menu' );
63
  add_settings_field( 'wpmc_hide_thumbnails', "Thumbnails",
64
  array( $this, 'admin_hide_thumbnails_callback' ),
@@ -67,6 +82,21 @@ class Meow_WPMC_Admin extends MeowApps_Admin {
67
  array( $this, 'admin_hide_warning_callback' ),
68
  'wpmc_ui_settings-menu', 'wpmc_ui_settings' );
69
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
70
  // SETTINGS
71
  register_setting( 'wpmc_settings', 'wpmc_method' );
72
  register_setting( 'wpmc_settings', 'wpmc_posts' );
@@ -79,8 +109,41 @@ class Meow_WPMC_Admin extends MeowApps_Admin {
79
 
80
  register_setting( 'wpmc_ui_settings', 'wpmc_hide_thumbnails' );
81
  register_setting( 'wpmc_ui_settings', 'wpmc_hide_warning' );
 
 
 
 
 
82
  }
83
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
84
  function admin_settings() {
85
  ?>
86
  <div class="wrap">
@@ -119,7 +182,7 @@ class Meow_WPMC_Admin extends MeowApps_Admin {
119
  <?php $this->display_serialkey_box( "https://meowapps.com/media-cleaner/" ); ?>
120
 
121
  <div class="meow-box">
122
- <h3>Scanning</h3>
123
  <div class="inside">
124
  <form method="post" action="options.php">
125
  <?php settings_fields( 'wpmc_ui_settings' ); ?>
@@ -129,6 +192,17 @@ class Meow_WPMC_Admin extends MeowApps_Admin {
129
  </div>
130
  </div>
131
 
 
 
 
 
 
 
 
 
 
 
 
132
  <?php if ( get_option( 'wpmc_shortcode', false ) ): ?>
133
  <div class="meow-box">
134
  <h3>Shortcodes</h3>
11
  }
12
 
13
  function admin_notices() {
14
+
15
+ $mediasBuffer = get_option( 'wpmc_medias_buffer', 500 );
16
+ $postsBuffer = get_option( 'wpmc_posts_buffer', 10 );
17
+ $analysisBuffer = get_option( 'wpmc_analysis_buffer', 5 );
18
+ $delay = get_option( 'wpmc_delay', 100 );
19
+
20
+ if ( !is_numeric( $mediasBuffer ) || $mediasBuffer < 1 )
21
+ update_option( 'wpmc_medias_buffer', 500 );
22
+ if ( !is_numeric( $postsBuffer ) || $postsBuffer < 1 )
23
+ update_option( 'wpmc_posts_buffer', 10 );
24
+ if ( !is_numeric( $analysisBuffer ) || $analysisBuffer < 1 )
25
+ update_option( 'wpmc_analysis_buffer', 5 );
26
+ if ( !is_numeric( $delay ) )
27
+ update_option( 'wpmc_delay', 100 );
28
+
29
  if ( !$this->is_registered() && get_option( 'wpmc_method', 'media' ) == 'files' ) {
30
  _e( "<div class='error'><p>The Pro version is required to scan files. You can <a target='_blank' href='http://meowapps.com/media-cleaner'>get a serial for the Pro version here</a>.</p></div>", 'media-cleaner' );
31
  }
73
  array( $this, 'admin_utf8_callback' ),
74
  'wpmc_settings-menu', 'wpmc_settings' );
75
 
76
+ // SUBMENU > Settings > UI
77
  add_settings_section( 'wpmc_ui_settings', null, null, 'wpmc_ui_settings-menu' );
78
  add_settings_field( 'wpmc_hide_thumbnails', "Thumbnails",
79
  array( $this, 'admin_hide_thumbnails_callback' ),
82
  array( $this, 'admin_hide_warning_callback' ),
83
  'wpmc_ui_settings-menu', 'wpmc_ui_settings' );
84
 
85
+ // SUBMENU > Settings > Advanced
86
+ add_settings_section( 'wpmc_advanced_settings', null, null, 'wpmc_advanced_settings-menu' );
87
+ add_settings_field( 'wpmc_medias_buffer', "Medias Buffer",
88
+ array( $this, 'admin_medias_buffer_callback' ),
89
+ 'wpmc_advanced_settings-menu', 'wpmc_advanced_settings' );
90
+ add_settings_field( 'wpmc_posts_buffer', "Posts Buffer",
91
+ array( $this, 'admin_posts_buffer_callback' ),
92
+ 'wpmc_advanced_settings-menu', 'wpmc_advanced_settings' );
93
+ add_settings_field( 'wpmc_analysis_buffer', "Analysis Buffer",
94
+ array( $this, 'admin_analysis_buffer_callback' ),
95
+ 'wpmc_advanced_settings-menu', 'wpmc_advanced_settings' );
96
+ add_settings_field( 'wpmc_delay', "Delay (in ms)",
97
+ array( $this, 'admin_delay_callback' ),
98
+ 'wpmc_advanced_settings-menu', 'wpmc_advanced_settings' );
99
+
100
  // SETTINGS
101
  register_setting( 'wpmc_settings', 'wpmc_method' );
102
  register_setting( 'wpmc_settings', 'wpmc_posts' );
109
 
110
  register_setting( 'wpmc_ui_settings', 'wpmc_hide_thumbnails' );
111
  register_setting( 'wpmc_ui_settings', 'wpmc_hide_warning' );
112
+
113
+ register_setting( 'wpmc_advanced_settings', 'wpmc_medias_buffer' );
114
+ register_setting( 'wpmc_advanced_settings', 'wpmc_posts_buffer' );
115
+ register_setting( 'wpmc_advanced_settings', 'wpmc_analysis_buffer' );
116
+ register_setting( 'wpmc_advanced_settings', 'wpmc_delay' );
117
  }
118
 
119
+ function admin_medias_buffer_callback( $args ) {
120
+ $value = get_option( 'wpmc_medias_buffer', 500 );
121
+ $html = '<input type="number" style="width: 100%;" id="wpmc_medias_buffer" name="wpmc_medias_buffer" value="' . $value . '" />';
122
+ $html .= '<br /><span class="description">The number of medias to read in one time during the preparation phase. This is fast, so the value should be between 50 and 1000.</label>';
123
+ echo $html;
124
+ }
125
+
126
+ function admin_posts_buffer_callback( $args ) {
127
+ $value = get_option( 'wpmc_posts_buffer', 10 );
128
+ $html = '<input type="number" style="width: 100%;" id="wpmc_posts_buffer" name="wpmc_posts_buffer" value="' . $value . '" />';
129
+ $html .= '<br /><span class="description">The number of posts to read in one time during the preparation phase. This takes a bit of time in case galleries are being used. Recommended value is between 5 and 20.</label>';
130
+ echo $html;
131
+ }
132
+
133
+ function admin_analysis_buffer_callback( $args ) {
134
+ $value = get_option( 'wpmc_analysis_buffer', 5 );
135
+ $html = '<input type="number" style="width: 100%;" id="wpmc_analysis_buffer" name="wpmc_analysis_buffer" value="' . $value . '" />';
136
+ $html .= '<br /><span class="description">The number of medias or files to analyse in one time. It is the main part of the process and it depends on the scanning options. Recommended value is 5 but can be more on a powerful server, or 1 if your server is not powerful or your WordPress very bloated.</label>';
137
+ echo $html;
138
+ }
139
+
140
+ function admin_delay_callback( $args ) {
141
+ $value = get_option( 'wpmc_delay', 100 );
142
+ $html = '<input type="number" style="width: 100%;" id="wpmc_delay" name="wpmc_delay" value="' . $value . '" />';
143
+ $html .= '<br /><span class="description">This is a delay Media Cleaner will wait between each request. The process is intensive so this gives the server time to relax a little (hosting services sometimes require this). Recommended value is actually 0, 100 (ms) is for safety, some servers require 2000 or 5000 (2 or 5 seconds).</label>';
144
+ echo $html;
145
+ }
146
+
147
  function admin_settings() {
148
  ?>
149
  <div class="wrap">
182
  <?php $this->display_serialkey_box( "https://meowapps.com/media-cleaner/" ); ?>
183
 
184
  <div class="meow-box">
185
+ <h3>UI</h3>
186
  <div class="inside">
187
  <form method="post" action="options.php">
188
  <?php settings_fields( 'wpmc_ui_settings' ); ?>
192
  </div>
193
  </div>
194
 
195
+ <div class="meow-box">
196
+ <h3>Advanced</h3>
197
+ <div class="inside">
198
+ <form method="post" action="options.php">
199
+ <?php settings_fields( 'wpmc_advanced_settings' ); ?>
200
+ <?php do_settings_sections( 'wpmc_advanced_settings-menu' ); ?>
201
+ <?php submit_button(); ?>
202
+ </form>
203
+ </div>
204
+ </div>
205
+
206
  <?php if ( get_option( 'wpmc_shortcode', false ) ): ?>
207
  <div class="meow-box">
208
  <h3>Shortcodes</h3>
wpmc_checkers.php CHANGED
@@ -49,13 +49,15 @@ class Meow_WPMC_Checkers {
49
  $regex = addcslashes( '(?:(?:http(?:s)?\\:)?//' .
50
  preg_quote( $parsedURL['host'] ).')?' .
51
  preg_quote( $parsedURL['path'] ) . '/' . $regex_match_file, '/');
52
- $images = $this->core->wpmc_get_galleries_images();
53
- foreach ( $images as $image ) {
54
- $found = preg_match('/'.$regex.'/i', $image);
55
- if ( $this->core->debug && $found )
56
- error_log("{$file} found in a galllery");
57
- if ( $found )
58
- return true;
 
 
59
  }
60
  return false;
61
  }
49
  $regex = addcslashes( '(?:(?:http(?:s)?\\:)?//' .
50
  preg_quote( $parsedURL['host'] ).')?' .
51
  preg_quote( $parsedURL['path'] ) . '/' . $regex_match_file, '/');
52
+ $images = get_transient( "wpmc_galleries_images" );
53
+ if ( !empty( $images ) ) {
54
+ foreach ( $images as $image ) {
55
+ $found = preg_match('/' . $regex . '/i', $image);
56
+ if ( $this->core->debug && $found )
57
+ error_log("{$file} found in a gallery");
58
+ if ( $found )
59
+ return true;
60
+ }
61
  }
62
  return false;
63
  }