Delete Duplicate Posts - Version 4.6

Version Description

  • 2020/01/12
  • Beta feature: Limit amount of duplicates to find. On big sites with many duplicates the plugin can time out. This feature allows you to limit the amount of results. This feature is only available for free while being tested. Thank you Fabio.
  • Minor text or layout fixes.
  • 286,392 downloads
Download this release

Release Info

Developer lkoudal
Plugin Icon 128x128 Delete Duplicate Posts
Version 4.6
Comparing to
See all releases

Code changes from version 4.5 to 4.6

Files changed (2) hide show
  1. delete-duplicate-posts.php +382 -269
  2. readme.txt +8 -2
delete-duplicate-posts.php CHANGED
@@ -5,7 +5,7 @@ Plugin Name: Delete Duplicate Posts
5
  Plugin Script: delete-duplicate-posts.php
6
  Plugin URI: https://cleverplugins.com
7
  Description: Remove duplicate blogposts on your blog! Searches and removes duplicate posts and their post meta tags. You can delete posts, pages and other Custom Post Types enabled on your website.
8
- Version: 4.5
9
  Author: cleverplugins.com
10
  Author URI: https://cleverplugins.com
11
  Min WP Version: 4.7
@@ -140,6 +140,12 @@ if ( !class_exists( 'Delete_Duplicate_Posts' ) ) {
140
 
141
  /**
142
  * Ajax callback to handle freemius opt in/out.
 
 
 
 
 
 
143
  */
144
  public static function cp_ddp_fs_opt_in()
145
  {
@@ -220,6 +226,15 @@ if ( !class_exists( 'Delete_Duplicate_Posts' ) ) {
220
  exit;
221
  }
222
 
 
 
 
 
 
 
 
 
 
223
  public static function ddp_action_admin_notices()
224
  {
225
  $screen = get_current_screen();
@@ -234,36 +249,36 @@ if ( !class_exists( 'Delete_Duplicate_Posts' ) ) {
234
 
235
  if ( PAnD::is_admin_notice_active( 'cp-ddp-improve-notice-14' ) ) {
236
  ?>
237
- <div id="cp-ddp-freemius" data-dismissible="cp-ddp-improve-notice-14" class="notice notice-success is-dismissible">
238
- <h3><?php
239
  esc_html_e( 'Help Delete Duplicate Posts improve!', 'delete-duplicate-posts' );
240
  ?></h3>
241
-
242
- <p><?php
243
  echo esc_html__( 'Gathering non-sensitive diagnostic data about the plugin install helps us improve the plugin.', 'delete-duplicate-posts' ) . ' <a href="' . esc_url( 'https://cleverplugins.com/docs/install/non-sensitive-diagnostic-data/' ) . '" target="_blank" rel="noopener">' . esc_html__( 'Read more about what we collect.', 'delete-duplicate-posts' ) . '</a>' ;
244
  ?></p>
245
-
246
- <p>
247
- <?php
248
  // translators:
249
  printf( esc_html__( 'If you opt-in, some data about your usage of %1$s will be sent to Freemius.com. If you skip this, that\'s okay! %1$s will still work just fine.', 'delete-duplicate-posts' ), '<b>Delete Duplicate Posts</b>' );
250
  ?>
251
- </p>
252
- <p>
253
- <a href="javascript:;" class="button button-primary" onclick="cp_ddp_freemius_opt_in(this)" data-opt="yes"><?php
254
  esc_html_e( 'Sure, opt-in', 'delete-duplicate-posts' );
255
  ?></a>
256
-
257
- <a href="javascript:;" class="button dismiss-this"><?php
258
  esc_html_e( 'No, thank you', 'delete-duplicate-posts' );
259
  ?></a>
260
- </p>
261
- <input type="hidden" id="cp-ddp-freemius-opt-nonce" value="<?php
262
  echo esc_attr( wp_create_nonce( 'cp-ddp-freemius-opt' ) ) ;
263
  ?>" />
264
-
265
- </div>
266
- <?php
267
  }
268
 
269
  }
@@ -277,31 +292,41 @@ if ( !class_exists( 'Delete_Duplicate_Posts' ) ) {
277
  if ( false !== $totaldeleted && 0 < $totaldeleted ) {
278
  $totaldeleted = number_format_i18n( $totaldeleted );
279
  ?>
280
- <div id="cp-ddp-reviewlink" data-dismissible="ddp-leavereview-14" class="updated notice notice-success is-dismissible">
281
- <h3>
282
- <?php
283
  // translators: Total number of deleted duplicates
284
  printf( esc_html__( '%s duplicates deleted!', 'delete-duplicate-posts' ), esc_html( $totaldeleted ) );
285
  ?>
286
- </h3>
287
- <p>
288
- <?php
289
  // translators: Asking for a review text
290
  printf( esc_html__( "Hey, I noticed this plugin has deleted %s duplicate posts for you - that's awesome! Could you please do me a BIG favor and give it a 5-star rating on WordPress? Just to help us spread the word and boost our motivation.", 'delete-duplicate-posts' ), esc_html( $totaldeleted ) );
291
  ?>
292
- </p>
293
-
294
- <p>
295
- <a href="https://wordpress.org/support/plugin/delete-duplicate-posts/reviews/?filter=5#new-post" class="cp-ddp-dismiss-review-notice cp-ddp-reviewlink button-primary dismiss-this" target="_blank" rel="noopener">Ok, you deserve it</a>
296
- <span class="dashicons dashicons-calendar"></span><a href="#" class="cp-ddp-dismiss-review-notice dismiss-this" target="_blank" rel="noopener">Nope, maybe later</a>
297
- <span class="dashicons dashicons-smiley"></span><a href="#" class="cp-ddp-dismiss-review-notice dismiss-this" target="_blank" rel="noopener">I already did</a>
298
- </p>
299
- </div>
300
- <?php
301
  }
302
 
303
  }
304
 
 
 
 
 
 
 
 
 
 
 
305
  public static function delete_duplicates( $return = false )
306
  {
307
  if ( defined( 'DOING_AJAX' ) && DOING_AJAX ) {
@@ -319,6 +344,16 @@ if ( !class_exists( 'Delete_Duplicate_Posts' ) ) {
319
  wp_send_json_success();
320
  }
321
 
 
 
 
 
 
 
 
 
 
 
322
  public static function return_loglines( $return = false )
323
  {
324
  if ( defined( 'DOING_AJAX' ) && DOING_AJAX ) {
@@ -356,6 +391,16 @@ if ( !class_exists( 'Delete_Duplicate_Posts' ) ) {
356
  wp_send_json_success( $json_response );
357
  }
358
 
 
 
 
 
 
 
 
 
 
 
359
  public static function return_duplicates_ajax( $return = false )
360
  {
361
  if ( defined( 'DOING_AJAX' ) && DOING_AJAX ) {
@@ -366,6 +411,13 @@ if ( !class_exists( 'Delete_Duplicate_Posts' ) ) {
366
 
367
  /**
368
  * Returns duplicates based on current settings - internal, not used via AJAX
 
 
 
 
 
 
 
369
  */
370
  public static function return_duplicates( $return = false )
371
  {
@@ -425,14 +477,23 @@ if ( !class_exists( 'Delete_Duplicate_Posts' ) ) {
425
 
426
  if ( 'titlecompare' === $comparemethod ) {
427
  // @todo - prepare - not urgent, there is no way to exploit this query
428
- $thisquery = "SELECT a.ID, a.post_title, a.post_type, a.post_status, save_this_post_id\n\t\t\t\t\tFROM {$table_name} AS a\n\t\t\t\t\tINNER JOIN (\n\t\t\t\t\tSELECT post_title, " . $minmax . " AS save_this_post_id\n\t\t\t\t\tFROM {$table_name}\n\t\t\t\t\tWHERE post_type IN(" . $ddp_pts . ')
429
- AND post_status IN(' . $post_stati . ')
430
- GROUP BY post_title
431
- HAVING COUNT( * ) > 1
432
- ) AS b ON b.post_title = a.post_title
433
- AND b.save_this_post_id <> a.id
434
- AND a.post_type IN(' . $ddp_pts . ')
435
- AND a.post_status IN(' . $post_stati . ')';
 
 
 
 
 
 
 
 
 
436
  $dupes = $wpdb->get_results( $thisquery, ARRAY_A );
437
 
438
  if ( $dupes ) {
@@ -476,7 +537,7 @@ if ( !class_exists( 'Delete_Duplicate_Posts' ) ) {
476
  if ( !$return_duplicates_time ) {
477
  $return_duplicates_time = self::timerstop( 'return_duplicates' );
478
  }
479
- $json_response['msg'] = $json_response['dupescount'] . ' duplicates found. Showing up to ' . $viewlimit . ' Time: ' . $return_duplicates_time . ' sec.';
480
  // @todo i8n
481
  if ( $return ) {
482
  // todo - limit amount of values to return
@@ -505,6 +566,7 @@ if ( !class_exists( 'Delete_Duplicate_Posts' ) ) {
505
  'ddp_pts' => array( 'post', 'page' ),
506
  'ddp_statusmail_recipient' => '',
507
  'ddp_statusmail' => 0,
 
508
  'ddp_enabled' => 0,
509
  'ddp_pstati' => array( 'publish' ),
510
  );
@@ -638,15 +700,15 @@ if ( !class_exists( 'Delete_Duplicate_Posts' ) ) {
638
 
639
  if ( $manualrun > 0 ) {
640
  ?>
641
- <div class="notice notice-success">
642
- <p>
643
- <?php
644
  // translators:
645
  printf( esc_html__( 'A total of %s duplicate posts were deleted.', 'delete-duplicate-posts' ), intval( $dispcount ) );
646
  ?>
647
- </p>
648
- </div>
649
- <?php
650
  }
651
 
652
  // manualrun
@@ -788,7 +850,7 @@ if ( !class_exists( 'Delete_Duplicate_Posts' ) ) {
788
  $table_name = $wpdb->prefix . 'ddp_log';
789
 
790
  if ( $table_name !== $wpdb->get_var( "show tables like '{$table_name}'" ) ) {
791
- $sql = "CREATE TABLE {$table_name} (\n\t\t\t\tid bigint(20) NOT NULL AUTO_INCREMENT,\n\t\t\t\tdatime timestamp NOT NULL DEFAULT '0000-00-00 00:00:00' ON UPDATE CURRENT_TIMESTAMP,\n\t\t\t\tnote tinytext NOT NULL,\n\t\t\t\tPRIMARY KEY (id)\n\t\t\t);";
792
  require_once ABSPATH . 'wp-admin/includes/upgrade.php';
793
  dbDelta( $sql );
794
  }
@@ -896,14 +958,14 @@ if ( !class_exists( 'Delete_Duplicate_Posts' ) ) {
896
  'id' => 'ddp_help',
897
  'title' => __( 'Usage and FAQ', 'delete-duplicate-posts' ),
898
  'content' => '
899
- <h4>' . __( 'What does this plugin do?', 'delete-duplicate-posts' ) . '</h4>
900
- <p>' . __( 'Helps you clean duplicate posts from your blog. The plugin checks for blogposts on your blog with the same title.', 'delete-duplicate-posts' ) . '</p>
901
- <p>' . __( "It can run automatically via WordPress's own internal CRON-system, or you can run it automatically.", 'delete-duplicate-posts' ) . '</p>
902
- <p>' . __( 'It also has a nice feature that can send you an e-mail when Delete Duplicate Posts finds and deletes something (if you have turned on the CRON feature).', 'delete-duplicate-posts' ) . '</p>
903
- <h4>' . __( 'Help! Something was deleted that was not supposed to be deleted!', 'delete-duplicate-posts' ) . '</h4>
904
- <p>' . __( 'I am sorry for that, I can only recommend you restore the database you took just before you ran this plugin.', 'delete-duplicate-posts' ) . '</p>
905
- <p>' . __( 'If you run this plugin, manually or automatically, it is at your OWN risk!', 'delete-duplicate-posts' ) . '</p>
906
- <p>' . __( 'I have done my best to avoid deleting something that should not be deleted, but if it happens, there is nothing I can do to help you.', 'delete-duplicate-posts' ) . "</p>\n\t\t\t\t\t\t<p><a href='https://cleverplugins.com' target='_blank'>cleverplugins.com</a>.</p>",
907
  ) );
908
  }
909
  }
@@ -962,6 +1024,9 @@ if ( !class_exists( 'Delete_Duplicate_Posts' ) ) {
962
  if ( isset( $_POST['ddp_method'] ) ) {
963
  $options['ddp_method'] = sanitize_text_field( $_POST['ddp_method'] );
964
  }
 
 
 
965
  $options['ddp_pts'] = $posttypes;
966
  // Previously sanitized
967
  if ( isset( $_POST['ddp_limit'] ) ) {
@@ -1003,18 +1068,18 @@ if ( !class_exists( 'Delete_Duplicate_Posts' ) ) {
1003
  $name = $pluginfo['Name'];
1004
  $options = self::get_options();
1005
  ?>
1006
-
1007
- <div class="wrap">
1008
-
1009
- <h2>Delete Duplicate Posts <span>v. <?php
1010
  echo esc_html( self::get_plugin_version() ) ;
1011
  ?></span></h2>
1012
-
1013
- <div class="ddp_content_wrapper">
1014
- <div class="ddp_content_cell">
1015
- <div id="ddp_container">
1016
- <div id="dashboard">
1017
- <?php
1018
 
1019
  if ( $options['ddp_enabled'] ) {
1020
  $nextscheduled = wp_next_scheduled( 'ddp_cron' );
@@ -1035,70 +1100,70 @@ if ( !class_exists( 'Delete_Duplicate_Posts' ) ) {
1035
 
1036
  $totaldeleted = get_option( 'ddp_deleted_duplicates' );
1037
  ?>
1038
-
1039
- <div class="statusdiv">
1040
- <div class="spinner is-active"></div>
1041
- <div class="statusmessage"></div>
1042
- <div class="dupelist">
1043
- <table class="wp-list-table widefat fixed striped posts duplicatetable" cellspacing="0">
1044
- <thead>
1045
  <tr>
1046
  <td id="cb" class="manage-column column-cb check-column"><label class="screen-reader-text" for="cb-select-all-1">Select All</label><input id="cb-select-all-1" type="checkbox"></td>
1047
- <th><?php
1048
  esc_html_e( 'Duplicate', 'delete-duplicate-posts' );
1049
  ?></th>
1050
- <th><?php
1051
  esc_html_e( 'Original', 'delete-duplicate-posts' );
1052
  ?></th>
1053
  </tr>
1054
- </thead>
1055
- <tbody id="listofduplicates">
1056
- </tbody>
1057
-
1058
- <tfoot>
1059
  <tr>
1060
  <td id="cb" class="manage-column column-cb check-column"><label class="screen-reader-text" for="cb-select-all-1">Select All</label><input id="cb-select-all-1" type="checkbox"></td>
1061
- <th><?php
1062
  esc_html_e( 'Duplicate', 'delete-duplicate-posts' );
1063
  ?></th>
1064
- <th><?php
1065
  esc_html_e( 'Original', 'delete-duplicate-posts' );
1066
  ?></th>
1067
  </tr>
1068
- </tfoot>
1069
- </table>
1070
- </div>
1071
- <form>
1072
- <?php
1073
  wp_nonce_field( 'ddp-buttons' );
1074
  ?>
1075
- <table id="ddp_buttons">
1076
- <tr>
1077
  <td><input type="submit" name="deleteduplicateposts_resetview" id="deleteduplicateposts_resetview"class="button button-small button-secondary" value="<?php
1078
  esc_html_e( 'Refresh list', 'delete-duplicate-posts' );
1079
  ?>" disabled/></td>
1080
  <td><input type="submit" name="deleteduplicateposts_deleteall" id="deleteduplicateposts_deleteall" class="button button-small button-primary" value="<?php
1081
  esc_html_e( 'Delete duplicates', 'delete-duplicate-posts' );
1082
  ?>" disabled/></td>
1083
- </tr>
1084
- </table>
1085
- </form>
1086
- </div>
1087
-
1088
- </div><!-- #dashboard -->
1089
-
1090
- <div id="configuration">
1091
- <h3><?php
1092
  esc_html_e( 'Settings', 'delete-duplicate-posts' );
1093
  ?></h3>
1094
- <p>
1095
- <?php
1096
  $nextscheduled = wp_next_scheduled( 'ddp_cron' );
1097
 
1098
  if ( $nextscheduled ) {
1099
  ?>
1100
- <div class="notice notice-info is-dismissible">
1101
- <?php
1102
  echo '<p class="cronstatus center">' . esc_html__( 'You have enabled automatic deletion, so I am running on automatic. I will take care of everything...', 'delete-duplicate-posts' ) . '</p>' ;
1103
  echo '<p class="center">' ;
1104
  echo sprintf(
@@ -1109,23 +1174,26 @@ if ( !class_exists( 'Delete_Duplicate_Posts' ) ) {
1109
  ) ;
1110
  echo '</p>' ;
1111
  ?>
1112
- </div>
1113
- <?php
1114
  }
1115
 
1116
  ?>
1117
- </p>
1118
- <form method="post" id="delete_duplicate_posts_options">
1119
- <?php
1120
  wp_nonce_field( 'ddp-update-options' );
1121
  ?>
1122
- <table width="100%" cellspacing="2" cellpadding="5" class="form-table">
1123
-
1124
- <tr valign="top">
1125
- <th><label for="ddp_enabled"><?php
 
 
 
1126
  esc_html_e( 'Which post types?:', 'delete-duplicate-posts' );
1127
  ?></label></th>
1128
- <td>
1129
  <?php
1130
  $builtin = array( 'post', 'page', 'attachment' );
1131
  $args = array(
@@ -1141,7 +1209,7 @@ if ( !class_exists( 'Delete_Duplicate_Posts' ) ) {
1141
  if ( $post_types ) {
1142
  ?>
1143
  <ul class="radio">
1144
- <?php
1145
  $step = 0;
1146
  if ( !is_array( $checked_post_types ) ) {
1147
  $checked_post_types = array();
@@ -1149,25 +1217,25 @@ if ( !class_exists( 'Delete_Duplicate_Posts' ) ) {
1149
  foreach ( $post_types as $pt ) {
1150
  $checked = array_search( $pt, $checked_post_types, true );
1151
  ?>
1152
- <li>
1153
- <input type="checkbox" name="ddp_pts[]" id="ddp_pt-<?php
1154
  echo esc_attr( $step ) ;
1155
  ?>" value="<?php
1156
  echo esc_html( $pt ) ;
1157
  ?>"
1158
- <?php
1159
  if ( false !== $checked ) {
1160
  echo ' checked' ;
1161
  }
1162
  ?>
1163
- />
1164
- <label for="ddp_pt-<?php
1165
  echo esc_attr( $step ) ;
1166
  ?>"><?php
1167
  echo esc_html( $pt ) ;
1168
  ?></label>
1169
- </li>
1170
- <?php
1171
  $step++;
1172
  }
1173
  ?>
@@ -1179,14 +1247,14 @@ if ( !class_exists( 'Delete_Duplicate_Posts' ) ) {
1179
  <p class="description"><?php
1180
  esc_html_e( 'Choose which post types to scan for duplicates.', 'delete-duplicate-posts' );
1181
  ?></p>
1182
- </td>
1183
- </tr>
1184
-
1185
- <tr>
1186
- <th><label for="ddp_enabled"><?php
1187
  esc_html_e( 'Post status', 'delete-duplicate-posts' );
1188
  ?></label></th>
1189
- <td>
1190
  <?php
1191
  $stati = array(
1192
  'publish' => (object) array(
@@ -1199,36 +1267,36 @@ if ( !class_exists( 'Delete_Duplicate_Posts' ) ) {
1199
  if ( $stati ) {
1200
  ?>
1201
  <ul class="radio">
1202
- <?php
1203
  $staticount = count( $stati );
1204
  foreach ( $stati as $key => $st ) {
1205
 
1206
  if ( $st->show_in_admin_status_list ) {
1207
  $checked = array_search( $key, $checked_post_stati, true );
1208
  ?>
1209
- <li>
1210
- <input type="checkbox" name="ddp_pstati[]" id="ddp_pstatus-<?php
1211
  echo esc_attr( $key ) ;
1212
  ?>" value="<?php
1213
  echo esc_attr( $key ) ;
1214
  ?>"
1215
- <?php
1216
  if ( false !== $checked ) {
1217
  echo ' checked' ;
1218
  }
1219
  ?>
1220
- <?php
1221
  if ( 1 === $staticount ) {
1222
  echo ' disabled' ;
1223
  }
1224
  ?> />
1225
- <label for="ddp_pstatus-<?php
1226
  echo esc_attr( $key ) ;
1227
  ?>"><?php
1228
  echo esc_html( $key . ' (' . $st->label . ')' ) ;
1229
  ?></label>
1230
- </li>
1231
- <?php
1232
  $step++;
1233
  }
1234
 
@@ -1239,88 +1307,131 @@ if ( !class_exists( 'Delete_Duplicate_Posts' ) ) {
1239
  }
1240
 
1241
  ?>
1242
- </td>
1243
-
1244
-
1245
- </tr>
1246
- <?php
1247
  $comparemethod = 'titlecompare';
1248
  global $ddp_fs ;
1249
  ?>
1250
- <tr valign="top">
1251
- <th><?php
1252
  esc_html_e( 'Comparison Method', 'delete-duplicate-posts' );
1253
  ?></th>
1254
- <td>
1255
  <ul class="ddpcomparemethod">
1256
-
1257
- <li>
1258
- <label>
1259
- <input type="radio" name="ddp_method" value="titlecompare" <?php
1260
  checked( 'titlecompare', $comparemethod );
1261
  ?> /> <?php
1262
  esc_html_e( 'Compare by title (default)', 'delete-duplicate-posts' );
1263
  ?>
1264
- <span class="optiondesc"><?php
1265
  esc_html_e( 'Looks at the title of the post itself.', 'delete-duplicate-posts' );
1266
  ?></span>
1267
- </label>
1268
-
1269
- </li>
1270
-
1271
- <?php
1272
  global $ddp_fs ;
1273
  ?>
1274
  </ul>
1275
- </td>
1276
- </tr>
1277
- <tr>
1278
- <th><label for="ddp_keep"><?php
1279
  esc_html_e( 'Delete which posts?:', 'delete-duplicate-posts' );
1280
  ?></label></th><td>
1281
-
1282
  <select name="ddp_keep" id="ddp_keep">
1283
- <option value="oldest"
1284
- <?php
1285
  if ( 'oldest' === $options['ddp_keep'] ) {
1286
  echo 'selected="selected"' ;
1287
  }
1288
  ?>
1289
- ><?php
1290
  esc_html_e( 'Keep oldest', 'delete-duplicate-posts' );
1291
  ?></option>
1292
- <option value="latest"
1293
- <?php
1294
  if ( 'latest' === $options['ddp_keep'] ) {
1295
  echo 'selected="selected"' ;
1296
  }
1297
  ?>
1298
- ><?php
1299
  esc_html_e( 'Keep latest', 'delete-duplicate-posts' );
1300
  ?></option>
1301
  </select>
1302
  <p class="description"><?php
1303
  esc_html_e( 'Keep the oldest or the latest version of duplicates? Default is keeping the oldest, and deleting any subsequent duplicate posts', 'delete-duplicate-posts' );
1304
  ?></p>
1305
- </td>
1306
- </tr>
 
1307
 
1308
 
1309
- <?php
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1310
  /*
1311
 
1312
  <tr valign="top">
1313
  <th><label for="ddp_limit"><?php esc_html_e( 'Delete at maximum :', 'delete-duplicate-posts' ); ?></label></th><td><select name="ddp_limit">
1314
- <?php
1315
- for ( $x = 1; $x <= 10; $x++ ) {
1316
- $val = ( $x * 50 );
1317
- echo "<option value='" . esc_attr( $val ) . "' ";
1318
- if ( $options['ddp_limit'] === $val ) {
1319
- echo 'selected';
1320
- }
1321
- echo '>' . esc_attr( $val ) . '</option>';
1322
  }
1323
- ?>
 
 
1324
  </select>
1325
  <?php esc_html_e( 'duplicates.', 'delete-duplicate-posts' ); ?>
1326
  <p class="description"><?php esc_html_e( 'Setting a limit is a good idea, especially if your site is on a busy server.', 'delete-duplicate-posts' ); ?></p>
@@ -1328,47 +1439,47 @@ if ( !class_exists( 'Delete_Duplicate_Posts' ) ) {
1328
  </tr>
1329
  */
1330
  ?>
1331
-
1332
- <tr>
1333
- <td colspan="2"><hr></td>
1334
- </tr>
1335
-
1336
 
1337
 
1338
- <tr valign="top">
1339
- <th><?php
 
 
 
 
1340
  esc_html_e( 'Enable automatic deletion?:', 'delete-duplicate-posts' );
1341
  ?>
1342
-
1343
- </th>
1344
- <td><label for="ddp_enabled">
1345
- <input type="checkbox" id="ddp_enabled" name="ddp_enabled"
1346
- <?php
1347
  if ( true === $options['ddp_enabled'] ) {
1348
  echo 'checked="checked"' ;
1349
  }
1350
  ?>
1351
- >
1352
- <p class="description"><?php
1353
  esc_html_e( 'Clean duplicates automatically.', 'delete-duplicate-posts' );
1354
  ?></p>
1355
- </label>
1356
- </td>
1357
- </tr>
1358
-
1359
-
1360
- <tr>
1361
- <th><label for="ddp_schedule"><?php
1362
  esc_html_e( 'How often?:', 'delete-duplicate-posts' );
1363
  ?></label></th><td>
1364
-
1365
- <select name="ddp_schedule" id="ddp_schedule">
1366
- <?php
1367
  $schedules = wp_get_schedules();
1368
  if ( $schedules ) {
1369
  foreach ( $schedules as $key => $sch ) {
1370
  ?>
1371
- <option value="<?php
1372
  echo esc_attr( $key ) ;
1373
  ?>"
1374
  <?php
@@ -1383,25 +1494,25 @@ if ( !class_exists( 'Delete_Duplicate_Posts' ) ) {
1383
  }
1384
  }
1385
  ?>
1386
- </select>
1387
- <p class="description"><?php
1388
  esc_html_e( 'How often should the cron job run?', 'delete-duplicate-posts' );
1389
  ?></p>
1390
- </td>
1391
- </tr>
1392
-
1393
-
1394
-
1395
- <tr>
1396
- <td colspan="2"><hr></td>
1397
- </tr>
1398
-
1399
- <tr>
1400
- <th><?php
1401
  esc_html_e( 'Send status mail?:', 'delete-duplicate-posts' );
1402
  ?></th>
1403
- <td>
1404
- <label for="ddp_statusmail">
1405
  <input type="checkbox" id="ddp_statusmail" name="ddp_statusmail"
1406
  <?php
1407
  if ( isset( $options['ddp_statusmail'] ) && true === $options['ddp_statusmail'] ) {
@@ -1411,80 +1522,80 @@ if ( !class_exists( 'Delete_Duplicate_Posts' ) ) {
1411
  <p class="description"><?php
1412
  esc_html_e( 'Sends a status email if duplicates have been found.', 'delete-duplicate-posts' );
1413
  ?></p>
1414
- </label>
1415
- </td>
1416
- </tr>
1417
-
1418
- <tr>
1419
- <th><?php
1420
  esc_html_e( 'Email recipient:', 'delete-duplicate-posts' );
1421
  ?></th>
1422
- <td>
1423
- <label for="ddp_statusmail_recipient">
1424
-
1425
  <input type="text" class="regular-text" id="ddp_statusmail_recipient" name="ddp_statusmail_recipient" value="<?php
1426
  echo esc_html( $options['ddp_statusmail_recipient'] ) ;
1427
  ?>">
1428
  <p class="description"><?php
1429
  esc_html_e( 'Who should get the notification email.', 'delete-duplicate-posts' );
1430
  ?></p>
1431
- </label>
1432
- </td>
1433
- </tr>
1434
-
1435
-
1436
-
1437
-
1438
- <th colspan=2><input type="submit" class="button-primary" name="delete_duplicate_posts_save" value="<?php
1439
  esc_html_e( 'Save Settings', 'delete-duplicate-posts' );
1440
  ?>" /></th>
1441
- </tr>
1442
-
1443
- </table>
1444
-
1445
- </form>
1446
- </div><!-- #configuration -->
1447
-
1448
-
1449
- <div id="log">
1450
-
1451
- <h3><?php
1452
  esc_html_e( 'The Log', 'delete-duplicate-posts' );
1453
  ?></h3>
1454
- <div class="spinner is-active"></div>
1455
- <ul class="large-text" name="ddp_log" id="ddp_log">
1456
- </ul>
1457
-
1458
- </div>
1459
- <p>
1460
- <form method="post" id="ddp_clearlog">
1461
- <?php
1462
  wp_nonce_field( 'ddp_clearlog_nonce' );
1463
  ?>
1464
-
1465
- <input class="button-secondary" type="submit" name="ddp_clearlog" value="<?php
1466
  esc_html_e( 'Reset log', 'delete-duplicate-posts' );
1467
  ?>" />
1468
- </form>
1469
- </p>
1470
-
1471
- </div><!-- #ddp_container -->
1472
-
1473
- <?php
1474
  include_once 'sidebar.php';
1475
  ?>
1476
-
1477
- <?php
1478
  if ( function_exists( 'ddp_fs' ) ) {
1479
  global $ddp_fs ;
1480
  }
1481
  ?>
1482
-
1483
- </div>
1484
- </div>
1485
-
1486
- </div>
1487
- <?php
1488
  }
1489
 
1490
  }
@@ -1493,4 +1604,6 @@ if ( !class_exists( 'Delete_Duplicate_Posts' ) ) {
1493
 
1494
  if ( class_exists( 'Delete_Duplicate_Posts' ) ) {
1495
  $delete_duplicate_posts_var = new Delete_Duplicate_Posts();
1496
- }
 
 
5
  Plugin Script: delete-duplicate-posts.php
6
  Plugin URI: https://cleverplugins.com
7
  Description: Remove duplicate blogposts on your blog! Searches and removes duplicate posts and their post meta tags. You can delete posts, pages and other Custom Post Types enabled on your website.
8
+ Version: 4.6
9
  Author: cleverplugins.com
10
  Author URI: https://cleverplugins.com
11
  Min WP Version: 4.7
140
 
141
  /**
142
  * Ajax callback to handle freemius opt in/out.
143
+ *
144
+ * @author Lars Koudal
145
+ * @since v0.0.1
146
+ * @version v1.0.0 Tuesday, January 12th, 2021.
147
+ * @access public static
148
+ * @return void
149
  */
150
  public static function cp_ddp_fs_opt_in()
151
  {
226
  exit;
227
  }
228
 
229
+ /**
230
+ * ddp_action_admin_notices.
231
+ *
232
+ * @author Lars Koudal
233
+ * @since v0.0.1
234
+ * @version v1.0.0 Tuesday, January 12th, 2021.
235
+ * @access public static
236
+ * @return void
237
+ */
238
  public static function ddp_action_admin_notices()
239
  {
240
  $screen = get_current_screen();
249
 
250
  if ( PAnD::is_admin_notice_active( 'cp-ddp-improve-notice-14' ) ) {
251
  ?>
252
+ <div id="cp-ddp-freemius" data-dismissible="cp-ddp-improve-notice-14" class="notice notice-success is-dismissible">
253
+ <h3><?php
254
  esc_html_e( 'Help Delete Duplicate Posts improve!', 'delete-duplicate-posts' );
255
  ?></h3>
256
+
257
+ <p><?php
258
  echo esc_html__( 'Gathering non-sensitive diagnostic data about the plugin install helps us improve the plugin.', 'delete-duplicate-posts' ) . ' <a href="' . esc_url( 'https://cleverplugins.com/docs/install/non-sensitive-diagnostic-data/' ) . '" target="_blank" rel="noopener">' . esc_html__( 'Read more about what we collect.', 'delete-duplicate-posts' ) . '</a>' ;
259
  ?></p>
260
+
261
+ <p>
262
+ <?php
263
  // translators:
264
  printf( esc_html__( 'If you opt-in, some data about your usage of %1$s will be sent to Freemius.com. If you skip this, that\'s okay! %1$s will still work just fine.', 'delete-duplicate-posts' ), '<b>Delete Duplicate Posts</b>' );
265
  ?>
266
+ </p>
267
+ <p>
268
+ <a href="javascript:;" class="button button-primary" onclick="cp_ddp_freemius_opt_in(this)" data-opt="yes"><?php
269
  esc_html_e( 'Sure, opt-in', 'delete-duplicate-posts' );
270
  ?></a>
271
+
272
+ <a href="javascript:;" class="button dismiss-this"><?php
273
  esc_html_e( 'No, thank you', 'delete-duplicate-posts' );
274
  ?></a>
275
+ </p>
276
+ <input type="hidden" id="cp-ddp-freemius-opt-nonce" value="<?php
277
  echo esc_attr( wp_create_nonce( 'cp-ddp-freemius-opt' ) ) ;
278
  ?>" />
279
+
280
+ </div>
281
+ <?php
282
  }
283
 
284
  }
292
  if ( false !== $totaldeleted && 0 < $totaldeleted ) {
293
  $totaldeleted = number_format_i18n( $totaldeleted );
294
  ?>
295
+ <div id="cp-ddp-reviewlink" data-dismissible="ddp-leavereview-14" class="updated notice notice-success is-dismissible">
296
+ <h3>
297
+ <?php
298
  // translators: Total number of deleted duplicates
299
  printf( esc_html__( '%s duplicates deleted!', 'delete-duplicate-posts' ), esc_html( $totaldeleted ) );
300
  ?>
301
+ </h3>
302
+ <p>
303
+ <?php
304
  // translators: Asking for a review text
305
  printf( esc_html__( "Hey, I noticed this plugin has deleted %s duplicate posts for you - that's awesome! Could you please do me a BIG favor and give it a 5-star rating on WordPress? Just to help us spread the word and boost our motivation.", 'delete-duplicate-posts' ), esc_html( $totaldeleted ) );
306
  ?>
307
+ </p>
308
+
309
+ <p>
310
+ <a href="https://wordpress.org/support/plugin/delete-duplicate-posts/reviews/?filter=5#new-post" class="cp-ddp-dismiss-review-notice cp-ddp-reviewlink button-primary dismiss-this" target="_blank" rel="noopener">Ok, you deserve it</a>
311
+ <span class="dashicons dashicons-calendar"></span><a href="#" class="cp-ddp-dismiss-review-notice dismiss-this" target="_blank" rel="noopener">Nope, maybe later</a>
312
+ <span class="dashicons dashicons-smiley"></span><a href="#" class="cp-ddp-dismiss-review-notice dismiss-this" target="_blank" rel="noopener">I already did</a>
313
+ </p>
314
+ </div>
315
+ <?php
316
  }
317
 
318
  }
319
 
320
+ /**
321
+ * delete_duplicates.
322
+ *
323
+ * @author Lars Koudal
324
+ * @since v0.0.1
325
+ * @version v1.0.0 Tuesday, January 12th, 2021.
326
+ * @access public static
327
+ * @param boolean $return Default: false
328
+ * @return void
329
+ */
330
  public static function delete_duplicates( $return = false )
331
  {
332
  if ( defined( 'DOING_AJAX' ) && DOING_AJAX ) {
344
  wp_send_json_success();
345
  }
346
 
347
+ /**
348
+ * return_loglines.
349
+ *
350
+ * @author Lars Koudal
351
+ * @since v0.0.1
352
+ * @version v1.0.0 Tuesday, January 12th, 2021.
353
+ * @access public static
354
+ * @param boolean $return Default: false
355
+ * @return void
356
+ */
357
  public static function return_loglines( $return = false )
358
  {
359
  if ( defined( 'DOING_AJAX' ) && DOING_AJAX ) {
391
  wp_send_json_success( $json_response );
392
  }
393
 
394
+ /**
395
+ * return_duplicates_ajax.
396
+ *
397
+ * @author Lars Koudal
398
+ * @since v0.0.1
399
+ * @version v1.0.0 Tuesday, January 12th, 2021.
400
+ * @access public static
401
+ * @param boolean $return Default: false
402
+ * @return mixed
403
+ */
404
  public static function return_duplicates_ajax( $return = false )
405
  {
406
  if ( defined( 'DOING_AJAX' ) && DOING_AJAX ) {
411
 
412
  /**
413
  * Returns duplicates based on current settings - internal, not used via AJAX
414
+ *
415
+ * @author Lars Koudal
416
+ * @since v0.0.1
417
+ * @version v1.0.0 Tuesday, January 12th, 2021.
418
+ * @access public static
419
+ * @param boolean $return Default: false
420
+ * @return void
421
  */
422
  public static function return_duplicates( $return = false )
423
  {
477
 
478
  if ( 'titlecompare' === $comparemethod ) {
479
  // @todo - prepare - not urgent, there is no way to exploit this query
480
+ // $resultslimit = 100; // @todo
481
+ $resultslimit = $options['ddp_resultslimit'];
482
+ if ( !$resultslimit ) {
483
+ $resultslimit = 0;
484
+ }
485
+ $resultsoutput = '';
486
+ if ( 0 < $resultslimit ) {
487
+ $resultsoutput = ' LIMIT ' . intval( $resultslimit );
488
+ }
489
+ $thisquery = "SELECT a.ID, a.post_title, a.post_type, a.post_status, save_this_post_id\n\t\t\t\t\t\t\t\t\t\t\tFROM {$table_name} AS a\n\t\t\t\t\t\t\t\t\t\t\tINNER JOIN (\n\t\t\t\t\t\t\t\t\t\t\t\tSELECT post_title, " . $minmax . " AS save_this_post_id\n\t\t\t\t\t\t\t\t\t\t\t\tFROM {$table_name}\n\t\t\t\t\t\t\t\t\t\t\t\tWHERE post_type IN(" . $ddp_pts . ')
490
+ AND post_status IN(' . $post_stati . ')
491
+ GROUP BY post_title
492
+ HAVING COUNT( * ) > 1
493
+ ) AS b ON b.post_title = a.post_title
494
+ AND b.save_this_post_id <> a.id
495
+ AND a.post_type IN(' . $ddp_pts . ')
496
+ AND a.post_status IN(' . $post_stati . ')' . $resultsoutput;
497
  $dupes = $wpdb->get_results( $thisquery, ARRAY_A );
498
 
499
  if ( $dupes ) {
537
  if ( !$return_duplicates_time ) {
538
  $return_duplicates_time = self::timerstop( 'return_duplicates' );
539
  }
540
+ $json_response['msg'] = number_format_i18n( $json_response['dupescount'] ) . ' duplicates found. Time: ' . esc_html( $return_duplicates_time ) . ' sec. Showing up to ' . esc_html( $viewlimit ) . ' results.';
541
  // @todo i8n
542
  if ( $return ) {
543
  // todo - limit amount of values to return
566
  'ddp_pts' => array( 'post', 'page' ),
567
  'ddp_statusmail_recipient' => '',
568
  'ddp_statusmail' => 0,
569
+ 'ddp_resultslimit' => 0,
570
  'ddp_enabled' => 0,
571
  'ddp_pstati' => array( 'publish' ),
572
  );
700
 
701
  if ( $manualrun > 0 ) {
702
  ?>
703
+ <div class="notice notice-success">
704
+ <p>
705
+ <?php
706
  // translators:
707
  printf( esc_html__( 'A total of %s duplicate posts were deleted.', 'delete-duplicate-posts' ), intval( $dispcount ) );
708
  ?>
709
+ </p>
710
+ </div>
711
+ <?php
712
  }
713
 
714
  // manualrun
850
  $table_name = $wpdb->prefix . 'ddp_log';
851
 
852
  if ( $table_name !== $wpdb->get_var( "show tables like '{$table_name}'" ) ) {
853
+ $sql = "CREATE TABLE {$table_name} (\n\t\t\t\t\t\t\t\t\t\t\t\t\tid bigint(20) NOT NULL AUTO_INCREMENT,\n\t\t\t\t\t\t\t\t\t\t\t\t\tdatime timestamp NOT NULL DEFAULT '0000-00-00 00:00:00' ON UPDATE CURRENT_TIMESTAMP,\n\t\t\t\t\t\t\t\t\t\t\t\t\tnote tinytext NOT NULL,\n\t\t\t\t\t\t\t\t\t\t\t\t\tPRIMARY KEY (id)\n\t\t\t\t\t\t\t\t\t\t\t\t);";
854
  require_once ABSPATH . 'wp-admin/includes/upgrade.php';
855
  dbDelta( $sql );
856
  }
958
  'id' => 'ddp_help',
959
  'title' => __( 'Usage and FAQ', 'delete-duplicate-posts' ),
960
  'content' => '
961
+ <h4>' . __( 'What does this plugin do?', 'delete-duplicate-posts' ) . '</h4>
962
+ <p>' . __( 'Helps you clean duplicate posts from your blog. The plugin checks for blogposts on your blog with the same title.', 'delete-duplicate-posts' ) . '</p>
963
+ <p>' . __( "It can run automatically via WordPress's own internal CRON-system, or you can run it automatically.", 'delete-duplicate-posts' ) . '</p>
964
+ <p>' . __( 'It also has a nice feature that can send you an e-mail when Delete Duplicate Posts finds and deletes something (if you have turned on the CRON feature).', 'delete-duplicate-posts' ) . '</p>
965
+ <h4>' . __( 'Help! Something was deleted that was not supposed to be deleted!', 'delete-duplicate-posts' ) . '</h4>
966
+ <p>' . __( 'I am sorry for that, I can only recommend you restore the database you took just before you ran this plugin.', 'delete-duplicate-posts' ) . '</p>
967
+ <p>' . __( 'If you run this plugin, manually or automatically, it is at your OWN risk!', 'delete-duplicate-posts' ) . '</p>
968
+ <p>' . __( 'I have done my best to avoid deleting something that should not be deleted, but if it happens, there is nothing I can do to help you.', 'delete-duplicate-posts' ) . "</p>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t<p><a href='https://cleverplugins.com' target='_blank'>cleverplugins.com</a>.</p>",
969
  ) );
970
  }
971
  }
1024
  if ( isset( $_POST['ddp_method'] ) ) {
1025
  $options['ddp_method'] = sanitize_text_field( $_POST['ddp_method'] );
1026
  }
1027
+ if ( isset( $_POST['ddp_resultslimit'] ) ) {
1028
+ $options['ddp_resultslimit'] = sanitize_text_field( $_POST['ddp_resultslimit'] );
1029
+ }
1030
  $options['ddp_pts'] = $posttypes;
1031
  // Previously sanitized
1032
  if ( isset( $_POST['ddp_limit'] ) ) {
1068
  $name = $pluginfo['Name'];
1069
  $options = self::get_options();
1070
  ?>
1071
+
1072
+ <div class="wrap">
1073
+
1074
+ <h2>Delete Duplicate Posts <span>v. <?php
1075
  echo esc_html( self::get_plugin_version() ) ;
1076
  ?></span></h2>
1077
+
1078
+ <div class="ddp_content_wrapper">
1079
+ <div class="ddp_content_cell">
1080
+ <div id="ddp_container">
1081
+ <div id="dashboard">
1082
+ <?php
1083
 
1084
  if ( $options['ddp_enabled'] ) {
1085
  $nextscheduled = wp_next_scheduled( 'ddp_cron' );
1100
 
1101
  $totaldeleted = get_option( 'ddp_deleted_duplicates' );
1102
  ?>
1103
+
1104
+ <div class="statusdiv">
1105
+ <div class="spinner is-active"></div>
1106
+ <div class="statusmessage"></div>
1107
+ <div class="dupelist">
1108
+ <table class="wp-list-table widefat fixed striped posts duplicatetable" cellspacing="0">
1109
+ <thead>
1110
  <tr>
1111
  <td id="cb" class="manage-column column-cb check-column"><label class="screen-reader-text" for="cb-select-all-1">Select All</label><input id="cb-select-all-1" type="checkbox"></td>
1112
+ <th><?php
1113
  esc_html_e( 'Duplicate', 'delete-duplicate-posts' );
1114
  ?></th>
1115
+ <th><?php
1116
  esc_html_e( 'Original', 'delete-duplicate-posts' );
1117
  ?></th>
1118
  </tr>
1119
+ </thead>
1120
+ <tbody id="listofduplicates">
1121
+ </tbody>
1122
+
1123
+ <tfoot>
1124
  <tr>
1125
  <td id="cb" class="manage-column column-cb check-column"><label class="screen-reader-text" for="cb-select-all-1">Select All</label><input id="cb-select-all-1" type="checkbox"></td>
1126
+ <th><?php
1127
  esc_html_e( 'Duplicate', 'delete-duplicate-posts' );
1128
  ?></th>
1129
+ <th><?php
1130
  esc_html_e( 'Original', 'delete-duplicate-posts' );
1131
  ?></th>
1132
  </tr>
1133
+ </tfoot>
1134
+ </table>
1135
+ </div>
1136
+ <form>
1137
+ <?php
1138
  wp_nonce_field( 'ddp-buttons' );
1139
  ?>
1140
+ <table id="ddp_buttons">
1141
+ <tr>
1142
  <td><input type="submit" name="deleteduplicateposts_resetview" id="deleteduplicateposts_resetview"class="button button-small button-secondary" value="<?php
1143
  esc_html_e( 'Refresh list', 'delete-duplicate-posts' );
1144
  ?>" disabled/></td>
1145
  <td><input type="submit" name="deleteduplicateposts_deleteall" id="deleteduplicateposts_deleteall" class="button button-small button-primary" value="<?php
1146
  esc_html_e( 'Delete duplicates', 'delete-duplicate-posts' );
1147
  ?>" disabled/></td>
1148
+ </tr>
1149
+ </table>
1150
+ </form>
1151
+ </div>
1152
+
1153
+ </div><!-- #dashboard -->
1154
+
1155
+ <div id="configuration">
1156
+ <h3><?php
1157
  esc_html_e( 'Settings', 'delete-duplicate-posts' );
1158
  ?></h3>
1159
+ <p>
1160
+ <?php
1161
  $nextscheduled = wp_next_scheduled( 'ddp_cron' );
1162
 
1163
  if ( $nextscheduled ) {
1164
  ?>
1165
+ <div class="notice notice-info is-dismissible">
1166
+ <?php
1167
  echo '<p class="cronstatus center">' . esc_html__( 'You have enabled automatic deletion, so I am running on automatic. I will take care of everything...', 'delete-duplicate-posts' ) . '</p>' ;
1168
  echo '<p class="center">' ;
1169
  echo sprintf(
1174
  ) ;
1175
  echo '</p>' ;
1176
  ?>
1177
+ </div>
1178
+ <?php
1179
  }
1180
 
1181
  ?>
1182
+ </p>
1183
+ <form method="post" id="delete_duplicate_posts_options">
1184
+ <?php
1185
  wp_nonce_field( 'ddp-update-options' );
1186
  ?>
1187
+ <table width="100%" cellspacing="2" cellpadding="5" class="form-table">
1188
+
1189
+
1190
+
1191
+
1192
+ <tr valign="top">
1193
+ <th><label for="ddp_enabled"><?php
1194
  esc_html_e( 'Which post types?:', 'delete-duplicate-posts' );
1195
  ?></label></th>
1196
+ <td>
1197
  <?php
1198
  $builtin = array( 'post', 'page', 'attachment' );
1199
  $args = array(
1209
  if ( $post_types ) {
1210
  ?>
1211
  <ul class="radio">
1212
+ <?php
1213
  $step = 0;
1214
  if ( !is_array( $checked_post_types ) ) {
1215
  $checked_post_types = array();
1217
  foreach ( $post_types as $pt ) {
1218
  $checked = array_search( $pt, $checked_post_types, true );
1219
  ?>
1220
+ <li>
1221
+ <input type="checkbox" name="ddp_pts[]" id="ddp_pt-<?php
1222
  echo esc_attr( $step ) ;
1223
  ?>" value="<?php
1224
  echo esc_html( $pt ) ;
1225
  ?>"
1226
+ <?php
1227
  if ( false !== $checked ) {
1228
  echo ' checked' ;
1229
  }
1230
  ?>
1231
+ />
1232
+ <label for="ddp_pt-<?php
1233
  echo esc_attr( $step ) ;
1234
  ?>"><?php
1235
  echo esc_html( $pt ) ;
1236
  ?></label>
1237
+ </li>
1238
+ <?php
1239
  $step++;
1240
  }
1241
  ?>
1247
  <p class="description"><?php
1248
  esc_html_e( 'Choose which post types to scan for duplicates.', 'delete-duplicate-posts' );
1249
  ?></p>
1250
+ </td>
1251
+ </tr>
1252
+
1253
+ <tr>
1254
+ <th><label for="ddp_enabled"><?php
1255
  esc_html_e( 'Post status', 'delete-duplicate-posts' );
1256
  ?></label></th>
1257
+ <td>
1258
  <?php
1259
  $stati = array(
1260
  'publish' => (object) array(
1267
  if ( $stati ) {
1268
  ?>
1269
  <ul class="radio">
1270
+ <?php
1271
  $staticount = count( $stati );
1272
  foreach ( $stati as $key => $st ) {
1273
 
1274
  if ( $st->show_in_admin_status_list ) {
1275
  $checked = array_search( $key, $checked_post_stati, true );
1276
  ?>
1277
+ <li>
1278
+ <input type="checkbox" name="ddp_pstati[]" id="ddp_pstatus-<?php
1279
  echo esc_attr( $key ) ;
1280
  ?>" value="<?php
1281
  echo esc_attr( $key ) ;
1282
  ?>"
1283
+ <?php
1284
  if ( false !== $checked ) {
1285
  echo ' checked' ;
1286
  }
1287
  ?>
1288
+ <?php
1289
  if ( 1 === $staticount ) {
1290
  echo ' disabled' ;
1291
  }
1292
  ?> />
1293
+ <label for="ddp_pstatus-<?php
1294
  echo esc_attr( $key ) ;
1295
  ?>"><?php
1296
  echo esc_html( $key . ' (' . $st->label . ')' ) ;
1297
  ?></label>
1298
+ </li>
1299
+ <?php
1300
  $step++;
1301
  }
1302
 
1307
  }
1308
 
1309
  ?>
1310
+ </td>
1311
+
1312
+
1313
+ </tr>
1314
+ <?php
1315
  $comparemethod = 'titlecompare';
1316
  global $ddp_fs ;
1317
  ?>
1318
+ <tr valign="top">
1319
+ <th><?php
1320
  esc_html_e( 'Comparison Method', 'delete-duplicate-posts' );
1321
  ?></th>
1322
+ <td>
1323
  <ul class="ddpcomparemethod">
1324
+
1325
+ <li>
1326
+ <label>
1327
+ <input type="radio" name="ddp_method" value="titlecompare" <?php
1328
  checked( 'titlecompare', $comparemethod );
1329
  ?> /> <?php
1330
  esc_html_e( 'Compare by title (default)', 'delete-duplicate-posts' );
1331
  ?>
1332
+ <span class="optiondesc"><?php
1333
  esc_html_e( 'Looks at the title of the post itself.', 'delete-duplicate-posts' );
1334
  ?></span>
1335
+ </label>
1336
+
1337
+ </li>
1338
+
1339
+ <?php
1340
  global $ddp_fs ;
1341
  ?>
1342
  </ul>
1343
+ </td>
1344
+ </tr>
1345
+ <tr>
1346
+ <th><label for="ddp_keep"><?php
1347
  esc_html_e( 'Delete which posts?:', 'delete-duplicate-posts' );
1348
  ?></label></th><td>
1349
+
1350
  <select name="ddp_keep" id="ddp_keep">
1351
+ <option value="oldest"
1352
+ <?php
1353
  if ( 'oldest' === $options['ddp_keep'] ) {
1354
  echo 'selected="selected"' ;
1355
  }
1356
  ?>
1357
+ ><?php
1358
  esc_html_e( 'Keep oldest', 'delete-duplicate-posts' );
1359
  ?></option>
1360
+ <option value="latest"
1361
+ <?php
1362
  if ( 'latest' === $options['ddp_keep'] ) {
1363
  echo 'selected="selected"' ;
1364
  }
1365
  ?>
1366
+ ><?php
1367
  esc_html_e( 'Keep latest', 'delete-duplicate-posts' );
1368
  ?></option>
1369
  </select>
1370
  <p class="description"><?php
1371
  esc_html_e( 'Keep the oldest or the latest version of duplicates? Default is keeping the oldest, and deleting any subsequent duplicate posts', 'delete-duplicate-posts' );
1372
  ?></p>
1373
+ </td>
1374
+ </tr>
1375
+
1376
 
1377
 
1378
+
1379
+ <tr>
1380
+ <th><label for="ddp_resultslimit"><?php
1381
+ esc_html_e( 'Find how many duplicates:', 'delete-duplicate-posts' );
1382
+ ?></label></th><td>
1383
+
1384
+ <?php
1385
+ $dupe_options = array(
1386
+ 0 => __( 'No limit', 'delete-duplicate-posts' ),
1387
+ 10000 => number_format_i18n( '10000' ),
1388
+ 5000 => number_format_i18n( '5000' ),
1389
+ 2500 => number_format_i18n( '2500' ),
1390
+ 1000 => number_format_i18n( '1000' ),
1391
+ 500 => '500',
1392
+ 250 => '250',
1393
+ 100 => '100',
1394
+ 50 => '50',
1395
+ );
1396
+ ?>
1397
+ <select name="ddp_resultslimit" id="ddp_resultslimit">
1398
+ <?php
1399
+ foreach ( $dupe_options as $key => $label ) {
1400
+ ?>
1401
+ <option value="<?php
1402
+ echo $key ;
1403
+ ?>" <?php
1404
+ selected( $options['ddp_resultslimit'], $key );
1405
+ ?>><?php
1406
+ echo $label ;
1407
+ ?></option>
1408
+ <?php
1409
+ }
1410
+ ?>
1411
+ </select>
1412
+ <p><strong>BETA feature</strong>. Available in free version while in beta. Once out of testing, this feature will be for premium users only.</p>
1413
+
1414
+ <p class="description"><?php
1415
+ esc_html_e( 'If you have many duplicates, the plugin might time out before finding them all. Try limiting the amount of duplicates here. Default: Unlimited.', 'delete-duplicate-posts' );
1416
+ ?></p>
1417
+ </td>
1418
+ </tr>
1419
+
1420
+ <?php
1421
  /*
1422
 
1423
  <tr valign="top">
1424
  <th><label for="ddp_limit"><?php esc_html_e( 'Delete at maximum :', 'delete-duplicate-posts' ); ?></label></th><td><select name="ddp_limit">
1425
+ <?php
1426
+ for ( $x = 1; $x <= 10; $x++ ) {
1427
+ $val = ( $x * 50 );
1428
+ echo "<option value='" . esc_attr( $val ) . "' ";
1429
+ if ( $options['ddp_limit'] === $val ) {
1430
+ echo 'selected';
 
 
1431
  }
1432
+ echo '>' . esc_attr( $val ) . '</option>';
1433
+ }
1434
+ ?>
1435
  </select>
1436
  <?php esc_html_e( 'duplicates.', 'delete-duplicate-posts' ); ?>
1437
  <p class="description"><?php esc_html_e( 'Setting a limit is a good idea, especially if your site is on a busy server.', 'delete-duplicate-posts' ); ?></p>
1439
  </tr>
1440
  */
1441
  ?>
1442
+
 
 
 
 
1443
 
1444
 
1445
+ <tr>
1446
+ <td colspan="2"><hr></td>
1447
+ </tr>
1448
+
1449
+ <tr valign="top">
1450
+ <th><?php
1451
  esc_html_e( 'Enable automatic deletion?:', 'delete-duplicate-posts' );
1452
  ?>
1453
+
1454
+ </th>
1455
+ <td><label for="ddp_enabled">
1456
+ <input type="checkbox" id="ddp_enabled" name="ddp_enabled"
1457
+ <?php
1458
  if ( true === $options['ddp_enabled'] ) {
1459
  echo 'checked="checked"' ;
1460
  }
1461
  ?>
1462
+ >
1463
+ <p class="description"><?php
1464
  esc_html_e( 'Clean duplicates automatically.', 'delete-duplicate-posts' );
1465
  ?></p>
1466
+ </label>
1467
+ </td>
1468
+ </tr>
1469
+
1470
+
1471
+ <tr>
1472
+ <th><label for="ddp_schedule"><?php
1473
  esc_html_e( 'How often?:', 'delete-duplicate-posts' );
1474
  ?></label></th><td>
1475
+
1476
+ <select name="ddp_schedule" id="ddp_schedule">
1477
+ <?php
1478
  $schedules = wp_get_schedules();
1479
  if ( $schedules ) {
1480
  foreach ( $schedules as $key => $sch ) {
1481
  ?>
1482
+ <option value="<?php
1483
  echo esc_attr( $key ) ;
1484
  ?>"
1485
  <?php
1494
  }
1495
  }
1496
  ?>
1497
+ </select>
1498
+ <p class="description"><?php
1499
  esc_html_e( 'How often should the cron job run?', 'delete-duplicate-posts' );
1500
  ?></p>
1501
+ </td>
1502
+ </tr>
1503
+
1504
+
1505
+
1506
+ <tr>
1507
+ <td colspan="2"><hr></td>
1508
+ </tr>
1509
+
1510
+ <tr>
1511
+ <th><?php
1512
  esc_html_e( 'Send status mail?:', 'delete-duplicate-posts' );
1513
  ?></th>
1514
+ <td>
1515
+ <label for="ddp_statusmail">
1516
  <input type="checkbox" id="ddp_statusmail" name="ddp_statusmail"
1517
  <?php
1518
  if ( isset( $options['ddp_statusmail'] ) && true === $options['ddp_statusmail'] ) {
1522
  <p class="description"><?php
1523
  esc_html_e( 'Sends a status email if duplicates have been found.', 'delete-duplicate-posts' );
1524
  ?></p>
1525
+ </label>
1526
+ </td>
1527
+ </tr>
1528
+
1529
+ <tr>
1530
+ <th><?php
1531
  esc_html_e( 'Email recipient:', 'delete-duplicate-posts' );
1532
  ?></th>
1533
+ <td>
1534
+ <label for="ddp_statusmail_recipient">
1535
+
1536
  <input type="text" class="regular-text" id="ddp_statusmail_recipient" name="ddp_statusmail_recipient" value="<?php
1537
  echo esc_html( $options['ddp_statusmail_recipient'] ) ;
1538
  ?>">
1539
  <p class="description"><?php
1540
  esc_html_e( 'Who should get the notification email.', 'delete-duplicate-posts' );
1541
  ?></p>
1542
+ </label>
1543
+ </td>
1544
+ </tr>
1545
+
1546
+
1547
+
1548
+
1549
+ <th colspan=2><input type="submit" class="button-primary" name="delete_duplicate_posts_save" value="<?php
1550
  esc_html_e( 'Save Settings', 'delete-duplicate-posts' );
1551
  ?>" /></th>
1552
+ </tr>
1553
+
1554
+ </table>
1555
+
1556
+ </form>
1557
+ </div><!-- #configuration -->
1558
+
1559
+
1560
+ <div id="log">
1561
+
1562
+ <h3><?php
1563
  esc_html_e( 'The Log', 'delete-duplicate-posts' );
1564
  ?></h3>
1565
+ <div class="spinner is-active"></div>
1566
+ <ul class="large-text" name="ddp_log" id="ddp_log">
1567
+ </ul>
1568
+
1569
+ </div>
1570
+ <p>
1571
+ <form method="post" id="ddp_clearlog">
1572
+ <?php
1573
  wp_nonce_field( 'ddp_clearlog_nonce' );
1574
  ?>
1575
+
1576
+ <input class="button-secondary" type="submit" name="ddp_clearlog" value="<?php
1577
  esc_html_e( 'Reset log', 'delete-duplicate-posts' );
1578
  ?>" />
1579
+ </form>
1580
+ </p>
1581
+
1582
+ </div><!-- #ddp_container -->
1583
+
1584
+ <?php
1585
  include_once 'sidebar.php';
1586
  ?>
1587
+
1588
+ <?php
1589
  if ( function_exists( 'ddp_fs' ) ) {
1590
  global $ddp_fs ;
1591
  }
1592
  ?>
1593
+
1594
+ </div>
1595
+ </div>
1596
+
1597
+ </div>
1598
+ <?php
1599
  }
1600
 
1601
  }
1604
 
1605
  if ( class_exists( 'Delete_Duplicate_Posts' ) ) {
1606
  $delete_duplicate_posts_var = new Delete_Duplicate_Posts();
1607
+ }
1608
+ ?>
1609
+
readme.txt CHANGED
@@ -6,7 +6,7 @@ License: GPLv2 or later
6
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
7
  Requires at least: 4.7
8
  Tested up to: 5.6
9
- Stable tag: 4.5
10
  Requires PHP: 5.6
11
 
12
  Get rid of duplicate posts and pages on your blog!
@@ -49,6 +49,12 @@ You should restore the backup you took of your website before you ran this tool.
49
 
50
  == Changelog ==
51
 
 
 
 
 
 
 
52
  = 4.5 =
53
  * 2021/01/11
54
  * New: Manually select which duplicates to delete (or use the automatic)
@@ -268,4 +274,4 @@ You should restore the backup you took of your website before you ran this tool.
268
  * First release
269
 
270
  == Upgrade Notice ==
271
- 4.5 Recommended update - compatibility with WordPress 5.6 and new features.
6
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
7
  Requires at least: 4.7
8
  Tested up to: 5.6
9
+ Stable tag: 4.6
10
  Requires PHP: 5.6
11
 
12
  Get rid of duplicate posts and pages on your blog!
49
 
50
  == Changelog ==
51
 
52
+ = 4.6 =
53
+ * 2020/01/12
54
+ * Beta feature: Limit amount of duplicates to find. On big sites with many duplicates the plugin can time out. This feature allows you to limit the amount of results. This feature is only available for free while being tested. Thank you Fabio.
55
+ * Minor text or layout fixes.
56
+ * 286,392 downloads
57
+
58
  = 4.5 =
59
  * 2021/01/11
60
  * New: Manually select which duplicates to delete (or use the automatic)
274
  * First release
275
 
276
  == Upgrade Notice ==
277
+ 4.6 Recommended update - compatibility with WordPress 5.6 and new features + solution for time out problem on big websites.