Delete Duplicate Posts - Version 4.7

Version Description

  • 2021/07/11
  • FIX: Duplicates not always properly detected, thank you for the reporters to help fix this bug :-)
  • NEW: Improved and faster lookup of duplicates.
  • NEW: See number of posts per post type.
  • NEW: See peak memory usage in the log.
  • NEW: See combined count by post_status in the log.
  • NEW: If there is a problem looking up duplicates in the database (shared servers have limited resources), the problem will be shown in the log.
  • Updated language files.
  • Tested up to WP 5.8
Download this release

Release Info

Developer cleverplugins
Plugin Icon 128x128 Delete Duplicate Posts
Version 4.7
Comparing to
See all releases

Code changes from version 4.6.2 to 4.7

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.6.2
9
  Author: cleverplugins.com
10
  Author URI: https://cleverplugins.com
11
  Min WP Version: 4.7
@@ -243,6 +243,47 @@ if ( !class_exists( 'Delete_Duplicate_Posts' ) ) {
243
  public static function ddp_action_admin_notices()
244
  {
245
  $screen = get_current_screen();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
246
  if ( 'tools_page_delete-duplicate-posts' !== $screen->id ) {
247
  return;
248
  }
@@ -252,43 +293,49 @@ if ( !class_exists( 'Delete_Duplicate_Posts' ) ) {
252
  if ( ddp_fs()->is_anonymous() && ddp_fs()->is_not_paying() && ddp_fs()->has_api_connectivity() ) {
253
  if ( !is_multisite() || is_multisite() && is_network_admin() ) {
254
 
255
- if ( PAnD::is_admin_notice_active( 'cp-ddp-improve-notice-14' ) ) {
256
  ?>
257
- <div id="cp-ddp-freemius" data-dismissible="cp-ddp-improve-notice-14" class="notice notice-success is-dismissible">
258
- <h3><?php
259
  esc_html_e( 'Help Delete Duplicate Posts improve!', 'delete-duplicate-posts' );
260
  ?></h3>
261
-
262
- <p><?php
 
263
  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>' ;
264
- ?></p>
265
-
266
- <p>
267
- <?php
 
268
  // translators:
269
  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>' );
270
  ?>
271
- </p>
272
- <p>
273
- <a href="javascript:;" class="button button-primary" onclick="cp_ddp_freemius_opt_in(this)" data-opt="yes"><?php
 
274
  esc_html_e( 'Sure, opt-in', 'delete-duplicate-posts' );
275
  ?></a>
276
-
277
- <a href="javascript:;" class="button dismiss-this"><?php
 
278
  esc_html_e( 'No, thank you', 'delete-duplicate-posts' );
279
  ?></a>
280
- </p>
281
- <input type="hidden" id="cp-ddp-freemius-opt-nonce" value="<?php
 
282
  echo esc_attr( wp_create_nonce( 'cp-ddp-freemius-opt' ) ) ;
283
  ?>" />
284
-
285
- </div>
286
- <?php
287
  }
288
 
289
  }
290
  }
291
  }
 
292
  if ( !PAnD::is_admin_notice_active( 'ddp-leavereview-14' ) ) {
293
  return;
294
  }
@@ -297,27 +344,31 @@ if ( !class_exists( 'Delete_Duplicate_Posts' ) ) {
297
  if ( false !== $totaldeleted && 0 < $totaldeleted ) {
298
  $totaldeleted = number_format_i18n( $totaldeleted );
299
  ?>
300
- <div id="cp-ddp-reviewlink" data-dismissible="ddp-leavereview-14" class="updated notice notice-success is-dismissible">
301
- <h3>
302
- <?php
303
  // translators: Total number of deleted duplicates
304
  printf( esc_html__( '%s duplicates deleted!', 'delete-duplicate-posts' ), esc_html( $totaldeleted ) );
305
  ?>
306
- </h3>
307
- <p>
308
- <?php
309
  // translators: Asking for a review text
310
  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 ) );
311
  ?>
312
- </p>
313
-
314
- <p>
315
- <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>
316
- <span class="dashicons dashicons-calendar"></span><a href="#" class="cp-ddp-dismiss-review-notice dismiss-this" target="_blank" rel="noopener">Nope, maybe later</a>
317
- <span class="dashicons dashicons-smiley"></span><a href="#" class="cp-ddp-dismiss-review-notice dismiss-this" target="_blank" rel="noopener">I already did</a>
318
- </p>
319
- </div>
320
- <?php
 
 
 
 
321
  }
322
 
323
  }
@@ -414,6 +465,28 @@ if ( !class_exists( 'Delete_Duplicate_Posts' ) ) {
414
  self::return_duplicates( $return );
415
  }
