Simple Download Monitor - Version 3.8.7

Version Description

  • Added a new filter for the visitor name tracking.
  • Added two new bot strings that will be filtered out from the log (when using the "Do Not Count Downloads from Bots" option).
  • Updated the 'sdm_fancy1_below_download_description' filter hook to also pass the Download ID via additional params.
  • Updated the addon auto-updater library.
  • Added more sanitization to the "Logs" interface.
Download this release

Release Info

Developer mra13
Plugin Icon 128x128 Simple Download Monitor
Version 3.8.7
Comparing to
See all releases

Code changes from version 3.8.3 to 3.8.7

Files changed (81) hide show
  1. includes/admin-side/sdm-admin-individual-item-logs-page.php +11 -8
  2. includes/class-sdm-addons-updater.php +6 -0
  3. includes/sdm-admin-menu-handler.php +49 -15
  4. includes/sdm-download-request-handler.php +195 -183
  5. includes/sdm-logs-list-table.php +19 -13
  6. includes/sdm-utility-functions-admin-side.php +1 -1
  7. includes/sdm-utility-functions.php +4 -2
  8. includes/templates/fancy1/sdm-fancy-1.php +6 -5
  9. languages/simple-download-monitor.pot +2 -2
  10. lib/plugin-update-checker/Puc/v4/Factory.php +1 -1
  11. lib/plugin-update-checker/Puc/{v4p8 → v4p9}/Autoloader.php +19 -3
  12. lib/plugin-update-checker/Puc/{v4p8 → v4p9}/DebugBar/Extension.php +8 -8
  13. lib/plugin-update-checker/Puc/{v4p8 → v4p9}/DebugBar/Panel.php +3 -3
  14. lib/plugin-update-checker/Puc/{v4p8 → v4p9}/DebugBar/PluginExtension.php +4 -4
  15. lib/plugin-update-checker/Puc/{v4p8 → v4p9}/DebugBar/PluginPanel.php +3 -3
  16. lib/plugin-update-checker/Puc/{v4p8 → v4p9}/DebugBar/ThemePanel.php +3 -3
  17. lib/plugin-update-checker/Puc/{v4p8 → v4p9}/Factory.php +64 -5
  18. lib/plugin-update-checker/Puc/{v4p8 → v4p9}/InstalledPackage.php +3 -3
  19. lib/plugin-update-checker/Puc/{v4p8 → v4p9}/Metadata.php +2 -2
  20. lib/plugin-update-checker/Puc/{v4p8 → v4p9}/OAuthSignature.php +2 -2
  21. lib/plugin-update-checker/Puc/{v4p8 → v4p9}/Plugin/Info.php +4 -2
  22. lib/plugin-update-checker/Puc/{v4p8 → v4p9}/Plugin/Package.php +5 -5
  23. lib/plugin-update-checker/Puc/{v4p8 → v4p9}/Plugin/Ui.php +3 -3
  24. lib/plugin-update-checker/Puc/{v4p8 → v4p9}/Plugin/Update.php +11 -9
  25. lib/plugin-update-checker/Puc/{v4p8 → v4p9}/Plugin/UpdateChecker.php +19 -19
  26. lib/plugin-update-checker/Puc/{v4p8 → v4p9}/Scheduler.php +36 -8
  27. lib/plugin-update-checker/Puc/{v4p8 → v4p9}/StateStore.php +9 -9
  28. lib/plugin-update-checker/Puc/{v4p8 → v4p9}/Theme/Package.php +2 -2
  29. lib/plugin-update-checker/Puc/{v4p8 → v4p9}/Theme/Update.php +4 -4
  30. lib/plugin-update-checker/Puc/{v4p8 → v4p9}/Theme/UpdateChecker.php +10 -10
  31. lib/plugin-update-checker/Puc/{v4p8 → v4p9}/Update.php +2 -2
  32. lib/plugin-update-checker/Puc/{v4p8 → v4p9}/UpdateChecker.php +57 -36
  33. lib/plugin-update-checker/Puc/{v4p8 → v4p9}/UpgraderStatus.php +2 -2
  34. lib/plugin-update-checker/Puc/{v4p8 → v4p9}/Utils.php +2 -2
  35. lib/plugin-update-checker/Puc/{v4p8 → v4p9}/Vcs/Api.php +7 -7
  36. lib/plugin-update-checker/Puc/{v4p8 → v4p9}/Vcs/BaseChecker.php +3 -3
  37. lib/plugin-update-checker/Puc/{v4p8 → v4p9}/Vcs/BitBucketApi.php +12 -12
  38. lib/plugin-update-checker/Puc/{v4p8 → v4p9}/Vcs/GitHubApi.php +65 -41
  39. lib/plugin-update-checker/Puc/{v4p8 → v4p9}/Vcs/GitLabApi.php +8 -8
  40. lib/plugin-update-checker/Puc/{v4p8 → v4p9}/Vcs/PluginUpdateChecker.php +13 -8
  41. lib/plugin-update-checker/Puc/{v4p8 → v4p9}/Vcs/Reference.php +2 -2
  42. lib/plugin-update-checker/Puc/{v4p8 → v4p9}/Vcs/ThemeUpdateChecker.php +9 -9
  43. lib/plugin-update-checker/README.md +6 -4
  44. lib/plugin-update-checker/composer.json +3 -2
  45. lib/plugin-update-checker/examples/plugin.json +51 -51
  46. lib/plugin-update-checker/examples/theme.json +4 -4
  47. lib/plugin-update-checker/languages/plugin-update-checker-cs_CZ.po +45 -45
  48. lib/plugin-update-checker/languages/plugin-update-checker-es_AR.mo +0 -0
  49. lib/plugin-update-checker/languages/plugin-update-checker-es_AR.po +48 -0
  50. lib/plugin-update-checker/languages/plugin-update-checker-es_CL.mo +0 -0
  51. lib/plugin-update-checker/languages/plugin-update-checker-es_CL.po +48 -0
  52. lib/plugin-update-checker/languages/plugin-update-checker-es_CO.mo +0 -0
  53. lib/plugin-update-checker/languages/plugin-update-checker-es_CO.po +48 -0
  54. lib/plugin-update-checker/languages/plugin-update-checker-es_CR.mo +0 -0
  55. lib/plugin-update-checker/languages/plugin-update-checker-es_CR.po +48 -0
  56. lib/plugin-update-checker/languages/plugin-update-checker-es_DO.mo +0 -0
  57. lib/plugin-update-checker/languages/plugin-update-checker-es_DO.po +48 -0
  58. lib/plugin-update-checker/languages/plugin-update-checker-es_ES.mo +0 -0
  59. lib/plugin-update-checker/languages/plugin-update-checker-es_ES.po +4 -4
  60. lib/plugin-update-checker/languages/plugin-update-checker-es_GT.mo +0 -0
  61. lib/plugin-update-checker/languages/plugin-update-checker-es_GT.po +48 -0
  62. lib/plugin-update-checker/languages/plugin-update-checker-es_HN.mo +0 -0
  63. lib/plugin-update-checker/languages/plugin-update-checker-es_HN.po +48 -0
  64. lib/plugin-update-checker/languages/plugin-update-checker-es_MX.mo +0 -0
  65. lib/plugin-update-checker/languages/plugin-update-checker-es_MX.po +48 -0
  66. lib/plugin-update-checker/languages/plugin-update-checker-es_PE.mo +0 -0
  67. lib/plugin-update-checker/languages/plugin-update-checker-es_PE.po +48 -0
  68. lib/plugin-update-checker/languages/plugin-update-checker-es_PR.mo +0 -0
  69. lib/plugin-update-checker/languages/plugin-update-checker-es_PR.po +48 -0
  70. lib/plugin-update-checker/languages/plugin-update-checker-es_UY.mo +0 -0
  71. lib/plugin-update-checker/languages/plugin-update-checker-es_UY.po +48 -0
  72. lib/plugin-update-checker/languages/plugin-update-checker-es_VE.mo +0 -0
  73. lib/plugin-update-checker/languages/plugin-update-checker-es_VE.po +48 -0
  74. lib/plugin-update-checker/load-v4p8.php +0 -28
  75. lib/plugin-update-checker/load-v4p9.php +28 -0
  76. lib/plugin-update-checker/plugin-update-checker.php +3 -3
  77. lib/plugin-update-checker/vendor/PucReadmeParser.php +7 -0
  78. main.php +1063 -1001
  79. readme.txt +26 -3
  80. sdm-post-type-content-handler.php +11 -10
  81. sdm-shortcodes.php +447 -411
includes/admin-side/sdm-admin-individual-item-logs-page.php CHANGED
@@ -4,18 +4,21 @@ function sdm_handle_individual_logs_tab_page(){
4
  echo '<h2>';
5
  _e( 'Specific Download Item Logs', 'simple-download-monitor' );
6
  echo '</h2>';
7
-
8
  $sdm_logs_dl_id = isset($_REQUEST['sdm_logs_dl_id'])? sanitize_text_field($_REQUEST['sdm_logs_dl_id']): '';
9
-
 
10
  if(isset($_REQUEST['sdm_show_specific_item_logs'])){
11
  $sdm_specific_download_id = isset($_REQUEST['sdm_specific_download_id'])? sanitize_text_field($_REQUEST['sdm_specific_download_id']): '';
 
 
12
  if(!empty($sdm_specific_download_id)){
13
  $target_url = 'edit.php?post_type=sdm_downloads&page=sdm-logs&action=sdm-logs-by-download&sdm_logs_dl_id='.$sdm_specific_download_id;
14
  sdm_redirect_to_url( $target_url );
15
  exit;
16
  }
17
  }
18
-
19
  ?>
20
 
21
  <div style="background:#ECECEC;border:1px solid #CCC;padding:0 10px;margin-top:5px;border-radius:5px;-moz-border-radius:5px;-webkit-border-radius:5px;">
@@ -23,7 +26,7 @@ function sdm_handle_individual_logs_tab_page(){
23
  </div>
24
 
25
  <div id="poststuff"><div id="post-body">
26
-
27
  <div class="postbox">
28
  <h3 class="hndle"><label for="title"><?php _e( 'View Specific Item Logs', 'simple-download-monitor' ); ?></label></h3>
29
  <div class="inside">
@@ -39,13 +42,13 @@ function sdm_handle_individual_logs_tab_page(){
39
  </form>
40
  </div>
41
  </div>
42
-
43
  </div></div><!-- end of .poststuff and .post-body -->
44
-
45
  <?php
46
  if(isset($sdm_logs_dl_id) && !empty($sdm_logs_dl_id)){
47
  //Show the specific item logs
48
-
49
  /* Prepare everything for the specific logs table */
50
  //Create an instance of our package class...
51
  $sdmListTable = new sdm_List_Table();
@@ -61,5 +64,5 @@ function sdm_handle_individual_logs_tab_page(){
61
  </form>
62
  <?php
63
  }
64
-
65
  }
4
  echo '<h2>';
5
  _e( 'Specific Download Item Logs', 'simple-download-monitor' );
6
  echo '</h2>';
7
+
8
  $sdm_logs_dl_id = isset($_REQUEST['sdm_logs_dl_id'])? sanitize_text_field($_REQUEST['sdm_logs_dl_id']): '';
9
+ $sdm_logs_dl_id = intval($sdm_logs_dl_id);
10
+
11
  if(isset($_REQUEST['sdm_show_specific_item_logs'])){
12
  $sdm_specific_download_id = isset($_REQUEST['sdm_specific_download_id'])? sanitize_text_field($_REQUEST['sdm_specific_download_id']): '';
13
+ $sdm_specific_download_id = intval($sdm_specific_download_id);
14
+
15
  if(!empty($sdm_specific_download_id)){
16
  $target_url = 'edit.php?post_type=sdm_downloads&page=sdm-logs&action=sdm-logs-by-download&sdm_logs_dl_id='.$sdm_specific_download_id;
17
  sdm_redirect_to_url( $target_url );
18
  exit;
19
  }
20
  }
21
+
22
  ?>
23
 
24
  <div style="background:#ECECEC;border:1px solid #CCC;padding:0 10px;margin-top:5px;border-radius:5px;-moz-border-radius:5px;-webkit-border-radius:5px;">
26
  </div>
27
 
28
  <div id="poststuff"><div id="post-body">
29
+
30
  <div class="postbox">
31
  <h3 class="hndle"><label for="title"><?php _e( 'View Specific Item Logs', 'simple-download-monitor' ); ?></label></h3>
32
  <div class="inside">
42
  </form>
43
  </div>
44
  </div>
45
+
46
  </div></div><!-- end of .poststuff and .post-body -->
47
+
48
  <?php
49
  if(isset($sdm_logs_dl_id) && !empty($sdm_logs_dl_id)){
50
  //Show the specific item logs
51
+
52
  /* Prepare everything for the specific logs table */
53
  //Create an instance of our package class...
54
  $sdmListTable = new sdm_List_Table();
64
  </form>
65
  <?php
66
  }
67
+
68
  }
includes/class-sdm-addons-updater.php CHANGED
@@ -26,6 +26,11 @@ class SDM_Addons_Updater {
26
  return $data;
27
  }
28
 
 
 
 
 
 
29
  public function plugins_loaded() {
30
  if ( ! class_exists( 'Puc_v4_Factory' ) ) {
31
  require_once WP_SIMPLE_DL_MONITOR_PATH . 'lib/plugin-update-checker/plugin-update-checker.php';
@@ -35,6 +40,7 @@ class SDM_Addons_Updater {
35
  $this->icons[ $addon[2] ] = $this->icons_path . $addon[3];
36
  add_filter( 'puc_request_info_result-' . $addon[2], array( $this, 'set_icon' ) );
37
  }
 
38
  $plugin_file = WP_PLUGIN_DIR . DIRECTORY_SEPARATOR . str_replace( '/', DIRECTORY_SEPARATOR, $addon[1] );
39
  if ( file_exists( $plugin_file ) ) {
40
  $my_update_checker = Puc_v4_Factory::buildUpdateChecker(
26
  return $data;
27
  }
28
 
29
+ public function set_request_options( $options ) {
30
+ $options['timeout'] = 5;
31
+ return $options;
32
+ }
33
+
34
  public function plugins_loaded() {
35
  if ( ! class_exists( 'Puc_v4_Factory' ) ) {
36
  require_once WP_SIMPLE_DL_MONITOR_PATH . 'lib/plugin-update-checker/plugin-update-checker.php';
40
  $this->icons[ $addon[2] ] = $this->icons_path . $addon[3];
41
  add_filter( 'puc_request_info_result-' . $addon[2], array( $this, 'set_icon' ) );
42
  }
43
+ add_filter( 'puc_request_info_options-' . $addon[2], array( $this, 'set_request_options' ) );
44
  $plugin_file = WP_PLUGIN_DIR . DIRECTORY_SEPARATOR . str_replace( '/', DIRECTORY_SEPARATOR, $addon[1] );
45
  if ( file_exists( $plugin_file ) ) {
46
  $my_update_checker = Puc_v4_Factory::buildUpdateChecker(
includes/sdm-admin-menu-handler.php CHANGED
@@ -155,7 +155,7 @@ function sdm_create_settings_page() {
155
  <div class="postbox" style="min-width: inherit;">
156
  <h3 class="hndle"><label for="title"><?php _e( 'Social', 'simple-download-monitor' ); ?></label></h3>
157
  <div class="inside">
158
- <?php echo sprintf( __( '<a target="_blank" href="%s">Facebook</a>', 'simple-download-monitor' ), 'https://www.facebook.com/Tips-and-Tricks-HQ-681802408532789/' ); ?> |
159
  <?php echo sprintf( __( '<a target="_blank" href="%s">Twitter</a>', 'simple-download-monitor' ), 'https://twitter.com/TipsAndTricksHQ' ); ?>
160
  </div>
161
  </div>
@@ -191,7 +191,7 @@ function sdm_admin_menu_general_settings() {
191
 
192
  submit_button();
193
  ?>
194
- <!-- END USER LOGIN OPTIONS DIV -->
195
 
196
  <!-- BEGIN ADMIN OPTIONS DIV -->
197
  <?php
@@ -341,6 +341,7 @@ function sdm_create_logs_page() {
341
 
342
  function sdm_handle_logs_main_tab_page() {
343
  global $wpdb;
 
344
 
345
  if ( isset( $_POST[ 'sdm_export_log_entries' ] ) ) {
346
  //Export log entries
@@ -361,12 +362,35 @@ function sdm_handle_logs_main_tab_page() {
361
  echo '</p></div>';
362
  }
363
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
364
  /* Display the logs table */
365
  //Create an instance of our package class...
366
  $sdmListTable = new sdm_List_Table();
367
  //Fetch, prepare, sort, and filter our data...
368
  $sdmListTable->prepare_items();
369
- ?>
370
 
371
  <h2><?php _e( 'Download Logs', 'simple-download-monitor' ); ?></h2>
372
 
@@ -383,6 +407,7 @@ function sdm_handle_logs_main_tab_page() {
383
  <form method="post" action="" onSubmit="return confirm('Are you sure you want to export all the log entries?');" >
384
  <div class="submit">
385
  <input type="submit" class="button" name="sdm_export_log_entries" value="<?php _e( 'Export Log Entries to CSV File', 'simple-download-monitor' ); ?>" />
 
386
  </div>
387
  </form>
388
  </div>
@@ -392,9 +417,18 @@ function sdm_handle_logs_main_tab_page() {
392
  <div class="postbox">
393
  <h3 class="hndle"><label for="title"><?php _e( 'Reset Download Log Entries', 'simple-download-monitor' ); ?></label></h3>
394
  <div class="inside">
395
- <form method="post" action="" onSubmit="return confirm('Are you sure you want to reset all the log entries to a CSV file?');" >
396
  <div class="submit">
397
  <input type="submit" class="button" name="sdm_reset_log_entries" value="<?php _e( 'Reset Log Entries', 'simple-download-monitor' ); ?>" />
 
 
 
 
 
 
 
 
 
398
  </div>
399
  </form>
400
  </div>
@@ -508,18 +542,18 @@ function sdm_create_stats_page() {
508
  <?php _e( 'Enter your Google Maps API Key <a href="edit.php?post_type=sdm_downloads&page=sdm-settings&action=advanced-settings#maps_api_key" target="_blank">in the settings</a> to properly display the chart.', 'simple-download-monitor' ); ?>
509
  </div>
510
  </div>
511
-
512
  <div id="country_chart" style="width: auto; max-width: 700px; height:437px;"></div>
513
  </div>
514
-
515
  <div data-tab-name="countrylistchart" class="sdm-tab"<?php echo ($active_tab == 'countrylistchart' ? '' : ' style="display:none;"'); ?>>
516
- <div class="wrap">
517
  <table class="widefat">
518
  <thead>
519
- <th><strong><?php _e('Country Name', 'simple-download-monitor'); ?></strong></th>
520
- <th><strong><?php _e('Total Downloads', 'simple-download-monitor'); ?></strong></th>
521
- </thead>
522
- <tbody>
523
  <?php
524
  //An array containing the downloads.
525
  $downloads_by_country_array = sdm_get_downloads_by_country($start_date, $end_date, false);
@@ -536,13 +570,13 @@ function sdm_create_stats_page() {
536
  ?>
537
  </tbody>
538
  <tfoot>
539
- <th><strong><?php _e('Country Name', 'simple-download-monitor'); ?></strong></th>
540
- <th><strong><?php _e('Total Downloads', 'simple-download-monitor'); ?></strong></th>
541
- </tfoot>
542
  </table>
543
  </div>
544
  </div><!-- end of countrylistchart -->
545
-
546
  </div>
547
  </div></div>
548
  </div>
155
  <div class="postbox" style="min-width: inherit;">
156
  <h3 class="hndle"><label for="title"><?php _e( 'Social', 'simple-download-monitor' ); ?></label></h3>
157
  <div class="inside">
158
+ <?php echo sprintf( __( '<a target="_blank" href="%s">Facebook</a>', 'simple-download-monitor' ), 'https://www.facebook.com/Tips-and-Tricks-HQ-681802408532789/' ); ?> |
159
  <?php echo sprintf( __( '<a target="_blank" href="%s">Twitter</a>', 'simple-download-monitor' ), 'https://twitter.com/TipsAndTricksHQ' ); ?>
160
  </div>
161
  </div>
191
 
192
  submit_button();
193
  ?>
194
+ <!-- END USER LOGIN OPTIONS DIV -->
195
 
196
  <!-- BEGIN ADMIN OPTIONS DIV -->
197
  <?php
341
 
342
  function sdm_handle_logs_main_tab_page() {
343
  global $wpdb;
344
+ $advanced_options = get_option( 'sdm_advanced_options' );
345
 
346
  if ( isset( $_POST[ 'sdm_export_log_entries' ] ) ) {
347
  //Export log entries
362
  echo '</p></div>';
363
  }
364
 
365
+ if ( isset( $_POST[ 'sdm_trim_log_entries' ] ) ) {
366
+ //Trim log entries
367
+ $interval_val = intval( $_POST['sdm_trim_log_entries_days'] );
368
+ $interval_unit = 'DAY';
369
+ $cur_time = current_time('mysql');
370
+
371
+ //Save the interval value for future use on this site.
372
+ $advanced_options ['sdm_trim_log_entries_days_saved'] = $interval_val;
373
+ update_option('sdm_advanced_options', $advanced_options);
374
+
375
+ //Trim entries in the DB table.
376
+ $table_name = $wpdb->prefix . 'sdm_downloads';
377
+ $cond = " DATE_SUB('$cur_time',INTERVAL '$interval_val' $interval_unit) > date_time";
378
+ $result = $wpdb->query("DELETE FROM $table_name WHERE $cond", OBJECT);
379
+
380
+ echo '<div id="message" class="updated fade"><p>';
381
+ _e( 'Download log entries trimmed!', 'simple-download-monitor' );
382
+ echo '</p></div>';
383
+ }
384
+
385
+ //Set the default log trim days value
386
+ $trim_log_entries_days_default_val = isset( $advanced_options ['sdm_trim_log_entries_days_saved'] ) ? $advanced_options ['sdm_trim_log_entries_days_saved'] : '30';
387
+
388
  /* Display the logs table */
389
  //Create an instance of our package class...
390
  $sdmListTable = new sdm_List_Table();
391
  //Fetch, prepare, sort, and filter our data...
392
  $sdmListTable->prepare_items();
393
+ ?>
394
 
395
  <h2><?php _e( 'Download Logs', 'simple-download-monitor' ); ?></h2>
396
 
407
  <form method="post" action="" onSubmit="return confirm('Are you sure you want to export all the log entries?');" >
408
  <div class="submit">
409
  <input type="submit" class="button" name="sdm_export_log_entries" value="<?php _e( 'Export Log Entries to CSV File', 'simple-download-monitor' ); ?>" />
410
+ <p class="description"><?php _e( 'This button will export all the log entries to a CSV file that you can download. The download link will be shown at the top of this page.', 'simple-download-monitor' ); ?></p>
411
  </div>
412
  </form>
413
  </div>
417
  <div class="postbox">
418
  <h3 class="hndle"><label for="title"><?php _e( 'Reset Download Log Entries', 'simple-download-monitor' ); ?></label></h3>
419
  <div class="inside">
420
+ <form method="post" action="" onSubmit="return confirm('Are you sure you want to reset all the log entries?');" >
421
  <div class="submit">
422
  <input type="submit" class="button" name="sdm_reset_log_entries" value="<?php _e( 'Reset Log Entries', 'simple-download-monitor' ); ?>" />
423
+ <p class="description"><?php _e( 'This button will reset all log entries. It can useful if you want to export all your log entries then reset them.', 'simple-download-monitor' ); ?></p>
424
+ </div>
425
+ </form>
426
+
427
+ <form method="post" action="" onSubmit="return confirm('Are you sure you want to trim log entries?');" >
428
+ <div class="submit">
429
+ Delete Log Entries Older Than <input name="sdm_trim_log_entries_days" type="text" size="4" value="<?php echo $trim_log_entries_days_default_val; ?>"/> Days
430
+ <input type="submit" class="button" name="sdm_trim_log_entries" value="<?php _e( 'Trim Log Entries', 'simple-download-monitor' ); ?>" />
431
+ <p class="description"><?php _e( 'This option can be useful if you want to delete older log entries. Enter a number of days value then click the Trim Log Entries button.', 'simple-download-monitor' ); ?></p>
432
  </div>
433
  </form>
434
  </div>
542
  <?php _e( 'Enter your Google Maps API Key <a href="edit.php?post_type=sdm_downloads&page=sdm-settings&action=advanced-settings#maps_api_key" target="_blank">in the settings</a> to properly display the chart.', 'simple-download-monitor' ); ?>
543
  </div>
544
  </div>
545
+
546
  <div id="country_chart" style="width: auto; max-width: 700px; height:437px;"></div>
547
  </div>
548
+
549
  <div data-tab-name="countrylistchart" class="sdm-tab"<?php echo ($active_tab == 'countrylistchart' ? '' : ' style="display:none;"'); ?>>
550
+ <div class="wrap">
551
  <table class="widefat">
552
  <thead>
553
+ <th><strong><?php _e('Country Name', 'simple-download-monitor'); ?></strong></th>
554
+ <th><strong><?php _e('Total Downloads', 'simple-download-monitor'); ?></strong></th>
555
+ </thead>
556
+ <tbody>
557
  <?php
558
  //An array containing the downloads.
559
  $downloads_by_country_array = sdm_get_downloads_by_country($start_date, $end_date, false);
570
  ?>
571
  </tbody>
572
  <tfoot>
573
+ <th><strong><?php _e('Country Name', 'simple-download-monitor'); ?></strong></th>
574
+ <th><strong><?php _e('Total Downloads', 'simple-download-monitor'); ?></strong></th>
575
+ </tfoot>
576
  </table>
577
  </div>
578
  </div><!-- end of countrylistchart -->
579
+
580
  </div>
581
  </div></div>
582
  </div>
includes/sdm-download-request-handler.php CHANGED
@@ -2,167 +2,179 @@
2
 
3
  //Handles the download request
4
  function handle_sdm_download_via_direct_post() {
5
- if ( isset( $_REQUEST[ 'smd_process_download' ] ) && $_REQUEST[ 'smd_process_download' ] == '1' ) {
6
- global $wpdb;
7
- $download_id = absint( $_REQUEST[ 'download_id' ] );
8
- $download_title = get_the_title( $download_id );
9
- $download_link = get_post_meta( $download_id, 'sdm_upload', true );
10
-
11
- //Do some validation checks
12
- if ( ! $download_id ) {
13
- wp_die( __( 'Error! Incorrect download item id.', 'simple-download-monitor' ) );
14
- }
15
- if ( empty( $download_link ) ) {
16
- wp_die( printf( __( 'Error! This download item (%s) does not have any download link. Edit this item and specify a downloadable file URL for it.', 'simple-download-monitor' ), $download_id ) );
17
- }
18
 
19
- sdm_recaptcha_verify();
20
-
21
- //Check download password (if applicable for this download)
22
- $post_object = get_post( $download_id ); // Get post object
23
- $post_pass = $post_object->post_password; // Get post password
24
- if ( ! empty( $post_pass ) ) {//This download item has a password. So validate the password.
25
- $pass_val = $_REQUEST[ 'pass_text' ];
26
- if ( empty( $pass_val ) ) {//No password was submitted with the downoad request.
27
- do_action( 'sdm_process_download_request_no_password');
28
-
29
- $dl_post_url = get_permalink( $download_id );
30
- $error_msg = __( 'Error! This download requires a password.', 'simple-download-monitor' );
31
- $error_msg .= '<p>';
32
- $error_msg .= '<a href="' . $dl_post_url . '">' . __( 'Click here', 'simple-download-monitor' ) . '</a>';
33
- $error_msg .= __( ' and enter a valid password for this item', 'simple-download-monitor' );
34
- $error_msg .= '</p>';
35
- wp_die( $error_msg );
36
- }
37
- if ( $post_pass != $pass_val ) {
38
- //Incorrect password submitted.
39
- do_action( 'sdm_process_download_request_incorrect_password');
40
-
41
- wp_die( __( 'Error! Incorrect password. This download requires a valid password.', 'simple-download-monitor' ) );
42
- } else {
43
- //Password is valid. Go ahead with the download
44
- }
45
- }
46
- //End of password check
47
 
48
- $main_option = get_option( 'sdm_downloads_options' );
49
 
50
- $ipaddress = '';
51
- //Check if do not capture IP is enabled.
52
- if ( ! isset( $main_option[ 'admin_do_not_capture_ip' ] ) ) {
53
- $ipaddress = sdm_get_ip_address();
54
- }
55
 
56
- $date_time = current_time( 'mysql' );
57
- $visitor_country = ! empty( $ipaddress ) ? sdm_ip_info( $ipaddress, 'country' ) : '';
58
-
59
- $visitor_name = sdm_get_logged_in_user();
60
-
61
- // Check if we only allow the download for logged-in users
62
- if ( isset( $main_option[ 'only_logged_in_can_download' ] ) ) {
63
- if ( $main_option[ 'only_logged_in_can_download' ] && $visitor_name === false ) {
64
- //User not logged in, let's display the error message.
65
- //But first let's see if we have login page URL set so we can display it as well
66
- $loginMsg = '';
67
- if ( isset( $main_option[ 'general_login_page_url' ] ) && ! empty( $main_option[ 'general_login_page_url' ] ) ) {
68
- //We have a login page URL set. Lets use it.
69
-
70
- if ( isset( $main_option[ 'redirect_user_back_to_download_page' ] ) ) {
71
- //Redirect to download page after login feature is enabled.
72
- $dl_post_url = get_permalink( $download_id );//The single download item page
73
- $redirect_url = apply_filters('sdm_after_login_redirect_query_arg', $dl_post_url);
74
- $login_page_url = add_query_arg( array( 'sdm_redirect_to' => urlencode($redirect_url) ), $main_option[ 'general_login_page_url' ] );
75
- } else {
76
- $login_page_url = $main_option[ 'general_login_page_url' ];
77
- }
78
-
79
- $tpl = __( "__Click here__ to go to login page.", 'simple-download-monitor' );
80
- $loginMsg = preg_replace( '/__(.*)__/', ' <a href="' . $login_page_url . '">$1</a> $2', $tpl );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
81
  }
82
- wp_die( __( 'You need to be logged in to download this file.', 'simple-download-monitor' ) . $loginMsg );
83
- }
84
- }
85
 
86
- $visitor_name = ($visitor_name === false) ? __( 'Not Logged In', 'simple-download-monitor' ) : $visitor_name;
87
 
88
- // Get option for global disabling of download logging
89
- $no_logs = isset( $main_option[ 'admin_no_logs' ] );
90
 
91
- // Get optoin for logging only unique IPs
92
- $unique_ips = isset( $main_option[ 'admin_log_unique' ] );
93
 
94
- // Get post meta for individual disabling of download logging
95
- $get_meta = get_post_meta( $download_id, 'sdm_item_no_log', true );
96
- $item_logging_checked = isset( $get_meta ) && $get_meta === 'on' ? 'on' : 'off';
97
 
98
- $dl_logging_needed = true;
99
 
100
- // Check if download logs have been disabled (globally or per download item)
101
- if ( $no_logs === true || $item_logging_checked === 'on' ) {
102
- $dl_logging_needed = false;
103
- }
104
 
105
- // Check if we are only logging unique ips
106
- if ( $unique_ips === true ) {
107
- $check_ip = $wpdb->get_results( 'SELECT * FROM ' . $wpdb->prefix . 'sdm_downloads WHERE post_id="' . $download_id . '" AND visitor_ip = "' . $ipaddress . '"' );
108
 
109
- //This IP is already logged for this download item. No need to log it again.
110
- if ( $check_ip ) {
111
- $dl_logging_needed = false;
112
- }
113
- }
114
 
115
- // Check if "Do Not Count Downloads from Bots" setting is enabled
116
- if ( isset( $main_option[ 'admin_dont_log_bots' ] ) ) {
117
- //it is. Now let's check if visitor is a bot
118
- if ( sdm_visitor_is_bot() ) {
119
- //visitor is a bot. We neither log nor count this download
120
- $dl_logging_needed = false;
121
- }
122
- }
123
 
124
- if ( $dl_logging_needed ) {
125
- // We need to log this download.
126
- $table = $wpdb->prefix . 'sdm_downloads';
127
- $data = array(
128
- 'post_id' => $download_id,
129
- 'post_title' => $download_title,
130
- 'file_url' => $download_link,
131
- 'visitor_ip' => $ipaddress,
132
- 'date_time' => $date_time,
133
- 'visitor_country' => $visitor_country,
134
- 'visitor_name' => $visitor_name
135
- );
136
-
137
- $data = array_filter( $data ); //Remove any null values.
138
- $insert_table = $wpdb->insert( $table, $data );
139
-
140
- if ( $insert_table ) {
141
- //Download request was logged successfully
142
- } else {
143
- //Failed to log the download request
144
- wp_die( __( 'Error! Failed to log the download request in the database table', 'simple-download-monitor' ) );
145
- }
146
- }
 
147
 
148
- // Allow plugin extensions to hook into download request.
149
- do_action( 'sdm_process_download_request', $download_id, $download_link );
150
 
151
- // Should the item be dispatched?
152
- $dispatch = apply_filters( 'sdm_dispatch_downloads', get_post_meta( $download_id, 'sdm_item_dispatch', true ) );
153
 
154
- // Only local file can be dispatched.
155
- if ( $dispatch && (stripos( $download_link, WP_CONTENT_URL ) === 0) ) {
156
- // Get file path
157
- $file = path_join( WP_CONTENT_DIR, ltrim( substr( $download_link, strlen( WP_CONTENT_URL ) ), '/' ) );
158
- // Try to dispatch file (terminates script execution on success)
159
- sdm_dispatch_file( $file );
160
- }
161
 
162
- // As a fallback or when dispatching is disabled, redirect to the file
163
- // (and terminate script execution).
164
- sdm_redirect_to_url( $download_link );
165
- }
166
  }
167
 
168
  /**
@@ -173,27 +185,27 @@ function handle_sdm_download_via_direct_post() {
173
  */
174
  function sdm_dispatch_file( $filename ) {
175
 
176
- if ( headers_sent() ) {
177
- trigger_error( __FUNCTION__ . ": Cannot dispatch file $filename, headers already sent." );
178
- return;
179
- }
180
-
181
- if ( ! is_readable( $filename ) ) {
182
- trigger_error( __FUNCTION__ . ": Cannot dispatch file $filename, file is not readable." );
183
- return;
184
- }
185
-
186
- header( 'Content-Description: File Transfer' );
187
- header( 'Content-Type: application/octet-stream' ); // http://stackoverflow.com/a/20509354
188
- header( 'Content-Disposition: attachment; filename="' . basename( $filename ) . '"' );
189
- header( 'Expires: 0' );
190
- header( 'Cache-Control: must-revalidate' );
191
- header( 'Pragma: public' );
192
- header( 'Content-Length: ' . filesize( $filename ) );
193
-
194
- ob_end_clean();
195
- readfile( $filename );
196
- exit;
197
  }
198
 
199
  /**
@@ -201,25 +213,25 @@ function sdm_dispatch_file( $filename ) {
201
  * @return boolean
202
  */
203
  function sdm_recaptcha_verify() {
204
- $main_advanced_opts = get_option( 'sdm_advanced_options' );
205
- $recaptcha_enable = isset( $main_advanced_opts[ 'recaptcha_enable' ] ) ? true : false;
206
- if ( $recaptcha_enable ) {
207
- if ( $_SERVER[ "REQUEST_METHOD" ] == "POST" && isset( $_POST[ "g-recaptcha-response" ] ) ) {
208
- $recaptcha_secret_key = $main_advanced_opts[ 'recaptcha_secret_key' ];
209
- $recaptcha_response = filter_input( INPUT_POST, "g-recaptcha-response", FILTER_SANITIZE_FULL_SPECIAL_CHARS );
210
- $response = wp_remote_get( "https://www.google.com/recaptcha/api/siteverify?secret={$recaptcha_secret_key}&response={$recaptcha_response}" );
211
- $response = json_decode( $response[ "body" ], 1 );
212
-
213
- if ( $response[ "success" ] ) {
214
- return true;
215
- } else {
216
- wp_die( "<p><strong>" . __( "ERROR:", 'simple-download-monitor' ) . "</strong> " . __( "Google reCAPTCHA verification failed.", 'simple-download-monitor' ) . "</p>\n\n<p><a href=" . wp_get_referer() . ">&laquo; " . __( "Back", 'simple-download-monitor' ) . "</a>", "", 403 );
217
- return false;
218
- }
219
- } else {
220
- wp_die( "<p><strong>" . __( "ERROR:", 'simple-download-monitor' ) . "</strong> " . __( "Google reCAPTCHA verification failed.", 'simple-download-monitor' ) . " " . __( "Do you have JavaScript enabled?", 'simple-download-monitor' ) . "</p>\n\n<p><a href=" . wp_get_referer() . ">&laquo; " . __( "Back", 'simple-download-monitor' ) . "</a>", "", 403 );
221
- return false;
 
222
  }
223
- }
224
- return true;
225
  }
2
 
3
  //Handles the download request
4
  function handle_sdm_download_via_direct_post() {
5
+ if ( isset( $_REQUEST['smd_process_download'] ) && $_REQUEST['smd_process_download'] == '1' ) {
6
+ global $wpdb;
7
+ $download_id = absint( $_REQUEST['download_id'] );
8
+ $download_title = get_the_title( $download_id );
9
+ $download_link = get_post_meta( $download_id, 'sdm_upload', true );
10
+
11
+ //Do some validation checks
12
+ if ( ! $download_id ) {
13
+ wp_die( __( 'Error! Incorrect download item id.', 'simple-download-monitor' ) );
14
+ }
15
+ if ( empty( $download_link ) ) {
16
+ wp_die( printf( __( 'Error! This download item (%s) does not have any download link. Edit this item and specify a downloadable file URL for it.', 'simple-download-monitor' ), $download_id ) );
17
+ }
18
 
19
+ sdm_recaptcha_verify();
20
+
21
+ //Check download password (if applicable for this download)
22
+ $post_object = get_post( $download_id ); // Get post object
23
+ $post_pass = $post_object->post_password; // Get post password
24
+ if ( ! empty( $post_pass ) ) {//This download item has a password. So validate the password.
25
+ $pass_val = $_REQUEST['pass_text'];
26
+ if ( empty( $pass_val ) ) {//No password was submitted with the downoad request.
27
+ do_action( 'sdm_process_download_request_no_password' );
28
+
29
+ $dl_post_url = get_permalink( $download_id );
30
+ $error_msg = __( 'Error! This download requires a password.', 'simple-download-monitor' );
31
+ $error_msg .= '<p>';
32
+ $error_msg .= '<a href="' . $dl_post_url . '">' . __( 'Click here', 'simple-download-monitor' ) . '</a>';
33
+ $error_msg .= __( ' and enter a valid password for this item', 'simple-download-monitor' );
34
+ $error_msg .= '</p>';
35
+ wp_die( $error_msg );
36
+ }
37
+ if ( $post_pass != $pass_val ) {
38
+ //Incorrect password submitted.
39
+ do_action( 'sdm_process_download_request_incorrect_password' );
40
+
41
+ wp_die( __( 'Error! Incorrect password. This download requires a valid password.', 'simple-download-monitor' ) );
42
+ } else {
43
+ //Password is valid. Go ahead with the download
44
+ }
45
+ }
46
+ //End of password check
47
 
48
+ $main_option = get_option( 'sdm_downloads_options' );
49
 
50
+ $ipaddress = '';
51
+ //Check if do not capture IP is enabled.
52
+ if ( ! isset( $main_option['admin_do_not_capture_ip'] ) ) {
53
+ $ipaddress = sdm_get_ip_address();
54
+ }
55
 
56
+ $user_agent = '';
57
+ //Check if do not capture User Agent is enabled.
58
+ if ( ! isset( $main_option['admin_do_not_capture_user_agent'] ) ) {
59
+ //Get the user agent data. The get_browser() function doesn't work on many servers. So use the HTTP var.
60
+ if ( isset( $_SERVER['HTTP_USER_AGENT'] ) ) {
61
+ $user_agent = $_SERVER['HTTP_USER_AGENT'];
62
+ }
63
+ }
64
+
65
+ $date_time = current_time( 'mysql' );
66
+ $visitor_country = ! empty( $ipaddress ) ? sdm_ip_info( $ipaddress, 'country' ) : '';
67
+
68
+ $visitor_name = sdm_get_logged_in_user();
69
+
70
+ $anonymous_can_download = get_post_meta( $download_id, 'sdm_item_anonymous_can_download', true );
71
+
72
+ // Check if we only allow the download for logged-in users
73
+ if ( isset( $main_option['only_logged_in_can_download'] ) ) {
74
+ if ( $main_option['only_logged_in_can_download'] && $visitor_name === false && ! $anonymous_can_download ) {
75
+ //User not logged in, let's display the error message.
76
+ //But first let's see if we have login page URL set so we can display it as well
77
+ $loginMsg = '';
78
+ if ( isset( $main_option['general_login_page_url'] ) && ! empty( $main_option['general_login_page_url'] ) ) {
79
+ //We have a login page URL set. Lets use it.
80
+
81
+ if ( isset( $main_option['redirect_user_back_to_download_page'] ) ) {
82
+ //Redirect to download page after login feature is enabled.
83
+ $dl_post_url = get_permalink( $download_id );//The single download item page
84
+ $redirect_url = apply_filters( 'sdm_after_login_redirect_query_arg', $dl_post_url );
85
+ $login_page_url = add_query_arg( array( 'sdm_redirect_to' => urlencode( $redirect_url ) ), $main_option['general_login_page_url'] );
86
+ } else {
87
+ $login_page_url = $main_option['general_login_page_url'];
88
+ }
89
+
90
+ $tpl = __( '__Click here__ to go to login page.', 'simple-download-monitor' );
91
+ $loginMsg = preg_replace( '/__(.*)__/', ' <a href="' . $login_page_url . '">$1</a> $2', $tpl );
92
+ }
93
+ wp_die( __( 'You need to be logged in to download this file.', 'simple-download-monitor' ) . $loginMsg );
94
+ }
95
  }
 
 
 
96
 
97
+ $visitor_name = ( $visitor_name === false ) ? __( 'Not Logged In', 'simple-download-monitor' ) : $visitor_name;
98
 
99
+ // Get option for global disabling of download logging
100
+ $no_logs = isset( $main_option['admin_no_logs'] );
101
 
102
+ // Get optoin for logging only unique IPs
103
+ $unique_ips = isset( $main_option['admin_log_unique'] );
104
 
105
+ // Get post meta for individual disabling of download logging
106
+ $get_meta = get_post_meta( $download_id, 'sdm_item_no_log', true );
107
+ $item_logging_checked = isset( $get_meta ) && $get_meta === 'on' ? 'on' : 'off';
108
 
109
+ $dl_logging_needed = true;
110
 
111
+ // Check if download logs have been disabled (globally or per download item)
112
+ if ( $no_logs === true || $item_logging_checked === 'on' ) {
113
+ $dl_logging_needed = false;
114
+ }
115
 
116
+ // Check if we are only logging unique ips
117
+ if ( $unique_ips === true ) {
118
+ $check_ip = $wpdb->get_results( 'SELECT * FROM ' . $wpdb->prefix . 'sdm_downloads WHERE post_id="' . $download_id . '" AND visitor_ip = "' . $ipaddress . '"' );
119
 
120
+ //This IP is already logged for this download item. No need to log it again.
121
+ if ( $check_ip ) {
122
+ $dl_logging_needed = false;
123
+ }
124
+ }
125
 
126
+ // Check if "Do Not Count Downloads from Bots" setting is enabled
127
+ if ( isset( $main_option['admin_dont_log_bots'] ) ) {
128
+ //it is. Now let's check if visitor is a bot
129
+ if ( sdm_visitor_is_bot() ) {
130
+ //visitor is a bot. We neither log nor count this download
131
+ $dl_logging_needed = false;
132
+ }
133
+ }
134
 
135
+ if ( $dl_logging_needed ) {
136
+ // We need to log this download.
137
+ $table = $wpdb->prefix . 'sdm_downloads';
138
+ $data = array(
139
+ 'post_id' => $download_id,
140
+ 'post_title' => $download_title,
141
+ 'file_url' => $download_link,
142
+ 'visitor_ip' => $ipaddress,
143
+ 'date_time' => $date_time,
144
+ 'visitor_country' => $visitor_country,
145
+ 'visitor_name' => $visitor_name,
146
+ 'user_agent' => $user_agent,
147
+ );
148
+
149
+ $data = array_filter( $data ); //Remove any null values.
150
+ $insert_table = $wpdb->insert( $table, $data );
151
+
152
+ if ( $insert_table ) {
153
+ //Download request was logged successfully
154
+ } else {
155
+ //Failed to log the download request
156
+ wp_die( __( 'Error! Failed to log the download request in the database table', 'simple-download-monitor' ) );
157
+ }
158
+ }
159
 
160
+ // Allow plugin extensions to hook into download request.
161
+ do_action( 'sdm_process_download_request', $download_id, $download_link );
162
 
163
+ // Should the item be dispatched?
164
+ $dispatch = apply_filters( 'sdm_dispatch_downloads', get_post_meta( $download_id, 'sdm_item_dispatch', true ) );
165
 
166
+ // Only local file can be dispatched.
167
+ if ( $dispatch && ( stripos( $download_link, WP_CONTENT_URL ) === 0 ) ) {
168
+ // Get file path
169
+ $file = path_join( WP_CONTENT_DIR, ltrim( substr( $download_link, strlen( WP_CONTENT_URL ) ), '/' ) );
170
+ // Try to dispatch file (terminates script execution on success)
171
+ sdm_dispatch_file( $file );
172
+ }
173
 
174
+ // As a fallback or when dispatching is disabled, redirect to the file
175
+ // (and terminate script execution).
176
+ sdm_redirect_to_url( $download_link );
177
+ }
178
  }
179
 
180
  /**
185
  */
186
  function sdm_dispatch_file( $filename ) {
187
 
188
+ if ( headers_sent() ) {
189
+ trigger_error( __FUNCTION__ . ": Cannot dispatch file $filename, headers already sent." );
190
+ return;
191
+ }
192
+
193
+ if ( ! is_readable( $filename ) ) {
194
+ trigger_error( __FUNCTION__ . ": Cannot dispatch file $filename, file is not readable." );
195
+ return;
196
+ }
197
+
198
+ header( 'Content-Description: File Transfer' );
199
+ header( 'Content-Type: application/octet-stream' ); // http://stackoverflow.com/a/20509354
200
+ header( 'Content-Disposition: attachment; filename="' . basename( $filename ) . '"' );
201
+ header( 'Expires: 0' );
202
+ header( 'Cache-Control: must-revalidate' );
203
+ header( 'Pragma: public' );
204
+ header( 'Content-Length: ' . filesize( $filename ) );
205
+
206
+ ob_end_clean();
207
+ readfile( $filename );
208
+ exit;
209
  }
210
 
211
  /**
213
  * @return boolean
214
  */
215
  function sdm_recaptcha_verify() {
216
+ $main_advanced_opts = get_option( 'sdm_advanced_options' );
217
+ $recaptcha_enable = isset( $main_advanced_opts['recaptcha_enable'] ) ? true : false;
218
+ if ( $recaptcha_enable ) {
219
+ if ( $_SERVER['REQUEST_METHOD'] == 'POST' && isset( $_POST['g-recaptcha-response'] ) ) {
220
+ $recaptcha_secret_key = $main_advanced_opts['recaptcha_secret_key'];
221
+ $recaptcha_response = filter_input( INPUT_POST, 'g-recaptcha-response', FILTER_SANITIZE_FULL_SPECIAL_CHARS );
222
+ $response = wp_remote_get( "https://www.google.com/recaptcha/api/siteverify?secret={$recaptcha_secret_key}&response={$recaptcha_response}" );
223
+ $response = json_decode( $response['body'], 1 );
224
+
225
+ if ( $response['success'] ) {
226
+ return true;
227
+ } else {
228
+ wp_die( '<p><strong>' . __( 'ERROR:', 'simple-download-monitor' ) . '</strong> ' . __( 'Google reCAPTCHA verification failed.', 'simple-download-monitor' ) . "</p>\n\n<p><a href=" . wp_get_referer() . '>&laquo; ' . __( 'Back', 'simple-download-monitor' ) . '</a>', '', 403 );
229
+ return false;
230
+ }
231
+ } else {
232
+ wp_die( '<p><strong>' . __( 'ERROR:', 'simple-download-monitor' ) . '</strong> ' . __( 'Google reCAPTCHA verification failed.', 'simple-download-monitor' ) . ' ' . __( 'Do you have JavaScript enabled?', 'simple-download-monitor' ) . "</p>\n\n<p><a href=" . wp_get_referer() . '>&laquo; ' . __( 'Back', 'simple-download-monitor' ) . '</a>', '', 403 );
233
+ return false;
234
+ }
235
  }
236
+ return true;
 
237
  }
includes/sdm-logs-list-table.php CHANGED
@@ -23,7 +23,7 @@ class sdm_List_Table extends WP_List_Table {
23
  }
24
 
25
  function column_default($item, $column_name) {
26
-
27
  switch ($column_name) {
28
  case 'URL':
29
  case 'visitor_ip':
@@ -33,6 +33,8 @@ class sdm_List_Table extends WP_List_Table {
33
  return $item[$column_name];
34
  case 'visitor_name':
35
  return $item[$column_name];
 
 
36
  default:
37
  return print_r($item, true); //Show the whole array for troubleshooting purposes
38
  }
@@ -72,7 +74,8 @@ class sdm_List_Table extends WP_List_Table {
72
  'visitor_ip' => __('Visitor IP', 'simple-download-monitor'),
73
  'date' => __('Date', 'simple-download-monitor'),
74
  'visitor_country' => __('Country', 'simple-download-monitor'),
75
- 'visitor_name' => __('Username', 'simple-download-monitor')
 
76
  );
77
  return $columns;
78
  }
@@ -85,7 +88,8 @@ class sdm_List_Table extends WP_List_Table {
85
  'visitor_ip' => array('visitor_ip', false),
86
  'date' => array('date_time', false),
87
  'visitor_country' => array('visitor_country', false),
88
- 'visitor_name' => array('visitor_name', false)
 
89
  );
90
  return $sortable_columns;
91
  }
@@ -110,7 +114,7 @@ class sdm_List_Table extends WP_List_Table {
110
  if (!wp_verify_nonce($nonce, $action)){
111
  wp_die(__('Nope! Security check failed!', 'simple-download-monitor'));
112
  }
113
-
114
  if (!isset($_POST['download']) || $_POST['download'] == null) {
115
  echo '<div id="message" class="updated fade"><p><strong>' . __('No entries were selected.', 'simple-download-monitor') . '</strong></p><p><em>' . __('Click to Dismiss', 'simple-download-monitor') . '</em></p></div>';
116
  return;
@@ -141,10 +145,10 @@ class sdm_List_Table extends WP_List_Table {
141
  if (!wp_verify_nonce($nonce, $action)){
142
  wp_die(__('Nope! Security check failed!', 'simple-download-monitor'));
143
  }
144
-
145
  //Grab the row id
146
  $row_id = filter_input(INPUT_GET, 'row_id', FILTER_SANITIZE_STRING);
147
-
148
  global $wpdb;
149
  $del_row = $wpdb->query('DELETE FROM ' . $wpdb->prefix . 'sdm_downloads WHERE id = "' . $row_id . '"');
150
  if ($del_row) {
@@ -174,15 +178,17 @@ class sdm_List_Table extends WP_List_Table {
174
  $orderby_column = "date_time";
175
  $sort_order = "DESC";
176
  }
177
- $orderby_column = sdm_sanitize_value_by_array($orderby_column, array('post_title'=>'1', 'file_url'=>'1', 'visitor_ip'=>'1', 'date_time'=>'1', 'visitor_country'=>'1', 'visitor_name'=>'1'));
178
- $sort_order = sdm_sanitize_value_by_array($sort_order, array('DESC' => '1', 'ASC' => '1'));
179
 
180
  //Do a query to find the total number of rows then calculate the query limit
181
  $table_name = $wpdb->prefix . 'sdm_downloads';
182
-
183
  if(isset($_REQUEST['sdm_logs_dl_id']) && !empty($_REQUEST['sdm_logs_dl_id'])){
184
  //For specific download logs
185
  $dl_id = sanitize_text_field($_REQUEST['sdm_logs_dl_id']);
 
 
186
  $query = "SELECT COUNT(*) FROM $table_name WHERE post_id = $dl_id";
187
  $total_items = $wpdb->get_var($query);//For pagination requirement
188
  $query = "SELECT * FROM $table_name WHERE post_id = $dl_id ORDER BY $orderby_column $sort_order";
@@ -198,15 +204,15 @@ class sdm_List_Table extends WP_List_Table {
198
  $query.=' LIMIT ' . (int) $offset . ',' . (int) $per_page;//Limit to query to only load a limited number of records
199
 
200
  $data_results = $wpdb->get_results($query);
201
-
202
  //Prepare the array with the correct index names that the table is expecting.
203
  $data = array();
204
  foreach ($data_results as $data_result) {
205
- $data[] = array('row_id' => $data_result->id, 'ID' => $data_result->post_id, 'title' => $data_result->post_title, 'URL' => $data_result->file_url, 'visitor_ip' => $data_result->visitor_ip, 'date' => $data_result->date_time, 'visitor_country' => $data_result->visitor_country, 'visitor_name' => $data_result->visitor_name);
206
  }
207
-
208
  // Now we add our *sorted* data to the items property, where it can be used by the rest of the class.
209
- $this->items = $data;
210
 
211
  $this->set_pagination_args(array(
212
  'total_items' => $total_items, //WE have to calculate the total number of items
23
  }
24
 
25
  function column_default($item, $column_name) {
26
+
27
  switch ($column_name) {
28
  case 'URL':
29
  case 'visitor_ip':
33
  return $item[$column_name];
34
  case 'visitor_name':
35
  return $item[$column_name];
36
+ case 'user_agent':
37
+ return $item[$column_name];
38
  default:
39
  return print_r($item, true); //Show the whole array for troubleshooting purposes
40
  }
74
  'visitor_ip' => __('Visitor IP', 'simple-download-monitor'),
75
  'date' => __('Date', 'simple-download-monitor'),
76
  'visitor_country' => __('Country', 'simple-download-monitor'),
77
+ 'visitor_name' => __('Username', 'simple-download-monitor'),
78
+ 'user_agent' => __('User Agent', 'simple-download-monitor')
79
  );
80
  return $columns;
81
  }
88
  'visitor_ip' => array('visitor_ip', false),
89
  'date' => array('date_time', false),
90
  'visitor_country' => array('visitor_country', false),
91
+ 'visitor_name' => array('visitor_name', false),
92
+ 'user_agent' => array('user_agent', false)
93
  );
94
  return $sortable_columns;
95
  }
114
  if (!wp_verify_nonce($nonce, $action)){
115
  wp_die(__('Nope! Security check failed!', 'simple-download-monitor'));
116
  }
117
+
118
  if (!isset($_POST['download']) || $_POST['download'] == null) {
119
  echo '<div id="message" class="updated fade"><p><strong>' . __('No entries were selected.', 'simple-download-monitor') . '</strong></p><p><em>' . __('Click to Dismiss', 'simple-download-monitor') . '</em></p></div>';
120
  return;
145
  if (!wp_verify_nonce($nonce, $action)){
146
  wp_die(__('Nope! Security check failed!', 'simple-download-monitor'));
147
  }
148
+
149
  //Grab the row id
150
  $row_id = filter_input(INPUT_GET, 'row_id', FILTER_SANITIZE_STRING);
151
+
152
  global $wpdb;
153
  $del_row = $wpdb->query('DELETE FROM ' . $wpdb->prefix . 'sdm_downloads WHERE id = "' . $row_id . '"');
154
  if ($del_row) {
178
  $orderby_column = "date_time";
179
  $sort_order = "DESC";
180
  }
181
+ $orderby_column = sdm_sanitize_value_by_array($orderby_column, array('post_title'=>'1', 'file_url'=>'1', 'visitor_ip'=>'1', 'date_time'=>'1', 'visitor_country'=>'1', 'visitor_name'=>'1', 'user_agent'=>'1'));
182
+ $sort_order = sdm_sanitize_value_by_array($sort_order, array('DESC' => '1', 'ASC' => '1'));
183
 
184
  //Do a query to find the total number of rows then calculate the query limit
185
  $table_name = $wpdb->prefix . 'sdm_downloads';
186
+
187
  if(isset($_REQUEST['sdm_logs_dl_id']) && !empty($_REQUEST['sdm_logs_dl_id'])){
188
  //For specific download logs
189
  $dl_id = sanitize_text_field($_REQUEST['sdm_logs_dl_id']);
190
+ $dl_id = intval($dl_id);
191
+
192
  $query = "SELECT COUNT(*) FROM $table_name WHERE post_id = $dl_id";
193
  $total_items = $wpdb->get_var($query);//For pagination requirement
194
  $query = "SELECT * FROM $table_name WHERE post_id = $dl_id ORDER BY $orderby_column $sort_order";
204
  $query.=' LIMIT ' . (int) $offset . ',' . (int) $per_page;//Limit to query to only load a limited number of records
205
 
206
  $data_results = $wpdb->get_results($query);
207
+
208
  //Prepare the array with the correct index names that the table is expecting.
209
  $data = array();
210
  foreach ($data_results as $data_result) {
211
+ $data[] = array('row_id' => $data_result->id, 'ID' => $data_result->post_id, 'title' => $data_result->post_title, 'URL' => $data_result->file_url, 'visitor_ip' => $data_result->visitor_ip, 'date' => $data_result->date_time, 'visitor_country' => $data_result->visitor_country, 'visitor_name' => $data_result->visitor_name, 'user_agent' => $data_result->user_agent);
212
  }
213
+
214
  // Now we add our *sorted* data to the items property, where it can be used by the rest of the class.
215
+ $this->items = $data;
216
 
217
  $this->set_pagination_args(array(
218
  'total_items' => $total_items, //WE have to calculate the total number of items
includes/sdm-utility-functions-admin-side.php CHANGED
@@ -17,7 +17,7 @@ function sdm_export_download_logs_to_csv() {
17
  $result->purchase_qty = 1;
18
  }
19
 
20
- $fields = array($result->id, $result->post_id, $result->post_title, $result->file_url, $result->date_time, $result->visitor_ip, $result->visitor_country, $result->visitor_name);
21
  fputcsv($fp, $fields);
22
  }
23
 
17
  $result->purchase_qty = 1;
18
  }
19
 
20
+ $fields = array($result->id, $result->post_id, $result->post_title, $result->file_url, $result->date_time, $result->visitor_ip, $result->visitor_country, $result->visitor_name, $result->user_agent);
21
  fputcsv($fp, $fields);
22
  }
23
 
includes/sdm-utility-functions.php CHANGED
@@ -188,12 +188,14 @@ function sdm_get_logged_in_user() {
188
  }
189
  }
190
 
 
 
191
  return $visitor_name;
192
  }
193
 
194
  // Checks if current visitor is a bot
195
  function sdm_visitor_is_bot() {
196
- $bots = array( 'archiver', 'baiduspider', 'bingbot', 'binlar', 'casper', 'checkprivacy', 'clshttp', 'cmsworldmap', 'comodo', 'curl', 'diavol', 'dotbot', 'DuckDuckBot', 'Exabot', 'email', 'extract', 'facebookexternalhit', 'feedfinder', 'flicky', 'googlebot', 'grab', 'harvest', 'httrack', 'ia_archiver', 'jakarta', 'kmccrew', 'libwww', 'loader', 'MJ12bot', 'miner', 'msnbot', 'nikto', 'nutch', 'planetwork', 'purebot', 'pycurl', 'python', 'scan', 'skygrid', 'slurp', 'sucker', 'turnit', 'vikspider', 'wget', 'winhttp', 'yandex', 'yandexbot', 'yahoo', 'youda', 'zmeu', 'zune' );
197
 
198
  $isBot = false;
199
 
@@ -323,7 +325,7 @@ function sdm_get_current_page_url() {
323
  } else {
324
  $page_url .= ltrim($_SERVER["SERVER_NAME"], ".*") . $_SERVER["REQUEST_URI"];
325
  }
326
-
327
  $page_url = apply_filters('sdm_get_current_page_url', $page_url);
328
  return $page_url;
329
  }
188
  }
189
  }
190
 
191
+ $visitor_name = apply_filters('sdm_get_logged_in_user_name', $visitor_name);
192
+
193
  return $visitor_name;
194
  }
195
 
196
  // Checks if current visitor is a bot
197
  function sdm_visitor_is_bot() {
198
+ $bots = array( 'archiver', 'baiduspider', 'bingbot', 'binlar', 'casper', 'checkprivacy', 'clshttp', 'cmsworldmap', 'comodo', 'curl', 'diavol', 'dotbot', 'DuckDuckBot', 'Exabot', 'email', 'extract', 'facebookexternalhit', 'feedfinder', 'flicky', 'googlebot', 'grab', 'harvest', 'httrack', 'ia_archiver', 'jakarta', 'kmccrew', 'libwww', 'loader', 'MJ12bot', 'miner', 'msnbot', 'nikto', 'nutch', 'planetwork', 'purebot', 'pycurl', 'python', 'scan', 'skygrid', 'slurp', 'sucker', 'turnit', 'vikspider', 'wget', 'winhttp', 'yandex', 'yandexbot', 'yahoo', 'youda', 'zmeu', 'zune', 'Sidetrade', 'AhrefsBot' );
199
 
200
  $isBot = false;
201
 
325
  } else {
326
  $page_url .= ltrim($_SERVER["SERVER_NAME"], ".*") . $_SERVER["REQUEST_URI"];
327
  }
328
+
329
  $page_url = apply_filters('sdm_get_current_page_url', $page_url);
330
  return $page_url;
331
  }
includes/templates/fancy1/sdm-fancy-1.php CHANGED
@@ -43,7 +43,7 @@ function sdm_generate_fancy1_category_display_output( $get_posts, $args ) {
43
  }
44
 
45
  /*
46
- * Generates the output of a single item using fancy2 sytle
47
  * $args array can have the following parameters
48
  * id, fancy, button_text, new_window
49
  */
@@ -112,10 +112,10 @@ function sdm_generate_fancy1_display_output( $args ) {
112
  $isset_item_version = ($show_version && isset( $item_version )) ? $item_version : ''; //check if show_version is enabled and if there is a version value
113
  //Check to see if the download link cpt is password protected
114
  $get_cpt_object = get_post( $id );
115
- $cpt_is_password = ! empty( $get_cpt_object->post_password ) ? 'yes' : 'no'; // yes = download is password protected;
116
  //Check if show date is enabled
117
  $show_date_fd = get_post_meta( $id, 'sdm_item_show_date_fd', true );
118
- //Get item date
119
  $download_date = get_the_date( get_option( 'date_format' ), $id );
120
 
121
  $main_advanced_opts = get_option( 'sdm_advanced_options' );
@@ -152,7 +152,8 @@ function sdm_generate_fancy1_display_output( $args ) {
152
  $output .= '<div class="sdm_download_description">' . $isset_item_description . '</div>';
153
 
154
  //This hook can be used to add content below the description in fancy1 template
155
- $output .= apply_filters( 'sdm_fancy1_below_download_description', '' );
 
156
 
157
  if ( ! empty( $isset_item_file_size ) ) {//Show file size info
158
  $output .= '<div class="sdm_download_size">';
@@ -168,7 +169,7 @@ function sdm_generate_fancy1_display_output( $args ) {
168
  $output .= '</div>';
169
  }
170
 
171
- if ( $show_date_fd ) {//Show date
172
  $output .= '<div class="sdm_download_date">';
173
  $output .= '<span class="sdm_download_date_label">' . __( 'Published: ', 'simple-download-monitor' ) . '</span>';
174
  $output .= '<span class="sdm_download_date_value">' . $download_date . '</span>';
43
  }
44
 
45
  /*
46
+ * Generates the output of a single item using fancy2 sytle
47
  * $args array can have the following parameters
48
  * id, fancy, button_text, new_window
49
  */
112
  $isset_item_version = ($show_version && isset( $item_version )) ? $item_version : ''; //check if show_version is enabled and if there is a version value
113
  //Check to see if the download link cpt is password protected
114
  $get_cpt_object = get_post( $id );
115
+ $cpt_is_password = ! empty( $get_cpt_object->post_password ) ? 'yes' : 'no'; // yes = download is password protected;
116
  //Check if show date is enabled
117
  $show_date_fd = get_post_meta( $id, 'sdm_item_show_date_fd', true );
118
+ //Get item date
119
  $download_date = get_the_date( get_option( 'date_format' ), $id );
120
 
121
  $main_advanced_opts = get_option( 'sdm_advanced_options' );
152
  $output .= '<div class="sdm_download_description">' . $isset_item_description . '</div>';
153
 
154
  //This hook can be used to add content below the description in fancy1 template
155
+ $params = array( 'id' => $id );
156
+ $output .= apply_filters( 'sdm_fancy1_below_download_description', '', $params);
157
 
158
  if ( ! empty( $isset_item_file_size ) ) {//Show file size info
159
  $output .= '<div class="sdm_download_size">';
169
  $output .= '</div>';
170
  }
171
 
172
+ if ( $show_date_fd ) {//Show date
173
  $output .= '<div class="sdm_download_date">';
174
  $output .= '<span class="sdm_download_date_label">' . __( 'Published: ', 'simple-download-monitor' ) . '</span>';
175
  $output .= '<span class="sdm_download_date_value">' . $download_date . '</span>';
languages/simple-download-monitor.pot CHANGED
@@ -802,8 +802,8 @@ msgstr ""
802
 
803
  #: main.php:547
804
  msgid ""
805
- "Read the full shortcode usage documentation <a href=\"https://www."
806
- "tipsandtricks-hq.com/simple-wordpress-download-monitor-plugin\" target="
807
  "\"_blank\">here</a>."
808
  msgstr ""
809
 
802
 
803
  #: main.php:547
804
  msgid ""
805
+ "Read the full shortcode usage documentation <a href=\"https://"
806
+ "simple-download-monitor.com/miscellaneous-shortcodes-and-shortcode-parameters/\" target="
807
  "\"_blank\">here</a>."
808
  msgstr ""
809
 
lib/plugin-update-checker/Puc/v4/Factory.php CHANGED
@@ -1,6 +1,6 @@
1
  <?php
2
  if ( !class_exists('Puc_v4_Factory', false) ):
3
 
4
- class Puc_v4_Factory extends Puc_v4p8_Factory { }
5
 
6
  endif;
1
  <?php
2
  if ( !class_exists('Puc_v4_Factory', false) ):
3
 
4
+ class Puc_v4_Factory extends Puc_v4p9_Factory { }
5
 
6
  endif;
lib/plugin-update-checker/Puc/{v4p8 → v4p9}/Autoloader.php RENAMED
@@ -1,8 +1,8 @@
1
  <?php
2
 
3
- if ( !class_exists('Puc_v4p8_Autoloader', false) ):
4
 
5
- class Puc_v4p8_Autoloader {
6
  private $prefix = '';
7
  private $rootDir = '';
8
  private $libraryDir = '';
@@ -14,7 +14,12 @@ if ( !class_exists('Puc_v4p8_Autoloader', false) ):
14
  $nameParts = explode('_', __CLASS__, 3);
15
  $this->prefix = $nameParts[0] . '_' . $nameParts[1] . '_';
16
 
17
- $this->libraryDir = realpath($this->rootDir . '../..') . '/';
 
 
 
 
 
18
  $this->staticMap = array(
19
  'PucReadmeParser' => 'vendor/PucReadmeParser.php',
20
  'Parsedown' => 'vendor/Parsedown.php',
@@ -24,6 +29,17 @@ if ( !class_exists('Puc_v4p8_Autoloader', false) ):
24
  spl_autoload_register(array($this, 'autoload'));
25
  }
26
 
 
 
 
 
 
 
 
 
 
 
 
27
  public function autoload($className) {
28
  if ( isset($this->staticMap[$className]) && file_exists($this->libraryDir . $this->staticMap[$className]) ) {
29
  /** @noinspection PhpIncludeInspection */
1
  <?php
2
 
3
+ if ( !class_exists('Puc_v4p9_Autoloader', false) ):
4
 
5
+ class Puc_v4p9_Autoloader {
6
  private $prefix = '';
7
  private $rootDir = '';
8
  private $libraryDir = '';
14
  $nameParts = explode('_', __CLASS__, 3);
15
  $this->prefix = $nameParts[0] . '_' . $nameParts[1] . '_';
16
 
17
+ $this->libraryDir = $this->rootDir . '../..';
18
+ if ( !self::isPhar() ) {
19
+ $this->libraryDir = realpath($this->libraryDir);
20
+ }
21
+ $this->libraryDir = $this->libraryDir . '/';
22
+
23
  $this->staticMap = array(
24
  'PucReadmeParser' => 'vendor/PucReadmeParser.php',
25
  'Parsedown' => 'vendor/Parsedown.php',
29
  spl_autoload_register(array($this, 'autoload'));
30
  }
31
 
32
+ /**
33
+ * Determine if this file is running as part of a Phar archive.
34
+ *
35
+ * @return bool
36
+ */
37
+ private static function isPhar() {
38
+ //Check if the current file path starts with "phar://".
39
+ static $pharProtocol = 'phar://';
40
+ return (substr(__FILE__, 0, strlen($pharProtocol)) === $pharProtocol);
41
+ }
42
+
43
  public function autoload($className) {
44
  if ( isset($this->staticMap[$className]) && file_exists($this->libraryDir . $this->staticMap[$className]) ) {
45
  /** @noinspection PhpIncludeInspection */
lib/plugin-update-checker/Puc/{v4p8 → v4p9}/DebugBar/Extension.php RENAMED
@@ -1,12 +1,12 @@
1
  <?php
2
- if ( !class_exists('Puc_v4p8_DebugBar_Extension', false) ):
3
 
4
- class Puc_v4p8_DebugBar_Extension {
5
  const RESPONSE_BODY_LENGTH_LIMIT = 4000;
6
 
7
- /** @var Puc_v4p8_UpdateChecker */
8
  protected $updateChecker;
9
- protected $panelClass = 'Puc_v4p8_DebugBar_Panel';
10
 
11
  public function __construct($updateChecker, $panelClass = null) {
12
  $this->updateChecker = $updateChecker;
@@ -150,11 +150,11 @@ if ( !class_exists('Puc_v4p8_DebugBar_Extension', false) ):
150
  $absolutePath = realpath(dirname(__FILE__) . '/../../../' . ltrim($filePath, '/'));
151
 
152
  //Where is the library located inside the WordPress directory structure?
153
- $absolutePath = Puc_v4p8_Factory::normalizePath($absolutePath);
154
 
155
- $pluginDir = Puc_v4p8_Factory::normalizePath(WP_PLUGIN_DIR);
156
- $muPluginDir = Puc_v4p8_Factory::normalizePath(WPMU_PLUGIN_DIR);
157
- $themeDir = Puc_v4p8_Factory::normalizePath(get_theme_root());
158
 
159
  if ( (strpos($absolutePath, $pluginDir) === 0) || (strpos($absolutePath, $muPluginDir) === 0) ) {
160
  //It's part of a plugin.
1
  <?php
2
+ if ( !class_exists('Puc_v4p9_DebugBar_Extension', false) ):
3
 
4
+ class Puc_v4p9_DebugBar_Extension {
5
  const RESPONSE_BODY_LENGTH_LIMIT = 4000;
6
 
7
+ /** @var Puc_v4p9_UpdateChecker */
8
  protected $updateChecker;
9
+ protected $panelClass = 'Puc_v4p9_DebugBar_Panel';
10
 
11
  public function __construct($updateChecker, $panelClass = null) {
12
  $this->updateChecker = $updateChecker;
150
  $absolutePath = realpath(dirname(__FILE__) . '/../../../' . ltrim($filePath, '/'));
151
 
152
  //Where is the library located inside the WordPress directory structure?
153
+ $absolutePath = Puc_v4p9_Factory::normalizePath($absolutePath);
154
 
155
+ $pluginDir = Puc_v4p9_Factory::normalizePath(WP_PLUGIN_DIR);
156
+ $muPluginDir = Puc_v4p9_Factory::normalizePath(WPMU_PLUGIN_DIR);
157
+ $themeDir = Puc_v4p9_Factory::normalizePath(get_theme_root());
158
 
159
  if ( (strpos($absolutePath, $pluginDir) === 0) || (strpos($absolutePath, $muPluginDir) === 0) ) {
160
  //It's part of a plugin.
lib/plugin-update-checker/Puc/{v4p8 → v4p9}/DebugBar/Panel.php RENAMED
@@ -1,9 +1,9 @@
1
  <?php
2
 
3
- if ( !class_exists('Puc_v4p8_DebugBar_Panel', false) && class_exists('Debug_Bar_Panel', false) ):
4
 
5
- class Puc_v4p8_DebugBar_Panel extends Debug_Bar_Panel {
6
- /** @var Puc_v4p8_UpdateChecker */
7
  protected $updateChecker;
8
 
9
  private $responseBox = '<div class="puc-ajax-response" style="display: none;"></div>';
1
  <?php
2
 
3
+ if ( !class_exists('Puc_v4p9_DebugBar_Panel', false) && class_exists('Debug_Bar_Panel', false) ):
4
 
5
+ class Puc_v4p9_DebugBar_Panel extends Debug_Bar_Panel {
6
+ /** @var Puc_v4p9_UpdateChecker */
7
  protected $updateChecker;
8
 
9
  private $responseBox = '<div class="puc-ajax-response" style="display: none;"></div>';
lib/plugin-update-checker/Puc/{v4p8 → v4p9}/DebugBar/PluginExtension.php RENAMED
@@ -1,12 +1,12 @@
1
  <?php
2
- if ( !class_exists('Puc_v4p8_DebugBar_PluginExtension', false) ):
3
 
4
- class Puc_v4p8_DebugBar_PluginExtension extends Puc_v4p8_DebugBar_Extension {
5
- /** @var Puc_v4p8_Plugin_UpdateChecker */
6
  protected $updateChecker;
7
 
8
  public function __construct($updateChecker) {
9
- parent::__construct($updateChecker, 'Puc_v4p8_DebugBar_PluginPanel');
10
 
11
  add_action('wp_ajax_puc_v4_debug_request_info', array($this, 'ajaxRequestInfo'));
12
  }
1
  <?php
2
+ if ( !class_exists('Puc_v4p9_DebugBar_PluginExtension', false) ):
3
 
4
+ class Puc_v4p9_DebugBar_PluginExtension extends Puc_v4p9_DebugBar_Extension {
5
+ /** @var Puc_v4p9_Plugin_UpdateChecker */
6
  protected $updateChecker;
7
 
8
  public function __construct($updateChecker) {
9
+ parent::__construct($updateChecker, 'Puc_v4p9_DebugBar_PluginPanel');
10
 
11
  add_action('wp_ajax_puc_v4_debug_request_info', array($this, 'ajaxRequestInfo'));
12
  }
lib/plugin-update-checker/Puc/{v4p8 → v4p9}/DebugBar/PluginPanel.php RENAMED
@@ -1,10 +1,10 @@
1
  <?php
2
 
3
- if ( !class_exists('Puc_v4p8_DebugBar_PluginPanel', false) ):
4
 
5
- class Puc_v4p8_DebugBar_PluginPanel extends Puc_v4p8_DebugBar_Panel {
6
  /**
7
- * @var Puc_v4p8_Plugin_UpdateChecker
8
  */
9
  protected $updateChecker;
10
 
1
  <?php
2
 
3
+ if ( !class_exists('Puc_v4p9_DebugBar_PluginPanel', false) ):
4
 
5
+ class Puc_v4p9_DebugBar_PluginPanel extends Puc_v4p9_DebugBar_Panel {
6
  /**
7
+ * @var Puc_v4p9_Plugin_UpdateChecker
8
  */
9
  protected $updateChecker;
10
 
lib/plugin-update-checker/Puc/{v4p8 → v4p9}/DebugBar/ThemePanel.php RENAMED
@@ -1,10 +1,10 @@
1
  <?php
2
 
3
- if ( !class_exists('Puc_v4p8_DebugBar_ThemePanel', false) ):
4
 
5
- class Puc_v4p8_DebugBar_ThemePanel extends Puc_v4p8_DebugBar_Panel {
6
  /**
7
- * @var Puc_v4p8_Theme_UpdateChecker
8
  */
9
  protected $updateChecker;
10
 
1
  <?php
2
 
3
+ if ( !class_exists('Puc_v4p9_DebugBar_ThemePanel', false) ):
4
 
5
+ class Puc_v4p9_DebugBar_ThemePanel extends Puc_v4p9_DebugBar_Panel {
6
  /**
7
+ * @var Puc_v4p9_Theme_UpdateChecker
8
  */
9
  protected $updateChecker;
10
 
lib/plugin-update-checker/Puc/{v4p8 → v4p9}/Factory.php RENAMED
@@ -1,5 +1,5 @@
1
  <?php
2
- if ( !class_exists('Puc_v4p8_Factory', false) ):
3
 
4
  /**
5
  * A factory that builds update checker instances.
@@ -11,20 +11,50 @@ if ( !class_exists('Puc_v4p8_Factory', false) ):
11
  * At the moment it can only build instances of the UpdateChecker class. Other classes are
12
  * intended mainly for internal use and refer directly to specific implementations.
13
  */
14
- class Puc_v4p8_Factory {
15
  protected static $classVersions = array();
16
  protected static $sorted = false;
17
 
18
  protected static $myMajorVersion = '';
19
  protected static $latestCompatibleVersion = '';
20
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
21
  /**
22
  * Create a new instance of the update checker.
23
  *
24
  * This method automatically detects if you're using it for a plugin or a theme and chooses
25
  * the appropriate implementation for your update source (JSON file, GitHub, BitBucket, etc).
26
  *
27
- * @see Puc_v4p8_UpdateChecker::__construct
28
  *
29
  * @param string $metadataUrl The URL of the metadata file, a GitHub repository, or another supported update source.
30
  * @param string $fullPath Full path to the main plugin file or to the theme directory.
@@ -32,7 +62,7 @@ if ( !class_exists('Puc_v4p8_Factory', false) ):
32
  * @param int $checkPeriod How often to check for updates (in hours).
33
  * @param string $optionName Where to store book-keeping info about update checks.
34
  * @param string $muPluginFile The plugin filename relative to the mu-plugins directory.
35
- * @return Puc_v4p8_Plugin_UpdateChecker|Puc_v4p8_Theme_UpdateChecker|Puc_v4p8_Vcs_BaseChecker
36
  */
37
  public static function buildUpdateChecker($metadataUrl, $fullPath, $slug = '', $checkPeriod = 12, $optionName = '', $muPluginFile = '') {
38
  $fullPath = self::normalizePath($fullPath);
@@ -178,6 +208,35 @@ if ( !class_exists('Puc_v4p8_Factory', false) ):
178
  return null;
179
  }
180
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
181
  /**
182
  * Get the name of the hosting service that the URL points to.
183
  *
@@ -294,4 +353,4 @@ if ( !class_exists('Puc_v4p8_Factory', false) ):
294
  }
295
  }
296
 
297
- endif;
1
  <?php
2
+ if ( !class_exists('Puc_v4p9_Factory', false) ):
3
 
4
  /**
5
  * A factory that builds update checker instances.
11
  * At the moment it can only build instances of the UpdateChecker class. Other classes are
12
  * intended mainly for internal use and refer directly to specific implementations.
13
  */
14
+ class Puc_v4p9_Factory {
15
  protected static $classVersions = array();
16
  protected static $sorted = false;
17
 
18
  protected static $myMajorVersion = '';
19
  protected static $latestCompatibleVersion = '';
20
 
21
+ /**
22
+ * A wrapper method for buildUpdateChecker() that reads the metadata URL from the plugin or theme header.
23
+ *
24
+ * @param string $fullPath Full path to the main plugin file or the theme's style.css.
25
+ * @param array $args Optional arguments. Keys should match the argument names of the buildUpdateChecker() method.
26
+ * @return Puc_v4p9_Plugin_UpdateChecker|Puc_v4p9_Theme_UpdateChecker|Puc_v4p9_Vcs_BaseChecker
27
+ */
28
+ public static function buildFromHeader($fullPath, $args = array()) {
29
+ $fullPath = self::normalizePath($fullPath);
30
+
31
+ //Set up defaults.
32
+ $defaults = array(
33
+ 'metadataUrl' => '',
34
+ 'slug' => '',
35
+ 'checkPeriod' => 12,
36
+ 'optionName' => '',
37
+ 'muPluginFile' => '',
38
+ );
39
+ $args = array_merge($defaults, array_intersect_key($args, $defaults));
40
+ extract($args, EXTR_SKIP);
41
+
42
+ //Check for the service URI
43
+ if ( empty($metadataUrl) ) {
44
+ $metadataUrl = self::getServiceURI($fullPath);
45
+ }
46
+
47
+ /** @noinspection PhpUndefinedVariableInspection These variables are created by extract(), above. */
48
+ return self::buildUpdateChecker($metadataUrl, $fullPath, $slug, $checkPeriod, $optionName, $muPluginFile);
49
+ }
50
+
51
  /**
52
  * Create a new instance of the update checker.
53
  *
54
  * This method automatically detects if you're using it for a plugin or a theme and chooses
55
  * the appropriate implementation for your update source (JSON file, GitHub, BitBucket, etc).
56
  *
57
+ * @see Puc_v4p9_UpdateChecker::__construct
58
  *
59
  * @param string $metadataUrl The URL of the metadata file, a GitHub repository, or another supported update source.
60
  * @param string $fullPath Full path to the main plugin file or to the theme directory.
62
  * @param int $checkPeriod How often to check for updates (in hours).
63
  * @param string $optionName Where to store book-keeping info about update checks.
64
  * @param string $muPluginFile The plugin filename relative to the mu-plugins directory.
65
+ * @return Puc_v4p9_Plugin_UpdateChecker|Puc_v4p9_Theme_UpdateChecker|Puc_v4p9_Vcs_BaseChecker
66
  */
67
  public static function buildUpdateChecker($metadataUrl, $fullPath, $slug = '', $checkPeriod = 12, $optionName = '', $muPluginFile = '') {
68
  $fullPath = self::normalizePath($fullPath);
208
  return null;
209
  }
210
 
211
+ /**
212
+ * Get the service URI from the file header.
213
+ *
214
+ * @param string $fullPath
215
+ * @return string
216
+ */
217
+ private static function getServiceURI($fullPath) {
218
+ //Look for the URI
219
+ if ( is_readable($fullPath) ) {
220
+ $seek = array(
221
+ 'github' => 'GitHub URI',
222
+ 'gitlab' => 'GitLab URI',
223
+ 'bucket' => 'BitBucket URI',
224
+ );
225
+ $seek = apply_filters('puc_get_source_uri', $seek);
226
+ $data = get_file_data($fullPath, $seek);
227
+ foreach ($data as $key => $uri) {
228
+ if ( $uri ) {
229
+ return $uri;
230
+ }
231
+ }
232
+ }
233
+
234
+ //URI was not found so throw an error.
235
+ throw new RuntimeException(
236
+ sprintf('Unable to locate URI in header of "%s"', htmlentities($fullPath))
237
+ );
238
+ }
239
+
240
  /**
241
  * Get the name of the hosting service that the URL points to.
242
  *
353
  }
354
  }
355
 
356
+ endif;
lib/plugin-update-checker/Puc/{v4p8 → v4p9}/InstalledPackage.php RENAMED
@@ -1,5 +1,5 @@
1
  <?php
2
- if ( !class_exists('Puc_v4p8_InstalledPackage', false) ):
3
 
4
  /**
5
  * This class represents a currently installed plugin or theme.
@@ -7,9 +7,9 @@ if ( !class_exists('Puc_v4p8_InstalledPackage', false) ):
7
  * Not to be confused with the "package" field in WP update API responses that contains
8
  * the download URL of a the new version.
9
  */
10
- abstract class Puc_v4p8_InstalledPackage {
11
  /**
12
- * @var Puc_v4p8_UpdateChecker
13
  */
14
  protected $updateChecker;
15
 
1
  <?php
2
+ if ( !class_exists('Puc_v4p9_InstalledPackage', false) ):
3
 
4
  /**
5
  * This class represents a currently installed plugin or theme.
7
  * Not to be confused with the "package" field in WP update API responses that contains
8
  * the download URL of a the new version.
9
  */
10
+ abstract class Puc_v4p9_InstalledPackage {
11
  /**
12
+ * @var Puc_v4p9_UpdateChecker
13
  */
14
  protected $updateChecker;
15
 
lib/plugin-update-checker/Puc/{v4p8 → v4p9}/Metadata.php RENAMED
@@ -1,5 +1,5 @@
1
  <?php
2
- if ( !class_exists('Puc_v4p8_Metadata', false) ):
3
 
4
  /**
5
  * A base container for holding information about updates and plugin metadata.
@@ -8,7 +8,7 @@ if ( !class_exists('Puc_v4p8_Metadata', false) ):
8
  * @copyright 2016
9
  * @access public
10
  */
11
- abstract class Puc_v4p8_Metadata {
12
 
13
  /**
14
  * Create an instance of this class from a JSON document.
1
  <?php
2
+ if ( !class_exists('Puc_v4p9_Metadata', false) ):
3
 
4
  /**
5
  * A base container for holding information about updates and plugin metadata.
8
  * @copyright 2016
9
  * @access public
10
  */
11
+ abstract class Puc_v4p9_Metadata {
12
 
13
  /**
14
  * Create an instance of this class from a JSON document.
lib/plugin-update-checker/Puc/{v4p8 → v4p9}/OAuthSignature.php RENAMED
@@ -1,11 +1,11 @@
1
  <?php
2
 
3
- if ( !class_exists('Puc_v4p8_OAuthSignature', false) ):
4
 
5
  /**
6
  * A basic signature generator for zero-legged OAuth 1.0.
7
  */
8
- class Puc_v4p8_OAuthSignature {
9
  private $consumerKey = '';
10
  private $consumerSecret = '';
11
 
1
  <?php
2
 
3
+ if ( !class_exists('Puc_v4p9_OAuthSignature', false) ):
4
 
5
  /**
6
  * A basic signature generator for zero-legged OAuth 1.0.
7
  */
8
+ class Puc_v4p9_OAuthSignature {
9
  private $consumerKey = '';
10
  private $consumerSecret = '';
11
 
lib/plugin-update-checker/Puc/{v4p8 → v4p9}/Plugin/Info.php RENAMED
@@ -1,5 +1,5 @@
1
  <?php
2
- if ( !class_exists('Puc_v4p8_Plugin_Info', false) ):
3
 
4
  /**
5
  * A container class for holding and transforming various plugin metadata.
@@ -8,7 +8,7 @@ if ( !class_exists('Puc_v4p8_Plugin_Info', false) ):
8
  * @copyright 2016
9
  * @access public
10
  */
11
- class Puc_v4p8_Plugin_Info extends Puc_v4p8_Metadata {
12
  //Most fields map directly to the contents of the plugin's info.json file.
13
  //See the relevant docs for a description of their meaning.
14
  public $name;
@@ -27,6 +27,7 @@ if ( !class_exists('Puc_v4p8_Plugin_Info', false) ):
27
 
28
  public $requires;
29
  public $tested;
 
30
  public $upgrade_notice;
31
 
32
  public $rating;
@@ -94,6 +95,7 @@ if ( !class_exists('Puc_v4p8_Plugin_Info', false) ):
94
  $sameFormat = array(
95
  'name', 'slug', 'version', 'requires', 'tested', 'rating', 'upgrade_notice',
96
  'num_ratings', 'downloaded', 'active_installs', 'homepage', 'last_updated',
 
97
  );
98
  foreach($sameFormat as $field){
99
  if ( isset($this->$field) ) {
1
  <?php
2
+ if ( !class_exists('Puc_v4p9_Plugin_Info', false) ):
3
 
4
  /**
5
  * A container class for holding and transforming various plugin metadata.
8
  * @copyright 2016
9
  * @access public
10
  */
11
+ class Puc_v4p9_Plugin_Info extends Puc_v4p9_Metadata {
12
  //Most fields map directly to the contents of the plugin's info.json file.
13
  //See the relevant docs for a description of their meaning.
14
  public $name;
27
 
28
  public $requires;
29
  public $tested;
30
+ public $requires_php;
31
  public $upgrade_notice;
32
 
33
  public $rating;
95
  $sameFormat = array(
96
  'name', 'slug', 'version', 'requires', 'tested', 'rating', 'upgrade_notice',
97
  'num_ratings', 'downloaded', 'active_installs', 'homepage', 'last_updated',
98
+ 'requires_php',
99
  );
100
  foreach($sameFormat as $field){
101
  if ( isset($this->$field) ) {
lib/plugin-update-checker/Puc/{v4p8 → v4p9}/Plugin/Package.php RENAMED
@@ -1,9 +1,9 @@
1
  <?php
2
- if ( !class_exists('Puc_v4p8_Plugin_Package', false) ):
3
 
4
- class Puc_v4p8_Plugin_Package extends Puc_v4p8_InstalledPackage {
5
  /**
6
- * @var Puc_v4p8_Plugin_UpdateChecker
7
  */
8
  protected $updateChecker;
9
 
@@ -170,8 +170,8 @@ if ( !class_exists('Puc_v4p8_Plugin_Package', false) ):
170
  $pluginPath = realpath($this->pluginAbsolutePath);
171
  //If realpath() fails, just normalize the syntax instead.
172
  if (($muPluginDir === false) || ($pluginPath === false)) {
173
- $muPluginDir = Puc_v4p8_Factory::normalizePath(WPMU_PLUGIN_DIR);
174
- $pluginPath = Puc_v4p8_Factory::normalizePath($this->pluginAbsolutePath);
175
  }
176
 
177
  $cachedResult = (strpos($pluginPath, $muPluginDir) === 0);
1
  <?php
2
+ if ( !class_exists('Puc_v4p9_Plugin_Package', false) ):
3
 
4
+ class Puc_v4p9_Plugin_Package extends Puc_v4p9_InstalledPackage {
5
  /**
6
+ * @var Puc_v4p9_Plugin_UpdateChecker
7
  */
8
  protected $updateChecker;
9
 
170
  $pluginPath = realpath($this->pluginAbsolutePath);
171
  //If realpath() fails, just normalize the syntax instead.
172
  if (($muPluginDir === false) || ($pluginPath === false)) {
173
+ $muPluginDir = Puc_v4p9_Factory::normalizePath(WPMU_PLUGIN_DIR);
174
+ $pluginPath = Puc_v4p9_Factory::normalizePath($this->pluginAbsolutePath);
175
  }
176
 
177
  $cachedResult = (strpos($pluginPath, $muPluginDir) === 0);
lib/plugin-update-checker/Puc/{v4p8 → v4p9}/Plugin/Ui.php RENAMED
@@ -1,14 +1,14 @@
1
  <?php
2
- if ( !class_exists('Puc_v4p8_Plugin_Ui', false) ):
3
  /**
4
  * Additional UI elements for plugins.
5
  */
6
- class Puc_v4p8_Plugin_Ui {
7
  private $updateChecker;
8
  private $manualCheckErrorTransient = '';
9
 
10
  /**
11
- * @param Puc_v4p8_Plugin_UpdateChecker $updateChecker
12
  */
13
  public function __construct($updateChecker) {
14
  $this->updateChecker = $updateChecker;
1
  <?php
2
+ if ( !class_exists('Puc_v4p9_Plugin_Ui', false) ):
3
  /**
4
  * Additional UI elements for plugins.
5
  */
6
+ class Puc_v4p9_Plugin_Ui {
7
  private $updateChecker;
8
  private $manualCheckErrorTransient = '';
9
 
10
  /**
11
+ * @param Puc_v4p9_Plugin_UpdateChecker $updateChecker
12
  */
13
  public function __construct($updateChecker) {
14
  $this->updateChecker = $updateChecker;
lib/plugin-update-checker/Puc/{v4p8 → v4p9}/Plugin/Update.php RENAMED
@@ -1,5 +1,5 @@
1
  <?php
2
- if ( !class_exists('Puc_v4p8_Plugin_Update', false) ):
3
 
4
  /**
5
  * A simple container class for holding information about an available update.
@@ -8,29 +8,30 @@ if ( !class_exists('Puc_v4p8_Plugin_Update', false) ):
8
  * @copyright 2016
9
  * @access public
10
  */
11
- class Puc_v4p8_Plugin_Update extends Puc_v4p8_Update {
12
  public $id = 0;
13
  public $homepage;
14
  public $upgrade_notice;
15
  public $tested;
 
16
  public $icons = array();
17
  public $filename; //Plugin filename relative to the plugins directory.
18
 
19
  protected static $extraFields = array(
20
- 'id', 'homepage', 'tested', 'upgrade_notice', 'icons', 'filename',
21
  );
22
 
23
  /**
24
  * Create a new instance of PluginUpdate from its JSON-encoded representation.
25
  *
26
  * @param string $json
27
- * @return Puc_v4p8_Plugin_Update|null
28
  */
29
  public static function fromJson($json){
30
  //Since update-related information is simply a subset of the full plugin info,
31
  //we can parse the update JSON as if it was a plugin info string, then copy over
32
  //the parts that we care about.
33
- $pluginInfo = Puc_v4p8_Plugin_Info::fromJson($json);
34
  if ( $pluginInfo !== null ) {
35
  return self::fromPluginInfo($pluginInfo);
36
  } else {
@@ -42,8 +43,8 @@ if ( !class_exists('Puc_v4p8_Plugin_Update', false) ):
42
  * Create a new instance of PluginUpdate based on an instance of PluginInfo.
43
  * Basically, this just copies a subset of fields from one object to another.
44
  *
45
- * @param Puc_v4p8_Plugin_Info $info
46
- * @return Puc_v4p8_Plugin_Update
47
  */
48
  public static function fromPluginInfo($info){
49
  return self::fromObject($info);
@@ -52,8 +53,8 @@ if ( !class_exists('Puc_v4p8_Plugin_Update', false) ):
52
  /**
53
  * Create a new instance by copying the necessary fields from another object.
54
  *
55
- * @param StdClass|Puc_v4p8_Plugin_Info|Puc_v4p8_Plugin_Update $object The source object.
56
- * @return Puc_v4p8_Plugin_Update The new copy.
57
  */
58
  public static function fromObject($object) {
59
  $update = new self();
@@ -79,6 +80,7 @@ if ( !class_exists('Puc_v4p8_Plugin_Update', false) ):
79
  $update->id = $this->id;
80
  $update->url = $this->homepage;
81
  $update->tested = $this->tested;
 
82
  $update->plugin = $this->filename;
83
 
84
  if ( !empty($this->upgrade_notice) ) {
1
  <?php
2
+ if ( !class_exists('Puc_v4p9_Plugin_Update', false) ):
3
 
4
  /**
5
  * A simple container class for holding information about an available update.
8
  * @copyright 2016
9
  * @access public
10
  */
11
+ class Puc_v4p9_Plugin_Update extends Puc_v4p9_Update {
12
  public $id = 0;
13
  public $homepage;
14
  public $upgrade_notice;
15
  public $tested;
16
+ public $requires_php = false;
17
  public $icons = array();
18
  public $filename; //Plugin filename relative to the plugins directory.
19
 
20
  protected static $extraFields = array(
21
+ 'id', 'homepage', 'tested', 'requires_php', 'upgrade_notice', 'icons', 'filename',
22
  );
23
 
24
  /**
25
  * Create a new instance of PluginUpdate from its JSON-encoded representation.
26
  *
27
  * @param string $json
28
+ * @return Puc_v4p9_Plugin_Update|null
29
  */
30
  public static function fromJson($json){
31
  //Since update-related information is simply a subset of the full plugin info,
32
  //we can parse the update JSON as if it was a plugin info string, then copy over
33
  //the parts that we care about.
34
+ $pluginInfo = Puc_v4p9_Plugin_Info::fromJson($json);
35
  if ( $pluginInfo !== null ) {
36
  return self::fromPluginInfo($pluginInfo);
37
  } else {
43
  * Create a new instance of PluginUpdate based on an instance of PluginInfo.
44
  * Basically, this just copies a subset of fields from one object to another.
45
  *
46
+ * @param Puc_v4p9_Plugin_Info $info
47
+ * @return Puc_v4p9_Plugin_Update
48
  */
49
  public static function fromPluginInfo($info){
50
  return self::fromObject($info);
53
  /**
54
  * Create a new instance by copying the necessary fields from another object.
55
  *
56
+ * @param StdClass|Puc_v4p9_Plugin_Info|Puc_v4p9_Plugin_Update $object The source object.
57
+ * @return Puc_v4p9_Plugin_Update The new copy.
58
  */
59
  public static function fromObject($object) {
60
  $update = new self();
80
  $update->id = $this->id;
81
  $update->url = $this->homepage;
82
  $update->tested = $this->tested;
83
+ $update->requires_php = $this->requires_php;
84
  $update->plugin = $this->filename;
85
 
86
  if ( !empty($this->upgrade_notice) ) {
lib/plugin-update-checker/Puc/{v4p8 → v4p9}/Plugin/UpdateChecker.php RENAMED
@@ -1,5 +1,5 @@
1
  <?php
2
- if ( !class_exists('Puc_v4p8_Plugin_UpdateChecker', false) ):
3
 
4
  /**
5
  * A custom plugin update checker.
@@ -8,7 +8,7 @@ if ( !class_exists('Puc_v4p8_Plugin_UpdateChecker', false) ):
8
  * @copyright 2018
9
  * @access public
10
  */
11
- class Puc_v4p8_Plugin_UpdateChecker extends Puc_v4p8_UpdateChecker {
12
  protected $updateTransient = 'update_plugins';
13
  protected $translationType = 'plugin';
14
 
@@ -17,7 +17,7 @@ if ( !class_exists('Puc_v4p8_Plugin_UpdateChecker', false) ):
17
  public $muPluginFile = ''; //For MU plugins, the plugin filename relative to the mu-plugins directory.
18
 
19
  /**
20
- * @var Puc_v4p8_Plugin_Package
21
  */
22
  protected $package;
23
 
@@ -56,6 +56,8 @@ if ( !class_exists('Puc_v4p8_Plugin_UpdateChecker', false) ):
56
  }
57
  add_filter($slugCheckFilter, array($this, 'getAbsolutePath'));
58
 
 
 
59
  //Backwards compatibility: If the plugin is a mu-plugin but no $muPluginFile is specified, assume
60
  //it's the same as $pluginFile given that it's not in a subdirectory (WP only looks in the base dir).
61
  if ( (strpbrk($this->pluginFile, '/\\') === false) && $this->isUnknownMuPlugin() ) {
@@ -66,19 +68,17 @@ if ( !class_exists('Puc_v4p8_Plugin_UpdateChecker', false) ):
66
  //Details: https://github.com/YahnisElsts/plugin-update-checker/issues/138#issuecomment-335590964
67
  add_action('uninstall_' . $this->pluginFile, array($this, 'removeHooks'));
68
 
69
- parent::__construct($metadataUrl, dirname($this->pluginFile), $slug, $checkPeriod, $optionName);
70
-
71
- $this->extraUi = new Puc_v4p8_Plugin_Ui($this);
72
  }
73
 
74
  /**
75
  * Create an instance of the scheduler.
76
  *
77
  * @param int $checkPeriod
78
- * @return Puc_v4p8_Scheduler
79
  */
80
  protected function createScheduler($checkPeriod) {
81
- $scheduler = new Puc_v4p8_Scheduler($this, $checkPeriod, array('load-plugins.php'));
82
  register_deactivation_hook($this->pluginFile, array($scheduler, 'removeUpdaterCron'));
83
  return $scheduler;
84
  }
@@ -124,13 +124,13 @@ if ( !class_exists('Puc_v4p8_Plugin_UpdateChecker', false) ):
124
  * @uses wp_remote_get()
125
  *
126
  * @param array $queryArgs Additional query arguments to append to the request. Optional.
127
- * @return Puc_v4p8_Plugin_Info
128
  */
129
  public function requestInfo($queryArgs = array()) {
130
- list($pluginInfo, $result) = $this->requestMetadata('Puc_v4p8_Plugin_Info', 'request_info', $queryArgs);
131
 
132
  if ( $pluginInfo !== null ) {
133
- /** @var Puc_v4p8_Plugin_Info $pluginInfo */
134
  $pluginInfo->filename = $this->pluginFile;
135
  $pluginInfo->slug = $this->slug;
136
  }
@@ -144,7 +144,7 @@ if ( !class_exists('Puc_v4p8_Plugin_UpdateChecker', false) ):
144
  *
145
  * @uses PluginUpdateChecker::requestInfo()
146
  *
147
- * @return Puc_v4p8_Update|null An instance of Plugin_Update, or NULL when no updates are available.
148
  */
149
  public function requestUpdate() {
150
  //For the sake of simplicity, this function just calls requestInfo()
@@ -153,7 +153,7 @@ if ( !class_exists('Puc_v4p8_Plugin_UpdateChecker', false) ):
153
  if ( $pluginInfo === null ){
154
  return null;
155
  }
156
- $update = Puc_v4p8_Plugin_Update::fromPluginInfo($pluginInfo);
157
 
158
  $update = $this->filterUpdateResult($update);
159
 
@@ -265,12 +265,12 @@ if ( !class_exists('Puc_v4p8_Plugin_UpdateChecker', false) ):
265
  * Uses cached update data. To retrieve update information straight from
266
  * the metadata URL, call requestUpdate() instead.
267
  *
268
- * @return Puc_v4p8_Plugin_Update|null
269
  */
270
  public function getUpdate() {
271
  $update = parent::getUpdate();
272
  if ( isset($update) ) {
273
- /** @var Puc_v4p8_Plugin_Update $update */
274
  $update->filename = $this->pluginFile;
275
  }
276
  return $update;
@@ -375,20 +375,20 @@ if ( !class_exists('Puc_v4p8_Plugin_UpdateChecker', false) ):
375
  }
376
 
377
  protected function createDebugBarExtension() {
378
- return new Puc_v4p8_DebugBar_PluginExtension($this);
379
  }
380
 
381
  /**
382
  * Create a package instance that represents this plugin or theme.
383
  *
384
- * @return Puc_v4p8_InstalledPackage
385
  */
386
  protected function createInstalledPackage() {
387
- return new Puc_v4p8_Plugin_Package($this->pluginAbsolutePath, $this);
388
  }
389
 
390
  /**
391
- * @return Puc_v4p8_Plugin_Package
392
  */
393
  public function getInstalledPackage() {
394
  return $this->package;
1
  <?php
2
+ if ( !class_exists('Puc_v4p9_Plugin_UpdateChecker', false) ):
3
 
4
  /**
5
  * A custom plugin update checker.
8
  * @copyright 2018
9
  * @access public
10
  */
11
+ class Puc_v4p9_Plugin_UpdateChecker extends Puc_v4p9_UpdateChecker {
12
  protected $updateTransient = 'update_plugins';
13
  protected $translationType = 'plugin';
14
 
17
  public $muPluginFile = ''; //For MU plugins, the plugin filename relative to the mu-plugins directory.
18
 
19
  /**
20
+ * @var Puc_v4p9_Plugin_Package
21
  */
22
  protected $package;
23
 
56
  }
57
  add_filter($slugCheckFilter, array($this, 'getAbsolutePath'));
58
 
59
+ parent::__construct($metadataUrl, dirname($this->pluginFile), $slug, $checkPeriod, $optionName);
60
+
61
  //Backwards compatibility: If the plugin is a mu-plugin but no $muPluginFile is specified, assume
62
  //it's the same as $pluginFile given that it's not in a subdirectory (WP only looks in the base dir).
63
  if ( (strpbrk($this->pluginFile, '/\\') === false) && $this->isUnknownMuPlugin() ) {
68
  //Details: https://github.com/YahnisElsts/plugin-update-checker/issues/138#issuecomment-335590964
69
  add_action('uninstall_' . $this->pluginFile, array($this, 'removeHooks'));
70
 
71
+ $this->extraUi = new Puc_v4p9_Plugin_Ui($this);
 
 
72
  }
73
 
74
  /**
75
  * Create an instance of the scheduler.
76
  *
77
  * @param int $checkPeriod
78
+ * @return Puc_v4p9_Scheduler
79
  */
80
  protected function createScheduler($checkPeriod) {
81
+ $scheduler = new Puc_v4p9_Scheduler($this, $checkPeriod, array('load-plugins.php'));
82
  register_deactivation_hook($this->pluginFile, array($scheduler, 'removeUpdaterCron'));
83
  return $scheduler;
84
  }
124
  * @uses wp_remote_get()
125
  *
126
  * @param array $queryArgs Additional query arguments to append to the request. Optional.
127
+ * @return Puc_v4p9_Plugin_Info
128
  */
129
  public function requestInfo($queryArgs = array()) {
130
+ list($pluginInfo, $result) = $this->requestMetadata('Puc_v4p9_Plugin_Info', 'request_info', $queryArgs);
131
 
132
  if ( $pluginInfo !== null ) {
133
+ /** @var Puc_v4p9_Plugin_Info $pluginInfo */
134
  $pluginInfo->filename = $this->pluginFile;
135
  $pluginInfo->slug = $this->slug;
136
  }
144
  *
145
  * @uses PluginUpdateChecker::requestInfo()
146
  *
147
+ * @return Puc_v4p9_Update|null An instance of Plugin_Update, or NULL when no updates are available.
148
  */
149
  public function requestUpdate() {
150
  //For the sake of simplicity, this function just calls requestInfo()
153
  if ( $pluginInfo === null ){
154
  return null;
155
  }
156
+ $update = Puc_v4p9_Plugin_Update::fromPluginInfo($pluginInfo);
157
 
158
  $update = $this->filterUpdateResult($update);
159
 
265
  * Uses cached update data. To retrieve update information straight from
266
  * the metadata URL, call requestUpdate() instead.
267
  *
268
+ * @return Puc_v4p9_Plugin_Update|null
269
  */
270
  public function getUpdate() {
271
  $update = parent::getUpdate();
272
  if ( isset($update) ) {
273
+ /** @var Puc_v4p9_Plugin_Update $update */
274
  $update->filename = $this->pluginFile;
275
  }
276
  return $update;
375
  }
376
 
377
  protected function createDebugBarExtension() {
378
+ return new Puc_v4p9_DebugBar_PluginExtension($this);
379
  }
380
 
381
  /**
382
  * Create a package instance that represents this plugin or theme.
383
  *
384
+ * @return Puc_v4p9_InstalledPackage
385
  */
386
  protected function createInstalledPackage() {
387
+ return new Puc_v4p9_Plugin_Package($this->pluginAbsolutePath, $this);
388
  }
389
 
390
  /**
391
+ * @return Puc_v4p9_Plugin_Package
392
  */
393
  public function getInstalledPackage() {
394
  return $this->package;
lib/plugin-update-checker/Puc/{v4p8 → v4p9}/Scheduler.php RENAMED
@@ -1,11 +1,11 @@
1
  <?php
2
- if ( !class_exists('Puc_v4p8_Scheduler', false) ):
3
 
4
  /**
5
  * The scheduler decides when and how often to check for updates.
6
- * It calls @see Puc_v4p8_UpdateChecker::checkForUpdates() to perform the actual checks.
7
  */
8
- class Puc_v4p8_Scheduler {
9
  public $checkPeriod = 12; //How often to check for updates (in hours).
10
  public $throttleRedundantChecks = false; //Check less often if we already know that an update is available.
11
  public $throttledCheckPeriod = 72;
@@ -13,7 +13,7 @@ if ( !class_exists('Puc_v4p8_Scheduler', false) ):
13
  protected $hourlyCheckHooks = array('load-update.php');
14
 
15
  /**
16
- * @var Puc_v4p8_UpdateChecker
17
  */
18
  protected $updateChecker;
19
 
@@ -22,7 +22,7 @@ if ( !class_exists('Puc_v4p8_Scheduler', false) ):
22
  /**
23
  * Scheduler constructor.
24
  *
25
- * @param Puc_v4p8_UpdateChecker $updateChecker
26
  * @param int $checkPeriod How often to check for updates (in hours).
27
  * @param array $hourlyHooks
28
  */
@@ -87,6 +87,7 @@ if ( !class_exists('Puc_v4p8_Scheduler', false) ):
87
  * Runs upon the WP action upgrader_process_complete.
88
  *
89
  * We look at the parameters to decide whether to call maybeCheckForUpdates() or not.
 
90
  *
91
  * @param WP_Upgrader $upgrader WP_Upgrader instance
92
  * @param array $upgradeInfo extra information about the upgrade
@@ -95,6 +96,15 @@ if ( !class_exists('Puc_v4p8_Scheduler', false) ):
95
  /** @noinspection PhpUnusedParameterInspection */
96
  $upgrader, $upgradeInfo
97
  ) {
 
 
 
 
 
 
 
 
 
98
 
99
  //Sanity check and limitation to relevant types.
100
  if (
@@ -106,7 +116,7 @@ if ( !class_exists('Puc_v4p8_Scheduler', false) ):
106
 
107
  //Filter out notifications of upgrades that should have no bearing upon whether or not our
108
  //current info is up-to-date.
109
- if ( is_a($this->updateChecker, 'Puc_v4p8_Theme_UpdateChecker') ) {
110
  if ( 'theme' !== $upgradeInfo['type'] || !isset($upgradeInfo['themes']) ) {
111
  return;
112
  }
@@ -120,7 +130,7 @@ if ( !class_exists('Puc_v4p8_Scheduler', false) ):
120
  }
121
  }
122
 
123
- if ( is_a($this->updateChecker, 'Puc_v4p8_Plugin_UpdateChecker') ) {
124
  if ( 'plugin' !== $upgradeInfo['type'] || !isset($upgradeInfo['plugins']) ) {
125
  return;
126
  }
@@ -136,7 +146,7 @@ if ( !class_exists('Puc_v4p8_Scheduler', false) ):
136
 
137
  $this->maybeCheckForUpdates();
138
  }
139
-
140
  /**
141
  * Check for updates if the configured check interval has already elapsed.
142
  * Will use a shorter check interval on certain admin pages like "Dashboard -> Updates" or when doing cron.
@@ -233,6 +243,24 @@ if ( !class_exists('Puc_v4p8_Scheduler', false) ):
233
  public function getCronHookName() {
234
  return $this->cronHook;
235
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
236
  }
237
 
238
  endif;
1
  <?php
2
+ if ( !class_exists('Puc_v4p9_Scheduler', false) ):
3
 
4
  /**
5
  * The scheduler decides when and how often to check for updates.
6
+ * It calls @see Puc_v4p9_UpdateChecker::checkForUpdates() to perform the actual checks.
7
  */
8
+ class Puc_v4p9_Scheduler {
9
  public $checkPeriod = 12; //How often to check for updates (in hours).
10
  public $throttleRedundantChecks = false; //Check less often if we already know that an update is available.
11
  public $throttledCheckPeriod = 72;
13
  protected $hourlyCheckHooks = array('load-update.php');
14
 
15
  /**
16
+ * @var Puc_v4p9_UpdateChecker
17
  */
18
  protected $updateChecker;
19
 
22
  /**
23
  * Scheduler constructor.
24
  *
25
+ * @param Puc_v4p9_UpdateChecker $updateChecker
26
  * @param int $checkPeriod How often to check for updates (in hours).
27
  * @param array $hourlyHooks
28
  */
87
  * Runs upon the WP action upgrader_process_complete.
88
  *
89
  * We look at the parameters to decide whether to call maybeCheckForUpdates() or not.
90
+ * We also check if the update checker has been removed by the update.
91
  *
92
  * @param WP_Upgrader $upgrader WP_Upgrader instance
93
  * @param array $upgradeInfo extra information about the upgrade
96
  /** @noinspection PhpUnusedParameterInspection */
97
  $upgrader, $upgradeInfo
98
  ) {
99
+ //Cancel all further actions if the current version of PUC has been deleted or overwritten
100
+ //by a different version during the upgrade. If we try to do anything more in that situation,
101
+ //we could trigger a fatal error by trying to autoload a deleted class.
102
+ clearstatcache();
103
+ if ( !file_exists(__FILE__) ) {
104
+ $this->removeHooks();
105
+ $this->updateChecker->removeHooks();
106
+ return;
107
+ }
108
 
109
  //Sanity check and limitation to relevant types.
110
  if (
116
 
117
  //Filter out notifications of upgrades that should have no bearing upon whether or not our
118
  //current info is up-to-date.
119
+ if ( is_a($this->updateChecker, 'Puc_v4p9_Theme_UpdateChecker') ) {
120
  if ( 'theme' !== $upgradeInfo['type'] || !isset($upgradeInfo['themes']) ) {
121
  return;
122
  }
130
  }
131
  }
132
 
133
+ if ( is_a($this->updateChecker, 'Puc_v4p9_Plugin_UpdateChecker') ) {
134
  if ( 'plugin' !== $upgradeInfo['type'] || !isset($upgradeInfo['plugins']) ) {
135
  return;
136
  }
146
 
147
  $this->maybeCheckForUpdates();
148
  }
149
+
150
  /**
151
  * Check for updates if the configured check interval has already elapsed.
152
  * Will use a shorter check interval on certain admin pages like "Dashboard -> Updates" or when doing cron.
243
  public function getCronHookName() {
244
  return $this->cronHook;
245
  }
246
+
247
+ /**
248
+ * Remove most hooks added by the scheduler.
249
+ */
250
+ public function removeHooks() {
251
+ remove_filter('cron_schedules', array($this, '_addCustomSchedule'));
252
+ remove_action('admin_init', array($this, 'maybeCheckForUpdates'));
253
+ remove_action('load-update-core.php', array($this, 'maybeCheckForUpdates'));
254
+
255
+ if ( $this->cronHook !== null ) {
256
+ remove_action($this->cronHook, array($this, 'maybeCheckForUpdates'));
257
+ }
258
+ if ( !empty($this->hourlyCheckHooks) ) {
259
+ foreach ($this->hourlyCheckHooks as $hook) {
260
+ remove_action($hook, array($this, 'maybeCheckForUpdates'));
261
+ }
262
+ }
263
+ }
264
  }
265
 
266
  endif;
lib/plugin-update-checker/Puc/{v4p8 → v4p9}/StateStore.php RENAMED
@@ -1,8 +1,8 @@
1
  <?php
2
 
3
- if ( !class_exists('Puc_v4p8_StateStore', false) ):
4
 
5
- class Puc_v4p8_StateStore {
6
  /**
7
  * @var int Last update check timestamp.
8
  */
@@ -14,7 +14,7 @@ if ( !class_exists('Puc_v4p8_StateStore', false) ):
14
  protected $checkedVersion = '';
15
 
16
  /**
17
- * @var Puc_v4p8_Update|null Cached update.
18
  */
19
  protected $update = null;
20
 
@@ -65,7 +65,7 @@ if ( !class_exists('Puc_v4p8_StateStore', false) ):
65
  }
66
 
67
  /**
68
- * @return null|Puc_v4p8_Update
69
  */
70
  public function getUpdate() {
71
  $this->lazyLoad();
@@ -73,10 +73,10 @@ if ( !class_exists('Puc_v4p8_StateStore', false) ):
73
  }
74
 
75
  /**
76
- * @param Puc_v4p8_Update|null $update
77
  * @return $this
78
  */
79
- public function setUpdate(Puc_v4p8_Update $update = null) {
80
  $this->lazyLoad();
81
  $this->update = $update;
82
  return $this;
@@ -138,7 +138,7 @@ if ( !class_exists('Puc_v4p8_StateStore', false) ):
138
  $updateClass = get_class($this->update);
139
  $state->updateClass = $updateClass;
140
  $prefix = $this->getLibPrefix();
141
- if ( Puc_v4p8_Utils::startsWith($updateClass, $prefix) ) {
142
  $state->updateBaseClass = substr($updateClass, strlen($prefix));
143
  }
144
  }
@@ -169,8 +169,8 @@ if ( !class_exists('Puc_v4p8_StateStore', false) ):
169
  return;
170
  }
171
 
172
- $this->lastCheck = intval(Puc_v4p8_Utils::get($state, 'lastCheck', 0));
173
- $this->checkedVersion = Puc_v4p8_Utils::get($state, 'checkedVersion', '');
174
  $this->update = null;
175
 
176
  if ( isset($state->update) ) {
1
  <?php
2
 
3
+ if ( !class_exists('Puc_v4p9_StateStore', false) ):
4
 
5
+ class Puc_v4p9_StateStore {
6
  /**
7
  * @var int Last update check timestamp.
8
  */
14
  protected $checkedVersion = '';
15
 
16
  /**
17
+ * @var Puc_v4p9_Update|null Cached update.
18
  */
19
  protected $update = null;
20
 
65
  }
66
 
67
  /**
68
+ * @return null|Puc_v4p9_Update
69
  */
70
  public function getUpdate() {
71
  $this->lazyLoad();
73
  }
74
 
75
  /**
76
+ * @param Puc_v4p9_Update|null $update
77
  * @return $this
78
  */
79
+ public function setUpdate(Puc_v4p9_Update $update = null) {
80
  $this->lazyLoad();
81
  $this->update = $update;
82
  return $this;
138
  $updateClass = get_class($this->update);
139
  $state->updateClass = $updateClass;
140
  $prefix = $this->getLibPrefix();
141
+ if ( Puc_v4p9_Utils::startsWith($updateClass, $prefix) ) {
142
  $state->updateBaseClass = substr($updateClass, strlen($prefix));
143
  }
144
  }
169
  return;
170
  }
171
 
172
+ $this->lastCheck = intval(Puc_v4p9_Utils::get($state, 'lastCheck', 0));
173
+ $this->checkedVersion = Puc_v4p9_Utils::get($state, 'checkedVersion', '');
174
  $this->update = null;
175
 
176
  if ( isset($state->update) ) {
lib/plugin-update-checker/Puc/{v4p8 → v4p9}/Theme/Package.php RENAMED
@@ -1,7 +1,7 @@
1
  <?php
2
- if ( !class_exists('Puc_v4p8_Theme_Package', false) ):
3
 
4
- class Puc_v4p8_Theme_Package extends Puc_v4p8_InstalledPackage {
5
  /**
6
  * @var string Theme directory name.
7
  */
1
  <?php
2
+ if ( !class_exists('Puc_v4p9_Theme_Package', false) ):
3
 
4
+ class Puc_v4p9_Theme_Package extends Puc_v4p9_InstalledPackage {
5
  /**
6
  * @var string Theme directory name.
7
  */
lib/plugin-update-checker/Puc/{v4p8 → v4p9}/Theme/Update.php RENAMED
@@ -1,8 +1,8 @@
1
  <?php
2
 
3
- if ( !class_exists('Puc_v4p8_Theme_Update', false) ):
4
 
5
- class Puc_v4p8_Theme_Update extends Puc_v4p8_Update {
6
  public $details_url = '';
7
 
8
  protected static $extraFields = array('details_url');
@@ -44,8 +44,8 @@ if ( !class_exists('Puc_v4p8_Theme_Update', false) ):
44
  /**
45
  * Create a new instance by copying the necessary fields from another object.
46
  *
47
- * @param StdClass|Puc_v4p8_Theme_Update $object The source object.
48
- * @return Puc_v4p8_Theme_Update The new copy.
49
  */
50
  public static function fromObject($object) {
51
  $update = new self();
1
  <?php
2
 
3
+ if ( !class_exists('Puc_v4p9_Theme_Update', false) ):
4
 
5
+ class Puc_v4p9_Theme_Update extends Puc_v4p9_Update {
6
  public $details_url = '';
7
 
8
  protected static $extraFields = array('details_url');
44
  /**
45
  * Create a new instance by copying the necessary fields from another object.
46
  *
47
+ * @param StdClass|Puc_v4p9_Theme_Update $object The source object.
48
+ * @return Puc_v4p9_Theme_Update The new copy.
49
  */
50
  public static function fromObject($object) {
51
  $update = new self();
lib/plugin-update-checker/Puc/{v4p8 → v4p9}/Theme/UpdateChecker.php RENAMED
@@ -1,8 +1,8 @@
1
  <?php
2
 
3
- if ( !class_exists('Puc_v4p8_Theme_UpdateChecker', false) ):
4
 
5
- class Puc_v4p8_Theme_UpdateChecker extends Puc_v4p8_UpdateChecker {
6
  protected $filterSuffix = 'theme';
7
  protected $updateTransient = 'update_themes';
8
  protected $translationType = 'theme';
@@ -39,13 +39,13 @@ if ( !class_exists('Puc_v4p8_Theme_UpdateChecker', false) ):
39
  /**
40
  * Retrieve the latest update (if any) from the configured API endpoint.
41
  *
42
- * @return Puc_v4p8_Update|null An instance of Update, or NULL when no updates are available.
43
  */
44
  public function requestUpdate() {
45
- list($themeUpdate, $result) = $this->requestMetadata('Puc_v4p8_Theme_Update', 'request_update');
46
 
47
  if ( $themeUpdate !== null ) {
48
- /** @var Puc_v4p8_Theme_Update $themeUpdate */
49
  $themeUpdate->slug = $this->slug;
50
  }
51
 
@@ -61,10 +61,10 @@ if ( !class_exists('Puc_v4p8_Theme_UpdateChecker', false) ):
61
  * Create an instance of the scheduler.
62
  *
63
  * @param int $checkPeriod
64
- * @return Puc_v4p8_Scheduler
65
  */
66
  protected function createScheduler($checkPeriod) {
67
- return new Puc_v4p8_Scheduler($this, $checkPeriod, array('load-themes.php'));
68
  }
69
 
70
  /**
@@ -78,7 +78,7 @@ if ( !class_exists('Puc_v4p8_Theme_UpdateChecker', false) ):
78
  }
79
 
80
  protected function createDebugBarExtension() {
81
- return new Puc_v4p8_DebugBar_Extension($this, 'Puc_v4p8_DebugBar_ThemePanel');
82
  }
83
 
84
  /**
@@ -132,10 +132,10 @@ if ( !class_exists('Puc_v4p8_Theme_UpdateChecker', false) ):
132
  /**
133
  * Create a package instance that represents this plugin or theme.
134
  *
135
- * @return Puc_v4p8_InstalledPackage
136
  */
137
  protected function createInstalledPackage() {
138
- return new Puc_v4p8_Theme_Package($this->stylesheet, $this);
139
  }
140
  }
141
 
1
  <?php
2
 
3
+ if ( !class_exists('Puc_v4p9_Theme_UpdateChecker', false) ):
4
 
5
+ class Puc_v4p9_Theme_UpdateChecker extends Puc_v4p9_UpdateChecker {
6
  protected $filterSuffix = 'theme';
7
  protected $updateTransient = 'update_themes';
8
  protected $translationType = 'theme';
39
  /**
40
  * Retrieve the latest update (if any) from the configured API endpoint.
41
  *
42
+ * @return Puc_v4p9_Update|null An instance of Update, or NULL when no updates are available.
43
  */
44
  public function requestUpdate() {
45
+ list($themeUpdate, $result) = $this->requestMetadata('Puc_v4p9_Theme_Update', 'request_update');
46
 
47
  if ( $themeUpdate !== null ) {
48
+ /** @var Puc_v4p9_Theme_Update $themeUpdate */
49
  $themeUpdate->slug = $this->slug;
50
  }
51
 
61
  * Create an instance of the scheduler.
62
  *
63
  * @param int $checkPeriod
64
+ * @return Puc_v4p9_Scheduler
65
  */
66
  protected function createScheduler($checkPeriod) {
67
+ return new Puc_v4p9_Scheduler($this, $checkPeriod, array('load-themes.php'));
68
  }
69
 
70
  /**
78
  }
79
 
80
  protected function createDebugBarExtension() {
81
+ return new Puc_v4p9_DebugBar_Extension($this, 'Puc_v4p9_DebugBar_ThemePanel');
82
  }
83
 
84
  /**
132
  /**
133
  * Create a package instance that represents this plugin or theme.
134
  *
135
+ * @return Puc_v4p9_InstalledPackage
136
  */
137
  protected function createInstalledPackage() {
138
+ return new Puc_v4p9_Theme_Package($this->stylesheet, $this);
139
  }
140
  }
141
 
lib/plugin-update-checker/Puc/{v4p8 → v4p9}/Update.php RENAMED
@@ -1,5 +1,5 @@
1
  <?php
2
- if ( !class_exists('Puc_v4p8_Update', false) ):
3
 
4
  /**
5
  * A simple container class for holding information about an available update.
@@ -7,7 +7,7 @@ if ( !class_exists('Puc_v4p8_Update', false) ):
7
  * @author Janis Elsts
8
  * @access public
9
  */
10
- abstract class Puc_v4p8_Update extends Puc_v4p8_Metadata {
11
  public $slug;
12
  public $version;
13
  public $download_url;
1
  <?php
2
+ if ( !class_exists('Puc_v4p9_Update', false) ):
3
 
4
  /**
5
  * A simple container class for holding information about an available update.
7
  * @author Janis Elsts
8
  * @access public
9
  */
10
+ abstract class Puc_v4p9_Update extends Puc_v4p9_Metadata {
11
  public $slug;
12
  public $version;
13
  public $download_url;
lib/plugin-update-checker/Puc/{v4p8 → v4p9}/UpdateChecker.php RENAMED
@@ -1,8 +1,8 @@
1
  <?php
2
 
3
- if ( !class_exists('Puc_v4p8_UpdateChecker', false) ):
4
 
5
- abstract class Puc_v4p8_UpdateChecker {
6
  protected $filterSuffix = '';
7
  protected $updateTransient = '';
8
  protected $translationType = ''; //"plugin" or "theme".
@@ -36,22 +36,22 @@ if ( !class_exists('Puc_v4p8_UpdateChecker', false) ):
36
  public $slug = '';
37
 
38
  /**
39
- * @var Puc_v4p8_InstalledPackage
40
  */
41
  protected $package;
42
 
43
  /**
44
- * @var Puc_v4p8_Scheduler
45
  */
46
  public $scheduler;
47
 
48
  /**
49
- * @var Puc_v4p8_UpgraderStatus
50
  */
51
  protected $upgraderStatus;
52
 
53
  /**
54
- * @var Puc_v4p8_StateStore
55
  */
56
  protected $updateState;
57
 
@@ -60,6 +60,11 @@ if ( !class_exists('Puc_v4p8_UpdateChecker', false) ):
60
  */
61
  protected $lastRequestApiErrors = array();
62
 
 
 
 
 
 
63
  public function __construct($metadataUrl, $directoryName, $slug = null, $checkPeriod = 12, $optionName = '') {
64
  $this->debugMode = (bool)(constant('WP_DEBUG'));
65
  $this->metadataUrl = $metadataUrl;
@@ -79,8 +84,8 @@ if ( !class_exists('Puc_v4p8_UpdateChecker', false) ):
79
 
80
  $this->package = $this->createInstalledPackage();
81
  $this->scheduler = $this->createScheduler($checkPeriod);
82
- $this->upgraderStatus = new Puc_v4p8_UpgraderStatus();
83
- $this->updateState = new Puc_v4p8_StateStore($this->optionName);
84
 
85
  if ( did_action('init') ) {
86
  $this->loadTextDomain();
@@ -146,7 +151,7 @@ if ( !class_exists('Puc_v4p8_UpdateChecker', false) ):
146
  /**
147
  * Remove hooks that were added by this update checker instance.
148
  */
149
- protected function removeHooks() {
150
  remove_filter('site_transient_' . $this->updateTransient, array($this,'injectUpdate'));
151
  remove_filter('site_transient_' . $this->updateTransient, array($this, 'injectTranslationUpdates'));
152
  remove_action(
@@ -159,6 +164,10 @@ if ( !class_exists('Puc_v4p8_UpdateChecker', false) ):
159
  remove_action('plugins_loaded', array($this, 'maybeInitDebugBar'));
160
 
161
  remove_action('init', array($this, 'loadTextDomain'));
 
 
 
 
162
  }
163
 
164
  /**
@@ -187,12 +196,11 @@ if ( !class_exists('Puc_v4p8_UpdateChecker', false) ):
187
  * @return bool
188
  */
189
  public function allowMetadataHost($allow, $host) {
190
- static $metadataHost = 0; //Using 0 instead of NULL because parse_url can return NULL.
191
- if ( $metadataHost === 0 ) {
192
- $metadataHost = parse_url($this->metadataUrl, PHP_URL_HOST);
193
  }
194
 
195
- if ( is_string($metadataHost) && (strtolower($host) === strtolower($metadataHost)) ) {
196
  return true;
197
  }
198
  return $allow;
@@ -201,12 +209,12 @@ if ( !class_exists('Puc_v4p8_UpdateChecker', false) ):
201
  /**
202
  * Create a package instance that represents this plugin or theme.
203
  *
204
- * @return Puc_v4p8_InstalledPackage
205
  */
206
  abstract protected function createInstalledPackage();
207
 
208
  /**
209
- * @return Puc_v4p8_InstalledPackage
210
  */
211
  public function getInstalledPackage() {
212
  return $this->package;
@@ -219,14 +227,14 @@ if ( !class_exists('Puc_v4p8_UpdateChecker', false) ):
219
  * and substitute their own scheduler.
220
  *
221
  * @param int $checkPeriod
222
- * @return Puc_v4p8_Scheduler
223
  */
224
  abstract protected function createScheduler($checkPeriod);
225
 
226
  /**
227
  * Check for updates. The results are stored in the DB option specified in $optionName.
228
  *
229
- * @return Puc_v4p8_Update|null
230
  */
231
  public function checkForUpdates() {
232
  $installedVersion = $this->getInstalledVersion();
@@ -260,7 +268,7 @@ if ( !class_exists('Puc_v4p8_UpdateChecker', false) ):
260
  /**
261
  * Load the update checker state from the DB.
262
  *
263
- * @return Puc_v4p8_StateStore
264
  */
265
  public function getUpdateState() {
266
  return $this->updateState->lazyLoad();
@@ -285,7 +293,7 @@ if ( !class_exists('Puc_v4p8_UpdateChecker', false) ):
285
  * Uses cached update data. To retrieve update information straight from
286
  * the metadata URL, call requestUpdate() instead.
287
  *
288
- * @return Puc_v4p8_Update|null
289
  */
290
  public function getUpdate() {
291
  $update = $this->updateState->getUpdate();
@@ -306,16 +314,16 @@ if ( !class_exists('Puc_v4p8_UpdateChecker', false) ):
306
  *
307
  * Subclasses should run the update through filterUpdateResult before returning it.
308
  *
309
- * @return Puc_v4p8_Update An instance of Update, or NULL when no updates are available.
310
  */
311
  abstract public function requestUpdate();
312
 
313
  /**
314
  * Filter the result of a requestUpdate() call.
315
  *
316
- * @param Puc_v4p8_Update|null $update
317
  * @param array|WP_Error|null $httpResult The value returned by wp_remote_get(), if any.
318
- * @return Puc_v4p8_Update
319
  */
320
  protected function filterUpdateResult($update, $httpResult = null) {
321
  //Let plugins/themes modify the update.
@@ -338,9 +346,9 @@ if ( !class_exists('Puc_v4p8_UpdateChecker', false) ):
338
  * "Compatibility: Unknown".
339
  * The function mimics how wordpress.org API crafts the "tested" field out of "Tested up to".
340
  *
341
- * @param Puc_v4p8_Metadata|null $update
342
  */
343
- protected function fixSupportedWordpressVersion(Puc_v4p8_Metadata $update = null) {
344
  if ( !isset($update->tested) || !preg_match('/^\d++\.\d++$/', $update->tested) ) {
345
  return;
346
  }
@@ -349,26 +357,39 @@ if ( !class_exists('Puc_v4p8_UpdateChecker', false) ):
349
 
350
  $wpVersion = $GLOBALS['wp_version'];
351
 
352
- if ( function_exists('get_preferred_from_update_core') ) {
353
- $coreUpdate = get_preferred_from_update_core();
354
- if ( isset($coreUpdate->current) && version_compare($coreUpdate->current, $wpVersion, '>') ) {
355
- $actualWpVersions[] = $coreUpdate->current;
 
 
 
 
356
  }
357
  }
358
 
359
  $actualWpVersions[] = $wpVersion;
360
 
361
- $actualWpPatchNumber = "999";
362
  foreach ($actualWpVersions as $version) {
363
- if ( preg_match('/^(?P<majorMinor>\d++\.\d++)\.(?P<patch>\d++)/', $version, $versionParts) ) {
364
  if ( $versionParts['majorMinor'] === $update->tested ) {
365
- $actualWpPatchNumber = $versionParts['patch'];
366
- break;
 
 
 
 
367
  }
368
  }
369
  }
 
 
 
370
 
371
- $update->tested .= '.' . $actualWpPatchNumber;
 
 
372
  }
373
 
374
  /**
@@ -570,7 +591,7 @@ if ( !class_exists('Puc_v4p8_UpdateChecker', false) ):
570
  * @param string $metaClass Parse the JSON as an instance of this class. It must have a static fromJson method.
571
  * @param string $filterRoot
572
  * @param array $queryArgs Additional query arguments.
573
- * @return array [Puc_v4p8_Metadata|null, array|WP_Error] A metadata instance and the value returned by wp_remote_get().
574
  */
575
  protected function requestMetadata($metaClass, $filterRoot, $queryArgs = array()) {
576
  //Query args to append to the URL. Plugins can add their own by using a filter callback (see addQueryArgFilter()).
@@ -909,13 +930,13 @@ if ( !class_exists('Puc_v4p8_UpdateChecker', false) ):
909
  }
910
 
911
  protected function createDebugBarExtension() {
912
- return new Puc_v4p8_DebugBar_Extension($this);
913
  }
914
 
915
  /**
916
  * Display additional configuration details in the Debug Bar panel.
917
  *
918
- * @param Puc_v4p8_DebugBar_Panel $panel
919
  */
920
  public function onDisplayConfiguration($panel) {
921
  //Do nothing. Subclasses can use this to add additional info to the panel.
1
  <?php
2
 
3
+ if ( !class_exists('Puc_v4p9_UpdateChecker', false) ):
4
 
5
+ abstract class Puc_v4p9_UpdateChecker {
6
  protected $filterSuffix = '';
7
  protected $updateTransient = '';
8
  protected $translationType = ''; //"plugin" or "theme".
36
  public $slug = '';
37
 
38
  /**
39
+ * @var Puc_v4p9_InstalledPackage
40
  */
41
  protected $package;
42
 
43
  /**
44
+ * @var Puc_v4p9_Scheduler
45
  */
46
  public $scheduler;
47
 
48
  /**
49
+ * @var Puc_v4p9_UpgraderStatus
50
  */
51
  protected $upgraderStatus;
52
 
53
  /**
54
+ * @var Puc_v4p9_StateStore
55
  */
56
  protected $updateState;
57
 
60
  */
61
  protected $lastRequestApiErrors = array();
62
 
63
+ /**
64
+ * @var string|mixed The default is 0 because parse_url() can return NULL or FALSE.
65
+ */
66
+ protected $cachedMetadataHost = 0;
67
+
68
  public function __construct($metadataUrl, $directoryName, $slug = null, $checkPeriod = 12, $optionName = '') {
69
  $this->debugMode = (bool)(constant('WP_DEBUG'));
70
  $this->metadataUrl = $metadataUrl;
84
 
85
  $this->package = $this->createInstalledPackage();
86
  $this->scheduler = $this->createScheduler($checkPeriod);
87
+ $this->upgraderStatus = new Puc_v4p9_UpgraderStatus();
88
+ $this->updateState = new Puc_v4p9_StateStore($this->optionName);
89
 
90
  if ( did_action('init') ) {
91
  $this->loadTextDomain();
151
  /**
152
  * Remove hooks that were added by this update checker instance.
153
  */
154
+ public function removeHooks() {
155
  remove_filter('site_transient_' . $this->updateTransient, array($this,'injectUpdate'));
156
  remove_filter('site_transient_' . $this->updateTransient, array($this, 'injectTranslationUpdates'));
157
  remove_action(
164
  remove_action('plugins_loaded', array($this, 'maybeInitDebugBar'));
165
 
166
  remove_action('init', array($this, 'loadTextDomain'));
167
+
168
+ if ( $this->scheduler ) {
169
+ $this->scheduler->removeHooks();
170
+ }
171
  }
172
 
173
  /**
196
  * @return bool
197
  */
198
  public function allowMetadataHost($allow, $host) {
199
+ if ( $this->cachedMetadataHost === 0 ) {
200
+ $this->cachedMetadataHost = parse_url($this->metadataUrl, PHP_URL_HOST);
 
201
  }
202
 
203
+ if ( is_string($this->cachedMetadataHost) && (strtolower($host) === strtolower($this->cachedMetadataHost)) ) {
204
  return true;
205
  }
206
  return $allow;
209
  /**
210
  * Create a package instance that represents this plugin or theme.
211
  *
212
+ * @return Puc_v4p9_InstalledPackage
213
  */
214
  abstract protected function createInstalledPackage();
215
 
216
  /**
217
+ * @return Puc_v4p9_InstalledPackage
218
  */
219
  public function getInstalledPackage() {
220
  return $this->package;
227
  * and substitute their own scheduler.
228
  *
229
  * @param int $checkPeriod
230
+ * @return Puc_v4p9_Scheduler
231
  */
232
  abstract protected function createScheduler($checkPeriod);
233
 
234
  /**
235
  * Check for updates. The results are stored in the DB option specified in $optionName.
236
  *
237
+ * @return Puc_v4p9_Update|null
238
  */
239
  public function checkForUpdates() {
240
  $installedVersion = $this->getInstalledVersion();
268
  /**
269
  * Load the update checker state from the DB.
270
  *
271
+ * @return Puc_v4p9_StateStore
272
  */
273
  public function getUpdateState() {
274
  return $this->updateState->lazyLoad();
293
  * Uses cached update data. To retrieve update information straight from
294
  * the metadata URL, call requestUpdate() instead.
295
  *
296
+ * @return Puc_v4p9_Update|null
297
  */
298
  public function getUpdate() {
299
  $update = $this->updateState->getUpdate();
314
  *
315
  * Subclasses should run the update through filterUpdateResult before returning it.
316
  *
317
+ * @return Puc_v4p9_Update An instance of Update, or NULL when no updates are available.
318
  */
319
  abstract public function requestUpdate();
320
 
321
  /**
322
  * Filter the result of a requestUpdate() call.
323
  *
324
+ * @param Puc_v4p9_Update|null $update
325
  * @param array|WP_Error|null $httpResult The value returned by wp_remote_get(), if any.
326
+ * @return Puc_v4p9_Update
327
  */
328
  protected function filterUpdateResult($update, $httpResult = null) {
329
  //Let plugins/themes modify the update.
346
  * "Compatibility: Unknown".
347
  * The function mimics how wordpress.org API crafts the "tested" field out of "Tested up to".
348
  *
349
+ * @param Puc_v4p9_Metadata|null $update
350
  */
351
+ protected function fixSupportedWordpressVersion(Puc_v4p9_Metadata $update = null) {
352
  if ( !isset($update->tested) || !preg_match('/^\d++\.\d++$/', $update->tested) ) {
353
  return;
354
  }
357
 
358
  $wpVersion = $GLOBALS['wp_version'];
359
 
360
+ if ( function_exists('get_core_updates') ) {
361
+ $coreUpdates = get_core_updates();
362
+ if ( is_array($coreUpdates) ) {
363
+ foreach ($coreUpdates as $coreUpdate) {
364
+ if ( isset($coreUpdate->current) ) {
365
+ $actualWpVersions[] = $coreUpdate->current;
366
+ }
367
+ }
368
  }
369
  }
370
 
371
  $actualWpVersions[] = $wpVersion;
372
 
373
+ $actualWpPatchNumber = null;
374
  foreach ($actualWpVersions as $version) {
375
+ if ( preg_match('/^(?P<majorMinor>\d++\.\d++)(?:\.(?P<patch>\d++))?/', $version, $versionParts) ) {
376
  if ( $versionParts['majorMinor'] === $update->tested ) {
377
+ $patch = isset($versionParts['patch']) ? intval($versionParts['patch']) : 0;
378
+ if ( $actualWpPatchNumber === null ) {
379
+ $actualWpPatchNumber = $patch;
380
+ } else {
381
+ $actualWpPatchNumber = max($actualWpPatchNumber, $patch);
382
+ }
383
  }
384
  }
385
  }
386
+ if ( $actualWpPatchNumber === null ) {
387
+ $actualWpPatchNumber = 999;
388
+ }
389
 
390
+ if ( $actualWpPatchNumber > 0 ) {
391
+ $update->tested .= '.' . $actualWpPatchNumber;
392
+ }
393
  }
394
 
395
  /**
591
  * @param string $metaClass Parse the JSON as an instance of this class. It must have a static fromJson method.
592
  * @param string $filterRoot
593
  * @param array $queryArgs Additional query arguments.
594
+ * @return array [Puc_v4p9_Metadata|null, array|WP_Error] A metadata instance and the value returned by wp_remote_get().
595
  */
596
  protected function requestMetadata($metaClass, $filterRoot, $queryArgs = array()) {
597
  //Query args to append to the URL. Plugins can add their own by using a filter callback (see addQueryArgFilter()).
930
  }
931
 
932
  protected function createDebugBarExtension() {
933
+ return new Puc_v4p9_DebugBar_Extension($this);
934
  }
935
 
936
  /**
937
  * Display additional configuration details in the Debug Bar panel.
938
  *
939
+ * @param Puc_v4p9_DebugBar_Panel $panel
940
  */
941
  public function onDisplayConfiguration($panel) {
942
  //Do nothing. Subclasses can use this to add additional info to the panel.
lib/plugin-update-checker/Puc/{v4p8 → v4p9}/UpgraderStatus.php RENAMED
@@ -1,5 +1,5 @@
1
  <?php
2
- if ( !class_exists('Puc_v4p8_UpgraderStatus', false) ):
3
 
4
  /**
5
  * A utility class that helps figure out which plugin or theme WordPress is upgrading.
@@ -8,7 +8,7 @@ if ( !class_exists('Puc_v4p8_UpgraderStatus', false) ):
8
  * Core classes like Plugin_Upgrader don't expose the plugin file name during an in-progress update (AFAICT).
9
  * This class uses a few workarounds and heuristics to get the file name.
10
  */
11
- class Puc_v4p8_UpgraderStatus {
12
  private $currentType = null; //"plugin" or "theme".
13
  private $currentId = null; //Plugin basename or theme directory name.
14
 
1
  <?php
2
+ if ( !class_exists('Puc_v4p9_UpgraderStatus', false) ):
3
 
4
  /**
5
  * A utility class that helps figure out which plugin or theme WordPress is upgrading.
8
  * Core classes like Plugin_Upgrader don't expose the plugin file name during an in-progress update (AFAICT).
9
  * This class uses a few workarounds and heuristics to get the file name.
10
  */
11
+ class Puc_v4p9_UpgraderStatus {
12
  private $currentType = null; //"plugin" or "theme".
13
  private $currentId = null; //Plugin basename or theme directory name.
14
 
lib/plugin-update-checker/Puc/{v4p8 → v4p9}/Utils.php RENAMED
@@ -1,8 +1,8 @@
1
  <?php
2
 
3
- if ( !class_exists('Puc_v4p8_Utils', false) ):
4
 
5
- class Puc_v4p8_Utils {
6
  /**
7
  * Get a value from a nested array or object based on a path.
8
  *
1
  <?php
2
 
3
+ if ( !class_exists('Puc_v4p9_Utils', false) ):
4
 
5
+ class Puc_v4p9_Utils {
6
  /**
7
  * Get a value from a nested array or object based on a path.
8
  *
lib/plugin-update-checker/Puc/{v4p8 → v4p9}/Vcs/Api.php RENAMED
@@ -1,7 +1,7 @@
1
  <?php
2
- if ( !class_exists('Puc_v4p8_Vcs_Api') ):
3
 
4
- abstract class Puc_v4p8_Vcs_Api {
5
  protected $tagNameProperty = 'name';
6
  protected $slug = '';
7
 
@@ -27,7 +27,7 @@ if ( !class_exists('Puc_v4p8_Vcs_Api') ):
27
  protected $localDirectory = null;
28
 
29
  /**
30
- * Puc_v4p8_Vcs_Api constructor.
31
  *
32
  * @param string $repositoryUrl
33
  * @param array|string|null $credentials
@@ -48,7 +48,7 @@ if ( !class_exists('Puc_v4p8_Vcs_Api') ):
48
  * Figure out which reference (i.e tag or branch) contains the latest version.
49
  *
50
  * @param string $configBranch Start looking in this branch.
51
- * @return null|Puc_v4p8_Vcs_Reference
52
  */
53
  abstract public function chooseReference($configBranch);
54
 
@@ -105,7 +105,7 @@ if ( !class_exists('Puc_v4p8_Vcs_Api') ):
105
  * Get a branch.
106
  *
107
  * @param string $branchName
108
- * @return Puc_v4p8_Vcs_Reference|null
109
  */
110
  abstract public function getBranch($branchName);
111
 
@@ -113,7 +113,7 @@ if ( !class_exists('Puc_v4p8_Vcs_Api') ):
113
  * Get a specific tag.
114
  *
115
  * @param string $tagName
116
- * @return Puc_v4p8_Vcs_Reference|null
117
  */
118
  abstract public function getTag($tagName);
119
 
@@ -121,7 +121,7 @@ if ( !class_exists('Puc_v4p8_Vcs_Api') ):
121
  * Get the tag that looks like the highest version number.
122
  * (Implementations should skip pre-release versions if possible.)
123
  *
124
- * @return Puc_v4p8_Vcs_Reference|null
125
  */
126
  abstract public function getLatestTag();
127
 
1
  <?php
2
+ if ( !class_exists('Puc_v4p9_Vcs_Api') ):
3
 
4
+ abstract class Puc_v4p9_Vcs_Api {
5
  protected $tagNameProperty = 'name';
6
  protected $slug = '';
7
 
27
  protected $localDirectory = null;
28
 
29
  /**
30
+ * Puc_v4p9_Vcs_Api constructor.
31
  *
32
  * @param string $repositoryUrl
33
  * @param array|string|null $credentials
48
  * Figure out which reference (i.e tag or branch) contains the latest version.
49
  *
50
  * @param string $configBranch Start looking in this branch.
51
+ * @return null|Puc_v4p9_Vcs_Reference
52
  */
53
  abstract public function chooseReference($configBranch);
54
 
105
  * Get a branch.
106
  *
107
  * @param string $branchName
108
+ * @return Puc_v4p9_Vcs_Reference|null
109
  */
110
  abstract public function getBranch($branchName);
111
 
113
  * Get a specific tag.
114
  *
115
  * @param string $tagName
116
+ * @return Puc_v4p9_Vcs_Reference|null
117
  */
118
  abstract public function getTag($tagName);
119
 
121
  * Get the tag that looks like the highest version number.
122
  * (Implementations should skip pre-release versions if possible.)
123
  *
124
+ * @return Puc_v4p9_Vcs_Reference|null
125
  */
126
  abstract public function getLatestTag();
127
 
lib/plugin-update-checker/Puc/{v4p8 → v4p9}/Vcs/BaseChecker.php RENAMED
@@ -1,7 +1,7 @@
1
  <?php
2
- if ( !interface_exists('Puc_v4p8_Vcs_BaseChecker', false) ):
3
 
4
- interface Puc_v4p8_Vcs_BaseChecker {
5
  /**
6
  * Set the repository branch to use for updates. Defaults to 'master'.
7
  *
@@ -19,7 +19,7 @@ if ( !interface_exists('Puc_v4p8_Vcs_BaseChecker', false) ):
19
  public function setAuthentication($credentials);
20
 
21
  /**
22
- * @return Puc_v4p8_Vcs_Api
23
  */
24
  public function getVcsApi();
25
  }
1
  <?php
2
+ if ( !interface_exists('Puc_v4p9_Vcs_BaseChecker', false) ):
3
 
4
+ interface Puc_v4p9_Vcs_BaseChecker {
5
  /**
6
  * Set the repository branch to use for updates. Defaults to 'master'.
7
  *
19
  public function setAuthentication($credentials);
20
 
21
  /**
22
+ * @return Puc_v4p9_Vcs_Api
23
  */
24
  public function getVcsApi();
25
  }
lib/plugin-update-checker/Puc/{v4p8 → v4p9}/Vcs/BitBucketApi.php RENAMED
@@ -1,9 +1,9 @@
1
  <?php
2
- if ( !class_exists('Puc_v4p8_Vcs_BitBucketApi', false) ):
3
 
4
- class Puc_v4p8_Vcs_BitBucketApi extends Puc_v4p8_Vcs_Api {
5
  /**
6
- * @var Puc_v4p8_OAuthSignature
7
  */
8
  private $oauth = null;
9
 
@@ -33,7 +33,7 @@ if ( !class_exists('Puc_v4p8_Vcs_BitBucketApi', false) ):
33
  * Figure out which reference (i.e tag or branch) contains the latest version.
34
  *
35
  * @param string $configBranch Start looking in this branch.
36
- * @return null|Puc_v4p8_Vcs_Reference
37
  */
38
  public function chooseReference($configBranch) {
39
  $updateSource = null;
@@ -59,7 +59,7 @@ if ( !class_exists('Puc_v4p8_Vcs_BitBucketApi', false) ):
59
  return null;
60
  }
61
 
62
- return new Puc_v4p8_Vcs_Reference(array(
63
  'name' => $branch->name,
64
  'updated' => $branch->target->date,
65
  'downloadUrl' => $this->getDownloadUrl($branch->name),
@@ -70,7 +70,7 @@ if ( !class_exists('Puc_v4p8_Vcs_BitBucketApi', false) ):
70
  * Get a specific tag.
71
  *
72
  * @param string $tagName
73
- * @return Puc_v4p8_Vcs_Reference|null
74
  */
75
  public function getTag($tagName) {
76
  $tag = $this->api('/refs/tags/' . $tagName);
@@ -78,7 +78,7 @@ if ( !class_exists('Puc_v4p8_Vcs_BitBucketApi', false) ):
78
  return null;
79
  }
80
 
81
- return new Puc_v4p8_Vcs_Reference(array(
82
  'name' => $tag->name,
83
  'version' => ltrim($tag->name, 'v'),
84
  'updated' => $tag->target->date,
@@ -89,7 +89,7 @@ if ( !class_exists('Puc_v4p8_Vcs_BitBucketApi', false) ):
89
  /**
90
  * Get the tag that looks like the highest version number.
91
  *
92
- * @return Puc_v4p8_Vcs_Reference|null
93
  */
94
  public function getLatestTag() {
95
  $tags = $this->api('/refs/tags?sort=-target.date');
@@ -103,7 +103,7 @@ if ( !class_exists('Puc_v4p8_Vcs_BitBucketApi', false) ):
103
  //Return the first result.
104
  if ( !empty($versionTags) ) {
105
  $tag = $versionTags[0];
106
- return new Puc_v4p8_Vcs_Reference(array(
107
  'name' => $tag->name,
108
  'version' => ltrim($tag->name, 'v'),
109
  'updated' => $tag->target->date,
@@ -117,7 +117,7 @@ if ( !class_exists('Puc_v4p8_Vcs_BitBucketApi', false) ):
117
  * Get the tag/ref specified by the "Stable tag" header in the readme.txt of a given branch.
118
  *
119
  * @param string $branch
120
- * @return null|Puc_v4p8_Vcs_Reference
121
  */
122
  protected function getStableTag($branch) {
123
  $remoteReadme = $this->getRemoteReadme($branch);
@@ -187,7 +187,7 @@ if ( !class_exists('Puc_v4p8_Vcs_BitBucketApi', false) ):
187
  */
188
  public function api($url, $version = '2.0') {
189
  $url = ltrim($url, '/');
190
- $isSrcResource = Puc_v4p8_Utils::startsWith($url, 'src/');
191
 
192
  $url = implode('/', array(
193
  'https://api.bitbucket.org',
@@ -242,7 +242,7 @@ if ( !class_exists('Puc_v4p8_Vcs_BitBucketApi', false) ):
242
  parent::setAuthentication($credentials);
243
 
244
  if ( !empty($credentials) && !empty($credentials['consumer_key']) ) {
245
- $this->oauth = new Puc_v4p8_OAuthSignature(
246
  $credentials['consumer_key'],
247
  $credentials['consumer_secret']
248
  );
1
  <?php
2
+ if ( !class_exists('Puc_v4p9_Vcs_BitBucketApi', false) ):
3
 
4
+ class Puc_v4p9_Vcs_BitBucketApi extends Puc_v4p9_Vcs_Api {
5
  /**
6
+ * @var Puc_v4p9_OAuthSignature
7
  */
8
  private $oauth = null;
9
 
33
  * Figure out which reference (i.e tag or branch) contains the latest version.
34
  *
35
  * @param string $configBranch Start looking in this branch.
36
+ * @return null|Puc_v4p9_Vcs_Reference
37
  */
38
  public function chooseReference($configBranch) {
39
  $updateSource = null;
59
  return null;
60
  }
61
 
62
+ return new Puc_v4p9_Vcs_Reference(array(
63
  'name' => $branch->name,
64
  'updated' => $branch->target->date,
65
  'downloadUrl' => $this->getDownloadUrl($branch->name),
70
  * Get a specific tag.
71
  *
72
  * @param string $tagName
73
+ * @return Puc_v4p9_Vcs_Reference|null
74
  */
75
  public function getTag($tagName) {
76
  $tag = $this->api('/refs/tags/' . $tagName);
78
  return null;
79
  }
80
 
81
+ return new Puc_v4p9_Vcs_Reference(array(
82
  'name' => $tag->name,
83
  'version' => ltrim($tag->name, 'v'),
84
  'updated' => $tag->target->date,
89
  /**
90
  * Get the tag that looks like the highest version number.
91
  *
92
+ * @return Puc_v4p9_Vcs_Reference|null
93
  */
94
  public function getLatestTag() {
95
  $tags = $this->api('/refs/tags?sort=-target.date');
103
  //Return the first result.
104
  if ( !empty($versionTags) ) {
105
  $tag = $versionTags[0];
106
+ return new Puc_v4p9_Vcs_Reference(array(
107
  'name' => $tag->name,
108
  'version' => ltrim($tag->name, 'v'),
109
  'updated' => $tag->target->date,
117
  * Get the tag/ref specified by the "Stable tag" header in the readme.txt of a given branch.
118
  *
119
  * @param string $branch
120
+ * @return null|Puc_v4p9_Vcs_Reference
121
  */
122
  protected function getStableTag($branch) {
123
  $remoteReadme = $this->getRemoteReadme($branch);
187
  */
188
  public function api($url, $version = '2.0') {
189
  $url = ltrim($url, '/');
190
+ $isSrcResource = Puc_v4p9_Utils::startsWith($url, 'src/');
191
 
192
  $url = implode('/', array(
193
  'https://api.bitbucket.org',
242
  parent::setAuthentication($credentials);
243
 
244
  if ( !empty($credentials) && !empty($credentials['consumer_key']) ) {
245
+ $this->oauth = new Puc_v4p9_OAuthSignature(
246
  $credentials['consumer_key'],
247
  $credentials['consumer_secret']
248
  );
lib/plugin-update-checker/Puc/{v4p8 → v4p9}/Vcs/GitHubApi.php RENAMED
@@ -1,8 +1,8 @@
1
  <?php
2
 
3
- if ( !class_exists('Puc_v4p8_Vcs_GitHubApi', false) ):
4
 
5
- class Puc_v4p8_Vcs_GitHubApi extends Puc_v4p8_Vcs_Api {
6
  /**
7
  * @var string GitHub username.
8
  */
@@ -57,7 +57,7 @@ if ( !class_exists('Puc_v4p8_Vcs_GitHubApi', false) ):
57
  /**
58
  * Get the latest release from GitHub.
59
  *
60
- * @return Puc_v4p8_Vcs_Reference|null
61
  */
62
  public function getLatestRelease() {
63
  $release = $this->api('/repos/:user/:repo/releases/latest');
@@ -65,10 +65,10 @@ if ( !class_exists('Puc_v4p8_Vcs_GitHubApi', false) ):
65
  return null;
66
  }
67
 
68
- $reference = new Puc_v4p8_Vcs_Reference(array(
69
  'name' => $release->tag_name,
70
  'version' => ltrim($release->tag_name, 'v'), //Remove the "v" prefix from "v1.2.3".
71
- 'downloadUrl' => $this->signDownloadUrl($release->zipball_url),
72
  'updated' => $release->created_at,
73
  'apiResponse' => $release,
74
  ));
@@ -84,9 +84,10 @@ if ( !class_exists('Puc_v4p8_Vcs_GitHubApi', false) ):
84
  if ( $this->isAuthenticationEnabled() ) {
85
  /**
86
  * Keep in mind that we'll need to add an "Accept" header to download this asset.
87
- * @see setReleaseDownloadHeader()
 
88
  */
89
- $reference->downloadUrl = $this->signDownloadUrl($matchingAssets[0]->url);
90
  } else {
91
  //It seems that browser_download_url only works for public repositories.
92
  //Using an access_token doesn't help. Maybe OAuth would work?
@@ -108,7 +109,7 @@ if ( !class_exists('Puc_v4p8_Vcs_GitHubApi', false) ):
108
  /**
109
  * Get the tag that looks like the highest version number.
110
  *
111
- * @return Puc_v4p8_Vcs_Reference|null
112
  */
113
  public function getLatestTag() {
114
  $tags = $this->api('/repos/:user/:repo/tags');
@@ -123,10 +124,10 @@ if ( !class_exists('Puc_v4p8_Vcs_GitHubApi', false) ):
123
  }
124
 
125
  $tag = $versionTags[0];
126
- return new Puc_v4p8_Vcs_Reference(array(
127
  'name' => $tag->name,
128
  'version' => ltrim($tag->name, 'v'),
129
- 'downloadUrl' => $this->signDownloadUrl($tag->zipball_url),
130
  'apiResponse' => $tag,
131
  ));
132
  }
@@ -135,7 +136,7 @@ if ( !class_exists('Puc_v4p8_Vcs_GitHubApi', false) ):
135
  * Get a branch by name.
136
  *
137
  * @param string $branchName
138
- * @return null|Puc_v4p8_Vcs_Reference
139
  */
140
  public function getBranch($branchName) {
141
  $branch = $this->api('/repos/:user/:repo/branches/' . $branchName);
@@ -143,7 +144,7 @@ if ( !class_exists('Puc_v4p8_Vcs_GitHubApi', false) ):
143
  return null;
144
  }
145
 
146
- $reference = new Puc_v4p8_Vcs_Reference(array(
147
  'name' => $branch->name,
148
  'downloadUrl' => $this->buildArchiveDownloadUrl($branch->name),
149
  'apiResponse' => $branch,
@@ -203,6 +204,10 @@ if ( !class_exists('Puc_v4p8_Vcs_GitHubApi', false) ):
203
  $url = $this->buildApiUrl($url, $queryParams);
204
 
205
  $options = array('timeout' => 10);
 
 
 
 
206
  if ( !empty($this->httpFilterName) ) {
207
  $options = apply_filters($this->httpFilterName, $options);
208
  }
@@ -245,9 +250,6 @@ if ( !class_exists('Puc_v4p8_Vcs_GitHubApi', false) ):
245
  }
246
  $url = 'https://api.github.com' . $url;
247
 
248
- if ( !empty($this->accessToken) ) {
249
- $queryParams['access_token'] = $this->accessToken;
250
- }
251
  if ( !empty($queryParams) ) {
252
  $url = add_query_arg($queryParams, $url);
253
  }
@@ -285,9 +287,6 @@ if ( !class_exists('Puc_v4p8_Vcs_GitHubApi', false) ):
285
  urlencode($this->repositoryName),
286
  urlencode($ref)
287
  );
288
- if ( !empty($this->accessToken) ) {
289
- $url = $this->signDownloadUrl($url);
290
- }
291
  return $url;
292
  }
293
 
@@ -305,13 +304,17 @@ if ( !class_exists('Puc_v4p8_Vcs_GitHubApi', false) ):
305
  public function setAuthentication($credentials) {
306
  parent::setAuthentication($credentials);
307
  $this->accessToken = is_string($credentials) ? $credentials : null;
 
 
 
 
308
  }
309
 
310
  /**
311
  * Figure out which reference (i.e tag or branch) contains the latest version.
312
  *
313
  * @param string $configBranch Start looking in this branch.
314
- * @return null|Puc_v4p8_Vcs_Reference
315
  */
316
  public function chooseReference($configBranch) {
317
  $updateSource = null;
@@ -332,17 +335,6 @@ if ( !class_exists('Puc_v4p8_Vcs_GitHubApi', false) ):
332
  return $updateSource;
333
  }
334
 
335
- /**
336
- * @param string $url
337
- * @return string
338
- */
339
- public function signDownloadUrl($url) {
340
- if ( empty($this->credentials) ) {
341
- return $url;
342
- }
343
- return add_query_arg('access_token', $this->credentials, $url);
344
- }
345
-
346
  /**
347
  * Enable updating via release assets.
348
  *
@@ -361,10 +353,6 @@ if ( !class_exists('Puc_v4p8_Vcs_GitHubApi', false) ):
361
  $this->userName,
362
  $this->repositoryName
363
  );
364
-
365
- //Optimization: Instead of filtering all HTTP requests, let's do it only when
366
- //WordPress is about to download an update.
367
- add_filter('upgrader_pre_download', array($this, 'addHttpRequestFilter'), 10, 1); //WP 3.7+
368
  }
369
 
370
  /**
@@ -387,31 +375,67 @@ if ( !class_exists('Puc_v4p8_Vcs_GitHubApi', false) ):
387
  * @return bool
388
  */
389
  public function addHttpRequestFilter($result) {
390
- if ( $this->releaseAssetsEnabled && !$this->downloadFilterAdded && $this->isAuthenticationEnabled() ) {
391
- add_filter('http_request_args', array($this, 'setReleaseDownloadHeader'), 10, 2);
 
392
  $this->downloadFilterAdded = true;
393
  }
394
  return $result;
395
  }
396
 
397
  /**
398
- * Set the HTTP header that's necessary to download private release assets.
399
  *
400
  * See GitHub docs:
401
  * @link https://developer.github.com/v3/repos/releases/#get-a-single-release-asset
 
402
  *
403
  * @internal
404
  * @param array $requestArgs
405
  * @param string $url
406
  * @return array
407
  */
408
- public function setReleaseDownloadHeader($requestArgs, $url = '') {
409
- //Is WordPress trying to download one of our assets?
410
- if ( strpos($url, $this->assetApiBaseUrl) !== false ) {
411
- $requestArgs['headers']['accept'] = 'application/octet-stream';
 
 
 
 
 
412
  }
413
  return $requestArgs;
414
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
415
  }
416
 
417
  endif;
1
  <?php
2
 
3
+ if ( !class_exists('Puc_v4p9_Vcs_GitHubApi', false) ):
4
 
5
+ class Puc_v4p9_Vcs_GitHubApi extends Puc_v4p9_Vcs_Api {
6
  /**
7
  * @var string GitHub username.
8
  */
57
  /**
58
  * Get the latest release from GitHub.
59
  *
60
+ * @return Puc_v4p9_Vcs_Reference|null
61
  */
62
  public function getLatestRelease() {
63
  $release = $this->api('/repos/:user/:repo/releases/latest');
65
  return null;
66
  }
67
 
68
+ $reference = new Puc_v4p9_Vcs_Reference(array(
69
  'name' => $release->tag_name,
70
  'version' => ltrim($release->tag_name, 'v'), //Remove the "v" prefix from "v1.2.3".
71
+ 'downloadUrl' => $release->zipball_url,
72
  'updated' => $release->created_at,
73
  'apiResponse' => $release,
74
  ));
84
  if ( $this->isAuthenticationEnabled() ) {
85
  /**
86
  * Keep in mind that we'll need to add an "Accept" header to download this asset.
87
+ *
88
+ * @see setUpdateDownloadHeaders()
89
  */
90
+ $reference->downloadUrl = $matchingAssets[0]->url;
91
  } else {
92
  //It seems that browser_download_url only works for public repositories.
93
  //Using an access_token doesn't help. Maybe OAuth would work?
109
  /**
110
  * Get the tag that looks like the highest version number.
111
  *
112
+ * @return Puc_v4p9_Vcs_Reference|null
113
  */
114
  public function getLatestTag() {
115
  $tags = $this->api('/repos/:user/:repo/tags');
124
  }
125
 
126
  $tag = $versionTags[0];
127
+ return new Puc_v4p9_Vcs_Reference(array(
128
  'name' => $tag->name,
129
  'version' => ltrim($tag->name, 'v'),
130
+ 'downloadUrl' => $tag->zipball_url,
131
  'apiResponse' => $tag,
132
  ));
133
  }
136
  * Get a branch by name.
137
  *
138
  * @param string $branchName
139
+ * @return null|Puc_v4p9_Vcs_Reference
140
  */
141
  public function getBranch($branchName) {
142
  $branch = $this->api('/repos/:user/:repo/branches/' . $branchName);
144
  return null;
145
  }
146
 
147
+ $reference = new Puc_v4p9_Vcs_Reference(array(
148
  'name' => $branch->name,
149
  'downloadUrl' => $this->buildArchiveDownloadUrl($branch->name),
150
  'apiResponse' => $branch,
204
  $url = $this->buildApiUrl($url, $queryParams);
205
 
206
  $options = array('timeout' => 10);
207
+ if ( $this->isAuthenticationEnabled() ) {
208
+ $options['headers'] = array('Authorization' => $this->getAuthorizationHeader());
209
+ }
210
+
211
  if ( !empty($this->httpFilterName) ) {
212
  $options = apply_filters($this->httpFilterName, $options);
213
  }
250
  }
251
  $url = 'https://api.github.com' . $url;
252
 
 
 
 
253
  if ( !empty($queryParams) ) {
254
  $url = add_query_arg($queryParams, $url);
255
  }
287
  urlencode($this->repositoryName),
288
  urlencode($ref)
289
  );
 
 
 
290
  return $url;
291
  }
292
 
304
  public function setAuthentication($credentials) {
305
  parent::setAuthentication($credentials);
306
  $this->accessToken = is_string($credentials) ? $credentials : null;
307
+
308
+ //Optimization: Instead of filtering all HTTP requests, let's do it only when
309
+ //WordPress is about to download an update.
310
+ add_filter('upgrader_pre_download', array($this, 'addHttpRequestFilter'), 10, 1); //WP 3.7+
311
  }
312
 
313
  /**
314
  * Figure out which reference (i.e tag or branch) contains the latest version.
315
  *
316
  * @param string $configBranch Start looking in this branch.
317
+ * @return null|Puc_v4p9_Vcs_Reference
318
  */
319
  public function chooseReference($configBranch) {
320
  $updateSource = null;
335
  return $updateSource;
336
  }
337
 
 
 
 
 
 
 
 
 
 
 
 
338
  /**
339
  * Enable updating via release assets.
340
  *
353
  $this->userName,
354
  $this->repositoryName
355
  );
 
 
 
 
356
  }
357
 
358
  /**
375
  * @return bool
376
  */
377
  public function addHttpRequestFilter($result) {
378
+ if ( !$this->downloadFilterAdded && $this->isAuthenticationEnabled() ) {
379
+ add_filter('http_request_args', array($this, 'setUpdateDownloadHeaders'), 10, 2);
380
+ add_action('requests-requests.before_redirect', array($this, 'removeAuthHeaderFromRedirects'), 10, 4);
381
  $this->downloadFilterAdded = true;
382
  }
383
  return $result;
384
  }
385
 
386
  /**
387
+ * Set the HTTP headers that are necessary to download updates from private repositories.
388
  *
389
  * See GitHub docs:
390
  * @link https://developer.github.com/v3/repos/releases/#get-a-single-release-asset
391
+ * @link https://developer.github.com/v3/auth/#basic-authentication
392
  *
393
  * @internal
394
  * @param array $requestArgs
395
  * @param string $url
396
  * @return array
397
  */
398
+ public function setUpdateDownloadHeaders($requestArgs, $url = '') {
399
+ //Is WordPress trying to download one of our release assets?
400
+ if ( $this->releaseAssetsEnabled && (strpos($url, $this->assetApiBaseUrl) !== false) ) {
401
+ $requestArgs['headers']['Accept'] = 'application/octet-stream';
402
+ }
403
+ //Use Basic authentication, but only if the download is from our repository.
404
+ $repoApiBaseUrl = $this->buildApiUrl('/repos/:user/:repo/', array());
405
+ if ( $this->isAuthenticationEnabled() && (strpos($url, $repoApiBaseUrl)) === 0 ) {
406
+ $requestArgs['headers']['Authorization'] = $this->getAuthorizationHeader();
407
  }
408
  return $requestArgs;
409
  }
410
+
411
+ /**
412
+ * When following a redirect, the Requests library will automatically forward
413
+ * the authorization header to other hosts. We don't want that because it breaks
414
+ * AWS downloads and can leak authorization information.
415
+ *
416
+ * @internal
417
+ * @param string $location
418
+ * @param array $headers
419
+ */
420
+ public function removeAuthHeaderFromRedirects(&$location, &$headers) {
421
+ $repoApiBaseUrl = $this->buildApiUrl('/repos/:user/:repo/', array());
422
+ if ( strpos($location, $repoApiBaseUrl) === 0 ) {
423
+ return; //This request is going to GitHub, so it's fine.
424
+ }
425
+ //Remove the header.
426
+ if ( isset($headers['Authorization']) ) {
427
+ unset($headers['Authorization']);
428
+ }
429
+ }
430
+
431
+ /**
432
+ * Generate the value of the "Authorization" header.
433
+ *
434
+ * @return string
435
+ */
436
+ protected function getAuthorizationHeader() {
437
+ return 'Basic ' . base64_encode($this->userName . ':' . $this->accessToken);
438
+ }
439
  }
440
 
441
  endif;
lib/plugin-update-checker/Puc/{v4p8 → v4p9}/Vcs/GitLabApi.php RENAMED
@@ -1,8 +1,8 @@
1
  <?php
2
 
3
- if ( !class_exists('Puc_v4p8_Vcs_GitLabApi', false) ):
4
 
5
- class Puc_v4p8_Vcs_GitLabApi extends Puc_v4p8_Vcs_Api {
6
  /**
7
  * @var string GitLab username.
8
  */
@@ -91,7 +91,7 @@ if ( !class_exists('Puc_v4p8_Vcs_GitLabApi', false) ):
91
  /**
92
  * Get the latest release from GitLab.
93
  *
94
- * @return Puc_v4p8_Vcs_Reference|null
95
  */
96
  public function getLatestRelease() {
97
  return $this->getLatestTag();
@@ -100,7 +100,7 @@ if ( !class_exists('Puc_v4p8_Vcs_GitLabApi', false) ):
100
  /**
101
  * Get the tag that looks like the highest version number.
102
  *
103
- * @return Puc_v4p8_Vcs_Reference|null
104
  */
105
  public function getLatestTag() {
106
  $tags = $this->api('/:id/repository/tags');
@@ -114,7 +114,7 @@ if ( !class_exists('Puc_v4p8_Vcs_GitLabApi', false) ):
114
  }
115
 
116
  $tag = $versionTags[0];
117
- return new Puc_v4p8_Vcs_Reference(array(
118
  'name' => $tag->name,
119
  'version' => ltrim($tag->name, 'v'),
120
  'downloadUrl' => $this->buildArchiveDownloadUrl($tag->name),
@@ -126,7 +126,7 @@ if ( !class_exists('Puc_v4p8_Vcs_GitLabApi', false) ):
126
  * Get a branch by name.
127
  *
128
  * @param string $branchName
129
- * @return null|Puc_v4p8_Vcs_Reference
130
  */
131
  public function getBranch($branchName) {
132
  $branch = $this->api('/:id/repository/branches/' . $branchName);
@@ -134,7 +134,7 @@ if ( !class_exists('Puc_v4p8_Vcs_GitLabApi', false) ):
134
  return null;
135
  }
136
 
137
- $reference = new Puc_v4p8_Vcs_Reference(array(
138
  'name' => $branch->name,
139
  'downloadUrl' => $this->buildArchiveDownloadUrl($branch->name),
140
  'apiResponse' => $branch,
@@ -283,7 +283,7 @@ if ( !class_exists('Puc_v4p8_Vcs_GitLabApi', false) ):
283
  * Figure out which reference (i.e tag or branch) contains the latest version.
284
  *
285
  * @param string $configBranch Start looking in this branch.
286
- * @return null|Puc_v4p8_Vcs_Reference
287
  */
288
  public function chooseReference($configBranch) {
289
  $updateSource = null;
1
  <?php
2
 
3
+ if ( !class_exists('Puc_v4p9_Vcs_GitLabApi', false) ):
4
 
5
+ class Puc_v4p9_Vcs_GitLabApi extends Puc_v4p9_Vcs_Api {
6
  /**
7
  * @var string GitLab username.
8
  */
91
  /**
92
  * Get the latest release from GitLab.
93
  *
94
+ * @return Puc_v4p9_Vcs_Reference|null
95
  */
96
  public function getLatestRelease() {
97
  return $this->getLatestTag();
100
  /**
101
  * Get the tag that looks like the highest version number.
102
  *
103
+ * @return Puc_v4p9_Vcs_Reference|null
104
  */
105
  public function getLatestTag() {
106
  $tags = $this->api('/:id/repository/tags');
114
  }
115
 
116
  $tag = $versionTags[0];
117
+ return new Puc_v4p9_Vcs_Reference(array(
118
  'name' => $tag->name,
119
  'version' => ltrim($tag->name, 'v'),
120
  'downloadUrl' => $this->buildArchiveDownloadUrl($tag->name),
126
  * Get a branch by name.
127
  *
128
  * @param string $branchName
129
+ * @return null|Puc_v4p9_Vcs_Reference
130
  */
131
  public function getBranch($branchName) {
132
  $branch = $this->api('/:id/repository/branches/' . $branchName);
134
  return null;
135
  }
136
 
137
+ $reference = new Puc_v4p9_Vcs_Reference(array(
138
  'name' => $branch->name,
139
  'downloadUrl' => $this->buildArchiveDownloadUrl($branch->name),
140
  'apiResponse' => $branch,
283
  * Figure out which reference (i.e tag or branch) contains the latest version.
284
  *
285
  * @param string $configBranch Start looking in this branch.
286
+ * @return null|Puc_v4p9_Vcs_Reference
287
  */
288
  public function chooseReference($configBranch) {
289
  $updateSource = null;
lib/plugin-update-checker/Puc/{v4p8 → v4p9}/Vcs/PluginUpdateChecker.php RENAMED
@@ -1,21 +1,21 @@
1
  <?php
2
- if ( !class_exists('Puc_v4p8_Vcs_PluginUpdateChecker') ):
3
 
4
- class Puc_v4p8_Vcs_PluginUpdateChecker extends Puc_v4p8_Plugin_UpdateChecker implements Puc_v4p8_Vcs_BaseChecker {
5
  /**
6
  * @var string The branch where to look for updates. Defaults to "master".
7
  */
8
  protected $branch = 'master';
9
 
10
  /**
11
- * @var Puc_v4p8_Vcs_Api Repository API client.
12
  */
13
  protected $api = null;
14
 
15
  /**
16
- * Puc_v4p8_Vcs_PluginUpdateChecker constructor.
17
  *
18
- * @param Puc_v4p8_Vcs_Api $api
19
  * @param string $pluginFile
20
  * @param string $slug
21
  * @param int $checkPeriod
@@ -41,7 +41,7 @@ if ( !class_exists('Puc_v4p8_Vcs_PluginUpdateChecker') ):
41
  $api = $this->api;
42
  $api->setLocalDirectory($this->package->getAbsoluteDirectoryPath());
43
 
44
- $info = new Puc_v4p8_Plugin_Info();
45
  $info->filename = $this->pluginFile;
46
  $info->slug = $this->slug;
47
 
@@ -124,7 +124,7 @@ if ( !class_exists('Puc_v4p8_Vcs_PluginUpdateChecker') ):
124
  * Copy plugin metadata from a file header to a Plugin Info object.
125
  *
126
  * @param array $fileHeader
127
- * @param Puc_v4p8_Plugin_Info $pluginInfo
128
  */
129
  protected function setInfoFromHeader($fileHeader, $pluginInfo) {
130
  $headerToPropertyMap = array(
@@ -139,6 +139,8 @@ if ( !class_exists('Puc_v4p8_Vcs_PluginUpdateChecker') ):
139
  'Tested WP' => 'tested',
140
  'Requires at least' => 'requires',
141
  'Tested up to' => 'tested',
 
 
142
  );
143
  foreach ($headerToPropertyMap as $headerName => $property) {
144
  if ( isset($fileHeader[$headerName]) && !empty($fileHeader[$headerName]) ) {
@@ -155,7 +157,7 @@ if ( !class_exists('Puc_v4p8_Vcs_PluginUpdateChecker') ):
155
  * Copy plugin metadata from the remote readme.txt file.
156
  *
157
  * @param string $ref GitHub tag or branch where to look for the readme.
158
- * @param Puc_v4p8_Plugin_Info $pluginInfo
159
  */
160
  protected function setInfoFromRemoteReadme($ref, $pluginInfo) {
161
  $readme = $this->api->getRemoteReadme($ref);
@@ -172,6 +174,9 @@ if ( !class_exists('Puc_v4p8_Vcs_PluginUpdateChecker') ):
172
  if ( !empty($readme['requires_at_least']) ) {
173
  $pluginInfo->requires = $readme['requires_at_least'];
174
  }
 
 
 
175
 
176
  if ( isset($readme['upgrade_notice'], $readme['upgrade_notice'][$pluginInfo->version]) ) {
177
  $pluginInfo->upgrade_notice = $readme['upgrade_notice'][$pluginInfo->version];
1
  <?php
2
+ if ( !class_exists('Puc_v4p9_Vcs_PluginUpdateChecker') ):
3
 
4
+ class Puc_v4p9_Vcs_PluginUpdateChecker extends Puc_v4p9_Plugin_UpdateChecker implements Puc_v4p9_Vcs_BaseChecker {
5
  /**
6
  * @var string The branch where to look for updates. Defaults to "master".
7
  */
8
  protected $branch = 'master';
9
 
10
  /**
11
+ * @var Puc_v4p9_Vcs_Api Repository API client.
12
  */
13
  protected $api = null;
14
 
15
  /**
16
+ * Puc_v4p9_Vcs_PluginUpdateChecker constructor.
17
  *
18
+ * @param Puc_v4p9_Vcs_Api $api
19
  * @param string $pluginFile
20
  * @param string $slug
21
  * @param int $checkPeriod
41
  $api = $this->api;
42
  $api->setLocalDirectory($this->package->getAbsoluteDirectoryPath());
43
 
44
+ $info = new Puc_v4p9_Plugin_Info();
45
  $info->filename = $this->pluginFile;
46
  $info->slug = $this->slug;
47
 
124
  * Copy plugin metadata from a file header to a Plugin Info object.
125
  *
126
  * @param array $fileHeader
127
+ * @param Puc_v4p9_Plugin_Info $pluginInfo
128
  */
129
  protected function setInfoFromHeader($fileHeader, $pluginInfo) {
130
  $headerToPropertyMap = array(
139
  'Tested WP' => 'tested',
140
  'Requires at least' => 'requires',
141
  'Tested up to' => 'tested',
142
+
143
+ 'Requires PHP' => 'requires_php',
144
  );
145
  foreach ($headerToPropertyMap as $headerName => $property) {
146
  if ( isset($fileHeader[$headerName]) && !empty($fileHeader[$headerName]) ) {
157
  * Copy plugin metadata from the remote readme.txt file.
158
  *
159
  * @param string $ref GitHub tag or branch where to look for the readme.
160
+ * @param Puc_v4p9_Plugin_Info $pluginInfo
161
  */
162
  protected function setInfoFromRemoteReadme($ref, $pluginInfo) {
163
  $readme = $this->api->getRemoteReadme($ref);
174
  if ( !empty($readme['requires_at_least']) ) {
175
  $pluginInfo->requires = $readme['requires_at_least'];
176
  }
177
+ if ( !empty($readme['requires_php']) ) {
178
+ $pluginInfo->requires_php = $readme['requires_php'];
179
+ }
180
 
181
  if ( isset($readme['upgrade_notice'], $readme['upgrade_notice'][$pluginInfo->version]) ) {
182
  $pluginInfo->upgrade_notice = $readme['upgrade_notice'][$pluginInfo->version];
lib/plugin-update-checker/Puc/{v4p8 → v4p9}/Vcs/Reference.php RENAMED
@@ -1,5 +1,5 @@
1
  <?php
2
- if ( !class_exists('Puc_v4p8_Vcs_Reference', false) ):
3
 
4
  /**
5
  * This class represents a VCS branch or tag. It's intended as a read only, short-lived container
@@ -13,7 +13,7 @@ if ( !class_exists('Puc_v4p8_Vcs_Reference', false) ):
13
  * @property string|null $changelog
14
  * @property int|null $downloadCount
15
  */
16
- class Puc_v4p8_Vcs_Reference {
17
  private $properties = array();
18
 
19
  public function __construct($properties = array()) {
1
  <?php
2
+ if ( !class_exists('Puc_v4p9_Vcs_Reference', false) ):
3
 
4
  /**
5
  * This class represents a VCS branch or tag. It's intended as a read only, short-lived container
13
  * @property string|null $changelog
14
  * @property int|null $downloadCount
15
  */
16
+ class Puc_v4p9_Vcs_Reference {
17
  private $properties = array();
18
 
19
  public function __construct($properties = array()) {
lib/plugin-update-checker/Puc/{v4p8 → v4p9}/Vcs/ThemeUpdateChecker.php RENAMED
@@ -1,22 +1,22 @@
1
  <?php
2
 
3
- if ( !class_exists('Puc_v4p8_Vcs_ThemeUpdateChecker', false) ):
4
 
5
- class Puc_v4p8_Vcs_ThemeUpdateChecker extends Puc_v4p8_Theme_UpdateChecker implements Puc_v4p8_Vcs_BaseChecker {
6
  /**
7
  * @var string The branch where to look for updates. Defaults to "master".
8
  */
9
  protected $branch = 'master';
10
 
11
  /**
12
- * @var Puc_v4p8_Vcs_Api Repository API client.
13
  */
14
  protected $api = null;
15
 
16
  /**
17
- * Puc_v4p8_Vcs_ThemeUpdateChecker constructor.
18
  *
19
- * @param Puc_v4p8_Vcs_Api $api
20
  * @param null $stylesheet
21
  * @param null $customSlug
22
  * @param int $checkPeriod
@@ -35,7 +35,7 @@ if ( !class_exists('Puc_v4p8_Vcs_ThemeUpdateChecker', false) ):
35
  $api = $this->api;
36
  $api->setLocalDirectory($this->package->getAbsoluteDirectoryPath());
37
 
38
- $update = new Puc_v4p8_Theme_Update();
39
  $update->slug = $this->slug;
40
 
41
  //Figure out which reference (tag or branch) we'll use to get the latest version of the theme.
@@ -60,13 +60,13 @@ if ( !class_exists('Puc_v4p8_Vcs_ThemeUpdateChecker', false) ):
60
  //Get headers from the main stylesheet in this branch/tag. Its "Version" header and other metadata
61
  //are what the WordPress install will actually see after upgrading, so they take precedence over releases/tags.
62
  $remoteHeader = $this->package->getFileHeader($api->getRemoteFile('style.css', $ref));
63
- $update->version = Puc_v4p8_Utils::findNotEmpty(array(
64
  $remoteHeader['Version'],
65
- Puc_v4p8_Utils::get($updateSource, 'version'),
66
  ));
67
 
68
  //The details URL defaults to the Theme URI header or the repository URL.
69
- $update->details_url = Puc_v4p8_Utils::findNotEmpty(array(
70
  $remoteHeader['ThemeURI'],
71
  $this->package->getHeaderValue('ThemeURI'),
72
  $this->metadataUrl,
1
  <?php
2
 
3
+ if ( !class_exists('Puc_v4p9_Vcs_ThemeUpdateChecker', false) ):
4
 
5
+ class Puc_v4p9_Vcs_ThemeUpdateChecker extends Puc_v4p9_Theme_UpdateChecker implements Puc_v4p9_Vcs_BaseChecker {
6
  /**
7
  * @var string The branch where to look for updates. Defaults to "master".
8
  */
9
  protected $branch = 'master';
10
 
11
  /**
12
+ * @var Puc_v4p9_Vcs_Api Repository API client.
13
  */
14
  protected $api = null;
15
 
16
  /**
17
+ * Puc_v4p9_Vcs_ThemeUpdateChecker constructor.
18
  *
19
+ * @param Puc_v4p9_Vcs_Api $api
20
  * @param null $stylesheet
21
  * @param null $customSlug
22
  * @param int $checkPeriod
35
  $api = $this->api;
36
  $api->setLocalDirectory($this->package->getAbsoluteDirectoryPath());
37
 
38
+ $update = new Puc_v4p9_Theme_Update();
39
  $update->slug = $this->slug;
40
 
41
  //Figure out which reference (tag or branch) we'll use to get the latest version of the theme.
60
  //Get headers from the main stylesheet in this branch/tag. Its "Version" header and other metadata
61
  //are what the WordPress install will actually see after upgrading, so they take precedence over releases/tags.
62
  $remoteHeader = $this->package->getFileHeader($api->getRemoteFile('style.css', $ref));
63
+ $update->version = Puc_v4p9_Utils::findNotEmpty(array(
64
  $remoteHeader['Version'],
65
+ Puc_v4p9_Utils::get($updateSource, 'version'),
66
  ));
67
 
68
  //The details URL defaults to the Theme URI header or the repository URL.
69
+ $update->details_url = Puc_v4p9_Utils::findNotEmpty(array(
70
  $remoteHeader['ThemeURI'],
71
  $this->package->getHeaderValue('ThemeURI'),
72
  $this->metadataUrl,
lib/plugin-update-checker/README.md CHANGED
@@ -28,6 +28,8 @@ From the users' perspective, it works just like with plugins and themes hosted o
28
  Getting Started
29
  ---------------
30
 
 
 
31
  ### Self-hosted Plugins and Themes
32
 
33
  1. Download [the latest release](https://github.com/YahnisElsts/plugin-update-checker/releases/latest) and copy the `plugin-update-checker` directory to your plugin or theme.
@@ -244,8 +246,8 @@ BitBucket doesn't have an equivalent to GitHub's releases, so the process is sli
244
 
245
  Alternatively, if you're using a self-hosted GitLab instance, initialize the update checker like this:
246
  ```php
247
- $myUpdateChecker = new Puc_v4p8_Vcs_PluginUpdateChecker(
248
- new Puc_v4p8_Vcs_GitLabApi('https://myserver.com/user-name/repo-name/'),
249
  __FILE__,
250
  'unique-plugin-or-theme-slug'
251
  );
@@ -253,8 +255,8 @@ BitBucket doesn't have an equivalent to GitHub's releases, so the process is sli
253
  ```
254
  If you're using a self-hosted GitLab instance and [subgroups or nested groups](https://docs.gitlab.com/ce/user/group/subgroups/index.html), you have to tell the update checker which parts of the URL are subgroups:
255
  ```php
256
- $myUpdateChecker = new Puc_v4p8_Vcs_PluginUpdateChecker(
257
- new Puc_v4p8_Vcs_GitLabApi('https://myserver.com/group-name/subgroup-level1/subgroup-level2/subgroup-level3/repo-name/', null, 'subgroup-level1/subgroup-level2/subgroup-level3'),
258
  __FILE__,
259
  'unique-plugin-or-theme-slug'
260
  );
28
  Getting Started
29
  ---------------
30
 
31
+ *Note:* In each of the below examples, part of the instructions are to create an instance of the update checker class. It's recommended to do this either during the `plugins_loaded` action or outside of any hooks. If you do it only during an `admin_*` action, then updates will not be visible to a wide variety of WordPress maanagement tools; they will only be visible to logged-in users on dashboard pages.
32
+
33
  ### Self-hosted Plugins and Themes
34
 
35
  1. Download [the latest release](https://github.com/YahnisElsts/plugin-update-checker/releases/latest) and copy the `plugin-update-checker` directory to your plugin or theme.
246
 
247
  Alternatively, if you're using a self-hosted GitLab instance, initialize the update checker like this:
248
  ```php
249
+ $myUpdateChecker = new Puc_v4p9_Vcs_PluginUpdateChecker(
250
+ new Puc_v4p9_Vcs_GitLabApi('https://myserver.com/user-name/repo-name/'),
251
  __FILE__,
252
  'unique-plugin-or-theme-slug'
253
  );
255
  ```
256
  If you're using a self-hosted GitLab instance and [subgroups or nested groups](https://docs.gitlab.com/ce/user/group/subgroups/index.html), you have to tell the update checker which parts of the URL are subgroups:
257
  ```php
258
+ $myUpdateChecker = new Puc_v4p9_Vcs_PluginUpdateChecker(
259
+ new Puc_v4p9_Vcs_GitLabApi('https://myserver.com/group-name/subgroup-level1/subgroup-level2/subgroup-level3/repo-name/', null, 'subgroup-level1/subgroup-level2/subgroup-level3'),
260
  __FILE__,
261
  'unique-plugin-or-theme-slug'
262
  );
lib/plugin-update-checker/composer.json CHANGED
@@ -14,9 +14,10 @@
14
  }
15
  ],
16
  "require": {
17
- "php": ">=5.2.0"
 
18
  },
19
  "autoload": {
20
- "files": ["load-v4p8.php"]
21
  }
22
  }
14
  }
15
  ],
16
  "require": {
17
+ "php": ">=5.2.0",
18
+ "ext-json": "*"
19
  },
20
  "autoload": {
21
+ "files": ["load-v4p9.php"]
22
  }
23
  }
lib/plugin-update-checker/examples/plugin.json CHANGED
@@ -1,52 +1,52 @@
1
- {
2
- "name": "My Example Plugin",
3
- "version": "2.0",
4
- "download_url": "http://example.com/updates/example-plugin.zip",
5
-
6
- "homepage": "http://example.com/",
7
- "requires": "4.5",
8
- "tested": "4.8",
9
- "last_updated": "2017-01-01 16:17:00",
10
- "upgrade_notice": "Here's why you should upgrade...",
11
-
12
- "author": "Janis Elsts",
13
- "author_homepage": "http://example.com/",
14
-
15
- "sections": {
16
- "description": "(Required) Plugin description. Basic HTML can be used in all sections.",
17
- "installation": "(Recommended) Installation instructions.",
18
- "changelog": "(Recommended) Changelog. <p>This section will be displayed by default when the user clicks 'View version x.y.z details'.</p>",
19
- "custom_section": "This is a custom section labeled 'Custom Section'."
20
- },
21
-
22
- "icons" : {
23
- "1x" : "http://w-shadow.com/files/external-update-example/assets/icon-128x128.png",
24
- "2x" : "http://w-shadow.com/files/external-update-example/assets/icon-256x256.png"
25
- },
26
-
27
- "banners": {
28
- "low": "http://w-shadow.com/files/external-update-example/assets/banner-772x250.png",
29
- "high": "http://w-shadow.com/files/external-update-example/assets/banner-1544x500.png"
30
- },
31
-
32
- "translations": [
33
- {
34
- "language": "fr_FR",
35
- "version": "4.0",
36
- "updated": "2016-04-22 23:22:42",
37
- "package": "http://example.com/updates/translations/french-language-pack.zip"
38
- },
39
- {
40
- "language": "de_DE",
41
- "version": "5.0",
42
- "updated": "2016-04-22 23:22:42",
43
- "package": "http://example.com/updates/translations/german-language-pack.zip"
44
- }
45
- ],
46
-
47
- "rating": 90,
48
- "num_ratings": 123,
49
-
50
- "downloaded": 1234,
51
- "active_installs": 12345
52
  }
1
+ {
2
+ "name": "My Example Plugin",
3
+ "version": "2.0",
4
+ "download_url": "http://example.com/updates/example-plugin.zip",
5
+
6
+ "homepage": "http://example.com/",
7
+ "requires": "4.5",
8
+ "tested": "4.8",
9
+ "last_updated": "2017-01-01 16:17:00",
10
+ "upgrade_notice": "Here's why you should upgrade...",
11
+
12
+ "author": "Janis Elsts",
13
+ "author_homepage": "http://example.com/",
14
+
15
+ "sections": {
16
+ "description": "(Required) Plugin description. Basic HTML can be used in all sections.",
17
+ "installation": "(Recommended) Installation instructions.",
18
+ "changelog": "(Recommended) Changelog. <p>This section will be displayed by default when the user clicks 'View version x.y.z details'.</p>",
19
+ "custom_section": "This is a custom section labeled 'Custom Section'."
20
+ },
21
+
22
+ "icons" : {
23
+ "1x" : "http://w-shadow.com/files/external-update-example/assets/icon-128x128.png",
24
+ "2x" : "http://w-shadow.com/files/external-update-example/assets/icon-256x256.png"
25
+ },
26
+
27
+ "banners": {
28
+ "low": "http://w-shadow.com/files/external-update-example/assets/banner-772x250.png",
29
+ "high": "http://w-shadow.com/files/external-update-example/assets/banner-1544x500.png"
30
+ },
31
+
32
+ "translations": [
33
+ {
34
+ "language": "fr_FR",
35
+ "version": "4.0",
36
+ "updated": "2016-04-22 23:22:42",
37
+ "package": "http://example.com/updates/translations/french-language-pack.zip"
38
+ },
39
+ {
40
+ "language": "de_DE",
41
+ "version": "5.0",
42
+ "updated": "2016-04-22 23:22:42",
43
+ "package": "http://example.com/updates/translations/german-language-pack.zip"
44
+ }
45
+ ],
46
+
47
+ "rating": 90,
48
+ "num_ratings": 123,
49
+
50
+ "downloaded": 1234,
51
+ "active_installs": 12345
52
  }
lib/plugin-update-checker/examples/theme.json CHANGED
@@ -1,5 +1,5 @@
1
- {
2
- "version": "2.0",
3
- "details_url": "http://example.com/version-2.0-details.html",
4
- "download_url": "http://example.com/example-theme-2.0.zip"
5
  }
1
+ {
2
+ "version": "2.0",
3
+ "details_url": "http://example.com/version-2.0-details.html",
4
+ "download_url": "http://example.com/example-theme-2.0.zip"
5
  }
lib/plugin-update-checker/languages/plugin-update-checker-cs_CZ.po CHANGED
@@ -1,45 +1,45 @@
1
- msgid ""
2
- msgstr ""
3
- "Project-Id-Version: plugin-update-checker\n"
4
- "Report-Msgid-Bugs-To: \n"
5
- "POT-Creation-Date: 2017-05-20 10:53+0300\n"
6
- "PO-Revision-Date: 2017-07-05 15:39+0000\n"
7
- "Last-Translator: Vojtěch Sajdl <vojtech@sajdl.com>\n"
8
- "Language-Team: Czech (Czech Republic)\n"
9
- "Language: cs-CZ\n"
10
- "Plural-Forms: nplurals=2; plural=(n != 1)\n"
11
- "MIME-Version: 1.0\n"
12
- "Content-Type: text/plain; charset=UTF-8\n"
13
- "Content-Transfer-Encoding: 8bit\n"
14
- "X-Loco-Source-Locale: cs_CZ\n"
15
- "X-Generator: Loco - https://localise.biz/\n"
16
- "X-Poedit-Basepath: ..\n"
17
- "X-Poedit-SourceCharset: UTF-8\n"
18
- "X-Poedit-KeywordsList: __;_e;_x:1,2c;_x\n"
19
- "X-Poedit-SearchPath-0: .\n"
20
- "X-Loco-Parser: loco_parse_po"
21
-
22
- #: Puc/v4p1/Plugin/UpdateChecker.php:358
23
- msgid "Check for updates"
24
- msgstr "Zkontrolovat aktualizace"
25
-
26
- #: Puc/v4p1/Plugin/UpdateChecker.php:405
27
- #, php-format
28
- msgctxt "the plugin title"
29
- msgid "The %s plugin is up to date."
30
- msgstr "Plugin %s je aktuální."
31
-
32
- #: Puc/v4p1/Plugin/UpdateChecker.php:407
33
- #, php-format
34
- msgctxt "the plugin title"
35
- msgid "A new version of the %s plugin is available."
36
- msgstr "Nová verze pluginu %s je dostupná."
37
-
38
- #: Puc/v4p1/Plugin/UpdateChecker.php:409
39
- #, php-format
40
- msgid "Unknown update checker status \"%s\""
41
- msgstr "Neznámý status kontroly aktualizací \"%s\""
42
-
43
- #: Puc/v4p1/Vcs/PluginUpdateChecker.php:83
44
- msgid "There is no changelog available."
45
- msgstr "Changelog není dostupný."
1
+ msgid ""
2
+ msgstr ""
3
+ "Project-Id-Version: plugin-update-checker\n"
4
+ "Report-Msgid-Bugs-To: \n"
5
+ "POT-Creation-Date: 2017-05-20 10:53+0300\n"
6
+ "PO-Revision-Date: 2017-07-05 15:39+0000\n"
7
+ "Last-Translator: Vojtěch Sajdl <vojtech@sajdl.com>\n"
8
+ "Language-Team: Czech (Czech Republic)\n"
9
+ "Language: cs-CZ\n"
10
+ "Plural-Forms: nplurals=2; plural=(n != 1)\n"
11
+ "MIME-Version: 1.0\n"
12
+ "Content-Type: text/plain; charset=UTF-8\n"
13
+ "Content-Transfer-Encoding: 8bit\n"
14
+ "X-Loco-Source-Locale: cs_CZ\n"
15
+ "X-Generator: Loco - https://localise.biz/\n"
16
+ "X-Poedit-Basepath: ..\n"
17
+ "X-Poedit-SourceCharset: UTF-8\n"
18
+ "X-Poedit-KeywordsList: __;_e;_x:1,2c;_x\n"
19
+ "X-Poedit-SearchPath-0: .\n"
20
+ "X-Loco-Parser: loco_parse_po"
21
+
22
+ #: Puc/v4p1/Plugin/UpdateChecker.php:358
23
+ msgid "Check for updates"
24
+ msgstr "Zkontrolovat aktualizace"
25
+
26
+ #: Puc/v4p1/Plugin/UpdateChecker.php:405
27
+ #, php-format
28
+ msgctxt "the plugin title"
29
+ msgid "The %s plugin is up to date."
30
+ msgstr "Plugin %s je aktuální."
31
+
32
+ #: Puc/v4p1/Plugin/UpdateChecker.php:407
33
+ #, php-format
34
+ msgctxt "the plugin title"
35
+ msgid "A new version of the %s plugin is available."
36
+ msgstr "Nová verze pluginu %s je dostupná."
37
+
38
+ #: Puc/v4p1/Plugin/UpdateChecker.php:409
39
+ #, php-format
40
+ msgid "Unknown update checker status \"%s\""
41
+ msgstr "Neznámý status kontroly aktualizací \"%s\""
42
+
43
+ #: Puc/v4p1/Vcs/PluginUpdateChecker.php:83
44
+ msgid "There is no changelog available."
45
+ msgstr "Changelog není dostupný."
lib/plugin-update-checker/languages/plugin-update-checker-es_AR.mo ADDED
Binary file
lib/plugin-update-checker/languages/plugin-update-checker-es_AR.po ADDED
@@ -0,0 +1,48 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ msgid ""
2
+ msgstr ""
3
+ "Project-Id-Version: plugin-update-checker\n"
4
+ "POT-Creation-Date: 2017-11-24 17:02+0200\n"
5
+ "PO-Revision-Date: 2020-03-21 15:13-0400\n"
6
+ "Language-Team: \n"
7
+ "MIME-Version: 1.0\n"
8
+ "Content-Type: text/plain; charset=UTF-8\n"
9
+ "Content-Transfer-Encoding: 8bit\n"
10
+ "X-Generator: Poedit 2.3\n"
11
+ "X-Poedit-Basepath: ..\n"
12
+ "Plural-Forms: nplurals=2; plural=(n != 1);\n"
13
+ "X-Poedit-SourceCharset: UTF-8\n"
14
+ "X-Poedit-KeywordsList: __;_e;_x:1,2c;_x\n"
15
+ "Last-Translator: \n"
16
+ "Language: es_ES\n"
17
+ "X-Poedit-SearchPath-0: .\n"
18
+
19
+ #: Puc/v4p3/Plugin/UpdateChecker.php:395
20
+ msgid "Check for updates"
21
+ msgstr "Comprobar si hay actualizaciones"
22
+
23
+ #: Puc/v4p3/Plugin/UpdateChecker.php:548
24
+ #, php-format
25
+ msgctxt "the plugin title"
26
+ msgid "The %s plugin is up to date."
27
+ msgstr "El plugin %s está actualizado."
28
+
29
+ #: Puc/v4p3/Plugin/UpdateChecker.php:550
30
+ #, php-format
31
+ msgctxt "the plugin title"
32
+ msgid "A new version of the %s plugin is available."
33
+ msgstr "Una nueva versión del %s plugin está disponible."
34
+
35
+ #: Puc/v4p3/Plugin/UpdateChecker.php:552
36
+ #, php-format
37
+ msgctxt "the plugin title"
38
+ msgid "Could not determine if updates are available for %s."
39
+ msgstr "No se pudo determinar si hay actualizaciones disponibles para %s."
40
+
41
+ #: Puc/v4p3/Plugin/UpdateChecker.php:558
42
+ #, php-format
43
+ msgid "Unknown update checker status \"%s\""
44
+ msgstr "Estado del comprobador de actualización desconocido «%s»"
45
+
46
+ #: Puc/v4p3/Vcs/PluginUpdateChecker.php:95
47
+ msgid "There is no changelog available."
48
+ msgstr "No hay un registro de cambios disponible."
lib/plugin-update-checker/languages/plugin-update-checker-es_CL.mo ADDED
Binary file
lib/plugin-update-checker/languages/plugin-update-checker-es_CL.po ADDED
@@ -0,0 +1,48 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ msgid ""
2
+ msgstr ""
3
+ "Project-Id-Version: plugin-update-checker\n"
4
+ "POT-Creation-Date: 2017-11-24 17:02+0200\n"
5
+ "PO-Revision-Date: 2020-03-21 15:14-0400\n"
6
+ "Language-Team: \n"
7
+ "MIME-Version: 1.0\n"
8
+ "Content-Type: text/plain; charset=UTF-8\n"
9
+ "Content-Transfer-Encoding: 8bit\n"
10
+ "X-Generator: Poedit 2.3\n"
11
+ "X-Poedit-Basepath: ..\n"
12
+ "Plural-Forms: nplurals=2; plural=(n != 1);\n"
13
+ "X-Poedit-SourceCharset: UTF-8\n"
14
+ "X-Poedit-KeywordsList: __;_e;_x:1,2c;_x\n"
15
+ "Last-Translator: \n"
16
+ "Language: es_ES\n"
17
+ "X-Poedit-SearchPath-0: .\n"
18
+
19
+ #: Puc/v4p3/Plugin/UpdateChecker.php:395
20
+ msgid "Check for updates"
21
+ msgstr "Comprobar si hay actualizaciones"
22
+
23
+ #: Puc/v4p3/Plugin/UpdateChecker.php:548
24
+ #, php-format
25
+ msgctxt "the plugin title"
26
+ msgid "The %s plugin is up to date."
27
+ msgstr "El plugin %s está actualizado."
28
+
29
+ #: Puc/v4p3/Plugin/UpdateChecker.php:550
30
+ #, php-format
31
+ msgctxt "the plugin title"
32
+ msgid "A new version of the %s plugin is available."
33
+ msgstr "Una nueva versión del %s plugin está disponible."
34
+
35
+ #: Puc/v4p3/Plugin/UpdateChecker.php:552
36
+ #, php-format
37
+ msgctxt "the plugin title"
38
+ msgid "Could not determine if updates are available for %s."
39
+ msgstr "No se pudo determinar si hay actualizaciones disponibles para %s."
40
+
41
+ #: Puc/v4p3/Plugin/UpdateChecker.php:558
42
+ #, php-format
43
+ msgid "Unknown update checker status \"%s\""
44
+ msgstr "Estado del comprobador de actualización desconocido «%s»"
45
+
46
+ #: Puc/v4p3/Vcs/PluginUpdateChecker.php:95
47
+ msgid "There is no changelog available."
48
+ msgstr "No hay un registro de cambios disponible."
lib/plugin-update-checker/languages/plugin-update-checker-es_CO.mo ADDED
Binary file
lib/plugin-update-checker/languages/plugin-update-checker-es_CO.po ADDED
@@ -0,0 +1,48 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ msgid ""
2
+ msgstr ""
3
+ "Project-Id-Version: plugin-update-checker\n"
4
+ "POT-Creation-Date: 2017-11-24 17:02+0200\n"
5
+ "PO-Revision-Date: 2020-03-21 15:14-0400\n"
6
+ "Language-Team: \n"
7
+ "MIME-Version: 1.0\n"
8
+ "Content-Type: text/plain; charset=UTF-8\n"
9
+ "Content-Transfer-Encoding: 8bit\n"
10
+ "X-Generator: Poedit 2.3\n"
11
+ "X-Poedit-Basepath: ..\n"
12
+ "Plural-Forms: nplurals=2; plural=(n != 1);\n"
13
+ "X-Poedit-SourceCharset: UTF-8\n"
14
+ "X-Poedit-KeywordsList: __;_e;_x:1,2c;_x\n"
15
+ "Last-Translator: \n"
16
+ "Language: es_ES\n"
17
+ "X-Poedit-SearchPath-0: .\n"
18
+
19
+ #: Puc/v4p3/Plugin/UpdateChecker.php:395
20
+ msgid "Check for updates"
21
+ msgstr "Comprobar si hay actualizaciones"
22
+
23
+ #: Puc/v4p3/Plugin/UpdateChecker.php:548
24
+ #, php-format
25
+ msgctxt "the plugin title"
26
+ msgid "The %s plugin is up to date."
27
+ msgstr "El plugin %s está actualizado."
28
+
29
+ #: Puc/v4p3/Plugin/UpdateChecker.php:550
30
+ #, php-format
31
+ msgctxt "the plugin title"
32
+ msgid "A new version of the %s plugin is available."
33
+ msgstr "Una nueva versión del %s plugin está disponible."
34
+
35
+ #: Puc/v4p3/Plugin/UpdateChecker.php:552
36
+ #, php-format
37
+ msgctxt "the plugin title"
38
+ msgid "Could not determine if updates are available for %s."
39
+ msgstr "No se pudo determinar si hay actualizaciones disponibles para %s."
40
+
41
+ #: Puc/v4p3/Plugin/UpdateChecker.php:558
42
+ #, php-format
43
+ msgid "Unknown update checker status \"%s\""
44
+ msgstr "Estado del comprobador de actualización desconocido «%s»"
45
+
46
+ #: Puc/v4p3/Vcs/PluginUpdateChecker.php:95
47
+ msgid "There is no changelog available."
48
+ msgstr "No hay un registro de cambios disponible."
lib/plugin-update-checker/languages/plugin-update-checker-es_CR.mo ADDED
Binary file
lib/plugin-update-checker/languages/plugin-update-checker-es_CR.po ADDED
@@ -0,0 +1,48 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ msgid ""
2
+ msgstr ""
3
+ "Project-Id-Version: plugin-update-checker\n"
4
+ "POT-Creation-Date: 2017-11-24 17:02+0200\n"
5
+ "PO-Revision-Date: 2020-03-21 15:14-0400\n"
6
+ "Language-Team: \n"
7
+ "MIME-Version: 1.0\n"
8
+ "Content-Type: text/plain; charset=UTF-8\n"
9
+ "Content-Transfer-Encoding: 8bit\n"
10
+ "X-Generator: Poedit 2.3\n"
11
+ "X-Poedit-Basepath: ..\n"
12
+ "Plural-Forms: nplurals=2; plural=(n != 1);\n"
13
+ "X-Poedit-SourceCharset: UTF-8\n"
14
+ "X-Poedit-KeywordsList: __;_e;_x:1,2c;_x\n"
15
+ "Last-Translator: \n"
16
+ "Language: es_ES\n"
17
+ "X-Poedit-SearchPath-0: .\n"
18
+
19
+ #: Puc/v4p3/Plugin/UpdateChecker.php:395
20
+ msgid "Check for updates"
21
+ msgstr "Comprobar si hay actualizaciones"
22
+
23
+ #: Puc/v4p3/Plugin/UpdateChecker.php:548
24
+ #, php-format
25
+ msgctxt "the plugin title"
26
+ msgid "The %s plugin is up to date."
27
+ msgstr "El plugin %s está actualizado."
28
+
29
+ #: Puc/v4p3/Plugin/UpdateChecker.php:550
30
+ #, php-format
31
+ msgctxt "the plugin title"
32
+ msgid "A new version of the %s plugin is available."
33
+ msgstr "Una nueva versión del %s plugin está disponible."
34
+
35
+ #: Puc/v4p3/Plugin/UpdateChecker.php:552
36
+ #, php-format
37
+ msgctxt "the plugin title"
38
+ msgid "Could not determine if updates are available for %s."
39
+ msgstr "No se pudo determinar si hay actualizaciones disponibles para %s."
40
+
41
+ #: Puc/v4p3/Plugin/UpdateChecker.php:558
42
+ #, php-format
43
+ msgid "Unknown update checker status \"%s\""
44
+ msgstr "Estado del comprobador de actualización desconocido «%s»"
45
+
46
+ #: Puc/v4p3/Vcs/PluginUpdateChecker.php:95
47
+ msgid "There is no changelog available."
48
+ msgstr "No hay un registro de cambios disponible."
lib/plugin-update-checker/languages/plugin-update-checker-es_DO.mo ADDED
Binary file
lib/plugin-update-checker/languages/plugin-update-checker-es_DO.po ADDED
@@ -0,0 +1,48 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ msgid ""
2
+ msgstr ""
3
+ "Project-Id-Version: plugin-update-checker\n"
4
+ "POT-Creation-Date: 2017-11-24 17:02+0200\n"
5
+ "PO-Revision-Date: 2020-03-21 15:14-0400\n"
6
+ "Language-Team: \n"
7
+ "MIME-Version: 1.0\n"
8
+ "Content-Type: text/plain; charset=UTF-8\n"
9
+ "Content-Transfer-Encoding: 8bit\n"
10
+ "X-Generator: Poedit 2.3\n"
11
+ "X-Poedit-Basepath: ..\n"
12
+ "Plural-Forms: nplurals=2; plural=(n != 1);\n"
13
+ "X-Poedit-SourceCharset: UTF-8\n"
14
+ "X-Poedit-KeywordsList: __;_e;_x:1,2c;_x\n"
15
+ "Last-Translator: \n"
16
+ "Language: es_ES\n"
17
+ "X-Poedit-SearchPath-0: .\n"
18
+
19
+ #: Puc/v4p3/Plugin/UpdateChecker.php:395
20
+ msgid "Check for updates"
21
+ msgstr "Comprobar si hay actualizaciones"
22
+
23
+ #: Puc/v4p3/Plugin/UpdateChecker.php:548
24
+ #, php-format
25
+ msgctxt "the plugin title"
26
+ msgid "The %s plugin is up to date."
27
+ msgstr "El plugin %s está actualizado."
28
+
29
+ #: Puc/v4p3/Plugin/UpdateChecker.php:550
30
+ #, php-format
31
+ msgctxt "the plugin title"
32
+ msgid "A new version of the %s plugin is available."
33
+ msgstr "Una nueva versión del %s plugin está disponible."
34
+
35
+ #: Puc/v4p3/Plugin/UpdateChecker.php:552
36
+ #, php-format
37
+ msgctxt "the plugin title"
38
+ msgid "Could not determine if updates are available for %s."
39
+ msgstr "No se pudo determinar si hay actualizaciones disponibles para %s."
40
+
41
+ #: Puc/v4p3/Plugin/UpdateChecker.php:558
42
+ #, php-format
43
+ msgid "Unknown update checker status \"%s\""
44
+ msgstr "Estado del comprobador de actualización desconocido «%s»"
45
+
46
+ #: Puc/v4p3/Vcs/PluginUpdateChecker.php:95
47
+ msgid "There is no changelog available."
48
+ msgstr "No hay un registro de cambios disponible."
lib/plugin-update-checker/languages/plugin-update-checker-es_ES.mo CHANGED
Binary file
lib/plugin-update-checker/languages/plugin-update-checker-es_ES.po CHANGED
@@ -2,12 +2,12 @@ msgid ""
2
  msgstr ""
3
  "Project-Id-Version: plugin-update-checker\n"
4
  "POT-Creation-Date: 2017-11-24 17:02+0200\n"
5
- "PO-Revision-Date: 2019-09-25 18:17+0200\n"
6
  "Language-Team: \n"
7
  "MIME-Version: 1.0\n"
8
  "Content-Type: text/plain; charset=UTF-8\n"
9
  "Content-Transfer-Encoding: 8bit\n"
10
- "X-Generator: Poedit 2.2.3\n"
11
  "X-Poedit-Basepath: ..\n"
12
  "Plural-Forms: nplurals=2; plural=(n != 1);\n"
13
  "X-Poedit-SourceCharset: UTF-8\n"
@@ -41,8 +41,8 @@ msgstr "No se pudo determinar si hay actualizaciones disponibles para %s."
41
  #: Puc/v4p3/Plugin/UpdateChecker.php:558
42
  #, php-format
43
  msgid "Unknown update checker status \"%s\""
44
- msgstr "Estado del comprobador de actualización desconocido \"%s\""
45
 
46
  #: Puc/v4p3/Vcs/PluginUpdateChecker.php:95
47
  msgid "There is no changelog available."
48
- msgstr "No hay registro de cambios disponible."
2
  msgstr ""
3
  "Project-Id-Version: plugin-update-checker\n"
4
  "POT-Creation-Date: 2017-11-24 17:02+0200\n"
5
+ "PO-Revision-Date: 2020-03-21 14:56-0400\n"
6
  "Language-Team: \n"
7
  "MIME-Version: 1.0\n"
8
  "Content-Type: text/plain; charset=UTF-8\n"
9
  "Content-Transfer-Encoding: 8bit\n"
10
+ "X-Generator: Poedit 2.3\n"
11
  "X-Poedit-Basepath: ..\n"
12
  "Plural-Forms: nplurals=2; plural=(n != 1);\n"
13
  "X-Poedit-SourceCharset: UTF-8\n"
41
  #: Puc/v4p3/Plugin/UpdateChecker.php:558
42
  #, php-format
43
  msgid "Unknown update checker status \"%s\""
44
+ msgstr "Estado del comprobador de actualización desconocido «%s»"
45
 
46
  #: Puc/v4p3/Vcs/PluginUpdateChecker.php:95
47
  msgid "There is no changelog available."
48
+ msgstr "No hay un registro de cambios disponible."
lib/plugin-update-checker/languages/plugin-update-checker-es_GT.mo ADDED
Binary file
lib/plugin-update-checker/languages/plugin-update-checker-es_GT.po ADDED
@@ -0,0 +1,48 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ msgid ""
2
+ msgstr ""
3
+ "Project-Id-Version: plugin-update-checker\n"
4
+ "POT-Creation-Date: 2017-11-24 17:02+0200\n"
5
+ "PO-Revision-Date: 2020-03-21 15:14-0400\n"
6
+ "Language-Team: \n"
7
+ "MIME-Version: 1.0\n"
8
+ "Content-Type: text/plain; charset=UTF-8\n"
9
+ "Content-Transfer-Encoding: 8bit\n"
10
+ "X-Generator: Poedit 2.3\n"
11
+ "X-Poedit-Basepath: ..\n"
12
+ "Plural-Forms: nplurals=2; plural=(n != 1);\n"
13
+ "X-Poedit-SourceCharset: UTF-8\n"
14
+ "X-Poedit-KeywordsList: __;_e;_x:1,2c;_x\n"
15
+ "Last-Translator: \n"
16
+ "Language: es_ES\n"
17
+ "X-Poedit-SearchPath-0: .\n"
18
+
19
+ #: Puc/v4p3/Plugin/UpdateChecker.php:395
20
+ msgid "Check for updates"
21
+ msgstr "Comprobar si hay actualizaciones"
22
+
23
+ #: Puc/v4p3/Plugin/UpdateChecker.php:548
24
+ #, php-format
25
+ msgctxt "the plugin title"
26
+ msgid "The %s plugin is up to date."
27
+ msgstr "El plugin %s está actualizado."
28
+
29
+ #: Puc/v4p3/Plugin/UpdateChecker.php:550
30
+ #, php-format
31
+ msgctxt "the plugin title"
32
+ msgid "A new version of the %s plugin is available."
33
+ msgstr "Una nueva versión del %s plugin está disponible."
34
+
35
+ #: Puc/v4p3/Plugin/UpdateChecker.php:552
36
+ #, php-format
37
+ msgctxt "the plugin title"
38
+ msgid "Could not determine if updates are available for %s."
39
+ msgstr "No se pudo determinar si hay actualizaciones disponibles para %s."
40
+
41
+ #: Puc/v4p3/Plugin/UpdateChecker.php:558
42
+ #, php-format
43
+ msgid "Unknown update checker status \"%s\""
44
+ msgstr "Estado del comprobador de actualización desconocido «%s»"
45
+
46
+ #: Puc/v4p3/Vcs/PluginUpdateChecker.php:95
47
+ msgid "There is no changelog available."
48
+ msgstr "No hay un registro de cambios disponible."
lib/plugin-update-checker/languages/plugin-update-checker-es_HN.mo ADDED
Binary file
lib/plugin-update-checker/languages/plugin-update-checker-es_HN.po ADDED
@@ -0,0 +1,48 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ msgid ""
2
+ msgstr ""
3
+ "Project-Id-Version: plugin-update-checker\n"
4
+ "POT-Creation-Date: 2017-11-24 17:02+0200\n"
5
+ "PO-Revision-Date: 2020-03-21 15:14-0400\n"
6
+ "Language-Team: \n"
7
+ "MIME-Version: 1.0\n"
8
+ "Content-Type: text/plain; charset=UTF-8\n"
9
+ "Content-Transfer-Encoding: 8bit\n"
10
+ "X-Generator: Poedit 2.3\n"
11
+ "X-Poedit-Basepath: ..\n"
12
+ "Plural-Forms: nplurals=2; plural=(n != 1);\n"
13
+ "X-Poedit-SourceCharset: UTF-8\n"
14
+ "X-Poedit-KeywordsList: __;_e;_x:1,2c;_x\n"
15
+ "Last-Translator: \n"
16
+ "Language: es_ES\n"
17
+ "X-Poedit-SearchPath-0: .\n"
18
+
19
+ #: Puc/v4p3/Plugin/UpdateChecker.php:395
20
+ msgid "Check for updates"
21
+ msgstr "Comprobar si hay actualizaciones"
22
+
23
+ #: Puc/v4p3/Plugin/UpdateChecker.php:548
24
+ #, php-format
25
+ msgctxt "the plugin title"
26
+ msgid "The %s plugin is up to date."
27
+ msgstr "El plugin %s está actualizado."
28
+
29
+ #: Puc/v4p3/Plugin/UpdateChecker.php:550
30
+ #, php-format
31
+ msgctxt "the plugin title"
32
+ msgid "A new version of the %s plugin is available."
33
+ msgstr "Una nueva versión del %s plugin está disponible."
34
+
35
+ #: Puc/v4p3/Plugin/UpdateChecker.php:552
36
+ #, php-format
37
+ msgctxt "the plugin title"
38
+ msgid "Could not determine if updates are available for %s."
39
+ msgstr "No se pudo determinar si hay actualizaciones disponibles para %s."
40
+
41
+ #: Puc/v4p3/Plugin/UpdateChecker.php:558
42
+ #, php-format
43
+ msgid "Unknown update checker status \"%s\""
44
+ msgstr "Estado del comprobador de actualización desconocido «%s»"
45
+
46
+ #: Puc/v4p3/Vcs/PluginUpdateChecker.php:95
47
+ msgid "There is no changelog available."
48
+ msgstr "No hay un registro de cambios disponible."
lib/plugin-update-checker/languages/plugin-update-checker-es_MX.mo ADDED
Binary file
lib/plugin-update-checker/languages/plugin-update-checker-es_MX.po ADDED
@@ -0,0 +1,48 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ msgid ""
2
+ msgstr ""
3
+ "Project-Id-Version: plugin-update-checker\n"
4
+ "POT-Creation-Date: 2017-11-24 17:02+0200\n"
5
+ "PO-Revision-Date: 2020-03-21 14:57-0400\n"
6
+ "Language-Team: \n"
7
+ "MIME-Version: 1.0\n"
8
+ "Content-Type: text/plain; charset=UTF-8\n"
9
+ "Content-Transfer-Encoding: 8bit\n"
10
+ "X-Generator: Poedit 2.3\n"
11
+ "X-Poedit-Basepath: ..\n"
12
+ "Plural-Forms: nplurals=2; plural=(n != 1);\n"
13
+ "X-Poedit-SourceCharset: UTF-8\n"
14
+ "X-Poedit-KeywordsList: __;_e;_x:1,2c;_x\n"
15
+ "Last-Translator: \n"
16
+ "Language: es_ES\n"
17
+ "X-Poedit-SearchPath-0: .\n"
18
+
19
+ #: Puc/v4p3/Plugin/UpdateChecker.php:395
20
+ msgid "Check for updates"
21
+ msgstr "Comprobar si hay actualizaciones"
22
+
23
+ #: Puc/v4p3/Plugin/UpdateChecker.php:548
24
+ #, php-format
25
+ msgctxt "the plugin title"
26
+ msgid "The %s plugin is up to date."
27
+ msgstr "El plugin %s está actualizado."
28
+
29
+ #: Puc/v4p3/Plugin/UpdateChecker.php:550
30
+ #, php-format
31
+ msgctxt "the plugin title"
32
+ msgid "A new version of the %s plugin is available."
33
+ msgstr "Una nueva versión del %s plugin está disponible."
34
+
35
+ #: Puc/v4p3/Plugin/UpdateChecker.php:552
36
+ #, php-format
37
+ msgctxt "the plugin title"
38
+ msgid "Could not determine if updates are available for %s."
39
+ msgstr "No se pudo determinar si hay actualizaciones disponibles para %s."
40
+
41
+ #: Puc/v4p3/Plugin/UpdateChecker.php:558
42
+ #, php-format
43
+ msgid "Unknown update checker status \"%s\""
44
+ msgstr "Estado del comprobador de actualización desconocido «%s»"
45
+
46
+ #: Puc/v4p3/Vcs/PluginUpdateChecker.php:95
47
+ msgid "There is no changelog available."
48
+ msgstr "No hay un registro de cambios disponible."
lib/plugin-update-checker/languages/plugin-update-checker-es_PE.mo ADDED
Binary file
lib/plugin-update-checker/languages/plugin-update-checker-es_PE.po ADDED
@@ -0,0 +1,48 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ msgid ""
2
+ msgstr ""
3
+ "Project-Id-Version: plugin-update-checker\n"
4
+ "POT-Creation-Date: 2017-11-24 17:02+0200\n"
5
+ "PO-Revision-Date: 2020-03-21 15:15-0400\n"
6
+ "Language-Team: \n"
7
+ "MIME-Version: 1.0\n"
8
+ "Content-Type: text/plain; charset=UTF-8\n"
9
+ "Content-Transfer-Encoding: 8bit\n"
10
+ "X-Generator: Poedit 2.3\n"
11
+ "X-Poedit-Basepath: ..\n"
12
+ "Plural-Forms: nplurals=2; plural=(n != 1);\n"
13
+ "X-Poedit-SourceCharset: UTF-8\n"
14
+ "X-Poedit-KeywordsList: __;_e;_x:1,2c;_x\n"
15
+ "Last-Translator: \n"
16
+ "Language: es_ES\n"
17
+ "X-Poedit-SearchPath-0: .\n"
18
+
19
+ #: Puc/v4p3/Plugin/UpdateChecker.php:395
20
+ msgid "Check for updates"
21
+ msgstr "Comprobar si hay actualizaciones"
22
+
23
+ #: Puc/v4p3/Plugin/UpdateChecker.php:548
24
+ #, php-format
25
+ msgctxt "the plugin title"
26
+ msgid "The %s plugin is up to date."
27
+ msgstr "El plugin %s está actualizado."
28
+
29
+ #: Puc/v4p3/Plugin/UpdateChecker.php:550
30
+ #, php-format
31
+ msgctxt "the plugin title"
32
+ msgid "A new version of the %s plugin is available."
33
+ msgstr "Una nueva versión del %s plugin está disponible."
34
+
35
+ #: Puc/v4p3/Plugin/UpdateChecker.php:552
36
+ #, php-format
37
+ msgctxt "the plugin title"
38
+ msgid "Could not determine if updates are available for %s."
39
+ msgstr "No se pudo determinar si hay actualizaciones disponibles para %s."
40
+
41
+ #: Puc/v4p3/Plugin/UpdateChecker.php:558
42
+ #, php-format
43
+ msgid "Unknown update checker status \"%s\""
44
+ msgstr "Estado del comprobador de actualización desconocido «%s»"
45
+
46
+ #: Puc/v4p3/Vcs/PluginUpdateChecker.php:95
47
+ msgid "There is no changelog available."
48
+ msgstr "No hay un registro de cambios disponible."
lib/plugin-update-checker/languages/plugin-update-checker-es_PR.mo ADDED
Binary file
lib/plugin-update-checker/languages/plugin-update-checker-es_PR.po ADDED
@@ -0,0 +1,48 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ msgid ""
2
+ msgstr ""
3
+ "Project-Id-Version: plugin-update-checker\n"
4
+ "POT-Creation-Date: 2017-11-24 17:02+0200\n"
5
+ "PO-Revision-Date: 2020-03-21 15:15-0400\n"
6
+ "Language-Team: \n"
7
+ "MIME-Version: 1.0\n"
8
+ "Content-Type: text/plain; charset=UTF-8\n"
9
+ "Content-Transfer-Encoding: 8bit\n"
10
+ "X-Generator: Poedit 2.3\n"
11
+ "X-Poedit-Basepath: ..\n"
12
+ "Plural-Forms: nplurals=2; plural=(n != 1);\n"
13
+ "X-Poedit-SourceCharset: UTF-8\n"
14
+ "X-Poedit-KeywordsList: __;_e;_x:1,2c;_x\n"
15
+ "Last-Translator: \n"
16
+ "Language: es_ES\n"
17
+ "X-Poedit-SearchPath-0: .\n"
18
+
19
+ #: Puc/v4p3/Plugin/UpdateChecker.php:395
20
+ msgid "Check for updates"
21
+ msgstr "Comprobar si hay actualizaciones"
22
+
23
+ #: Puc/v4p3/Plugin/UpdateChecker.php:548
24
+ #, php-format
25
+ msgctxt "the plugin title"
26
+ msgid "The %s plugin is up to date."
27
+ msgstr "El plugin %s está actualizado."
28
+
29
+ #: Puc/v4p3/Plugin/UpdateChecker.php:550
30
+ #, php-format
31
+ msgctxt "the plugin title"
32
+ msgid "A new version of the %s plugin is available."
33
+ msgstr "Una nueva versión del %s plugin está disponible."
34
+
35
+ #: Puc/v4p3/Plugin/UpdateChecker.php:552
36
+ #, php-format
37
+ msgctxt "the plugin title"
38
+ msgid "Could not determine if updates are available for %s."
39
+ msgstr "No se pudo determinar si hay actualizaciones disponibles para %s."
40
+
41
+ #: Puc/v4p3/Plugin/UpdateChecker.php:558
42
+ #, php-format
43
+ msgid "Unknown update checker status \"%s\""
44
+ msgstr "Estado del comprobador de actualización desconocido «%s»"
45
+
46
+ #: Puc/v4p3/Vcs/PluginUpdateChecker.php:95
47
+ msgid "There is no changelog available."
48
+ msgstr "No hay un registro de cambios disponible."
lib/plugin-update-checker/languages/plugin-update-checker-es_UY.mo ADDED
Binary file
lib/plugin-update-checker/languages/plugin-update-checker-es_UY.po ADDED
@@ -0,0 +1,48 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ msgid ""
2
+ msgstr ""
3
+ "Project-Id-Version: plugin-update-checker\n"
4
+ "POT-Creation-Date: 2017-11-24 17:02+0200\n"
5
+ "PO-Revision-Date: 2020-03-21 15:15-0400\n"
6
+ "Language-Team: \n"
7
+ "MIME-Version: 1.0\n"
8
+ "Content-Type: text/plain; charset=UTF-8\n"
9
+ "Content-Transfer-Encoding: 8bit\n"
10
+ "X-Generator: Poedit 2.3\n"
11
+ "X-Poedit-Basepath: ..\n"
12
+ "Plural-Forms: nplurals=2; plural=(n != 1);\n"
13
+ "X-Poedit-SourceCharset: UTF-8\n"
14
+ "X-Poedit-KeywordsList: __;_e;_x:1,2c;_x\n"
15
+ "Last-Translator: \n"
16
+ "Language: es_ES\n"
17
+ "X-Poedit-SearchPath-0: .\n"
18
+
19
+ #: Puc/v4p3/Plugin/UpdateChecker.php:395
20
+ msgid "Check for updates"
21
+ msgstr "Comprobar si hay actualizaciones"
22
+
23
+ #: Puc/v4p3/Plugin/UpdateChecker.php:548
24
+ #, php-format
25
+ msgctxt "the plugin title"
26
+ msgid "The %s plugin is up to date."
27
+ msgstr "El plugin %s está actualizado."
28
+
29
+ #: Puc/v4p3/Plugin/UpdateChecker.php:550
30
+ #, php-format
31
+ msgctxt "the plugin title"
32
+ msgid "A new version of the %s plugin is available."
33
+ msgstr "Una nueva versión del %s plugin está disponible."
34
+
35
+ #: Puc/v4p3/Plugin/UpdateChecker.php:552
36
+ #, php-format
37
+ msgctxt "the plugin title"
38
+ msgid "Could not determine if updates are available for %s."
39
+ msgstr "No se pudo determinar si hay actualizaciones disponibles para %s."
40
+
41
+ #: Puc/v4p3/Plugin/UpdateChecker.php:558
42
+ #, php-format
43
+ msgid "Unknown update checker status \"%s\""
44
+ msgstr "Estado del comprobador de actualización desconocido «%s»"
45
+
46
+ #: Puc/v4p3/Vcs/PluginUpdateChecker.php:95
47
+ msgid "There is no changelog available."
48
+ msgstr "No hay un registro de cambios disponible."
lib/plugin-update-checker/languages/plugin-update-checker-es_VE.mo ADDED
Binary file
lib/plugin-update-checker/languages/plugin-update-checker-es_VE.po ADDED
@@ -0,0 +1,48 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ msgid ""
2
+ msgstr ""
3
+ "Project-Id-Version: plugin-update-checker\n"
4
+ "POT-Creation-Date: 2017-11-24 17:02+0200\n"
5
+ "PO-Revision-Date: 2020-03-21 14:57-0400\n"
6
+ "Language-Team: \n"
7
+ "MIME-Version: 1.0\n"
8
+ "Content-Type: text/plain; charset=UTF-8\n"
9
+ "Content-Transfer-Encoding: 8bit\n"
10
+ "X-Generator: Poedit 2.3\n"
11
+ "X-Poedit-Basepath: ..\n"
12
+ "Plural-Forms: nplurals=2; plural=(n != 1);\n"
13
+ "X-Poedit-SourceCharset: UTF-8\n"
14
+ "X-Poedit-KeywordsList: __;_e;_x:1,2c;_x\n"
15
+ "Last-Translator: \n"
16
+ "Language: es_ES\n"
17
+ "X-Poedit-SearchPath-0: .\n"
18
+
19
+ #: Puc/v4p3/Plugin/UpdateChecker.php:395
20
+ msgid "Check for updates"
21
+ msgstr "Comprobar si hay actualizaciones"
22
+
23
+ #: Puc/v4p3/Plugin/UpdateChecker.php:548
24
+ #, php-format
25
+ msgctxt "the plugin title"
26
+ msgid "The %s plugin is up to date."
27
+ msgstr "El plugin %s está actualizado."
28
+
29
+ #: Puc/v4p3/Plugin/UpdateChecker.php:550
30
+ #, php-format
31
+ msgctxt "the plugin title"
32
+ msgid "A new version of the %s plugin is available."
33
+ msgstr "Una nueva versión del %s plugin está disponible."
34
+
35
+ #: Puc/v4p3/Plugin/UpdateChecker.php:552
36
+ #, php-format
37
+ msgctxt "the plugin title"
38
+ msgid "Could not determine if updates are available for %s."
39
+ msgstr "No se pudo determinar si hay actualizaciones disponibles para %s."
40
+
41
+ #: Puc/v4p3/Plugin/UpdateChecker.php:558
42
+ #, php-format
43
+ msgid "Unknown update checker status \"%s\""
44
+ msgstr "Estado del comprobador de actualización desconocido «%s»"
45
+
46
+ #: Puc/v4p3/Vcs/PluginUpdateChecker.php:95
47
+ msgid "There is no changelog available."
48
+ msgstr "No hay un registro de cambios disponible."
lib/plugin-update-checker/load-v4p8.php DELETED
@@ -1,28 +0,0 @@
1
- <?php
2
- require dirname(__FILE__) . '/Puc/v4p8/Autoloader.php';
3
- new Puc_v4p8_Autoloader();
4
-
5
- require dirname(__FILE__) . '/Puc/v4p8/Factory.php';
6
- require dirname(__FILE__) . '/Puc/v4/Factory.php';
7
-
8
- //Register classes defined in this version with the factory.
9
- foreach (
10
- array(
11
- 'Plugin_UpdateChecker' => 'Puc_v4p8_Plugin_UpdateChecker',
12
- 'Theme_UpdateChecker' => 'Puc_v4p8_Theme_UpdateChecker',
13
-
14
- 'Vcs_PluginUpdateChecker' => 'Puc_v4p8_Vcs_PluginUpdateChecker',
15
- 'Vcs_ThemeUpdateChecker' => 'Puc_v4p8_Vcs_ThemeUpdateChecker',
16
-
17
- 'GitHubApi' => 'Puc_v4p8_Vcs_GitHubApi',
18
- 'BitBucketApi' => 'Puc_v4p8_Vcs_BitBucketApi',
19
- 'GitLabApi' => 'Puc_v4p8_Vcs_GitLabApi',
20
- )
21
- as $pucGeneralClass => $pucVersionedClass
22
- ) {
23
- Puc_v4_Factory::addVersion($pucGeneralClass, $pucVersionedClass, '4.8');
24
- //Also add it to the minor-version factory in case the major-version factory
25
- //was already defined by another, older version of the update checker.
26
- Puc_v4p8_Factory::addVersion($pucGeneralClass, $pucVersionedClass, '4.8');
27
- }
28
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/plugin-update-checker/load-v4p9.php ADDED
@@ -0,0 +1,28 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ require dirname(__FILE__) . '/Puc/v4p9/Autoloader.php';
3
+ new Puc_v4p9_Autoloader();
4
+
5
+ require dirname(__FILE__) . '/Puc/v4p9/Factory.php';
6
+ require dirname(__FILE__) . '/Puc/v4/Factory.php';
7
+
8
+ //Register classes defined in this version with the factory.
9
+ foreach (
10
+ array(
11
+ 'Plugin_UpdateChecker' => 'Puc_v4p9_Plugin_UpdateChecker',
12
+ 'Theme_UpdateChecker' => 'Puc_v4p9_Theme_UpdateChecker',
13
+
14
+ 'Vcs_PluginUpdateChecker' => 'Puc_v4p9_Vcs_PluginUpdateChecker',
15
+ 'Vcs_ThemeUpdateChecker' => 'Puc_v4p9_Vcs_ThemeUpdateChecker',
16
+
17
+ 'GitHubApi' => 'Puc_v4p9_Vcs_GitHubApi',
18
+ 'BitBucketApi' => 'Puc_v4p9_Vcs_BitBucketApi',
19
+ 'GitLabApi' => 'Puc_v4p9_Vcs_GitLabApi',
20
+ )
21
+ as $pucGeneralClass => $pucVersionedClass
22
+ ) {
23
+ Puc_v4_Factory::addVersion($pucGeneralClass, $pucVersionedClass, '4.9');
24
+ //Also add it to the minor-version factory in case the major-version factory
25
+ //was already defined by another, older version of the update checker.
26
+ Puc_v4p9_Factory::addVersion($pucGeneralClass, $pucVersionedClass, '4.9');
27
+ }
28
+
lib/plugin-update-checker/plugin-update-checker.php CHANGED
@@ -1,10 +1,10 @@
1
  <?php
2
  /**
3
- * Plugin Update Checker Library 4.8
4
  * http://w-shadow.com/
5
  *
6
- * Copyright 2019 Janis Elsts
7
  * Released under the MIT license. See license.txt for details.
8
  */
9
 
10
- require dirname(__FILE__) . '/load-v4p8.php';
1
  <?php
2
  /**
3
+ * Plugin Update Checker Library 4.9
4
  * http://w-shadow.com/
5
  *
6
+ * Copyright 2020 Janis Elsts
7
  * Released under the MIT license. See license.txt for details.
8
  */
9
 
10
+ require dirname(__FILE__) . '/load-v4p9.php';
lib/plugin-update-checker/vendor/PucReadmeParser.php CHANGED
@@ -52,6 +52,12 @@ class PucReadmeParser {
52
  else
53
  $tested_up_to = NULL;
54
 
 
 
 
 
 
 
55
 
56
  // Stable tag: 10.4-ride-the-fire-eagle-danger-day
57
  if ( preg_match('|Stable tag:(.*)|i', $file_contents, $_stable_tag) )
@@ -196,6 +202,7 @@ class PucReadmeParser {
196
  'tags' => $tags,
197
  'requires_at_least' => $requires_at_least,
198
  'tested_up_to' => $tested_up_to,
 
199
  'stable_tag' => $stable_tag,
200
  'contributors' => $contributors,
201
  'donate_link' => $donate_link,
52
  else
53
  $tested_up_to = NULL;
54
 
55
+ // Requires PHP: 5.2.4
56
+ if ( preg_match('|Requires PHP:(.*)|i', $file_contents, $_requires_php) ) {
57
+ $requires_php = $this->sanitize_text( $_requires_php[1] );
58
+ } else {
59
+ $requires_php = null;
60
+ }
61
 
62
  // Stable tag: 10.4-ride-the-fire-eagle-danger-day
63
  if ( preg_match('|Stable tag:(.*)|i', $file_contents, $_stable_tag) )
202
  'tags' => $tags,
203
  'requires_at_least' => $requires_at_least,
204
  'tested_up_to' => $tested_up_to,
205
+ 'requires_php' => $requires_php,
206
  'stable_tag' => $stable_tag,
207
  'contributors' => $contributors,
208
  'donate_link' => $donate_link,
main.php CHANGED
@@ -3,7 +3,7 @@
3
  * Plugin Name: Simple Download Monitor
4
  * Plugin URI: https://simple-download-monitor.com/
5
  * Description: Easily manage downloadable files and monitor downloads of your digital files from your WordPress site.
6
- * Version: 3.8.3
7
  * Author: Tips and Tricks HQ, Ruhul Amin, Josh Lobe
8
  * Author URI: https://www.tipsandtricks-hq.com/development-center
9
  * License: GPL2
@@ -11,10 +11,10 @@
11
  * Domain Path: /languages/
12
  */
13
  if ( ! defined( 'ABSPATH' ) ) {
14
- exit;
15
  }
16
 
17
- define( 'WP_SIMPLE_DL_MONITOR_VERSION', '3.8.3' );
18
  define( 'WP_SIMPLE_DL_MONITOR_DIR_NAME', dirname( plugin_basename( __FILE__ ) ) );
19
  define( 'WP_SIMPLE_DL_MONITOR_URL', plugins_url( '', __FILE__ ) );
20
  define( 'WP_SIMPLE_DL_MONITOR_PATH', plugin_dir_path( __FILE__ ) );
@@ -22,21 +22,21 @@ define( 'WP_SIMPLE_DL_MONITOR_SITE_HOME_URL', home_url() );
22
  define( 'WP_SDM_LOG_FILE', WP_SIMPLE_DL_MONITOR_PATH . 'sdm-debug-log.txt' );
23
 
24
  global $sdm_db_version;
25
- $sdm_db_version = '1.2';
26
 
27
  //File includes
28
- include_once('includes/sdm-debug.php');
29
- include_once('includes/sdm-utility-functions.php');
30
- include_once('includes/sdm-utility-functions-admin-side.php');
31
- include_once('includes/sdm-download-request-handler.php');
32
- include_once('includes/sdm-user-login-related.php');
33
- include_once('includes/sdm-logs-list-table.php');
34
- include_once('includes/sdm-latest-downloads.php');
35
- include_once('includes/sdm-popular-downloads.php');
36
- include_once('includes/sdm-search-shortcode-handler.php');
37
- include_once('sdm-post-type-and-taxonomy.php');
38
- include_once('sdm-shortcodes.php');
39
- include_once('sdm-post-type-content-handler.php');
40
 
41
  if ( is_admin() ) {
42
  //load addons update checker class
@@ -48,11 +48,11 @@ register_activation_hook( __FILE__, 'sdm_install_db_table' );
48
 
49
  function sdm_install_db_table() {
50
 
51
- global $wpdb;
52
- global $sdm_db_version;
53
- $table_name = $wpdb->prefix . 'sdm_downloads';
54
 
55
- $sql = 'CREATE TABLE ' . $table_name . ' (
56
  id mediumint(9) NOT NULL AUTO_INCREMENT,
57
  post_id mediumint(9) NOT NULL,
58
  post_title mediumtext NOT NULL,
@@ -61,19 +61,20 @@ function sdm_install_db_table() {
61
  date_time datetime DEFAULT "0000-00-00 00:00:00" NOT NULL,
62
  visitor_country mediumtext NOT NULL,
63
  visitor_name mediumtext NOT NULL,
 
64
  UNIQUE KEY id (id)
65
  );';
66
 
67
- require_once( ABSPATH . 'wp-admin/includes/upgrade.php' );
68
- dbDelta( $sql );
69
 
70
- update_option( 'sdm_db_version', $sdm_db_version );
71
 
72
- //Register the post type so you can flush the rewrite rules
73
- sdm_register_post_type();
74
 
75
- // Flush rules after install/activation
76
- flush_rewrite_rules();
77
  }
78
 
79
  /*
@@ -82,11 +83,11 @@ function sdm_install_db_table() {
82
  add_action( 'plugins_loaded', 'sdm_plugins_loaded_tasks' );
83
 
84
  function sdm_plugins_loaded_tasks() {
85
- //Load language
86
- load_plugin_textdomain( 'simple-download-monitor', false, dirname( plugin_basename( __FILE__ ) ) . '/languages/' );
87
 
88
- //Handle db upgrade stuff
89
- sdm_db_update_check();
90
  }
91
 
92
  /*
@@ -96,73 +97,73 @@ add_action( 'init', 'sdm_init_time_tasks' );
96
  add_action( 'admin_init', 'sdm_admin_init_time_tasks' );
97
 
98
  function sdm_init_time_tasks() {
99
- //Handle download request if any
100
- handle_sdm_download_via_direct_post();
101
 
102
- //Check if the redirect option is being used
103
- sdm_check_redirect_query_and_settings();
104
 
105
- if ( is_admin() ) {
106
- //Register Google Charts library
107
- wp_register_script( 'sdm_google_charts', 'https://www.gstatic.com/charts/loader.js', array(), null, true );
108
- wp_register_style( 'sdm_jquery_ui_style', WP_SIMPLE_DL_MONITOR_URL . '/css/jquery.ui.min.css', array(), null, 'all' );
109
- }
110
  }
111
 
112
  function sdm_admin_init_time_tasks() {
113
- //Register ajax handlers
114
- add_action( 'wp_ajax_sdm_reset_log', 'sdm_reset_log_handler' );
115
- add_action( 'wp_ajax_sdm_delete_data', 'sdm_delete_data_handler' );
116
-
117
- if ( is_admin() ) {
118
- if ( user_can( wp_get_current_user(), 'administrator' ) ) {
119
- // user is an admin
120
- if ( isset( $_GET[ 'sdm-action' ] ) ) {
121
- if ( $_GET[ 'sdm-action' ] === 'view_log' ) {
122
- $logfile = fopen( WP_SDM_LOG_FILE, 'rb' );
123
- header( 'Content-Type: text/plain' );
124
- fpassthru( $logfile );
125
- die;
 
 
126
  }
127
- }
128
  }
129
- }
130
  }
131
 
132
  function sdm_reset_log_handler() {
133
- SDM_Debug::reset_log();
134
- echo '1';
135
- wp_die();
136
  }
137
 
138
  function sdm_delete_data_handler() {
139
- if ( ! check_ajax_referer( 'sdm_delete_data', 'nonce', false ) ) {
140
- //nonce check failed
141
- wp_die( 0 );
142
- }
143
- global $wpdb;
144
- //let's find and delete smd_download posts and meta
145
- $posts = $wpdb->get_results( 'SELECT id FROM ' . $wpdb->prefix . 'posts WHERE post_type="sdm_downloads"', ARRAY_A );
146
- if ( ! is_null( $posts ) ) {
147
- foreach ( $posts as $post ) {
148
- wp_delete_post( $post[ 'id' ], true );
149
- }
150
- }
151
- //let's delete options
152
- delete_option( 'sdm_downloads_options' );
153
- delete_option( 'sdm_db_version' );
154
- //remove post type and taxonomies
155
- unregister_post_type( 'sdm_downloads' );
156
- unregister_taxonomy( 'sdm_categories' );
157
- unregister_taxonomy( 'sdm_tags' );
158
- //let's delete sdm_downloads table
159
- $wpdb->query( "DROP TABLE " . $wpdb->prefix . "sdm_downloads" );
160
- //deactivate plugin
161
- deactivate_plugins( plugin_basename( __FILE__ ) );
162
- //flush rewrite rules
163
- flush_rewrite_rules( false );
164
- echo '1';
165
- wp_die();
166
  }
167
 
168
  /*
@@ -170,13 +171,13 @@ function sdm_delete_data_handler() {
170
  */
171
 
172
  function sdm_db_update_check() {
173
- if ( is_admin() ) {//Check if DB needs to be upgraded
174
- global $sdm_db_version;
175
- $inst_db_version = get_option( 'sdm_db_version' );
176
- if ( $inst_db_version != $sdm_db_version ) {
177
- sdm_install_db_table();
 
178
  }
179
- }
180
  }
181
 
182
  /*
@@ -185,246 +186,241 @@ function sdm_db_update_check() {
185
  add_filter( 'plugin_action_links', 'sdm_settings_link', 10, 2 );
186
 
187
  function sdm_settings_link( $links, $file ) {
188
- static $this_plugin;
189
- if ( ! $this_plugin )
190
- $this_plugin = plugin_basename( __FILE__ );
191
- if ( $file == $this_plugin ) {
192
- $settings_link = '<a href="edit.php?post_type=sdm_downloads&page=sdm-settings" title="SDM Settings Page">' . __( "Settings", 'simple-download-monitor' ) . '</a>';
193
- array_unshift( $links, $settings_link );
194
- }
195
- return $links;
 
196
  }
197
 
198
  // Houston... we have lift-off!!
199
  class simpleDownloadManager {
200
 
201
- public function __construct() {
202
 
203
- add_action( 'init', 'sdm_register_post_type' ); // Create 'sdm_downloads' custom post type
204
- add_action( 'init', 'sdm_create_taxonomies' ); // Register 'tags' and 'categories' taxonomies
205
- add_action( 'init', 'sdm_register_shortcodes' ); //Register the shortcodes
206
- add_action( 'wp_enqueue_scripts', array( $this, 'sdm_frontend_scripts' ) ); // Register frontend scripts
207
- include_once('includes/sdm-blocks.php');
208
 
209
- if ( is_admin() ) {
210
- add_action( 'admin_menu', array( $this, 'sdm_create_menu_pages' ) ); // Create admin pages
211
- add_action( 'add_meta_boxes', array( $this, 'sdm_create_upload_metabox' ) ); // Create metaboxes
212
-
213
- add_action( 'save_post', array( $this, 'sdm_save_description_meta_data' ) ); // Save 'description' metabox
214
- add_action( 'save_post', array( $this, 'sdm_save_upload_meta_data' ) ); // Save 'upload file' metabox
215
- add_action( 'save_post', array( $this, 'sdm_save_dispatch_meta_data' ) ); // Save 'dispatch' metabox
216
- add_action( 'save_post', array( $this, 'sdm_save_misc_properties_meta_data' ) ); // Save 'misc properties/settings' metabox
217
- add_action( 'save_post', array( $this, 'sdm_save_thumbnail_meta_data' ) ); // Save 'thumbnail' metabox
218
- add_action( 'save_post', array( $this, 'sdm_save_statistics_meta_data' ) ); // Save 'statistics' metabox
219
- add_action( 'save_post', array( $this, 'sdm_save_other_details_meta_data' ) ); // Save 'other details' metabox
220
-
221
- add_action( 'admin_enqueue_scripts', array( $this, 'sdm_admin_scripts' ) ); // Register admin scripts
222
- add_action( 'admin_print_styles', array( $this, 'sdm_admin_styles' ) ); // Register admin styles
223
-
224
- add_action( 'admin_init', array( $this, 'sdm_register_options' ) ); // Register admin options
225
- //add_filter('post_row_actions', array($this, 'sdm_remove_view_link_cpt'), 10, 2); // Remove 'View' link in all downloads list view
226
-
227
- add_filter( 'page_row_actions', array( $this, 'sdm_add_clone_record_btn' ), 10, 2 ); // Add 'Clone' link in all downloads list view
228
- add_filter( 'post_row_actions', array( $this, 'sdm_add_clone_record_btn' ), 10, 2 ); // Add 'Clone' link in all downloads list view
229
-
230
- add_action( 'admin_action_sdm_clone_post', array( $this, 'sdm_action_clone_post' ) );
231
- }
232
- }
233
-
234
- public function sdm_admin_scripts() {
235
-
236
- global $current_screen, $post;
237
-
238
- if ( is_admin() && $current_screen->post_type == 'sdm_downloads' && $current_screen->base == 'post' ) {
239
-
240
- // These scripts are needed for the media upload thickbox
241
- wp_enqueue_script( 'media-upload' );
242
- wp_enqueue_script( 'thickbox' );
243
- wp_register_script( 'sdm-upload', WP_SIMPLE_DL_MONITOR_URL . '/js/sdm_admin_scripts.js', array( 'jquery', 'media-upload', 'thickbox' ), WP_SIMPLE_DL_MONITOR_VERSION );
244
- wp_enqueue_script( 'sdm-upload' );
245
-
246
- // Pass postID for thumbnail deletion
247
- ?>
248
- <script type="text/javascript">
249
- var sdm_del_thumb_postid = '<?php echo $post->ID; ?>';
250
- </script>
251
- <?php
252
- // Localize langauge strings used in js file
253
- $sdmTranslations = array(
254
- 'select_file' => __( 'Select File', 'simple-download-monitor' ),
255
- 'select_thumbnail' => __( 'Select Thumbnail', 'simple-download-monitor' ),
256
- 'insert' => __( 'Insert', 'simple-download-monitor' ),
257
- 'image_removed' => __( 'Image Successfully Removed', 'simple-download-monitor' ),
258
- 'ajax_error' => __( 'Error with AJAX', 'simple-download-monitor' )
259
- );
260
- wp_localize_script( 'sdm-upload', 'sdm_translations', $sdmTranslations );
261
- }
262
-
263
- // Pass admin ajax url
264
- ?>
265
- <script type="text/javascript">
266
- var sdm_admin_ajax_url = {sdm_admin_ajax_url: '<?php echo admin_url( 'admin-ajax.php?action=ajax' ); ?>'};
267
- var sdm_plugin_url = '<?php echo plugins_url(); ?>';
268
- var tinymce_langs = {
269
- select_download_item: '<?php _e( 'Please select a Download Item:', 'simple-download-monitor' ) ?>',
270
- download_title: '<?php _e( 'Download Title', 'simple-download-monitor' ) ?>',
271
- include_fancy: '<?php _e( 'Include Fancy Box', 'simple-download-monitor' ) ?>',
272
- open_new_window: '<?php _e( 'Open New Window', 'simple-download-monitor' ) ?>',
273
- button_color: '<?php _e( 'Button Color', 'simple-download-monitor' ); ?>',
274
- insert_shortcode: '<?php _e( 'Insert SDM Shortcode', 'simple-download-monitor' ) ?>'
275
- };
276
- var sdm_button_colors = <?php echo wp_json_encode( sdm_get_download_button_colors() ); ?>;
277
- </script>
278
- <?php
279
- }
280
-
281
- public function sdm_frontend_scripts() {
282
- //Use this function to enqueue fron-end js scripts.
283
- wp_enqueue_style( 'sdm-styles', WP_SIMPLE_DL_MONITOR_URL . '/css/sdm_wp_styles.css' );
284
- wp_register_script( 'sdm-scripts', WP_SIMPLE_DL_MONITOR_URL . '/js/sdm_wp_scripts.js', array( 'jquery' ) );
285
- wp_enqueue_script( 'sdm-scripts' );
286
-
287
- //Check if reCAPTCHA is enabled.
288
- $main_advanced_opts = get_option( 'sdm_advanced_options' );
289
- $recaptcha_enable = isset( $main_advanced_opts[ 'recaptcha_enable' ] ) ? true : false;
290
- if ( $recaptcha_enable ) {
291
- wp_register_script( 'sdm-recaptcha-scripts-js', WP_SIMPLE_DL_MONITOR_URL . '/js/sdm_g_recaptcha.js', array(), true );
292
- wp_localize_script( "sdm-recaptcha-scripts-js", "sdm_recaptcha_opt", array( "site_key" => $main_advanced_opts[ 'recaptcha_site_key' ] ) );
293
- wp_register_script( 'sdm-recaptcha-scripts-lib', "//www.google.com/recaptcha/api.js?hl=" . get_locale() . "&onload=sdm_reCaptcha&render=explicit", array(), false );
294
- wp_enqueue_script( 'sdm-recaptcha-scripts-js' );
295
- wp_enqueue_script( 'sdm-recaptcha-scripts-lib' );
296
- }
297
-
298
- // Localize ajax script for frontend
299
- wp_localize_script( 'sdm-scripts', 'sdm_ajax_script', array( 'ajaxurl' => admin_url( 'admin-ajax.php' ) ) );
300
- }
301
-
302
- public function sdm_admin_styles() {
303
-
304
- wp_enqueue_style( 'thickbox' ); // Needed for media upload thickbox
305
- wp_enqueue_style( 'sdm_admin_styles', WP_SIMPLE_DL_MONITOR_URL . '/css/sdm_admin_styles.css', array(), WP_SIMPLE_DL_MONITOR_VERSION ); // Needed for media upload thickbox
306
- }
307
-
308
- public function sdm_create_menu_pages() {
309
- include_once('includes/sdm-admin-menu-handler.php');
310
- sdm_handle_admin_menu();
311
- }
312
-
313
- public function sdm_create_upload_metabox() {
314
-
315
- //***** Create metaboxes for the custom post type
316
- add_meta_box( 'sdm_description_meta_box', __( 'Description', 'simple-download-monitor' ), array( $this, 'display_sdm_description_meta_box' ), 'sdm_downloads', 'normal', 'default' );
317
- add_meta_box( 'sdm_upload_meta_box', __( 'Downloadable File (Visitors will download this item)', 'simple-download-monitor' ), array( $this, 'display_sdm_upload_meta_box' ), 'sdm_downloads', 'normal', 'default' );
318
- add_meta_box( 'sdm_dispatch_meta_box', __( 'PHP Dispatch or Redirect', 'simple-download-monitor' ), array( $this, 'display_sdm_dispatch_meta_box' ), 'sdm_downloads', 'normal', 'default' );
319
- add_meta_box( 'sdm_misc_properties_meta_box', __( 'Miscellaneous Download Item Properties', 'simple-download-monitor' ), array( $this, 'display_sdm_misc_properties_meta_box' ), 'sdm_downloads', 'normal', 'default' ); // Meta box for misc properies/settings
320
- add_meta_box( 'sdm_thumbnail_meta_box', __( 'File Thumbnail (Optional)', 'simple-download-monitor' ), array( $this, 'display_sdm_thumbnail_meta_box' ), 'sdm_downloads', 'normal', 'default' );
321
- add_meta_box( 'sdm_stats_meta_box', __( 'Statistics', 'simple-download-monitor' ), array( $this, 'display_sdm_stats_meta_box' ), 'sdm_downloads', 'normal', 'default' );
322
- do_action( 'sdm_admin_add_edit_download_before_other_details_meta_box_action' );
323
- add_meta_box( 'sdm_other_details_meta_box', __( 'Other Details (Optional)', 'simple-download-monitor' ), array( $this, 'display_sdm_other_details_meta_box' ), 'sdm_downloads', 'normal', 'default' );
324
- add_meta_box( 'sdm_shortcode_meta_box', __( 'Shortcodes', 'simple-download-monitor' ), array( $this, 'display_sdm_shortcode_meta_box' ), 'sdm_downloads', 'normal', 'default' );
325
- }
326
-
327
- public function display_sdm_description_meta_box( $post ) { // Description metabox
328
- _e( 'Add a description for this download item.', 'simple-download-monitor' );
329
- echo '<br /><br />';
330
-
331
- $old_description = get_post_meta( $post->ID, 'sdm_description', true );
332
- $sdm_description_field = array( 'textarea_name' => 'sdm_description' );
333
- wp_editor( $old_description, "sdm_description_editor_content", $sdm_description_field );
334
-
335
- wp_nonce_field( 'sdm_description_box_nonce', 'sdm_description_box_nonce_check' );
336
- }
337
-
338
- public function display_sdm_upload_meta_box( $post ) { // File Upload metabox
339
- $old_upload = get_post_meta( $post->ID, 'sdm_upload', true );
340
- $old_value = isset( $old_upload ) ? $old_upload : '';
341
-
342
- _e( 'Manually enter a valid URL of the file in the text box below, or click "Select File" button to upload (or choose) the downloadable file.', 'simple-download-monitor' );
343
- echo '<br /><br />';
344
-
345
- echo '<div class="sdm-download-edit-file-url-section">';
346
- echo '<input id="sdm_upload" type="text" size="100" name="sdm_upload" value="' . esc_url( $old_value ) . '" placeholder="http://..." />';
347
- echo '</div>';
348
-
349
- echo '<br />';
350
- echo '<input id="upload_image_button" type="button" class="button-primary" value="' . __( 'Select File', 'simple-download-monitor' ) . '" />';
351
-
352
- echo '<br /><br />';
353
- _e( 'Steps to upload a file or choose one from your media library:', 'simple-download-monitor' );
354
- echo '<ol>';
355
- echo '<li>' . __( 'Hit the "Select File" button.', 'simple-download-monitor' ) . '</li>';
356
- echo '<li>' . __( 'Upload a new file or choose an existing one from your media library.', 'simple-download-monitor' ) . '</li>';
357
- echo '<li>' . __( 'Click the "Insert" button, this will populate the uploaded file\'s URL in the above text field.', 'simple-download-monitor' ) . '</li>';
358
- echo '</ol>';
359
-
360
- wp_nonce_field( 'sdm_upload_box_nonce', 'sdm_upload_box_nonce_check' );
361
- }
362
-
363
- public function display_sdm_dispatch_meta_box( $post ) {
364
- $dispatch = get_post_meta( $post->ID, 'sdm_item_dispatch', true );
365
-
366
- if ( $dispatch === '' ) {
367
- // No value yet (either new item or saved with older version of plugin)
368
- $screen = get_current_screen();
369
-
370
- if ( $screen->action === 'add' ) {
371
- // New item: set default value as per plugin settings.
372
- $main_opts = get_option( 'sdm_downloads_options' );
373
- $dispatch = isset( $main_opts[ 'general_default_dispatch_value' ] ) && $main_opts[ 'general_default_dispatch_value' ];
374
- }
375
- }
376
-
377
- echo '<input id="sdm_item_dispatch" type="checkbox" name="sdm_item_dispatch" value="yes"' . checked( true, $dispatch, false ) . ' />';
378
- echo '<label for="sdm_item_dispatch">' . __( 'Dispatch the file via PHP directly instead of redirecting to it. PHP Dispatching keeps the download URL hidden. Dispatching works only for local files (files that you uploaded to this site via this plugin or media library).', 'simple-download-monitor' ) . '</label>';
379
-
380
- wp_nonce_field( 'sdm_dispatch_box_nonce', 'sdm_dispatch_box_nonce_check' );
381
- }
382
-
383
- // Open Download in new window
384
- public function display_sdm_misc_properties_meta_box( $post ) {
385
-
386
- //Check the open in new window value
387
- $new_window = get_post_meta( $post->ID, 'sdm_item_new_window', true );
388
- if ( $new_window === '' ) {
389
- // No value yet (either new item or saved with older version of plugin)
390
- $screen = get_current_screen();
391
- if ( $screen->action === 'add' ) {
392
- //New item: we can set a default value as per plugin settings. If a general settings is introduced at a later stage.
393
- //Does nothing at the moment.
394
- }
395
- }
396
-
397
- //Check the sdm_item_disable_single_download_page value
398
- $sdm_item_disable_single_download_page = get_post_meta( $post->ID, 'sdm_item_disable_single_download_page', true );
399
- $sdm_item_hide_dl_button_single_download_page = get_post_meta( $post->ID, 'sdm_item_hide_dl_button_single_download_page', true );
400
-
401
- echo '<p> <input id="sdm_item_new_window" type="checkbox" name="sdm_item_new_window" value="yes"' . checked( true, $new_window, false ) . ' />';
402
- echo '<label for="sdm_item_new_window">' . __( 'Open download in a new window.', 'simple-download-monitor' ) . '</label> </p>';
403
-
404
- //the new window will have no download button
405
- echo '<p> <input id="sdm_item_hide_dl_button_single_download_page" type="checkbox" name="sdm_item_hide_dl_button_single_download_page" value="yes"' . checked( true, $sdm_item_hide_dl_button_single_download_page, false ) . ' />';
406
- echo '<label for="sdm_item_hide_dl_button_single_download_page">';
407
-
408
- $disable_dl_button_label = __( 'Hide the download button on the single download page of this item.', 'simple-download-monitor' );
409
- echo $disable_dl_button_label . '</label>';
410
- echo '</p>';
411
-
412
- echo '<p> <input id="sdm_item_disable_single_download_page" type="checkbox" name="sdm_item_disable_single_download_page" value="yes"' . checked( true, $sdm_item_disable_single_download_page, false ) . ' />';
413
- echo '<label for="sdm_item_disable_single_download_page">';
414
- $disable_single_dl_label = __( 'Disable the single download page for this download item. ', 'simple-download-monitor' );
415
- $disable_single_dl_label .= __( 'This can be useful if you are using an addon like the ', 'simple-download-monitor' );
416
- $disable_single_dl_label .= '<a href="https://simple-download-monitor.com/squeeze-form-addon-for-simple-download-monitor/" target="_blank">Squeeze Form</a>' . '.';
417
- echo $disable_single_dl_label . '</label>';
418
- echo '</p>';
419
-
420
- wp_nonce_field( 'sdm_misc_properties_box_nonce', 'sdm_misc_properties_box_nonce_check' );
421
- }
422
-
423
- public function display_sdm_thumbnail_meta_box( $post ) { // Thumbnail upload metabox
424
- $old_thumbnail = get_post_meta( $post->ID, 'sdm_upload_thumbnail', true );
425
- $old_value = isset( $old_thumbnail ) ? $old_thumbnail : '';
426
- _e( 'Manually enter a valid URL, or click "Select Image" to upload (or choose) the file thumbnail image.', 'simple-download-monitor' );
427
- ?>
428
  <br /><br />
429
  <input id="sdm_upload_thumbnail" type="text" size="100" name="sdm_upload_thumbnail" value="<?php echo esc_url( $old_value ); ?>" placeholder="http://..." />
430
  <br /><br />
@@ -433,618 +429,645 @@ class simpleDownloadManager {
433
  <br /><br />
434
 
435
  <span id="sdm_admin_thumb_preview">
436
- <?php
437
- if ( ! empty( $old_value ) ) {
438
- ?><img id="sdm_thumbnail_image" src="<?php echo $old_value; ?>" style="max-width:200px;" />
439
  <?php
440
- }
441
- ?>
 
 
 
 
442
  </span>
443
 
444
- <?php
445
- echo '<p class="description">';
446
- _e( 'This thumbnail image will be used to create a fancy file download box if you want to use it.', 'simple-download-monitor' );
447
- echo '</p>';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
448
 
449
- wp_nonce_field( 'sdm_thumbnail_box_nonce', 'sdm_thumbnail_box_nonce_check' );
450
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
451
 
452
- public function display_sdm_stats_meta_box( $post ) { //Stats metabox
453
- $old_count = get_post_meta( $post->ID, 'sdm_count_offset', true );
454
- $value = isset( $old_count ) && $old_count != '' ? $old_count : '0';
 
 
 
 
 
 
 
 
 
 
 
 
 
455
 
456
- // Get checkbox for "disable download logging"
457
- $no_logs = get_post_meta( $post->ID, 'sdm_item_no_log', true );
458
- $checked = isset( $no_logs ) && $no_logs === 'on' ? 'checked="checked"' : '';
 
 
 
 
 
 
 
 
 
459
 
460
- _e( 'These are the statistics for this download item.', 'simple-download-monitor' );
461
- echo '<br /><br />';
 
 
 
 
 
 
462
 
463
- global $wpdb;
464
- $wpdb->get_results( $wpdb->prepare( 'SELECT * FROM ' . $wpdb->prefix . 'sdm_downloads WHERE post_id=%s', $post->ID ) );
465
-
466
- echo '<div class="sdm-download-edit-dl-count">';
467
- _e( 'Number of Downloads:', 'simple-download-monitor' );
468
- echo ' <strong>' . $wpdb->num_rows . '</strong>';
469
- echo '</div>';
470
-
471
- echo '<div class="sdm-download-edit-offset-count">';
472
- _e( 'Offset Count: ', 'simple-download-monitor' );
473
- echo '<br />';
474
- echo ' <input type="text" size="10" name="sdm_count_offset" value="' . esc_attr( $value ) . '" />';
475
- echo '<p class="description">' . __( 'Enter any positive or negative numerical value; to offset the download count shown to the visitors (when using the download counter shortcode).', 'simple-download-monitor' ) . '</p>';
476
- echo '</div>';
477
-
478
- echo '<br />';
479
- echo '<div class="sdm-download-edit-disable-logging">';
480
- echo '<input type="checkbox" name="sdm_item_no_log" ' . $checked . ' />';
481
- echo '<span style="margin-left: 5px;"></span>';
482
- _e( 'Disable download logging for this item.', 'simple-download-monitor' );
483
- echo '</div>';
484
-
485
- wp_nonce_field( 'sdm_count_offset_nonce', 'sdm_count_offset_nonce_check' );
486
- }
487
-
488
- public function display_sdm_other_details_meta_box( $post ) { //Other details metabox
489
- $show_date_fd = get_post_meta( $post->ID, 'sdm_item_show_date_fd', true );
490
- $sdm_item_show_file_size_fd = get_post_meta( $post->ID, 'sdm_item_show_file_size_fd', true );
491
- $sdm_item_show_item_version_fd = get_post_meta( $post->ID, 'sdm_item_show_item_version_fd', true );
492
-
493
- $file_size = get_post_meta( $post->ID, 'sdm_item_file_size', true );
494
- $file_size = isset( $file_size ) ? $file_size : '';
495
-
496
- $version = get_post_meta( $post->ID, 'sdm_item_version', true );
497
- $version = isset( $version ) ? $version : '';
498
-
499
- $download_button_text = get_post_meta( $post->ID, 'sdm_download_button_text', true );
500
- $download_button_text = isset( $download_button_text ) ? $download_button_text : '';
501
-
502
- echo '<div class="sdm-download-edit-filesize">';
503
- echo '<strong>' . __( 'File Size: ', 'simple-download-monitor' ) . '</strong>';
504
- echo '<br />';
505
- echo ' <input type="text" name="sdm_item_file_size" value="' . esc_attr( $file_size ) . '" size="20" />';
506
- echo '<p class="description">' . __( 'Enter the size of this file (example value: 2.15 MB).', 'simple-download-monitor' ) . '</p>';
507
- echo '<div class="sdm-download-edit-show-file-size"> <input id="sdm_item_show_file_size_fd" type="checkbox" name="sdm_item_show_file_size_fd" value="yes"' . checked( true, $sdm_item_show_file_size_fd, false ) . ' />';
508
- echo '<label for="sdm_item_show_file_size_fd">' . __( 'Show file size in fancy display.', 'simple-download-monitor' ) . '</label> </div>';
509
- echo '</div>';
510
- echo '<hr />';
511
-
512
- echo '<div class="sdm-download-edit-version">';
513
- echo '<strong>' . __( 'Version: ', 'simple-download-monitor' ) . '</strong>';
514
- echo '<br />';
515
- echo ' <input type="text" name="sdm_item_version" value="' . esc_attr( $version ) . '" size="20" />';
516
- echo '<p class="description">' . __( 'Enter the version number for this item if any (example value: v2.5.10).', 'simple-download-monitor' ) . '</p>';
517
- echo '<div class="sdm-download-edit-show-item-version"> <input id="sdm_item_show_item_version_fd" type="checkbox" name="sdm_item_show_item_version_fd" value="yes"' . checked( true, $sdm_item_show_item_version_fd, false ) . ' />';
518
- echo '<label for="sdm_item_show_item_version_fd">' . __( 'Show version number in fancy display.', 'simple-download-monitor' ) . '</label> </div>';
519
- echo '</div>';
520
- echo '<hr />';
521
-
522
- echo '<div class="sdm-download-edit-show-publish-date">';
523
- echo '<strong>' . __( 'Publish Date: ', 'simple-download-monitor' ) . '</strong>';
524
- echo '<br /> <input id="sdm_item_show_date_fd" type="checkbox" name="sdm_item_show_date_fd" value="yes"' . checked( true, $show_date_fd, false ) . ' />';
525
- echo '<label for="sdm_item_show_date_fd">' . __( 'Show download published date in fancy display.', 'simple-download-monitor' ) . '</label>';
526
- echo '</div>';
527
- echo '<hr />';
528
-
529
- echo '<div class="sdm-download-edit-button-text">';
530
- echo '<strong>' . __( 'Download Button Text: ', 'simple-download-monitor' ) . '</strong>';
531
- echo '<br />';
532
- echo "<input id='sdm-download-button-text' type='text' name='sdm_download_button_text' value='{$download_button_text}' />";
533
- echo '<p class="description">' . __( 'You can use this field to customize the download now button text of this item.', 'simple-download-monitor' ) . '</p>';
534
- echo '</div>';
535
-
536
- wp_nonce_field( 'sdm_other_details_nonce', 'sdm_other_details_nonce_check' );
537
- }
538
-
539
- public function display_sdm_shortcode_meta_box( $post ) { //Shortcode metabox
540
- _e( 'The following shortcode can be used on posts or pages to embed a download now button for this file. You can also use the shortcode inserter (in the post editor) to add this shortcode to a post or page.', 'simple-download-monitor' );
541
- echo '<br />';
542
- $shortcode_text = '[sdm_download id="' . $post->ID . '" fancy="0"]';
543
- echo "<input type='text' class='code' onfocus='this.select();' readonly='readonly' value='" . $shortcode_text . "' size='40'>";
544
- echo "<br /><br />";
545
-
546
- _e( 'The following shortcode can be used to show a download counter for this item.', 'simple-download-monitor' );
547
- echo '<br />';
548
- $shortcode_text = '[sdm_download_counter id="' . $post->ID . '"]';
549
- echo "<input type='text' class='code' onfocus='this.select();' readonly='readonly' value='" . $shortcode_text . "' size='40'>";
550
-
551
- echo '<br /><br />';
552
- _e( 'Read the full shortcode usage documentation <a href="https://www.tipsandtricks-hq.com/simple-wordpress-download-monitor-plugin" target="_blank">here</a>.', 'simple-download-monitor' );
553
- }
554
-
555
- public function sdm_save_description_meta_data( $post_id ) { // Save Description metabox
556
- if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) {
557
- return;
558
- }
559
- if ( ! isset( $_POST[ 'sdm_description_box_nonce_check' ] ) || ! wp_verify_nonce( $_POST[ 'sdm_description_box_nonce_check' ], 'sdm_description_box_nonce' ) ) {
560
- return;
561
- }
562
- if ( isset( $_POST[ 'sdm_description' ] ) ) {
563
- update_post_meta( $post_id, 'sdm_description', wp_kses_post( $_POST[ 'sdm_description' ] ) );
564
- }
565
- }
566
-
567
- public function sdm_save_upload_meta_data( $post_id ) { // Save File Upload metabox
568
- if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE )
569
- return;
570
- if ( ! isset( $_POST[ 'sdm_upload_box_nonce_check' ] ) || ! wp_verify_nonce( $_POST[ 'sdm_upload_box_nonce_check' ], 'sdm_upload_box_nonce' ) )
571
- return;
572
-
573
- if ( isset( $_POST[ 'sdm_upload' ] ) ) {
574
- update_post_meta( $post_id, 'sdm_upload', sanitize_text_field( $_POST[ 'sdm_upload' ] ) );
575
- }
576
- }
577
-
578
- public function sdm_save_dispatch_meta_data( $post_id ) { // Save "Dispatch or Redirect" metabox
579
- if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) {
580
- return;
581
- }
582
- if ( ! isset( $_POST[ 'sdm_dispatch_box_nonce_check' ] ) || ! wp_verify_nonce( $_POST[ 'sdm_dispatch_box_nonce_check' ], 'sdm_dispatch_box_nonce' ) ) {
583
- return;
584
- }
585
- // Get POST-ed data as boolean value
586
- $value = filter_input( INPUT_POST, 'sdm_item_dispatch', FILTER_VALIDATE_BOOLEAN );
587
- update_post_meta( $post_id, 'sdm_item_dispatch', $value );
588
- }
589
-
590
- public function sdm_save_misc_properties_meta_data( $post_id ) {
591
- if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) {
592
- return;
593
- }
594
- if ( ! isset( $_POST[ 'sdm_misc_properties_box_nonce_check' ] ) || ! wp_verify_nonce( $_POST[ 'sdm_misc_properties_box_nonce_check' ], 'sdm_misc_properties_box_nonce' ) ) {
595
- return;
596
- }
597
- // Get POST-ed data as boolean value
598
- $new_window_open = filter_input( INPUT_POST, 'sdm_item_new_window', FILTER_VALIDATE_BOOLEAN );
599
- $sdm_item_hide_dl_button_single_download_page = filter_input( INPUT_POST, 'sdm_item_hide_dl_button_single_download_page', FILTER_VALIDATE_BOOLEAN );
600
- $sdm_item_disable_single_download_page = filter_input( INPUT_POST, 'sdm_item_disable_single_download_page', FILTER_VALIDATE_BOOLEAN );
601
-
602
- //Save the data
603
- update_post_meta( $post_id, 'sdm_item_new_window', $new_window_open );
604
- update_post_meta( $post_id, 'sdm_item_hide_dl_button_single_download_page', $sdm_item_hide_dl_button_single_download_page );
605
- update_post_meta( $post_id, 'sdm_item_disable_single_download_page', $sdm_item_disable_single_download_page );
606
- }
607
-
608
- public function sdm_save_thumbnail_meta_data( $post_id ) { // Save Thumbnail Upload metabox
609
- if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) {
610
- return;
611
  }
612
- if ( ! isset( $_POST[ 'sdm_thumbnail_box_nonce_check' ] ) || ! wp_verify_nonce( $_POST[ 'sdm_thumbnail_box_nonce_check' ], 'sdm_thumbnail_box_nonce' ) ) {
613
- return;
614
- }
615
- if ( isset( $_POST[ 'sdm_upload_thumbnail' ] ) ) {
616
- update_post_meta( $post_id, 'sdm_upload_thumbnail', sanitize_text_field( $_POST[ 'sdm_upload_thumbnail' ] ) );
 
 
 
 
 
 
 
617
  }
618
- }
619
 
620
- public function sdm_save_statistics_meta_data( $post_id ) { // Save Statistics Upload metabox
621
- if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) {
622
- return;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
623
  }
624
- if ( ! isset( $_POST[ 'sdm_count_offset_nonce_check' ] ) || ! wp_verify_nonce( $_POST[ 'sdm_count_offset_nonce_check' ], 'sdm_count_offset_nonce' ) ) {
625
- return;
 
 
 
 
 
 
 
 
 
 
626
  }
627
- if ( isset( $_POST[ 'sdm_count_offset' ] ) && is_numeric( $_POST[ 'sdm_count_offset' ] ) ) {
628
- update_post_meta( $post_id, 'sdm_count_offset', intval( $_POST[ 'sdm_count_offset' ] ) );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
629
  }
630
 
631
- // Checkbox for disabling download logging for this item
632
- if ( isset( $_POST[ 'sdm_item_no_log' ] ) ) {
633
- update_post_meta( $post_id, 'sdm_item_no_log', sanitize_text_field( $_POST[ 'sdm_item_no_log' ] ) );
634
- } else {
635
- delete_post_meta( $post_id, 'sdm_item_no_log' );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
636
  }
637
- }
638
 
639
- public function sdm_save_other_details_meta_data( $post_id ) { // Save Statistics Upload metabox
640
- if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) {
641
- return;
 
 
 
 
 
642
  }
643
- if ( ! isset( $_POST[ 'sdm_other_details_nonce_check' ] ) || ! wp_verify_nonce( $_POST[ 'sdm_other_details_nonce_check' ], 'sdm_other_details_nonce' ) ) {
644
- return;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
645
  }
646
 
647
- $show_date_fd = filter_input( INPUT_POST, 'sdm_item_show_date_fd', FILTER_VALIDATE_BOOLEAN );
648
- update_post_meta( $post_id, 'sdm_item_show_date_fd', $show_date_fd );
 
 
649
 
650
- $sdm_item_show_file_size_fd = filter_input( INPUT_POST, 'sdm_item_show_file_size_fd', FILTER_VALIDATE_BOOLEAN );
651
- update_post_meta( $post_id, 'sdm_item_show_file_size_fd', $sdm_item_show_file_size_fd );
 
 
652
 
653
- $sdm_item_show_item_version_fd = filter_input( INPUT_POST, 'sdm_item_show_item_version_fd', FILTER_VALIDATE_BOOLEAN );
654
- update_post_meta( $post_id, 'sdm_item_show_item_version_fd', $sdm_item_show_item_version_fd );
 
 
 
 
 
 
 
655
 
656
- if ( isset( $_POST[ 'sdm_item_file_size' ] ) ) {
657
- update_post_meta( $post_id, 'sdm_item_file_size', sanitize_text_field( $_POST[ 'sdm_item_file_size' ] ) );
 
658
  }
659
 
660
- if ( isset( $_POST[ 'sdm_item_version' ] ) ) {
661
- update_post_meta( $post_id, 'sdm_item_version', sanitize_text_field( $_POST[ 'sdm_item_version' ] ) );
 
 
 
 
662
  }
663
 
664
- if ( isset( $_POST[ 'sdm_download_button_text' ] ) ) {
665
- update_post_meta( $post_id, 'sdm_download_button_text', sanitize_text_field( $_POST[ 'sdm_download_button_text' ] ) );
 
666
  }
667
- }
668
 
669
- public function sdm_remove_view_link_cpt( $action, $post ) {
670
 
671
- // Only execute on SDM CPT posts page
672
- if ( $post->post_type == 'sdm_downloads' ) {
673
- unset( $action[ 'view' ] );
674
  }
675
 
676
- return $action;
677
- }
 
 
678
 
679
- public function sdm_register_options() {
 
 
680
 
681
- //Register the main setting
682
- register_setting( 'sdm_downloads_options', 'sdm_downloads_options' );
 
 
 
 
683
 
684
- /* * ************************** */
685
- /* General Settings Section */
686
- /* * ************************** */
 
 
 
687
 
688
- //Add all the settings section that will go under the main settings
689
- add_settings_section( 'general_options', __( 'General Options', 'simple-download-monitor' ), array( $this, 'general_options_cb' ), 'general_options_section' );
690
- add_settings_section( 'user_login_options', __( 'User Login Related', 'simple-download-monitor' ), array( $this, 'user_login_options_cb' ), 'user_login_options_section' );
691
- add_settings_section( 'admin_options', __( 'Admin Options', 'simple-download-monitor' ), array( $this, 'admin_options_cb' ), 'admin_options_section' );
 
 
692
 
693
- add_settings_section( 'sdm_colors', __( 'Colors', 'simple-download-monitor' ), array( $this, 'sdm_colors_cb' ), 'sdm_colors_section' );
694
- add_settings_section( 'sdm_debug', __( 'Debug', 'simple-download-monitor' ), array( $this, 'sdm_debug_cb' ), 'sdm_debug_section' );
695
- add_settings_section( 'sdm_deldata', __( 'Delete Plugin Data', 'simple-download-monitor' ), array( $this, 'sdm_deldata_cb' ), 'sdm_deldata_section' );
 
 
696
 
697
- //Add all the individual settings fields that goes under the sections
698
- add_settings_field( 'general_hide_donwload_count', __( 'Hide Download Count', 'simple-download-monitor' ), array( $this, 'hide_download_count_cb' ), 'general_options_section', 'general_options' );
699
- add_settings_field( 'general_default_dispatch_value', __( 'PHP Dispatching', 'simple-download-monitor' ), array( $this, 'general_default_dispatch_value_cb' ), 'general_options_section', 'general_options' );
 
 
 
700
 
701
- add_settings_field( 'only_logged_in_can_download', __( 'Only Allow Logged-in Users to Download', 'simple-download-monitor' ), array( $this, 'general_only_logged_in_can_download_cb' ), 'user_login_options_section', 'user_login_options' );
702
- add_settings_field( 'general_login_page_url', __( 'Login Page URL', 'simple-download-monitor' ), array( $this, 'general_login_page_url_cb' ), 'user_login_options_section', 'user_login_options' );
703
- add_settings_field( 'redirect_user_back_to_download_page', __( 'Redirect Users to Download Page', 'simple-download-monitor' ), array( $this, 'redirect_user_back_to_download_page_cb' ), 'user_login_options_section', 'user_login_options' );
 
 
 
704
 
705
- add_settings_field( 'admin_tinymce_button', __( 'Remove Tinymce Button', 'simple-download-monitor' ), array( $this, 'admin_tinymce_button_cb' ), 'admin_options_section', 'admin_options' );
706
- add_settings_field( 'admin_log_unique', __( 'Log Unique IP', 'simple-download-monitor' ), array( $this, 'admin_log_unique' ), 'admin_options_section', 'admin_options' );
707
- add_settings_field( 'admin_do_not_capture_ip', __( 'Do Not Capture IP Address', 'simple-download-monitor' ), array( $this, 'admin_do_not_capture_ip' ), 'admin_options_section', 'admin_options' );
708
- add_settings_field( 'admin_dont_log_bots', __( 'Do Not Count Downloads from Bots', 'simple-download-monitor' ), array( $this, 'admin_dont_log_bots' ), 'admin_options_section', 'admin_options' );
709
- add_settings_field( 'admin_no_logs', __( 'Disable Download Logs', 'simple-download-monitor' ), array( $this, 'admin_no_logs_cb' ), 'admin_options_section', 'admin_options' );
 
710
 
711
- add_settings_field( 'download_button_color', __( 'Download Button Color', 'simple-download-monitor' ), array( $this, 'download_button_color_cb' ), 'sdm_colors_section', 'sdm_colors' );
 
 
 
 
 
712
 
713
- add_settings_field( 'enable_debug', __( 'Enable Debug', 'simple-download-monitor' ), array( $this, 'enable_debug_cb' ), 'sdm_debug_section', 'sdm_debug' );
 
 
 
 
714
 
715
- /* * ************************** */
716
- /* Advanced Settings Section */
717
- /* * ************************** */
718
- //Add the advanced settings section
719
- add_settings_section( 'recaptcha_options', __( 'Google Captcha (reCAPTCHA)', 'simple-download-monitor' ), array( $this, 'recaptcha_options_cb' ), 'recaptcha_options_section' );
720
- add_settings_section( 'termscond_options', __( 'Terms and Conditions', 'simple-download-monitor' ), array( $this, 'termscond_options_cb' ), 'termscond_options_section' );
721
- add_settings_section( 'adsense_options', __( 'Adsense/Ad Insertion', 'simple-download-monitor' ), array( $this, 'adsense_options_cb' ), 'adsense_options_section' );
722
- add_settings_section( 'maps_api_options', __( 'Google Maps API Key', 'simple-download-monitor' ), array( $this, 'maps_api_options_cb' ), 'maps_api_options_section' );
723
 
724
- //Add reCAPTCHA section fields
725
- add_settings_field( 'recaptcha_enable', __( 'Enable reCAPTCHA', 'simple-download-monitor' ), array( $this, 'recaptcha_enable_cb' ), 'recaptcha_options_section', 'recaptcha_options' );
726
- add_settings_field( 'recaptcha_site_key', __( 'Site Key', 'simple-download-monitor' ), array( $this, 'recaptcha_site_key_cb' ), 'recaptcha_options_section', 'recaptcha_options' );
727
- add_settings_field( 'recaptcha_secret_key', __( 'Secret Key', 'simple-download-monitor' ), array( $this, 'recaptcha_secret_key_cb' ), 'recaptcha_options_section', 'recaptcha_options' );
 
728
 
729
- //Add Terms & Condition section fields
730
- add_settings_field( 'termscond_enable', __( 'Enable Terms and Conditions', 'simple-download-monitor' ), array( $this, 'termscond_enable_cb' ), 'termscond_options_section', 'termscond_options' );
731
- add_settings_field( 'termscond_url', __( 'Terms Page URL', 'simple-download-monitor' ), array( $this, 'termscond_url_cb' ), 'termscond_options_section', 'termscond_options' );
 
 
732
 
733
- //Add Adsense section fields
734
- add_settings_field( 'adsense_below_description', __( 'Below Download Description', 'simple-download-monitor' ), array( $this, 'adsense_below_description_cb' ), 'adsense_options_section', 'adsense_options' );
 
 
 
735
 
736
- //Maps API section fields
737
- add_settings_field( 'maps_api_key', __( 'API Key', 'simple-download-monitor' ), array( $this, 'maps_api_key_cb' ), 'maps_api_options_section', 'maps_api_options' );
738
- }
739
-
740
- public function general_options_cb() {
741
- //Set the message that will be shown below the general options settings heading
742
- _e( 'General options settings', 'simple-download-monitor' );
743
- }
744
-
745
- public function user_login_options_cb() {
746
- //Set the message that will be shown below the user login related settings heading
747
- _e( 'Visitor login related settings (useful if you only want to allow logged-in users to be able to download files.', 'simple-download-monitor' );
748
- }
749
-
750
- public function admin_options_cb() {
751
- //Set the message that will be shown below the admin options settings heading
752
- _e( 'Admin options settings', 'simple-download-monitor' );
753
- }
754
-
755
- public function sdm_colors_cb() {
756
- //Set the message that will be shown below the color options settings heading
757
- _e( 'Front End colors settings', 'simple-download-monitor' );
758
- }
759
-
760
- public function sdm_debug_cb() {
761
- //Set the message that will be shown below the debug options settings heading
762
- _e( 'Debug settings', 'simple-download-monitor' );
763
- }
764
-
765
- public function sdm_deldata_cb() {
766
- //Set the message that will be shown below the debug options settings heading
767
- _e( 'You can delete all the data related to this plugin from database using the button below. Useful when you\'re uninstalling the plugin and don\'t want any leftovers remaining.', 'simple-download-monitor' );
768
- echo '<p><b>' . __( 'Warning', 'simple-download-monitor' ) . ': </b> ' . __( 'this can\'t be undone. All settings, download items, download logs will be deleted.', 'simple-download-monitor' ) . '</p>';
769
- echo '<p><button id="sdmDeleteData" class="button" style="color:red;">' . __( 'Delete all data and deactivate plugin', 'simple-download-monitor' ) . '</button></p>';
770
- echo '<br />';
771
- }
772
-
773
- public function recaptcha_options_cb() {
774
- //Set the message that will be shown below the recaptcha options settings heading
775
- _e( 'Google Captcha (reCAPTCHA) options', 'simple-download-monitor' );
776
- }
777
-
778
- public function termscond_options_cb() {
779
-
780
- }
781
-
782
- public function adsense_options_cb() {
783
- //Set the message that will be shown below the adsense/ad code settings heading
784
- _e( 'You can use this section to insert adsense or other ad code inside the download item output', 'simple-download-monitor' );
785
- }
786
-
787
- public function maps_api_options_cb() {
788
- _e( 'Google Maps API key is required to display the "Downloads by Country" chart.', 'simple-download-monitor' );
789
- }
790
-
791
- public function recaptcha_enable_cb() {
792
- $main_opts = get_option( 'sdm_advanced_options' );
793
- echo '<input name="sdm_advanced_options[recaptcha_enable]" id="recaptcha_enable" type="checkbox" ' . checked( 1, isset( $main_opts[ 'recaptcha_enable' ] ), false ) . ' /> ';
794
- echo '<p class="description">' . __( 'Check this box if you want to use <a href="https://www.google.com/recaptcha/admin" target="_blank">reCAPTCHA</a>. ', 'simple-download-monitor' ) . '</p>';
795
- echo '<p class="description">' . __( 'The captcha option adds a captcha to the download now buttons.', 'simple-download-monitor' ) . '</p>';
796
- }
797
-
798
- public function recaptcha_site_key_cb() {
799
- $main_opts = get_option( 'sdm_advanced_options' );
800
- $value = isset( $main_opts[ 'recaptcha_site_key' ] ) ? $main_opts[ 'recaptcha_site_key' ] : '';
801
- echo '<input size="100" name="sdm_advanced_options[recaptcha_site_key]" id="recaptcha_site_key" type="text" value="' . $value . '" /> ';
802
- echo '<p class="description">' . __( 'The site key for the reCAPTCHA API', 'simple-download-monitor' ) . '</p>';
803
- }
804
-
805
- public function recaptcha_secret_key_cb() {
806
- $main_opts = get_option( 'sdm_advanced_options' );
807
- $value = isset( $main_opts[ 'recaptcha_secret_key' ] ) ? $main_opts[ 'recaptcha_secret_key' ] : '';
808
- echo '<input size="100" name="sdm_advanced_options[recaptcha_secret_key]" id="recaptcha_secret_key" type="text" value="' . $value . '" /> ';
809
- echo '<p class="description">' . __( 'The secret key for the reCAPTCHA API', 'simple-download-monitor' ) . '</p>';
810
- }
811
-
812
- public function hide_download_count_cb() {
813
- $main_opts = get_option( 'sdm_downloads_options' );
814
- echo '<input name="sdm_downloads_options[general_hide_donwload_count]" id="general_hide_download_count" type="checkbox" ' . checked( 1, isset( $main_opts[ 'general_hide_donwload_count' ] ), false ) . ' /> ';
815
- echo '<label for="general_hide_download_count">' . __( 'Hide the download count that is shown in some of the fancy templates.', 'simple-download-monitor' ) . '</label>';
816
- }
817
-
818
- public function general_default_dispatch_value_cb() {
819
- $main_opts = get_option( 'sdm_downloads_options' );
820
- $value = isset( $main_opts[ 'general_default_dispatch_value' ] ) && $main_opts[ 'general_default_dispatch_value' ];
821
- echo '<input name="sdm_downloads_options[general_default_dispatch_value]" id="general_default_dispatch_value" type="checkbox" value="1"' . checked( true, $value, false ) . ' />';
822
- echo '<label for="general_default_dispatch_value">' . __( 'When you create a new download item, The PHP Dispatching option should be enabled by default. PHP Dispatching keeps the URL of the downloadable files hidden.', 'simple-download-monitor' ) . '</label>';
823
- }
824
-
825
- public function general_only_logged_in_can_download_cb() {
826
- $main_opts = get_option( 'sdm_downloads_options' );
827
- $value = isset( $main_opts[ 'only_logged_in_can_download' ] ) && $main_opts[ 'only_logged_in_can_download' ];
828
- echo '<input name="sdm_downloads_options[only_logged_in_can_download]" id="only_logged_in_can_download" type="checkbox" value="1"' . checked( true, $value, false ) . ' />';
829
- echo '<label for="only_logged_in_can_download">' . __( 'Enable this option if you want to allow downloads only for logged-in users. When enabled, anonymous users clicking on the download button will receive an error message.', 'simple-download-monitor' ) . '</label>';
830
- }
831
-
832
- public function redirect_user_back_to_download_page_cb() {
833
- $main_opts = get_option( 'sdm_downloads_options' );
834
- $value = isset( $main_opts[ 'redirect_user_back_to_download_page' ] ) && $main_opts[ 'redirect_user_back_to_download_page' ];
835
- echo '<input name="sdm_downloads_options[redirect_user_back_to_download_page]" id="redirect_user_back_to_download_page" type="checkbox" value="1"' . checked( true, $value, false ) . ' />';
836
- echo '<label for="redirect_user_back_to_download_page">' . __( 'Only works if you have set a Login Page URL value above. Enable this option if you want to redirect the users to the download page after they log into the site.', 'simple-download-monitor' ) . '</label>';
837
- }
838
-
839
- public function general_login_page_url_cb() {
840
- $main_opts = get_option( 'sdm_downloads_options' );
841
- $value = isset( $main_opts[ 'general_login_page_url' ] ) ? $main_opts[ 'general_login_page_url' ] : '';
842
- echo '<input size="100" name="sdm_downloads_options[general_login_page_url]" id="general_login_page_url" type="text" value="' . $value . '" />';
843
- echo '<p class="description">' . __( '(Optional) Specify a login page URL where users can login. This is useful if you only allow logged in users to be able to download. This link will be added to the message that is shown to anonymous users.', 'simple-download-monitor' ) . '</p>';
844
- }
845
-
846
- public function admin_tinymce_button_cb() {
847
- $main_opts = get_option( 'sdm_downloads_options' );
848
- echo '<input name="sdm_downloads_options[admin_tinymce_button]" id="admin_tinymce_button" type="checkbox" class="sdm_opts_ajax_checkboxes" ' . checked( 1, isset( $main_opts[ 'admin_tinymce_button' ] ), false ) . ' /> ';
849
- echo '<label for="admin_tinymce_button">' . __( 'Removes the SDM Downloads button from the WP content editor.', 'simple-download-monitor' ) . '</label>';
850
- }
851
-
852
- public function admin_log_unique() {
853
- $main_opts = get_option( 'sdm_downloads_options' );
854
- echo '<input name="sdm_downloads_options[admin_log_unique]" id="admin_log_unique" type="checkbox" class="sdm_opts_ajax_checkboxes" ' . checked( 1, isset( $main_opts[ 'admin_log_unique' ] ), false ) . ' /> ';
855
- echo '<label for="admin_log_unique">' . __( 'Only logs downloads from unique IP addresses.', 'simple-download-monitor' ) . '</label>';
856
- }
857
-
858
- public function admin_do_not_capture_ip() {
859
- $main_opts = get_option( 'sdm_downloads_options' );
860
- echo '<input name="sdm_downloads_options[admin_do_not_capture_ip]" id="admin_do_not_capture_ip" type="checkbox" class="sdm_opts_ajax_checkboxes" ' . checked( 1, isset( $main_opts[ 'admin_do_not_capture_ip' ] ), false ) . ' /> ';
861
- echo '<label for="admin_do_not_capture_ip">' . __( 'Use this if you do not want to capture the IP address and Country of the visitors when they download an item.', 'simple-download-monitor' ) . '</label>';
862
- }
863
-
864
- public function admin_dont_log_bots() {
865
- $main_opts = get_option( 'sdm_downloads_options' );
866
- echo '<input name="sdm_downloads_options[admin_dont_log_bots]" id="admin_dont_log_bots" type="checkbox" class="sdm_opts_ajax_checkboxes" ' . checked( 1, isset( $main_opts[ 'admin_dont_log_bots' ] ), false ) . ' /> ';
867
- echo '<label for="admin_dont_log_bots">' . __( 'When enabled, the plugin won\'t count and log downloads from bots.', 'simple-download-monitor' ) . '</label>';
868
- }
869
-
870
- public function admin_no_logs_cb() {
871
- $main_opts = get_option( 'sdm_downloads_options' );
872
- echo '<input name="sdm_downloads_options[admin_no_logs]" id="admin_no_logs" type="checkbox" class="sdm_opts_ajax_checkboxes" ' . checked( 1, isset( $main_opts[ 'admin_no_logs' ] ), false ) . ' /> ';
873
- echo '<label for="admin_no_logs">' . __( 'Disables all download logs. (This global option overrides the individual download item option.)', 'simple-download-monitor' ) . '</label>';
874
- }
875
-
876
- public function download_button_color_cb() {
877
- $main_opts = get_option( 'sdm_downloads_options' );
878
- // Read current color class.
879
- $color_opt = isset( $main_opts[ 'download_button_color' ] ) ? $main_opts[ 'download_button_color' ] : null;
880
- $color_opts = sdm_get_download_button_colors();
881
-
882
- echo '<select name="sdm_downloads_options[download_button_color]" id="download_button_color" class="sdm_opts_ajax_dropdowns">';
883
- foreach ( $color_opts as $color_class => $color_name ) {
884
- echo '<option value="' . $color_class . '"' . selected( $color_class, $color_opt, false ) . '>' . $color_name . '</option>';
885
- }
886
- echo '</select> ';
887
- esc_html_e( 'Adjusts the color of the "Download Now" button.', 'simple-download-monitor' );
888
- }
889
-
890
- public function enable_debug_cb() {
891
- $main_opts = get_option( 'sdm_downloads_options' );
892
- echo '<input name="sdm_downloads_options[enable_debug]" id="enable_debug" type="checkbox" class="sdm_opts_ajax_checkboxes" ' . checked( 1, isset( $main_opts[ 'enable_debug' ] ), false ) . ' /> ';
893
- echo '<label for="enable_debug">' . __( 'Check this option to enable debug logging.', 'simple-download-monitor' ) .
894
- '<p class="description"><a href="' . get_admin_url() . '?sdm-action=view_log" target="_blank">' .
895
- __( 'Click here', 'simple-download-monitor' ) . '</a>' .
896
- __( ' to view log file.', 'simple-download-monitor' ) . '<br>' .
897
- '<a id="sdm-reset-log" href="#0" style="color: red">' . __( 'Click here', 'simple-download-monitor' ) . '</a>' .
898
- __( ' to reset log file.', 'simple-download-monitor' ) . '</p></label>';
899
- }
900
-
901
- public function termscond_enable_cb() {
902
- $main_opts = get_option( 'sdm_advanced_options' );
903
- echo '<input name="sdm_advanced_options[termscond_enable]" id="termscond_enable" type="checkbox" ' . checked( 1, isset( $main_opts[ 'termscond_enable' ] ), false ) . ' /> ';
904
- echo '<p class="description">' . __( 'You can use this option to make the visitors agree to your terms before they can download the item.', 'simple-download-monitor' ) . '</p>';
905
- }
906
-
907
- public function termscond_url_cb() {
908
- $main_opts = get_option( 'sdm_advanced_options' );
909
- $value = isset( $main_opts[ 'termscond_url' ] ) ? $main_opts[ 'termscond_url' ] : '';
910
- echo '<input size="100" name="sdm_advanced_options[termscond_url]" id="termscond_url" type="text" value="' . $value . '" /> ';
911
- echo '<p class="description">' . __( 'Enter the URL of your terms and conditions page.', 'simple-download-monitor' ) . '</p>';
912
- }
913
-
914
- public function adsense_below_description_cb() {
915
- $main_opts = get_option( 'sdm_advanced_options' );
916
- $value = isset( $main_opts[ 'adsense_below_description' ] ) ? $main_opts[ 'adsense_below_description' ] : '';
917
- //echo '<input size="100" name="sdm_advanced_options[adsense_below_description]" id="adsense_below_description" type="text" value="'.$value.'" /> ';
918
- echo '<textarea name="sdm_advanced_options[adsense_below_description]" id="adsense_below_description" rows="6" cols="60">' . $value . '</textarea>';
919
- echo '<p class="description">' . __( 'Enter the Adsense or Ad code that you want to show below the download item description.', 'simple-download-monitor' ) . '</p>';
920
- }
921
-
922
- public function maps_api_key_cb() {
923
- $main_opts = get_option( 'sdm_advanced_options' );
924
- $value = isset( $main_opts[ 'maps_api_key' ] ) ? $main_opts[ 'maps_api_key' ] : '';
925
- echo '<input size="100" name="sdm_advanced_options[maps_api_key]" id="maps_api_key" type="text" value="' . $value . '" />';
926
- echo '<p class="description">' . __( 'Enter your Google Maps API key. You can create new API key using <a href="https://developers.google.com/maps/documentation/javascript/get-api-key" target="_blank">this instruction</a>.', 'simple-download-monitor' ) . '</p>';
927
- }
928
-
929
- public function sdm_add_clone_record_btn( $action, $post ) {
930
- // Only execute on SDM CPT posts page
931
- if ( $post->post_type == 'sdm_downloads' ) {
932
- $action[ 'clone' ] = sprintf(
933
- '<a href="%2$s" aria-label="%1$s">%1$s</a>', esc_html__( 'Clone', 'simple-download-monitor' ), $this->get_duplicate_url( $post->ID )
934
- );
935
- }
936
- return $action;
937
- }
938
-
939
- /**
940
- * Returns duplicate post URL
941
- *
942
- * @return string
943
- */
944
- public function get_duplicate_url( $post_id ) {
945
- global $wp;
946
- return add_query_arg( array(
947
- 'action' => 'sdm_clone_post',
948
- 'post' => $post_id,
949
- 'ref' => urlencode( add_query_arg( $wp->query_string, '', home_url( $wp->request ) ) ),
950
- '_nonce' => wp_create_nonce( 'sdm_downloads' )
951
- ), esc_url( admin_url( 'admin.php' ) )
952
- );
953
- }
954
 
955
- public function sdm_action_clone_post() {
 
 
 
 
956
 
957
- global $wpdb;
958
- if ( ! ( isset( $_GET[ 'post' ] ) || isset( $_POST[ 'post' ] ) || ( isset( $_REQUEST[ 'action' ] ) && 'sdm_clone_post' == $_REQUEST[ 'action' ] ) ) ) {
959
- wp_die( __( 'No post to duplicate has been supplied!', 'simple-download-monitor' ) );
 
 
 
960
  }
961
 
962
- /*
963
- * Nonce verification
964
- */
965
- if ( ! isset( $_GET[ '_nonce' ] ) || ! wp_verify_nonce( $_GET[ '_nonce' ], 'sdm_downloads' ) )
966
- return;
 
 
 
 
 
967
 
968
- /*
969
- * get the original post id
970
- */
971
- $post_id = (isset( $_GET[ 'post' ] ) ? absint( $_GET[ 'post' ] ) : absint( $_POST[ 'post' ] ) );
972
- /*
973
- * and all the original post data then
974
- */
975
- $post = get_post( $post_id );
976
 
977
- /*
978
- * if you don't want current user to be the new post author,
979
- * then change next couple of lines to this: $new_post_author = $post->post_author;
980
- */
981
- $current_user = wp_get_current_user();
982
- $new_post_author = $current_user->ID;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
983
 
984
- /*
985
- * if post data exists, create the post duplicate
 
 
986
  */
987
- if ( isset( $post ) && $post != null ) {
988
-
989
- /*
990
- * new post data array
991
- */
992
- $args = array(
993
- 'comment_status' => $post->comment_status,
994
- 'ping_status' => $post->ping_status,
995
- 'post_author' => $new_post_author,
996
- 'post_content' => $post->post_content,
997
- 'post_excerpt' => $post->post_excerpt,
998
- 'post_name' => $post->post_name,
999
- 'post_parent' => $post->post_parent,
1000
- 'post_password' => $post->post_password,
1001
- 'post_status' => 'draft',
1002
- 'post_title' => $post->post_title,
1003
- 'post_type' => $post->post_type,
1004
- 'to_ping' => $post->to_ping,
1005
- 'menu_order' => $post->menu_order
1006
- );
1007
-
1008
- /*
1009
- * insert the post by wp_insert_post() function
1010
- */
1011
- $new_post_id = wp_insert_post( $args );
1012
-
1013
- /*
1014
- * get all current post terms ad set them to the new post draft
1015
- */
1016
- $taxonomies = get_object_taxonomies( $post->post_type ); // returns array of taxonomy names for post type, ex array("category", "post_tag");
1017
- foreach ( $taxonomies as $taxonomy ) {
1018
- $post_terms = wp_get_object_terms( $post_id, $taxonomy, array( 'fields' => 'slugs' ) );
1019
- wp_set_object_terms( $new_post_id, $post_terms, $taxonomy, false );
1020
- }
1021
-
1022
- /*
1023
- * duplicate all post meta just in two SQL queries
1024
- */
1025
- $post_meta_infos = $wpdb->get_results( "SELECT meta_key, meta_value FROM $wpdb->postmeta WHERE post_id=$post_id" );
1026
- if ( count( $post_meta_infos ) != 0 ) {
1027
- $sql_query = "INSERT INTO $wpdb->postmeta (post_id, meta_key, meta_value) ";
1028
- foreach ( $post_meta_infos as $meta_info ) {
1029
- $meta_key = $meta_info->meta_key;
1030
- if ( $meta_key == '_wp_old_slug' )
1031
- continue;
1032
- $meta_value = addslashes( $meta_info->meta_value );
1033
- $sql_query_sel[] = "SELECT $new_post_id, '$meta_key', '$meta_value'";
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1034
  }
1035
- $sql_query .= implode( " UNION ALL ", $sql_query_sel );
1036
- $wpdb->query( $sql_query );
1037
- }
1038
-
1039
- /*
1040
- * finally, redirect to the edit post screen for the new draft
1041
- */
1042
- wp_redirect( admin_url( 'post.php?action=edit&post=' . $new_post_id ) );
1043
- exit;
1044
- } else {
1045
- wp_die( __( 'Post creation failed, could not find original post: ', 'simple-download-monitor' ) . $post_id );
1046
  }
1047
- }
1048
 
1049
  }
1050
 
@@ -1058,20 +1081,29 @@ add_action( 'wp_ajax_sdm_tiny_get_post_ids', 'sdm_tiny_get_post_ids_ajax_call' )
1058
 
1059
  function sdm_tiny_get_post_ids_ajax_call() {
1060
 
1061
- $posts = get_posts( array(
1062
- 'post_type' => 'sdm_downloads',
1063
- 'numberposts' => -1,
1064
- )
1065
- );
1066
- foreach ( $posts as $item ) {
1067
- $test[] = array( 'post_id' => $item->ID, 'post_title' => $item->post_title );
1068
- }
 
 
 
 
1069
 
1070
- $response = json_encode( array( 'success' => true, 'test' => $test ) );
 
 
 
 
 
1071
 
1072
- header( 'Content-Type: application/json' );
1073
- echo $response;
1074
- exit;
1075
  }
1076
 
1077
  //Remove Thumbnail Image
@@ -1079,28 +1111,28 @@ function sdm_tiny_get_post_ids_ajax_call() {
1079
  add_action( 'wp_ajax_sdm_remove_thumbnail_image', 'sdm_remove_thumbnail_image_ajax_call' ); //Execute this for authenticated users only
1080
 
1081
  function sdm_remove_thumbnail_image_ajax_call() {
1082
- if ( ! current_user_can( 'edit_posts' ) ) {
1083
- //Permission denied
1084
- wp_die( __( 'Permission denied!', 'simple-download-monitor' ) );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1085
  exit;
1086
- }
1087
-
1088
- //Go ahead with the thumbnail removal
1089
- $post_id = intval( $_POST[ 'post_id_del' ] );
1090
- $key_exists = metadata_exists( 'post', $post_id, 'sdm_upload_thumbnail' );
1091
- if ( $key_exists ) {
1092
- $success = delete_post_meta( $post_id, 'sdm_upload_thumbnail' );
1093
- if ( $success ) {
1094
- $response = json_encode( array( 'success' => true ) );
1095
- }
1096
- } else {
1097
- // in order for frontend script to not display "Ajax error", let's return some data
1098
- $response = json_encode( array( 'not_exists' => true ) );
1099
- }
1100
-
1101
- header( 'Content-Type: application/json' );
1102
- echo $response;
1103
- exit;
1104
  }
1105
 
1106
  // Populate category tree
@@ -1109,37 +1141,43 @@ add_action( 'wp_ajax_sdm_pop_cats', 'sdm_pop_cats_ajax_call' );
1109
 
1110
  function sdm_pop_cats_ajax_call() {
1111
 
1112
- $cat_slug = sanitize_text_field( $_POST[ 'cat_slug' ] ); // Get button cpt slug
1113
- $parent_id = intval( $_POST[ 'parent_id' ] ); // Get button cpt id
1114
- // Query custom posts based on taxonomy slug
1115
- $posts = get_posts( array(
1116
- 'post_type' => 'sdm_downloads',
1117
- 'numberposts' => -1,
1118
- 'tax_query' => array(
1119
- array(
1120
- 'taxonomy' => 'sdm_categories',
1121
- 'field' => 'slug',
1122
- 'terms' => $cat_slug,
1123
- 'include_children' => 0
1124
- )
1125
- ),
1126
- 'orderby' => 'title',
1127
- 'order' => 'ASC' )
1128
- );
1129
-
1130
- $final_array = array();
1131
-
1132
- // Loop results
1133
- foreach ( $posts as $post ) {
1134
- // Create array of variables to pass to js
1135
- $final_array[] = array( 'id' => $post->ID, 'permalink' => get_permalink( $post->ID ), 'title' => $post->post_title );
1136
- }
1137
-
1138
- // Generate ajax response
1139
- $response = json_encode( array( 'final_array' => $final_array ) );
1140
- header( 'Content-Type: application/json' );
1141
- echo $response;
1142
- exit;
 
 
 
 
 
 
1143
  }
1144
 
1145
  /*
@@ -1151,54 +1189,54 @@ add_action( 'manage_sdm_downloads_posts_custom_column', 'sdm_downloads_columns_c
1151
 
1152
  function sdm_create_columns( $cols ) {
1153
 
1154
- unset( $cols[ 'title' ] );
1155
- unset( $cols[ 'taxonomy-sdm_tags' ] );
1156
- unset( $cols[ 'taxonomy-sdm_categories' ] );
1157
- unset( $cols[ 'date' ] );
1158
-
1159
- $cols[ 'title' ] = __( 'Title', 'simple-download-monitor' );
1160
- $cols[ 'sdm_downloads_thumbnail' ] = __( 'Image', 'simple-download-monitor' );
1161
- $cols[ 'sdm_downloads_id' ] = __( 'ID', 'simple-download-monitor' );
1162
- $cols[ 'sdm_downloads_file' ] = __( 'File', 'simple-download-monitor' );
1163
- $cols[ 'taxonomy-sdm_categories' ] = __( 'Categories', 'simple-download-monitor' );
1164
- $cols[ 'taxonomy-sdm_tags' ] = __( 'Tags', 'simple-download-monitor' );
1165
- $cols[ 'sdm_downloads_count' ] = __( 'Downloads', 'simple-download-monitor' );
1166
- $cols[ 'date' ] = __( 'Date Posted', 'simple-download-monitor' );
1167
- return $cols;
1168
  }
1169
 
1170
  function sdm_downloads_sortable( $cols ) {
1171
 
1172
- $cols[ 'sdm_downloads_id' ] = 'sdm_downloads_id';
1173
- $cols[ 'sdm_downloads_file' ] = 'sdm_downloads_file';
1174
- $cols[ 'sdm_downloads_count' ] = 'sdm_downloads_count';
1175
- $cols[ 'taxonomy-sdm_categories' ] = 'taxonomy-sdm_categories';
1176
- $cols[ 'taxonomy-sdm_tags' ] = 'taxonomy-sdm_tags';
1177
- return $cols;
1178
  }
1179
 
1180
  function sdm_downloads_columns_content( $column_name, $post_ID ) {
1181
 
1182
- if ( $column_name == 'sdm_downloads_thumbnail' ) {
1183
- $old_thumbnail = get_post_meta( $post_ID, 'sdm_upload_thumbnail', true );
1184
- //$old_value = isset($old_thumbnail) ? $old_thumbnail : '';
1185
- if ( $old_thumbnail ) {
1186
- echo '<p class="sdm_downloads_thumbnail_in_admin_listing"><img src="' . $old_thumbnail . '" style="width:50px;height:50px;" /></p>';
1187
- }
1188
- }
1189
- if ( $column_name == 'sdm_downloads_id' ) {
1190
- echo '<p class="sdm_downloads_postid">' . $post_ID . '</p>';
1191
- }
1192
- if ( $column_name == 'sdm_downloads_file' ) {
1193
- $old_file = get_post_meta( $post_ID, 'sdm_upload', true );
1194
- $file = isset( $old_file ) ? $old_file : '--';
1195
- echo '<p class="sdm_downloads_file">' . $file . '</p>';
1196
- }
1197
- if ( $column_name == 'sdm_downloads_count' ) {
1198
- global $wpdb;
1199
- $wpdb->get_results( $wpdb->prepare( 'SELECT * FROM ' . $wpdb->prefix . 'sdm_downloads WHERE post_id=%s', $post_ID ) );
1200
- echo '<p class="sdm_downloads_count">' . $wpdb->num_rows . '</p>';
1201
- }
1202
  }
1203
 
1204
  /*
@@ -1206,29 +1244,53 @@ function sdm_downloads_columns_content( $column_name, $post_ID ) {
1206
  */
1207
 
1208
  // First check if option is checked to disable tinymce button
1209
- $main_option = get_option( 'sdm_downloads_options' );
1210
- $tiny_button_option = isset( $main_option[ 'admin_tinymce_button' ] );
1211
- if ( $tiny_button_option != true ) {
1212
 
1213
- // Okay.. we're good. Add the button.
1214
- add_action( 'init', 'sdm_downloads_tinymce_button' );
1215
 
1216
- function sdm_downloads_tinymce_button() {
 
 
1217
 
1218
- add_filter( 'mce_external_plugins', 'sdm_downloads_add_button' );
1219
- add_filter( 'mce_buttons', 'sdm_downloads_register_button' );
1220
- }
1221
 
1222
- function sdm_downloads_add_button( $plugin_array ) {
 
 
 
 
1223
 
1224
- $plugin_array[ 'sdm_downloads' ] = WP_SIMPLE_DL_MONITOR_URL . '/tinymce/sdm_editor_plugin.js';
1225
- return $plugin_array;
1226
- }
1227
 
1228
- function sdm_downloads_register_button( $buttons ) {
1229
 
1230
- $buttons[] = 'sdm_downloads';
1231
- return $buttons;
1232
- }
1233
 
1234
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3
  * Plugin Name: Simple Download Monitor
4
  * Plugin URI: https://simple-download-monitor.com/
5
  * Description: Easily manage downloadable files and monitor downloads of your digital files from your WordPress site.
6
+ * Version: 3.8.7
7
  * Author: Tips and Tricks HQ, Ruhul Amin, Josh Lobe
8
  * Author URI: https://www.tipsandtricks-hq.com/development-center
9
  * License: GPL2
11
  * Domain Path: /languages/
12
  */
13
  if ( ! defined( 'ABSPATH' ) ) {
14
+ exit;
15
  }
16
 
17
+ define( 'WP_SIMPLE_DL_MONITOR_VERSION', '3.8.7' );
18
  define( 'WP_SIMPLE_DL_MONITOR_DIR_NAME', dirname( plugin_basename( __FILE__ ) ) );
19
  define( 'WP_SIMPLE_DL_MONITOR_URL', plugins_url( '', __FILE__ ) );
20
  define( 'WP_SIMPLE_DL_MONITOR_PATH', plugin_dir_path( __FILE__ ) );
22
  define( 'WP_SDM_LOG_FILE', WP_SIMPLE_DL_MONITOR_PATH . 'sdm-debug-log.txt' );
23
 
24
  global $sdm_db_version;
25
+ $sdm_db_version = '1.3';
26
 
27
  //File includes
28
+ require_once 'includes/sdm-debug.php';
29
+ require_once 'includes/sdm-utility-functions.php';
30
+ require_once 'includes/sdm-utility-functions-admin-side.php';
31
+ require_once 'includes/sdm-download-request-handler.php';
32
+ require_once 'includes/sdm-user-login-related.php';
33
+ require_once 'includes/sdm-logs-list-table.php';
34
+ require_once 'includes/sdm-latest-downloads.php';
35
+ require_once 'includes/sdm-popular-downloads.php';
36
+ require_once 'includes/sdm-search-shortcode-handler.php';
37
+ require_once 'sdm-post-type-and-taxonomy.php';
38
+ require_once 'sdm-shortcodes.php';
39
+ require_once 'sdm-post-type-content-handler.php';
40
 
41
  if ( is_admin() ) {
42
  //load addons update checker class
48
 
49
  function sdm_install_db_table() {
50
 
51
+ global $wpdb;
52
+ global $sdm_db_version;
53
+ $table_name = $wpdb->prefix . 'sdm_downloads';
54
 
55
+ $sql = 'CREATE TABLE ' . $table_name . ' (
56
  id mediumint(9) NOT NULL AUTO_INCREMENT,
57
  post_id mediumint(9) NOT NULL,
58
  post_title mediumtext NOT NULL,
61
  date_time datetime DEFAULT "0000-00-00 00:00:00" NOT NULL,
62
  visitor_country mediumtext NOT NULL,
63
  visitor_name mediumtext NOT NULL,
64
+ user_agent mediumtext NOT NULL,
65
  UNIQUE KEY id (id)
66
  );';
67
 
68
+ require_once ABSPATH . 'wp-admin/includes/upgrade.php';
69
+ dbDelta( $sql );
70
 
71
+ update_option( 'sdm_db_version', $sdm_db_version );
72
 
73
+ //Register the post type so you can flush the rewrite rules
74
+ sdm_register_post_type();
75
 
76
+ // Flush rules after install/activation
77
+ flush_rewrite_rules();
78
  }
79
 
80
  /*
83
  add_action( 'plugins_loaded', 'sdm_plugins_loaded_tasks' );
84
 
85
  function sdm_plugins_loaded_tasks() {
86
+ //Load language
87
+ load_plugin_textdomain( 'simple-download-monitor', false, dirname( plugin_basename( __FILE__ ) ) . '/languages/' );
88
 
89
+ //Handle db upgrade stuff
90
+ sdm_db_update_check();
91
  }
92
 
93
  /*
97
  add_action( 'admin_init', 'sdm_admin_init_time_tasks' );
98
 
99
  function sdm_init_time_tasks() {
100
+ //Handle download request if any
101
+ handle_sdm_download_via_direct_post();
102
 
103
+ //Check if the redirect option is being used
104
+ sdm_check_redirect_query_and_settings();
105
 
106
+ if ( is_admin() ) {
107
+ //Register Google Charts library
108
+ wp_register_script( 'sdm_google_charts', 'https://www.gstatic.com/charts/loader.js', array(), null, true );
109
+ wp_register_style( 'sdm_jquery_ui_style', WP_SIMPLE_DL_MONITOR_URL . '/css/jquery.ui.min.css', array(), null, 'all' );
110
+ }
111
  }
112
 
113
  function sdm_admin_init_time_tasks() {
114
+ //Register ajax handlers
115
+ add_action( 'wp_ajax_sdm_reset_log', 'sdm_reset_log_handler' );
116
+ add_action( 'wp_ajax_sdm_delete_data', 'sdm_delete_data_handler' );
117
+
118
+ if ( is_admin() ) {
119
+ if ( user_can( wp_get_current_user(), 'administrator' ) ) {
120
+ // user is an admin
121
+ if ( isset( $_GET['sdm-action'] ) ) {
122
+ if ( $_GET['sdm-action'] === 'view_log' ) {
123
+ $logfile = fopen( WP_SDM_LOG_FILE, 'rb' );
124
+ header( 'Content-Type: text/plain' );
125
+ fpassthru( $logfile );
126
+ die;
127
+ }
128
+ }
129
  }
 
130
  }
 
131
  }
132
 
133
  function sdm_reset_log_handler() {
134
+ SDM_Debug::reset_log();
135
+ echo '1';
136
+ wp_die();
137
  }
138
 
139
  function sdm_delete_data_handler() {
140
+ if ( ! check_ajax_referer( 'sdm_delete_data', 'nonce', false ) ) {
141
+ //nonce check failed
142
+ wp_die( 0 );
143
+ }
144
+ global $wpdb;
145
+ //let's find and delete smd_download posts and meta
146
+ $posts = $wpdb->get_results( 'SELECT id FROM ' . $wpdb->prefix . 'posts WHERE post_type="sdm_downloads"', ARRAY_A );
147
+ if ( ! is_null( $posts ) ) {
148
+ foreach ( $posts as $post ) {
149
+ wp_delete_post( $post['id'], true );
150
+ }
151
+ }
152
+ //let's delete options
153
+ delete_option( 'sdm_downloads_options' );
154
+ delete_option( 'sdm_db_version' );
155
+ //remove post type and taxonomies
156
+ unregister_post_type( 'sdm_downloads' );
157
+ unregister_taxonomy( 'sdm_categories' );
158
+ unregister_taxonomy( 'sdm_tags' );
159
+ //let's delete sdm_downloads table
160
+ $wpdb->query( 'DROP TABLE ' . $wpdb->prefix . 'sdm_downloads' );
161
+ //deactivate plugin
162
+ deactivate_plugins( plugin_basename( __FILE__ ) );
163
+ //flush rewrite rules
164
+ flush_rewrite_rules( false );
165
+ echo '1';
166
+ wp_die();
167
  }
168
 
169
  /*
171
  */
172
 
173
  function sdm_db_update_check() {
174
+ if ( is_admin() ) {//Check if DB needs to be upgraded
175
+ global $sdm_db_version;
176
+ $inst_db_version = get_option( 'sdm_db_version' );
177
+ if ( $inst_db_version != $sdm_db_version ) {
178
+ sdm_install_db_table();
179
+ }
180
  }
 
181
  }
182
 
183
  /*
186
  add_filter( 'plugin_action_links', 'sdm_settings_link', 10, 2 );
187
 
188
  function sdm_settings_link( $links, $file ) {
189
+ static $this_plugin;
190
+ if ( ! $this_plugin ) {
191
+ $this_plugin = plugin_basename( __FILE__ );
192
+ }
193
+ if ( $file == $this_plugin ) {
194
+ $settings_link = '<a href="edit.php?post_type=sdm_downloads&page=sdm-settings" title="SDM Settings Page">' . __( 'Settings', 'simple-download-monitor' ) . '</a>';
195
+ array_unshift( $links, $settings_link );
196
+ }
197
+ return $links;
198
  }
199
 
200
  // Houston... we have lift-off!!
201
  class simpleDownloadManager {
202
 
203
+ public function __construct() {
204
 
205
+ add_action( 'init', 'sdm_register_post_type' ); // Create 'sdm_downloads' custom post type
206
+ add_action( 'init', 'sdm_create_taxonomies' ); // Register 'tags' and 'categories' taxonomies
207
+ add_action( 'init', 'sdm_register_shortcodes' ); //Register the shortcodes
208
+ add_action( 'wp_enqueue_scripts', array( $this, 'sdm_frontend_scripts' ) ); // Register frontend scripts
209
+ include_once 'includes/sdm-blocks.php';
210
 
211
+ if ( is_admin() ) {
212
+ add_action( 'admin_menu', array( $this, 'sdm_create_menu_pages' ) ); // Create admin pages
213
+ add_action( 'add_meta_boxes', array( $this, 'sdm_create_upload_metabox' ) ); // Create metaboxes
214
+
215
+ add_action( 'save_post', array( $this, 'sdm_save_description_meta_data' ) ); // Save 'description' metabox
216
+ add_action( 'save_post', array( $this, 'sdm_save_upload_meta_data' ) ); // Save 'upload file' metabox
217
+ add_action( 'save_post', array( $this, 'sdm_save_dispatch_meta_data' ) ); // Save 'dispatch' metabox
218
+ add_action( 'save_post', array( $this, 'sdm_save_misc_properties_meta_data' ) ); // Save 'misc properties/settings' metabox
219
+ add_action( 'save_post', array( $this, 'sdm_save_thumbnail_meta_data' ) ); // Save 'thumbnail' metabox
220
+ add_action( 'save_post', array( $this, 'sdm_save_statistics_meta_data' ) ); // Save 'statistics' metabox
221
+ add_action( 'save_post', array( $this, 'sdm_save_other_details_meta_data' ) ); // Save 'other details' metabox
222
+
223
+ add_action( 'admin_enqueue_scripts', array( $this, 'sdm_admin_scripts' ) ); // Register admin scripts
224
+ add_action( 'admin_print_styles', array( $this, 'sdm_admin_styles' ) ); // Register admin styles
225
+
226
+ add_action( 'admin_init', array( $this, 'sdm_register_options' ) ); // Register admin options
227
+ //add_filter('post_row_actions', array($this, 'sdm_remove_view_link_cpt'), 10, 2); // Remove 'View' link in all downloads list view
228
+
229
+ add_filter( 'page_row_actions', array( $this, 'sdm_add_clone_record_btn' ), 10, 2 ); // Add 'Clone' link in all downloads list view
230
+ add_filter( 'post_row_actions', array( $this, 'sdm_add_clone_record_btn' ), 10, 2 ); // Add 'Clone' link in all downloads list view
231
+
232
+ add_action( 'admin_action_sdm_clone_post', array( $this, 'sdm_action_clone_post' ) );
233
+ }
234
+ }
235
+
236
+ public function sdm_admin_scripts() {
237
+
238
+ global $current_screen, $post;
239
+
240
+ if ( is_admin() && $current_screen->post_type == 'sdm_downloads' && $current_screen->base == 'post' ) {
241
+
242
+ // These scripts are needed for the media upload thickbox
243
+ wp_enqueue_script( 'media-upload' );
244
+ wp_enqueue_script( 'thickbox' );
245
+ wp_register_script( 'sdm-upload', WP_SIMPLE_DL_MONITOR_URL . '/js/sdm_admin_scripts.js', array( 'jquery', 'media-upload', 'thickbox' ), WP_SIMPLE_DL_MONITOR_VERSION );
246
+ wp_enqueue_script( 'sdm-upload' );
247
+
248
+ // Localize langauge strings used in js file
249
+ $sdmTranslations = array(
250
+ 'select_file' => __( 'Select File', 'simple-download-monitor' ),
251
+ 'select_thumbnail' => __( 'Select Thumbnail', 'simple-download-monitor' ),
252
+ 'insert' => __( 'Insert', 'simple-download-monitor' ),
253
+ 'image_removed' => __( 'Image Successfully Removed', 'simple-download-monitor' ),
254
+ 'ajax_error' => __( 'Error with AJAX', 'simple-download-monitor' ),
255
+ );
256
+ wp_localize_script( 'sdm-upload', 'sdm_translations', $sdmTranslations );
257
+ }
258
+ }
259
+
260
+ public function sdm_frontend_scripts() {
261
+ //Use this function to enqueue fron-end js scripts.
262
+ wp_enqueue_style( 'sdm-styles', WP_SIMPLE_DL_MONITOR_URL . '/css/sdm_wp_styles.css' );
263
+ wp_register_script( 'sdm-scripts', WP_SIMPLE_DL_MONITOR_URL . '/js/sdm_wp_scripts.js', array( 'jquery' ) );
264
+ wp_enqueue_script( 'sdm-scripts' );
265
+
266
+ //Check if reCAPTCHA is enabled.
267
+ $main_advanced_opts = get_option( 'sdm_advanced_options' );
268
+ $recaptcha_enable = isset( $main_advanced_opts['recaptcha_enable'] ) ? true : false;
269
+ if ( $recaptcha_enable ) {
270
+ wp_register_script( 'sdm-recaptcha-scripts-js', WP_SIMPLE_DL_MONITOR_URL . '/js/sdm_g_recaptcha.js', array(), true );
271
+ wp_localize_script( 'sdm-recaptcha-scripts-js', 'sdm_recaptcha_opt', array( 'site_key' => $main_advanced_opts['recaptcha_site_key'] ) );
272
+ wp_register_script( 'sdm-recaptcha-scripts-lib', '//www.google.com/recaptcha/api.js?hl=' . get_locale() . '&onload=sdm_reCaptcha&render=explicit', array(), false );
273
+ wp_enqueue_script( 'sdm-recaptcha-scripts-js' );
274
+ wp_enqueue_script( 'sdm-recaptcha-scripts-lib' );
275
+ }
276
+
277
+ // Localize ajax script for frontend
278
+ wp_localize_script( 'sdm-scripts', 'sdm_ajax_script', array( 'ajaxurl' => admin_url( 'admin-ajax.php' ) ) );
279
+ }
280
+
281
+ public function sdm_admin_styles() {
282
+
283
+ wp_enqueue_style( 'thickbox' ); // Needed for media upload thickbox
284
+ wp_enqueue_style( 'sdm_admin_styles', WP_SIMPLE_DL_MONITOR_URL . '/css/sdm_admin_styles.css', array(), WP_SIMPLE_DL_MONITOR_VERSION ); // Needed for media upload thickbox
285
+ }
286
+
287
+ public function sdm_create_menu_pages() {
288
+ include_once 'includes/sdm-admin-menu-handler.php';
289
+ sdm_handle_admin_menu();
290
+ }
291
+
292
+ public function sdm_create_upload_metabox() {
293
+
294
+ //***** Create metaboxes for the custom post type
295
+ add_meta_box( 'sdm_description_meta_box', __( 'Description', 'simple-download-monitor' ), array( $this, 'display_sdm_description_meta_box' ), 'sdm_downloads', 'normal', 'default' );
296
+ add_meta_box( 'sdm_upload_meta_box', __( 'Downloadable File (Visitors will download this item)', 'simple-download-monitor' ), array( $this, 'display_sdm_upload_meta_box' ), 'sdm_downloads', 'normal', 'default' );
297
+ add_meta_box( 'sdm_dispatch_meta_box', __( 'PHP Dispatch or Redirect', 'simple-download-monitor' ), array( $this, 'display_sdm_dispatch_meta_box' ), 'sdm_downloads', 'normal', 'default' );
298
+ add_meta_box( 'sdm_misc_properties_meta_box', __( 'Miscellaneous Download Item Properties', 'simple-download-monitor' ), array( $this, 'display_sdm_misc_properties_meta_box' ), 'sdm_downloads', 'normal', 'default' ); // Meta box for misc properies/settings
299
+ add_meta_box( 'sdm_thumbnail_meta_box', __( 'File Thumbnail (Optional)', 'simple-download-monitor' ), array( $this, 'display_sdm_thumbnail_meta_box' ), 'sdm_downloads', 'normal', 'default' );
300
+ add_meta_box( 'sdm_stats_meta_box', __( 'Statistics', 'simple-download-monitor' ), array( $this, 'display_sdm_stats_meta_box' ), 'sdm_downloads', 'normal', 'default' );
301
+ do_action( 'sdm_admin_add_edit_download_before_other_details_meta_box_action' );
302
+ add_meta_box( 'sdm_other_details_meta_box', __( 'Other Details (Optional)', 'simple-download-monitor' ), array( $this, 'display_sdm_other_details_meta_box' ), 'sdm_downloads', 'normal', 'default' );
303
+ add_meta_box( 'sdm_shortcode_meta_box', __( 'Shortcodes', 'simple-download-monitor' ), array( $this, 'display_sdm_shortcode_meta_box' ), 'sdm_downloads', 'normal', 'default' );
304
+ }
305
+
306
+ public function display_sdm_description_meta_box( $post ) {
307
+ // Description metabox
308
+ _e( 'Add a description for this download item.', 'simple-download-monitor' );
309
+ echo '<br /><br />';
310
+
311
+ $old_description = get_post_meta( $post->ID, 'sdm_description', true );
312
+ $sdm_description_field = array( 'textarea_name' => 'sdm_description' );
313
+ wp_editor( $old_description, 'sdm_description_editor_content', $sdm_description_field );
314
+
315
+ wp_nonce_field( 'sdm_description_box_nonce', 'sdm_description_box_nonce_check' );
316
+ }
317
+
318
+ public function display_sdm_upload_meta_box( $post ) {
319
+ // File Upload metabox
320
+ $old_upload = get_post_meta( $post->ID, 'sdm_upload', true );
321
+ $old_value = isset( $old_upload ) ? $old_upload : '';
322
+
323
+ //Trigger filter to allow "sdm_upload" field validation override.
324
+ $url_validation_override = apply_filters( 'sdm_file_download_url_validation_override', '' );
325
+ if ( ! empty( $url_validation_override ) ) {
326
+ //This site has customized the behavior and overriden the "sdm_upload" field validation. It can be useful if you are offering app download URLs (that has unconventional URL patterns).
327
+ } else {
328
+ //Do the normal URL validation.
329
+ $old_value = esc_url( $old_value );
330
+ }
331
+
332
+ _e( 'Manually enter a valid URL of the file in the text box below, or click "Select File" button to upload (or choose) the downloadable file.', 'simple-download-monitor' );
333
+ echo '<br /><br />';
334
+
335
+ echo '<div class="sdm-download-edit-file-url-section">';
336
+ echo '<input id="sdm_upload" type="text" size="100" name="sdm_upload" value="' . $old_value . '" placeholder="http://..." />';
337
+ echo '</div>';
338
+
339
+ echo '<br />';
340
+ echo '<input id="upload_image_button" type="button" class="button-primary" value="' . __( 'Select File', 'simple-download-monitor' ) . '" />';
341
+
342
+ echo '<br /><br />';
343
+ _e( 'Steps to upload a file or choose one from your media library:', 'simple-download-monitor' );
344
+ echo '<ol>';
345
+ echo '<li>' . __( 'Hit the "Select File" button.', 'simple-download-monitor' ) . '</li>';
346
+ echo '<li>' . __( 'Upload a new file or choose an existing one from your media library.', 'simple-download-monitor' ) . '</li>';
347
+ echo '<li>' . __( 'Click the "Insert" button, this will populate the uploaded file\'s URL in the above text field.', 'simple-download-monitor' ) . '</li>';
348
+ echo '</ol>';
349
+
350
+ wp_nonce_field( 'sdm_upload_box_nonce', 'sdm_upload_box_nonce_check' );
351
+ }
352
+
353
+ public function display_sdm_dispatch_meta_box( $post ) {
354
+ $dispatch = get_post_meta( $post->ID, 'sdm_item_dispatch', true );
355
+
356
+ if ( $dispatch === '' ) {
357
+ // No value yet (either new item or saved with older version of plugin)
358
+ $screen = get_current_screen();
359
+
360
+ if ( $screen->action === 'add' ) {
361
+ // New item: set default value as per plugin settings.
362
+ $main_opts = get_option( 'sdm_downloads_options' );
363
+ $dispatch = isset( $main_opts['general_default_dispatch_value'] ) && $main_opts['general_default_dispatch_value'];
364
+ }
365
+ }
366
+
367
+ echo '<input id="sdm_item_dispatch" type="checkbox" name="sdm_item_dispatch" value="yes"' . checked( true, $dispatch, false ) . ' />';
368
+ echo '<label for="sdm_item_dispatch">' . __( 'Dispatch the file via PHP directly instead of redirecting to it. PHP Dispatching keeps the download URL hidden. Dispatching works only for local files (files that you uploaded to this site via this plugin or media library).', 'simple-download-monitor' ) . '</label>';
369
+
370
+ wp_nonce_field( 'sdm_dispatch_box_nonce', 'sdm_dispatch_box_nonce_check' );
371
+ }
372
+
373
+ // Open Download in new window
374
+ public function display_sdm_misc_properties_meta_box( $post ) {
375
+
376
+ //Check the open in new window value
377
+ $new_window = get_post_meta( $post->ID, 'sdm_item_new_window', true );
378
+ if ( $new_window === '' ) {
379
+ // No value yet (either new item or saved with older version of plugin)
380
+ $screen = get_current_screen();
381
+ if ( $screen->action === 'add' ) {
382
+ //New item: we can set a default value as per plugin settings. If a general settings is introduced at a later stage.
383
+ //Does nothing at the moment.
384
+ }
385
+ }
386
+
387
+ //Check the sdm_item_disable_single_download_page value
388
+ $sdm_item_disable_single_download_page = get_post_meta( $post->ID, 'sdm_item_disable_single_download_page', true );
389
+ $sdm_item_hide_dl_button_single_download_page = get_post_meta( $post->ID, 'sdm_item_hide_dl_button_single_download_page', true );
390
+
391
+ echo '<p> <input id="sdm_item_new_window" type="checkbox" name="sdm_item_new_window" value="yes"' . checked( true, $new_window, false ) . ' />';
392
+ echo '<label for="sdm_item_new_window">' . __( 'Open download in a new window.', 'simple-download-monitor' ) . '</label> </p>';
393
+
394
+ //the new window will have no download button
395
+ echo '<p> <input id="sdm_item_hide_dl_button_single_download_page" type="checkbox" name="sdm_item_hide_dl_button_single_download_page" value="yes"' . checked( true, $sdm_item_hide_dl_button_single_download_page, false ) . ' />';
396
+ echo '<label for="sdm_item_hide_dl_button_single_download_page">';
397
+
398
+ $disable_dl_button_label = __( 'Hide the download button on the single download page of this item.', 'simple-download-monitor' );
399
+ echo $disable_dl_button_label . '</label>';
400
+ echo '</p>';
401
+
402
+ echo '<p> <input id="sdm_item_disable_single_download_page" type="checkbox" name="sdm_item_disable_single_download_page" value="yes"' . checked( true, $sdm_item_disable_single_download_page, false ) . ' />';
403
+ echo '<label for="sdm_item_disable_single_download_page">';
404
+ $disable_single_dl_label = __( 'Disable the single download page for this download item. ', 'simple-download-monitor' );
405
+ $disable_single_dl_label .= __( 'This can be useful if you are using an addon like the ', 'simple-download-monitor' );
406
+ $disable_single_dl_label .= '<a href="https://simple-download-monitor.com/squeeze-form-addon-for-simple-download-monitor/" target="_blank">Squeeze Form</a>' . '.';
407
+ echo $disable_single_dl_label . '</label>';
408
+ echo '</p>';
409
+
410
+ $sdm_item_anonymous_can_download = get_post_meta( $post->ID, 'sdm_item_anonymous_can_download', true );
411
+
412
+ echo '<p> <input id="sdm_item_anonymous_can_download" type="checkbox" name="sdm_item_anonymous_can_download" value="yes"' . checked( true, $sdm_item_anonymous_can_download, false ) . ' />';
413
+ echo '<label for="sdm_item_anonymous_can_download">' . __( 'Ignore "Only Allow Logged-in Users to Download" global setting for this item.', 'simple-download-monitor' ) . '</label> </p>';
414
+
415
+ wp_nonce_field( 'sdm_misc_properties_box_nonce', 'sdm_misc_properties_box_nonce_check' );
416
+ }
417
+
418
+ public function display_sdm_thumbnail_meta_box( $post ) {
419
+ // Thumbnail upload metabox
420
+ $old_thumbnail = get_post_meta( $post->ID, 'sdm_upload_thumbnail', true );
421
+ $old_value = isset( $old_thumbnail ) ? $old_thumbnail : '';
422
+ _e( 'Manually enter a valid URL, or click "Select Image" to upload (or choose) the file thumbnail image.', 'simple-download-monitor' );
423
+ ?>
 
 
 
 
 
 
424
  <br /><br />
425
  <input id="sdm_upload_thumbnail" type="text" size="100" name="sdm_upload_thumbnail" value="<?php echo esc_url( $old_value ); ?>" placeholder="http://..." />
426
  <br /><br />
429
  <br /><br />
430
 
431
  <span id="sdm_admin_thumb_preview">
 
 
 
432
  <?php
433
+ if ( ! empty( $old_value ) ) {
434
+ ?>
435
+ <img id="sdm_thumbnail_image" src="<?php echo $old_value; ?>" style="max-width:200px;" />
436
+ <?php
437
+ }
438
+ ?>
439
  </span>
440
 
441
+ <?php
442
+ echo '<p class="description">';
443
+ _e( 'This thumbnail image will be used to create a fancy file download box if you want to use it.', 'simple-download-monitor' );
444
+ echo '</p>';
445
+
446
+ wp_nonce_field( 'sdm_thumbnail_box_nonce', 'sdm_thumbnail_box_nonce_check' );
447
+ }
448
+
449
+ public function display_sdm_stats_meta_box( $post ) {
450
+ //Stats metabox
451
+ $old_count = get_post_meta( $post->ID, 'sdm_count_offset', true );
452
+ $value = isset( $old_count ) && $old_count != '' ? $old_count : '0';
453
+
454
+ // Get checkbox for "disable download logging"
455
+ $no_logs = get_post_meta( $post->ID, 'sdm_item_no_log', true );
456
+ $checked = isset( $no_logs ) && $no_logs === 'on' ? 'checked="checked"' : '';
457
+
458
+ _e( 'These are the statistics for this download item.', 'simple-download-monitor' );
459
+ echo '<br /><br />';
460
+
461
+ global $wpdb;
462
+ $wpdb->get_results( $wpdb->prepare( 'SELECT * FROM ' . $wpdb->prefix . 'sdm_downloads WHERE post_id=%s', $post->ID ) );
463
+
464
+ echo '<div class="sdm-download-edit-dl-count">';
465
+ _e( 'Number of Downloads:', 'simple-download-monitor' );
466
+ echo ' <strong>' . $wpdb->num_rows . '</strong>';
467
+ echo '</div>';
468
+
469
+ echo '<div class="sdm-download-edit-offset-count">';
470
+ _e( 'Offset Count: ', 'simple-download-monitor' );
471
+ echo '<br />';
472
+ echo ' <input type="text" size="10" name="sdm_count_offset" value="' . esc_attr( $value ) . '" />';
473
+ echo '<p class="description">' . __( 'Enter any positive or negative numerical value; to offset the download count shown to the visitors (when using the download counter shortcode).', 'simple-download-monitor' ) . '</p>';
474
+ echo '</div>';
475
+
476
+ echo '<br />';
477
+ echo '<div class="sdm-download-edit-disable-logging">';
478
+ echo '<input type="checkbox" name="sdm_item_no_log" ' . $checked . ' />';
479
+ echo '<span style="margin-left: 5px;"></span>';
480
+ _e( 'Disable download logging for this item.', 'simple-download-monitor' );
481
+ echo '</div>';
482
+
483
+ wp_nonce_field( 'sdm_count_offset_nonce', 'sdm_count_offset_nonce_check' );
484
+ }
485
 
486
+ public function display_sdm_other_details_meta_box( $post ) {
487
+ //Other details metabox
488
+ $show_date_fd = get_post_meta( $post->ID, 'sdm_item_show_date_fd', true );
489
+ $sdm_item_show_file_size_fd = get_post_meta( $post->ID, 'sdm_item_show_file_size_fd', true );
490
+ $sdm_item_show_item_version_fd = get_post_meta( $post->ID, 'sdm_item_show_item_version_fd', true );
491
+
492
+ $file_size = get_post_meta( $post->ID, 'sdm_item_file_size', true );
493
+ $file_size = isset( $file_size ) ? $file_size : '';
494
+
495
+ $version = get_post_meta( $post->ID, 'sdm_item_version', true );
496
+ $version = isset( $version ) ? $version : '';
497
+
498
+ $download_button_text = get_post_meta( $post->ID, 'sdm_download_button_text', true );
499
+ $download_button_text = isset( $download_button_text ) ? $download_button_text : '';
500
+
501
+ echo '<div class="sdm-download-edit-filesize">';
502
+ echo '<strong>' . __( 'File Size: ', 'simple-download-monitor' ) . '</strong>';
503
+ echo '<br />';
504
+ echo ' <input type="text" name="sdm_item_file_size" value="' . esc_attr( $file_size ) . '" size="20" />';
505
+ echo '<p class="description">' . __( 'Enter the size of this file (example value: 2.15 MB).', 'simple-download-monitor' ) . '</p>';
506
+ echo '<div class="sdm-download-edit-show-file-size"> <input id="sdm_item_show_file_size_fd" type="checkbox" name="sdm_item_show_file_size_fd" value="yes"' . checked( true, $sdm_item_show_file_size_fd, false ) . ' />';
507
+ echo '<label for="sdm_item_show_file_size_fd">' . __( 'Show file size in fancy display.', 'simple-download-monitor' ) . '</label> </div>';
508
+ echo '</div>';
509
+ echo '<hr />';
510
+
511
+ echo '<div class="sdm-download-edit-version">';
512
+ echo '<strong>' . __( 'Version: ', 'simple-download-monitor' ) . '</strong>';
513
+ echo '<br />';
514
+ echo ' <input type="text" name="sdm_item_version" value="' . esc_attr( $version ) . '" size="20" />';
515
+ echo '<p class="description">' . __( 'Enter the version number for this item if any (example value: v2.5.10).', 'simple-download-monitor' ) . '</p>';
516
+ echo '<div class="sdm-download-edit-show-item-version"> <input id="sdm_item_show_item_version_fd" type="checkbox" name="sdm_item_show_item_version_fd" value="yes"' . checked( true, $sdm_item_show_item_version_fd, false ) . ' />';
517
+ echo '<label for="sdm_item_show_item_version_fd">' . __( 'Show version number in fancy display.', 'simple-download-monitor' ) . '</label> </div>';
518
+ echo '</div>';
519
+ echo '<hr />';
520
+
521
+ echo '<div class="sdm-download-edit-show-publish-date">';
522
+ echo '<strong>' . __( 'Publish Date: ', 'simple-download-monitor' ) . '</strong>';
523
+ echo '<br /> <input id="sdm_item_show_date_fd" type="checkbox" name="sdm_item_show_date_fd" value="yes"' . checked( true, $show_date_fd, false ) . ' />';
524
+ echo '<label for="sdm_item_show_date_fd">' . __( 'Show download published date in fancy display.', 'simple-download-monitor' ) . '</label>';
525
+ echo '</div>';
526
+ echo '<hr />';
527
+
528
+ echo '<div class="sdm-download-edit-button-text">';
529
+ echo '<strong>' . __( 'Download Button Text: ', 'simple-download-monitor' ) . '</strong>';
530
+ echo '<br />';
531
+ echo "<input id='sdm-download-button-text' type='text' name='sdm_download_button_text' value='{$download_button_text}' />";
532
+ echo '<p class="description">' . __( 'You can use this field to customize the download now button text of this item.', 'simple-download-monitor' ) . '</p>';
533
+ echo '</div>';
534
+
535
+ wp_nonce_field( 'sdm_other_details_nonce', 'sdm_other_details_nonce_check' );
536
+ }
537
 
538
+ public function display_sdm_shortcode_meta_box( $post ) {
539
+ //Shortcode metabox
540
+ _e( 'The following shortcode can be used on posts or pages to embed a download now button for this file. You can also use the shortcode inserter (in the post editor) to add this shortcode to a post or page.', 'simple-download-monitor' );
541
+ echo '<br />';
542
+ $shortcode_text = '[sdm_download id="' . $post->ID . '" fancy="0"]';
543
+ echo "<input type='text' class='code' onfocus='this.select();' readonly='readonly' value='" . $shortcode_text . "' size='40'>";
544
+ echo '<br /><br />';
545
+
546
+ _e( 'The following shortcode can be used to show a download counter for this item.', 'simple-download-monitor' );
547
+ echo '<br />';
548
+ $shortcode_text = '[sdm_download_counter id="' . $post->ID . '"]';
549
+ echo "<input type='text' class='code' onfocus='this.select();' readonly='readonly' value='" . $shortcode_text . "' size='40'>";
550
+
551
+ echo '<br /><br />';
552
+ _e( 'Read the full shortcode usage documentation <a href="https://simple-download-monitor.com/miscellaneous-shortcodes-and-shortcode-parameters/" target="_blank">here</a>.', 'simple-download-monitor' );
553
+ }
554
 
555
+ public function sdm_save_description_meta_data( $post_id ) {
556
+ // Save Description metabox
557
+ if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) {
558
+ return;
559
+ }
560
+ if ( ! isset( $_POST['sdm_description_box_nonce_check'] ) || ! wp_verify_nonce( $_POST['sdm_description_box_nonce_check'], 'sdm_description_box_nonce' ) ) {
561
+ return;
562
+ }
563
+ if ( isset( $_POST['sdm_description'] ) ) {
564
+ update_post_meta( $post_id, 'sdm_description', wp_kses_post( $_POST['sdm_description'] ) );
565
+ }
566
+ }
567
 
568
+ public function sdm_save_upload_meta_data( $post_id ) {
569
+ // Save File Upload metabox
570
+ if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) {
571
+ return;
572
+ }
573
+ if ( ! isset( $_POST['sdm_upload_box_nonce_check'] ) || ! wp_verify_nonce( $_POST['sdm_upload_box_nonce_check'], 'sdm_upload_box_nonce' ) ) {
574
+ return;
575
+ }
576
 
577
+ if ( isset( $_POST['sdm_upload'] ) ) {
578
+ update_post_meta( $post_id, 'sdm_upload', sanitize_text_field( $_POST['sdm_upload'] ) );
579
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
580
  }
581
+
582
+ public function sdm_save_dispatch_meta_data( $post_id ) {
583
+ // Save "Dispatch or Redirect" metabox
584
+ if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) {
585
+ return;
586
+ }
587
+ if ( ! isset( $_POST['sdm_dispatch_box_nonce_check'] ) || ! wp_verify_nonce( $_POST['sdm_dispatch_box_nonce_check'], 'sdm_dispatch_box_nonce' ) ) {
588
+ return;
589
+ }
590
+ // Get POST-ed data as boolean value
591
+ $value = filter_input( INPUT_POST, 'sdm_item_dispatch', FILTER_VALIDATE_BOOLEAN );
592
+ update_post_meta( $post_id, 'sdm_item_dispatch', $value );
593
  }
 
594
 
595
+ public function sdm_save_misc_properties_meta_data( $post_id ) {
596
+ if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) {
597
+ return;
598
+ }
599
+ if ( ! isset( $_POST['sdm_misc_properties_box_nonce_check'] ) || ! wp_verify_nonce( $_POST['sdm_misc_properties_box_nonce_check'], 'sdm_misc_properties_box_nonce' ) ) {
600
+ return;
601
+ }
602
+ // Get POST-ed data as boolean value
603
+ $new_window_open = filter_input( INPUT_POST, 'sdm_item_new_window', FILTER_VALIDATE_BOOLEAN );
604
+ $sdm_item_hide_dl_button_single_download_page = filter_input( INPUT_POST, 'sdm_item_hide_dl_button_single_download_page', FILTER_VALIDATE_BOOLEAN );
605
+ $sdm_item_disable_single_download_page = filter_input( INPUT_POST, 'sdm_item_disable_single_download_page', FILTER_VALIDATE_BOOLEAN );
606
+ $sdm_item_anonymous_can_download = filter_input( INPUT_POST, 'sdm_item_anonymous_can_download', FILTER_VALIDATE_BOOLEAN );
607
+
608
+ //Save the data
609
+ update_post_meta( $post_id, 'sdm_item_new_window', $new_window_open );
610
+ update_post_meta( $post_id, 'sdm_item_hide_dl_button_single_download_page', $sdm_item_hide_dl_button_single_download_page );
611
+ update_post_meta( $post_id, 'sdm_item_disable_single_download_page', $sdm_item_disable_single_download_page );
612
+ update_post_meta( $post_id, 'sdm_item_anonymous_can_download', $sdm_item_anonymous_can_download );
613
  }
614
+
615
+ public function sdm_save_thumbnail_meta_data( $post_id ) {
616
+ // Save Thumbnail Upload metabox
617
+ if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) {
618
+ return;
619
+ }
620
+ if ( ! isset( $_POST['sdm_thumbnail_box_nonce_check'] ) || ! wp_verify_nonce( $_POST['sdm_thumbnail_box_nonce_check'], 'sdm_thumbnail_box_nonce' ) ) {
621
+ return;
622
+ }
623
+ if ( isset( $_POST['sdm_upload_thumbnail'] ) ) {
624
+ update_post_meta( $post_id, 'sdm_upload_thumbnail', sanitize_text_field( $_POST['sdm_upload_thumbnail'] ) );
625
+ }
626
  }
627
+
628
+ public function sdm_save_statistics_meta_data( $post_id ) {
629
+ // Save Statistics Upload metabox
630
+ if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) {
631
+ return;
632
+ }
633
+ if ( ! isset( $_POST['sdm_count_offset_nonce_check'] ) || ! wp_verify_nonce( $_POST['sdm_count_offset_nonce_check'], 'sdm_count_offset_nonce' ) ) {
634
+ return;
635
+ }
636
+ if ( isset( $_POST['sdm_count_offset'] ) && is_numeric( $_POST['sdm_count_offset'] ) ) {
637
+ update_post_meta( $post_id, 'sdm_count_offset', intval( $_POST['sdm_count_offset'] ) );
638
+ }
639
+
640
+ // Checkbox for disabling download logging for this item
641
+ if ( isset( $_POST['sdm_item_no_log'] ) ) {
642
+ update_post_meta( $post_id, 'sdm_item_no_log', sanitize_text_field( $_POST['sdm_item_no_log'] ) );
643
+ } else {
644
+ delete_post_meta( $post_id, 'sdm_item_no_log' );
645
+ }
646
  }
647
 
648
+ public function sdm_save_other_details_meta_data( $post_id ) {
649
+ // Save Statistics Upload metabox
650
+ if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) {
651
+ return;
652
+ }
653
+ if ( ! isset( $_POST['sdm_other_details_nonce_check'] ) || ! wp_verify_nonce( $_POST['sdm_other_details_nonce_check'], 'sdm_other_details_nonce' ) ) {
654
+ return;
655
+ }
656
+
657
+ $show_date_fd = filter_input( INPUT_POST, 'sdm_item_show_date_fd', FILTER_VALIDATE_BOOLEAN );
658
+ update_post_meta( $post_id, 'sdm_item_show_date_fd', $show_date_fd );
659
+
660
+ $sdm_item_show_file_size_fd = filter_input( INPUT_POST, 'sdm_item_show_file_size_fd', FILTER_VALIDATE_BOOLEAN );
661
+ update_post_meta( $post_id, 'sdm_item_show_file_size_fd', $sdm_item_show_file_size_fd );
662
+
663
+ $sdm_item_show_item_version_fd = filter_input( INPUT_POST, 'sdm_item_show_item_version_fd', FILTER_VALIDATE_BOOLEAN );
664
+ update_post_meta( $post_id, 'sdm_item_show_item_version_fd', $sdm_item_show_item_version_fd );
665
+
666
+ if ( isset( $_POST['sdm_item_file_size'] ) ) {
667
+ update_post_meta( $post_id, 'sdm_item_file_size', sanitize_text_field( $_POST['sdm_item_file_size'] ) );
668
+ }
669
+
670
+ if ( isset( $_POST['sdm_item_version'] ) ) {
671
+ update_post_meta( $post_id, 'sdm_item_version', sanitize_text_field( $_POST['sdm_item_version'] ) );
672
+ }
673
+
674
+ if ( isset( $_POST['sdm_download_button_text'] ) ) {
675
+ update_post_meta( $post_id, 'sdm_download_button_text', sanitize_text_field( $_POST['sdm_download_button_text'] ) );
676
+ }
677
  }
 
678
 
679
+ public function sdm_remove_view_link_cpt( $action, $post ) {
680
+
681
+ // Only execute on SDM CPT posts page
682
+ if ( $post->post_type == 'sdm_downloads' ) {
683
+ unset( $action['view'] );
684
+ }
685
+
686
+ return $action;
687
  }
688
+
689
+ public function sdm_register_options() {
690
+
691
+ //Register the main setting
692
+ register_setting( 'sdm_downloads_options', 'sdm_downloads_options' );
693
+
694
+ /* * ************************** */
695
+ /* General Settings Section */
696
+ /* * ************************** */
697
+
698
+ //Add all the settings section that will go under the main settings
699
+ add_settings_section( 'general_options', __( 'General Options', 'simple-download-monitor' ), array( $this, 'general_options_cb' ), 'general_options_section' );
700
+ add_settings_section( 'user_login_options', __( 'User Login Related', 'simple-download-monitor' ), array( $this, 'user_login_options_cb' ), 'user_login_options_section' );
701
+ add_settings_section( 'admin_options', __( 'Admin Options', 'simple-download-monitor' ), array( $this, 'admin_options_cb' ), 'admin_options_section' );
702
+
703
+ add_settings_section( 'sdm_colors', __( 'Colors', 'simple-download-monitor' ), array( $this, 'sdm_colors_cb' ), 'sdm_colors_section' );
704
+ add_settings_section( 'sdm_debug', __( 'Debug', 'simple-download-monitor' ), array( $this, 'sdm_debug_cb' ), 'sdm_debug_section' );
705
+ add_settings_section( 'sdm_deldata', __( 'Delete Plugin Data', 'simple-download-monitor' ), array( $this, 'sdm_deldata_cb' ), 'sdm_deldata_section' );
706
+
707
+ //Add all the individual settings fields that goes under the sections
708
+ add_settings_field( 'general_hide_donwload_count', __( 'Hide Download Count', 'simple-download-monitor' ), array( $this, 'hide_download_count_cb' ), 'general_options_section', 'general_options' );
709
+ add_settings_field( 'general_default_dispatch_value', __( 'PHP Dispatching', 'simple-download-monitor' ), array( $this, 'general_default_dispatch_value_cb' ), 'general_options_section', 'general_options' );
710
+
711
+ add_settings_field( 'only_logged_in_can_download', __( 'Only Allow Logged-in Users to Download', 'simple-download-monitor' ), array( $this, 'general_only_logged_in_can_download_cb' ), 'user_login_options_section', 'user_login_options' );
712
+ add_settings_field( 'general_login_page_url', __( 'Login Page URL', 'simple-download-monitor' ), array( $this, 'general_login_page_url_cb' ), 'user_login_options_section', 'user_login_options' );
713
+ add_settings_field( 'redirect_user_back_to_download_page', __( 'Redirect Users to Download Page', 'simple-download-monitor' ), array( $this, 'redirect_user_back_to_download_page_cb' ), 'user_login_options_section', 'user_login_options' );
714
+
715
+ add_settings_field( 'admin_tinymce_button', __( 'Remove Tinymce Button', 'simple-download-monitor' ), array( $this, 'admin_tinymce_button_cb' ), 'admin_options_section', 'admin_options' );
716
+ add_settings_field( 'admin_log_unique', __( 'Log Unique IP', 'simple-download-monitor' ), array( $this, 'admin_log_unique' ), 'admin_options_section', 'admin_options' );
717
+ add_settings_field( 'admin_do_not_capture_ip', __( 'Do Not Capture IP Address', 'simple-download-monitor' ), array( $this, 'admin_do_not_capture_ip' ), 'admin_options_section', 'admin_options' );
718
+ add_settings_field( 'admin_do_not_capture_user_agent', __( 'Do Not Capture User Agent', 'simple-download-monitor' ), array( $this, 'admin_do_not_capture_user_agent' ), 'admin_options_section', 'admin_options' );
719
+ add_settings_field( 'admin_dont_log_bots', __( 'Do Not Count Downloads from Bots', 'simple-download-monitor' ), array( $this, 'admin_dont_log_bots' ), 'admin_options_section', 'admin_options' );
720
+ add_settings_field( 'admin_no_logs', __( 'Disable Download Logs', 'simple-download-monitor' ), array( $this, 'admin_no_logs_cb' ), 'admin_options_section', 'admin_options' );
721
+
722
+ add_settings_field( 'download_button_color', __( 'Download Button Color', 'simple-download-monitor' ), array( $this, 'download_button_color_cb' ), 'sdm_colors_section', 'sdm_colors' );
723
+
724
+ add_settings_field( 'enable_debug', __( 'Enable Debug', 'simple-download-monitor' ), array( $this, 'enable_debug_cb' ), 'sdm_debug_section', 'sdm_debug' );
725
+
726
+ /* * ************************** */
727
+ /* Advanced Settings Section */
728
+ /* * ************************** */
729
+ //Add the advanced settings section
730
+ add_settings_section( 'recaptcha_options', __( 'Google Captcha (reCAPTCHA)', 'simple-download-monitor' ), array( $this, 'recaptcha_options_cb' ), 'recaptcha_options_section' );
731
+ add_settings_section( 'termscond_options', __( 'Terms and Conditions', 'simple-download-monitor' ), array( $this, 'termscond_options_cb' ), 'termscond_options_section' );
732
+ add_settings_section( 'adsense_options', __( 'Adsense/Ad Insertion', 'simple-download-monitor' ), array( $this, 'adsense_options_cb' ), 'adsense_options_section' );
733
+ add_settings_section( 'maps_api_options', __( 'Google Maps API Key', 'simple-download-monitor' ), array( $this, 'maps_api_options_cb' ), 'maps_api_options_section' );
734
+
735
+ //Add reCAPTCHA section fields
736
+ add_settings_field( 'recaptcha_enable', __( 'Enable reCAPTCHA', 'simple-download-monitor' ), array( $this, 'recaptcha_enable_cb' ), 'recaptcha_options_section', 'recaptcha_options' );
737
+ add_settings_field( 'recaptcha_site_key', __( 'Site Key', 'simple-download-monitor' ), array( $this, 'recaptcha_site_key_cb' ), 'recaptcha_options_section', 'recaptcha_options' );
738
+ add_settings_field( 'recaptcha_secret_key', __( 'Secret Key', 'simple-download-monitor' ), array( $this, 'recaptcha_secret_key_cb' ), 'recaptcha_options_section', 'recaptcha_options' );
739
+
740
+ //Add Terms & Condition section fields
741
+ add_settings_field( 'termscond_enable', __( 'Enable Terms and Conditions', 'simple-download-monitor' ), array( $this, 'termscond_enable_cb' ), 'termscond_options_section', 'termscond_options' );
742
+ add_settings_field( 'termscond_url', __( 'Terms Page URL', 'simple-download-monitor' ), array( $this, 'termscond_url_cb' ), 'termscond_options_section', 'termscond_options' );
743
+
744
+ //Add Adsense section fields
745
+ add_settings_field( 'adsense_below_description', __( 'Below Download Description', 'simple-download-monitor' ), array( $this, 'adsense_below_description_cb' ), 'adsense_options_section', 'adsense_options' );
746
+
747
+ //Maps API section fields
748
+ add_settings_field( 'maps_api_key', __( 'API Key', 'simple-download-monitor' ), array( $this, 'maps_api_key_cb' ), 'maps_api_options_section', 'maps_api_options' );
749
  }
750
 
751
+ public function general_options_cb() {
752
+ //Set the message that will be shown below the general options settings heading
753
+ _e( 'General options settings', 'simple-download-monitor' );
754
+ }
755
 
756
+ public function user_login_options_cb() {
757
+ //Set the message that will be shown below the user login related settings heading
758
+ _e( 'Visitor login related settings (useful if you only want to allow logged-in users to be able to download files.', 'simple-download-monitor' );
759
+ }
760
 
761
+ public function admin_options_cb() {
762
+ //Set the message that will be shown below the admin options settings heading
763
+ _e( 'Admin options settings', 'simple-download-monitor' );
764
+ }
765
+
766
+ public function sdm_colors_cb() {
767
+ //Set the message that will be shown below the color options settings heading
768
+ _e( 'Front End colors settings', 'simple-download-monitor' );
769
+ }
770
 
771
+ public function sdm_debug_cb() {
772
+ //Set the message that will be shown below the debug options settings heading
773
+ _e( 'Debug settings', 'simple-download-monitor' );
774
  }
775
 
776
+ public function sdm_deldata_cb() {
777
+ //Set the message that will be shown below the debug options settings heading
778
+ _e( 'You can delete all the data related to this plugin from database using the button below. Useful when you\'re uninstalling the plugin and don\'t want any leftovers remaining.', 'simple-download-monitor' );
779
+ echo '<p><b>' . __( 'Warning', 'simple-download-monitor' ) . ': </b> ' . __( 'this can\'t be undone. All settings, download items, download logs will be deleted.', 'simple-download-monitor' ) . '</p>';
780
+ echo '<p><button id="sdmDeleteData" class="button" style="color:red;">' . __( 'Delete all data and deactivate plugin', 'simple-download-monitor' ) . '</button></p>';
781
+ echo '<br />';
782
  }
783
 
784
+ public function recaptcha_options_cb() {
785
+ //Set the message that will be shown below the recaptcha options settings heading
786
+ _e( 'Google Captcha (reCAPTCHA) options', 'simple-download-monitor' );
787
  }
 
788
 
789
+ public function termscond_options_cb() {
790
 
 
 
 
791
  }
792
 
793
+ public function adsense_options_cb() {
794
+ //Set the message that will be shown below the adsense/ad code settings heading
795
+ _e( 'You can use this section to insert adsense or other ad code inside the download item output', 'simple-download-monitor' );
796
+ }
797
 
798
+ public function maps_api_options_cb() {
799
+ _e( 'Google Maps API key is required to display the "Downloads by Country" chart.', 'simple-download-monitor' );
800
+ }
801
 
802
+ public function recaptcha_enable_cb() {
803
+ $main_opts = get_option( 'sdm_advanced_options' );
804
+ echo '<input name="sdm_advanced_options[recaptcha_enable]" id="recaptcha_enable" type="checkbox" ' . checked( 1, isset( $main_opts['recaptcha_enable'] ), false ) . ' /> ';
805
+ echo '<p class="description">' . __( 'Check this box if you want to use <a href="https://www.google.com/recaptcha/admin" target="_blank">reCAPTCHA</a>. ', 'simple-download-monitor' ) . '</p>';
806
+ echo '<p class="description">' . __( 'The captcha option adds a captcha to the download now buttons.', 'simple-download-monitor' ) . '</p>';
807
+ }
808
 
809
+ public function recaptcha_site_key_cb() {
810
+ $main_opts = get_option( 'sdm_advanced_options' );
811
+ $value = isset( $main_opts['recaptcha_site_key'] ) ? $main_opts['recaptcha_site_key'] : '';
812
+ echo '<input size="100" name="sdm_advanced_options[recaptcha_site_key]" id="recaptcha_site_key" type="text" value="' . $value . '" /> ';
813
+ echo '<p class="description">' . __( 'The site key for the reCAPTCHA API', 'simple-download-monitor' ) . '</p>';
814
+ }
815
 
816
+ public function recaptcha_secret_key_cb() {
817
+ $main_opts = get_option( 'sdm_advanced_options' );
818
+ $value = isset( $main_opts['recaptcha_secret_key'] ) ? $main_opts['recaptcha_secret_key'] : '';
819
+ echo '<input size="100" name="sdm_advanced_options[recaptcha_secret_key]" id="recaptcha_secret_key" type="text" value="' . $value . '" /> ';
820
+ echo '<p class="description">' . __( 'The secret key for the reCAPTCHA API', 'simple-download-monitor' ) . '</p>';
821
+ }
822
 
823
+ public function hide_download_count_cb() {
824
+ $main_opts = get_option( 'sdm_downloads_options' );
825
+ echo '<input name="sdm_downloads_options[general_hide_donwload_count]" id="general_hide_download_count" type="checkbox" ' . checked( 1, isset( $main_opts['general_hide_donwload_count'] ), false ) . ' /> ';
826
+ echo '<label for="general_hide_download_count">' . __( 'Hide the download count that is shown in some of the fancy templates.', 'simple-download-monitor' ) . '</label>';
827
+ }
828
 
829
+ public function general_default_dispatch_value_cb() {
830
+ $main_opts = get_option( 'sdm_downloads_options' );
831
+ $value = isset( $main_opts['general_default_dispatch_value'] ) && $main_opts['general_default_dispatch_value'];
832
+ echo '<input name="sdm_downloads_options[general_default_dispatch_value]" id="general_default_dispatch_value" type="checkbox" value="1"' . checked( true, $value, false ) . ' />';
833
+ echo '<label for="general_default_dispatch_value">' . __( 'When you create a new download item, The PHP Dispatching option should be enabled by default. PHP Dispatching keeps the URL of the downloadable files hidden.', 'simple-download-monitor' ) . '</label>';
834
+ }
835
 
836
+ public function general_only_logged_in_can_download_cb() {
837
+ $main_opts = get_option( 'sdm_downloads_options' );
838
+ $value = isset( $main_opts['only_logged_in_can_download'] ) && $main_opts['only_logged_in_can_download'];
839
+ echo '<input name="sdm_downloads_options[only_logged_in_can_download]" id="only_logged_in_can_download" type="checkbox" value="1"' . checked( true, $value, false ) . ' />';
840
+ echo '<label for="only_logged_in_can_download">' . __( 'Enable this option if you want to allow downloads only for logged-in users. When enabled, anonymous users clicking on the download button will receive an error message.', 'simple-download-monitor' ) . '</label>';
841
+ }
842
 
843
+ public function redirect_user_back_to_download_page_cb() {
844
+ $main_opts = get_option( 'sdm_downloads_options' );
845
+ $value = isset( $main_opts['redirect_user_back_to_download_page'] ) && $main_opts['redirect_user_back_to_download_page'];
846
+ echo '<input name="sdm_downloads_options[redirect_user_back_to_download_page]" id="redirect_user_back_to_download_page" type="checkbox" value="1"' . checked( true, $value, false ) . ' />';
847
+ echo '<label for="redirect_user_back_to_download_page">' . __( 'Only works if you have set a Login Page URL value above. Enable this option if you want to redirect the users to the download page after they log into the site.', 'simple-download-monitor' ) . '</label>';
848
+ }
849
 
850
+ public function general_login_page_url_cb() {
851
+ $main_opts = get_option( 'sdm_downloads_options' );
852
+ $value = isset( $main_opts['general_login_page_url'] ) ? $main_opts['general_login_page_url'] : '';
853
+ echo '<input size="100" name="sdm_downloads_options[general_login_page_url]" id="general_login_page_url" type="text" value="' . $value . '" />';
854
+ echo '<p class="description">' . __( '(Optional) Specify a login page URL where users can login. This is useful if you only allow logged in users to be able to download. This link will be added to the message that is shown to anonymous users.', 'simple-download-monitor' ) . '</p>';
855
+ }
856
 
857
+ public function admin_tinymce_button_cb() {
858
+ $main_opts = get_option( 'sdm_downloads_options' );
859
+ echo '<input name="sdm_downloads_options[admin_tinymce_button]" id="admin_tinymce_button" type="checkbox" class="sdm_opts_ajax_checkboxes" ' . checked( 1, isset( $main_opts['admin_tinymce_button'] ), false ) . ' /> ';
860
+ echo '<label for="admin_tinymce_button">' . __( 'Removes the SDM Downloads button from the WP content editor.', 'simple-download-monitor' ) . '</label>';
861
+ }
862
 
863
+ public function admin_log_unique() {
864
+ $main_opts = get_option( 'sdm_downloads_options' );
865
+ echo '<input name="sdm_downloads_options[admin_log_unique]" id="admin_log_unique" type="checkbox" class="sdm_opts_ajax_checkboxes" ' . checked( 1, isset( $main_opts['admin_log_unique'] ), false ) . ' /> ';
866
+ echo '<label for="admin_log_unique">' . __( 'Only logs downloads from unique IP addresses.', 'simple-download-monitor' ) . '</label>';
867
+ }
 
 
 
868
 
869
+ public function admin_do_not_capture_ip() {
870
+ $main_opts = get_option( 'sdm_downloads_options' );
871
+ echo '<input name="sdm_downloads_options[admin_do_not_capture_ip]" id="admin_do_not_capture_ip" type="checkbox" class="sdm_opts_ajax_checkboxes" ' . checked( 1, isset( $main_opts['admin_do_not_capture_ip'] ), false ) . ' /> ';
872
+ echo '<label for="admin_do_not_capture_ip">' . __( 'Use this if you do not want to capture the IP address and Country of the visitors when they download an item.', 'simple-download-monitor' ) . '</label>';
873
+ }
874
 
875
+ public function admin_do_not_capture_user_agent() {
876
+ $main_opts = get_option( 'sdm_downloads_options' );
877
+ echo '<input name="sdm_downloads_options[admin_do_not_capture_user_agent]" id="admin_do_not_capture_user_agent" type="checkbox" class="sdm_opts_ajax_checkboxes" ' . checked( 1, isset( $main_opts['admin_do_not_capture_user_agent'] ), false ) . ' /> ';
878
+ echo '<label for="admin_do_not_capture_user_agent">' . __( 'Use this if you do not want to capture the User Agent value of the browser when they download an item.', 'simple-download-monitor' ) . '</label>';
879
+ }
880
 
881
+ public function admin_dont_log_bots() {
882
+ $main_opts = get_option( 'sdm_downloads_options' );
883
+ echo '<input name="sdm_downloads_options[admin_dont_log_bots]" id="admin_dont_log_bots" type="checkbox" class="sdm_opts_ajax_checkboxes" ' . checked( 1, isset( $main_opts['admin_dont_log_bots'] ), false ) . ' /> ';
884
+ echo '<label for="admin_dont_log_bots">' . __( 'When enabled, the plugin won\'t count and log downloads from bots.', 'simple-download-monitor' ) . '</label>';
885
+ }
886
 
887
+ public function admin_no_logs_cb() {
888
+ $main_opts = get_option( 'sdm_downloads_options' );
889
+ echo '<input name="sdm_downloads_options[admin_no_logs]" id="admin_no_logs" type="checkbox" class="sdm_opts_ajax_checkboxes" ' . checked( 1, isset( $main_opts['admin_no_logs'] ), false ) . ' /> ';
890
+ echo '<label for="admin_no_logs">' . __( 'Disables all download logs. (This global option overrides the individual download item option.)', 'simple-download-monitor' ) . '</label>';
891
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
892
 
893
+ public function download_button_color_cb() {
894
+ $main_opts = get_option( 'sdm_downloads_options' );
895
+ // Read current color class.
896
+ $color_opt = isset( $main_opts['download_button_color'] ) ? $main_opts['download_button_color'] : null;
897
+ $color_opts = sdm_get_download_button_colors();
898
 
899
+ echo '<select name="sdm_downloads_options[download_button_color]" id="download_button_color" class="sdm_opts_ajax_dropdowns">';
900
+ foreach ( $color_opts as $color_class => $color_name ) {
901
+ echo '<option value="' . $color_class . '"' . selected( $color_class, $color_opt, false ) . '>' . $color_name . '</option>';
902
+ }
903
+ echo '</select> ';
904
+ esc_html_e( 'Adjusts the color of the "Download Now" button.', 'simple-download-monitor' );
905
  }
906
 
907
+ public function enable_debug_cb() {
908
+ $main_opts = get_option( 'sdm_downloads_options' );
909
+ echo '<input name="sdm_downloads_options[enable_debug]" id="enable_debug" type="checkbox" class="sdm_opts_ajax_checkboxes" ' . checked( 1, isset( $main_opts['enable_debug'] ), false ) . ' /> ';
910
+ echo '<label for="enable_debug">' . __( 'Check this option to enable debug logging.', 'simple-download-monitor' ) .
911
+ '<p class="description"><a href="' . get_admin_url() . '?sdm-action=view_log" target="_blank">' .
912
+ __( 'Click here', 'simple-download-monitor' ) . '</a>' .
913
+ __( ' to view log file.', 'simple-download-monitor' ) . '<br>' .
914
+ '<a id="sdm-reset-log" href="#0" style="color: red">' . __( 'Click here', 'simple-download-monitor' ) . '</a>' .
915
+ __( ' to reset log file.', 'simple-download-monitor' ) . '</p></label>';
916
+ }
917
 
918
+ public function termscond_enable_cb() {
919
+ $main_opts = get_option( 'sdm_advanced_options' );
920
+ echo '<input name="sdm_advanced_options[termscond_enable]" id="termscond_enable" type="checkbox" ' . checked( 1, isset( $main_opts['termscond_enable'] ), false ) . ' /> ';
921
+ echo '<p class="description">' . __( 'You can use this option to make the visitors agree to your terms before they can download the item.', 'simple-download-monitor' ) . '</p>';
922
+ }
 
 
 
923
 
924
+ public function termscond_url_cb() {
925
+ $main_opts = get_option( 'sdm_advanced_options' );
926
+ $value = isset( $main_opts['termscond_url'] ) ? $main_opts['termscond_url'] : '';
927
+ echo '<input size="100" name="sdm_advanced_options[termscond_url]" id="termscond_url" type="text" value="' . $value . '" /> ';
928
+ echo '<p class="description">' . __( 'Enter the URL of your terms and conditions page.', 'simple-download-monitor' ) . '</p>';
929
+ }
930
+
931
+ public function adsense_below_description_cb() {
932
+ $main_opts = get_option( 'sdm_advanced_options' );
933
+ $value = isset( $main_opts['adsense_below_description'] ) ? $main_opts['adsense_below_description'] : '';
934
+ //echo '<input size="100" name="sdm_advanced_options[adsense_below_description]" id="adsense_below_description" type="text" value="'.$value.'" /> ';
935
+ echo '<textarea name="sdm_advanced_options[adsense_below_description]" id="adsense_below_description" rows="6" cols="60">' . $value . '</textarea>';
936
+ echo '<p class="description">' . __( 'Enter the Adsense or Ad code that you want to show below the download item description.', 'simple-download-monitor' ) . '</p>';
937
+ }
938
+
939
+ public function maps_api_key_cb() {
940
+ $main_opts = get_option( 'sdm_advanced_options' );
941
+ $value = isset( $main_opts['maps_api_key'] ) ? $main_opts['maps_api_key'] : '';
942
+ echo '<input size="100" name="sdm_advanced_options[maps_api_key]" id="maps_api_key" type="text" value="' . $value . '" />';
943
+ echo '<p class="description">' . __( 'Enter your Google Maps API key. You can create new API key using <a href="https://developers.google.com/maps/documentation/javascript/get-api-key" target="_blank">this instruction</a>.', 'simple-download-monitor' ) . '</p>';
944
+ }
945
+
946
+ public function sdm_add_clone_record_btn( $action, $post ) {
947
+ // Only execute on SDM CPT posts page
948
+ if ( $post->post_type == 'sdm_downloads' ) {
949
+ $action['clone'] = sprintf(
950
+ '<a href="%2$s" aria-label="%1$s">%1$s</a>',
951
+ esc_html__( 'Clone', 'simple-download-monitor' ),
952
+ $this->get_duplicate_url( $post->ID )
953
+ );
954
+ }
955
+ return $action;
956
+ }
957
 
958
+ /**
959
+ * Returns duplicate post URL
960
+ *
961
+ * @return string
962
  */
963
+ public function get_duplicate_url( $post_id ) {
964
+ global $wp;
965
+ return add_query_arg(
966
+ array(
967
+ 'action' => 'sdm_clone_post',
968
+ 'post' => $post_id,
969
+ 'ref' => urlencode( add_query_arg( $wp->query_string, '', home_url( $wp->request ) ) ),
970
+ '_nonce' => wp_create_nonce( 'sdm_downloads' ),
971
+ ),
972
+ esc_url( admin_url( 'admin.php' ) )
973
+ );
974
+ }
975
+
976
+ public function sdm_action_clone_post() {
977
+
978
+ global $wpdb;
979
+ if ( ! ( isset( $_GET['post'] ) || isset( $_POST['post'] ) || ( isset( $_REQUEST['action'] ) && 'sdm_clone_post' == $_REQUEST['action'] ) ) ) {
980
+ wp_die( __( 'No post to duplicate has been supplied!', 'simple-download-monitor' ) );
981
+ }
982
+
983
+ /*
984
+ * Nonce verification
985
+ */
986
+ if ( ! isset( $_GET['_nonce'] ) || ! wp_verify_nonce( $_GET['_nonce'], 'sdm_downloads' ) ) {
987
+ return;
988
+ }
989
+
990
+ /*
991
+ * get the original post id
992
+ */
993
+ $post_id = ( isset( $_GET['post'] ) ? absint( $_GET['post'] ) : absint( $_POST['post'] ) );
994
+ /*
995
+ * and all the original post data then
996
+ */
997
+ $post = get_post( $post_id );
998
+
999
+ /*
1000
+ * if you don't want current user to be the new post author,
1001
+ * then change next couple of lines to this: $new_post_author = $post->post_author;
1002
+ */
1003
+ $current_user = wp_get_current_user();
1004
+ $new_post_author = $current_user->ID;
1005
+
1006
+ /*
1007
+ * if post data exists, create the post duplicate
1008
+ */
1009
+ if ( isset( $post ) && $post != null ) {
1010
+
1011
+ /*
1012
+ * new post data array
1013
+ */
1014
+ $args = array(
1015
+ 'comment_status' => $post->comment_status,
1016
+ 'ping_status' => $post->ping_status,
1017
+ 'post_author' => $new_post_author,
1018
+ 'post_content' => $post->post_content,
1019
+ 'post_excerpt' => $post->post_excerpt,
1020
+ 'post_name' => $post->post_name,
1021
+ 'post_parent' => $post->post_parent,
1022
+ 'post_password' => $post->post_password,
1023
+ 'post_status' => 'draft',
1024
+ 'post_title' => $post->post_title,
1025
+ 'post_type' => $post->post_type,
1026
+ 'to_ping' => $post->to_ping,
1027
+ 'menu_order' => $post->menu_order,
1028
+ );
1029
+
1030
+ /*
1031
+ * insert the post by wp_insert_post() function
1032
+ */
1033
+ $new_post_id = wp_insert_post( $args );
1034
+
1035
+ /*
1036
+ * get all current post terms ad set them to the new post draft
1037
+ */
1038
+ $taxonomies = get_object_taxonomies( $post->post_type ); // returns array of taxonomy names for post type, ex array("category", "post_tag");
1039
+ foreach ( $taxonomies as $taxonomy ) {
1040
+ $post_terms = wp_get_object_terms( $post_id, $taxonomy, array( 'fields' => 'slugs' ) );
1041
+ wp_set_object_terms( $new_post_id, $post_terms, $taxonomy, false );
1042
+ }
1043
+
1044
+ /*
1045
+ * duplicate all post meta just in two SQL queries
1046
+ */
1047
+ $post_meta_infos = $wpdb->get_results( "SELECT meta_key, meta_value FROM $wpdb->postmeta WHERE post_id=$post_id" );
1048
+ if ( count( $post_meta_infos ) != 0 ) {
1049
+ $sql_query = "INSERT INTO $wpdb->postmeta (post_id, meta_key, meta_value) ";
1050
+ foreach ( $post_meta_infos as $meta_info ) {
1051
+ $meta_key = $meta_info->meta_key;
1052
+ if ( $meta_key == '_wp_old_slug' ) {
1053
+ continue;
1054
+ }
1055
+ $meta_value = addslashes( $meta_info->meta_value );
1056
+ $sql_query_sel[] = "SELECT $new_post_id, '$meta_key', '$meta_value'";
1057
+ }
1058
+ $sql_query .= implode( ' UNION ALL ', $sql_query_sel );
1059
+ $wpdb->query( $sql_query );
1060
+ }
1061
+
1062
+ /*
1063
+ * finally, redirect to the edit post screen for the new draft
1064
+ */
1065
+ wp_redirect( admin_url( 'post.php?action=edit&post=' . $new_post_id ) );
1066
+ exit;
1067
+ } else {
1068
+ wp_die( __( 'Post creation failed, could not find original post: ', 'simple-download-monitor' ) . $post_id );
1069
  }
 
 
 
 
 
 
 
 
 
 
 
1070
  }
 
1071
 
1072
  }
1073
 
1081
 
1082
  function sdm_tiny_get_post_ids_ajax_call() {
1083
 
1084
+ $posts = get_posts(
1085
+ array(
1086
+ 'post_type' => 'sdm_downloads',
1087
+ 'numberposts' => -1,
1088
+ )
1089
+ );
1090
+ foreach ( $posts as $item ) {
1091
+ $test[] = array(
1092
+ 'post_id' => $item->ID,
1093
+ 'post_title' => $item->post_title,
1094
+ );
1095
+ }
1096
 
1097
+ $response = json_encode(
1098
+ array(
1099
+ 'success' => true,
1100
+ 'test' => $test,
1101
+ )
1102
+ );
1103
 
1104
+ header( 'Content-Type: application/json' );
1105
+ echo $response;
1106
+ exit;
1107
  }
1108
 
1109
  //Remove Thumbnail Image
1111
  add_action( 'wp_ajax_sdm_remove_thumbnail_image', 'sdm_remove_thumbnail_image_ajax_call' ); //Execute this for authenticated users only
1112
 
1113
  function sdm_remove_thumbnail_image_ajax_call() {
1114
+ if ( ! current_user_can( 'edit_posts' ) ) {
1115
+ //Permission denied
1116
+ wp_die( __( 'Permission denied!', 'simple-download-monitor' ) );
1117
+ exit;
1118
+ }
1119
+
1120
+ //Go ahead with the thumbnail removal
1121
+ $post_id = intval( $_POST['post_id_del'] );
1122
+ $key_exists = metadata_exists( 'post', $post_id, 'sdm_upload_thumbnail' );
1123
+ if ( $key_exists ) {
1124
+ $success = delete_post_meta( $post_id, 'sdm_upload_thumbnail' );
1125
+ if ( $success ) {
1126
+ $response = json_encode( array( 'success' => true ) );
1127
+ }
1128
+ } else {
1129
+ // in order for frontend script to not display "Ajax error", let's return some data
1130
+ $response = json_encode( array( 'not_exists' => true ) );
1131
+ }
1132
+
1133
+ header( 'Content-Type: application/json' );
1134
+ echo $response;
1135
  exit;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1136
  }
1137
 
1138
  // Populate category tree
1141
 
1142
  function sdm_pop_cats_ajax_call() {
1143
 
1144
+ $cat_slug = sanitize_text_field( $_POST['cat_slug'] ); // Get button cpt slug
1145
+ $parent_id = intval( $_POST['parent_id'] ); // Get button cpt id
1146
+ // Query custom posts based on taxonomy slug
1147
+ $posts = get_posts(
1148
+ array(
1149
+ 'post_type' => 'sdm_downloads',
1150
+ 'numberposts' => -1,
1151
+ 'tax_query' => array(
1152
+ array(
1153
+ 'taxonomy' => 'sdm_categories',
1154
+ 'field' => 'slug',
1155
+ 'terms' => $cat_slug,
1156
+ 'include_children' => 0,
1157
+ ),
1158
+ ),
1159
+ 'orderby' => 'title',
1160
+ 'order' => 'ASC',
1161
+ )
1162
+ );
1163
+
1164
+ $final_array = array();
1165
+
1166
+ // Loop results
1167
+ foreach ( $posts as $post ) {
1168
+ // Create array of variables to pass to js
1169
+ $final_array[] = array(
1170
+ 'id' => $post->ID,
1171
+ 'permalink' => get_permalink( $post->ID ),
1172
+ 'title' => $post->post_title,
1173
+ );
1174
+ }
1175
+
1176
+ // Generate ajax response
1177
+ $response = json_encode( array( 'final_array' => $final_array ) );
1178
+ header( 'Content-Type: application/json' );
1179
+ echo $response;
1180
+ exit;
1181
  }
1182
 
1183
  /*
1189
 
1190
  function sdm_create_columns( $cols ) {
1191
 
1192
+ unset( $cols['title'] );
1193
+ unset( $cols['taxonomy-sdm_tags'] );
1194
+ unset( $cols['taxonomy-sdm_categories'] );
1195
+ unset( $cols['date'] );
1196
+
1197
+ $cols['title'] = __( 'Title', 'simple-download-monitor' );
1198
+ $cols['sdm_downloads_thumbnail'] = __( 'Image', 'simple-download-monitor' );
1199
+ $cols['sdm_downloads_id'] = __( 'ID', 'simple-download-monitor' );
1200
+ $cols['sdm_downloads_file'] = __( 'File', 'simple-download-monitor' );
1201
+ $cols['taxonomy-sdm_categories'] = __( 'Categories', 'simple-download-monitor' );
1202
+ $cols['taxonomy-sdm_tags'] = __( 'Tags', 'simple-download-monitor' );
1203
+ $cols['sdm_downloads_count'] = __( 'Downloads', 'simple-download-monitor' );
1204
+ $cols['date'] = __( 'Date Posted', 'simple-download-monitor' );
1205
+ return $cols;
1206
  }
1207
 
1208
  function sdm_downloads_sortable( $cols ) {
1209
 
1210
+ $cols['sdm_downloads_id'] = 'sdm_downloads_id';
1211
+ $cols['sdm_downloads_file'] = 'sdm_downloads_file';
1212
+ $cols['sdm_downloads_count'] = 'sdm_downloads_count';
1213
+ $cols['taxonomy-sdm_categories'] = 'taxonomy-sdm_categories';
1214
+ $cols['taxonomy-sdm_tags'] = 'taxonomy-sdm_tags';
1215
+ return $cols;
1216
  }
1217
 
1218
  function sdm_downloads_columns_content( $column_name, $post_ID ) {
1219
 
1220
+ if ( $column_name == 'sdm_downloads_thumbnail' ) {
1221
+ $old_thumbnail = get_post_meta( $post_ID, 'sdm_upload_thumbnail', true );
1222
+ //$old_value = isset($old_thumbnail) ? $old_thumbnail : '';
1223
+ if ( $old_thumbnail ) {
1224
+ echo '<p class="sdm_downloads_thumbnail_in_admin_listing"><img src="' . $old_thumbnail . '" style="width:50px;height:50px;" /></p>';
1225
+ }
1226
+ }
1227
+ if ( $column_name == 'sdm_downloads_id' ) {
1228
+ echo '<p class="sdm_downloads_postid">' . $post_ID . '</p>';
1229
+ }
1230
+ if ( $column_name == 'sdm_downloads_file' ) {
1231
+ $old_file = get_post_meta( $post_ID, 'sdm_upload', true );
1232
+ $file = isset( $old_file ) ? $old_file : '--';
1233
+ echo '<p class="sdm_downloads_file">' . $file . '</p>';
1234
+ }
1235
+ if ( $column_name == 'sdm_downloads_count' ) {
1236
+ global $wpdb;
1237
+ $wpdb->get_results( $wpdb->prepare( 'SELECT * FROM ' . $wpdb->prefix . 'sdm_downloads WHERE post_id=%s', $post_ID ) );
1238
+ echo '<p class="sdm_downloads_count">' . $wpdb->num_rows . '</p>';
1239
+ }
1240
  }
1241
 
1242
  /*
1244
  */
1245
 
1246
  // First check if option is checked to disable tinymce button
1247
+ $main_option = get_option( 'sdm_downloads_options' );
1248
+ $tiny_button_option = isset( $main_option['admin_tinymce_button'] );
1249
+ if ( $tiny_button_option != true && is_admin() ) {
1250
 
1251
+ // Okay.. we're good. Add the button.
1252
+ add_action( 'init', 'sdm_downloads_tinymce_button' );
1253
 
1254
+ foreach ( array( 'post.php', 'post-new.php' ) as $hook ) {
1255
+ add_action( "admin_head-$hook", 'sdm_downloads_tinymce_admin_head' );
1256
+ }
1257
 
1258
+ function sdm_downloads_tinymce_button() {
 
 
1259
 
1260
+ add_filter( 'mce_external_plugins', 'sdm_downloads_add_button' );
1261
+ add_filter( 'mce_buttons', 'sdm_downloads_register_button' );
1262
+ }
1263
+
1264
+ function sdm_downloads_add_button( $plugin_array ) {
1265
 
1266
+ $plugin_array['sdm_downloads'] = WP_SIMPLE_DL_MONITOR_URL . '/tinymce/sdm_editor_plugin.js';
1267
+ return $plugin_array;
1268
+ }
1269
 
1270
+ function sdm_downloads_register_button( $buttons ) {
1271
 
1272
+ $buttons[] = 'sdm_downloads';
1273
+ return $buttons;
1274
+ }
1275
 
1276
+ function sdm_downloads_tinymce_admin_head() {
1277
+ global $post;
1278
+ //Pass some JS variables
1279
+ ?>
1280
+ <script type="text/javascript">
1281
+ var sdm_del_thumb_postid = '<?php echo $post->ID; ?>';
1282
+ var sdm_admin_ajax_url = {sdm_admin_ajax_url: '<?php echo admin_url( 'admin-ajax.php?action=ajax' ); ?>'};
1283
+ var sdm_plugin_url = '<?php echo plugins_url(); ?>';
1284
+ var tinymce_langs = {
1285
+ select_download_item: '<?php _e( 'Please select a Download Item:', 'simple-download-monitor' ); ?>',
1286
+ download_title: '<?php esc_js( __( 'Download Title', 'simple-download-monitor' ) ); ?>',
1287
+ include_fancy: '<?php _e( 'Include Fancy Box', 'simple-download-monitor' ); ?>',
1288
+ open_new_window: '<?php _e( 'Open New Window', 'simple-download-monitor' ); ?>',
1289
+ button_color: '<?php _e( 'Button Color', 'simple-download-monitor' ); ?>',
1290
+ insert_shortcode: '<?php _e( 'Insert SDM Shortcode', 'simple-download-monitor' ); ?>'
1291
+ };
1292
+ var sdm_button_colors = <?php echo wp_json_encode( sdm_get_download_button_colors() ); ?>;
1293
+ </script>
1294
+ <?php
1295
+ }
1296
+ }
readme.txt CHANGED
@@ -3,8 +3,8 @@ Contributors: Tips and Tricks HQ, Ruhul Amin, josh401, mbrsolution, alexanderfox
3
  Donate link: https://www.tipsandtricks-hq.com
4
  Tags: download, downloads, count, counter, tracker, tracking, hits, logging, monitor, manager, files, media, digital, download monitor, download manager, downloadmanager, file manager, protect downloads, password, download category, file tree, ajax, download template, grid, documents, ip address
5
  Requires at least: 4.1.0
6
- Tested up to: 5.4
7
- Stable tag: 3.8.3
8
  License: GPLv2 or later
9
 
10
  Easily manage downloadable files and monitor downloads of your digital files from your WordPress site.
@@ -41,6 +41,7 @@ https://www.youtube.com/watch?v=SjVaanbulRU
41
  * Track IP addresses of the users who downloaded your files.
42
  * Track date and time of each file downloads.
43
  * Track the usernames of the users downloading the files.
 
44
  * Option to setup secure downloads for your files (the URL of the downloadable file will be hidden).
45
  * Option to upload a thumbnail image for each of your downloadable files.
46
  * Option to use a nice looking template to show your download now buttons.
@@ -61,6 +62,7 @@ https://www.youtube.com/watch?v=SjVaanbulRU
61
  * Ability to show your downloads in a grid display. [View the tutorial](https://www.tipsandtricks-hq.com/show-file-downloads-in-a-nice-grid-display-7273)
62
  * Export all the file download logs to a CSV file.
63
  * Ability to reset the log entries.
 
64
  * Shortcode to show a number of latest downloads to your visitors.
65
  * Shortcode to show a number of popular downloads to your visitors.
66
  * Ability to disable the download monitoring (logging) for certain items (or all items).
@@ -68,7 +70,7 @@ https://www.youtube.com/watch?v=SjVaanbulRU
68
  * Option to specify file size info so it can be shown to your visitors. [View the tutorial](https://simple-download-monitor.com/how-to-show-file-size-info-of-your-downloads/)
69
  * Option to specify version number info for the download item so it can be shown to your visitors.
70
  * Option to show the download published date.
71
- * Option to restrict downloads to logged-in users only.
72
  * Option to ignore download count from bots.
73
  * Option to add Google reCAPTCHA to your download buttons.
74
  * Option to add Terms and Condtions to your download buttons.
@@ -186,6 +188,27 @@ For screenshots please visit the [download monitor plugin page](https://www.tips
186
 
187
  == Changelog ==
188
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
189
  = 3.8.3 =
190
  - Spanish translation file updated.
191
  - Better handling of the stats admin menu interface in mobile devices.
3
  Donate link: https://www.tipsandtricks-hq.com
4
  Tags: download, downloads, count, counter, tracker, tracking, hits, logging, monitor, manager, files, media, digital, download monitor, download manager, downloadmanager, file manager, protect downloads, password, download category, file tree, ajax, download template, grid, documents, ip address
5
  Requires at least: 4.1.0
6
+ Tested up to: 5.5
7
+ Stable tag: 3.8.7
8
  License: GPLv2 or later
9
 
10
  Easily manage downloadable files and monitor downloads of your digital files from your WordPress site.
41
  * Track IP addresses of the users who downloaded your files.
42
  * Track date and time of each file downloads.
43
  * Track the usernames of the users downloading the files.
44
+ * Track the User Agent of the visitors downloading the files.
45
  * Option to setup secure downloads for your files (the URL of the downloadable file will be hidden).
46
  * Option to upload a thumbnail image for each of your downloadable files.
47
  * Option to use a nice looking template to show your download now buttons.
62
  * Ability to show your downloads in a grid display. [View the tutorial](https://www.tipsandtricks-hq.com/show-file-downloads-in-a-nice-grid-display-7273)
63
  * Export all the file download logs to a CSV file.
64
  * Ability to reset the log entries.
65
+ * Ability to trim the download log entries.
66
  * Shortcode to show a number of latest downloads to your visitors.
67
  * Shortcode to show a number of popular downloads to your visitors.
68
  * Ability to disable the download monitoring (logging) for certain items (or all items).
70
  * Option to specify file size info so it can be shown to your visitors. [View the tutorial](https://simple-download-monitor.com/how-to-show-file-size-info-of-your-downloads/)
71
  * Option to specify version number info for the download item so it can be shown to your visitors.
72
  * Option to show the download published date.
73
+ * Option to restrict downloads to logged-in users only. [View the tutorial](https://simple-download-monitor.com/offering-downloads-to-logged-in-users-members-only/)
74
  * Option to ignore download count from bots.
75
  * Option to add Google reCAPTCHA to your download buttons.
76
  * Option to add Terms and Condtions to your download buttons.
188
 
189
  == Changelog ==
190
 
191
+ = 3.8.7 =
192
+ - Added a new filter for the visitor name tracking.
193
+ - Added two new bot strings that will be filtered out from the log (when using the "Do Not Count Downloads from Bots" option).
194
+ - Updated the 'sdm_fancy1_below_download_description' filter hook to also pass the Download ID via additional params.
195
+ - Updated the addon auto-updater library.
196
+ - Added more sanitization to the "Logs" interface.
197
+
198
+ = 3.8.6 =
199
+ - Added a new feature to ignore the "Only Allow Logged-in Users to Download" option on a per download item basis.
200
+ - Added a new settings option to disable capturing of the "User Agent" value in the logs.
201
+ - Added a new feature in the "Logs" menu to allow trimming of log entries. This option can be used to delete log entries older than 3 months for example.
202
+ - Fixed a minor JavaScript issue.
203
+
204
+ = 3.8.5 =
205
+ - Removed the usage of the get_browser() function since it is not supported in some servers. Instead it will just log the full user agent data.
206
+
207
+ = 3.8.4 =
208
+ - Added a new feature to log the user agent data.
209
+ - Added a new filter to allow overriding of the File Download field's URL validation.
210
+ - Fixed a header already sent warning when using the "customizer"
211
+
212
  = 3.8.3 =
213
  - Spanish translation file updated.
214
  - Better handling of the stats admin menu interface in mobile devices.
sdm-post-type-content-handler.php CHANGED
@@ -3,7 +3,7 @@
3
  //Handles the output on the SDM individual download page (Custom Post Type)
4
  add_filter( 'the_content', 'filter_sdm_post_type_content' );
5
 
6
- function filter_sdm_post_type_content( $content ) {
7
  global $post;
8
  if ( isset( $post->post_type ) && $post->post_type == "sdm_downloads" ) {//Handle the content for sdm_downloads type post
9
  //$download_id = $post->ID;
@@ -21,9 +21,9 @@ function filter_sdm_post_type_content( $content ) {
21
  $content .= '</div>';
22
  return $content;
23
  }
24
-
25
  //Check to see if the download link cpt is password protected
26
- $get_cpt_object = get_post( $id );
27
  $cpt_is_password = ! empty( $get_cpt_object->post_password ) ? 'yes' : 'no'; // yes = download is password protected;
28
  //Get item thumbnail
29
  $item_download_thumbnail = get_post_meta( $id, 'sdm_upload_thumbnail', true );
@@ -47,7 +47,7 @@ function filter_sdm_post_type_content( $content ) {
47
 
48
  //Check if show published date is enabled
49
  $show_date_fd = get_post_meta( $id, 'sdm_item_show_date_fd', true );
50
- //Get published date
51
  $published_date = get_the_date( get_option( 'date_format' ), $id );
52
 
53
  // See if user color option is selected
@@ -116,12 +116,13 @@ function filter_sdm_post_type_content( $content ) {
116
  $content .= '<div class="sdm_post_description">' . $isset_item_description . '</div>';
117
 
118
  //This hook can be used to add content below the description
119
- $content .= apply_filters( 'sdm_cpt_below_download_description', '' );
 
120
 
121
  //Check if the button of the single download page is disabled.
122
  $sdm_item_hide_dl_button_single_download_page = get_post_meta( $id, 'sdm_item_hide_dl_button_single_download_page', true );
123
  if ($sdm_item_hide_dl_button_single_download_page){
124
- //the download button is disabled.
125
  $content .= '<div class="sdm_post_single_download_page_disabled_dl_button_msg">';
126
  $msg = '<p>' . __('The admin of this site has disabled the download button for this page.', 'simple-download-monitor') . '</p>';
127
  $content .= apply_filters('sdm_post_single_download_page_disabled_dl_button_msg', $msg);
@@ -129,7 +130,7 @@ function filter_sdm_post_type_content( $content ) {
129
  } else {
130
  $content .= '<div class="sdm_post_download_section"><div class="sdm_download_link">' . $download_button_code . '</div></div>';
131
  }
132
-
133
  if ( ! empty( $isset_item_file_size ) ) {//Show file size info
134
  $content .= '<div class="sdm_post_download_file_size">';
135
  $content .= '<span class="sdm_post_download_size_label">' . __( 'Size: ', 'simple-download-monitor' ) . '</span>';
@@ -186,10 +187,10 @@ function sdm_get_item_description_output( $id ) {
186
  }
187
 
188
  //Add adsense or ad code below the description (if applicable)
189
- add_filter( 'sdm_cpt_below_download_description', 'sdm_add_ad_code_below_description' );
190
- add_filter( 'sdm_fancy1_below_download_description', 'sdm_add_ad_code_below_description' );
191
 
192
- function sdm_add_ad_code_below_description( $output ) {
193
  $main_advanced_opts = get_option( 'sdm_advanced_options' );
194
  $adsense_below_desc = isset( $main_advanced_opts[ 'adsense_below_description' ] ) ? $main_advanced_opts[ 'adsense_below_description' ] : '';
195
  if ( ! empty( $adsense_below_desc ) ) {
3
  //Handles the output on the SDM individual download page (Custom Post Type)
4
  add_filter( 'the_content', 'filter_sdm_post_type_content' );
5
 
6
+ function filter_sdm_post_type_content( $content ) {
7
  global $post;
8
  if ( isset( $post->post_type ) && $post->post_type == "sdm_downloads" ) {//Handle the content for sdm_downloads type post
9
  //$download_id = $post->ID;
21
  $content .= '</div>';
22
  return $content;
23
  }
24
+
25
  //Check to see if the download link cpt is password protected
26
+ $get_cpt_object = get_post( $id );
27
  $cpt_is_password = ! empty( $get_cpt_object->post_password ) ? 'yes' : 'no'; // yes = download is password protected;
28
  //Get item thumbnail
29
  $item_download_thumbnail = get_post_meta( $id, 'sdm_upload_thumbnail', true );
47
 
48
  //Check if show published date is enabled
49
  $show_date_fd = get_post_meta( $id, 'sdm_item_show_date_fd', true );
50
+ //Get published date
51
  $published_date = get_the_date( get_option( 'date_format' ), $id );
52
 
53
  // See if user color option is selected
116
  $content .= '<div class="sdm_post_description">' . $isset_item_description . '</div>';
117
 
118
  //This hook can be used to add content below the description
119
+ $params = array( 'id' => $id );
120
+ $content .= apply_filters( 'sdm_cpt_below_download_description', '', $params);
121
 
122
  //Check if the button of the single download page is disabled.
123
  $sdm_item_hide_dl_button_single_download_page = get_post_meta( $id, 'sdm_item_hide_dl_button_single_download_page', true );
124
  if ($sdm_item_hide_dl_button_single_download_page){
125
+ //the download button is disabled.
126
  $content .= '<div class="sdm_post_single_download_page_disabled_dl_button_msg">';
127
  $msg = '<p>' . __('The admin of this site has disabled the download button for this page.', 'simple-download-monitor') . '</p>';
128
  $content .= apply_filters('sdm_post_single_download_page_disabled_dl_button_msg', $msg);
130
  } else {
131
  $content .= '<div class="sdm_post_download_section"><div class="sdm_download_link">' . $download_button_code . '</div></div>';
132
  }
133
+
134
  if ( ! empty( $isset_item_file_size ) ) {//Show file size info
135
  $content .= '<div class="sdm_post_download_file_size">';
136
  $content .= '<span class="sdm_post_download_size_label">' . __( 'Size: ', 'simple-download-monitor' ) . '</span>';
187
  }
188
 
189
  //Add adsense or ad code below the description (if applicable)
190
+ add_filter( 'sdm_cpt_below_download_description', 'sdm_add_ad_code_below_description', 10, 2 );
191
+ add_filter( 'sdm_fancy1_below_download_description', 'sdm_add_ad_code_below_description', 10, 2 );
192
 
193
+ function sdm_add_ad_code_below_description( $output, $args ) {
194
  $main_advanced_opts = get_option( 'sdm_advanced_options' );
195
  $adsense_below_desc = isset( $main_advanced_opts[ 'adsense_below_description' ] ) ? $main_advanced_opts[ 'adsense_below_description' ] : '';
196
  if ( ! empty( $adsense_below_desc ) ) {
sdm-shortcodes.php CHANGED
@@ -8,27 +8,27 @@ add_filter( 'widget_text', 'do_shortcode' ); //Enable shortcode filtering in sta
8
 
9
  function sdm_register_shortcodes() {
10
 
11
- //Note: shortcode name should use underscores (not dashes). Some of the shortcodes have dashes for backwards compatibility.
12
 
13
- add_shortcode( 'sdm_download', 'sdm_create_download_shortcode' ); // For download shortcode (underscores)
14
- add_shortcode( 'sdm-download', 'sdm_create_download_shortcode' ); // For download shortcode (for backwards compatibility)
15
- add_shortcode( 'sdm_download_counter', 'sdm_create_counter_shortcode' ); // For counter shortcode (underscores)
16
- add_shortcode( 'sdm-download-counter', 'sdm_create_counter_shortcode' ); // For counter shortcode (for backwards compatibility)
17
- add_shortcode( 'sdm_latest_downloads', 'sdm_show_latest_downloads' ); // For showing X number of latest downloads
18
- add_shortcode( 'sdm-latest-downloads', 'sdm_show_latest_downloads' ); // For showing X number of latest downloads(for backwards compatibility)
19
- add_shortcode( 'sdm_popular_downloads', 'sdm_show_popular_downloads' ); // For showing X number of popular downloads
20
 
21
- add_shortcode( 'sdm_download_link', 'sdm_create_simple_download_link' );
22
 
23
- add_shortcode( 'sdm_show_all_dl', 'sdm_handle_show_all_dl_shortcode' ); // For show all downloads shortcode
24
 
25
- add_shortcode( 'sdm_show_dl_from_category', 'sdm_handle_category_shortcode' ); //For category shortcode
26
- add_shortcode( 'sdm_download_categories', 'sdm_download_categories_shortcode' ); // Ajax file tree browser
27
 
28
- add_shortcode( 'sdm_download_categories_list', 'sdm_download_categories_list_shortcode' );
29
- add_shortcode( 'sdm_search_form', 'sdm_search_form_shortcode' );
30
 
31
- add_shortcode( 'sdm_show_download_info', 'sdm_show_download_info_shortcode' );
32
  }
33
 
34
  /**
@@ -40,345 +40,376 @@ function sdm_register_shortcodes() {
40
  */
41
  function sanitize_sdm_create_download_shortcode_atts( $atts ) {
42
 
43
- // Sanitize download item ID
44
- $atts[ 'id' ] = absint( $atts[ 'id' ] );
45
 
46
- // See if user color option is selected
47
- $main_opts = get_option( 'sdm_downloads_options' );
48
 
49
- if ( empty( $atts[ 'color' ] ) ) {
50
- // No color provided by shortcode, read color from plugin settings.
51
- $atts[ 'color' ] = isset( $main_opts[ 'download_button_color' ] ) ? strtolower( $main_opts[ 'download_button_color' ] ) // default values needs to be lowercased
52
- : 'green'
53
- ;
54
- }
55
 
56
- // Remove spaces from color key to make a proper CSS class name.
57
- $atts[ 'color' ] = str_replace( ' ', '', $atts[ 'color' ] );
58
 
59
- return $atts;
60
  }
61
 
62
  // Create Download Shortcode
63
  function sdm_create_download_shortcode( $atts ) {
64
 
65
- $shortcode_atts = sanitize_sdm_create_download_shortcode_atts(
66
- shortcode_atts( array(
67
- 'id' => '',
68
- 'fancy' => '0',
69
- 'button_text' => sdm_get_default_download_button_text( $atts[ 'id' ] ),
70
- 'new_window' => '',
71
- 'color' => '',
72
- 'css_class' => '',
73
- 'show_size' => '',
74
- 'show_version' => '',
75
- ), $atts )
76
- );
77
-
78
- // Make shortcode attributes available in function local scope.
79
- extract( $shortcode_atts );
80
-
81
- if ( empty( $id ) ) {
82
- return '<p style="color: red;">' . __( 'Error! Please enter an ID value with this shortcode.', 'simple-download-monitor' ) . '</p>';
83
- }
84
-
85
- // Check to see if the download link cpt is password protected
86
- $get_cpt_object = get_post( $id );
87
- $cpt_is_password = ! empty( $get_cpt_object->post_password ) ? 'yes' : 'no'; // yes = download is password protected;
88
- // Get CPT title
89
- $item_title = get_the_title( $id );
90
-
91
- //*** Generate the download now button code ***
92
- if ( empty( $new_window ) ) {
93
- $new_window = get_post_meta( $id, 'sdm_item_new_window', true );
94
- }
95
- $window_target = empty( $new_window ) ? '_self' : '_blank';
96
-
97
- $homepage = get_bloginfo( 'url' );
98
- $download_url = $homepage . '/?smd_process_download=1&download_id=' . $id;
99
- $download_button_code = '<a href="' . $download_url . '" class="sdm_download ' . $color . '" title="' . $item_title . '" target="' . $window_target . '">' . $button_text . '</a>';
100
-
101
- $main_advanced_opts = get_option( 'sdm_advanced_options' );
102
-
103
- //Check if Terms & Condition enabled
104
- $termscond_enable = isset( $main_advanced_opts[ 'termscond_enable' ] ) ? true : false;
105
- if ( $termscond_enable ) {
106
- $download_button_code = sdm_get_download_form_with_termsncond( $id, $shortcode_atts, 'sdm_download ' . $color );
107
- }
108
-
109
- //Check if reCAPTCHA enabled
110
- $recaptcha_enable = isset( $main_advanced_opts[ 'recaptcha_enable' ] ) ? true : false;
111
- if ( $recaptcha_enable && $cpt_is_password == 'no' ) {
112
- $download_button_code = sdm_get_download_form_with_recaptcha( $id, $shortcode_atts, 'sdm_download ' . $color );
113
- }
114
-
115
- if ( $cpt_is_password !== 'no' ) {//This is a password protected download so replace the download now button with password requirement
116
- $download_button_code = sdm_get_password_entry_form( $id, $shortcode_atts, 'sdm_download ' . $color );
117
- }
118
- //End of download now button code generation
119
-
120
- $output = '';
121
- switch ( $fancy ) {
122
- case '1':
123
- include_once('includes/templates/fancy1/sdm-fancy-1.php');
124
- $output .= sdm_generate_fancy1_display_output( $shortcode_atts );
125
- $output .= '<div class="sdm_clear_float"></div>';
126
- break;
127
- case '2':
128
- include_once('includes/templates/fancy2/sdm-fancy-2.php');
129
- $output .= '<link type="text/css" rel="stylesheet" href="' . WP_SIMPLE_DL_MONITOR_URL . '/includes/templates/fancy2/sdm-fancy-2-styles.css?ver=' . WP_SIMPLE_DL_MONITOR_VERSION . '" />';
130
- $output .= sdm_generate_fancy2_display_output( $shortcode_atts );
131
- $output .= '<div class="sdm_clear_float"></div>';
132
- break;
133
- case '3':
134
- include_once('includes/templates/fancy3/sdm-fancy-3.php');
135
- $output .= sdm_generate_fancy3_display_output( $shortcode_atts );
136
- $output .= '<div class="sdm_clear_float"></div>';
137
- break;
138
- default: // Default output is the standard download now button (fancy 0)
139
- include_once('includes/templates/fancy0/sdm-fancy-0.php');
140
- $output .= sdm_generate_fancy0_display_output( $shortcode_atts );
141
- }
142
-
143
- return apply_filters( 'sdm_download_shortcode_output', $output, $atts );
 
 
 
144
  }
145
 
146
  function sdm_create_simple_download_link( $atts ) {
147
- extract( shortcode_atts( array(
148
- 'id' => '',
149
- ), $atts ) );
150
-
151
- if ( empty( $id ) ) {
152
- return '<p style="color: red;">' . __( 'Error! Please enter an ID value with this shortcode.', 'simple-download-monitor' ) . '</p>';
153
- }
 
 
 
 
 
154
 
155
- return WP_SIMPLE_DL_MONITOR_SITE_HOME_URL . '/?smd_process_download=1&download_id=' . $id;
156
  }
157
 
158
  // Create Counter Shortcode
159
  function sdm_create_counter_shortcode( $atts ) {
160
 
161
- extract( shortcode_atts( array(
162
- 'id' => ''
163
- ), $atts ) );
164
-
165
- if ( empty( $id ) ) {
166
- return '<p style="color: red;">' . __( 'Error! Please enter an ID value with this shortcode.', 'simple-download-monitor' ) . '</p>';
167
- }
 
 
 
 
 
168
 
169
- $db_count = sdm_get_download_count_for_post( $id );
170
 
171
- // Set string for singular/plural results
172
- $string = ($db_count == '1') ? __( 'Download', 'simple-download-monitor' ) : __( 'Downloads', 'simple-download-monitor' );
173
 
174
- $output = '<div class="sdm_download_count"><span class="sdm_count_number">' . $db_count . '</span><span class="sdm_count_string"> ' . $string . '</span></div>';
175
- // Return result
176
- return apply_filters( 'sdm_download_count_output', $output, $atts );
177
  }
178
 
179
  // Create Category Shortcode
180
  function sdm_handle_category_shortcode( $args ) {
181
 
182
- extract( shortcode_atts( array(
183
- 'category_slug' => '',
184
- 'category_id' => '',
185
- 'fancy' => '0',
186
- 'button_text' => __( 'Download Now!', 'simple-download-monitor' ),
187
- 'new_window' => '',
188
- 'orderby' => 'post_date',
189
- 'order' => 'DESC',
190
- 'pagination' => '',
191
- ), $args ) );
192
-
193
- // Define vars
194
- $field = '';
195
- $terms = '';
196
-
197
- // If category slug and category id are empty.. return error
198
- if ( empty( $category_slug ) && empty( $category_id ) && empty( $args[ 'show_all' ] ) ) {
199
- return '<p style="color: red;">' . __( 'Error! You must enter a category slug OR a category id with this shortcode. Refer to the documentation for usage instructions.', 'simple-download-monitor' ) . '</p>';
200
- }
201
-
202
- // If both category slug AND category id are defined... return error
203
- if ( ! empty( $category_slug ) && ! empty( $category_id ) ) {
204
- return '<p style="color: red;">' . __( 'Error! Please enter a category slug OR id; not both.', 'simple-download-monitor' ) . '</p>';
205
- }
206
-
207
- // Else setup query arguments for category_slug
208
- if ( ! empty( $category_slug ) && empty( $category_id ) ) {
209
-
210
- $field = 'slug';
211
-
212
- $terms = array_filter( explode( ',', $category_slug ), function($value) {
213
- return ! empty( $value ) ? trim( $value ) : false;
214
- } );
215
- }
216
- // Else setup query arguments for category_id
217
- else if ( ! empty( $category_id ) && empty( $category_slug ) ) {
218
-
219
- $field = 'term_id';
220
- //$terms = $category_id;
221
- $terms = array_filter( explode( ',', $category_id ), function($value) {
222
- return ! empty( $value ) ? trim( $value ) : false;
223
- } );
224
- }
225
-
226
- if ( isset( $args[ 'show_all' ] ) ) {
227
- $tax_query = array();
228
- } else {
229
- $tax_query = array( array(
230
- 'taxonomy' => 'sdm_categories',
231
- 'field' => $field,
232
- 'terms' => $terms
233
- ) );
234
- }
235
-
236
- // For pagination
237
- $paged = ( get_query_var( 'paged' ) ) ? absint( get_query_var( 'paged' ) ) : 1;
238
- if ( isset( $args[ 'pagination' ] ) ) {
239
- if ( ! is_numeric( $args[ 'pagination' ] ) ) {
240
- return '<p style="color: red;">' . __( 'Error! You must enter a numeric number for the "pagination" parameter of the shortcode. Refer to the usage documentation.', 'simple-download-monitor' ) . '</p>';
241
  }
242
- $posts_per_page = $args[ 'pagination' ];
243
- } else {
244
- $posts_per_page = 9999;
245
- }
246
-
247
-
248
- // Query cpt's based on arguments above
249
- $get_posts_args = array(
250
- 'post_type' => 'sdm_downloads',
251
- 'show_posts' => -1,
252
- 'posts_per_page' => $posts_per_page,
253
- 'tax_query' => $tax_query,
254
- 'orderby' => $orderby,
255
- 'order' => $order,
256
- 'paged' => $paged,
257
- );
258
-
259
- $query = new WP_Query;
260
-
261
- $get_posts = $query->query( $get_posts_args );
262
-
263
- // If no cpt's are found
264
- if ( ! $get_posts ) {
265
- return '<p style="color: red;">' . __( 'There are no download items matching this category criteria.', 'simple-download-monitor' ) . '</p>';
266
- }
267
- // Else iterate cpt's
268
- else {
269
 
270
- $output = '';
 
 
 
271
 
272
- // See if user color option is selected
273
- $main_opts = get_option( 'sdm_downloads_options' );
274
- $color_opt = $main_opts[ 'download_button_color' ];
275
- $def_color = isset( $color_opt ) ? str_replace( ' ', '', strtolower( $color_opt ) ) : 'green';
276
 
277
- if ( $fancy == '0' ) {
278
 
279
- // Setup download location
280
- $homepage = get_bloginfo( 'url' );
281
- if ( empty( $new_window ) ) {
282
- $new_window = get_post_meta( $id, 'sdm_item_new_window', true );
283
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
284
 
285
- $window_target = empty( $new_window ) ? '_self' : '_blank';
 
 
 
 
 
 
 
 
 
 
286
 
287
- // Iterate cpt's
288
- foreach ( $get_posts as $item ) {
 
 
 
 
 
 
 
 
289
 
290
- // Set download location
291
- $id = $item->ID; // get each cpt ID
292
- $download_url = $homepage . '/?smd_process_download=1&download_id=' . $id;
 
 
 
 
 
 
 
293
 
294
- // Get each cpt title
295
- $item_title = get_the_title( $id );
296
 
297
- // Setup download button code
298
- $download_button_code = '<a href="' . $download_url . '" class="sdm_download ' . $def_color . '" title="' . $item_title . '" target="' . $window_target . '">' . $button_text . '</a>';
299
 
 
 
 
 
 
 
300
 
301
- $main_advanced_opts = get_option( 'sdm_advanced_options' );
302
 
303
- //Check if Terms & Condition enabled
304
- $termscond_enable = isset( $main_advanced_opts[ 'termscond_enable' ] ) ? true : false;
305
- if ( $termscond_enable ) {
306
- $download_button_code = sdm_get_download_form_with_termsncond( $id, $args, 'sdm_download ' . $def_color );
307
- }
308
 
309
- //Check if reCAPTCHA enabled
310
- $recaptcha_enable = isset( $main_advanced_opts[ 'recaptcha_enable' ] ) ? true : false;
311
- if ( $recaptcha_enable ) {
312
- $download_button_code = sdm_get_download_form_with_recaptcha( $id, $args, 'sdm_download ' . $def_color );
313
- }
314
 
315
- // Generate download buttons
316
- $output .= '<div class="sdm_download_link">' . $download_button_code . '</div><br />';
317
- } // End foreach
318
- }
319
- // Fancy 1 and onwards handles the loop inside the template function
320
- else if ( $fancy == '1' ) {
321
- include_once('includes/templates/fancy1/sdm-fancy-1.php');
322
- $output .= sdm_generate_fancy1_category_display_output( $get_posts, $args );
323
- } else if ( $fancy == '2' ) {
324
- include_once('includes/templates/fancy2/sdm-fancy-2.php');
325
- $output .= sdm_generate_fancy2_category_display_output( $get_posts, $args );
326
- } else if ( $fancy == '3' ) {
327
- include_once('includes/templates/fancy3/sdm-fancy-3.php');
328
- $output .= sdm_generate_fancy3_category_display_output( $get_posts, $args );
329
- }
330
 
331
- // Pagination related
332
- if ( isset( $args[ 'pagination' ] ) ) {
333
- $posts_per_page = $args[ 'pagination' ];
334
- $count_sdm_posts = $query->found_posts;
335
- $published_sdm_posts = $count_sdm_posts;
336
- $total_pages = ceil( $published_sdm_posts / $posts_per_page );
337
-
338
- $big = 999999999; // Need an unlikely integer
339
- $pagination = paginate_links( array(
340
- 'base' => str_replace( $big, '%#%', esc_url( get_pagenum_link( $big ) ) ),
341
- 'format' => '',
342
- 'add_args' => '',
343
- 'current' => max( 1, get_query_var( 'paged' ) ),
344
- 'total' => $total_pages,
345
- 'prev_text' => '&laquo;',
346
- 'next_text' => '&raquo;',
347
- ) );
348
- $output .= '<div class="sdm_pagination">' . $pagination . '</div>';
349
- }
350
 
351
- // Return results
352
- return apply_filters( 'sdm_category_download_items_shortcode_output', $output, $args, $get_posts );
353
- } // End else iterate cpt's
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
354
  }
355
 
356
  // Create category tree shortcode
357
  function sdm_download_categories_shortcode() {
358
 
359
- function custom_taxonomy_walker( $taxonomy, $parent = 0 ) {
360
-
361
- // Get terms (check if has parent)
362
- $terms = get_terms( $taxonomy, array( 'parent' => $parent, 'hide_empty' => false ) );
363
-
364
- // If there are terms, start displaying
365
- if ( count( $terms ) > 0 ) {
366
- // Displaying as a list
367
- $out = '<ul>';
368
- // Cycle though the terms
369
- foreach ( $terms as $term ) {
370
- // Secret sauce. Function calls itself to display child elements, if any
371
- $out .= '<li class="sdm_cat" id="' . $term->slug . '"><span id="' . $term->term_id . '" class="sdm_cat_title" style="cursor:pointer;">' . $term->name . '</span>';
372
- $out .= '<p class="sdm_placeholder" style="margin-bottom:0;"></p>' . custom_taxonomy_walker( $taxonomy, $term->term_id );
373
- $out .= '</li>';
374
- }
375
- $out .= '</ul>';
376
- return $out;
 
 
 
 
 
 
 
 
377
  }
378
- return;
379
- }
380
 
381
- return '<div class="sdm_object_tree">' . custom_taxonomy_walker( 'sdm_categories' ) . '</div>';
382
  }
383
 
384
  /**
@@ -389,38 +420,39 @@ function sdm_download_categories_shortcode() {
389
  */
390
  function sdm_download_categories_list_walker( $atts, $parent = 0 ) {
391
 
392
- $count = (bool) $atts[ 'count' ];
393
- $hierarchical = (bool) $atts[ 'hierarchical' ];
394
- $show_empty = (bool) $atts[ 'empty' ];
395
- $list_tag = $atts[ 'numbered' ] ? 'ol' : 'ul';
396
-
397
- // Get terms (check if has parent)
398
- $terms = get_terms( array(
399
- 'taxonomy' => 'sdm_categories',
400
- 'parent' => $parent,
401
- 'hide_empty' => ! $show_empty
402
- ) );
403
-
404
- // Return empty string, if no terms found.
405
- if ( empty( $terms ) ) {
406
- return '';
407
- }
408
-
409
- // Produce list of download categories under $parent.
410
- $out = '<' . $list_tag . '>';
411
-
412
- foreach ( $terms as $term ) {
413
- $out .= '<li>'
414
- . '<a href="' . get_term_link( $term ) . '">' . $term->name . '</a>' // link
415
- . ( $count ? (' <span>(' . $term->count . ')</span>') : '') // count
416
- . ( $hierarchical ? sdm_download_categories_list_walker( $atts, $term->term_id ) : '' ) // subcategories
417
- . '</li>'
418
- ;
419
- }
420
-
421
- $out .= '</' . $list_tag . '>';
422
-
423
- return $out;
 
424
  }
425
 
426
  /**
@@ -430,89 +462,93 @@ function sdm_download_categories_list_walker( $atts, $parent = 0 ) {
430
  */
431
  function sdm_download_categories_list_shortcode( $attributes ) {
432
 
433
- $atts = shortcode_atts(
434
- array(
435
- 'class' => 'sdm-download-categories', // wrapper class
436
- 'empty' => '0', // show empty categories
437
- 'numbered' => '0', // use <ol> instead of <ul> to wrap the list
438
- 'count' => '0', // display count of items in every category
439
- 'hierarchical' => '1', // display subcategories as well
440
- ), $attributes
441
- );
442
-
443
- return
444
- '<div class="' . esc_attr( $atts[ 'class' ] ) . '">'
445
- . sdm_download_categories_list_walker( $atts )
446
- . '</div>'
447
- ;
448
  }
449
 
450
  function sdm_show_download_info_shortcode( $args ) {
451
- extract( shortcode_atts( array(
452
- 'id' => '',
453
- 'download_info' => '',
454
- ), $args ) );
 
 
 
 
 
 
 
 
 
455
 
456
- if ( empty( $id ) || empty( $download_info ) ) {
457
- return '<div class="sdm_shortcode_error">Error! you must enter a value for "id" and "download_info" parameters.</div>';
458
- }
459
 
460
- //Available values: title, description, download_url, thumbnail, file_size, file_version, download_count
 
461
 
462
- $id = absint( $id );
463
- $get_cpt_object = get_post( $id );
 
 
464
 
465
- if ( $download_info == "title" ) {//download title
466
- $item_title = get_the_title( $id );
467
- return $item_title;
468
- }
469
-
470
- if ( $download_info == "description" ) {//download description
471
- $item_description = sdm_get_item_description_output( $id );
472
- return $item_description;
473
- }
474
-
475
- if ( $download_info == "download_url" ) {//download URL
476
- $download_link = get_post_meta( $id, 'sdm_upload', true );
477
- return $download_link;
478
- }
479
-
480
- if ( $download_info == "thumbnail" ) {//download thumb
481
- $download_thumbnail = get_post_meta( $id, 'sdm_upload_thumbnail', true );
482
- $download_thumbnail = '<img class="sdm_download_thumbnail_image" src="' . $download_thumbnail . '" />';
483
- return $download_thumbnail;
484
- }
485
-
486
- if ( $download_info == "thumbnail_url" ) {//download thumbnail raw URL
487
- $download_thumbnail = get_post_meta( $id, 'sdm_upload_thumbnail', true );
488
- return $download_thumbnail;
489
- }
490
-
491
- if ( $download_info == "file_size" ) {//download file size
492
- $file_size = get_post_meta( $id, 'sdm_item_file_size', true );
493
- return $file_size;
494
- }
495
-
496
- if ( $download_info == "file_version" ) {//download file version
497
- $file_version = get_post_meta( $id, 'sdm_item_version', true );
498
- return $file_version;
499
- }
500
-
501
- if ( $download_info == "download_count" ) {//download count
502
- $dl_count = sdm_get_download_count_for_post( $id );
503
- return $dl_count;
504
- }
505
-
506
- return '<div class="sdm_shortcode_error">Error! The value of "download_info" field does not match any availalbe parameters.</div>';
507
  }
508
 
509
  function sdm_handle_show_all_dl_shortcode( $args ) {
510
- if ( isset( $args[ 'category_id' ] ) ) {
511
- unset( $args[ 'category_id' ] );
512
- }
513
- if ( isset( $args[ 'category_slug' ] ) ) {
514
- unset( $args[ 'category_slug' ] );
515
- }
516
- $args[ 'show_all' ] = 1;
517
- return sdm_handle_category_shortcode( $args );
518
  }
8
 
9
  function sdm_register_shortcodes() {
10
 
11
+ //Note: shortcode name should use underscores (not dashes). Some of the shortcodes have dashes for backwards compatibility.
12
 
13
+ add_shortcode( 'sdm_download', 'sdm_create_download_shortcode' ); // For download shortcode (underscores)
14
+ add_shortcode( 'sdm-download', 'sdm_create_download_shortcode' ); // For download shortcode (for backwards compatibility)
15
+ add_shortcode( 'sdm_download_counter', 'sdm_create_counter_shortcode' ); // For counter shortcode (underscores)
16
+ add_shortcode( 'sdm-download-counter', 'sdm_create_counter_shortcode' ); // For counter shortcode (for backwards compatibility)
17
+ add_shortcode( 'sdm_latest_downloads', 'sdm_show_latest_downloads' ); // For showing X number of latest downloads
18
+ add_shortcode( 'sdm-latest-downloads', 'sdm_show_latest_downloads' ); // For showing X number of latest downloads(for backwards compatibility)
19
+ add_shortcode( 'sdm_popular_downloads', 'sdm_show_popular_downloads' ); // For showing X number of popular downloads
20
 
21
+ add_shortcode( 'sdm_download_link', 'sdm_create_simple_download_link' );
22
 
23
+ add_shortcode( 'sdm_show_all_dl', 'sdm_handle_show_all_dl_shortcode' ); // For show all downloads shortcode
24
 
25
+ add_shortcode( 'sdm_show_dl_from_category', 'sdm_handle_category_shortcode' ); //For category shortcode
26
+ add_shortcode( 'sdm_download_categories', 'sdm_download_categories_shortcode' ); // Ajax file tree browser
27
 
28
+ add_shortcode( 'sdm_download_categories_list', 'sdm_download_categories_list_shortcode' );
29
+ add_shortcode( 'sdm_search_form', 'sdm_search_form_shortcode' );
30
 
31
+ add_shortcode( 'sdm_show_download_info', 'sdm_show_download_info_shortcode' );
32
  }
33
 
34
  /**
40
  */
41
  function sanitize_sdm_create_download_shortcode_atts( $atts ) {
42
 
43
+ // Sanitize download item ID
44
+ $atts['id'] = absint( $atts['id'] );
45
 
46
+ // See if user color option is selected
47
+ $main_opts = get_option( 'sdm_downloads_options' );
48
 
49
+ if ( empty( $atts['color'] ) ) {
50
+ // No color provided by shortcode, read color from plugin settings.
51
+ $atts['color'] = isset( $main_opts['download_button_color'] ) ? strtolower( $main_opts['download_button_color'] ) // default values needs to be lowercased
52
+ : 'green';
53
+ }
 
54
 
55
+ // Remove spaces from color key to make a proper CSS class name.
56
+ $atts['color'] = str_replace( ' ', '', $atts['color'] );
57
 
58
+ return $atts;
59
  }
60
 
61
  // Create Download Shortcode
62
  function sdm_create_download_shortcode( $atts ) {
63
 
64
+ $shortcode_atts = sanitize_sdm_create_download_shortcode_atts(
65
+ shortcode_atts(
66
+ array(
67
+ 'id' => '',
68
+ 'fancy' => '0',
69
+ 'button_text' => sdm_get_default_download_button_text( $atts['id'] ),
70
+ 'new_window' => '',
71
+ 'color' => '',
72
+ 'css_class' => '',
73
+ 'show_size' => '',
74
+ 'show_version' => '',
75
+ ),
76
+ $atts
77
+ )
78
+ );
79
+
80
+ // Make shortcode attributes available in function local scope.
81
+ extract( $shortcode_atts );
82
+
83
+ if ( empty( $id ) ) {
84
+ return '<p style="color: red;">' . __( 'Error! Please enter an ID value with this shortcode.', 'simple-download-monitor' ) . '</p>';
85
+ }
86
+
87
+ // Check to see if the download link cpt is password protected
88
+ $get_cpt_object = get_post( $id );
89
+ $cpt_is_password = ! empty( $get_cpt_object->post_password ) ? 'yes' : 'no'; // yes = download is password protected;
90
+ // Get CPT title
91
+ $item_title = get_the_title( $id );
92
+
93
+ //*** Generate the download now button code ***
94
+ if ( empty( $new_window ) ) {
95
+ $new_window = get_post_meta( $id, 'sdm_item_new_window', true );
96
+ }
97
+ $window_target = empty( $new_window ) ? '_self' : '_blank';
98
+
99
+ $homepage = get_bloginfo( 'url' );
100
+ $download_url = $homepage . '/?smd_process_download=1&download_id=' . $id;
101
+ $download_button_code = '<a href="' . $download_url . '" class="sdm_download ' . $color . '" title="' . $item_title . '" target="' . $window_target . '">' . $button_text . '</a>';
102
+
103
+ $main_advanced_opts = get_option( 'sdm_advanced_options' );
104
+
105
+ //Check if Terms & Condition enabled
106
+ $termscond_enable = isset( $main_advanced_opts['termscond_enable'] ) ? true : false;
107
+ if ( $termscond_enable ) {
108
+ $download_button_code = sdm_get_download_form_with_termsncond( $id, $shortcode_atts, 'sdm_download ' . $color );
109
+ }
110
+
111
+ //Check if reCAPTCHA enabled
112
+ $recaptcha_enable = isset( $main_advanced_opts['recaptcha_enable'] ) ? true : false;
113
+ if ( $recaptcha_enable && $cpt_is_password == 'no' ) {
114
+ $download_button_code = sdm_get_download_form_with_recaptcha( $id, $shortcode_atts, 'sdm_download ' . $color );
115
+ }
116
+
117
+ if ( $cpt_is_password !== 'no' ) {//This is a password protected download so replace the download now button with password requirement
118
+ $download_button_code = sdm_get_password_entry_form( $id, $shortcode_atts, 'sdm_download ' . $color );
119
+ }
120
+ //End of download now button code generation
121
+
122
+ $output = '';
123
+ switch ( $fancy ) {
124
+ case '1':
125
+ include_once 'includes/templates/fancy1/sdm-fancy-1.php';
126
+ $output .= sdm_generate_fancy1_display_output( $shortcode_atts );
127
+ $output .= '<div class="sdm_clear_float"></div>';
128
+ break;
129
+ case '2':
130
+ include_once 'includes/templates/fancy2/sdm-fancy-2.php';
131
+ $output .= '<link type="text/css" rel="stylesheet" href="' . WP_SIMPLE_DL_MONITOR_URL . '/includes/templates/fancy2/sdm-fancy-2-styles.css?ver=' . WP_SIMPLE_DL_MONITOR_VERSION . '" />';
132
+ $output .= sdm_generate_fancy2_display_output( $shortcode_atts );
133
+ $output .= '<div class="sdm_clear_float"></div>';
134
+ break;
135
+ case '3':
136
+ include_once 'includes/templates/fancy3/sdm-fancy-3.php';
137
+ $output .= sdm_generate_fancy3_display_output( $shortcode_atts );
138
+ $output .= '<div class="sdm_clear_float"></div>';
139
+ break;
140
+ default: // Default output is the standard download now button (fancy 0)
141
+ include_once 'includes/templates/fancy0/sdm-fancy-0.php';
142
+ $output .= sdm_generate_fancy0_display_output( $shortcode_atts );
143
+ }
144
+
145
+ return apply_filters( 'sdm_download_shortcode_output', $output, $atts );
146
  }
147
 
148
  function sdm_create_simple_download_link( $atts ) {
149
+ extract(
150
+ shortcode_atts(
151
+ array(
152
+ 'id' => '',
153
+ ),
154
+ $atts
155
+ )
156
+ );
157
+
158
+ if ( empty( $id ) ) {
159
+ return '<p style="color: red;">' . __( 'Error! Please enter an ID value with this shortcode.', 'simple-download-monitor' ) . '</p>';
160
+ }
161
 
162
+ return WP_SIMPLE_DL_MONITOR_SITE_HOME_URL . '/?smd_process_download=1&download_id=' . $id;
163
  }
164
 
165
  // Create Counter Shortcode
166
  function sdm_create_counter_shortcode( $atts ) {
167
 
168
+ extract(
169
+ shortcode_atts(
170
+ array(
171
+ 'id' => '',
172
+ ),
173
+ $atts
174
+ )
175
+ );
176
+
177
+ if ( empty( $id ) ) {
178
+ return '<p style="color: red;">' . __( 'Error! Please enter an ID value with this shortcode.', 'simple-download-monitor' ) . '</p>';
179
+ }
180
 
181
+ $db_count = sdm_get_download_count_for_post( $id );
182
 
183
+ // Set string for singular/plural results
184
+ $string = ( $db_count == '1' ) ? __( 'Download', 'simple-download-monitor' ) : __( 'Downloads', 'simple-download-monitor' );
185
 
186
+ $output = '<div class="sdm_download_count"><span class="sdm_count_number">' . $db_count . '</span><span class="sdm_count_string"> ' . $string . '</span></div>';
187
+ // Return result
188
+ return apply_filters( 'sdm_download_count_output', $output, $atts );
189
  }
190
 
191
  // Create Category Shortcode
192
  function sdm_handle_category_shortcode( $args ) {
193
 
194
+ extract(
195
+ shortcode_atts(
196
+ array(
197
+ 'category_slug' => '',
198
+ 'category_id' => '',
199
+ 'fancy' => '0',
200
+ 'button_text' => __( 'Download Now!', 'simple-download-monitor' ),
201
+ 'new_window' => '',
202
+ 'orderby' => 'post_date',
203
+ 'order' => 'DESC',
204
+ 'pagination' => '',
205
+ ),
206
+ $args
207
+ )
208
+ );
209
+
210
+ // Define vars
211
+ $field = '';
212
+ $terms = '';
213
+
214
+ // If category slug and category id are empty.. return error
215
+ if ( empty( $category_slug ) && empty( $category_id ) && empty( $args['show_all'] ) ) {
216
+ return '<p style="color: red;">' . __( 'Error! You must enter a category slug OR a category id with this shortcode. Refer to the documentation for usage instructions.', 'simple-download-monitor' ) . '</p>';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
217
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
218
 
219
+ // If both category slug AND category id are defined... return error
220
+ if ( ! empty( $category_slug ) && ! empty( $category_id ) ) {
221
+ return '<p style="color: red;">' . __( 'Error! Please enter a category slug OR id; not both.', 'simple-download-monitor' ) . '</p>';
222
+ }
223
 
224
+ // Else setup query arguments for category_slug
225
+ if ( ! empty( $category_slug ) && empty( $category_id ) ) {
 
 
226
 
227
+ $field = 'slug';
228
 
229
+ $terms = array_filter(
230
+ explode( ',', $category_slug ),
231
+ function( $value ) {
232
+ return ! empty( $value ) ? trim( $value ) : false;
233
+ }
234
+ );
235
+ }
236
+ // Else setup query arguments for category_id
237
+ elseif ( ! empty( $category_id ) && empty( $category_slug ) ) {
238
+
239
+ $field = 'term_id';
240
+ //$terms = $category_id;
241
+ $terms = array_filter(
242
+ explode( ',', $category_id ),
243
+ function( $value ) {
244
+ return ! empty( $value ) ? trim( $value ) : false;
245
+ }
246
+ );
247
+ }
248
 
249
+ if ( isset( $args['show_all'] ) ) {
250
+ $tax_query = array();
251
+ } else {
252
+ $tax_query = array(
253
+ array(
254
+ 'taxonomy' => 'sdm_categories',
255
+ 'field' => $field,
256
+ 'terms' => $terms,
257
+ ),
258
+ );
259
+ }
260
 
261
+ // For pagination
262
+ $paged = ( get_query_var( 'paged' ) ) ? absint( get_query_var( 'paged' ) ) : 1;
263
+ if ( isset( $args['pagination'] ) ) {
264
+ if ( ! is_numeric( $args['pagination'] ) ) {
265
+ return '<p style="color: red;">' . __( 'Error! You must enter a numeric number for the "pagination" parameter of the shortcode. Refer to the usage documentation.', 'simple-download-monitor' ) . '</p>';
266
+ }
267
+ $posts_per_page = $args['pagination'];
268
+ } else {
269
+ $posts_per_page = 9999;
270
+ }
271
 
272
+ // Query cpt's based on arguments above
273
+ $get_posts_args = array(
274
+ 'post_type' => 'sdm_downloads',
275
+ 'show_posts' => -1,
276
+ 'posts_per_page' => $posts_per_page,
277
+ 'tax_query' => $tax_query,
278
+ 'orderby' => $orderby,
279
+ 'order' => $order,
280
+ 'paged' => $paged,
281
+ );
282
 
283
+ $query = new WP_Query();
 
284
 
285
+ $get_posts = $query->query( $get_posts_args );
 
286
 
287
+ // If no cpt's are found
288
+ if ( ! $get_posts ) {
289
+ return '<p style="color: red;">' . __( 'There are no download items matching this category criteria.', 'simple-download-monitor' ) . '</p>';
290
+ }
291
+ // Else iterate cpt's
292
+ else {
293
 
294
+ $output = '';
295
 
296
+ // See if user color option is selected
297
+ $main_opts = get_option( 'sdm_downloads_options' );
298
+ $color_opt = $main_opts['download_button_color'];
299
+ $def_color = isset( $color_opt ) ? str_replace( ' ', '', strtolower( $color_opt ) ) : 'green';
 
300
 
301
+ if ( $fancy == '0' ) {
 
 
 
 
302
 
303
+ // Setup download location
304
+ $homepage = get_bloginfo( 'url' );
305
+ if ( empty( $new_window ) ) {
306
+ $new_window = get_post_meta( $id, 'sdm_item_new_window', true );
307
+ }
 
 
 
 
 
 
 
 
 
 
308
 
309
+ $window_target = empty( $new_window ) ? '_self' : '_blank';
310
+
311
+ // Iterate cpt's
312
+ foreach ( $get_posts as $item ) {
313
+
314
+ // Set download location
315
+ $id = $item->ID; // get each cpt ID
316
+ $download_url = $homepage . '/?smd_process_download=1&download_id=' . $id;
 
 
 
 
 
 
 
 
 
 
 
317
 
318
+ // Get each cpt title
319
+ $item_title = get_the_title( $id );
320
+
321
+ // Setup download button code
322
+ $download_button_code = '<a href="' . $download_url . '" class="sdm_download ' . $def_color . '" title="' . $item_title . '" target="' . $window_target . '">' . $button_text . '</a>';
323
+
324
+ $main_advanced_opts = get_option( 'sdm_advanced_options' );
325
+
326
+ //Check if Terms & Condition enabled
327
+ $termscond_enable = isset( $main_advanced_opts['termscond_enable'] ) ? true : false;
328
+ if ( $termscond_enable ) {
329
+ $download_button_code = sdm_get_download_form_with_termsncond( $id, $args, 'sdm_download ' . $def_color );
330
+ }
331
+
332
+ //Check if reCAPTCHA enabled
333
+ $recaptcha_enable = isset( $main_advanced_opts['recaptcha_enable'] ) ? true : false;
334
+ if ( $recaptcha_enable ) {
335
+ $download_button_code = sdm_get_download_form_with_recaptcha( $id, $args, 'sdm_download ' . $def_color );
336
+ }
337
+
338
+ // Generate download buttons
339
+ $output .= '<div class="sdm_download_link">' . $download_button_code . '</div><br />';
340
+ } // End foreach
341
+ }
342
+ // Fancy 1 and onwards handles the loop inside the template function
343
+ elseif ( $fancy == '1' ) {
344
+ include_once 'includes/templates/fancy1/sdm-fancy-1.php';
345
+ $output .= sdm_generate_fancy1_category_display_output( $get_posts, $args );
346
+ } elseif ( $fancy == '2' ) {
347
+ include_once 'includes/templates/fancy2/sdm-fancy-2.php';
348
+ $output .= sdm_generate_fancy2_category_display_output( $get_posts, $args );
349
+ } elseif ( $fancy == '3' ) {
350
+ include_once 'includes/templates/fancy3/sdm-fancy-3.php';
351
+ $output .= sdm_generate_fancy3_category_display_output( $get_posts, $args );
352
+ }
353
+
354
+ // Pagination related
355
+ if ( isset( $args['pagination'] ) ) {
356
+ $posts_per_page = $args['pagination'];
357
+ $count_sdm_posts = $query->found_posts;
358
+ $published_sdm_posts = $count_sdm_posts;
359
+ $total_pages = ceil( $published_sdm_posts / $posts_per_page );
360
+
361
+ $big = 999999999; // Need an unlikely integer
362
+ $pagination = paginate_links(
363
+ array(
364
+ 'base' => str_replace( $big, '%#%', esc_url( get_pagenum_link( $big ) ) ),
365
+ 'format' => '',
366
+ 'add_args' => '',
367
+ 'current' => max( 1, get_query_var( 'paged' ) ),
368
+ 'total' => $total_pages,
369
+ 'prev_text' => '&laquo;',
370
+ 'next_text' => '&raquo;',
371
+ )
372
+ );
373
+ $output .= '<div class="sdm_pagination">' . $pagination . '</div>';
374
+ }
375
+
376
+ // Return results
377
+ return apply_filters( 'sdm_category_download_items_shortcode_output', $output, $args, $get_posts );
378
+ } // End else iterate cpt's
379
  }
380
 
381
  // Create category tree shortcode
382
  function sdm_download_categories_shortcode() {
383
 
384
+ function custom_taxonomy_walker( $taxonomy, $parent = 0 ) {
385
+
386
+ // Get terms (check if has parent)
387
+ $terms = get_terms(
388
+ $taxonomy,
389
+ array(
390
+ 'parent' => $parent,
391
+ 'hide_empty' => false,
392
+ )
393
+ );
394
+
395
+ // If there are terms, start displaying
396
+ if ( count( $terms ) > 0 ) {
397
+ // Displaying as a list
398
+ $out = '<ul>';
399
+ // Cycle though the terms
400
+ foreach ( $terms as $term ) {
401
+ // Secret sauce. Function calls itself to display child elements, if any
402
+ $out .= '<li class="sdm_cat" id="' . $term->slug . '"><span id="' . $term->term_id . '" class="sdm_cat_title" style="cursor:pointer;">' . $term->name . '</span>';
403
+ $out .= '<p class="sdm_placeholder" style="margin-bottom:0;"></p>' . custom_taxonomy_walker( $taxonomy, $term->term_id );
404
+ $out .= '</li>';
405
+ }
406
+ $out .= '</ul>';
407
+ return $out;
408
+ }
409
+ return;
410
  }
 
 
411
 
412
+ return '<div class="sdm_object_tree">' . custom_taxonomy_walker( 'sdm_categories' ) . '</div>';
413
  }
414
 
415
  /**
420
  */
421
  function sdm_download_categories_list_walker( $atts, $parent = 0 ) {
422
 
423
+ $count = (bool) $atts['count'];
424
+ $hierarchical = (bool) $atts['hierarchical'];
425
+ $show_empty = (bool) $atts['empty'];
426
+ $list_tag = $atts['numbered'] ? 'ol' : 'ul';
427
+
428
+ // Get terms (check if has parent)
429
+ $terms = get_terms(
430
+ array(
431
+ 'taxonomy' => 'sdm_categories',
432
+ 'parent' => $parent,
433
+ 'hide_empty' => ! $show_empty,
434
+ )
435
+ );
436
+
437
+ // Return empty string, if no terms found.
438
+ if ( empty( $terms ) ) {
439
+ return '';
440
+ }
441
+
442
+ // Produce list of download categories under $parent.
443
+ $out = '<' . $list_tag . '>';
444
+
445
+ foreach ( $terms as $term ) {
446
+ $out .= '<li>'
447
+ . '<a href="' . get_term_link( $term ) . '">' . $term->name . '</a>' // link
448
+ . ( $count ? ( ' <span>(' . $term->count . ')</span>' ) : '' ) // count
449
+ . ( $hierarchical ? sdm_download_categories_list_walker( $atts, $term->term_id ) : '' ) // subcategories
450
+ . '</li>';
451
+ }
452
+
453
+ $out .= '</' . $list_tag . '>';
454
+
455
+ return $out;
456
  }
457
 
458
  /**
462
  */
463
  function sdm_download_categories_list_shortcode( $attributes ) {
464
 
465
+ $atts = shortcode_atts(
466
+ array(
467
+ 'class' => 'sdm-download-categories', // wrapper class
468
+ 'empty' => '0', // show empty categories
469
+ 'numbered' => '0', // use <ol> instead of <ul> to wrap the list
470
+ 'count' => '0', // display count of items in every category
471
+ 'hierarchical' => '1', // display subcategories as well
472
+ ),
473
+ $attributes
474
+ );
475
+
476
+ return '<div class="' . esc_attr( $atts['class'] ) . '">'
477
+ . sdm_download_categories_list_walker( $atts )
478
+ . '</div>';
 
479
  }
480
 
481
  function sdm_show_download_info_shortcode( $args ) {
482
+ extract(
483
+ shortcode_atts(
484
+ array(
485
+ 'id' => '',
486
+ 'download_info' => '',
487
+ ),
488
+ $args
489
+ )
490
+ );
491
+
492
+ if ( empty( $id ) || empty( $download_info ) ) {
493
+ return '<div class="sdm_shortcode_error">Error! you must enter a value for "id" and "download_info" parameters.</div>';
494
+ }
495
 
496
+ //Available values: title, description, download_url, thumbnail, file_size, file_version, download_count
 
 
497
 
498
+ $id = absint( $id );
499
+ $get_cpt_object = get_post( $id );
500
 
501
+ if ( $download_info == 'title' ) {//download title
502
+ $item_title = get_the_title( $id );
503
+ return $item_title;
504
+ }
505
 
506
+ if ( $download_info == 'description' ) {//download description
507
+ $item_description = sdm_get_item_description_output( $id );
508
+ return $item_description;
509
+ }
510
+
511
+ if ( $download_info == 'download_url' ) {//download URL
512
+ $download_link = get_post_meta( $id, 'sdm_upload', true );
513
+ return $download_link;
514
+ }
515
+
516
+ if ( $download_info == 'thumbnail' ) {//download thumb
517
+ $download_thumbnail = get_post_meta( $id, 'sdm_upload_thumbnail', true );
518
+ $download_thumbnail = '<img class="sdm_download_thumbnail_image" src="' . $download_thumbnail . '" />';
519
+ return $download_thumbnail;
520
+ }
521
+
522
+ if ( $download_info == 'thumbnail_url' ) {//download thumbnail raw URL
523
+ $download_thumbnail = get_post_meta( $id, 'sdm_upload_thumbnail', true );
524
+ return $download_thumbnail;
525
+ }
526
+
527
+ if ( $download_info == 'file_size' ) {//download file size
528
+ $file_size = get_post_meta( $id, 'sdm_item_file_size', true );
529
+ return $file_size;
530
+ }
531
+
532
+ if ( $download_info == 'file_version' ) {//download file version
533
+ $file_version = get_post_meta( $id, 'sdm_item_version', true );
534
+ return $file_version;
535
+ }
536
+
537
+ if ( $download_info == 'download_count' ) {//download count
538
+ $dl_count = sdm_get_download_count_for_post( $id );
539
+ return $dl_count;
540
+ }
541
+
542
+ return '<div class="sdm_shortcode_error">Error! The value of "download_info" field does not match any availalbe parameters.</div>';
 
 
 
 
 
543
  }
544
 
545
  function sdm_handle_show_all_dl_shortcode( $args ) {
546
+ if ( isset( $args['category_id'] ) ) {
547
+ unset( $args['category_id'] );
548
+ }
549
+ if ( isset( $args['category_slug'] ) ) {
550
+ unset( $args['category_slug'] );
551
+ }
552
+ $args['show_all'] = 1;
553
+ return sdm_handle_category_shortcode( $args );
554
  }