Delete Duplicate Posts - Version 4.7.1

Version Description

  • 2021/07/21
  • Security Hardening
Download this release

Release Info

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

Code changes from version 4.7 to 4.7.1

Files changed (3) hide show
  1. delete-duplicate-posts.php +433 -413
  2. readme.txt +7 -1
  3. sidebar.php +70 -70
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.7
9
  Author: cleverplugins.com
10
  Author URI: https://cleverplugins.com
11
  Min WP Version: 4.7
@@ -81,10 +81,10 @@ if ( function_exists( 'ddp_fs' ) ) {
81
  /**
82
  * Cleans up when uninstalling
83
  *
84
- * @author Lars Koudal
85
- * @since v0.0.1
86
- * @version v1.0.0 Tuesday, January 12th, 2021.
87
- * @return void
88
  */
89
  function ddp_fs_uninstall_cleanup()
90
  {
@@ -146,11 +146,11 @@ if ( !class_exists( 'Delete_Duplicate_Posts' ) ) {
146
  /**
147
  * Ajax callback to handle freemius opt in/out.
148
  *
149
- * @author Lars Koudal
150
- * @since v0.0.1
151
- * @version v1.0.0 Tuesday, January 12th, 2021.
152
- * @access public static
153
- * @return void
154
  */
155
  public static function cp_ddp_fs_opt_in()
156
  {
@@ -234,55 +234,57 @@ if ( !class_exists( 'Delete_Duplicate_Posts' ) ) {
234
  /**
235
  * ddp_action_admin_notices.
236
  *
237
- * @author Lars Koudal
238
- * @since v0.0.1
239
- * @version v1.0.0 Tuesday, January 12th, 2021.
240
- * @access public static
241
- * @return void
242
  */
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;
@@ -301,35 +303,35 @@ if ( !class_exists( '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
  }
@@ -346,29 +348,29 @@ if ( !class_exists( 'Delete_Duplicate_Posts' ) ) {
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
  }
@@ -376,12 +378,12 @@ if ( !class_exists( 'Delete_Duplicate_Posts' ) ) {
376
  /**
377
  * delete_duplicates.
378
  *
379
- * @author Lars Koudal
380
- * @since v0.0.1
381
- * @version v1.0.0 Tuesday, January 12th, 2021.
382
- * @access public static
383
- * @param boolean $return Default: false
384
- * @return void
385
  */
386
  public static function delete_duplicates( $return = false )
387
  {
@@ -403,12 +405,12 @@ if ( !class_exists( 'Delete_Duplicate_Posts' ) ) {
403
  /**
404
  * return_loglines.
405
  *
406
- * @author Lars Koudal
407
- * @since v0.0.1
408
- * @version v1.0.0 Tuesday, January 12th, 2021.
409
- * @access public static
410
- * @param boolean $return Default: false
411
- * @return void
412
  */
413
  public static function return_loglines( $return = false )
414
  {
@@ -450,12 +452,12 @@ if ( !class_exists( 'Delete_Duplicate_Posts' ) ) {
450
  /**
451
  * return_duplicates_ajax.
452
  *
453
- * @author Lars Koudal
454
- * @since v0.0.1
455
- * @version v1.0.0 Tuesday, January 12th, 2021.
456
- * @access public static
457
- * @param boolean $return Default: false
458
- * @return mixed
459
  */
460
  public static function return_duplicates_ajax( $return = false )
461
  {
@@ -468,11 +470,11 @@ if ( !class_exists( 'Delete_Duplicate_Posts' ) ) {
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
  {
@@ -484,18 +486,22 @@ if ( !class_exists( 'Delete_Duplicate_Posts' ) ) {
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
  *
493
- * @author Lars Koudal
494
- * @since v0.0.1
495
- * @version v1.0.0 Tuesday, January 12th, 2021.
496
- * @access public static
497
- * @param boolean $return Default: false
498
- * @return void
499
  */
500
  public static function return_duplicates( $return = false )
501
  {
@@ -567,12 +573,18 @@ if ( !class_exists( 'Delete_Duplicate_Posts' ) ) {
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
  }
@@ -592,7 +604,7 @@ if ( !class_exists( 'Delete_Duplicate_Posts' ) ) {
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'] ),
@@ -659,14 +671,14 @@ if ( !class_exists( 'Delete_Duplicate_Posts' ) ) {
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
  {
@@ -677,11 +689,11 @@ if ( !class_exists( 'Delete_Duplicate_Posts' ) ) {
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
  {
@@ -828,13 +840,13 @@ if ( !class_exists( 'Delete_Duplicate_Posts' ) ) {
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
@@ -892,12 +904,12 @@ if ( !class_exists( 'Delete_Duplicate_Posts' ) ) {
892
  /**
893
  * Log a notification to the database
894
  *
895
- * @author Lars Koudal
896
- * @since v0.0.1
897
- * @version v1.0.0 Monday, January 11th, 2021.
898
- * @access public static
899
- * @param mixed $text
900
- * @return void
901
  */
902
  public static function log( $text )
903
  {
@@ -914,7 +926,7 @@ if ( !class_exists( 'Delete_Duplicate_Posts' ) ) {
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
  }
@@ -922,11 +934,11 @@ if ( !class_exists( 'Delete_Duplicate_Posts' ) ) {
922
  /**
923
  * Enqueues scripts and styles
924
  *
925
- * @author Lars Koudal
926
- * @since v0.0.1
927
- * @version v1.0.0 Monday, January 11th, 2021.
928
- * @access public static
929
- * @return void
930
  */
931
  public static function admin_enqueue_scripts()
932
  {
@@ -963,18 +975,18 @@ if ( !class_exists( 'Delete_Duplicate_Posts' ) ) {
963
  /**
964
  * Create plugin tables
965
  *
966
- * @author Lars Koudal
967
- * @since v0.0.1
968
- * @version v1.0.0 Monday, January 11th, 2021.
969
- * @access public static
970
- * @return void
971
  */
972
  public static function create_table()
973
  {
974
  global $wpdb ;
975
  $table_name = $wpdb->prefix . 'ddp_log';
976
 
977
- if ( $table_name !== $wpdb->get_var( "show tables like '{$table_name}'" ) ) {
978
  $sql = "CREATE TABLE {$table_name} (id bigint(20) NOT NULL AUTO_INCREMENT,datime timestamp NOT NULL DEFAULT '0000-00-00 00:00:00' ON UPDATE CURRENT_TIMESTAMP, note tinytext NOT NULL, PRIMARY KEY (id));";
979
  require_once ABSPATH . 'wp-admin/includes/upgrade.php';
980
  dbDelta( $sql );
@@ -1083,14 +1095,14 @@ if ( !class_exists( 'Delete_Duplicate_Posts' ) ) {
1083
  'id' => 'ddp_help',
1084
  'title' => __( 'Usage and FAQ', 'delete-duplicate-posts' ),
1085
  'content' => '
1086
- <h4>' . __( 'What does this plugin do?', 'delete-duplicate-posts' ) . '</h4>
1087
- <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>
1088
- <p>' . __( "It can run automatically via WordPress's own internal CRON-system, or you can run it automatically.", 'delete-duplicate-posts' ) . '</p>
1089
- <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>
1090
- <h4>' . __( 'Help! Something was deleted that was not supposed to be deleted!', 'delete-duplicate-posts' ) . '</h4>
1091
- <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>
1092
- <p>' . __( 'If you run this plugin, manually or automatically, it is at your OWN risk!', 'delete-duplicate-posts' ) . '</p>
1093
- <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>",
1094
  ) );
1095
  }
1096
  }
@@ -1184,6 +1196,7 @@ if ( !class_exists( 'Delete_Duplicate_Posts' ) ) {
1184
  global $wpdb ;
1185
  $table_name_log = $wpdb->prefix . 'ddp_log';
1186
  $wpdb->query( "TRUNCATE {$table_name_log};" );
 
1187
  echo '<div class="updated"><p>' . esc_html( __( 'The log was cleared.', 'delete-duplicate-posts' ) ) . '</p></div>' ;
1188
  unset( $wpdb );
1189
  }
@@ -1203,25 +1216,16 @@ if ( !class_exists( 'Delete_Duplicate_Posts' ) ) {
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'];
1213
  if ( !$interval ) {
1214
  $interval = 'hourly';
1215
  }
1216
- // if ( $interval !== $last_interval ) {
1217
- // wp_unschedule_hook('ddp_cron');
1218
- // wp_schedule_event( time(), $interval, 'ddp_cron');
1219
- // $options['last_interval'] = $interval;
1220
- // self::save_options( $options );
1221
- // }
1222
- // else {
1223
- // error_log('all good, no change in schedule');
1224
- // }
1225
  $nextscheduled = wp_next_scheduled( 'ddp_cron' );
1226
 
1227
  if ( !$nextscheduled ) {
@@ -1238,76 +1242,76 @@ if ( !class_exists( 'Delete_Duplicate_Posts' ) ) {
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,27 +1322,27 @@ if ( !class_exists( 'Delete_Duplicate_Posts' ) ) {
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,8 +1356,8 @@ if ( !class_exists( 'Delete_Duplicate_Posts' ) ) {
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,23 +1365,25 @@ if ( !class_exists( 'Delete_Duplicate_Posts' ) ) {
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;
@@ -1387,31 +1393,31 @@ if ( !class_exists( 'Delete_Duplicate_Posts' ) ) {
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,128 +1428,135 @@ if ( !class_exists( 'Delete_Duplicate_Posts' ) ) {
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,53 +1570,54 @@ if ( !class_exists( 'Delete_Duplicate_Posts' ) ) {
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
  */
@@ -1611,169 +1625,175 @@ if ( !class_exists( 'Delete_Duplicate_Posts' ) ) {
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
  }
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.1
9
  Author: cleverplugins.com
10
  Author URI: https://cleverplugins.com
11
  Min WP Version: 4.7
81
  /**
82
  * Cleans up when uninstalling
83
  *
84
+ * @author Lars Koudal
85
+ * @since v0.0.1
86
+ * @version v1.0.0 Tuesday, January 12th, 2021.
87
+ * @return void
88
  */
89
  function ddp_fs_uninstall_cleanup()
90
  {
146
  /**
147
  * Ajax callback to handle freemius opt in/out.
148
  *
149
+ * @author Lars Koudal
150
+ * @since v0.0.1
151
+ * @version v1.0.0 Tuesday, January 12th, 2021.
152
+ * @access public static
153
+ * @return void
154
  */
155
  public static function cp_ddp_fs_opt_in()
156
  {
234
  /**
235
  * ddp_action_admin_notices.
236
  *
237
+ * @author Lars Koudal
238
+ * @since v0.0.1
239
+ * @version v1.0.0 Tuesday, January 12th, 2021.
240
+ * @access public static
241
+ * @return void
242
  */
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' ), true ) ) {
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"
258
+ autocomplete="name" style="width:15em;">
259
+ </div>
260
+ </td>
261
+ <td>
262
+ <div class="ml-field-group ml-field-email ml-validate-email ml-validate-required">
263
+ <input type="email" class="regular-text required email" data-inputmask="" name="fields[email]"
264
+ placeholder="Email" autocomplete="email">
265
+ </div>
266
+ </td>
267
+ <td>
268
+ <button type="submit" class="button">Subscribe</button>
269
+ </td>
270
+ </tr>
271
+ <tr>
272
+ <td colspan="3">
273
+ <div class="privacy-policy">
274
+ <p>You can unsubscribe anytime. For more details, review our <a
275
+ href="https://cleverplugins.com/privacy-policy/" target="_blank">Privacy Policy</a>.</p>
276
+ </div>
277
+ </td>
278
+ </tr>
279
+ </table>
280
+ </table>
281
+ <input type="hidden" name="fields[signupsource]" value="PluginInstall">
282
+ <input type="hidden" name="ml-submit" value="1">
283
+ <input type="hidden" name="anticsrf" value="true">
284
+ </form>
285
+ <p><small>Signup form is shown every 14 days until dismissed</small></p>
286
+ </div>
287
+ <?php
288
  }
289
  if ( 'tools_page_delete-duplicate-posts' !== $screen->id ) {
290
  return;
303
  ?></h3>
304
 
305
  <p>
306
+ <?php
307
  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>' ;
308
  ?>
309
  </p>
310
 
311
  <p>
312
+ <?php
313
  // translators:
314
  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>' );
315
  ?>
316
  </p>
317
  <p>
318
+ <a href="javascript:;" class="button button-primary" onclick="cp_ddp_freemius_opt_in(this)"
319
+ data-opt="yes"><?php
320
  esc_html_e( 'Sure, opt-in', 'delete-duplicate-posts' );
321
  ?></a>
322
 
323
+ <a href="javascript:;"
324
+ class="button dismiss-this"><?php
325
  esc_html_e( 'No, thank you', 'delete-duplicate-posts' );
326
  ?></a>
327
  </p>
328
  <input type="hidden" id="cp-ddp-freemius-opt-nonce"
329
+ value="<?php
330
  echo esc_attr( wp_create_nonce( 'cp-ddp-freemius-opt' ) ) ;
331
  ?>" />
332
 
333
  </div>
334
+ <?php
335
  }
336
 
337
  }
348
  ?>
349
  <div id="cp-ddp-reviewlink" data-dismissible="ddp-leavereview-14" class="updated notice notice-success is-dismissible">
350
  <h3>
351
+ <?php
352
  // translators: Total number of deleted duplicates
353
  printf( esc_html__( '%s duplicates deleted!', 'delete-duplicate-posts' ), esc_html( $totaldeleted ) );
354
  ?>
355
  </h3>
356
  <p>
357
+ <?php
358
  // translators: Asking for a review text
359
  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 ) );
360
  ?>
361
  </p>
362
 
363
  <p>
364
+ <a href="https://wordpress.org/support/plugin/delete-duplicate-posts/reviews/?filter=5#new-post"
365
+ class="cp-ddp-dismiss-review-notice cp-ddp-reviewlink button-primary dismiss-this" target="_blank"
366
+ rel="noopener">Ok, you deserve it</a>
367
+ <span class="dashicons dashicons-calendar"></span><a href="#" class="cp-ddp-dismiss-review-notice dismiss-this"
368
+ target="_blank" rel="noopener">Nope, maybe later</a>
369
+ <span class="dashicons dashicons-smiley"></span><a href="#" class="cp-ddp-dismiss-review-notice dismiss-this"
370
+ target="_blank" rel="noopener">I already did</a>
371
  </p>
372
  </div>
373
+ <?php
374
  }
375
 
376
  }
378
  /**
379
  * delete_duplicates.
380
  *
381
+ * @author Lars Koudal
382
+ * @since v0.0.1
383
+ * @version v1.0.0 Tuesday, January 12th, 2021.
384
+ * @access public static
385
+ * @param boolean $return Default: false
386
+ * @return void
387
  */
388
  public static function delete_duplicates( $return = false )
389
  {
405
  /**
406
  * return_loglines.
407
  *
408
+ * @author Lars Koudal
409
+ * @since v0.0.1
410
+ * @version v1.0.0 Tuesday, January 12th, 2021.
411
+ * @access public static
412
+ * @param boolean $return Default: false
413
+ * @return void
414
  */
415
  public static function return_loglines( $return = false )
416
  {
452
  /**
453
  * return_duplicates_ajax.
454
  *
455
+ * @author Lars Koudal
456
+ * @since v0.0.1
457
+ * @version v1.0.0 Tuesday, January 12th, 2021.
458
+ * @access public static
459
+ * @param boolean $return Default: false
460
+ * @return mixed
461
  */
462
  public static function return_duplicates_ajax( $return = false )
463
  {
470
  /**
471
  * Converts a number to relevant unit size
472
  *
473
+ * @author Lars Koudal
474
+ * @since v0.0.1
475
+ * @version v1.0.0 Thursday, June 24th, 2021.
476
+ * @param mixed $size
477
+ * @return void
478
  */
479
  public static function pretty_value( $size )
480
  {
486
  'tb',
487
  'pb'
488
  );
489
+ $log = log( $size, 1024 );
490
+ $i = floor( $log );
491
+ $num = $size / pow( 1024, $i );
492
+ $calc = round( $num, 2 ) . ' ' . $unit[$i];
493
+ return $calc;
494
  }
495
 
496
  /**
497
  * Returns duplicates based on current settings - internal, not used via AJAX
498
  *
499
+ * @author Lars Koudal
500
+ * @since v0.0.1
501
+ * @version v1.0.0 Tuesday, January 12th, 2021.
502
+ * @access public static
503
+ * @param boolean $return Default: false
504
+ * @return void
505
  */
506
  public static function return_duplicates( $return = false )
507
  {
573
  if ( 0 > $resultslimit ) {
574
  $resultsoutput = ' LIMIT ' . intval( $resultslimit );
575
  }
576
+ $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\t\t\tFROM {$table_name} AS t1 INNER JOIN (\n\t\t\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\t\t\tFROM {$table_name}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tWHERE post_type IN (" . $ddp_pts . ')
577
+ AND post_status IN (' . $post_stati . ')
578
+ GROUP BY post_title HAVING COUNT(*)>1 LIMIT 0,100
579
+ ) AS t2 ON t1.post_title = t2.post_title
580
+ AND post_status IN (' . $post_stati . ')
581
+ ORDER BY t1.post_title, t1.post_date DESC';
582
  $json_response['lookup_query'] = $thisquery;
583
  $dupes = $wpdb->get_results( $thisquery, ARRAY_A );
584
+ // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
585
  $json_response['lookup_error'] = htmlspecialchars( $wpdb->last_error, ENT_QUOTES );
586
 
587
+ if ( '' !== $wpdb->last_error ) {
588
  $last_error = htmlspecialchars( $wpdb->last_error, ENT_QUOTES );
589
  self::log( 'Look up error: ' . $last_error );
590
  }
604
  }
605
 
606
 
607
+ if ( $dupe['ID'] !== $dupe['save_this_post_id'] ) {
608
  $dupedetails = array(
609
  'ID' => $dupe['ID'],
610
  'permalink' => get_permalink( $dupe['ID'] ),
671
  /**
672
  * create_redirect. @todo @pending
673
  *
674
+ * @author Lars Koudal
675
+ * @since v0.0.1
676
+ * @version v1.0.0 Friday, July 2nd, 2021.
677
+ * @access public static
678
+ * @param mixed $inurl
679
+ * @param mixed $targeturl
680
+ * @param integer $code Default: 301
681
+ * @return void
682
  */
683
  public static function create_redirect( $inurl, $targeturl, $code = 301 )
684
  {
689
  /**
690
  * Return default options
691
  *
692
+ * @author Lars Koudal
693
+ * @since v0.0.1
694
+ * @version v1.0.0 Friday, July 2nd, 2021.
695
+ * @access public static
696
+ * @return mixed
697
  */
698
  public static function default_options()
699
  {
840
  ?>
841
  <div class="notice notice-success">
842
  <p>
843
+ <?php
844
  // translators:
845
  printf( esc_html__( 'A total of %s duplicate posts were deleted.', 'delete-duplicate-posts' ), intval( $dispcount ) );
846
  ?>
847
  </p>
848
  </div>
849
+ <?php
850
  }
851
 
852
  // manualrun
904
  /**
905
  * Log a notification to the database
906
  *
907
+ * @author Lars Koudal
908
+ * @since v0.0.1
909
+ * @version v1.0.0 Monday, January 11th, 2021.
910
+ * @access public static
911
+ * @param mixed $text
912
+ * @return void
913
  */
914
  public static function log( $text )
915
  {
926
  if ( $total > 1000 ) {
927
  $targettime = $wpdb->get_var( "SELECT `datime` from `{$ddp_logtable}` order by `datime` DESC limit 500,1;" );
928
  // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared
929
+ $wpdb->query( $wpdb->prepare( 'DELETE from `$ddp_logtable` where `datime` < %s', $targettime ) );
930
  }
931
 
932
  }
934
  /**
935
  * Enqueues scripts and styles
936
  *
937
+ * @author Lars Koudal
938
+ * @since v0.0.1
939
+ * @version v1.0.0 Monday, January 11th, 2021.
940
+ * @access public static
941
+ * @return void
942
  */
943
  public static function admin_enqueue_scripts()
944
  {
975
  /**
976
  * Create plugin tables
977
  *
978
+ * @author Lars Koudal
979
+ * @since v0.0.1
980
+ * @version v1.0.0 Monday, January 11th, 2021.
981
+ * @access public static
982
+ * @return void
983
  */
984
  public static function create_table()
985
  {
986
  global $wpdb ;
987
  $table_name = $wpdb->prefix . 'ddp_log';
988
 
989
+ if ( $wpdb->get_var( $wpdb->prepare( 'SHOW TABLES LIKE %s', $table_name ) ) === $table_name ) {
990
  $sql = "CREATE TABLE {$table_name} (id bigint(20) NOT NULL AUTO_INCREMENT,datime timestamp NOT NULL DEFAULT '0000-00-00 00:00:00' ON UPDATE CURRENT_TIMESTAMP, note tinytext NOT NULL, PRIMARY KEY (id));";
991
  require_once ABSPATH . 'wp-admin/includes/upgrade.php';
992
  dbDelta( $sql );
1095
  'id' => 'ddp_help',
1096
  'title' => __( 'Usage and FAQ', 'delete-duplicate-posts' ),
1097
  'content' => '
1098
+ <h4>' . __( 'What does this plugin do?', 'delete-duplicate-posts' ) . '</h4>
1099
+ <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>
1100
+ <p>' . __( "It can run automatically via WordPress's own internal CRON-system, or you can run it automatically.", 'delete-duplicate-posts' ) . '</p>
1101
+ <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>
1102
+ <h4>' . __( 'Help! Something was deleted that was not supposed to be deleted!', 'delete-duplicate-posts' ) . '</h4>
1103
+ <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>
1104
+ <p>' . __( 'If you run this plugin, manually or automatically, it is at your OWN risk!', 'delete-duplicate-posts' ) . '</p>
1105
+ <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\t\t<p><a href='https://cleverplugins.com' target='_blank'>cleverplugins.com</a>.</p>",
1106
  ) );
1107
  }
1108
  }
1196
  global $wpdb ;
1197
  $table_name_log = $wpdb->prefix . 'ddp_log';
1198
  $wpdb->query( "TRUNCATE {$table_name_log};" );
1199
+ //phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared
1200
  echo '<div class="updated"><p>' . esc_html( __( 'The log was cleared.', 'delete-duplicate-posts' ) ) . '</p></div>' ;
1201
  unset( $wpdb );
1202
  }
1216
  ?></span></h2>
1217
 
1218
  <div class="ddp_content_wrapper">
1219
+ <div class="ddp_content_cell">
1220
+ <div id="ddp_container">
1221
+ <div id="dashboard">
1222
+ <?php
1223
 
1224
  if ( $options['ddp_enabled'] ) {
1225
  $interval = $options['ddp_schedule'];
1226
  if ( !$interval ) {
1227
  $interval = 'hourly';
1228
  }
 
 
 
 
 
 
 
 
 
1229
  $nextscheduled = wp_next_scheduled( 'ddp_cron' );
1230
 
1231
  if ( !$nextscheduled ) {
1242
 
1243
  $totaldeleted = get_option( 'ddp_deleted_duplicates' );
1244
  ?>
1245
+ <div class="statusdiv">
1246
+ <div class="spinner is-active"></div>
1247
+ <div class="statusmessage"></div>
1248
+ <div class="dupelist">
1249
+ <table class="wp-list-table widefat fixed striped posts duplicatetable" cellspacing="0">
1250
+ <thead>
1251
+ <tr>
1252
+ <td id="cb" class="manage-column column-cb check-column"><label class="screen-reader-text"
1253
+ for="cb-select-all-1">Select All</label><input id="cb-select-all-1" type="checkbox"></td>
1254
+ <th><?php
1255
  esc_html_e( 'Duplicate', 'delete-duplicate-posts' );
1256
  ?></th>
1257
+ <th><?php
1258
  esc_html_e( 'Original', 'delete-duplicate-posts' );
1259
  ?></th>
1260
+ </tr>
1261
+ </thead>
1262
+ <tbody id="listofduplicates">
1263
+ </tbody>
1264
 
1265
+ <tfoot>
1266
+ <tr>
1267
+ <td id="cb" class="manage-column column-cb check-column"><label class="screen-reader-text"
1268
+ for="cb-select-all-1">Select All</label><input id="cb-select-all-1" type="checkbox"></td>
1269
+ <th><?php
1270
  esc_html_e( 'Duplicate', 'delete-duplicate-posts' );
1271
  ?></th>
1272
+ <th><?php
1273
  esc_html_e( 'Original', 'delete-duplicate-posts' );
1274
  ?></th>
1275
+ </tr>
1276
+ </tfoot>
1277
+ </table>
1278
+ </div>
1279
+ <form>
1280
+ <?php
1281
  wp_nonce_field( 'ddp-buttons' );
1282
  ?>
1283
+ <table id="ddp_buttons">
1284
+ <tr>
1285
+ <td><input type="submit" name="deleteduplicateposts_resetview" id="deleteduplicateposts_resetview"
1286
+ class="button button-small button-secondary"
1287
+ value="<?php
1288
  esc_html_e( 'Refresh list', 'delete-duplicate-posts' );
1289
  ?>" disabled /></td>
1290
+ <td><input type="submit" name="deleteduplicateposts_deleteall" id="deleteduplicateposts_deleteall"
1291
+ class="button button-small button-primary"
1292
+ value="<?php
1293
  esc_html_e( 'Delete duplicates', 'delete-duplicate-posts' );
1294
  ?>" disabled /></td>
1295
+ </tr>
1296
+ </table>
1297
+ </form>
1298
+ </div>
1299
 
1300
+ </div><!-- #dashboard -->
1301
 
1302
+ <div id="configuration">
1303
+ <h3><?php
1304
  esc_html_e( 'Settings', 'delete-duplicate-posts' );
1305
  ?></h3>
1306
+ <p>
1307
+ <?php
1308
  $nextscheduled = wp_next_scheduled( 'ddp_cron' );
1309
 
1310
  if ( $nextscheduled ) {
1311
  ?>
1312
+ <div class="notice notice-info is-dismissible">
1313
+ <h3><span class="dashicons dashicons-saved"></span> Automatically Deleting Duplicates</h3>
1314
+ <?php
1315
  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>' ;
1316
  echo '<p class="center">' ;
1317
  echo sprintf(
1322
  ) ;
1323
  echo '</p>' ;
1324
  ?>
1325
+ </div>
1326
+ <?php
1327
  }
1328
 
1329
  ?>
1330
+ </p>
1331
+ <form method="post" id="delete_duplicate_posts_options">
1332
+ <?php
1333
  wp_nonce_field( 'ddp-update-options' );
1334
  ?>
1335
+ <table width="100%" cellspacing="2" cellpadding="5" class="form-table">
1336
 
1337
 
1338
+ <tr valign="top">
1339
+ <th><label
1340
+ for="ddp_enabled"><?php
1341
  esc_html_e( 'Which post types?:', 'delete-duplicate-posts' );
1342
  ?></label>
1343
+ </th>
1344
+ <td>
1345
+ <?php
1346
  $builtin = array( 'post', 'page', 'attachment' );
1347
  $args = array(
1348
  'public' => true,
1356
 
1357
  if ( $post_types ) {
1358
  ?>
1359
+ <ul class="radio">
1360
+ <?php
1361
  $step = 0;
1362
  if ( !is_array( $checked_post_types ) ) {
1363
  $checked_post_types = array();
1365
  foreach ( $post_types as $pt ) {
1366
  $checked = array_search( $pt, $checked_post_types, true );
1367
  ?>
1368
+ <li>
1369
+ <input type="checkbox" name="ddp_pts[]" id="ddp_pt-<?php
1370
  echo esc_attr( $step ) ;
1371
  ?>"
1372
+ value="<?php
1373
  echo esc_html( $pt ) ;
1374
+ ?>"
1375
+ <?php
1376
  if ( false !== $checked ) {
1377
  echo ' checked' ;
1378
  }
1379
+ ?>
1380
+ />
1381
+ <label for="ddp_pt-<?php
1382
  echo esc_attr( $step ) ;
1383
  ?>"><?php
1384
  echo esc_html( $pt ) ;
1385
  ?></label>
1386
+ <?php
1387
  // Count for each post type
1388
  $postinfo = wp_count_posts( $pt );
1389
  $othercount = 0;
1393
  // translators: Total number of deleted duplicates
1394
  echo '<small>' . sprintf( esc_html__( '(%s total found)', 'delete-duplicate-posts' ), esc_html( number_format_i18n( $othercount ) ) ) . '</small>' ;
1395
  ?>
1396
+ </li>
1397
+ <?php
1398
  $step++;
1399
  }
1400
  ?>
1401
+ </ul>
1402
+ <?php
1403
  }
1404
 
1405
  ?>
1406
+ <p class="description">
1407
+ <?php
1408
  esc_html_e( 'Choose which post types to scan for duplicates.', 'delete-duplicate-posts' );
1409
  ?>
1410
+ </p>
1411
+ </td>
1412
+ </tr>
1413
 
1414
+ <tr>
1415
+ <th><label for="ddp_enabled"><?php
1416
  esc_html_e( 'Post status', 'delete-duplicate-posts' );
1417
  ?></label>
1418
+ </th>
1419
+ <td>
1420
+ <?php
1421
  $stati = array(
1422
  'publish' => (object) array(
1423
  'label' => 'Published',
1428
 
1429
  if ( $stati ) {
1430
  ?>
1431
+ <ul class="radio">
1432
+ <?php
1433
  $staticount = count( $stati );
1434
  foreach ( $stati as $key => $st ) {
1435
 
1436
  if ( $st->show_in_admin_status_list ) {
1437
  $checked = array_search( $key, $checked_post_stati, true );
1438
  ?>
1439
+ <li>
1440
+ <input type="checkbox" name="ddp_pstati[]" id="ddp_pstatus-<?php
1441
  echo esc_attr( $key ) ;
1442
  ?>"
1443
+ value="<?php
1444
  echo esc_attr( $key ) ;
1445
+ ?>"
1446
+ <?php
1447
  if ( false !== $checked ) {
1448
  echo ' checked' ;
1449
  }
1450
+ ?>
1451
+ <?php
1452
  if ( 1 === $staticount ) {
1453
  echo ' disabled' ;
1454
  }
1455
+ ?>
1456
+ />
1457
+ <label
1458
+ for="ddp_pstatus-<?php
1459
  echo esc_attr( $key ) ;
1460
  ?>"><?php
1461
  echo esc_html( $key . ' (' . $st->label . ')' ) ;
1462
  ?></label>
1463
+ </li>
1464
+ <?php
1465
  $step++;
1466
  }
1467
 
1468
  }
1469
  ?>
1470
+ </ul>
1471
+ <?php
1472
  }
1473
 
1474
  ?>
1475
+ </td>
1476
 
1477
 
1478
+ </tr>
1479
+ <?php
1480
  $comparemethod = 'titlecompare';
1481
  global $ddp_fs ;
1482
  ?>
1483
+ <tr valign="top">
1484
+ <th><?php
1485
  esc_html_e( 'Comparison Method', 'delete-duplicate-posts' );
1486
  ?></th>
1487
+ <td>
1488
+ <ul class="ddpcomparemethod">
1489
 
1490
+ <li>
1491
+ <label>
1492
+ <input type="radio" name="ddp_method" value="titlecompare"
1493
+ <?php
1494
  checked( 'titlecompare', $comparemethod );
1495
  ?> />
1496
+ <?php
1497
  esc_html_e( 'Compare by title (default)', 'delete-duplicate-posts' );
1498
  ?>
1499
+ <span
1500
+ class="optiondesc"><?php
1501
  esc_html_e( 'Looks at the title of the post itself.', 'delete-duplicate-posts' );
1502
  ?></span>
1503
+ </label>
1504
 
1505
+ </li>
1506
 
1507
+ <?php
1508
  global $ddp_fs ;
1509
  ?>
1510
+ </ul>
1511
+ </td>
1512
+ </tr>
1513
+ <tr>
1514
+ <th><label
1515
+ for="ddp_keep"><?php
1516
  esc_html_e( 'Delete which posts?:', 'delete-duplicate-posts' );
1517
  ?></label></th>
1518
+ <td>
1519
 
1520
+ <select name="ddp_keep" id="ddp_keep">
1521
+ <option value="oldest"
1522
+ <?php
1523
  if ( 'oldest' === $options['ddp_keep'] ) {
1524
  echo 'selected="selected"' ;
1525
  }
1526
+ ?>
1527
+ ><?php
1528
  esc_html_e( 'Keep oldest', 'delete-duplicate-posts' );
1529
  ?></option>
1530
+ <option value="latest"
1531
+ <?php
1532
  if ( 'latest' === $options['ddp_keep'] ) {
1533
  echo 'selected="selected"' ;
1534
  }
1535
+ ?>
1536
+ ><?php
1537
  esc_html_e( 'Keep latest', 'delete-duplicate-posts' );
1538
  ?></option>
1539
+ </select>
1540
+ <p class="description">
1541
+ <?php
1542
  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' );
1543
  ?>
1544
+ </p>
1545
+ </td>
1546
+ </tr>
1547
 
1548
 
1549
 
1550
 
1551
+ <tr>
1552
+ <th><label
1553
+ for="ddp_resultslimit"><?php
1554
  esc_html_e( 'Find how many duplicates:', 'delete-duplicate-posts' );
1555
  ?></label>
1556
+ </th>
1557
+ <td>
1558
 
1559
+ <?php
1560
  $dupe_options = array(
1561
  0 => __( 'No limit', 'delete-duplicate-posts' ),
1562
  10000 => number_format_i18n( '10000' ),
1570
  10 => '10',
1571
  );
1572
  ?>
1573
+ <select name="ddp_resultslimit" id="ddp_resultslimit">
1574
+ <?php
1575
  foreach ( $dupe_options as $key => $label ) {
1576
  ?>
1577
+ <option value="<?php
1578
+ echo esc_attr( $key ) ;
1579
+ ?>"
1580
+ <?php
1581
  selected( $options['ddp_resultslimit'], $key );
1582
  ?>>
1583
+ <?php
1584
+ echo esc_attr( $label ) ;
1585
  ?></option>
1586
+ <?php
1587
  }
1588
  ?>
1589
+ </select>
1590
 
1591
+ <p class="description">
1592
+ <?php
1593
  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' );
1594
  ?>
1595
+ </p>
1596
+ </td>
1597
+ </tr>
1598
 
1599
+ <?php
1600
  /*
1601
+
1602
+ <tr valign="top">
1603
+ <th><label for="ddp_limit"><?php esc_html_e( 'Delete at maximum :', 'delete-duplicate-posts' ); ?></label>
1604
  </th>
1605
  <td><select name="ddp_limit">
1606
+ <?php
1607
+ for ( $x = 1; $x <= 10; $x++ ) {
1608
+ $val = ( $x * 50 );
1609
+ echo "<option value='" . esc_attr( $val ) . "' ";
1610
+ if ( $options['ddp_limit'] === $val ) {
1611
+ echo 'selected';
1612
+ }
1613
+ echo '>' . esc_attr( $val ) . '</option>';
1614
+ }
1615
+ ?>
1616
+ </select>
1617
+ <?php esc_html_e( 'duplicates.', 'delete-duplicate-posts' ); ?>
1618
+ <p class="description">
1619
+ <?php esc_html_e( 'Setting a limit is a good idea, especially if your site is on a busy server.', 'delete-duplicate-posts' ); ?>
1620
+ </p>
1621
  </td>
1622
  </tr>
1623
  */
1625
 
1626
 
1627
 
1628
+ <tr>
1629
+ <td colspan="2">
1630
+ <hr>
1631
+ </td>
1632
+ </tr>
1633
 
1634
+ <tr valign="top">
1635
+ <th><?php
1636
  esc_html_e( 'Enable automatic deletion?:', 'delete-duplicate-posts' );
1637
  ?>
1638
 
1639
+ </th>
1640
+ <td><label for="ddp_enabled">
1641
+ <input type="checkbox" id="ddp_enabled" name="ddp_enabled"
1642
+ <?php
1643
  if ( true === $options['ddp_enabled'] ) {
1644
  echo 'checked="checked"' ;
1645
  }
1646
+ ?>
1647
+ >
1648
+ <p class="description">
1649
+ <?php
1650
  esc_html_e( 'Clean duplicates automatically.', 'delete-duplicate-posts' );
1651
  ?></p>
1652
+ </label>
1653
+ </td>
1654
+ </tr>
1655
 
1656
 
1657
+ <tr>
1658
+ <th><label for="ddp_schedule"><?php
1659
  esc_html_e( 'How often?:', 'delete-duplicate-posts' );
1660
  ?></label>
1661
+ </th>
1662
+ <td>
1663
 
1664
+ <select name="ddp_schedule" id="ddp_schedule">
1665
+ <?php
1666
  $schedules = wp_get_schedules();
1667
  if ( $schedules ) {
1668
  foreach ( $schedules as $key => $sch ) {
1669
  ?>
1670
+ <option value="<?php
1671
  echo esc_attr( $key ) ;
1672
+ ?>"
1673
+ <?php
1674
  if ( isset( $options['ddp_schedule'] ) && esc_attr( $key ) === $options['ddp_schedule'] ) {
1675
  echo esc_html( 'selected="selected"' ) ;
1676
  }
1677
+ ?>
1678
+ ><?php
1679
  echo esc_html( $sch['display'] ) ;
1680
  ?></option>
1681
+ <?php
1682
  }
1683
  }
1684
  ?>
1685
+ </select>
1686
+ <p class="description">
1687
+ <?php
1688
  esc_html_e( 'How often should the cron job run?', 'delete-duplicate-posts' );
1689
  ?></p>
1690
+ </td>
1691
+ </tr>
1692
 
1693
 
1694
 
1695
+ <tr>
1696
+ <td colspan="2">
1697
+ <hr>
1698
+ </td>
1699
+ </tr>
1700
 
1701
+ <tr>
1702
+ <th><?php
1703
  esc_html_e( 'Send status mail?:', 'delete-duplicate-posts' );
1704
  ?></th>
1705
+ <td>
1706
+ <label for="ddp_statusmail">
1707
+ <input type="checkbox" id="ddp_statusmail" name="ddp_statusmail"
1708
+ <?php
1709
  if ( isset( $options['ddp_statusmail'] ) && true === $options['ddp_statusmail'] ) {
1710
  echo 'checked="checked"' ;
1711
  }
1712
+ ?>
1713
+ <p
1714
+ class="description"><?php
1715
  esc_html_e( 'Sends a status email if duplicates have been found.', 'delete-duplicate-posts' );
1716
  ?>
1717
+ </p>
1718
+ </label>
1719
+ </td>
1720
+ </tr>
1721
 
1722
+ <tr>
1723
+ <th><?php
1724
  esc_html_e( 'Email recipient:', 'delete-duplicate-posts' );
1725
  ?></th>
1726
+ <td>
1727
+ <label for="ddp_statusmail_recipient">
1728
 
1729
+ <input type="text" class="regular-text" id="ddp_statusmail_recipient"
1730
+ name="ddp_statusmail_recipient"
1731
+ value="<?php
1732
  echo esc_html( $options['ddp_statusmail_recipient'] ) ;
1733
  ?>">
1734
+ <p class="description">
1735
+ <?php
1736
  esc_html_e( 'Who should get the notification email.', 'delete-duplicate-posts' );
1737
  ?></p>
1738
+ </label>
1739
+ </td>
1740
+ </tr>
1741
 
1742
 
1743
 
1744
 
1745
+ <th colspan=2><input type="submit" class="button-primary" name="delete_duplicate_posts_save"
1746
+ value="<?php
1747
  esc_html_e( 'Save Settings', 'delete-duplicate-posts' );
1748
  ?>" /></th>
1749
+ </tr>
1750
 
1751
+ </table>
1752
 
1753
+ </form>
1754
+ </div><!-- #configuration -->
1755
 
1756
 
1757
+ <div id="log">
1758
 
1759
+ <h3><?php
1760
  esc_html_e( 'The Log', 'delete-duplicate-posts' );
1761
  ?></h3>
1762
+ <div class="spinner is-active"></div>
1763
+ <ul class="large-text" name="ddp_log" id="ddp_log">
1764
+ </ul>
1765
 
1766
+ </div>
1767
+ <p>
1768
+ <form method="post" id="ddp_clearlog">
1769
+ <?php
1770
  wp_nonce_field( 'ddp_clearlog_nonce' );
1771
  ?>
1772
 
1773
+ <input class="button-secondary" type="submit" name="ddp_clearlog"
1774
+ value="<?php
1775
  esc_html_e( 'Reset log', 'delete-duplicate-posts' );
1776
  ?>" />
1777
+ </form>
1778
+ </p>
1779
 
1780
+ </div><!-- #ddp_container -->
1781
 
1782
+ <?php
1783
  include_once 'sidebar.php';
1784
  ?>
1785
 
1786
+ <?php
1787
  if ( function_exists( 'ddp_fs' ) ) {
1788
  global $ddp_fs ;
1789
  }
1790
  ?>
1791
 
1792
+ </div>
1793
+ </div>
1794
 
1795
  </div>
1796
+ <?php
1797
  }
1798
 
1799
  }
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.8
9
- Stable tag: 4.7
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.7 =
53
  * 2021/07/11
54
  * FIX: Duplicates not always properly detected, thank you for the reporters to help fix this bug :-)
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.1
10
  Requires PHP: 5.6
11
 
12
  Get rid of duplicate posts and pages on your blog!
49
 
50
  == Changelog ==
51
 
52
+
53
+ = 4.7.1 =
54
+ * 2021/07/21
55
+ * Security Hardening
56
+
57
+
58
  = 4.7 =
59
  * 2021/07/11
60
  * FIX: Duplicates not always properly detected, thank you for the reporters to help fix this bug :-)
sidebar.php CHANGED
@@ -7,130 +7,130 @@ if ( !defined( 'ABSPATH' ) ) {
7
  ?>
8
 
9
  <div id="sidebar-container" class="ddp_content_cell">
10
- <?php
11
  global $ddp_fs ;
12
 
13
  if ( !$ddp_fs->is_registered() && !$ddp_fs->is_pending_activation() ) {
14
  ?>
15
- <div class="sidebarrow optin">
16
- <h3><span class="dashicons dashicons-warning"></span>
17
- <?php
18
  esc_html_e( 'Help us improve!', 'delete-duplicate-posts' );
19
  ?></h3>
20
- <p>
21
- <?php
22
  esc_html_e( 'Opt-in to our security and feature updates notifications, and non-sensitive diagnostic tracking.', 'delete-duplicate-posts' );
23
  ?>
24
- </p>
25
- <a href="javascript:;" class="button button-secondary" onclick="cp_ddp_freemius_opt_in(this)"
26
- data-opt="yes"><?php
27
  esc_html_e( 'Click here to opt in.', 'delete-duplicate-posts' );
28
  ?></a>
29
- <div id="cp-ddp-opt-spin" class="spinner"></div><input type="hidden" id="cp-ddp-freemius-opt-nonce"
30
- value="<?php
31
  echo esc_attr( wp_create_nonce( 'cp-ddp-freemius-opt' ) ) ;
32
  ?>" />
33
- </div>
34
- <?php
35
  }
36
 
37
  $ddp_deleted_duplicates = get_option( 'ddp_deleted_duplicates' );
38
 
39
  if ( $ddp_deleted_duplicates ) {
40
  ?>
41
- <div class="sidebarrow">
42
- <h3>
43
- <?php
44
  printf(
45
  /* translators: %s: Number of deleted posts */
46
  esc_html__( '%s duplicates deleted!', 'delete-duplicate-posts' ),
47
  esc_html( number_format_i18n( $ddp_deleted_duplicates ) )
48
  );
49
  ?>
50
- </h3>
51
- </div>
52
- <?php
53
  }
54
 
55
  ?>
56
 
57
- <div class="sidebarrow">
58
- <p class="warning">
59
- <?php
60
  esc_html_e( 'We recommend you always make a backup before running this tool. Changes are permanent!', 'delete-duplicate-posts' );
61
  ?>
62
- </p>
63
- </div>
64
 
65
- <?php
66
  $display_promotion = true;
67
 
68
  if ( $display_promotion ) {
69
  ?>
70
- <div class="sidebarrow">
71
- <hr>
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
87
  echo esc_url( $ddp_fs->pricing_url() ) ;
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 -->
101
- <?php
102
  }
103
 
104
  ?>
105
 
106
- <div class="sidebarrow">
107
- <h3><?php
108
  esc_html_e( 'Our other plugins', 'delete-duplicate-posts' );
109
  ?></h3>
110
- <a href="https://wpsecurityninja.com" target="_blank" style="float: right;" rel="noopener"><img
111
- src="<?php
112
  echo esc_url( plugin_dir_url( __FILE__ ) . 'images/security-ninja-logo.png' ) ;
113
  ?>"
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
121
  echo esc_url( plugin_dir_url( __FILE__ ) . 'images/seoboosterlogo.png' ) ;
122
  ?>"
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">
130
- <h3>Need help?</h3>
131
- <p><a href="https://wordpress.org/support/plugin/delete-duplicate-posts/" target="_blank"
132
- rel="noopener"><?php
133
  esc_html_e( 'Support Forum on WordPress.org', 'delete-duplicate-posts' );
134
  ?></a></p>
135
- </div><!-- .sidebarrow -->
136
- </div>
7
  ?>
8
 
9
  <div id="sidebar-container" class="ddp_content_cell">
10
+ <?php
11
  global $ddp_fs ;
12
 
13
  if ( !$ddp_fs->is_registered() && !$ddp_fs->is_pending_activation() ) {
14
  ?>
15
+ <div class="sidebarrow optin">
16
+ <h3><span class="dashicons dashicons-warning"></span>
17
+ <?php
18
  esc_html_e( 'Help us improve!', 'delete-duplicate-posts' );
19
  ?></h3>
20
+ <p>
21
+ <?php
22
  esc_html_e( 'Opt-in to our security and feature updates notifications, and non-sensitive diagnostic tracking.', 'delete-duplicate-posts' );
23
  ?>
24
+ </p>
25
+ <a href="javascript:;" class="button button-secondary" onclick="cp_ddp_freemius_opt_in(this)"
26
+ data-opt="yes"><?php
27
  esc_html_e( 'Click here to opt in.', 'delete-duplicate-posts' );
28
  ?></a>
29
+ <div id="cp-ddp-opt-spin" class="spinner"></div><input type="hidden" id="cp-ddp-freemius-opt-nonce"
30
+ value="<?php
31
  echo esc_attr( wp_create_nonce( 'cp-ddp-freemius-opt' ) ) ;
32
  ?>" />
33
+ </div>
34
+ <?php
35
  }
36
 
37
  $ddp_deleted_duplicates = get_option( 'ddp_deleted_duplicates' );
38
 
39
  if ( $ddp_deleted_duplicates ) {
40
  ?>
41
+ <div class="sidebarrow">
42
+ <h3>
43
+ <?php
44
  printf(
45
  /* translators: %s: Number of deleted posts */
46
  esc_html__( '%s duplicates deleted!', 'delete-duplicate-posts' ),
47
  esc_html( number_format_i18n( $ddp_deleted_duplicates ) )
48
  );
49
  ?>
50
+ </h3>
51
+ </div>
52
+ <?php
53
  }
54
 
55
  ?>
56
 
57
+ <div class="sidebarrow">
58
+ <p class="warning">
59
+ <?php
60
  esc_html_e( 'We recommend you always make a backup before running this tool. Changes are permanent!', 'delete-duplicate-posts' );
61
  ?>
62
+ </p>
63
+ </div>
64
 
65
+ <?php
66
  $display_promotion = true;
67
 
68
  if ( $display_promotion ) {
69
  ?>
70
+ <div class="sidebarrow">
71
+ <hr>
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
87
  echo esc_url( $ddp_fs->pricing_url() ) ;
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 -->
101
+ <?php
102
  }
103
 
104
  ?>
105
 
106
+ <div class="sidebarrow">
107
+ <h3><?php
108
  esc_html_e( 'Our other plugins', 'delete-duplicate-posts' );
109
  ?></h3>
110
+ <a href="https://wpsecurityninja.com" target="_blank" style="float: right;" rel="noopener"><img
111
+ src="<?php
112
  echo esc_url( plugin_dir_url( __FILE__ ) . 'images/security-ninja-logo.png' ) ;
113
  ?>"
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
121
  echo esc_url( plugin_dir_url( __FILE__ ) . 'images/seoboosterlogo.png' ) ;
122
  ?>"
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">
130
+ <h3>Need help?</h3>
131
+ <p><a href="https://wordpress.org/support/plugin/delete-duplicate-posts/" target="_blank"
132
+ rel="noopener"><?php
133
  esc_html_e( 'Support Forum on WordPress.org', 'delete-duplicate-posts' );
134
  ?></a></p>
135
+ </div><!-- .sidebarrow -->
136
+ </div>