416
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
417
  /**
418
  * Returns duplicates based on current settings - internal, not used via AJAX
419
  *
@@ -481,48 +554,62 @@ if ( !class_exists( 'Delete_Duplicate_Posts' ) ) {
481
  if ( 'latest' === $order ) {
482
  $minmax = 'MAX(id)';
483
  }
 
484
  $dupescount = 0;
485
 
486
  if ( '' !== $ddp_pts ) {
487
  $thisquery = false;
 
488
 
489
  if ( 'titlecompare' === $comparemethod ) {
490
  // @todo - prepare - not urgent, there is no way to exploit this query
491
- // $resultslimit = 100; // @todo
492
- // if ( !$resultslimit ) $resultslimit = 0;
493
  $resultsoutput = '';
494
  if ( 0 > $resultslimit ) {
495
  $resultsoutput = ' LIMIT ' . intval( $resultslimit );
496
  }
497
- $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 . ')
498
- AND post_status IN(' . $post_stati . ')
499
- GROUP BY post_title
500
- HAVING COUNT( * ) > 1
501
- ) AS b ON b.post_title = a.post_title
502
- AND b.save_this_post_id <> a.id
503
- AND a.post_type IN(' . $ddp_pts . ')
504
- AND a.post_status IN(' . $post_stati . ')' . $resultsoutput;
505
  $dupes = $wpdb->get_results( $thisquery, ARRAY_A );
 
 
 
 
 
 
 
506
 
507
  if ( $dupes ) {
508
  $dupescount = count( $dupes );
509
  $json_response['dupescount'] = $dupescount;
510
  $stepcount = 0;
511
  foreach ( $dupes as $dupe ) {
512
- $dupedetails = array(
513
- 'ID' => $dupe['ID'],
514
- 'permalink' => get_permalink( $dupe['ID'] ),
515
- 'title' => $dupe['post_title'],
516
- 'type' => $dupe['post_type'],
517
- 'orgID' => $dupe['save_this_post_id'],
518
- 'orgtitle' => $dupe['post_title'],
519
- 'orgpermalink' => get_permalink( $dupe['save_this_post_id'] ),
520
- 'status' => $dupe['post_status'],
521
- 'why' => '',
522
- );
523
- $json_response['dupes'][] = $dupedetails;
 
 
 
 
 
 
 
 
 
 
 
 
524
  $stepcount++;
525
  }
 
526
  }
527
 
528
  }
@@ -530,8 +617,20 @@ if ( !class_exists( 'Delete_Duplicate_Posts' ) ) {
530
  if ( !isset( $json_response['dupescount'] ) ) {
531
  $json_response['dupescount'] = 0;
532
  }
 
 
 
 
 
 
 
 
 
 
 
533
  $return_duplicates_time = self::timerstop( 'return_duplicates' );
534
- self::log( $json_response['dupescount'] . ' duplicates found in ' . $return_duplicates_time . ' sec.' );
 
535
  } else {
536
  $json_response['msg'] = __( 'Error: Choose post types to check.', 'delete-duplicate-posts' );
537
  $return_duplicates_time = self::timerstop( 'return_duplicates' );
@@ -557,13 +656,33 @@ if ( !class_exists( 'Delete_Duplicate_Posts' ) ) {
557
  wp_send_json_success( $json_response );
558
  }
559
 
 
 
 
 
 
 
 
 
 
 
 
 
560
  public static function create_redirect( $inurl, $targeturl, $code = 301 )
561
  {
562
  global $wpdb ;
563
  // @todo - future
564
  }
565
 
566
- // return default options
 
 
 
 
 
 
 
 
567
  public static function default_options()
568
  {
569
  $defaults = array(
@@ -707,15 +826,15 @@ if ( !class_exists( 'Delete_Duplicate_Posts' ) ) {
707
 
708
  if ( $manualrun > 0 ) {
709
  ?>
710
- <div class="notice notice-success">
711
- <p>
712
- <?php
713
  // translators:
714
  printf( esc_html__( 'A total of %s duplicate posts were deleted.', 'delete-duplicate-posts' ), intval( $dispcount ) );
715
  ?>
716
- </p>
717
- </div>
718
- <?php
719
  }
720
 
721
  // manualrun
@@ -792,11 +911,10 @@ if ( !class_exists( 'Delete_Duplicate_Posts' ) ) {
792
  $total = (int) $wpdb->get_var( "SELECT COUNT(*) FROM `{$ddp_logtable}`;" );
793
  // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared
794
 
795
- if ( $total > 10 ) {
796
  $targettime = $wpdb->get_var( "SELECT `datime` from `{$ddp_logtable}` order by `datime` DESC limit 500,1;" );
797
  // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared
798
- $query = "DELETE from `{$ddp_logtable}` where `datime` < '{$targettime}';";
799
- $success = $wpdb->query( $wpdb->prepare( "DELETE from `{$ddp_logtable}` where `datime` < %s", $targettime ) );
800
  }
801
 
802
  }
@@ -1077,18 +1195,18 @@ if ( !class_exists( 'Delete_Duplicate_Posts' ) ) {
1077
  $name = $pluginfo['Name'];
1078
  $options = self::get_options();
1079
  ?>
1080
-
1081
- <div class="wrap">
1082
-
1083
- <h2>Delete Duplicate Posts <span>v. <?php
1084
  echo esc_html( self::get_plugin_version() ) ;
1085
- ?></span></h2>
1086
-
1087
- <div class="ddp_content_wrapper">
1088
- <div class="ddp_content_cell">
1089
- <div id="ddp_container">
1090
- <div id="dashboard">
1091
- <?php
1092
 
1093
  if ( $options['ddp_enabled'] ) {
1094
  $interval = $options['ddp_schedule'];
@@ -1120,70 +1238,76 @@ if ( !class_exists( 'Delete_Duplicate_Posts' ) ) {
1120
 
1121
  $totaldeleted = get_option( 'ddp_deleted_duplicates' );
1122
  ?>
1123
- <div class="statusdiv">
1124
- <div class="spinner is-active"></div>
1125
- <div class="statusmessage"></div>
1126
- <div class="dupelist">
1127
- <table class="wp-list-table widefat fixed striped posts duplicatetable" cellspacing="0">
1128
- <thead>
1129
- <tr>
1130
- <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>
1131
- <th><?php
 
1132
  esc_html_e( 'Duplicate', 'delete-duplicate-posts' );
1133
  ?></th>
1134
- <th><?php
1135
  esc_html_e( 'Original', 'delete-duplicate-posts' );
1136
  ?></th>
1137
- </tr>
1138
- </thead>
1139
- <tbody id="listofduplicates">
1140
- </tbody>
1141
-
1142
- <tfoot>
1143
- <tr>
1144
- <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>
1145
- <th><?php
 
1146
  esc_html_e( 'Duplicate', 'delete-duplicate-posts' );
1147
  ?></th>
1148
- <th><?php
1149
  esc_html_e( 'Original', 'delete-duplicate-posts' );
1150
  ?></th>
1151
- </tr>
1152
- </tfoot>
1153
- </table>
1154
- </div>
1155
- <form>
1156
- <?php
1157
  wp_nonce_field( 'ddp-buttons' );
1158
  ?>
1159
- <table id="ddp_buttons">
1160
- <tr>
1161
- <td><input type="submit" name="deleteduplicateposts_resetview" id="deleteduplicateposts_resetview"class="button button-small button-secondary" value="<?php
 
 
1162
  esc_html_e( 'Refresh list', 'delete-duplicate-posts' );
1163
- ?>" disabled/></td>
1164
- <td><input type="submit" name="deleteduplicateposts_deleteall" id="deleteduplicateposts_deleteall" class="button button-small button-primary" value="<?php
 
 
1165
  esc_html_e( 'Delete duplicates', 'delete-duplicate-posts' );
1166
- ?>" disabled/></td>
1167
- </tr>
1168
- </table>
1169
- </form>
1170
- </div>
1171
-
1172
- </div><!-- #dashboard -->
1173
-
1174
- <div id="configuration">
1175
- <h3><?php
1176
  esc_html_e( 'Settings', 'delete-duplicate-posts' );
1177
  ?></h3>
1178
- <p>
1179
- <?php
1180
  $nextscheduled = wp_next_scheduled( 'ddp_cron' );
1181
 
1182
  if ( $nextscheduled ) {
1183
  ?>
1184
- <div class="notice notice-info is-dismissible">
1185
- <h3><span class="dashicons dashicons-saved"></span> Automatically Deleting Duplicates</h3>
1186
- <?php
1187
  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>' ;
1188
  echo '<p class="center">' ;
1189
  echo sprintf(
@@ -1194,27 +1318,27 @@ if ( !class_exists( 'Delete_Duplicate_Posts' ) ) {
1194
  ) ;
1195
  echo '</p>' ;
1196
  ?>
1197
- </div>
1198
- <?php
1199
  }
1200
 
1201
  ?>
1202
- </p>
1203
- <form method="post" id="delete_duplicate_posts_options">
1204
- <?php
1205
  wp_nonce_field( 'ddp-update-options' );
1206
  ?>
1207
- <table width="100%" cellspacing="2" cellpadding="5" class="form-table">
1208
-
1209
-
1210
-
1211
-
1212
- <tr valign="top">
1213
- <th><label for="ddp_enabled"><?php
1214
  esc_html_e( 'Which post types?:', 'delete-duplicate-posts' );
1215
- ?></label></th>
1216
- <td>
1217
- <?php
 
1218
  $builtin = array( 'post', 'page', 'attachment' );
1219
  $args = array(
1220
  'public' => true,
@@ -1228,8 +1352,8 @@ if ( !class_exists( 'Delete_Duplicate_Posts' ) ) {
1228
 
1229
  if ( $post_types ) {
1230
  ?>
1231
- <ul class="radio">
1232
- <?php
1233
  $step = 0;
1234
  if ( !is_array( $checked_post_types ) ) {
1235
  $checked_post_types = array();
@@ -1237,45 +1361,57 @@ if ( !class_exists( 'Delete_Duplicate_Posts' ) ) {
1237
  foreach ( $post_types as $pt ) {
1238
  $checked = array_search( $pt, $checked_post_types, true );
1239
  ?>
1240
- <li>
1241
- <input type="checkbox" name="ddp_pts[]" id="ddp_pt-<?php
1242
  echo esc_attr( $step ) ;
1243
- ?>" value="<?php
 
1244
  echo esc_html( $pt ) ;
1245
- ?>"
1246
- <?php
1247
  if ( false !== $checked ) {
1248
  echo ' checked' ;
1249
  }
1250
- ?>
1251
- />
1252
- <label for="ddp_pt-<?php
1253
  echo esc_attr( $step ) ;
1254
  ?>"><?php
1255
  echo esc_html( $pt ) ;
1256
  ?></label>
1257
- </li>
1258
- <?php
 
 
 
 
 
 
 
 
 
 
1259
  $step++;
1260
  }
1261
  ?>
1262
- </ul>
1263
- <?php
1264
  }
1265
 
1266
  ?>
1267
- <p class="description"><?php
 
1268
  esc_html_e( 'Choose which post types to scan for duplicates.', 'delete-duplicate-posts' );
1269
- ?></p>
1270
- </td>
1271
- </tr>
1272
-
1273
- <tr>
1274
- <th><label for="ddp_enabled"><?php
 
1275
  esc_html_e( 'Post status', 'delete-duplicate-posts' );
1276
- ?></label></th>
1277
- <td>
1278
- <?php
 
1279
  $stati = array(
1280
  'publish' => (object) array(
1281
  'label' => 'Published',
@@ -1286,122 +1422,128 @@ if ( !class_exists( 'Delete_Duplicate_Posts' ) ) {
1286
 
1287
  if ( $stati ) {
1288
  ?>
1289
- <ul class="radio">
1290
- <?php
1291
  $staticount = count( $stati );
1292
  foreach ( $stati as $key => $st ) {
1293
 
1294
  if ( $st->show_in_admin_status_list ) {
1295
  $checked = array_search( $key, $checked_post_stati, true );
1296
  ?>
1297
- <li>
1298
- <input type="checkbox" name="ddp_pstati[]" id="ddp_pstatus-<?php
1299
  echo esc_attr( $key ) ;
1300
- ?>" value="<?php
 
1301
  echo esc_attr( $key ) ;
1302
- ?>"
1303
- <?php
1304
  if ( false !== $checked ) {
1305
  echo ' checked' ;
1306
  }
1307
- ?>
1308
- <?php
1309
  if ( 1 === $staticount ) {
1310
  echo ' disabled' ;
1311
  }
1312
- ?> />
1313
- <label for="ddp_pstatus-<?php
 
1314
  echo esc_attr( $key ) ;
1315
  ?>"><?php
1316
  echo esc_html( $key . ' (' . $st->label . ')' ) ;
1317
  ?></label>
1318
- </li>
1319
- <?php
1320
  $step++;
1321
  }
1322
 
1323
  }
1324
  ?>
1325
- </ul>
1326
- <?php
1327
  }
1328
 
1329
  ?>
1330
- </td>
1331
-
1332
-
1333
- </tr>
1334
- <?php
1335
  $comparemethod = 'titlecompare';
1336
  global $ddp_fs ;
1337
  ?>
1338
- <tr valign="top">
1339
- <th><?php
1340
  esc_html_e( 'Comparison Method', 'delete-duplicate-posts' );
1341
  ?></th>
1342
- <td>
1343
- <ul class="ddpcomparemethod">
1344
-
1345
- <li>
1346
- <label>
1347
- <input type="radio" name="ddp_method" value="titlecompare" <?php
 
1348
  checked( 'titlecompare', $comparemethod );
1349
- ?> /> <?php
 
1350
  esc_html_e( 'Compare by title (default)', 'delete-duplicate-posts' );
1351
  ?>
1352
- <span class="optiondesc"><?php
 
1353
  esc_html_e( 'Looks at the title of the post itself.', 'delete-duplicate-posts' );
1354
  ?></span>
1355
- </label>
1356
-
1357
- </li>
1358
-
1359
- <?php
1360
  global $ddp_fs ;
1361
  ?>
1362
- </ul>
1363
- </td>
1364
- </tr>
1365
- <tr>
1366
- <th><label for="ddp_keep"><?php
 
1367
  esc_html_e( 'Delete which posts?:', 'delete-duplicate-posts' );
1368
- ?></label></th><td>
1369
-
1370
- <select name="ddp_keep" id="ddp_keep">
1371
- <option value="oldest"
1372
- <?php
1373
  if ( 'oldest' === $options['ddp_keep'] ) {
1374
  echo 'selected="selected"' ;
1375
  }
1376
- ?>
1377
- ><?php
1378
  esc_html_e( 'Keep oldest', 'delete-duplicate-posts' );
1379
  ?></option>
1380
- <option value="latest"
1381
- <?php
1382
  if ( 'latest' === $options['ddp_keep'] ) {
1383
  echo 'selected="selected"' ;
1384
  }
1385
- ?>
1386
- ><?php
1387
  esc_html_e( 'Keep latest', 'delete-duplicate-posts' );
1388
  ?></option>
1389
- </select>
1390
- <p class="description"><?php
 
1391
  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' );
1392
- ?></p>
1393
- </td>
1394
- </tr>
1395
-
1396
 
1397
 
1398
 
1399
- <tr>
1400
- <th><label for="ddp_resultslimit"><?php
 
 
1401
  esc_html_e( 'Find how many duplicates:', 'delete-duplicate-posts' );
1402
- ?></label></th><td>
1403
-
1404
- <?php
 
 
1405
  $dupe_options = array(
1406
  0 => __( 'No limit', 'delete-duplicate-posts' ),
1407
  10000 => number_format_i18n( '10000' ),
@@ -1415,207 +1557,223 @@ if ( !class_exists( 'Delete_Duplicate_Posts' ) ) {
1415
  10 => '10',
1416
  );
1417
  ?>
1418
- <select name="ddp_resultslimit" id="ddp_resultslimit">
1419
- <?php
1420
  foreach ( $dupe_options as $key => $label ) {
1421
  ?>
1422
- <option value="<?php
1423
  echo $key ;
1424
  ?>" <?php
1425
  selected( $options['ddp_resultslimit'], $key );
1426
- ?>><?php
 
1427
  echo $label ;
1428
  ?></option>
1429
- <?php
1430
  }
1431
  ?>
1432
- </select>
1433
 
1434
- <p class="description"><?php
 
1435
  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' );
1436
- ?></p>
1437
- </td>
1438
- </tr>
1439
-
1440
- <?php
1441
- /*
1442
-
1443
- <tr valign="top">
1444
- <th><label for="ddp_limit"><?php esc_html_e( 'Delete at maximum :', 'delete-duplicate-posts' ); ?></label></th><td><select name="ddp_limit">
1445
- <?php
1446
- for ( $x = 1; $x <= 10; $x++ ) {
1447
- $val = ( $x * 50 );
1448
- echo "<option value='" . esc_attr( $val ) . "' ";
1449
- if ( $options['ddp_limit'] === $val ) {
1450
- echo 'selected';
1451
- }
1452
- echo '>' . esc_attr( $val ) . '</option>';
1453
- }
1454
  ?>
1455
- </select>
1456
- <?php esc_html_e( 'duplicates.', 'delete-duplicate-posts' ); ?>
1457
- <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>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1458
  </td>
1459
  </tr>
1460
  */
1461
  ?>
1462
-
1463
 
1464
 
1465
- <tr>
1466
- <td colspan="2"><hr></td>
1467
- </tr>
1468
-
1469
- <tr valign="top">
1470
- <th><?php
 
 
 
1471
  esc_html_e( 'Enable automatic deletion?:', 'delete-duplicate-posts' );
1472
  ?>
1473
-
1474
- </th>
1475
- <td><label for="ddp_enabled">
1476
- <input type="checkbox" id="ddp_enabled" name="ddp_enabled"
1477
- <?php
1478
  if ( true === $options['ddp_enabled'] ) {
1479
  echo 'checked="checked"' ;
1480
  }
1481
- ?>
1482
- >
1483
- <p class="description"><?php
1484
  esc_html_e( 'Clean duplicates automatically.', 'delete-duplicate-posts' );
1485
  ?></p>
1486
- </label>
1487
- </td>
1488
- </tr>
1489
-
1490
-
1491
- <tr>
1492
- <th><label for="ddp_schedule"><?php
1493
  esc_html_e( 'How often?:', 'delete-duplicate-posts' );
1494
- ?></label></th><td>
1495
-
1496
- <select name="ddp_schedule" id="ddp_schedule">
1497
- <?php
 
 
1498
  $schedules = wp_get_schedules();
1499
  if ( $schedules ) {
1500
  foreach ( $schedules as $key => $sch ) {
1501
  ?>
1502
- <option value="<?php
1503
  echo esc_attr( $key ) ;
1504
- ?>"
1505
- <?php
1506
  if ( isset( $options['ddp_schedule'] ) && esc_attr( $key ) === $options['ddp_schedule'] ) {
1507
  echo esc_html( 'selected="selected"' ) ;
1508
  }
1509
- ?>
1510
- ><?php
1511
  echo esc_html( $sch['display'] ) ;
1512
  ?></option>
1513
- <?php
1514
  }
1515
  }
1516
  ?>
1517
- </select>
1518
- <p class="description"><?php
 
1519
  esc_html_e( 'How often should the cron job run?', 'delete-duplicate-posts' );
1520
  ?></p>
1521
- </td>
1522
- </tr>
1523
-
1524
-
1525
-
1526
- <tr>
1527
- <td colspan="2"><hr></td>
1528
- </tr>
1529
-
1530
- <tr>
1531
- <th><?php
 
 
1532
  esc_html_e( 'Send status mail?:', 'delete-duplicate-posts' );
1533
  ?></th>
1534
- <td>
1535
- <label for="ddp_statusmail">
1536
- <input type="checkbox" id="ddp_statusmail" name="ddp_statusmail"
1537
- <?php
1538
  if ( isset( $options['ddp_statusmail'] ) && true === $options['ddp_statusmail'] ) {
1539
  echo 'checked="checked"' ;
1540
  }
1541
- ?>
1542
- <p class="description"><?php
1543
  esc_html_e( 'Sends a status email if duplicates have been found.', 'delete-duplicate-posts' );
1544
- ?></p>
1545
- </label>
1546
- </td>
1547
- </tr>
1548
-
1549
- <tr>
1550
- <th><?php
 
1551
  esc_html_e( 'Email recipient:', 'delete-duplicate-posts' );
1552
  ?></th>
1553
- <td>
1554
- <label for="ddp_statusmail_recipient">
1555
-
1556
- <input type="text" class="regular-text" id="ddp_statusmail_recipient" name="ddp_statusmail_recipient" value="<?php
 
 
1557
  echo esc_html( $options['ddp_statusmail_recipient'] ) ;
1558
  ?>">
1559
- <p class="description"><?php
 
1560
  esc_html_e( 'Who should get the notification email.', 'delete-duplicate-posts' );
1561
  ?></p>
1562
- </label>
1563
- </td>
1564
- </tr>
1565
-
1566
-
1567
-
1568
-
1569
- <th colspan=2><input type="submit" class="button-primary" name="delete_duplicate_posts_save" value="<?php
 
1570
  esc_html_e( 'Save Settings', 'delete-duplicate-posts' );
1571
  ?>" /></th>
