BackUpWordPress - Version 3.4.4-beta

Version Description

= 3.4 =

  • This version introduces a major refactoring of the code responsible for the core backup engine. We made sure to write unit tests for the new code, and we have tested it on several user's sites. It fixes a lot of old bugs, and Windows users should see major improvements to reliability.

= 3.3.4 =

  • WordPress 4.4 compatibility.

= 3.3.1 =

  • Fixes a bug that would prevent downloading backups since 3.3.0 - please update.

= 3.2.5 =

  • Security fixes related to add_query_arg

= 3.2.1 =

  • Important bug fixes. Please upgrade to this version to avoid incomplete or broken backups.

= 3.1.3 =

  • Fixes backwards compatibility for add-ons and avoids a Fatal Error. Please upgrade straight to this version before upgrading your add-ons.

= 3.0.4 =

  • Fixes a few minor bugs. Immediate update is recommended.

= 3.0.2 =

  • Important: we have dropped support for PHP 5.2, you will not be able to activate BackUpWordPress on a server running PHP versions older than PHP 5.3.29

= 3.0.1 =

  • This is a critical update. Fixes a bug in the core backup library. Please update immediately.
Download this release

Release Info

Developer pauldewouters
Plugin Icon 128x128 BackUpWordPress
Version 3.4.4-beta
Comparing to
See all releases

Code changes from version 3.4.3 to 3.4.4-beta

admin/backups.php CHANGED
@@ -13,18 +13,20 @@ if ( ! empty( $_GET['hmbkp_schedule_id'] ) ) {
13
  $current_schedule = reset( $schedules );
14
  } ?>
15
 
16
- <h2 class="nav-tab-wrapper">
 
17
 
18
- <?php foreach ( $schedules as $schedule ) :
19
- $status = new Backup_Status( $schedule->get_id() ); ?>
20
 
21
- <a class="nav-tab<?php if ( $status->get_status() ) { ?> hmbkp-running<?php } ?><?php if ( $schedule->get_id() === $current_schedule->get_id() ) { ?> nav-tab-active<?php } ?>" <?php if ( $status->get_status() ) { ?>title="<?php echo esc_attr( strip_tags( $status->get_status() ) ); ?>"<?php } ?> href="<?php echo esc_url( add_query_arg( 'hmbkp_schedule_id', $schedule->get_id(), HMBKP_ADMIN_URL ) ); ?> "><?php echo esc_html( translated_schedule_title( $schedule->get_slug(), $schedule->get_name() ) ); ?> <span class="count">(<?php echo esc_html( count( $schedule->get_backups() ) ); ?>)</span></a>
22
 
23
- <?php endforeach; ?>
24
 
25
- <a class="nav-tab<?php if ( ! Schedules::get_instance()->get_schedule( $current_schedule->get_id() ) ) { ?> nav-tab-active<?php } ?>" href="<?php echo esc_url( add_query_arg( array( 'hmbkp_add_schedule' => '1', 'action' => 'hmbkp_edit_schedule', 'hmbkp_schedule_id' => time(), 'hmbkp_panel' => 'hmbkp_edit_schedule_settings' ), HMBKP_ADMIN_URL ) ); ?>"> + <?php _e( 'add schedule', 'backupwordpress' ); ?></a>
26
 
27
- </h2>
 
28
 
29
  <?php // Don't continue if we don't have a schedule
30
  if ( ! $schedule = $current_schedule ) {
13
  $current_schedule = reset( $schedules );
14
  } ?>
15
 
16
+ <div class="wp-filter">
17
+ <ul class="filter-links">
18
 
19
+ <?php foreach ( $schedules as $schedule ) :
20
+ $status = new Backup_Status( $schedule->get_id() ); ?>
21
 
22
+ <li<?php if ( $status->get_status() ) { ?> title="<?php echo esc_attr( strip_tags( $status->get_status() ) ); ?>"<?php } ?>><a href="<?php echo esc_url( add_query_arg( 'hmbkp_schedule_id', $schedule->get_id(), HMBKP_ADMIN_URL ) ); ?>" class="<?php if ( $status->get_status() ) { ?>hmbkp-running<?php } ?> <?php if ( $schedule->get_id() === $current_schedule->get_id() ) { ?>current<?php } ?>"><?php echo esc_html( translated_schedule_title( $schedule->get_slug(), $schedule->get_name() ) ); ?> <span class="count">(<?php echo esc_html( count( $schedule->get_backups() ) ); ?>)</span></a></li>
23
 
24
+ <?php endforeach; ?>
25
 
26
+ <li><a href="<?php echo esc_url( add_query_arg( array( 'hmbkp_add_schedule' => '1', 'action' => 'hmbkp_edit_schedule', 'hmbkp_schedule_id' => time(), 'hmbkp_panel' => 'hmbkp_edit_schedule_settings' ), HMBKP_ADMIN_URL ) ); ?>" class="<?php if ( ! Schedules::get_instance()->get_schedule( $current_schedule->get_id() ) ) { ?> current<?php } ?>"> + <?php _e( 'add schedule', 'backupwordpress' ); ?></a></li>
27
 
28
+ </ul>
29
+ </div>
30
 
31
  <?php // Don't continue if we don't have a schedule
