BackUpWordPress - Version 1.5.1

Version Description

Download this release

Release Info

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

Code changes from version 1.5 to 1.5.1

admin.menus.php CHANGED
@@ -49,13 +49,12 @@ 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' );
@@ -65,8 +64,8 @@ function hmbkp_contextual_help() {
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>' .
49
 
50
  require_once( ABSPATH . 'wp-admin/includes/plugin-install.php' );
51
  $plugin = plugins_api( 'plugin_information', array( 'slug' => 'backupwordpress' ) );
52
+
53
+ $warning = '';
54
 
55
  // Check if help is for the right version.
56
+ if ( ! empty( $plugin->version ) && version_compare( HMBKP_VERSION, $plugin->version, '=' ) )
57
+ $warning = 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>' );
 
 
 
58
 
59
  ob_start();
60
  require_once( HMBKP_PLUGIN_PATH . '/admin.constants.php' );
64
  if ( ! method_exists( get_current_screen(), 'add_help_tab' ) )
65
  return;
66
 
67
+ get_current_screen()->add_help_tab( array( 'title' => 'FAQ', 'id' => 'hmbkp_faq', 'content' => $warning . $plugin->sections['faq'] ) );
68
+ get_current_screen()->add_help_tab( array( 'title' => 'Constants', 'id' => 'hmbkp_constants', 'content' => $warning . $constants ) );
69
 
70
  get_current_screen()->set_help_sidebar(
71
  '<p><strong>' . __( 'For more information:' ) . '</strong></p>' .
assets/hmbkp.css CHANGED
@@ -19,4 +19,4 @@ tfoot p { margin: 0; font-weight: normal; }
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; }
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
+ .contextual-help-tabs-wrap .updated { margin: 15px 0 0; }
assets/hmbkp.js CHANGED
@@ -22,8 +22,12 @@ jQuery( document ).ready( function( $ ) {
22
  }
23
  );
24
 
25
- $( '.hmbkp-settings-toggle' ).click( function() {
 
26
  $( '#hmbkp-settings' ).toggle();
 
 
 
27
  } );
28
 
29
  if ( typeof( screenMeta ) != 'undefined' ) {
22
  }
23
  );
24
 
25
+ $( '.hmbkp-settings-toggle' ).click( function( e ) {
26
+
27
  $( '#hmbkp-settings' ).toggle();
28
+
29
+ e.preventDefault();
30
+
31
  } );
32
 
