BackUpWordPress - Version 1.5

Version Description

Download this release

Release Info

Developer willmot
Plugin Icon 128x128 BackUpWordPress
Version 1.5
Comparing to
See all releases

Code changes from version 1.4.1 to 1.5

admin.actions.php CHANGED
@@ -1,22 +1,22 @@
1
  <?php
2
 
3
  /**
4
- * hmbkp_option_save function
5
  *
6
- * Verify & save all the options set on
7
- * the backupwordpress advanced options page.
8
- *
9
- * Returns array of errors encountered when updating options.
10
- * If no errors - returns false.
11
  *
12
  * Uses $_POST data
 
 
 
13
  */
14
  function hmbkp_option_save() {
15
 
16
- if ( empty( $_POST['hmbkp_options_submit'] ) )
17
  return;
18
 
19
- check_admin_referer( 'hmbkp_options', 'hmbkp_options_nonce' );
20
 
21
  global $hmbkp_errors;
22
  $hmbkp_errors = new WP_Error;
@@ -81,17 +81,15 @@ function hmbkp_option_save() {
81
  delete_option( 'hmbkp_email_address' );
82
  }
83
 
84
- if ( isset( $_POST['hmbkp_excludes'] ) && !empty( $_POST['hmbkp_excludes'] ) ) {
85
-
86
  update_option( 'hmbkp_excludes', $_POST['hmbkp_excludes'] );
87
- delete_transient( 'hmbkp_estimated_filesize');
88
 
89
  } else {
90
-
91
  delete_option( 'hmbkp_excludes' );
92
- delete_transient( 'hmbkp_estimated_filesize' );
93
 
94
  }
 
 
95
 
96
  if ( $hmbkp_errors->get_error_code() )
97
  return $hmbkp_errors;
@@ -99,7 +97,7 @@ function hmbkp_option_save() {
99
  return true;
100
 
101
  }
102
- add_action( 'admin_init', 'hmbkp_option_save', 11 );
103
 
104
  /**
105
  * Delete the backup and then redirect
@@ -107,7 +105,7 @@ add_action( 'admin_init', 'hmbkp_option_save', 11 );
107
  */
108
  function hmbkp_request_delete_backup() {
109
 
110
- if ( !isset( $_GET['hmbkp_delete'] ) || empty( $_GET['hmbkp_delete'] ) )
111
  return false;
112
 
113
  hmbkp_delete_backup( $_GET['hmbkp_delete'] );
@@ -125,7 +123,7 @@ add_action( 'load-tools_page_' . HMBKP_PLUGIN_SLUG, 'hmbkp_request_delete_backup
125
  function hmbkp_request_do_backup() {
126
 
127
  // Are we sure
128
- if ( !isset( $_GET['action'] ) || $_GET['action'] !== 'hmbkp_backup_now' || hmbkp_is_in_progress() || !hmbkp_possible() )
129
  return false;
130
 
131
  // If cron is disabled for manual backups
@@ -136,14 +134,14 @@ function hmbkp_request_do_backup() {
136
  // If not fire the cron
137
  } else {
138
 
139
- // Schedule a single backup
140
  wp_schedule_single_event( time(), 'hmbkp_schedule_single_backup_hook' );
141
 
142
- // Remove the once every 60 seconds limitation
143
- delete_transient( 'doing_cron' );
144
-
145
- // Fire the cron now
146
- spawn_cron();
147
 
148
  }
149
 
@@ -157,10 +155,12 @@ add_action( 'load-tools_page_' . HMBKP_PLUGIN_SLUG, 'hmbkp_request_do_backup' );
157
  /**
158
  * Send the download file to the browser and
159
  * then redirect back to the backups page
 
 
160
  */
161
  function hmbkp_request_download_backup() {
162
 
163
- if ( !isset( $_GET['hmbkp_download'] ) || empty( $_GET['hmbkp_download'] ) )
164
  return false;
165
 
166
  hmbkp_send_file( base64_decode( $_GET['hmbkp_download'] ) );
@@ -175,7 +175,7 @@ add_action( 'load-tools_page_' . HMBKP_PLUGIN_SLUG, 'hmbkp_request_download_back
175
  */
176
  function hmbkp_ajax_is_backup_in_progress() {
177
 
178
- if ( !hmbkp_is_in_progress() )
179
  echo 0;
180
 
181
  elseif ( $status = hmbkp_get_status() )
@@ -208,7 +208,7 @@ function hmbkp_ajax_cron_test() {
208
 
209
  $response = wp_remote_get( site_url( 'wp-cron.php' ) );
210
 
211
- if ( !is_wp_error( $response ) && $response['response']['code'] != '200' )
212
  echo '<div id="hmbkp-warning" class="updated fade"><p><strong>' . __( 'BackUpWordPress has detected a problem.', 'hmbkp' ) . '</strong> ' . sprintf( __( '%s is returning a %s response which could mean cron jobs aren\'t getting fired properly. BackUpWordPress relies on wp-cron to run back ups in a separate process.', 'hmbkp' ), '<code>wp-cron.php</code>', '<code>' . $response['response']['code'] . '</code>' ) . '</p></div>';
213
  else
214
  echo 1;
@@ -222,7 +222,7 @@ add_action( 'wp_ajax_hmbkp_cron_test', 'hmbkp_ajax_cron_test' );
222
  * that users can define to control advanced
223
  * settings
224
  *
225
- * @return void
226
  */
227
  function hmbkp_constant_changes() {
228
 
@@ -231,7 +231,7 @@ function hmbkp_constant_changes() {
231
  wp_clear_scheduled_hook( 'hmbkp_schedule_backup_hook' );
232
 
233
  // Or whether we need to re-enable it
234
- if ( !hmbkp_get_disable_automatic_backup() && !wp_next_scheduled( 'hmbkp_schedule_backup_hook' ) )
235
  hmbkp_setup_schedule();
236
 
237
  // Allow the time of the daily backup to be changed
@@ -239,7 +239,7 @@ function hmbkp_constant_changes() {
239
  hmbkp_setup_schedule();
240
 
241
  // Reset if custom time is removed
242
- if ( ( ( defined( 'HMBKP_DAILY_SCHEDULE_TIME' ) && !HMBKP_DAILY_SCHEDULE_TIME ) || !defined( 'HMBKP_DAILY_SCHEDULE_TIME' ) ) && get_option( 'hmbkp_schedule_frequency' ) == 'daily' && date( 'H:i', wp_next_scheduled( 'hmbkp_schedule_backup_hook' ) ) != '23:00' && !hmbkp_get_disable_automatic_backup() )
243
  hmbkp_setup_schedule();
244
 
245
  // If a custom backup path has been set or changed
@@ -247,7 +247,7 @@ function hmbkp_constant_changes() {
247
  hmbkp_path_move( $from, HMBKP_PATH );
248
 
249
  // If a custom backup path has been removed
250
- if ( ( ( defined( 'HMBKP_PATH' ) && !HMBKP_PATH ) || !defined( 'HMBKP_PATH' ) && hmbkp_conform_dir( hmbkp_path_default() ) != ( $from = hmbkp_conform_dir( get_option( 'hmbkp_path' ) ) ) ) )
251
  hmbkp_path_move( $from, hmbkp_path_default() );
252
 
253
  // If the custom path has changed and the new directory isn't writable
1
  <?php
2
 
3
  /**
4
+ * Verify & save all the user settings
5
  *
6
+ * Returns WP_Error object if there are errors when updating settings.
7
+ * Return (bool) true if no errors.
 
 
 
8
  *
9
  * Uses $_POST data
10
+ *
11
+ * @todo Should redirect on success
12
+ * @return mixed
13
  */
14
  function hmbkp_option_save() {
15
 
16
+ if ( empty( $_POST['hmbkp_settings_submit'] ) )
17
  return;
18
 
19
+ check_admin_referer( 'hmbkp_settings', 'hmbkp_settings_nonce' );
20
 
21
  global $hmbkp_errors;
22
  $hmbkp_errors = new WP_Error;
81
  delete_option( 'hmbkp_email_address' );
82
  }
83
 
84
+ if ( isset( $_POST['hmbkp_excludes'] ) && ! empty( $_POST['hmbkp_excludes'] ) ) {
 
85
  update_option( 'hmbkp_excludes', $_POST['hmbkp_excludes'] );
 
86
 
87
  } else {
 
88
  delete_option( 'hmbkp_excludes' );
 
89
 
90
  }
91
+
92
+ delete_transient( 'hmbkp_estimated_filesize' );
93
 
94
  if ( $hmbkp_errors->get_error_code() )
95
  return $hmbkp_errors;
97
  return true;
98
 
99
  }
100
+ add_action( 'load-tools_page_' . HMBKP_PLUGIN_SLUG, 'hmbkp_option_save' );
101
 
102
  /**
103
  * Delete the backup and then redirect
105
  */
106
  function hmbkp_request_delete_backup() {
107
 
108
+ if ( ! isset( $_GET['hmbkp_delete'] ) || empty( $_GET['hmbkp_delete'] ) )
109
  return false;
110
 
111
  hmbkp_delete_backup( $_GET['hmbkp_delete'] );
123
  function hmbkp_request_do_backup() {
124
 
125
  // Are we sure
126
+ if ( ! isset( $_GET['action'] ) || $_GET['action'] !== 'hmbkp_backup_now' || hmbkp_is_in_progress() || ! hmbkp_possible() )
127
  return false;
128
 
129
  // If cron is disabled for manual backups
134
  // If not fire the cron
135
  } else {
136
 
137
+ // Schedule a single backup
138
  wp_schedule_single_event( time(), 'hmbkp_schedule_single_backup_hook' );
139
 
140
+ // Remove the once every 60 seconds limitation
141
+ delete_transient( 'doing_cron' );
142
+
143
+ // Fire the cron now
144
+ spawn_cron();
145
 
146
  }
147
 
155
  /**
156
  * Send the download file to the browser and
157
  * then redirect back to the backups page
158
+ *
159
+ * @todo We need to find a way to do this without streaming the file through PHP
160
  */
161
  function hmbkp_request_download_backup() {
162
 
163
+ if ( ! isset( $_GET['hmbkp_download'] ) || empty( $_GET['hmbkp_download'] ) )
164
  return false;
165
 
166
  hmbkp_send_file( base64_decode( $_GET['hmbkp_download'] ) );
175
  */
176
  function hmbkp_ajax_is_backup_in_progress() {
177
 
178
+ if ( ! hmbkp_is_in_progress() )
179
  echo 0;
180
 
181
  elseif ( $status = hmbkp_get_status() )
208
 
209
  $response = wp_remote_get( site_url( 'wp-cron.php' ) );
210
 
211
+ if ( ! is_wp_error( $response ) && $response['response']['code'] != '200' )
212
  echo '<div id="hmbkp-warning" class="updated fade"><p><strong>' . __( 'BackUpWordPress has detected a problem.', 'hmbkp' ) . '</strong> ' . sprintf( __( '%s is returning a %s response which could mean cron jobs aren\'t getting fired properly. BackUpWordPress relies on wp-cron to run back ups in a separate process.', 'hmbkp' ), '<code>wp-cron.php</code>', '<code>' . $response['response']['code'] . '</code>' ) . '</p></div>';
213
  else
214
  echo 1;
222
  * that users can define to control advanced
223
  * settings
224
  *
225
+ * @return null
226
  */
227
  function hmbkp_constant_changes() {
228
 
231
  wp_clear_scheduled_hook( 'hmbkp_schedule_backup_hook' );
232
 
233
  // Or whether we need to re-enable it
234
+ if ( ! hmbkp_get_disable_automatic_backup() && ! wp_next_scheduled( 'hmbkp_schedule_backup_hook' ) )
235
  hmbkp_setup_schedule();
236
 
237
  // Allow the time of the daily backup to be changed
239
  hmbkp_setup_schedule();
240
 
241
  // Reset if custom time is removed
242
+ if ( ( ( defined( 'HMBKP_DAILY_SCHEDULE_TIME' ) && ! HMBKP_DAILY_SCHEDULE_TIME ) || ! defined( 'HMBKP_DAILY_SCHEDULE_TIME' ) ) && get_option( 'hmbkp_schedule_frequency' ) == 'daily' && date( 'H:i', wp_next_scheduled( 'hmbkp_schedule_backup_hook' ) ) != '23:00' && ! hmbkp_get_disable_automatic_backup() )
243
  hmbkp_setup_schedule();
244
 
245
  // If a custom backup path has been set or changed
247
  hmbkp_path_move( $from, HMBKP_PATH );
248
 
249
  // If a custom backup path has been removed
250
+ if ( ( ( defined( 'HMBKP_PATH' ) && ! HMBKP_PATH ) || !defined( 'HMBKP_PATH' ) && hmbkp_conform_dir( hmbkp_path_default() ) != ( $from = hmbkp_conform_dir( get_option( 'hmbkp_path' ) ) ) ) )
251
  hmbkp_path_move( $from, hmbkp_path_default() );
252
 
253
  // If the custom path has changed and the new directory isn't writable
admin.backups-table.php CHANGED
@@ -1,11 +1,10 @@
1
  <?php
2
 
3
  // If max backups has changed
4
- if ( !hmbkp_is_in_progress() )
5
  hmbkp_delete_old_backups();
6
 
7
- $backup_archives = hmbkp_get_backups();
8
- if ( $backup_archives && count( $backup_archives ) ) : ?>
9
 
10
  <table class="widefat" id="hmbkp_manage_backups_table">
11
  <thead>
@@ -28,7 +27,7 @@ if ( $backup_archives && count( $backup_archives ) ) : ?>
28
 
29
  <?php foreach ( (array) $backup_archives as $file ) :
30
 
31
- if ( !file_exists( $file ) )
32
  continue;
33
 
34
  hmbkp_get_backup_row( $file );
1
  <?php
2
 
3
  // If max backups has changed
4
+ if ( ! hmbkp_is_in_progress() )
5
  hmbkp_delete_old_backups();
6
 
7
+ if ( ( $backup_archives = hmbkp_get_backups() ) && count( $backup_archives ) ) : ?>
 
8
 
9
  <table class="widefat" id="hmbkp_manage_backups_table">
10
  <thead>
27
 
28
  <?php foreach ( (array) $backup_archives as $file ) :
29
 
30
+ if ( ! file_exists( $file ) )
31
  continue;
32
 
33
  hmbkp_get_backup_row( $file );
admin.advanced-options.php → admin.constants.php RENAMED
@@ -1,8 +1,6 @@
1
- <div id="hmbkp_advanced-options">
2
 
3
- <h4><?php _e( 'Advanced Options', 'hmbkp' ); ?></h4>
4
-
5
- <p><?php printf( __( 'You can %s any of the following %s in your %s to control advanced options. %s. Defined %s will be highlighted.', 'hmbkp' ), '<code>define</code>', '<code>Constants</code>', '<code>wp-config.php</code>', '<a href="http://codex.wordpress.org/Editing_wp-config.php">' . __( 'The Codex can help', 'hmbkp' ) . '</a>', '<code>Constants</code>' ); ?></p>
6
 
7
  <dl>
8
 
@@ -33,11 +31,14 @@
33
  <dt<?php if ( defined( 'HMBKP_EMAIL' ) ) { ?> class="hmbkp_active"<?php } ?>><code>HMBKP_EMAIL</code></dt>
34
  <dd><p><?php printf( __( 'Attempt to email a copy of your backups. Value should be email address to send backups to. Defaults to %s.', 'hmbkp' ), '<code>(bool) false</code>' ); ?><p class="example">e.g. <code>define( 'HMBKP_EMAIL', 'email@example.com' );</code></p></dd>
35
 
36
- <dt<?php if ( hmbkp_get_excludes() ) { ?> class="hmbkp_active"<?php } ?>><code>HMBKP_EXCLUDE</code></dt>
37
  <dd><p><?php _e( 'Comma separated list of files or directories to exclude, the backups directory is automatically excluded.', 'hmbkp' ); ?><p class="example">e.g. <code>define( 'HMBKP_EXCLUDE', '/wp-content/uploads/, /stats/, .svn/, *.txt' );</code></p></dd>
38
 
39
  <dt<?php if ( defined( 'HMBKP_DISABLE_MANUAL_BACKUP_CRON' ) ) { ?> class="hmbkp_active"<?php } ?>><code>HMBKP_DISABLE_MANUAL_BACKUP_CRON</code></dt>
40
  <dd><p><?php _e( 'Disable the use of wp-cron for manual backups.', 'hmbkp' ); ?><p class="example">e.g. <code>define( 'HMBKP_DISABLE_MANUAL_BACKUP_CRON', true );</code></p></dd>
 
 
 
41
 
42
  </dl>
43
 
1
+ <div id="hmbkp-constants">
2
 
3
+ <p><?php printf( __( 'You can %s any of the following %s in your %s to control advanced settings. %s. Defined %s will be highlighted.', 'hmbkp' ), '<code>define</code>', '<code>Constants</code>', '<code>wp-config.php</code>', '<a href="http://codex.wordpress.org/Editing_wp-config.php">' . __( 'The Codex can help', 'hmbkp' ) . '</a>', '<code>Constants</code>' ); ?></p>
 
 
4
 
5
  <dl>
6
 
31
  <dt<?php if ( defined( 'HMBKP_EMAIL' ) ) { ?> class="hmbkp_active"<?php } ?>><code>HMBKP_EMAIL</code></dt>
32
  <dd><p><?php printf( __( 'Attempt to email a copy of your backups. Value should be email address to send backups to. Defaults to %s.', 'hmbkp' ), '<code>(bool) false</code>' ); ?><p class="example">e.g. <code>define( 'HMBKP_EMAIL', 'email@example.com' );</code></p></dd>
33
 
34
+ <dt<?php if ( defined( 'HMBKP_EXCLUDE' ) ) { ?> class="hmbkp_active"<?php } ?>><code>HMBKP_EXCLUDE</code></dt>
35
  <dd><p><?php _e( 'Comma separated list of files or directories to exclude, the backups directory is automatically excluded.', 'hmbkp' ); ?><p class="example">e.g. <code>define( 'HMBKP_EXCLUDE', '/wp-content/uploads/, /stats/, .svn/, *.txt' );</code></p></dd>
36
 
37
  <dt<?php if ( defined( 'HMBKP_DISABLE_MANUAL_BACKUP_CRON' ) ) { ?> class="hmbkp_active"<?php } ?>><code>HMBKP_DISABLE_MANUAL_BACKUP_CRON</code></dt>
38
  <dd><p><?php _e( 'Disable the use of wp-cron for manual backups.', 'hmbkp' ); ?><p class="example">e.g. <code>define( 'HMBKP_DISABLE_MANUAL_BACKUP_CRON', true );</code></p></dd>
39
+
40
+ <dt<?php if ( defined( 'HMBKP_CAPABILITY' ) ) { ?> class="hmbkp_active"<?php } ?>><code>HMBKP_CAPABILITY</code></dt>
41
+ <dd><p><?php printf( __( 'The capability to use when calling %s. Defaults to %s.', 'hmbkp' ), '<code>add_menu_page</code>', '<code>manage_options</code>' ); ?><p class="example">e.g. <code>define( 'HMBKP_CAPABILITY', 'edit_posts' );</code></p></dd>
42
 
43
  </dl>
44
 
admin.menus.php CHANGED
@@ -3,15 +3,19 @@
3
  /**
4
  * Add the backups menu item
5
  * to the tools menu
 
 
6
  */
7
  function hmbkp_admin_menu() {
8
- add_management_page( __( 'Manage Backups','hmbkp' ), __( 'Backups','hmbkp' ), 'manage_options', HMBKP_PLUGIN_SLUG, 'hmbkp_manage_backups' );
9
  }
10
  add_action( 'admin_menu', 'hmbkp_admin_menu' );
11
 
12
  /**
13
  * Load the backups admin page
14
  * when the menu option is clicked
 
 
15
  */
16
  function hmbkp_manage_backups() {
17
  require_once( HMBKP_PLUGIN_PATH . '/admin.page.php' );
@@ -20,43 +24,55 @@ function hmbkp_manage_backups() {
20
  /**
21
  * Add a link to the backups page to the plugin action links.
22
  *
23
- * @param Array $links
24
  * @param string $file
25
- * @return Array $links
26
  */
27
  function hmbkp_plugin_action_link( $links, $file ) {
28
-
29
  if ( strpos( $file, HMBKP_PLUGIN_SLUG ) !== false )
30
  array_push( $links, '<a href="tools.php?page=' . HMBKP_PLUGIN_SLUG . '">' . __( 'Backups', 'hmbkp' ) . '</a>' );
31
-
32
  return $links;
33
 
34
  }
35
  add_filter('plugin_action_links', 'hmbkp_plugin_action_link', 10, 2 );
 
36
  /**
37
  * Add Contextual Help to Backups tools page.
38
  *
39
  * Help is pulled from the readme FAQ.
40
- * NOTE: FAQ used is from the wordpress repo, and might not be up to date for development versions.
41
  *
 
42
  */
43
- function hmbkp_contextual_help( $contextual_help, $screen_id, $screen ) {
44
 
45
- if ( isset( $_GET['page'] ) && $_GET['page'] == HMBKP_PLUGIN_SLUG ) :
 
46
 
47
- require_once( ABSPATH . 'wp-admin/includes/plugin-install.php' );
48
- $plugin = plugins_api( 'plugin_information', array( 'slug' => 'backupwordpress' ) );
 
49
 
50
- // Check if help is for the right version.
51
- if ( ! empty( $plugin->version ) && version_compare( HMBKP_VERSION, $plugin->version, '!=' ) )
52
- $contextual_help = sprintf( '<p><strong>' . __( 'You are not using the latest stable version of BackUpWordPress', 'hmbkp' ) . '</strong>' . __( ' &mdash; The information below is for version %s. View the readme.txt file for help specific to version %s.', 'hmbkp' ) . '</p>', '<code>' . $plugin->version . '</code>', '<code>' . HMBKP_VERSION . '</code>' );
53
 
54
- if( ! empty( $plugin->sections['faq'] ) )
55
- $contextual_help .= $plugin->sections['faq'];
 
 
 
 
 
56
 
57
- endif;
 
58
 
59
- return $contextual_help;
 
 
 
 
60
 
61
  }
62
- add_filter( 'contextual_help', 'hmbkp_contextual_help', 10, 3 );
3
  /**
4
  * Add the backups menu item
5
  * to the tools menu
6
+ *
7
+ * @return null
8
  */
9
  function hmbkp_admin_menu() {
10
+ add_management_page( __( 'Manage Backups','hmbkp' ), __( 'Backups','hmbkp' ), ( defined( 'HMBKP_CAPABILITY' ) && HMBKP_CAPABILITY ) ? HMBKP_CAPABILITY : 'manage_options', HMBKP_PLUGIN_SLUG, 'hmbkp_manage_backups' );
11
  }
12
  add_action( 'admin_menu', 'hmbkp_admin_menu' );
13
 
14
  /**
15
  * Load the backups admin page
16
  * when the menu option is clicked
17
+ *
18
+ * @return null
19
  */
20
  function hmbkp_manage_backups() {
21
  require_once( HMBKP_PLUGIN_PATH . '/admin.page.php' );
24
  /**
25
  * Add a link to the backups page to the plugin action links.
26
  *
27
+ * @param array $links
28
  * @param string $file
29
+ * @return array $links
30
  */
31
  function hmbkp_plugin_action_link( $links, $file ) {
32
+
33
  if ( strpos( $file, HMBKP_PLUGIN_SLUG ) !== false )
34
  array_push( $links, '<a href="tools.php?page=' . HMBKP_PLUGIN_SLUG . '">' . __( 'Backups', 'hmbkp' ) . '</a>' );
35
+
36
  return $links;
37
 
38
  }
39
  add_filter('plugin_action_links', 'hmbkp_plugin_action_link', 10, 2 );
40
+
41
  /**
42
  * Add Contextual Help to Backups tools page.
43
  *
44
  * Help is pulled from the readme FAQ.
 
45
  *
46
+ * @return null
47
  */
48
+ function hmbkp_contextual_help() {
49
 
50
+ require_once( ABSPATH . 'wp-admin/includes/plugin-install.php' );
51
+ $plugin = plugins_api( 'plugin_information', array( 'slug' => 'backupwordpress' ) );
52
 
53
+ // Check if help is for the right version.
54
+ if ( ! empty( $plugin->version ) && version_compare( HMBKP_VERSION, $plugin->version, '!=' ) )
55
+ $contextual_help = sprintf( '<div id="message" class="updated inline"><p><strong>' . __( 'You are not using the latest stable version of BackUpWordPress', 'hmbkp' ) . '</strong>' . __( ' &mdash; The information below is for version %s. View the readme.txt file for help specific to version %s.', 'hmbkp' ) . '</p></div>', '<code>' . $plugin->version . '</code>', '<code>' . HMBKP_VERSION . '</code>' );
56
 
57
+ if ( ! empty( $plugin->sections['faq'] ) )
58
+ $contextual_help .= $plugin->sections['faq'];
 
59
 
60
+ ob_start();
61
+ require_once( HMBKP_PLUGIN_PATH . '/admin.constants.php' );
62
+ $constants = ob_get_clean();
63
+
64
+ // Pre WordPress 3.3 compat
65
+ if ( ! method_exists( get_current_screen(), 'add_help_tab' ) )
66
+ return;
67
 
68
+ get_current_screen()->add_help_tab( array( 'title' => 'FAQ', 'id' => 'hmbkp_faq', 'content' => $contextual_help ) );
69
+ get_current_screen()->add_help_tab( array( 'title' => 'Constants', 'id' => 'hmbkp_constants', 'content' => $constants ) );
70
 
71
+ get_current_screen()->set_help_sidebar(
72
+ '<p><strong>' . __( 'For more information:' ) . '</strong></p>' .
73
+ '<p>' . __( '<a href="http://https://github.com/humanmade/backupwordpress" target="_blank">github</a>' ) . '</p>' .
74
+ '<p>' . __( '<a href="http://wordpress.org/tags/backupwordpress?forum_id=10" target="_blank">Support Forums</a>' ) . '</p>'
75
+ );
76
 
77
  }
78
+ add_filter( 'load-tools_page_' . HMBKP_PLUGIN_SLUG, 'hmbkp_contextual_help' );
admin.page.php CHANGED
@@ -14,7 +14,7 @@
14
 
15
  <?php endif; ?>
16
 
17
- <a href="#hmbkp_advanced-options" class="add-new-h2 hmbkp_advanced-options-toggle"><?php _e( 'Advanced Options', 'hmbkp' ); ?></a>
18
 
19
  </h2>
20
 
14
 
15
  <?php endif; ?>
16
 
17
+ <a href="#hmbkp-settings" class="add-new-h2 hmbkp-settings-toggle"><?php _e( 'Settings', 'hmbkp' ); ?></a>
18
 
19
  </h2>
20
 
admin.settings.php CHANGED
@@ -1,12 +1,12 @@
1
- <div id="hmbkp_advanced-options" <?php if ( !hmbkp_get_backups() || !empty( $_POST['hmbkp_options_submit'] ) ) echo ' class="show_form"' ?>>
2
 
3
- <h4><?php _e( 'Advanced Options', 'hmbkp' ); ?></h4>
4
 
5
- <p><?php printf( __( 'You can still define %s in your %s to control some settings. A full list of %s can be found in the readme. Defined settings will not be editable below.', 'hmbkp' ), '<code>Constants</code>', '<code>wp-config.php</code>', '<code>Constants</code>' ); ?></p>
6
 
7
  <form method="post">
8
 
9
- <?php wp_nonce_field( 'hmbkp_options', 'hmbkp_options_nonce' ); ?>
10
 
11
  <table class="form-table">
12
  <tbody>
@@ -18,7 +18,7 @@
18
  <td>
19
 
20
  <label for="hmbkp_automatic_on">
21
- <input name="hmbkp_automatic" type="radio" id="hmbkp_automatic_on" value="1" <?php checked( !hmbkp_get_disable_automatic_backup() ); ?> <?php disabled( defined( 'HMBKP_DISABLE_AUTOMATIC_BACKUP' ) ); ?>>
22
  <?php _e( 'Backup my site automatically.', 'hmbkp' ); ?>
23
  </label><br/>
24
 
@@ -91,7 +91,7 @@
91
 
92
  </table>
93
 
94
- <p class="submit"><input type="submit" name="hmbkp_options_submit" id="submit" class="button-primary" value="Save Changes"></p>
95
 
96
  </form>
97
 
1
+ <div id="hmbkp-settings" <?php if ( ! hmbkp_get_backups() || ! empty( $_POST['hmbkp_settings_submit'] ) ) echo ' class="show_form"' ?>>
2
 
3
+ <h3><?php _e( 'Settings', 'hmbkp' ); ?></h3>
4
 
5
+ <p><?php printf( __( 'You can define %s in your %s to control some settings. A full list of %s can be found in the <a href="#contextual-help-wrap" class="hmbkp-show-help-tab">help</a> panel. Defined settings will not be editable below.', 'hmbkp' ), '<code>Constants</code>', '<code>wp-config.php</code>', '<code>Constants</code>' ); ?></p>
6
 
7
  <form method="post">
8
 
9
+ <?php wp_nonce_field( 'hmbkp_settings', 'hmbkp_settings_nonce' ); ?>
10
 
11
  <table class="form-table">
12
  <tbody>
18
  <td>
19
 
20
  <label for="hmbkp_automatic_on">
21
+ <input name="hmbkp_automatic" type="radio" id="hmbkp_automatic_on" value="1" <?php checked( ! hmbkp_get_disable_automatic_backup() ); ?> <?php disabled( defined( 'HMBKP_DISABLE_AUTOMATIC_BACKUP' ) ); ?>>
22
  <?php _e( 'Backup my site automatically.', 'hmbkp' ); ?>
23
  </label><br/>
24
 
91
 
92
  </table>
93
 
94
+ <p class="submit"><input type="submit" name="hmbkp_settings_submit" id="submit" class="button-primary" value="Save Changes"></p>
95
 
96
  </form>
97
 
admin.status.php CHANGED
@@ -1,7 +1,6 @@
1
  <?php // If the form has been submitted, things may have changed.
2
- if ( ( !empty( $_POST['hmbkp_options_submit'] ) ) && ( !wp_next_scheduled('hmbkp_schedule_backup_hook') || hmbkp_get_disable_automatic_backup() ) ) {
3
- hmbkp_constant_changes();
4
- } ?>
5
 
6
  <p>&#10003;
7
 
@@ -11,7 +10,7 @@ if ( ( !empty( $_POST['hmbkp_options_submit'] ) ) && ( !wp_next_scheduled('hmbkp
11
 
12
  <?php else :
13
 
14
- if ( !hmbkp_get_database_only() && !hmbkp_get_files_only() )
15
  $what_to_backup = '<code>' . __( 'database', 'hmbkp' ) . '</code> ' . __( '&amp;', 'hmbkp' ) . ' <code>' . __( 'files', 'hmbkp' ) . '</code>';
16
 
17
  elseif( hmbkp_get_database_only() )
@@ -22,7 +21,7 @@ if ( ( !empty( $_POST['hmbkp_options_submit'] ) ) && ( !wp_next_scheduled('hmbkp
22
 
23
  <?php $offset = current_time( 'timestamp' ) - time();
24
  $schedules = wp_get_schedules();
25
- $schedule = $schedules[ wp_get_schedule('hmbkp_schedule_backup_hook') ]['display'];
26
  printf( __( 'Your %s will be automatically backed up <code>%s</code>. The next backup will occur at %s on %s and be saved to %s.', 'hmbkp' ), $what_to_backup , $schedule, '<code>' . date_i18n( get_option( 'time_format' ), wp_next_scheduled( 'hmbkp_schedule_backup_hook' ) + $offset ) . '</code>', '<code title="' . sprintf( __( 'It\'s currently %s', 'hmbkp' ), date_i18n( get_option( 'time_format' ) ) ) . '">' . date_i18n( get_option( 'date_format' ), wp_next_scheduled( 'hmbkp_schedule_backup_hook' ) + $offset ) . '</code>', '<code>' . hmbkp_path() . '</code>' ); ?>
27
 
28
  <?php endif; ?>
@@ -31,28 +30,10 @@ if ( ( !empty( $_POST['hmbkp_options_submit'] ) ) && ( !wp_next_scheduled('hmbkp
31
 
32
  <p>&#10003; <span class="hmbkp_estimated-size"><?php printf( __( 'Your site is %s. Backups will be compressed and should be smaller than this.', 'hmbkp' ), get_transient( 'hmbkp_estimated_filesize' ) ? '<code>' . hmbkp_calculate() . '</code>' : '<code class="calculate">' . __( 'Calculating Size...', 'hmbkp' ) . '</code>' ); ?></span></p>
33
 
34
- <?php if ( !hmbkp_shell_exec_available() ) : ?>
35
- <p>&#10007; <?php printf( __( '%s is disabled which means we have to use the slower PHP fallbacks, you could try contacting your host and asking them to enable it.', 'hmbkp' ), '<code>shell_exec</code>' ); ?></p>
36
- <?php endif; ?>
37
-
38
- <?php if ( hmbkp_shell_exec_available() ) : ?>
39
-
40
- <?php if ( hmbkp_zip_path() && !hmbkp_get_database_only() ) : ?>
41
- <p>&#10003; <?php printf( __( 'Your %s will be backed up using %s.', 'hmbkp' ), '<code>' . __( 'files', 'hmbkp' ) . '</code>', '<code>' . hmbkp_zip_path() . '</code>' ); ?></p>
42
- <?php endif; ?>
43
-
44
- <?php if ( hmbkp_mysqldump_path() && !hmbkp_get_files_only() ) : ?>
45
- <p>&#10003; <?php printf( __( 'Your %s will be backed up using %s.', 'hmbkp' ), '<code>' . __( 'database', 'hmbkp' ) . '</code>', '<code>' . hmbkp_mysqldump_path() . '</code>' ); ?></p>
46
- <?php endif; ?>
47
-
48
- <?php endif; ?>
49
-
50
  <?php if ( hmbkp_get_email_address() ) : ?>
51
  <p>&#10003; <?php printf( __( 'A copy of each backup will be emailed to %s.', 'hmbkp' ), '<code>' . hmbkp_get_email_address() . '</code>' ); ?></p>
52
  <?php endif; ?>
53
 
54
- <?php hmbkp_valid_custom_excludes(); ?>
55
-
56
  <?php if ( ( $valid_excludes = hmbkp_valid_custom_excludes() ) && !hmbkp_get_database_only() ) : ?>
57
  <p>&#10003; <?php printf( __( 'The following paths will be excluded from your backups %s.', 'hmbkp' ), '<code>' . implode( '</code>, <code>', $valid_excludes ) . '</code>' ); ?></p>
58
  <?php endif; ?>
1
  <?php // If the form has been submitted, things may have changed.
2
+ if ( ( !empty( $_POST['hmbkp_settings_submit'] ) ) && ( ! wp_next_scheduled( 'hmbkp_schedule_backup_hook') || hmbkp_get_disable_automatic_backup() ) )
3
+ hmbkp_constant_changes(); ?>
 
4
 
5
  <p>&#10003;
6
 
10
 
11
  <?php else :
12
 
13
+ if ( ! hmbkp_get_database_only() && ! hmbkp_get_files_only() )
14
  $what_to_backup = '<code>' . __( 'database', 'hmbkp' ) . '</code> ' . __( '&amp;', 'hmbkp' ) . ' <code>' . __( 'files', 'hmbkp' ) . '</code>';
15
 
16
  elseif( hmbkp_get_database_only() )
21
 
22
  <?php $offset = current_time( 'timestamp' ) - time();
23
  $schedules = wp_get_schedules();
24
+ $schedule = $schedules[wp_get_schedule( 'hmbkp_schedule_backup_hook' )]['display'];
25
  printf( __( 'Your %s will be automatically backed up <code>%s</code>. The next backup will occur at %s on %s and be saved to %s.', 'hmbkp' ), $what_to_backup , $schedule, '<code>' . date_i18n( get_option( 'time_format' ), wp_next_scheduled( 'hmbkp_schedule_backup_hook' ) + $offset ) . '</code>', '<code title="' . sprintf( __( 'It\'s currently %s', 'hmbkp' ), date_i18n( get_option( 'time_format' ) ) ) . '">' . date_i18n( get_option( 'date_format' ), wp_next_scheduled( 'hmbkp_schedule_backup_hook' ) + $offset ) . '</code>', '<code>' . hmbkp_path() . '</code>' ); ?>
26
 
27
  <?php endif; ?>
30
 
31
  <p>&#10003; <span class="hmbkp_estimated-size"><?php printf( __( 'Your site is %s. Backups will be compressed and should be smaller than this.', 'hmbkp' ), get_transient( 'hmbkp_estimated_filesize' ) ? '<code>' . hmbkp_calculate() . '</code>' : '<code class="calculate">' . __( 'Calculating Size...', 'hmbkp' ) . '</code>' ); ?></span></p>
32
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
33
  <?php if ( hmbkp_get_email_address() ) : ?>
34
  <p>&#10003; <?php printf( __( 'A copy of each backup will be emailed to %s.', 'hmbkp' ), '<code>' . hmbkp_get_email_address() . '</code>' ); ?></p>
35
  <?php endif; ?>
36
 
 
 
37
  <?php if ( ( $valid_excludes = hmbkp_valid_custom_excludes() ) && !hmbkp_get_database_only() ) : ?>
38
  <p>&#10003; <?php printf( __( 'The following paths will be excluded from your backups %s.', 'hmbkp' ), '<code>' . implode( '</code>, <code>', $valid_excludes ) . '</code>' ); ?></p>
39
  <?php endif; ?>
assets/hmbkp.css CHANGED
@@ -2,20 +2,21 @@
2
  .hmbkp_running .add-new-h2 img { margin: 0 3px -4px -6px; opacity: 0.3; }
3
  .add-new-h2[disabled="disabled"], add-new-h2[disabled="disabled"]:hover, .add-new-h2[disabled="disabled"]:active, .add-new-h2[disabled="disabled"]:focus { cursor: default; color: #666; }
4
  tfoot p { margin: 0; font-weight: normal; }
5
- #hmbkp_advanced-options { display: none; }
6
- #hmbkp_advanced-options.show_form { display: block; }
7
- #hmbkp_advanced-options dl { overflow: hidden; margin: 20px 0; }
8
- #hmbkp_advanced-options dt { float: left; min-width: 250px; clear: both; padding: 6px; margin: 1px 0; cursor: pointer; }
9
- #hmbkp_advanced-options dd { color: #666; padding: 7px 0 7px 250px; border-top: 1px solid #DFDFDF; margin: 0; cursor: pointer; min-height: 34px; }
10
- #hmbkp_advanced-options dd:last-child { border-bottom: 1px solid #DFDFDF; }
11
- #hmbkp_advanced-options dt:not(.hmbkp_active) + dd { background: #F9F9F9; }
12
- #hmbkp_advanced-options dd .example { white-space: nowrap; display: none; }
13
- #hmbkp_advanced-options dd p { margin: 0; }
14
- #hmbkp_advanced-options dt:not(.hmbkp_active):hover + dd, #hmbkp_advanced-options dt:not(.hmbkp_active) + dd:hover { background-color: #FFF; }
15
- #hmbkp_advanced-options dd:hover p, #hmbkp_advanced-options dt:hover + dd p { display: none; }
16
- #hmbkp_advanced-options dd:hover .example, #hmbkp_advanced-options dt:hover + dd .example { display: inline; }
17
  .hmbkp_manage_backups_row .delete { color: #BC0B0B; }
18
  .hmbkp_manage_backups_row .delete:hover { color: red; }
19
  .completed th, .completed td { background-color: #FFFFE0; }
20
  .hmbkp_active:before { content: "\00a0 \2713 "; font-size: 11px; }
21
- .hmbkp_active, .hmbkp_active code, #hmbkp_advanced-options .hmbkp_active + dd { background: #E5F7E8; }
 
2
  .hmbkp_running .add-new-h2 img { margin: 0 3px -4px -6px; opacity: 0.3; }
3
  .add-new-h2[disabled="disabled"], add-new-h2[disabled="disabled"]:hover, .add-new-h2[disabled="disabled"]:active, .add-new-h2[disabled="disabled"]:focus { cursor: default; color: #666; }
4
  tfoot p { margin: 0; font-weight: normal; }
5
+ #hmbkp-settings { display: none; }
6
+ #hmbkp-settings.show_form { display: block; }
7
+ #hmbkp-constants dl { overflow: hidden; margin: 20px 0; }
8
+ #hmbkp-constants dt { float: left; min-width: 250px; clear: both; padding: 6px; margin: 1px 0; cursor: pointer; }
9
+ #hmbkp-constants dd { color: #666; padding: 7px 0 7px 250px; border-top: 1px solid #DFDFDF; margin: 0; cursor: pointer; min-height: 40px; }
10
+ #hmbkp-constants dd:last-child { border-bottom: 1px solid #DFDFDF; }
11
+ #hmbkp-constants dt:not(.hmbkp_active) + dd { background: #F9F9F9; }
12
+ #hmbkp-constants dd .example { white-space: nowrap; display: none; }
13
+ #hmbkp-constants dd p { margin: 0; }
14
+ #hmbkp-constants dt:not(.hmbkp_active):hover + dd, #hmbkp-constants dt:not(.hmbkp_active) + dd:hover { background-color: #FFF; }
15
+ #hmbkp-constants dd:hover p, #hmbkp-constants dt:hover + dd p { display: none; }
16
+ #hmbkp-constants dd:hover .example, #hmbkp-constants dt:hover + dd .example { display: inline; }
17
  .hmbkp_manage_backups_row .delete { color: #BC0B0B; }
18
  .hmbkp_manage_backups_row .delete:hover { color: red; }
19
  .completed th, .completed td { background-color: #FFFFE0; }
20
  .hmbkp_active:before { content: "\00a0 \2713 "; font-size: 11px; }
21
+ .hmbkp_active, .hmbkp_active code, #hmbkp-constants .hmbkp_active + dd { background: #E5F7E8; }
22
+ #tab-panel-hmbkp_faq .updated { margin: 15px 0 0; }
assets/hmbkp.js CHANGED
@@ -22,12 +22,16 @@ jQuery( document ).ready( function( $ ) {
22
  }
23
  );
24
 
25
- $( '.hmbkp_advanced-options-toggle' ).click( function() {
26
- $( '#hmbkp_advanced-options' ).toggle();
27
  } );
28
 
29
- if( window.location.hash == '#hmbkp_advanced-options' ){
30
- $( '#hmbkp_advanced-options' ).css( 'display', 'block' );
 
 
 
 
31
  }
32
 
33
 
22
  }
23
  );
24
 
25
+ $( '.hmbkp-settings-toggle' ).click( function() {
26
+ $( '#hmbkp-settings' ).toggle();
27
  } );
28
 
29
+ if ( typeof( screenMeta ) != 'undefined' ) {
30
+ $( '.hmbkp-show-help-tab' ).click( screenMeta.toggleEvent );
31
+ }
32
+
33
+ if ( window.location.hash == '#hmbkp-settings' ){
34
+ $( '#hmbkp-settings' ).show();
35
  }
36
 
37
 
functions/backup.actions.php ADDED
@@ -0,0 +1,24 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ // Mark the backup as started
4
+ add_action( 'hmbkp_backup_started', 'hmbkp_set_status', 10, 0 );
5
+
6
+ /**
7
+ * Set the backup status to dumping database
8
+ *
9
+ * @return null
10
+ */
11
+ function hmbkp_set_status_dumping_database() {
12
+ hmbkp_set_status( __( 'Dumping database', 'hmbkp' ) );
13
+ }
14
+ add_action( 'hmbkp_mysqldump_started', 'hmbkp_set_status_dumping_database' );
15
+
16
+ /**
17
+ * Set the backup status to archiving
18
+ *
19
+ * @return null
20
+ */
21
+ function hmbkp_set_status_archiving() {
22
+ hmbkp_set_status( __( 'Creating zip archive', 'hmbkp' ) );
23
+ }
24
+ add_action( 'hmbkp_archive_started', 'hmbkp_set_status_archiving' );
functions/backup.files.fallback.functions.php DELETED
@@ -1,55 +0,0 @@
1
- <?php
2
-
3
- /**
4
- * Fallback for creating zip archive if zip command is
5
- * unnavailable.
6
- *
7
- * Uses the PCLZIP library that ships with WordPress
8
- *
9
- * @todo support zipArchive
10
- * @param string $path
11
- */
12
- function hmbkp_archive_files_fallback( $path ) {
13
-
14
- require_once( ABSPATH . 'wp-admin/includes/class-pclzip.php' );
15
-
16
- $archive = new PclZip( $path );
17
-
18
- // Zip up everything
19
- if ( ! hmbkp_get_database_only() )
20
- $archive->create( ABSPATH, PCLZIP_OPT_REMOVE_PATH, ABSPATH, PCLZIP_CB_PRE_ADD, 'hmbkp_pclzip_exclude' );
21
-
22
- // Only zip up the database
23
- if ( hmbkp_get_database_only() )
24
- $archive->create( hmbkp_path() . '/database_' . DB_NAME . '.sql', PCLZIP_OPT_REMOVE_PATH, hmbkp_path() );
25
-
26
- }
27
-
28
- /**
29
- * Add file callback, excludes files in the backups directory
30
- * and sets the database dump to be stored in the root
31
- * of the zip
32
- *
33
- * @param string $event
34
- * @param array &$file
35
- * @return bool
36
- */
37
- function hmbkp_pclzip_exclude( $event, &$file ) {
38
-
39
- $excludes = hmbkp_exclude_string( 'pclzip' );
40
-
41
- // Include the database file
42
- if ( strpos( $file['filename'], 'database_' . DB_NAME . '.sql' ) !== false )
43
- $file['stored_filename'] = 'database_' . DB_NAME . '.sql';
44
-
45
- // Match everything else past the exclude list
46
- elseif ( preg_match( '(' . $excludes . ')', $file['stored_filename'] ) )
47
- return false;
48
-
49
- // Don't try to add unreadable files.
50
- if ( !is_readable( $file['filename'] ) )
51
- return false;
52
-
53
- return true;
54
-
55
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
functions/backup.files.functions.php DELETED
@@ -1,243 +0,0 @@
1
- <?php
2
-
3
- /**
4
- * Zip up all the wordpress files.
5
- *
6
- * Attempts to use the shell zip command, if
7
- * thats not available then it fallsback on
8
- * PHP zip classes.
9
- *
10
- * @param string $path
11
- */
12
- function hmbkp_archive_files( $path ) {
13
-
14
- // Do we have the path to the zip command
15
- if ( hmbkp_zip_path() ) :
16
-
17
- // Zip up ABSPATH
18
- if ( !hmbkp_get_database_only() ) :
19
-
20
- $excludes = ' -x ' . hmbkp_exclude_string( 'zip' );
21
-
22
- shell_exec( 'cd ' . escapeshellarg( ABSPATH ) . ' && ' . escapeshellarg( hmbkp_zip_path() ) . ' -rq ' . escapeshellarg( $path ) . ' ./' . $excludes );
23
-
24
- endif;
25
-
26
- // Add the database dump to the archive
27
- if ( !hmbkp_get_files_only() ) :
28
- shell_exec( 'cd ' . escapeshellarg( hmbkp_path() ) . ' && ' . escapeshellarg( hmbkp_zip_path() ) . ' -uq ' . escapeshellarg( $path ) . ' ' . escapeshellarg( 'database_' . DB_NAME . '.sql' ) );
29
- endif;
30
-
31
- // If not use the fallback
32
- else :
33
- hmbkp_archive_files_fallback( $path );
34
-
35
- endif;
36
-
37
- }
38
-
39
- /**
40
- * Attempt to work out the path to the zip command
41
- *
42
- * Can be overridden by defining HMBKP_ZIP_PATH in
43
- * wp-config.php.
44
- *
45
- * @return string $path on success, empty string on failure
46
- */
47
- function hmbkp_zip_path() {
48
-
49
- if ( !hmbkp_shell_exec_available() || ( defined( 'HMBKP_ZIP_PATH' ) && !HMBKP_ZIP_PATH ) )
50
- return false;
51
-
52
- $path = '';
53
-
54
- // List of possible zip locations
55
- $zip_locations = array(
56
- 'zip',
57
- '/usr/bin/zip'
58
- );
59
-
60
- // Allow the path to be overridden
61
- if ( defined( 'HMBKP_ZIP_PATH' ) && HMBKP_ZIP_PATH )
62
- array_unshift( $zip_locations, HMBKP_ZIP_PATH );
63
-
64
- // If we don't have a path set
65
- if ( !$path = get_option( 'hmbkp_zip_path' ) ) :
66
-
67
- // Try to find out where zip is
68
- foreach ( $zip_locations as $location )
69
- if ( shell_exec( 'which ' . $location ) )
70
- $path = $location;
71
-
72
- // Save it for later
73
- if ( $path )
74
- update_option( 'hmbkp_zip_path', $path );
75
-
76
- endif;
77
-
78
- // Check again in-case the saved path has stopped working for some reason
79
- if ( $path && !shell_exec( 'which ' . $path ) ) :
80
- delete_option( 'hmbkp_zip_path' );
81
- return hmbkp_zip_path();
82
-
83
- endif;
84
-
85
- return $path;
86
-
87
- }
88
-
89
- /**
90
- * Returns an array of default exclude paths
91
- *
92
- * @access public
93
- * @return array
94
- */
95
- function hmbkp_excludes() {
96
-
97
- // Exclude the back up path
98
- $excludes[] = hmbkp_path();
99
-
100
- // Exclude the default back up path
101
- $excludes[] = hmbkp_path_default();
102
-
103
- // Exclude the custom path if one is defined
104
- if ( defined( 'HMBKP_PATH' ) && HMBKP_PATH )
105
- $excludes[] = hmbkp_conform_dir( HMBKP_PATH );
106
-
107
- return array_map( 'trailingslashit', array_unique( $excludes ) );
108
-
109
- }
110
-
111
- /**
112
- * Generate the exclude param string for the zip backup
113
- *
114
- * Takes the exclude rules and formats them for use with either
115
- * the shell zip command or pclzip
116
- *
117
- * @param string $context. (default: 'zip')
118
- * @return string
119
- */
120
- function hmbkp_exclude_string( $context = 'zip' ) {
121
-
122
- // Return a comma separated list by default
123
- $separator = ', ';
124
- $wildcard = '';
125
-
126
- // The zip command
127
- if ( $context == 'zip' ) :
128
- $wildcard = '*';
129
- $separator = ' -x ';
130
-
131
- // The PCLZIP fallback library
132
- elseif ( $context == 'pclzip' ) :
133
- $wildcard = '([.]*?)';
134
- $separator = '|';
135
-
136
- endif;
137
-
138
- // Get the excludes
139
- $excludes = hmbkp_excludes();
140
-
141
- // Add any defined excludes
142
- if ( hmbkp_get_excludes() )
143
- $excludes = array_merge( explode( ',', hmbkp_get_excludes() ), $excludes );
144
-
145
- $excludes = array_map( 'trim', $excludes );
146
-
147
- // Add wildcards to the directories
148
- foreach( $excludes as $key => &$rule ) :
149
-
150
- $file = $absolute = $fragment = false;
151
-
152
- // Files don't end with /
153
- if ( !in_array( substr( $rule, -1 ), array( '\\', '/' ) ) )
154
- $file = true;
155
-
156
- // If rule starts with a / then treat as absolute path
157
- elseif ( in_array( substr( $rule, 0, 1 ), array( '\\', '/' ) ) )
158
- $absolute = true;
159
-
160
- // Otherwise treat as dir fragment
161
- else
162
- $fragment = true;
163
-
164
- // Strip ABSPATH and conform
165
- $rule = str_replace( hmbkp_conform_dir( ABSPATH ), '', untrailingslashit( hmbkp_conform_dir( $rule ) ) );
166
-
167
- if ( in_array( substr( $rule, 0, 1 ), array( '\\', '/' ) ) )
168
- $rule = substr( $rule, 1 );
169
-
170
- // Escape string for regex
171
- if ( $context == 'pclzip' )
172
- //$rule = preg_quote( $rule );
173
- $rule = str_replace( '.', '\.', $rule );
174
-
175
- // Convert any existing wildcards
176
- if ( $wildcard != '*' && strpos( $rule, '*' ) !== false )
177
- $rule = str_replace( '*', $wildcard, $rule );
178
-
179
- // Wrap directory fragments in wildcards for zip
180
- if ( $context == 'zip' && $fragment )
181
- $rule = $wildcard . $rule . $wildcard;
182
-
183
- // Add a wildcard to the end of absolute url for zips
184
- if ( $context == 'zip' && $absolute )
185
- $rule .= $wildcard;
186
-
187
- // Add and end carrot to files for pclzip
188
- if ( $file && $context == 'pclzip' )
189
- $rule .= '$';
190
-
191
- // Add a start carrot to absolute urls for pclzip
192
- if ( $absolute && $context == 'pclzip' )
193
- $rule = '^' . $rule;
194
-
195
- endforeach;
196
-
197
- // Escape shell args for zip command
198
- if ( $context == 'zip' )
199
- $excludes = array_map( 'escapeshellarg', $excludes );
200
-
201
- return implode( $separator, $excludes );
202
-
203
- }
204
-
205
- /**
206
- * Return an array of invalid custom exclude rules
207
- *
208
- * @return array
209
- */
210
- function hmbkp_invalid_custom_excludes() {
211
-
212
- $invalid_rules = array();
213
-
214
- // Check if any absolute path excludes actually exist
215
- if ( $excludes = hmbkp_get_excludes() )
216
-
217
- foreach ( explode( ',', $excludes ) as $rule )
218
- if ( ( $rule = trim( $rule ) ) && in_array( substr( $rule, 0, 1 ), array( '/', '\\' ) ) && !file_exists( $rule ) && ! file_exists( ABSPATH . $rule ) && ! file_exists( trailingslashit( ABSPATH ) . $rule ) )
219
- $invalid_rules[] = $rule;
220
-
221
- return $invalid_rules;
222
-
223
- }
224
-
225
- /**
226
- * Return an array of valid custom exclude rules
227
- *
228
- * @return array
229
- */
230
- function hmbkp_valid_custom_excludes() {
231
-
232
- $valid_rules = array();
233
-
234
- $excludes = hmbkp_get_excludes();
235
-
236
- if ( ! $excludes )
237
- array();
238
-
239
- $valid_rules = array_diff( explode( ',', $excludes ), hmbkp_invalid_custom_excludes() );
240
-
241
- return array_map( 'trim', $valid_rules );
242
-
243
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
functions/backup.functions.php CHANGED
@@ -1,78 +1,51 @@
1
  <?php
2
 
3
- /**
4
- * Backup database and files
5
- *
6
- * Creates a temporary directory containing a copy of all files
7
- * and a dump of the database. Then zip that up and delete the temporary files
8
  *
9
- * @uses hmbkp_backup_mysql
10
- * @uses hmbkp_backup_files
11
- * @uses hmbkp_delete_old_backups
12
  */
13
  function hmbkp_do_backup() {
14
-
15
  // Make sure it's possible to do a backup
16
- if ( !hmbkp_possible() )
17
- return false;
18
-
19
  // Clean up any mess left by the last backup
20
  hmbkp_cleanup();
21
-
22
- $offset = current_time( 'timestamp' ) - time();
23
- $time_start = date( 'Y-m-d-H-i-s', time() + $offset );
24
-
25
- $filename = sanitize_file_name( get_bloginfo( 'name' ) . '.backup.' . $time_start . '.zip' );
26
- $filepath = trailingslashit( hmbkp_path() ) . $filename;
27
-
28
- // Set as running
29
- hmbkp_set_status();
30
 
31
- // Raise the memory limit
32
- @ini_set( 'memory_limit', apply_filters( 'admin_memory_limit', '256M' ) );
33
- @set_time_limit( 0 );
34
-
35
- // Set running status
36
- hmbkp_set_status( __( 'Dumping database', 'hmbkp' ) );
37
-
38
- // Backup database
39
- if ( !hmbkp_get_files_only() )
40
- hmbkp_backup_mysql();
41
-
42
- hmbkp_set_status( __( 'Creating zip archive', 'hmbkp' ) );
43
-
44
- // Zip everything up
45
- hmbkp_archive_files( $filepath );
46
-
47
- // Delete the database dump file
48
- if ( file_exists( hmbkp_path() . '/database_' . DB_NAME . '.sql' ) )
49
- unlink( hmbkp_path() . '/database_' . DB_NAME . '.sql' );
50
-
51
  // Email Backup
52
- hmbkp_email_backup( $filepath );
53
-
54
  hmbkp_set_status( __( 'Removing old backups', 'hmbkp' ) );
55
-
56
  // Delete any old backup files
57
  hmbkp_delete_old_backups();
58
 
59
  if ( file_exists( hmbkp_path() . '/.backup_running' ) )
60
  unlink( hmbkp_path() . '/.backup_running' );
61
 
62
- $file = hmbkp_path() . '/.backup_complete';
 
 
63
 
64
- if ( !$handle = @fopen( $file, 'w' ) )
65
- return false;
66
 
67
- fwrite( $handle, '' );
68
 
69
- fclose( $handle );
70
-
71
-
 
72
  }
73
 
74
  /**
75
  * Deletes old backup files
 
 
76
  */
77
  function hmbkp_delete_old_backups() {
78
 
@@ -88,6 +61,8 @@ function hmbkp_delete_old_backups() {
88
 
89
  /**
90
  * Returns an array of backup files
 
 
91
  */
92
  function hmbkp_get_backups() {
93
 
@@ -99,7 +74,7 @@ function hmbkp_get_backups() {
99
 
100
  while ( false !== ( $file = readdir( $handle ) ) )
101
  if ( strpos( $file, '.zip' ) !== false )
102
- $files[filemtime( trailingslashit( $hmbkp_path ) . $file )] = trailingslashit( $hmbkp_path ) . $file;
103
 
104
  closedir( $handle );
105
 
@@ -112,7 +87,7 @@ function hmbkp_get_backups() {
112
 
113
  while ( false !== ( $file = readdir( $handle ) ) )
114
  if ( strpos( $file, '.zip' ) !== false )
115
- $files[filemtime( trailingslashit( HMBKP_PATH ) . $file )] = trailingslashit( HMBKP_PATH ) . $file;
116
 
117
  closedir( $handle );
118
 
@@ -122,9 +97,6 @@ function hmbkp_get_backups() {
122
 
123
  krsort( $files );
124
 
125
- if( empty($files) )
126
- return false;
127
-
128
  return $files;
129
  }
130
 
@@ -143,15 +115,6 @@ function hmbkp_delete_backup( $file ) {
143
 
144
  }
145
 
146
- /**
147
- * Check if a backup is running
148
- *
149
- * @return bool
150
- */
151
- function hmbkp_is_in_progress() {
152
- return file_exists( hmbkp_path() . '/.backup_running' );
153
- }
154
-
155
  /**
156
  * Email backup.
157
  *
@@ -164,9 +127,10 @@ function hmbkp_email_backup( $file ) {
164
  return;
165
 
166
  // Raise the memory and time limit
167
- @ini_set( 'memory_limit', apply_filters( 'admin_memory_limit', '256M' ) );
168
  @set_time_limit( 0 );
169
-
 
170
  $download = get_bloginfo( 'wpurl' ) . '/wp-admin/tools.php?page=' . HMBKP_PLUGIN_SLUG . '&hmbkp_download=' . base64_encode( $file );
171
  $domain = parse_url( get_bloginfo( 'url' ), PHP_URL_HOST ) . parse_url( get_bloginfo( 'url' ), PHP_URL_PATH );
172
 
@@ -178,7 +142,7 @@ function hmbkp_email_backup( $file ) {
178
  $sent = wp_mail( hmbkp_get_email_address(), $subject, $message, $headers, $file );
179
 
180
  // If it failed- Try to send a download link - The file was probably too large.
181
- if ( !$sent ) :
182
 
183
  $subject = sprintf( __( 'Backup of %s', 'hmbkp' ), $domain );
184
  $message = sprintf( __( "BackUpWordPress has completed a backup of your site %s.\n\nUnfortunately the backup file was too large to attach to this email.\n\nYou can download the backup file by clicking the link below:\n\n%s\n\nKind Regards\n\n The Happy BackUpWordPress Backup Emailing Robot", 'hmbkp' ), get_bloginfo( 'url' ), $download );
@@ -188,8 +152,9 @@ function hmbkp_email_backup( $file ) {
188
  endif;
189
 
190
  // Set option for email not sent error
191
- if ( !$sent )
192
  update_option( 'hmbkp_email_error', 'hmbkp_email_failed' );
 
193
  else
194
  delete_option( 'hmbkp_email_error' );
195
 
@@ -207,8 +172,8 @@ function hmbkp_set_status( $message = '' ) {
207
 
208
  $file = hmbkp_path() . '/.backup_running';
209
 
210
- if ( !$handle = @fopen( $file, 'w' ) )
211
- return false;
212
 
213
  fwrite( $handle, $message );
214
 
@@ -223,9 +188,82 @@ function hmbkp_set_status( $message = '' ) {
223
  */
224
  function hmbkp_get_status() {
225
 
226
- if ( !file_exists( hmbkp_path() . '/.backup_running' ) )
227
- return false;
228
 
229
  return file_get_contents( hmbkp_path() .'/.backup_running' );
230
 
231
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  <?php
2
 
3
+ /**
4
+ * Run HM Backup
 
 
 
5
  *
6
+ * @return null
 
 
7
  */
8
  function hmbkp_do_backup() {
9
+
10
  // Make sure it's possible to do a backup
11
+ if ( ! hmbkp_possible() )
12
+ return;
13
+
14
  // Clean up any mess left by the last backup
15
  hmbkp_cleanup();
 
 
 
 
 
 
 
 
 
16
 
17
+ HM_Backup::get_instance()->backup();
18
+
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
19
  // Email Backup
20
+ hmbkp_email_backup( HM_Backup::get_instance()->archive_filepath() );
21
+
22
  hmbkp_set_status( __( 'Removing old backups', 'hmbkp' ) );
23
+
24
  // Delete any old backup files
25
  hmbkp_delete_old_backups();
26
 
27
  if ( file_exists( hmbkp_path() . '/.backup_running' ) )
28
  unlink( hmbkp_path() . '/.backup_running' );
29
 
30
+ if ( file_exists( HM_Backup::get_instance()->archive_filepath() ) ) {
31
+
32
+ $file = hmbkp_path() . '/.backup_complete';
33
 
34
+ if ( !$handle = @fopen( $file, 'w' ) )
35
+ return false;
36
 
37
+ fwrite( $handle, '' );
38
 
39
+ fclose( $handle );
40
+
41
+ }
42
+
43
  }
44
 
45
  /**
46
  * Deletes old backup files
47
+ *
48
+ * @return null
49
  */
50
  function hmbkp_delete_old_backups() {
51
 
61
 
62
  /**
63
  * Returns an array of backup files
64
+ *
65
+ * @return array $files
66
  */
67
  function hmbkp_get_backups() {
68
 
74
 
75
  while ( false !== ( $file = readdir( $handle ) ) )
76
  if ( strpos( $file, '.zip' ) !== false )
77
+ $files[@filemtime( trailingslashit( $hmbkp_path ) . $file )] = trailingslashit( $hmbkp_path ) . $file;
78
 
79
  closedir( $handle );
80
 
87
 
88
  while ( false !== ( $file = readdir( $handle ) ) )
89
  if ( strpos( $file, '.zip' ) !== false )
90
+ $files[@filemtime( trailingslashit( HMBKP_PATH ) . $file )] = trailingslashit( HMBKP_PATH ) . $file;
91
 
92
  closedir( $handle );
93
 
97
 
98
  krsort( $files );
99
 
 
 
 
100
  return $files;
101
  }
102
 
115
 
116
  }
117
 
 
 
 
 
 
 
 
 
 
118
  /**
119
  * Email backup.
120
  *
127
  return;
128
 
129
  // Raise the memory and time limit
130
+ @ini_set( 'memory_limit', apply_filters( 'admin_memory_limit', WP_MAX_MEMORY_LIMIT ) );
131
  @set_time_limit( 0 );
132
+
133
+ // @todo admin_url?
134
  $download = get_bloginfo( 'wpurl' ) . '/wp-admin/tools.php?page=' . HMBKP_PLUGIN_SLUG . '&hmbkp_download=' . base64_encode( $file );
135
  $domain = parse_url( get_bloginfo( 'url' ), PHP_URL_HOST ) . parse_url( get_bloginfo( 'url' ), PHP_URL_PATH );
136
 
142
  $sent = wp_mail( hmbkp_get_email_address(), $subject, $message, $headers, $file );
143
 
144
  // If it failed- Try to send a download link - The file was probably too large.
145
+ if ( ! $sent ) :
146
 
147
  $subject = sprintf( __( 'Backup of %s', 'hmbkp' ), $domain );
148
  $message = sprintf( __( "BackUpWordPress has completed a backup of your site %s.\n\nUnfortunately the backup file was too large to attach to this email.\n\nYou can download the backup file by clicking the link below:\n\n%s\n\nKind Regards\n\n The Happy BackUpWordPress Backup Emailing Robot", 'hmbkp' ), get_bloginfo( 'url' ), $download );
152
  endif;
153
 
154
  // Set option for email not sent error
155
+ if ( ! $sent )
156
  update_option( 'hmbkp_email_error', 'hmbkp_email_failed' );
157
+
158
  else
159
  delete_option( 'hmbkp_email_error' );
160
 
172
 
173
  $file = hmbkp_path() . '/.backup_running';
174
 
175
+ if ( ! $handle = @fopen( $file, 'w' ) )
176
+ return;
177
 
178
  fwrite( $handle, $message );
179
 
188
  */
189
  function hmbkp_get_status() {
190
 
191
+ if ( ! file_exists( hmbkp_path() . '/.backup_running' ) )
192
+ return '';
193
 
194
  return file_get_contents( hmbkp_path() .'/.backup_running' );
195
 
196
  }
197
+
198
+ /**
199
+ * Get the list of excludes
200
+ *
201
+ * @return bool
202
+ */
203
+ function hmbkp_get_excludes() {
204
+
205
+ if ( defined( 'HMBKP_EXCLUDE' ) && HMBKP_EXCLUDE )
206
+ return HMBKP_EXCLUDE;
207
+
208
+ if ( get_option( 'hmbkp_excludes' ) )
209
+ return get_option( 'hmbkp_excludes' );
210
+
211
+ return false;
212
+
213
+ }
214
+
215
+ /**
216
+ * Return an array of invalid custom exclude rules
217
+ *
218
+ * @return array
219
+ */
220
+ function hmbkp_invalid_custom_excludes() {
221
+
222
+ $invalid_rules = array();
223
+
224
+ // Check if any absolute path excludes actually exist
225
+ if ( $excludes = hmbkp_get_excludes() )
226
+
227
+ foreach ( explode( ',', $excludes ) as $rule )
228
+ if ( ( $rule = trim( $rule ) ) && in_array( substr( $rule, 0, 1 ), array( '/', '\\' ) ) && !file_exists( $rule ) && ! file_exists( ABSPATH . $rule ) && ! file_exists( trailingslashit( ABSPATH ) . $rule ) )
229
+ $invalid_rules[] = $rule;
230
+
231
+ return array_filter( $invalid_rules );
232
+
233
+ }
234
+
235
+ /**
236
+ * Return an array of valid custom exclude rules
237
+ *
238
+ * @return array
239
+ */
240
+ function hmbkp_valid_custom_excludes() {
241
+
242
+ $valid_rules = array();
243
+
244
+ $excludes = hmbkp_get_excludes();
245
+
246
+ $valid_rules = array_diff( explode( ',', $excludes ), hmbkp_invalid_custom_excludes() );
247
+
248
+ return array_filter( array_map( 'trim', $valid_rules ) );
249
+
250
+ }
251
+
252
+ /**
253
+ * Check if a backup is running
254
+ *
255
+ * @return bool
256
+ */
257
+ function hmbkp_is_in_progress() {
258
+ return file_exists( hmbkp_path() . '/.backup_running' );
259
+ }
260
+
261
+ /**
262
+ * Get the exclude string from HM Backup
263
+ *
264
+ * @param string $context
265
+ * @return string
266
+ */
267
+ function hmbkp_exclude_string( $context ) {
268
+ return HM_Backup::get_instance()->exclude_string( $context );
269
+ }
functions/backup.mysql.fallback.functions.php DELETED
@@ -1,260 +0,0 @@
1
- <?php
2
-
3
- /**
4
- * hmbkp_backquote function.
5
- *
6
- * Add backquotes to tables and db-names inSQL queries. Taken from phpMyAdmin.
7
- *
8
- * @access public
9
- * @param mixed $a_name
10
- */
11
- function hmbkp_backquote( $a_name ) {
12
-
13
- if ( !empty( $a_name ) && $a_name != '*' ) :
14
-
15
- if ( is_array( $a_name ) ) :
16
- $result = array();
17
- reset( $a_name );
18
-
19
- while ( list( $key, $val ) = each( $a_name ) )
20
- $result[$key] = '`' . $val . '`';
21
-
22
- return $result;
23
-
24
- else :
25
- return '`' . $a_name . '`';
26
-
27
- endif;
28
-
29
- else :
30
- return $a_name;
31
- endif;
32
- }
33
-
34
- /**
35
- * hmbkp_make_sql function.
36
- *
37
- * Reads the Database table in $table and creates
38
- * SQL Statements for recreating structure and data
39
- * Taken partially from phpMyAdmin and partially from
40
- * Alain Wolf, Zurich - Switzerland
41
- * Website: http://restkultur.ch/personal/wolf/scripts/db_backup/
42
- *
43
- * @access public
44
- * @param mixed $sql_file
45
- * @param mixed $table
46
- */
47
- function hmbkp_make_sql( $sql_file, $table ) {
48
-
49
- global $hmbkp_db_connect;
50
-
51
- // Add SQL statement to drop existing table
52
- $sql_file = "\n";
53
- $sql_file .= "\n";
54
- $sql_file .= "#\n";
55
- $sql_file .= "# Delete any existing table " . hmbkp_backquote( $table ) . "\n";
56
- $sql_file .= "#\n";
57
- $sql_file .= "\n";
58
- $sql_file .= "DROP TABLE IF EXISTS " . hmbkp_backquote( $table ) . ";\n";
59
-
60
- /* Table Structure */
61
-
62
- // Comment in SQL-file
63
- $sql_file .= "\n";
64
- $sql_file .= "\n";
65
- $sql_file .= "#\n";
66
- $sql_file .= "# Table structure of table " . hmbkp_backquote( $table ) . "\n";
67
- $sql_file .= "#\n";
68
- $sql_file .= "\n";
69
-
70
- // Get table structure
71
- $query = 'SHOW CREATE TABLE ' . hmbkp_backquote( $table );
72
- $result = mysql_query( $query, $hmbkp_db_connect );
73
-
74
- if ( $result ) :
75
-
76
- if ( mysql_num_rows( $result ) > 0 ) :
77
- $sql_create_arr = mysql_fetch_array( $result );
78
- $sql_file .= $sql_create_arr[1];
79
- endif;
80
-
81
- mysql_free_result( $result );
82
- $sql_file .= ' ;';
83
-
84
- endif;
85
-
86
- /* Table Contents */
87
-
88
- // Get table contents
89
- $query = 'SELECT * FROM ' . hmbkp_backquote( $table );
90
- $result = mysql_query( $query, $hmbkp_db_connect );
91
-
92
- if ( $result ) :
93
- $fields_cnt = mysql_num_fields( $result );
94
- $rows_cnt = mysql_num_rows( $result );
95
- endif;
96
-
97
- // Comment in SQL-file
98
- $sql_file .= "\n";
99
- $sql_file .= "\n";
100
- $sql_file .= "#\n";
101
- $sql_file .= "# Data contents of table " . $table . " (" . $rows_cnt . " records)\n";
102
- $sql_file .= "#\n";
103
-
104
- // Checks whether the field is an integer or not
105
- for ( $j = 0; $j < $fields_cnt; $j++ ) :
106
- $field_set[$j] = hmbkp_backquote( mysql_field_name( $result, $j ) );
107
- $type = mysql_field_type( $result, $j );
108
-
109
- if ( $type == 'tinyint' || $type == 'smallint' || $type == 'mediumint' || $type == 'int' || $type == 'bigint' ||$type == 'timestamp')
110
- $field_num[$j] = true;
111
- else
112
- $field_num[$j] = false;
113
-
114
- endfor;
115
-
116
- // Sets the scheme
117
- $entries = 'INSERT INTO ' . hmbkp_backquote($table) . ' VALUES (';
118
- $search = array( '\x00', '\x0a', '\x0d', '\x1a' ); //\x08\\x09, not required
119
- $replace = array( '\0', '\n', '\r', '\Z' );
120
- $current_row = 0;
121
- $batch_write = 0;
122
-
123
- while ( $row = mysql_fetch_row( $result ) ) :
124
- $current_row++;
125
-
126
- // build the statement
127
- for ( $j = 0; $j < $fields_cnt; $j++ ) :
128
-
129
- if ( !isset($row[$j] ) ) :
130
- $values[] = 'NULL';
131
-
132
- elseif ( $row[$j] == '0' || $row[$j] != '' ) :
133
-
134
- // a number
135
- if ( $field_num[$j] )
136
- $values[] = $row[$j];
137
-
138
- else
139
- $values[] = "'" . str_replace( $search, $replace, hmbkp_sql_addslashes( $row[$j] ) ) . "'";
140
-
141
- else :
142
- $values[] = "''";
143
- endif;
144
-
145
- endfor;
146
-
147
- $sql_file .= " \n" . $entries . implode( ', ', $values ) . ") ;";
148
-
149
- // write the rows in batches of 100
150
- if ( $batch_write == 100 ) :
151
- $batch_write = 0;
152
- hmbkp_write_sql( $sql_file );
153
- $sql_file = '';
154
- endif;
155
-
156
- $batch_write++;
157
-
158
- unset( $values );
159
-
160
- endwhile;
161
-
162
- mysql_free_result( $result );
163
-
164
- // Create footer/closing comment in SQL-file
165
- $sql_file .= "\n";
166
- $sql_file .= "#\n";
167
- $sql_file .= "# End of data contents of table " . $table . "\n";
168
- $sql_file .= "# --------------------------------------------------------\n";
169
- $sql_file .= "\n";
170
-
171
- hmbkp_write_sql( $sql_file );
172
-
173
- }
174
-
175
- /**
176
- * hmbkp_sql_addslashes function.
177
- *
178
- * Better addslashes for SQL queries.
179
- * Taken from phpMyAdmin.
180
- *
181
- * @access public
182
- * @param string $a_string. (default: '')
183
- * @param bool $is_like. (default: false)
184
- */
185
- function hmbkp_sql_addslashes( $a_string = '', $is_like = false ) {
186
-
187
- if ( $is_like )
188
- $a_string = str_replace( '\\', '\\\\\\\\', $a_string );
189
-
190
- else
191
- $a_string = str_replace( '\\', '\\\\', $a_string );
192
-
193
- $a_string = str_replace( '\'', '\\\'', $a_string );
194
-
195
- return $a_string;
196
- }
197
-
198
- /**
199
- * hmbkp_mysql function.
200
- *
201
- * @access public
202
- */
203
- function hmbkp_backup_mysql_fallback() {
204
-
205
- global $hmbkp_db_connect;
206
-
207
- @set_time_limit( 0 );
208
-
209
- $hmbkp_db_connect = mysql_pconnect( DB_HOST, DB_USER, DB_PASSWORD );
210
-
211
- mysql_select_db( DB_NAME, $hmbkp_db_connect );
212
-
213
- // Begin new backup of MySql
214
- $tables = mysql_list_tables( DB_NAME );
215
-
216
- $sql_file = "# WordPress : " . get_bloginfo( 'url' ) . " MySQL database backup\n";
217
- $sql_file .= "#\n";
218
- $sql_file .= "# Generated: " . date( 'l j. F Y H:i T' ) . "\n";
219
- $sql_file .= "# Hostname: " . DB_HOST . "\n";
220
- $sql_file .= "# Database: " . hmbkp_backquote( DB_NAME ) . "\n";
221
- $sql_file .= "# --------------------------------------------------------\n";
222
-
223
- for ( $i = 0; $i < mysql_num_rows( $tables ); $i++ ) :
224
-
225
- $curr_table = mysql_tablename( $tables, $i );
226
-
227
- // Create the SQL statements
228
- $sql_file .= "# --------------------------------------------------------\n";
229
- $sql_file .= "# Table: " . hmbkp_backquote( $curr_table ) . "\n";
230
- $sql_file .= "# --------------------------------------------------------\n";
231
- hmbkp_make_sql( $sql_file, $curr_table );
232
-
233
- endfor;
234
-
235
- }
236
-
237
- /**
238
- * hmbkp_write_sql function.
239
- *
240
- * @param mixed $sql
241
- */
242
- function hmbkp_write_sql( $sql ) {
243
-
244
- $sqlname = hmbkp_path() . '/database_' . DB_NAME . '.sql';
245
-
246
- // Actually write the sql file
247
- if ( is_writable( $sqlname ) || !file_exists( $sqlname ) ) :
248
-
249
- if ( !$handle = fopen( $sqlname, 'a' ) )
250
- return;
251
-
252
- if ( !fwrite( $handle, $sql ) )
253
- return;
254
-
255
- fclose( $handle );
256
-
257
- return true;
258
-
259
- endif;
260
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
functions/backup.mysql.functions.php DELETED
@@ -1,113 +0,0 @@
1
- <?php
2
-
3
- /**
4
- * Create the mysql backup
5
- *
6
- * Uses mysqldump if available, fallsback to PHP
7
- * if not.
8
- */
9
- function hmbkp_backup_mysql() {
10
-
11
- // Use mysqldump if we can
12
- if ( hmbkp_mysqldump_path() ) {
13
-
14
- // Path to the mysqldump executable
15
- $cmd = escapeshellarg( hmbkp_mysqldump_path() );
16
-
17
- // No Create DB command
18
- $cmd .= ' --no-create-db';
19
-
20
- // Make sure binary data is exported properly
21
- $cmd .= ' --hex-blob';
22
-
23
- // Username
24
- $cmd .= ' -u ' . escapeshellarg( DB_USER );
25
-
26
- // Don't pass the password if it's blank
27
- if ( DB_PASSWORD )
28
- $cmd .= ' -p' . escapeshellarg( DB_PASSWORD );
29
-
30
- // Set the host
31
- $cmd .= ' -h ' . escapeshellarg( DB_HOST );
32
-
33
- // Save the file
34
- $cmd .= ' -r ' . escapeshellarg( hmbkp_path() . '/database_' . DB_NAME . '.sql' );
35
-
36
- // The database we're dumping
37
- $cmd .= ' ' . escapeshellarg( DB_NAME );
38
-
39
- shell_exec( $cmd );
40
-
41
- // If the file doesn't exist then the shell_exec must have failed
42
- if ( file_exists( hmbkp_path() . '/database_' . DB_NAME . '.sql' ) )
43
- return true;
44
-
45
- }
46
-
47
- // Fallback to using the PHP library
48
- hmbkp_backup_mysql_fallback();
49
- }
50
-
51
- /**
52
- * Attempt to work out the path to mysqldump
53
- *
54
- * Can be overridden by defining HMBKP_MYSQLDUMP_PATH in
55
- * wp-config.php.
56
- *
57
- * @return string $path on success, empty string on failure
58
- */
59
- function hmbkp_mysqldump_path() {
60
-
61
- if ( !hmbkp_shell_exec_available() || ( defined( 'HMBKP_MYSQLDUMP_PATH' ) && !HMBKP_MYSQLDUMP_PATH ) )
62
- return false;
63
-
64
- $path = '';
65
-
66
- // List of possible mysqldump locations
67
- $mysqldump_locations = array(
68
- 'mysqldump',
69
- '/usr/local/bin/mysqldump',
70
- '/usr/local/mysql/bin/mysqldump',
71
- '/usr/mysql/bin/mysqldump',
72
- '/usr/bin/mysqldump',
73
- '/opt/local/lib/mysql6/bin/mysqldump',
74
- '/opt/local/lib/mysql5/bin/mysqldump',
75
- '/opt/local/lib/mysql4/bin/mysqldump',
76
- '\xampp\mysql\bin\mysqldump',
77
- '\Program Files\xampp\mysql\bin\mysqldump',
78
- '\Program Files\MySQL\MySQL Server 6.0\bin\mysqldump',
79
- '\Program Files\MySQL\MySQL Server 5.5\bin\mysqldump',
80
- '\Program Files\MySQL\MySQL Server 5.4\bin\mysqldump',
81
- '\Program Files\MySQL\MySQL Server 5.1\bin\mysqldump',
82
- '\Program Files\MySQL\MySQL Server 5.0\bin\mysqldump',
83
- '\Program Files\MySQL\MySQL Server 4.1\bin\mysqldump'
84
- );
85
-
86
- // Allow the path to be overridden
87
- if ( defined( 'HMBKP_MYSQLDUMP_PATH' ) && HMBKP_MYSQLDUMP_PATH )
88
- array_unshift( $mysqldump_locations, HMBKP_MYSQLDUMP_PATH );
89
-
90
- // If we don't have a path set
91
- if ( !$path = get_option( 'hmbkp_mysqldump_path' ) ) :
92
-
93
- // Try to find out where mysqldump is
94
- foreach ( $mysqldump_locations as $location )
95
- if ( shell_exec( $location ) )
96
- $path = $location;
97
-
98
- // Save it for later
99
- if ( $path )
100
- update_option( 'hmbkp_mysqldump_path', $path );
101
-
102
- endif;
103
-
104
- // Check again in-case the saved path has stopped working for some reason
105
- if ( $path && !shell_exec( $path ) ) :
106
- delete_option( 'hmbkp_mysqldump_path' );
107
- return hmbkp_mysqldump_path();
108
-
109
- endif;
110
-
111
- return $path;
112
-
113
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
functions/core.functions.php CHANGED
@@ -1,7 +1,7 @@
1
  <?php
2
 
3
  /**
4
- * Setup the default options on plugin activation
5
  */
6
  function hmbkp_activate() {
7
 
@@ -18,6 +18,8 @@ function hmbkp_activate() {
18
  */
19
  function hmbkp_deactivate() {
20
 
 
 
21
  // Options to delete
22
  $options = array(
23
  'hmbkp_zip_path',
@@ -71,7 +73,7 @@ function hmbkp_update() {
71
  endif;
72
 
73
  // Pre 1.1
74
- if ( !get_option( 'hmbkp_plugin_version' ) ) :
75
 
76
  // Delete the obsolete max backups option
77
  delete_option( 'hmbkp_max_backups' );
@@ -123,31 +125,6 @@ function hmbkp_update() {
123
 
124
  }
125
 
126
- /**
127
- * Sanitize a directory path
128
- *
129
- * @param string $dir
130
- * @param bool $rel. (default: false)
131
- * @return string $dir
132
- */
133
- function hmbkp_conform_dir( $dir, $rel = false ) {
134
-
135
- // Normalise slashes
136
- $dir = str_replace( '\\', '/', $dir );
137
- $dir = str_replace( '//', '/', $dir );
138
-
139
- // Remove the trailingslash
140
- $dir = untrailingslashit( $dir );
141
-
142
- // If we're on Windows
143
- if ( strpos( ABSPATH, '\\' ) !== false )
144
- $dir = str_replace( '\\', '/', $dir );
145
-
146
- if ( $rel == true )
147
- $dir = str_replace( hmbkp_conform_dir( ABSPATH ), '', $dir );
148
-
149
- return $dir;
150
- }
151
  /**
152
  * Take a file size and return a human readable
153
  * version
@@ -266,7 +243,7 @@ function hmbkp_send_file( $path ) {
266
  */
267
  function hmbkp_ls( $dir, $files = array() ) {
268
 
269
- if ( !is_readable( $dir ) )
270
  return $files;
271
 
272
  $d = opendir( $dir );
@@ -275,7 +252,7 @@ function hmbkp_ls( $dir, $files = array() ) {
275
  $excludes = hmbkp_exclude_string( 'pclzip' );
276
 
277
  while ( $file = readdir( $d ) ) :
278
-
279
  // Ignore current dir and containing dir and any unreadable files or directories
280
  if ( $file == '.' || $file == '..' )
281
  continue;
@@ -283,7 +260,7 @@ function hmbkp_ls( $dir, $files = array() ) {
283
  $file = hmbkp_conform_dir( trailingslashit( $dir ) . $file );
284
 
285
  // Skip the backups dir and any excluded paths
286
- if ( ( $file == hmbkp_path() || preg_match( '(' . $excludes . ')', $file ) || !is_readable( $file ) ) )
287
  continue;
288
 
289
  $files[] = $file;
@@ -357,7 +334,7 @@ function hmbkp_rmdirtree( $dir ) {
357
  */
358
  function hmbkp_calculate() {
359
 
360
- @ini_set( 'memory_limit', apply_filters( 'admin_memory_limit', '256M' ) );
361
 
362
  // Check cache
363
  if ( $filesize = get_transient( 'hmbkp_estimated_filesize' ) )
@@ -394,43 +371,6 @@ function hmbkp_calculate() {
394
 
395
  }
396
 
397
- /**
398
- * Check whether shell_exec has been disabled.
399
- *
400
- * @return bool
401
- */
402
- function hmbkp_shell_exec_available() {
403
-
404
- $disable_functions = ini_get( 'disable_functions' );
405
-
406
- // Is shell_exec disabled?
407
- if ( strpos( $disable_functions, 'shell_exec' ) !== false )
408
- return false;
409
-
410
- // Are we in Safe Mode
411
- if ( hmbkp_is_safe_mode_active() )
412
- return false;
413
-
414
- return true;
415
-
416
- }
417
-
418
- /**
419
- * Check whether safe mode if active or not
420
- *
421
- * @return bool
422
- */
423
- function hmbkp_is_safe_mode_active() {
424
-
425
- $safe_mode = ini_get( 'safe_mode' );
426
-
427
- if ( $safe_mode && strtolower( $safe_mode ) != 'off' )
428
- return true;
429
-
430
- return false;
431
-
432
- }
433
-
434
  /**
435
  * Calculate the total filesize of all backups
436
  *
@@ -463,8 +403,8 @@ function hmbkp_setup_schedule() {
463
  // Clear any old schedules
464
  wp_clear_scheduled_hook( 'hmbkp_schedule_backup_hook' );
465
 
466
- if( hmbkp_get_disable_automatic_backup() )
467
- return;
468
 
469
  // Default to 11 in the evening
470
  $time = '23:00';
@@ -628,9 +568,8 @@ function hmbkp_get_database_only() {
628
 
629
  /**
630
  * Returns defined email address or email address saved in options.
631
- * If none set, return false.
632
  */
633
-
634
  function hmbkp_get_email_address() {
635
 
636
  if ( defined( 'HMBKP_EMAIL' ) && HMBKP_EMAIL )
@@ -640,12 +579,12 @@ function hmbkp_get_email_address() {
640
  $email = get_option( 'hmbkp_email_address' );
641
 
642
  else
643
- return false;
644
 
645
  if ( is_email( $email ) )
646
  return $email;
647
 
648
- return false;
649
 
650
  }
651
 
@@ -666,23 +605,6 @@ function hmbkp_get_disable_automatic_backup() {
666
 
667
  }
668
 
669
- /**
670
- * Get the list of excludes
671
- *
672
- * @return bool
673
- */
674
- function hmbkp_get_excludes() {
675
-
676
- if ( defined( 'HMBKP_EXCLUDE' ) && HMBKP_EXCLUDE )
677
- return HMBKP_EXCLUDE;
678
-
679
- if ( get_option( 'hmbkp_excludes' ) )
680
- return get_option( 'hmbkp_excludes' );
681
-
682
- return false;
683
-
684
- }
685
-
686
  /**
687
  * Check if a backup is possible with regards to file
688
  * permissions etc.
@@ -722,4 +644,12 @@ function hmbkp_cleanup() {
722
 
723
  endif;
724
 
 
 
 
 
 
 
 
 
725
  }
1
  <?php
2
 
3
  /**
4
+ * Setup the plugin defaults on activation
5
  */
6
  function hmbkp_activate() {
7
 
18
  */
19
  function hmbkp_deactivate() {
20
 
21
+ hmbkp_setup_hm_backup();
22
+
23
  // Options to delete
24
  $options = array(
25
  'hmbkp_zip_path',
73
  endif;
74
 
75
  // Pre 1.1
76
+ if ( ! get_option( 'hmbkp_plugin_version' ) ) :
77
 
78
  // Delete the obsolete max backups option
79
  delete_option( 'hmbkp_max_backups' );
125
 
126
  }
127
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
128
  /**
129
  * Take a file size and return a human readable
130
  * version
243
  */
244
  function hmbkp_ls( $dir, $files = array() ) {
245
 
246
+ if ( ! is_readable( $dir ) )
247
  return $files;
248
 
249
  $d = opendir( $dir );
252
  $excludes = hmbkp_exclude_string( 'pclzip' );
253
 
254
  while ( $file = readdir( $d ) ) :
255
+
256
  // Ignore current dir and containing dir and any unreadable files or directories
257
  if ( $file == '.' || $file == '..' )
258
  continue;
260
  $file = hmbkp_conform_dir( trailingslashit( $dir ) . $file );
261
 
262
  // Skip the backups dir and any excluded paths
263
+ if ( ! is_readable( $file ) || $file == hmbkp_path() || preg_match( '(' . $excludes . ')', str_replace( ABSPATH, '', $file ) ) )
264
  continue;
265
 
266
  $files[] = $file;
334
  */
335
  function hmbkp_calculate() {
336
 
337
+ @ini_set( 'memory_limit', apply_filters( 'admin_memory_limit', WP_MAX_MEMORY_LIMIT ) );
338
 
339
  // Check cache
340
  if ( $filesize = get_transient( 'hmbkp_estimated_filesize' ) )
371
 
372
  }
373
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
374
  /**
375
  * Calculate the total filesize of all backups
376
  *
403
  // Clear any old schedules
404
  wp_clear_scheduled_hook( 'hmbkp_schedule_backup_hook' );
405
 
406
+ if( hmbkp_get_disable_automatic_backup() )
407
+ return;
408
 
409
  // Default to 11 in the evening
410
  $time = '23:00';
568
 
569
  /**
570
  * Returns defined email address or email address saved in options.
571
+ * If none set, return empty string.
572
  */
 
573
  function hmbkp_get_email_address() {
574
 
575
  if ( defined( 'HMBKP_EMAIL' ) && HMBKP_EMAIL )
579
  $email = get_option( 'hmbkp_email_address' );
580
 
581
  else
582
+ return '';
583
 
584
  if ( is_email( $email ) )
585
  return $email;
586
 
587
+ return '';
588
 
589
  }
590
 
605
 
606
  }
607
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
608
  /**
609
  * Check if a backup is possible with regards to file
610
  * permissions etc.
644
 
645
  endif;
646
 
647
+ }
648
+
649
+ function hmbkp_conform_dir( $dir ) {
650
+ return HM_Backup::get_instance()->conform_dir( $dir );
651
+ }
652
+
653
+ function hmbkp_is_safe_mode_active() {
654
+ return HM_Backup::get_instance()->is_safe_mode_active();
655
  }
functions/interface.functions.php CHANGED
@@ -1,4 +1,5 @@
1
  <?php
 
2
  /**
3
  * Displays a row in the manage backups table
4
  *
@@ -6,15 +7,13 @@
6
  */
7
  function hmbkp_get_backup_row( $file ) {
8
 
9
- $encode = base64_encode( $file );
10
- $offset = current_time( 'timestamp' ) - time();
11
-
12
- ?>
13
 
14
  <tr class="hmbkp_manage_backups_row<?php if ( file_exists( hmbkp_path() . '/.backup_complete' ) ) : ?> completed<?php unlink( hmbkp_path() . '/.backup_complete' ); endif; ?>">
15
 
16
  <th scope="row">
17
- <?php echo date_i18n( get_option( 'date_format' ) . ' - ' . get_option( 'time_format' ), filemtime( $file ) + $offset ); ?>
18
  </th>
19
 
20
  <td>
@@ -33,31 +32,32 @@ function hmbkp_get_backup_row( $file ) {
33
  <?php }
34
 
35
  /**
36
- * Displays admin notices for various error / warning
37
  * conditions
38
- *
39
  * @return void
40
  */
41
  function hmbkp_admin_notices() {
42
 
43
- // If the form has been submitted, display un updated notification
44
- // Display notifications for any errors in the advanced options form.
45
- if( !empty( $_POST['hmbkp_options_submit'] ) ) :
 
 
46
 
47
- function hmbkp_advanced_options_saved() {
48
  echo '<div id="setting-error-settings_updated" class="updated settings-error"><p><strong>Settings saved.</strong></p></div>';
49
 
50
  global $hmbkp_errors;
51
- if ( !empty( $hmbkp_errors ) && $hmbkp_errors->get_error_code() ) {
52
- foreach( $hmbkp_errors->get_error_messages() as $hmbkp_error ) {
 
53
  echo '<div class="error"><p>' . $hmbkp_error . '</p></div>';
54
- }
55
- }
56
  }
57
- add_action( 'admin_notices', 'hmbkp_advanced_options_saved' );
58
-
59
- endif;
60
-
61
  // If the backups directory doesn't exist and can't be automatically created
62
  if ( !is_dir( hmbkp_path() ) ) :
63
 
1
  <?php
2
+
3
  /**
4
  * Displays a row in the manage backups table
5
  *
7
  */
8
  function hmbkp_get_backup_row( $file ) {
9
 
10
+ $encode = base64_encode( $file );
11
+ $offset = current_time( 'timestamp' ) - time(); ?>
 
 
12
 
13
  <tr class="hmbkp_manage_backups_row<?php if ( file_exists( hmbkp_path() . '/.backup_complete' ) ) : ?> completed<?php unlink( hmbkp_path() . '/.backup_complete' ); endif; ?>">
14
 
15
  <th scope="row">
16
+ <?php echo date_i18n( get_option( 'date_format' ) . ' - ' . get_option( 'time_format' ), @filemtime( $file ) + $offset ); ?>
17
  </th>
18
 
19
  <td>
32
  <?php }
33
 
34
  /**
35
+ * Displays admin notices for various error / warning
36
  * conditions
37
+ *
38
  * @return void
39
  */
40
  function hmbkp_admin_notices() {
41
 
42
+ // If the form has been submitted, display updated notification
43
+ // Display notifications for any errors in the settings form.
44
+ if ( ! empty( $_POST['hmbkp_settings_submit'] ) ) :
45
+
46
+ function hmbkp_advanced_settings_saved() {
47
 
 
48
  echo '<div id="setting-error-settings_updated" class="updated settings-error"><p><strong>Settings saved.</strong></p></div>';
49
 
50
  global $hmbkp_errors;
51
+
52
+ if ( !empty( $hmbkp_errors ) && $hmbkp_errors->get_error_code() )
53
+ foreach( $hmbkp_errors->get_error_messages() as $hmbkp_error )
54
  echo '<div class="error"><p>' . $hmbkp_error . '</p></div>';
55
+
 
56
  }
57
+ add_action( 'admin_notices', 'hmbkp_advanced_settings_saved' );
58
+
59
+ endif;
60
+
61
  // If the backups directory doesn't exist and can't be automatically created
62
  if ( !is_dir( hmbkp_path() ) ) :
63
 
hm-backup/hm-backup.php ADDED
@@ -0,0 +1,812 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Runs the backup process
5
+ */
6
+ class HM_Backup {
7
+
8
+ /**
9
+ * The path where the backup file should be saved
10
+ *
11
+ * @string
12
+ * @access public
13
+ */
14
+ public $path;
15
+
16
+ /**
17
+ * Whether the backup should be files only
18
+ *
19
+ * @bool
20
+ * @access public
21
+ */
22
+ public $files_only;
23
+
24
+ /**
25
+ * Whether the backup should be database only
26
+ *
27
+ * @bool
28
+ * @access public
29
+ */
30
+ public $database_only;
31
+
32
+ /**
33
+ * The filename of the backup file
34
+ *
35
+ * @string
36
+ * @access public
37
+ */
38
+ public $archive_filename;
39
+
40
+ /**
41
+ * The filename of the database dump
42
+ *
43
+ * @string
44
+ * @access public
45
+ */
46
+ public $database_dump_filename;
47
+
48
+ /**
49
+ * The path to the zip command
50
+ *
51
+ * @string
52
+ * @access public
53
+ */
54
+ public $zip_command_path;
55
+
56
+ /**
57
+ * The path to the mysqldump command
58
+ *
59
+ * @string
60
+ * @access public
61
+ */
62
+ public $mysqldump_command_path;
63
+
64
+ /**
65
+ * An array of exclude rules
66
+ *
67
+ * @array
68
+ * @access public
69
+ */
70
+ public $excludes;
71
+
72
+ /**
73
+ * The path that should be backed up
74
+ *
75
+ * @var string
76
+ * @access public
77
+ */
78
+ public $root;
79
+
80
+ /**
81
+ * Holds the current db connection
82
+ *
83
+ * @var resource
84
+ * @access private
85
+ */
86
+ private $db;
87
+
88
+ static $instance;
89
+
90
+ /**
91
+ * Sets up the default properties
92
+ *
93
+ * @access public
94
+ * @return null
95
+ */
96
+ public function __construct() {
97
+
98
+ // Raise the memory limit and max_execution_time time
99
+ @ini_set( 'memory_limit', apply_filters( 'admin_memory_limit', WP_MAX_MEMORY_LIMIT ) );
100
+ @set_time_limit( 0 );
101
+
102
+ // Defaults
103
+ $this->root = ABSPATH;
104
+
105
+ $this->path = $this->conform_dir( WP_CONTENT_DIR . '/backups' );
106
+
107
+ $this->database_dump_filename = 'database_' . DB_NAME . '.sql';
108
+
109
+ $this->archive_filename = strtolower( sanitize_file_name( get_bloginfo( 'name' ) . '.backup.' . date( 'Y-m-d-H-i-s', time() + ( current_time( 'timestamp' ) - time() ) ) . '.zip' ) );
110
+
111
+ $this->mysqldump_command_path = $this->guess_mysqldump_command_path();
112
+ $this->zip_command_path = $this->guess_zip_command_path();
113
+
114
+ $this->database_only = false;
115
+ $this->files_only = false;
116
+
117
+ }
118
+
119
+ public static function get_instance() {
120
+
121
+ if ( empty( self::$instance ) )
122
+ self::$instance = new HM_Backup();
123
+
124
+ return self::$instance;
125
+
126
+ }
127
+
128
+ public function __destruct() {
129
+ unset( $GLOBALS['hm_backup'] );
130
+ }
131
+
132
+ /**
133
+ * The full filepath to the archive filepath.
134
+ *
135
+ * @access public
136
+ * @return string
137
+ */
138
+ public function archive_filepath() {
139
+ return trailingslashit( $this->path ) . $this->archive_filename;
140
+ }
141
+
142
+ /**
143
+ * The full filepath to the database dump filepath.
144
+ *
145
+ * @access public
146
+ * @return string
147
+ */
148
+ public function database_dump_filepath() {
149
+ return trailingslashit( $this->path ) . $this->database_dump_filename;
150
+ }
151
+
152
+ /**
153
+ * Run the backup
154
+ *
155
+ * @access public
156
+ * @return bool
157
+ */
158
+ public function backup() {
159
+
160
+ do_action( 'hmbkp_backup_started', $this );
161
+
162
+ // Backup database
163
+ if ( ! $this->files_only )
164
+ $this->mysqldump();
165
+
166
+ // Zip everything up
167
+ $this->archive();
168
+
169
+ do_action( 'hmbkp_backup_complete' );
170
+
171
+ }
172
+
173
+ /**
174
+ * Create the mysql backup
175
+ *
176
+ * Uses mysqldump if available, falls back to PHP
177
+ * if not.
178
+ *
179
+ * @access public
180
+ * @return null
181
+ */
182
+ public function mysqldump() {
183
+
184
+ do_action( 'hmbkp_mysqldump_started' );
185
+
186
+ // Use mysqldump if we can
187
+ if ( $this->mysqldump_command_path ) {
188
+
189
+ // Path to the mysqldump executable
190
+ $cmd = escapeshellarg( $this->mysqldump_command_path );
191
+
192
+ // No Create DB command
193
+ $cmd .= ' --no-create-db';
194
+
195
+ // Make sure binary data is exported properly
196
+ $cmd .= ' --hex-blob';
197
+
198
+ // Username
199
+ $cmd .= ' -u ' . escapeshellarg( DB_USER );
200
+
201
+ // Don't pass the password if it's blank
202
+ if ( DB_PASSWORD )
203
+ $cmd .= ' -p' . escapeshellarg( DB_PASSWORD );
204
+
205
+ // Set the host
206
+ $cmd .= ' -h ' . escapeshellarg( DB_HOST );
207
+
208
+ // Save the file
209
+ $cmd .= ' -r ' . escapeshellarg( $this->database_dump_filepath() );
210
+
211
+ // The database we're dumping
212
+ $cmd .= ' ' . escapeshellarg( DB_NAME );
213
+
214
+ // Send stdout to null
215
+ $cmd .= ' 2> /dev/null';
216
+
217
+ shell_exec( $cmd );
218
+
219
+ }
220
+
221
+ // If not or if the shell mysqldump command failed, use the PHP fallback
222
+ if ( ! file_exists( $this->database_dump_filepath() ) )
223
+ $this->mysqldump_fallback();
224
+
225
+ do_action( 'hmbkp_mysqldump_finished' );
226
+
227
+ }
228
+
229
+ /**
230
+ * PHP mysqldump fallback functions, exports the database to a .sql file
231
+ *
232
+ * @access public
233
+ * @return null
234
+ */
235
+ public function mysqldump_fallback() {
236
+
237
+ $this->db = mysql_pconnect( DB_HOST, DB_USER, DB_PASSWORD );
238
+
239
+ mysql_select_db( DB_NAME, $this->db );
240
+ mysql_set_charset( DB_CHARSET, $this->db );
241
+
242
+ // Begin new backup of MySql
243
+ $tables = mysql_list_tables( DB_NAME );
244
+
245
+ $sql_file = "# WordPress : " . get_bloginfo( 'url' ) . " MySQL database backup\n";
246
+ $sql_file .= "#\n";
247
+ $sql_file .= "# Generated: " . date( 'l j. F Y H:i T' ) . "\n";
248
+ $sql_file .= "# Hostname: " . DB_HOST . "\n";
249
+ $sql_file .= "# Database: " . $this->sql_backquote( DB_NAME ) . "\n";
250
+ $sql_file .= "# --------------------------------------------------------\n";
251
+
252
+ for ( $i = 0; $i < mysql_num_rows( $tables ); $i++ ) {
253
+
254
+ $curr_table = mysql_tablename( $tables, $i );
255
+
256
+ // Create the SQL statements
257
+ $sql_file .= "# --------------------------------------------------------\n";
258
+ $sql_file .= "# Table: " . $this->sql_backquote( $curr_table ) . "\n";
259
+ $sql_file .= "# --------------------------------------------------------\n";
260
+
261
+ $this->make_sql( $sql_file, $curr_table );
262
+
263
+ }
264
+
265
+ }
266
+
267
+ /**
268
+ * Zip up all the wordpress files.
269
+ *
270
+ * Attempts to use the shell zip command, if
271
+ * thats not available then it fallsback on
272
+ * PHP zip classes.
273
+ *
274
+ * @access public
275
+ * @return null
276
+ */
277
+ public function archive() {
278
+
279
+ do_action( 'hmbkp_archive_started' );
280
+
281
+ // Do we have the path to the zip command
282
+ if ( $this->zip_command_path ) {
283
+
284
+ // Zip up $this->root
285
+ if ( ! $this->database_only )
286
+ shell_exec( 'cd ' . escapeshellarg( $this->root ) . ' && ' . escapeshellarg( $this->zip_command_path ) . ' -rq ' . escapeshellarg( $this->archive_filepath() ) . ' ./' . ' -x ' . $this->exclude_string( 'zip' ) . ' 2> /dev/null' );
287
+
288
+ // Add the database dump to the archive
289
+ if ( ! $this->files_only )
290
+ shell_exec( 'cd ' . escapeshellarg( $this->path ) . ' && ' . escapeshellarg( $this->zip_command_path ) . ' -uq ' . escapeshellarg( $this->archive_filepath() ) . ' ' . escapeshellarg( $this->database_dump_filename ) . ' 2> /dev/null' );
291
+
292
+ }
293
+
294
+ // If not or if the shell zip failed then use the PHP fallback
295
+ if ( ! file_exists( $this->archive_filepath() ) )
296
+ $this->archive_fallback();
297
+
298
+ // Delete the database dump file
299
+ if ( file_exists( $this->database_dump_filepath() ) )
300
+ unlink( $this->database_dump_filepath() );
301
+
302
+ do_action( 'hmbkp_archive_finished' );
303
+
304
+ }
305
+
306
+ /**
307
+ * Fallback for creating zip archives if zip command is
308
+ * unnavailable.
309
+ *
310
+ * Uses the PCLZIP library that ships with WordPress
311
+ *
312
+ * @todo support zipArchive
313
+ * @access public
314
+ * @param string $path
315
+ */
316
+ public function archive_fallback() {
317
+
318
+ global $_hmbkp_exclude_string;
319
+
320
+ $_hmbkp_exclude_string = $this->exclude_string( 'pclzip' );
321
+
322
+ if ( ! defined( 'PCLZIP_TEMPORARY_DIR' ) )
323
+ define( 'PCLZIP_TEMPORARY_DIR', $this->path );
324
+
325
+ require_once( ABSPATH . 'wp-admin/includes/class-pclzip.php' );
326
+
327
+ $archive = new PclZip( $this->archive_filepath() );
328
+
329
+ // Zip up everything
330
+ if ( ! $this->database_only )
331
+ $archive->add( $this->root, PCLZIP_OPT_REMOVE_PATH, $this->root, PCLZIP_CB_PRE_ADD, 'hmbkp_pclzip_callback' );
332
+
333
+ if ( ! $this->files_only )
334
+ $archive->add( $this->database_dump_filepath(), PCLZIP_OPT_REMOVE_PATH, $this->path );
335
+
336
+ unset( $GLOBALS['_hmbkp_exclude_string'] );
337
+
338
+ }
339
+
340
+ /**
341
+ * Attempt to work out the path to mysqldump
342
+ *
343
+ * @access public
344
+ * @return bool
345
+ */
346
+ public function guess_mysqldump_command_path() {
347
+
348
+ if ( ! $this->shell_exec_available() )
349
+ return '';
350
+
351
+ // List of possible mysqldump locations
352
+ $mysqldump_locations = array(
353
+ 'mysqldump',
354
+ '/usr/local/bin/mysqldump',
355
+ '/usr/local/mysql/bin/mysqldump',
356
+ '/usr/mysql/bin/mysqldump',
357
+ '/usr/bin/mysqldump',
358
+ '/opt/local/lib/mysql6/bin/mysqldump',
359
+ '/opt/local/lib/mysql5/bin/mysqldump',
360
+ '/opt/local/lib/mysql4/bin/mysqldump',
361
+ '\xampp\mysql\bin\mysqldump',
362
+ '\Program Files\xampp\mysql\bin\mysqldump',
363
+ '\Program Files\MySQL\MySQL Server 6.0\bin\mysqldump',
364
+ '\Program Files\MySQL\MySQL Server 5.5\bin\mysqldump',
365
+ '\Program Files\MySQL\MySQL Server 5.4\bin\mysqldump',
366
+ '\Program Files\MySQL\MySQL Server 5.1\bin\mysqldump',
367
+ '\Program Files\MySQL\MySQL Server 5.0\bin\mysqldump',
368
+ '\Program Files\MySQL\MySQL Server 4.1\bin\mysqldump'
369
+ );
370
+
371
+ // Find the one which works
372
+ foreach ( $mysqldump_locations as $location )
373
+ if ( shell_exec( $location . ' --version 2> /dev/null' ) )
374
+ return $location;
375
+
376
+ return '';
377
+
378
+ }
379
+
380
+ /**
381
+ * Attempt to work out the path to the zip command
382
+ *
383
+ * @access public
384
+ * @return bool
385
+ */
386
+ public function guess_zip_command_path() {
387
+
388
+ // Check shell_exec is available and hasn't been explicitly bypassed
389
+ if ( ! $this->shell_exec_available() )
390
+ return '';
391
+
392
+ // List of possible zip locations
393
+ $zip_locations = array(
394
+ 'zip',
395
+ '/usr/bin/zip'
396
+ );
397
+
398
+ // Find the one which works
399
+ foreach ( $zip_locations as $location )
400
+ if ( shell_exec( $location . ' --version 2> /dev/null' ) )
401
+ return $location;
402
+
403
+ return '';
404
+
405
+ }
406
+
407
+ /**
408
+ * Get the array of exclude rules
409
+ *
410
+ * @access public
411
+ * @return array
412
+ */
413
+ public function excludes() {
414
+ return array_filter( array_unique( array_map( 'trim', array_merge( array( trailingslashit( $this->path ) ), (array) $this->excludes ) ) ) );
415
+ }
416
+
417
+ /**
418
+ * Generate the exclude param string for the zip backup
419
+ *
420
+ * Takes the exclude rules and formats them for use with either
421
+ * the shell zip command or pclzip
422
+ *
423
+ * @access public
424
+ * @param string $context. (default: 'zip')
425
+ * @return string
426
+ */
427
+ public function exclude_string( $context = 'zip' ) {
428
+
429
+ // Return a comma separated list by default
430
+ $separator = ', ';
431
+ $wildcard = '';
432
+
433
+ // The zip command
434
+ if ( $context == 'zip' ) {
435
+ $wildcard = '*';
436
+ $separator = ' -x ';
437
+
438
+ // The PCLZIP fallback library
439
+ } elseif ( $context == 'pclzip' ) {
440
+ $wildcard = '([.]*?)';
441
+ $separator = '|';
442
+
443
+ }
444
+
445
+ $excludes = $this->excludes();
446
+
447
+ // Add wildcards to the directories
448
+ foreach( $excludes as $key => &$rule ) {
449
+
450
+ $file = $absolute = $fragment = false;
451
+
452
+ // Files don't end with /
453
+ if ( ! in_array( substr( $rule, -1 ), array( '\\', '/' ) ) )
454
+ $file = true;
455
+
456
+ // If rule starts with a / then treat as absolute path
457
+ elseif ( in_array( substr( $rule, 0, 1 ), array( '\\', '/' ) ) )
458
+ $absolute = true;
459
+
460
+ // Otherwise treat as dir fragment
461
+ else
462
+ $fragment = true;
463
+
464
+ // Strip $this->root and conform
465
+ $rule = str_replace( $this->conform_dir( $this->root ), '', untrailingslashit( $this->conform_dir( $rule ) ) );
466
+
467
+ if ( in_array( substr( $rule, 0, 1 ), array( '\\', '/' ) ) )
468
+ $rule = substr( $rule, 1 );
469
+
470
+ // Escape string for regex
471
+ if ( $context == 'pclzip' )
472
+ $rule = str_replace( '.', '\.', $rule );
473
+
474
+ // Convert any existing wildcards
475
+ if ( $wildcard != '*' && strpos( $rule, '*' ) !== false )
476
+ $rule = str_replace( '*', $wildcard, $rule );
477
+
478
+ // Wrap directory fragments in wildcards for zip
479
+ if ( $context == 'zip' && $fragment )
480
+ $rule = $wildcard . $rule . $wildcard;
481
+
482
+ // Add a wildcard to the end of absolute url for zips
483
+ if ( $context == 'zip' && $absolute )
484
+ $rule .= $wildcard;
485
+
486
+ // Add and end carrot to files for pclzip
487
+ if ( $file && $context == 'pclzip' )
488
+ $rule .= '$';
489
+
490
+ // Add a start carrot to absolute urls for pclzip
491
+ if ( $absolute && $context == 'pclzip' )
492
+ $rule = '^' . $rule;
493
+
494
+ }
495
+
496
+ // Escape shell args for zip command
497
+ if ( $context == 'zip' )
498
+ $excludes = array_map( 'escapeshellarg', $excludes );
499
+
500
+
501
+ return implode( $separator, $excludes );
502
+
503
+ }
504
+
505
+ /**
506
+ * Check whether safe mode if active or not
507
+ *
508
+ * @access private
509
+ * @return bool
510
+ */
511
+ public function is_safe_mode_active() {
512
+
513
+ if ( $safe_mode = ini_get( 'safe_mode' ) && strtolower( $safe_mode ) != 'off' )
514
+ return true;
515
+
516
+ return false;
517
+
518
+ }
519
+
520
+ /**
521
+ * Check whether shell_exec has been disabled.
522
+ *
523
+ * @access private
524
+ * @return bool
525
+ */
526
+ private function shell_exec_available() {
527
+
528
+ // Are we in Safe Mode
529
+ if ( $this->is_safe_mode_active() )
530
+ return false;
531
+
532
+ // Is shell_exec disabled?
533
+ if ( in_array( 'shell_exec', array_map( 'trim', explode( ',', ini_get( 'disable_functions' ) ) ) ) )
534
+ return false;
535
+
536
+ return true;
537
+
538
+ }
539
+
540
+ /**
541
+ * Sanitize a directory path
542
+ *
543
+ * @access private
544
+ * @param string $dir
545
+ * @param bool $rel. (default: false)
546
+ * @return string $dir
547
+ */
548
+ public function conform_dir( $dir, $recursive = false ) {
549
+
550
+ // Replace single forward slash (looks like double slash because we have to escape it)
551
+ $dir = str_replace( '\\', '/', $dir );
552
+ $dir = str_replace( '//', '/', $dir );
553
+
554
+ // Remove the trailing slash
555
+ $dir = untrailingslashit( $dir );
556
+
557
+ // Carry on until completely normalized
558
+ if ( ! $recursive && self::conform_dir( $dir, true ) != $dir )
559
+ return self::conform_dir( $dir );
560
+
561
+ return $dir;
562
+ }
563
+
564
+ /**
565
+ * Add backquotes to tables and db-names inSQL queries. Taken from phpMyAdmin.
566
+ *
567
+ * @access private
568
+ * @param mixed $a_name
569
+ */
570
+ private function sql_backquote( $a_name ) {
571
+
572
+ if ( ! empty( $a_name ) && $a_name != '*' ) {
573
+
574
+ if ( is_array( $a_name ) ) {
575
+
576
+ $result = array();
577
+
578
+ reset( $a_name );
579
+
580
+ while ( list( $key, $val ) = each( $a_name ) )
581
+ $result[$key] = '`' . $val . '`';
582
+
583
+ return $result;
584
+
585
+ } else {
586
+
587
+ return '`' . $a_name . '`';
588
+
589
+ }
590
+
591
+ } else {
592
+
593
+ return $a_name;
594
+
595
+ }
596
+
597
+ }
598
+
599
+ /**
600
+ * Reads the Database table in $table and creates
601
+ * SQL Statements for recreating structure and data
602
+ * Taken partially from phpMyAdmin and partially from
603
+ * Alain Wolf, Zurich - Switzerland
604
+ * Website: http://restkultur.ch/personal/wolf/scripts/db_backup/
605
+ *
606
+ * @access private
607
+ * @param string $sql_file
608
+ * @param string $table
609
+ */
610
+ private function make_sql( $sql_file, $table ) {
611
+
612
+ // Add SQL statement to drop existing table
613
+ $sql_file = "\n";
614
+ $sql_file .= "\n";
615
+ $sql_file .= "#\n";
616
+ $sql_file .= "# Delete any existing table " . $this->sql_backquote( $table ) . "\n";
617
+ $sql_file .= "#\n";
618
+ $sql_file .= "\n";
619
+ $sql_file .= "DROP TABLE IF EXISTS " . $this->sql_backquote( $table ) . ";\n";
620
+
621
+ /* Table Structure */
622
+
623
+ // Comment in SQL-file
624
+ $sql_file .= "\n";
625
+ $sql_file .= "\n";
626
+ $sql_file .= "#\n";
627
+ $sql_file .= "# Table structure of table " . $this->sql_backquote( $table ) . "\n";
628
+ $sql_file .= "#\n";
629
+ $sql_file .= "\n";
630
+
631
+ // Get table structure
632
+ $query = 'SHOW CREATE TABLE ' . $this->sql_backquote( $table );
633
+ $result = mysql_query( $query, $this->db );
634
+
635
+ if ( $result ) {
636
+
637
+ if ( mysql_num_rows( $result ) > 0 ) {
638
+ $sql_create_arr = mysql_fetch_array( $result );
639
+ $sql_file .= $sql_create_arr[1];
640
+ }
641
+
642
+ mysql_free_result( $result );
643
+ $sql_file .= ' ;';
644
+
645
+ }
646
+
647
+ /* Table Contents */
648
+
649
+ // Get table contents
650
+ $query = 'SELECT * FROM ' . $this->sql_backquote( $table );
651
+ $result = mysql_query( $query, $this->db );
652
+
653
+ if ( $result ) {
654
+ $fields_cnt = mysql_num_fields( $result );
655
+ $rows_cnt = mysql_num_rows( $result );
656
+ }
657
+
658
+ // Comment in SQL-file
659
+ $sql_file .= "\n";
660
+ $sql_file .= "\n";
661
+ $sql_file .= "#\n";
662
+ $sql_file .= "# Data contents of table " . $table . " (" . $rows_cnt . " records)\n";
663
+ $sql_file .= "#\n";
664
+
665
+ // Checks whether the field is an integer or not
666
+ for ( $j = 0; $j < $fields_cnt; $j++ ) {
667
+ $field_set[$j] = $this->sql_backquote( mysql_field_name( $result, $j ) );
668
+ $type = mysql_field_type( $result, $j );
669
+
670
+ if ( $type == 'tinyint' || $type == 'smallint' || $type == 'mediumint' || $type == 'int' || $type == 'bigint' || $type == 'timestamp')
671
+ $field_num[$j] = true;
672
+ else
673
+ $field_num[$j] = false;
674
+
675
+ }
676
+
677
+ // Sets the scheme
678
+ $entries = 'INSERT INTO ' . $this->sql_backquote( $table ) . ' VALUES (';
679
+ $search = array( '\x00', '\x0a', '\x0d', '\x1a' ); //\x08\\x09, not required
680
+ $replace = array( '\0', '\n', '\r', '\Z' );
681
+ $current_row = 0;
682
+ $batch_write = 0;
683
+
684
+ while ( $row = mysql_fetch_row( $result ) ) {
685
+
686
+ $current_row++;
687
+
688
+ // build the statement
689
+ for ( $j = 0; $j < $fields_cnt; $j++ ) {
690
+
691
+ if ( ! isset($row[$j] ) ) {
692
+ $values[] = 'NULL';
693
+
694
+ } elseif ( $row[$j] == '0' || $row[$j] != '' ) {
695
+
696
+ // a number
697
+ if ( $field_num[$j] )
698
+ $values[] = $row[$j];
699
+
700
+ else
701
+ $values[] = "'" . str_replace( $search, $replace, $this->sql_addslashes( $row[$j] ) ) . "'";
702
+
703
+ } else {
704
+ $values[] = "''";
705
+
706
+ }
707
+
708
+ }
709
+
710
+ $sql_file .= " \n" . $entries . implode( ', ', $values ) . ") ;";
711
+
712
+ // write the rows in batches of 100
713
+ if ( $batch_write == 100 ) {
714
+ $batch_write = 0;
715
+ $this->write_sql( $sql_file );
716
+ $sql_file = '';
717
+ }
718
+
719
+ $batch_write++;
720
+
721
+ unset( $values );
722
+
723
+ }
724
+
725
+ mysql_free_result( $result );
726
+
727
+ // Create footer/closing comment in SQL-file
728
+ $sql_file .= "\n";
729
+ $sql_file .= "#\n";
730
+ $sql_file .= "# End of data contents of table " . $table . "\n";
731
+ $sql_file .= "# --------------------------------------------------------\n";
732
+ $sql_file .= "\n";
733
+
734
+ $this->write_sql( $sql_file );
735
+
736
+ }
737
+
738
+ /**
739
+ * Better addslashes for SQL queries.
740
+ * Taken from phpMyAdmin.
741
+ *
742
+ * @access private
743
+ * @param string $a_string. (default: '')
744
+ * @param bool $is_like. (default: false)
745
+ */
746
+ private function sql_addslashes( $a_string = '', $is_like = false ) {
747
+
748
+ if ( $is_like )
749
+ $a_string = str_replace( '\\', '\\\\\\\\', $a_string );
750
+
751
+ else
752
+ $a_string = str_replace( '\\', '\\\\', $a_string );
753
+
754
+ $a_string = str_replace( '\'', '\\\'', $a_string );
755
+
756
+ return $a_string;
757
+ }
758
+
759
+ /**
760
+ * Write the SQL file
761
+ *
762
+ * @access private
763
+ * @param string $sql
764
+ */
765
+ private function write_sql( $sql ) {
766
+
767
+ $sqlname = $this->database_dump_filepath();
768
+
769
+ // Actually write the sql file
770
+ if ( is_writable( $sqlname ) || ! file_exists( $sqlname ) ) {
771
+
772
+ if ( ! $handle = fopen( $sqlname, 'a' ) )
773
+ return;
774
+
775
+ if ( ! fwrite( $handle, $sql ) )
776
+ return;
777
+
778
+ fclose( $handle );
779
+
780
+ return true;
781
+
782
+ }
783
+
784
+ }
785
+
786
+ }
787
+
788
+ /**
789
+ * Add file callback, excludes files in the backups directory
790
+ * and sets the database dump to be stored in the root
791
+ * of the zip
792
+ *
793
+ * @access private
794
+ * @param string $event
795
+ * @param array &$file
796
+ * @return bool
797
+ */
798
+ function hmbkp_pclzip_callback( $event, &$file ) {
799
+
800
+ global $_hmbkp_exclude_string;
801
+
802
+ // Don't try to add unreadable files.
803
+ if ( ! is_readable( $file['filename'] ) )
804
+ return false;
805
+
806
+ // Match everything else past the exclude list
807
+ elseif ( preg_match( '(' . $_hmbkp_exclude_string . ')', $file['stored_filename'] ) )
808
+ return false;
809
+
810
+ return true;
811
+
812
+ }
plugin.php CHANGED
@@ -5,7 +5,7 @@ Plugin Name: BackUpWordPress
5
  Plugin URI: http://hmn.md/backupwordpress/
6
  Description: Simple automated backups of your WordPress powered website. Once activated you'll find me under <strong>Tools &rarr; Backups</strong>.
7
  Author: Human Made Limited
8
- Version: 1.4.1
9
  Author URI: http://hmn.md/
10
  */
11
 
@@ -31,6 +31,9 @@ define( 'HMBKP_PLUGIN_PATH', WP_PLUGIN_DIR . '/' . HMBKP_PLUGIN_SLUG );
31
  define( 'HMBKP_PLUGIN_URL', WP_PLUGIN_URL . '/' . HMBKP_PLUGIN_SLUG );
32
  define( 'HMBKP_REQUIRED_WP_VERSION', '3.1' );
33
 
 
 
 
34
  // Don't activate on anything less than PHP 5.2.4
35
  if ( version_compare( phpversion(), '5.2.4', '<' ) ) {
36
 
@@ -53,13 +56,17 @@ if ( version_compare( get_bloginfo('version'), HMBKP_REQUIRED_WP_VERSION, '<' )
53
 
54
  }
55
 
56
- // Load the admin actions file
 
 
 
 
57
  function hmbkp_actions() {
58
 
59
  $plugin_data = get_plugin_data( __FILE__ );
60
 
61
  define( 'HMBKP_VERSION', $plugin_data['Version'] );
62
-
63
  load_plugin_textdomain( 'hmbkp', false, HMBKP_PLUGIN_SLUG . '/languages/' );
64
 
65
  // Fire the update action
@@ -69,10 +76,10 @@ function hmbkp_actions() {
69
  require_once( HMBKP_PLUGIN_PATH . '/admin.actions.php' );
70
 
71
  // Load admin css and js
72
- if ( isset( $_GET['page'] ) && $_GET['page'] == HMBKP_PLUGIN_SLUG ) :
73
  wp_enqueue_script( 'hmbkp', HMBKP_PLUGIN_URL . '/assets/hmbkp.js' );
74
  wp_enqueue_style( 'hmbkp', HMBKP_PLUGIN_URL . '/assets/hmbkp.css' );
75
- endif;
76
 
77
  // Handle any advanced option changes
78
  hmbkp_constant_changes();
@@ -80,17 +87,42 @@ function hmbkp_actions() {
80
  }
81
  add_action( 'admin_init', 'hmbkp_actions' );
82
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
83
  // Load the admin menu
84
  require_once( HMBKP_PLUGIN_PATH . '/admin.menus.php' );
85
 
 
 
 
86
  // Load the core functions
 
87
  require_once( HMBKP_PLUGIN_PATH . '/functions/core.functions.php' );
88
  require_once( HMBKP_PLUGIN_PATH . '/functions/interface.functions.php' );
89
  require_once( HMBKP_PLUGIN_PATH . '/functions/backup.functions.php' );
90
- require_once( HMBKP_PLUGIN_PATH . '/functions/backup.mysql.functions.php' );
91
- require_once( HMBKP_PLUGIN_PATH . '/functions/backup.files.functions.php' );
92
- require_once( HMBKP_PLUGIN_PATH . '/functions/backup.mysql.fallback.functions.php' );
93
- require_once( HMBKP_PLUGIN_PATH . '/functions/backup.files.fallback.functions.php' );
94
 
95
  // Plugin activation and deactivation
96
  add_action( 'activate_' . HMBKP_PLUGIN_SLUG . '/plugin.php', 'hmbkp_activate' );
5
  Plugin URI: http://hmn.md/backupwordpress/
6
  Description: Simple automated backups of your WordPress powered website. Once activated you'll find me under <strong>Tools &rarr; Backups</strong>.
7
  Author: Human Made Limited
8
+ Version: 1.5
9
  Author URI: http://hmn.md/
10
  */
11
 
31
  define( 'HMBKP_PLUGIN_URL', WP_PLUGIN_URL . '/' . HMBKP_PLUGIN_SLUG );
32
  define( 'HMBKP_REQUIRED_WP_VERSION', '3.1' );
33
 
34
+ if ( ! defined( 'WP_MAX_MEMORY_LIMIT' ) )
35
+ define( 'WP_MAX_MEMORY_LIMIT', '256M' );
36
+
37
  // Don't activate on anything less than PHP 5.2.4
38
  if ( version_compare( phpversion(), '5.2.4', '<' ) ) {
39
 
56
 
57
  }
58
 
59
+ /**
60
+ * Plugin setup
61
+ *
62
+ * @return null
63
+ */
64
  function hmbkp_actions() {
65
 
66
  $plugin_data = get_plugin_data( __FILE__ );
67
 
68
  define( 'HMBKP_VERSION', $plugin_data['Version'] );
69
+
70
  load_plugin_textdomain( 'hmbkp', false, HMBKP_PLUGIN_SLUG . '/languages/' );
71
 
72
  // Fire the update action
76
  require_once( HMBKP_PLUGIN_PATH . '/admin.actions.php' );
77
 
78
  // Load admin css and js
79
+ if ( isset( $_GET['page'] ) && $_GET['page'] == HMBKP_PLUGIN_SLUG ) {
80
  wp_enqueue_script( 'hmbkp', HMBKP_PLUGIN_URL . '/assets/hmbkp.js' );
81
  wp_enqueue_style( 'hmbkp', HMBKP_PLUGIN_URL . '/assets/hmbkp.css' );
82
+ }
83
 
84
  // Handle any advanced option changes
85
  hmbkp_constant_changes();
87
  }
88
  add_action( 'admin_init', 'hmbkp_actions' );
89
 
90
+ /**
91
+ * Setup the HM_Backup class
92
+ *
93
+ * @return null
94
+ */
95
+ function hmbkp_setup_hm_backup() {
96
+
97
+ $hm_backup = HM_Backup::get_instance();
98
+
99
+ $hm_backup->path = hmbkp_path();
100
+ $hm_backup->root = ABSPATH;
101
+ $hm_backup->files_only = hmbkp_get_files_only();
102
+ $hm_backup->database_only = hmbkp_get_database_only();
103
+
104
+ if ( defined( 'HMBKP_MYSQLDUMP_PATH' ) )
105
+ $hm_backup->mysql_command_path = HMBKP_MYSQLDUMP_PATH;
106
+
107
+ if ( defined( 'HMBKP_ZIP_PATH' ) )
108
+ $hm_backup->zip_command_path = HMBKP_ZIP_PATH;
109
+
110
+ $hm_backup->excludes = hmbkp_valid_custom_excludes();
111
+
112
+ }
113
+ add_action( 'init', 'hmbkp_setup_hm_backup' );
114
+
115
  // Load the admin menu
116
  require_once( HMBKP_PLUGIN_PATH . '/admin.menus.php' );
117
 
118
+ // Load hm-backup
119
+ require_once( HMBKP_PLUGIN_PATH . '/hm-backup/hm-backup.php' );
120
+
121
  // Load the core functions
122
+ require_once( HMBKP_PLUGIN_PATH . '/functions/backup.actions.php' );
123
  require_once( HMBKP_PLUGIN_PATH . '/functions/core.functions.php' );
124
  require_once( HMBKP_PLUGIN_PATH . '/functions/interface.functions.php' );
125
  require_once( HMBKP_PLUGIN_PATH . '/functions/backup.functions.php' );
 
 
 
 
126
 
127
  // Plugin activation and deactivation
128
  add_action( 'activate_' . HMBKP_PLUGIN_SLUG . '/plugin.php', 'hmbkp_activate' );
readme.txt CHANGED
@@ -3,13 +3,13 @@ Contributors: humanmade, joehoyle, mattheu, tcrsavage, willmot
3
  Tags: back up, backup, backups, database, zip, db, files, archive, humanmade
4
  Requires at least: 3.1
5
  Tested up to: 3.2.1
6
- Stable tag: 1.4.1
7
 
8
  Simple automated back ups of your WordPress powered website.
9
 
10
  == Description ==
11
 
12
- BackUpWordPress will back up your entire site including your database and all your files once every day. It has several advanced options for power users.
13
 
14
  = Features =
15
 
@@ -19,9 +19,9 @@ BackUpWordPress will back up your entire site including your database and all yo
19
  * Option to have each backup file emailed to you.
20
  * Works on Linux & Windows Server.
21
  * Exclude files and folders from your back ups.
22
- * Control advanced options by defining any of the optional `Constants`.
23
  * Good support should you need help.
24
- * Spanish & Russian translations.
25
 
26
  = Help develop this plugin =
27
 
@@ -35,7 +35,7 @@ We'd also love help translating the plugin into more languages, if you can help
35
  2. Activate the plugin.
36
  3. Sit back and relax safe in the knowledge that your whole site will be backed up every day.
37
 
38
- The plugin will try to use the `mysqldump` and `zip` commands via shell if they are available, using these will greatly improve the time it takes to back up your site. If you know about such things then you can point the plugin in the right direction by defining `HMBKP_ZIP_PATH` and `HMBKP_MYSQLDUMP_PATH` in your `wp-config.php`.
39
 
40
  == Frequently Asked Questions ==
41
 
@@ -53,10 +53,29 @@ You need to download the latest backup file either by clicking download on the b
53
 
54
  No.
55
 
56
- **How many backups are stored by default**
57
 
58
  BackUpWordPress stores the last 10 backups by default.
59
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
60
  **Further Support & Feedbask**
61
 
62
  General support questions should be posted in the <a href="http://wordpress.org/tags/backupwordpress?forum_id=10">WordPress support forums, tagged with backupwordpress.</a>
@@ -71,6 +90,19 @@ You can also tweet <a href="http://twitter.com/humanmadeltd">@humanmadeltd</a> o
71
 
72
  == Changelog ==
73
 
 
 
 
 
 
 
 
 
 
 
 
 
 
74
  #### 1.4.1
75
 
76
  * 1.4 was incorrectly marked as beta.
3
  Tags: back up, backup, backups, database, zip, db, files, archive, humanmade
4
  Requires at least: 3.1
5
  Tested up to: 3.2.1
6
+ Stable tag: 1.5
7
 
8
  Simple automated back ups of your WordPress powered website.
9
 
10
  == Description ==
11
 
12
+ BackUpWordPress will back up your entire site including your database and all your files once every day.
13
 
14
  = Features =
15
 
19
  * Option to have each backup file emailed to you.
20
  * Works on Linux & Windows Server.
21
  * Exclude files and folders from your back ups.
22
+ * Control advanced settings by defining any of the optional `Constants`.
23
  * Good support should you need help.
24
+ * (Partial) Spanish & Russian translations.
25
 
26
  = Help develop this plugin =
27
 
35
  2. Activate the plugin.
36
  3. Sit back and relax safe in the knowledge that your whole site will be backed up every day.
37
 
38
+ The plugin will try to use the `mysqldump` and `zip` commands via shell if they are available, using these will greatly improve the time it takes to back up your site.
39
 
40
  == Frequently Asked Questions ==
41
 
53
 
54
  No.
55
 
56
+ **How many backups are stored by default?**
57
 
58
  BackUpWordPress stores the last 10 backups by default.
59
 
60
+ **How long should a backup take?**
61
+
62
+ Unless your site is very large (many gigabytes) it should only take a few minutes to perform a back up, if your back up has been running for longer than an hour it's safe to assume that something has gone wrong, try de-activating and re-activating the plugin, if it keeps happening, contact support.
63
+
64
+ **What do I do if I get the wp-cron error message**
65
+
66
+ The issue is that your `wp-cron.php` is not returning a `200` response when hit with a http request originating from your own server, it could be several things, most of the time it's an issue with the server / site and not with BackUpWordPress.
67
+
68
+ Some things you can test are.
69
+
70
+ * Are scheduled posts working? (They use wp-cron too).
71
+ * Are you hosted on Heart Internet? (wp-cron is known not to work with them).
72
+ * If you click manual backup does it work?
73
+ * Try adding `define( 'HMBKP_DISABLE_MANUAL_BACKUP_CRON', true );` to your `wp-config.php`, does your manual backup work then?
74
+ * Try adding `define( 'ALTERNATE_WP_CRON', true ); to your `wp-config.php`, do backups (manual and automatic) work?
75
+ * Is your site private (I.E. is it behind some kind of authentication, maintenance plugin, .htaccess) if so wp-cron won't work until you remove it, if you are and you temporarily remove the authentication, do backups start working?
76
+
77
+ If you have tried all these then feel free to contact support.
78
+
79
  **Further Support & Feedbask**
80
 
81
  General support questions should be posted in the <a href="http://wordpress.org/tags/backupwordpress?forum_id=10">WordPress support forums, tagged with backupwordpress.</a>
90
 
91
  == Changelog ==
92
 
93
+ #### 1.5
94
+
95
+ * Re-written core backup engine should be more robust especially in edge case scenarios.
96
+ * 48 unit tests for the core backup engine, yay for unit tests.
97
+ * Remove some extraneous status information from the admin interface.
98
+ * Rename Advanced Options to Settings
99
+ * New `Constant` `HMBKP_CAPABILITY` to allow the default `add_menu_page` capability to be changed.
100
+ * Suppress possible filemtime warnings in some edge cases.
101
+ * 3.3 compatability.
102
+ * Set proper charset of MySQL backup, props valericus.
103
+ * Fix some inconsistencies between the estimated backup size and actual backup size when excluding files.
104
+ *
105
+
106
  #### 1.4.1
107
 
108
  * 1.4 was incorrectly marked as beta.