32
  if ( ! $schedule = $current_schedule ) {
assets/hmbkp.css CHANGED
@@ -6,7 +6,7 @@
6
  div#hmbkp-warning, h2.nav-tab-wrapper + div[id^="hmbkp"] { margin: 20px 0 15px; }
7
  h2 + div[id^="hmbkp"] input { max-width: 100%; }
8
 
9
- .nav-tab.hmbkp-running:not(.nav-tab-active):before { width: 20px; height: 20px; margin: 0 10px -4px 0; content: ""; background: transparent url('spinner-2x.gif') no-repeat 0 0; background-size: 20px; display: inline-block; }
10
 
11
  .hmbkp-upsell { margin-top: 40px; padding-top: 16px; border-top: 1px solid #ccc; }
12
  .hmbkp-upsell a { color: #57792b }
@@ -20,7 +20,7 @@ h2 + div[id^="hmbkp"] input { max-width: 100%; }
20
  .hmbkp-upsell .howto { font-weight: normal; display: inline; }
21
  .hmbkp-upsell .hmbkp_hide { float: right; }
22
 
23
- .hmbkp-schedule-sentence { font-size: 16px; font-weight: lighter; margin: 20px 0; background-color: #FBFBFB; padding: 20px; border: 1px solid #e5e5e5; box-shadow: 0 1px 1px rgba( 0,0,0,.04 ); }
24
  .hmbkp-schedule-sentence::before { content: "\2714"; margin-right: 10px; width: 16px; height: 60px; display: block; float: left; }
25
  .hmbkp-schedule-sentence.hmbkp-error:before { content: "\2718"; }
26
  .hmbkp-schedule-sentence.hmbkp-running:before { width: 20px; height: 80px; margin: -1px 10px 0 0; content: ""; background: transparent url('spinner-2x.gif') no-repeat 0 0; background-size: 20px; display: inline-block; }
6
  div#hmbkp-warning, h2.nav-tab-wrapper + div[id^="hmbkp"] { margin: 20px 0 15px; }
7
  h2 + div[id^="hmbkp"] input { max-width: 100%; }
8
 
9
+ li a.hmbkp-running:not(.current):before { width: 20px; height: 20px; margin: -1px 10px -5px 0; content: ""; background: transparent url('spinner-2x.gif') no-repeat 0 0; background-size: 20px; display: inline-block; }
10
 
11
  .hmbkp-upsell { margin-top: 40px; padding-top: 16px; border-top: 1px solid #ccc; }
12
  .hmbkp-upsell a { color: #57792b }
20
  .hmbkp-upsell .howto { font-weight: normal; display: inline; }
21
  .hmbkp-upsell .hmbkp_hide { float: right; }
22
 
23
+ .hmbkp-schedule-sentence { font-size: 16px; font-weight: lighter; margin: 0 0 20px 0; background-color: #FBFBFB; padding: 20px; border: 1px solid #e5e5e5; box-shadow: 0 1px 1px rgba( 0,0,0,.04 ); }
24
  .hmbkp-schedule-sentence::before { content: "\2714"; margin-right: 10px; width: 16px; height: 60px; display: block; float: left; }
25
  .hmbkp-schedule-sentence.hmbkp-error:before { content: "\2718"; }
26
  .hmbkp-schedule-sentence.hmbkp-running:before { width: 20px; height: 80px; margin: -1px 10px 0 0; content: ""; background: transparent url('spinner-2x.gif') no-repeat 0 0; background-size: 20px; display: inline-block; }
assets/hmbkp.js CHANGED
@@ -1,179 +1,207 @@
1
- jQuery( document ).ready( function ( $ ) {
2
  'use strict';
3
- var recurrenceType = $( 'select#hmbkp_schedule_recurrence_type' );
4
- // Don't ever cache ajax requests
5
- $.ajaxSetup( {'cache': false} );
6
 
7
- if ( recurrenceType.length ) {
8
 
9
- hmbkpToggleScheduleFields( recurrenceType.val() );
10
 
11
- $( document ).on( 'change', 'select#hmbkp_schedule_recurrence_type', function () {
12
- hmbkpToggleScheduleFields( $( this ).val() );
13
- } );
14
-
15
- }
16
 
17
- // Show delete confirm message for delete schedule
18
- $( document ).on( 'click', '.hmbkp-schedule-actions .delete-action', function ( e ) {
19
-
20
- if ( ! confirm( hmbkp.delete_schedule ) ) {
21
- e.preventDefault();
22
- }
23
 
24
- } );
25
 
26
- // Show delete confirm message for delete backup
27
- $( document ).on( 'click', '.hmbkp_manage_backups_row .delete-action', function ( e ) {
 
28
 
29
- if ( ! confirm( hmbkp.delete_backup ) ) {
30
- e.preventDefault();
31
  }
32
 
33
- } );
 
34
 
35
- // Show delete confirm message for remove exclude rule
36
- $( document ).on( 'click', '.hmbkp-edit-schedule-excludes-form .delete-action', function ( e ) {
 
37
 
38
- if ( ! confirm( hmbkp.remove_exclude_rule ) ) {
39
- e.preventDefault();
40
- }
41
 
42
- } );
 
43
 
44
- // Test the cron response using ajax
45
- $.post( ajaxurl, {'nonce': hmbkp.nonce, 'action': 'hmbkp_cron_test'},
46
- function ( data ) {
47
- if ( data !== '1' ) {
48
- $( '.wrap > h2' ).after( data );
49
  }
50
- }
51
- );
52
-
53
- // Run a backup
54
- $( document ).on( 'click', '.hmbkp-run', function ( e ) {
55
- wp.heartbeat.interval( 'fast' );
56
- $( this ).closest( '.hmbkp-schedule-sentence' ).addClass( 'hmbkp-running' );
57
 
58
- $( '.hmbkp-error' ).removeClass( 'hmbkp-error' );
59
 
60
- var scheduleId = $( '[data-hmbkp-schedule-id]' ).attr( 'data-hmbkp-schedule-id' );
 
61
 
62
- $.post(
63
- ajaxurl,
64
- {
65
- 'hmbkp_run_schedule_nonce': hmbkp.hmbkp_run_schedule_nonce,
66
- 'action': 'hmbkp_run_schedule',
67
- 'hmbkp_schedule_id': scheduleId
68
  }
69
- );
70
 
71
- e.preventDefault();
72
 
73
- } );
 
 
 
 
 
 
 
74
 
75
- // Send the schedule id with the heartbeat
76
- $( document ).on( 'heartbeat-send', function ( e, data ) {
 
 
77
 
78
- data.hmbkp_schedule_id = $( '[data-hmbkp-schedule-id]' ).attr( 'data-hmbkp-schedule-id' );
79
 
80
- if ( $( '.hmbkp-schedule-sentence.hmbkp-running' ).length ) {
81
- data.hmbkp_is_in_progress = true;
82
- } else {
83
- data.hmbkp_client_request = 'site_size';
84
- }
85
 
86
- } );
 
 
 
 
 
 
 
87
 
88
- // Update schedule status on heartbeat tick
89
- $( document ).on( 'heartbeat-tick', function ( e, data ) {
90
 
91
- // If the schedule has finished then reload the page
92
- if ( data.hmbkp_schedule_status === 0 && ! $( '.hmbkp-error' ).length ) {
93
- location.reload( true );
94
- }
95
 
96
- // If the schedule is still running then update the schedule status
97
- if ( ( data.hmbkp_schedule_status !== 0 ) && ( data.hmbkp_schedule_status !== undefined ) ) {
98
- $( '.hmbkp-status' ).replaceWith( data.hmbkp_schedule_status );
99
- }
100
 
101
- if ( ( data.hmbkp_site_size !== undefined ) && ( $( 'code.calculating' ).length ) ) {
102
- $( 'code.calculating' ).text( data.hmbkp_site_size );
103
- var excludes = $( '.hmbkp-exclude-settings' );
104
- if ( excludes.length ) {
105
- excludes.replaceWith( data.hmbkp_dir_sizes );
106
  }
107
- }
108
 
109
- } );
110
 
111
- // Closing ThickBox Modal Window
112
- $( document ).on( 'click', '.hmbkp-thickbox-close', function ( e ) {
113
 
114
- e.preventDefault();
115
- window.parent.tb_remove();
 
 
116
 
117
- } );
 
 
 
118
 
119
- $( document ).on( 'click', '#hmbkp-warning-backup .notice-dismiss', function(){
120
- $.post(
121
- ajaxurl,
122
- {
123
- 'action': 'hmbkp_dismiss_error'
 
124
  }
125
- );
126
- } )
127
 
128
- } );
129
 
130
- function hmbkpToggleScheduleFields( recurrence ) {
 
131
 
132
- recurrence = (
133
- typeof recurrence !== 'undefined'
134
- ) ? recurrence : 'manually';
135
 
136
- var settingFields = jQuery( '.recurring-setting' );
137
- var scheduleSettingFields = jQuery( '#schedule-start' );
138
- var twiceDailyNote = jQuery( '.twice-js' );
139
 
140
- switch ( recurrence ) {
 
 
 
 
 
 
 
141
 
142
- case 'manually':
143
- settingFields.hide();
144
- break;
145
 
146
- case 'hourly' :
147
- settingFields.hide();
148
- break;
149
 
150
- case 'daily' :
151
- settingFields.hide();
152
- scheduleSettingFields.show();
153
- twiceDailyNote.hide();
154
- break;
155
 
156
- case 'twicedaily' :
157
- settingFields.hide();
158
- scheduleSettingFields.show();
159
- twiceDailyNote.show();
160
- break;
 
 
161
 
162
- case 'weekly' : // fall through
163
- case 'fortnightly' :
164
- settingFields.hide();
165
- jQuery( '#start-day' ).show();
166
- scheduleSettingFields.show();
167
- twiceDailyNote.hide();
168
- break;
169
 
170
- case 'monthly' :
171
- settingFields.hide();
172
- scheduleSettingFields.show();
173
- jQuery( '#start-date' ).show();
174
- twiceDailyNote.hide();
175
- break;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
176
 
177
  }
178
 
179
- }
 
 
 
 
 
 
1
+ var BackUpWordPressAdmin = (function($){
2
  'use strict';
 
 
 
3
 
4
+ var recurrenceType;
5
 
6
+ function init(){
7
 
8
+ recurrenceType = $( 'select#hmbkp_schedule_recurrence_type' );
9
+ // Don't ever cache ajax requests
10
+ $.ajaxSetup( {'cache': false} );
 
 
11
 
12
+ if ( recurrenceType.length ) {
 
 
 
 
 
13
 
14
+ hmbkpToggleScheduleFields( recurrenceType.val() );
15
 
16
+ $( document ).on( 'change', 'select#hmbkp_schedule_recurrence_type', function () {
17
+ hmbkpToggleScheduleFields( $( this ).val() );
18
+ } );
19
 
 
 
20
  }
21
 
22
+ // Show delete confirm message for delete schedule
23
+ $( document ).on( 'click', '.hmbkp-schedule-actions .delete-action', function ( e ) {
24
 
25
+ if ( ! confirm( hmbkp.delete_schedule ) ) {
26
+ e.preventDefault();
27
+ }
28
 
29
+ } );
 
 
30
 
31
+ // Show delete confirm message for delete backup
32
+ $( document ).on( 'click', '.hmbkp_manage_backups_row .delete-action', function ( e ) {
33
 
34
+ if ( ! confirm( hmbkp.delete_backup ) ) {
35
+ e.preventDefault();
 
 
 
36
  }
 
 
 
 
 
 
 
37
 
38
+ } );
39
 
40
+ // Show delete confirm message for remove exclude rule
41
+ $( document ).on( 'click', '.hmbkp-edit-schedule-excludes-form .delete-action', function ( e ) {
42
 
43
+ if ( ! confirm( hmbkp.remove_exclude_rule ) ) {
44
+ e.preventDefault();
 
 
 
 
45
  }
 
46
 
47
+ } );
48
 
49
+ // Test the cron response using ajax
50
+ $.post( ajaxurl, {'nonce': hmbkp.nonce, 'action': 'hmbkp_cron_test'},
51
+ function ( data ) {
52
+ if ( data !== '1' ) {
53
+ $( '.wrap > h2' ).after( data );
54
+ }
55
+ }
56
+ );
57
 
58
+ // Run a backup
59
+ $( document ).on( 'click', '.hmbkp-run', function ( e ) {
60
+ wp.heartbeat.interval( 'fast' );
61
+ $( this ).closest( '.hmbkp-schedule-sentence' ).addClass( 'hmbkp-running' );
62
 
63
+ $( '.hmbkp-error' ).removeClass( 'hmbkp-error' );
64
 
65
+ var scheduleId = $( '[data-hmbkp-schedule-id]' ).attr( 'data-hmbkp-schedule-id' );
 
 
 
 
66
 
67
+ $.post(
68
+ ajaxurl,
69
+ {
70
+ 'hmbkp_run_schedule_nonce': hmbkp.hmbkp_run_schedule_nonce,
71
+ 'action': 'hmbkp_run_schedule',
72
+ 'hmbkp_schedule_id': scheduleId
73
+ }
74
+ );
75
 
76
+ e.preventDefault();
 
77
 
78
+ } );
 
 
 
79
 
80
+ // Send the schedule id with the heartbeat
81
+ $( document ).on( 'heartbeat-send', function ( e, data ) {
82
+
83
+ data.hmbkp_schedule_id = $( '[data-hmbkp-schedule-id]' ).attr( 'data-hmbkp-schedule-id' );
84
 
85
+ if ( $( '.hmbkp-schedule-sentence.hmbkp-running' ).length ) {
86
+ data.hmbkp_is_in_progress = true;
87
+ } else {
88
+ data.hmbkp_client_request = 'site_size';
 
89
  }
 
90
 
91
+ } );
92
 
93
+ // Update schedule status on heartbeat tick
94
+ $( document ).on( 'heartbeat-tick', function ( e, data ) {
95
 
96
+ // If the schedule has finished then reload the page
97
+ if ( data.hmbkp_schedule_status === 0 && ! $( '.hmbkp-error' ).length ) {
98
+ location.reload( true );
99
+ }
100
 
101
+ // If the schedule is still running then update the schedule status
102
+ if ( ( data.hmbkp_schedule_status !== 0 ) && ( data.hmbkp_schedule_status !== undefined ) ) {
103
+ $( '.hmbkp-status' ).replaceWith( data.hmbkp_schedule_status );
104
+ }
105
 
106
+ if ( ( data.hmbkp_site_size !== undefined ) && ( $( 'code.calculating' ).length ) ) {
107
+ $( 'code.calculating' ).text( data.hmbkp_site_size );
108
+ var excludes = $( '.hmbkp-exclude-settings' );
109
+ if ( excludes.length ) {
110
+ excludes.replaceWith( data.hmbkp_dir_sizes );
111
+ }
112
  }
 
 
113
 
114
+ } );
115
 
116
+ // Closing ThickBox Modal Window
117
+ $( document ).on( 'click', '.hmbkp-thickbox-close', function ( e ) {
118
 
119
+ e.preventDefault();
120
+ window.parent.tb_remove();
 
121
 
122
+ } );
 
 
123
 
124
+ $( document ).on( 'click', '#hmbkp-warning-backup .notice-dismiss', function(){
125
+ $.post(
126
+ ajaxurl,
127
+ {
128
+ 'action': 'hmbkp_dismiss_error'
129
+ }
130
+ );
131
+ } );
132
 
133
+ jQuery( document ).one( 'click', '.hmbkp_send_error_via_email', function ( e ) {
 
 
134
 
135
+ e.preventDefault();
 
 
136
 
137
+ jQuery( this ).addClass( 'hmbkp-ajax-loading' ).attr( 'disabled', 'disabled' );
 
 
 
 
138
 
139
+ jQuery.post(
140
+ ajaxurl,
141
+ {'nonce': hmbkp.nonce, 'action': 'hmbkp_email_error', 'hmbkp_error': data},
142
+ function () {
143
+ //jQuery.colorbox.close();
144
+ }
145
+ );
146
 
147
+ } );
148
+ }
 
 
 
 
 
149
 
150
+ function hmbkpToggleScheduleFields( recurrence ) {
151
+
152
+ recurrence = (
153
+ typeof recurrence !== 'undefined'
154
+ ) ? recurrence : 'manually';
155
+
156
+ var settingFields = jQuery( '.recurring-setting' );
157
+ var scheduleSettingFields = jQuery( '#schedule-start' );
158
+ var twiceDailyNote = jQuery( '.twice-js' );
159
+
160
+ switch ( recurrence ) {
161
+
162
+ case 'manually':
163
+ settingFields.hide();
164
+ break;
165
+
166
+ case 'hourly' :
167
+ settingFields.hide();
168
+ break;
169
+
170
+ case 'daily' :
171
+ settingFields.hide();
172
+ scheduleSettingFields.show();
173
+ twiceDailyNote.hide();
174
+ break;
175
+
176
+ case 'twicedaily' :
177
+ settingFields.hide();
178
+ scheduleSettingFields.show();
179
+ twiceDailyNote.show();
180
+ break;
181
+
182
+ case 'weekly' : // fall through
183
+ case 'fortnightly' :
184
+ settingFields.hide();
185
+ jQuery( '#start-day' ).show();
186
+ scheduleSettingFields.show();
187
+ twiceDailyNote.hide();
188
+ break;
189
+
190
+ case 'monthly' :
191
+ settingFields.hide();
192
+ scheduleSettingFields.show();
193
+ jQuery( '#start-date' ).show();
194
+ twiceDailyNote.hide();
195
+ break;
196
+
197
+ }
198
 
199
  }
200
 
201
+ return {
202
+ init: init
203
+ };
204
+
205
+ })(jQuery);
206
+
207
+ jQuery( document ).ready(BackUpWordPressAdmin.init);
assets/hmbkp.min.css CHANGED
@@ -1 +1 @@
1
- .hmbkp-schedule-actions a,.hmbkp-schedule-settings .column-format code{white-space:nowrap}.hmbkp_active td:first-child>code:before{content:"\00a0 \2713 ";font-size:11px}.hmbkp_active{background:#E5F7E8}div#hmbkp-warning,h2.nav-tab-wrapper+div[id^=hmbkp]{margin:20px 0 15px}h2+div[id^=hmbkp] input{max-width:100%}.nav-tab.hmbkp-running:not(.nav-tab-active):before{width:20px;height:20px;margin:0 10px -4px 0;content:"";background:url(spinner-2x.gif) no-repeat;background-size:20px;display:inline-block}.hmbkp-upsell{margin-top:40px;padding-top:16px;border-top:1px solid #ccc}.hmbkp-upsell a{color:#57792b}.hmbkp-upsell a:hover{color:#98c063}.hmbkp-upsell-sep{color:#bbb}.hmbkp-upsell ul{overflow:hidden}.hmbkp-upsell li{float:left;margin:0 20px 20px 0}.hmbkp-upsell img{display:block;margin:0 auto;max-width:120px;min-height:60px}.hmbkp-upsell ul a{display:block;margin-bottom:0;width:120px}.hmbkp-upsell .howto{font-weight:400;display:inline}.hmbkp-upsell .hmbkp_hide{float:right}.hmbkp-schedule-sentence{font-size:16px;font-weight:lighter;margin:20px 0;background-color:#FBFBFB;padding:20px;border:1px solid #e5e5e5;box-shadow:0 1px 1px rgba(0,0,0,.04)}.hmbkp-schedule-sentence::before{content:"\2714";margin-right:10px;width:16px;height:60px;display:block;float:left}.hmbkp-schedule-sentence.hmbkp-error:before{content:"\2718"}.hmbkp-schedule-sentence.hmbkp-running:before{width:20px;height:80px;margin:-1px 10px 0 0;content:"";background:url(spinner-2x.gif) no-repeat;background-size:20px;display:inline-block}.hmbkp-schedule-sentence .hmbkp-status{display:none;font-size:12px;color:#666;margin:2px 0 0 30px}.hmbkp-schedule-sentence.hmbkp-running .hmbkp-status{display:block}.hmbkp-schedule-sentence.hmbkp-running .hmbkp-schedule-actions{display:none}.hmbkp-schedule-sentence :not(a)[title]{border-bottom:1px dotted #CCC;cursor:help}.hmbkp-schedule-sentence .hmbkp-status[title]{border-bottom:none}.hmbkp-schedule-sentence .submit{padding:0}.hmbkp-schedule-sentence .hmbkp-schedule-actions{visibility:visible;font-size:12px;font-weight:400;margin:0 0 0 26px}.hmbkp-schedule-sentence .row-actions{position:static}.hmbkp-schedule-settings{border-top:1px solid #e5e5e5;margin:20px -20px -20px;background-color:#f5f5f5;padding:0 20px 20px}.hmbkp-exclude-settings thead tr:last-child,table.widefat tbody tr:nth-child(odd){background-color:#f9f9f9}.hmbkp-ajax-loading,button.hmbkp-ajax-loading{padding-left:20px;position:relative}.hmbkp-ajax-loading::after{content:"";width:16px;height:16px;background-image:url(spinner-2x.gif);background-size:16px 16px;background-repeat:no-repeat;background-position:0 0;position:absolute;right:-30px;top:5px}.delete-action{color:#a00;-webkit-transition:all .3s ease;transition:all .3s ease}.delete-action:hover .delete-action:focus{color:red;-webkit-transition:all .3s ease;transition:all .3s ease}.strikethrough{text-decoration:line-through}.hmbkp-exclude-settings td:first-child,.hmbkp-exclude-settings th:first-child{width:20px;padding-right:0}.hmbkp-exclude-settings table .button-secondary{line-height:18px;height:20px}thead td{border-bottom:1px solid #e1e1e1}.hmbkp-exclude-settings table .spinner{display:block;float:left;margin:0}.column-filesize code{position:relative}.column-filesize .dashicons-update{display:none;overflow:hidden;position:absolute;width:100%;left:0;text-align:center;background-color:rgba(255,255,255,.8)}.column-filesize .dashicons-update span{display:none}.column-filesize:hover .dashicons-update{display:inline-block}.hmbkp-exclude-settings td span.reason{color:#CCC}.server-info{overflow:auto;max-height:50%;outline:#000 solid 1px}.server-info pre{max-height:100px;overflow-x:hidden}.page-title-action span.dashicons-admin-users{position:relative;display:inline-block;vertical-align:middle;top:-2px}pre{background-color:#eee;padding:10px;white-space:pre;max-height:320px;overflow:auto;word-wrap:normal!important}@media screen and (max-width:768px){.wrap h2{padding:10px 0 0}.hmbkp-schedule-sentence::before{height:80px}h2 .nav-tab{display:block;padding:10px;margin:0}#intercom-info,.hmbkp-exclude-settings tr>:first-child,.hmbkp-schedule-settings thead tr:nth-child(2),.hmbkp-schedule-settings tr :nth-child(4),.hmbkp-schedule-settings tr :nth-child(5){display:none}.hmbkp-schedule-sentence{margin:10px 0;padding:10px}.hmbkp-exclude-settings table{margin:0 -10px;border-left:none;border-right:none;width:calc(100% + 20px)}.hmbkp-schedule-settings{padding:0 10px 10px;margin-left:-10px;margin-right:-10px;margin-bottom:-10px}table.widefat tbody tr:nth-child(even){background-color:#fff}table.widefat tbody tr:nth-child(odd){background-color:#f9f9f9}}
1
+ .hmbkp-schedule-actions a,.hmbkp-schedule-settings .column-format code{white-space:nowrap}.hmbkp_active td:first-child>code:before{content:"\00a0 \2713 ";font-size:11px}.hmbkp_active{background:#E5F7E8}div#hmbkp-warning,h2.nav-tab-wrapper+div[id^=hmbkp]{margin:20px 0 15px}h2+div[id^=hmbkp] input{max-width:100%}li a.hmbkp-running:not(.current):before{width:20px;height:20px;margin:-1px 10px -5px 0;content:"";background:url(spinner-2x.gif) no-repeat;background-size:20px;display:inline-block}.hmbkp-upsell{margin-top:40px;padding-top:16px;border-top:1px solid #ccc}.hmbkp-upsell a{color:#57792b}.hmbkp-upsell a:hover{color:#98c063}.hmbkp-upsell-sep{color:#bbb}.hmbkp-upsell ul{overflow:hidden}.hmbkp-upsell li{float:left;margin:0 20px 20px 0}.hmbkp-upsell img{display:block;margin:0 auto;max-width:120px;min-height:60px}.hmbkp-upsell ul a{display:block;margin-bottom:0;width:120px}.hmbkp-upsell .howto{font-weight:400;display:inline}.hmbkp-upsell .hmbkp_hide{float:right}.hmbkp-schedule-sentence{font-size:16px;font-weight:lighter;margin:0 0 20px;background-color:#FBFBFB;padding:20px;border:1px solid #e5e5e5;box-shadow:0 1px 1px rgba(0,0,0,.04)}.hmbkp-schedule-sentence::before{content:"\2714";margin-right:10px;width:16px;height:60px;display:block;float:left}.hmbkp-schedule-sentence.hmbkp-error:before{content:"\2718"}.hmbkp-schedule-sentence.hmbkp-running:before{width:20px;height:80px;margin:-1px 10px 0 0;content:"";background:url(spinner-2x.gif) no-repeat;background-size:20px;display:inline-block}.hmbkp-schedule-sentence .hmbkp-status{display:none;font-size:12px;color:#666;margin:2px 0 0 30px}.hmbkp-schedule-sentence.hmbkp-running .hmbkp-status{display:block}.hmbkp-schedule-sentence.hmbkp-running .hmbkp-schedule-actions{display:none}.hmbkp-schedule-sentence :not(a)[title]{border-bottom:1px dotted #CCC;cursor:help}.hmbkp-schedule-sentence .hmbkp-status[title]{border-bottom:none}.hmbkp-schedule-sentence .submit{padding:0}.hmbkp-schedule-sentence .hmbkp-schedule-actions{visibility:visible;font-size:12px;font-weight:400;margin:0 0 0 26px}.hmbkp-schedule-sentence .row-actions{position:static}.hmbkp-schedule-settings{border-top:1px solid #e5e5e5;margin:20px -20px -20px;background-color:#f5f5f5;padding:0 20px 20px}.hmbkp-exclude-settings thead tr:last-child,table.widefat tbody tr:nth-child(odd){background-color:#f9f9f9}.hmbkp-ajax-loading,button.hmbkp-ajax-loading{padding-left:20px;position:relative}.hmbkp-ajax-loading::after{content:"";width:16px;height:16px;background-image:url(spinner-2x.gif);background-size:16px 16px;background-repeat:no-repeat;background-position:0 0;position:absolute;right:-30px;top:5px}.delete-action{color:#a00;-webkit-transition:all .3s ease;transition:all .3s ease}.delete-action:hover .delete-action:focus{color:red;-webkit-transition:all .3s ease;transition:all .3s ease}.strikethrough{text-decoration:line-through}.hmbkp-exclude-settings td:first-child,.hmbkp-exclude-settings th:first-child{width:20px;padding-right:0}.hmbkp-exclude-settings table .button-secondary{line-height:18px;height:20px}thead td{border-bottom:1px solid #e1e1e1}.hmbkp-exclude-settings table .spinner{display:block;float:left;margin:0}.column-filesize code{position:relative}.column-filesize .dashicons-update{display:none;overflow:hidden;position:absolute;width:100%;left:0;text-align:center;background-color:rgba(255,255,255,.8)}.column-filesize .dashicons-update span{display:none}.column-filesize:hover .dashicons-update{display:inline-block}.hmbkp-exclude-settings td span.reason{color:#CCC}.server-info{overflow:auto;max-height:50%;outline:#000 solid 1px}.server-info pre{max-height:100px;overflow-x:hidden}.page-title-action span.dashicons-admin-users{position:relative;display:inline-block;vertical-align:middle;top:-2px}pre{background-color:#eee;padding:10px;white-space:pre;max-height:320px;overflow:auto;word-wrap:normal!important}@media screen and (max-width:768px){.wrap h2{padding:10px 0 0}.hmbkp-schedule-sentence::before{height:80px}h2 .nav-tab{display:block;padding:10px;margin:0}#intercom-info,.hmbkp-exclude-settings tr>:first-child,.hmbkp-schedule-settings thead tr:nth-child(2),.hmbkp-schedule-settings tr :nth-child(4),.hmbkp-schedule-settings tr :nth-child(5){display:none}.hmbkp-schedule-sentence{margin:10px 0;padding:10px}.hmbkp-exclude-settings table{margin:0 -10px;border-left:none;border-right:none;width:calc(100% + 20px)}.hmbkp-schedule-settings{padding:0 10px 10px;margin-left:-10px;margin-right:-10px;margin-bottom:-10px}table.widefat tbody tr:nth-child(even){background-color:#fff}table.widefat tbody tr:nth-child(odd){background-color:#f9f9f9}}
assets/hmbkp.min.js CHANGED
@@ -1,24 +1,2 @@
1
- function hmbkpToggleScheduleFields(a){a="undefined"!=typeof a?a:"manually";var b=jQuery(".recurring-setting"),c=jQuery("#schedule-start"),d=jQuery(".twice-js");switch(a){case"manually":b.hide();break;case"hourly":b.hide();break;case"daily":b.hide(),c.show(),d.hide();break;case"twicedaily":b.hide(),c.show(),d.show();break;case"weekly":// fall through
2
- case"fortnightly":b.hide(),jQuery("#start-day").show(),c.show(),d.hide();break;case"monthly":b.hide(),c.show(),jQuery("#start-date").show(),d.hide()}}jQuery(document).ready(function(a){"use strict";var b=a("select#hmbkp_schedule_recurrence_type");
3
- // Don't ever cache ajax requests
4
- a.ajaxSetup({cache:!1}),b.length&&(hmbkpToggleScheduleFields(b.val()),a(document).on("change","select#hmbkp_schedule_recurrence_type",function(){hmbkpToggleScheduleFields(a(this).val())})),
5
- // Show delete confirm message for delete schedule
6
- a(document).on("click",".hmbkp-schedule-actions .delete-action",function(a){confirm(hmbkp.delete_schedule)||a.preventDefault()}),
7
- // Show delete confirm message for delete backup
8
- a(document).on("click",".hmbkp_manage_backups_row .delete-action",function(a){confirm(hmbkp.delete_backup)||a.preventDefault()}),
9
- // Show delete confirm message for remove exclude rule
10
- a(document).on("click",".hmbkp-edit-schedule-excludes-form .delete-action",function(a){confirm(hmbkp.remove_exclude_rule)||a.preventDefault()}),
11
- // Test the cron response using ajax
12
- a.post(ajaxurl,{nonce:hmbkp.nonce,action:"hmbkp_cron_test"},function(b){"1"!==b&&a(".wrap > h2").after(b)}),
13
- // Run a backup
14
- a(document).on("click",".hmbkp-run",function(b){wp.heartbeat.interval("fast"),a(this).closest(".hmbkp-schedule-sentence").addClass("hmbkp-running"),a(".hmbkp-error").removeClass("hmbkp-error");var c=a("[data-hmbkp-schedule-id]").attr("data-hmbkp-schedule-id");a.post(ajaxurl,{hmbkp_run_schedule_nonce:hmbkp.hmbkp_run_schedule_nonce,action:"hmbkp_run_schedule",hmbkp_schedule_id:c}),b.preventDefault()}),
15
- // Send the schedule id with the heartbeat
16
- a(document).on("heartbeat-send",function(b,c){c.hmbkp_schedule_id=a("[data-hmbkp-schedule-id]").attr("data-hmbkp-schedule-id"),a(".hmbkp-schedule-sentence.hmbkp-running").length?c.hmbkp_is_in_progress=!0:c.hmbkp_client_request="site_size"}),
17
- // Update schedule status on heartbeat tick
18
- a(document).on("heartbeat-tick",function(b,c){if(
19
- // If the schedule has finished then reload the page
20
- 0!==c.hmbkp_schedule_status||a(".hmbkp-error").length||location.reload(!0),
21
- // If the schedule is still running then update the schedule status
22
- 0!==c.hmbkp_schedule_status&&void 0!==c.hmbkp_schedule_status&&a(".hmbkp-status").replaceWith(c.hmbkp_schedule_status),void 0!==c.hmbkp_site_size&&a("code.calculating").length){a("code.calculating").text(c.hmbkp_site_size);var d=a(".hmbkp-exclude-settings");d.length&&d.replaceWith(c.hmbkp_dir_sizes)}}),
23
- // Closing ThickBox Modal Window
24
- a(document).on("click",".hmbkp-thickbox-close",function(a){a.preventDefault(),window.parent.tb_remove()}),a(document).on("click","#hmbkp-warning-backup .notice-dismiss",function(){a.post(ajaxurl,{action:"hmbkp_dismiss_error"})})});
1
+ var BackUpWordPressAdmin=function(a){"use strict";function b(){d=a("select#hmbkp_schedule_recurrence_type"),a.ajaxSetup({cache:!1}),d.length&&(c(d.val()),a(document).on("change","select#hmbkp_schedule_recurrence_type",function(){c(a(this).val())})),a(document).on("click",".hmbkp-schedule-actions .delete-action",function(a){confirm(hmbkp.delete_schedule)||a.preventDefault()}),a(document).on("click",".hmbkp_manage_backups_row .delete-action",function(a){confirm(hmbkp.delete_backup)||a.preventDefault()}),a(document).on("click",".hmbkp-edit-schedule-excludes-form .delete-action",function(a){confirm(hmbkp.remove_exclude_rule)||a.preventDefault()}),a.post(ajaxurl,{nonce:hmbkp.nonce,action:"hmbkp_cron_test"},function(b){"1"!==b&&a(".wrap > h2").after(b)}),a(document).on("click",".hmbkp-run",function(b){wp.heartbeat.interval("fast"),a(this).closest(".hmbkp-schedule-sentence").addClass("hmbkp-running"),a(".hmbkp-error").removeClass("hmbkp-error");var c=a("[data-hmbkp-schedule-id]").attr("data-hmbkp-schedule-id");a.post(ajaxurl,{hmbkp_run_schedule_nonce:hmbkp.hmbkp_run_schedule_nonce,action:"hmbkp_run_schedule",hmbkp_schedule_id:c}),b.preventDefault()}),a(document).on("heartbeat-send",function(b,c){c.hmbkp_schedule_id=a("[data-hmbkp-schedule-id]").attr("data-hmbkp-schedule-id"),a(".hmbkp-schedule-sentence.hmbkp-running").length?c.hmbkp_is_in_progress=!0:c.hmbkp_client_request="site_size"}),a(document).on("heartbeat-tick",function(b,c){if(0!==c.hmbkp_schedule_status||a(".hmbkp-error").length||location.reload(!0),0!==c.hmbkp_schedule_status&&void 0!==c.hmbkp_schedule_status&&a(".hmbkp-status").replaceWith(c.hmbkp_schedule_status),void 0!==c.hmbkp_site_size&&a("code.calculating").length){a("code.calculating").text(c.hmbkp_site_size);var d=a(".hmbkp-exclude-settings");d.length&&d.replaceWith(c.hmbkp_dir_sizes)}}),a(document).on("click",".hmbkp-thickbox-close",function(a){a.preventDefault(),window.parent.tb_remove()}),a(document).on("click","#hmbkp-warning-backup .notice-dismiss",function(){a.post(ajaxurl,{action:"hmbkp_dismiss_error"})}),jQuery(document).one("click",".hmbkp_send_error_via_email",function(a){a.preventDefault(),jQuery(this).addClass("hmbkp-ajax-loading").attr("disabled","disabled"),jQuery.post(ajaxurl,{nonce:hmbkp.nonce,action:"hmbkp_email_error",hmbkp_error:data},function(){})})}function c(a){a="undefined"!=typeof a?a:"manually";var b=jQuery(".recurring-setting"),c=jQuery("#schedule-start"),d=jQuery(".twice-js");switch(a){case"manually":b.hide();break;case"hourly":b.hide();break;case"daily":b.hide(),c.show(),d.hide();break;case"twicedaily":b.hide(),c.show(),d.show();break;case"weekly":// fall through
2
+ case"fortnightly":b.hide(),jQuery("#start-day").show(),c.show(),d.hide();break;case"monthly":b.hide(),c.show(),jQuery("#start-date").show(),d.hide()}}var d;return{init:b}}(jQuery);jQuery(document).ready(BackUpWordPressAdmin.init);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
backupwordpress.php CHANGED
@@ -3,7 +3,7 @@
3
  Plugin Name: BackUpWordPress
4
  Plugin URI: http://bwp.hmn.md/
5
  Description: Simple automated backups of your WordPress powered website. Once activated you'll find me under <strong>Tools &rarr; Backups</strong>. On multisite, you'll find me under the Network Settings menu.
6
- Version: 3.4.3
7
  Author: Human Made Limited
8
  Author URI: http://hmn.md/
9
  License: GPL-2+
3
  Plugin Name: BackUpWordPress
4
  Plugin URI: http://bwp.hmn.md/
5
  Description: Simple automated backups of your WordPress powered website. Once activated you'll find me under <strong>Tools &rarr; Backups</strong>. On multisite, you'll find me under the Network Settings menu.
6
+ Version: 3.4.4-beta
7
  Author: Human Made Limited
8
  Author URI: http://hmn.md/
9
  License: GPL-2+
classes/class-path.php CHANGED
@@ -105,18 +105,22 @@ class Path {
105
 
106
  if ( path_in_php_open_basedir( dirname( $site_path ) ) ) {
107
 
108
- // Handle wordpress installed in a subdirectory
109
- // 1. index.php and wp-config.php found in parent dir
110
- // 2. index.php in parent dir, wp-config.php in $site_path ( wp-config.php can be in both locations )
111
- if ( ( file_exists( dirname( $site_path ) . '/wp-config.php' ) || file_exists( $site_path . '/wp-config.php' ) ) && file_exists( dirname( $site_path ) . '/index.php' ) ) {
112
- $home_path = dirname( $site_path );
 
 
113
  }
114
 
115
- // Handle wp-config.php being above site_path
116
- if ( file_exists( dirname( $site_path ) . '/wp-config.php' ) && ! file_exists( $site_path . '/wp-config.php' ) && ! file_exists( dirname( $site_path ) . '/index.php' ) ) {
117
- $home_path = $site_path;
 
 
 
118
  }
119
-
120
  }
121
 
122
  return wp_normalize_path( untrailingslashit( $home_path ) );
105
 
106
  if ( path_in_php_open_basedir( dirname( $site_path ) ) ) {
107
 
108
+ $home = set_url_scheme( get_option( 'home' ), 'http' );
109
+ $siteurl = set_url_scheme( get_option( 'siteurl' ), 'http' );
110
+ if ( ! empty( $home ) && 0 !== strcasecmp( $home, $siteurl ) ) {
111
+ $wp_path_rel_to_home = str_ireplace( $home, '', $siteurl ); /* $siteurl - $home */
112
+ $pos = strripos( wp_normalize_path( $_SERVER['SCRIPT_FILENAME'] ), trailingslashit( $wp_path_rel_to_home ) );
113
+ $home_path = substr( $_SERVER['SCRIPT_FILENAME'], 0, $pos );
114
+ $home_path = trailingslashit( $home_path );
115
  }
116
 
117
+ if ( is_multisite() ) {
118
+ $slashed_home = trailingslashit( get_option( 'home' ) );
119
+ $base = parse_url( $slashed_home, PHP_URL_PATH );
120
+ $document_root_fix = wp_normalize_path( realpath( $_SERVER['DOCUMENT_ROOT'] ) );
121
+ $abspath_fix = wp_normalize_path( ABSPATH );
122
+ $home_path = 0 === strpos( $abspath_fix, $document_root_fix ) ? $document_root_fix . $base : $home_path;
123
  }
 
124
  }
125
 
126
  return wp_normalize_path( untrailingslashit( $home_path ) );
classes/class-plugin.php CHANGED
@@ -6,8 +6,7 @@ namespace HM\BackUpWordPress;
6
  * Class Plugin
7
  */
8
  final class Plugin {
9
-
10
- const PLUGIN_VERSION = '3.4.3';
11
 
12
  /**
13
  * @var Plugin The singleton instance.
6
  * Class Plugin
7
  */
8
  final class Plugin {
9
+ const PLUGIN_VERSION = '3.4.4-beta';
 
10
 
11
  /**
12
  * @var Plugin The singleton instance.
languages/backupwordpress.pot CHANGED
@@ -2,9 +2,9 @@
2
  # This file is distributed under the GPL-2+.
3
  msgid ""
4
  msgstr ""
5
- "Project-Id-Version: BackUpWordPress 3.4.3\n"
6
  "Report-Msgid-Bugs-To: backupwordpress@hmn.md\n"
7
- "POT-Creation-Date: 2016-02-01 16:52:33+00:00\n"
8
  "MIME-Version: 1.0\n"
9
  "Content-Type: text/plain; charset=utf-8\n"
10
  "Content-Transfer-Encoding: 8bit\n"
@@ -96,7 +96,7 @@ msgstr ""
96
  msgid "This is where your backups will appear once you have some."
97
  msgstr ""
98
 
99
- #: admin/backups.php:25
100
  msgid "add schedule"
101
  msgstr ""
102
 
@@ -799,7 +799,7 @@ msgstr ""
799
  msgid "Unfortunately, the backup file was too large to attach to this email."
800
  msgstr ""
801
 
802
- #: classes/class-path.php:338
803
  msgid "This %s file ensures that other people cannot download your backup files."
804
  msgstr ""
805
 
@@ -1151,4 +1151,4 @@ msgctxt "backups count"
1151
  msgid "One backup completed"
1152
  msgid_plural "%1$s backups completed"
1153
  msgstr[0] ""
1154
- msgstr[1] ""
2
  # This file is distributed under the GPL-2+.
3
  msgid ""
4
  msgstr ""
5
+ "Project-Id-Version: BackUpWordPress 3.4.4-beta\n"
6
  "Report-Msgid-Bugs-To: backupwordpress@hmn.md\n"
7
+ "POT-Creation-Date: 2016-02-11 15:36:33+00:00\n"
8
  "MIME-Version: 1.0\n"
9
  "Content-Type: text/plain; charset=utf-8\n"
10
  "Content-Transfer-Encoding: 8bit\n"
96
  msgid "This is where your backups will appear once you have some."
97
  msgstr ""
98
 
99
+ #: admin/backups.php:26
100
  msgid "add schedule"
101
  msgstr ""
102
 
799
  msgid "Unfortunately, the backup file was too large to attach to this email."
800
  msgstr ""
801
 
802
+ #: classes/class-path.php:342
803
  msgid "This %s file ensures that other people cannot download your backup files."
804
  msgstr ""
805
 
1151
  msgid "One backup completed"
1152
  msgid_plural "%1$s backups completed"
1153
  msgstr[0] ""
1154
+ msgstr[1] ""
readme.txt CHANGED
@@ -2,7 +2,7 @@
2
  Contributors: humanmade, willmot, pauldewouters, joehoyle, mattheu, tcrsavage, cuvelier
3
  Tags: back up, backup, backups, database, zip, db, files, archive, wp-cli, humanmade
4
  Requires at least: 3.9
5
- Tested up to: 4.4.1
6
  Stable tag: 3.4.3
7
 
8
  Simple automated backups of your WordPress-powered website.
@@ -158,6 +158,10 @@ users should see major improvements to reliability.
158
 
159
  == Changelog ==
160
 
 
 
 
 
161
  ### 3.4.3
162
 
163
  * Fix a bug where backups were not downloadable when WordPress installed in a subdirectory
2
  Contributors: humanmade, willmot, pauldewouters, joehoyle, mattheu, tcrsavage, cuvelier
3
  Tags: back up, backup, backups, database, zip, db, files, archive, wp-cli, humanmade
4
  Requires at least: 3.9
5
+ Tested up to: 4.4.2
6
  Stable tag: 3.4.3
7
 
8
  Simple automated backups of your WordPress-powered website.
158
 
159
  == Changelog ==
160
 
161
+ ### 3.4.4-beta
162
+
163
+ * Fixes a bug which caused the root path to the WordPress install to be miscalulated in certain setups.
164
+
165
  ### 3.4.3
166
 
167
  * Fix a bug where backups were not downloadable when WordPress installed in a subdirectory
vendor/composer/LICENSE ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ Copyright (c) 2015 Nils Adermann, Jordi Boggiano
3
+
4
+ Permission is hereby granted, free of charge, to any person obtaining a copy
5
+ of this software and associated documentation files (the "Software"), to deal
6
+ in the Software without restriction, including without limitation the rights
7
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+ copies of the Software, and to permit persons to whom the Software is furnished
9
+ to do so, subject to the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be included in all
12
+ copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20
+ THE SOFTWARE.
21
+