33
  if ( typeof( screenMeta ) != 'undefined' ) {
functions/backup.functions.php CHANGED
@@ -62,6 +62,7 @@ function hmbkp_delete_old_backups() {
62
  /**
63
  * Returns an array of backup files
64
  *
 
65
  * @return array $files
66
  */
67
  function hmbkp_get_backups() {
@@ -73,7 +74,7 @@ function hmbkp_get_backups() {
73
  if ( $handle = opendir( $hmbkp_path ) ) :
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 );
62
  /**
63
  * Returns an array of backup files
64
  *
65
+ * @todo exclude the currently running backup
66
  * @return array $files
67
  */
68
  function hmbkp_get_backups() {
74
  if ( $handle = opendir( $hmbkp_path ) ) :
75
 
76
  while ( false !== ( $file = readdir( $handle ) ) )
77
+ if ( end( explode( '.', $file ) ) == 'zip' )
78
  $files[@filemtime( trailingslashit( $hmbkp_path ) . $file )] = trailingslashit( $hmbkp_path ) . $file;
79
 
80
  closedir( $handle );
functions/core.functions.php CHANGED
@@ -29,10 +29,7 @@ function hmbkp_deactivate() {
29
  'hmbkp_running',
30
  'hmbkp_status',
31
  'hmbkp_complete',
32
- 'hmbkp_email_error',
33
- 'hmbkp_email_address',
34
- 'hmbkp_schedule_frequency',
35
- 'hmbkp_excludes'
36
  );
37
 
38
  foreach ( $options as $option )
@@ -233,46 +230,6 @@ function hmbkp_send_file( $path ) {
233
  return ( connection_status() == 0 ) and !connection_aborted();
234
  }
235
 
236
- /**
237
- * Takes a directory and returns an array of files.
238
- * Does traverse sub-directories
239
- *
240
- * @param string $dir
241
- * @param array $files. (default: array())
242
- * @return arrat $files
243
- */
244
- function hmbkp_ls( $dir, $files = array() ) {
245
-
246
- if ( ! is_readable( $dir ) )
247
- return $files;
248
-
249
- $d = opendir( $dir );
250
-
251
- // Get excluded files & directories.
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;
259
-
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;
267
-
268
- if ( is_dir( $file ) )
269
- $files = hmbkp_ls( $file, $files );
270
-
271
- endwhile;
272
-
273
- return $files;
274
- }
275
-
276
  /**
277
  * Recursively delete a directory including
278
  * all the files and sub-directories.
@@ -343,7 +300,7 @@ function hmbkp_calculate() {
343
  $filesize = 0;
344
 
345
  // Don't include database if files only
346
- if ( ! hmbkp_get_files_only() ) :
347
 
348
  global $wpdb;
349
 
@@ -352,17 +309,32 @@ function hmbkp_calculate() {
352
  foreach ( $res as $r )
353
  $filesize += (float) $r['Data_length'];
354
 
355
- endif;
356
 
357
- if ( ! hmbkp_get_database_only() ) :
358
 
359
  // Get rid of any cached filesizes
360
  clearstatcache();
361
 
362
- foreach ( hmbkp_ls( ABSPATH ) as $f )
363
- $filesize += (float) @filesize( $f );
364
 
365
- endif;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
366
 
367
  // Cache in a transient for a week
368
  set_transient( 'hmbkp_estimated_filesize', $filesize, 604800 );
29
  'hmbkp_running',
30
  'hmbkp_status',
31
  'hmbkp_complete',
32
+ 'hmbkp_email_error'
 
 
 
33
  );
34
 
35
  foreach ( $options as $option )
230
  return ( connection_status() == 0 ) and !connection_aborted();
231
  }
232
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
233
  /**
234
  * Recursively delete a directory including
235
  * all the files and sub-directories.
300
  $filesize = 0;
301
 
302
  // Don't include database if files only
303
+ if ( ! hmbkp_get_files_only() ) {
304
 
305
  global $wpdb;
306
 
309
  foreach ( $res as $r )
310
  $filesize += (float) $r['Data_length'];
311
 
312
+ }
313
 
314
+ if ( ! hmbkp_get_database_only() ) {
315
 
316
  // Get rid of any cached filesizes
317
  clearstatcache();
318
 
319
+ $files = new RecursiveIteratorIterator( new RecursiveDirectoryIterator( ABSPATH ), RecursiveIteratorIterator::SELF_FIRST );
 
320
 
321
+ $excludes = hmbkp_exclude_string( 'regex' );
322
+
323
+ foreach ( $files as $file ) {
324
+
325
+ // Skip bad files
326
+ if ( ! is_readable( $file ) || ! file_exists( $file ) || is_link( $file ) )
327
+ continue;
328
+
329
+ // Excludes
330
+ if ( $excludes && preg_match( '(' . $excludes . ')', str_replace( ABSPATH, '', $file ) ) )
331
+ continue;
332
+
333
+ $filesize += (float) @filesize( $file );
334
+
335
+ }
336
+
337
+ }
338
 
339
  // Cache in a transient for a week
340
  set_transient( 'hmbkp_estimated_filesize', $filesize, 604800 );
hm-backup/hm-backup.php CHANGED
@@ -2,6 +2,8 @@
2
 
3
  /**
4
  * Runs the backup process
 
 
5
  */
6
  class HM_Backup {
7
 
@@ -76,15 +78,15 @@ class HM_Backup {
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
  /**
@@ -115,18 +117,14 @@ class HM_Backup {
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
  /**
@@ -210,7 +208,7 @@ class HM_Backup {
210
 
211
  // The database we're dumping
212
  $cmd .= ' ' . escapeshellarg( DB_NAME );
213
-
214
  // Send stdout to null
215
  $cmd .= ' 2> /dev/null';
216
 
@@ -279,21 +277,16 @@ class HM_Backup {
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() ) )
@@ -303,22 +296,91 @@ class HM_Backup {
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
 
@@ -330,9 +392,10 @@ class HM_Backup {
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
  }
@@ -370,7 +433,7 @@ class HM_Backup {
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 '';
@@ -397,23 +460,13 @@ class HM_Backup {
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
  *
@@ -435,16 +488,16 @@ class HM_Backup {
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;
@@ -464,31 +517,32 @@ class HM_Backup {
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
  }
@@ -496,7 +550,6 @@ class HM_Backup {
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
 
@@ -553,7 +606,7 @@ class HM_Backup {
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 );
@@ -800,11 +853,11 @@ function hmbkp_pclzip_callback( $event, &$file ) {
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;
2
 
3
  /**
4
  * Runs the backup process
5
+ *
6
+ * @version 1.2
7
  */
8
  class HM_Backup {
9
 
78
  * @access public
79
  */
80
  public $root;
81
+
82
  /**
83
  * Holds the current db connection
84
+ *
85
  * @var resource
86
  * @access private
87
  */
88
  private $db;
89
+
90
  static $instance;
91
 
92
  /**
117
  $this->files_only = false;
118
 
119
  }
120
+
121
  public static function get_instance() {
122
+
123
  if ( empty( self::$instance ) )
124
  self::$instance = new HM_Backup();
125
+
126
  return self::$instance;
127
+
 
 
 
 
128
  }
129
 
130
  /**
208
 
209
  // The database we're dumping
210
  $cmd .= ' ' . escapeshellarg( DB_NAME );
211
+
212
  // Send stdout to null
213
  $cmd .= ' 2> /dev/null';
214
 
277
  do_action( 'hmbkp_archive_started' );
278
 
279
  // Do we have the path to the zip command
280
+ if ( $this->zip_command_path )
281
+ $this->zip();
282
 
283
+ // If not or if the shell zip failed then use ZipArchive
284
+ if ( ! file_exists( $this->archive_filepath() ) && class_exists( 'ZipArchive' ) && empty( $this->skip_zip_archive ) )
285
+ $this->zip_archive();
286
 
287
+ // If ZipArchive is unavailable or one of the above failed
 
 
 
 
 
 
288
  if ( ! file_exists( $this->archive_filepath() ) )
289
+ $this->pcl_zip();
290
 
291
  // Delete the database dump file
292
  if ( file_exists( $this->database_dump_filepath() ) )
296
 
297
  }
298
 
299
+ public function zip() {
300
+
301
+ // Zip up $this->root with excludes
302
+ if ( ! $this->database_only && $this->exclude_string( 'zip' ) )
303
+ shell_exec( 'cd ' . escapeshellarg( $this->root ) . ' && ' . escapeshellarg( $this->zip_command_path ) . ' -rq ' . escapeshellarg( $this->archive_filepath() ) . ' ./' . ' -x ' . $this->exclude_string( 'zip' ) . ' 2> /dev/null' );
304
+
305
+ // Zip up $this->root
306
+ elseif ( ! $this->database_only )
307
+ shell_exec( 'cd ' . escapeshellarg( $this->root ) . ' && ' . escapeshellarg( $this->zip_command_path ) . ' -rq ' . escapeshellarg( $this->archive_filepath() ) . ' ./' . ' 2> /dev/null' );
308
+
309
+ // Add the database dump to the archive
310
+ if ( ! $this->files_only )
311
+ shell_exec( 'cd ' . escapeshellarg( $this->path ) . ' && ' . escapeshellarg( $this->zip_command_path ) . ' -uq ' . escapeshellarg( $this->archive_filepath() ) . ' ' . escapeshellarg( $this->database_dump_filename ) . ' 2> /dev/null' );
312
+
313
+ }
314
+
315
  /**
316
  * Fallback for creating zip archives if zip command is
317
  * unnavailable.
318
  *
319
+ * @access public
320
+ * @param string $path
321
+ */
322
+ public function zip_archive() {
323
+
324
+ $zip = new ZipArchive();
325
+
326
+ if ( ! class_exists( 'ZipArchive' ) || ! $zip->open( $this->archive_filepath(), ZIPARCHIVE::CREATE ) )
327
+ return;
328
+
329
+ if ( ! $this->database_only ) {
330
+
331
+ $files = new RecursiveIteratorIterator( new RecursiveDirectoryIterator( $this->root ), RecursiveIteratorIterator::SELF_FIRST );
332
+
333
+ $files_added = 0;
334
+
335
+ $excludes = $this->exclude_string( 'regex' );
336
+
337
+ foreach ( $files as $file ) {
338
+
339
+ // Skip bad files
340
+ if ( ! is_readable( $file ) || ! file_exists( $file ) || is_link( $file ) )
341
+ continue;
342
+
343
+ // Excludes
344
+ if ( $excludes && preg_match( '(' . $excludes . ')', str_replace( $this->root, '', $this->conform_dir( $file ) ) ) )
345
+ continue;
346
+
347
+ if ( is_dir( $file ) )
348
+ $zip->addEmptyDir( str_replace( trailingslashit( $this->root ), '', trailingslashit( $file ) ) );
349
+
350
+ elseif ( is_file( $file ) )
351
+ $zip->addFile( $file, str_replace( trailingslashit( $this->root ), '', $file ) );
352
+
353
+ if ( ++$files_added % 500 === 0 )
354
+ if ( ! $zip->close() || ! $zip->open( $this->archive_filepath(), ZIPARCHIVE::CREATE ) )
355
+ return;
356
+
357
+ }
358
+
359
+ }
360
+
361
+ // Add the database
362
+ if ( ! $this->files_only )
363
+ $zip->addFile( $this->database_dump_filepath(), $this->database_dump_filename );
364
+
365
+ $zip->close();
366
+
367
+ }
368
+
369
+ /**
370
+ * Fallback for creating zip archives if zip command and ZipArchive are
371
+ * unnavailable.
372
+ *
373
+ * Uses the PclZip library that ships with WordPress
374
  *
 
375
  * @access public
376
  * @param string $path
377
  */
378
+ public function pcl_zip() {
379
+
380
  global $_hmbkp_exclude_string;
381
+
382
+ $_hmbkp_exclude_string = $this->exclude_string( 'regex' );
383
+
384
  if ( ! defined( 'PCLZIP_TEMPORARY_DIR' ) )
385
  define( 'PCLZIP_TEMPORARY_DIR', $this->path );
386
 
392
  if ( ! $this->database_only )
393
  $archive->add( $this->root, PCLZIP_OPT_REMOVE_PATH, $this->root, PCLZIP_CB_PRE_ADD, 'hmbkp_pclzip_callback' );
394
 
395
+ // Add the database
396
  if ( ! $this->files_only )
397
  $archive->add( $this->database_dump_filepath(), PCLZIP_OPT_REMOVE_PATH, $this->path );
398
+
399
  unset( $GLOBALS['_hmbkp_exclude_string'] );
400
 
401
  }
433
 
434
  // Find the one which works
435
  foreach ( $mysqldump_locations as $location )
436
+ if ( ! shell_exec( 'hash ' . $location . ' 2>&1' ) )
437
  return $location;
438
 
439
  return '';
460
 
461
  // Find the one which works
462
  foreach ( $zip_locations as $location )
463
+ if ( ! shell_exec( 'hash ' . $location . ' 2>&1' ) )
464
  return $location;
465
 
466
  return '';
467
 
468
  }
469
 
 
 
 
 
 
 
 
 
 
 
470
  /**
471
  * Generate the exclude param string for the zip backup
472
  *
488
  $wildcard = '*';
489
  $separator = ' -x ';
490
 
491
+ // The PclZip fallback library
492
+ } elseif ( $context == 'regex' ) {
493
+ $wildcard = '([\s\S]*?)';
494
  $separator = '|';
495
 
496
  }
497
 
498
+ // Sanitize the excludes
499
+ $excludes = array_filter( array_unique( array_map( 'trim', (array) $this->excludes ) ) );
500
 
 
501
  foreach( $excludes as $key => &$rule ) {
502
 
503
  $file = $absolute = $fragment = false;
517
  // Strip $this->root and conform
518
  $rule = str_replace( $this->conform_dir( $this->root ), '', untrailingslashit( $this->conform_dir( $rule ) ) );
519
 
520
+ // Strip the preceeding slash
521
  if ( in_array( substr( $rule, 0, 1 ), array( '\\', '/' ) ) )
522
  $rule = substr( $rule, 1 );
523
 
524
  // Escape string for regex
525
+ if ( $context == 'regex' )
526
  $rule = str_replace( '.', '\.', $rule );
527
 
528
  // Convert any existing wildcards
529
  if ( $wildcard != '*' && strpos( $rule, '*' ) !== false )
530
  $rule = str_replace( '*', $wildcard, $rule );
531
 
532
+ // Wrap directory fragments and files in wildcards for zip
533
+ if ( $context == 'zip' && ( $fragment || $file ) )
534
  $rule = $wildcard . $rule . $wildcard;
535
 
536
  // Add a wildcard to the end of absolute url for zips
537
  if ( $context == 'zip' && $absolute )
538
  $rule .= $wildcard;
539
 
540
+ // Add and end carrot to files for pclzip but only if it doesn't end in a wildcard
541
+ if ( $file && $context == 'regex' )
542
  $rule .= '$';
543
 
544
  // Add a start carrot to absolute urls for pclzip
545
+ if ( $absolute && $context == 'regex' )
546
  $rule = '^' . $rule;
547
 
548
  }
550
  // Escape shell args for zip command
551
  if ( $context == 'zip' )
552
  $excludes = array_map( 'escapeshellarg', $excludes );
 
553
 
554
  return implode( $separator, $excludes );
555
 
606
 
607
  // Remove the trailing slash
608
  $dir = untrailingslashit( $dir );
609
+
610
  // Carry on until completely normalized
611
  if ( ! $recursive && self::conform_dir( $dir, true ) != $dir )
612
  return self::conform_dir( $dir );
853
  global $_hmbkp_exclude_string;
854
 
855
  // Don't try to add unreadable files.
856
+ if ( ! is_readable( $file['filename'] ) || ! file_exists( $file['filename'] ) || is_link( $file['filename'] ) )
857
  return false;
858
 
859
  // Match everything else past the exclude list
860
+ elseif ( $_hmbkp_exclude_string && preg_match( '(' . $_hmbkp_exclude_string . ')', $file['stored_filename'] ) )
861
  return false;
862
 
863
  return true;
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.5
9
  Author URI: http://hmn.md/
10
  */
11
 
@@ -108,6 +108,10 @@ function hmbkp_setup_hm_backup() {
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' );
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.1
9
  Author URI: http://hmn.md/
10
  */
11
 
108
  $hm_backup->zip_command_path = HMBKP_ZIP_PATH;
109
 
110
  $hm_backup->excludes = hmbkp_valid_custom_excludes();
111
+
112
+ // If the backup path is inside ABSPATH then exclude it by default
113
+ if ( strpos( hmbkp_path(), ABSPATH ) === 0 )
114
+ $hm_backup->excludes[] = trailingslashit( str_replace( untrailingslashit( ABSPATH ), '', hmbkp_path() ) );
115
 
116
  }
117
  add_action( 'init', 'hmbkp_setup_hm_backup' );
readme.txt CHANGED
@@ -2,8 +2,8 @@
2
  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.5
7
 
8
  Simple automated back ups of your WordPress powered website.
9
 
@@ -90,6 +90,14 @@ You can also tweet <a href="http://twitter.com/humanmadeltd">@humanmadeltd</a> o
90
 
91
  == Changelog ==
92
 
 
 
 
 
 
 
 
 
93
  #### 1.5
94
 
95
  * Re-written core backup engine should be more robust especially in edge case scenarios.
@@ -101,7 +109,6 @@ You can also tweet <a href="http://twitter.com/humanmadeltd">@humanmadeltd</a> o
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
 
2
  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.3
6
+ Stable tag: 1.5.1
7
 
8
  Simple automated back ups of your WordPress powered website.
9
 
90
 
91
  == Changelog ==
92
 
93
+ #### 1.5.1
94
+
95
+ * Better detection of `zip` command.
96
+ * Don't delete user settings on update / deactivate.
97
+ * Use `ZipArchive` if `zip` is not available, still falls back to `PclZip` if neither `zip` nor `ZipArchive` are installed.
98
+ * Better exclude rule parsing, fixes lots of edge cases, excludes now pass all 52 unit tests.
99
+ * Improved the speed of the backup size calculation.
100
+
101
  #### 1.5
102
 
103
  * Re-written core backup engine should be more robust especially in edge case scenarios.
109
  * 3.3 compatability.
110
  * Set proper charset of MySQL backup, props valericus.
111
  * Fix some inconsistencies between the estimated backup size and actual backup size when excluding files.
 
112
 
113
  #### 1.4.1
114