1572
- </tr>
1573
-
1574
- </table>
1575
-
1576
- </form>
1577
- </div><!-- #configuration -->
1578
-
1579
-
1580
- <div id="log">
1581
-
1582
- <h3><?php
1583
  esc_html_e( 'The Log', 'delete-duplicate-posts' );
1584
  ?></h3>
1585
- <div class="spinner is-active"></div>
1586
- <ul class="large-text" name="ddp_log" id="ddp_log">
1587
- </ul>
1588
-
1589
- </div>
1590
- <p>
1591
- <form method="post" id="ddp_clearlog">
1592
- <?php
1593
  wp_nonce_field( 'ddp_clearlog_nonce' );
1594
  ?>
1595
-
1596
- <input class="button-secondary" type="submit" name="ddp_clearlog" value="<?php
 
1597
  esc_html_e( 'Reset log', 'delete-duplicate-posts' );
1598
  ?>" />
1599
- </form>
1600
- </p>
1601
-
1602
- </div><!-- #ddp_container -->
1603
-
1604
- <?php
1605
  include_once 'sidebar.php';
1606
  ?>
1607
-
1608
- <?php
1609
  if ( function_exists( 'ddp_fs' ) ) {
1610
  global $ddp_fs ;
1611
  }
1612
  ?>
1613
-
1614
- </div>
1615
- </div>
1616
-
1617
- </div>
1618
- <?php
1619
  }
1620
 
1621
  }
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.7
9
  Author: cleverplugins.com
10
  Author URI: https://cleverplugins.com
11
  Min WP Version: 4.7
243
  public static function ddp_action_admin_notices()
244
  {
245
  $screen = get_current_screen();
246
+ if ( PAnD::is_admin_notice_active( 'ddp-newsletter-14' ) && in_array( $screen->id, array( 'dashboard', 'tools_page_delete-duplicate-posts', 'plugins' ) ) ) {
247
+ ?>
248
+ <div id="cp-ddp-newsletter" data-dismissible="ddp-newsletter-14" class="updated notice notice-success is-dismissible">
249
+ <h3>Please sign up for the cleverplugins.com newsletter</h3>
250
+ <form class="ml-block-form" action="https://static.mailerlite.com/webforms/submit/l2v7x5" data-code="l2v7x5"
251
+ method="post" target="_blank">
252
+ <table>
253
+ <tbody>
254
+ <tr>
255
+ <td>
256
+ <div class="ml-field-group ml-field-name">
257
+ <input type="text" class="regular-text" data-inputmask="" name="fields[name]" placeholder="Name" autocomplete="name" style="width:15em;">
258
+ </div>
259
+ </td>
260
+ <td>
261
+ <div class="ml-field-group ml-field-email ml-validate-email ml-validate-required">
262
+ <input type="email" class="regular-text required email" data-inputmask="" name="fields[email]" placeholder="Email"
263
+ autocomplete="email">
264
+ </div>
265
+ </td>
266
+ <td>
267
+ <button type="submit" class="button">Subscribe</button>
268
+ </td>
269
+ </tr>
270
+ <tr>
271
+ <td colspan="3">
272
+ <div class="privacy-policy">
273
+ <p>You can unsubscribe anytime. For more details, review our <a
274
+ href="https://cleverplugins.com/privacy-policy/" target="_blank">Privacy Policy</a>.</p>
275
+ </div>
276
+ </td>
277
+ </tr>
278
+ </table>
279
+ </table>
280
+ <input type="hidden" name="ml-submit" value="1">
281
+ <input type="hidden" name="anticsrf" value="true">
282
+ </form>
283
+ <p><small>Signup form is shown every 14 days until dismissed</small></p>
284
+ </div>
285
+ <?php
286
+ }
287
  if ( 'tools_page_delete-duplicate-posts' !== $screen->id ) {
288
  return;
289
  }
293
  if ( ddp_fs()->is_anonymous() && ddp_fs()->is_not_paying() && ddp_fs()->has_api_connectivity() ) {
294
  if ( !is_multisite() || is_multisite() && is_network_admin() ) {
295
 
296
+ if ( PAnD::is_admin_notice_active( 'cp-ddp-improve-notice-7' ) ) {
297
  ?>
298
+ <div id="cp-ddp-freemius" data-dismissible="cp-ddp-improve-notice-7" class="notice notice-success is-dismissible">
299
+ <h3><?php
300
  esc_html_e( 'Help Delete Duplicate Posts improve!', 'delete-duplicate-posts' );
301
  ?></h3>
302
+
303
+ <p>
304
+ <?php
305
  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>' ;
306
+ ?>
307
+ </p>
308
+
309
+ <p>
310
+ <?php
311
  // translators:
312
  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>' );
313
  ?>
314
+ </p>
315
+ <p>
316
+ <a href="javascript:;" class="button button-primary" onclick="cp_ddp_freemius_opt_in(this)"
317
+ data-opt="yes"><?php
318
  esc_html_e( 'Sure, opt-in', 'delete-duplicate-posts' );
319
  ?></a>
320
+
321
+ <a href="javascript:;"
322
+ class="button dismiss-this"><?php
323
  esc_html_e( 'No, thank you', 'delete-duplicate-posts' );
324
  ?></a>
325
+ </p>
326
+ <input type="hidden" id="cp-ddp-freemius-opt-nonce"
327
+ value="<?php
328
  echo esc_attr( wp_create_nonce( 'cp-ddp-freemius-opt' ) ) ;
329
  ?>" />
330
+
331
+ </div>
332
+ <?php
333
  }
334
 
335
  }
336
  }
337
  }
338
+ // Leave if it is not time to ask for review.
339
  if ( !PAnD::is_admin_notice_active( 'ddp-leavereview-14' ) ) {
340
  return;
341
  }
344
  if ( false !== $totaldeleted && 0 < $totaldeleted ) {
345
  $totaldeleted = number_format_i18n( $totaldeleted );
346
  ?>
347
+ <div id="cp-ddp-reviewlink" data-dismissible="ddp-leavereview-14" class="updated notice notice-success is-dismissible">
348
+ <h3>
349
+ <?php
350
  // translators: Total number of deleted duplicates
351
  printf( esc_html__( '%s duplicates deleted!', 'delete-duplicate-posts' ), esc_html( $totaldeleted ) );
352
  ?>
353
+ </h3>
354
+ <p>
355
+ <?php
356
  // translators: Asking for a review text
357
  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 ) );
358
  ?>
359
+ </p>
360
+
361
+ <p>
362
+ <a href="https://wordpress.org/support/plugin/delete-duplicate-posts/reviews/?filter=5#new-post"
363
+ class="cp-ddp-dismiss-review-notice cp-ddp-reviewlink button-primary dismiss-this" target="_blank"
364
+ rel="noopener">Ok, you deserve it</a>
365
+ <span class="dashicons dashicons-calendar"></span><a href="#" class="cp-ddp-dismiss-review-notice dismiss-this"
366
+ target="_blank" rel="noopener">Nope, maybe later</a>
367
+ <span class="dashicons dashicons-smiley"></span><a href="#" class="cp-ddp-dismiss-review-notice dismiss-this"
368
+ target="_blank" rel="noopener">I already did</a>
369
+ </p>
370
+ </div>
371
+ <?php
372
  }
373
 
374
  }
465
  self::return_duplicates( $return );
466
  }
467
 
468
+ /**
469
+ * Converts a number to relevant unit size
470
+ *
471
+ * @author Lars Koudal
472
+ * @since v0.0.1
473
+ * @version v1.0.0 Thursday, June 24th, 2021.
474
+ * @param mixed $size
475
+ * @return void
476
+ */
477
+ public static function pretty_value( $size )
478
+ {
479
+ $unit = array(
480
+ 'b',
481
+ 'kb',
482
+ 'mb',
483
+ 'gb',
484
+ 'tb',
485
+ 'pb'
486
+ );
487
+ return round( $size / pow( 1024, $i = floor( log( $size, 1024 ) ) ), 2 ) . ' ' . $unit[$i];
488
+ }
489
+
490
  /**
491
  * Returns duplicates based on current settings - internal, not used via AJAX
492
  *
554
  if ( 'latest' === $order ) {
555
  $minmax = 'MAX(id)';
556
  }
557
+ $ddpstatuscnt = array();
558
  $dupescount = 0;
559
 
560
  if ( '' !== $ddp_pts ) {
561
  $thisquery = false;
562
+ // **** Compare by title ****
563
 
564
  if ( 'titlecompare' === $comparemethod ) {
565
  // @todo - prepare - not urgent, there is no way to exploit this query
 
 
566
  $resultsoutput = '';
567
  if ( 0 > $resultslimit ) {
568
  $resultsoutput = ' LIMIT ' . intval( $resultslimit );
569
  }
570
+ $thisquery = "SELECT t1.ID, t1.post_title, t1.post_type, t1.post_status, save_this_post_id\n\t\t\t\t\t\t\t\t\t\t\tFROM {$table_name} AS t1 INNER 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 . ") \n\t\t\t\t\t\t\t\t\t\t\t\tAND post_status IN (" . $post_stati . ") \n\t\t\t\t\t\t\t\t\t\t\t\tGROUP BY post_title HAVING COUNT(*)>1 LIMIT 0,100\n\t\t\t\t\t\t\t\t\t\t\t\t) AS t2 ON t1.post_title = t2.post_title\n\t\t\t\t\t\t\t\t\t\t\t\tAND post_status IN (" . $post_stati . ") \n\t\t\t\t\t\t\t\t\t\t\t\tORDER BY t1.post_title, t1.post_date DESC";
571
+ $json_response['lookup_query'] = $thisquery;
 
 
 
 
 
 
572
  $dupes = $wpdb->get_results( $thisquery, ARRAY_A );
573
+ $json_response['lookup_error'] = htmlspecialchars( $wpdb->last_error, ENT_QUOTES );
574
+
575
+ if ( $wpdb->last_error !== '' ) {
576
+ $last_error = htmlspecialchars( $wpdb->last_error, ENT_QUOTES );
577
+ self::log( 'Look up error: ' . $last_error );
578
+ }
579
+
580
 
581
  if ( $dupes ) {
582
  $dupescount = count( $dupes );
583
  $json_response['dupescount'] = $dupescount;
584
  $stepcount = 0;
585
  foreach ( $dupes as $dupe ) {
586
+ $mystatus = $dupe['post_status'];
587
+
588
+ if ( isset( $ddpstatuscnt[$mystatus] ) ) {
589
+ $ddpstatuscnt[$mystatus] = $ddpstatuscnt[$mystatus] + 1;
590
+ } else {
591
+ $ddpstatuscnt[$mystatus] = 1;
592
+ }
593
+
594
+
595
+ if ( $dupe['ID'] != $dupe['save_this_post_id'] ) {
596
+ $dupedetails = array(
597
+ 'ID' => $dupe['ID'],
598
+ 'permalink' => get_permalink( $dupe['ID'] ),
599
+ 'title' => $dupe['post_title'],
600
+ 'type' => $dupe['post_type'],
601
+ 'orgID' => $dupe['save_this_post_id'],
602
+ 'orgtitle' => $dupe['post_title'],
603
+ 'orgpermalink' => get_permalink( $dupe['save_this_post_id'] ),
604
+ 'status' => $dupe['post_status'],
605
+ 'why' => '',
606
+ );
607
+ $json_response['dupes'][] = $dupedetails;
608
+ }
609
+
610
  $stepcount++;
611
  }
612
+ $json_response['dupescount'] = count( $json_response['dupes'] );
613
  }
614
 
615
  }
617
  if ( !isset( $json_response['dupescount'] ) ) {
618
  $json_response['dupescount'] = 0;
619
  }
620
+ $statusdata = '';
621
+
622
+ if ( is_array( $ddpstatuscnt ) && count( $ddpstatuscnt ) > 1 ) {
623
+ $statusdata .= '(';
624
+ foreach ( $ddpstatuscnt as $key => $dsc ) {
625
+ $statusdata .= $key . ': ' . number_format_i18n( $dsc ) . ', ';
626
+ }
627
+ $statusdata = rtrim( $statusdata, ', ' );
628
+ $statusdata .= ')';
629
+ }
630
+
631
  $return_duplicates_time = self::timerstop( 'return_duplicates' );
632
+ // @todo memory usage
633
+ self::log( $json_response['dupescount'] . ' duplicates found in ' . $return_duplicates_time . ' sec. ' . $statusdata . ' Mem usage: ' . self::pretty_value( memory_get_peak_usage( true ) ) );
634
  } else {
635
  $json_response['msg'] = __( 'Error: Choose post types to check.', 'delete-duplicate-posts' );
636
  $return_duplicates_time = self::timerstop( 'return_duplicates' );
656
  wp_send_json_success( $json_response );
657
  }
658
 
659
+ /**
660
+ * create_redirect. @todo @pending
661
+ *
662
+ * @author Lars Koudal
663
+ * @since v0.0.1
664
+ * @version v1.0.0 Friday, July 2nd, 2021.
665
+ * @access public static
666
+ * @param mixed $inurl
667
+ * @param mixed $targeturl
668
+ * @param integer $code Default: 301
669
+ * @return void
670
+ */
671
  public static function create_redirect( $inurl, $targeturl, $code = 301 )
672
  {
673
  global $wpdb ;
674
  // @todo - future
675
  }
676
 
677
+ /**
678
+ * Return default options
679
+ *
680
+ * @author Lars Koudal
681
+ * @since v0.0.1
682
+ * @version v1.0.0 Friday, July 2nd, 2021.
683
+ * @access public static
684
+ * @return mixed
685
+ */
686
  public static function default_options()
687
  {
688
  $defaults = array(
826
 
827
  if ( $manualrun > 0 ) {
828
  ?>
829
+ <div class="notice notice-success">
830
+ <p>
831
+ <?php
832
  // translators:
833
  printf( esc_html__( 'A total of %s duplicate posts were deleted.', 'delete-duplicate-posts' ), intval( $dispcount ) );
834
  ?>
835
+ </p>
836
+ </div>
837
+ <?php
838
  }
839
 
840
  // manualrun
911
  $total = (int) $wpdb->get_var( "SELECT COUNT(*) FROM `{$ddp_logtable}`;" );
912
  // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared
913
 
914
+ if ( $total > 1000 ) {
915
  $targettime = $wpdb->get_var( "SELECT `datime` from `{$ddp_logtable}` order by `datime` DESC limit 500,1;" );
916
  // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared
917
+ $wpdb->query( $wpdb->prepare( "DELETE from `{$ddp_logtable}` where `datime` < %s", $targettime ) );
 
918
  }
919
 
920
  }
1195
  $name = $pluginfo['Name'];
1196
  $options = self::get_options();
1197
  ?>
1198
+
1199
+ <div class="wrap">
1200
+
1201
+ <h2>Delete Duplicate Posts <span>v. <?php
1202
  echo esc_html( self::get_plugin_version() ) ;
1203
+ ?></span></h2>
1204
+
1205
+ <div class="ddp_content_wrapper">
1206
+ <div class="ddp_content_cell">
1207
+ <div id="ddp_container">
1208
+ <div id="dashboard">
1209
+ <?php
1210
 
1211
  if ( $options['ddp_enabled'] ) {
1212
  $interval = $options['ddp_schedule'];
1238
 
1239
  $totaldeleted = get_option( 'ddp_deleted_duplicates' );
1240
  ?>
1241
+ <div class="statusdiv">
1242
+ <div class="spinner is-active"></div>
1243
+ <div class="statusmessage"></div>
1244
+ <div class="dupelist">
1245
+ <table class="wp-list-table widefat fixed striped posts duplicatetable" cellspacing="0">
1246
+ <thead>
1247
+ <tr>
1248
+ <td id="cb" class="manage-column column-cb check-column"><label class="screen-reader-text"
1249
+ for="cb-select-all-1">Select All</label><input id="cb-select-all-1" type="checkbox"></td>
1250
+ <th><?php
1251
  esc_html_e( 'Duplicate', 'delete-duplicate-posts' );
1252
  ?></th>
1253
+ <th><?php
1254
  esc_html_e( 'Original', 'delete-duplicate-posts' );
1255
  ?></th>
1256
+ </tr>
1257
+ </thead>
1258
+ <tbody id="listofduplicates">
1259
+ </tbody>
1260
+
1261
+ <tfoot>
1262
+ <tr>
1263
+ <td id="cb" class="manage-column column-cb check-column"><label class="screen-reader-text"
1264
+ for="cb-select-all-1">Select All</label><input id="cb-select-all-1" type="checkbox"></td>
1265
+ <th><?php
1266
  esc_html_e( 'Duplicate', 'delete-duplicate-posts' );
1267
  ?></th>
1268
+ <th><?php
1269
  esc_html_e( 'Original', 'delete-duplicate-posts' );
1270
  ?></th>
1271
+ </tr>
1272
+ </tfoot>
1273
+ </table>
1274
+ </div>
1275
+ <form>
1276
+ <?php
1277
  wp_nonce_field( 'ddp-buttons' );
1278
  ?>
1279
+ <table id="ddp_buttons">
1280
+ <tr>
1281
+ <td><input type="submit" name="deleteduplicateposts_resetview" id="deleteduplicateposts_resetview"
1282
+ class="button button-small button-secondary"
1283
+ value="<?php
1284
  esc_html_e( 'Refresh list', 'delete-duplicate-posts' );
1285
+ ?>" disabled /></td>
1286
+ <td><input type="submit" name="deleteduplicateposts_deleteall" id="deleteduplicateposts_deleteall"
1287
+ class="button button-small button-primary"
1288
+ value="<?php
1289
  esc_html_e( 'Delete duplicates', 'delete-duplicate-posts' );
1290
+ ?>" disabled /></td>
1291
+ </tr>
1292
+ </table>
1293
+ </form>
1294
+ </div>
1295
+
1296
+ </div><!-- #dashboard -->
1297
+
1298
+ <div id="configuration">
1299
+ <h3><?php
1300
  esc_html_e( 'Settings', 'delete-duplicate-posts' );
1301
  ?></h3>
1302
+ <p>
1303
+ <?php
1304
  $nextscheduled = wp_next_scheduled( 'ddp_cron' );
1305
 
1306
  if ( $nextscheduled ) {
1307
  ?>
1308
+ <div class="notice notice-info is-dismissible">
1309
+ <h3><span class="dashicons dashicons-saved"></span> Automatically Deleting Duplicates</h3>
1310
+ <?php
1311
  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>' ;
1312
  echo '<p class="center">' ;
1313
  echo sprintf(
1318
  ) ;
1319
  echo '</p>' ;
1320
  ?>
1321
+ </div>
1322
+ <?php
1323
  }
1324
 
1325
  ?>
1326
+ </p>
1327
+ <form method="post" id="delete_duplicate_posts_options">
1328
+ <?php
1329
  wp_nonce_field( 'ddp-update-options' );
1330
  ?>
1331
+ <table width="100%" cellspacing="2" cellpadding="5" class="form-table">
1332
+
1333
+
1334
+ <tr valign="top">
1335
+ <th><label
1336
+ for="ddp_enabled"><?php
 
1337
  esc_html_e( 'Which post types?:', 'delete-duplicate-posts' );
1338
+ ?></label>
1339
+ </th>
1340
+ <td>
1341
+ <?php
1342
  $builtin = array( 'post', 'page', 'attachment' );
1343
  $args = array(
1344
  'public' => true,
1352
 
1353
  if ( $post_types ) {
1354
  ?>
1355
+ <ul class="radio">
1356
+ <?php
1357
  $step = 0;
1358
  if ( !is_array( $checked_post_types ) ) {
1359
  $checked_post_types = array();
1361
  foreach ( $post_types as $pt ) {
1362
  $checked = array_search( $pt, $checked_post_types, true );
1363
  ?>
1364
+ <li>
1365
+ <input type="checkbox" name="ddp_pts[]" id="ddp_pt-<?php
1366
  echo esc_attr( $step ) ;
1367
+ ?>"
1368
+ value="<?php
1369
  echo esc_html( $pt ) ;
1370
+ ?>" <?php
 
1371
  if ( false !== $checked ) {
1372
  echo ' checked' ;
1373
  }
1374
+ ?> />
1375
+ <label for="ddp_pt-<?php
 
1376
  echo esc_attr( $step ) ;
1377
  ?>"><?php
1378
  echo esc_html( $pt ) ;
1379
  ?></label>
1380
+ <?php
1381
+ // Count for each post type
1382
+ $postinfo = wp_count_posts( $pt );
1383
+ $othercount = 0;
1384
+ foreach ( $postinfo as $pi ) {
1385
+ $othercount = $othercount + intval( $pi );
1386
+ }
1387
+ // translators: Total number of deleted duplicates
1388
+ echo '<small>' . sprintf( esc_html__( '(%s total found)', 'delete-duplicate-posts' ), esc_html( number_format_i18n( $othercount ) ) ) . '</small>' ;
1389
+ ?>
1390
+ </li>
1391
+ <?php
1392
  $step++;
1393
  }
1394
  ?>
1395
+ </ul>
1396
+ <?php
1397
  }
1398
 
1399
  ?>
1400
+ <p class="description">
1401
+ <?php
1402
  esc_html_e( 'Choose which post types to scan for duplicates.', 'delete-duplicate-posts' );
1403
+ ?>
1404
+ </p>
1405
+ </td>
1406
+ </tr>
1407
+
1408
+ <tr>
1409
+ <th><label for="ddp_enabled"><?php
1410
  esc_html_e( 'Post status', 'delete-duplicate-posts' );
1411
+ ?></label>
1412
+ </th>
1413
+ <td>
1414
+ <?php
1415
  $stati = array(
1416
  'publish' => (object) array(
1417
  'label' => 'Published',
1422
 
1423
  if ( $stati ) {
1424
  ?>
1425
+ <ul class="radio">
1426
+ <?php
1427
  $staticount = count( $stati );
1428
  foreach ( $stati as $key => $st ) {
1429
 
1430
  if ( $st->show_in_admin_status_list ) {
1431
  $checked = array_search( $key, $checked_post_stati, true );
1432
  ?>
1433
+ <li>
1434
+ <input type="checkbox" name="ddp_pstati[]" id="ddp_pstatus-<?php
1435
  echo esc_attr( $key ) ;
1436
+ ?>"
1437
+ value="<?php
1438
  echo esc_attr( $key ) ;
1439
+ ?>" <?php
 
1440
  if ( false !== $checked ) {
1441
  echo ' checked' ;
1442
  }
1443
+ ?> <?php
 
1444
  if ( 1 === $staticount ) {
1445
  echo ' disabled' ;
1446
  }
1447
+ ?> />
1448
+ <label
1449
+ for="ddp_pstatus-<?php
1450
  echo esc_attr( $key ) ;
1451
  ?>"><?php
1452
  echo esc_html( $key . ' (' . $st->label . ')' ) ;
1453
  ?></label>
1454
+ </li>
1455
+ <?php
1456
  $step++;
1457
  }
1458
 
1459
  }
1460
  ?>
1461
+ </ul>
1462
+ <?php
1463
  }
1464
 
1465
  ?>
1466
+ </td>
1467
+
1468
+
1469
+ </tr>
1470
+ <?php
1471
  $comparemethod = 'titlecompare';
1472
  global $ddp_fs ;
1473
  ?>
1474
+ <tr valign="top">
1475
+ <th><?php
1476
  esc_html_e( 'Comparison Method', 'delete-duplicate-posts' );
1477
  ?></th>
1478
+ <td>
1479
+ <ul class="ddpcomparemethod">
1480
+
1481
+ <li>
1482
+ <label>
1483
+ <input type="radio" name="ddp_method" value="titlecompare"
1484
+ <?php
1485
  checked( 'titlecompare', $comparemethod );
1486
+ ?> />
1487
+ <?php
1488
  esc_html_e( 'Compare by title (default)', 'delete-duplicate-posts' );
1489
  ?>
1490
+ <span
1491
+ class="optiondesc"><?php
1492
  esc_html_e( 'Looks at the title of the post itself.', 'delete-duplicate-posts' );
1493
  ?></span>
1494
+ </label>
1495
+
1496
+ </li>
1497
+
1498
+ <?php
1499
  global $ddp_fs ;
1500
  ?>
1501
+ </ul>
1502
+ </td>
1503
+ </tr>
1504
+ <tr>
1505
+ <th><label
1506
+ for="ddp_keep"><?php
1507
  esc_html_e( 'Delete which posts?:', 'delete-duplicate-posts' );
1508
+ ?></label></th>
1509
+ <td>
1510
+
1511
+ <select name="ddp_keep" id="ddp_keep">
1512
+ <option value="oldest" <?php
1513
  if ( 'oldest' === $options['ddp_keep'] ) {
1514
  echo 'selected="selected"' ;
1515
  }
1516
+ ?>><?php
 
1517
  esc_html_e( 'Keep oldest', 'delete-duplicate-posts' );
1518
  ?></option>
1519
+ <option value="latest" <?php
 
1520
  if ( 'latest' === $options['ddp_keep'] ) {
1521
  echo 'selected="selected"' ;
1522
  }
1523
+ ?>><?php
 
1524
  esc_html_e( 'Keep latest', 'delete-duplicate-posts' );
1525
  ?></option>
1526
+ </select>
1527
+ <p class="description">
1528
+ <?php
1529
  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' );
1530
+ ?>
1531
+ </p>
1532
+ </td>
1533
+ </tr>
1534
 
1535
 
1536
 
1537
+
1538
+ <tr>
1539
+ <th><label
1540
+ for="ddp_resultslimit"><?php
1541
  esc_html_e( 'Find how many duplicates:', 'delete-duplicate-posts' );
1542
+ ?></label>
1543
+ </th>
1544
+ <td>
1545
+
1546
+ <?php
1547
  $dupe_options = array(
1548
  0 => __( 'No limit', 'delete-duplicate-posts' ),
1549
  10000 => number_format_i18n( '10000' ),
1557
  10 => '10',
1558
  );
1559
  ?>
1560
+ <select name="ddp_resultslimit" id="ddp_resultslimit">
1561
+ <?php
1562
  foreach ( $dupe_options as $key => $label ) {
1563
  ?>
1564
+ <option value="<?php
1565
  echo $key ;
1566
  ?>" <?php
1567
  selected( $options['ddp_resultslimit'], $key );
1568
+ ?>>
1569
+ <?php
1570
  echo $label ;
1571
  ?></option>
1572
+ <?php
1573
  }
1574
  ?>
1575
+ </select>
1576
 
1577
+ <p class="description">
1578
+ <?php
1579
  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' );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1580
  ?>
1581
+ </p>
1582
+ </td>
1583
+ </tr>
1584
+
1585
+ <?php
1586
+ /*
1587
+
1588
+ <tr valign="top">
1589
+ <th><label for="ddp_limit"><?php esc_html_e( 'Delete at maximum :', 'delete-duplicate-posts' ); ?></label>
1590
+ </th>
1591
+ <td><select name="ddp_limit">
1592
+ <?php
1593
+ for ( $x = 1; $x <= 10; $x++ ) {
1594
+ $val = ( $x * 50 );
1595
+ echo "<option value='" . esc_attr( $val ) . "' ";
1596
+ if ( $options['ddp_limit'] === $val ) {
1597
+ echo 'selected';
1598
+ }
1599
+ echo '>' . esc_attr( $val ) . '</option>';
1600
+ }
1601
+ ?>
1602
+ </select>
1603
+ <?php esc_html_e( 'duplicates.', 'delete-duplicate-posts' ); ?>
1604
+ <p class="description">
1605
+ <?php esc_html_e( 'Setting a limit is a good idea, especially if your site is on a busy server.', 'delete-duplicate-posts' ); ?>
1606
+ </p>
1607
  </td>
1608
  </tr>
1609
  */
1610
  ?>
 
1611
 
1612
 
1613
+
1614
+ <tr>
1615
+ <td colspan="2">
1616
+ <hr>
1617
+ </td>
1618
+ </tr>
1619
+
1620
+ <tr valign="top">
1621
+ <th><?php
1622
  esc_html_e( 'Enable automatic deletion?:', 'delete-duplicate-posts' );
1623
  ?>
1624
+
1625
+ </th>
1626
+ <td><label for="ddp_enabled">
1627
+ <input type="checkbox" id="ddp_enabled" name="ddp_enabled" <?php
 
1628
  if ( true === $options['ddp_enabled'] ) {
1629
  echo 'checked="checked"' ;
1630
  }
1631
+ ?>>
1632
+ <p class="description">
1633
+ <?php
1634
  esc_html_e( 'Clean duplicates automatically.', 'delete-duplicate-posts' );
1635
  ?></p>
1636
+ </label>
1637
+ </td>
1638
+ </tr>
1639
+
1640
+
1641
+ <tr>
1642
+ <th><label for="ddp_schedule"><?php
1643
  esc_html_e( 'How often?:', 'delete-duplicate-posts' );
1644
+ ?></label>
1645
+ </th>
1646
+ <td>
1647
+
1648
+ <select name="ddp_schedule" id="ddp_schedule">
1649
+ <?php
1650
  $schedules = wp_get_schedules();
1651
  if ( $schedules ) {
1652
  foreach ( $schedules as $key => $sch ) {
1653
  ?>
1654
+ <option value="<?php
1655
  echo esc_attr( $key ) ;
1656
+ ?>" <?php
 
1657
  if ( isset( $options['ddp_schedule'] ) && esc_attr( $key ) === $options['ddp_schedule'] ) {
1658
  echo esc_html( 'selected="selected"' ) ;
1659
  }
1660
+ ?>><?php
 
1661
  echo esc_html( $sch['display'] ) ;
1662
  ?></option>
1663
+ <?php
1664
  }
1665
  }
1666
  ?>
1667
+ </select>
1668
+ <p class="description">
1669
+ <?php
1670
  esc_html_e( 'How often should the cron job run?', 'delete-duplicate-posts' );
1671
  ?></p>
1672
+ </td>
1673
+ </tr>
1674
+
1675
+
1676
+
1677
+ <tr>
1678
+ <td colspan="2">
1679
+ <hr>
1680
+ </td>
1681
+ </tr>
1682
+
1683
+ <tr>
1684
+ <th><?php
1685
  esc_html_e( 'Send status mail?:', 'delete-duplicate-posts' );
1686
  ?></th>
1687
+ <td>
1688
+ <label for="ddp_statusmail">
1689
+ <input type="checkbox" id="ddp_statusmail" name="ddp_statusmail" <?php
 
1690
  if ( isset( $options['ddp_statusmail'] ) && true === $options['ddp_statusmail'] ) {
1691
  echo 'checked="checked"' ;
1692
  }
1693
+ ?> <p
1694
+ class="description"><?php
1695
  esc_html_e( 'Sends a status email if duplicates have been found.', 'delete-duplicate-posts' );
1696
+ ?>
1697
+ </p>
1698
+ </label>
1699
+ </td>
1700
+ </tr>
1701
+
1702
+ <tr>
1703
+ <th><?php
1704
  esc_html_e( 'Email recipient:', 'delete-duplicate-posts' );
1705
  ?></th>
1706
+ <td>
1707
+ <label for="ddp_statusmail_recipient">
1708
+
1709
+ <input type="text" class="regular-text" id="ddp_statusmail_recipient"
1710
+ name="ddp_statusmail_recipient"
1711
+ value="<?php
1712
  echo esc_html( $options['ddp_statusmail_recipient'] ) ;
1713
  ?>">
1714
+ <p class="description">
1715
+ <?php
1716
  esc_html_e( 'Who should get the notification email.', 'delete-duplicate-posts' );
1717
  ?></p>
1718
+ </label>
1719
+ </td>
1720
+ </tr>
1721
+
1722
+
1723
+
1724
+
1725
+ <th colspan=2><input type="submit" class="button-primary" name="delete_duplicate_posts_save"
1726
+ value="<?php
1727
  esc_html_e( 'Save Settings', 'delete-duplicate-posts' );
1728
  ?>" /></th>
1729
+ </tr>
1730
+
1731
+ </table>
1732
+
1733
+ </form>
1734
+ </div><!-- #configuration -->
1735
+
1736
+
1737
+ <div id="log">
1738
+
1739
+ <h3><?php
1740
  esc_html_e( 'The Log', 'delete-duplicate-posts' );
1741
  ?></h3>
1742
+ <div class="spinner is-active"></div>
1743
+ <ul class="large-text" name="ddp_log" id="ddp_log">
1744
+ </ul>
1745
+
1746
+ </div>
1747
+ <p>
1748
+ <form method="post" id="ddp_clearlog">
1749
+ <?php
1750
  wp_nonce_field( 'ddp_clearlog_nonce' );
1751
  ?>
1752
+
1753
+ <input class="button-secondary" type="submit" name="ddp_clearlog"
1754
+ value="<?php
1755
  esc_html_e( 'Reset log', 'delete-duplicate-posts' );
1756
  ?>" />
1757
+ </form>
1758
+ </p>
1759
+
1760
+ </div><!-- #ddp_container -->
1761
+
1762
+ <?php
1763
  include_once 'sidebar.php';
1764
  ?>
1765
+
1766
+ <?php
1767
  if ( function_exists( 'ddp_fs' ) ) {
1768
  global $ddp_fs ;
1769
  }
1770
  ?>
1771
+
1772
+ </div>
1773
+ </div>
1774
+
1775
+ </div>
1776
+ <?php
1777
  }
1778
 
1779
  }
js/delete-duplicate-posts.js CHANGED
@@ -168,7 +168,7 @@ jQuery(document).ready(function () {
168
  jQuery('#ddp_container #dashboard .statusdiv .dupelist .duplicatetable').show();
169
 
170
  jQuery.each(dupes, function (key, value) {
171
- jQuery('#ddp_container #dashboard .statusdiv .dupelist .duplicatetable tbody').append('<tr><th scope="row" class="check-column"><label class="screen-reader-text" for="cb-select-' + value.ID + '">Select Post</label><input id="cb-select-' + value.ID + '" type="checkbox" name="delpost[]" value="' + value.ID + '"><div class="locked-indicator"></div></th><td><a href="' + value.permalink + '" target="_blank">' + value.title + '</a> (ID #' + value.ID + ' type:' + value.type + ' status:' + value.status + ')</td><td><a href="' + value.orgpermalink + '" target="_blank">' + value.orgtitle + '</a> (ID #' + value.orgID + ')' + value.why + '</td></tr>');
172
 
173
  });
174
 
168
  jQuery('#ddp_container #dashboard .statusdiv .dupelist .duplicatetable').show();
169
 
170
  jQuery.each(dupes, function (key, value) {
171
+ jQuery('#ddp_container #dashboard .statusdiv .dupelist .duplicatetable tbody').append('<tr><th scope="row" class="check-column"><label class="screen-reader-text" for="cb-select-' + value.ID + '">Select Post</label><input id="cb-select-' + value.ID + '" type="checkbox" name="delpost[]" value="' + value.ID + '"><div class="locked-indicator"></div></th><td><a href="' + value.permalink + '" target="_blank">' + value.title + '</a> (ID #' + value.ID + ' type:' + value.type + ' status:' + value.status + ')</td><td><a href="' + value.orgpermalink + '" target="_blank">' + value.orgtitle + '</a> (ID #' + value.orgID + ') ' + value.why + '</td></tr>');
172
 
173
  });
174
 
languages/delete_duplicate_posts.pot CHANGED
@@ -3,14 +3,14 @@ msgid ""
3
  msgstr ""
4
  "Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n"
5
  "Project-Id-Version: Delete Duplicate Posts\n"
6
- "POT-Creation-Date: 2020-05-04 13:21+0200\n"
7
  "PO-Revision-Date: 2017-03-30 09:17-0400\n"
8
  "Last-Translator: Lars Koudal\n"
9
  "Language-Team: Lars Koudal\n"
10
  "MIME-Version: 1.0\n"
11
  "Content-Type: text/plain; charset=UTF-8\n"
12
  "Content-Transfer-Encoding: 8bit\n"
13
- "X-Generator: Poedit 2.3\n"
14
  "X-Poedit-Basepath: ..\n"
15
  "X-Poedit-Flags-xgettext: --add-comments=translators:\n"
16
  "X-Poedit-WPHeader: delete-duplicate-posts.php\n"
@@ -21,15 +21,57 @@ msgstr ""
21
  "X-Poedit-SearchPath-0: .\n"
22
  "X-Poedit-SearchPathExcluded-0: *.js\n"
23
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
24
  #. translators: Total number of deleted duplicates
25
  #. translators: %s: Number of deleted posts
26
- #: delete-duplicate-posts.php:133 sidebar.php:32
27
  #, php-format
28
  msgid "%s duplicates deleted!"
29
  msgstr ""
30
 
31
  #. translators: Asking for a review text
32
- #: delete-duplicate-posts.php:139
33
  #, php-format
34
  msgid ""
35
  "Hey, I noticed this plugin has deleted %s duplicate posts for you - that's "
@@ -37,325 +79,354 @@ msgid ""
37
  "WordPress? Just to help us spread the word and boost our motivation."
38
  msgstr ""
39
 
40
- #: delete-duplicate-posts.php:144
41
- msgid "Please leave a review"
42
- msgstr ""
43
-
44
- #: delete-duplicate-posts.php:157
45
  msgid "Cleaning duplicates"
46
  msgstr ""
47
 
48
- #: delete-duplicate-posts.php:198
49
  msgid "Error: Log is empty.. do something :-)"
50
  msgstr ""
51
 
52
- #: delete-duplicate-posts.php:367
53
  msgid "Error, choose which meta_key to look for duplicate values in."
54
  msgstr ""
55
 
56
- #: delete-duplicate-posts.php:461
57
  msgid "Error: Choose post types to check."
58
  msgstr ""
59
 
60
- #: delete-duplicate-posts.php:533
61
  msgid "Rendering Help Scouts beacon for easy help and support"
62
  msgstr ""
63
 
64
- #: delete-duplicate-posts.php:540
65
  msgid ""
66
  "Your email is added to cleverplugins.com newsletter. Unsubscribe any time."
67
  msgstr ""
68
 
69
- #: delete-duplicate-posts.php:584
70
  msgid "Cron job running."
71
  msgstr ""
72
 
73
- #: delete-duplicate-posts.php:586
74
  msgid "Manually cleaning."
75
  msgstr ""
76
 
77
- #: delete-duplicate-posts.php:610
78
- #, php-format
79
- msgid "Error, problem deleting %1$s '%2$d'"
80
- msgstr ""
81
-
82
- #: delete-duplicate-posts.php:621
83
  #, php-format
84
  msgid "Deleted %1$s '%2$s' (id: %3$s) in %4$s sec."
85
  msgstr ""
86
 
87
  #. translators: How many posts were deleted and how long it took in seconds
88
- #: delete-duplicate-posts.php:630
89
  #, php-format
90
  msgid "A total of %1$s duplicate posts were deleted in %2$s sec."
91
  msgstr ""
92
 
93
- #: delete-duplicate-posts.php:637
 
94
  #, php-format
95
  msgid "A total of %s duplicate posts were deleted."
96
  msgstr ""
97
 
98
  #. translators:
99
- #: delete-duplicate-posts.php:654
100
  #, php-format
101
  msgid ""
102
  "Hi Admin, I have deleted <strong>%1$d</strong> posts on your blog, %2$s."
103
- "<br><br><em>You are receiving this e-mail because you have turned on e-mail "
104
- "notifications by the plugin, Delete Duplicate Posts.</em>"
105
  msgstr ""
106
 
107
- #: delete-duplicate-posts.php:662
 
 
 
 
 
 
108
  msgid "Deleted Duplicate Posts Status"
109
  msgstr ""
110
 
111
- #: delete-duplicate-posts.php:664
 
112
  #, php-format
113
  msgid "Status email sent to %s."
114
  msgstr ""
115
 
116
- #: delete-duplicate-posts.php:667
 
117
  #, php-format
118
  msgid "Not a vaild email %s."
119
  msgstr ""
120
 
121
- #: delete-duplicate-posts.php:685
122
  msgid "Every 5 minutes"
123
  msgstr ""
124
 
125
- #: delete-duplicate-posts.php:689
126
  msgid "Every 10 minutes"
127
  msgstr ""
128
 
129
- #: delete-duplicate-posts.php:693
130
  msgid "Every 15 minutes"
131
  msgstr ""
132
 
133
- #: delete-duplicate-posts.php:697
134
  msgid "Every 30 minutes"
135
  msgstr ""
136
 
137
- #: delete-duplicate-posts.php:742
138
  msgid "Are you sure you want to delete duplicates? There is no undo feature."
139
  msgstr ""
140
 
141
- #: delete-duplicate-posts.php:771
 
 
 
 
 
 
142
  msgid "Plugin activated."
143
  msgstr ""
144
 
145
- #: delete-duplicate-posts.php:794 delete-duplicate-posts.php:1010
146
  msgid "Settings"
147
  msgstr ""
148
 
149
- #: delete-duplicate-posts.php:811
150
  msgid "Usage and FAQ"
151
  msgstr ""
152
 
153
- #: delete-duplicate-posts.php:813
154
  msgid "What does this plugin do?"
155
  msgstr ""
156
 
157
- #: delete-duplicate-posts.php:814
158
  msgid ""
159
  "Helps you clean duplicate posts from your blog. The plugin checks for "
160
  "blogposts on your blog with the same title."
161
  msgstr ""
162
 
163
- #: delete-duplicate-posts.php:815
164
  msgid ""
165
  "It can run automatically via WordPress's own internal CRON-system, or you "
166
  "can run it automatically."
167
  msgstr ""
168
 
169
- #: delete-duplicate-posts.php:816
170
  msgid ""
171
  "It also has a nice feature that can send you an e-mail when Delete Duplicate "
172
  "Posts finds and deletes something (if you have turned on the CRON feature)."
173
  msgstr ""
174
 
175
- #: delete-duplicate-posts.php:817
176
  msgid "Help! Something was deleted that was not supposed to be deleted!"
177
  msgstr ""
178
 
179
- #: delete-duplicate-posts.php:818
180
  msgid ""
181
  "I am sorry for that, I can only recommend you restore the database you took "
182
  "just before you ran this plugin."
183
  msgstr ""
184
 
185
- #: delete-duplicate-posts.php:819
186
  msgid ""
187
  "If you run this plugin, manually or automatically, it is at your OWN risk!"
188
  msgstr ""
189
 
190
- #: delete-duplicate-posts.php:820
191
  msgid ""
192
  "I have done my best to avoid deleting something that should not be deleted, "
193
  "but if it happens, there is nothing I can do to help you."
194
  msgstr ""
195
 
196
- #: delete-duplicate-posts.php:842 delete-duplicate-posts.php:926
197
  msgid "Whoops! Some error occured, try again, please!"
198
  msgstr ""
199
 
200
- #: delete-duplicate-posts.php:849
201
  msgid ""
202
  "Whoops! There was a problem with the data you posted. Please go back and try "
203
  "again."
204
  msgstr ""
205
 
206
- #: delete-duplicate-posts.php:920
207
  msgid "Settings saved."
208
  msgstr ""
209
 
210
- #: delete-duplicate-posts.php:931
211
  msgid "The log was cleared."
212
  msgstr ""
213
 
214
- #: delete-duplicate-posts.php:987
215
  msgid "Duplicate"
216
  msgstr ""
217
 
218
- #: delete-duplicate-posts.php:988
219
  msgid "Original"
220
  msgstr ""
221
 
222
- #: delete-duplicate-posts.php:1000
223
  msgid "Refresh list"
224
  msgstr ""
225
 
226
- #: delete-duplicate-posts.php:1001
227
  msgid "Delete duplicates"
228
  msgstr ""
229
 
230
- #: delete-duplicate-posts.php:1020
231
  msgid ""
232
  "You have enabled automatic deletion, so I am running on automatic. I will "
233
  "take care of everything..."
234
  msgstr ""
235
 
236
- #: delete-duplicate-posts.php:1025
 
237
  #, php-format
238
  msgid "Next automated check %1$s. Current time %2$s"
239
  msgstr ""
240
 
241
- #: delete-duplicate-posts.php:1042
242
  msgid "Which post types?:"
243
  msgstr ""
244
 
245
- #: delete-duplicate-posts.php:1087
 
 
 
 
 
 
246
  msgid "Choose which post types to scan for duplicates."
247
  msgstr ""
248
 
249
- #: delete-duplicate-posts.php:1092
250
  msgid "Post status"
251
  msgstr ""
252
 
253
- #: delete-duplicate-posts.php:1156
254
  msgid "Comparison Method"
255
  msgstr ""
256
 
257
- #: delete-duplicate-posts.php:1162
258
  msgid "Compare by title (default)"
259
  msgstr ""
260
 
261
- #: delete-duplicate-posts.php:1163
262
- msgid "Looks at the title."
263
  msgstr ""
264
 
265
- #: delete-duplicate-posts.php:1175
266
  msgid "Compare by meta tag"
267
  msgstr ""
268
 
269
- #: delete-duplicate-posts.php:1176
270
  msgid "Compare by any meta tag."
271
  msgstr ""
272
 
273
- #: delete-duplicate-posts.php:1217
274
  msgid "Delete which posts?:"
275
  msgstr ""
276
 
277
- #: delete-duplicate-posts.php:1225
278
  msgid "Keep oldest"
279
  msgstr ""
280
 
281
- #: delete-duplicate-posts.php:1231
282
  msgid "Keep latest"
283
  msgstr ""
284
 
285
- #: delete-duplicate-posts.php:1233
286
  msgid ""
287
  "Keep the oldest or the latest version of duplicates? Default is keeping the "
288
  "oldest, and deleting any subsequent duplicate posts"
289
  msgstr ""
290
 
291
- #: delete-duplicate-posts.php:1268
 
 
 
 
 
 
 
 
 
 
 
 
 
 
292
  msgid "Enable automatic deletion?:"
293
  msgstr ""
294
 
295
- #: delete-duplicate-posts.php:1278
296
  msgid "Clean duplicates automatically."
297
  msgstr ""
298
 
299
- #: delete-duplicate-posts.php:1285
300
  msgid "How often?:"
301
  msgstr ""
302
 
303
- #: delete-duplicate-posts.php:1305
304
  msgid "How often should the cron job run?"
305
  msgstr ""
306
 
307
- #: delete-duplicate-posts.php:1316
308
  msgid "Send status mail?:"
309
  msgstr ""
310
 
311
- #: delete-duplicate-posts.php:1324
312
  msgid "Sends a status email if duplicates have been found."
313
  msgstr ""
314
 
315
- #: delete-duplicate-posts.php:1330
316
  msgid "Email recipient:"
317
  msgstr ""
318
 
319
- #: delete-duplicate-posts.php:1335
320
  msgid "Who should get the notification email."
321
  msgstr ""
322
 
323
- #: delete-duplicate-posts.php:1343
324
  msgid "Save Settings"
325
  msgstr ""
326
 
327
- #: delete-duplicate-posts.php:1354
328
  msgid "The Log"
329
  msgstr ""
330
 
331
- #: delete-duplicate-posts.php:1364
332
  msgid "Reset log"
333
  msgstr ""
334
 
335
- #: sidebar.php:16
336
- msgid "Never miss an important update"
337
  msgstr ""
338
 
339
- #: sidebar.php:17
340
  msgid ""
341
  "Opt-in to our security and feature updates notifications, and non-sensitive "
342
  "diagnostic tracking."
343
  msgstr ""
344
 
345
- #: sidebar.php:18
346
  msgid "Click here to opt in."
347
  msgstr ""
348
 
349
- #: sidebar.php:45
350
  msgid ""
351
  "We recommend you always make a backup before running this tool. Changes are "
352
  "permanent!"
353
  msgstr ""
354
 
355
- #: sidebar.php:94
356
  msgid "Our other plugins"
357
  msgstr ""
358
 
 
 
 
 
359
  #. Plugin Name of the plugin/theme
360
  msgid "Delete Duplicate Posts"
361
  msgstr ""
3
  msgstr ""
4
  "Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n"
5
  "Project-Id-Version: Delete Duplicate Posts\n"
6
+ "POT-Creation-Date: 2021-07-11 13:07-0400\n"
7
  "PO-Revision-Date: 2017-03-30 09:17-0400\n"
8
  "Last-Translator: Lars Koudal\n"
9
  "Language-Team: Lars Koudal\n"
10
  "MIME-Version: 1.0\n"
11
  "Content-Type: text/plain; charset=UTF-8\n"
12
  "Content-Transfer-Encoding: 8bit\n"
13
+ "X-Generator: Poedit 3.0\n"
14
  "X-Poedit-Basepath: ..\n"
15
  "X-Poedit-Flags-xgettext: --add-comments=translators:\n"
16
  "X-Poedit-WPHeader: delete-duplicate-posts.php\n"
21
  "X-Poedit-SearchPath-0: .\n"
22
  "X-Poedit-SearchPathExcluded-0: *.js\n"
23
 
24
+ #: delete-duplicate-posts.php:176
25
+ msgid "Nonce verification failed."
26
+ msgstr ""
27
+
28
+ #: delete-duplicate-posts.php:216
29
+ msgid "Freemius opt choice selected."
30
+ msgstr ""
31
+
32
+ #: delete-duplicate-posts.php:223
33
+ msgid "Freemius opt choice not found."
34
+ msgstr ""
35
+
36
+ #: delete-duplicate-posts.php:316
37
+ msgid "Help Delete Duplicate Posts improve!"
38
+ msgstr ""
39
+
40
+ #: delete-duplicate-posts.php:319
41
+ msgid ""
42
+ "Gathering non-sensitive diagnostic data about the plugin install helps us "
43
+ "improve the plugin."
44
+ msgstr ""
45
+
46
+ #: delete-duplicate-posts.php:319
47
+ msgid "Read more about what we collect."
48
+ msgstr ""
49
+
50
+ #. translators:
51
+ #: delete-duplicate-posts.php:325
52
+ #, php-format
53
+ msgid ""
54
+ "If you opt-in, some data about your usage of %1$s will be sent to Freemius."
55
+ "com. If you skip this, that's okay! %1$s will still work just fine."
56
+ msgstr ""
57
+
58
+ #: delete-duplicate-posts.php:330
59
+ msgid "Sure, opt-in"
60
+ msgstr ""
61
+
62
+ #: delete-duplicate-posts.php:333
63
+ msgid "No, thank you"
64
+ msgstr ""
65
+
66
  #. translators: Total number of deleted duplicates
67
  #. translators: %s: Number of deleted posts
68
+ #: delete-duplicate-posts.php:361 sidebar.php:39
69
  #, php-format
70
  msgid "%s duplicates deleted!"
71
  msgstr ""
72
 
73
  #. translators: Asking for a review text
74
+ #: delete-duplicate-posts.php:367
75
  #, php-format
76
  msgid ""
77
  "Hey, I noticed this plugin has deleted %s duplicate posts for you - that's "
79
  "WordPress? Just to help us spread the word and boost our motivation."
80
  msgstr ""
81
 
82
+ #: delete-duplicate-posts.php:403
 
 
 
 
83
  msgid "Cleaning duplicates"
84
  msgstr ""
85
 
86
+ #: delete-duplicate-posts.php:463
87
  msgid "Error: Log is empty.. do something :-)"
88
  msgstr ""
89
 
90
+ #: delete-duplicate-posts.php:700
91
  msgid "Error, choose which meta_key to look for duplicate values in."
92
  msgstr ""
93
 
94
+ #: delete-duplicate-posts.php:821
95
  msgid "Error: Choose post types to check."
96
  msgstr ""
97
 
98
+ #: delete-duplicate-posts.php:914
99
  msgid "Rendering Help Scouts beacon for easy help and support"
100
  msgstr ""
101
 
102
+ #: delete-duplicate-posts.php:921
103
  msgid ""
104
  "Your email is added to cleverplugins.com newsletter. Unsubscribe any time."
105
  msgstr ""
106
 
107
+ #: delete-duplicate-posts.php:966
108
  msgid "Cron job running."
109
  msgstr ""
110
 
111
+ #: delete-duplicate-posts.php:968
112
  msgid "Manually cleaning."
113
  msgstr ""
114
 
115
+ #: delete-duplicate-posts.php:1014
 
 
 
 
 
116
  #, php-format
117
  msgid "Deleted %1$s '%2$s' (id: %3$s) in %4$s sec."
118
  msgstr ""
119
 
120
  #. translators: How many posts were deleted and how long it took in seconds
121
+ #: delete-duplicate-posts.php:1023
122
  #, php-format
123
  msgid "A total of %1$s duplicate posts were deleted in %2$s sec."
124
  msgstr ""
125
 
126
+ #. translators:
127
+ #: delete-duplicate-posts.php:1031
128
  #, php-format
129
  msgid "A total of %s duplicate posts were deleted."
130
  msgstr ""
131
 
132
  #. translators:
133
+ #: delete-duplicate-posts.php:1049
134
  #, php-format
135
  msgid ""
136
  "Hi Admin, I have deleted <strong>%1$d</strong> posts on your blog, %2$s."
 
 
137
  msgstr ""
138
 
139
+ #: delete-duplicate-posts.php:1051
140
+ msgid ""
141
+ "You are receiving this e-mail because you have turned on e-mail "
142
+ "notifications by the plugin, Delete Duplicate Posts."
143
+ msgstr ""
144
+
145
+ #: delete-duplicate-posts.php:1058
146
  msgid "Deleted Duplicate Posts Status"
147
  msgstr ""
148
 
149
+ #. translators:
150
+ #: delete-duplicate-posts.php:1061
151
  #, php-format
152
  msgid "Status email sent to %s."
153
  msgstr ""
154
 
155
+ #. translators:
156
+ #: delete-duplicate-posts.php:1065
157
  #, php-format
158
  msgid "Not a vaild email %s."
159
  msgstr ""
160
 
161
+ #: delete-duplicate-posts.php:1076
162
  msgid "Every 5 minutes"
163
  msgstr ""
164
 
165
+ #: delete-duplicate-posts.php:1080
166
  msgid "Every 10 minutes"
167
  msgstr ""
168
 
169
+ #: delete-duplicate-posts.php:1084
170
  msgid "Every 15 minutes"
171
  msgstr ""
172
 
173
+ #: delete-duplicate-posts.php:1088
174
  msgid "Every 30 minutes"
175
  msgstr ""
176
 
177
+ #: delete-duplicate-posts.php:1150
178
  msgid "Are you sure you want to delete duplicates? There is no undo feature."
179
  msgstr ""
180
 
181
+ #: delete-duplicate-posts.php:1151
182
+ msgid ""
183
+ "You have to select which duplicates to delete. Tip: You can click the top or "
184
+ "bottom checkbox to select all."
185
+ msgstr ""
186
+
187
+ #: delete-duplicate-posts.php:1179
188
  msgid "Plugin activated."
189
  msgstr ""
190
 
191
+ #: delete-duplicate-posts.php:1241 delete-duplicate-posts.php:1487
192
  msgid "Settings"
193
  msgstr ""
194
 
195
+ #: delete-duplicate-posts.php:1258
196
  msgid "Usage and FAQ"
197
  msgstr ""
198
 
199
+ #: delete-duplicate-posts.php:1260
200
  msgid "What does this plugin do?"
201
  msgstr ""
202
 
203
+ #: delete-duplicate-posts.php:1261
204
  msgid ""
205
  "Helps you clean duplicate posts from your blog. The plugin checks for "
206
  "blogposts on your blog with the same title."
207
  msgstr ""
208
 
209
+ #: delete-duplicate-posts.php:1262
210
  msgid ""
211
  "It can run automatically via WordPress's own internal CRON-system, or you "
212
  "can run it automatically."
213
  msgstr ""
214
 
215
+ #: delete-duplicate-posts.php:1263
216
  msgid ""
217
  "It also has a nice feature that can send you an e-mail when Delete Duplicate "
218
  "Posts finds and deletes something (if you have turned on the CRON feature)."
219
  msgstr ""
220
 
221
+ #: delete-duplicate-posts.php:1264
222
  msgid "Help! Something was deleted that was not supposed to be deleted!"
223
  msgstr ""
224
 
225
+ #: delete-duplicate-posts.php:1265
226
  msgid ""
227
  "I am sorry for that, I can only recommend you restore the database you took "
228
  "just before you ran this plugin."
229
  msgstr ""
230
 
231
+ #: delete-duplicate-posts.php:1266
232
  msgid ""
233
  "If you run this plugin, manually or automatically, it is at your OWN risk!"
234
  msgstr ""
235
 
236
+ #: delete-duplicate-posts.php:1267
237
  msgid ""
238
  "I have done my best to avoid deleting something that should not be deleted, "
239
  "but if it happens, there is nothing I can do to help you."
240
  msgstr ""
241
 
242
+ #: delete-duplicate-posts.php:1289 delete-duplicate-posts.php:1377
243
  msgid "Whoops! Some error occured, try again, please!"
244
  msgstr ""
245
 
246
+ #: delete-duplicate-posts.php:1296
247
  msgid ""
248
  "Whoops! There was a problem with the data you posted. Please go back and try "
249
  "again."
250
  msgstr ""
251
 
252
+ #: delete-duplicate-posts.php:1371
253
  msgid "Settings saved."
254
  msgstr ""
255
 
256
+ #: delete-duplicate-posts.php:1382
257
  msgid "The log was cleared."
258
  msgstr ""
259
 
260
+ #: delete-duplicate-posts.php:1452 delete-duplicate-posts.php:1463
261
  msgid "Duplicate"
262
  msgstr ""
263
 
264
+ #: delete-duplicate-posts.php:1453 delete-duplicate-posts.php:1464
265
  msgid "Original"
266
  msgstr ""
267
 
268
+ #: delete-duplicate-posts.php:1475
269
  msgid "Refresh list"
270
  msgstr ""
271
 
272
+ #: delete-duplicate-posts.php:1478
273
  msgid "Delete duplicates"
274
  msgstr ""
275
 
276
+ #: delete-duplicate-posts.php:1497
277
  msgid ""
278
  "You have enabled automatic deletion, so I am running on automatic. I will "
279
  "take care of everything..."
280
  msgstr ""
281
 
282
+ #. translators: Showing when the next check happens and what the current time is
283
+ #: delete-duplicate-posts.php:1503
284
  #, php-format
285
  msgid "Next automated check %1$s. Current time %2$s"
286
  msgstr ""
287
 
288
+ #: delete-duplicate-posts.php:1522
289
  msgid "Which post types?:"
290
  msgstr ""
291
 
292
+ #. translators: Total number of deleted duplicates
293
+ #: delete-duplicate-posts.php:1567
294
+ #, php-format
295
+ msgid "(%s total found)"
296
+ msgstr ""
297
+
298
+ #: delete-duplicate-posts.php:1579
299
  msgid "Choose which post types to scan for duplicates."
300
  msgstr ""
301
 
302
+ #: delete-duplicate-posts.php:1585
303
  msgid "Post status"
304
  msgstr ""
305
 
306
+ #: delete-duplicate-posts.php:1656
307
  msgid "Comparison Method"
308
  msgstr ""
309
 
310
+ #: delete-duplicate-posts.php:1664
311
  msgid "Compare by title (default)"
312
  msgstr ""
313
 
314
+ #: delete-duplicate-posts.php:1666
315
+ msgid "Looks at the title of the post itself."
316
  msgstr ""
317
 
318
+ #: delete-duplicate-posts.php:1680
319
  msgid "Compare by meta tag"
320
  msgstr ""
321
 
322
+ #: delete-duplicate-posts.php:1682
323
  msgid "Compare by any meta tag."
324
  msgstr ""
325
 
326
+ #: delete-duplicate-posts.php:1728
327
  msgid "Delete which posts?:"
328
  msgstr ""
329
 
330
+ #: delete-duplicate-posts.php:1735
331
  msgid "Keep oldest"
332
  msgstr ""
333
 
334
+ #: delete-duplicate-posts.php:1739
335
  msgid "Keep latest"
336
  msgstr ""
337
 
338
+ #: delete-duplicate-posts.php:1742
339
  msgid ""
340
  "Keep the oldest or the latest version of duplicates? Default is keeping the "
341
  "oldest, and deleting any subsequent duplicate posts"
342
  msgstr ""
343
 
344
+ #: delete-duplicate-posts.php:1752
345
+ msgid "Find how many duplicates:"
346
+ msgstr ""
347
+
348
+ #: delete-duplicate-posts.php:1759
349
+ msgid "No limit"
350
+ msgstr ""
351
+
352
+ #: delete-duplicate-posts.php:1783
353
+ msgid ""
354
+ "If you have many duplicates, the plugin might time out before finding them "
355
+ "all. Try limiting the amount of duplicates here. Default: Unlimited."
356
+ msgstr ""
357
+
358
+ #: delete-duplicate-posts.php:1824
359
  msgid "Enable automatic deletion?:"
360
  msgstr ""
361
 
362
+ #: delete-duplicate-posts.php:1833
363
  msgid "Clean duplicates automatically."
364
  msgstr ""
365
 
366
+ #: delete-duplicate-posts.php:1840
367
  msgid "How often?:"
368
  msgstr ""
369
 
370
+ #: delete-duplicate-posts.php:1861
371
  msgid "How often should the cron job run?"
372
  msgstr ""
373
 
374
+ #: delete-duplicate-posts.php:1874
375
  msgid "Send status mail?:"
376
  msgstr ""
377
 
378
+ #: delete-duplicate-posts.php:1881
379
  msgid "Sends a status email if duplicates have been found."
380
  msgstr ""
381
 
382
+ #: delete-duplicate-posts.php:1888
383
  msgid "Email recipient:"
384
  msgstr ""
385
 
386
+ #: delete-duplicate-posts.php:1896
387
  msgid "Who should get the notification email."
388
  msgstr ""
389
 
390
+ #: delete-duplicate-posts.php:1905
391
  msgid "Save Settings"
392
  msgstr ""
393
 
394
+ #: delete-duplicate-posts.php:1916
395
  msgid "The Log"
396
  msgstr ""
397
 
398
+ #: delete-duplicate-posts.php:1927
399
  msgid "Reset log"
400
  msgstr ""
401
 
402
+ #: sidebar.php:18
403
+ msgid "Help us improve!"
404
  msgstr ""
405
 
406
+ #: sidebar.php:20
407
  msgid ""
408
  "Opt-in to our security and feature updates notifications, and non-sensitive "
409
  "diagnostic tracking."
410
  msgstr ""
411
 
412
+ #: sidebar.php:23
413
  msgid "Click here to opt in."
414
  msgstr ""
415
 
416
+ #: sidebar.php:51
417
  msgid ""
418
  "We recommend you always make a backup before running this tool. Changes are "
419
  "permanent!"
420
  msgstr ""
421
 
422
+ #: sidebar.php:103
423
  msgid "Our other plugins"
424
  msgstr ""
425
 
426
+ #: sidebar.php:122
427
+ msgid "Support Forum on WordPress.org"
428
+ msgstr ""
429
+
430
  #. Plugin Name of the plugin/theme
431
  msgid "Delete Duplicate Posts"
432
  msgstr ""
readme.txt CHANGED
@@ -5,8 +5,8 @@ Tags: delete duplicate posts, delete, duplicate
5
  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.7
9
- Stable tag: 4.6.2
10
  Requires PHP: 5.6
11
 
12
  Get rid of duplicate posts and pages on your blog!
@@ -49,6 +49,17 @@ You should restore the backup you took of your website before you ran this tool.
49
 
50
  == Changelog ==
51
 
 
 
 
 
 
 
 
 
 
 
 
52
  = 4.6.2 =
53
  * 2021/04/14
54
  * Updated 3rd party libraries for PHP 8
5
  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.8
9
+ Stable tag: 4.7
10
  Requires PHP: 5.6
11
 
12
  Get rid of duplicate posts and pages on your blog!
49
 
50
  == Changelog ==
51
 
52
+ = 4.7 =
53
+ * 2021/07/11
54
+ * FIX: Duplicates not always properly detected, thank you for the reporters to help fix this bug :-)
55
+ * NEW: Improved and faster lookup of duplicates.
56
+ * NEW: See number of posts per post type.
57
+ * NEW: See peak memory usage in the log.
58
+ * NEW: See combined count by post_status in the log.
59
+ * NEW: If there is a problem looking up duplicates in the database (shared servers have limited resources), the problem will be shown in the log.
60
+ * Updated language files.
61
+ * Tested up to WP 5.8
62
+
63
  = 4.6.2 =
64
  * 2021/04/14
65
  * Updated 3rd party libraries for PHP 8
sidebar.php CHANGED
@@ -72,17 +72,15 @@ if ( $display_promotion ) {
72
  <h3><span class="dashicons dashicons-star-filled"></span> DDP Pro <span
73
  class="dashicons dashicons-star-filled"></span></h3>
74
  <ul class="linklist">
75
- <li><strong>New compare method</strong> - Compare by meta tag <span>Use with WooCommerce (compare SKU) or other
76
- plugins</span></li>
77
- <li><strong>Choose post status</strong> - Look for duplicates in scheduled posts, drafts or any other available
78
- post status on your site.</li>
79
  <li><strong>Premium Support</strong> - Get help from the developers behind the plugin.</li>
80
  <?php
81
  /*
82
  <li>301 Redirect deleted posts <span>Make sure traffic is directed to the right place</span></li>
83
  */
84
  ?>
85
- <li><strong>No ads</strong> - Support the developer :-)</li>
86
  </ul>
87
 
88
  <a href="<?php
@@ -90,15 +88,13 @@ if ( $display_promotion ) {
90
  ?>" class="button button-primary"
91
  id="ddpprobutton"><?php
92
  echo 'Click here' ;
93
- ?><span>$14.99 /year</span></a>
94
  <p>
95
- <center><em>$14.99/year - discount for more sites</em></center>
96
  </p>
97
  <div class="moneybackguarantee">
98
  <p><strong>Money Back Guarantee!</strong></p>
99
- <p>You are fully protected by our 100% Money Back Guarantee. If during the next 30 days you experience an issue
100
- that makes the plugin unusable and we are unable to resolve it, we'll happily consider offering a full refund of
101
- your money.</p>
102
  </div>
103
  <hr>
104
  </div><!-- .sidebarrow -->
@@ -118,7 +114,7 @@ echo esc_url( plugin_dir_url( __FILE__ ) . 'images/security-ninja-logo.png' ) ;
118
  alt="Visit wpsecurityninja.com" class="logo"></a>
119
  <p>Protect your website with <a href="https://wordpress.org/plugins/security-ninja/" target="_blank"
120
  rel="noopener">wordpress.org/plugins/security-ninja/</a><br />
121
- <p>Read more on <a href="https://wpsecurityninja.com/">wpsecurityninja.com</a></p>
122
  <br />
123
  <a href="https://cleverplugins.com" target="_blank" style="float: right;" rel="noopener"><img
124
  src="<?php
@@ -127,7 +123,7 @@ echo esc_url( plugin_dir_url( __FILE__ ) . 'images/seoboosterlogo.png' ) ;
127
  alt="Visit cleverplugins.com" class="logo"></a>
128
  <p>SEO Booster is a powerful tool for anyone serious about SEO. <a href="https://wordpress.org/plugins/seo-booster/"
129
  target="_blank" rel="noopener">wordpress.org/plugins/seo-booster/</a><br />
130
- <p>Read more on <a href="https://cleverplugins.com/">cleverplugins.com</a></p>
131
 
132
  </div><!-- .sidebarrow -->
133
  <div class="sidebarrow">
72
  <h3><span class="dashicons dashicons-star-filled"></span> DDP Pro <span
73
  class="dashicons dashicons-star-filled"></span></h3>
74
  <ul class="linklist">
75
+ <li><strong>New compare method</strong> - Compare by meta tag <span>Use with WooCommerce (compare SKU) or other plugins</span></li>
76
+ <li><strong>Choose post status</strong> - Look for duplicates in scheduled posts, drafts or any other available post status on your site.</li>
 
 
77
  <li><strong>Premium Support</strong> - Get help from the developers behind the plugin.</li>
78
  <?php
79
  /*
80
  <li>301 Redirect deleted posts <span>Make sure traffic is directed to the right place</span></li>
81
  */
82
  ?>
83
+ <li><strong>No ads</strong> - Support the developer ;-)</li>
84
  </ul>
85
 
86
  <a href="<?php
88
  ?>" class="button button-primary"
89
  id="ddpprobutton"><?php
90
  echo 'Click here' ;
91
+ ?><span>$19.99 /year</span></a>
92
  <p>
93
+ <center><em>$19.99/year - discount for more sites</em></center>
94
  </p>
95
  <div class="moneybackguarantee">
96
  <p><strong>Money Back Guarantee!</strong></p>
97
+ <p>You are fully protected by our 100% Money Back Guarantee. If during the next 30 days you experience an issue that makes the plugin unusable and we are unable to resolve it, we'll happily consider offering a full refund of your money.</p>
 
 
98
  </div>
99
  <hr>
100
  </div><!-- .sidebarrow -->
114
  alt="Visit wpsecurityninja.com" class="logo"></a>
115
  <p>Protect your website with <a href="https://wordpress.org/plugins/security-ninja/" target="_blank"
116
  rel="noopener">wordpress.org/plugins/security-ninja/</a><br />
117
+ <p>Read more on <a href="https://wpsecurityninja.com/" target="_blank" rel="noopener">wpsecurityninja.com</a></p>
118
  <br />
119
  <a href="https://cleverplugins.com" target="_blank" style="float: right;" rel="noopener"><img
120
  src="<?php
123
  alt="Visit cleverplugins.com" class="logo"></a>
124
  <p>SEO Booster is a powerful tool for anyone serious about SEO. <a href="https://wordpress.org/plugins/seo-booster/"
125
  target="_blank" rel="noopener">wordpress.org/plugins/seo-booster/</a><br />
126
+ <p>Read more on <a href="https://cleverplugins.com/" target="_blank" rel="noopener">cleverplugins.com</a></p>
127
 
128
  </div><!-- .sidebarrow -->
129
  <div class="sidebarrow">
vendor/collizo4sky/persist-admin-notices-dismissal/CHANGES.md CHANGED
@@ -1,18 +1,21 @@
 
 
 
1
  #### 1.4.3
2
- * added filter hook `pand_dismiss_notice_js_url` in case you're using this in a theme or a local environment that doesn't quite find the correct URL.
3
- * added filter hook `pand_theme_loader` that returns a boolean for simpler usage of the `pand_dismiss_notice_js_url` hook
4
 
5
  #### 1.4.2
6
  * No changes to `class PAnD`
7
- * updated `.gitignore` and `.gitattributes`
8
- * now use classmap in composer's autoloader, should be more efficient
9
 
10
  #### 1.4.1
11
- * fixed the `forever` setting with options
12
 
13
  #### 1.4.0
14
  * WPCS 1.1.0 linting done
15
- * switched from storing timeout in transients to storing in the options table, this should play much better with object caching
16
 
17
  #### 1.3.x
18
- * uses transients to store timeout
1
+ #### 1.4.4
2
+ * Added support for extra dismissible links via `.dismiss-this` CSS class.
3
+
4
  #### 1.4.3
5
+ * Added filter hook `pand_dismiss_notice_js_url` in case you're using this in a theme or a local environment that doesn't quite find the correct URL.
6
+ * Added filter hook `pand_theme_loader` that returns a boolean for simpler usage of the `pand_dismiss_notice_js_url` hook
7
 
8
  #### 1.4.2
9
  * No changes to `class PAnD`
10
+ * Updated `.gitignore` and `.gitattributes`
11
+ * Now use classmap in composer's autoloader, should be more efficient
12
 
13
  #### 1.4.1
14
+ * Fixed the `forever` setting with options
15
 
16
  #### 1.4.0
17
  * WPCS 1.1.0 linting done
18
+ * Switched from storing timeout in transients to storing in the options table, this should play much better with object caching
19
 
20
  #### 1.3.x
21
+ * Uses transients to store timeout
vendor/collizo4sky/persist-admin-notices-dismissal/composer.json CHANGED
@@ -1,12 +1,24 @@
1
  {
2
  "name": "collizo4sky/persist-admin-notices-dismissal",
3
  "description": "Simple library to persist dismissal of admin notices across pages in WordPress dashboard.",
 
 
 
4
  "authors": [
5
  {
6
  "name": "Collins Agbonghama",
7
- "email": "me@w3guy.com"
 
8
  }
9
  ],
 
 
 
 
 
 
 
 
10
  "autoload": {
11
  "classmap": [
12
  "persist-admin-notices-dismissal.php"
1
  {
2
  "name": "collizo4sky/persist-admin-notices-dismissal",
3
  "description": "Simple library to persist dismissal of admin notices across pages in WordPress dashboard.",
4
+ "version": "1.4.4",
5
+ "type": "library",
6
+ "license": "GPL-3.0-or-later",
7
  "authors": [
8
  {
9
  "name": "Collins Agbonghama",
10
+ "email": "me@w3guy.com",
11
+ "role": "developer"
12
  }
13
  ],
14
+ "prefer-stable": true,
15
+ "require": {
16
+ "php": ">=5.4"
17
+ },
18
+ "support": {
19
+ "issues": "https://github.com/w3guy/persist-admin-notices-dismissal/issues",
20
+ "source": "https://github.com/w3guy/persist-admin-notices-dismissal"
21
+ },
22
  "autoload": {
23
  "classmap": [
24
  "persist-admin-notices-dismissal.php"
vendor/collizo4sky/persist-admin-notices-dismissal/persist-admin-notices-dismissal.php CHANGED
@@ -3,7 +3,7 @@
3
  /**
4
  * Persist Admin notices Dismissal
5
  *
6
- * Copyright (C) 2016 Collins Agbonghama <http://w3guy.com>
7
  *
8
  * This program is free software: you can redistribute it and/or modify
9
  * it under the terms of the GNU General Public License as published by
@@ -22,7 +22,6 @@
22
  * @author Collins Agbonghama
23
  * @author Andy Fragen
24
  * @license http://www.gnu.org/licenses GNU General Public License
25
- * @version 1.4.3
26
  */
27
 
28
  /**
3
  /**
4
  * Persist Admin notices Dismissal
5
  *
6
+ * Copyright (C) 2016 Collins Agbonghama <https://w3guy.com>
7
  *
8
  * This program is free software: you can redistribute it and/or modify
9
  * it under the terms of the GNU General Public License as published by
22
  * @author Collins Agbonghama
23
  * @author Andy Fragen
24
  * @license http://www.gnu.org/licenses GNU General Public License
 
25
  */
26
 
27
  /**
vendor/composer/installed.json CHANGED
@@ -1,20 +1,23 @@
1
  [
2
  {
3
  "name": "collizo4sky/persist-admin-notices-dismissal",
4
- "version": "dev-extra-dismiss-links",
5
- "version_normalized": "dev-extra-dismiss-links",
6
  "source": {
7
  "type": "git",
8
- "url": "https://github.com/lkoudal/persist-admin-notices-dismissal.git",
9
- "reference": "c8cc0cffa751ddcb3bbe6539a987ed04e3bc59d4"
10
  },
11
  "dist": {
12
  "type": "zip",
13
- "url": "https://api.github.com/repos/lkoudal/persist-admin-notices-dismissal/zipball/c8cc0cffa751ddcb3bbe6539a987ed04e3bc59d4",
14
- "reference": "c8cc0cffa751ddcb3bbe6539a987ed04e3bc59d4",
15
  "shasum": ""
16
  },
17
- "time": "2020-12-31T00:00:33+00:00",
 
 
 
18
  "type": "library",
19
  "installation-source": "source",
20
  "autoload": {
@@ -22,16 +25,18 @@
22
  "persist-admin-notices-dismissal.php"
23
  ]
24
  },
 
 
 
 
25
  "authors": [
26
  {
27
  "name": "Collins Agbonghama",
28
- "email": "me@w3guy.com"
 
29
  }
30
  ],
31
- "description": "Simple library to persist dismissal of admin notices across pages in WordPress dashboard.",
32
- "support": {
33
- "source": "https://github.com/lkoudal/persist-admin-notices-dismissal/tree/extra-dismiss-links"
34
- }
35
  },
36
  {
37
  "name": "typisttech/imposter",
1
  [
2
  {
3
  "name": "collizo4sky/persist-admin-notices-dismissal",
4
+ "version": "1.4.4",
5
+ "version_normalized": "1.4.4.0",
6
  "source": {
7
  "type": "git",
8
+ "url": "https://github.com/w3guy/persist-admin-notices-dismissal.git",
9
+ "reference": "900739eb6b0ec0210465f5983a6d4e0e420289e4"
10
  },
11
  "dist": {
12
  "type": "zip",
13
+ "url": "https://api.github.com/repos/w3guy/persist-admin-notices-dismissal/zipball/900739eb6b0ec0210465f5983a6d4e0e420289e4",
14
+ "reference": "900739eb6b0ec0210465f5983a6d4e0e420289e4",
15
  "shasum": ""
16
  },
17
+ "require": {
18
+ "php": ">=5.4"
19
+ },
20
+ "time": "2020-12-31T17:12:37+00:00",
21
  "type": "library",
22
  "installation-source": "source",
23
  "autoload": {
25
  "persist-admin-notices-dismissal.php"
26
  ]
27
  },
28
+ "notification-url": "https://packagist.org/downloads/",
29
+ "license": [
30
+ "GPL-3.0-or-later"
31
+ ],
32
  "authors": [
33
  {
34
  "name": "Collins Agbonghama",
35
+ "email": "me@w3guy.com",
36
+ "role": "developer"
37
  }
38
  ],
39
+ "description": "Simple library to persist dismissal of admin notices across pages in WordPress dashboard."
 
 
 
40
  },
41
  {
42
  "name": "typisttech/imposter",